@solidjs/signals 0.8.1 → 0.8.3

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
@@ -129,8 +129,8 @@ function adjustHeight(el, heap) {
129
129
  let newHeight = el._height;
130
130
  for (let d = el._deps; d; d = d._nextDep) {
131
131
  const dep1 = d._dep;
132
- const dep = "_owner" in dep1 ? dep1._owner : dep1;
133
- if ("_fn" in dep) {
132
+ const dep = dep1._firewall || dep1;
133
+ if (dep._fn) {
134
134
  if (dep._height >= newHeight) {
135
135
  newHeight = dep._height + 1;
136
136
  }
@@ -147,7 +147,6 @@ function adjustHeight(el, heap) {
147
147
  // src/core/scheduler.ts
148
148
  var clock = 0;
149
149
  var activeTransition = null;
150
- var unobserved = [];
151
150
  var transitions = /* @__PURE__ */ new Set();
152
151
  var scheduled = false;
153
152
  function schedule() {
@@ -205,6 +204,30 @@ var Queue = class {
205
204
  this._queues[type - 1].push(fn);
206
205
  schedule();
207
206
  }
207
+ stashQueues(stub) {
208
+ stub._queues[0].push(...this._queues[0]);
209
+ stub._queues[1].push(...this._queues[1]);
210
+ this._queues = [[], []];
211
+ for (let i = 0; i < this._children.length; i++) {
212
+ let child = this._children[i];
213
+ let childStub = stub._children[i];
214
+ if (!childStub) {
215
+ childStub = { _queues: [[], []], _children: [] };
216
+ stub._children[i] = childStub;
217
+ }
218
+ child.stashQueues(childStub);
219
+ }
220
+ }
221
+ restoreQueues(stub) {
222
+ this._queues[0].push(...stub._queues[0]);
223
+ this._queues[1].push(...stub._queues[1]);
224
+ for (let i = 0; i < stub._children.length; i++) {
225
+ const childStub = stub._children[i];
226
+ let child = this._children[i];
227
+ if (child)
228
+ child.restoreQueues(childStub);
229
+ }
230
+ }
208
231
  };
209
232
  var GlobalQueue = class _GlobalQueue extends Queue {
210
233
  _running = false;
@@ -221,9 +244,7 @@ var GlobalQueue = class _GlobalQueue extends Queue {
221
244
  if (!transitionComplete(activeTransition)) {
222
245
  runHeap(zombieQueue, _GlobalQueue._update);
223
246
  globalQueue._pendingNodes = [];
224
- activeTransition.queues[0].push(...globalQueue._queues[0]);
225
- activeTransition.queues[1].push(...globalQueue._queues[1]);
226
- globalQueue._queues = [[], []];
247
+ globalQueue.stashQueues(activeTransition.queueStash);
227
248
  clock++;
228
249
  scheduled = false;
229
250
  runPending(activeTransition.pendingNodes, true);
@@ -231,8 +252,7 @@ var GlobalQueue = class _GlobalQueue extends Queue {
231
252
  return;
232
253
  }
233
254
  globalQueue._pendingNodes.push(...activeTransition.pendingNodes);
234
- globalQueue._queues[0].push(...activeTransition.queues[0]);
235
- globalQueue._queues[1].push(...activeTransition.queues[1]);
255
+ globalQueue.restoreQueues(activeTransition.queueStash);
236
256
  transitions.delete(activeTransition);
237
257
  activeTransition = null;
238
258
  if (runPending(globalQueue._pendingNodes, false))
@@ -255,7 +275,6 @@ var GlobalQueue = class _GlobalQueue extends Queue {
255
275
  this.run(2 /* User */);
256
276
  } finally {
257
277
  this._running = false;
258
- unobserved.length && notifyUnobserved();
259
278
  }
260
279
  }
261
280
  notify(node, mask, flags) {
@@ -276,7 +295,7 @@ var GlobalQueue = class _GlobalQueue extends Queue {
276
295
  time: clock,
277
296
  pendingNodes: [],
278
297
  asyncNodes: [],
279
- queues: [[], []]
298
+ queueStash: { _queues: [[], []], _children: [] }
280
299
  };
281
300
  }
282
301
  transitions.add(activeTransition);
@@ -325,14 +344,6 @@ function transitionComplete(transition) {
325
344
  }
326
345
  return done;
327
346
  }
328
- function notifyUnobserved() {
329
- for (let i = 0; i < unobserved.length; i++) {
330
- const source = unobserved[i];
331
- if (!source._subs)
332
- unobserved[i]._unobserved?.();
333
- }
334
- unobserved = [];
335
- }
336
347
 
337
348
  // src/core/core.ts
338
349
  GlobalQueue._update = recompute;
@@ -343,6 +354,14 @@ var pendingValueCheck = false;
343
354
  var pendingCheck = null;
344
355
  var context = null;
345
356
  var defaultContext = {};
357
+ function notifySubs(node) {
358
+ for (let s = node._subs; s !== null; s = s._nextSub) {
359
+ const queue = s._sub._flags & 32 /* Zombie */ ? zombieQueue : dirtyQueue;
360
+ if (queue._min > s._sub._height)
361
+ queue._min = s._sub._height;
362
+ insertIntoHeap(s._sub, queue);
363
+ }
364
+ }
346
365
  function recompute(el, create = false) {
347
366
  deleteFromHeap(el, el._flags & 32 /* Zombie */ ? zombieQueue : dirtyQueue);
348
367
  if (el._pendingValue !== NOT_PENDING || el._pendingFirstChild || el._pendingDisposal)
@@ -425,8 +444,8 @@ function updateIfNecessary(el) {
425
444
  if (el._flags & 1 /* Check */) {
426
445
  for (let d = el._deps; d; d = d._nextDep) {
427
446
  const dep1 = d._dep;
428
- const dep = "_owner" in dep1 ? dep1._owner : dep1;
429
- if ("_fn" in dep) {
447
+ const dep = dep1._firewall || dep1;
448
+ if (dep._fn) {
430
449
  updateIfNecessary(dep);
431
450
  }
432
451
  if (el._flags & 2 /* Dirty */) {
@@ -453,9 +472,22 @@ function unlinkSubs(link2) {
453
472
  prevSub._nextSub = nextSub;
454
473
  } else {
455
474
  dep._subs = nextSub;
475
+ if (nextSub === null) {
476
+ dep._unobserved?.();
477
+ dep._fn && unobserved(dep);
478
+ }
456
479
  }
457
480
  return nextDep;
458
481
  }
482
+ function unobserved(el) {
483
+ deleteFromHeap(el, el._flags & 32 /* Zombie */ ? zombieQueue : dirtyQueue);
484
+ let dep = el._deps;
485
+ while (dep !== null) {
486
+ dep = unlinkSubs(dep);
487
+ }
488
+ el._deps = null;
489
+ runDisposal(el);
490
+ }
459
491
  function link(dep, sub) {
460
492
  const prevDep = sub._depsTail;
461
493
  if (prevDep !== null && prevDep._dep === dep) {
@@ -513,7 +545,7 @@ function setStatusFlags(signal2, flags, error = null) {
513
545
  signal2._error = error;
514
546
  }
515
547
  function setError(signal2, error) {
516
- setStatusFlags(signal2, 2 /* Error */ | 4 /* Uninitialized */, error);
548
+ setStatusFlags(signal2, 2 /* Error */, error);
517
549
  }
518
550
  function clearStatusFlags(signal2) {
519
551
  setStatusFlags(signal2, 0 /* None */);
@@ -531,6 +563,15 @@ function markDisposal(el) {
531
563
  child = child._nextSibling;
532
564
  }
533
565
  }
566
+ function dispose(node) {
567
+ let toRemove = node._deps || null;
568
+ do {
569
+ toRemove = unlinkSubs(toRemove);
570
+ } while (toRemove !== null);
571
+ node._deps = null;
572
+ node._depsTail = null;
573
+ disposeChildren(node, true);
574
+ }
534
575
  function disposeChildren(node, self = false, zombie) {
535
576
  if (node._flags & 64 /* Disposed */)
536
577
  return;
@@ -664,6 +705,9 @@ function asyncComputed(asyncFn, initialValue, options) {
664
705
  return;
665
706
  globalQueue.initTransition(self);
666
707
  setError(self, e);
708
+ self._time = clock;
709
+ notifySubs(self);
710
+ schedule();
667
711
  flush();
668
712
  });
669
713
  } else {
@@ -681,6 +725,9 @@ function asyncComputed(asyncFn, initialValue, options) {
681
725
  return;
682
726
  globalQueue.initTransition(self);
683
727
  setError(self, error);
728
+ self._time = clock;
729
+ notifySubs(self);
730
+ schedule();
684
731
  flush();
685
732
  }
686
733
  })();
@@ -703,7 +750,7 @@ function signal(v, options, firewall = null) {
703
750
  _value: v,
704
751
  _subs: null,
705
752
  _subsTail: null,
706
- _owner: firewall,
753
+ _firewall: firewall,
707
754
  _nextChild: firewall._child,
708
755
  _statusFlags: 0 /* None */,
709
756
  _time: clock,
@@ -744,8 +791,8 @@ function read(el) {
744
791
  c = c._parentComputed;
745
792
  if (c && tracking) {
746
793
  link(el, c);
747
- const owner = "_owner" in el ? el._owner : el;
748
- if ("_fn" in owner) {
794
+ const owner = el._firewall || el;
795
+ if (owner._fn) {
749
796
  const isZombie = el._flags & 32 /* Zombie */;
750
797
  if (owner._height >= (isZombie ? zombieQueue._min : dirtyQueue._min)) {
751
798
  markNode(c);
@@ -808,7 +855,7 @@ function read(el) {
808
855
  return !c || el._pendingValue === NOT_PENDING || stale && !pendingCheck && el._transition && activeTransition !== el._transition ? el._value : el._pendingValue;
809
856
  }
810
857
  function setSignal(el, v) {
811
- if (!el._pureWrite && context && !context.firewall)
858
+ if (!el._pureWrite && context && el._firewall !== context)
812
859
  console.warn("A Signal was written to in an owned scope.");
813
860
  if (typeof v === "function") {
814
861
  v = v(
@@ -831,12 +878,7 @@ function setSignal(el, v) {
831
878
  }
832
879
  clearStatusFlags(el);
833
880
  el._time = clock;
834
- for (let s = el._subs; s !== null; s = s._nextSub) {
835
- const queue = s._sub._flags & 32 /* Zombie */ ? zombieQueue : dirtyQueue;
836
- if (queue._min > s._sub._height)
837
- queue._min = s._sub._height;
838
- insertIntoHeap(s._sub, queue);
839
- }
881
+ notifySubs(el);
840
882
  schedule();
841
883
  return v;
842
884
  }
@@ -1013,9 +1055,8 @@ function effect(compute, effect2, error, initialValue, options) {
1013
1055
  }
1014
1056
  });
1015
1057
  initialized = true;
1016
- if (node._type === 1 /* Render */) {
1017
- node._fn = (p) => !(node._statusFlags & 2 /* Error */) ? staleValues(() => compute(p)) : compute(p);
1018
- }
1058
+ if (node._type === 1 /* Render */)
1059
+ node._fn = (p) => staleValues(() => compute(p));
1019
1060
  !options?.defer && !(node._statusFlags & (2 /* Error */ | 1 /* Pending */)) && (node._type === 2 /* User */ ? node._queue.enqueue(node._type, runEffect.bind(node)) : runEffect.call(node));
1020
1061
  onCleanup(() => node._cleanup?.());
1021
1062
  if (!node._parent)
@@ -1084,11 +1125,29 @@ function createRenderEffect(compute, effectFn, value, options) {
1084
1125
  }
1085
1126
  function createTrackedEffect(compute, options) {
1086
1127
  }
1087
- function createReaction(effect2, options) {
1128
+ function createReaction(effectFn, options) {
1129
+ let cleanup = void 0;
1130
+ onCleanup(() => cleanup?.());
1131
+ return (tracking2) => {
1132
+ effect(
1133
+ () => (tracking2(), getOwner()),
1134
+ (node) => {
1135
+ cleanup?.();
1136
+ cleanup = (effectFn.effect || effectFn)?.();
1137
+ dispose(node);
1138
+ },
1139
+ effectFn.error,
1140
+ void 0,
1141
+ {
1142
+ defer: true,
1143
+ ...{ ...options, name: options?.name ?? "effect" }
1144
+ }
1145
+ );
1146
+ };
1088
1147
  }
1089
1148
  function resolve(fn) {
1090
1149
  return new Promise((res, rej) => {
1091
- createRoot((dispose) => {
1150
+ createRoot((dispose2) => {
1092
1151
  computed(() => {
1093
1152
  try {
1094
1153
  res(fn());
@@ -1097,7 +1156,7 @@ function resolve(fn) {
1097
1156
  throw err;
1098
1157
  rej(err);
1099
1158
  }
1100
- dispose();
1159
+ dispose2();
1101
1160
  });
1102
1161
  });
1103
1162
  });
@@ -1106,6 +1165,14 @@ function createOptimistic(first, second, third) {
1106
1165
  return {};
1107
1166
  }
1108
1167
  function onSettled(callback) {
1168
+ let cleanup;
1169
+ const o = getOwner();
1170
+ if (o)
1171
+ onCleanup(() => cleanup?.());
1172
+ globalQueue.enqueue(2 /* User */, () => {
1173
+ cleanup = callback();
1174
+ !o && cleanup?.();
1175
+ });
1109
1176
  }
1110
1177
 
1111
1178
  // src/store/reconcile.ts
@@ -1241,23 +1308,17 @@ function reconcile(value, key, all = false) {
1241
1308
  function createProjectionInternal(fn, initialValue = {}, options) {
1242
1309
  let node;
1243
1310
  const wrappedMap = /* @__PURE__ */ new WeakMap();
1244
- const traps = {
1245
- ...storeTraps,
1246
- get(target, property, receiver) {
1247
- const o = getOwner();
1248
- const n = node;
1249
- (!o || o !== n) && n && read(n);
1250
- return storeTraps.get(target, property, receiver);
1251
- }
1252
- };
1253
1311
  const wrapProjection = (source) => {
1254
1312
  if (wrappedMap.has(source))
1255
1313
  return wrappedMap.get(source);
1256
1314
  if (source[$TARGET]?.[STORE_WRAP] === wrapProjection)
1257
1315
  return source;
1258
- const wrapped = createStoreProxy(source, traps, {
1316
+ const wrapped = createStoreProxy(source, storeTraps, {
1259
1317
  [STORE_WRAP]: wrapProjection,
1260
- [STORE_LOOKUP]: wrappedMap
1318
+ [STORE_LOOKUP]: wrappedMap,
1319
+ [STORE_FIREWALL]() {
1320
+ return node;
1321
+ }
1261
1322
  });
1262
1323
  wrappedMap.set(source, wrapped);
1263
1324
  return wrapped;
@@ -1290,6 +1351,7 @@ var STORE_NODE = "n";
1290
1351
  var STORE_HAS = "h";
1291
1352
  var STORE_WRAP = "w";
1292
1353
  var STORE_LOOKUP = "l";
1354
+ var STORE_FIREWALL = "f";
1293
1355
  function createStoreProxy(value, traps = storeTraps, extend) {
1294
1356
  let newTarget;
1295
1357
  if (Array.isArray(value)) {
@@ -1318,18 +1380,24 @@ function getNodes(target, type) {
1318
1380
  target[type] = nodes = /* @__PURE__ */ Object.create(null);
1319
1381
  return nodes;
1320
1382
  }
1321
- function getNode(nodes, property, value, equals = isEqual) {
1383
+ function getNode(nodes, property, value, firewall, equals = isEqual) {
1322
1384
  if (nodes[property])
1323
1385
  return nodes[property];
1324
- return nodes[property] = signal(value, {
1325
- equals,
1326
- unobserved() {
1327
- delete nodes[property];
1328
- }
1329
- });
1386
+ return nodes[property] = signal(
1387
+ value,
1388
+ {
1389
+ equals,
1390
+ unobserved() {
1391
+ delete nodes[property];
1392
+ }
1393
+ },
1394
+ firewall
1395
+ );
1330
1396
  }
1331
1397
  function trackSelf(target, symbol = $TRACK) {
1332
- getObserver() && read(getNode(getNodes(target, STORE_NODE), symbol, void 0, false));
1398
+ getObserver() && read(
1399
+ getNode(getNodes(target, STORE_NODE), symbol, void 0, target[STORE_FIREWALL]?.(), false)
1400
+ );
1333
1401
  }
1334
1402
  function getKeys(source, override, enumerable = true) {
1335
1403
  const baseKeys = untrack(() => enumerable ? Object.keys(source) : Reflect.ownKeys(source));
@@ -1392,7 +1460,14 @@ var storeTraps = {
1392
1460
  let proto;
1393
1461
  return !Array.isArray(target[STORE_VALUE]) && (proto = Object.getPrototypeOf(target[STORE_VALUE])) && proto !== Object.prototype ? value.bind(storeValue) : value;
1394
1462
  } else if (getObserver()) {
1395
- return read(getNode(nodes, property, isWrappable(value) ? wrap(value, target) : value));
1463
+ return read(
1464
+ getNode(
1465
+ nodes,
1466
+ property,
1467
+ isWrappable(value) ? wrap(value, target) : value,
1468
+ target[STORE_FIREWALL]?.()
1469
+ )
1470
+ );
1396
1471
  }
1397
1472
  }
1398
1473
  return isWrappable(value) ? wrap(value, target) : value;
@@ -1401,7 +1476,7 @@ var storeTraps = {
1401
1476
  if (property === $PROXY || property === $TRACK || property === "__proto__")
1402
1477
  return true;
1403
1478
  const has = target[STORE_OVERRIDE] && property in target[STORE_OVERRIDE] ? target[STORE_OVERRIDE][property] !== $DELETED : property in target[STORE_VALUE];
1404
- getObserver() && read(getNode(getNodes(target, STORE_HAS), property, has));
1479
+ getObserver() && read(getNode(getNodes(target, STORE_HAS), property, has, target[STORE_FIREWALL]?.()));
1405
1480
  return has;
1406
1481
  },
1407
1482
  set(target, property, rawValue) {
@@ -2045,12 +2120,6 @@ var CollectionQueue = class extends Queue {
2045
2120
  return;
2046
2121
  return super.run(type);
2047
2122
  }
2048
- enqueue(type, fn) {
2049
- if (this._collectionType & 1 /* Pending */ && this._initialized) {
2050
- return this._parent?.enqueue(type, fn);
2051
- }
2052
- return super.enqueue(type, fn);
2053
- }
2054
2123
  notify(node, type, flags) {
2055
2124
  if (!(type & this._collectionType) || this._collectionType & 1 /* Pending */ && this._initialized)
2056
2125
  return super.notify(node, type, flags);