@pyreon/reactivity 0.14.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","names":["_countSink","cleanupLocalDeps","_countSink"],"sources":["../src/batch.ts","../src/cell.ts","../src/scope.ts","../src/tracking.ts","../src/effect.ts","../src/computed.ts","../src/createSelector.ts","../src/debug.ts","../src/signal.ts","../src/store.ts","../src/reconcile.ts","../src/resource.ts","../src/watch.ts"],"sourcesContent":["// Batch multiple signal updates into a single notification pass.\n// Uses a Set so the same subscriber is never flushed more than once per batch,\n// even if multiple signals it depends on change within the same batch.\n\nlet batchDepth = 0\n\n// Two pre-allocated Sets swapped on each flush — avoids allocating a new Set()\n// on every batch exit. The \"active\" set collects enqueued notifications; on flush\n// we swap to the other set and iterate the captured one, then clear it for reuse.\nconst setA = new Set<() => void>()\nconst setB = new Set<() => void>()\nlet pendingNotifications = setA\n\nexport function batch(fn: () => void): void {\n batchDepth++\n try {\n fn()\n } finally {\n batchDepth--\n if (batchDepth === 0 && pendingNotifications.size > 0) {\n // Keep batching active during flush so cascade-notifications emitted\n // by flushing subscribers enqueue into the pending Set (and dedupe\n // against what's already queued) instead of firing inline. The\n // while-loop drains any cascade rounds until the graph is stable.\n //\n // Without this, a diamond dependency (a → b, c → d → effect) re-fires\n // the apex effect TWICE per signal write: the first notification path\n // through `b` reaches `effect`, whose read clears `d`'s dirty flag;\n // then when `c` is notified (still in the first flush round), it\n // re-dirties `d`, which re-notifies `effect`. Keeping batchDepth at 1\n // during flush routes those cascade-notifications through the Set,\n // which dedupes on `d`'s recompute and on `effect`'s run.\n //\n // See `packages/internals/perf-harness/src/tests/diamond-probe.test.ts`\n // for the empirical probe that caught this.\n batchDepth = 1\n try {\n while (pendingNotifications.size > 0) {\n // Swap to the other pre-allocated Set before flushing so new\n // enqueues during notification land in the alternate Set, not\n // mixed into the current iteration.\n const flush = pendingNotifications\n pendingNotifications = flush === setA ? setB : setA\n for (const notify of flush) notify()\n flush.clear()\n }\n } finally {\n batchDepth = 0\n }\n }\n }\n}\n\nexport function isBatching(): boolean {\n return batchDepth > 0\n}\n\nexport function enqueuePendingNotification(notify: () => void): void {\n pendingNotifications.add(notify)\n}\n\n/**\n * Returns a Promise that resolves after all currently-pending microtasks have flushed.\n * Useful when you need to read the DOM after a batch of signal updates has settled.\n *\n * @example\n * count.set(1); count.set(2)\n * await nextTick()\n * // DOM is now up-to-date\n */\nexport function nextTick(): Promise<void> {\n return new Promise((resolve) => queueMicrotask(resolve))\n}\n","/**\n * Lightweight reactive cell — class-based alternative to signal().\n *\n * - 1 object allocation vs signal()'s 6 closures\n * - Same API surface: peek(), set(), update(), subscribe(), listen()\n * - NOT callable as a getter (no effect tracking) — use for fixed subscriptions\n * - Methods on prototype, shared across all instances\n * - Single-listener fast path: no Set allocated when ≤1 subscriber\n *\n * Use when you need reactive state but don't need automatic effect dependency tracking.\n * Ideal for list item labels in keyed reconcilers where subscribe() is used directly.\n */\nexport class Cell<T> {\n /** @internal */ _v: T\n /** @internal */ _l: (() => void) | null = null // single-listener fast path\n /** @internal */ _s: Set<() => void> | null = null // multi-listener fallback\n\n constructor(value: T) {\n this._v = value\n }\n\n peek(): T {\n return this._v\n }\n\n set(value: T): void {\n if (Object.is(this._v, value)) return\n this._v = value\n if (this._l) this._l()\n else if (this._s) for (const fn of this._s) fn()\n }\n\n update(fn: (current: T) => T): void {\n this.set(fn(this._v))\n }\n\n /**\n * Fire-and-forget subscription — no unsubscribe returned.\n * Use when the listener's lifetime matches the cell's (e.g., list rows).\n * Saves 1 closure allocation per call vs subscribe().\n */\n listen(listener: () => void): void {\n if (!this._l && !this._s) {\n this._l = listener\n } else {\n // Promote to Set\n if (!this._s) {\n this._s = new Set()\n if (this._l) {\n this._s.add(this._l)\n this._l = null\n }\n }\n this._s.add(listener)\n }\n }\n\n subscribe(listener: () => void): () => void {\n this.listen(listener)\n // The listener could be in _l (single) or _s (multi).\n // A later subscribe() call may promote it from _l to _s,\n // so the disposer must check both locations.\n return () => {\n if (this._l === listener) this._l = null\n else this._s?.delete(listener)\n }\n }\n}\n\nexport function cell<T>(value: T): Cell<T> {\n return new Cell(value)\n}\n","// EffectScope — auto-tracks effects created during a component's setup\n// and disposes them all at once when the component unmounts.\n\nexport class EffectScope {\n private _effects: { dispose(): void }[] | null = null\n private _active = true\n private _updateHooks: (() => void)[] | null = null\n private _updatePending = false\n\n /** Register an effect/computed to be disposed when this scope stops. */\n add(e: { dispose(): void }): void {\n if (!this._active) return\n if (this._effects === null) this._effects = []\n this._effects.push(e)\n }\n\n /**\n * Temporarily re-activate this scope so effects created inside `fn` are\n * auto-tracked and will be disposed when the scope stops.\n * Used to ensure effects created in `onMount` callbacks belong to their\n * component's scope rather than leaking as global effects.\n */\n runInScope<T>(fn: () => T): T {\n const prev = _currentScope\n _currentScope = this\n try {\n return fn()\n } finally {\n _currentScope = prev\n }\n }\n\n /** Register a callback to run after any reactive update in this scope. */\n addUpdateHook(fn: () => void): void {\n if (this._updateHooks === null) this._updateHooks = []\n this._updateHooks.push(fn)\n }\n\n /**\n * Called by effects after each non-initial re-run.\n * Schedules onUpdate hooks via microtask so all synchronous effects settle first.\n */\n notifyEffectRan(): void {\n if (!this._active || !this._updateHooks || this._updateHooks.length === 0 || this._updatePending) return\n this._updatePending = true\n queueMicrotask(() => {\n this._updatePending = false\n if (!this._active || !this._updateHooks) return\n for (const fn of this._updateHooks) {\n try {\n fn()\n } catch (err) {\n console.error('[pyreon] onUpdate hook error:', err)\n }\n }\n })\n }\n\n /** Dispose all tracked effects. */\n stop(): void {\n if (!this._active) return\n if (this._effects) {\n for (const e of this._effects) e.dispose()\n }\n this._effects = null\n this._updateHooks = null\n this._updatePending = false\n this._active = false\n }\n}\n\nlet _currentScope: EffectScope | null = null\n\nexport function getCurrentScope(): EffectScope | null {\n return _currentScope\n}\n\nexport function setCurrentScope(scope: EffectScope | null): void {\n _currentScope = scope\n}\n\n/** Create a new EffectScope. */\nexport function effectScope(): EffectScope {\n return new EffectScope()\n}\n","// Global subscriber tracking context\n\nimport { enqueuePendingNotification, isBatching } from './batch'\n\nlet activeEffect: (() => void) | null = null\n\n// Tracks which subscriber sets each effect is registered in, so we can\n// clean them up before a re-run (dynamic dependency tracking).\nconst effectDeps = new WeakMap<() => void, Set<Set<() => void>>>()\n\n// Fast deps collector for renderEffect — avoids WeakMap overhead entirely.\n// When set, trackSubscriber pushes subscriber sets here instead of effectDeps.\nlet _depsCollector: Set<() => void>[] | null = null\n\n// Skip deps collection mode — for re-evaluating computeds/effects with static deps.\n// When true, trackSubscriber only does Set.add (no-op if already subscribed) and skips\n// the _depsCollector.push / WeakMap work entirely.\nlet _skipDepsCollection = false\n\nexport function setDepsCollector(collector: Set<() => void>[] | null): void {\n _depsCollector = collector\n}\n\nexport function setSkipDepsCollection(skip: boolean): void {\n _skipDepsCollection = skip\n}\n\n/**\n * Subscriber host — any reactive source that can have downstream subscribers.\n * Signals, computeds, and createSelector buckets all implement this interface.\n * The Set is created lazily — only allocated when an effect actually tracks this source.\n */\nexport interface SubscriberHost {\n /** @internal subscriber set — null until first tracked by an effect */\n _s: Set<() => void> | null\n}\n\n/**\n * Register the active effect as a subscriber of the given reactive source.\n * The subscriber Set is created lazily on the host — sources read only outside\n * effects never allocate a Set.\n */\nexport function trackSubscriber(host: SubscriberHost) {\n if (activeEffect) {\n if (!host._s) host._s = new Set()\n host._s.add(activeEffect)\n // Skip collection mode: we're already subscribed (Set.add is no-op),\n // just need activeEffect set for nested computed reads to work.\n if (_skipDepsCollection) return\n if (_depsCollector) {\n // Fast path: renderEffect stores deps inline, no WeakMap\n _depsCollector.push(host._s)\n } else {\n // Record this dep so we can remove it on cleanup\n let deps = effectDeps.get(activeEffect)\n if (!deps) {\n deps = new Set()\n effectDeps.set(activeEffect, deps)\n }\n deps.add(host._s)\n }\n }\n}\n\n/**\n * Remove an effect from every subscriber set it was registered in,\n * then clear its dep record. Call this before each re-run and on dispose.\n */\nexport function cleanupEffect(fn: () => void): void {\n const deps = effectDeps.get(fn)\n if (deps) {\n for (const sub of deps) sub.delete(fn)\n deps.clear()\n }\n}\n\nexport function notifySubscribers(subscribers: Set<() => void>) {\n if (subscribers.size === 0) return\n // Single-subscriber fast path: avoid any iteration overhead.\n if (subscribers.size === 1) {\n const sub = subscribers.values().next().value as () => void\n if (isBatching()) enqueuePendingNotification(sub)\n else sub()\n return\n }\n if (isBatching()) {\n // Effects are queued not run inline — no re-entrancy risk, iterate the live Set directly.\n for (const sub of subscribers) enqueuePendingNotification(sub)\n } else {\n // Effects run inline and may call cleanupEffect (removes) + trackSubscriber (re-adds).\n // Instead of snapshotting with [...subscribers] (allocates an array), we iterate the\n // live Set but cap iterations at the original size to prevent infinite loops from\n // re-inserted entries. This is safe because:\n // - cleanupEffect removes the effect from the Set (no double-fire)\n // - trackSubscriber may re-add it (but we stop after originalSize iterations)\n // - Any effects re-added during this pass are already up-to-date (just ran)\n const originalSize = subscribers.size\n let i = 0\n for (const sub of subscribers) {\n if (i >= originalSize) break\n sub()\n i++\n }\n }\n}\n\nexport function withTracking<T>(fn: () => void, compute: () => T): T {\n const prev = activeEffect\n activeEffect = fn\n try {\n return compute()\n } finally {\n activeEffect = prev\n }\n}\n\n// Stack for inlined tracking in renderEffect — avoids withTracking function call overhead.\nlet _prevEffect: (() => void) | null = null\n\nexport function _setActiveEffect(fn: () => void): void {\n _prevEffect = activeEffect\n activeEffect = fn\n}\n\nexport function _restoreActiveEffect(): void {\n activeEffect = _prevEffect\n _prevEffect = null\n}\n\n/** Read signals without subscribing. Alias: `untrack`. */\nexport function runUntracked<T>(fn: () => T): T {\n const prev = activeEffect\n activeEffect = null\n try {\n return fn()\n } finally {\n activeEffect = prev\n }\n}\n","import { getCurrentScope } from './scope'\nimport { _restoreActiveEffect, _setActiveEffect, setDepsCollector, withTracking } from './tracking'\n\n// Dev-time counter sink — see packages/internals/perf-harness for contract.\ninterface ViteMeta {\n readonly env?: { readonly DEV?: boolean }\n}\nconst _countSink = globalThis as { __pyreon_count__?: (name: string, n?: number) => void }\n\nexport interface Effect {\n dispose(): void\n}\n\n// ─── onCleanup ───────────────────────────────────────────────────────────────\n// Thread-local collector for cleanup functions registered via onCleanup()\n// during effect execution. Pushed/popped around the user callback in effect().\nlet _cleanupCollector: (() => void)[] | null = null\n\n/**\n * Register a cleanup function inside an effect. The cleanup runs:\n * - Before the effect re-runs (when dependencies change)\n * - When the effect is disposed\n *\n * Can be called multiple times — all cleanups run in registration order.\n * Must be called synchronously during effect setup (like onMount/onUnmount).\n *\n * @example\n * effect(() => {\n * const controller = new AbortController()\n * onCleanup(() => controller.abort())\n * fetch(`/api/user/${userId()}`, { signal: controller.signal })\n * .then(r => r.json())\n * .then(data => user.set(data))\n * })\n */\nexport function onCleanup(fn: () => void): void {\n if (_cleanupCollector) {\n _cleanupCollector.push(fn)\n }\n}\n\n// Thread-local collector for nested effects — captures effect() calls made\n// inside another effect's fn() body so the parent can dispose them on\n// re-run / disposal. Without this, inner effects leak across outer\n// lifecycle boundaries (caught by cleanup-nested.test.ts).\nlet _innerEffectCollector: Effect[] | null = null\n\n// Global error handler — called for unhandled errors thrown inside effects.\n// Defaults to console.error so silent failures are never swallowed.\nexport let _errorHandler: (err: unknown) => void = (err) => {\n console.error('[pyreon] Unhandled effect error:', err)\n}\n\nexport function setErrorHandler(fn: (err: unknown) => void): void {\n _errorHandler = fn\n}\n\n/** Remove an effect from all dependency subscriber sets (local deps array). */\nfunction cleanupLocalDeps(deps: Set<() => void>[], fn: () => void): void {\n if (deps.length === 1) {\n ;(deps[0] as Set<() => void>).delete(fn)\n deps.length = 0\n } else if (deps.length > 1) {\n for (let i = 0; i < deps.length; i++) (deps[i] as Set<() => void>).delete(fn)\n deps.length = 0\n }\n}\n\nexport function effect(fn: () => (() => void) | void): Effect {\n // Capture the scope at creation time — remains correct during future re-runs\n // even after setCurrentScope(null) has been called post-setup.\n const scope = getCurrentScope()\n let disposed = false\n let isFirstRun = true\n let cleanup: (() => void) | undefined\n // Local deps array — avoids WeakMap overhead (like renderEffect)\n const deps: Set<() => void>[] = []\n\n let cleanups: (() => void)[] | undefined\n // Inner effects created during this effect's fn() body. Disposed on\n // outer re-run (before the next fn()) and on outer dispose(). Without\n // this, nested effects leak across outer lifecycle boundaries.\n let innerEffects: Effect[] | null = null\n\n const runCleanup = () => {\n if (innerEffects) {\n for (const ie of innerEffects) {\n try {\n ie.dispose()\n } catch (err) {\n _errorHandler(err)\n }\n }\n innerEffects = null\n }\n if (cleanups) {\n for (const c of cleanups) {\n try {\n c()\n } catch (err) {\n _errorHandler(err)\n }\n }\n cleanups = undefined\n }\n if (typeof cleanup === 'function') {\n try {\n cleanup()\n } catch (err) {\n _errorHandler(err)\n }\n cleanup = undefined\n }\n }\n\n const run = () => {\n if (disposed) return\n if ((import.meta as ViteMeta).env?.DEV === true)\n _countSink.__pyreon_count__?.('reactivity.effectRun')\n // Run previous cleanup before re-running\n runCleanup()\n // Start a new inner-effect collection window. Effects created during\n // fn() will push themselves into this array and be disposed on the\n // next re-run or on dispose.\n const outerCollector = _innerEffectCollector\n const myInners: Effect[] = []\n _innerEffectCollector = myInners\n try {\n cleanupLocalDeps(deps, run)\n setDepsCollector(deps)\n // Collect onCleanup() registrations during execution\n const collected: (() => void)[] = []\n _cleanupCollector = collected\n cleanup = withTracking(run, fn) || undefined\n _cleanupCollector = null\n if (collected.length > 0) cleanups = collected\n setDepsCollector(null)\n } catch (err) {\n _cleanupCollector = null\n setDepsCollector(null)\n _errorHandler(err)\n } finally {\n _innerEffectCollector = outerCollector\n }\n if (myInners.length > 0) innerEffects = myInners\n // Notify scope after each reactive re-run (not the initial synchronous run)\n // so onUpdate hooks fire after the DOM has settled.\n if (!isFirstRun) scope?.notifyEffectRan()\n isFirstRun = false\n }\n\n run()\n\n const e: Effect = {\n dispose() {\n runCleanup()\n disposed = true\n cleanupLocalDeps(deps, run)\n },\n }\n\n // If we're inside another effect's run, register with it so the outer\n // disposes this inner automatically.\n if (_innerEffectCollector !== null) {\n _innerEffectCollector.push(e)\n } else {\n // Otherwise auto-register with the active EffectScope (if any)\n getCurrentScope()?.add(e)\n }\n\n return e\n}\n\n/**\n * Lightweight effect for DOM render bindings.\n *\n * Differences from `effect()`:\n * - No EffectScope registration (caller owns the dispose lifecycle)\n * - No error handler (errors propagate naturally)\n * - No onUpdate notification\n * - Deps stored in a local array instead of the global WeakMap — faster\n * creation and disposal (~200ns saved per effect vs WeakMap path)\n *\n * Returns a dispose function (not an Effect object — saves 1 allocation).\n */\n/**\n * Static-dep binding — compiler helper for template expressions.\n *\n * Like renderEffect but assumes dependencies never change (true for all\n * compiler-emitted template bindings like `_tpl()` text/attribute updates).\n *\n * Tracks dependencies only on the first run. Re-runs skip cleanup, re-tracking,\n * and tracking context save/restore entirely — just calls `fn()` directly.\n *\n * Per re-run savings vs renderEffect:\n * - No deps iteration + Set.delete (cleanup)\n * - No setDepsCollector + withTracking (re-registration)\n * - Signal reads hit `if (activeEffect)` null check → instant return\n */\nexport function _bind(fn: () => void): () => void {\n const deps: Set<() => void>[] = []\n let disposed = false\n\n const run = () => {\n if (disposed) return\n fn()\n }\n\n // First run: track deps so we know what to unsubscribe on dispose\n setDepsCollector(deps)\n withTracking(run, fn)\n setDepsCollector(null)\n\n const dispose = () => {\n if (disposed) return\n disposed = true\n for (const s of deps) s.delete(run)\n deps.length = 0\n }\n\n // Auto-register with scope so template bindings are disposed during teardown\n getCurrentScope()?.add({ dispose })\n\n return dispose\n}\n\n/** Full re-track path for renderEffect: cleanup old deps, evaluate with tracking. */\nfunction renderEffectFullTrack(deps: Set<() => void>[], run: () => void, fn: () => void): void {\n if (deps.length === 1) {\n ;(deps[0] as Set<() => void>).delete(run)\n deps.length = 0\n } else if (deps.length > 1) {\n for (const s of deps) s.delete(run)\n deps.length = 0\n }\n setDepsCollector(deps)\n _setActiveEffect(run)\n try {\n fn()\n } finally {\n _restoreActiveEffect()\n setDepsCollector(null)\n }\n}\n\nexport function renderEffect(fn: () => void): () => void {\n const deps: Set<() => void>[] = []\n let disposed = false\n let isFirstRun = true\n\n const run = () => {\n if (disposed) return\n // After first run, if deps haven't changed structure, we can skip\n // the full cleanup+retrack path. However, renderEffect deps CAN\n // change (unlike _bind), so we always do the full track.\n // Optimization: skip cleanup on first run (deps are empty).\n if (isFirstRun) {\n isFirstRun = false\n setDepsCollector(deps)\n _setActiveEffect(run)\n try {\n fn()\n } finally {\n _restoreActiveEffect()\n setDepsCollector(null)\n }\n } else {\n renderEffectFullTrack(deps, run, fn)\n }\n }\n\n run()\n\n const dispose = () => {\n if (disposed) return\n disposed = true\n if (deps.length === 1) {\n ;(deps[0] as Set<() => void>).delete(run)\n } else {\n for (const s of deps) s.delete(run)\n }\n deps.length = 0\n }\n\n // Auto-register with scope so render effects are disposed during teardown\n getCurrentScope()?.add({ dispose })\n\n return dispose\n}\n","import { _errorHandler } from './effect'\nimport { getCurrentScope } from './scope'\nimport {\n cleanupEffect,\n notifySubscribers,\n setDepsCollector,\n setSkipDepsCollection,\n trackSubscriber,\n withTracking,\n} from './tracking'\n\n// Dev-time counter sink — see packages/internals/perf-harness for contract.\ninterface ViteMeta {\n readonly env?: { readonly DEV?: boolean }\n}\nconst _countSink = globalThis as { __pyreon_count__?: (name: string, n?: number) => void }\n\nexport interface Computed<T> {\n (): T\n /** Remove this computed from all its reactive dependencies. */\n dispose(): void\n /** Cached value for compiler-emitted direct bindings (_bindText, _bindDirect). */\n _v: T\n /** Register a direct updater — used by compiler-emitted _bindText/_bindDirect. */\n direct(updater: () => void): () => void\n}\n\nexport interface ComputedOptions<T> {\n /**\n * Custom equality function. When provided, the computed eagerly re-evaluates\n * on dependency change and only notifies downstream if `equals(prev, next)`\n * returns false. Useful for derived objects/arrays to skip spurious updates.\n *\n * @example\n * const sorted = computed(() => items().slice().sort(), {\n * equals: (a, b) => a.length === b.length && a.every((v, i) => v === b[i])\n * })\n */\n equals?: (prev: T, next: T) => boolean\n}\n\n/** Remove a computed from all dependency subscriber sets (local deps array). */\nfunction cleanupLocalDeps(deps: Set<() => void>[], fn: () => void): void {\n for (let i = 0; i < deps.length; i++) (deps[i] as Set<() => void>).delete(fn)\n deps.length = 0\n}\n\n/** Re-track dependencies using the local deps array collector. */\nfunction trackWithLocalDeps<T>(deps: Set<() => void>[], effect: () => void, fn: () => T): T {\n setDepsCollector(deps)\n const result = withTracking(effect, fn)\n setDepsCollector(null)\n return result\n}\n\nexport function computed<T>(fn: () => T, options?: ComputedOptions<T>): Computed<T> {\n return options?.equals ? computedWithEquals(fn, options.equals) : computedLazy(fn)\n}\n\n/**\n * Default computed — lazy evaluation with deferred cleanup.\n *\n * On notification: just marks dirty and propagates (no cleanup/re-track).\n * On read: cleans up old deps, re-evaluates, re-tracks.\n *\n * The `if (dirty) return` early exit in recompute prevents double-propagation\n * in diamond patterns (a→b,c→d: b notifies d, c tries to notify d again —\n * skipped because d is already dirty).\n */\nfunction computedLazy<T>(fn: () => T): Computed<T> {\n let value: T\n let dirty = true\n let disposed = false\n let tracked = false\n const deps: Set<() => void>[] = []\n const host: { _s: Set<() => void> | null } = { _s: null }\n let directFns: ((() => void) | null)[] | null = null\n\n const recompute = () => {\n if (disposed || dirty) return\n dirty = true\n if (host._s) notifySubscribers(host._s)\n if (directFns) for (const f of directFns) f?.()\n }\n\n const read = (): T => {\n trackSubscriber(host)\n if (dirty) {\n if ((import.meta as ViteMeta).env?.DEV === true)\n _countSink.__pyreon_count__?.('reactivity.computedRecompute')\n try {\n if (tracked) {\n // Deps already established from first run — skip adding to\n // subscriber Sets again (they already contain recompute).\n // Still need withTracking so activeEffect is set correctly\n // for any NEW signals read on this evaluation.\n setSkipDepsCollection(true)\n value = withTracking(recompute, fn)\n setSkipDepsCollection(false)\n } else {\n value = trackWithLocalDeps(deps, recompute, fn)\n tracked = true\n }\n } catch (err) {\n _errorHandler(err)\n }\n dirty = false\n }\n return value as T\n }\n\n read.dispose = () => {\n disposed = true\n cleanupLocalDeps(deps, recompute)\n }\n\n Object.defineProperty(read, '_v', {\n get: () => {\n if (dirty) read() // ensure value is fresh\n return value\n },\n enumerable: false,\n })\n\n read.direct = (updater: () => void): (() => void) => {\n if (!directFns) directFns = []\n const arr = directFns\n const idx = arr.length\n arr.push(updater)\n return () => {\n arr[idx] = null\n }\n }\n\n getCurrentScope()?.add({ dispose: read.dispose })\n return read as Computed<T>\n}\n\n/**\n * Computed with custom equality — eager evaluation on notification.\n *\n * Re-evaluates immediately when deps change and only notifies downstream\n * if `equals(prev, next)` returns false.\n */\nfunction computedWithEquals<T>(fn: () => T, equals: (prev: T, next: T) => boolean): Computed<T> {\n let value: T\n let dirty = true\n let initialized = false\n let disposed = false\n const deps: Set<() => void>[] = []\n const host: { _s: Set<() => void> | null } = { _s: null }\n let directFns: ((() => void) | null)[] | null = null\n\n const recompute = () => {\n if (disposed) return\n if ((import.meta as ViteMeta).env?.DEV === true)\n _countSink.__pyreon_count__?.('reactivity.computedRecompute')\n cleanupLocalDeps(deps, recompute)\n try {\n const next = trackWithLocalDeps(deps, recompute, fn)\n if (initialized && equals(value as T, next)) return\n value = next\n dirty = false\n initialized = true\n } catch (err) {\n _errorHandler(err)\n return\n }\n if (host._s) notifySubscribers(host._s)\n if (directFns) for (const f of directFns) f?.()\n }\n\n const read = (): T => {\n trackSubscriber(host)\n if (dirty) {\n if ((import.meta as ViteMeta).env?.DEV === true)\n _countSink.__pyreon_count__?.('reactivity.computedRecompute')\n cleanupLocalDeps(deps, recompute)\n try {\n value = trackWithLocalDeps(deps, recompute, fn)\n } catch (err) {\n _errorHandler(err)\n }\n dirty = false\n initialized = true\n }\n return value as T\n }\n\n read.dispose = () => {\n disposed = true\n cleanupLocalDeps(deps, recompute)\n cleanupEffect(recompute)\n }\n\n Object.defineProperty(read, '_v', {\n get: () => {\n if (dirty) read()\n return value\n },\n enumerable: false,\n })\n\n read.direct = (updater: () => void): (() => void) => {\n if (!directFns) directFns = []\n const arr = directFns\n const idx = arr.length\n arr.push(updater)\n return () => {\n arr[idx] = null\n }\n }\n\n getCurrentScope()?.add({ dispose: read.dispose })\n return read as Computed<T>\n}\n","import { effect } from './effect'\nimport { trackSubscriber } from './tracking'\n\n/**\n * Notify a subscriber bucket without snapshot allocation.\n * Caps iteration at the original size to avoid infinite loops from\n * re-inserted entries (same pattern as notifySubscribers in tracking.ts).\n */\nfunction notifyBucket(bucket: Set<() => void>): void {\n if (bucket.size === 0) return\n if (bucket.size === 1) {\n ;(bucket.values().next().value as () => void)()\n return\n }\n const originalSize = bucket.size\n let i = 0\n for (const fn of bucket) {\n if (i >= originalSize) break\n fn()\n i++\n }\n}\n\n/**\n * Create an equality selector — returns a reactive predicate that is true\n * only for the currently selected value.\n *\n * Unlike a plain `() => source() === value`, this only triggers the TWO\n * affected subscribers (deselected + newly selected) instead of ALL\n * subscribers, making selection O(1) regardless of list size.\n *\n * @example\n * const isSelected = createSelector(selectedId)\n * // In each row:\n * class: () => (isSelected(row.id) ? \"selected\" : \"\")\n */\nexport function createSelector<T>(source: () => T): (value: T) => boolean {\n const subs = new Map<T, Set<() => void>>()\n let current: T\n let initialized = false\n\n effect(() => {\n const next = source()\n if (!initialized) {\n initialized = true\n current = next\n return\n }\n if (Object.is(next, current)) return\n const old = current\n current = next\n // Only notify the two affected buckets — O(1) regardless of list size.\n // Iteration-capped loop avoids [...bucket] snapshot allocation.\n const oldBucket = subs.get(old)\n const newBucket = subs.get(next)\n if (oldBucket) notifyBucket(oldBucket)\n if (newBucket) notifyBucket(newBucket)\n })\n\n // Reusable hosts per value — avoids allocating a closure per trackSubscriber call\n const hosts = new Map<T, { _s: Set<() => void> | null }>()\n\n return (value: T): boolean => {\n let host = hosts.get(value)\n if (!host) {\n let bucket = subs.get(value)\n if (!bucket) {\n bucket = new Set()\n subs.set(value, bucket)\n }\n host = { _s: bucket }\n hosts.set(value, host)\n }\n trackSubscriber(host)\n return Object.is(current, value)\n }\n}\n","/**\n * @pyreon/reactivity debug utilities.\n *\n * Development-only tools for tracing signal updates, inspecting reactive\n * graphs, and understanding why DOM nodes re-render.\n *\n * All utilities are tree-shakeable — they compile away in production builds\n * when unused.\n */\n\nimport type { Signal, SignalDebugInfo } from './signal'\n\n// ─── Signal update tracing ───────────────────────────────────────────────────\n\ninterface SignalUpdateEvent {\n /** The signal that changed */\n signal: Signal<unknown>\n /** Signal name (from options or label) */\n name: string | undefined\n /** Previous value */\n prev: unknown\n /** New value */\n next: unknown\n /** Stack trace at the point of the .set() / .update() call */\n stack: string\n /** Timestamp */\n timestamp: number\n}\n\ntype SignalUpdateListener = (event: SignalUpdateEvent) => void\n\nlet _traceListeners: SignalUpdateListener[] | null = null\n\n/**\n * Register a listener that fires on every signal write.\n * Returns a dispose function.\n *\n * @example\n * const dispose = onSignalUpdate(e => {\n * console.log(`${e.name ?? 'anonymous'}: ${e.prev} → ${e.next}`)\n * })\n */\nexport function onSignalUpdate(listener: SignalUpdateListener): () => void {\n if (!_traceListeners) _traceListeners = []\n _traceListeners.push(listener)\n return () => {\n if (!_traceListeners) return\n _traceListeners = _traceListeners.filter((l) => l !== listener)\n if (_traceListeners.length === 0) _traceListeners = null\n }\n}\n\n/** @internal — called from signal.set() when tracing is active */\nexport function _notifyTraceListeners(sig: Signal<unknown>, prev: unknown, next: unknown): void {\n if (!_traceListeners) return\n const event: SignalUpdateEvent = {\n signal: sig,\n name: sig.label,\n prev,\n next,\n stack: new Error().stack ?? '',\n timestamp: performance.now(),\n }\n for (const l of _traceListeners) l(event)\n}\n\n/** Check if any trace listeners are active (fast path for signal.set) */\nexport function isTracing(): boolean {\n return _traceListeners !== null\n}\n\n// ─── why() — trace which signal caused a re-run ──────────────────────────────\n\nlet _whyActive = false\nlet _whyLog: { name: string | undefined; prev: unknown; next: unknown }[] = []\n\n/**\n * Trace the next signal update. Logs which signals fire and what changed.\n * Call before triggering a state change to see what updates and why.\n *\n * @example\n * why()\n * count.set(5)\n * // Console: [pyreon:why] \"count\": 3 → 5 (2 subscribers)\n */\nexport function why(): void {\n if (_whyActive) return\n _whyActive = true\n _whyLog = []\n\n const dispose = onSignalUpdate((e) => {\n const _subCount = (e.signal as unknown as { _s: Set<unknown> | null })._s?.size ?? 0\n const _name = e.name ? `\"${e.name}\"` : '(anonymous signal)'\n\n console.log(\n `[pyreon:why] ${_name}: ${JSON.stringify(e.prev)} → ${JSON.stringify(e.next)} (${_subCount} subscriber${_subCount === 1 ? '' : 's'})`,\n )\n _whyLog.push({ name: e.name, prev: e.prev, next: e.next })\n })\n\n // Auto-dispose after the current microtask (captures the synchronous batch)\n queueMicrotask(() => {\n dispose()\n if (_whyLog.length === 0) {\n console.log('[pyreon:why] No signal updates detected')\n }\n _whyActive = false\n _whyLog = []\n })\n}\n\n// ─── inspectSignal — rich console output ─────────────────────────────────────\n\n/**\n * Print a signal's current state to the console in a readable format.\n *\n * @example\n * const count = signal(42, { name: \"count\" })\n * inspectSignal(count)\n * // Console:\n * // 🔍 Signal \"count\"\n * // value: 42\n * // subscribers: 3\n */\nexport function inspectSignal<T>(sig: Signal<T>): SignalDebugInfo<T> {\n const info = sig.debug()\n\n console.group(`🔍 Signal ${info.name ? `\"${info.name}\"` : '(anonymous)'}`)\n console.log('value:', info.value)\n console.log('subscribers:', info.subscriberCount)\n console.groupEnd()\n\n return info\n}\n","declare const process: { env: { NODE_ENV?: string } } | undefined\n\nconst __DEV__ = typeof process !== 'undefined' && process?.env?.NODE_ENV !== 'production'\n\nimport { batch, enqueuePendingNotification, isBatching } from './batch'\nimport { _notifyTraceListeners, isTracing } from './debug'\nimport { notifySubscribers, trackSubscriber } from './tracking'\n\n// Dev-time counter sink — see packages/internals/perf-harness for contract.\ninterface ViteMeta {\n readonly env?: { readonly DEV?: boolean }\n}\nconst _countSink = globalThis as { __pyreon_count__?: (name: string, n?: number) => void }\n\nexport interface SignalDebugInfo<T> {\n /** Signal name (set via options or inferred) */\n name: string | undefined\n /** Current value (same as peek()) */\n value: T\n /** Number of active subscribers */\n subscriberCount: number\n}\n\n/**\n * Read-only reactive value — the common interface that both Signal and Computed satisfy.\n * Use this as the parameter type when a function only needs to read a reactive value.\n */\nexport type ReadonlySignal<T> = () => T\n\nexport interface Signal<T> {\n (): T\n /** Read the current value WITHOUT registering a reactive dependency. */\n peek(): T\n set(value: T): void\n update(fn: (current: T) => T): void\n /**\n * Subscribe a static listener directly — no effect overhead (no withTracking,\n * no cleanupEffect, no effectDeps WeakMap). Use when the dependency is fixed\n * and dynamic re-tracking is not needed.\n * Returns a disposer that removes the subscription.\n */\n subscribe(listener: () => void): () => void\n /**\n * Register a direct updater — even lighter than subscribe().\n * Uses a flat array instead of Set. Disposal nulls the slot (no Set.delete).\n * Intended for compiler-emitted DOM bindings (_bindText, _bindDirect).\n * Returns a disposer that nulls the slot.\n */\n direct(updater: () => void): () => void\n /** Debug name — useful for devtools and logging. */\n label: string | undefined\n /** Returns a snapshot of the signal's debug info (value, name, subscriber count). */\n debug(): SignalDebugInfo<T>\n}\n\nexport interface SignalOptions {\n /** Debug name for this signal — shows up in devtools and debug() output. */\n name?: string\n}\n\n// Internal shape of a signal function — state stored as properties on the\n// function object so methods can be shared via assignment (not per-signal closures).\ninterface SignalFn<T> {\n (): T\n /** @internal current value */\n _v: T\n /** @internal subscriber set (lazily allocated by trackSubscriber) */\n _s: Set<() => void> | null\n /** @internal direct updaters array — compiler-emitted DOM updaters (lazily allocated) */\n _d: ((() => void) | null)[] | null\n peek(): T\n set(value: T): void\n update(fn: (current: T) => T): void\n subscribe(listener: () => void): () => void\n /** Register a direct updater — lighter than subscribe, uses array index disposal. */\n direct(updater: () => void): () => void\n label: string | undefined\n debug(): SignalDebugInfo<T>\n}\n\n// Shared method implementations — defined once, assigned to every signal.\n// Uses `this` binding (signal methods are always called as `signal.method()`).\nfunction _peek(this: SignalFn<unknown>) {\n return this._v\n}\n\nfunction _set(this: SignalFn<unknown>, newValue: unknown) {\n if (Object.is(this._v, newValue)) return\n if ((import.meta as ViteMeta).env?.DEV === true)\n _countSink.__pyreon_count__?.('reactivity.signalWrite')\n const prev = this._v\n this._v = newValue\n if (isTracing()) _notifyTraceListeners(this as unknown as Signal<unknown>, prev, newValue)\n // Auto-batch the notification chain. Without this, a diamond dependency\n // graph (a → b, c → d → effect) fires the apex effect TWICE per write\n // because subscribers cascade inline: the first path through `b` reaches\n // `effect`, whose read clears `d`'s dirty flag; then `c`'s notification\n // re-dirties `d` and re-notifies `effect`. Wrapping the notify chain in\n // `batch()` routes cascade-notifications through the pending Set, which\n // dedupes on `d.recompute` and on `effect.run`.\n //\n // The batch is synchronous — observable behaviour is unchanged for the\n // common case (subscribers still fire immediately after the write). Only\n // the dedup semantics change, which is a bug fix.\n //\n // Short-circuit when already inside a batch so we don't wrap redundantly.\n if (isBatching()) {\n if (this._d) notifyDirect(this._d)\n if (this._s) notifySubscribers(this._s)\n } else {\n batch(() => {\n if (this._d) notifyDirect(this._d)\n if (this._s) notifySubscribers(this._s)\n })\n }\n}\n\nfunction _update(this: SignalFn<unknown>, fn: (current: unknown) => unknown) {\n _set.call(this, fn(this._v))\n}\n\nfunction _subscribe(this: SignalFn<unknown>, listener: () => void): () => void {\n if (!this._s) this._s = new Set()\n this._s.add(listener)\n return () => this._s?.delete(listener)\n}\n\n/**\n * Register a direct updater — lighter than subscribe().\n * Uses a flat array instead of Set. Disposal nulls the slot (no Set.delete overhead).\n * Used by compiler-emitted _bindText/_bindDirect for zero-overhead DOM bindings.\n */\nfunction _directFn(this: SignalFn<unknown>, updater: () => void): () => void {\n if (!this._d) this._d = []\n const arr = this._d\n const idx = arr.length\n arr.push(updater)\n return () => {\n arr[idx] = null\n }\n}\n\n/**\n * Notify direct updaters — flat array iteration, batch-aware.\n * Null slots (from disposed updaters) are skipped.\n */\nfunction notifyDirect(updaters: ((() => void) | null)[]): void {\n if (isBatching()) {\n for (let i = 0; i < updaters.length; i++) {\n const fn = updaters[i]\n if (fn) enqueuePendingNotification(fn)\n }\n } else {\n for (let i = 0; i < updaters.length; i++) {\n updaters[i]?.()\n }\n }\n}\n\nfunction _debug(this: SignalFn<unknown>): SignalDebugInfo<unknown> {\n return {\n name: this.label,\n value: this._v,\n subscriberCount: this._s?.size ?? 0,\n }\n}\n\n/**\n * Create a reactive signal.\n *\n * Only 1 closure is allocated (the read function). State is stored as\n * properties on the function object (_v, _s) and methods (peek, set,\n * update, subscribe) are shared across all signals — not per-signal closures.\n */\nexport function signal<T>(initialValue: T, options?: SignalOptions): Signal<T> {\n if ((import.meta as ViteMeta).env?.DEV === true)\n _countSink.__pyreon_count__?.('reactivity.signalCreate')\n // The read function is the only per-signal closure.\n // It doubles as the SubscriberHost (_s property) for trackSubscriber.\n const read = ((...args: unknown[]) => {\n if (__DEV__ && args.length > 0) {\n // oxlint-disable-next-line no-console\n console.warn(\n '[Pyreon] signal() was called with an argument. ' +\n 'Use signal.set(value) or signal.update(fn) to write. ' +\n 'signal(value) only reads — the argument is ignored.',\n )\n }\n trackSubscriber(read as SignalFn<T>)\n return read._v\n }) as unknown as SignalFn<T>\n\n read._v = initialValue\n read._s = null\n read._d = null\n read.peek = _peek as () => T\n read.set = _set as (value: T) => void\n read.update = _update as (fn: (current: T) => T) => void\n read.subscribe = _subscribe as (listener: () => void) => () => void\n read.direct = _directFn as (updater: () => void) => () => void\n read.debug = _debug as () => SignalDebugInfo<T>\n read.label = options?.name\n\n return read as unknown as Signal<T>\n}\n","/**\n * createStore — deep reactive Proxy store.\n *\n * Wraps a plain object/array in a Proxy that creates a fine-grained signal for\n * every property. Direct mutations (`store.count++`, `store.items[0].label = \"x\"`)\n * trigger only the signals for the mutated properties — not the whole tree.\n *\n * @example\n * const state = createStore({ count: 0, items: [{ id: 1, text: \"hello\" }] })\n *\n * effect(() => console.log(state.count)) // tracks state.count only\n * state.count++ // only the count effect re-runs\n * state.items[0].text = \"world\" // only text-tracking effects re-run\n */\n\nimport { type Signal, signal } from './signal'\n\n// WeakMap: raw object → its reactive proxy (ensures each raw object gets one proxy)\nconst proxyCache = new WeakMap<object, object>()\n\nconst IS_STORE = Symbol('pyreon.store')\n\n/** Returns true if the value is a createStore proxy. */\nexport function isStore(value: unknown): boolean {\n return (\n value !== null &&\n typeof value === 'object' &&\n (value as Record<symbol, unknown>)[IS_STORE] === true\n )\n}\n\n/**\n * Create a deep reactive store from a plain object or array.\n * Returns a proxy — mutations to the proxy trigger fine-grained reactive updates.\n */\nexport function createStore<T extends object>(initial: T): T {\n return wrap(initial) as T\n}\n\nfunction wrap(raw: object): object {\n const cached = proxyCache.get(raw)\n if (cached) return cached\n\n // Per-property signals. Lazily created on first access.\n const propSignals = new Map<PropertyKey, Signal<unknown>>()\n // For arrays: track length changes separately (push/pop/splice affect length)\n const isArray = Array.isArray(raw)\n const lengthSig = isArray ? signal((raw as unknown[]).length) : null\n\n function getOrCreateSignal(key: PropertyKey): Signal<unknown> {\n if (!propSignals.has(key)) {\n propSignals.set(key, signal((raw as Record<PropertyKey, unknown>)[key]))\n }\n return propSignals.get(key) as Signal<unknown>\n }\n\n const proxy = new Proxy(raw, {\n get(target, key) {\n // Pass through the identity marker and non-string/number keys (symbols, etc.)\n if (key === IS_STORE) return true\n if (typeof key === 'symbol') return (target as Record<symbol, unknown>)[key]\n\n // Array length — tracked via dedicated signal for push/pop/splice reactivity\n if (isArray && key === 'length') return lengthSig?.()\n\n // Non-own properties: prototype methods (forEach, map, push, …)\n // These must be returned untracked so array methods work normally.\n // Array methods will then go through set/get on indices via the proxy.\n if (!Object.hasOwn(target, key)) {\n return (target as Record<PropertyKey, unknown>)[key]\n }\n\n // Track via per-property signal\n const value = getOrCreateSignal(key)()\n\n // Deep reactivity: wrap nested objects/arrays transparently\n if (value !== null && typeof value === 'object') {\n return wrap(value as object)\n }\n\n return value\n },\n\n set(target, key, value) {\n if (typeof key === 'symbol') {\n ;(target as Record<symbol, unknown>)[key] = value\n return true\n }\n\n const prevLength = isArray ? (target as unknown[]).length : 0\n ;(target as Record<PropertyKey, unknown>)[key] = value\n\n // Array length set directly (e.g. arr.length = 0)\n if (isArray && key === 'length') {\n lengthSig?.set(value as number)\n return true\n }\n\n // Update or create signal for this property\n if (propSignals.has(key)) {\n propSignals.get(key)?.set(value)\n } else {\n propSignals.set(key, signal(value))\n }\n\n // If array length changed (e.g. via push/splice index assignment), update it\n if (isArray && (target as unknown[]).length !== prevLength) {\n lengthSig?.set((target as unknown[]).length)\n }\n\n return true\n },\n\n deleteProperty(target, key) {\n delete (target as Record<PropertyKey, unknown>)[key]\n if (typeof key !== 'symbol' && propSignals.has(key)) {\n propSignals.get(key)?.set(undefined)\n propSignals.delete(key)\n }\n if (isArray) lengthSig?.set((target as unknown[]).length)\n return true\n },\n\n has(target, key) {\n return Reflect.has(target, key)\n },\n\n ownKeys(target) {\n return Reflect.ownKeys(target)\n },\n\n getOwnPropertyDescriptor(target, key) {\n return Reflect.getOwnPropertyDescriptor(target, key)\n },\n })\n\n proxyCache.set(raw, proxy)\n return proxy\n}\n","/**\n * reconcile — surgically diff new state into an existing createStore proxy.\n *\n * Instead of replacing the store root (which would trigger all downstream effects),\n * reconcile walks both the new value and the store in parallel and only calls\n * `.set()` on signals whose value actually changed.\n *\n * Ideal for applying API responses to a long-lived store:\n *\n * @example\n * const state = createStore({ user: { name: \"Alice\", age: 30 }, items: [] })\n *\n * // API response arrives:\n * reconcile({ user: { name: \"Alice\", age: 31 }, items: [{ id: 1 }] }, state)\n * // → only state.user.age signal fires (name unchanged)\n * // → state.items[0] is newly created\n *\n * Arrays are reconciled by index — elements at the same index are recursively\n * diffed rather than replaced wholesale. Excess old elements are removed.\n */\n\nimport { isStore } from './store'\n\ntype AnyObject = Record<PropertyKey, unknown>\n\nexport function reconcile<T extends object>(source: T, target: T): void {\n _reconcileInner(source, target, new WeakSet())\n}\n\nfunction _reconcileInner(source: object, target: object, seen: WeakSet<object>): void {\n if (seen.has(source)) return // circular reference — stop recursion\n seen.add(source)\n if (Array.isArray(source) && Array.isArray(target)) {\n _reconcileArray(source as unknown[], target as unknown[], seen)\n } else {\n _reconcileObject(source as AnyObject, target as AnyObject, seen)\n }\n}\n\nfunction _reconcileArray(source: unknown[], target: unknown[], seen: WeakSet<object>): void {\n const targetLen = target.length\n const sourceLen = source.length\n\n // Update / add entries\n for (let i = 0; i < sourceLen; i++) {\n const sv = source[i]\n const tv = (target as unknown[])[i]\n\n if (\n i < targetLen &&\n sv !== null &&\n typeof sv === 'object' &&\n tv !== null &&\n typeof tv === 'object'\n ) {\n // Both sides are objects — recurse\n _reconcileInner(sv as object, tv as object, seen)\n } else {\n // Scalar or new entry — write directly (signal will skip if equal via Object.is)\n ;(target as unknown[])[i] = sv\n }\n }\n\n // Trim excess entries\n if (targetLen > sourceLen) {\n target.length = sourceLen\n }\n}\n\nfunction _reconcileObject(source: AnyObject, target: AnyObject, seen: WeakSet<object>): void {\n const sourceKeys = Object.keys(source)\n const targetKeys = new Set(Object.keys(target))\n\n for (const key of sourceKeys) {\n const sv = source[key]\n const tv = target[key]\n\n if (sv !== null && typeof sv === 'object' && tv !== null && typeof tv === 'object') {\n if (isStore(tv)) {\n // Both objects — recurse into the store node\n _reconcileInner(sv as object, tv as object, seen)\n } else {\n // Target is a raw object (not yet proxied) — just assign\n target[key] = sv\n }\n } else {\n // Scalar: assign (store proxy's set trap skips if Object.is equal)\n target[key] = sv\n }\n\n targetKeys.delete(key)\n }\n\n // Remove keys that no longer exist in source\n for (const key of targetKeys) {\n delete target[key]\n }\n}\n","import { effect } from './effect'\nimport type { Signal } from './signal'\nimport { signal } from './signal'\nimport { runUntracked } from './tracking'\n\nexport interface Resource<T> {\n /** The latest resolved value (undefined while loading or on error). */\n data: Signal<T | undefined>\n /** True while a fetch is in flight. */\n loading: Signal<boolean>\n /** The last error thrown by the fetcher, or undefined. */\n error: Signal<unknown>\n /** Re-run the fetcher with the current source value. */\n refetch(): void\n}\n\n/**\n * Async data primitive. Fetches data reactively whenever `source()` changes.\n *\n * @example\n * const userId = signal(1)\n * const user = createResource(userId, (id) => fetchUser(id))\n * // user.data() — the fetched user (undefined while loading)\n * // user.loading() — true while in flight\n * // user.error() — last error\n */\nexport function createResource<T, P>(\n source: () => P,\n fetcher: (param: P) => Promise<T>,\n): Resource<T> {\n const data = signal<T | undefined>(undefined)\n const loading = signal(false)\n const error = signal<unknown>(undefined)\n let requestId = 0\n\n const doFetch = (param: P) => {\n const id = ++requestId\n loading.set(true)\n error.set(undefined)\n fetcher(param)\n .then((result) => {\n if (id !== requestId) return\n data.set(result)\n loading.set(false)\n })\n .catch((err: unknown) => {\n if (id !== requestId) return\n error.set(err)\n loading.set(false)\n })\n }\n\n effect(() => {\n const param = source()\n runUntracked(() => doFetch(param))\n })\n\n return {\n data,\n loading,\n error,\n refetch() {\n runUntracked(() => doFetch(source()))\n },\n }\n}\n","import { effect } from './effect'\n\nexport interface WatchOptions {\n /** If true, call the callback immediately with the current value on setup. Default: false. */\n immediate?: boolean\n}\n\n/**\n * Watch a reactive source and run a callback whenever it changes.\n *\n * Returns a stop function that disposes the watcher.\n *\n * The callback receives (newValue, oldValue). On the first call (when\n * `immediate` is true) oldValue is `undefined`.\n *\n * The callback may return a cleanup function that is called before each\n * re-run and on stop — useful for cancelling async work.\n *\n * @example\n * const stop = watch(\n * () => userId(),\n * async (id, prev) => {\n * const data = await fetch(`/api/user/${id}`)\n * setUser(await data.json())\n * },\n * )\n * // Later: stop()\n */\nexport function watch<T>(\n source: () => T,\n callback: (newVal: T, oldVal: T | undefined) => void | (() => void),\n opts: WatchOptions = {},\n): () => void {\n let oldVal: T | undefined\n let isFirst = true\n let cleanupFn: (() => void) | undefined\n\n const e = effect(() => {\n const newVal = source()\n\n if (isFirst) {\n isFirst = false\n oldVal = newVal\n if (opts.immediate) {\n const result = callback(newVal, undefined)\n if (typeof result === 'function') cleanupFn = result\n }\n return\n }\n\n if (cleanupFn) {\n cleanupFn()\n cleanupFn = undefined\n }\n\n const result = callback(newVal, oldVal)\n if (typeof result === 'function') cleanupFn = result\n oldVal = newVal\n })\n\n return () => {\n e.dispose()\n if (cleanupFn) {\n cleanupFn()\n cleanupFn = undefined\n }\n }\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index2.d.ts","names":[],"sources":["../../../src/batch.ts","../../../src/cell.ts","../../../src/computed.ts","../../../src/createSelector.ts","../../../src/signal.ts","../../../src/debug.ts","../../../src/effect.ts","../../../src/reconcile.ts","../../../src/resource.ts","../../../src/scope.ts","../../../src/store.ts","../../../src/tracking.ts","../../../src/watch.ts"],"mappings":"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"}