-
Notifications
You must be signed in to change notification settings - Fork 3
Hook Instrumentation
The src/hooks/ directory is the interface between the React runtime and the Basis engine. Every standard React hook is wrapped in a proxy that injects telemetry while keeping 100% API parity with the original React hooks.
Each Basis hook works as a wrapper around the real React hook. It calls the standard hook internally, but extends the signature to accept an optional label (injected at compile-time by the Babel plugin).
// Internal Logic Flow
1. Receive call from User/Babel.
2. Initialize standard React hook.
3. Register the hook's Role (LOCAL, CONTEXT, or PROJ) with the Engine.
4. Intercept the dispatcher (setter) to record temporal pulses.
5. Return standard React values to the component.Normally, React state setters are black boxes. Basis wraps the dispatcher in a useCallback that notifies the engine before the actual state change happens.
-
Registration: On mount, the hook calls
registerVariable(label, { role: SignalRole.LOCAL }). -
Interception: The setter is proxied. When called, it runs
recordUpdate(label)first. -
Circuit Breaking: If the engine detects an infinite loop (>150 updates/sec),
recordUpdatereturnsfalseand the hook blocks the state update entirely. This saves the browser thread from freezing.
v0.5.0 added instrumentation for global context to enable Subspace Decomposition.
-
createContext: The proxy attaches a hidden, non-enumerable_basis_labelto the context object. -
useContext: When a component consumes a context, the proxy uses auseLayoutEffectto pulse that context's label. This lets the engine see the update rhythm of the context and identify local hooks that are shadowing it.
To build the causal graph, the engine needs to know which effect caused which state update. This is done with a "bracketing" technique:
export function useEffect(effect: React.EffectCallback, deps?: React.DependencyList, label?: string) {
const effectiveLabel = label || 'anonymous_effect';
reactUseEffect(() => {
beginEffectTracking(effectiveLabel); // Set global source
const destructor = effect(); // Execute user logic
endEffectTracking(); // Clear global source
return destructor;
}, deps);
}Any state update that happens while an effect is "bracketed" gets an edge in the graph pointing from that effect. This is how the engine detects Double Render Cycles.
Not all signals are equal. The instrumentation layer classifies hooks into three roles:
-
Subspace Anchors (
$\Omega$ ): Global Contexts. Treated as the source of truth. -
Basis Vectors (!): Local hooks (
useState). Audited for independence from the anchors. -
Projections: Derived signals (
useMemo,useCallback). The engine checks if these are stable. If a projection pulses on every tick, it gets flagged as unstable, which usually means a missing dependency or reference drift.
Basis instruments the React 19 Actions API. Optimistic updates and action states are treated as regular signals in the system.
-
useOptimistic: Tracked as a local signal, same asuseState. -
useActionState: The engine correlates the pending transition with the primary state mutation, so async actions don't create false edges in the graph.
Every registered variable is cleaned up when its component unmounts:
return () => unregisterVariable(effectiveLabel);
This keeps the system clean. The efficiency score and rankings only reflect currently active components. No zombie signals from unmounted components leaking into the audit.