@solidjs/signals 0.3.0 → 0.3.2

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
@@ -49,42 +49,39 @@ function schedule() {
49
49
  if (!globalQueue._running)
50
50
  queueMicrotask(flushSync);
51
51
  }
52
+ var pureQueue = [];
52
53
  var Queue = class {
54
+ _parent = null;
53
55
  _running = false;
54
- _queues = [[], [], []];
56
+ _queues = [[], []];
55
57
  _children = [];
56
58
  created = clock;
57
59
  enqueue(type, node) {
58
- this._queues[0].push(node);
60
+ pureQueue.push(node);
59
61
  if (type)
60
- this._queues[type].push(node);
62
+ this._queues[type - 1].push(node);
61
63
  schedule();
62
64
  }
63
65
  run(type) {
64
- if (this._queues[type].length) {
65
- if (type === EFFECT_PURE) {
66
- runPureQueue(this._queues[type]);
67
- this._queues[type] = [];
68
- } else {
69
- const effects = this._queues[type];
70
- this._queues[type] = [];
71
- runEffectQueue(effects);
72
- }
66
+ if (type === EFFECT_PURE) {
67
+ pureQueue.length && runPureQueue(pureQueue);
68
+ pureQueue = [];
69
+ return;
70
+ } else if (this._queues[type - 1].length) {
71
+ const effects = this._queues[type - 1];
72
+ this._queues[type - 1] = [];
73
+ runEffectQueue(effects);
73
74
  }
74
- let rerun = false;
75
75
  for (let i = 0; i < this._children.length; i++) {
76
- rerun = this._children[i].run(type) || rerun;
76
+ this._children[i].run(type);
77
77
  }
78
- if (type === EFFECT_PURE)
79
- return rerun || !!this._queues[type].length;
80
78
  }
81
79
  flush() {
82
80
  if (this._running)
83
81
  return;
84
82
  this._running = true;
85
83
  try {
86
- while (this.run(EFFECT_PURE)) {
87
- }
84
+ this.run(EFFECT_PURE);
88
85
  incrementClock();
89
86
  scheduled = false;
90
87
  this.run(EFFECT_RENDER);
@@ -95,12 +92,18 @@ var Queue = class {
95
92
  }
96
93
  addChild(child) {
97
94
  this._children.push(child);
95
+ child._parent = this;
98
96
  }
99
97
  removeChild(child) {
100
98
  const index = this._children.indexOf(child);
101
99
  if (index >= 0)
102
100
  this._children.splice(index, 1);
103
101
  }
102
+ notify(...args) {
103
+ if (this._parent)
104
+ return this._parent.notify(...args);
105
+ return false;
106
+ }
104
107
  };
105
108
  var globalQueue = new Queue();
106
109
  function flushSync() {
@@ -184,23 +187,20 @@ var Owner = class {
184
187
  _state = STATE_CLEAN;
185
188
  _disposal = null;
186
189
  _context = defaultContext;
187
- _handlers = null;
188
190
  _queue = globalQueue;
189
- _siblingCount = null;
190
191
  _childCount = 0;
191
192
  id = null;
192
193
  constructor(id = null, skipAppend = false) {
193
194
  this.id = id;
194
- if (currentOwner && !skipAppend)
195
- currentOwner.append(this);
195
+ if (currentOwner) {
196
+ if (id == null && currentOwner.id != null)
197
+ this.id = currentOwner.getNextChildId();
198
+ !skipAppend && currentOwner.append(this);
199
+ }
196
200
  }
197
201
  append(child) {
198
202
  child._parent = this;
199
203
  child._prevSibling = this;
200
- if (this.id) {
201
- child._siblingCount = this._nextSibling ? this._nextSibling._siblingCount + 1 : 0;
202
- child.id = formatId(this.id, child._siblingCount);
203
- }
204
204
  if (this._nextSibling)
205
205
  this._nextSibling._prevSibling = child;
206
206
  child._nextSibling = this._nextSibling;
@@ -208,9 +208,6 @@ var Owner = class {
208
208
  if (child._context !== this._context) {
209
209
  child._context = { ...this._context, ...child._context };
210
210
  }
211
- if (this._handlers) {
212
- child._handlers = !child._handlers ? this._handlers : [...child._handlers, ...this._handlers];
213
- }
214
211
  if (this._queue)
215
212
  child._queue = this._queue;
216
213
  }
@@ -225,6 +222,7 @@ var Owner = class {
225
222
  current._nextSibling = null;
226
223
  current = next;
227
224
  }
225
+ this._childCount = 0;
228
226
  if (self)
229
227
  this._disposeNode();
230
228
  if (current)
@@ -238,7 +236,6 @@ var Owner = class {
238
236
  this._parent = null;
239
237
  this._prevSibling = null;
240
238
  this._context = defaultContext;
241
- this._handlers = null;
242
239
  this._state = STATE_DISPOSED;
243
240
  this.emptyDisposal();
244
241
  }
@@ -255,27 +252,9 @@ var Owner = class {
255
252
  }
256
253
  this._disposal = null;
257
254
  }
258
- addErrorHandler(handler) {
259
- this._handlers = this._handlers ? [handler, ...this._handlers] : [handler];
260
- }
261
- handleError(error) {
262
- if (!this._handlers)
263
- throw error;
264
- let i = 0, len = this._handlers.length;
265
- for (i = 0; i < len; i++) {
266
- try {
267
- this._handlers[i](error, this);
268
- break;
269
- } catch (e) {
270
- error = e;
271
- }
272
- }
273
- if (i === len)
274
- throw error;
275
- }
276
255
  getNextChildId() {
277
- if (this.id)
278
- return formatId(this.id + "-", this._childCount++);
256
+ if (this.id != null)
257
+ return formatId(this.id, this._childCount++);
279
258
  throw new Error("Cannot get child id from owner without an id");
280
259
  }
281
260
  };
@@ -800,10 +779,10 @@ var Effect = class extends Computation {
800
779
  }
801
780
  write(value, flags = 0) {
802
781
  if (this._state == STATE_DIRTY) {
803
- const currentFlags = this._stateFlags;
782
+ this._stateFlags;
804
783
  this._stateFlags = flags;
805
- if (this._type === EFFECT_RENDER && (flags & LOADING_BIT) !== (currentFlags & LOADING_BIT)) {
806
- this._queue._update?.(this);
784
+ if (this._type === EFFECT_RENDER) {
785
+ this._queue.notify(this, LOADING_BIT | ERROR_BIT, flags);
807
786
  }
808
787
  }
809
788
  if (value === UNCHANGED)
@@ -820,10 +799,9 @@ var Effect = class extends Computation {
820
799
  this._state = state;
821
800
  }
822
801
  _setError(error) {
802
+ this._error = error;
823
803
  this._cleanup?.();
824
- if (this._stateFlags & LOADING_BIT) {
825
- this._queue._update?.(this);
826
- }
804
+ this._queue.notify(this, LOADING_BIT, 0);
827
805
  this._stateFlags = ERROR_BIT;
828
806
  if (this._type === EFFECT_USER) {
829
807
  try {
@@ -832,7 +810,8 @@ var Effect = class extends Computation {
832
810
  error = e;
833
811
  }
834
812
  }
835
- this.handleError(error);
813
+ if (!this._queue.notify(this, ERROR_BIT, ERROR_BIT))
814
+ throw error;
836
815
  }
837
816
  _disposeNode() {
838
817
  if (this._state === STATE_DISPOSED)
@@ -850,7 +829,8 @@ var Effect = class extends Computation {
850
829
  try {
851
830
  this._cleanup = this._effect(this._value, this._prevValue);
852
831
  } catch (e) {
853
- this.handleError(e);
832
+ if (!this._queue.notify(this, ERROR_BIT, ERROR_BIT))
833
+ throw e;
854
834
  } finally {
855
835
  this._prevValue = this._value;
856
836
  this._modified = false;
@@ -868,7 +848,7 @@ var EagerComputation = class extends Computation {
868
848
  _notify(state, skipQueue) {
869
849
  if (this._state >= state && !this._forceNotify)
870
850
  return;
871
- if (this._state === STATE_CLEAN && !skipQueue)
851
+ if (!skipQueue && (this._state === STATE_CLEAN || this._state === STATE_CHECK && this._forceNotify))
872
852
  this._queue.enqueue(EFFECT_PURE, this);
873
853
  super._notify(state, skipQueue);
874
854
  }
@@ -882,104 +862,137 @@ var ProjectionComputation = class extends Computation {
882
862
  _notify(state, skipQueue) {
883
863
  if (this._state >= state && !this._forceNotify)
884
864
  return;
885
- if (this._state === STATE_CLEAN && !skipQueue)
865
+ if (!skipQueue && (this._state === STATE_CLEAN || this._state === STATE_CHECK && this._forceNotify))
886
866
  this._queue.enqueue(EFFECT_PURE, this);
887
867
  super._notify(state, true);
868
+ this._forceNotify = !!skipQueue;
888
869
  }
889
870
  };
890
871
 
891
872
  // src/core/boundaries.ts
892
- function createBoundary(owner, fn, queue) {
893
- if (queue) {
894
- const parentQueue = owner._queue;
895
- parentQueue.addChild(owner._queue = queue);
896
- onCleanup(() => parentQueue.removeChild(owner._queue));
873
+ var BoundaryComputation = class extends EagerComputation {
874
+ _propagationMask;
875
+ constructor(compute2, propagationMask) {
876
+ super(void 0, compute2, { defer: true });
877
+ this._propagationMask = propagationMask;
878
+ }
879
+ write(value, flags) {
880
+ super.write(value, flags & ~this._propagationMask);
881
+ if (this._propagationMask & LOADING_BIT && !(this._stateFlags & UNINITIALIZED_BIT)) {
882
+ flags &= ~LOADING_BIT;
883
+ }
884
+ this._queue.notify(this, this._propagationMask, flags);
885
+ return this._value;
897
886
  }
887
+ };
888
+ function createBoundChildren(owner, fn, queue, mask) {
889
+ const parentQueue = owner._queue;
890
+ parentQueue.addChild(owner._queue = queue);
891
+ onCleanup(() => parentQueue.removeChild(owner._queue));
898
892
  return compute(
899
893
  owner,
900
894
  () => {
901
895
  const c = new Computation(void 0, fn);
902
- return new EagerComputation(void 0, () => flatten(c.wait()), { defer: true });
896
+ return new BoundaryComputation(() => flatten(c.wait()), mask);
903
897
  },
904
898
  null
905
899
  );
906
900
  }
907
- function createDecision(main, condition, fallback) {
908
- const decision = new Computation(void 0, () => {
909
- if (!condition.read()) {
910
- const resolved = main.read();
911
- if (!condition.read())
912
- return resolved;
901
+ var ConditionalQueue = class extends Queue {
902
+ _disabled;
903
+ _errorNodes = /* @__PURE__ */ new Set();
904
+ _pendingNodes = /* @__PURE__ */ new Set();
905
+ constructor(disabled) {
906
+ super();
907
+ this._disabled = disabled;
908
+ }
909
+ run(type) {
910
+ if (!type || this._disabled.read())
911
+ return;
912
+ return super.run(type);
913
+ }
914
+ notify(node, type, flags) {
915
+ if (this._disabled.read()) {
916
+ if (type === LOADING_BIT) {
917
+ flags & LOADING_BIT ? this._pendingNodes.add(node) : this._pendingNodes.delete(node);
918
+ }
919
+ if (type === ERROR_BIT) {
920
+ flags & ERROR_BIT ? this._errorNodes.add(node) : this._errorNodes.delete(node);
921
+ }
922
+ return true;
913
923
  }
914
- return fallback();
915
- });
916
- return decision.read.bind(decision);
917
- }
918
- var SuspenseQueue = class extends Queue {
924
+ return super.notify(node, type, flags);
925
+ }
926
+ };
927
+ var CollectionQueue = class extends Queue {
928
+ _collectionType;
919
929
  _nodes = /* @__PURE__ */ new Set();
920
- _fallback = new Computation(false, null);
930
+ _disabled = new Computation(false, null);
931
+ constructor(type) {
932
+ super();
933
+ this._collectionType = type;
934
+ }
921
935
  run(type) {
922
- if (type && this._fallback.read())
936
+ if (!type || this._disabled.read())
923
937
  return;
924
938
  return super.run(type);
925
939
  }
926
- _update(node) {
927
- if (node._stateFlags & LOADING_BIT) {
940
+ notify(node, type, flags) {
941
+ if (!(type & this._collectionType))
942
+ return super.notify(node, type, flags);
943
+ if (flags & this._collectionType) {
928
944
  this._nodes.add(node);
929
945
  if (this._nodes.size === 1)
930
- this._fallback.write(true);
946
+ this._disabled.write(true);
931
947
  } else {
932
948
  this._nodes.delete(node);
933
949
  if (this._nodes.size === 0)
934
- this._fallback.write(false);
950
+ this._disabled.write(false);
935
951
  }
952
+ type &= ~this._collectionType;
953
+ return type ? super.notify(node, type, flags) : true;
936
954
  }
937
955
  };
938
- function createSuspense(fn, fallback) {
956
+ function createBoundary(fn, condition) {
939
957
  const owner = new Owner();
940
- const queue = new SuspenseQueue();
941
- const tree = createBoundary(owner, fn, queue);
942
- const ogWrite = tree.write;
943
- tree.write = function(value, flags = 0) {
944
- const currentFlags = this._stateFlags;
945
- const dirty = this._state === STATE_DIRTY;
946
- ogWrite.call(this, value, flags);
947
- if (dirty && (flags & LOADING_BIT) !== (currentFlags & LOADING_BIT)) {
948
- this._queue._update?.(this);
958
+ const queue = new ConditionalQueue(new Computation(void 0, () => condition() === "hidden" /* HIDDEN */));
959
+ const tree = createBoundChildren(owner, fn, queue, 0);
960
+ new EagerComputation(void 0, () => {
961
+ const disabled = queue._disabled.read();
962
+ tree._propagationMask = disabled ? ERROR_BIT | LOADING_BIT : 0;
963
+ if (!disabled) {
964
+ queue._pendingNodes.forEach((node) => queue.notify(node, LOADING_BIT, LOADING_BIT));
965
+ queue._errorNodes.forEach((node) => queue.notify(node, ERROR_BIT, ERROR_BIT));
966
+ queue._pendingNodes.clear();
967
+ queue._errorNodes.clear();
949
968
  }
950
- return this._value;
951
- };
952
- return createDecision(tree, queue._fallback, fallback);
969
+ });
970
+ return () => queue._disabled.read() ? void 0 : tree.read();
953
971
  }
954
- function createErrorBoundary(fn, fallback) {
972
+ function createCollectionBoundary(type, fn, fallback) {
955
973
  const owner = new Owner();
956
- const error = new Computation(void 0, null);
957
- const nodes = /* @__PURE__ */ new Set();
958
- function handler(err, node) {
959
- if (nodes.has(node))
960
- return;
961
- compute(
962
- node,
963
- () => onCleanup(() => {
964
- nodes.delete(node);
965
- if (!nodes.size)
966
- error.write(void 0);
967
- }),
968
- null
969
- );
970
- nodes.add(node);
971
- if (nodes.size === 1)
972
- error.write({ _error: err });
973
- }
974
- owner.addErrorHandler(handler);
975
- const tree = createBoundary(owner, fn);
976
- tree._setError = tree.handleError;
977
- return createDecision(
978
- tree,
979
- error,
980
- () => fallback(error.read()._error, () => {
974
+ const queue = new CollectionQueue(type);
975
+ const tree = createBoundChildren(owner, fn, queue, type);
976
+ const decision = new Computation(void 0, () => {
977
+ if (!queue._disabled.read()) {
978
+ const resolved = tree.read();
979
+ if (!queue._disabled.read())
980
+ return resolved;
981
+ }
982
+ return fallback(queue);
983
+ });
984
+ return decision.read.bind(decision);
985
+ }
986
+ function createSuspense(fn, fallback) {
987
+ return createCollectionBoundary(LOADING_BIT, fn, () => fallback());
988
+ }
989
+ function createErrorBoundary(fn, fallback) {
990
+ return createCollectionBoundary(
991
+ ERROR_BIT,
992
+ fn,
993
+ (queue) => fallback(queue._nodes.values().next().value._error, () => {
981
994
  incrementClock();
982
- for (let node of nodes) {
995
+ for (let node of queue._nodes) {
983
996
  node._state = STATE_DIRTY;
984
997
  node._queue?.enqueue(node._type, node);
985
998
  }
@@ -1238,7 +1251,7 @@ function ownKeys(target) {
1238
1251
  trackSelf(target);
1239
1252
  return Reflect.ownKeys(target[STORE_VALUE]);
1240
1253
  }
1241
- var Writing = /* @__PURE__ */ new Set();
1254
+ var Writing = null;
1242
1255
  var proxyTraps = {
1243
1256
  get(target, property, receiver) {
1244
1257
  if (property === $TARGET)
@@ -1259,7 +1272,7 @@ var proxyTraps = {
1259
1272
  if (desc && desc.get)
1260
1273
  return desc.get.call(receiver);
1261
1274
  }
1262
- if (Writing.has(storeValue)) {
1275
+ if (Writing?.has(storeValue)) {
1263
1276
  const value2 = tracked ? tracked._value : storeValue[property];
1264
1277
  return isWrappable(value2) ? (Writing.add(value2[$RAW] || value2), wrap2(value2)) : value2;
1265
1278
  }
@@ -1282,11 +1295,11 @@ var proxyTraps = {
1282
1295
  return has;
1283
1296
  },
1284
1297
  set(target, property, value) {
1285
- Writing.has(target[STORE_VALUE]) && setProperty(target[STORE_VALUE], property, unwrap(value, false));
1298
+ Writing?.has(target[STORE_VALUE]) && setProperty(target[STORE_VALUE], property, unwrap(value, false));
1286
1299
  return true;
1287
1300
  },
1288
1301
  deleteProperty(target, property) {
1289
- Writing.has(target[STORE_VALUE]) && setProperty(target[STORE_VALUE], property, void 0, true);
1302
+ Writing?.has(target[STORE_VALUE]) && setProperty(target[STORE_VALUE], property, void 0, true);
1290
1303
  return true;
1291
1304
  },
1292
1305
  ownKeys,
@@ -1369,11 +1382,14 @@ function createStore(first, second) {
1369
1382
  const unwrappedStore = unwrap(store);
1370
1383
  let wrappedStore = wrap2(unwrappedStore);
1371
1384
  const setStore = (fn) => {
1385
+ const prevWriting = Writing;
1386
+ Writing = /* @__PURE__ */ new Set();
1387
+ Writing.add(unwrappedStore);
1372
1388
  try {
1373
- Writing.add(unwrappedStore);
1374
1389
  fn(wrappedStore);
1375
1390
  } finally {
1376
1391
  Writing.clear();
1392
+ Writing = prevWriting;
1377
1393
  }
1378
1394
  };
1379
1395
  if (derived)
@@ -1843,4 +1859,4 @@ function compare(key, a, b) {
1843
1859
  return key ? key(a) === key(b) : true;
1844
1860
  }
1845
1861
 
1846
- export { $PROXY, $RAW, $TARGET, $TRACK, Computation, ContextNotFoundError, NoOwnerError, NotReadyError, Owner, Queue, SUPPORTS_PROXY, createAsync, createContext, createEffect, createErrorBoundary, createMemo, createProjection, createRenderEffect, createRoot, createSignal, createStore, createSuspense, deep, flatten, flushSync, getContext, getObserver, getOwner, hasContext, hasUpdated, isEqual, isPending, isWrappable, latest, mapArray, merge, omit, onCleanup, reconcile, repeat, resolve, runWithObserver, runWithOwner, setContext, tryCatch, untrack, unwrap };
1862
+ export { $PROXY, $RAW, $TARGET, $TRACK, Computation, ContextNotFoundError, NoOwnerError, NotReadyError, Owner, Queue, SUPPORTS_PROXY, createAsync, createBoundary, createContext, createEffect, createErrorBoundary, createMemo, createProjection, createRenderEffect, createRoot, createSignal, createStore, createSuspense, deep, flatten, flushSync, getContext, getObserver, getOwner, hasContext, hasUpdated, isEqual, isPending, isWrappable, latest, mapArray, merge, omit, onCleanup, reconcile, repeat, resolve, runWithObserver, runWithOwner, setContext, tryCatch, untrack, unwrap };