@solidjs/signals 0.4.4 → 0.4.6

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
@@ -39,7 +39,7 @@ function incrementClock() {
39
39
  clock++;
40
40
  }
41
41
  var ActiveTransition = null;
42
- var unobserved = [];
42
+ var Unobserved = [];
43
43
  var scheduled = false;
44
44
  function schedule() {
45
45
  if (scheduled)
@@ -49,12 +49,12 @@ function schedule() {
49
49
  queueMicrotask(flush);
50
50
  }
51
51
  function notifyUnobserved() {
52
- for (let i = 0; i < unobserved.length; i++) {
53
- const source = unobserved[i];
52
+ for (let i = 0; i < Unobserved.length; i++) {
53
+ const source = Unobserved[i];
54
54
  if (!source._observers || !source._observers.length)
55
- unobserved[i]._unobserved?.();
55
+ Unobserved[i]._unobserved?.();
56
56
  }
57
- unobserved = [];
57
+ Unobserved = [];
58
58
  }
59
59
  var pureQueue = [];
60
60
  var Queue = class {
@@ -97,7 +97,7 @@ var Queue = class {
97
97
  this.run(EFFECT_USER);
98
98
  } finally {
99
99
  this._running = false;
100
- unobserved.length && notifyUnobserved();
100
+ Unobserved.length && notifyUnobserved();
101
101
  }
102
102
  }
103
103
  addChild(child) {
@@ -285,29 +285,37 @@ function cloneGraph(node) {
285
285
  return node._transition._sources.get(node);
286
286
  }
287
287
  const clone = Object.create(Object.getPrototypeOf(node));
288
- Object.assign(clone, node, { _disposal: null, _nextSibling: null, _cloned: node });
288
+ Object.assign(clone, node, {
289
+ _disposal: null,
290
+ _nextSibling: null,
291
+ _observers: null,
292
+ _sources: node._sources ? [...node._sources] : null,
293
+ _cloned: node
294
+ });
289
295
  ActiveTransition._sources.set(node, clone);
290
296
  node._transition = ActiveTransition;
297
+ if (node._sources) {
298
+ for (let i = 0; i < node._sources.length; i++)
299
+ node._sources[i]._observers.push(clone);
300
+ }
291
301
  if (node._observers) {
302
+ clone._observers = [];
292
303
  for (let i = 0, length = node._observers.length; i < length; i++) {
293
- const o = node._observers[i];
294
- node._observers.push(cloneGraph(o));
304
+ !node._observers[i]._cloned && clone._observers.push(cloneGraph(node._observers[i]));
295
305
  }
296
306
  }
297
307
  return clone;
298
308
  }
299
- function removeSourceObservers(node, index) {
309
+ function replaceSourceObservers(node, transition2) {
300
310
  let source;
311
+ let transitionSource;
301
312
  let swap;
302
- for (let i = index; i < node._sources.length; i++) {
303
- source = ActiveTransition && ActiveTransition._sources.get(node._sources[i]) || node._sources[i];
304
- if (source._observers) {
305
- if ((swap = source._observers.indexOf(node)) !== -1) {
306
- source._observers[swap] = source._observers[source._observers.length - 1];
307
- source._observers.pop();
308
- }
309
- if (!source._observers.length)
310
- unobserved.push(source);
313
+ for (let i = 0; i < node._sources.length; i++) {
314
+ transitionSource = transition2._sources.get(node._sources[i]);
315
+ source = transitionSource || node._sources[i];
316
+ if (source._observers && (swap = source._observers.indexOf(node)) !== -1) {
317
+ source._observers[swap] = transitionSource ? node._cloned : source._observers[source._observers.length - 1];
318
+ !transitionSource && source._observers.pop();
311
319
  }
312
320
  }
313
321
  }
@@ -375,7 +383,7 @@ function finishTransition(transition2) {
375
383
  if (source === clone || source._transition !== transition2)
376
384
  continue;
377
385
  if (clone._sources)
378
- removeSourceObservers(clone, 0);
386
+ replaceSourceObservers(clone, transition2);
379
387
  source.dispose(false);
380
388
  source.emptyDisposal();
381
389
  Object.assign(source, clone);
@@ -386,11 +394,11 @@ function finishTransition(transition2) {
386
394
  globalQueue._queues[1].push.apply(globalQueue._queues[1], transition2._queues[1]);
387
395
  resolveQueues(transition2._children);
388
396
  transition2._done = true;
389
- globalQueue.flush();
390
397
  for (const reset of transition2._optimistic) {
391
398
  delete reset._transition;
392
399
  reset();
393
400
  }
401
+ globalQueue.flush();
394
402
  }
395
403
 
396
404
  // src/core/owner.ts
@@ -597,8 +605,8 @@ var Computation = class extends Owner {
597
605
  * Automatically re-executes the surrounding computation when the value changes
598
606
  */
599
607
  read() {
600
- if (ActiveTransition && ActiveTransition._sources.has(this)) {
601
- const clone = ActiveTransition._sources.get(this);
608
+ if (ActiveTransition && (ActiveTransition._sources.has(this) || !this._cloned && this._stateFlags & UNINITIALIZED_BIT)) {
609
+ const clone = ActiveTransition._sources.get(this) || cloneGraph(this);
602
610
  if (clone !== this)
603
611
  return clone.read();
604
612
  }
@@ -618,8 +626,8 @@ var Computation = class extends Owner {
618
626
  * before continuing
619
627
  */
620
628
  wait() {
621
- if (ActiveTransition && ActiveTransition._sources.has(this)) {
622
- const clone = ActiveTransition._sources.get(this);
629
+ if (ActiveTransition && (ActiveTransition._sources.has(this) || !this._cloned && this._stateFlags & UNINITIALIZED_BIT)) {
630
+ const clone = ActiveTransition._sources.get(this) || cloneGraph(this);
623
631
  if (clone !== this)
624
632
  return clone.wait();
625
633
  }
@@ -672,11 +680,6 @@ var Computation = class extends Owner {
672
680
  * Set the current node's state, and recursively mark all of this node's observers as STATE_CHECK
673
681
  */
674
682
  _notify(state, skipQueue) {
675
- if (ActiveTransition && ActiveTransition._sources.has(this)) {
676
- const clone = ActiveTransition._sources.get(this);
677
- if (clone !== this)
678
- return clone._notify(state, skipQueue);
679
- }
680
683
  if (this._state >= state && !this._forceNotify)
681
684
  return;
682
685
  this._forceNotify = !!skipQueue;
@@ -746,7 +749,7 @@ var Computation = class extends Owner {
746
749
  for (let i = 0; i < this._sources.length; i++) {
747
750
  const source = ActiveTransition && ActiveTransition._sources.get(this._sources[i]) || this._sources[i];
748
751
  source._updateIfNecessary();
749
- observerFlags |= source._stateFlags;
752
+ observerFlags |= source._stateFlags & ~UNINITIALIZED_BIT;
750
753
  if (this._state === STATE_DIRTY) {
751
754
  break;
752
755
  }
@@ -816,7 +819,7 @@ function update(node) {
816
819
  }
817
820
  let source;
818
821
  for (let i = newSourcesIndex; i < node._sources.length; i++) {
819
- source = node._sources[i];
822
+ source = ActiveTransition && ActiveTransition._sources.get(node._sources[i]) || node._sources[i];
820
823
  if (!source._observers)
821
824
  source._observers = [node];
822
825
  else
@@ -833,6 +836,21 @@ function update(node) {
833
836
  node._state = STATE_CLEAN;
834
837
  }
835
838
  }
839
+ function removeSourceObservers(node, index) {
840
+ let source;
841
+ let swap;
842
+ for (let i = index; i < node._sources.length; i++) {
843
+ source = ActiveTransition && ActiveTransition._sources.get(node._sources[i]) || node._sources[i];
844
+ if (source._observers) {
845
+ if ((swap = source._observers.indexOf(node)) !== -1) {
846
+ source._observers[swap] = source._observers[source._observers.length - 1];
847
+ source._observers.pop();
848
+ }
849
+ if (!source._observers.length)
850
+ Unobserved.push(source);
851
+ }
852
+ }
853
+ }
836
854
  function isEqual(a, b) {
837
855
  return a === b;
838
856
  }
@@ -936,7 +954,7 @@ function compute(owner, fn, observer) {
936
954
  currentMask = observer?._handlerMask ?? DEFAULT_FLAGS;
937
955
  notStale = true;
938
956
  try {
939
- return fn(observer ? observer._value : void 0);
957
+ return fn.call(observer, observer ? observer._value : void 0);
940
958
  } finally {
941
959
  setOwner(prevOwner);
942
960
  currentObserver = prevObserver;
@@ -960,7 +978,9 @@ var Effect = class extends Computation {
960
978
  this._prevValue = initialValue;
961
979
  this._type = options?.render ? EFFECT_RENDER : EFFECT_USER;
962
980
  if (this._type === EFFECT_RENDER) {
963
- this._compute = (p) => !ActiveTransition && clock > this._queue.created && !(this._stateFlags & ERROR_BIT) ? latest(() => compute2(p)) : compute2(p);
981
+ this._compute = function(p) {
982
+ return !this._cloned && clock > this._queue.created && !(this._stateFlags & ERROR_BIT) ? latest(() => compute2(p)) : compute2(p);
983
+ };
964
984
  }
965
985
  this._updateIfNecessary();
966
986
  !options?.defer && (this._type === EFFECT_USER ? this._queue.enqueue(this._type, this._run.bind(this)) : this._run(this._type));
@@ -971,19 +991,17 @@ var Effect = class extends Computation {
971
991
  if (this._state == STATE_DIRTY) {
972
992
  this._stateFlags = flags;
973
993
  if (this._type === EFFECT_RENDER) {
974
- this._queue.notify(this, LOADING_BIT | ERROR_BIT, flags);
994
+ this._queue.notify(this, LOADING_BIT | ERROR_BIT, this._stateFlags);
975
995
  }
976
996
  }
977
997
  if (value === UNCHANGED)
978
998
  return this._value;
979
999
  this._value = value;
980
1000
  this._modified = true;
1001
+ this._error = void 0;
981
1002
  return value;
982
1003
  }
983
1004
  _notify(state, skipQueue) {
984
- if (ActiveTransition && ActiveTransition._sources.has(this)) {
985
- return ActiveTransition._sources.get(this)._notify(state, skipQueue);
986
- }
987
1005
  if (this._state >= state || skipQueue)
988
1006
  return;
989
1007
  if (this._state === STATE_CLEAN)
@@ -991,8 +1009,8 @@ var Effect = class extends Computation {
991
1009
  this._state = state;
992
1010
  }
993
1011
  _notifyFlags(mask, newFlags2) {
994
- if (ActiveTransition && ActiveTransition._sources.has(this)) {
995
- if (this._state >= STATE_CHECK)
1012
+ if (this._cloned) {
1013
+ if (this._state >= STATE_DIRTY)
996
1014
  return;
997
1015
  if (mask & 3) {
998
1016
  this._notify(STATE_DIRTY);
@@ -1026,6 +1044,7 @@ var Effect = class extends Computation {
1026
1044
  this._onerror = void 0;
1027
1045
  this._cleanup?.();
1028
1046
  this._cleanup = void 0;
1047
+ this._queue.notify(this, ERROR_BIT | LOADING_BIT, 0);
1029
1048
  super._disposeNode();
1030
1049
  }
1031
1050
  _run(type) {
@@ -1055,9 +1074,6 @@ var EagerComputation = class extends Computation {
1055
1074
  console.warn("Eager Computations created outside a reactive context will never be disposed");
1056
1075
  }
1057
1076
  _notify(state, skipQueue) {
1058
- if (ActiveTransition && ActiveTransition._sources.has(this)) {
1059
- return ActiveTransition._sources.get(this)._notify(state, skipQueue);
1060
- }
1061
1077
  if (this._state >= state && !this._forceNotify)
1062
1078
  return;
1063
1079
  if (!skipQueue && (this._state === STATE_CLEAN || this._state === STATE_CHECK && this._forceNotify))
@@ -1076,9 +1092,6 @@ var FirewallComputation = class extends Computation {
1076
1092
  console.warn("Eager Computations created outside a reactive context will never be disposed");
1077
1093
  }
1078
1094
  _notify(state, skipQueue) {
1079
- if (ActiveTransition && ActiveTransition._sources.has(this)) {
1080
- return ActiveTransition._sources.get(this)._notify(state, skipQueue);
1081
- }
1082
1095
  if (this._state >= state && !this._forceNotify)
1083
1096
  return;
1084
1097
  if (!skipQueue && (this._state === STATE_CLEAN || this._state === STATE_CHECK && this._forceNotify))
@@ -1524,6 +1537,8 @@ function applyState(next, state, keyFn, all) {
1524
1537
  }
1525
1538
  function reconcile(value, key, all = false) {
1526
1539
  return (state) => {
1540
+ if (state == null)
1541
+ throw new Error("Cannot reconcile null or undefined state");
1527
1542
  const keyFn = typeof key === "string" ? (item) => item[key] : key;
1528
1543
  const eq = keyFn(state);
1529
1544
  if (eq !== void 0 && keyFn(value) !== keyFn(state))
@@ -1768,7 +1783,7 @@ function createMemo(compute2, value, options) {
1768
1783
  return resolvedValue;
1769
1784
  }
1770
1785
  resolvedValue = node.wait();
1771
- if (!node._sources?.length && node._nextSibling?._parent !== node) {
1786
+ if (!node._sources?.length && node._nextSibling?._parent !== node && !(node._stateFlags & UNINITIALIZED_BIT)) {
1772
1787
  node.dispose();
1773
1788
  node = void 0;
1774
1789
  }
@@ -1829,9 +1844,13 @@ function createAsync(compute2, value, options) {
1829
1844
  );
1830
1845
  const read = node.wait.bind(node);
1831
1846
  read.refresh = () => {
1832
- node._state = STATE_DIRTY;
1847
+ let n = node;
1848
+ if (ActiveTransition && !node._cloned) {
1849
+ n = cloneGraph(node);
1850
+ }
1851
+ n._state = STATE_DIRTY;
1833
1852
  refreshing = true;
1834
- node._updateIfNecessary();
1853
+ n._updateIfNecessary();
1835
1854
  };
1836
1855
  return read;
1837
1856
  }
@@ -1912,7 +1931,7 @@ function createOptimistic(initial, compute2, key) {
1912
1931
  (s) => {
1913
1932
  const value = initial();
1914
1933
  if (!ActiveTransition)
1915
- s.value = value;
1934
+ reconcile({ value }, key)(s);
1916
1935
  },
1917
1936
  { value: void 0 }
1918
1937
  );
@@ -1920,9 +1939,9 @@ function createOptimistic(initial, compute2, key) {
1920
1939
  [store, setStore] = createStore({ value: initial });
1921
1940
  const reset = () => setStore(
1922
1941
  (s) => reconcile(
1923
- typeof initial === "function" ? initial() : initial,
1942
+ { value: typeof initial === "function" ? initial() : initial },
1924
1943
  key
1925
- )(s.value)
1944
+ )(s)
1926
1945
  );
1927
1946
  let lastChange = void 0;
1928
1947
  function write(v) {
@@ -2284,6 +2303,8 @@ function createErrorBoundary(fn, fallback) {
2284
2303
  return fallback(node._error, () => {
2285
2304
  incrementClock();
2286
2305
  for (let node2 of queue._nodes) {
2306
+ if (ActiveTransition && !node2._cloned)
2307
+ node2 = cloneGraph(node2);
2287
2308
  node2._state = STATE_DIRTY;
2288
2309
  node2._queue?.enqueue(node2._type, node2._run.bind(node2));
2289
2310
  }