signalium 2.2.2 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/cjs/development/config-B0MtLBgx.js.map +1 -1
  3. package/dist/cjs/development/{debug-DuXQhd5q.js → debug-gCDAvnLM.js} +237 -214
  4. package/dist/cjs/development/debug-gCDAvnLM.js.map +1 -0
  5. package/dist/cjs/development/debug.js +9 -3
  6. package/dist/cjs/development/debug.js.map +1 -1
  7. package/dist/cjs/development/index.js +8 -8
  8. package/dist/cjs/development/react/index.js +43 -38
  9. package/dist/cjs/development/react/index.js.map +1 -1
  10. package/dist/cjs/development/snapshot-Di0yziPX.js +147 -0
  11. package/dist/cjs/development/snapshot-Di0yziPX.js.map +1 -0
  12. package/dist/cjs/development/transform/index.js +137 -118
  13. package/dist/cjs/development/transform/index.js.map +1 -1
  14. package/dist/cjs/development/utils.js +5 -3
  15. package/dist/cjs/development/utils.js.map +1 -1
  16. package/dist/cjs/production/config-B0MtLBgx.js.map +1 -1
  17. package/dist/cjs/production/{contexts-DOH1tHd8.js → contexts-Wgq2NOVX.js} +156 -140
  18. package/dist/cjs/production/contexts-Wgq2NOVX.js.map +1 -0
  19. package/dist/cjs/production/debug.js +61 -66
  20. package/dist/cjs/production/debug.js.map +1 -1
  21. package/dist/cjs/production/index.js +8 -8
  22. package/dist/cjs/production/react/index.js +43 -38
  23. package/dist/cjs/production/react/index.js.map +1 -1
  24. package/dist/cjs/production/snapshot-YJJyLbxS.js +147 -0
  25. package/dist/cjs/production/snapshot-YJJyLbxS.js.map +1 -0
  26. package/dist/cjs/production/transform/index.js +137 -118
  27. package/dist/cjs/production/transform/index.js.map +1 -1
  28. package/dist/cjs/production/utils.js +5 -3
  29. package/dist/cjs/production/utils.js.map +1 -1
  30. package/dist/esm/development/config-CPQL7hX-.js.map +1 -1
  31. package/dist/esm/development/{debug-E2E1pZe5.js → debug-AoHfqs62.js} +221 -196
  32. package/dist/esm/development/debug-AoHfqs62.js.map +1 -0
  33. package/dist/esm/development/debug.js +1 -1
  34. package/dist/esm/development/index.js +6 -6
  35. package/dist/esm/development/react/index.js +43 -38
  36. package/dist/esm/development/react/index.js.map +1 -1
  37. package/dist/esm/development/snapshot-Bq0Um_hQ.js +148 -0
  38. package/dist/esm/development/snapshot-Bq0Um_hQ.js.map +1 -0
  39. package/dist/esm/development/transform/index.js +137 -118
  40. package/dist/esm/development/transform/index.js.map +1 -1
  41. package/dist/esm/development/utils.js +7 -4
  42. package/dist/esm/development/utils.js.map +1 -1
  43. package/dist/esm/internals/async.d.ts.map +1 -1
  44. package/dist/esm/internals/core-api.d.ts +2 -2
  45. package/dist/esm/internals/core-api.d.ts.map +1 -1
  46. package/dist/esm/internals/edge.d.ts +4 -4
  47. package/dist/esm/internals/edge.d.ts.map +1 -1
  48. package/dist/esm/internals/reactive.d.ts +14 -4
  49. package/dist/esm/internals/reactive.d.ts.map +1 -1
  50. package/dist/esm/internals/scheduling.d.ts.map +1 -1
  51. package/dist/esm/internals/signal.d.ts.map +1 -1
  52. package/dist/esm/internals/utils/snapshot.d.ts +29 -0
  53. package/dist/esm/internals/utils/snapshot.d.ts.map +1 -0
  54. package/dist/esm/production/config-CPQL7hX-.js.map +1 -1
  55. package/dist/esm/production/{contexts-Dj9Y86xW.js → contexts-X0gSj6rQ.js} +159 -143
  56. package/dist/esm/production/contexts-X0gSj6rQ.js.map +1 -0
  57. package/dist/esm/production/debug.js +51 -54
  58. package/dist/esm/production/debug.js.map +1 -1
  59. package/dist/esm/production/index.js +7 -7
  60. package/dist/esm/production/react/index.js +43 -38
  61. package/dist/esm/production/react/index.js.map +1 -1
  62. package/dist/esm/production/snapshot-CDS1d8mq.js +148 -0
  63. package/dist/esm/production/snapshot-CDS1d8mq.js.map +1 -0
  64. package/dist/esm/production/transform/index.js +137 -118
  65. package/dist/esm/production/transform/index.js.map +1 -1
  66. package/dist/esm/production/utils.js +7 -4
  67. package/dist/esm/production/utils.js.map +1 -1
  68. package/dist/esm/react/index.d.ts +1 -1
  69. package/dist/esm/react/index.d.ts.map +1 -1
  70. package/dist/esm/react/provider.d.ts.map +1 -1
  71. package/dist/esm/react/use-reactive.d.ts +1 -0
  72. package/dist/esm/react/use-reactive.d.ts.map +1 -1
  73. package/dist/esm/transform/callback.d.ts.map +1 -1
  74. package/dist/esm/transform/promise.d.ts.map +1 -1
  75. package/dist/esm/types.d.ts +5 -1
  76. package/dist/esm/types.d.ts.map +1 -1
  77. package/dist/esm/utils.d.ts +1 -0
  78. package/dist/esm/utils.d.ts.map +1 -1
  79. package/package.json +7 -5
  80. package/dist/cjs/development/core-api-C8J7lYBC.js +0 -55
  81. package/dist/cjs/development/core-api-C8J7lYBC.js.map +0 -1
  82. package/dist/cjs/development/debug-DuXQhd5q.js.map +0 -1
  83. package/dist/cjs/production/contexts-DOH1tHd8.js.map +0 -1
  84. package/dist/cjs/production/core-api-Cx2_AumW.js +0 -55
  85. package/dist/cjs/production/core-api-Cx2_AumW.js.map +0 -1
  86. package/dist/esm/development/core-api-CF5aK2Lx.js +0 -56
  87. package/dist/esm/development/core-api-CF5aK2Lx.js.map +0 -1
  88. package/dist/esm/development/debug-E2E1pZe5.js.map +0 -1
  89. package/dist/esm/production/contexts-Dj9Y86xW.js.map +0 -1
  90. package/dist/esm/production/core-api-D_uw3umM.js +0 -56
  91. package/dist/esm/production/core-api-D_uw3umM.js.map +0 -1
@@ -1,5 +1,6 @@
1
1
  import { s as scheduleFlush$1, r as runBatch } from "./config-CPQL7hX-.js";
2
2
  class WeakRefPolyfill {
3
+ value;
3
4
  constructor(value) {
4
5
  this.value = value;
5
6
  }
@@ -15,7 +16,14 @@ const setCurrentConsumer = (consumer) => {
15
16
  const getCurrentConsumer = () => {
16
17
  return CURRENT_CONSUMER;
17
18
  };
18
- let STATE_ID = 0;
19
+ const DEFAULT_EQUALS = (a, b) => a === b;
20
+ const FALSE_EQUALS = () => false;
21
+ const equalsFrom = (equals) => {
22
+ if (equals === false) {
23
+ return FALSE_EQUALS;
24
+ }
25
+ return equals ?? DEFAULT_EQUALS;
26
+ };
19
27
  class StateSignal {
20
28
  _value;
21
29
  _equals;
@@ -26,8 +34,6 @@ class StateSignal {
26
34
  constructor(value, equals = (a, b) => a === b, desc = "signal") {
27
35
  this._value = value;
28
36
  this._equals = equals;
29
- this._id = STATE_ID++;
30
- this._desc = desc;
31
37
  }
32
38
  get value() {
33
39
  this.consume();
@@ -58,7 +64,7 @@ class StateSignal {
58
64
  }
59
65
  dirtySignal(sub);
60
66
  }
61
- this._subs = /* @__PURE__ */ new Map();
67
+ this._subs.clear();
62
68
  scheduleListeners(this);
63
69
  }
64
70
  addListener(listener) {
@@ -79,13 +85,12 @@ function runListeners$1(signal2) {
79
85
  listener();
80
86
  }
81
87
  }
82
- const FALSE_EQUALS$1 = () => false;
83
88
  function signal(initialValue, opts) {
84
- const equals = opts?.equals === false ? FALSE_EQUALS$1 : opts?.equals ?? ((a, b) => a === b);
89
+ const equals = opts?.equals === false ? FALSE_EQUALS : opts?.equals ?? ((a, b) => a === b);
85
90
  return new StateSignal(initialValue, equals, opts?.desc);
86
91
  }
87
92
  const notifier = (opts) => {
88
- return new StateSignal(void 0, FALSE_EQUALS$1, opts?.desc);
93
+ return new StateSignal(void 0, FALSE_EQUALS, opts?.desc);
89
94
  };
90
95
  function watchSignal(signal2, parentIsSuspended) {
91
96
  if (parentIsSuspended) {
@@ -208,7 +213,8 @@ let PENDING_GC = /* @__PURE__ */ new Set();
208
213
  const microtask = () => Promise.resolve();
209
214
  let currentFlush = null;
210
215
  const scheduleFlush = (fn) => {
211
- if (currentFlush) return;
216
+ if (currentFlush)
217
+ return;
212
218
  let resolve;
213
219
  const promise = new Promise((r) => resolve = r);
214
220
  currentFlush = { promise, resolve };
@@ -241,7 +247,8 @@ const scheduleTracer = (tracer) => {
241
247
  };
242
248
  const scheduleGcSweep = (scope) => {
243
249
  PENDING_GC.add(scope);
244
- if (PENDING_GC.size > 1) return;
250
+ if (PENDING_GC.size > 1)
251
+ return;
245
252
  scheduleIdleCallback(() => {
246
253
  for (const scope2 of PENDING_GC) {
247
254
  scope2.sweepGc();
@@ -251,6 +258,8 @@ const scheduleGcSweep = (scope) => {
251
258
  };
252
259
  const flushWatchers = async () => {
253
260
  const flush = currentFlush;
261
+ if (!flush)
262
+ return;
254
263
  while (PENDING_ASYNC_PULLS.length > 0 || PENDING_PULLS.size > 0) {
255
264
  const asyncPulls = PENDING_ASYNC_PULLS;
256
265
  PENDING_ASYNC_PULLS = [];
@@ -288,19 +297,17 @@ const settled = async () => {
288
297
  };
289
298
  function dirtySignal(signal2) {
290
299
  const prevState = signal2._state;
291
- if (prevState === ReactiveFnState.Dirty) {
300
+ if (prevState === 2) {
292
301
  return;
293
302
  }
294
- signal2._state = ReactiveFnState.Dirty;
295
- if (prevState < ReactiveFnState.MaybeDirty) {
303
+ signal2._state = 2;
304
+ if (prevState < 3) {
296
305
  propagateDirty(signal2);
297
306
  }
298
307
  }
299
308
  function propagateDirty(signal2) {
300
309
  if (getCurrentConsumer() === signal2) {
301
- throw new Error(
302
- "A signal was dirtied after it was consumed by the current function. This can cause race conditions and infinite rerenders and is not allowed."
303
- );
310
+ throw new Error("A signal was dirtied after it was consumed by the current function. This can cause race conditions and infinite rerenders and is not allowed.");
304
311
  }
305
312
  if (isRelay(signal2)) {
306
313
  if (signal2.watchCount > 0) {
@@ -311,31 +318,32 @@ function propagateDirty(signal2) {
311
318
  schedulePull(signal2);
312
319
  }
313
320
  dirtySignalConsumers(signal2.subs);
314
- signal2.subs = /* @__PURE__ */ new Map();
321
+ signal2.subs.clear();
315
322
  }
316
323
  }
317
324
  function dirtySignalConsumers(map) {
318
325
  for (const [subRef, edge] of map) {
319
326
  const sub = subRef.deref();
320
- if (sub === void 0 || sub.computedCount !== edge.consumedAt) continue;
327
+ if (sub === void 0 || sub.computedCount !== edge.consumedAt)
328
+ continue;
321
329
  const dirtyState = sub._state;
322
330
  switch (dirtyState) {
323
- case ReactiveFnState.Clean:
324
- sub._state = ReactiveFnState.MaybeDirty;
331
+ case 0:
332
+ sub._state = 3;
325
333
  sub.dirtyHead = edge;
326
334
  edge.nextDirty = void 0;
327
335
  propagateDirty(sub);
328
336
  break;
329
- case ReactiveFnState.Pending:
330
- case ReactiveFnState.MaybeDirty:
331
- case ReactiveFnState.PendingDirty: {
337
+ case 1:
338
+ case 3:
339
+ case 4: {
332
340
  let subEdge = sub.dirtyHead;
333
341
  const ord = edge.ord;
334
342
  if (subEdge.ord > ord) {
335
343
  sub.dirtyHead = edge;
336
344
  edge.nextDirty = subEdge;
337
- if (dirtyState === ReactiveFnState.Pending || dirtyState === ReactiveFnState.PendingDirty) {
338
- sub._state = ReactiveFnState.MaybeDirty;
345
+ if (dirtyState === 1 || dirtyState === 4) {
346
+ sub._state = 3;
339
347
  propagateDirty(sub);
340
348
  }
341
349
  } else {
@@ -353,21 +361,25 @@ function dirtySignalConsumers(map) {
353
361
  }
354
362
  }
355
363
  let CURRENT_ORD = 0;
356
- var EdgeType = /* @__PURE__ */ ((EdgeType2) => {
357
- EdgeType2[EdgeType2["Signal"] = 0] = "Signal";
358
- EdgeType2[EdgeType2["Promise"] = 1] = "Promise";
359
- return EdgeType2;
360
- })(EdgeType || {});
364
+ class EdgeBase {
365
+ type;
366
+ dep;
367
+ ord;
368
+ updatedAt;
369
+ consumedAt;
370
+ nextDirty;
371
+ constructor(type, dep, updatedAt, consumedAt) {
372
+ this.type = type;
373
+ this.dep = dep;
374
+ this.ord = CURRENT_ORD++;
375
+ this.updatedAt = updatedAt;
376
+ this.consumedAt = consumedAt;
377
+ this.nextDirty = void 0;
378
+ }
379
+ }
361
380
  function createEdge(prevEdge, type, dep, updatedAt, consumedAt) {
362
381
  if (prevEdge === void 0) {
363
- return {
364
- type,
365
- dep,
366
- ord: CURRENT_ORD++,
367
- updatedAt,
368
- consumedAt,
369
- nextDirty: void 0
370
- };
382
+ return new EdgeBase(type, dep, updatedAt, consumedAt);
371
383
  }
372
384
  prevEdge.ord = CURRENT_ORD++;
373
385
  prevEdge.updatedAt = updatedAt;
@@ -395,14 +407,6 @@ function findAndRemoveDirty(sub, dep) {
395
407
  }
396
408
  return void 0;
397
409
  }
398
- const DEFAULT_EQUALS = (a, b) => a === b;
399
- const FALSE_EQUALS = () => false;
400
- const equalsFrom = (equals) => {
401
- if (equals === false) {
402
- return FALSE_EQUALS;
403
- }
404
- return equals ?? DEFAULT_EQUALS;
405
- };
406
410
  const GeneratorResultConstructor = (function* () {
407
411
  })().constructor;
408
412
  function isGeneratorResult(value) {
@@ -591,12 +595,15 @@ class ReactivePromiseImpl {
591
595
  let remaining = len;
592
596
  let rejected = false;
593
597
  const onFulfillAt = (i) => (v) => {
594
- if (rejected) return;
598
+ if (rejected)
599
+ return;
595
600
  results[i] = v;
596
- if (--remaining === 0) p._setValue(results);
601
+ if (--remaining === 0)
602
+ p._setValue(results);
597
603
  };
598
604
  const onReject = (r) => {
599
- if (rejected) return;
605
+ if (rejected)
606
+ return;
600
607
  rejected = true;
601
608
  p._setError(r);
602
609
  };
@@ -609,15 +616,18 @@ class ReactivePromiseImpl {
609
616
  const p = new ReactivePromiseImpl();
610
617
  const arr = arrayFrom(values);
611
618
  const len = arr.length;
612
- if (len === 0) return p;
619
+ if (len === 0)
620
+ return p;
613
621
  let settled2 = false;
614
622
  const onFulfill = (v) => {
615
- if (settled2) return;
623
+ if (settled2)
624
+ return;
616
625
  settled2 = true;
617
626
  p._setValue(v);
618
627
  };
619
628
  const onReject = (r) => {
620
- if (settled2) return;
629
+ if (settled2)
630
+ return;
621
631
  settled2 = true;
622
632
  p._setError(r);
623
633
  };
@@ -638,12 +648,14 @@ class ReactivePromiseImpl {
638
648
  const errors = new Array(len);
639
649
  let fulfilled = false;
640
650
  const onFulfill = (value) => {
641
- if (fulfilled) return;
651
+ if (fulfilled)
652
+ return;
642
653
  fulfilled = true;
643
654
  p._setValue(value);
644
655
  };
645
656
  const onRejectAt = (index) => (reason) => {
646
- if (fulfilled) return;
657
+ if (fulfilled)
658
+ return;
647
659
  errors[index] = reason;
648
660
  if (--pending === 0) {
649
661
  p._setError(new AggregateError(errors, "All promises were rejected in ReactivePromise.any"));
@@ -666,11 +678,13 @@ class ReactivePromiseImpl {
666
678
  let remaining = len;
667
679
  const onFulfillAt = (index) => (value) => {
668
680
  results[index] = { status: "fulfilled", value };
669
- if (--remaining === 0) p._setValue(results);
681
+ if (--remaining === 0)
682
+ p._setValue(results);
670
683
  };
671
684
  const onRejectAt = (index) => (reason) => {
672
685
  results[index] = { status: "rejected", reason };
673
- if (--remaining === 0) p._setValue(results);
686
+ if (--remaining === 0)
687
+ p._setValue(results);
674
688
  };
675
689
  for (let i = 0; i < len; i++) {
676
690
  thenLoop(arr[i], onFulfillAt(i), onRejectAt(i));
@@ -678,7 +692,8 @@ class ReactivePromiseImpl {
678
692
  return p;
679
693
  }
680
694
  static resolve(value) {
681
- if (value instanceof ReactivePromiseImpl) return value;
695
+ if (value instanceof ReactivePromiseImpl)
696
+ return value;
682
697
  return new ReactivePromiseImpl((resolve) => resolve(value));
683
698
  }
684
699
  static reject(reason) {
@@ -689,7 +704,7 @@ class ReactivePromiseImpl {
689
704
  p._equals = DEFAULT_EQUALS;
690
705
  p._initFlags(
691
706
  1
692
- /* Pending */
707
+ /* AsyncFlags.Pending */
693
708
  );
694
709
  const resolve = (value) => {
695
710
  if (value && typeof value.then === "function") {
@@ -708,7 +723,8 @@ class ReactivePromiseImpl {
708
723
  }
709
724
  _consumeFlags(flags) {
710
725
  const currentConsumer = getCurrentConsumer();
711
- if (currentConsumer === void 0) return;
726
+ if (currentConsumer === void 0)
727
+ return;
712
728
  if ((this._flags & 128) !== 0) {
713
729
  this._connect();
714
730
  }
@@ -724,7 +740,7 @@ class ReactivePromiseImpl {
724
740
  const { ref, computedCount, deps } = currentConsumer;
725
741
  const prevEdge = deps.get(signal2);
726
742
  if (prevEdge?.consumedAt !== computedCount) {
727
- const newEdge = createEdge(prevEdge, EdgeType.Signal, signal2, signal2.updatedCount, computedCount);
743
+ const newEdge = createEdge(prevEdge, 0, signal2, signal2.updatedCount, computedCount);
728
744
  signal2.subs.set(ref, newEdge);
729
745
  deps.set(signal2, newEdge);
730
746
  }
@@ -764,7 +780,7 @@ class ReactivePromiseImpl {
764
780
  }
765
781
  this._setFlags(
766
782
  1
767
- /* Pending */
783
+ /* AsyncFlags.Pending */
768
784
  );
769
785
  dirtySignalConsumers(this._awaitSubs);
770
786
  return this._awaitSubs = /* @__PURE__ */ new Map();
@@ -776,10 +792,10 @@ class ReactivePromiseImpl {
776
792
  this._promise = promise;
777
793
  const flags = this._flags;
778
794
  let awaitSubs = this._awaitSubs;
779
- if ((flags & 1) === 0) {
780
- awaitSubs = this._setPending();
781
- }
782
795
  try {
796
+ if ((flags & 1) === 0) {
797
+ awaitSubs = this._setPending();
798
+ }
783
799
  const nextValue = await promise;
784
800
  if (promise !== this._promise) {
785
801
  return;
@@ -856,7 +872,7 @@ class ReactivePromiseImpl {
856
872
  }
857
873
  }
858
874
  _scheduleSubs(awaitSubs, dirty) {
859
- const newState = dirty ? ReactiveFnState.Dirty : ReactiveFnState.PendingDirty;
875
+ const newState = dirty ? 2 : 4;
860
876
  for (const ref of awaitSubs.keys()) {
861
877
  const signal2 = ref.deref();
862
878
  if (signal2 === void 0) {
@@ -869,49 +885,49 @@ class ReactivePromiseImpl {
869
885
  get value() {
870
886
  this._consumeFlags(
871
887
  16
872
- /* Value */
888
+ /* AsyncFlags.Value */
873
889
  );
874
890
  return this._value;
875
891
  }
876
892
  get error() {
877
893
  this._consumeFlags(
878
894
  32
879
- /* Error */
895
+ /* AsyncFlags.Error */
880
896
  );
881
897
  return this._error;
882
898
  }
883
899
  get isPending() {
884
900
  this._consumeFlags(
885
901
  1
886
- /* Pending */
902
+ /* AsyncFlags.Pending */
887
903
  );
888
904
  return (this._flags & 1) !== 0;
889
905
  }
890
906
  get isRejected() {
891
907
  this._consumeFlags(
892
908
  2
893
- /* Rejected */
909
+ /* AsyncFlags.Rejected */
894
910
  );
895
911
  return (this._flags & 2) !== 0;
896
912
  }
897
913
  get isResolved() {
898
914
  this._consumeFlags(
899
915
  4
900
- /* Resolved */
916
+ /* AsyncFlags.Resolved */
901
917
  );
902
918
  return (this._flags & 4) !== 0;
903
919
  }
904
920
  get isReady() {
905
921
  this._consumeFlags(
906
922
  8
907
- /* Ready */
923
+ /* AsyncFlags.Ready */
908
924
  );
909
925
  return (this._flags & 8) !== 0;
910
926
  }
911
927
  get isSettled() {
912
928
  this._consumeFlags(
913
929
  6
914
- /* Settled */
930
+ /* AsyncFlags.Settled */
915
931
  );
916
932
  return (this._flags & 6) !== 0;
917
933
  }
@@ -927,13 +943,7 @@ class ReactivePromiseImpl {
927
943
  }
928
944
  ref = currentConsumer.ref;
929
945
  const prevEdge = this._awaitSubs.get(ref) ?? findAndRemoveDirty(currentConsumer, this);
930
- edge = createEdge(
931
- prevEdge,
932
- EdgeType.Promise,
933
- this,
934
- this._updatedCount,
935
- currentConsumer.computedCount
936
- );
946
+ edge = createEdge(prevEdge, 1, this, this._updatedCount, currentConsumer.computedCount);
937
947
  }
938
948
  const wrappedFulfilled = onfulfilled ? (value) => {
939
949
  try {
@@ -969,16 +979,13 @@ class ReactivePromiseImpl {
969
979
  return this.then(null, onrejected);
970
980
  }
971
981
  finally(onfinally) {
972
- return this.then(
973
- (value) => {
974
- onfinally?.();
975
- return value;
976
- },
977
- (reason) => {
978
- onfinally?.();
979
- throw reason;
980
- }
981
- );
982
+ return this.then((value) => {
983
+ onfinally?.();
984
+ return value;
985
+ }, (reason) => {
986
+ onfinally?.();
987
+ throw reason;
988
+ });
982
989
  }
983
990
  get [Symbol.toStringTag]() {
984
991
  return `ReactivePromise`;
@@ -1000,7 +1007,7 @@ function createPromise(promise, signal2) {
1000
1007
  p["_equals"] = signal2.def.equals;
1001
1008
  p["_initFlags"](
1002
1009
  1
1003
- /* Pending */
1010
+ /* AsyncFlags.Pending */
1004
1011
  );
1005
1012
  p["_setPromise"](promise);
1006
1013
  return p;
@@ -1017,11 +1024,14 @@ function createRelay(activate, scope, opts) {
1017
1024
  }
1018
1025
  const signal2 = p["_signal"];
1019
1026
  signal2.subs = /* @__PURE__ */ new Map();
1020
- signal2._state = ReactiveFnState.Dirty;
1027
+ signal2._state = 2;
1021
1028
  active = false;
1022
1029
  currentSub = void 0;
1023
1030
  };
1024
1031
  const state = {
1032
+ get isPending() {
1033
+ return (p["_flags"] & 1) !== 0;
1034
+ },
1025
1035
  get value() {
1026
1036
  return p["_value"];
1027
1037
  },
@@ -1059,7 +1069,7 @@ function createRelay(activate, scope, opts) {
1059
1069
  p["_equals"] = equalsFrom(opts?.equals);
1060
1070
  p["_initFlags"](
1061
1071
  128 | 1
1062
- /* Pending */
1072
+ /* AsyncFlags.Pending */
1063
1073
  );
1064
1074
  return p;
1065
1075
  }
@@ -1069,9 +1079,13 @@ function createTask(task, scope, opts) {
1069
1079
  p["_equals"] = equalsFrom(opts?.equals);
1070
1080
  p["_initFlags"](
1071
1081
  64
1072
- /* isRunnable */
1082
+ /* AsyncFlags.isRunnable */
1073
1083
  );
1084
+ const throwIfRunning = opts?.throwIfRunning === true;
1074
1085
  p["run"] = ((...args) => {
1086
+ if (throwIfRunning && (p["_flags"] & 1) !== 0) {
1087
+ throw new Error("Task is already running");
1088
+ }
1075
1089
  p._setPromise(fn(...args));
1076
1090
  return p;
1077
1091
  });
@@ -1091,7 +1105,7 @@ function getSignal(signal2) {
1091
1105
  }
1092
1106
  }
1093
1107
  const updatedAt = checkSignal(signal2);
1094
- const newEdge = createEdge(prevEdge, EdgeType.Signal, signal2, updatedAt, computedCount);
1108
+ const newEdge = createEdge(prevEdge, 0, signal2, updatedAt, computedCount);
1095
1109
  signal2.subs.set(ref, newEdge);
1096
1110
  deps.set(signal2, newEdge);
1097
1111
  } else {
@@ -1107,26 +1121,26 @@ function getSignal(signal2) {
1107
1121
  }
1108
1122
  function checkSignal(signal2) {
1109
1123
  const { ref, _state: state } = signal2;
1110
- if (state < ReactiveFnState.Dirty) {
1124
+ if (state < 2) {
1111
1125
  return signal2.updatedCount;
1112
1126
  }
1113
- if (state >= ReactiveFnState.MaybeDirty) {
1127
+ if (state >= 3) {
1114
1128
  let edge = signal2.dirtyHead;
1115
1129
  while (edge !== void 0) {
1116
- if (edge.type === EdgeType.Promise) {
1130
+ if (edge.type === 1) {
1117
1131
  const dep2 = edge.dep;
1118
1132
  if (dep2._getPending()) {
1119
1133
  const value = signal2._value;
1120
1134
  dep2["_awaitSubs"].set(ref, edge);
1121
1135
  value._setPending();
1122
- signal2._state = ReactiveFnState.Pending;
1136
+ signal2._state = 1;
1123
1137
  signal2.dirtyHead = edge;
1124
1138
  return signal2.updatedCount;
1125
1139
  } else if (edge.updatedAt === edge.dep._updatedCount) {
1126
1140
  dep2["_awaitSubs"].set(ref, edge);
1127
1141
  } else {
1128
1142
  signal2.dirtyHead = edge.nextDirty;
1129
- signal2._state = ReactiveFnState.Dirty;
1143
+ signal2._state = 2;
1130
1144
  break;
1131
1145
  }
1132
1146
  edge = edge.nextDirty;
@@ -1137,23 +1151,23 @@ function checkSignal(signal2) {
1137
1151
  dep.subs.set(ref, edge);
1138
1152
  if (edge.updatedAt !== updatedAt) {
1139
1153
  signal2.dirtyHead = edge.nextDirty;
1140
- signal2._state = ReactiveFnState.Dirty;
1154
+ signal2._state = 2;
1141
1155
  break;
1142
1156
  }
1143
1157
  edge = edge.nextDirty;
1144
1158
  }
1145
1159
  }
1146
1160
  const newState = signal2._state;
1147
- if (newState === ReactiveFnState.Dirty) {
1161
+ if (newState === 2) {
1148
1162
  if (signal2._isLazy) {
1149
1163
  signal2.updatedCount++;
1150
1164
  } else {
1151
1165
  runSignal(signal2);
1152
1166
  }
1153
- } else if (newState === ReactiveFnState.PendingDirty) {
1167
+ } else if (newState === 4) {
1154
1168
  signal2._value._clearPending();
1155
1169
  }
1156
- signal2._state = ReactiveFnState.Clean;
1170
+ signal2._state = 0;
1157
1171
  signal2.dirtyHead = void 0;
1158
1172
  return signal2.updatedCount;
1159
1173
  }
@@ -1322,56 +1336,56 @@ function hashDate(date, _seen) {
1322
1336
  return hashNumber(
1323
1337
  date.getTime(),
1324
1338
  14
1325
- /* DATE */
1339
+ /* HashType.DATE */
1326
1340
  );
1327
1341
  }
1328
1342
  function hashRegExp(regexp, _seen) {
1329
1343
  const h = hashStr(
1330
1344
  regexp.source + regexp.flags,
1331
1345
  15
1332
- /* REGEXP */
1346
+ /* HashType.REGEXP */
1333
1347
  );
1334
1348
  return (h ^ regexp.lastIndex) >>> 0;
1335
1349
  }
1336
1350
  const UNDEFINED = hashStr(
1337
1351
  "undefined",
1338
1352
  0
1339
- /* UNDEFINED */
1353
+ /* HashType.UNDEFINED */
1340
1354
  );
1341
1355
  const NULL = hashStr(
1342
1356
  "null",
1343
1357
  1
1344
- /* NULL */
1358
+ /* HashType.NULL */
1345
1359
  );
1346
1360
  const TRUE = hashStr(
1347
1361
  "true",
1348
1362
  2
1349
- /* TRUE */
1363
+ /* HashType.TRUE */
1350
1364
  );
1351
1365
  const FALSE = hashStr(
1352
1366
  "false",
1353
1367
  3
1354
- /* FALSE */
1368
+ /* HashType.FALSE */
1355
1369
  );
1356
1370
  const ARRAY = hashStr(
1357
1371
  "array",
1358
1372
  7
1359
- /* ARRAY */
1373
+ /* HashType.ARRAY */
1360
1374
  );
1361
1375
  const OBJECT = hashStr(
1362
1376
  "object",
1363
1377
  8
1364
- /* OBJECT */
1378
+ /* HashType.OBJECT */
1365
1379
  );
1366
1380
  const SET = hashStr(
1367
1381
  "set",
1368
1382
  13
1369
- /* SET */
1383
+ /* HashType.SET */
1370
1384
  );
1371
1385
  const MAP = hashStr(
1372
1386
  "map",
1373
1387
  12
1374
- /* MAP */
1388
+ /* HashType.MAP */
1375
1389
  );
1376
1390
  const getObjectProto = Object.getPrototypeOf;
1377
1391
  const PROTO_TO_HASH = /* @__PURE__ */ new Map([
@@ -1395,19 +1409,19 @@ function hashValue(node, seen = []) {
1395
1409
  return hashStr(
1396
1410
  String(node),
1397
1411
  4
1398
- /* NUMBER */
1412
+ /* HashType.NUMBER */
1399
1413
  );
1400
1414
  case "string":
1401
1415
  return hashStr(
1402
1416
  node,
1403
1417
  5
1404
- /* STRING */
1418
+ /* HashType.STRING */
1405
1419
  );
1406
1420
  case "bigint":
1407
1421
  return hashStr(
1408
1422
  node.toString(),
1409
1423
  6
1410
- /* BIGINT */
1424
+ /* HashType.BIGINT */
1411
1425
  );
1412
1426
  case "object": {
1413
1427
  if (node === null) {
@@ -1418,7 +1432,7 @@ function hashValue(node, seen = []) {
1418
1432
  return hashStr(
1419
1433
  String(index),
1420
1434
  11
1421
- /* CYCLE */
1435
+ /* HashType.CYCLE */
1422
1436
  );
1423
1437
  }
1424
1438
  const hashFn = PROTO_TO_HASH.get(getObjectProto(node));
@@ -1436,7 +1450,7 @@ function hashValue(node, seen = []) {
1436
1450
  return hashStr(
1437
1451
  node.toString(),
1438
1452
  10
1439
- /* SYMBOL */
1453
+ /* HashType.SYMBOL */
1440
1454
  );
1441
1455
  }
1442
1456
  }
@@ -1448,7 +1462,7 @@ function getObjectHash(obj) {
1448
1462
  id = hashNumber(
1449
1463
  nextHashMapId++,
1450
1464
  9
1451
- /* REFERENCE */
1465
+ /* HashType.REFERENCE */
1452
1466
  );
1453
1467
  objectToHashMap.set(obj, id);
1454
1468
  }
@@ -1465,25 +1479,16 @@ function hashReactiveFn(fn, args) {
1465
1479
  h = h << 13 | h >>> 19;
1466
1480
  return imul(h, 5) + 3864292196 >>> 0;
1467
1481
  }
1468
- var ReactiveFnState = /* @__PURE__ */ ((ReactiveFnState2) => {
1469
- ReactiveFnState2[ReactiveFnState2["Clean"] = 0] = "Clean";
1470
- ReactiveFnState2[ReactiveFnState2["Pending"] = 1] = "Pending";
1471
- ReactiveFnState2[ReactiveFnState2["Dirty"] = 2] = "Dirty";
1472
- ReactiveFnState2[ReactiveFnState2["MaybeDirty"] = 3] = "MaybeDirty";
1473
- ReactiveFnState2[ReactiveFnState2["PendingDirty"] = 4] = "PendingDirty";
1474
- return ReactiveFnState2;
1475
- })(ReactiveFnState || {});
1476
1482
  let ID = 0;
1477
1483
  function createReactiveDefinition(id, desc, compute, equals, isRelay2, paramKey, tracer) {
1478
- return {
1479
- id,
1480
- desc,
1484
+ const def = {
1481
1485
  compute,
1482
1486
  equals: equalsFrom(equals),
1483
1487
  isRelay: isRelay2,
1484
1488
  paramKey,
1485
- tracer
1489
+ tracer: void 0
1486
1490
  };
1491
+ return def;
1487
1492
  }
1488
1493
  class ReactiveSignal {
1489
1494
  // Bitmask containing state in the first 2 bits and boolean properties in the remaining bits
@@ -1552,22 +1557,33 @@ class ReactiveSignal {
1552
1557
  get listeners() {
1553
1558
  return this._listeners ?? (this._listeners = {
1554
1559
  updatedAt: 0,
1555
- current: /* @__PURE__ */ new Set(),
1560
+ current: /* @__PURE__ */ new Map(),
1556
1561
  cachedBoundAdd: this.addListener.bind(this)
1557
1562
  });
1558
1563
  }
1559
1564
  get value() {
1560
1565
  return getSignal(this);
1561
1566
  }
1562
- addListener(listener) {
1567
+ addListener(listener, opts) {
1563
1568
  const { current } = this.listeners;
1564
1569
  if (!current.has(listener)) {
1570
+ let effective = listener;
1571
+ if (opts?.skipInitial) {
1572
+ let initial = true;
1573
+ effective = () => {
1574
+ if (initial) {
1575
+ initial = false;
1576
+ return;
1577
+ }
1578
+ listener();
1579
+ };
1580
+ }
1565
1581
  if (!this._isListener) {
1566
1582
  watchSignal(this, this._isSuspended);
1567
1583
  this.flags |= 16;
1568
1584
  }
1569
1585
  schedulePull(this);
1570
- current.add(listener);
1586
+ current.set(listener, effective);
1571
1587
  }
1572
1588
  return () => {
1573
1589
  if (current.has(listener)) {
@@ -1576,6 +1592,7 @@ class ReactiveSignal {
1576
1592
  cancelPull(this);
1577
1593
  unwatchSignal(this, this._isSuspended);
1578
1594
  this.flags &= -17;
1595
+ this.listeners.updatedAt = 0;
1579
1596
  }
1580
1597
  }
1581
1598
  };
@@ -1623,7 +1640,7 @@ const runListeners = (signal2) => {
1623
1640
  return;
1624
1641
  }
1625
1642
  const { current } = listeners;
1626
- for (const listener of current) {
1643
+ for (const listener of current.values()) {
1627
1644
  listener();
1628
1645
  }
1629
1646
  };
@@ -1635,13 +1652,14 @@ function createReactiveSignal(def, args = [], key, scope) {
1635
1652
  }
1636
1653
  let CONTEXT_ID = 0;
1637
1654
  class ContextImpl {
1655
+ defaultValue;
1656
+ _key;
1657
+ _description;
1638
1658
  constructor(defaultValue, desc) {
1639
1659
  this.defaultValue = defaultValue;
1640
1660
  this._description = desc ?? `context:${CONTEXT_ID++}`;
1641
1661
  this._key = Symbol(this._description);
1642
1662
  }
1643
- _key;
1644
- _description;
1645
1663
  }
1646
1664
  const context = (initialValue, description) => {
1647
1665
  return new ContextImpl(initialValue, description);
@@ -1659,9 +1677,7 @@ function withContexts(contexts, fn) {
1659
1677
  const getContext = (context2) => {
1660
1678
  const scope = CURRENT_SCOPE ?? getCurrentConsumer()?.scope;
1661
1679
  if (scope === void 0) {
1662
- throw new Error(
1663
- "getContext must be used within a reactive function, a withContext, or within a framework-specific context provider."
1664
- );
1680
+ throw new Error("getContext must be used within a reactive function, a withContext, or within a framework-specific context provider.");
1665
1681
  }
1666
1682
  return scope.getContext(context2) ?? context2.defaultValue;
1667
1683
  };
@@ -1792,9 +1808,9 @@ export {
1792
1808
  getCurrentConsumer as f,
1793
1809
  getCurrentScope as g,
1794
1810
  getGlobalScope as h,
1795
- hashValue as i,
1796
- signal as j,
1797
- isReactivePromise as k,
1811
+ isReactivePromise as i,
1812
+ hashValue as j,
1813
+ signal as k,
1798
1814
  isRelay$1 as l,
1799
1815
  getSignal as m,
1800
1816
  isPromise as n,
@@ -1811,4 +1827,4 @@ export {
1811
1827
  getContext as y,
1812
1828
  withContexts as z
1813
1829
  };
1814
- //# sourceMappingURL=contexts-Dj9Y86xW.js.map
1830
+ //# sourceMappingURL=contexts-X0gSj6rQ.js.map