import DerivationFromSource from './derivations/DerivationFromSource' import type {IDerivation} from './derivations/IDerivation' import Emitter from './utils/Emitter' export interface IBox { set(v: V): void get(): V derivation: IDerivation } export default class Box implements IBox { private _publicDerivation: IDerivation private _emitter = new Emitter() constructor(protected _value: V) { this._publicDerivation = new DerivationFromSource( (listener) => this._emitter.tappable.tap(listener), this.get.bind(this), ) } set(v: V) { if (v === this._value) return this._value = v this._emitter.emit(v) } get() { return this._value } get derivation() { return this._publicDerivation } }