@webnode/livedata
Version:
Observed within a given lifecycle
88 lines (73 loc) • 2.01 kB
text/typescript
export interface LifecycleOwner {
addLiveCanceler(cb: LiveCanceler): void
deleteLiveCanceler(cb: LiveCanceler): void
}
export interface LiveCanceler {
(): void
}
export interface LiveCallback<T> {
(value: T): void
}
interface LiveHandler<T> {
callback: LiveCallback<T> | Array<LiveCallback<T>>
canceler: LiveCanceler
}
export class LiveData<T> {
private _value: T
private handlers: Map<LifecycleOwner, LiveHandler<T>> = new Map()
public observe(com: LifecycleOwner, cb: LiveCallback<T>) {
if (this.handlers.has(com)) {
let handler = this.handlers.get(com) as LiveHandler<T>
if (handler.callback instanceof Array) {
handler.callback.push(cb)
} else {
handler.callback = [handler.callback, cb]
}
} else {
let canceler = () => this.handlers.delete(com)
this.handlers.set(com, {
callback: cb,
canceler: canceler
})
com.addLiveCanceler(canceler)
}
}
public async set(value: T) {
await Promise.resolve()
this._value = value
for (let handler of this.handlers.values()) {
if (handler.callback instanceof Array) {
for (let cb of handler.callback) {
cb(this._value)
}
} else {
handler.callback(this._value)
}
}
}
public get value(): T {
return this._value
}
public hasObservers(): boolean {
return this.handlers.size > 0
}
public sizeOfObservers(): number {
return this.handlers.size
}
public hasObserver(com: LifecycleOwner) {
return this.handlers.has(com)
}
public deleteObserver(com: LifecycleOwner) {
com.deleteLiveCanceler((this.handlers.get(com) as LiveHandler<T>).canceler)
this.handlers.delete(com)
}
public deleteObserverIfHas(com: LifecycleOwner) {
if (this.handlers.has(com)) {
com.deleteLiveCanceler((this.handlers.get(com) as LiveHandler<T>).canceler)
this.handlers.delete(com)
}
}
public clearObservers() {
this.handlers.clear()
}
}