Make repository less of a store
This commit is contained in:
@@ -2,7 +2,7 @@ export class LRUCache<T, U> {
|
|||||||
map = new Map<T, U>()
|
map = new Map<T, U>()
|
||||||
keys: T[] = []
|
keys: T[] = []
|
||||||
|
|
||||||
constructor(readonly maxSize: number) {}
|
constructor(readonly maxSize: number = Infinity) {}
|
||||||
|
|
||||||
has(k: T) {
|
has(k: T) {
|
||||||
return this.map.has(k)
|
return this.map.has(k)
|
||||||
|
|||||||
+9
-43
@@ -9,11 +9,18 @@ type Unsubscriber = () => void
|
|||||||
type R = Record<string, any>
|
type R = Record<string, any>
|
||||||
type M<T> = Map<string, T>
|
type M<T> = Map<string, T>
|
||||||
|
|
||||||
export interface IDerivable<T> {
|
export interface ISubscribable<T> {
|
||||||
get: () => T
|
|
||||||
subscribe(this: void, run: Subscriber<T>, invalidate?: Invalidator<T>): Unsubscriber
|
subscribe(this: void, run: Subscriber<T>, invalidate?: Invalidator<T>): Unsubscriber
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ISettable<T> {
|
||||||
|
set: (xs: T) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IDerivable<T> extends ISubscribable<T> {
|
||||||
|
get: () => T
|
||||||
|
}
|
||||||
|
|
||||||
export interface IReadable<T> extends IDerivable<T> {
|
export interface IReadable<T> extends IDerivable<T> {
|
||||||
derived: <U>(f: (v: T) => U) => IReadable<U>
|
derived: <U>(f: (v: T) => U) => IReadable<U>
|
||||||
throttle(t: number): IReadable<T>
|
throttle(t: number): IReadable<T>
|
||||||
@@ -339,44 +346,3 @@ export const asReadable = <T>(store: IDerivable<T>) => {
|
|||||||
throttle: (t: number) => new Derived<T>(store, identity, t),
|
throttle: (t: number) => new Derived<T>(store, identity, t),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ICustomStore<T> = {
|
|
||||||
get: () => T
|
|
||||||
start: (set: (x: T) => void) => () => void
|
|
||||||
}
|
|
||||||
|
|
||||||
export const customStore = <T>({get, start}: ICustomStore<T>) => {
|
|
||||||
const subs: Subscriber<T>[] = []
|
|
||||||
|
|
||||||
const set = (newValue: T) => {
|
|
||||||
value = newValue
|
|
||||||
|
|
||||||
for (const sub of subs) {
|
|
||||||
sub(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let stop: () => void
|
|
||||||
let value = get()
|
|
||||||
|
|
||||||
return asReadable({
|
|
||||||
get: () => subs.length === 0 ? get() : value,
|
|
||||||
subscribe: (sub: Subscriber<T>) => {
|
|
||||||
subs.push(sub)
|
|
||||||
|
|
||||||
if (subs.length === 1) {
|
|
||||||
stop = start(set)
|
|
||||||
set(get())
|
|
||||||
}
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
subs.splice(subs.findIndex(s => s === sub), 1)
|
|
||||||
|
|
||||||
if (subs.length === 0) {
|
|
||||||
stop()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import {throttle} from 'throttle-debounce'
|
import {throttle} from 'throttle-debounce'
|
||||||
import type {IReadable, Subscriber, Invalidator} from '@welshman/lib'
|
import type {ISubscribable, ISettable, Subscriber, Invalidator} from '@welshman/lib'
|
||||||
import {Derived, flatten, Emitter, sortBy, customStore, inc, first, chunk, sleep, uniq, omit, now, range, identity} from '@welshman/lib'
|
import {flatten, Emitter, sortBy, inc, chunk, sleep, uniq, omit, now, range, identity} from '@welshman/lib'
|
||||||
import {DELETE} from './Kinds'
|
import {DELETE} from './Kinds'
|
||||||
import {EPOCH, matchFilter, getIdFilters, matchFilters} from './Filters'
|
import {EPOCH, matchFilter} from './Filters'
|
||||||
import {isReplaceable, isTrustedEvent} from './Events'
|
import {isReplaceable, isTrustedEvent} from './Events'
|
||||||
import {getAddress} from './Address'
|
import {getAddress} from './Address'
|
||||||
import type {Filter} from './Filters'
|
import type {Filter} from './Filters'
|
||||||
@@ -18,7 +18,7 @@ export type RepositoryOptions = {
|
|||||||
throttle?: number
|
throttle?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Repository extends Emitter implements IReadable<TrustedEvent[]> {
|
export class Repository extends Emitter implements ISubscribable<TrustedEvent[]>, ISettable<TrustedEvent[]> {
|
||||||
eventsById = new Map<string, TrustedEvent>()
|
eventsById = new Map<string, TrustedEvent>()
|
||||||
eventsByAddress = new Map<string, TrustedEvent>()
|
eventsByAddress = new Map<string, TrustedEvent>()
|
||||||
eventsByTag = new Map<string, TrustedEvent[]>()
|
eventsByTag = new Map<string, TrustedEvent[]>()
|
||||||
@@ -68,41 +68,6 @@ export class Repository extends Emitter implements IReadable<TrustedEvent[]> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
derived<U>(f: (v: TrustedEvent[]) => U): Derived<U> {
|
|
||||||
return new Derived<U>(this, f)
|
|
||||||
}
|
|
||||||
|
|
||||||
throttle(t: number): Derived<TrustedEvent[]> {
|
|
||||||
return new Derived<TrustedEvent[]>(this, identity, t)
|
|
||||||
}
|
|
||||||
|
|
||||||
filter(filters: Filter[], {includeDeleted = false} = {}) {
|
|
||||||
const getValue = () => this.query(filters, {includeDeleted})
|
|
||||||
|
|
||||||
return customStore<TrustedEvent[]>({
|
|
||||||
get: getValue,
|
|
||||||
start: setValue => {
|
|
||||||
const onEvent = (event: TrustedEvent) => {
|
|
||||||
if (matchFilters(filters, event)) {
|
|
||||||
setValue(getValue())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const onRefresh = () => {
|
|
||||||
setValue(getValue())
|
|
||||||
}
|
|
||||||
|
|
||||||
this.on('event', onEvent)
|
|
||||||
this.on('delete', onRefresh)
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
this.off('event', onEvent)
|
|
||||||
this.off('delete', onRefresh)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
notifyUpdate = maybeThrottle(this.options.throttle, () => {
|
notifyUpdate = maybeThrottle(this.options.throttle, () => {
|
||||||
const events = this.get()
|
const events = this.get()
|
||||||
|
|
||||||
@@ -138,10 +103,6 @@ export class Repository extends Emitter implements IReadable<TrustedEvent[]> {
|
|||||||
return duplicate && duplicate.created_at >= event.created_at
|
return duplicate && duplicate.created_at >= event.created_at
|
||||||
}
|
}
|
||||||
|
|
||||||
watchEvent(idOrAddress: string) {
|
|
||||||
return this.filter(getIdFilters([idOrAddress]), {includeDeleted: true}).derived(first)
|
|
||||||
}
|
|
||||||
|
|
||||||
query(filters: Filter[], {includeDeleted = false} = {}) {
|
query(filters: Filter[], {includeDeleted = false} = {}) {
|
||||||
const result: TrustedEvent[][] = []
|
const result: TrustedEvent[][] = []
|
||||||
for (let filter of filters) {
|
for (let filter of filters) {
|
||||||
|
|||||||
Reference in New Issue
Block a user