@pyreon/reactivity 0.2.1 → 0.3.1
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/analysis/index.js.html +1 -1
- package/lib/index.js +90 -23
- package/lib/index.js.map +1 -1
- package/lib/types/index.d.ts +84 -12
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index2.d.ts +15 -1
- package/lib/types/index2.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/batch.ts +12 -5
- package/src/createSelector.ts +24 -3
- package/src/effect.ts +29 -8
- package/src/index.ts +7 -1
- package/src/signal.ts +58 -17
- package/src/tracking.ts +26 -2
|
@@ -5386,7 +5386,7 @@ var drawChart = (function (exports) {
|
|
|
5386
5386
|
</script>
|
|
5387
5387
|
<script>
|
|
5388
5388
|
/*<!--*/
|
|
5389
|
-
const data = {"version":2,"tree":{"name":"root","children":[{"name":"index.js","children":[{"name":"src","children":[{"uid":"
|
|
5389
|
+
const data = {"version":2,"tree":{"name":"root","children":[{"name":"index.js","children":[{"name":"src","children":[{"uid":"dc498794-1","name":"batch.ts"},{"uid":"dc498794-3","name":"cell.ts"},{"uid":"dc498794-5","name":"scope.ts"},{"uid":"dc498794-7","name":"tracking.ts"},{"uid":"dc498794-9","name":"computed.ts"},{"uid":"dc498794-11","name":"effect.ts"},{"uid":"dc498794-13","name":"createSelector.ts"},{"uid":"dc498794-15","name":"debug.ts"},{"uid":"dc498794-17","name":"signal.ts"},{"uid":"dc498794-19","name":"store.ts"},{"uid":"dc498794-21","name":"reconcile.ts"},{"uid":"dc498794-23","name":"resource.ts"},{"uid":"dc498794-25","name":"watch.ts"},{"uid":"dc498794-27","name":"index.ts"}]}]}],"isRoot":true},"nodeParts":{"dc498794-1":{"renderedLength":916,"gzipLength":475,"brotliLength":0,"metaUid":"dc498794-0"},"dc498794-3":{"renderedLength":1669,"gzipLength":792,"brotliLength":0,"metaUid":"dc498794-2"},"dc498794-5":{"renderedLength":1787,"gzipLength":764,"brotliLength":0,"metaUid":"dc498794-4"},"dc498794-7":{"renderedLength":2073,"gzipLength":797,"brotliLength":0,"metaUid":"dc498794-6"},"dc498794-9":{"renderedLength":914,"gzipLength":385,"brotliLength":0,"metaUid":"dc498794-8"},"dc498794-11":{"renderedLength":2957,"gzipLength":1131,"brotliLength":0,"metaUid":"dc498794-10"},"dc498794-13":{"renderedLength":1810,"gzipLength":833,"brotliLength":0,"metaUid":"dc498794-12"},"dc498794-15":{"renderedLength":2469,"gzipLength":1092,"brotliLength":0,"metaUid":"dc498794-14"},"dc498794-17":{"renderedLength":2019,"gzipLength":916,"brotliLength":0,"metaUid":"dc498794-16"},"dc498794-19":{"renderedLength":2879,"gzipLength":1056,"brotliLength":0,"metaUid":"dc498794-18"},"dc498794-21":{"renderedLength":2109,"gzipLength":867,"brotliLength":0,"metaUid":"dc498794-20"},"dc498794-23":{"renderedLength":1029,"gzipLength":475,"brotliLength":0,"metaUid":"dc498794-22"},"dc498794-25":{"renderedLength":1249,"gzipLength":582,"brotliLength":0,"metaUid":"dc498794-24"},"dc498794-27":{"renderedLength":0,"gzipLength":0,"brotliLength":0,"metaUid":"dc498794-26"}},"nodeMetas":{"dc498794-0":{"id":"/src/batch.ts","moduleParts":{"index.js":"dc498794-1"},"imported":[],"importedBy":[{"uid":"dc498794-26"},{"uid":"dc498794-16"},{"uid":"dc498794-6"}]},"dc498794-2":{"id":"/src/cell.ts","moduleParts":{"index.js":"dc498794-3"},"imported":[],"importedBy":[{"uid":"dc498794-26"}]},"dc498794-4":{"id":"/src/scope.ts","moduleParts":{"index.js":"dc498794-5"},"imported":[],"importedBy":[{"uid":"dc498794-26"},{"uid":"dc498794-8"},{"uid":"dc498794-10"}]},"dc498794-6":{"id":"/src/tracking.ts","moduleParts":{"index.js":"dc498794-7"},"imported":[{"uid":"dc498794-0"}],"importedBy":[{"uid":"dc498794-26"},{"uid":"dc498794-8"},{"uid":"dc498794-12"},{"uid":"dc498794-10"},{"uid":"dc498794-22"},{"uid":"dc498794-16"}]},"dc498794-8":{"id":"/src/computed.ts","moduleParts":{"index.js":"dc498794-9"},"imported":[{"uid":"dc498794-4"},{"uid":"dc498794-6"}],"importedBy":[{"uid":"dc498794-26"}]},"dc498794-10":{"id":"/src/effect.ts","moduleParts":{"index.js":"dc498794-11"},"imported":[{"uid":"dc498794-4"},{"uid":"dc498794-6"}],"importedBy":[{"uid":"dc498794-26"},{"uid":"dc498794-12"},{"uid":"dc498794-22"},{"uid":"dc498794-24"}]},"dc498794-12":{"id":"/src/createSelector.ts","moduleParts":{"index.js":"dc498794-13"},"imported":[{"uid":"dc498794-10"},{"uid":"dc498794-6"}],"importedBy":[{"uid":"dc498794-26"}]},"dc498794-14":{"id":"/src/debug.ts","moduleParts":{"index.js":"dc498794-15"},"imported":[],"importedBy":[{"uid":"dc498794-26"},{"uid":"dc498794-16"}]},"dc498794-16":{"id":"/src/signal.ts","moduleParts":{"index.js":"dc498794-17"},"imported":[{"uid":"dc498794-0"},{"uid":"dc498794-14"},{"uid":"dc498794-6"}],"importedBy":[{"uid":"dc498794-26"},{"uid":"dc498794-22"},{"uid":"dc498794-18"}]},"dc498794-18":{"id":"/src/store.ts","moduleParts":{"index.js":"dc498794-19"},"imported":[{"uid":"dc498794-16"}],"importedBy":[{"uid":"dc498794-26"},{"uid":"dc498794-20"}]},"dc498794-20":{"id":"/src/reconcile.ts","moduleParts":{"index.js":"dc498794-21"},"imported":[{"uid":"dc498794-18"}],"importedBy":[{"uid":"dc498794-26"}]},"dc498794-22":{"id":"/src/resource.ts","moduleParts":{"index.js":"dc498794-23"},"imported":[{"uid":"dc498794-10"},{"uid":"dc498794-16"},{"uid":"dc498794-6"}],"importedBy":[{"uid":"dc498794-26"}]},"dc498794-24":{"id":"/src/watch.ts","moduleParts":{"index.js":"dc498794-25"},"imported":[{"uid":"dc498794-10"}],"importedBy":[{"uid":"dc498794-26"}]},"dc498794-26":{"id":"/src/index.ts","moduleParts":{"index.js":"dc498794-27"},"imported":[{"uid":"dc498794-0"},{"uid":"dc498794-2"},{"uid":"dc498794-8"},{"uid":"dc498794-12"},{"uid":"dc498794-14"},{"uid":"dc498794-10"},{"uid":"dc498794-20"},{"uid":"dc498794-22"},{"uid":"dc498794-4"},{"uid":"dc498794-16"},{"uid":"dc498794-18"},{"uid":"dc498794-6"},{"uid":"dc498794-24"}],"importedBy":[],"isEntry":true}},"env":{"rollup":"4.23.0"},"options":{"gzip":true,"brotli":false,"sourcemap":false}};
|
|
5390
5390
|
|
|
5391
5391
|
const run = () => {
|
|
5392
5392
|
const width = window.innerWidth;
|
package/lib/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
//#region src/batch.ts
|
|
2
2
|
let batchDepth = 0;
|
|
3
|
-
let
|
|
3
|
+
let setA = /* @__PURE__ */ new Set();
|
|
4
|
+
let setB = /* @__PURE__ */ new Set();
|
|
5
|
+
let pendingNotifications = setA;
|
|
4
6
|
function batch(fn) {
|
|
5
7
|
batchDepth++;
|
|
6
8
|
try {
|
|
@@ -9,8 +11,9 @@ function batch(fn) {
|
|
|
9
11
|
batchDepth--;
|
|
10
12
|
if (batchDepth === 0) {
|
|
11
13
|
const flush = pendingNotifications;
|
|
12
|
-
pendingNotifications =
|
|
14
|
+
pendingNotifications = flush === setA ? setB : setA;
|
|
13
15
|
for (const notify of flush) notify();
|
|
16
|
+
flush.clear();
|
|
14
17
|
}
|
|
15
18
|
}
|
|
16
19
|
}
|
|
@@ -214,7 +217,15 @@ function notifySubscribers(subscribers) {
|
|
|
214
217
|
return;
|
|
215
218
|
}
|
|
216
219
|
if (isBatching()) for (const sub of subscribers) enqueuePendingNotification(sub);
|
|
217
|
-
else
|
|
220
|
+
else {
|
|
221
|
+
const originalSize = subscribers.size;
|
|
222
|
+
let i = 0;
|
|
223
|
+
for (const sub of subscribers) {
|
|
224
|
+
if (i >= originalSize) break;
|
|
225
|
+
sub();
|
|
226
|
+
i++;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
218
229
|
}
|
|
219
230
|
function withTracking(fn, compute) {
|
|
220
231
|
const prev = activeEffect;
|
|
@@ -225,6 +236,15 @@ function withTracking(fn, compute) {
|
|
|
225
236
|
activeEffect = prev;
|
|
226
237
|
}
|
|
227
238
|
}
|
|
239
|
+
let _prevEffect = null;
|
|
240
|
+
function _setActiveEffect(fn) {
|
|
241
|
+
_prevEffect = activeEffect;
|
|
242
|
+
activeEffect = fn;
|
|
243
|
+
}
|
|
244
|
+
function _restoreActiveEffect() {
|
|
245
|
+
activeEffect = _prevEffect;
|
|
246
|
+
_prevEffect = null;
|
|
247
|
+
}
|
|
228
248
|
function runUntracked(fn) {
|
|
229
249
|
const prev = activeEffect;
|
|
230
250
|
activeEffect = null;
|
|
@@ -370,17 +390,28 @@ function renderEffect(fn) {
|
|
|
370
390
|
let disposed = false;
|
|
371
391
|
const run = () => {
|
|
372
392
|
if (disposed) return;
|
|
373
|
-
|
|
374
|
-
|
|
393
|
+
if (deps.length === 1) {
|
|
394
|
+
deps[0].delete(run);
|
|
395
|
+
deps.length = 0;
|
|
396
|
+
} else if (deps.length > 1) {
|
|
397
|
+
for (const s of deps) s.delete(run);
|
|
398
|
+
deps.length = 0;
|
|
399
|
+
}
|
|
375
400
|
setDepsCollector(deps);
|
|
376
|
-
|
|
377
|
-
|
|
401
|
+
_setActiveEffect(run);
|
|
402
|
+
try {
|
|
403
|
+
fn();
|
|
404
|
+
} finally {
|
|
405
|
+
_restoreActiveEffect();
|
|
406
|
+
setDepsCollector(null);
|
|
407
|
+
}
|
|
378
408
|
};
|
|
379
409
|
run();
|
|
380
410
|
const dispose = () => {
|
|
381
411
|
if (disposed) return;
|
|
382
412
|
disposed = true;
|
|
383
|
-
|
|
413
|
+
if (deps.length === 1) deps[0].delete(run);
|
|
414
|
+
else for (const s of deps) s.delete(run);
|
|
384
415
|
deps.length = 0;
|
|
385
416
|
};
|
|
386
417
|
getCurrentScope()?.add({ dispose });
|
|
@@ -390,6 +421,25 @@ function renderEffect(fn) {
|
|
|
390
421
|
//#endregion
|
|
391
422
|
//#region src/createSelector.ts
|
|
392
423
|
/**
|
|
424
|
+
* Notify a subscriber bucket without snapshot allocation.
|
|
425
|
+
* Caps iteration at the original size to avoid infinite loops from
|
|
426
|
+
* re-inserted entries (same pattern as notifySubscribers in tracking.ts).
|
|
427
|
+
*/
|
|
428
|
+
function notifyBucket(bucket) {
|
|
429
|
+
if (bucket.size === 0) return;
|
|
430
|
+
if (bucket.size === 1) {
|
|
431
|
+
bucket.values().next().value();
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
434
|
+
const originalSize = bucket.size;
|
|
435
|
+
let i = 0;
|
|
436
|
+
for (const fn of bucket) {
|
|
437
|
+
if (i >= originalSize) break;
|
|
438
|
+
fn();
|
|
439
|
+
i++;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
/**
|
|
393
443
|
* Create an equality selector — returns a reactive predicate that is true
|
|
394
444
|
* only for the currently selected value.
|
|
395
445
|
*
|
|
@@ -418,8 +468,8 @@ function createSelector(source) {
|
|
|
418
468
|
current = next;
|
|
419
469
|
const oldBucket = subs.get(old);
|
|
420
470
|
const newBucket = subs.get(next);
|
|
421
|
-
if (oldBucket)
|
|
422
|
-
if (newBucket)
|
|
471
|
+
if (oldBucket) notifyBucket(oldBucket);
|
|
472
|
+
if (newBucket) notifyBucket(newBucket);
|
|
423
473
|
});
|
|
424
474
|
const hosts = /* @__PURE__ */ new Map();
|
|
425
475
|
return (value) => {
|
|
@@ -538,6 +588,7 @@ function _set(newValue) {
|
|
|
538
588
|
const prev = this._v;
|
|
539
589
|
this._v = newValue;
|
|
540
590
|
if (isTracing()) _notifyTraceListeners(this, prev, newValue);
|
|
591
|
+
if (this._d) notifyDirect(this._d);
|
|
541
592
|
if (this._s) notifySubscribers(this._s);
|
|
542
593
|
}
|
|
543
594
|
function _update(fn) {
|
|
@@ -548,23 +599,38 @@ function _subscribe(listener) {
|
|
|
548
599
|
this._s.add(listener);
|
|
549
600
|
return () => this._s?.delete(listener);
|
|
550
601
|
}
|
|
602
|
+
/**
|
|
603
|
+
* Register a direct updater — lighter than subscribe().
|
|
604
|
+
* Uses a flat array instead of Set. Disposal nulls the slot (no Set.delete overhead).
|
|
605
|
+
* Used by compiler-emitted _bindText/_bindDirect for zero-overhead DOM bindings.
|
|
606
|
+
*/
|
|
607
|
+
function _directFn(updater) {
|
|
608
|
+
if (!this._d) this._d = [];
|
|
609
|
+
const arr = this._d;
|
|
610
|
+
const idx = arr.length;
|
|
611
|
+
arr.push(updater);
|
|
612
|
+
return () => {
|
|
613
|
+
arr[idx] = null;
|
|
614
|
+
};
|
|
615
|
+
}
|
|
616
|
+
/**
|
|
617
|
+
* Notify direct updaters — flat array iteration, batch-aware.
|
|
618
|
+
* Null slots (from disposed updaters) are skipped.
|
|
619
|
+
*/
|
|
620
|
+
function notifyDirect(updaters) {
|
|
621
|
+
if (isBatching()) for (let i = 0; i < updaters.length; i++) {
|
|
622
|
+
const fn = updaters[i];
|
|
623
|
+
if (fn) enqueuePendingNotification(fn);
|
|
624
|
+
}
|
|
625
|
+
else for (let i = 0; i < updaters.length; i++) updaters[i]?.();
|
|
626
|
+
}
|
|
551
627
|
function _debug() {
|
|
552
628
|
return {
|
|
553
|
-
name: this.
|
|
629
|
+
name: this.label,
|
|
554
630
|
value: this._v,
|
|
555
631
|
subscriberCount: this._s?.size ?? 0
|
|
556
632
|
};
|
|
557
633
|
}
|
|
558
|
-
const _labelDescriptor = {
|
|
559
|
-
get() {
|
|
560
|
-
return this._n;
|
|
561
|
-
},
|
|
562
|
-
set(v) {
|
|
563
|
-
this._n = v;
|
|
564
|
-
},
|
|
565
|
-
enumerable: false,
|
|
566
|
-
configurable: true
|
|
567
|
-
};
|
|
568
634
|
/**
|
|
569
635
|
* Create a reactive signal.
|
|
570
636
|
*
|
|
@@ -579,13 +645,14 @@ function signal(initialValue, options) {
|
|
|
579
645
|
});
|
|
580
646
|
read._v = initialValue;
|
|
581
647
|
read._s = null;
|
|
582
|
-
read.
|
|
648
|
+
read._d = null;
|
|
583
649
|
read.peek = _peek;
|
|
584
650
|
read.set = _set;
|
|
585
651
|
read.update = _update;
|
|
586
652
|
read.subscribe = _subscribe;
|
|
653
|
+
read.direct = _directFn;
|
|
587
654
|
read.debug = _debug;
|
|
588
|
-
|
|
655
|
+
read.label = options?.name;
|
|
589
656
|
return read;
|
|
590
657
|
}
|
|
591
658
|
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/batch.ts","../src/cell.ts","../src/scope.ts","../src/tracking.ts","../src/computed.ts","../src/effect.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\nlet pendingNotifications = new Set<() => void>()\n\nexport function batch(fn: () => void): void {\n batchDepth++\n try {\n fn()\n } finally {\n batchDepth--\n if (batchDepth === 0) {\n // Swap to a fresh Set before flushing so new enqueues during notification\n // (e.g. from nested batch() calls) land in the new Set and are handled in\n // the next flush pass, not mixed into the current iteration.\n const flush = pendingNotifications\n pendingNotifications = new Set()\n for (const notify of flush) notify()\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 if (this._l === listener) {\n return () => {\n if (this._l === listener) this._l = null\n }\n }\n return () => this._s?.delete(listener)\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 }[] = []\n private _active = true\n private _updateHooks: (() => void)[] = []\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) 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 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.length === 0 || this._updatePending) return\n this._updatePending = true\n queueMicrotask(() => {\n this._updatePending = false\n if (!this._active) 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 for (const e of this._effects) e.dispose()\n this._effects = []\n this._updateHooks = []\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\nexport function setDepsCollector(collector: Set<() => void>[] | null): void {\n _depsCollector = collector\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 const subscribers = host._s\n subscribers.add(activeEffect)\n if (_depsCollector) {\n // Fast path: renderEffect stores deps inline, no WeakMap\n _depsCollector.push(subscribers)\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(subscribers)\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 // Snapshot first to prevent the iterator from visiting re-inserted entries → infinite loop.\n for (const sub of [...subscribers]) sub()\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\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 { cleanupEffect, notifySubscribers, trackSubscriber, withTracking } from \"./tracking\"\n\nexport interface Computed<T> {\n (): T\n /** Remove this computed from all its reactive dependencies. */\n dispose(): 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\nexport function computed<T>(fn: () => T, options?: ComputedOptions<T>): Computed<T> {\n let value: T\n let dirty = true\n let initialized = false\n let disposed = false\n const customEquals = options?.equals\n\n // SubscriberHost — _s is lazily allocated by trackSubscriber\n const host: { _s: Set<() => void> | null } = { _s: null }\n\n const recompute = () => {\n if (disposed) return\n // Remove from all current deps before re-evaluating (dynamic deps support)\n cleanupEffect(recompute)\n if (customEquals) {\n // Eager evaluation: only notify downstream if the value actually changed\n const next = withTracking(recompute, fn)\n if (initialized && customEquals(value as T, next)) return\n value = next\n dirty = false\n initialized = true\n if (host._s) notifySubscribers(host._s)\n } else {\n dirty = true\n if (host._s) notifySubscribers(host._s)\n }\n }\n\n const read = (): T => {\n trackSubscriber(host)\n if (dirty) {\n value = withTracking(recompute, fn)\n dirty = false\n initialized = true\n }\n return value as T\n }\n\n read.dispose = () => {\n disposed = true\n cleanupEffect(recompute)\n }\n\n // Auto-register with the active EffectScope (if any)\n getCurrentScope()?.add({ dispose: read.dispose })\n\n return read\n}\n","import { getCurrentScope } from \"./scope\"\nimport { cleanupEffect, setDepsCollector, withTracking } from \"./tracking\"\n\nexport interface Effect {\n dispose(): void\n}\n\n// Global error handler — called for unhandled errors thrown inside effects.\n// Defaults to console.error so silent failures are never swallowed.\nlet _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// biome-ignore lint/suspicious/noConfusingVoidType: void is intentional — callbacks that return nothing must be assignable\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\n const runCleanup = () => {\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 // Run previous cleanup before re-running\n runCleanup()\n // Clean up previous subscriptions before re-running (dynamic dep tracking)\n cleanupEffect(run)\n try {\n cleanup = withTracking(run, fn) || undefined\n } catch (err) {\n _errorHandler(err)\n }\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 cleanupEffect(run)\n },\n }\n\n // Auto-register with the active EffectScope (if any)\n getCurrentScope()?.add(e)\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\nexport function renderEffect(fn: () => void): () => void {\n const deps: Set<() => void>[] = []\n let disposed = false\n\n const run = () => {\n if (disposed) return\n // Clean up old subscriptions\n for (const s of deps) s.delete(run)\n deps.length = 0\n // Track with fast collector — pushes to our local deps array\n setDepsCollector(deps)\n withTracking(run, fn)\n setDepsCollector(null)\n }\n\n run()\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 render effects are disposed during teardown\n getCurrentScope()?.add({ dispose })\n\n return dispose\n}\n","import { effect } from \"./effect\"\nimport { trackSubscriber } from \"./tracking\"\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 const oldBucket = subs.get(old)\n const newBucket = subs.get(next)\n if (oldBucket) for (const fn of [...oldBucket]) fn()\n if (newBucket) for (const fn of [...newBucket]) fn()\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","import { _notifyTraceListeners, isTracing } from \"./debug\"\nimport { notifySubscribers, trackSubscriber } from \"./tracking\"\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\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 /** 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 debug name */\n _n: string | undefined\n peek(): T\n set(value: T): void\n update(fn: (current: T) => T): void\n subscribe(listener: () => 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 const prev = this._v\n this._v = newValue\n if (isTracing()) _notifyTraceListeners(this as unknown as Signal<unknown>, prev, newValue)\n if (this._s) notifySubscribers(this._s)\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\nfunction _debug(this: SignalFn<unknown>): SignalDebugInfo<unknown> {\n return {\n name: this._n,\n value: this._v,\n subscriberCount: this._s?.size ?? 0,\n }\n}\n\n// label getter/setter — maps to _n for devtools-friendly access\nconst _labelDescriptor: PropertyDescriptor = {\n get(this: SignalFn<unknown>) {\n return this._n\n },\n set(this: SignalFn<unknown>, v: string | undefined) {\n this._n = v\n },\n enumerable: false,\n configurable: true,\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 // The read function is the only per-signal closure.\n // It doubles as the SubscriberHost (_s property) for trackSubscriber.\n const read = (() => {\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._n = options?.name\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.debug = _debug as () => SignalDebugInfo<T>\n Object.defineProperty(read, \"label\", _labelDescriptor)\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 // biome-ignore lint/suspicious/noConfusingVoidType: void is intentional — callers may return void\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
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/batch.ts","../src/cell.ts","../src/scope.ts","../src/tracking.ts","../src/computed.ts","../src/effect.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.\nlet setA = new Set<() => void>()\nlet 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) {\n // Swap to the other pre-allocated Set before flushing so new enqueues\n // during notification land in the alternate Set, not mixed into the\n // current iteration.\n const flush = pendingNotifications\n pendingNotifications = flush === setA ? setB : setA\n for (const notify of flush) notify()\n flush.clear()\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 if (this._l === listener) {\n return () => {\n if (this._l === listener) this._l = null\n }\n }\n return () => this._s?.delete(listener)\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 }[] = []\n private _active = true\n private _updateHooks: (() => void)[] = []\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) 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 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.length === 0 || this._updatePending) return\n this._updatePending = true\n queueMicrotask(() => {\n this._updatePending = false\n if (!this._active) 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 for (const e of this._effects) e.dispose()\n this._effects = []\n this._updateHooks = []\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\nexport function setDepsCollector(collector: Set<() => void>[] | null): void {\n _depsCollector = collector\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 const subscribers = host._s\n subscribers.add(activeEffect)\n if (_depsCollector) {\n // Fast path: renderEffect stores deps inline, no WeakMap\n _depsCollector.push(subscribers)\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(subscribers)\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\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 { cleanupEffect, notifySubscribers, trackSubscriber, withTracking } from \"./tracking\"\n\nexport interface Computed<T> {\n (): T\n /** Remove this computed from all its reactive dependencies. */\n dispose(): 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\nexport function computed<T>(fn: () => T, options?: ComputedOptions<T>): Computed<T> {\n let value: T\n let dirty = true\n let initialized = false\n let disposed = false\n const customEquals = options?.equals\n\n // SubscriberHost — _s is lazily allocated by trackSubscriber\n const host: { _s: Set<() => void> | null } = { _s: null }\n\n const recompute = () => {\n if (disposed) return\n // Remove from all current deps before re-evaluating (dynamic deps support)\n cleanupEffect(recompute)\n if (customEquals) {\n // Eager evaluation: only notify downstream if the value actually changed\n const next = withTracking(recompute, fn)\n if (initialized && customEquals(value as T, next)) return\n value = next\n dirty = false\n initialized = true\n if (host._s) notifySubscribers(host._s)\n } else {\n dirty = true\n if (host._s) notifySubscribers(host._s)\n }\n }\n\n const read = (): T => {\n trackSubscriber(host)\n if (dirty) {\n value = withTracking(recompute, fn)\n dirty = false\n initialized = true\n }\n return value as T\n }\n\n read.dispose = () => {\n disposed = true\n cleanupEffect(recompute)\n }\n\n // Auto-register with the active EffectScope (if any)\n getCurrentScope()?.add({ dispose: read.dispose })\n\n return read\n}\n","import { getCurrentScope } from \"./scope\"\nimport {\n _restoreActiveEffect,\n _setActiveEffect,\n cleanupEffect,\n setDepsCollector,\n withTracking,\n} from \"./tracking\"\n\nexport interface Effect {\n dispose(): void\n}\n\n// Global error handler — called for unhandled errors thrown inside effects.\n// Defaults to console.error so silent failures are never swallowed.\nlet _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// biome-ignore lint/suspicious/noConfusingVoidType: void is intentional — callbacks that return nothing must be assignable\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\n const runCleanup = () => {\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 // Run previous cleanup before re-running\n runCleanup()\n // Clean up previous subscriptions before re-running (dynamic dep tracking)\n cleanupEffect(run)\n try {\n cleanup = withTracking(run, fn) || undefined\n } catch (err) {\n _errorHandler(err)\n }\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 cleanupEffect(run)\n },\n }\n\n // Auto-register with the active EffectScope (if any)\n getCurrentScope()?.add(e)\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\nexport function renderEffect(fn: () => void): () => void {\n const deps: Set<() => void>[] = []\n let disposed = false\n\n const run = () => {\n if (disposed) return\n // Single-dep fast path — most render effects track exactly 1 signal.\n // Avoids for-of iterator creation + deps.length check on every re-run.\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 // Inline tracking setup — avoids setDepsCollector + withTracking function call overhead\n setDepsCollector(deps)\n _setActiveEffect(run)\n try {\n fn()\n } finally {\n _restoreActiveEffect()\n setDepsCollector(null)\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 { 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","import { enqueuePendingNotification, isBatching } from \"./batch\"\nimport { _notifyTraceListeners, isTracing } from \"./debug\"\nimport { notifySubscribers, trackSubscriber } from \"./tracking\"\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 interface ReadonlySignal<T> {\n (): T\n}\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 const prev = this._v\n this._v = newValue\n if (isTracing()) _notifyTraceListeners(this as unknown as Signal<unknown>, prev, newValue)\n // Direct updaters — flat array, no Set overhead, batch-aware\n if (this._d) notifyDirect(this._d)\n if (this._s) notifySubscribers(this._s)\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 // The read function is the only per-signal closure.\n // It doubles as the SubscriberHost (_s property) for trackSubscriber.\n const read = (() => {\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 // biome-ignore lint/suspicious/noConfusingVoidType: void is intentional — callers may return void\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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"}
|
package/lib/types/index.d.ts
CHANGED
|
@@ -6,8 +6,9 @@ function batch(fn) {
|
|
|
6
6
|
batchDepth--;
|
|
7
7
|
if (batchDepth === 0) {
|
|
8
8
|
const flush = pendingNotifications;
|
|
9
|
-
pendingNotifications =
|
|
9
|
+
pendingNotifications = flush === setA ? setB : setA;
|
|
10
10
|
for (const notify of flush) notify();
|
|
11
|
+
flush.clear();
|
|
11
12
|
}
|
|
12
13
|
}
|
|
13
14
|
}
|
|
@@ -107,7 +108,15 @@ function notifySubscribers(subscribers) {
|
|
|
107
108
|
if (isBatching()) enqueuePendingNotification(sub);else sub();
|
|
108
109
|
return;
|
|
109
110
|
}
|
|
110
|
-
if (isBatching()) for (const sub of subscribers) enqueuePendingNotification(sub);else
|
|
111
|
+
if (isBatching()) for (const sub of subscribers) enqueuePendingNotification(sub);else {
|
|
112
|
+
const originalSize = subscribers.size;
|
|
113
|
+
let i = 0;
|
|
114
|
+
for (const sub of subscribers) {
|
|
115
|
+
if (i >= originalSize) break;
|
|
116
|
+
sub();
|
|
117
|
+
i++;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
111
120
|
}
|
|
112
121
|
function withTracking(fn, compute) {
|
|
113
122
|
const prev = activeEffect;
|
|
@@ -118,6 +127,14 @@ function withTracking(fn, compute) {
|
|
|
118
127
|
activeEffect = prev;
|
|
119
128
|
}
|
|
120
129
|
}
|
|
130
|
+
function _setActiveEffect(fn) {
|
|
131
|
+
_prevEffect = activeEffect;
|
|
132
|
+
activeEffect = fn;
|
|
133
|
+
}
|
|
134
|
+
function _restoreActiveEffect() {
|
|
135
|
+
activeEffect = _prevEffect;
|
|
136
|
+
_prevEffect = null;
|
|
137
|
+
}
|
|
121
138
|
function runUntracked(fn) {
|
|
122
139
|
const prev = activeEffect;
|
|
123
140
|
activeEffect = null;
|
|
@@ -269,17 +286,27 @@ function renderEffect(fn) {
|
|
|
269
286
|
let disposed = false;
|
|
270
287
|
const run = () => {
|
|
271
288
|
if (disposed) return;
|
|
272
|
-
|
|
273
|
-
|
|
289
|
+
if (deps.length === 1) {
|
|
290
|
+
deps[0].delete(run);
|
|
291
|
+
deps.length = 0;
|
|
292
|
+
} else if (deps.length > 1) {
|
|
293
|
+
for (const s of deps) s.delete(run);
|
|
294
|
+
deps.length = 0;
|
|
295
|
+
}
|
|
274
296
|
setDepsCollector(deps);
|
|
275
|
-
|
|
276
|
-
|
|
297
|
+
_setActiveEffect(run);
|
|
298
|
+
try {
|
|
299
|
+
fn();
|
|
300
|
+
} finally {
|
|
301
|
+
_restoreActiveEffect();
|
|
302
|
+
setDepsCollector(null);
|
|
303
|
+
}
|
|
277
304
|
};
|
|
278
305
|
run();
|
|
279
306
|
const dispose = () => {
|
|
280
307
|
if (disposed) return;
|
|
281
308
|
disposed = true;
|
|
282
|
-
for (const s of deps) s.delete(run);
|
|
309
|
+
if (deps.length === 1) deps[0].delete(run);else for (const s of deps) s.delete(run);
|
|
283
310
|
deps.length = 0;
|
|
284
311
|
};
|
|
285
312
|
getCurrentScope()?.add({
|
|
@@ -291,6 +318,25 @@ function renderEffect(fn) {
|
|
|
291
318
|
//#endregion
|
|
292
319
|
//#region src/createSelector.ts
|
|
293
320
|
/**
|
|
321
|
+
* Notify a subscriber bucket without snapshot allocation.
|
|
322
|
+
* Caps iteration at the original size to avoid infinite loops from
|
|
323
|
+
* re-inserted entries (same pattern as notifySubscribers in tracking.ts).
|
|
324
|
+
*/
|
|
325
|
+
function notifyBucket(bucket) {
|
|
326
|
+
if (bucket.size === 0) return;
|
|
327
|
+
if (bucket.size === 1) {
|
|
328
|
+
bucket.values().next().value();
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
const originalSize = bucket.size;
|
|
332
|
+
let i = 0;
|
|
333
|
+
for (const fn of bucket) {
|
|
334
|
+
if (i >= originalSize) break;
|
|
335
|
+
fn();
|
|
336
|
+
i++;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
294
340
|
* Create an equality selector — returns a reactive predicate that is true
|
|
295
341
|
* only for the currently selected value.
|
|
296
342
|
*
|
|
@@ -319,8 +365,8 @@ function createSelector(source) {
|
|
|
319
365
|
current = next;
|
|
320
366
|
const oldBucket = subs.get(old);
|
|
321
367
|
const newBucket = subs.get(next);
|
|
322
|
-
if (oldBucket)
|
|
323
|
-
if (newBucket)
|
|
368
|
+
if (oldBucket) notifyBucket(oldBucket);
|
|
369
|
+
if (newBucket) notifyBucket(newBucket);
|
|
324
370
|
});
|
|
325
371
|
const hosts = /* @__PURE__ */new Map();
|
|
326
372
|
return value => {
|
|
@@ -439,6 +485,7 @@ function _set(newValue) {
|
|
|
439
485
|
const prev = this._v;
|
|
440
486
|
this._v = newValue;
|
|
441
487
|
if (isTracing()) _notifyTraceListeners(this, prev, newValue);
|
|
488
|
+
if (this._d) notifyDirect(this._d);
|
|
442
489
|
if (this._s) notifySubscribers(this._s);
|
|
443
490
|
}
|
|
444
491
|
function _update(fn) {
|
|
@@ -449,9 +496,33 @@ function _subscribe(listener) {
|
|
|
449
496
|
this._s.add(listener);
|
|
450
497
|
return () => this._s?.delete(listener);
|
|
451
498
|
}
|
|
499
|
+
/**
|
|
500
|
+
* Register a direct updater — lighter than subscribe().
|
|
501
|
+
* Uses a flat array instead of Set. Disposal nulls the slot (no Set.delete overhead).
|
|
502
|
+
* Used by compiler-emitted _bindText/_bindDirect for zero-overhead DOM bindings.
|
|
503
|
+
*/
|
|
504
|
+
function _directFn(updater) {
|
|
505
|
+
if (!this._d) this._d = [];
|
|
506
|
+
const arr = this._d;
|
|
507
|
+
const idx = arr.length;
|
|
508
|
+
arr.push(updater);
|
|
509
|
+
return () => {
|
|
510
|
+
arr[idx] = null;
|
|
511
|
+
};
|
|
512
|
+
}
|
|
513
|
+
/**
|
|
514
|
+
* Notify direct updaters — flat array iteration, batch-aware.
|
|
515
|
+
* Null slots (from disposed updaters) are skipped.
|
|
516
|
+
*/
|
|
517
|
+
function notifyDirect(updaters) {
|
|
518
|
+
if (isBatching()) for (let i = 0; i < updaters.length; i++) {
|
|
519
|
+
const fn = updaters[i];
|
|
520
|
+
if (fn) enqueuePendingNotification(fn);
|
|
521
|
+
} else for (let i = 0; i < updaters.length; i++) updaters[i]?.();
|
|
522
|
+
}
|
|
452
523
|
function _debug() {
|
|
453
524
|
return {
|
|
454
|
-
name: this.
|
|
525
|
+
name: this.label,
|
|
455
526
|
value: this._v,
|
|
456
527
|
subscriberCount: this._s?.size ?? 0
|
|
457
528
|
};
|
|
@@ -470,13 +541,14 @@ function signal(initialValue, options) {
|
|
|
470
541
|
};
|
|
471
542
|
read._v = initialValue;
|
|
472
543
|
read._s = null;
|
|
473
|
-
read.
|
|
544
|
+
read._d = null;
|
|
474
545
|
read.peek = _peek;
|
|
475
546
|
read.set = _set;
|
|
476
547
|
read.update = _update;
|
|
477
548
|
read.subscribe = _subscribe;
|
|
549
|
+
read.direct = _directFn;
|
|
478
550
|
read.debug = _debug;
|
|
479
|
-
|
|
551
|
+
read.label = options?.name;
|
|
480
552
|
return read;
|
|
481
553
|
}
|
|
482
554
|
|
package/lib/types/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/batch.ts","../../src/cell.ts","../../src/scope.ts","../../src/tracking.ts","../../src/computed.ts","../../src/effect.ts","../../src/createSelector.ts","../../src/debug.ts","../../src/signal.ts","../../src/store.ts","../../src/reconcile.ts","../../src/resource.ts","../../src/watch.ts"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/batch.ts","../../src/cell.ts","../../src/scope.ts","../../src/tracking.ts","../../src/computed.ts","../../src/effect.ts","../../src/createSelector.ts","../../src/debug.ts","../../src/signal.ts","../../src/store.ts","../../src/reconcile.ts","../../src/resource.ts","../../src/watch.ts"],"mappings":"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"}
|
package/lib/types/index2.d.ts
CHANGED
|
@@ -91,6 +91,13 @@ interface SignalDebugInfo<T> {
|
|
|
91
91
|
/** Number of active subscribers */
|
|
92
92
|
subscriberCount: number;
|
|
93
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* Read-only reactive value — the common interface that both Signal and Computed satisfy.
|
|
96
|
+
* Use this as the parameter type when a function only needs to read a reactive value.
|
|
97
|
+
*/
|
|
98
|
+
interface ReadonlySignal<T> {
|
|
99
|
+
(): T;
|
|
100
|
+
}
|
|
94
101
|
interface Signal<T> {
|
|
95
102
|
(): T;
|
|
96
103
|
/** Read the current value WITHOUT registering a reactive dependency. */
|
|
@@ -104,6 +111,13 @@ interface Signal<T> {
|
|
|
104
111
|
* Returns a disposer that removes the subscription.
|
|
105
112
|
*/
|
|
106
113
|
subscribe(listener: () => void): () => void;
|
|
114
|
+
/**
|
|
115
|
+
* Register a direct updater — even lighter than subscribe().
|
|
116
|
+
* Uses a flat array instead of Set. Disposal nulls the slot (no Set.delete).
|
|
117
|
+
* Intended for compiler-emitted DOM bindings (_bindText, _bindDirect).
|
|
118
|
+
* Returns a disposer that nulls the slot.
|
|
119
|
+
*/
|
|
120
|
+
direct(updater: () => void): () => void;
|
|
107
121
|
/** Debug name — useful for devtools and logging. */
|
|
108
122
|
label: string | undefined;
|
|
109
123
|
/** Returns a snapshot of the signal's debug info (value, name, subscriber count). */
|
|
@@ -338,5 +352,5 @@ interface WatchOptions {
|
|
|
338
352
|
*/
|
|
339
353
|
declare function watch<T>(source: () => T, callback: (newVal: T, oldVal: T | undefined) => void | (() => void), opts?: WatchOptions): () => void;
|
|
340
354
|
//#endregion
|
|
341
|
-
export { Cell, type Computed, type ComputedOptions, type Effect, EffectScope, type Resource, type Signal, type SignalDebugInfo, type SignalOptions, type WatchOptions, _bind, batch, cell, computed, createResource, createSelector, createStore, effect, effectScope, getCurrentScope, inspectSignal, isStore, nextTick, onSignalUpdate, reconcile, renderEffect, runUntracked, setCurrentScope, setErrorHandler, signal, watch, why };
|
|
355
|
+
export { Cell, type Computed, type ComputedOptions, type Effect, EffectScope, type ReadonlySignal, type Resource, type Signal, type SignalDebugInfo, type SignalOptions, type WatchOptions, _bind, batch, cell, computed, createResource, createSelector, createStore, effect, effectScope, getCurrentScope, inspectSignal, isStore, nextTick, onSignalUpdate, reconcile, renderEffect, runUntracked, setCurrentScope, setErrorHandler, signal, watch, why };
|
|
342
356
|
//# sourceMappingURL=index2.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
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":";
|
|
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":";iBAagB,KAAA,CAAM,EAAA;;;;AAmCtB;;;;;;iBAAgB,QAAA,CAAA,GAAY,OAAA;;;;AAnC5B;;;;;AAmCA;;;;;;cCpCa,IAAA;;EACM,EAAA,EAAI,CAAA;EADV;EAEM,EAAA;EAFF;EAGE,EAAA,EAAI,GAAA;cAET,KAAA,EAAO,CAAA;EAInB,IAAA,CAAA,GAAQ,CAAA;EAIR,GAAA,CAAI,KAAA,EAAO,CAAA;EAOX,MAAA,CAAO,EAAA,GAAK,OAAA,EAAS,CAAA,KAAM,CAAA;EAXnB;;;;;EAoBR,MAAA,CAAO,QAAA;EAgBP,SAAA,CAAU,QAAA;AAAA;AAAA,iBAWI,IAAA,GAAA,CAAQ,KAAA,EAAO,CAAA,GAAI,IAAA,CAAK,CAAA;;;UCjEvB,QAAA;EAAA,IACX,CAAA;EFSe;EEPnB,OAAA;AAAA;AAAA,UAGe,eAAA;EFuCD;;;;;;;;ACpChB;;ECQE,MAAA,IAAU,IAAA,EAAM,CAAA,EAAG,IAAA,EAAM,CAAA;AAAA;AAAA,iBAGX,QAAA,GAAA,CAAY,EAAA,QAAU,CAAA,EAAG,OAAA,GAAU,eAAA,CAAgB,CAAA,IAAK,QAAA,CAAS,CAAA;;;;AFVjF;;;;;AAmCA;;;;;;;iBGZgB,cAAA,GAAA,CAAkB,MAAA,QAAc,CAAA,IAAK,KAAA,EAAO,CAAA;;;UChC3C,eAAA;EJSD;EIPd,IAAA;;EAEA,KAAA,EAAO,CAAA;EJK2B;EIHlC,eAAA;AAAA;;;;;UAOe,cAAA;EAAA,IACX,CAAA;AAAA;AAAA,UAGW,MAAA;EAAA,IACX,CAAA;EHTiB;EGWrB,IAAA,IAAQ,CAAA;EACR,GAAA,CAAI,KAAA,EAAO,CAAA;EACX,MAAA,CAAO,EAAA,GAAK,OAAA,EAAS,CAAA,KAAM,CAAA;EHDhB;;;;;;EGQX,SAAA,CAAU,QAAA;EHpBW;;;;;;EG2BrB,MAAA,CAAO,OAAA;EHnBP;EGqBA,KAAA;EHjBA;EGmBA,KAAA,IAAS,eAAA,CAAgB,CAAA;AAAA;AAAA,UAGV,aAAA;EHfM;EGiBrB,IAAA;AAAA;;;;;;;;iBAgGc,MAAA,GAAA,CAAU,YAAA,EAAc,CAAA,EAAG,OAAA,GAAU,aAAA,GAAgB,MAAA,CAAO,CAAA;;;UCnIlE,iBAAA;;EAER,MAAA,EAAQ,MAAA;;EAER,IAAA;EJNe;EIQf,IAAA;EJPqB;EISrB,IAAA;EJLmB;EIOnB,KAAA;EJCW;EICX,SAAA;AAAA;AAAA,KAGG,oBAAA,IAAwB,KAAA,EAAO,iBAAA;;;;;;;;;;iBAapB,cAAA,CAAe,QAAA,EAAU,oBAAA;;;;;;;;;;iBA2CzB,GAAA,CAAA;;;AJjBhB;;;;;;;;;iBIwDgB,aAAA,GAAA,CAAiB,GAAA,EAAK,MAAA,CAAO,CAAA,IAAK,eAAA,CAAgB,CAAA;;;UCnHjD,MAAA;EACf,OAAA;AAAA;AAAA,iBASc,eAAA,CAAgB,EAAA,GAAK,GAAA;AAAA,iBAKrB,MAAA,CAAO,EAAA,8BAAgC,MAAA;;ANwBvD;;;;;;;;ACpCA;;;;;;;;;;;;;;;;;iBK0FgB,KAAA,CAAM,EAAA;AAAA,iBA2BN,YAAA,CAAa,EAAA;;;;ANpH7B;;;;;AAmCA;;;;;;;;ACpCA;;;;;;iBMagB,SAAA,kBAAA,CAA4B,MAAA,EAAQ,CAAA,EAAG,MAAA,EAAQ,CAAA;;;UCpB9C,QAAA;ERQI;EQNnB,IAAA,EAAM,MAAA,CAAO,CAAA;ERMO;EQJpB,OAAA,EAAS,MAAA;ERuCK;EQrCd,KAAA,EAAO,MAAA;;EAEP,OAAA;AAAA;;;;APDF;;;;;;;iBOcgB,cAAA,MAAA,CACd,MAAA,QAAc,CAAA,EACd,OAAA,GAAU,KAAA,EAAO,CAAA,KAAM,OAAA,CAAQ,CAAA,IAC9B,QAAA,CAAS,CAAA;;;cC1BC,WAAA;EAAA,QACH,QAAA;EAAA,QACA,OAAA;EAAA,QACA,YAAA;EAAA,QACA,cAAA;ETM0B;ESHlC,GAAA,CAAI,CAAA;IAAK,OAAA;EAAA;ETsCiB;;;;;ACpC5B;EQQE,UAAA,GAAA,CAAc,EAAA,QAAU,CAAA,GAAI,CAAA;ERRb;EQmBf,aAAA,CAAc,EAAA;ERhBO;;;;EQwBrB,eAAA,CAAA;ERP2B;EQwB3B,IAAA,CAAA;AAAA;AAAA,iBAYc,eAAA,CAAA,GAAmB,WAAA;AAAA,iBAInB,eAAA,CAAgB,KAAA,EAAO,WAAA;;iBAKvB,WAAA,CAAA,GAAe,WAAA;;;;AThE/B;;;;;AAmCA;;;;;;;;ACpCA;AAAA,iBSWgB,OAAA,CAAQ,KAAA;;;;;iBAYR,WAAA,kBAAA,CAA8B,OAAA,EAAS,CAAA,GAAI,CAAA;;;iBCmF3C,YAAA,GAAA,CAAgB,EAAA,QAAU,CAAA,GAAI,CAAA;;;UCpH7B,YAAA;EZWD;EYTd,SAAA;AAAA;;;AZ4CF;;;;;;;;ACpCA;;;;;;;;;;;iBWgBgB,KAAA,GAAA,CACd,MAAA,QAAc,CAAA,EAEd,QAAA,GAAW,MAAA,EAAQ,CAAA,EAAG,MAAA,EAAQ,CAAA,sCAC9B,IAAA,GAAM,YAAA"}
|
package/package.json
CHANGED
package/src/batch.ts
CHANGED
|
@@ -3,7 +3,13 @@
|
|
|
3
3
|
// even if multiple signals it depends on change within the same batch.
|
|
4
4
|
|
|
5
5
|
let batchDepth = 0
|
|
6
|
-
|
|
6
|
+
|
|
7
|
+
// Two pre-allocated Sets swapped on each flush — avoids allocating a new Set()
|
|
8
|
+
// on every batch exit. The "active" set collects enqueued notifications; on flush
|
|
9
|
+
// we swap to the other set and iterate the captured one, then clear it for reuse.
|
|
10
|
+
let setA = new Set<() => void>()
|
|
11
|
+
let setB = new Set<() => void>()
|
|
12
|
+
let pendingNotifications = setA
|
|
7
13
|
|
|
8
14
|
export function batch(fn: () => void): void {
|
|
9
15
|
batchDepth++
|
|
@@ -12,12 +18,13 @@ export function batch(fn: () => void): void {
|
|
|
12
18
|
} finally {
|
|
13
19
|
batchDepth--
|
|
14
20
|
if (batchDepth === 0) {
|
|
15
|
-
// Swap to
|
|
16
|
-
//
|
|
17
|
-
//
|
|
21
|
+
// Swap to the other pre-allocated Set before flushing so new enqueues
|
|
22
|
+
// during notification land in the alternate Set, not mixed into the
|
|
23
|
+
// current iteration.
|
|
18
24
|
const flush = pendingNotifications
|
|
19
|
-
pendingNotifications =
|
|
25
|
+
pendingNotifications = flush === setA ? setB : setA
|
|
20
26
|
for (const notify of flush) notify()
|
|
27
|
+
flush.clear()
|
|
21
28
|
}
|
|
22
29
|
}
|
|
23
30
|
}
|
package/src/createSelector.ts
CHANGED
|
@@ -1,6 +1,26 @@
|
|
|
1
1
|
import { effect } from "./effect"
|
|
2
2
|
import { trackSubscriber } from "./tracking"
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Notify a subscriber bucket without snapshot allocation.
|
|
6
|
+
* Caps iteration at the original size to avoid infinite loops from
|
|
7
|
+
* re-inserted entries (same pattern as notifySubscribers in tracking.ts).
|
|
8
|
+
*/
|
|
9
|
+
function notifyBucket(bucket: Set<() => void>): void {
|
|
10
|
+
if (bucket.size === 0) return
|
|
11
|
+
if (bucket.size === 1) {
|
|
12
|
+
;(bucket.values().next().value as () => void)()
|
|
13
|
+
return
|
|
14
|
+
}
|
|
15
|
+
const originalSize = bucket.size
|
|
16
|
+
let i = 0
|
|
17
|
+
for (const fn of bucket) {
|
|
18
|
+
if (i >= originalSize) break
|
|
19
|
+
fn()
|
|
20
|
+
i++
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
4
24
|
/**
|
|
5
25
|
* Create an equality selector — returns a reactive predicate that is true
|
|
6
26
|
* only for the currently selected value.
|
|
@@ -29,11 +49,12 @@ export function createSelector<T>(source: () => T): (value: T) => boolean {
|
|
|
29
49
|
if (Object.is(next, current)) return
|
|
30
50
|
const old = current
|
|
31
51
|
current = next
|
|
32
|
-
// Only notify the two affected buckets — O(1) regardless of list size
|
|
52
|
+
// Only notify the two affected buckets — O(1) regardless of list size.
|
|
53
|
+
// Iteration-capped loop avoids [...bucket] snapshot allocation.
|
|
33
54
|
const oldBucket = subs.get(old)
|
|
34
55
|
const newBucket = subs.get(next)
|
|
35
|
-
if (oldBucket)
|
|
36
|
-
if (newBucket)
|
|
56
|
+
if (oldBucket) notifyBucket(oldBucket)
|
|
57
|
+
if (newBucket) notifyBucket(newBucket)
|
|
37
58
|
})
|
|
38
59
|
|
|
39
60
|
// Reusable hosts per value — avoids allocating a closure per trackSubscriber call
|
package/src/effect.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { getCurrentScope } from "./scope"
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
_restoreActiveEffect,
|
|
4
|
+
_setActiveEffect,
|
|
5
|
+
cleanupEffect,
|
|
6
|
+
setDepsCollector,
|
|
7
|
+
withTracking,
|
|
8
|
+
} from "./tracking"
|
|
3
9
|
|
|
4
10
|
export interface Effect {
|
|
5
11
|
dispose(): void
|
|
@@ -127,13 +133,24 @@ export function renderEffect(fn: () => void): () => void {
|
|
|
127
133
|
|
|
128
134
|
const run = () => {
|
|
129
135
|
if (disposed) return
|
|
130
|
-
//
|
|
131
|
-
for
|
|
132
|
-
deps.length
|
|
133
|
-
|
|
136
|
+
// Single-dep fast path — most render effects track exactly 1 signal.
|
|
137
|
+
// Avoids for-of iterator creation + deps.length check on every re-run.
|
|
138
|
+
if (deps.length === 1) {
|
|
139
|
+
;(deps[0] as Set<() => void>).delete(run)
|
|
140
|
+
deps.length = 0
|
|
141
|
+
} else if (deps.length > 1) {
|
|
142
|
+
for (const s of deps) s.delete(run)
|
|
143
|
+
deps.length = 0
|
|
144
|
+
}
|
|
145
|
+
// Inline tracking setup — avoids setDepsCollector + withTracking function call overhead
|
|
134
146
|
setDepsCollector(deps)
|
|
135
|
-
|
|
136
|
-
|
|
147
|
+
_setActiveEffect(run)
|
|
148
|
+
try {
|
|
149
|
+
fn()
|
|
150
|
+
} finally {
|
|
151
|
+
_restoreActiveEffect()
|
|
152
|
+
setDepsCollector(null)
|
|
153
|
+
}
|
|
137
154
|
}
|
|
138
155
|
|
|
139
156
|
run()
|
|
@@ -141,7 +158,11 @@ export function renderEffect(fn: () => void): () => void {
|
|
|
141
158
|
const dispose = () => {
|
|
142
159
|
if (disposed) return
|
|
143
160
|
disposed = true
|
|
144
|
-
|
|
161
|
+
if (deps.length === 1) {
|
|
162
|
+
;(deps[0] as Set<() => void>).delete(run)
|
|
163
|
+
} else {
|
|
164
|
+
for (const s of deps) s.delete(run)
|
|
165
|
+
}
|
|
145
166
|
deps.length = 0
|
|
146
167
|
}
|
|
147
168
|
|
package/src/index.ts
CHANGED
|
@@ -9,7 +9,13 @@ export { _bind, type Effect, effect, renderEffect, setErrorHandler } from "./eff
|
|
|
9
9
|
export { reconcile } from "./reconcile"
|
|
10
10
|
export { createResource, type Resource } from "./resource"
|
|
11
11
|
export { EffectScope, effectScope, getCurrentScope, setCurrentScope } from "./scope"
|
|
12
|
-
export {
|
|
12
|
+
export {
|
|
13
|
+
type ReadonlySignal,
|
|
14
|
+
type Signal,
|
|
15
|
+
type SignalDebugInfo,
|
|
16
|
+
type SignalOptions,
|
|
17
|
+
signal,
|
|
18
|
+
} from "./signal"
|
|
13
19
|
export { createStore, isStore } from "./store"
|
|
14
20
|
export { runUntracked } from "./tracking"
|
|
15
21
|
export { type WatchOptions, watch } from "./watch"
|
package/src/signal.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { enqueuePendingNotification, isBatching } from "./batch"
|
|
1
2
|
import { _notifyTraceListeners, isTracing } from "./debug"
|
|
2
3
|
import { notifySubscribers, trackSubscriber } from "./tracking"
|
|
3
4
|
|
|
@@ -10,6 +11,14 @@ export interface SignalDebugInfo<T> {
|
|
|
10
11
|
subscriberCount: number
|
|
11
12
|
}
|
|
12
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Read-only reactive value — the common interface that both Signal and Computed satisfy.
|
|
16
|
+
* Use this as the parameter type when a function only needs to read a reactive value.
|
|
17
|
+
*/
|
|
18
|
+
export interface ReadonlySignal<T> {
|
|
19
|
+
(): T
|
|
20
|
+
}
|
|
21
|
+
|
|
13
22
|
export interface Signal<T> {
|
|
14
23
|
(): T
|
|
15
24
|
/** Read the current value WITHOUT registering a reactive dependency. */
|
|
@@ -23,6 +32,13 @@ export interface Signal<T> {
|
|
|
23
32
|
* Returns a disposer that removes the subscription.
|
|
24
33
|
*/
|
|
25
34
|
subscribe(listener: () => void): () => void
|
|
35
|
+
/**
|
|
36
|
+
* Register a direct updater — even lighter than subscribe().
|
|
37
|
+
* Uses a flat array instead of Set. Disposal nulls the slot (no Set.delete).
|
|
38
|
+
* Intended for compiler-emitted DOM bindings (_bindText, _bindDirect).
|
|
39
|
+
* Returns a disposer that nulls the slot.
|
|
40
|
+
*/
|
|
41
|
+
direct(updater: () => void): () => void
|
|
26
42
|
/** Debug name — useful for devtools and logging. */
|
|
27
43
|
label: string | undefined
|
|
28
44
|
/** Returns a snapshot of the signal's debug info (value, name, subscriber count). */
|
|
@@ -42,12 +58,14 @@ interface SignalFn<T> {
|
|
|
42
58
|
_v: T
|
|
43
59
|
/** @internal subscriber set (lazily allocated by trackSubscriber) */
|
|
44
60
|
_s: Set<() => void> | null
|
|
45
|
-
/** @internal
|
|
46
|
-
|
|
61
|
+
/** @internal direct updaters array — compiler-emitted DOM updaters (lazily allocated) */
|
|
62
|
+
_d: ((() => void) | null)[] | null
|
|
47
63
|
peek(): T
|
|
48
64
|
set(value: T): void
|
|
49
65
|
update(fn: (current: T) => T): void
|
|
50
66
|
subscribe(listener: () => void): () => void
|
|
67
|
+
/** Register a direct updater — lighter than subscribe, uses array index disposal. */
|
|
68
|
+
direct(updater: () => void): () => void
|
|
51
69
|
label: string | undefined
|
|
52
70
|
debug(): SignalDebugInfo<T>
|
|
53
71
|
}
|
|
@@ -63,6 +81,8 @@ function _set(this: SignalFn<unknown>, newValue: unknown) {
|
|
|
63
81
|
const prev = this._v
|
|
64
82
|
this._v = newValue
|
|
65
83
|
if (isTracing()) _notifyTraceListeners(this as unknown as Signal<unknown>, prev, newValue)
|
|
84
|
+
// Direct updaters — flat array, no Set overhead, batch-aware
|
|
85
|
+
if (this._d) notifyDirect(this._d)
|
|
66
86
|
if (this._s) notifySubscribers(this._s)
|
|
67
87
|
}
|
|
68
88
|
|
|
@@ -76,26 +96,46 @@ function _subscribe(this: SignalFn<unknown>, listener: () => void): () => void {
|
|
|
76
96
|
return () => this._s?.delete(listener)
|
|
77
97
|
}
|
|
78
98
|
|
|
99
|
+
/**
|
|
100
|
+
* Register a direct updater — lighter than subscribe().
|
|
101
|
+
* Uses a flat array instead of Set. Disposal nulls the slot (no Set.delete overhead).
|
|
102
|
+
* Used by compiler-emitted _bindText/_bindDirect for zero-overhead DOM bindings.
|
|
103
|
+
*/
|
|
104
|
+
function _directFn(this: SignalFn<unknown>, updater: () => void): () => void {
|
|
105
|
+
if (!this._d) this._d = []
|
|
106
|
+
const arr = this._d
|
|
107
|
+
const idx = arr.length
|
|
108
|
+
arr.push(updater)
|
|
109
|
+
return () => {
|
|
110
|
+
arr[idx] = null
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Notify direct updaters — flat array iteration, batch-aware.
|
|
116
|
+
* Null slots (from disposed updaters) are skipped.
|
|
117
|
+
*/
|
|
118
|
+
function notifyDirect(updaters: ((() => void) | null)[]): void {
|
|
119
|
+
if (isBatching()) {
|
|
120
|
+
for (let i = 0; i < updaters.length; i++) {
|
|
121
|
+
const fn = updaters[i]
|
|
122
|
+
if (fn) enqueuePendingNotification(fn)
|
|
123
|
+
}
|
|
124
|
+
} else {
|
|
125
|
+
for (let i = 0; i < updaters.length; i++) {
|
|
126
|
+
updaters[i]?.()
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
79
131
|
function _debug(this: SignalFn<unknown>): SignalDebugInfo<unknown> {
|
|
80
132
|
return {
|
|
81
|
-
name: this.
|
|
133
|
+
name: this.label,
|
|
82
134
|
value: this._v,
|
|
83
135
|
subscriberCount: this._s?.size ?? 0,
|
|
84
136
|
}
|
|
85
137
|
}
|
|
86
138
|
|
|
87
|
-
// label getter/setter — maps to _n for devtools-friendly access
|
|
88
|
-
const _labelDescriptor: PropertyDescriptor = {
|
|
89
|
-
get(this: SignalFn<unknown>) {
|
|
90
|
-
return this._n
|
|
91
|
-
},
|
|
92
|
-
set(this: SignalFn<unknown>, v: string | undefined) {
|
|
93
|
-
this._n = v
|
|
94
|
-
},
|
|
95
|
-
enumerable: false,
|
|
96
|
-
configurable: true,
|
|
97
|
-
}
|
|
98
|
-
|
|
99
139
|
/**
|
|
100
140
|
* Create a reactive signal.
|
|
101
141
|
*
|
|
@@ -113,13 +153,14 @@ export function signal<T>(initialValue: T, options?: SignalOptions): Signal<T> {
|
|
|
113
153
|
|
|
114
154
|
read._v = initialValue
|
|
115
155
|
read._s = null
|
|
116
|
-
read.
|
|
156
|
+
read._d = null
|
|
117
157
|
read.peek = _peek as () => T
|
|
118
158
|
read.set = _set as (value: T) => void
|
|
119
159
|
read.update = _update as (fn: (current: T) => T) => void
|
|
120
160
|
read.subscribe = _subscribe as (listener: () => void) => () => void
|
|
161
|
+
read.direct = _directFn as (updater: () => void) => () => void
|
|
121
162
|
read.debug = _debug as () => SignalDebugInfo<T>
|
|
122
|
-
|
|
163
|
+
read.label = options?.name
|
|
123
164
|
|
|
124
165
|
return read as unknown as Signal<T>
|
|
125
166
|
}
|
package/src/tracking.ts
CHANGED
|
@@ -77,8 +77,19 @@ export function notifySubscribers(subscribers: Set<() => void>) {
|
|
|
77
77
|
for (const sub of subscribers) enqueuePendingNotification(sub)
|
|
78
78
|
} else {
|
|
79
79
|
// Effects run inline and may call cleanupEffect (removes) + trackSubscriber (re-adds).
|
|
80
|
-
//
|
|
81
|
-
|
|
80
|
+
// Instead of snapshotting with [...subscribers] (allocates an array), we iterate the
|
|
81
|
+
// live Set but cap iterations at the original size to prevent infinite loops from
|
|
82
|
+
// re-inserted entries. This is safe because:
|
|
83
|
+
// - cleanupEffect removes the effect from the Set (no double-fire)
|
|
84
|
+
// - trackSubscriber may re-add it (but we stop after originalSize iterations)
|
|
85
|
+
// - Any effects re-added during this pass are already up-to-date (just ran)
|
|
86
|
+
const originalSize = subscribers.size
|
|
87
|
+
let i = 0
|
|
88
|
+
for (const sub of subscribers) {
|
|
89
|
+
if (i >= originalSize) break
|
|
90
|
+
sub()
|
|
91
|
+
i++
|
|
92
|
+
}
|
|
82
93
|
}
|
|
83
94
|
}
|
|
84
95
|
|
|
@@ -92,6 +103,19 @@ export function withTracking<T>(fn: () => void, compute: () => T): T {
|
|
|
92
103
|
}
|
|
93
104
|
}
|
|
94
105
|
|
|
106
|
+
// Stack for inlined tracking in renderEffect — avoids withTracking function call overhead.
|
|
107
|
+
let _prevEffect: (() => void) | null = null
|
|
108
|
+
|
|
109
|
+
export function _setActiveEffect(fn: () => void): void {
|
|
110
|
+
_prevEffect = activeEffect
|
|
111
|
+
activeEffect = fn
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export function _restoreActiveEffect(): void {
|
|
115
|
+
activeEffect = _prevEffect
|
|
116
|
+
_prevEffect = null
|
|
117
|
+
}
|
|
118
|
+
|
|
95
119
|
export function runUntracked<T>(fn: () => T): T {
|
|
96
120
|
const prev = activeEffect
|
|
97
121
|
activeEffect = null
|