import { type Closure } from "@"; export namespace Ref { export type Task = Closure<[new: T1, old: T1], void>; export type DeletionTask = Closure<[], void>; } export type Ref = { /** * ***Brief*** * Unwraps the wrapped value of type `T1`. * * ***Requirement*** * Does not `panic`. * * ***Example*** * ```ts * let unsafe: Unsafe = Unsafe(500n); * unsafe.unwrap(); * ``` */ unwrap(): T1; /** * ***Brief*** * Mutates the internal value of the `Ref` instance. */ mut(value: T1): Ref; /** * ***Brief*** * Registers a callback that is invoked whenever the value changes. * * ***Example*** * ```ts * let ref: Ref = Ref(200n); * ref.onChange(value => { * /// ... * return; * }); * ref.mut(404n); * ``` */ onChange(task: Ref.Task): Ref.DeletionTask; }; /** * ***Brief*** * Wrapper that supports mutation and change tracking. */ export function Ref(_value: T1): Ref { let _this: Ref; let _count: bigint; let _taskMap: Map>; /** @constructor */ { _count = 0n; _taskMap = new Map(); return _this = { unwrap, mut, onChange }; } function unwrap(): T1 { return _value; } function mut(value: T1): Ref { let oldValue: T1 = unwrap(); let newValue: T1 = value; _value = value; _taskMap .values() .toArray() .forEach(task => { return task(newValue, oldValue); }); return _this; } function onChange(task: Ref.Task): Ref.DeletionTask { let key: bigint = _newKey(); _taskMap.set(key, task); return () => { _taskMap.delete(key); return; } } function _newKey(): bigint { return _count += 1n; } }