UNPKG

@winged/core

Version:

Morden webapp framekwork made only for ts developers. (UNDER DEVELOPMENT, PLEASE DO NOT USE)

67 lines (58 loc) 1.82 kB
import { ModificationTree } from '../types' type WatcherCallback = (modificationTree: ModificationTree) => void export abstract class Observable { private static idCounter = 0 public readonly _observableId = ++Observable.idCounter protected _watchedTargets: { [id: string]: { target: Observable, watcherCount: number } } = {} protected _watchers: Array<{ context: any; callback: WatcherCallback; }> = [] public _watchBy(context: any, callback: WatcherCallback) { this._watchers.push({ context, callback } as any) } public _stopWatchBy(context: any) { this._watchers = this._watchers.filter((w) => w.context !== context) } protected _emitValueChange(modificationTree: ModificationTree) { for (const { callback } of this._watchers) { callback(modificationTree) } } protected _registerChild(field: () => string | string, child: Observable) { const id = child._observableId if (!child._watchedTargets[id]) { child._watchedTargets[id] = { target: child, watcherCount: 0 } } child._watchedTargets[id].watcherCount++ child._watchBy(this, (modificationTree) => { let s: string if (typeof field === 'function') { s = field() } else { s = field } this._emitValueChange({ [s]: modificationTree }) }) } protected _unregisterChild(childOrChildId: Observable | string) { let id: string if (childOrChildId instanceof Observable) { id = childOrChildId._observableId + '' } else { id = childOrChildId } const watchInfo = this._watchedTargets[id] if (watchInfo.watcherCount > 1) { watchInfo.watcherCount-- } else { this._watchedTargets[id].target._stopWatchBy(this) delete this._watchedTargets[id] } } }