@solidjs/signals 0.3.0 → 0.3.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.
package/dist/dev.js CHANGED
@@ -50,6 +50,7 @@ function schedule() {
50
50
  queueMicrotask(flushSync);
51
51
  }
52
52
  var Queue = class {
53
+ _parent = null;
53
54
  _running = false;
54
55
  _queues = [[], [], []];
55
56
  _children = [];
@@ -95,12 +96,18 @@ var Queue = class {
95
96
  }
96
97
  addChild(child) {
97
98
  this._children.push(child);
99
+ child._parent = this;
98
100
  }
99
101
  removeChild(child) {
100
102
  const index = this._children.indexOf(child);
101
103
  if (index >= 0)
102
104
  this._children.splice(index, 1);
103
105
  }
106
+ notify(...args) {
107
+ if (this._parent)
108
+ return this._parent.notify(...args);
109
+ return false;
110
+ }
104
111
  };
105
112
  var globalQueue = new Queue();
106
113
  function flushSync() {
@@ -184,23 +191,20 @@ var Owner = class {
184
191
  _state = STATE_CLEAN;
185
192
  _disposal = null;
186
193
  _context = defaultContext;
187
- _handlers = null;
188
194
  _queue = globalQueue;
189
- _siblingCount = null;
190
195
  _childCount = 0;
191
196
  id = null;
192
197
  constructor(id = null, skipAppend = false) {
193
198
  this.id = id;
194
- if (currentOwner && !skipAppend)
195
- currentOwner.append(this);
199
+ if (currentOwner) {
200
+ if (!id && currentOwner.id)
201
+ this.id = currentOwner.getNextChildId();
202
+ !skipAppend && currentOwner.append(this);
203
+ }
196
204
  }
197
205
  append(child) {
198
206
  child._parent = this;
199
207
  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
208
  if (this._nextSibling)
205
209
  this._nextSibling._prevSibling = child;
206
210
  child._nextSibling = this._nextSibling;
@@ -208,9 +212,6 @@ var Owner = class {
208
212
  if (child._context !== this._context) {
209
213
  child._context = { ...this._context, ...child._context };
210
214
  }
211
- if (this._handlers) {
212
- child._handlers = !child._handlers ? this._handlers : [...child._handlers, ...this._handlers];
213
- }
214
215
  if (this._queue)
215
216
  child._queue = this._queue;
216
217
  }
@@ -225,6 +226,7 @@ var Owner = class {
225
226
  current._nextSibling = null;
226
227
  current = next;
227
228
  }
229
+ this._childCount = 0;
228
230
  if (self)
229
231
  this._disposeNode();
230
232
  if (current)
@@ -238,7 +240,6 @@ var Owner = class {
238
240
  this._parent = null;
239
241
  this._prevSibling = null;
240
242
  this._context = defaultContext;
241
- this._handlers = null;
242
243
  this._state = STATE_DISPOSED;
243
244
  this.emptyDisposal();
244
245
  }
@@ -255,27 +256,9 @@ var Owner = class {
255
256
  }
256
257
  this._disposal = null;
257
258
  }
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
259
  getNextChildId() {
277
260
  if (this.id)
278
- return formatId(this.id + "-", this._childCount++);
261
+ return formatId(this.id, this._childCount++);
279
262
  throw new Error("Cannot get child id from owner without an id");
280
263
  }
281
264
  };
@@ -800,10 +783,10 @@ var Effect = class extends Computation {
800
783
  }
801
784
  write(value, flags = 0) {
802
785
  if (this._state == STATE_DIRTY) {
803
- const currentFlags = this._stateFlags;
786
+ this._stateFlags;
804
787
  this._stateFlags = flags;
805
- if (this._type === EFFECT_RENDER && (flags & LOADING_BIT) !== (currentFlags & LOADING_BIT)) {
806
- this._queue._update?.(this);
788
+ if (this._type === EFFECT_RENDER) {
789
+ this._queue.notify(this, LOADING_BIT | ERROR_BIT, flags);
807
790
  }
808
791
  }
809
792
  if (value === UNCHANGED)
@@ -820,10 +803,9 @@ var Effect = class extends Computation {
820
803
  this._state = state;
821
804
  }
822
805
  _setError(error) {
806
+ this._error = error;
823
807
  this._cleanup?.();
824
- if (this._stateFlags & LOADING_BIT) {
825
- this._queue._update?.(this);
826
- }
808
+ this._queue.notify(this, LOADING_BIT, 0);
827
809
  this._stateFlags = ERROR_BIT;
828
810
  if (this._type === EFFECT_USER) {
829
811
  try {
@@ -832,7 +814,8 @@ var Effect = class extends Computation {
832
814
  error = e;
833
815
  }
834
816
  }
835
- this.handleError(error);
817
+ if (!this._queue.notify(this, ERROR_BIT, ERROR_BIT))
818
+ throw error;
836
819
  }
837
820
  _disposeNode() {
838
821
  if (this._state === STATE_DISPOSED)
@@ -850,7 +833,8 @@ var Effect = class extends Computation {
850
833
  try {
851
834
  this._cleanup = this._effect(this._value, this._prevValue);
852
835
  } catch (e) {
853
- this.handleError(e);
836
+ if (!this._queue.notify(this, ERROR_BIT, ERROR_BIT))
837
+ throw e;
854
838
  } finally {
855
839
  this._prevValue = this._value;
856
840
  this._modified = false;
@@ -882,104 +866,132 @@ var ProjectionComputation = class extends Computation {
882
866
  _notify(state, skipQueue) {
883
867
  if (this._state >= state && !this._forceNotify)
884
868
  return;
885
- if (this._state === STATE_CLEAN && !skipQueue)
869
+ if (!skipQueue && (this._state === STATE_CLEAN || this._state === STATE_CHECK && this._forceNotify))
886
870
  this._queue.enqueue(EFFECT_PURE, this);
887
871
  super._notify(state, true);
872
+ this._forceNotify = !!skipQueue;
888
873
  }
889
874
  };
890
875
 
891
876
  // 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));
877
+ var BoundaryComputation = class extends EagerComputation {
878
+ _propagationMask;
879
+ constructor(compute2, propagationMask) {
880
+ super(void 0, compute2, { defer: true });
881
+ this._propagationMask = propagationMask;
882
+ }
883
+ write(value, flags) {
884
+ super.write(value, flags & ~this._propagationMask);
885
+ if (this._propagationMask & LOADING_BIT && !(this._stateFlags & UNINITIALIZED_BIT)) {
886
+ flags &= ~LOADING_BIT;
887
+ }
888
+ this._queue.notify(this, this._propagationMask, flags);
889
+ return this._value;
897
890
  }
891
+ };
892
+ function createBoundChildren(owner, fn, queue, mask) {
893
+ const parentQueue = owner._queue;
894
+ parentQueue.addChild(owner._queue = queue);
895
+ onCleanup(() => parentQueue.removeChild(owner._queue));
898
896
  return compute(
899
897
  owner,
900
898
  () => {
901
899
  const c = new Computation(void 0, fn);
902
- return new EagerComputation(void 0, () => flatten(c.wait()), { defer: true });
900
+ return new BoundaryComputation(() => flatten(c.wait()), mask);
903
901
  },
904
902
  null
905
903
  );
906
904
  }
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;
913
- }
914
- return fallback();
915
- });
916
- return decision.read.bind(decision);
917
- }
918
- var SuspenseQueue = class extends Queue {
919
- _nodes = /* @__PURE__ */ new Set();
920
- _fallback = new Computation(false, null);
905
+ var ConditionalQueue = class extends Queue {
906
+ _disabled;
907
+ _errorNodes = /* @__PURE__ */ new Set();
908
+ _pendingNodes = /* @__PURE__ */ new Set();
909
+ constructor(disabled) {
910
+ super();
911
+ this._disabled = disabled;
912
+ }
921
913
  run(type) {
922
- if (type && this._fallback.read())
914
+ if (type && this._disabled.read())
923
915
  return;
924
916
  return super.run(type);
925
917
  }
926
- _update(node) {
927
- if (node._stateFlags & LOADING_BIT) {
918
+ notify(node, type, flags) {
919
+ if (this._disabled.read()) {
920
+ if (type === LOADING_BIT) {
921
+ flags & LOADING_BIT ? this._pendingNodes.add(node) : this._pendingNodes.delete(node);
922
+ }
923
+ if (type === ERROR_BIT) {
924
+ flags & ERROR_BIT ? this._errorNodes.add(node) : this._errorNodes.delete(node);
925
+ }
926
+ return true;
927
+ }
928
+ return super.notify(node, type, flags);
929
+ }
930
+ };
931
+ var CollectionQueue = class extends Queue {
932
+ _collectionType;
933
+ _nodes = /* @__PURE__ */ new Set();
934
+ _disabled = new Computation(false, null);
935
+ constructor(type) {
936
+ super();
937
+ this._collectionType = type;
938
+ }
939
+ notify(node, type, flags) {
940
+ if (!(type & this._collectionType))
941
+ return super.notify(node, type, flags);
942
+ if (flags & this._collectionType) {
928
943
  this._nodes.add(node);
929
944
  if (this._nodes.size === 1)
930
- this._fallback.write(true);
945
+ this._disabled.write(true);
931
946
  } else {
932
947
  this._nodes.delete(node);
933
948
  if (this._nodes.size === 0)
934
- this._fallback.write(false);
949
+ this._disabled.write(false);
935
950
  }
951
+ type &= ~this._collectionType;
952
+ return type ? super.notify(node, type, flags) : true;
936
953
  }
937
954
  };
938
- function createSuspense(fn, fallback) {
955
+ function createBoundary(fn, condition) {
939
956
  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);
957
+ const queue = new ConditionalQueue(new Computation(void 0, () => condition() === "hidden" /* HIDDEN */));
958
+ const tree = createBoundChildren(owner, fn, queue, 0);
959
+ new EagerComputation(void 0, () => {
960
+ const disabled = queue._disabled.read();
961
+ tree._propagationMask = disabled ? ERROR_BIT | LOADING_BIT : 0;
962
+ if (!disabled) {
963
+ queue._pendingNodes.forEach((node) => queue.notify(node, LOADING_BIT, LOADING_BIT));
964
+ queue._errorNodes.forEach((node) => queue.notify(node, ERROR_BIT, ERROR_BIT));
965
+ queue._pendingNodes.clear();
966
+ queue._errorNodes.clear();
949
967
  }
950
- return this._value;
951
- };
952
- return createDecision(tree, queue._fallback, fallback);
968
+ });
969
+ return () => queue._disabled.read() ? void 0 : tree.read();
953
970
  }
954
- function createErrorBoundary(fn, fallback) {
971
+ function createCollectionBoundary(type, fn, fallback) {
955
972
  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, () => {
973
+ const queue = new CollectionQueue(type);
974
+ const tree = createBoundChildren(owner, fn, queue, type);
975
+ const decision = new Computation(void 0, () => {
976
+ if (!queue._disabled.read()) {
977
+ const resolved = tree.read();
978
+ if (!queue._disabled.read())
979
+ return resolved;
980
+ }
981
+ return fallback(queue);
982
+ });
983
+ return decision.read.bind(decision);
984
+ }
985
+ function createSuspense(fn, fallback) {
986
+ return createCollectionBoundary(LOADING_BIT, fn, () => fallback());
987
+ }
988
+ function createErrorBoundary(fn, fallback) {
989
+ return createCollectionBoundary(
990
+ ERROR_BIT,
991
+ fn,
992
+ (queue) => fallback(queue._nodes.values().next().value._error, () => {
981
993
  incrementClock();
982
- for (let node of nodes) {
994
+ for (let node of queue._nodes) {
983
995
  node._state = STATE_DIRTY;
984
996
  node._queue?.enqueue(node._type, node);
985
997
  }
@@ -1238,7 +1250,7 @@ function ownKeys(target) {
1238
1250
  trackSelf(target);
1239
1251
  return Reflect.ownKeys(target[STORE_VALUE]);
1240
1252
  }
1241
- var Writing = /* @__PURE__ */ new Set();
1253
+ var Writing = null;
1242
1254
  var proxyTraps = {
1243
1255
  get(target, property, receiver) {
1244
1256
  if (property === $TARGET)
@@ -1259,7 +1271,7 @@ var proxyTraps = {
1259
1271
  if (desc && desc.get)
1260
1272
  return desc.get.call(receiver);
1261
1273
  }
1262
- if (Writing.has(storeValue)) {
1274
+ if (Writing?.has(storeValue)) {
1263
1275
  const value2 = tracked ? tracked._value : storeValue[property];
1264
1276
  return isWrappable(value2) ? (Writing.add(value2[$RAW] || value2), wrap2(value2)) : value2;
1265
1277
  }
@@ -1282,11 +1294,11 @@ var proxyTraps = {
1282
1294
  return has;
1283
1295
  },
1284
1296
  set(target, property, value) {
1285
- Writing.has(target[STORE_VALUE]) && setProperty(target[STORE_VALUE], property, unwrap(value, false));
1297
+ Writing?.has(target[STORE_VALUE]) && setProperty(target[STORE_VALUE], property, unwrap(value, false));
1286
1298
  return true;
1287
1299
  },
1288
1300
  deleteProperty(target, property) {
1289
- Writing.has(target[STORE_VALUE]) && setProperty(target[STORE_VALUE], property, void 0, true);
1301
+ Writing?.has(target[STORE_VALUE]) && setProperty(target[STORE_VALUE], property, void 0, true);
1290
1302
  return true;
1291
1303
  },
1292
1304
  ownKeys,
@@ -1369,11 +1381,14 @@ function createStore(first, second) {
1369
1381
  const unwrappedStore = unwrap(store);
1370
1382
  let wrappedStore = wrap2(unwrappedStore);
1371
1383
  const setStore = (fn) => {
1384
+ const prevWriting = Writing;
1385
+ Writing = /* @__PURE__ */ new Set();
1386
+ Writing.add(unwrappedStore);
1372
1387
  try {
1373
- Writing.add(unwrappedStore);
1374
1388
  fn(wrappedStore);
1375
1389
  } finally {
1376
1390
  Writing.clear();
1391
+ Writing = prevWriting;
1377
1392
  }
1378
1393
  };
1379
1394
  if (derived)
@@ -1843,4 +1858,4 @@ function compare(key, a, b) {
1843
1858
  return key ? key(a) === key(b) : true;
1844
1859
  }
1845
1860
 
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 };
1861
+ 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 };