@solidjs/signals 0.0.9 → 0.0.10

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/dist/dev.js CHANGED
@@ -33,6 +33,106 @@ var EFFECT_RENDER = 1;
33
33
  var EFFECT_USER = 2;
34
34
  var SUPPORTS_PROXY = typeof Proxy === "function";
35
35
 
36
+ // src/core/scheduler.ts
37
+ var clock = 0;
38
+ function getClock() {
39
+ return clock;
40
+ }
41
+ function incrementClock() {
42
+ clock++;
43
+ }
44
+ var scheduled = false;
45
+ function schedule() {
46
+ if (scheduled)
47
+ return;
48
+ scheduled = true;
49
+ if (!globalQueue._running)
50
+ queueMicrotask(flushSync);
51
+ }
52
+ var Queue = class {
53
+ _running = false;
54
+ _queues = [[], [], []];
55
+ _children = [];
56
+ enqueue(type, node) {
57
+ this._queues[0].push(node);
58
+ if (type)
59
+ this._queues[type].push(node);
60
+ schedule();
61
+ }
62
+ run(type) {
63
+ if (this._queues[type].length) {
64
+ if (type === EFFECT_PURE) {
65
+ runPureQueue(this._queues[type]);
66
+ this._queues[type] = [];
67
+ } else {
68
+ const effects = this._queues[type];
69
+ this._queues[type] = [];
70
+ runEffectQueue(effects);
71
+ }
72
+ }
73
+ let rerun = false;
74
+ for (let i = 0; i < this._children.length; i++) {
75
+ rerun = this._children[i].run(type) || rerun;
76
+ }
77
+ if (type === EFFECT_PURE && this._queues[type].length)
78
+ return true;
79
+ }
80
+ flush() {
81
+ if (this._running)
82
+ return;
83
+ this._running = true;
84
+ try {
85
+ while (this.run(EFFECT_PURE)) {
86
+ }
87
+ incrementClock();
88
+ scheduled = false;
89
+ this.run(EFFECT_RENDER);
90
+ this.run(EFFECT_USER);
91
+ } finally {
92
+ this._running = false;
93
+ }
94
+ }
95
+ addChild(child) {
96
+ this._children.push(child);
97
+ }
98
+ removeChild(child) {
99
+ const index = this._children.indexOf(child);
100
+ if (index >= 0)
101
+ this._children.splice(index, 1);
102
+ }
103
+ };
104
+ var globalQueue = new Queue();
105
+ function flushSync() {
106
+ let count = 0;
107
+ while (scheduled) {
108
+ if (++count === 1e5)
109
+ throw new Error("Potential Infinite Loop Detected.");
110
+ globalQueue.flush();
111
+ }
112
+ }
113
+ function runTop(node) {
114
+ const ancestors = [];
115
+ for (let current = node; current !== null; current = current._parent) {
116
+ if (current._state !== STATE_CLEAN) {
117
+ ancestors.push(current);
118
+ }
119
+ }
120
+ for (let i = ancestors.length - 1; i >= 0; i--) {
121
+ if (ancestors[i]._state !== STATE_DISPOSED)
122
+ ancestors[i]._updateIfNecessary();
123
+ }
124
+ }
125
+ function runPureQueue(queue) {
126
+ for (let i = 0; i < queue.length; i++) {
127
+ if (queue[i]._state !== STATE_CLEAN)
128
+ runTop(queue[i]);
129
+ }
130
+ }
131
+ function runEffectQueue(queue) {
132
+ for (let i = 0; i < queue.length; i++)
133
+ queue[i]._runEffect();
134
+ }
135
+
36
136
  // src/core/utils.ts
37
137
  function isUndefined(value) {
38
138
  return typeof value === "undefined";
@@ -114,7 +214,7 @@ var Owner = class {
114
214
  _disposal = null;
115
215
  _context = defaultContext;
116
216
  _handlers = null;
117
- _queue = null;
217
+ _queue = globalQueue;
118
218
  constructor(signal = false) {
119
219
  if (currentOwner && !signal)
120
220
  currentOwner.append(this);
@@ -182,7 +282,7 @@ var Owner = class {
182
282
  let i = 0, len = this._handlers.length;
183
283
  for (i = 0; i < len; i++) {
184
284
  try {
185
- this._handlers[i](error);
285
+ this._handlers[i](error, this);
186
286
  break;
187
287
  } catch (e) {
188
288
  error = e;
@@ -246,19 +346,12 @@ var currentMask = DEFAULT_FLAGS;
246
346
  var newSources = null;
247
347
  var newSourcesIndex = 0;
248
348
  var newFlags = 0;
249
- var clock = 0;
250
349
  var notStale = false;
251
350
  var updateCheck = null;
252
351
  var staleCheck = null;
253
352
  function getObserver() {
254
353
  return currentObserver;
255
354
  }
256
- function getClock() {
257
- return clock;
258
- }
259
- function incrementClock() {
260
- clock++;
261
- }
262
355
  var UNCHANGED = Symbol("unchanged" );
263
356
  var Computation = class extends Owner {
264
357
  _sources = null;
@@ -292,8 +385,12 @@ var Computation = class extends Owner {
292
385
  this._unobserved = options?.unobserved;
293
386
  }
294
387
  _read() {
295
- if (this._compute)
296
- this._updateIfNecessary();
388
+ if (this._compute) {
389
+ if (this._stateFlags & ERROR_BIT && this._time <= getClock())
390
+ update(this);
391
+ else
392
+ this._updateIfNecessary();
393
+ }
297
394
  if (!this._compute || this._sources?.length)
298
395
  track(this);
299
396
  newFlags |= this._stateFlags & ~currentMask;
@@ -318,7 +415,7 @@ var Computation = class extends Owner {
318
415
  * before continuing
319
416
  */
320
417
  wait() {
321
- if (this._compute && this._stateFlags & ERROR_BIT && this._time <= clock) {
418
+ if (this._compute && this._stateFlags & ERROR_BIT && this._time <= getClock()) {
322
419
  update(this);
323
420
  }
324
421
  if ((notStale || this._stateFlags & UNINITIALIZED_BIT) && this.loading()) {
@@ -351,7 +448,7 @@ var Computation = class extends Owner {
351
448
  }
352
449
  const changedFlagsMask = this._stateFlags ^ flags, changedFlags = changedFlagsMask & flags;
353
450
  this._stateFlags = flags;
354
- this._time = clock + 1;
451
+ this._time = getClock() + 1;
355
452
  if (this._observers) {
356
453
  for (let i = 0; i < this._observers.length; i++) {
357
454
  if (valueChanged) {
@@ -524,7 +621,7 @@ function update(node) {
524
621
  newSources = prevSources;
525
622
  newSourcesIndex = prevSourcesIndex;
526
623
  newFlags = prevFlags;
527
- node._time = clock + 1;
624
+ node._time = getClock() + 1;
528
625
  node._state = STATE_CLEAN;
529
626
  }
530
627
  }
@@ -606,106 +703,13 @@ function compute(owner, fn, observer) {
606
703
  notStale = prevNotStale;
607
704
  }
608
705
  }
609
-
610
- // src/core/scheduler.ts
611
- var scheduled = false;
612
- function schedule() {
613
- if (scheduled)
614
- return;
615
- scheduled = true;
616
- if (!globalQueue._running)
617
- queueMicrotask(flushSync);
618
- }
619
- var Queue = class {
620
- _running = false;
621
- _queues = [[], [], []];
622
- _children = [];
623
- enqueue(type, node) {
624
- this._queues[0].push(node);
625
- if (type)
626
- this._queues[type].push(node);
627
- schedule();
628
- }
629
- run(type) {
630
- if (this._queues[type].length) {
631
- if (type === EFFECT_PURE) {
632
- runPureQueue(this._queues[type]);
633
- this._queues[type] = [];
634
- } else {
635
- const effects = this._queues[type];
636
- this._queues[type] = [];
637
- runEffectQueue(effects);
638
- }
639
- }
640
- let rerun = false;
641
- for (let i = 0; i < this._children.length; i++) {
642
- rerun = this._children[i].run(type) || rerun;
643
- }
644
- if (type === EFFECT_PURE && this._queues[type].length)
645
- return true;
646
- }
647
- flush() {
648
- if (this._running)
649
- return;
650
- this._running = true;
651
- try {
652
- while (this.run(EFFECT_PURE)) {
653
- }
654
- incrementClock();
655
- scheduled = false;
656
- this.run(EFFECT_RENDER);
657
- this.run(EFFECT_USER);
658
- } finally {
659
- this._running = false;
660
- }
661
- }
662
- addChild(child) {
663
- this._children.push(child);
664
- }
665
- removeChild(child) {
666
- const index = this._children.indexOf(child);
667
- if (index >= 0)
668
- this._children.splice(index, 1);
669
- }
670
- };
671
- var globalQueue = new Queue();
672
- function flushSync() {
673
- let count = 0;
674
- while (scheduled) {
675
- if (++count === 1e5)
676
- throw new Error("Potential Infinite Loop Detected.");
677
- globalQueue.flush();
678
- }
679
- }
680
706
  function createBoundary(fn, queue) {
681
707
  const owner = new Owner();
682
- const parentQueue = owner._queue || globalQueue;
708
+ const parentQueue = owner._queue;
683
709
  parentQueue.addChild(owner._queue = queue);
684
710
  onCleanup(() => parentQueue.removeChild(owner._queue));
685
711
  return compute(owner, fn, null);
686
712
  }
687
- function runTop(node) {
688
- const ancestors = [];
689
- for (let current = node; current !== null; current = current._parent) {
690
- if (current._state !== STATE_CLEAN) {
691
- ancestors.push(current);
692
- }
693
- }
694
- for (let i = ancestors.length - 1; i >= 0; i--) {
695
- if (ancestors[i]._state !== STATE_DISPOSED)
696
- ancestors[i]._updateIfNecessary();
697
- }
698
- }
699
- function runPureQueue(queue) {
700
- for (let i = 0; i < queue.length; i++) {
701
- if (queue[i]._state !== STATE_CLEAN)
702
- runTop(queue[i]);
703
- }
704
- }
705
- function runEffectQueue(queue) {
706
- for (let i = 0; i < queue.length; i++)
707
- queue[i]._runEffect();
708
- }
709
713
 
710
714
  // src/core/effect.ts
711
715
  var Effect = class extends Computation {
@@ -715,7 +719,6 @@ var Effect = class extends Computation {
715
719
  _modified = false;
716
720
  _prevValue;
717
721
  _type;
718
- _queue;
719
722
  constructor(initialValue, compute2, effect, error, options) {
720
723
  super(initialValue, compute2, options);
721
724
  this._effect = effect;
@@ -725,7 +728,6 @@ var Effect = class extends Computation {
725
728
  if (this._type === EFFECT_RENDER) {
726
729
  this._compute = (p) => latest(() => compute2(p));
727
730
  }
728
- this._queue = getOwner()?._queue || globalQueue;
729
731
  if (!options?.defer) {
730
732
  this._updateIfNecessary();
731
733
  this._type === EFFECT_USER ? this._queue.enqueue(this._type, this) : this._runEffect();
@@ -794,11 +796,9 @@ var Effect = class extends Computation {
794
796
  }
795
797
  };
796
798
  var EagerComputation = class extends Computation {
797
- _queue;
798
799
  constructor(initialValue, compute2, options) {
799
800
  super(initialValue, compute2, options);
800
- this._queue = getOwner()?._queue || globalQueue;
801
- this._updateIfNecessary();
801
+ !options?.defer && this._updateIfNecessary();
802
802
  if (!this._parent)
803
803
  console.warn("Eager Computations created outside a reactive context will never be disposed");
804
804
  }
@@ -811,10 +811,8 @@ var EagerComputation = class extends Computation {
811
811
  }
812
812
  };
813
813
  var ProjectionComputation = class extends Computation {
814
- _queue;
815
814
  constructor(compute2) {
816
815
  super(null, compute2);
817
- this._queue = getOwner()?._queue || globalQueue;
818
816
  if (!this._parent)
819
817
  console.warn("Eager Computations created outside a reactive context will never be disposed");
820
818
  }
@@ -856,8 +854,9 @@ var SuspenseQueue = class extends Queue {
856
854
  var LiveComputation = class extends EagerComputation {
857
855
  write(value, flags = 0) {
858
856
  const currentFlags = this._stateFlags;
857
+ const dirty = this._state === STATE_DIRTY;
859
858
  super.write(value, flags);
860
- if ((flags & LOADING_BIT) !== (currentFlags & LOADING_BIT)) {
859
+ if (dirty && (flags & LOADING_BIT) !== (currentFlags & LOADING_BIT)) {
861
860
  this._queue._update?.(this);
862
861
  }
863
862
  return this._value;
@@ -1000,15 +999,30 @@ function runWithOwner(owner, run) {
1000
999
  }
1001
1000
  function createErrorBoundary(fn, fallback) {
1002
1001
  const owner = new Owner();
1003
- const error = new Computation(null, null);
1004
- const reset = new Computation(null, null, { equals: false });
1005
- const handler = (err) => error.write({ _error: err });
1002
+ const error = new Computation(void 0, null);
1003
+ const nodes = /* @__PURE__ */ new Set();
1004
+ function handler(err, node) {
1005
+ if (nodes.has(node))
1006
+ return;
1007
+ compute(
1008
+ node,
1009
+ () => onCleanup(() => {
1010
+ nodes.delete(node);
1011
+ if (!nodes.size)
1012
+ error.write(void 0);
1013
+ }),
1014
+ null
1015
+ );
1016
+ nodes.add(node);
1017
+ if (nodes.size === 1)
1018
+ error.write({ _error: err });
1019
+ }
1006
1020
  owner._handlers = owner._handlers ? [handler, ...owner._handlers] : [handler];
1007
1021
  const guarded = compute(
1008
1022
  owner,
1009
1023
  () => {
1010
- const c = new Computation(null, () => (reset.read(), fn()));
1011
- const f = new Computation(null, () => flatten(c.read()));
1024
+ const c = new Computation(void 0, fn);
1025
+ const f = new EagerComputation(void 0, () => flatten(c.read()), { defer: true });
1012
1026
  f._setError = function(error2) {
1013
1027
  this.handleError(error2);
1014
1028
  };
@@ -1023,23 +1037,28 @@ function createErrorBoundary(fn, fallback) {
1023
1037
  return resolved;
1024
1038
  }
1025
1039
  return fallback(error.read()._error, () => {
1026
- error.write(null);
1027
- reset.write(null);
1040
+ incrementClock();
1041
+ for (let node of nodes) {
1042
+ node._state = STATE_DIRTY;
1043
+ node._queue?.enqueue(node._type, node);
1044
+ }
1028
1045
  });
1029
1046
  });
1030
1047
  return decision.read.bind(decision);
1031
1048
  }
1032
1049
  function resolve(fn) {
1033
1050
  return new Promise((res, rej) => {
1034
- let node = new EagerComputation(void 0, () => {
1035
- try {
1036
- res(fn());
1037
- } catch (err) {
1038
- if (err instanceof NotReadyError)
1039
- throw err;
1040
- rej(err);
1041
- }
1042
- node.dispose(true);
1051
+ createRoot((dispose) => {
1052
+ new EagerComputation(void 0, () => {
1053
+ try {
1054
+ res(fn());
1055
+ } catch (err) {
1056
+ if (err instanceof NotReadyError)
1057
+ throw err;
1058
+ rej(err);
1059
+ }
1060
+ dispose();
1061
+ });
1043
1062
  });
1044
1063
  });
1045
1064
  }