Files
vacuum-wall/webui/static/hoover/reactivity.js
T

60 lines
1.5 KiB
JavaScript

/**
* Hoover — reactivity.js
*
* Reactive Proxy state + batched render requests via queueMicrotask.
* Multiple property mutations in the same microtask tick produce a single
* render cycle across all registered render roots.
*/
/**
* Global flag to prevent duplicate microtask scheduling.
*/
let _scheduled = false;
/**
* Callback invoked by render.js to perform the actual batched re-render.
* Set via setCommitFn() during render engine initialization.
*/
let _commitFn = null;
/**
* Register the commit callback that performs batched re-renders.
* Called by render.js during initialization.
*/
export function setCommitFn(fn) {
_commitFn = fn;
}
/**
* Schedule a single batched re-render for all active render roots.
* Multiple reactive property mutations in the same tick produce one diff pass.
*/
export function requestUpdate() {
if (_scheduled) return;
_scheduled = true;
queueMicrotask(() => {
_scheduled = false;
if (_commitFn) _commitFn();
});
}
/**
* Wrap an object in a reactive Proxy.
* Any property *assignment* that changes the value automatically triggers
* a batched re-render via requestUpdate().
*/
export function reactive(obj = {}) {
return new Proxy(obj, {
set(target, key, value, receiver) {
const old = target[key];
const ok = Reflect.set(target, key, value, receiver);
if (ok && !Object.is(old, value)) {
requestUpdate();
}
return ok;
}
});
}