UNPKG

@dvcol/common-utils

Version:

Typescript library for common utility functions and constants

115 lines (113 loc) 3.27 kB
// lib/common/utils/observable.utils.ts var isFunction = (value) => typeof value === "function"; var Observable = class { _observers = /* @__PURE__ */ new Set(); /** * Notifies all observers with optional data. * * @protected * @param {T} data - The new data to be sent to observers. * @memberof Observable */ _notify(data) { this._observers.forEach((observer) => observer(data)); } /** * Updates the observers with the new data. * * @param {T} data - The new data to be sent to observers. * @memberof Observable */ update(data) { this._notify(data); } /** * Subscribes an observer to the observable and returns an unsubscribe function. * * @param {Observer<T>} observer - The observer function to be added. * @returns {() => boolean} An unsubscribe function that removes the observer. * @memberof Observable */ subscribe(observer) { this._observers.add(observer); return () => this.unsubscribe(observer); } /** * Unsubscribes an observer from the observable. * If no observer is provided, unsubscribes all observers. * * @param {Observer<T>} [observer] - The observer to be removed. * @returns {boolean} True if the observer(s) were successfully removed, false otherwise. * @memberof Observable */ unsubscribe(observer) { if (observer) return this._observers.delete(observer); this._observers.clear(); return true; } }; var ObservableState = class extends Observable { _mutable; _state; /** * Notifies all observers with optional data and previous state. * * @protected * @param {T} data - The new data to be sent to observers. * @param {T} prev - the previous data (defaults to this._state). * @memberof Observable */ _notify(data, prev = this._state) { this._observers.forEach((observer) => observer(data, prev)); } /** * Gets the current state of the observable. * * @readonly * @type {T} The current state. * @memberof ObservableState */ get state() { return this._state; } /** * Creates an instance of ObservableState with an initial state and mutability option. * * @param {T} state - The initial state. * @param {boolean} [mutable=false] - Indicates whether the state is mutable. * @memberof ObservableState */ constructor(state, mutable = false) { super(); this._state = state; this._mutable = mutable; } /** * Updates the state based on mutability and freezes it if necessary. * * @private * @param {T} state - The new state. * @memberof ObservableState */ _update(state) { if (this._mutable) this._state = state; else this._state = Object.freeze(state); } /** * Updates the state based on either a direct value or an update function. * Notifies observers with the new state. * * @param {T | UpdateFunction<T>} state - The new state or an update function. * @memberof ObservableState */ update(state) { const prev = typeof this._state === "object" ? structuredClone({ ...this._state }) : this._state; const data = isFunction(state) ? state(this._state) : state; this._update(data); this._notify(data, prev); } }; export { Observable, ObservableState };