@solidjs/signals 2.0.0-beta.15 → 2.0.0-beta.17

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.
Files changed (88) hide show
  1. package/dist/dev.js +782 -413
  2. package/dist/node.cjs +1927 -1625
  3. package/dist/prod.js +1525 -1227
  4. package/dist/types/boundaries.d.ts +3 -3
  5. package/dist/types/core/async.d.ts +1 -0
  6. package/dist/types/core/core.d.ts +25 -1
  7. package/dist/types/core/dev.d.ts +10 -2
  8. package/dist/types/core/effect.d.ts +1 -3
  9. package/dist/types/core/error.d.ts +2 -0
  10. package/dist/types/core/graph.d.ts +1 -1
  11. package/dist/types/core/index.d.ts +2 -2
  12. package/dist/types/core/invariants.d.ts +49 -0
  13. package/dist/types/core/scheduler.d.ts +8 -0
  14. package/dist/types/core/types.d.ts +19 -0
  15. package/dist/types/index.d.ts +1 -1
  16. package/dist/types/signals.d.ts +39 -2
  17. package/dist/types/store/projection.d.ts +2 -2
  18. package/dist/types/store/store.d.ts +28 -1
  19. package/dist/types-cjs/boundaries.d.cts +3 -3
  20. package/dist/types-cjs/core/async.d.cts +1 -0
  21. package/dist/types-cjs/core/core.d.cts +25 -1
  22. package/dist/types-cjs/core/dev.d.cts +10 -2
  23. package/dist/types-cjs/core/effect.d.cts +1 -3
  24. package/dist/types-cjs/core/error.d.cts +2 -0
  25. package/dist/types-cjs/core/graph.d.cts +1 -1
  26. package/dist/types-cjs/core/index.d.cts +2 -2
  27. package/dist/types-cjs/core/invariants.d.cts +49 -0
  28. package/dist/types-cjs/core/scheduler.d.cts +8 -0
  29. package/dist/types-cjs/core/types.d.cts +19 -0
  30. package/dist/types-cjs/index.d.cts +1 -1
  31. package/dist/types-cjs/signals.d.cts +39 -2
  32. package/dist/types-cjs/store/projection.d.cts +2 -2
  33. package/dist/types-cjs/store/store.d.cts +28 -1
  34. package/package.json +1 -1
  35. package/dist/types/src/boundaries.d.ts +0 -173
  36. package/dist/types/src/core/action.d.ts +0 -35
  37. package/dist/types/src/core/async.d.ts +0 -6
  38. package/dist/types/src/core/constants.d.ts +0 -51
  39. package/dist/types/src/core/context.d.ts +0 -36
  40. package/dist/types/src/core/core.d.ts +0 -174
  41. package/dist/types/src/core/dev.d.ts +0 -49
  42. package/dist/types/src/core/effect.d.ts +0 -32
  43. package/dist/types/src/core/error.d.ts +0 -38
  44. package/dist/types/src/core/external.d.ts +0 -45
  45. package/dist/types/src/core/graph.d.ts +0 -5
  46. package/dist/types/src/core/heap.d.ts +0 -14
  47. package/dist/types/src/core/index.d.ts +0 -12
  48. package/dist/types/src/core/lanes.d.ts +0 -54
  49. package/dist/types/src/core/owner.d.ts +0 -116
  50. package/dist/types/src/core/scheduler.d.ts +0 -122
  51. package/dist/types/src/core/types.d.ts +0 -85
  52. package/dist/types/src/index.d.ts +0 -9
  53. package/dist/types/src/map.d.ts +0 -53
  54. package/dist/types/src/signals.d.ts +0 -512
  55. package/dist/types/src/store/index.d.ts +0 -9
  56. package/dist/types/src/store/optimistic.d.ts +0 -45
  57. package/dist/types/src/store/projection.d.ts +0 -66
  58. package/dist/types/src/store/reconcile.d.ts +0 -23
  59. package/dist/types/src/store/store.d.ts +0 -125
  60. package/dist/types/src/store/storePath.d.ts +0 -58
  61. package/dist/types/src/store/utils.d.ts +0 -114
  62. package/dist/types-cjs/src/boundaries.d.cts +0 -173
  63. package/dist/types-cjs/src/core/action.d.cts +0 -35
  64. package/dist/types-cjs/src/core/async.d.cts +0 -6
  65. package/dist/types-cjs/src/core/constants.d.cts +0 -51
  66. package/dist/types-cjs/src/core/context.d.cts +0 -36
  67. package/dist/types-cjs/src/core/core.d.cts +0 -174
  68. package/dist/types-cjs/src/core/dev.d.cts +0 -49
  69. package/dist/types-cjs/src/core/effect.d.cts +0 -32
  70. package/dist/types-cjs/src/core/error.d.cts +0 -38
  71. package/dist/types-cjs/src/core/external.d.cts +0 -45
  72. package/dist/types-cjs/src/core/graph.d.cts +0 -5
  73. package/dist/types-cjs/src/core/heap.d.cts +0 -14
  74. package/dist/types-cjs/src/core/index.d.cts +0 -12
  75. package/dist/types-cjs/src/core/lanes.d.cts +0 -54
  76. package/dist/types-cjs/src/core/owner.d.cts +0 -116
  77. package/dist/types-cjs/src/core/scheduler.d.cts +0 -122
  78. package/dist/types-cjs/src/core/types.d.cts +0 -85
  79. package/dist/types-cjs/src/index.d.cts +0 -9
  80. package/dist/types-cjs/src/map.d.cts +0 -53
  81. package/dist/types-cjs/src/signals.d.cts +0 -512
  82. package/dist/types-cjs/src/store/index.d.cts +0 -9
  83. package/dist/types-cjs/src/store/optimistic.d.cts +0 -45
  84. package/dist/types-cjs/src/store/projection.d.cts +0 -66
  85. package/dist/types-cjs/src/store/reconcile.d.cts +0 -23
  86. package/dist/types-cjs/src/store/store.d.cts +0 -125
  87. package/dist/types-cjs/src/store/storePath.d.cts +0 -58
  88. package/dist/types-cjs/src/store/utils.d.cts +0 -114
package/dist/dev.js CHANGED
@@ -12,6 +12,9 @@ class StatusError extends Error {
12
12
  this.source = source;
13
13
  }
14
14
  }
15
+ function unwrapStatusError(error) {
16
+ return error instanceof StatusError ? error.cause : error;
17
+ }
15
18
  class NoOwnerError extends Error {
16
19
  constructor() {
17
20
  super("Context can only be accessed under a reactive root.");
@@ -140,6 +143,22 @@ function getObservers(node) {
140
143
  }
141
144
  return observers;
142
145
  }
146
+ function createAsyncReporters() {
147
+ return new Map();
148
+ }
149
+ function devCheckActiveOverrides(isRegisteredForRevert) {
150
+ return;
151
+ }
152
+ function devCheckFlushStart() {
153
+ return;
154
+ }
155
+ typeof globalThis !== "undefined" && !!globalThis.process?.env?.COMPANION_CENSUS;
156
+ function devCensusCompanions(isQueuedForCommit) {
157
+ return;
158
+ }
159
+ function devCheckQuiescent(isQueuedForCommit) {
160
+ return;
161
+ }
143
162
  const signalLanes = new WeakMap();
144
163
  const activeLanes = new Set();
145
164
  function getOrCreateLane(signal) {
@@ -159,7 +178,6 @@ function getOrCreateLane(signal) {
159
178
  };
160
179
  signalLanes.set(signal, lane);
161
180
  activeLanes.add(lane);
162
- signal._overrideSinceLane = false;
163
181
  return lane;
164
182
  }
165
183
  function findLane(lane) {
@@ -172,8 +190,11 @@ function mergeLanes(lane1, lane2) {
172
190
  if (lane1 === lane2) return lane1;
173
191
  lane2._mergedInto = lane1;
174
192
  for (const node of lane2._pendingAsync) lane1._pendingAsync.add(node);
193
+ lane2._pendingAsync.clear();
175
194
  lane1._effectQueues[0].push(...lane2._effectQueues[0]);
176
195
  lane1._effectQueues[1].push(...lane2._effectQueues[1]);
196
+ lane2._effectQueues[0].length = 0;
197
+ lane2._effectQueues[1].length = 0;
177
198
  return lane1;
178
199
  }
179
200
  function resolveLane(el) {
@@ -217,6 +238,8 @@ const zombieQueue = { _heap: new Array(2e3).fill(undefined), _marked: false, _mi
217
238
  let clock = 0;
218
239
  let activeTransition = null;
219
240
  let scheduled = false;
241
+ let halted = false;
242
+ let haltNotified = false;
220
243
  let syncDepth = 0;
221
244
  let projectionWriteActive = false;
222
245
  let inTrackedQueueCallback = false;
@@ -305,19 +328,24 @@ function mergeTransitionState(target, outgoing) {
305
328
  for (const sub of outgoing._gatedSubs) target._gatedSubs.add(sub);
306
329
  }
307
330
  function resolveOptimisticNodes(nodes) {
308
- for (let i = 0; i < nodes.length; i++) {
331
+ const len = nodes.length;
332
+ for (let i = 0; i < len; i++) {
309
333
  const node = nodes[i];
310
334
  node._optimisticLane = undefined;
311
- if (node._pendingValue !== NOT_PENDING) {
312
- node._value = node._pendingValue;
313
- node._pendingValue = NOT_PENDING;
314
- }
335
+ if (!(node._statusFlags & STATUS_PENDING)) node._statusFlags &= ~STATUS_UNINITIALIZED;
315
336
  const prevOverride = node._overrideValue;
316
337
  node._overrideValue = NOT_PENDING;
317
338
  if (prevOverride !== NOT_PENDING && node._value !== prevOverride) insertSubs(node, true);
318
339
  node._transition = null;
319
340
  }
320
- nodes.length = 0;
341
+ for (let i = 0; i < len; i++) {
342
+ const node = nodes[i];
343
+ if (node._pendingSignal || node._latestValueComputed) snapCompanionsToState(node);
344
+ const owner = node._parentSource;
345
+ if (owner && (owner._pendingSignal === node || owner._latestValueComputed === node))
346
+ snapCompanionsToState(owner);
347
+ }
348
+ nodes.splice(0, len);
321
349
  }
322
350
  function cleanupCompletedLanes(completingTransition) {
323
351
  for (const lane of activeLanes) {
@@ -338,10 +366,41 @@ function cleanupCompletedLanes(completingTransition) {
338
366
  }
339
367
  }
340
368
  function schedule() {
369
+ if (halted) {
370
+ notifyHalted();
371
+ return;
372
+ }
341
373
  if (scheduled) return;
342
374
  scheduled = true;
343
375
  if (!syncDepth && !globalQueue._running && !projectionWriteActive) queueMicrotask(flush);
344
376
  }
377
+ function haltReactivity() {
378
+ if (halted) return;
379
+ halted = true;
380
+ let message = "[REACTIVITY_HALTED] An uncaught error halted the reactive system.";
381
+ {
382
+ message +=
383
+ " No further updates will be processed. Handle errors with createErrorBoundary/<Errored> or treat this as a crash.";
384
+ emitDiagnostic({
385
+ code: "REACTIVITY_HALTED",
386
+ kind: "error",
387
+ severity: "error",
388
+ message: message
389
+ });
390
+ }
391
+ console.error(message);
392
+ }
393
+ function notifyHalted() {
394
+ if (haltNotified) return;
395
+ haltNotified = true;
396
+ console.error(
397
+ "[REACTIVITY_HALTED] Update ignored: the reactive system was halted by an earlier uncaught error."
398
+ );
399
+ }
400
+ function resetErrorHalt() {
401
+ halted = false;
402
+ haltNotified = false;
403
+ }
345
404
  class Queue {
346
405
  _parent = null;
347
406
  _queues = [[], []];
@@ -419,6 +478,7 @@ class GlobalQueue extends Queue {
419
478
  if (this._running) return;
420
479
  this._running = true;
421
480
  try {
481
+ if (true) devCheckFlushStart();
422
482
  runHeap(dirtyQueue, GlobalQueue._update);
423
483
  if (activeTransition) {
424
484
  const isComplete = transitionComplete(activeTransition);
@@ -482,6 +542,24 @@ class GlobalQueue extends Queue {
482
542
  this.run(EFFECT_RENDER);
483
543
  activeLanes.size && runLaneEffects(EFFECT_USER);
484
544
  this.run(EFFECT_USER);
545
+ if (true) {
546
+ devCheckActiveOverrides(n => {
547
+ if (this._optimisticNodes.includes(n)) return true;
548
+ if (activeTransition?._optimisticNodes.includes(n)) return true;
549
+ for (const t of transitions) if (t._optimisticNodes.includes(n)) return true;
550
+ return false;
551
+ });
552
+ devCensusCompanions(n => n === this._pendingNode || this._pendingNodes.includes(n));
553
+ }
554
+ if (
555
+ true &&
556
+ !scheduled &&
557
+ !activeTransition &&
558
+ transitions.size === 0 &&
559
+ activeLanes.size === 0
560
+ ) {
561
+ devCheckQuiescent(n => n === this._pendingNode || this._pendingNodes.includes(n));
562
+ }
485
563
  if (true) DEV$1.hooks.onUpdate?.();
486
564
  } finally {
487
565
  this._running = false;
@@ -513,7 +591,7 @@ class GlobalQueue extends Queue {
513
591
  activeTransition = transition ?? {
514
592
  _time: clock,
515
593
  _pendingNodes: [],
516
- _asyncReporters: new Map(),
594
+ _asyncReporters: createAsyncReporters(),
517
595
  _optimisticNodes: [],
518
596
  _optimisticStores: new Set(),
519
597
  _actions: [],
@@ -609,6 +687,7 @@ function commitPendingNode(n) {
609
687
  n._value = n._pendingValue;
610
688
  n._pendingValue = NOT_PENDING;
611
689
  }
690
+ if (n._pendingSignal || n._latestValueComputed) snapCompanionsToState(n);
612
691
  return;
613
692
  }
614
693
  if (n._pendingValue !== NOT_PENDING) {
@@ -620,6 +699,7 @@ function commitPendingNode(n) {
620
699
  if (!(c._statusFlags & STATUS_PENDING)) c._statusFlags &= ~STATUS_UNINITIALIZED;
621
700
  if (c._pendingFirstChild !== null || c._pendingDisposal !== null)
622
701
  GlobalQueue._dispose(c, false, true);
702
+ if (n._pendingSignal || n._latestValueComputed) snapCompanionsToState(n);
623
703
  }
624
704
  function commitPendingNodes() {
625
705
  if (globalQueue._pendingNode !== null) {
@@ -710,6 +790,7 @@ function flush(fn) {
710
790
  }
711
791
  return;
712
792
  }
793
+ if (halted) return;
713
794
  let count = 0;
714
795
  while (scheduled || activeTransition) {
715
796
  if (++count === 1e5) throw new Error("Potential Infinite Loop Detected.");
@@ -761,8 +842,7 @@ function transitionComplete(transition) {
761
842
  hasActiveOverride(node) &&
762
843
  "_statusFlags" in node &&
763
844
  node._statusFlags & STATUS_PENDING &&
764
- node._error instanceof NotReadyError &&
765
- node._error.source !== node
845
+ node._error instanceof NotReadyError
766
846
  ) {
767
847
  done = false;
768
848
  break;
@@ -916,7 +996,11 @@ function dispose(node) {
916
996
  function disposeChildren(node, self = false, zombie) {
917
997
  const flags = node._flags;
918
998
  if (flags & REACTIVE_DISPOSED) return;
919
- if (self) node._flags = flags | REACTIVE_DISPOSED;
999
+ if (self) {
1000
+ node._flags = flags | REACTIVE_DISPOSED;
1001
+ const n = node;
1002
+ if (n._pendingSignal || n._latestValueComputed) snapCompanionsToState(n);
1003
+ }
920
1004
  if (self && true) clearSignals(node);
921
1005
  if (self && node._fn) node._inFlight = null;
922
1006
  let child = zombie ? node._pendingFirstChild : node._firstChild;
@@ -956,6 +1040,11 @@ function disposeChildren(node, self = false, zombie) {
956
1040
  node._prevSibling = null;
957
1041
  }
958
1042
  runDisposal(node, zombie);
1043
+ if (self && node._cleanup) {
1044
+ const effectCleanup = node._cleanup;
1045
+ node._cleanup = undefined;
1046
+ effectCleanup();
1047
+ }
959
1048
  }
960
1049
  function runDisposal(node, zombie) {
961
1050
  let disposal = zombie ? node._pendingDisposal : node._disposal;
@@ -1097,42 +1186,49 @@ function unobserved(el) {
1097
1186
  el._depsTail = null;
1098
1187
  disposeChildren(el, true);
1099
1188
  }
1100
- function link(dep, sub) {
1189
+ function link(dep, sub, pendingObserver = false) {
1101
1190
  const prevDep = sub._depsTail;
1102
- if (prevDep !== null && prevDep._dep === dep) return;
1191
+ if (prevDep !== null && prevDep._dep === dep) {
1192
+ prevDep._pendingObserver = pendingObserver;
1193
+ return;
1194
+ }
1103
1195
  let nextDep = null;
1104
1196
  const isRecomputing = sub._flags & REACTIVE_RECOMPUTING_DEPS;
1105
1197
  if (isRecomputing) {
1106
1198
  nextDep = prevDep !== null ? prevDep._nextDep : sub._deps;
1107
1199
  if (nextDep !== null && nextDep._dep === dep) {
1200
+ nextDep._gen = sub._depGen;
1108
1201
  sub._depsTail = nextDep;
1202
+ nextDep._pendingObserver = pendingObserver;
1109
1203
  return;
1110
1204
  }
1111
1205
  }
1112
1206
  const prevSub = dep._subsTail;
1113
- if (prevSub !== null && prevSub._sub === sub && (!isRecomputing || isValidLink(prevSub, sub)))
1207
+ if (
1208
+ prevSub !== null &&
1209
+ prevSub._sub === sub &&
1210
+ (!isRecomputing || prevSub._gen === sub._depGen)
1211
+ ) {
1212
+ prevSub._pendingObserver = pendingObserver;
1114
1213
  return;
1214
+ }
1115
1215
  const newLink =
1116
1216
  (sub._depsTail =
1117
1217
  dep._subsTail =
1118
- { _dep: dep, _sub: sub, _nextDep: nextDep, _prevSub: prevSub, _nextSub: null });
1218
+ {
1219
+ _dep: dep,
1220
+ _sub: sub,
1221
+ _nextDep: nextDep,
1222
+ _prevSub: prevSub,
1223
+ _nextSub: null,
1224
+ _gen: sub._depGen,
1225
+ _pendingObserver: pendingObserver
1226
+ });
1119
1227
  if (prevDep !== null) prevDep._nextDep = newLink;
1120
1228
  else sub._deps = newLink;
1121
1229
  if (prevSub !== null) prevSub._nextSub = newLink;
1122
1230
  else dep._subs = newLink;
1123
1231
  }
1124
- function isValidLink(checkLink, sub) {
1125
- const depsTail = sub._depsTail;
1126
- if (depsTail !== null) {
1127
- let link = sub._deps;
1128
- do {
1129
- if (link === checkLink) return true;
1130
- if (link === depsTail) break;
1131
- link = link._nextDep;
1132
- } while (link !== null);
1133
- }
1134
- return false;
1135
- }
1136
1232
  function addPendingSource(el, source) {
1137
1233
  if (el._pendingSource === source || el._pendingSources?.has(source)) return false;
1138
1234
  if (!el._pendingSource) {
@@ -1182,9 +1278,22 @@ function setPendingError(el, source, error) {
1182
1278
  }
1183
1279
  }
1184
1280
  function forEachDependent(el, fn) {
1185
- for (let s = el._subs; s !== null; s = s._nextSub) fn(s._sub);
1281
+ for (let s = el._subs; s !== null; s = s._nextSub) fn(s._sub, s);
1186
1282
  for (let child = el._child; child !== null; child = child._nextChild) {
1187
- for (let s = child._subs; s !== null; s = s._nextSub) fn(s._sub);
1283
+ for (let s = child._subs; s !== null; s = s._nextSub) fn(s._sub, s);
1284
+ }
1285
+ }
1286
+ function enqueueForRerun(node) {
1287
+ if (node._type === EFFECT_TRACKED) {
1288
+ const tracked = node;
1289
+ if (!tracked._modified) {
1290
+ tracked._modified = true;
1291
+ tracked._queue.enqueue(EFFECT_USER, tracked._run);
1292
+ }
1293
+ } else {
1294
+ const queue = node._flags & REACTIVE_ZOMBIE ? zombieQueue : dirtyQueue;
1295
+ if (queue._min > node._height) queue._min = node._height;
1296
+ insertIntoHeap(node, queue);
1188
1297
  }
1189
1298
  }
1190
1299
  function settlePendingSource(el) {
@@ -1203,17 +1312,7 @@ function settlePendingSource(el) {
1203
1312
  setPendingError(node);
1204
1313
  updatePendingSignal(node);
1205
1314
  if (node._blocked) {
1206
- if (node._type === EFFECT_TRACKED) {
1207
- const tracked = node;
1208
- if (!tracked._modified) {
1209
- tracked._modified = true;
1210
- tracked._queue.enqueue(EFFECT_USER, tracked._run);
1211
- }
1212
- } else {
1213
- const queue = node._flags & REACTIVE_ZOMBIE ? zombieQueue : dirtyQueue;
1214
- if (queue._min > node._height) queue._min = node._height;
1215
- insertIntoHeap(node, queue);
1216
- }
1315
+ enqueueForRerun(node);
1217
1316
  scheduled = true;
1218
1317
  }
1219
1318
  node._blocked = false;
@@ -1223,23 +1322,26 @@ function settlePendingSource(el) {
1223
1322
  forEachDependent(el, settle);
1224
1323
  if (scheduled) schedule();
1225
1324
  }
1325
+ function isThenable(value) {
1326
+ return value != null && typeof value === "object" && typeof value.then === "function";
1327
+ }
1226
1328
  function handleAsync(el, result, setter) {
1227
1329
  let iterator = false;
1228
- let isThenable = false;
1330
+ let thenable = false;
1229
1331
  if (typeof result === "object" && result !== null) {
1230
1332
  untrack(() => {
1231
1333
  iterator = result[Symbol.asyncIterator];
1232
- isThenable = !iterator && typeof result.then === "function";
1334
+ thenable = !iterator && isThenable(result);
1233
1335
  });
1234
1336
  }
1235
- if (!isThenable && !iterator) {
1337
+ if (!thenable && !iterator) {
1236
1338
  el._inFlight = null;
1237
1339
  return result;
1238
1340
  }
1239
1341
  if (el._config & CONFIG_SYNC) {
1240
1342
  const message =
1241
1343
  `[SYNC_NODE_RECEIVED_ASYNC] A computed/effect created with \`sync: true\` returned ` +
1242
- `${isThenable ? "a Promise" : "an AsyncIterable"}. The value would be stored as-is and ` +
1344
+ `${thenable ? "a Promise" : "an AsyncIterable"}. The value would be stored as-is and ` +
1243
1345
  `never awaited in production; remove \`sync: true\` to use async-aware behavior, or ` +
1244
1346
  `unwrap the value before returning.`;
1245
1347
  emitDiagnostic({
@@ -1273,35 +1375,41 @@ function handleAsync(el, result, setter) {
1273
1375
  setter(value);
1274
1376
  if (wasUninitialized) clearStatus(el, true);
1275
1377
  } else if (el._overrideValue !== undefined) {
1276
- if (el._overrideValue !== undefined && el._overrideValue !== NOT_PENDING)
1277
- el._pendingValue = value;
1278
- else {
1279
- el._value = value;
1280
- insertSubs(el);
1281
- }
1378
+ if (el._pendingValue === NOT_PENDING) queuePendingNode(el);
1379
+ el._pendingValue = value;
1380
+ syncCompanions(el, value);
1381
+ if (!hasActiveOverride(el)) insertSubs(el);
1282
1382
  el._time = clock;
1283
1383
  } else if (lane) {
1284
1384
  const isEffect = el._type;
1285
1385
  const prevValue = el._value;
1286
1386
  const equals = el._equals;
1287
- if ((!isEffect && wasUninitialized) || !equals || !equals(value, prevValue)) {
1288
- el._value = value;
1289
- el._time = clock;
1290
- if (el._latestValueComputed) {
1291
- setSignal(el._latestValueComputed, value);
1387
+ try {
1388
+ if ((!isEffect && wasUninitialized) || !equals || !equals(value, prevValue)) {
1389
+ el._value = value;
1390
+ el._time = clock;
1391
+ syncCompanions(el, value);
1392
+ insertSubs(el, true);
1292
1393
  }
1293
- insertSubs(el, true);
1394
+ } catch (e) {
1395
+ notifyStatus(el, STATUS_ERROR, e);
1294
1396
  }
1295
1397
  } else {
1296
- setSignal(el, () => value);
1398
+ try {
1399
+ setSignal(el, () => value);
1400
+ } catch (e) {
1401
+ notifyStatus(el, STATUS_ERROR, e);
1402
+ }
1297
1403
  }
1298
1404
  settlePendingSource(el);
1299
1405
  schedule();
1300
1406
  flush();
1301
1407
  then?.();
1302
1408
  };
1303
- if (isThenable) {
1409
+ if (thenable) {
1304
1410
  let resolved = false,
1411
+ rejected = false,
1412
+ syncError,
1305
1413
  isSync = true;
1306
1414
  result.then(
1307
1415
  v => {
@@ -1311,32 +1419,39 @@ function handleAsync(el, result, setter) {
1311
1419
  } else asyncWrite(v);
1312
1420
  },
1313
1421
  e => {
1314
- if (!isSync) handleError(e);
1422
+ if (isSync) {
1423
+ syncError = e;
1424
+ rejected = true;
1425
+ } else handleError(e);
1315
1426
  }
1316
1427
  );
1317
1428
  isSync = false;
1318
- if (!resolved) {
1429
+ if (rejected) {
1430
+ handleError(syncError);
1431
+ throw syncError;
1432
+ } else if (!resolved) {
1319
1433
  globalQueue.initTransition(resolveTransition(el));
1320
1434
  throw new NotReadyError(context);
1321
1435
  }
1322
1436
  }
1323
1437
  if (iterator) {
1324
1438
  const it = result[Symbol.asyncIterator]();
1325
- let hadSyncValue = false;
1439
+ let hadValue = false;
1326
1440
  let completed = false;
1441
+ let initialRead = true;
1327
1442
  cleanup(() => {
1328
1443
  if (completed) return;
1329
1444
  completed = true;
1330
1445
  try {
1331
1446
  const returned = it.return?.();
1332
- if (returned && typeof returned.then === "function") {
1333
- returned.then(undefined, () => {});
1334
- }
1447
+ if (isThenable(returned)) returned.then(undefined, () => {});
1335
1448
  } catch {}
1336
1449
  });
1337
1450
  const iterate = () => {
1338
1451
  let syncResult,
1452
+ syncError,
1339
1453
  resolved = false,
1454
+ rejected = false,
1340
1455
  isSync = true;
1341
1456
  it.next().then(
1342
1457
  r => {
@@ -1346,30 +1461,46 @@ function handleAsync(el, result, setter) {
1346
1461
  if (r.done) completed = true;
1347
1462
  } else if (el._inFlight !== result) {
1348
1463
  return;
1349
- } else if (!r.done) asyncWrite(r.value, iterate);
1350
- else {
1464
+ } else if (!r.done) {
1465
+ hadValue = true;
1466
+ asyncWrite(r.value, iterate);
1467
+ } else {
1351
1468
  completed = true;
1352
- schedule();
1353
- flush();
1469
+ if (hadValue) {
1470
+ schedule();
1471
+ flush();
1472
+ } else {
1473
+ asyncWrite(undefined);
1474
+ }
1354
1475
  }
1355
1476
  },
1356
1477
  e => {
1357
- if (!isSync && el._inFlight === result) {
1478
+ if (isSync) {
1479
+ syncError = e;
1480
+ rejected = true;
1481
+ } else if (el._inFlight === result) {
1358
1482
  completed = true;
1359
1483
  handleError(e);
1360
1484
  }
1361
1485
  }
1362
1486
  );
1363
1487
  isSync = false;
1488
+ if (rejected) {
1489
+ completed = true;
1490
+ handleError(syncError);
1491
+ if (initialRead) throw syncError;
1492
+ return true;
1493
+ }
1364
1494
  if (resolved && !syncResult.done) {
1365
1495
  syncValue = syncResult.value;
1366
- hadSyncValue = true;
1496
+ hadValue = true;
1367
1497
  return iterate();
1368
1498
  }
1369
1499
  return resolved && syncResult.done;
1370
1500
  };
1371
1501
  const immediatelyDone = iterate();
1372
- if (!hadSyncValue && !immediatelyDone) {
1502
+ initialRead = false;
1503
+ if (!hadValue && !immediatelyDone) {
1373
1504
  globalQueue.initTransition(resolveTransition(el));
1374
1505
  throw new NotReadyError(context);
1375
1506
  }
@@ -1381,7 +1512,8 @@ function clearStatus(el, clearUninitialized = false) {
1381
1512
  if (el._blocked) el._blocked = false;
1382
1513
  el._statusFlags = clearUninitialized ? 0 : el._statusFlags & STATUS_UNINITIALIZED;
1383
1514
  if (el._error) setPendingError(el);
1384
- if (el._pendingSignal) updatePendingSignal(el);
1515
+ if (el._pendingSignal || el._latestValueComputed) updatePendingSignal(el);
1516
+ if (el._child) updateChildCompanions(el);
1385
1517
  if (el._notifyStatus) el._notifyStatus();
1386
1518
  }
1387
1519
  function notifyStatus(el, status, error, blockStatus, lane) {
@@ -1409,6 +1541,7 @@ function notifyStatus(el, status, error, blockStatus, lane) {
1409
1541
  el._error = error;
1410
1542
  }
1411
1543
  updatePendingSignal(el);
1544
+ if (el._child) updateChildCompanions(el);
1412
1545
  }
1413
1546
  if (lane && !blockStatus) {
1414
1547
  assignOrMergeLane(el, lane);
@@ -1426,7 +1559,7 @@ function notifyStatus(el, status, error, blockStatus, lane) {
1426
1559
  }
1427
1560
  return;
1428
1561
  }
1429
- forEachDependent(el, sub => {
1562
+ forEachDependent(el, (sub, link) => {
1430
1563
  sub._time = clock;
1431
1564
  if (
1432
1565
  (status === STATUS_PENDING &&
@@ -1436,6 +1569,11 @@ function notifyStatus(el, status, error, blockStatus, lane) {
1436
1569
  (status !== STATUS_PENDING &&
1437
1570
  (sub._error !== error || sub._pendingSource || sub._pendingSources))
1438
1571
  ) {
1572
+ if (link._pendingObserver && status !== STATUS_PENDING && !(error instanceof NotReadyError)) {
1573
+ enqueueForRerun(sub);
1574
+ schedule();
1575
+ return;
1576
+ }
1439
1577
  if (!downstreamBlockStatus && !sub._transition) queuePendingNode(sub);
1440
1578
  notifyStatus(sub, status, error, downstreamBlockStatus, downstreamLane);
1441
1579
  }
@@ -1477,11 +1615,10 @@ const REACTIVE_WRITE_IN_OWNED_SCOPE_REFRESH_MESSAGE =
1477
1615
  let tracking = false;
1478
1616
  let stale = false;
1479
1617
  let pendingCheckActive = false;
1480
- let foundPending = false;
1481
1618
  let latestReadActive = false;
1482
1619
  let context = null;
1483
1620
  let currentOptimisticLane = null;
1484
- let pendingCheckSources = null;
1621
+ let pendingProbe = null;
1485
1622
  let snapshotCaptureActive = false;
1486
1623
  let snapshotSources = null;
1487
1624
  function ownerInSnapshotScope(owner) {
@@ -1554,11 +1691,12 @@ function recompute(el, create = false) {
1554
1691
  }
1555
1692
  let isOptimisticDirty = !!(el._flags & REACTIVE_OPTIMISTIC_DIRTY);
1556
1693
  const hasOverride = el._overrideValue !== undefined && el._overrideValue !== NOT_PENDING;
1557
- const wasPending = !!(el._statusFlags & STATUS_PENDING);
1694
+ !!(el._statusFlags & STATUS_PENDING);
1558
1695
  const wasUninitialized = !!(el._statusFlags & STATUS_UNINITIALIZED);
1559
1696
  const oldcontext = context;
1560
1697
  context = el;
1561
1698
  el._depsTail = null;
1699
+ el._depGen++;
1562
1700
  el._flags = REACTIVE_RECOMPUTING_DEPS;
1563
1701
  el._time = clock;
1564
1702
  let value = el._pendingValue === NOT_PENDING ? el._value : el._pendingValue;
@@ -1641,26 +1779,35 @@ function recompute(el, create = false) {
1641
1779
  : el._pendingValue === NOT_PENDING
1642
1780
  ? el._value
1643
1781
  : el._pendingValue;
1644
- const valueChanged =
1645
- (!isEffect && wasUninitialized) || !el._equals || !el._equals(compareValue, value);
1782
+ let valueChanged = false;
1783
+ try {
1784
+ valueChanged =
1785
+ (!isEffect && wasUninitialized) || !el._equals || !el._equals(compareValue, value);
1786
+ } catch (e) {
1787
+ notifyStatus(el, STATUS_ERROR, e);
1788
+ }
1646
1789
  if (isEffect && valueChanged) {
1647
1790
  el._modified = !el._error;
1648
- if (!create) el._queue.enqueue(isEffect, GlobalQueue._runEffect.bind(null, el));
1791
+ if (!create)
1792
+ el._queue.enqueue(isEffect, (el._boundRunEffect ??= GlobalQueue._runEffect.bind(null, el)));
1649
1793
  }
1650
- if (valueChanged) {
1794
+ if (el._error);
1795
+ else if (valueChanged) {
1651
1796
  const prevVisible = hasOverride ? el._overrideValue : undefined;
1652
1797
  if (create || (isEffect && activeTransition !== el._transition) || isOptimisticDirty) {
1653
1798
  el._value = value;
1654
1799
  if (hasOverride && isOptimisticDirty) {
1655
1800
  el._overrideValue = value;
1656
- el._pendingValue = value;
1801
+ el._pendingValue = NOT_PENDING;
1657
1802
  }
1658
- } else el._pendingValue = value;
1659
- if (hasOverride && !isOptimisticDirty && wasPending && !el._overrideSinceLane)
1660
- el._overrideValue = value;
1803
+ } else {
1804
+ el._pendingValue = value;
1805
+ if (activeTransition || el._transition) syncCompanions(el, value);
1806
+ }
1661
1807
  if (!hasOverride || isOptimisticDirty || el._overrideValue !== prevVisible)
1662
1808
  insertSubs(el, isOptimisticDirty || hasOverride);
1663
1809
  } else if (hasOverride) {
1810
+ if (el._pendingValue === NOT_PENDING) queuePendingNode(el);
1664
1811
  el._pendingValue = value;
1665
1812
  } else if (el._height != oldHeight) {
1666
1813
  for (let s = el._subs; s !== null; s = s._nextSub) {
@@ -1676,8 +1823,7 @@ function recompute(el, create = false) {
1676
1823
  !!(el._statusFlags & (STATUS_PENDING | STATUS_UNINITIALIZED));
1677
1824
  needsPendingCommit &&
1678
1825
  (!create || el._statusFlags & STATUS_PENDING) &&
1679
- !el._transition &&
1680
- !(activeTransition && hasOverride) &&
1826
+ (!el._transition || hasOverride) &&
1681
1827
  queuePendingNode(el);
1682
1828
  el._transition &&
1683
1829
  isEffect &&
@@ -1716,6 +1862,7 @@ function computed(fn, options) {
1716
1862
  (options?.ownedWrite ? CONFIG_OWNED_WRITE : 0) |
1717
1863
  (!context || options?.lazy ? CONFIG_AUTO_DISPOSE : 0) |
1718
1864
  (options?.sync ? CONFIG_SYNC : 0) |
1865
+ (options?._noSnapshot ? CONFIG_NO_SNAPSHOT : 0) |
1719
1866
  (snapshotCaptureActive && ownerInSnapshotScope(context) ? CONFIG_IN_SNAPSHOT_SCOPE : 0),
1720
1867
  _equals: options?.equals != null ? options.equals : isEqual,
1721
1868
  _unobserved: options?.unobserved,
@@ -1731,6 +1878,7 @@ function computed(fn, options) {
1731
1878
  _prevHeap: null,
1732
1879
  _deps: null,
1733
1880
  _depsTail: null,
1881
+ _depGen: 0,
1734
1882
  _subs: null,
1735
1883
  _subsTail: null,
1736
1884
  _parent: context,
@@ -1775,6 +1923,7 @@ function createEffectNode(fn, effectFn, errorFn, type, notifyStatus, options) {
1775
1923
  _prevHeap: null,
1776
1924
  _deps: null,
1777
1925
  _depsTail: null,
1926
+ _depGen: 0,
1778
1927
  _subs: null,
1779
1928
  _subsTail: null,
1780
1929
  _parent: context,
@@ -1794,7 +1943,6 @@ function createEffectNode(fn, effectFn, errorFn, type, notifyStatus, options) {
1794
1943
  _effectFn: effectFn,
1795
1944
  _errorFn: errorFn,
1796
1945
  _cleanup: undefined,
1797
- _cleanupRegistered: false,
1798
1946
  _type: type,
1799
1947
  _notifyStatus: notifyStatus
1800
1948
  };
@@ -1842,7 +1990,7 @@ function setupComputedNode(self, options) {
1842
1990
  }
1843
1991
  !options?.lazy && recompute(self, true);
1844
1992
  if (snapshotCaptureActive && !options?.lazy) {
1845
- if (!(self._statusFlags & STATUS_PENDING)) {
1993
+ if (!(self._statusFlags & STATUS_PENDING) && !(self._config & CONFIG_NO_SNAPSHOT)) {
1846
1994
  self._snapshotValue = self._value === undefined ? NO_SNAPSHOT : self._value;
1847
1995
  snapshotSources.add(self);
1848
1996
  }
@@ -1911,6 +2059,16 @@ function untrack(fn, strictReadLabel) {
1911
2059
  strictRead = prevStrictRead;
1912
2060
  }
1913
2061
  }
2062
+ function prepareComputed(comp, refresh) {
2063
+ if (comp._flags & REACTIVE_LAZY) {
2064
+ comp._flags &= ~REACTIVE_LAZY;
2065
+ recompute(comp, true);
2066
+ } else if (comp._flags & REACTIVE_DISPOSED) {
2067
+ recompute(comp, true);
2068
+ } else if (refresh) {
2069
+ updateIfNecessary(comp);
2070
+ }
2071
+ }
1914
2072
  function read(el) {
1915
2073
  if (latestReadActive) {
1916
2074
  const pendingComputed = getLatestValueComputed(el);
@@ -1924,7 +2082,8 @@ function read(el) {
1924
2082
  try {
1925
2083
  value = read(pendingComputed);
1926
2084
  } catch (e) {
1927
- if (!context && e instanceof NotReadyError) return visibleValue;
2085
+ if (e instanceof NotReadyError && (!context || !(el._statusFlags & STATUS_UNINITIALIZED)))
2086
+ return visibleValue;
1928
2087
  throw e;
1929
2088
  } finally {
1930
2089
  latestReadActive = prevPending;
@@ -1939,59 +2098,25 @@ function read(el) {
1939
2098
  }
1940
2099
  return value;
1941
2100
  }
2101
+ let c = context;
2102
+ if (c?._root) c = c._parentComputed;
2103
+ const computed = el;
2104
+ const firewall = el._firewall;
2105
+ const owner = firewall || el;
1942
2106
  if (pendingCheckActive) {
1943
- const firewall = el._firewall;
1944
- const prevCheck = pendingCheckActive;
1945
2107
  pendingCheckActive = false;
1946
- let c = context;
1947
- if (c?._root) c = c._parentComputed;
1948
- const owner = firewall || el;
1949
- const pendingComputed = el;
1950
- if (typeof pendingComputed._fn === "function") {
1951
- const comp = el;
1952
- if (comp._flags & REACTIVE_LAZY) {
1953
- comp._flags &= ~REACTIVE_LAZY;
1954
- recompute(comp, true);
1955
- } else if (comp._flags & REACTIVE_DISPOSED) {
1956
- recompute(comp, true);
1957
- } else {
1958
- updateIfNecessary(comp);
1959
- }
1960
- }
2108
+ if (typeof computed._fn === "function") prepareComputed(el, true);
1961
2109
  if (c && owner._statusFlags & STATUS_PENDING && owner._statusFlags & STATUS_UNINITIALIZED) {
1962
2110
  if (tracking && el !== c) link(el, c);
1963
- pendingCheckActive = prevCheck;
2111
+ pendingCheckActive = true;
1964
2112
  throw owner._error;
1965
2113
  }
1966
- if (firewall && el._overrideValue !== undefined) {
1967
- if (
1968
- el._overrideValue !== NOT_PENDING &&
1969
- (firewall._inFlight || !!(firewall._statusFlags & STATUS_PENDING))
1970
- ) {
1971
- foundPending = true;
1972
- }
1973
- collectPendingSources(el);
1974
- collectPendingSources(firewall);
1975
- if (c && tracking) link(el, c);
1976
- } else {
1977
- collectPendingSources(el);
1978
- if (firewall) collectPendingSources(firewall);
1979
- }
1980
- pendingCheckActive = prevCheck;
2114
+ collectPendingSources(el);
2115
+ if (firewall) collectPendingSources(firewall);
2116
+ pendingCheckActive = true;
2117
+ } else if (typeof computed._fn === "function") {
2118
+ prepareComputed(el, false);
1981
2119
  }
1982
- let c = context;
1983
- if (c?._root) c = c._parentComputed;
1984
- const computed = el;
1985
- if (typeof computed._fn === "function") {
1986
- const comp = el;
1987
- if (comp._flags & REACTIVE_LAZY) {
1988
- comp._flags &= ~REACTIVE_LAZY;
1989
- recompute(comp, true);
1990
- } else if (comp._flags & REACTIVE_DISPOSED) {
1991
- recompute(comp, true);
1992
- }
1993
- }
1994
- const owner = el._firewall || el;
1995
2120
  if (
1996
2121
  !computed._fn &&
1997
2122
  owner === el &&
@@ -2022,7 +2147,7 @@ function read(el) {
2022
2147
  throw new Error(message);
2023
2148
  }
2024
2149
  if (c && tracking) {
2025
- link(el, c);
2150
+ link(el, c, pendingCheckActive);
2026
2151
  if (owner._fn) {
2027
2152
  const isZombie = el._flags & REACTIVE_ZOMBIE;
2028
2153
  if (owner._height >= (isZombie ? zombieQueue._min : dirtyQueue._min)) {
@@ -2072,7 +2197,7 @@ function read(el) {
2072
2197
  }
2073
2198
  }
2074
2199
  if (el._fn && el._statusFlags & STATUS_ERROR) {
2075
- if (el._time < clock) {
2200
+ if (tracking && !pendingCheckActive && el._time < clock) {
2076
2201
  recompute(el);
2077
2202
  return read(el);
2078
2203
  } else throw el._error;
@@ -2123,12 +2248,19 @@ function read(el) {
2123
2248
  (currentOptimisticLane !== null &&
2124
2249
  (el._overrideValue !== undefined ||
2125
2250
  el._optimisticLane ||
2126
- (owner === el && stale) ||
2251
+ (owner === el && stale && c._parentSource !== el) ||
2127
2252
  !!(owner._statusFlags & STATUS_PENDING))) ||
2128
2253
  el._pendingValue === NOT_PENDING ||
2129
2254
  (stale && el._transition && activeTransition !== el._transition)
2130
2255
  ? el._value
2131
2256
  : el._pendingValue;
2257
+ if (
2258
+ pendingCheckActive &&
2259
+ pendingProbe !== null &&
2260
+ el._pendingValue !== NOT_PENDING &&
2261
+ value === el._pendingValue
2262
+ )
2263
+ pendingProbe.freshReads.add(el);
2132
2264
  if (
2133
2265
  !c &&
2134
2266
  owner === el &&
@@ -2173,26 +2305,18 @@ function setSignal(el, v) {
2173
2305
  : el._pendingValue;
2174
2306
  if (typeof v === "function") v = v(currentValue);
2175
2307
  const valueChanged =
2176
- !el._equals || !el._equals(currentValue, v) || !!(el._statusFlags & STATUS_UNINITIALIZED);
2308
+ !!(el._statusFlags & STATUS_UNINITIALIZED) || !el._equals || !el._equals(currentValue, v);
2177
2309
  if (!valueChanged) {
2178
2310
  if (isOptimistic && hasOverride) {
2179
2311
  const transition = resolveTransition(el);
2180
2312
  if (transition && activeTransition !== transition) globalQueue.initTransition(transition);
2181
- if (el._fn) {
2182
- insertSubs(el, true);
2183
- schedule();
2184
- }
2185
2313
  }
2186
2314
  return v;
2187
2315
  }
2188
2316
  if (isOptimistic) {
2189
2317
  const firstOverride = el._overrideValue === NOT_PENDING;
2190
2318
  if (!firstOverride) globalQueue.initTransition(resolveTransition(el));
2191
- if (firstOverride) {
2192
- el._pendingValue = el._value;
2193
- globalQueue._optimisticNodes.push(el);
2194
- }
2195
- el._overrideSinceLane = true;
2319
+ if (firstOverride) globalQueue._optimisticNodes.push(el);
2196
2320
  const lane = getOrCreateLane(el);
2197
2321
  el._optimisticLane = lane;
2198
2322
  el._overrideValue = v;
@@ -2200,10 +2324,7 @@ function setSignal(el, v) {
2200
2324
  if (el._pendingValue === NOT_PENDING) queuePendingNode(el);
2201
2325
  el._pendingValue = v;
2202
2326
  }
2203
- if (el._pendingSignal) updatePendingSignal(el);
2204
- if (el._latestValueComputed) {
2205
- setSignal(el._latestValueComputed, v);
2206
- }
2327
+ syncCompanions(el, v);
2207
2328
  el._time = clock;
2208
2329
  insertSubs(el, isOptimistic);
2209
2330
  schedule();
@@ -2250,64 +2371,82 @@ function runWithOwner(owner, fn) {
2250
2371
  function getPendingSignal(el) {
2251
2372
  if (!el._pendingSignal) {
2252
2373
  el._pendingSignal = optimisticSignal(false, { ownedWrite: true });
2253
- if (el._parentSource) {
2254
- el._pendingSignal._parentSource = el;
2255
- }
2374
+ el._pendingSignal._parentSource = el;
2256
2375
  if (computePendingState(el)) setSignal(el._pendingSignal, true);
2257
2376
  }
2258
2377
  return el._pendingSignal;
2259
2378
  }
2260
2379
  function collectPendingSources(el) {
2261
- pendingCheckSources?.add(el);
2380
+ if (!pendingProbe) return;
2381
+ pendingProbe.sources.add(el);
2262
2382
  const owner = el._firewall || el;
2263
- if (owner !== el) pendingCheckSources?.add(owner);
2383
+ if (owner !== el) pendingProbe.sources.add(owner);
2264
2384
  }
2265
2385
  function computePendingState(el) {
2266
2386
  const comp = el;
2387
+ if (comp._flags & REACTIVE_DISPOSED) return false;
2267
2388
  const firewall = el._firewall;
2389
+ if ((firewall || comp)._optimisticMask) return false;
2268
2390
  if (el._parentSource) {
2269
- const parent = el._parentSource;
2270
- if (parent._statusFlags & STATUS_PENDING && !(parent._statusFlags & STATUS_UNINITIALIZED))
2271
- return true;
2272
- return el._pendingValue !== NOT_PENDING && !(comp._statusFlags & STATUS_UNINITIALIZED);
2391
+ const parentNode = el._parentSource;
2392
+ if (hasActiveOverride(parentNode)) return false;
2393
+ const parent = parentNode._firewall || parentNode;
2394
+ if (parent._optimisticMask) return false;
2395
+ return !!(
2396
+ parent._statusFlags & STATUS_PENDING && !(parent._statusFlags & STATUS_UNINITIALIZED)
2397
+ );
2273
2398
  }
2399
+ if (hasActiveOverride(el)) return false;
2274
2400
  if (firewall && el._pendingValue !== NOT_PENDING) {
2275
2401
  return (
2276
2402
  !!(firewall._flags & REACTIVE_MANUAL_WRITE) ||
2277
2403
  (!firewall._inFlight && !(firewall._statusFlags & STATUS_PENDING))
2278
2404
  );
2279
2405
  }
2280
- if (el._overrideValue !== undefined && el._overrideValue !== NOT_PENDING) {
2281
- if (comp._statusFlags & STATUS_PENDING && !(comp._statusFlags & STATUS_UNINITIALIZED))
2282
- return true;
2283
- if (el._parentSource) {
2284
- const lane = el._optimisticLane ? findLane(el._optimisticLane) : null;
2285
- return !!(lane && lane._pendingAsync.size > 0);
2286
- }
2287
- return true;
2288
- }
2289
- if (el._overrideValue !== undefined && el._overrideValue === NOT_PENDING && !el._parentSource) {
2290
- return false;
2291
- }
2292
2406
  if (el._pendingValue !== NOT_PENDING && !(comp._statusFlags & STATUS_UNINITIALIZED)) return true;
2293
2407
  return !!(comp._statusFlags & STATUS_PENDING && !(comp._statusFlags & STATUS_UNINITIALIZED));
2294
2408
  }
2409
+ function syncCompanions(el, value) {
2410
+ if (el._pendingSignal) updatePendingSignal(el);
2411
+ if (el._latestValueComputed) setSignal(el._latestValueComputed, value);
2412
+ }
2295
2413
  function updatePendingSignal(el) {
2296
2414
  if (el._pendingSignal) {
2297
- const pending = computePendingState(el);
2298
- const sig = el._pendingSignal;
2299
- setSignal(sig, pending);
2300
- if (!pending && sig._optimisticLane) {
2301
- const sourceLane = resolveLane(el);
2302
- if (sourceLane && sourceLane._pendingAsync.size > 0) {
2303
- const sigLane = findLane(sig._optimisticLane);
2304
- if (sigLane !== sourceLane) {
2305
- mergeLanes(sourceLane, sigLane);
2306
- }
2307
- }
2308
- signalLanes.delete(sig);
2309
- sig._optimisticLane = undefined;
2415
+ setSignal(el._pendingSignal, computePendingState(el));
2416
+ }
2417
+ if (el._latestValueComputed) updatePendingSignal(el._latestValueComputed);
2418
+ }
2419
+ function updateChildCompanions(el) {
2420
+ for (let child = el._child; child !== null; child = child._nextChild) {
2421
+ if (child._pendingSignal || child._latestValueComputed) updatePendingSignal(child);
2422
+ }
2423
+ }
2424
+ function snapCompanionsToState(owner) {
2425
+ const sig = owner._pendingSignal;
2426
+ if (sig && (sig._overrideValue === undefined || sig._overrideValue === NOT_PENDING)) {
2427
+ const pending = computePendingState(owner);
2428
+ if (sig._value !== pending || sig._pendingValue !== NOT_PENDING) {
2429
+ sig._value = pending;
2430
+ sig._pendingValue = NOT_PENDING;
2431
+ sig._time = clock;
2432
+ insertSubs(sig);
2433
+ schedule();
2434
+ }
2435
+ }
2436
+ const shadow = owner._latestValueComputed;
2437
+ if (shadow && !(shadow._flags & REACTIVE_DISPOSED)) {
2438
+ if (
2439
+ (shadow._overrideValue === undefined || shadow._overrideValue === NOT_PENDING) &&
2440
+ shadow._pendingValue === NOT_PENDING &&
2441
+ !Object.is(shadow._value, owner._value) &&
2442
+ !(shadow._flags & (REACTIVE_DIRTY | REACTIVE_CHECK))
2443
+ ) {
2444
+ shadow._flags |= REACTIVE_DIRTY;
2445
+ insertIntoHeap(shadow, shadow._flags & REACTIVE_ZOMBIE ? zombieQueue : dirtyQueue);
2446
+ insertSubs(shadow);
2447
+ schedule();
2310
2448
  }
2449
+ snapCompanionsToState(shadow);
2311
2450
  }
2312
2451
  }
2313
2452
  function getLatestValueComputed(el) {
@@ -2346,18 +2485,16 @@ function latest(fn) {
2346
2485
  }
2347
2486
  function isPending(fn) {
2348
2487
  const prevPendingCheck = pendingCheckActive;
2349
- const prevFoundPending = foundPending;
2350
- const prevPendingCheckSources = pendingCheckSources;
2488
+ const prevProbe = pendingProbe;
2351
2489
  pendingCheckActive = true;
2352
- foundPending = false;
2353
- pendingCheckSources = new Set();
2490
+ const probe = (pendingProbe = { found: false, sources: new Set(), freshReads: new Set() });
2354
2491
  const collectPending = () => {
2355
2492
  pendingCheckActive = false;
2356
2493
  const prevStrictRead = strictRead;
2357
2494
  strictRead = false;
2358
2495
  try {
2359
- pendingCheckSources.forEach(source => {
2360
- if (read(getPendingSignal(source))) foundPending = true;
2496
+ probe.sources.forEach(source => {
2497
+ if (read(getPendingSignal(source)) && !probe.freshReads.has(source)) probe.found = true;
2361
2498
  });
2362
2499
  } finally {
2363
2500
  strictRead = prevStrictRead;
@@ -2367,18 +2504,17 @@ function isPending(fn) {
2367
2504
  try {
2368
2505
  fn();
2369
2506
  collectPending();
2370
- return foundPending;
2507
+ return probe.found;
2371
2508
  } catch (e) {
2372
2509
  collectPending();
2373
2510
  if (e instanceof NotReadyError) {
2374
- if (foundPending && !(e.source?._statusFlags & STATUS_UNINITIALIZED)) return true;
2511
+ if (probe.found && !(e.source?._statusFlags & STATUS_UNINITIALIZED)) return true;
2375
2512
  if (context) throw e;
2376
2513
  }
2377
- return foundPending;
2514
+ return probe.found;
2378
2515
  } finally {
2379
2516
  pendingCheckActive = prevPendingCheck;
2380
- foundPending = prevFoundPending;
2381
- pendingCheckSources = prevPendingCheckSources;
2517
+ pendingProbe = prevProbe;
2382
2518
  }
2383
2519
  }
2384
2520
  function refresh(target) {
@@ -2485,50 +2621,66 @@ function notifyEffectStatus(status, error) {
2485
2621
  const actualStatus = status !== undefined ? status : this._statusFlags;
2486
2622
  const actualError = error !== undefined ? error : this._error;
2487
2623
  if (actualStatus & STATUS_ERROR) {
2488
- let err = actualError;
2489
2624
  this._queue.notify(this, STATUS_PENDING, 0);
2490
2625
  if (this._type === EFFECT_USER) {
2491
- try {
2492
- return this._errorFn
2493
- ? this._errorFn(err, () => {
2494
- this._cleanup?.();
2495
- this._cleanup = undefined;
2496
- })
2497
- : console.error(err);
2498
- } catch (e) {
2499
- err = e;
2626
+ if (this._statusFlags & STATUS_ERROR) {
2627
+ this._modified = true;
2628
+ this._queue.enqueue(this._type, (this._boundRunEffect ??= runEffect.bind(null, this)));
2500
2629
  }
2630
+ return;
2631
+ }
2632
+ if (!this._queue.notify(this, STATUS_ERROR, STATUS_ERROR)) {
2633
+ haltReactivity();
2634
+ throw actualError;
2501
2635
  }
2502
- if (!this._queue.notify(this, STATUS_ERROR, STATUS_ERROR)) throw err;
2503
2636
  } else if (this._type === EFFECT_RENDER) {
2504
2637
  this._queue.notify(this, STATUS_PENDING | STATUS_ERROR, actualStatus, actualError);
2505
2638
  if (_hitUnhandledAsync) {
2506
2639
  resetUnhandledAsync();
2507
- if (!this._queue.notify(this, STATUS_ERROR, STATUS_ERROR)) {
2508
- const message =
2509
- "[ASYNC_OUTSIDE_LOADING_BOUNDARY] An async value was read outside a Loading boundary. The root mount will be deferred until all pending async settles.";
2510
- emitDiagnostic({
2511
- code: "ASYNC_OUTSIDE_LOADING_BOUNDARY",
2512
- kind: "async",
2513
- severity: "warn",
2514
- message: message,
2515
- ownerId: this.id,
2516
- ownerName: this._name
2517
- });
2518
- console.warn(message);
2519
- }
2640
+ const message =
2641
+ "[ASYNC_OUTSIDE_LOADING_BOUNDARY] An async value was read outside a Loading boundary. The root mount will be deferred until all pending async settles.";
2642
+ emitDiagnostic({
2643
+ code: "ASYNC_OUTSIDE_LOADING_BOUNDARY",
2644
+ kind: "async",
2645
+ severity: "warn",
2646
+ message: message,
2647
+ ownerId: this.id,
2648
+ ownerName: this._name
2649
+ });
2650
+ console.warn(message);
2520
2651
  }
2521
2652
  }
2522
2653
  }
2523
2654
  function runEffect(node) {
2524
2655
  if (!node._modified || node._flags & REACTIVE_DISPOSED) return;
2656
+ if (node._statusFlags & STATUS_ERROR && node._type === EFFECT_USER) {
2657
+ const err = unwrapStatusError(node._error);
2658
+ node._prevValue = node._value;
2659
+ node._modified = false;
2660
+ try {
2661
+ node._errorFn
2662
+ ? node._errorFn(err, () => {
2663
+ const prevCleanup = node._cleanup;
2664
+ node._cleanup = undefined;
2665
+ prevCleanup?.();
2666
+ })
2667
+ : console.error(err);
2668
+ } catch (error) {
2669
+ if (!node._queue.notify(node, STATUS_ERROR, STATUS_ERROR)) {
2670
+ haltReactivity();
2671
+ throw error;
2672
+ }
2673
+ }
2674
+ return;
2675
+ }
2525
2676
  let prevStrictRead = false;
2526
2677
  {
2527
2678
  prevStrictRead = setStrictRead("an effect callback");
2528
2679
  }
2529
- node._cleanup?.();
2680
+ const prevCleanup = node._cleanup;
2530
2681
  node._cleanup = undefined;
2531
2682
  try {
2683
+ prevCleanup?.();
2532
2684
  const nextCleanup = node._effectFn(node._value, node._prevValue);
2533
2685
  if (true && nextCleanup !== undefined && typeof nextCleanup !== "function") {
2534
2686
  throw new Error(
@@ -2536,14 +2688,13 @@ function runEffect(node) {
2536
2688
  );
2537
2689
  }
2538
2690
  node._cleanup = nextCleanup;
2539
- if (node._cleanup && !node._cleanupRegistered) {
2540
- node._cleanupRegistered = true;
2541
- runWithOwner(node._parent, () => cleanup(() => node._cleanup?.()));
2542
- }
2543
2691
  } catch (error) {
2544
2692
  node._error = new StatusError(node, error);
2545
2693
  node._statusFlags |= STATUS_ERROR;
2546
- if (!node._queue.notify(node, STATUS_ERROR, STATUS_ERROR)) throw error;
2694
+ if (!node._queue.notify(node, STATUS_ERROR, STATUS_ERROR)) {
2695
+ haltReactivity();
2696
+ throw error;
2697
+ }
2547
2698
  } finally {
2548
2699
  setStrictRead(prevStrictRead);
2549
2700
  node._prevValue = node._value;
@@ -2564,8 +2715,9 @@ function trackedEffect(fn, options) {
2564
2715
  };
2565
2716
  const node = computed(
2566
2717
  () => {
2567
- node._cleanup?.();
2718
+ const prevCleanup = node._cleanup;
2568
2719
  node._cleanup = undefined;
2720
+ prevCleanup?.();
2569
2721
  const cleanup = staleValues(fn);
2570
2722
  if (cleanup !== undefined && typeof cleanup !== "function") {
2571
2723
  throw new Error(
@@ -2585,12 +2737,14 @@ function trackedEffect(fn, options) {
2585
2737
  if (actualStatus & STATUS_ERROR) {
2586
2738
  node._queue.notify(node, STATUS_PENDING, 0);
2587
2739
  const err = error !== undefined ? error : node._error;
2588
- if (!node._queue.notify(node, STATUS_ERROR, STATUS_ERROR)) throw err;
2740
+ if (!node._queue.notify(node, STATUS_ERROR, STATUS_ERROR)) {
2741
+ haltReactivity();
2742
+ throw err;
2743
+ }
2589
2744
  }
2590
2745
  };
2591
2746
  node._run = run;
2592
2747
  node._queue.enqueue(EFFECT_USER, run);
2593
- cleanup(() => node._cleanup?.());
2594
2748
  if (!node._parent) {
2595
2749
  const message =
2596
2750
  "[NO_OWNER_EFFECT] Effects created outside a reactive context will never be disposed";
@@ -2606,6 +2760,9 @@ function trackedEffect(fn, options) {
2606
2760
  console.warn(message);
2607
2761
  }
2608
2762
  }
2763
+ const ACTION_CALLED_IN_OWNED_SCOPE_MESSAGE =
2764
+ "[ACTION_CALLED_IN_OWNED_SCOPE] Calling an action inside an owned scope (component, computation) is not allowed. " +
2765
+ "Call it from an event handler or another imperative scope.";
2609
2766
  function restoreTransition(transition, fn) {
2610
2767
  globalQueue.initTransition(transition);
2611
2768
  const result = fn();
@@ -2613,34 +2770,47 @@ function restoreTransition(transition, fn) {
2613
2770
  return result;
2614
2771
  }
2615
2772
  function action(genFn) {
2616
- return (...args) =>
2617
- new Promise((resolve, reject) => {
2773
+ return (...args) => {
2774
+ {
2775
+ const owner = getOwner();
2776
+ if (owner && !(owner._config & CONFIG_CHILDREN_FORBIDDEN)) {
2777
+ emitDiagnostic({
2778
+ code: "ACTION_CALLED_IN_OWNED_SCOPE",
2779
+ kind: "write",
2780
+ severity: "error",
2781
+ message: ACTION_CALLED_IN_OWNED_SCOPE_MESSAGE,
2782
+ ownerId: owner.id,
2783
+ ownerName: owner._name
2784
+ });
2785
+ throw new Error(ACTION_CALLED_IN_OWNED_SCOPE_MESSAGE);
2786
+ }
2787
+ }
2788
+ return new Promise((resolve, reject) => {
2618
2789
  const it = genFn(...args);
2619
2790
  globalQueue.initTransition();
2620
2791
  let ctx = activeTransition;
2621
2792
  ctx._actions.push(it);
2622
- const done = (v, e) => {
2793
+ const done = (v, e, failed = false) => {
2623
2794
  ctx = currentTransition(ctx);
2624
2795
  const i = ctx._actions.indexOf(it);
2625
2796
  if (i >= 0) ctx._actions.splice(i, 1);
2626
2797
  setActiveTransition(ctx);
2627
2798
  schedule();
2628
- e ? reject(e) : resolve(v);
2799
+ failed ? reject(e) : resolve(v);
2629
2800
  };
2630
2801
  const step = (v, err) => {
2631
2802
  let r;
2632
2803
  try {
2633
2804
  r = err ? it.throw(v) : it.next(v);
2634
2805
  } catch (e) {
2635
- return done(undefined, e);
2806
+ return done(undefined, e, true);
2636
2807
  }
2637
- if (r instanceof Promise)
2638
- return void r.then(run, e => restoreTransition(ctx, () => step(e, true)));
2808
+ if (isThenable(r)) return void r.then(run, e => done(undefined, e, true));
2639
2809
  run(r);
2640
2810
  };
2641
2811
  const run = r => {
2642
2812
  if (r.done) return done(r.value);
2643
- if (r.value instanceof Promise)
2813
+ if (isThenable(r.value))
2644
2814
  return void r.value.then(
2645
2815
  v => restoreTransition(ctx, () => step(v)),
2646
2816
  e => restoreTransition(ctx, () => step(e, true))
@@ -2649,6 +2819,7 @@ function action(genFn) {
2649
2819
  };
2650
2820
  step();
2651
2821
  });
2822
+ };
2652
2823
  }
2653
2824
  function onCleanup(fn) {
2654
2825
  {
@@ -2727,11 +2898,17 @@ function createReaction(effectFn, options) {
2727
2898
  let cl = undefined;
2728
2899
  cleanup(() => cl?.());
2729
2900
  const owner = getOwner();
2901
+ let arm;
2730
2902
  return tracking => {
2903
+ if (arm) {
2904
+ dispose(arm);
2905
+ arm = undefined;
2906
+ }
2731
2907
  runWithOwner(owner, () => {
2732
2908
  effect(
2733
- () => (tracking(), getOwner()),
2909
+ () => (tracking(), (arm = getOwner())),
2734
2910
  node => {
2911
+ arm = undefined;
2735
2912
  cl?.();
2736
2913
  const cleanup = (effectFn.effect || effectFn)?.();
2737
2914
  if (true && cleanup !== undefined && typeof cleanup !== "function") {
@@ -2760,15 +2937,18 @@ function resolve(fn) {
2760
2937
  }
2761
2938
  return new Promise((res, rej) => {
2762
2939
  createRoot(dispose => {
2763
- computed(() => {
2764
- try {
2765
- res(fn());
2766
- } catch (err) {
2767
- if (err instanceof NotReadyError) throw err;
2940
+ effect(
2941
+ fn,
2942
+ value => {
2943
+ res(value);
2944
+ dispose();
2945
+ },
2946
+ err => {
2768
2947
  rej(err);
2769
- }
2770
- dispose();
2771
- });
2948
+ dispose();
2949
+ },
2950
+ { user: true }
2951
+ );
2772
2952
  });
2773
2953
  });
2774
2954
  }
@@ -2788,27 +2968,110 @@ function onSettled(callback) {
2788
2968
  ? createTrackedEffect(() => untrack(callback), { name: "onSettled" })
2789
2969
  : globalQueue.enqueue(EFFECT_USER, () => {
2790
2970
  const cleanup = callback();
2791
- if (cleanup !== undefined && typeof cleanup !== "function") {
2792
- throw new Error(
2793
- "onSettled callback returned an invalid cleanup value. Return a cleanup function or undefined."
2794
- );
2971
+ if (cleanup !== undefined) {
2972
+ const message =
2973
+ "[SETTLED_CLEANUP_UNOWNED] onSettled returned a cleanup in an unowned scope; a cleanup can only be honored under an owner. Call your setup helper from an owned scope (e.g. the component body) instead of from inside an event handler, tracked effect, or another onSettled.";
2974
+ emitDiagnostic({
2975
+ code: "SETTLED_CLEANUP_UNOWNED",
2976
+ kind: "lifecycle",
2977
+ severity: "error",
2978
+ message: message
2979
+ });
2980
+ throw new Error(message);
2795
2981
  }
2796
- cleanup?.();
2797
2982
  });
2798
2983
  }
2984
+ function nodeKeys(nodes) {
2985
+ const keys = Object.keys(nodes);
2986
+ if (symbolKeyedRecords.has(nodes)) {
2987
+ const syms = Object.getOwnPropertySymbols(nodes);
2988
+ for (let i = 0, len = syms.length; i < len; i++) {
2989
+ if (syms[i] !== $TRACK) keys.push(syms[i]);
2990
+ }
2991
+ }
2992
+ return keys;
2993
+ }
2799
2994
  function unwrap(value) {
2800
- return value?.[$TARGET]?.[STORE_NODE] ?? value;
2995
+ if (value === null || typeof value !== "object") return value;
2996
+ return value[$TARGET]?.[STORE_VALUE] ?? value;
2801
2997
  }
2802
2998
  function getOverrideValue(value, override, key, optOverride) {
2803
2999
  if (optOverride && key in optOverride) return optOverride[key];
2804
3000
  return override && key in override ? override[key] : value[key];
2805
3001
  }
3002
+ function addEnumSymbols(o, syms, keys) {
3003
+ for (let i = 0, len = syms.length; i < len; i++) {
3004
+ if (Object.prototype.propertyIsEnumerable.call(o, syms[i])) keys.add(syms[i]);
3005
+ }
3006
+ }
2806
3007
  function getAllKeys(value, override, next) {
2807
3008
  const keys = getKeys(value, override);
2808
3009
  const nextKeys = Object.keys(next);
2809
- return Array.from(new Set([...keys, ...nextKeys]));
3010
+ const valueSyms = value[$TARGET]
3011
+ ? untrack(() => Object.getOwnPropertySymbols(value))
3012
+ : Object.getOwnPropertySymbols(value);
3013
+ const nextSyms = Object.getOwnPropertySymbols(next);
3014
+ if (valueSyms.length === 0 && nextSyms.length === 0) {
3015
+ if (keys.length === nextKeys.length) {
3016
+ let same = true;
3017
+ for (let i = 0; i < keys.length; i++) {
3018
+ if (keys[i] !== nextKeys[i]) {
3019
+ same = false;
3020
+ break;
3021
+ }
3022
+ }
3023
+ if (same) return keys;
3024
+ }
3025
+ const set = new Set(keys);
3026
+ for (let i = 0; i < nextKeys.length; i++) set.add(nextKeys[i]);
3027
+ return Array.from(set);
3028
+ }
3029
+ const set = new Set(keys);
3030
+ addEnumSymbols(value, valueSyms, set);
3031
+ if (override) {
3032
+ for (const key of Reflect.ownKeys(override)) {
3033
+ override[key] === $DELETED ? set.delete(key) : set.add(key);
3034
+ }
3035
+ }
3036
+ for (let i = 0; i < nextKeys.length; i++) set.add(nextKeys[i]);
3037
+ addEnumSymbols(next, nextSyms, set);
3038
+ return Array.from(set);
3039
+ }
3040
+ function wrapValue(value, target) {
3041
+ return isWrappable(value) ? wrap(value, target) : value;
3042
+ }
3043
+ function itemKey(item, keyFn) {
3044
+ return isWrappable(item) ? keyFn(item) : item;
3045
+ }
3046
+ function keyedMatch(a, b, keyFn) {
3047
+ return a === b || (isWrappable(a) && isWrappable(b) && keyFn(a) === keyFn(b));
3048
+ }
3049
+ function syncArrayNodeMembership(target, next) {
3050
+ let nodes = target[STORE_NODE];
3051
+ if (nodes) {
3052
+ const keys = nodeKeys(nodes);
3053
+ for (let i = 0, len = keys.length; i < len; i++) {
3054
+ const key = keys[i];
3055
+ key in next || setSignal(nodes[key], undefined);
3056
+ }
3057
+ }
3058
+ if ((nodes = target[STORE_HAS])) {
3059
+ const keys = nodeKeys(nodes);
3060
+ for (let i = 0, len = keys.length; i < len; i++) {
3061
+ const key = keys[i];
3062
+ setSignal(nodes[key], key in next);
3063
+ }
3064
+ }
3065
+ }
3066
+ function applyArrayItem(next, previous, target, node, keyFn) {
3067
+ if (isWrappable(next) && isWrappable(previous)) {
3068
+ const wrapped = wrap(previous, target);
3069
+ node && setSignal(node, wrapped);
3070
+ applyState(next, wrapped, keyFn);
3071
+ } else node && setSignal(node, wrapValue(next, target));
2810
3072
  }
2811
3073
  function applyState(next, state, keyFn) {
3074
+ next = unwrap(next);
2812
3075
  const target = state?.[$TARGET];
2813
3076
  if (!target) return;
2814
3077
  if (target[STORE_OVERRIDE] || target[STORE_OPTIMISTIC_OVERRIDE]) {
@@ -2826,25 +3089,22 @@ function applyStateFast(next, target, keyFn) {
2826
3089
  if (Array.isArray(previous)) {
2827
3090
  let changed = false;
2828
3091
  const prevLength = previous.length;
2829
- if (next.length && prevLength && next[0] && keyFn(next[0]) != null) {
3092
+ if (next.length && prevLength && isWrappable(next[0]) && keyFn(next[0]) != null) {
2830
3093
  let i, j, start, end, newEnd, item, newIndicesNext, keyVal;
2831
3094
  for (
2832
3095
  start = 0, end = Math.min(prevLength, next.length);
2833
- start < end &&
2834
- ((item = previous[start]) === next[start] ||
2835
- (item && next[start] && keyFn(item) === keyFn(next[start])));
3096
+ start < end && keyedMatch((item = previous[start]), next[start], keyFn);
2836
3097
  start++
2837
3098
  ) {
2838
- applyState(next[start], wrap(item, target), keyFn);
3099
+ isWrappable(item) &&
3100
+ isWrappable(next[start]) &&
3101
+ applyState(next[start], wrap(item, target), keyFn);
2839
3102
  }
2840
3103
  const temp = new Array(next.length),
2841
3104
  newIndices = new Map();
2842
3105
  for (
2843
3106
  end = prevLength - 1, newEnd = next.length - 1;
2844
- end >= start &&
2845
- newEnd >= start &&
2846
- ((item = previous[end]) === next[newEnd] ||
2847
- (item && next[newEnd] && keyFn(item) === keyFn(next[newEnd])));
3107
+ end >= start && newEnd >= start && keyedMatch((item = previous[end]), next[newEnd], keyFn);
2848
3108
  end--, newEnd--
2849
3109
  ) {
2850
3110
  temp[newEnd] = item;
@@ -2852,15 +3112,14 @@ function applyStateFast(next, target, keyFn) {
2852
3112
  if (start > newEnd || start > end) {
2853
3113
  for (j = start; j <= newEnd; j++) {
2854
3114
  changed = true;
2855
- arrayNodes?.[j] && setSignal(arrayNodes[j], wrap(next[j], target));
3115
+ arrayNodes?.[j] && setSignal(arrayNodes[j], wrapValue(next[j], target));
2856
3116
  }
2857
3117
  for (; j < next.length; j++) {
2858
3118
  changed = true;
2859
- const wrapped = wrap(temp[j], target);
2860
- arrayNodes?.[j] && setSignal(arrayNodes[j], wrapped);
2861
- applyState(next[j], wrapped, keyFn);
3119
+ applyArrayItem(next[j], temp[j], target, arrayNodes?.[j], keyFn);
2862
3120
  }
2863
- changed && notifySelf(target);
3121
+ syncArrayNodeMembership(target, next);
3122
+ (changed || prevLength !== next.length) && notifySelf(target);
2864
3123
  prevLength !== next.length &&
2865
3124
  arrayNodes?.length &&
2866
3125
  setSignal(arrayNodes.length, next.length);
@@ -2869,14 +3128,14 @@ function applyStateFast(next, target, keyFn) {
2869
3128
  newIndicesNext = new Array(newEnd + 1);
2870
3129
  for (j = newEnd; j >= start; j--) {
2871
3130
  item = next[j];
2872
- keyVal = item ? keyFn(item) : item;
3131
+ keyVal = itemKey(item, keyFn);
2873
3132
  i = newIndices.get(keyVal);
2874
3133
  newIndicesNext[j] = i === undefined ? -1 : i;
2875
3134
  newIndices.set(keyVal, j);
2876
3135
  }
2877
3136
  for (i = start; i <= end; i++) {
2878
3137
  item = previous[i];
2879
- keyVal = item ? keyFn(item) : item;
3138
+ keyVal = itemKey(item, keyFn);
2880
3139
  j = newIndices.get(keyVal);
2881
3140
  if (j !== undefined && j !== -1) {
2882
3141
  temp[j] = item;
@@ -2886,22 +3145,22 @@ function applyStateFast(next, target, keyFn) {
2886
3145
  }
2887
3146
  for (j = start; j < next.length; j++) {
2888
3147
  if (j in temp) {
2889
- const wrapped = wrap(temp[j], target);
2890
- arrayNodes?.[j] && setSignal(arrayNodes[j], wrapped);
2891
- applyState(next[j], wrapped, keyFn);
2892
- } else arrayNodes?.[j] && setSignal(arrayNodes[j], wrap(next[j], target));
3148
+ applyArrayItem(next[j], temp[j], target, arrayNodes?.[j], keyFn);
3149
+ } else arrayNodes?.[j] && setSignal(arrayNodes[j], wrapValue(next[j], target));
2893
3150
  }
2894
3151
  if (start < next.length) changed = true;
2895
3152
  } else if (next.length) {
2896
3153
  for (let i = 0, len = next.length; i < len; i++) {
2897
3154
  const item = previous[i];
2898
- if (isWrappable(item)) applyState(next[i], wrap(item, target), keyFn);
3155
+ if (isWrappable(item) && isWrappable(next[i]))
3156
+ applyState(next[i], wrap(item, target), keyFn);
2899
3157
  else {
2900
3158
  if (item !== next[i]) changed = true;
2901
- arrayNodes?.[i] && setSignal(arrayNodes[i], next[i]);
3159
+ arrayNodes?.[i] && setSignal(arrayNodes[i], wrapValue(next[i], target));
2902
3160
  }
2903
3161
  }
2904
3162
  }
3163
+ syncArrayNodeMembership(target, next);
2905
3164
  if (prevLength !== next.length) {
2906
3165
  changed = true;
2907
3166
  arrayNodes?.length && setSignal(arrayNodes.length, next.length);
@@ -2912,7 +3171,7 @@ function applyStateFast(next, target, keyFn) {
2912
3171
  let nodes = target[STORE_NODE];
2913
3172
  if (nodes) {
2914
3173
  const tracked = nodes[$TRACK];
2915
- const keys = tracked ? getAllKeys(previous, undefined, next) : Object.keys(nodes);
3174
+ const keys = tracked ? getAllKeys(previous, undefined, next) : nodeKeys(nodes);
2916
3175
  for (let i = 0, len = keys.length; i < len; i++) {
2917
3176
  const key = keys[i];
2918
3177
  const node = nodes[key];
@@ -2923,6 +3182,7 @@ function applyStateFast(next, target, keyFn) {
2923
3182
  !previousValue ||
2924
3183
  !isWrappable(previousValue) ||
2925
3184
  !isWrappable(nextValue) ||
3185
+ Array.isArray(previousValue) !== Array.isArray(nextValue) ||
2926
3186
  (keyFn(previousValue) != null && keyFn(previousValue) !== keyFn(nextValue))
2927
3187
  ) {
2928
3188
  tracked && setSignal(tracked, void 0);
@@ -2931,7 +3191,7 @@ function applyStateFast(next, target, keyFn) {
2931
3191
  }
2932
3192
  }
2933
3193
  if ((nodes = target[STORE_HAS])) {
2934
- const keys = Object.keys(nodes);
3194
+ const keys = nodeKeys(nodes);
2935
3195
  for (let i = 0, len = keys.length; i < len; i++) {
2936
3196
  const key = keys[i];
2937
3197
  setSignal(nodes[key], key in next);
@@ -2949,16 +3209,21 @@ function applyStateSlow(next, target, keyFn) {
2949
3209
  if (Array.isArray(previous)) {
2950
3210
  let changed = false;
2951
3211
  const prevLength = getOverrideValue(previous, override, "length", optOverride);
2952
- if (next.length && prevLength && next[0] && keyFn(next[0]) != null) {
3212
+ if (next.length && prevLength && isWrappable(next[0]) && keyFn(next[0]) != null) {
2953
3213
  let i, j, start, end, newEnd, item, newIndicesNext, keyVal;
2954
3214
  for (
2955
3215
  start = 0, end = Math.min(prevLength, next.length);
2956
3216
  start < end &&
2957
- ((item = getOverrideValue(previous, override, start, optOverride)) === next[start] ||
2958
- (item && next[start] && keyFn(item) === keyFn(next[start])));
3217
+ keyedMatch(
3218
+ (item = getOverrideValue(previous, override, start, optOverride)),
3219
+ next[start],
3220
+ keyFn
3221
+ );
2959
3222
  start++
2960
3223
  ) {
2961
- applyState(next[start], wrap(item, target), keyFn);
3224
+ isWrappable(item) &&
3225
+ isWrappable(next[start]) &&
3226
+ applyState(next[start], wrap(item, target), keyFn);
2962
3227
  }
2963
3228
  const temp = new Array(next.length),
2964
3229
  newIndices = new Map();
@@ -2966,8 +3231,11 @@ function applyStateSlow(next, target, keyFn) {
2966
3231
  end = prevLength - 1, newEnd = next.length - 1;
2967
3232
  end >= start &&
2968
3233
  newEnd >= start &&
2969
- ((item = getOverrideValue(previous, override, end, optOverride)) === next[newEnd] ||
2970
- (item && next[newEnd] && keyFn(item) === keyFn(next[newEnd])));
3234
+ keyedMatch(
3235
+ (item = getOverrideValue(previous, override, end, optOverride)),
3236
+ next[newEnd],
3237
+ keyFn
3238
+ );
2971
3239
  end--, newEnd--
2972
3240
  ) {
2973
3241
  temp[newEnd] = item;
@@ -2975,30 +3243,29 @@ function applyStateSlow(next, target, keyFn) {
2975
3243
  if (start > newEnd || start > end) {
2976
3244
  for (j = start; j <= newEnd; j++) {
2977
3245
  changed = true;
2978
- nodes?.[j] && setSignal(nodes[j], wrap(next[j], target));
3246
+ nodes?.[j] && setSignal(nodes[j], wrapValue(next[j], target));
2979
3247
  }
2980
3248
  for (; j < next.length; j++) {
2981
3249
  changed = true;
2982
- const wrapped = wrap(temp[j], target);
2983
- nodes?.[j] && setSignal(nodes[j], wrapped);
2984
- applyState(next[j], wrapped, keyFn);
3250
+ applyArrayItem(next[j], temp[j], target, nodes?.[j], keyFn);
2985
3251
  }
2986
3252
  const nextLength = next.length;
2987
- changed && notifySelf(target);
3253
+ syncArrayNodeMembership(target, next);
3254
+ (changed || prevLength !== nextLength) && notifySelf(target);
2988
3255
  prevLength !== nextLength && nodes?.length && setSignal(nodes.length, nextLength);
2989
3256
  return;
2990
3257
  }
2991
3258
  newIndicesNext = new Array(newEnd + 1);
2992
3259
  for (j = newEnd; j >= start; j--) {
2993
3260
  item = next[j];
2994
- keyVal = item ? keyFn(item) : item;
3261
+ keyVal = itemKey(item, keyFn);
2995
3262
  i = newIndices.get(keyVal);
2996
3263
  newIndicesNext[j] = i === undefined ? -1 : i;
2997
3264
  newIndices.set(keyVal, j);
2998
3265
  }
2999
3266
  for (i = start; i <= end; i++) {
3000
3267
  item = getOverrideValue(previous, override, i, optOverride);
3001
- keyVal = item ? keyFn(item) : item;
3268
+ keyVal = itemKey(item, keyFn);
3002
3269
  j = newIndices.get(keyVal);
3003
3270
  if (j !== undefined && j !== -1) {
3004
3271
  temp[j] = item;
@@ -3008,23 +3275,23 @@ function applyStateSlow(next, target, keyFn) {
3008
3275
  }
3009
3276
  for (j = start; j < next.length; j++) {
3010
3277
  if (j in temp) {
3011
- const wrapped = wrap(temp[j], target);
3012
- nodes?.[j] && setSignal(nodes[j], wrapped);
3013
- applyState(next[j], wrapped, keyFn);
3014
- } else nodes?.[j] && setSignal(nodes[j], wrap(next[j], target));
3278
+ applyArrayItem(next[j], temp[j], target, nodes?.[j], keyFn);
3279
+ } else nodes?.[j] && setSignal(nodes[j], wrapValue(next[j], target));
3015
3280
  }
3016
3281
  if (start < next.length) changed = true;
3017
3282
  } else if (next.length) {
3018
3283
  for (let i = 0, len = next.length; i < len; i++) {
3019
3284
  const item = getOverrideValue(previous, override, i, optOverride);
3020
- if (isWrappable(item)) applyState(next[i], wrap(item, target), keyFn);
3285
+ if (isWrappable(item) && isWrappable(next[i]))
3286
+ applyState(next[i], wrap(item, target), keyFn);
3021
3287
  else {
3022
3288
  if (item !== next[i]) changed = true;
3023
- nodes?.[i] && setSignal(nodes[i], next[i]);
3289
+ nodes?.[i] && setSignal(nodes[i], wrapValue(next[i], target));
3024
3290
  }
3025
3291
  }
3026
3292
  }
3027
3293
  const nextLength = next.length;
3294
+ syncArrayNodeMembership(target, next);
3028
3295
  if (prevLength !== nextLength) {
3029
3296
  changed = true;
3030
3297
  nodes?.length && setSignal(nodes.length, nextLength);
@@ -3034,7 +3301,7 @@ function applyStateSlow(next, target, keyFn) {
3034
3301
  }
3035
3302
  if (nodes) {
3036
3303
  const tracked = nodes[$TRACK];
3037
- const keys = tracked ? getAllKeys(previous, override, next) : Object.keys(nodes);
3304
+ const keys = tracked ? getAllKeys(previous, override, next) : nodeKeys(nodes);
3038
3305
  for (let i = 0, len = keys.length; i < len; i++) {
3039
3306
  const key = keys[i];
3040
3307
  const node = nodes[key];
@@ -3045,6 +3312,7 @@ function applyStateSlow(next, target, keyFn) {
3045
3312
  !previousValue ||
3046
3313
  !isWrappable(previousValue) ||
3047
3314
  !isWrappable(nextValue) ||
3315
+ Array.isArray(previousValue) !== Array.isArray(nextValue) ||
3048
3316
  (keyFn(previousValue) != null && keyFn(previousValue) !== keyFn(nextValue))
3049
3317
  ) {
3050
3318
  tracked && setSignal(tracked, void 0);
@@ -3053,7 +3321,7 @@ function applyStateSlow(next, target, keyFn) {
3053
3321
  }
3054
3322
  }
3055
3323
  if ((nodes = target[STORE_HAS])) {
3056
- const keys = Object.keys(nodes);
3324
+ const keys = nodeKeys(nodes);
3057
3325
  for (let i = 0, len = keys.length; i < len; i++) {
3058
3326
  const key = keys[i];
3059
3327
  setSignal(nodes[key], key in next);
@@ -3193,7 +3461,8 @@ const STORE_VALUE = "v",
3193
3461
  STORE_WRAP = "w",
3194
3462
  STORE_LOOKUP = "l",
3195
3463
  STORE_FIREWALL = "f",
3196
- STORE_OPTIMISTIC = "p";
3464
+ STORE_OPTIMISTIC = "p",
3465
+ STORE_MASKED = "m";
3197
3466
  const STORE_SELF_PENDING = Symbol("STORE_SELF_PENDING");
3198
3467
  function createStoreProxy(value, traps = storeTraps, extend) {
3199
3468
  let newTarget;
@@ -3212,6 +3481,7 @@ function createStoreProxy(value, traps = storeTraps, extend) {
3212
3481
  return (newTarget[$PROXY] = new Proxy(newTarget, traps));
3213
3482
  }
3214
3483
  const storeLookup = new WeakMap();
3484
+ const symbolKeyedRecords = new WeakSet();
3215
3485
  function wrap(value, target) {
3216
3486
  if (target?.[STORE_WRAP]) return target[STORE_WRAP](value, target);
3217
3487
  let p = value[$PROXY] || storeLookup.get(value);
@@ -3252,21 +3522,26 @@ function unwrapStoreValue(value, map, lookup) {
3252
3522
  function isPrototypePollutionKey$1(property) {
3253
3523
  return property === "__proto__" || property === "constructor" || property === "prototype";
3254
3524
  }
3255
- function hasOwnStoreProperty(target, property) {
3256
- const optimisticOverride = target[STORE_OPTIMISTIC_OVERRIDE];
3257
- if (
3258
- optimisticOverride &&
3259
- Object.prototype.hasOwnProperty.call(optimisticOverride, property) &&
3260
- optimisticOverride[property] !== $DELETED
3261
- )
3262
- return true;
3525
+ function ownEnumerableKeys(o) {
3526
+ return Reflect.ownKeys(o).filter(k => Object.prototype.propertyIsEnumerable.call(o, k));
3527
+ }
3528
+ function getOverlayLayer(target, property) {
3529
+ const opt = target[STORE_OPTIMISTIC_OVERRIDE];
3530
+ if (opt && property in opt) return opt;
3263
3531
  const override = target[STORE_OVERRIDE];
3264
- if (
3265
- override &&
3266
- Object.prototype.hasOwnProperty.call(override, property) &&
3267
- override[property] !== $DELETED
3268
- )
3269
- return true;
3532
+ if (override && property in override) return override;
3533
+ return undefined;
3534
+ }
3535
+ function visibleNodeValue(node) {
3536
+ return node._overrideValue !== undefined && node._overrideValue !== NOT_PENDING
3537
+ ? node._overrideValue
3538
+ : node._pendingValue !== NOT_PENDING
3539
+ ? node._pendingValue
3540
+ : node._value;
3541
+ }
3542
+ function hasOwnStoreProperty(target, property) {
3543
+ const layer = getOverlayLayer(target, property);
3544
+ if (layer) return layer[property] !== $DELETED;
3270
3545
  return Object.prototype.hasOwnProperty.call(unwrapStoreValue(target[STORE_VALUE]), property);
3271
3546
  }
3272
3547
  function hasInheritedAccessor(source, property) {
@@ -3290,7 +3565,24 @@ function getNode(nodes, property, value, firewall, equals = isEqual, optimistic,
3290
3565
  {
3291
3566
  equals: equals,
3292
3567
  unobserved() {
3293
- if (nodes[property] === s) delete nodes[property];
3568
+ if (nodes[property] === s) {
3569
+ delete nodes[property];
3570
+ if (
3571
+ typeof property === "symbol" &&
3572
+ property !== $TRACK &&
3573
+ symbolKeyedRecords.has(nodes)
3574
+ ) {
3575
+ const syms = Object.getOwnPropertySymbols(nodes);
3576
+ let hasUserSymbol = false;
3577
+ for (let i = 0, len = syms.length; i < len; i++) {
3578
+ if (syms[i] !== $TRACK) {
3579
+ hasUserSymbol = true;
3580
+ break;
3581
+ }
3582
+ }
3583
+ if (!hasUserSymbol) symbolKeyedRecords.delete(nodes);
3584
+ }
3585
+ }
3294
3586
  }
3295
3587
  },
3296
3588
  firewall
@@ -3303,20 +3595,28 @@ function getNode(nodes, property, value, firewall, equals = isEqual, optimistic,
3303
3595
  s._snapshotValue = sv === undefined ? NO_SNAPSHOT : sv;
3304
3596
  snapshotSources?.add(s);
3305
3597
  }
3598
+ if (typeof property === "symbol" && property !== $TRACK) symbolKeyedRecords.add(nodes);
3306
3599
  return (nodes[property] = s);
3307
3600
  }
3308
3601
  function trackSelf(target, symbol = $TRACK) {
3309
- getObserver() &&
3310
- read(
3311
- getNode(
3312
- getNodes(target, STORE_NODE),
3313
- symbol,
3314
- undefined,
3315
- target[STORE_FIREWALL],
3316
- false,
3317
- target[STORE_OPTIMISTIC]
3318
- )
3319
- );
3602
+ if (!getObserver()) return;
3603
+ read(
3604
+ getNode(
3605
+ getNodes(target, STORE_NODE),
3606
+ symbol,
3607
+ undefined,
3608
+ target[STORE_FIREWALL],
3609
+ false,
3610
+ target[STORE_OPTIMISTIC]
3611
+ )
3612
+ );
3613
+ if (
3614
+ symbol === $TRACK &&
3615
+ !target[STORE_OVERRIDE] &&
3616
+ !target[STORE_OPTIMISTIC_OVERRIDE] &&
3617
+ target[STORE_VALUE][$TARGET]
3618
+ )
3619
+ target[STORE_VALUE][$TRACK];
3320
3620
  }
3321
3621
  function notifySelf(target) {
3322
3622
  const node = target[STORE_NODE]?.[$TRACK];
@@ -3327,7 +3627,11 @@ function notifySelf(target) {
3327
3627
  );
3328
3628
  }
3329
3629
  function getKeys(source, override, enumerable = true) {
3330
- const baseKeys = untrack(() => (enumerable ? Object.keys(source) : Reflect.ownKeys(source)));
3630
+ const baseKeys = source[$TARGET]
3631
+ ? untrack(() => (enumerable ? Object.keys(source) : Reflect.ownKeys(source)))
3632
+ : enumerable
3633
+ ? Object.keys(source)
3634
+ : Reflect.ownKeys(source);
3331
3635
  if (!override) return baseKeys;
3332
3636
  const keys = new Set(baseKeys);
3333
3637
  const overrides = Reflect.ownKeys(override);
@@ -3341,10 +3645,26 @@ function getPropertyDescriptor(source, override, property) {
3341
3645
  if (override && property in override) {
3342
3646
  if (override[property] === $DELETED) return void 0;
3343
3647
  const overrideDesc = Reflect.getOwnPropertyDescriptor(override, property);
3344
- if (overrideDesc?.get || overrideDesc?.set || !(property in source)) return overrideDesc;
3648
+ if (overrideDesc?.get || overrideDesc?.set) return overrideDesc;
3649
+ const baseDesc = Reflect.getOwnPropertyDescriptor(source, property);
3650
+ if (!baseDesc) return overrideDesc;
3651
+ if (baseDesc.get || baseDesc.set) return baseDesc;
3652
+ baseDesc.value = override[property];
3653
+ return baseDesc;
3345
3654
  }
3346
3655
  return Reflect.getOwnPropertyDescriptor(source, property);
3347
3656
  }
3657
+ function maskStoreTarget(target, on) {
3658
+ const firewall = target[STORE_FIREWALL];
3659
+ if (!firewall) return;
3660
+ if (!!target[STORE_MASKED] === on) return;
3661
+ target[STORE_MASKED] = on;
3662
+ const count = (firewall._optimisticMask = (firewall._optimisticMask || 0) + (on ? 1 : -1));
3663
+ if ((on && count === 1) || (!on && count === 0)) {
3664
+ updatePendingSignal(firewall);
3665
+ updateChildCompanions(firewall);
3666
+ }
3667
+ }
3348
3668
  function prepareStoreWrite(target, store, property) {
3349
3669
  if (target[STORE_OPTIMISTIC]) {
3350
3670
  const firewall = target[STORE_FIREWALL];
@@ -3369,9 +3689,14 @@ function prepareStoreWrite(target, store, property) {
3369
3689
  }
3370
3690
  const useOptimistic = target[STORE_OPTIMISTIC] && !projectionWriteActive;
3371
3691
  const overrideKey = useOptimistic ? STORE_OPTIMISTIC_OVERRIDE : STORE_OVERRIDE;
3372
- if (useOptimistic) trackOptimisticStore(store);
3373
3692
  return { base: base, overrideKey: overrideKey, state: state };
3374
3693
  }
3694
+ function armOptimisticStoreWrite(target, store) {
3695
+ if (target[STORE_OPTIMISTIC] && !projectionWriteActive) {
3696
+ trackOptimisticStore(store);
3697
+ maskStoreTarget(target, true);
3698
+ }
3699
+ }
3375
3700
  function upsertStoreNode(target, nodes, property, prev, snapshotProps) {
3376
3701
  if (nodes[property]) return nodes[property];
3377
3702
  const initial = isWrappable(prev) ? wrap(prev, target) : prev;
@@ -3449,16 +3774,10 @@ const storeTraps = {
3449
3774
  ) {
3450
3775
  return read(getNode(nodes, property, undefined, target[STORE_FIREWALL]));
3451
3776
  }
3452
- const optOverridden =
3453
- target[STORE_OPTIMISTIC_OVERRIDE] && property in target[STORE_OPTIMISTIC_OVERRIDE];
3454
- const overridden =
3455
- optOverridden || (target[STORE_OVERRIDE] && property in target[STORE_OVERRIDE]);
3777
+ const overlay = getOverlayLayer(target, property);
3778
+ const overridden = !!overlay;
3456
3779
  const proxySource = !!target[STORE_VALUE][$TARGET];
3457
- const storeValue = optOverridden
3458
- ? target[STORE_OPTIMISTIC_OVERRIDE]
3459
- : target[STORE_OVERRIDE] && property in target[STORE_OVERRIDE]
3460
- ? target[STORE_OVERRIDE]
3461
- : target[STORE_VALUE];
3780
+ const storeValue = overlay ?? target[STORE_VALUE];
3462
3781
  if (!tracked) {
3463
3782
  const desc = Object.getOwnPropertyDescriptor(storeValue, property);
3464
3783
  if (desc && desc.get) return desc.get.call(receiver);
@@ -3473,13 +3792,7 @@ const storeTraps = {
3473
3792
  if (isPrototypePollutionKey$1(property) && !hasOwnStoreProperty(target, property))
3474
3793
  return undefined;
3475
3794
  let value =
3476
- tracked && (overridden || !proxySource)
3477
- ? tracked._overrideValue !== undefined && tracked._overrideValue !== NOT_PENDING
3478
- ? tracked._overrideValue
3479
- : tracked._pendingValue !== NOT_PENDING
3480
- ? tracked._pendingValue
3481
- : tracked._value
3482
- : storeValue[property];
3795
+ tracked && (overridden || !proxySource) ? visibleNodeValue(tracked) : storeValue[property];
3483
3796
  value === $DELETED && (value = undefined);
3484
3797
  if (!isWrappable(value)) return value;
3485
3798
  const wrapped = wrap(value, target);
@@ -3493,7 +3806,11 @@ const storeTraps = {
3493
3806
  : storeValue[property];
3494
3807
  value === $DELETED && (value = undefined);
3495
3808
  if (!tracked) {
3496
- if (!overridden && typeof value === "function" && !storeValue.hasOwnProperty(property)) {
3809
+ if (
3810
+ !overridden &&
3811
+ typeof value === "function" &&
3812
+ !Object.prototype.hasOwnProperty.call(storeValue, property)
3813
+ ) {
3497
3814
  let proto;
3498
3815
  return !Array.isArray(target[STORE_VALUE]) &&
3499
3816
  (proto = Object.getPrototypeOf(target[STORE_VALUE])) &&
@@ -3532,12 +3849,8 @@ const storeTraps = {
3532
3849
  },
3533
3850
  has(target, property) {
3534
3851
  if (property === $PROXY || property === $TRACK || property === "__proto__") return true;
3535
- const has =
3536
- target[STORE_OPTIMISTIC_OVERRIDE] && property in target[STORE_OPTIMISTIC_OVERRIDE]
3537
- ? target[STORE_OPTIMISTIC_OVERRIDE][property] !== $DELETED
3538
- : target[STORE_OVERRIDE] && property in target[STORE_OVERRIDE]
3539
- ? target[STORE_OVERRIDE][property] !== $DELETED
3540
- : property in target[STORE_VALUE];
3852
+ const hasLayer = getOverlayLayer(target, property);
3853
+ const has = hasLayer ? hasLayer[property] !== $DELETED : property in target[STORE_VALUE];
3541
3854
  if (writeOnly(target[$PROXY]) || getObserver() === target[STORE_FIREWALL]) return has;
3542
3855
  const nodes = getNodes(target, STORE_HAS);
3543
3856
  if (nodes[property]) return read(nodes[property]);
@@ -3558,30 +3871,24 @@ const storeTraps = {
3558
3871
  overrideKey: overrideKey,
3559
3872
  state: state
3560
3873
  } = prepareStoreWrite(target, store, property);
3561
- const prev =
3562
- target[STORE_OPTIMISTIC_OVERRIDE] && property in target[STORE_OPTIMISTIC_OVERRIDE]
3563
- ? target[STORE_OPTIMISTIC_OVERRIDE][property]
3564
- : target[STORE_OVERRIDE] && property in target[STORE_OVERRIDE]
3565
- ? target[STORE_OVERRIDE][property]
3566
- : base;
3567
- const prevHas =
3568
- target[STORE_OPTIMISTIC_OVERRIDE] && property in target[STORE_OPTIMISTIC_OVERRIDE]
3569
- ? target[STORE_OPTIMISTIC_OVERRIDE][property] !== $DELETED
3570
- : target[STORE_OVERRIDE] && property in target[STORE_OVERRIDE]
3571
- ? target[STORE_OVERRIDE][property] !== $DELETED
3572
- : property in target[STORE_VALUE];
3874
+ const prevLayer = getOverlayLayer(target, property);
3875
+ const prev = prevLayer ? prevLayer[property] : base;
3876
+ const prevHas = prevLayer
3877
+ ? prevLayer[property] !== $DELETED
3878
+ : property in target[STORE_VALUE];
3573
3879
  const value = unwrapStoreValue(rawValue);
3574
- const isArrayIndexWrite = Array.isArray(state) && property !== "length";
3575
- const nextIndex = isArrayIndexWrite ? parseInt(property) + 1 : 0;
3576
- const len =
3577
- isArrayIndexWrite &&
3578
- (target[STORE_OPTIMISTIC_OVERRIDE] && "length" in target[STORE_OPTIMISTIC_OVERRIDE]
3579
- ? target[STORE_OPTIMISTIC_OVERRIDE].length
3580
- : target[STORE_OVERRIDE] && "length" in target[STORE_OVERRIDE]
3581
- ? target[STORE_OVERRIDE].length
3582
- : state.length);
3880
+ const index = typeof property === "string" ? Number(property) : -1;
3881
+ const isArrayIndexWrite =
3882
+ Array.isArray(state) &&
3883
+ Number.isInteger(index) &&
3884
+ index >= 0 &&
3885
+ index < 4294967295 &&
3886
+ String(index) === property;
3887
+ const nextIndex = isArrayIndexWrite ? index + 1 : 0;
3888
+ const len = isArrayIndexWrite && (getOverlayLayer(target, "length") ?? state).length;
3583
3889
  const nextLength = isArrayIndexWrite && nextIndex > len ? nextIndex : undefined;
3584
3890
  if (prev === value && nextLength === undefined) return true;
3891
+ armOptimisticStoreWrite(target, store);
3585
3892
  if (value !== undefined && value === base && nextLength === undefined)
3586
3893
  delete target[overrideKey]?.[property];
3587
3894
  else {
@@ -3590,6 +3897,22 @@ const storeTraps = {
3590
3897
  if (nextLength !== undefined) override.length = nextLength;
3591
3898
  }
3592
3899
  notifyStoreProperty(target, property, "set", value, prev, prevHas);
3900
+ if (
3901
+ Array.isArray(state) &&
3902
+ property === "length" &&
3903
+ typeof value === "number" &&
3904
+ typeof prev === "number" &&
3905
+ value < prev
3906
+ ) {
3907
+ const override = target[overrideKey] || (target[overrideKey] = Object.create(null));
3908
+ for (let i = value; i < prev; i++) {
3909
+ if (override[i] === $DELETED) continue;
3910
+ const prevIndex = i in override ? override[i] : state[i];
3911
+ if (!(i in override) && !(i in state)) continue;
3912
+ override[i] = $DELETED;
3913
+ notifyStoreProperty(target, i, "delete", undefined, prevIndex, true);
3914
+ }
3915
+ }
3593
3916
  if (Array.isArray(state) && property !== "length" && nextLength !== undefined) {
3594
3917
  const nodes = getNodes(target, STORE_NODE);
3595
3918
  if (nodes.length) {
@@ -3616,6 +3939,7 @@ const storeTraps = {
3616
3939
  if (writeOnly(store)) {
3617
3940
  untrack(() => {
3618
3941
  const { base: base, overrideKey: overrideKey } = prepareStoreWrite(target, store, property);
3942
+ armOptimisticStoreWrite(target, store);
3619
3943
  const normalizedDescriptor =
3620
3944
  "value" in descriptor
3621
3945
  ? { ...descriptor, value: unwrapStoreValue(descriptor.value) }
@@ -3645,19 +3969,16 @@ const storeTraps = {
3645
3969
  untrack(() => {
3646
3970
  const useOptimistic = target[STORE_OPTIMISTIC] && !projectionWriteActive;
3647
3971
  const overrideKey = useOptimistic ? STORE_OPTIMISTIC_OVERRIDE : STORE_OVERRIDE;
3648
- if (useOptimistic) trackOptimisticStore(target[$PROXY]);
3649
- const prev =
3650
- target[STORE_OPTIMISTIC_OVERRIDE] && property in target[STORE_OPTIMISTIC_OVERRIDE]
3651
- ? target[STORE_OPTIMISTIC_OVERRIDE][property]
3652
- : target[STORE_OVERRIDE] && property in target[STORE_OVERRIDE]
3653
- ? target[STORE_OVERRIDE][property]
3654
- : target[STORE_VALUE][property];
3972
+ const prevLayer = getOverlayLayer(target, property);
3973
+ const prev = prevLayer ? prevLayer[property] : target[STORE_VALUE][property];
3655
3974
  if (
3656
3975
  property in target[STORE_VALUE] ||
3657
3976
  (target[STORE_OVERRIDE] && property in target[STORE_OVERRIDE])
3658
3977
  ) {
3978
+ armOptimisticStoreWrite(target, target[$PROXY]);
3659
3979
  (target[overrideKey] || (target[overrideKey] = Object.create(null)))[property] = $DELETED;
3660
3980
  } else if (target[overrideKey] && property in target[overrideKey]) {
3981
+ armOptimisticStoreWrite(target, target[$PROXY]);
3661
3982
  delete target[overrideKey][property];
3662
3983
  } else return true;
3663
3984
  notifyStoreProperty(target, property, "delete", undefined, prev, true);
@@ -3686,7 +4007,13 @@ const storeTraps = {
3686
4007
  if (optDesc?.get || optDesc?.set || !(property in target[STORE_VALUE])) return optDesc;
3687
4008
  const baseDesc = getPropertyDescriptor(target[STORE_VALUE], target[STORE_OVERRIDE], property);
3688
4009
  if (baseDesc) {
3689
- return { ...baseDesc, value: target[STORE_OPTIMISTIC_OVERRIDE][property] };
4010
+ const targetDesc = Reflect.getOwnPropertyDescriptor(target, property);
4011
+ const configurable = !targetDesc || targetDesc.configurable ? true : baseDesc.configurable;
4012
+ return {
4013
+ ...baseDesc,
4014
+ configurable: configurable,
4015
+ value: target[STORE_OPTIMISTIC_OVERRIDE][property]
4016
+ };
3690
4017
  }
3691
4018
  return {
3692
4019
  value: target[STORE_OPTIMISTIC_OVERRIDE][property],
@@ -3695,7 +4022,12 @@ const storeTraps = {
3695
4022
  configurable: true
3696
4023
  };
3697
4024
  }
3698
- return getPropertyDescriptor(target[STORE_VALUE], target[STORE_OVERRIDE], property);
4025
+ const desc = getPropertyDescriptor(target[STORE_VALUE], target[STORE_OVERRIDE], property);
4026
+ if (desc && !desc.configurable) {
4027
+ const targetDesc = Reflect.getOwnPropertyDescriptor(target, property);
4028
+ if (!targetDesc || targetDesc.configurable) return { ...desc, configurable: true };
4029
+ }
4030
+ return desc;
3699
4031
  },
3700
4032
  getPrototypeOf(target) {
3701
4033
  return Object.getPrototypeOf(target[STORE_VALUE]);
@@ -3712,7 +4044,7 @@ function storeSetter(store, fn) {
3712
4044
  for (let i = 0, len = value.length; i < len; i++) store[i] = value[i];
3713
4045
  store.length = value.length;
3714
4046
  } else {
3715
- const keys = new Set([...Object.keys(store), ...Object.keys(value)]);
4047
+ const keys = new Set([...ownEnumerableKeys(store), ...ownEnumerableKeys(value)]);
3716
4048
  keys.forEach(key => {
3717
4049
  if (key in value) store[key] = value[key];
3718
4050
  else delete store[key];
@@ -3748,12 +4080,15 @@ function createOptimisticStore(first, second, options) {
3748
4080
  }
3749
4081
  function clearOptimisticStore(store) {
3750
4082
  const target = store[$TARGET];
3751
- if (!target || !target[STORE_OPTIMISTIC_OVERRIDE]) return;
4083
+ if (!target) return;
4084
+ maskStoreTarget(target, false);
4085
+ if (!target[STORE_OPTIMISTIC_OVERRIDE]) return;
3752
4086
  clearOptimisticOverride(target);
3753
4087
  }
3754
4088
  function clearOptimisticOverride(target) {
3755
4089
  const override = target[STORE_OPTIMISTIC_OVERRIDE];
3756
4090
  if (!override) return;
4091
+ maskStoreTarget(target, false);
3757
4092
  const nodes = target[STORE_NODE];
3758
4093
  delete target[STORE_OPTIMISTIC_OVERRIDE];
3759
4094
  const wasProjectionWriteActive = projectionWriteActive;
@@ -3764,18 +4099,11 @@ function clearOptimisticOverride(target) {
3764
4099
  if (nodes[key]) {
3765
4100
  const node = nodes[key];
3766
4101
  node._optimisticLane = undefined;
3767
- const baseValue =
3768
- target[STORE_OVERRIDE] && key in target[STORE_OVERRIDE]
3769
- ? target[STORE_OVERRIDE][key]
3770
- : target[STORE_VALUE][key];
4102
+ const layer = getOverlayLayer(target, key);
4103
+ const baseValue = layer ? layer[key] : target[STORE_VALUE][key];
3771
4104
  const value = baseValue === $DELETED ? undefined : baseValue;
3772
4105
  const next = isWrappable(value) ? wrap(value, target) : value;
3773
- const prev =
3774
- node._overrideValue !== undefined && node._overrideValue !== NOT_PENDING
3775
- ? node._overrideValue
3776
- : node._pendingValue !== NOT_PENDING
3777
- ? node._pendingValue
3778
- : node._value;
4106
+ const prev = visibleNodeValue(node);
3779
4107
  node._overrideValue = NOT_PENDING;
3780
4108
  node._pendingValue = NOT_PENDING;
3781
4109
  node._value = next;
@@ -3907,10 +4235,10 @@ function updatePath(current, args, i = 0) {
3907
4235
  (isWrappable(prev) && isWrappable(value) && !Array.isArray(value))
3908
4236
  ) {
3909
4237
  const target = part !== undefined ? current[part] : current;
3910
- const keys = Object.keys(value);
4238
+ const keys = ownEnumerableKeys(value);
3911
4239
  for (let i = 0; i < keys.length; i++) {
3912
4240
  const key = keys[i];
3913
- if (isPrototypePollutionKey(key)) continue;
4241
+ if (typeof key === "string" && isPrototypePollutionKey(key)) continue;
3914
4242
  const desc = Object.getOwnPropertyDescriptor(value, key);
3915
4243
  if (desc.get || desc.set) Object.defineProperty(target, key, desc);
3916
4244
  else target[key] = desc.value;
@@ -3927,6 +4255,11 @@ const storePath = Object.assign(
3927
4255
  },
3928
4256
  { DELETE: DELETE }
3929
4257
  );
4258
+ function mergedOverlay(target) {
4259
+ const override = target[STORE_OVERRIDE];
4260
+ const opt = target[STORE_OPTIMISTIC_OVERRIDE];
4261
+ return override && opt ? { ...override, ...opt } : (opt ?? override);
4262
+ }
3930
4263
  function snapshotImpl(item, track, map, lookup) {
3931
4264
  let target, isArray, override, result, unwrapped, v;
3932
4265
  if (!isWrappable(item)) return item;
@@ -3934,7 +4267,7 @@ function snapshotImpl(item, track, map, lookup) {
3934
4267
  if (!map) map = new Map();
3935
4268
  if ((target = item[$TARGET] || lookup?.get(item)?.[$TARGET])) {
3936
4269
  if (track) trackSelf(target, $TRACK);
3937
- override = target[STORE_OVERRIDE];
4270
+ override = mergedOverlay(target);
3938
4271
  isArray = Array.isArray(target[STORE_VALUE]);
3939
4272
  map.set(
3940
4273
  item,
@@ -3959,13 +4292,30 @@ function snapshotImpl(item, track, map, lookup) {
3959
4292
  result[i] = unwrapped;
3960
4293
  }
3961
4294
  }
4295
+ if (result) result.length = len;
4296
+ } else if (!override) {
4297
+ const keys = getKeys(item, undefined);
4298
+ for (let i = 0, l = keys.length; i < l; i++) {
4299
+ const prop = keys[i];
4300
+ const desc = Object.getOwnPropertyDescriptor(item, prop);
4301
+ if (desc.get) continue;
4302
+ v = desc.value;
4303
+ if (track && isWrappable(v)) wrap(v, target);
4304
+ if ((unwrapped = snapshotImpl(v, track, map, lookup)) !== v || result) {
4305
+ if (!result) {
4306
+ result = Object.create(Object.getPrototypeOf(item));
4307
+ Object.assign(result, item);
4308
+ }
4309
+ result[prop] = unwrapped;
4310
+ }
4311
+ }
3962
4312
  } else {
3963
4313
  const keys = getKeys(item, override);
3964
4314
  for (let i = 0, l = keys.length; i < l; i++) {
3965
4315
  let prop = keys[i];
3966
4316
  const desc = getPropertyDescriptor(item, override, prop);
3967
4317
  if (desc.get) continue;
3968
- v = override && prop in override ? override[prop] : item[prop];
4318
+ v = prop in override ? override[prop] : item[prop];
3969
4319
  if (track && isWrappable(v)) wrap(v, target);
3970
4320
  if ((unwrapped = snapshotImpl(v, track, map, lookup)) !== item[prop] || result) {
3971
4321
  if (!result) {
@@ -4048,7 +4398,7 @@ function merge(...sources) {
4048
4398
  keys() {
4049
4399
  const keys = new Set();
4050
4400
  for (let i = 0; i < flattened.length; i++) {
4051
- const sourceKeys = Object.keys(resolveSource(flattened[i]));
4401
+ const sourceKeys = ownEnumerableKeys(resolveSource(flattened[i]));
4052
4402
  for (let j = 0; j < sourceKeys.length; j++) keys.add(sourceKeys[j]);
4053
4403
  }
4054
4404
  return [...keys];
@@ -4102,7 +4452,7 @@ function omit(props, ...keys) {
4102
4452
  return !keys.includes(property) && property in props;
4103
4453
  },
4104
4454
  keys() {
4105
- return Object.keys(props).filter(k => !keys.includes(k));
4455
+ return ownEnumerableKeys(props).filter(k => !keys.includes(k));
4106
4456
  }
4107
4457
  },
4108
4458
  propTraps
@@ -4331,6 +4681,18 @@ function updateRepeat() {
4331
4681
  const to = from + newLen;
4332
4682
  const prevTo = this._offset + this._len;
4333
4683
  if (this._len === 0 && this._nodes[0]) this._nodes[0].dispose();
4684
+ if (from >= prevTo || to <= this._offset) {
4685
+ for (let i = 0; i < this._len; i++) this._nodes[i].dispose();
4686
+ this._nodes = new Array(newLen);
4687
+ this._mappings = new Array(newLen);
4688
+ for (let i = 0; i < newLen; i++)
4689
+ this._mappings[i] = runWithOwner((this._nodes[i] = createOwner()), () =>
4690
+ this._map(from + i)
4691
+ );
4692
+ this._offset = from;
4693
+ this._len = newLen;
4694
+ return;
4695
+ }
4334
4696
  for (let i = to; i < prevTo; i++) this._nodes[i - this._offset].dispose();
4335
4697
  if (this._offset < from) {
4336
4698
  const removed = from - this._offset;
@@ -4372,7 +4734,13 @@ function boundaryComputed(fn, propagationMask) {
4372
4734
  const flags = status !== undefined ? status : node._statusFlags;
4373
4735
  const actualError = error !== undefined ? error : node._error;
4374
4736
  node._statusFlags &= ~node._propagationMask;
4375
- node._queue.notify(node, node._propagationMask, flags, actualError);
4737
+ node._queue.notify(node, STATUS_PENDING | STATUS_ERROR, flags, actualError);
4738
+ const foreign = flags & ~node._propagationMask & (STATUS_PENDING | STATUS_ERROR);
4739
+ if (foreign) {
4740
+ node._statusFlags &= ~foreign;
4741
+ if (node._error === actualError && !(node._statusFlags & (STATUS_PENDING | STATUS_ERROR)))
4742
+ node._error = undefined;
4743
+ }
4376
4744
  };
4377
4745
  node._propagationMask = propagationMask;
4378
4746
  node._config &= ~CONFIG_AUTO_DISPOSE;
@@ -4566,9 +4934,6 @@ class CollectionQueue extends Queue {
4566
4934
  }
4567
4935
  if (this._collectionType & STATUS_PENDING && this._initialized)
4568
4936
  return super.notify(node, type, flags, error);
4569
- if (this._collectionType & STATUS_PENDING && flags & STATUS_ERROR) {
4570
- return super.notify(node, STATUS_ERROR, flags, error);
4571
- }
4572
4937
  if (flags & this._collectionType) {
4573
4938
  this._pending = true;
4574
4939
  const source = error?.source || node._error?.source;
@@ -4577,7 +4942,7 @@ class CollectionQueue extends Queue {
4577
4942
  this._sources.add(source);
4578
4943
  if (wasEmpty) setSignal(this._disabled, true);
4579
4944
  if (this._collectionType & STATUS_ERROR) {
4580
- setSignal(this._error, source._error?.cause ?? source._error);
4945
+ setSignal(this._error, unwrapStatusError(source._error));
4581
4946
  }
4582
4947
  }
4583
4948
  }
@@ -4655,14 +5020,17 @@ function createCollectionBoundary(type, fn, fallback, onFn) {
4655
5020
  cleanup(() => controller.unregister(queue));
4656
5021
  }
4657
5022
  return accessor(
4658
- computed(() => {
4659
- if (!read(queue._disabled)) {
4660
- const resolved = read(tree);
4661
- if (!untrack(() => read(queue._disabled))) return ((queue._initialized = true), resolved);
4662
- }
4663
- if (_revealUsed && read(queue._collapsed)) return undefined;
4664
- return fallback(queue);
4665
- })
5023
+ computed(
5024
+ () => {
5025
+ if (!read(queue._disabled)) {
5026
+ const resolved = read(tree);
5027
+ if (!untrack(() => read(queue._disabled))) return ((queue._initialized = true), resolved);
5028
+ }
5029
+ if (_revealUsed && read(queue._collapsed)) return undefined;
5030
+ return fallback(queue);
5031
+ },
5032
+ { _noSnapshot: true }
5033
+ )
4666
5034
  );
4667
5035
  }
4668
5036
  function createLoadingBoundary(fn, fallback, options) {
@@ -4809,6 +5177,7 @@ export {
4809
5177
  refresh,
4810
5178
  releaseSnapshotScope,
4811
5179
  repeat,
5180
+ resetErrorHalt,
4812
5181
  resolve,
4813
5182
  runWithOwner,
4814
5183
  setContext,