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

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 (86) hide show
  1. package/dist/dev.js +700 -385
  2. package/dist/node.cjs +1865 -1592
  3. package/dist/prod.js +1496 -1232
  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/graph.d.ts +1 -1
  10. package/dist/types/core/index.d.ts +2 -2
  11. package/dist/types/core/invariants.d.ts +49 -0
  12. package/dist/types/core/scheduler.d.ts +8 -0
  13. package/dist/types/core/types.d.ts +19 -0
  14. package/dist/types/index.d.ts +1 -1
  15. package/dist/types/signals.d.ts +39 -2
  16. package/dist/types/store/projection.d.ts +2 -2
  17. package/dist/types/store/store.d.ts +28 -1
  18. package/dist/types-cjs/boundaries.d.cts +3 -3
  19. package/dist/types-cjs/core/async.d.cts +1 -0
  20. package/dist/types-cjs/core/core.d.cts +25 -1
  21. package/dist/types-cjs/core/dev.d.cts +10 -2
  22. package/dist/types-cjs/core/effect.d.cts +1 -3
  23. package/dist/types-cjs/core/graph.d.cts +1 -1
  24. package/dist/types-cjs/core/index.d.cts +2 -2
  25. package/dist/types-cjs/core/invariants.d.cts +49 -0
  26. package/dist/types-cjs/core/scheduler.d.cts +8 -0
  27. package/dist/types-cjs/core/types.d.cts +19 -0
  28. package/dist/types-cjs/index.d.cts +1 -1
  29. package/dist/types-cjs/signals.d.cts +39 -2
  30. package/dist/types-cjs/store/projection.d.cts +2 -2
  31. package/dist/types-cjs/store/store.d.cts +28 -1
  32. package/package.json +1 -1
  33. package/dist/types/src/boundaries.d.ts +0 -173
  34. package/dist/types/src/core/action.d.ts +0 -35
  35. package/dist/types/src/core/async.d.ts +0 -6
  36. package/dist/types/src/core/constants.d.ts +0 -51
  37. package/dist/types/src/core/context.d.ts +0 -36
  38. package/dist/types/src/core/core.d.ts +0 -174
  39. package/dist/types/src/core/dev.d.ts +0 -49
  40. package/dist/types/src/core/effect.d.ts +0 -32
  41. package/dist/types/src/core/error.d.ts +0 -38
  42. package/dist/types/src/core/external.d.ts +0 -45
  43. package/dist/types/src/core/graph.d.ts +0 -5
  44. package/dist/types/src/core/heap.d.ts +0 -14
  45. package/dist/types/src/core/index.d.ts +0 -12
  46. package/dist/types/src/core/lanes.d.ts +0 -54
  47. package/dist/types/src/core/owner.d.ts +0 -116
  48. package/dist/types/src/core/scheduler.d.ts +0 -122
  49. package/dist/types/src/core/types.d.ts +0 -85
  50. package/dist/types/src/index.d.ts +0 -9
  51. package/dist/types/src/map.d.ts +0 -53
  52. package/dist/types/src/signals.d.ts +0 -512
  53. package/dist/types/src/store/index.d.ts +0 -9
  54. package/dist/types/src/store/optimistic.d.ts +0 -45
  55. package/dist/types/src/store/projection.d.ts +0 -66
  56. package/dist/types/src/store/reconcile.d.ts +0 -23
  57. package/dist/types/src/store/store.d.ts +0 -125
  58. package/dist/types/src/store/storePath.d.ts +0 -58
  59. package/dist/types/src/store/utils.d.ts +0 -114
  60. package/dist/types-cjs/src/boundaries.d.cts +0 -173
  61. package/dist/types-cjs/src/core/action.d.cts +0 -35
  62. package/dist/types-cjs/src/core/async.d.cts +0 -6
  63. package/dist/types-cjs/src/core/constants.d.cts +0 -51
  64. package/dist/types-cjs/src/core/context.d.cts +0 -36
  65. package/dist/types-cjs/src/core/core.d.cts +0 -174
  66. package/dist/types-cjs/src/core/dev.d.cts +0 -49
  67. package/dist/types-cjs/src/core/effect.d.cts +0 -32
  68. package/dist/types-cjs/src/core/error.d.cts +0 -38
  69. package/dist/types-cjs/src/core/external.d.cts +0 -45
  70. package/dist/types-cjs/src/core/graph.d.cts +0 -5
  71. package/dist/types-cjs/src/core/heap.d.cts +0 -14
  72. package/dist/types-cjs/src/core/index.d.cts +0 -12
  73. package/dist/types-cjs/src/core/lanes.d.cts +0 -54
  74. package/dist/types-cjs/src/core/owner.d.cts +0 -116
  75. package/dist/types-cjs/src/core/scheduler.d.cts +0 -122
  76. package/dist/types-cjs/src/core/types.d.cts +0 -85
  77. package/dist/types-cjs/src/index.d.cts +0 -9
  78. package/dist/types-cjs/src/map.d.cts +0 -53
  79. package/dist/types-cjs/src/signals.d.cts +0 -512
  80. package/dist/types-cjs/src/store/index.d.cts +0 -9
  81. package/dist/types-cjs/src/store/optimistic.d.cts +0 -45
  82. package/dist/types-cjs/src/store/projection.d.cts +0 -66
  83. package/dist/types-cjs/src/store/reconcile.d.cts +0 -23
  84. package/dist/types-cjs/src/store/store.d.cts +0 -125
  85. package/dist/types-cjs/src/store/storePath.d.cts +0 -58
  86. package/dist/types-cjs/src/store/utils.d.cts +0 -114
package/dist/dev.js CHANGED
@@ -140,6 +140,22 @@ function getObservers(node) {
140
140
  }
141
141
  return observers;
142
142
  }
143
+ function createAsyncReporters() {
144
+ return new Map();
145
+ }
146
+ function devCheckActiveOverrides(isRegisteredForRevert) {
147
+ return;
148
+ }
149
+ function devCheckFlushStart() {
150
+ return;
151
+ }
152
+ typeof globalThis !== "undefined" && !!globalThis.process?.env?.COMPANION_CENSUS;
153
+ function devCensusCompanions(isQueuedForCommit) {
154
+ return;
155
+ }
156
+ function devCheckQuiescent(isQueuedForCommit) {
157
+ return;
158
+ }
143
159
  const signalLanes = new WeakMap();
144
160
  const activeLanes = new Set();
145
161
  function getOrCreateLane(signal) {
@@ -159,7 +175,6 @@ function getOrCreateLane(signal) {
159
175
  };
160
176
  signalLanes.set(signal, lane);
161
177
  activeLanes.add(lane);
162
- signal._overrideSinceLane = false;
163
178
  return lane;
164
179
  }
165
180
  function findLane(lane) {
@@ -172,8 +187,11 @@ function mergeLanes(lane1, lane2) {
172
187
  if (lane1 === lane2) return lane1;
173
188
  lane2._mergedInto = lane1;
174
189
  for (const node of lane2._pendingAsync) lane1._pendingAsync.add(node);
190
+ lane2._pendingAsync.clear();
175
191
  lane1._effectQueues[0].push(...lane2._effectQueues[0]);
176
192
  lane1._effectQueues[1].push(...lane2._effectQueues[1]);
193
+ lane2._effectQueues[0].length = 0;
194
+ lane2._effectQueues[1].length = 0;
177
195
  return lane1;
178
196
  }
179
197
  function resolveLane(el) {
@@ -217,6 +235,8 @@ const zombieQueue = { _heap: new Array(2e3).fill(undefined), _marked: false, _mi
217
235
  let clock = 0;
218
236
  let activeTransition = null;
219
237
  let scheduled = false;
238
+ let halted = false;
239
+ let haltNotified = false;
220
240
  let syncDepth = 0;
221
241
  let projectionWriteActive = false;
222
242
  let inTrackedQueueCallback = false;
@@ -305,19 +325,24 @@ function mergeTransitionState(target, outgoing) {
305
325
  for (const sub of outgoing._gatedSubs) target._gatedSubs.add(sub);
306
326
  }
307
327
  function resolveOptimisticNodes(nodes) {
308
- for (let i = 0; i < nodes.length; i++) {
328
+ const len = nodes.length;
329
+ for (let i = 0; i < len; i++) {
309
330
  const node = nodes[i];
310
331
  node._optimisticLane = undefined;
311
- if (node._pendingValue !== NOT_PENDING) {
312
- node._value = node._pendingValue;
313
- node._pendingValue = NOT_PENDING;
314
- }
332
+ if (!(node._statusFlags & STATUS_PENDING)) node._statusFlags &= ~STATUS_UNINITIALIZED;
315
333
  const prevOverride = node._overrideValue;
316
334
  node._overrideValue = NOT_PENDING;
317
335
  if (prevOverride !== NOT_PENDING && node._value !== prevOverride) insertSubs(node, true);
318
336
  node._transition = null;
319
337
  }
320
- nodes.length = 0;
338
+ for (let i = 0; i < len; i++) {
339
+ const node = nodes[i];
340
+ if (node._pendingSignal || node._latestValueComputed) snapCompanionsToState(node);
341
+ const owner = node._parentSource;
342
+ if (owner && (owner._pendingSignal === node || owner._latestValueComputed === node))
343
+ snapCompanionsToState(owner);
344
+ }
345
+ nodes.splice(0, len);
321
346
  }
322
347
  function cleanupCompletedLanes(completingTransition) {
323
348
  for (const lane of activeLanes) {
@@ -338,10 +363,41 @@ function cleanupCompletedLanes(completingTransition) {
338
363
  }
339
364
  }
340
365
  function schedule() {
366
+ if (halted) {
367
+ notifyHalted();
368
+ return;
369
+ }
341
370
  if (scheduled) return;
342
371
  scheduled = true;
343
372
  if (!syncDepth && !globalQueue._running && !projectionWriteActive) queueMicrotask(flush);
344
373
  }
374
+ function haltReactivity() {
375
+ if (halted) return;
376
+ halted = true;
377
+ let message = "[REACTIVITY_HALTED] An uncaught error halted the reactive system.";
378
+ {
379
+ message +=
380
+ " No further updates will be processed. Handle errors with createErrorBoundary/<Errored> or treat this as a crash.";
381
+ emitDiagnostic({
382
+ code: "REACTIVITY_HALTED",
383
+ kind: "error",
384
+ severity: "error",
385
+ message: message
386
+ });
387
+ }
388
+ console.error(message);
389
+ }
390
+ function notifyHalted() {
391
+ if (haltNotified) return;
392
+ haltNotified = true;
393
+ console.error(
394
+ "[REACTIVITY_HALTED] Update ignored: the reactive system was halted by an earlier uncaught error."
395
+ );
396
+ }
397
+ function resetErrorHalt() {
398
+ halted = false;
399
+ haltNotified = false;
400
+ }
345
401
  class Queue {
346
402
  _parent = null;
347
403
  _queues = [[], []];
@@ -419,6 +475,7 @@ class GlobalQueue extends Queue {
419
475
  if (this._running) return;
420
476
  this._running = true;
421
477
  try {
478
+ if (true) devCheckFlushStart();
422
479
  runHeap(dirtyQueue, GlobalQueue._update);
423
480
  if (activeTransition) {
424
481
  const isComplete = transitionComplete(activeTransition);
@@ -482,6 +539,24 @@ class GlobalQueue extends Queue {
482
539
  this.run(EFFECT_RENDER);
483
540
  activeLanes.size && runLaneEffects(EFFECT_USER);
484
541
  this.run(EFFECT_USER);
542
+ if (true) {
543
+ devCheckActiveOverrides(n => {
544
+ if (this._optimisticNodes.includes(n)) return true;
545
+ if (activeTransition?._optimisticNodes.includes(n)) return true;
546
+ for (const t of transitions) if (t._optimisticNodes.includes(n)) return true;
547
+ return false;
548
+ });
549
+ devCensusCompanions(n => n === this._pendingNode || this._pendingNodes.includes(n));
550
+ }
551
+ if (
552
+ true &&
553
+ !scheduled &&
554
+ !activeTransition &&
555
+ transitions.size === 0 &&
556
+ activeLanes.size === 0
557
+ ) {
558
+ devCheckQuiescent(n => n === this._pendingNode || this._pendingNodes.includes(n));
559
+ }
485
560
  if (true) DEV$1.hooks.onUpdate?.();
486
561
  } finally {
487
562
  this._running = false;
@@ -513,7 +588,7 @@ class GlobalQueue extends Queue {
513
588
  activeTransition = transition ?? {
514
589
  _time: clock,
515
590
  _pendingNodes: [],
516
- _asyncReporters: new Map(),
591
+ _asyncReporters: createAsyncReporters(),
517
592
  _optimisticNodes: [],
518
593
  _optimisticStores: new Set(),
519
594
  _actions: [],
@@ -609,6 +684,7 @@ function commitPendingNode(n) {
609
684
  n._value = n._pendingValue;
610
685
  n._pendingValue = NOT_PENDING;
611
686
  }
687
+ if (n._pendingSignal || n._latestValueComputed) snapCompanionsToState(n);
612
688
  return;
613
689
  }
614
690
  if (n._pendingValue !== NOT_PENDING) {
@@ -620,6 +696,7 @@ function commitPendingNode(n) {
620
696
  if (!(c._statusFlags & STATUS_PENDING)) c._statusFlags &= ~STATUS_UNINITIALIZED;
621
697
  if (c._pendingFirstChild !== null || c._pendingDisposal !== null)
622
698
  GlobalQueue._dispose(c, false, true);
699
+ if (n._pendingSignal || n._latestValueComputed) snapCompanionsToState(n);
623
700
  }
624
701
  function commitPendingNodes() {
625
702
  if (globalQueue._pendingNode !== null) {
@@ -710,6 +787,7 @@ function flush(fn) {
710
787
  }
711
788
  return;
712
789
  }
790
+ if (halted) return;
713
791
  let count = 0;
714
792
  while (scheduled || activeTransition) {
715
793
  if (++count === 1e5) throw new Error("Potential Infinite Loop Detected.");
@@ -761,8 +839,7 @@ function transitionComplete(transition) {
761
839
  hasActiveOverride(node) &&
762
840
  "_statusFlags" in node &&
763
841
  node._statusFlags & STATUS_PENDING &&
764
- node._error instanceof NotReadyError &&
765
- node._error.source !== node
842
+ node._error instanceof NotReadyError
766
843
  ) {
767
844
  done = false;
768
845
  break;
@@ -916,7 +993,11 @@ function dispose(node) {
916
993
  function disposeChildren(node, self = false, zombie) {
917
994
  const flags = node._flags;
918
995
  if (flags & REACTIVE_DISPOSED) return;
919
- if (self) node._flags = flags | REACTIVE_DISPOSED;
996
+ if (self) {
997
+ node._flags = flags | REACTIVE_DISPOSED;
998
+ const n = node;
999
+ if (n._pendingSignal || n._latestValueComputed) snapCompanionsToState(n);
1000
+ }
920
1001
  if (self && true) clearSignals(node);
921
1002
  if (self && node._fn) node._inFlight = null;
922
1003
  let child = zombie ? node._pendingFirstChild : node._firstChild;
@@ -956,6 +1037,11 @@ function disposeChildren(node, self = false, zombie) {
956
1037
  node._prevSibling = null;
957
1038
  }
958
1039
  runDisposal(node, zombie);
1040
+ if (self && node._cleanup) {
1041
+ const effectCleanup = node._cleanup;
1042
+ node._cleanup = undefined;
1043
+ effectCleanup();
1044
+ }
959
1045
  }
960
1046
  function runDisposal(node, zombie) {
961
1047
  let disposal = zombie ? node._pendingDisposal : node._disposal;
@@ -1097,42 +1183,49 @@ function unobserved(el) {
1097
1183
  el._depsTail = null;
1098
1184
  disposeChildren(el, true);
1099
1185
  }
1100
- function link(dep, sub) {
1186
+ function link(dep, sub, pendingObserver = false) {
1101
1187
  const prevDep = sub._depsTail;
1102
- if (prevDep !== null && prevDep._dep === dep) return;
1188
+ if (prevDep !== null && prevDep._dep === dep) {
1189
+ prevDep._pendingObserver = pendingObserver;
1190
+ return;
1191
+ }
1103
1192
  let nextDep = null;
1104
1193
  const isRecomputing = sub._flags & REACTIVE_RECOMPUTING_DEPS;
1105
1194
  if (isRecomputing) {
1106
1195
  nextDep = prevDep !== null ? prevDep._nextDep : sub._deps;
1107
1196
  if (nextDep !== null && nextDep._dep === dep) {
1197
+ nextDep._gen = sub._depGen;
1108
1198
  sub._depsTail = nextDep;
1199
+ nextDep._pendingObserver = pendingObserver;
1109
1200
  return;
1110
1201
  }
1111
1202
  }
1112
1203
  const prevSub = dep._subsTail;
1113
- if (prevSub !== null && prevSub._sub === sub && (!isRecomputing || isValidLink(prevSub, sub)))
1204
+ if (
1205
+ prevSub !== null &&
1206
+ prevSub._sub === sub &&
1207
+ (!isRecomputing || prevSub._gen === sub._depGen)
1208
+ ) {
1209
+ prevSub._pendingObserver = pendingObserver;
1114
1210
  return;
1211
+ }
1115
1212
  const newLink =
1116
1213
  (sub._depsTail =
1117
1214
  dep._subsTail =
1118
- { _dep: dep, _sub: sub, _nextDep: nextDep, _prevSub: prevSub, _nextSub: null });
1215
+ {
1216
+ _dep: dep,
1217
+ _sub: sub,
1218
+ _nextDep: nextDep,
1219
+ _prevSub: prevSub,
1220
+ _nextSub: null,
1221
+ _gen: sub._depGen,
1222
+ _pendingObserver: pendingObserver
1223
+ });
1119
1224
  if (prevDep !== null) prevDep._nextDep = newLink;
1120
1225
  else sub._deps = newLink;
1121
1226
  if (prevSub !== null) prevSub._nextSub = newLink;
1122
1227
  else dep._subs = newLink;
1123
1228
  }
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
1229
  function addPendingSource(el, source) {
1137
1230
  if (el._pendingSource === source || el._pendingSources?.has(source)) return false;
1138
1231
  if (!el._pendingSource) {
@@ -1182,9 +1275,22 @@ function setPendingError(el, source, error) {
1182
1275
  }
1183
1276
  }
1184
1277
  function forEachDependent(el, fn) {
1185
- for (let s = el._subs; s !== null; s = s._nextSub) fn(s._sub);
1278
+ for (let s = el._subs; s !== null; s = s._nextSub) fn(s._sub, s);
1186
1279
  for (let child = el._child; child !== null; child = child._nextChild) {
1187
- for (let s = child._subs; s !== null; s = s._nextSub) fn(s._sub);
1280
+ for (let s = child._subs; s !== null; s = s._nextSub) fn(s._sub, s);
1281
+ }
1282
+ }
1283
+ function enqueueForRerun(node) {
1284
+ if (node._type === EFFECT_TRACKED) {
1285
+ const tracked = node;
1286
+ if (!tracked._modified) {
1287
+ tracked._modified = true;
1288
+ tracked._queue.enqueue(EFFECT_USER, tracked._run);
1289
+ }
1290
+ } else {
1291
+ const queue = node._flags & REACTIVE_ZOMBIE ? zombieQueue : dirtyQueue;
1292
+ if (queue._min > node._height) queue._min = node._height;
1293
+ insertIntoHeap(node, queue);
1188
1294
  }
1189
1295
  }
1190
1296
  function settlePendingSource(el) {
@@ -1203,17 +1309,7 @@ function settlePendingSource(el) {
1203
1309
  setPendingError(node);
1204
1310
  updatePendingSignal(node);
1205
1311
  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
- }
1312
+ enqueueForRerun(node);
1217
1313
  scheduled = true;
1218
1314
  }
1219
1315
  node._blocked = false;
@@ -1223,23 +1319,26 @@ function settlePendingSource(el) {
1223
1319
  forEachDependent(el, settle);
1224
1320
  if (scheduled) schedule();
1225
1321
  }
1322
+ function isThenable(value) {
1323
+ return value != null && typeof value === "object" && typeof value.then === "function";
1324
+ }
1226
1325
  function handleAsync(el, result, setter) {
1227
1326
  let iterator = false;
1228
- let isThenable = false;
1327
+ let thenable = false;
1229
1328
  if (typeof result === "object" && result !== null) {
1230
1329
  untrack(() => {
1231
1330
  iterator = result[Symbol.asyncIterator];
1232
- isThenable = !iterator && typeof result.then === "function";
1331
+ thenable = !iterator && isThenable(result);
1233
1332
  });
1234
1333
  }
1235
- if (!isThenable && !iterator) {
1334
+ if (!thenable && !iterator) {
1236
1335
  el._inFlight = null;
1237
1336
  return result;
1238
1337
  }
1239
1338
  if (el._config & CONFIG_SYNC) {
1240
1339
  const message =
1241
1340
  `[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 ` +
1341
+ `${thenable ? "a Promise" : "an AsyncIterable"}. The value would be stored as-is and ` +
1243
1342
  `never awaited in production; remove \`sync: true\` to use async-aware behavior, or ` +
1244
1343
  `unwrap the value before returning.`;
1245
1344
  emitDiagnostic({
@@ -1273,35 +1372,41 @@ function handleAsync(el, result, setter) {
1273
1372
  setter(value);
1274
1373
  if (wasUninitialized) clearStatus(el, true);
1275
1374
  } 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
- }
1375
+ if (el._pendingValue === NOT_PENDING) queuePendingNode(el);
1376
+ el._pendingValue = value;
1377
+ syncCompanions(el, value);
1378
+ if (!hasActiveOverride(el)) insertSubs(el);
1282
1379
  el._time = clock;
1283
1380
  } else if (lane) {
1284
1381
  const isEffect = el._type;
1285
1382
  const prevValue = el._value;
1286
1383
  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);
1384
+ try {
1385
+ if ((!isEffect && wasUninitialized) || !equals || !equals(value, prevValue)) {
1386
+ el._value = value;
1387
+ el._time = clock;
1388
+ syncCompanions(el, value);
1389
+ insertSubs(el, true);
1292
1390
  }
1293
- insertSubs(el, true);
1391
+ } catch (e) {
1392
+ notifyStatus(el, STATUS_ERROR, e);
1294
1393
  }
1295
1394
  } else {
1296
- setSignal(el, () => value);
1395
+ try {
1396
+ setSignal(el, () => value);
1397
+ } catch (e) {
1398
+ notifyStatus(el, STATUS_ERROR, e);
1399
+ }
1297
1400
  }
1298
1401
  settlePendingSource(el);
1299
1402
  schedule();
1300
1403
  flush();
1301
1404
  then?.();
1302
1405
  };
1303
- if (isThenable) {
1406
+ if (thenable) {
1304
1407
  let resolved = false,
1408
+ rejected = false,
1409
+ syncError,
1305
1410
  isSync = true;
1306
1411
  result.then(
1307
1412
  v => {
@@ -1311,11 +1416,17 @@ function handleAsync(el, result, setter) {
1311
1416
  } else asyncWrite(v);
1312
1417
  },
1313
1418
  e => {
1314
- if (!isSync) handleError(e);
1419
+ if (isSync) {
1420
+ syncError = e;
1421
+ rejected = true;
1422
+ } else handleError(e);
1315
1423
  }
1316
1424
  );
1317
1425
  isSync = false;
1318
- if (!resolved) {
1426
+ if (rejected) {
1427
+ handleError(syncError);
1428
+ throw syncError;
1429
+ } else if (!resolved) {
1319
1430
  globalQueue.initTransition(resolveTransition(el));
1320
1431
  throw new NotReadyError(context);
1321
1432
  }
@@ -1329,9 +1440,7 @@ function handleAsync(el, result, setter) {
1329
1440
  completed = true;
1330
1441
  try {
1331
1442
  const returned = it.return?.();
1332
- if (returned && typeof returned.then === "function") {
1333
- returned.then(undefined, () => {});
1334
- }
1443
+ if (isThenable(returned)) returned.then(undefined, () => {});
1335
1444
  } catch {}
1336
1445
  });
1337
1446
  const iterate = () => {
@@ -1381,7 +1490,8 @@ function clearStatus(el, clearUninitialized = false) {
1381
1490
  if (el._blocked) el._blocked = false;
1382
1491
  el._statusFlags = clearUninitialized ? 0 : el._statusFlags & STATUS_UNINITIALIZED;
1383
1492
  if (el._error) setPendingError(el);
1384
- if (el._pendingSignal) updatePendingSignal(el);
1493
+ if (el._pendingSignal || el._latestValueComputed) updatePendingSignal(el);
1494
+ if (el._child) updateChildCompanions(el);
1385
1495
  if (el._notifyStatus) el._notifyStatus();
1386
1496
  }
1387
1497
  function notifyStatus(el, status, error, blockStatus, lane) {
@@ -1409,6 +1519,7 @@ function notifyStatus(el, status, error, blockStatus, lane) {
1409
1519
  el._error = error;
1410
1520
  }
1411
1521
  updatePendingSignal(el);
1522
+ if (el._child) updateChildCompanions(el);
1412
1523
  }
1413
1524
  if (lane && !blockStatus) {
1414
1525
  assignOrMergeLane(el, lane);
@@ -1426,7 +1537,7 @@ function notifyStatus(el, status, error, blockStatus, lane) {
1426
1537
  }
1427
1538
  return;
1428
1539
  }
1429
- forEachDependent(el, sub => {
1540
+ forEachDependent(el, (sub, link) => {
1430
1541
  sub._time = clock;
1431
1542
  if (
1432
1543
  (status === STATUS_PENDING &&
@@ -1436,6 +1547,11 @@ function notifyStatus(el, status, error, blockStatus, lane) {
1436
1547
  (status !== STATUS_PENDING &&
1437
1548
  (sub._error !== error || sub._pendingSource || sub._pendingSources))
1438
1549
  ) {
1550
+ if (link._pendingObserver && status !== STATUS_PENDING && !(error instanceof NotReadyError)) {
1551
+ enqueueForRerun(sub);
1552
+ schedule();
1553
+ return;
1554
+ }
1439
1555
  if (!downstreamBlockStatus && !sub._transition) queuePendingNode(sub);
1440
1556
  notifyStatus(sub, status, error, downstreamBlockStatus, downstreamLane);
1441
1557
  }
@@ -1477,11 +1593,10 @@ const REACTIVE_WRITE_IN_OWNED_SCOPE_REFRESH_MESSAGE =
1477
1593
  let tracking = false;
1478
1594
  let stale = false;
1479
1595
  let pendingCheckActive = false;
1480
- let foundPending = false;
1481
1596
  let latestReadActive = false;
1482
1597
  let context = null;
1483
1598
  let currentOptimisticLane = null;
1484
- let pendingCheckSources = null;
1599
+ let pendingProbe = null;
1485
1600
  let snapshotCaptureActive = false;
1486
1601
  let snapshotSources = null;
1487
1602
  function ownerInSnapshotScope(owner) {
@@ -1554,11 +1669,12 @@ function recompute(el, create = false) {
1554
1669
  }
1555
1670
  let isOptimisticDirty = !!(el._flags & REACTIVE_OPTIMISTIC_DIRTY);
1556
1671
  const hasOverride = el._overrideValue !== undefined && el._overrideValue !== NOT_PENDING;
1557
- const wasPending = !!(el._statusFlags & STATUS_PENDING);
1672
+ !!(el._statusFlags & STATUS_PENDING);
1558
1673
  const wasUninitialized = !!(el._statusFlags & STATUS_UNINITIALIZED);
1559
1674
  const oldcontext = context;
1560
1675
  context = el;
1561
1676
  el._depsTail = null;
1677
+ el._depGen++;
1562
1678
  el._flags = REACTIVE_RECOMPUTING_DEPS;
1563
1679
  el._time = clock;
1564
1680
  let value = el._pendingValue === NOT_PENDING ? el._value : el._pendingValue;
@@ -1641,26 +1757,35 @@ function recompute(el, create = false) {
1641
1757
  : el._pendingValue === NOT_PENDING
1642
1758
  ? el._value
1643
1759
  : el._pendingValue;
1644
- const valueChanged =
1645
- (!isEffect && wasUninitialized) || !el._equals || !el._equals(compareValue, value);
1760
+ let valueChanged = false;
1761
+ try {
1762
+ valueChanged =
1763
+ (!isEffect && wasUninitialized) || !el._equals || !el._equals(compareValue, value);
1764
+ } catch (e) {
1765
+ notifyStatus(el, STATUS_ERROR, e);
1766
+ }
1646
1767
  if (isEffect && valueChanged) {
1647
1768
  el._modified = !el._error;
1648
- if (!create) el._queue.enqueue(isEffect, GlobalQueue._runEffect.bind(null, el));
1769
+ if (!create)
1770
+ el._queue.enqueue(isEffect, (el._boundRunEffect ??= GlobalQueue._runEffect.bind(null, el)));
1649
1771
  }
1650
- if (valueChanged) {
1772
+ if (el._error);
1773
+ else if (valueChanged) {
1651
1774
  const prevVisible = hasOverride ? el._overrideValue : undefined;
1652
1775
  if (create || (isEffect && activeTransition !== el._transition) || isOptimisticDirty) {
1653
1776
  el._value = value;
1654
1777
  if (hasOverride && isOptimisticDirty) {
1655
1778
  el._overrideValue = value;
1656
- el._pendingValue = value;
1779
+ el._pendingValue = NOT_PENDING;
1657
1780
  }
1658
- } else el._pendingValue = value;
1659
- if (hasOverride && !isOptimisticDirty && wasPending && !el._overrideSinceLane)
1660
- el._overrideValue = value;
1781
+ } else {
1782
+ el._pendingValue = value;
1783
+ if (activeTransition || el._transition) syncCompanions(el, value);
1784
+ }
1661
1785
  if (!hasOverride || isOptimisticDirty || el._overrideValue !== prevVisible)
1662
1786
  insertSubs(el, isOptimisticDirty || hasOverride);
1663
1787
  } else if (hasOverride) {
1788
+ if (el._pendingValue === NOT_PENDING) queuePendingNode(el);
1664
1789
  el._pendingValue = value;
1665
1790
  } else if (el._height != oldHeight) {
1666
1791
  for (let s = el._subs; s !== null; s = s._nextSub) {
@@ -1676,8 +1801,7 @@ function recompute(el, create = false) {
1676
1801
  !!(el._statusFlags & (STATUS_PENDING | STATUS_UNINITIALIZED));
1677
1802
  needsPendingCommit &&
1678
1803
  (!create || el._statusFlags & STATUS_PENDING) &&
1679
- !el._transition &&
1680
- !(activeTransition && hasOverride) &&
1804
+ (!el._transition || hasOverride) &&
1681
1805
  queuePendingNode(el);
1682
1806
  el._transition &&
1683
1807
  isEffect &&
@@ -1716,6 +1840,7 @@ function computed(fn, options) {
1716
1840
  (options?.ownedWrite ? CONFIG_OWNED_WRITE : 0) |
1717
1841
  (!context || options?.lazy ? CONFIG_AUTO_DISPOSE : 0) |
1718
1842
  (options?.sync ? CONFIG_SYNC : 0) |
1843
+ (options?._noSnapshot ? CONFIG_NO_SNAPSHOT : 0) |
1719
1844
  (snapshotCaptureActive && ownerInSnapshotScope(context) ? CONFIG_IN_SNAPSHOT_SCOPE : 0),
1720
1845
  _equals: options?.equals != null ? options.equals : isEqual,
1721
1846
  _unobserved: options?.unobserved,
@@ -1731,6 +1856,7 @@ function computed(fn, options) {
1731
1856
  _prevHeap: null,
1732
1857
  _deps: null,
1733
1858
  _depsTail: null,
1859
+ _depGen: 0,
1734
1860
  _subs: null,
1735
1861
  _subsTail: null,
1736
1862
  _parent: context,
@@ -1775,6 +1901,7 @@ function createEffectNode(fn, effectFn, errorFn, type, notifyStatus, options) {
1775
1901
  _prevHeap: null,
1776
1902
  _deps: null,
1777
1903
  _depsTail: null,
1904
+ _depGen: 0,
1778
1905
  _subs: null,
1779
1906
  _subsTail: null,
1780
1907
  _parent: context,
@@ -1794,7 +1921,6 @@ function createEffectNode(fn, effectFn, errorFn, type, notifyStatus, options) {
1794
1921
  _effectFn: effectFn,
1795
1922
  _errorFn: errorFn,
1796
1923
  _cleanup: undefined,
1797
- _cleanupRegistered: false,
1798
1924
  _type: type,
1799
1925
  _notifyStatus: notifyStatus
1800
1926
  };
@@ -1842,7 +1968,7 @@ function setupComputedNode(self, options) {
1842
1968
  }
1843
1969
  !options?.lazy && recompute(self, true);
1844
1970
  if (snapshotCaptureActive && !options?.lazy) {
1845
- if (!(self._statusFlags & STATUS_PENDING)) {
1971
+ if (!(self._statusFlags & STATUS_PENDING) && !(self._config & CONFIG_NO_SNAPSHOT)) {
1846
1972
  self._snapshotValue = self._value === undefined ? NO_SNAPSHOT : self._value;
1847
1973
  snapshotSources.add(self);
1848
1974
  }
@@ -1911,6 +2037,16 @@ function untrack(fn, strictReadLabel) {
1911
2037
  strictRead = prevStrictRead;
1912
2038
  }
1913
2039
  }
2040
+ function prepareComputed(comp, refresh) {
2041
+ if (comp._flags & REACTIVE_LAZY) {
2042
+ comp._flags &= ~REACTIVE_LAZY;
2043
+ recompute(comp, true);
2044
+ } else if (comp._flags & REACTIVE_DISPOSED) {
2045
+ recompute(comp, true);
2046
+ } else if (refresh) {
2047
+ updateIfNecessary(comp);
2048
+ }
2049
+ }
1914
2050
  function read(el) {
1915
2051
  if (latestReadActive) {
1916
2052
  const pendingComputed = getLatestValueComputed(el);
@@ -1924,7 +2060,8 @@ function read(el) {
1924
2060
  try {
1925
2061
  value = read(pendingComputed);
1926
2062
  } catch (e) {
1927
- if (!context && e instanceof NotReadyError) return visibleValue;
2063
+ if (e instanceof NotReadyError && (!context || !(el._statusFlags & STATUS_UNINITIALIZED)))
2064
+ return visibleValue;
1928
2065
  throw e;
1929
2066
  } finally {
1930
2067
  latestReadActive = prevPending;
@@ -1939,59 +2076,25 @@ function read(el) {
1939
2076
  }
1940
2077
  return value;
1941
2078
  }
2079
+ let c = context;
2080
+ if (c?._root) c = c._parentComputed;
2081
+ const computed = el;
2082
+ const firewall = el._firewall;
2083
+ const owner = firewall || el;
1942
2084
  if (pendingCheckActive) {
1943
- const firewall = el._firewall;
1944
- const prevCheck = pendingCheckActive;
1945
2085
  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
- }
2086
+ if (typeof computed._fn === "function") prepareComputed(el, true);
1961
2087
  if (c && owner._statusFlags & STATUS_PENDING && owner._statusFlags & STATUS_UNINITIALIZED) {
1962
2088
  if (tracking && el !== c) link(el, c);
1963
- pendingCheckActive = prevCheck;
2089
+ pendingCheckActive = true;
1964
2090
  throw owner._error;
1965
2091
  }
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;
1981
- }
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
- }
2092
+ collectPendingSources(el);
2093
+ if (firewall) collectPendingSources(firewall);
2094
+ pendingCheckActive = true;
2095
+ } else if (typeof computed._fn === "function") {
2096
+ prepareComputed(el, false);
1993
2097
  }
1994
- const owner = el._firewall || el;
1995
2098
  if (
1996
2099
  !computed._fn &&
1997
2100
  owner === el &&
@@ -2022,7 +2125,7 @@ function read(el) {
2022
2125
  throw new Error(message);
2023
2126
  }
2024
2127
  if (c && tracking) {
2025
- link(el, c);
2128
+ link(el, c, pendingCheckActive);
2026
2129
  if (owner._fn) {
2027
2130
  const isZombie = el._flags & REACTIVE_ZOMBIE;
2028
2131
  if (owner._height >= (isZombie ? zombieQueue._min : dirtyQueue._min)) {
@@ -2072,7 +2175,7 @@ function read(el) {
2072
2175
  }
2073
2176
  }
2074
2177
  if (el._fn && el._statusFlags & STATUS_ERROR) {
2075
- if (el._time < clock) {
2178
+ if (tracking && !pendingCheckActive && el._time < clock) {
2076
2179
  recompute(el);
2077
2180
  return read(el);
2078
2181
  } else throw el._error;
@@ -2123,12 +2226,19 @@ function read(el) {
2123
2226
  (currentOptimisticLane !== null &&
2124
2227
  (el._overrideValue !== undefined ||
2125
2228
  el._optimisticLane ||
2126
- (owner === el && stale) ||
2229
+ (owner === el && stale && c._parentSource !== el) ||
2127
2230
  !!(owner._statusFlags & STATUS_PENDING))) ||
2128
2231
  el._pendingValue === NOT_PENDING ||
2129
2232
  (stale && el._transition && activeTransition !== el._transition)
2130
2233
  ? el._value
2131
2234
  : el._pendingValue;
2235
+ if (
2236
+ pendingCheckActive &&
2237
+ pendingProbe !== null &&
2238
+ el._pendingValue !== NOT_PENDING &&
2239
+ value === el._pendingValue
2240
+ )
2241
+ pendingProbe.freshReads.add(el);
2132
2242
  if (
2133
2243
  !c &&
2134
2244
  owner === el &&
@@ -2173,26 +2283,18 @@ function setSignal(el, v) {
2173
2283
  : el._pendingValue;
2174
2284
  if (typeof v === "function") v = v(currentValue);
2175
2285
  const valueChanged =
2176
- !el._equals || !el._equals(currentValue, v) || !!(el._statusFlags & STATUS_UNINITIALIZED);
2286
+ !!(el._statusFlags & STATUS_UNINITIALIZED) || !el._equals || !el._equals(currentValue, v);
2177
2287
  if (!valueChanged) {
2178
2288
  if (isOptimistic && hasOverride) {
2179
2289
  const transition = resolveTransition(el);
2180
2290
  if (transition && activeTransition !== transition) globalQueue.initTransition(transition);
2181
- if (el._fn) {
2182
- insertSubs(el, true);
2183
- schedule();
2184
- }
2185
2291
  }
2186
2292
  return v;
2187
2293
  }
2188
2294
  if (isOptimistic) {
2189
2295
  const firstOverride = el._overrideValue === NOT_PENDING;
2190
2296
  if (!firstOverride) globalQueue.initTransition(resolveTransition(el));
2191
- if (firstOverride) {
2192
- el._pendingValue = el._value;
2193
- globalQueue._optimisticNodes.push(el);
2194
- }
2195
- el._overrideSinceLane = true;
2297
+ if (firstOverride) globalQueue._optimisticNodes.push(el);
2196
2298
  const lane = getOrCreateLane(el);
2197
2299
  el._optimisticLane = lane;
2198
2300
  el._overrideValue = v;
@@ -2200,10 +2302,7 @@ function setSignal(el, v) {
2200
2302
  if (el._pendingValue === NOT_PENDING) queuePendingNode(el);
2201
2303
  el._pendingValue = v;
2202
2304
  }
2203
- if (el._pendingSignal) updatePendingSignal(el);
2204
- if (el._latestValueComputed) {
2205
- setSignal(el._latestValueComputed, v);
2206
- }
2305
+ syncCompanions(el, v);
2207
2306
  el._time = clock;
2208
2307
  insertSubs(el, isOptimistic);
2209
2308
  schedule();
@@ -2250,64 +2349,82 @@ function runWithOwner(owner, fn) {
2250
2349
  function getPendingSignal(el) {
2251
2350
  if (!el._pendingSignal) {
2252
2351
  el._pendingSignal = optimisticSignal(false, { ownedWrite: true });
2253
- if (el._parentSource) {
2254
- el._pendingSignal._parentSource = el;
2255
- }
2352
+ el._pendingSignal._parentSource = el;
2256
2353
  if (computePendingState(el)) setSignal(el._pendingSignal, true);
2257
2354
  }
2258
2355
  return el._pendingSignal;
2259
2356
  }
2260
2357
  function collectPendingSources(el) {
2261
- pendingCheckSources?.add(el);
2358
+ if (!pendingProbe) return;
2359
+ pendingProbe.sources.add(el);
2262
2360
  const owner = el._firewall || el;
2263
- if (owner !== el) pendingCheckSources?.add(owner);
2361
+ if (owner !== el) pendingProbe.sources.add(owner);
2264
2362
  }
2265
2363
  function computePendingState(el) {
2266
2364
  const comp = el;
2365
+ if (comp._flags & REACTIVE_DISPOSED) return false;
2267
2366
  const firewall = el._firewall;
2367
+ if ((firewall || comp)._optimisticMask) return false;
2268
2368
  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);
2369
+ const parentNode = el._parentSource;
2370
+ if (hasActiveOverride(parentNode)) return false;
2371
+ const parent = parentNode._firewall || parentNode;
2372
+ if (parent._optimisticMask) return false;
2373
+ return !!(
2374
+ parent._statusFlags & STATUS_PENDING && !(parent._statusFlags & STATUS_UNINITIALIZED)
2375
+ );
2273
2376
  }
2377
+ if (hasActiveOverride(el)) return false;
2274
2378
  if (firewall && el._pendingValue !== NOT_PENDING) {
2275
2379
  return (
2276
2380
  !!(firewall._flags & REACTIVE_MANUAL_WRITE) ||
2277
2381
  (!firewall._inFlight && !(firewall._statusFlags & STATUS_PENDING))
2278
2382
  );
2279
2383
  }
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
2384
  if (el._pendingValue !== NOT_PENDING && !(comp._statusFlags & STATUS_UNINITIALIZED)) return true;
2293
2385
  return !!(comp._statusFlags & STATUS_PENDING && !(comp._statusFlags & STATUS_UNINITIALIZED));
2294
2386
  }
2387
+ function syncCompanions(el, value) {
2388
+ if (el._pendingSignal) updatePendingSignal(el);
2389
+ if (el._latestValueComputed) setSignal(el._latestValueComputed, value);
2390
+ }
2295
2391
  function updatePendingSignal(el) {
2296
2392
  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;
2393
+ setSignal(el._pendingSignal, computePendingState(el));
2394
+ }
2395
+ if (el._latestValueComputed) updatePendingSignal(el._latestValueComputed);
2396
+ }
2397
+ function updateChildCompanions(el) {
2398
+ for (let child = el._child; child !== null; child = child._nextChild) {
2399
+ if (child._pendingSignal || child._latestValueComputed) updatePendingSignal(child);
2400
+ }
2401
+ }
2402
+ function snapCompanionsToState(owner) {
2403
+ const sig = owner._pendingSignal;
2404
+ if (sig && (sig._overrideValue === undefined || sig._overrideValue === NOT_PENDING)) {
2405
+ const pending = computePendingState(owner);
2406
+ if (sig._value !== pending || sig._pendingValue !== NOT_PENDING) {
2407
+ sig._value = pending;
2408
+ sig._pendingValue = NOT_PENDING;
2409
+ sig._time = clock;
2410
+ insertSubs(sig);
2411
+ schedule();
2412
+ }
2413
+ }
2414
+ const shadow = owner._latestValueComputed;
2415
+ if (shadow && !(shadow._flags & REACTIVE_DISPOSED)) {
2416
+ if (
2417
+ (shadow._overrideValue === undefined || shadow._overrideValue === NOT_PENDING) &&
2418
+ shadow._pendingValue === NOT_PENDING &&
2419
+ !Object.is(shadow._value, owner._value) &&
2420
+ !(shadow._flags & (REACTIVE_DIRTY | REACTIVE_CHECK))
2421
+ ) {
2422
+ shadow._flags |= REACTIVE_DIRTY;
2423
+ insertIntoHeap(shadow, shadow._flags & REACTIVE_ZOMBIE ? zombieQueue : dirtyQueue);
2424
+ insertSubs(shadow);
2425
+ schedule();
2310
2426
  }
2427
+ snapCompanionsToState(shadow);
2311
2428
  }
2312
2429
  }
2313
2430
  function getLatestValueComputed(el) {
@@ -2346,18 +2463,16 @@ function latest(fn) {
2346
2463
  }
2347
2464
  function isPending(fn) {
2348
2465
  const prevPendingCheck = pendingCheckActive;
2349
- const prevFoundPending = foundPending;
2350
- const prevPendingCheckSources = pendingCheckSources;
2466
+ const prevProbe = pendingProbe;
2351
2467
  pendingCheckActive = true;
2352
- foundPending = false;
2353
- pendingCheckSources = new Set();
2468
+ const probe = (pendingProbe = { found: false, sources: new Set(), freshReads: new Set() });
2354
2469
  const collectPending = () => {
2355
2470
  pendingCheckActive = false;
2356
2471
  const prevStrictRead = strictRead;
2357
2472
  strictRead = false;
2358
2473
  try {
2359
- pendingCheckSources.forEach(source => {
2360
- if (read(getPendingSignal(source))) foundPending = true;
2474
+ probe.sources.forEach(source => {
2475
+ if (read(getPendingSignal(source)) && !probe.freshReads.has(source)) probe.found = true;
2361
2476
  });
2362
2477
  } finally {
2363
2478
  strictRead = prevStrictRead;
@@ -2367,18 +2482,17 @@ function isPending(fn) {
2367
2482
  try {
2368
2483
  fn();
2369
2484
  collectPending();
2370
- return foundPending;
2485
+ return probe.found;
2371
2486
  } catch (e) {
2372
2487
  collectPending();
2373
2488
  if (e instanceof NotReadyError) {
2374
- if (foundPending && !(e.source?._statusFlags & STATUS_UNINITIALIZED)) return true;
2489
+ if (probe.found && !(e.source?._statusFlags & STATUS_UNINITIALIZED)) return true;
2375
2490
  if (context) throw e;
2376
2491
  }
2377
- return foundPending;
2492
+ return probe.found;
2378
2493
  } finally {
2379
2494
  pendingCheckActive = prevPendingCheck;
2380
- foundPending = prevFoundPending;
2381
- pendingCheckSources = prevPendingCheckSources;
2495
+ pendingProbe = prevProbe;
2382
2496
  }
2383
2497
  }
2384
2498
  function refresh(target) {
@@ -2485,50 +2599,67 @@ function notifyEffectStatus(status, error) {
2485
2599
  const actualStatus = status !== undefined ? status : this._statusFlags;
2486
2600
  const actualError = error !== undefined ? error : this._error;
2487
2601
  if (actualStatus & STATUS_ERROR) {
2488
- let err = actualError;
2489
2602
  this._queue.notify(this, STATUS_PENDING, 0);
2490
2603
  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;
2604
+ if (this._statusFlags & STATUS_ERROR) {
2605
+ this._modified = true;
2606
+ this._queue.enqueue(this._type, (this._boundRunEffect ??= runEffect.bind(null, this)));
2500
2607
  }
2608
+ return;
2609
+ }
2610
+ if (!this._queue.notify(this, STATUS_ERROR, STATUS_ERROR)) {
2611
+ haltReactivity();
2612
+ throw actualError;
2501
2613
  }
2502
- if (!this._queue.notify(this, STATUS_ERROR, STATUS_ERROR)) throw err;
2503
2614
  } else if (this._type === EFFECT_RENDER) {
2504
2615
  this._queue.notify(this, STATUS_PENDING | STATUS_ERROR, actualStatus, actualError);
2505
2616
  if (_hitUnhandledAsync) {
2506
2617
  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
- }
2618
+ const message =
2619
+ "[ASYNC_OUTSIDE_LOADING_BOUNDARY] An async value was read outside a Loading boundary. The root mount will be deferred until all pending async settles.";
2620
+ emitDiagnostic({
2621
+ code: "ASYNC_OUTSIDE_LOADING_BOUNDARY",
2622
+ kind: "async",
2623
+ severity: "warn",
2624
+ message: message,
2625
+ ownerId: this.id,
2626
+ ownerName: this._name
2627
+ });
2628
+ console.warn(message);
2520
2629
  }
2521
2630
  }
2522
2631
  }
2523
2632
  function runEffect(node) {
2524
2633
  if (!node._modified || node._flags & REACTIVE_DISPOSED) return;
2634
+ if (node._statusFlags & STATUS_ERROR && node._type === EFFECT_USER) {
2635
+ const err =
2636
+ node._error instanceof StatusError ? (node._error.cause ?? node._error) : node._error;
2637
+ node._prevValue = node._value;
2638
+ node._modified = false;
2639
+ try {
2640
+ node._errorFn
2641
+ ? node._errorFn(err, () => {
2642
+ const prevCleanup = node._cleanup;
2643
+ node._cleanup = undefined;
2644
+ prevCleanup?.();
2645
+ })
2646
+ : console.error(err);
2647
+ } catch (error) {
2648
+ if (!node._queue.notify(node, STATUS_ERROR, STATUS_ERROR)) {
2649
+ haltReactivity();
2650
+ throw error;
2651
+ }
2652
+ }
2653
+ return;
2654
+ }
2525
2655
  let prevStrictRead = false;
2526
2656
  {
2527
2657
  prevStrictRead = setStrictRead("an effect callback");
2528
2658
  }
2529
- node._cleanup?.();
2659
+ const prevCleanup = node._cleanup;
2530
2660
  node._cleanup = undefined;
2531
2661
  try {
2662
+ prevCleanup?.();
2532
2663
  const nextCleanup = node._effectFn(node._value, node._prevValue);
2533
2664
  if (true && nextCleanup !== undefined && typeof nextCleanup !== "function") {
2534
2665
  throw new Error(
@@ -2536,14 +2667,13 @@ function runEffect(node) {
2536
2667
  );
2537
2668
  }
2538
2669
  node._cleanup = nextCleanup;
2539
- if (node._cleanup && !node._cleanupRegistered) {
2540
- node._cleanupRegistered = true;
2541
- runWithOwner(node._parent, () => cleanup(() => node._cleanup?.()));
2542
- }
2543
2670
  } catch (error) {
2544
2671
  node._error = new StatusError(node, error);
2545
2672
  node._statusFlags |= STATUS_ERROR;
2546
- if (!node._queue.notify(node, STATUS_ERROR, STATUS_ERROR)) throw error;
2673
+ if (!node._queue.notify(node, STATUS_ERROR, STATUS_ERROR)) {
2674
+ haltReactivity();
2675
+ throw error;
2676
+ }
2547
2677
  } finally {
2548
2678
  setStrictRead(prevStrictRead);
2549
2679
  node._prevValue = node._value;
@@ -2564,8 +2694,9 @@ function trackedEffect(fn, options) {
2564
2694
  };
2565
2695
  const node = computed(
2566
2696
  () => {
2567
- node._cleanup?.();
2697
+ const prevCleanup = node._cleanup;
2568
2698
  node._cleanup = undefined;
2699
+ prevCleanup?.();
2569
2700
  const cleanup = staleValues(fn);
2570
2701
  if (cleanup !== undefined && typeof cleanup !== "function") {
2571
2702
  throw new Error(
@@ -2585,12 +2716,14 @@ function trackedEffect(fn, options) {
2585
2716
  if (actualStatus & STATUS_ERROR) {
2586
2717
  node._queue.notify(node, STATUS_PENDING, 0);
2587
2718
  const err = error !== undefined ? error : node._error;
2588
- if (!node._queue.notify(node, STATUS_ERROR, STATUS_ERROR)) throw err;
2719
+ if (!node._queue.notify(node, STATUS_ERROR, STATUS_ERROR)) {
2720
+ haltReactivity();
2721
+ throw err;
2722
+ }
2589
2723
  }
2590
2724
  };
2591
2725
  node._run = run;
2592
2726
  node._queue.enqueue(EFFECT_USER, run);
2593
- cleanup(() => node._cleanup?.());
2594
2727
  if (!node._parent) {
2595
2728
  const message =
2596
2729
  "[NO_OWNER_EFFECT] Effects created outside a reactive context will never be disposed";
@@ -2634,13 +2767,12 @@ function action(genFn) {
2634
2767
  } catch (e) {
2635
2768
  return done(undefined, e);
2636
2769
  }
2637
- if (r instanceof Promise)
2638
- return void r.then(run, e => restoreTransition(ctx, () => step(e, true)));
2770
+ if (isThenable(r)) return void r.then(run, e => done(undefined, e));
2639
2771
  run(r);
2640
2772
  };
2641
2773
  const run = r => {
2642
2774
  if (r.done) return done(r.value);
2643
- if (r.value instanceof Promise)
2775
+ if (isThenable(r.value))
2644
2776
  return void r.value.then(
2645
2777
  v => restoreTransition(ctx, () => step(v)),
2646
2778
  e => restoreTransition(ctx, () => step(e, true))
@@ -2760,15 +2892,18 @@ function resolve(fn) {
2760
2892
  }
2761
2893
  return new Promise((res, rej) => {
2762
2894
  createRoot(dispose => {
2763
- computed(() => {
2764
- try {
2765
- res(fn());
2766
- } catch (err) {
2767
- if (err instanceof NotReadyError) throw err;
2895
+ effect(
2896
+ fn,
2897
+ value => {
2898
+ res(value);
2899
+ dispose();
2900
+ },
2901
+ err => {
2768
2902
  rej(err);
2769
- }
2770
- dispose();
2771
- });
2903
+ dispose();
2904
+ },
2905
+ { user: true }
2906
+ );
2772
2907
  });
2773
2908
  });
2774
2909
  }
@@ -2788,27 +2923,110 @@ function onSettled(callback) {
2788
2923
  ? createTrackedEffect(() => untrack(callback), { name: "onSettled" })
2789
2924
  : globalQueue.enqueue(EFFECT_USER, () => {
2790
2925
  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
- );
2926
+ if (cleanup !== undefined) {
2927
+ const message =
2928
+ "[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.";
2929
+ emitDiagnostic({
2930
+ code: "SETTLED_CLEANUP_UNOWNED",
2931
+ kind: "lifecycle",
2932
+ severity: "error",
2933
+ message: message
2934
+ });
2935
+ throw new Error(message);
2795
2936
  }
2796
- cleanup?.();
2797
2937
  });
2798
2938
  }
2939
+ function nodeKeys(nodes) {
2940
+ const keys = Object.keys(nodes);
2941
+ if (symbolKeyedRecords.has(nodes)) {
2942
+ const syms = Object.getOwnPropertySymbols(nodes);
2943
+ for (let i = 0, len = syms.length; i < len; i++) {
2944
+ if (syms[i] !== $TRACK) keys.push(syms[i]);
2945
+ }
2946
+ }
2947
+ return keys;
2948
+ }
2799
2949
  function unwrap(value) {
2800
- return value?.[$TARGET]?.[STORE_NODE] ?? value;
2950
+ if (value === null || typeof value !== "object") return value;
2951
+ return value[$TARGET]?.[STORE_VALUE] ?? value;
2801
2952
  }
2802
2953
  function getOverrideValue(value, override, key, optOverride) {
2803
2954
  if (optOverride && key in optOverride) return optOverride[key];
2804
2955
  return override && key in override ? override[key] : value[key];
2805
2956
  }
2957
+ function addEnumSymbols(o, syms, keys) {
2958
+ for (let i = 0, len = syms.length; i < len; i++) {
2959
+ if (Object.prototype.propertyIsEnumerable.call(o, syms[i])) keys.add(syms[i]);
2960
+ }
2961
+ }
2806
2962
  function getAllKeys(value, override, next) {
2807
2963
  const keys = getKeys(value, override);
2808
2964
  const nextKeys = Object.keys(next);
2809
- return Array.from(new Set([...keys, ...nextKeys]));
2965
+ const valueSyms = value[$TARGET]
2966
+ ? untrack(() => Object.getOwnPropertySymbols(value))
2967
+ : Object.getOwnPropertySymbols(value);
2968
+ const nextSyms = Object.getOwnPropertySymbols(next);
2969
+ if (valueSyms.length === 0 && nextSyms.length === 0) {
2970
+ if (keys.length === nextKeys.length) {
2971
+ let same = true;
2972
+ for (let i = 0; i < keys.length; i++) {
2973
+ if (keys[i] !== nextKeys[i]) {
2974
+ same = false;
2975
+ break;
2976
+ }
2977
+ }
2978
+ if (same) return keys;
2979
+ }
2980
+ const set = new Set(keys);
2981
+ for (let i = 0; i < nextKeys.length; i++) set.add(nextKeys[i]);
2982
+ return Array.from(set);
2983
+ }
2984
+ const set = new Set(keys);
2985
+ addEnumSymbols(value, valueSyms, set);
2986
+ if (override) {
2987
+ for (const key of Reflect.ownKeys(override)) {
2988
+ override[key] === $DELETED ? set.delete(key) : set.add(key);
2989
+ }
2990
+ }
2991
+ for (let i = 0; i < nextKeys.length; i++) set.add(nextKeys[i]);
2992
+ addEnumSymbols(next, nextSyms, set);
2993
+ return Array.from(set);
2994
+ }
2995
+ function wrapValue(value, target) {
2996
+ return isWrappable(value) ? wrap(value, target) : value;
2997
+ }
2998
+ function itemKey(item, keyFn) {
2999
+ return isWrappable(item) ? keyFn(item) : item;
3000
+ }
3001
+ function keyedMatch(a, b, keyFn) {
3002
+ return a === b || (isWrappable(a) && isWrappable(b) && keyFn(a) === keyFn(b));
3003
+ }
3004
+ function syncArrayNodeMembership(target, next) {
3005
+ let nodes = target[STORE_NODE];
3006
+ if (nodes) {
3007
+ const keys = nodeKeys(nodes);
3008
+ for (let i = 0, len = keys.length; i < len; i++) {
3009
+ const key = keys[i];
3010
+ key in next || setSignal(nodes[key], undefined);
3011
+ }
3012
+ }
3013
+ if ((nodes = target[STORE_HAS])) {
3014
+ const keys = nodeKeys(nodes);
3015
+ for (let i = 0, len = keys.length; i < len; i++) {
3016
+ const key = keys[i];
3017
+ setSignal(nodes[key], key in next);
3018
+ }
3019
+ }
3020
+ }
3021
+ function applyArrayItem(next, previous, target, node, keyFn) {
3022
+ if (isWrappable(next) && isWrappable(previous)) {
3023
+ const wrapped = wrap(previous, target);
3024
+ node && setSignal(node, wrapped);
3025
+ applyState(next, wrapped, keyFn);
3026
+ } else node && setSignal(node, wrapValue(next, target));
2810
3027
  }
2811
3028
  function applyState(next, state, keyFn) {
3029
+ next = unwrap(next);
2812
3030
  const target = state?.[$TARGET];
2813
3031
  if (!target) return;
2814
3032
  if (target[STORE_OVERRIDE] || target[STORE_OPTIMISTIC_OVERRIDE]) {
@@ -2826,25 +3044,22 @@ function applyStateFast(next, target, keyFn) {
2826
3044
  if (Array.isArray(previous)) {
2827
3045
  let changed = false;
2828
3046
  const prevLength = previous.length;
2829
- if (next.length && prevLength && next[0] && keyFn(next[0]) != null) {
3047
+ if (next.length && prevLength && isWrappable(next[0]) && keyFn(next[0]) != null) {
2830
3048
  let i, j, start, end, newEnd, item, newIndicesNext, keyVal;
2831
3049
  for (
2832
3050
  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])));
3051
+ start < end && keyedMatch((item = previous[start]), next[start], keyFn);
2836
3052
  start++
2837
3053
  ) {
2838
- applyState(next[start], wrap(item, target), keyFn);
3054
+ isWrappable(item) &&
3055
+ isWrappable(next[start]) &&
3056
+ applyState(next[start], wrap(item, target), keyFn);
2839
3057
  }
2840
3058
  const temp = new Array(next.length),
2841
3059
  newIndices = new Map();
2842
3060
  for (
2843
3061
  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])));
3062
+ end >= start && newEnd >= start && keyedMatch((item = previous[end]), next[newEnd], keyFn);
2848
3063
  end--, newEnd--
2849
3064
  ) {
2850
3065
  temp[newEnd] = item;
@@ -2852,15 +3067,14 @@ function applyStateFast(next, target, keyFn) {
2852
3067
  if (start > newEnd || start > end) {
2853
3068
  for (j = start; j <= newEnd; j++) {
2854
3069
  changed = true;
2855
- arrayNodes?.[j] && setSignal(arrayNodes[j], wrap(next[j], target));
3070
+ arrayNodes?.[j] && setSignal(arrayNodes[j], wrapValue(next[j], target));
2856
3071
  }
2857
3072
  for (; j < next.length; j++) {
2858
3073
  changed = true;
2859
- const wrapped = wrap(temp[j], target);
2860
- arrayNodes?.[j] && setSignal(arrayNodes[j], wrapped);
2861
- applyState(next[j], wrapped, keyFn);
3074
+ applyArrayItem(next[j], temp[j], target, arrayNodes?.[j], keyFn);
2862
3075
  }
2863
- changed && notifySelf(target);
3076
+ syncArrayNodeMembership(target, next);
3077
+ (changed || prevLength !== next.length) && notifySelf(target);
2864
3078
  prevLength !== next.length &&
2865
3079
  arrayNodes?.length &&
2866
3080
  setSignal(arrayNodes.length, next.length);
@@ -2869,14 +3083,14 @@ function applyStateFast(next, target, keyFn) {
2869
3083
  newIndicesNext = new Array(newEnd + 1);
2870
3084
  for (j = newEnd; j >= start; j--) {
2871
3085
  item = next[j];
2872
- keyVal = item ? keyFn(item) : item;
3086
+ keyVal = itemKey(item, keyFn);
2873
3087
  i = newIndices.get(keyVal);
2874
3088
  newIndicesNext[j] = i === undefined ? -1 : i;
2875
3089
  newIndices.set(keyVal, j);
2876
3090
  }
2877
3091
  for (i = start; i <= end; i++) {
2878
3092
  item = previous[i];
2879
- keyVal = item ? keyFn(item) : item;
3093
+ keyVal = itemKey(item, keyFn);
2880
3094
  j = newIndices.get(keyVal);
2881
3095
  if (j !== undefined && j !== -1) {
2882
3096
  temp[j] = item;
@@ -2886,22 +3100,22 @@ function applyStateFast(next, target, keyFn) {
2886
3100
  }
2887
3101
  for (j = start; j < next.length; j++) {
2888
3102
  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));
3103
+ applyArrayItem(next[j], temp[j], target, arrayNodes?.[j], keyFn);
3104
+ } else arrayNodes?.[j] && setSignal(arrayNodes[j], wrapValue(next[j], target));
2893
3105
  }
2894
3106
  if (start < next.length) changed = true;
2895
3107
  } else if (next.length) {
2896
3108
  for (let i = 0, len = next.length; i < len; i++) {
2897
3109
  const item = previous[i];
2898
- if (isWrappable(item)) applyState(next[i], wrap(item, target), keyFn);
3110
+ if (isWrappable(item) && isWrappable(next[i]))
3111
+ applyState(next[i], wrap(item, target), keyFn);
2899
3112
  else {
2900
3113
  if (item !== next[i]) changed = true;
2901
- arrayNodes?.[i] && setSignal(arrayNodes[i], next[i]);
3114
+ arrayNodes?.[i] && setSignal(arrayNodes[i], wrapValue(next[i], target));
2902
3115
  }
2903
3116
  }
2904
3117
  }
3118
+ syncArrayNodeMembership(target, next);
2905
3119
  if (prevLength !== next.length) {
2906
3120
  changed = true;
2907
3121
  arrayNodes?.length && setSignal(arrayNodes.length, next.length);
@@ -2912,7 +3126,7 @@ function applyStateFast(next, target, keyFn) {
2912
3126
  let nodes = target[STORE_NODE];
2913
3127
  if (nodes) {
2914
3128
  const tracked = nodes[$TRACK];
2915
- const keys = tracked ? getAllKeys(previous, undefined, next) : Object.keys(nodes);
3129
+ const keys = tracked ? getAllKeys(previous, undefined, next) : nodeKeys(nodes);
2916
3130
  for (let i = 0, len = keys.length; i < len; i++) {
2917
3131
  const key = keys[i];
2918
3132
  const node = nodes[key];
@@ -2923,6 +3137,7 @@ function applyStateFast(next, target, keyFn) {
2923
3137
  !previousValue ||
2924
3138
  !isWrappable(previousValue) ||
2925
3139
  !isWrappable(nextValue) ||
3140
+ Array.isArray(previousValue) !== Array.isArray(nextValue) ||
2926
3141
  (keyFn(previousValue) != null && keyFn(previousValue) !== keyFn(nextValue))
2927
3142
  ) {
2928
3143
  tracked && setSignal(tracked, void 0);
@@ -2931,7 +3146,7 @@ function applyStateFast(next, target, keyFn) {
2931
3146
  }
2932
3147
  }
2933
3148
  if ((nodes = target[STORE_HAS])) {
2934
- const keys = Object.keys(nodes);
3149
+ const keys = nodeKeys(nodes);
2935
3150
  for (let i = 0, len = keys.length; i < len; i++) {
2936
3151
  const key = keys[i];
2937
3152
  setSignal(nodes[key], key in next);
@@ -2949,16 +3164,21 @@ function applyStateSlow(next, target, keyFn) {
2949
3164
  if (Array.isArray(previous)) {
2950
3165
  let changed = false;
2951
3166
  const prevLength = getOverrideValue(previous, override, "length", optOverride);
2952
- if (next.length && prevLength && next[0] && keyFn(next[0]) != null) {
3167
+ if (next.length && prevLength && isWrappable(next[0]) && keyFn(next[0]) != null) {
2953
3168
  let i, j, start, end, newEnd, item, newIndicesNext, keyVal;
2954
3169
  for (
2955
3170
  start = 0, end = Math.min(prevLength, next.length);
2956
3171
  start < end &&
2957
- ((item = getOverrideValue(previous, override, start, optOverride)) === next[start] ||
2958
- (item && next[start] && keyFn(item) === keyFn(next[start])));
3172
+ keyedMatch(
3173
+ (item = getOverrideValue(previous, override, start, optOverride)),
3174
+ next[start],
3175
+ keyFn
3176
+ );
2959
3177
  start++
2960
3178
  ) {
2961
- applyState(next[start], wrap(item, target), keyFn);
3179
+ isWrappable(item) &&
3180
+ isWrappable(next[start]) &&
3181
+ applyState(next[start], wrap(item, target), keyFn);
2962
3182
  }
2963
3183
  const temp = new Array(next.length),
2964
3184
  newIndices = new Map();
@@ -2966,8 +3186,11 @@ function applyStateSlow(next, target, keyFn) {
2966
3186
  end = prevLength - 1, newEnd = next.length - 1;
2967
3187
  end >= start &&
2968
3188
  newEnd >= start &&
2969
- ((item = getOverrideValue(previous, override, end, optOverride)) === next[newEnd] ||
2970
- (item && next[newEnd] && keyFn(item) === keyFn(next[newEnd])));
3189
+ keyedMatch(
3190
+ (item = getOverrideValue(previous, override, end, optOverride)),
3191
+ next[newEnd],
3192
+ keyFn
3193
+ );
2971
3194
  end--, newEnd--
2972
3195
  ) {
2973
3196
  temp[newEnd] = item;
@@ -2975,30 +3198,29 @@ function applyStateSlow(next, target, keyFn) {
2975
3198
  if (start > newEnd || start > end) {
2976
3199
  for (j = start; j <= newEnd; j++) {
2977
3200
  changed = true;
2978
- nodes?.[j] && setSignal(nodes[j], wrap(next[j], target));
3201
+ nodes?.[j] && setSignal(nodes[j], wrapValue(next[j], target));
2979
3202
  }
2980
3203
  for (; j < next.length; j++) {
2981
3204
  changed = true;
2982
- const wrapped = wrap(temp[j], target);
2983
- nodes?.[j] && setSignal(nodes[j], wrapped);
2984
- applyState(next[j], wrapped, keyFn);
3205
+ applyArrayItem(next[j], temp[j], target, nodes?.[j], keyFn);
2985
3206
  }
2986
3207
  const nextLength = next.length;
2987
- changed && notifySelf(target);
3208
+ syncArrayNodeMembership(target, next);
3209
+ (changed || prevLength !== nextLength) && notifySelf(target);
2988
3210
  prevLength !== nextLength && nodes?.length && setSignal(nodes.length, nextLength);
2989
3211
  return;
2990
3212
  }
2991
3213
  newIndicesNext = new Array(newEnd + 1);
2992
3214
  for (j = newEnd; j >= start; j--) {
2993
3215
  item = next[j];
2994
- keyVal = item ? keyFn(item) : item;
3216
+ keyVal = itemKey(item, keyFn);
2995
3217
  i = newIndices.get(keyVal);
2996
3218
  newIndicesNext[j] = i === undefined ? -1 : i;
2997
3219
  newIndices.set(keyVal, j);
2998
3220
  }
2999
3221
  for (i = start; i <= end; i++) {
3000
3222
  item = getOverrideValue(previous, override, i, optOverride);
3001
- keyVal = item ? keyFn(item) : item;
3223
+ keyVal = itemKey(item, keyFn);
3002
3224
  j = newIndices.get(keyVal);
3003
3225
  if (j !== undefined && j !== -1) {
3004
3226
  temp[j] = item;
@@ -3008,23 +3230,23 @@ function applyStateSlow(next, target, keyFn) {
3008
3230
  }
3009
3231
  for (j = start; j < next.length; j++) {
3010
3232
  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));
3233
+ applyArrayItem(next[j], temp[j], target, nodes?.[j], keyFn);
3234
+ } else nodes?.[j] && setSignal(nodes[j], wrapValue(next[j], target));
3015
3235
  }
3016
3236
  if (start < next.length) changed = true;
3017
3237
  } else if (next.length) {
3018
3238
  for (let i = 0, len = next.length; i < len; i++) {
3019
3239
  const item = getOverrideValue(previous, override, i, optOverride);
3020
- if (isWrappable(item)) applyState(next[i], wrap(item, target), keyFn);
3240
+ if (isWrappable(item) && isWrappable(next[i]))
3241
+ applyState(next[i], wrap(item, target), keyFn);
3021
3242
  else {
3022
3243
  if (item !== next[i]) changed = true;
3023
- nodes?.[i] && setSignal(nodes[i], next[i]);
3244
+ nodes?.[i] && setSignal(nodes[i], wrapValue(next[i], target));
3024
3245
  }
3025
3246
  }
3026
3247
  }
3027
3248
  const nextLength = next.length;
3249
+ syncArrayNodeMembership(target, next);
3028
3250
  if (prevLength !== nextLength) {
3029
3251
  changed = true;
3030
3252
  nodes?.length && setSignal(nodes.length, nextLength);
@@ -3034,7 +3256,7 @@ function applyStateSlow(next, target, keyFn) {
3034
3256
  }
3035
3257
  if (nodes) {
3036
3258
  const tracked = nodes[$TRACK];
3037
- const keys = tracked ? getAllKeys(previous, override, next) : Object.keys(nodes);
3259
+ const keys = tracked ? getAllKeys(previous, override, next) : nodeKeys(nodes);
3038
3260
  for (let i = 0, len = keys.length; i < len; i++) {
3039
3261
  const key = keys[i];
3040
3262
  const node = nodes[key];
@@ -3045,6 +3267,7 @@ function applyStateSlow(next, target, keyFn) {
3045
3267
  !previousValue ||
3046
3268
  !isWrappable(previousValue) ||
3047
3269
  !isWrappable(nextValue) ||
3270
+ Array.isArray(previousValue) !== Array.isArray(nextValue) ||
3048
3271
  (keyFn(previousValue) != null && keyFn(previousValue) !== keyFn(nextValue))
3049
3272
  ) {
3050
3273
  tracked && setSignal(tracked, void 0);
@@ -3053,7 +3276,7 @@ function applyStateSlow(next, target, keyFn) {
3053
3276
  }
3054
3277
  }
3055
3278
  if ((nodes = target[STORE_HAS])) {
3056
- const keys = Object.keys(nodes);
3279
+ const keys = nodeKeys(nodes);
3057
3280
  for (let i = 0, len = keys.length; i < len; i++) {
3058
3281
  const key = keys[i];
3059
3282
  setSignal(nodes[key], key in next);
@@ -3193,7 +3416,8 @@ const STORE_VALUE = "v",
3193
3416
  STORE_WRAP = "w",
3194
3417
  STORE_LOOKUP = "l",
3195
3418
  STORE_FIREWALL = "f",
3196
- STORE_OPTIMISTIC = "p";
3419
+ STORE_OPTIMISTIC = "p",
3420
+ STORE_MASKED = "m";
3197
3421
  const STORE_SELF_PENDING = Symbol("STORE_SELF_PENDING");
3198
3422
  function createStoreProxy(value, traps = storeTraps, extend) {
3199
3423
  let newTarget;
@@ -3212,6 +3436,7 @@ function createStoreProxy(value, traps = storeTraps, extend) {
3212
3436
  return (newTarget[$PROXY] = new Proxy(newTarget, traps));
3213
3437
  }
3214
3438
  const storeLookup = new WeakMap();
3439
+ const symbolKeyedRecords = new WeakSet();
3215
3440
  function wrap(value, target) {
3216
3441
  if (target?.[STORE_WRAP]) return target[STORE_WRAP](value, target);
3217
3442
  let p = value[$PROXY] || storeLookup.get(value);
@@ -3252,21 +3477,26 @@ function unwrapStoreValue(value, map, lookup) {
3252
3477
  function isPrototypePollutionKey$1(property) {
3253
3478
  return property === "__proto__" || property === "constructor" || property === "prototype";
3254
3479
  }
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;
3480
+ function ownEnumerableKeys(o) {
3481
+ return Reflect.ownKeys(o).filter(k => Object.prototype.propertyIsEnumerable.call(o, k));
3482
+ }
3483
+ function getOverlayLayer(target, property) {
3484
+ const opt = target[STORE_OPTIMISTIC_OVERRIDE];
3485
+ if (opt && property in opt) return opt;
3263
3486
  const override = target[STORE_OVERRIDE];
3264
- if (
3265
- override &&
3266
- Object.prototype.hasOwnProperty.call(override, property) &&
3267
- override[property] !== $DELETED
3268
- )
3269
- return true;
3487
+ if (override && property in override) return override;
3488
+ return undefined;
3489
+ }
3490
+ function visibleNodeValue(node) {
3491
+ return node._overrideValue !== undefined && node._overrideValue !== NOT_PENDING
3492
+ ? node._overrideValue
3493
+ : node._pendingValue !== NOT_PENDING
3494
+ ? node._pendingValue
3495
+ : node._value;
3496
+ }
3497
+ function hasOwnStoreProperty(target, property) {
3498
+ const layer = getOverlayLayer(target, property);
3499
+ if (layer) return layer[property] !== $DELETED;
3270
3500
  return Object.prototype.hasOwnProperty.call(unwrapStoreValue(target[STORE_VALUE]), property);
3271
3501
  }
3272
3502
  function hasInheritedAccessor(source, property) {
@@ -3290,7 +3520,24 @@ function getNode(nodes, property, value, firewall, equals = isEqual, optimistic,
3290
3520
  {
3291
3521
  equals: equals,
3292
3522
  unobserved() {
3293
- if (nodes[property] === s) delete nodes[property];
3523
+ if (nodes[property] === s) {
3524
+ delete nodes[property];
3525
+ if (
3526
+ typeof property === "symbol" &&
3527
+ property !== $TRACK &&
3528
+ symbolKeyedRecords.has(nodes)
3529
+ ) {
3530
+ const syms = Object.getOwnPropertySymbols(nodes);
3531
+ let hasUserSymbol = false;
3532
+ for (let i = 0, len = syms.length; i < len; i++) {
3533
+ if (syms[i] !== $TRACK) {
3534
+ hasUserSymbol = true;
3535
+ break;
3536
+ }
3537
+ }
3538
+ if (!hasUserSymbol) symbolKeyedRecords.delete(nodes);
3539
+ }
3540
+ }
3294
3541
  }
3295
3542
  },
3296
3543
  firewall
@@ -3303,6 +3550,7 @@ function getNode(nodes, property, value, firewall, equals = isEqual, optimistic,
3303
3550
  s._snapshotValue = sv === undefined ? NO_SNAPSHOT : sv;
3304
3551
  snapshotSources?.add(s);
3305
3552
  }
3553
+ if (typeof property === "symbol" && property !== $TRACK) symbolKeyedRecords.add(nodes);
3306
3554
  return (nodes[property] = s);
3307
3555
  }
3308
3556
  function trackSelf(target, symbol = $TRACK) {
@@ -3327,7 +3575,11 @@ function notifySelf(target) {
3327
3575
  );
3328
3576
  }
3329
3577
  function getKeys(source, override, enumerable = true) {
3330
- const baseKeys = untrack(() => (enumerable ? Object.keys(source) : Reflect.ownKeys(source)));
3578
+ const baseKeys = source[$TARGET]
3579
+ ? untrack(() => (enumerable ? Object.keys(source) : Reflect.ownKeys(source)))
3580
+ : enumerable
3581
+ ? Object.keys(source)
3582
+ : Reflect.ownKeys(source);
3331
3583
  if (!override) return baseKeys;
3332
3584
  const keys = new Set(baseKeys);
3333
3585
  const overrides = Reflect.ownKeys(override);
@@ -3341,10 +3593,26 @@ function getPropertyDescriptor(source, override, property) {
3341
3593
  if (override && property in override) {
3342
3594
  if (override[property] === $DELETED) return void 0;
3343
3595
  const overrideDesc = Reflect.getOwnPropertyDescriptor(override, property);
3344
- if (overrideDesc?.get || overrideDesc?.set || !(property in source)) return overrideDesc;
3596
+ if (overrideDesc?.get || overrideDesc?.set) return overrideDesc;
3597
+ const baseDesc = Reflect.getOwnPropertyDescriptor(source, property);
3598
+ if (!baseDesc) return overrideDesc;
3599
+ if (baseDesc.get || baseDesc.set) return baseDesc;
3600
+ baseDesc.value = override[property];
3601
+ return baseDesc;
3345
3602
  }
3346
3603
  return Reflect.getOwnPropertyDescriptor(source, property);
3347
3604
  }
3605
+ function maskStoreTarget(target, on) {
3606
+ const firewall = target[STORE_FIREWALL];
3607
+ if (!firewall) return;
3608
+ if (!!target[STORE_MASKED] === on) return;
3609
+ target[STORE_MASKED] = on;
3610
+ const count = (firewall._optimisticMask = (firewall._optimisticMask || 0) + (on ? 1 : -1));
3611
+ if ((on && count === 1) || (!on && count === 0)) {
3612
+ updatePendingSignal(firewall);
3613
+ updateChildCompanions(firewall);
3614
+ }
3615
+ }
3348
3616
  function prepareStoreWrite(target, store, property) {
3349
3617
  if (target[STORE_OPTIMISTIC]) {
3350
3618
  const firewall = target[STORE_FIREWALL];
@@ -3369,9 +3637,14 @@ function prepareStoreWrite(target, store, property) {
3369
3637
  }
3370
3638
  const useOptimistic = target[STORE_OPTIMISTIC] && !projectionWriteActive;
3371
3639
  const overrideKey = useOptimistic ? STORE_OPTIMISTIC_OVERRIDE : STORE_OVERRIDE;
3372
- if (useOptimistic) trackOptimisticStore(store);
3373
3640
  return { base: base, overrideKey: overrideKey, state: state };
3374
3641
  }
3642
+ function armOptimisticStoreWrite(target, store) {
3643
+ if (target[STORE_OPTIMISTIC] && !projectionWriteActive) {
3644
+ trackOptimisticStore(store);
3645
+ maskStoreTarget(target, true);
3646
+ }
3647
+ }
3375
3648
  function upsertStoreNode(target, nodes, property, prev, snapshotProps) {
3376
3649
  if (nodes[property]) return nodes[property];
3377
3650
  const initial = isWrappable(prev) ? wrap(prev, target) : prev;
@@ -3449,16 +3722,10 @@ const storeTraps = {
3449
3722
  ) {
3450
3723
  return read(getNode(nodes, property, undefined, target[STORE_FIREWALL]));
3451
3724
  }
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]);
3725
+ const overlay = getOverlayLayer(target, property);
3726
+ const overridden = !!overlay;
3456
3727
  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];
3728
+ const storeValue = overlay ?? target[STORE_VALUE];
3462
3729
  if (!tracked) {
3463
3730
  const desc = Object.getOwnPropertyDescriptor(storeValue, property);
3464
3731
  if (desc && desc.get) return desc.get.call(receiver);
@@ -3473,13 +3740,7 @@ const storeTraps = {
3473
3740
  if (isPrototypePollutionKey$1(property) && !hasOwnStoreProperty(target, property))
3474
3741
  return undefined;
3475
3742
  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];
3743
+ tracked && (overridden || !proxySource) ? visibleNodeValue(tracked) : storeValue[property];
3483
3744
  value === $DELETED && (value = undefined);
3484
3745
  if (!isWrappable(value)) return value;
3485
3746
  const wrapped = wrap(value, target);
@@ -3493,7 +3754,11 @@ const storeTraps = {
3493
3754
  : storeValue[property];
3494
3755
  value === $DELETED && (value = undefined);
3495
3756
  if (!tracked) {
3496
- if (!overridden && typeof value === "function" && !storeValue.hasOwnProperty(property)) {
3757
+ if (
3758
+ !overridden &&
3759
+ typeof value === "function" &&
3760
+ !Object.prototype.hasOwnProperty.call(storeValue, property)
3761
+ ) {
3497
3762
  let proto;
3498
3763
  return !Array.isArray(target[STORE_VALUE]) &&
3499
3764
  (proto = Object.getPrototypeOf(target[STORE_VALUE])) &&
@@ -3532,12 +3797,8 @@ const storeTraps = {
3532
3797
  },
3533
3798
  has(target, property) {
3534
3799
  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];
3800
+ const hasLayer = getOverlayLayer(target, property);
3801
+ const has = hasLayer ? hasLayer[property] !== $DELETED : property in target[STORE_VALUE];
3541
3802
  if (writeOnly(target[$PROXY]) || getObserver() === target[STORE_FIREWALL]) return has;
3542
3803
  const nodes = getNodes(target, STORE_HAS);
3543
3804
  if (nodes[property]) return read(nodes[property]);
@@ -3558,30 +3819,19 @@ const storeTraps = {
3558
3819
  overrideKey: overrideKey,
3559
3820
  state: state
3560
3821
  } = 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];
3822
+ const prevLayer = getOverlayLayer(target, property);
3823
+ const prev = prevLayer ? prevLayer[property] : base;
3824
+ const prevHas = prevLayer
3825
+ ? prevLayer[property] !== $DELETED
3826
+ : property in target[STORE_VALUE];
3573
3827
  const value = unwrapStoreValue(rawValue);
3574
- const isArrayIndexWrite = Array.isArray(state) && property !== "length";
3828
+ const isArrayIndexWrite =
3829
+ Array.isArray(state) && property !== "length" && typeof property !== "symbol";
3575
3830
  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);
3831
+ const len = isArrayIndexWrite && (getOverlayLayer(target, "length") ?? state).length;
3583
3832
  const nextLength = isArrayIndexWrite && nextIndex > len ? nextIndex : undefined;
3584
3833
  if (prev === value && nextLength === undefined) return true;
3834
+ armOptimisticStoreWrite(target, store);
3585
3835
  if (value !== undefined && value === base && nextLength === undefined)
3586
3836
  delete target[overrideKey]?.[property];
3587
3837
  else {
@@ -3590,6 +3840,22 @@ const storeTraps = {
3590
3840
  if (nextLength !== undefined) override.length = nextLength;
3591
3841
  }
3592
3842
  notifyStoreProperty(target, property, "set", value, prev, prevHas);
3843
+ if (
3844
+ Array.isArray(state) &&
3845
+ property === "length" &&
3846
+ typeof value === "number" &&
3847
+ typeof prev === "number" &&
3848
+ value < prev
3849
+ ) {
3850
+ const override = target[overrideKey] || (target[overrideKey] = Object.create(null));
3851
+ for (let i = value; i < prev; i++) {
3852
+ if (override[i] === $DELETED) continue;
3853
+ const prevIndex = i in override ? override[i] : state[i];
3854
+ if (!(i in override) && !(i in state)) continue;
3855
+ override[i] = $DELETED;
3856
+ notifyStoreProperty(target, i, "delete", undefined, prevIndex, true);
3857
+ }
3858
+ }
3593
3859
  if (Array.isArray(state) && property !== "length" && nextLength !== undefined) {
3594
3860
  const nodes = getNodes(target, STORE_NODE);
3595
3861
  if (nodes.length) {
@@ -3616,6 +3882,7 @@ const storeTraps = {
3616
3882
  if (writeOnly(store)) {
3617
3883
  untrack(() => {
3618
3884
  const { base: base, overrideKey: overrideKey } = prepareStoreWrite(target, store, property);
3885
+ armOptimisticStoreWrite(target, store);
3619
3886
  const normalizedDescriptor =
3620
3887
  "value" in descriptor
3621
3888
  ? { ...descriptor, value: unwrapStoreValue(descriptor.value) }
@@ -3645,19 +3912,16 @@ const storeTraps = {
3645
3912
  untrack(() => {
3646
3913
  const useOptimistic = target[STORE_OPTIMISTIC] && !projectionWriteActive;
3647
3914
  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];
3915
+ const prevLayer = getOverlayLayer(target, property);
3916
+ const prev = prevLayer ? prevLayer[property] : target[STORE_VALUE][property];
3655
3917
  if (
3656
3918
  property in target[STORE_VALUE] ||
3657
3919
  (target[STORE_OVERRIDE] && property in target[STORE_OVERRIDE])
3658
3920
  ) {
3921
+ armOptimisticStoreWrite(target, target[$PROXY]);
3659
3922
  (target[overrideKey] || (target[overrideKey] = Object.create(null)))[property] = $DELETED;
3660
3923
  } else if (target[overrideKey] && property in target[overrideKey]) {
3924
+ armOptimisticStoreWrite(target, target[$PROXY]);
3661
3925
  delete target[overrideKey][property];
3662
3926
  } else return true;
3663
3927
  notifyStoreProperty(target, property, "delete", undefined, prev, true);
@@ -3686,7 +3950,13 @@ const storeTraps = {
3686
3950
  if (optDesc?.get || optDesc?.set || !(property in target[STORE_VALUE])) return optDesc;
3687
3951
  const baseDesc = getPropertyDescriptor(target[STORE_VALUE], target[STORE_OVERRIDE], property);
3688
3952
  if (baseDesc) {
3689
- return { ...baseDesc, value: target[STORE_OPTIMISTIC_OVERRIDE][property] };
3953
+ const targetDesc = Reflect.getOwnPropertyDescriptor(target, property);
3954
+ const configurable = !targetDesc || targetDesc.configurable ? true : baseDesc.configurable;
3955
+ return {
3956
+ ...baseDesc,
3957
+ configurable: configurable,
3958
+ value: target[STORE_OPTIMISTIC_OVERRIDE][property]
3959
+ };
3690
3960
  }
3691
3961
  return {
3692
3962
  value: target[STORE_OPTIMISTIC_OVERRIDE][property],
@@ -3695,7 +3965,12 @@ const storeTraps = {
3695
3965
  configurable: true
3696
3966
  };
3697
3967
  }
3698
- return getPropertyDescriptor(target[STORE_VALUE], target[STORE_OVERRIDE], property);
3968
+ const desc = getPropertyDescriptor(target[STORE_VALUE], target[STORE_OVERRIDE], property);
3969
+ if (desc && !desc.configurable) {
3970
+ const targetDesc = Reflect.getOwnPropertyDescriptor(target, property);
3971
+ if (!targetDesc || targetDesc.configurable) return { ...desc, configurable: true };
3972
+ }
3973
+ return desc;
3699
3974
  },
3700
3975
  getPrototypeOf(target) {
3701
3976
  return Object.getPrototypeOf(target[STORE_VALUE]);
@@ -3712,7 +3987,7 @@ function storeSetter(store, fn) {
3712
3987
  for (let i = 0, len = value.length; i < len; i++) store[i] = value[i];
3713
3988
  store.length = value.length;
3714
3989
  } else {
3715
- const keys = new Set([...Object.keys(store), ...Object.keys(value)]);
3990
+ const keys = new Set([...ownEnumerableKeys(store), ...ownEnumerableKeys(value)]);
3716
3991
  keys.forEach(key => {
3717
3992
  if (key in value) store[key] = value[key];
3718
3993
  else delete store[key];
@@ -3748,12 +4023,15 @@ function createOptimisticStore(first, second, options) {
3748
4023
  }
3749
4024
  function clearOptimisticStore(store) {
3750
4025
  const target = store[$TARGET];
3751
- if (!target || !target[STORE_OPTIMISTIC_OVERRIDE]) return;
4026
+ if (!target) return;
4027
+ maskStoreTarget(target, false);
4028
+ if (!target[STORE_OPTIMISTIC_OVERRIDE]) return;
3752
4029
  clearOptimisticOverride(target);
3753
4030
  }
3754
4031
  function clearOptimisticOverride(target) {
3755
4032
  const override = target[STORE_OPTIMISTIC_OVERRIDE];
3756
4033
  if (!override) return;
4034
+ maskStoreTarget(target, false);
3757
4035
  const nodes = target[STORE_NODE];
3758
4036
  delete target[STORE_OPTIMISTIC_OVERRIDE];
3759
4037
  const wasProjectionWriteActive = projectionWriteActive;
@@ -3764,18 +4042,11 @@ function clearOptimisticOverride(target) {
3764
4042
  if (nodes[key]) {
3765
4043
  const node = nodes[key];
3766
4044
  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];
4045
+ const layer = getOverlayLayer(target, key);
4046
+ const baseValue = layer ? layer[key] : target[STORE_VALUE][key];
3771
4047
  const value = baseValue === $DELETED ? undefined : baseValue;
3772
4048
  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;
4049
+ const prev = visibleNodeValue(node);
3779
4050
  node._overrideValue = NOT_PENDING;
3780
4051
  node._pendingValue = NOT_PENDING;
3781
4052
  node._value = next;
@@ -3907,10 +4178,10 @@ function updatePath(current, args, i = 0) {
3907
4178
  (isWrappable(prev) && isWrappable(value) && !Array.isArray(value))
3908
4179
  ) {
3909
4180
  const target = part !== undefined ? current[part] : current;
3910
- const keys = Object.keys(value);
4181
+ const keys = ownEnumerableKeys(value);
3911
4182
  for (let i = 0; i < keys.length; i++) {
3912
4183
  const key = keys[i];
3913
- if (isPrototypePollutionKey(key)) continue;
4184
+ if (typeof key === "string" && isPrototypePollutionKey(key)) continue;
3914
4185
  const desc = Object.getOwnPropertyDescriptor(value, key);
3915
4186
  if (desc.get || desc.set) Object.defineProperty(target, key, desc);
3916
4187
  else target[key] = desc.value;
@@ -3927,6 +4198,11 @@ const storePath = Object.assign(
3927
4198
  },
3928
4199
  { DELETE: DELETE }
3929
4200
  );
4201
+ function mergedOverlay(target) {
4202
+ const override = target[STORE_OVERRIDE];
4203
+ const opt = target[STORE_OPTIMISTIC_OVERRIDE];
4204
+ return override && opt ? { ...override, ...opt } : (opt ?? override);
4205
+ }
3930
4206
  function snapshotImpl(item, track, map, lookup) {
3931
4207
  let target, isArray, override, result, unwrapped, v;
3932
4208
  if (!isWrappable(item)) return item;
@@ -3934,7 +4210,7 @@ function snapshotImpl(item, track, map, lookup) {
3934
4210
  if (!map) map = new Map();
3935
4211
  if ((target = item[$TARGET] || lookup?.get(item)?.[$TARGET])) {
3936
4212
  if (track) trackSelf(target, $TRACK);
3937
- override = target[STORE_OVERRIDE];
4213
+ override = mergedOverlay(target);
3938
4214
  isArray = Array.isArray(target[STORE_VALUE]);
3939
4215
  map.set(
3940
4216
  item,
@@ -3959,13 +4235,30 @@ function snapshotImpl(item, track, map, lookup) {
3959
4235
  result[i] = unwrapped;
3960
4236
  }
3961
4237
  }
4238
+ if (result) result.length = len;
4239
+ } else if (!override) {
4240
+ const keys = getKeys(item, undefined);
4241
+ for (let i = 0, l = keys.length; i < l; i++) {
4242
+ const prop = keys[i];
4243
+ const desc = Object.getOwnPropertyDescriptor(item, prop);
4244
+ if (desc.get) continue;
4245
+ v = desc.value;
4246
+ if (track && isWrappable(v)) wrap(v, target);
4247
+ if ((unwrapped = snapshotImpl(v, track, map, lookup)) !== v || result) {
4248
+ if (!result) {
4249
+ result = Object.create(Object.getPrototypeOf(item));
4250
+ Object.assign(result, item);
4251
+ }
4252
+ result[prop] = unwrapped;
4253
+ }
4254
+ }
3962
4255
  } else {
3963
4256
  const keys = getKeys(item, override);
3964
4257
  for (let i = 0, l = keys.length; i < l; i++) {
3965
4258
  let prop = keys[i];
3966
4259
  const desc = getPropertyDescriptor(item, override, prop);
3967
4260
  if (desc.get) continue;
3968
- v = override && prop in override ? override[prop] : item[prop];
4261
+ v = prop in override ? override[prop] : item[prop];
3969
4262
  if (track && isWrappable(v)) wrap(v, target);
3970
4263
  if ((unwrapped = snapshotImpl(v, track, map, lookup)) !== item[prop] || result) {
3971
4264
  if (!result) {
@@ -4048,7 +4341,7 @@ function merge(...sources) {
4048
4341
  keys() {
4049
4342
  const keys = new Set();
4050
4343
  for (let i = 0; i < flattened.length; i++) {
4051
- const sourceKeys = Object.keys(resolveSource(flattened[i]));
4344
+ const sourceKeys = ownEnumerableKeys(resolveSource(flattened[i]));
4052
4345
  for (let j = 0; j < sourceKeys.length; j++) keys.add(sourceKeys[j]);
4053
4346
  }
4054
4347
  return [...keys];
@@ -4102,7 +4395,7 @@ function omit(props, ...keys) {
4102
4395
  return !keys.includes(property) && property in props;
4103
4396
  },
4104
4397
  keys() {
4105
- return Object.keys(props).filter(k => !keys.includes(k));
4398
+ return ownEnumerableKeys(props).filter(k => !keys.includes(k));
4106
4399
  }
4107
4400
  },
4108
4401
  propTraps
@@ -4331,6 +4624,18 @@ function updateRepeat() {
4331
4624
  const to = from + newLen;
4332
4625
  const prevTo = this._offset + this._len;
4333
4626
  if (this._len === 0 && this._nodes[0]) this._nodes[0].dispose();
4627
+ if (from >= prevTo || to <= this._offset) {
4628
+ for (let i = 0; i < this._len; i++) this._nodes[i].dispose();
4629
+ this._nodes = new Array(newLen);
4630
+ this._mappings = new Array(newLen);
4631
+ for (let i = 0; i < newLen; i++)
4632
+ this._mappings[i] = runWithOwner((this._nodes[i] = createOwner()), () =>
4633
+ this._map(from + i)
4634
+ );
4635
+ this._offset = from;
4636
+ this._len = newLen;
4637
+ return;
4638
+ }
4334
4639
  for (let i = to; i < prevTo; i++) this._nodes[i - this._offset].dispose();
4335
4640
  if (this._offset < from) {
4336
4641
  const removed = from - this._offset;
@@ -4372,7 +4677,13 @@ function boundaryComputed(fn, propagationMask) {
4372
4677
  const flags = status !== undefined ? status : node._statusFlags;
4373
4678
  const actualError = error !== undefined ? error : node._error;
4374
4679
  node._statusFlags &= ~node._propagationMask;
4375
- node._queue.notify(node, node._propagationMask, flags, actualError);
4680
+ node._queue.notify(node, STATUS_PENDING | STATUS_ERROR, flags, actualError);
4681
+ const foreign = flags & ~node._propagationMask & (STATUS_PENDING | STATUS_ERROR);
4682
+ if (foreign) {
4683
+ node._statusFlags &= ~foreign;
4684
+ if (node._error === actualError && !(node._statusFlags & (STATUS_PENDING | STATUS_ERROR)))
4685
+ node._error = undefined;
4686
+ }
4376
4687
  };
4377
4688
  node._propagationMask = propagationMask;
4378
4689
  node._config &= ~CONFIG_AUTO_DISPOSE;
@@ -4564,11 +4875,11 @@ class CollectionQueue extends Queue {
4564
4875
  this._sources.clear();
4565
4876
  }
4566
4877
  }
4567
- if (this._collectionType & STATUS_PENDING && this._initialized)
4568
- return super.notify(node, type, flags, error);
4569
4878
  if (this._collectionType & STATUS_PENDING && flags & STATUS_ERROR) {
4570
4879
  return super.notify(node, STATUS_ERROR, flags, error);
4571
4880
  }
4881
+ if (this._collectionType & STATUS_PENDING && this._initialized)
4882
+ return super.notify(node, type, flags, error);
4572
4883
  if (flags & this._collectionType) {
4573
4884
  this._pending = true;
4574
4885
  const source = error?.source || node._error?.source;
@@ -4655,14 +4966,17 @@ function createCollectionBoundary(type, fn, fallback, onFn) {
4655
4966
  cleanup(() => controller.unregister(queue));
4656
4967
  }
4657
4968
  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
- })
4969
+ computed(
4970
+ () => {
4971
+ if (!read(queue._disabled)) {
4972
+ const resolved = read(tree);
4973
+ if (!untrack(() => read(queue._disabled))) return ((queue._initialized = true), resolved);
4974
+ }
4975
+ if (_revealUsed && read(queue._collapsed)) return undefined;
4976
+ return fallback(queue);
4977
+ },
4978
+ { _noSnapshot: true }
4979
+ )
4666
4980
  );
4667
4981
  }
4668
4982
  function createLoadingBoundary(fn, fallback, options) {
@@ -4809,6 +5123,7 @@ export {
4809
5123
  refresh,
4810
5124
  releaseSnapshotScope,
4811
5125
  repeat,
5126
+ resetErrorHalt,
4812
5127
  resolve,
4813
5128
  runWithOwner,
4814
5129
  setContext,