// 当前正在收集依赖的 effect;null 表示非追踪态 let active: (() => void) | null = null; /*** 响应式信号:无参调用读值并收集依赖,传参写值并触发订阅 ***/ export interface Signal { (): T; (value: T): void; } /*** 创建信号:框架状态的最小单元 ***/ export function signal(initial: T): Signal { let value = initial; const subs = new Set<() => void>(); const read = (...args: unknown[]) => { if (args.length === 0) { if (active) subs.add(active); // 依赖收集 return value; } const v = args[0] as T; if (Object.is(v, value)) return; // 值未变不触发 value = v; for (const fn of [...subs]) fn(); // 拷贝后触发,防遍历中修改 }; return read as Signal; } /*** 副作用:立即执行一次并追踪内部读取的信号,依赖变化自动重跑 ***/ export function effect(fn: () => void): () => void { const run = () => { const prev = active; active = run; try { fn(); } finally { active = prev; } }; run(); return () => { /* 演示级实现:不做依赖清理 */ }; } /*** 计算值:由信号派生的只读视图,同样参与上层依赖收集 ***/ export function computed(fn: () => T): () => T { const out = signal(undefined as T); effect(() => out(fn())); return () => out(); }