signalium 2.1.7 → 2.2.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.
Files changed (69) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/cjs/development/{core-api-C3NaxanI.js → core-api-BLfPllpC.js} +2 -2
  3. package/dist/cjs/development/core-api-BLfPllpC.js.map +1 -0
  4. package/dist/cjs/development/{debug-CjBhOupU.js → debug-C4VkJKKv.js} +173 -49
  5. package/dist/cjs/development/debug-C4VkJKKv.js.map +1 -0
  6. package/dist/cjs/development/debug.js +1 -1
  7. package/dist/cjs/development/index.js +3 -2
  8. package/dist/cjs/development/index.js.map +1 -1
  9. package/dist/cjs/development/react/index.js +8 -8
  10. package/dist/cjs/development/react/index.js.map +1 -1
  11. package/dist/cjs/development/utils.js +6 -6
  12. package/dist/cjs/development/utils.js.map +1 -1
  13. package/dist/cjs/production/{contexts-BTZGnOKa.js → contexts-D9PmMMc5.js} +173 -49
  14. package/dist/cjs/production/contexts-D9PmMMc5.js.map +1 -0
  15. package/dist/cjs/production/{core-api-B_CAhQeH.js → core-api-nNbd4L7C.js} +2 -2
  16. package/dist/cjs/production/core-api-nNbd4L7C.js.map +1 -0
  17. package/dist/cjs/production/debug.js +1 -1
  18. package/dist/cjs/production/index.js +3 -2
  19. package/dist/cjs/production/index.js.map +1 -1
  20. package/dist/cjs/production/react/index.js +8 -8
  21. package/dist/cjs/production/react/index.js.map +1 -1
  22. package/dist/cjs/production/utils.js +6 -6
  23. package/dist/cjs/production/utils.js.map +1 -1
  24. package/dist/esm/development/{core-api-DUouSDpe.js → core-api-BKTJuFkJ.js} +2 -2
  25. package/dist/esm/development/core-api-BKTJuFkJ.js.map +1 -0
  26. package/dist/esm/development/{debug-DeCeAOHQ.js → debug-qm_Izoi_.js} +187 -63
  27. package/dist/esm/development/debug-qm_Izoi_.js.map +1 -0
  28. package/dist/esm/development/debug.js +9 -9
  29. package/dist/esm/development/index.js +9 -8
  30. package/dist/esm/development/react/index.js +9 -9
  31. package/dist/esm/development/react/index.js.map +1 -1
  32. package/dist/esm/development/utils.js +7 -7
  33. package/dist/esm/development/utils.js.map +1 -1
  34. package/dist/esm/index.d.ts +1 -0
  35. package/dist/esm/index.d.ts.map +1 -1
  36. package/dist/esm/internals/async.d.ts +1 -0
  37. package/dist/esm/internals/async.d.ts.map +1 -1
  38. package/dist/esm/internals/contexts.d.ts.map +1 -1
  39. package/dist/esm/internals/reactive.d.ts +10 -2
  40. package/dist/esm/internals/reactive.d.ts.map +1 -1
  41. package/dist/esm/internals/scheduling.d.ts +5 -1
  42. package/dist/esm/internals/scheduling.d.ts.map +1 -1
  43. package/dist/esm/internals/watch.d.ts +5 -2
  44. package/dist/esm/internals/watch.d.ts.map +1 -1
  45. package/dist/esm/production/{contexts-Bg501Zo9.js → contexts-BLI-Vgt4.js} +179 -55
  46. package/dist/esm/production/contexts-BLI-Vgt4.js.map +1 -0
  47. package/dist/esm/production/{core-api-dRINtUzf.js → core-api-Ckj2uqeX.js} +2 -2
  48. package/dist/esm/production/core-api-Ckj2uqeX.js.map +1 -0
  49. package/dist/esm/production/debug.js +1 -1
  50. package/dist/esm/production/index.js +9 -8
  51. package/dist/esm/production/react/index.js +9 -9
  52. package/dist/esm/production/react/index.js.map +1 -1
  53. package/dist/esm/production/utils.js +7 -7
  54. package/dist/esm/production/utils.js.map +1 -1
  55. package/dist/esm/react/component.d.ts.map +1 -1
  56. package/dist/esm/react/index.d.ts +1 -0
  57. package/dist/esm/react/index.d.ts.map +1 -1
  58. package/dist/esm/react/use-reactive.d.ts.map +1 -1
  59. package/dist/esm/types.d.ts +1 -0
  60. package/dist/esm/types.d.ts.map +1 -1
  61. package/package.json +1 -1
  62. package/dist/cjs/development/core-api-C3NaxanI.js.map +0 -1
  63. package/dist/cjs/development/debug-CjBhOupU.js.map +0 -1
  64. package/dist/cjs/production/contexts-BTZGnOKa.js.map +0 -1
  65. package/dist/cjs/production/core-api-B_CAhQeH.js.map +0 -1
  66. package/dist/esm/development/core-api-DUouSDpe.js.map +0 -1
  67. package/dist/esm/development/debug-DeCeAOHQ.js.map +0 -1
  68. package/dist/esm/production/contexts-Bg501Zo9.js.map +0 -1
  69. package/dist/esm/production/core-api-dRINtUzf.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # signalium
2
2
 
3
+ ## 2.2.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 5378406: Fix async and add chaos tests
8
+
9
+ ## 2.2.0
10
+
11
+ ### Minor Changes
12
+
13
+ - 0b6b650: Add setSuspended API for more explicit suspension support
14
+
3
15
  ## 2.1.7
4
16
 
5
17
  ### Patch Changes
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- const debug = require("./debug-CjBhOupU.js");
2
+ const debug = require("./debug-C4VkJKKv.js");
3
3
  const DERIVED_DEFINITION_MAP = /* @__PURE__ */ new Map();
4
4
  function getReactiveFnAndDefinition(fn, opts) {
5
5
  let fnAndDef = DERIVED_DEFINITION_MAP.get(fn);
@@ -52,4 +52,4 @@ exports.reactiveSignal = reactiveSignal;
52
52
  exports.relay = relay;
53
53
  exports.task = task;
54
54
  exports.watcher = watcher;
55
- //# sourceMappingURL=core-api-C3NaxanI.js.map
55
+ //# sourceMappingURL=core-api-BLfPllpC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core-api-BLfPllpC.js","sources":["../../../src/internals/core-api.ts"],"sourcesContent":["import {\n ReactiveTask,\n ReactiveValue,\n Watcher,\n ReactiveOptions,\n RelayActivate,\n type DiscriminatedReactivePromise,\n SignalOptions,\n ReactiveFn,\n ReadonlySignal,\n} from '../types.js';\nimport { getCurrentScope, getScopeOwner, SignalScope } from './contexts.js';\nimport {\n createReactiveDefinition,\n createReactiveSignal,\n ReactiveDefinition as ReactiveDefinition,\n} from './reactive.js';\nimport { createRelay, createTask } from './async.js';\nimport { Tracer } from './trace.js';\n\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nexport const DERIVED_DEFINITION_MAP = new Map<Function, [(...args: any) => any, ReactiveDefinition<any, any>]>();\n\nexport function getReactiveFnAndDefinition<T, Args extends unknown[]>(\n fn: (...args: Args) => T,\n opts?: ReactiveOptions<T, Args>,\n): [(...args: Args) => ReactiveValue<T>, ReactiveDefinition<T, Args>] {\n let fnAndDef = DERIVED_DEFINITION_MAP.get(fn);\n\n if (!fnAndDef) {\n const def = createReactiveDefinition(opts?.id, opts?.desc, fn, opts?.equals, false, opts?.paramKey, undefined);\n\n const defScope = getCurrentScope();\n\n const reactiveFn: ReactiveFn<T, Args> = (...args) => {\n const scope = getCurrentScope(defScope);\n const signal = scope.get(def, args as any);\n\n return signal.value;\n };\n\n fnAndDef = [reactiveFn, def];\n\n DERIVED_DEFINITION_MAP.set(fn, fnAndDef);\n }\n\n return fnAndDef;\n}\n\nexport function reactive<T, Args extends unknown[]>(\n fn: (...args: Args) => T,\n opts?: ReactiveOptions<T, Args>,\n): ReactiveFn<T, Args> {\n return getReactiveFnAndDefinition(fn, opts)[0];\n}\n\nexport const reactiveMethod = <T, Args extends unknown[]>(\n owner: object,\n fn: (...args: Args) => T,\n opts?: ReactiveOptions<T, Args>,\n): ReactiveFn<T, Args> => {\n const def = createReactiveDefinition(opts?.id, opts?.desc, fn, opts?.equals, false, opts?.paramKey, undefined);\n\n const reactiveFn: ReactiveFn<T, Args> = (...args) => {\n return getScopeOwner(owner).get(def, args as any).value;\n };\n\n DERIVED_DEFINITION_MAP.set(reactiveFn, [reactiveFn, def]);\n\n return reactiveFn;\n};\n\nexport function relay<T>(activate: RelayActivate<T>, opts?: SignalOptions<T>): DiscriminatedReactivePromise<T> {\n const scope = getCurrentScope();\n\n return createRelay(activate, scope, opts) as DiscriminatedReactivePromise<T>;\n}\n\nexport const task = <T, Args extends unknown[]>(\n fn: (...args: Args) => Promise<T>,\n opts?: SignalOptions<T>,\n): ReactiveTask<T, Args> => {\n const scope = getCurrentScope();\n\n return createTask(fn, scope, opts);\n};\n\nexport function watcher<T>(fn: () => T, opts?: SignalOptions<T> & { isolate?: boolean; tracer?: Tracer }): Watcher<T> {\n const def = createReactiveDefinition(opts?.id, opts?.desc, fn, opts?.equals, false, undefined, opts?.tracer);\n\n const scope = opts?.isolate ? new SignalScope([]) : getCurrentScope();\n\n return createReactiveSignal(def, undefined, undefined, scope);\n}\n\n/**\n * Creates a reactive signal from a compute function. This is useful for when you\n * want to create a signal that does not receive parameters, but is still reactive.\n *\n * @param compute\n * @param opts\n * @returns\n */\nexport const reactiveSignal = <T>(\n compute: () => T,\n opts?: SignalOptions<T> & { isolate?: boolean },\n): ReadonlySignal<T> => {\n const def = createReactiveDefinition(opts?.id, opts?.desc, compute, opts?.equals, false, undefined, undefined);\n\n const scope = opts?.isolate ? new SignalScope([]) : getCurrentScope();\n\n return createReactiveSignal(def, undefined, undefined, scope);\n};\n"],"names":["createReactiveDefinition","getCurrentScope","getScopeOwner","createRelay","createTask","SignalScope","createReactiveSignal"],"mappings":";;AAqBO,MAAM,6CAA6B,IAAA;AAEnC,SAAS,2BACd,IACA,MACoE;AACpE,MAAI,WAAW,uBAAuB,IAAI,EAAE;AAE5C,MAAI,CAAC,UAAU;AACb,UAAM,MAAMA,MAAAA,yBAAyB,MAAM,IAAI,MAAM,MAAM,IAAI,MAAM,QAAQ,OAAO,MAAM,UAAU,MAAS;AAE7G,UAAM,WAAWC,MAAAA,gBAAA;AAEjB,UAAM,aAAkC,IAAI,SAAS;AACnD,YAAM,QAAQA,MAAAA,gBAAgB,QAAQ;AACtC,YAAM,SAAS,MAAM,IAAI,KAAK,IAAW;AAEzC,aAAO,OAAO;AAAA,IAChB;AAEA,eAAW,CAAC,YAAY,GAAG;AAE3B,2BAAuB,IAAI,IAAI,QAAQ;AAAA,EACzC;AAEA,SAAO;AACT;AAEO,SAAS,SACd,IACA,MACqB;AACrB,SAAO,2BAA2B,IAAI,IAAI,EAAE,CAAC;AAC/C;AAEO,MAAM,iBAAiB,CAC5B,OACA,IACA,SACwB;AACxB,QAAM,MAAMD,MAAAA,yBAAyB,MAAM,IAAI,MAAM,MAAM,IAAI,MAAM,QAAQ,OAAO,MAAM,UAAU,MAAS;AAE7G,QAAM,aAAkC,IAAI,SAAS;AACnD,WAAOE,MAAAA,cAAc,KAAK,EAAE,IAAI,KAAK,IAAW,EAAE;AAAA,EACpD;AAEA,yBAAuB,IAAI,YAAY,CAAC,YAAY,GAAG,CAAC;AAExD,SAAO;AACT;AAEO,SAAS,MAAS,UAA4B,MAA0D;AAC7G,QAAM,QAAQD,MAAAA,gBAAA;AAEd,SAAOE,kBAAY,UAAU,OAAO,IAAI;AAC1C;AAEO,MAAM,OAAO,CAClB,IACA,SAC0B;AAC1B,QAAM,QAAQF,MAAAA,gBAAA;AAEd,SAAOG,iBAAW,IAAI,OAAO,IAAI;AACnC;AAEO,SAAS,QAAW,IAAa,MAA8E;AACpH,QAAM,MAAMJ,MAAAA,yBAAyB,MAAM,IAAI,MAAM,MAAM,IAAI,MAAM,QAAQ,OAAO,QAAW,MAAM,MAAM;AAE3G,QAAM,QAAQ,MAAM,UAAU,IAAIK,MAAAA,YAAY,CAAA,CAAE,IAAIJ,sBAAA;AAEpD,SAAOK,MAAAA,qBAAqB,KAAK,QAAW,QAAW,KAAK;AAC9D;AAUO,MAAM,iBAAiB,CAC5B,SACA,SACsB;AACtB,QAAM,MAAMN,MAAAA,yBAAyB,MAAM,IAAI,MAAM,MAAM,SAAS,MAAM,QAAQ,OAAO,QAAW,MAAS;AAE7G,QAAM,QAAQ,MAAM,UAAU,IAAIK,MAAAA,YAAY,CAAA,CAAE,IAAIJ,sBAAA;AAEpD,SAAOK,MAAAA,qBAAqB,KAAK,QAAW,QAAW,KAAK;AAC9D;;;;;;;;"}
@@ -414,40 +414,121 @@ function signal(initialValue, opts) {
414
414
  const notifier = (opts) => {
415
415
  return new StateSignal(void 0, FALSE_EQUALS$1, opts?.desc);
416
416
  };
417
- function watchSignal(signal2) {
417
+ function watchSignal(signal2, parentIsSuspended) {
418
+ if (parentIsSuspended) {
419
+ watchSuspendedSignal(signal2);
420
+ } else {
421
+ watchActiveSignal(signal2);
422
+ }
423
+ }
424
+ function unwatchSignal(signal2, parentIsSuspended) {
425
+ if (parentIsSuspended) {
426
+ unwatchSuspendedSignal(signal2);
427
+ } else {
428
+ unwatchActiveSignal(signal2);
429
+ }
430
+ }
431
+ function watchActiveSignal(signal2) {
418
432
  const { watchCount } = signal2;
419
433
  const newWatchCount = watchCount + 1;
420
434
  signal2.watchCount = newWatchCount;
421
- if (watchCount > 0) return;
422
- signal2.scope?.removeFromGc(signal2);
423
- for (const dep of signal2.deps.keys()) {
424
- watchSignal(dep);
435
+ if (signal2._isActive) {
436
+ return;
425
437
  }
426
- if (isRelay(signal2)) {
427
- checkSignal(signal2);
438
+ for (const dep of signal2.deps.keys()) {
439
+ watchActiveSignal(dep);
428
440
  }
441
+ activateSignal(signal2);
429
442
  }
430
- function unwatchSignal(signal2, count = 1) {
443
+ function unwatchActiveSignal(signal2) {
431
444
  const { watchCount } = signal2;
432
- const newWatchCount = Math.max(watchCount - count, 0);
445
+ const newWatchCount = Math.max(watchCount - 1, 0);
433
446
  signal2.watchCount = newWatchCount;
434
- if (newWatchCount > 0) {
435
- return;
447
+ if (newWatchCount === 0) {
448
+ scheduleDeactivate(signal2);
449
+ }
450
+ }
451
+ function watchSuspendedSignal(signal2) {
452
+ const { watchCount, suspendCount } = signal2;
453
+ const newWatchCount = watchCount + 1;
454
+ const newSuspendCount = suspendCount + 1;
455
+ signal2.watchCount = newWatchCount;
456
+ signal2.suspendCount = newSuspendCount;
457
+ signal2.scope?.removeFromGc(signal2);
458
+ cancelDeactivate(signal2);
459
+ if (watchCount === 0) {
460
+ for (const dep of signal2.deps.keys()) {
461
+ watchSuspendedSignal(dep);
462
+ }
463
+ }
464
+ }
465
+ function unwatchSuspendedSignal(signal2) {
466
+ const { watchCount, suspendCount } = signal2;
467
+ const newWatchCount = Math.max(watchCount - 1, 0);
468
+ const newSuspendCount = Math.max(suspendCount - 1, 0);
469
+ signal2.watchCount = newWatchCount;
470
+ signal2.suspendCount = newSuspendCount;
471
+ if (newWatchCount === 0) {
472
+ scheduleDeactivate(signal2);
473
+ }
474
+ }
475
+ function resumeSignal(signal2) {
476
+ const { watchCount, suspendCount } = signal2;
477
+ const newSuspendCount = Math.max(suspendCount - 1, 0);
478
+ signal2.suspendCount = newSuspendCount;
479
+ if (watchCount > 0 && !signal2._isActive) {
480
+ for (const dep of signal2.deps.keys()) {
481
+ resumeSignal(dep);
482
+ }
483
+ activateSignal(signal2);
484
+ }
485
+ }
486
+ function suspendSignal(signal2) {
487
+ const { watchCount, suspendCount } = signal2;
488
+ const newSuspendCount = suspendCount + 1;
489
+ signal2.suspendCount = newSuspendCount;
490
+ if (watchCount > 0 && newSuspendCount === watchCount) {
491
+ scheduleDeactivate(signal2);
492
+ }
493
+ }
494
+ function activateSignal(signal2) {
495
+ signal2.scope?.removeFromGc(signal2);
496
+ cancelDeactivate(signal2);
497
+ signal2._isActive = true;
498
+ if (isRelay(signal2)) {
499
+ checkSignal(signal2);
436
500
  }
501
+ }
502
+ function deactivateSignal(signal2) {
503
+ const { watchCount, suspendCount } = signal2;
504
+ signal2._isActive = false;
505
+ const isSuspending = watchCount > 0 && suspendCount === watchCount;
437
506
  for (const dep of signal2.deps.keys()) {
438
- unwatchSignal(dep);
507
+ const { watchCount: depWatchCount, suspendCount: depSuspendCount } = dep;
508
+ if (isSuspending) {
509
+ const newSuspendCount = dep.suspendCount = depSuspendCount + 1;
510
+ if (newSuspendCount === depWatchCount) {
511
+ deactivateSignal(dep);
512
+ }
513
+ } else {
514
+ const newWatchCount = dep.watchCount = depWatchCount - 1;
515
+ if (newWatchCount === 0) {
516
+ deactivateSignal(dep);
517
+ }
518
+ }
439
519
  }
440
520
  if (isRelay(signal2)) {
441
521
  signal2._value?.();
442
522
  }
443
- if (newWatchCount === 0 && signal2.scope) {
444
- signal2.scope.markForGc(signal2);
523
+ if (watchCount === 0) {
524
+ signal2.scope?.markForGc(signal2);
525
+ signal2.reset();
445
526
  }
446
527
  }
447
528
  const scheduleIdleCallback = typeof requestIdleCallback === "function" ? requestIdleCallback : (cb) => config.scheduleFlush(cb);
448
529
  let PENDING_PULLS = /* @__PURE__ */ new Set();
449
530
  let PENDING_ASYNC_PULLS = [];
450
- let PENDING_UNWATCH = /* @__PURE__ */ new Map();
531
+ let PENDING_DEACTIVE = /* @__PURE__ */ new Set();
451
532
  let PENDING_LISTENERS = [];
452
533
  let PENDING_TRACERS = [];
453
534
  let PENDING_GC = /* @__PURE__ */ new Set();
@@ -471,11 +552,13 @@ const scheduleAsyncPull = (signal2) => {
471
552
  PENDING_ASYNC_PULLS.push(signal2);
472
553
  scheduleFlush();
473
554
  };
474
- const scheduleUnwatch = (unwatch) => {
475
- const current = PENDING_UNWATCH.get(unwatch) ?? 0;
476
- PENDING_UNWATCH.set(unwatch, current + 1);
555
+ const scheduleDeactivate = (signal2) => {
556
+ PENDING_DEACTIVE.add(signal2);
477
557
  scheduleFlush();
478
558
  };
559
+ const cancelDeactivate = (signal2) => {
560
+ PENDING_DEACTIVE.delete(signal2);
561
+ };
479
562
  const scheduleListeners = (signal2) => {
480
563
  PENDING_LISTENERS.push(signal2);
481
564
  scheduleFlush();
@@ -513,9 +596,10 @@ const flushWatchers = async () => {
513
596
  }
514
597
  currentFlush = null;
515
598
  config.runBatch(() => {
516
- for (const [signal2, count] of PENDING_UNWATCH) {
517
- unwatchSignal(signal2, count);
599
+ for (const signal2 of PENDING_DEACTIVE) {
600
+ deactivateSignal(signal2);
518
601
  }
602
+ PENDING_DEACTIVE.clear();
519
603
  for (const signal2 of PENDING_LISTENERS) {
520
604
  if (signal2 instanceof ReactiveSignal) {
521
605
  runListeners(signal2);
@@ -529,11 +613,15 @@ const flushWatchers = async () => {
529
613
  }
530
614
  PENDING_TRACERS = [];
531
615
  }
532
- PENDING_UNWATCH.clear();
533
616
  PENDING_LISTENERS = [];
534
617
  });
535
618
  flush.resolve();
536
619
  };
620
+ const settled = async () => {
621
+ while (currentFlush) {
622
+ await currentFlush.promise;
623
+ }
624
+ };
537
625
  function dirtySignal(signal2) {
538
626
  const prevState = signal2._state;
539
627
  if (prevState === ReactiveFnState.Dirty) {
@@ -555,7 +643,7 @@ function propagateDirty(signal2) {
555
643
  scheduleAsyncPull(signal2);
556
644
  }
557
645
  } else {
558
- if (signal2._isListener) {
646
+ if (signal2._isListener && !signal2._isSuspendedListener) {
559
647
  schedulePull(signal2);
560
648
  }
561
649
  dirtySignalConsumers(signal2.subs);
@@ -861,15 +949,15 @@ class ReactivePromiseImpl {
861
949
  const arr = arrayFrom(values);
862
950
  const len = arr.length;
863
951
  if (len === 0) return p;
864
- let settled = false;
952
+ let settled2 = false;
865
953
  const onFulfill = (v) => {
866
- if (settled) return;
867
- settled = true;
954
+ if (settled2) return;
955
+ settled2 = true;
868
956
  p._setValue(v);
869
957
  };
870
958
  const onReject = (r) => {
871
- if (settled) return;
872
- settled = true;
959
+ if (settled2) return;
960
+ settled2 = true;
873
961
  p._setError(r);
874
962
  };
875
963
  for (let i = 0; i < len; i++) {
@@ -1032,8 +1120,11 @@ class ReactivePromiseImpl {
1032
1120
  }
1033
1121
  }
1034
1122
  }
1123
+ _getPending() {
1124
+ return (this._flags & 1) !== 0;
1125
+ }
1035
1126
  _setPending() {
1036
- if ((this._flags & 1) !== 0) {
1127
+ if (this._getPending()) {
1037
1128
  return this._awaitSubs;
1038
1129
  }
1039
1130
  this._setFlags(
@@ -1044,11 +1135,7 @@ class ReactivePromiseImpl {
1044
1135
  return this._awaitSubs = /* @__PURE__ */ new Map();
1045
1136
  }
1046
1137
  _clearPending() {
1047
- this._setFlags(
1048
- 0,
1049
- 1
1050
- /* Pending */
1051
- );
1138
+ this._setValue(this._value);
1052
1139
  }
1053
1140
  async _setPromise(promise) {
1054
1141
  this._promise = promise;
@@ -1296,7 +1383,6 @@ function createRelay(activate, scope, opts) {
1296
1383
  const signal2 = p["_signal"];
1297
1384
  signal2.subs = /* @__PURE__ */ new Map();
1298
1385
  signal2._state = ReactiveFnState.Dirty;
1299
- signal2.watchCount = 0;
1300
1386
  active = false;
1301
1387
  currentSub = void 0;
1302
1388
  };
@@ -1376,7 +1462,7 @@ function getSignal(signal2) {
1376
1462
  });
1377
1463
  }
1378
1464
  if (currentConsumer.watchCount > 0) {
1379
- watchSignal(signal2);
1465
+ watchSignal(signal2, currentConsumer._isSuspended);
1380
1466
  }
1381
1467
  }
1382
1468
  const updatedAt = checkSignal(signal2);
@@ -1404,7 +1490,7 @@ function checkSignal(signal2) {
1404
1490
  while (edge !== void 0) {
1405
1491
  if (edge.type === EdgeType.Promise) {
1406
1492
  const dep2 = edge.dep;
1407
- if (dep2.isPending) {
1493
+ if (dep2._getPending()) {
1408
1494
  const value = signal2._value;
1409
1495
  dep2["_awaitSubs"].set(ref, edge);
1410
1496
  value._setPending();
@@ -1501,10 +1587,10 @@ function runSignal(signal2) {
1501
1587
  }
1502
1588
  }
1503
1589
  function disconnectSignal(signal2, computedCount = signal2.computedCount) {
1504
- const { ref, deps } = signal2;
1590
+ const { ref, deps, _isSuspended: isSuspended } = signal2;
1505
1591
  for (const [dep, edge] of deps) {
1506
1592
  if (edge.consumedAt !== computedCount) {
1507
- scheduleUnwatch(dep);
1593
+ unwatchSignal(dep, isSuspended);
1508
1594
  dep.subs.delete(ref);
1509
1595
  deps.delete(dep);
1510
1596
  }
@@ -1844,6 +1930,7 @@ class ReactiveSignal {
1844
1930
  updatedCount = 0;
1845
1931
  computedCount = 0;
1846
1932
  watchCount = 0;
1933
+ suspendCount = 0;
1847
1934
  key;
1848
1935
  args;
1849
1936
  callbacks = void 0;
@@ -1876,21 +1963,31 @@ class ReactiveSignal {
1876
1963
  get _isListener() {
1877
1964
  return (this.flags & 16) !== 0;
1878
1965
  }
1879
- set _isListener(isListener) {
1880
- if (isListener) {
1881
- this.flags |= 16;
1966
+ get _isSuspendedListener() {
1967
+ return (this.flags & 32) !== 0;
1968
+ }
1969
+ get _isSuspended() {
1970
+ const { watchCount, suspendCount } = this;
1971
+ return watchCount > 0 && watchCount === suspendCount;
1972
+ }
1973
+ get _isActive() {
1974
+ return (this.flags & 64) !== 0;
1975
+ }
1976
+ set _isActive(isActive) {
1977
+ if (isActive) {
1978
+ this.flags |= 64;
1882
1979
  } else {
1883
- this.flags &= -17;
1980
+ this.flags &= -65;
1884
1981
  }
1885
1982
  }
1886
1983
  get _isLazy() {
1887
- return (this.flags & 32) !== 0;
1984
+ return (this.flags & 128) !== 0;
1888
1985
  }
1889
1986
  set _isLazy(isLazy) {
1890
1987
  if (isLazy) {
1891
- this.flags |= 32;
1988
+ this.flags |= 128;
1892
1989
  } else {
1893
- this.flags &= -33;
1990
+ this.flags &= -129;
1894
1991
  }
1895
1992
  }
1896
1993
  get listeners() {
@@ -1907,7 +2004,7 @@ class ReactiveSignal {
1907
2004
  const { current } = this.listeners;
1908
2005
  if (!current.has(listener)) {
1909
2006
  if (!this._isListener) {
1910
- watchSignal(this);
2007
+ watchSignal(this, this._isSuspended);
1911
2008
  this.flags |= 16;
1912
2009
  }
1913
2010
  schedulePull(this);
@@ -1918,7 +2015,7 @@ class ReactiveSignal {
1918
2015
  current.delete(listener);
1919
2016
  if (current.size === 0) {
1920
2017
  cancelPull(this);
1921
- scheduleUnwatch(this);
2018
+ unwatchSignal(this, this._isSuspended);
1922
2019
  this.flags &= -17;
1923
2020
  }
1924
2021
  }
@@ -1929,11 +2026,37 @@ class ReactiveSignal {
1929
2026
  // the listener as watched so that relays that are accessed will be activated.
1930
2027
  addListenerLazy() {
1931
2028
  if (!this._isListener) {
1932
- watchSignal(this);
2029
+ watchSignal(this, this._isSuspended);
1933
2030
  this.flags |= 16;
1934
2031
  }
1935
2032
  return this.listeners.cachedBoundAdd;
1936
2033
  }
2034
+ setSuspended(suspended) {
2035
+ const { flags } = this;
2036
+ const isListener = (flags & 16) !== 0;
2037
+ const isSuspendedListener = (flags & 32) !== 0;
2038
+ if (suspended && !isSuspendedListener) {
2039
+ this.flags = flags | 32;
2040
+ if (isListener) {
2041
+ suspendSignal(this);
2042
+ }
2043
+ } else if (!suspended && isSuspendedListener) {
2044
+ this.flags = flags & -33;
2045
+ if (isListener) {
2046
+ resumeSignal(this);
2047
+ }
2048
+ }
2049
+ }
2050
+ reset() {
2051
+ this.flags = (this.def.isRelay ? 8 : 0) | 2;
2052
+ this.dirtyHead = void 0;
2053
+ this.updatedCount = 0;
2054
+ this.computedCount = 0;
2055
+ this.deps = /* @__PURE__ */ new Map();
2056
+ this.subs = /* @__PURE__ */ new Map();
2057
+ this.watchCount = 0;
2058
+ this.suspendCount = 0;
2059
+ }
1937
2060
  }
1938
2061
  const runListeners = (signal2) => {
1939
2062
  const { listeners } = signal2;
@@ -2131,8 +2254,9 @@ exports.setGlobalContexts = setGlobalContexts;
2131
2254
  exports.setReactivePromise = setReactivePromise;
2132
2255
  exports.setScopeOwner = setScopeOwner;
2133
2256
  exports.setTracing = setTracing;
2257
+ exports.settled = settled;
2134
2258
  exports.signal = signal;
2135
2259
  exports.unwatchSignal = unwatchSignal;
2136
2260
  exports.watchSignal = watchSignal;
2137
2261
  exports.withContexts = withContexts;
2138
- //# sourceMappingURL=debug-CjBhOupU.js.map
2262
+ //# sourceMappingURL=debug-C4VkJKKv.js.map