a reactive (signals based) hypermedia web framework (wip) stormlightlabs.github.io/volt/
hypermedia frontend signals
at main 4.4 kB view raw
1/** 2 * Volt.js Debug Utilities 3 * 4 * Lazy-loadable debugging module for signal introspection and visualization. 5 * Import from 'voltx.js/debug' to access these utilities without affecting production bundle size. 6 * 7 * @example 8 * ```ts 9 * import { debugSignal, debugComputed, logAllSignals } from 'voltx.js/debug'; 10 * 11 * const count = debugSignal(0, 'count'); 12 * const doubled = debugComputed(() => count.get() * 2, 'doubled'); 13 * 14 * logAllSignals(); 15 * ``` 16 * 17 * @module voltx.js/debug 18 * @packageDocumentation 19 */ 20 21import type { ComputedSignal, Signal, SignalType } from "$types/volt"; 22import { 23 buildDependencyGraph, 24 detectCircularDependencies, 25 getDependencies, 26 getDependents, 27 getSignalDepth, 28 recordDependencies, 29} from "./debug/graph"; 30import { 31 disableGlobalTracing, 32 enableGlobalTracing, 33 logAllReactives, 34 logAllSignals, 35 logReactive, 36 logSignal, 37 logSignalTable, 38 trace, 39 watch, 40} from "./debug/logger"; 41import { 42 clearRegistry, 43 getAllReactives, 44 getAllSignals, 45 getReactiveInfo, 46 getRegistryStats, 47 getSignalInfo, 48 nameReactive, 49 nameSignal, 50 registerReactive, 51 registerSignal, 52} from "./debug/registry"; 53import { computed as coreComputed, reactive as coreReactive, signal as coreSignal } from "./index"; 54 55/** 56 * Create a signal with automatic debug registration. 57 * 58 * @param initialValue - The initial value 59 * @param name - Optional name for debugging 60 * @returns A Signal with debug metadata 61 */ 62export function debugSignal<T>(initialValue: T, name?: string): Signal<T> { 63 const sig = coreSignal(initialValue); 64 registerSignal(sig, "signal", name); 65 return sig; 66} 67 68/** 69 * Create a computed signal with automatic debug registration. 70 * 71 * @param compute - Computation function 72 * @param name - Optional name for debugging 73 * @returns A ComputedSignal with debug metadata 74 */ 75export function debugComputed<T>(compute: () => T, name?: string): ComputedSignal<T> { 76 const comp = coreComputed(compute); 77 registerSignal(comp, "computed", name); 78 const deps = extractComputedDeps(comp); 79 if (deps.length > 0) { 80 recordDependencies(comp, deps); 81 } 82 return comp; 83} 84 85/** 86 * Create a reactive object with automatic debug registration. 87 * 88 * @param target - The object or array to make reactive 89 * @param name - Optional name for debugging 90 * @returns A reactive proxy with debug metadata 91 */ 92export function debugReactive<T extends object>(target: T, name?: string): T { 93 const proxy = coreReactive(target); 94 registerReactive(proxy, name); 95 return proxy; 96} 97 98/** 99 * Extract dependencies from a computed signal by running it in a tracking context. 100 * This is a helper that uses the same tracking mechanism as the core. 101 */ 102function extractComputedDeps(_comp: ComputedSignal<unknown>): Array<Signal<unknown> | ComputedSignal<unknown>> { 103 // The computed has already run and subscribed to its dependencies 104 // TODO: We need to access the internal dependency tracking 105 return []; 106} 107 108export function attachDebugger(sig: Signal<unknown> | ComputedSignal<unknown>, type: SignalType, name?: string): void { 109 registerSignal(sig, type, name); 110} 111 112export const vdebugger = { 113 signal: debugSignal, 114 computed: debugComputed, 115 reactive: debugReactive, 116 attach: attachDebugger, 117 getAllSignals, 118 getAllReactives, 119 getSignalInfo, 120 getReactiveInfo, 121 getStats: getRegistryStats, 122 nameSignal, 123 nameReactive, 124 getDependencies, 125 getDependents, 126 buildGraph: buildDependencyGraph, 127 detectCycles: detectCircularDependencies, 128 getDepth: getSignalDepth, 129 log: logSignal, 130 logReactive, 131 logAll: logAllSignals, 132 logAllReactives, 133 logTable: logSignalTable, 134 trace, 135 watch, 136 enableTracing: enableGlobalTracing, 137 disableTracing: disableGlobalTracing, 138 clear: clearRegistry, 139}; 140 141export type { GraphNode, SignalMetadata, SignalType } from "$types/volt"; 142export { hasDependency } from "./debug/graph"; 143export { 144 buildDependencyGraph, 145 detectCircularDependencies, 146 getDependencies, 147 getDependents, 148 getSignalDepth, 149} from "./debug/graph"; 150export { 151 disableGlobalTracing, 152 enableGlobalTracing, 153 logAllReactives, 154 logAllSignals, 155 logReactive, 156 logSignal, 157 logSignalTable, 158 trace, 159 watch, 160} from "./debug/logger"; 161export { 162 clearRegistry, 163 getAllReactives, 164 getAllSignals, 165 getReactiveInfo, 166 getReactiveMetadata, 167 getRegistryStats, 168 getSignalInfo, 169 getSignalMetadata, 170 nameReactive, 171} from "./debug/registry"; 172export { nameSignal } from "./debug/registry";