Files
terminal-lab/xterminal/source/base/reactivity.ts
douboer@gmail.com 3b7c1d558a first commit
2026-03-03 13:23:14 +08:00

71 lines
1.7 KiB
TypeScript

import { isFunction } from "../helpers";
import type { IDisposable } from "../types";
/**
* Reactivity
* => https://github.com/henryhale/reactivity
*/
/**
* Effect - callback triggered when a reactive value changes
*/
export type IEffect = () => void;
/**
* Reactive value -> all effects are disposable
*/
export interface IReactive<T> extends IDisposable {
value: T;
}
/**
* Global observer
*/
let observer: IEffect | null;
/**
* Function that creates a disposable reactive object from a primitive value
* @param value The primitive value (initial)
* @returns Reactive object
*/
export function ref<T>(value: T): IReactive<T> {
const observers = new Set<IEffect>();
let disposed = false;
return {
get value() {
// allow subscriptons only when the object is not disposed
if (!disposed && isFunction(observer)) {
observers.add(observer);
}
return value;
},
set value(newValue) {
value = newValue;
// alert subscribers only when the object is not disposed
if (!disposed) {
observers.forEach((o) => o.call(undefined));
}
},
dispose() {
if (disposed) return;
disposed = true;
// remove all subscriptions
observers.clear();
}
};
}
/**
* Function that opens a subscription to reactive values
* @param fn The subscription (function) to be made
*/
export function createEffect(fn: IEffect): void {
if (!isFunction(fn)) return;
observer = fn;
try {
fn.call(undefined);
} finally {
observer = null;
}
}