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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/dev.js CHANGED
@@ -140,107 +140,6 @@ function getObservers(node) {
140
140
  }
141
141
  return observers;
142
142
  }
143
- function actualInsertIntoHeap(n, heap) {
144
- const parentHeight =
145
- (n._parent?._root ? n._parent._parentComputed?._height : n._parent?._height) ?? -1;
146
- if (parentHeight >= n._height) n._height = parentHeight + 1;
147
- const height = n._height;
148
- const heapAtHeight = heap._heap[height];
149
- if (heapAtHeight === undefined) heap._heap[height] = n;
150
- else {
151
- const tail = heapAtHeight._prevHeap;
152
- tail._nextHeap = n;
153
- n._prevHeap = tail;
154
- heapAtHeight._prevHeap = n;
155
- }
156
- if (height > heap._max) heap._max = height;
157
- }
158
- function insertIntoHeap(n, heap) {
159
- let flags = n._flags;
160
- if (flags & (REACTIVE_IN_HEAP | REACTIVE_RECOMPUTING_DEPS | REACTIVE_MANUAL_WRITE)) return;
161
- if (flags & REACTIVE_CHECK) {
162
- n._flags = (flags & -4) | REACTIVE_DIRTY | REACTIVE_IN_HEAP;
163
- } else n._flags = flags | REACTIVE_IN_HEAP;
164
- if (!(flags & REACTIVE_IN_HEAP_HEIGHT)) actualInsertIntoHeap(n, heap);
165
- }
166
- function insertIntoHeapHeight(n, heap) {
167
- let flags = n._flags;
168
- if (
169
- flags &
170
- (REACTIVE_IN_HEAP | REACTIVE_RECOMPUTING_DEPS | REACTIVE_IN_HEAP_HEIGHT | REACTIVE_MANUAL_WRITE)
171
- )
172
- return;
173
- n._flags = flags | REACTIVE_IN_HEAP_HEIGHT;
174
- actualInsertIntoHeap(n, heap);
175
- }
176
- function deleteFromHeap(n, heap) {
177
- const flags = n._flags;
178
- if (!(flags & (REACTIVE_IN_HEAP | REACTIVE_IN_HEAP_HEIGHT))) return;
179
- n._flags = flags & -25;
180
- const height = n._height;
181
- if (n._prevHeap === n) heap._heap[height] = undefined;
182
- else {
183
- const next = n._nextHeap;
184
- const dhh = heap._heap[height];
185
- const end = next ?? dhh;
186
- if (n === dhh) heap._heap[height] = next;
187
- else n._prevHeap._nextHeap = next;
188
- end._prevHeap = n._prevHeap;
189
- }
190
- n._prevHeap = n;
191
- n._nextHeap = undefined;
192
- }
193
- function markHeap(heap) {
194
- if (heap._marked) return;
195
- heap._marked = true;
196
- for (let i = 0; i <= heap._max; i++) {
197
- for (let el = heap._heap[i]; el !== undefined; el = el._nextHeap) {
198
- if (el._flags & REACTIVE_IN_HEAP) markNode(el);
199
- }
200
- }
201
- }
202
- function markNode(el, newState = REACTIVE_DIRTY) {
203
- const flags = el._flags;
204
- if ((flags & (REACTIVE_CHECK | REACTIVE_DIRTY)) >= newState) return;
205
- el._flags = (flags & -4) | newState;
206
- for (let link = el._subs; link !== null; link = link._nextSub) {
207
- markNode(link._sub, REACTIVE_CHECK);
208
- }
209
- if (el._child !== null) {
210
- for (let child = el._child; child !== null; child = child._nextChild) {
211
- for (let link = child._subs; link !== null; link = link._nextSub) {
212
- markNode(link._sub, REACTIVE_CHECK);
213
- }
214
- }
215
- }
216
- }
217
- function runHeap(heap, recompute) {
218
- heap._marked = false;
219
- for (heap._min = 0; heap._min <= heap._max; heap._min++) {
220
- let el = heap._heap[heap._min];
221
- while (el !== undefined) {
222
- if (el._flags & REACTIVE_IN_HEAP) recompute(el);
223
- else adjustHeight(el, heap);
224
- el = heap._heap[heap._min];
225
- }
226
- }
227
- heap._max = 0;
228
- }
229
- function adjustHeight(el, heap) {
230
- deleteFromHeap(el, heap);
231
- let newHeight = el._height;
232
- for (let d = el._deps; d; d = d._nextDep) {
233
- const dep1 = d._dep;
234
- const dep = dep1._firewall || dep1;
235
- if (dep._fn && dep._height >= newHeight) newHeight = dep._height + 1;
236
- }
237
- if (el._height !== newHeight) {
238
- el._height = newHeight;
239
- for (let s = el._subs; s !== null; s = s._nextSub) {
240
- insertIntoHeapHeight(s._sub, heap);
241
- }
242
- }
243
- }
244
143
  const signalLanes = new WeakMap();
245
144
  const activeLanes = new Set();
246
145
  function getOrCreateLane(signal) {
@@ -796,8 +695,11 @@ function flush(fn) {
796
695
  try {
797
696
  return fn();
798
697
  } finally {
799
- flush();
800
- syncDepth--;
698
+ try {
699
+ flush();
700
+ } finally {
701
+ syncDepth--;
702
+ }
801
703
  }
802
704
  }
803
705
  if (globalQueue._running) {
@@ -886,24 +788,127 @@ function runInTransition(transition, fn) {
886
788
  activeTransition = prevTransition;
887
789
  }
888
790
  }
791
+ function actualInsertIntoHeap(n, heap) {
792
+ const parentHeight =
793
+ (n._parent?._root ? n._parent._parentComputed?._height : n._parent?._height) ?? -1;
794
+ if (parentHeight >= n._height) n._height = parentHeight + 1;
795
+ const height = n._height;
796
+ const heapAtHeight = heap._heap[height];
797
+ if (heapAtHeight === undefined) heap._heap[height] = n;
798
+ else {
799
+ const tail = heapAtHeight._prevHeap;
800
+ tail._nextHeap = n;
801
+ n._prevHeap = tail;
802
+ heapAtHeight._prevHeap = n;
803
+ }
804
+ if (height > heap._max) heap._max = height;
805
+ }
806
+ function insertIntoHeap(n, heap) {
807
+ let flags = n._flags;
808
+ if (flags & (REACTIVE_IN_HEAP | REACTIVE_RECOMPUTING_DEPS | REACTIVE_MANUAL_WRITE)) return;
809
+ if (flags & REACTIVE_CHECK) {
810
+ n._flags = (flags & -4) | REACTIVE_DIRTY | REACTIVE_IN_HEAP;
811
+ } else n._flags = flags | REACTIVE_IN_HEAP;
812
+ if (!(flags & REACTIVE_IN_HEAP_HEIGHT)) actualInsertIntoHeap(n, heap);
813
+ }
814
+ function insertIntoHeapHeight(n, heap) {
815
+ let flags = n._flags;
816
+ if (
817
+ flags &
818
+ (REACTIVE_IN_HEAP | REACTIVE_RECOMPUTING_DEPS | REACTIVE_IN_HEAP_HEIGHT | REACTIVE_MANUAL_WRITE)
819
+ )
820
+ return;
821
+ n._flags = flags | REACTIVE_IN_HEAP_HEIGHT;
822
+ actualInsertIntoHeap(n, heap);
823
+ }
824
+ function deleteFromHeap(n, heap) {
825
+ const flags = n._flags;
826
+ if (!(flags & (REACTIVE_IN_HEAP | REACTIVE_IN_HEAP_HEIGHT))) return;
827
+ n._flags = flags & -25;
828
+ const height = n._height;
829
+ if (n._prevHeap === n) heap._heap[height] = undefined;
830
+ else {
831
+ const next = n._nextHeap;
832
+ const dhh = heap._heap[height];
833
+ const end = next ?? dhh;
834
+ if (n === dhh) heap._heap[height] = next;
835
+ else n._prevHeap._nextHeap = next;
836
+ end._prevHeap = n._prevHeap;
837
+ }
838
+ n._prevHeap = n;
839
+ n._nextHeap = undefined;
840
+ }
841
+ function markHeap(heap) {
842
+ if (heap._marked) return;
843
+ heap._marked = true;
844
+ for (let i = 0; i <= heap._max; i++) {
845
+ for (let el = heap._heap[i]; el !== undefined; el = el._nextHeap) {
846
+ if (el._flags & REACTIVE_IN_HEAP) markNode(el);
847
+ }
848
+ }
849
+ }
850
+ function markNode(el, newState = REACTIVE_DIRTY) {
851
+ const flags = el._flags;
852
+ if ((flags & (REACTIVE_CHECK | REACTIVE_DIRTY)) >= newState) return;
853
+ el._flags = (flags & -4) | newState;
854
+ for (let link = el._subs; link !== null; link = link._nextSub) {
855
+ markNode(link._sub, REACTIVE_CHECK);
856
+ }
857
+ if (el._child !== null) {
858
+ for (let child = el._child; child !== null; child = child._nextChild) {
859
+ for (let link = child._subs; link !== null; link = link._nextSub) {
860
+ markNode(link._sub, REACTIVE_CHECK);
861
+ }
862
+ }
863
+ }
864
+ }
865
+ function runHeap(heap, recompute) {
866
+ heap._marked = false;
867
+ for (heap._min = 0; heap._min <= heap._max; heap._min++) {
868
+ let el = heap._heap[heap._min];
869
+ while (el !== undefined) {
870
+ if (el._flags & REACTIVE_IN_HEAP) recompute(el);
871
+ else adjustHeight(el, heap);
872
+ el = heap._heap[heap._min];
873
+ }
874
+ }
875
+ heap._max = 0;
876
+ }
877
+ function adjustHeight(el, heap) {
878
+ deleteFromHeap(el, heap);
879
+ let newHeight = el._height;
880
+ for (let d = el._deps; d; d = d._nextDep) {
881
+ const dep1 = d._dep;
882
+ const dep = dep1._firewall || dep1;
883
+ if (dep._fn && dep._height >= newHeight) newHeight = dep._height + 1;
884
+ }
885
+ if (el._height !== newHeight) {
886
+ el._height = newHeight;
887
+ for (let s = el._subs; s !== null; s = s._nextSub) {
888
+ insertIntoHeapHeight(s._sub, s._sub._flags & REACTIVE_ZOMBIE ? zombieQueue : dirtyQueue);
889
+ }
890
+ }
891
+ }
889
892
  const PENDING_OWNER = {};
890
893
  function markDisposal(el) {
891
894
  let child = el._firstChild;
892
895
  while (child) {
893
- child._flags |= REACTIVE_ZOMBIE;
894
- if (child._flags & REACTIVE_IN_HEAP) {
895
- deleteFromHeap(child, dirtyQueue);
896
- insertIntoHeap(child, zombieQueue);
896
+ const flags = child._flags;
897
+ child._flags = flags | REACTIVE_ZOMBIE;
898
+ if (flags & (REACTIVE_IN_HEAP | REACTIVE_IN_HEAP_HEIGHT)) {
899
+ deleteFromHeap(child, flags & REACTIVE_ZOMBIE ? zombieQueue : dirtyQueue);
900
+ if (flags & REACTIVE_IN_HEAP) insertIntoHeap(child, zombieQueue);
901
+ else insertIntoHeapHeight(child, zombieQueue);
897
902
  }
898
903
  markDisposal(child);
899
904
  child = child._nextSibling;
900
905
  }
901
906
  }
902
907
  function dispose(node) {
903
- let toRemove = node._deps || null;
904
- do {
908
+ let toRemove = node._deps;
909
+ while (toRemove !== null) {
905
910
  toRemove = unlinkSubs(toRemove);
906
- } while (toRemove !== null);
911
+ }
907
912
  node._deps = null;
908
913
  node._depsTail = null;
909
914
  disposeChildren(node, true);
@@ -1264,8 +1269,10 @@ function handleAsync(el, result, setter) {
1264
1269
  clearStatus(el);
1265
1270
  const lane = resolveLane(el);
1266
1271
  if (lane) lane._pendingAsync.delete(el);
1267
- if (setter) setter(value);
1268
- else if (el._overrideValue !== undefined) {
1272
+ if (setter) {
1273
+ setter(value);
1274
+ if (wasUninitialized) clearStatus(el, true);
1275
+ } else if (el._overrideValue !== undefined) {
1269
1276
  if (el._overrideValue !== undefined && el._overrideValue !== NOT_PENDING)
1270
1277
  el._pendingValue = value;
1271
1278
  else {
@@ -1461,9 +1468,14 @@ GlobalQueue._update = recompute;
1461
1468
  GlobalQueue._dispose = disposeChildren;
1462
1469
  const PRIMITIVE_IN_FORBIDDEN_SCOPE_MESSAGE =
1463
1470
  "[PRIMITIVE_IN_FORBIDDEN_SCOPE] Cannot create reactive primitives inside createTrackedEffect or owner-backed onSettled";
1471
+ const REACTIVE_WRITE_IN_OWNED_SCOPE_SIGNAL_MESSAGE =
1472
+ "[REACTIVE_WRITE_IN_OWNED_SCOPE] Writing to reactive state inside an owned scope (component, computation) is not allowed. " +
1473
+ "Move the write outside or set the `ownedWrite` option if this is intentional.";
1474
+ const REACTIVE_WRITE_IN_OWNED_SCOPE_REFRESH_MESSAGE =
1475
+ "[REACTIVE_WRITE_IN_OWNED_SCOPE] Calling refresh() inside an owned scope (component, computation) is not allowed. " +
1476
+ "Move the invalidation outside pure computation.";
1464
1477
  let tracking = false;
1465
1478
  let stale = false;
1466
- let refreshing = false;
1467
1479
  let pendingCheckActive = false;
1468
1480
  let foundPending = false;
1469
1481
  let latestReadActive = false;
@@ -2099,7 +2111,7 @@ function read(el) {
2099
2111
  currentOptimisticLane !== null &&
2100
2112
  !latestReadActive &&
2101
2113
  el._pendingValue !== NOT_PENDING &&
2102
- owner === el &&
2114
+ (owner === el || !!(owner._flags & REACTIVE_MANUAL_WRITE)) &&
2103
2115
  !el._fn &&
2104
2116
  c
2105
2117
  ) {
@@ -2136,19 +2148,17 @@ function setSignal(el, v) {
2136
2148
  context &&
2137
2149
  el._firewall !== context
2138
2150
  ) {
2139
- const message =
2140
- "[SIGNAL_WRITE_IN_OWNED_SCOPE] Writing to a Signal inside an owned scope (component, computation) is not allowed. " +
2141
- "Move the write outside or set the `ownedWrite` option if this is intentional.";
2142
2151
  emitDiagnostic({
2143
- code: "SIGNAL_WRITE_IN_OWNED_SCOPE",
2152
+ code: "REACTIVE_WRITE_IN_OWNED_SCOPE",
2144
2153
  kind: "write",
2145
2154
  severity: "error",
2146
- message: message,
2155
+ message: REACTIVE_WRITE_IN_OWNED_SCOPE_SIGNAL_MESSAGE,
2147
2156
  ownerId: context.id,
2148
2157
  ownerName: context._name,
2149
- nodeName: el._name
2158
+ nodeName: el._name,
2159
+ data: { operation: "setSignal" }
2150
2160
  });
2151
- throw new Error(message);
2161
+ throw new Error(REACTIVE_WRITE_IN_OWNED_SCOPE_SIGNAL_MESSAGE);
2152
2162
  }
2153
2163
  if (el._transition && activeTransition !== el._transition)
2154
2164
  globalQueue.initTransition(el._transition);
@@ -2165,9 +2175,13 @@ function setSignal(el, v) {
2165
2175
  const valueChanged =
2166
2176
  !el._equals || !el._equals(currentValue, v) || !!(el._statusFlags & STATUS_UNINITIALIZED);
2167
2177
  if (!valueChanged) {
2168
- if (isOptimistic && hasOverride && el._fn) {
2169
- insertSubs(el, true);
2170
- schedule();
2178
+ if (isOptimistic && hasOverride) {
2179
+ const transition = resolveTransition(el);
2180
+ if (transition && activeTransition !== transition) globalQueue.initTransition(transition);
2181
+ if (el._fn) {
2182
+ insertSubs(el, true);
2183
+ schedule();
2184
+ }
2171
2185
  }
2172
2186
  return v;
2173
2187
  }
@@ -2197,8 +2211,10 @@ function setSignal(el, v) {
2197
2211
  }
2198
2212
  function suppressComputedRecompute(el) {
2199
2213
  deleteFromHeap(el, el._flags & REACTIVE_ZOMBIE ? zombieQueue : dirtyQueue);
2200
- if (!(el._flags & REACTIVE_MANUAL_WRITE) && el._pendingValue === NOT_PENDING)
2214
+ if (!(el._flags & REACTIVE_MANUAL_WRITE) && el._pendingValue === NOT_PENDING) {
2201
2215
  queuePendingNode(el);
2216
+ schedule();
2217
+ }
2202
2218
  el._flags = (el._flags & -4) | REACTIVE_MANUAL_WRITE;
2203
2219
  }
2204
2220
  function setMemo(el, v) {
@@ -2256,7 +2272,10 @@ function computePendingState(el) {
2256
2272
  return el._pendingValue !== NOT_PENDING && !(comp._statusFlags & STATUS_UNINITIALIZED);
2257
2273
  }
2258
2274
  if (firewall && el._pendingValue !== NOT_PENDING) {
2259
- return !firewall._inFlight && !(firewall._statusFlags & STATUS_PENDING);
2275
+ return (
2276
+ !!(firewall._flags & REACTIVE_MANUAL_WRITE) ||
2277
+ (!firewall._inFlight && !(firewall._statusFlags & STATUS_PENDING))
2278
+ );
2260
2279
  }
2261
2280
  if (el._overrideValue !== undefined && el._overrideValue !== NOT_PENDING) {
2262
2281
  if (comp._statusFlags & STATUS_PENDING && !(comp._statusFlags & STATUS_UNINITIALIZED))
@@ -2363,11 +2382,9 @@ function isPending(fn) {
2363
2382
  }
2364
2383
  }
2365
2384
  function refresh(target) {
2366
- let prevRefreshing = refreshing;
2367
- refreshing = true;
2368
- try {
2369
- const node = target?.[$REFRESH];
2370
- if (true && !node) {
2385
+ const node = target?.[$REFRESH];
2386
+ if (!node) {
2387
+ {
2371
2388
  const message =
2372
2389
  "[INVALID_REFRESH_TARGET] refresh() expects a Solid source accessor or refreshable store. " +
2373
2390
  "Pass the original source target, not a wrapper function or derived property read.";
@@ -2379,18 +2396,32 @@ function refresh(target) {
2379
2396
  });
2380
2397
  throw new Error(message);
2381
2398
  }
2382
- if (node && typeof node._fn === "function" && !(node._flags & REACTIVE_DISPOSED)) {
2383
- recompute(node);
2384
- }
2385
- } finally {
2386
- refreshing = prevRefreshing;
2387
- if (!prevRefreshing) {
2388
- schedule();
2389
- }
2390
2399
  }
2391
- }
2392
- function isRefreshing() {
2393
- return refreshing;
2400
+ if (
2401
+ context &&
2402
+ !((node._config ?? 0) & CONFIG_OWNED_WRITE) &&
2403
+ !(context._config & CONFIG_CHILDREN_FORBIDDEN)
2404
+ ) {
2405
+ emitDiagnostic({
2406
+ code: "REACTIVE_WRITE_IN_OWNED_SCOPE",
2407
+ kind: "write",
2408
+ severity: "error",
2409
+ message: REACTIVE_WRITE_IN_OWNED_SCOPE_REFRESH_MESSAGE,
2410
+ ownerId: context.id,
2411
+ ownerName: context._name,
2412
+ nodeName: node._name,
2413
+ data: { operation: "refresh" }
2414
+ });
2415
+ throw new Error(REACTIVE_WRITE_IN_OWNED_SCOPE_REFRESH_MESSAGE);
2416
+ }
2417
+ if (
2418
+ typeof node._fn === "function" &&
2419
+ !(node._flags & (REACTIVE_DISPOSED | REACTIVE_MANUAL_WRITE))
2420
+ ) {
2421
+ node._flags = (node._flags & ~REACTIVE_CHECK) | REACTIVE_DIRTY;
2422
+ insertIntoHeap(node, node._flags & REACTIVE_ZOMBIE ? zombieQueue : dirtyQueue);
2423
+ schedule();
2424
+ }
2394
2425
  }
2395
2426
  function createContext(defaultValue, description) {
2396
2427
  return { id: Symbol(description), defaultValue: defaultValue };
@@ -2789,6 +2820,7 @@ function applyState(next, state, keyFn) {
2789
2820
  function applyStateFast(next, target, keyFn) {
2790
2821
  const previous = target[STORE_VALUE];
2791
2822
  if (next === previous) return;
2823
+ const arrayNodes = target[STORE_NODE];
2792
2824
  (target[STORE_LOOKUP] || storeLookup).set(next, target[$PROXY]);
2793
2825
  target[STORE_VALUE] = next;
2794
2826
  if (Array.isArray(previous)) {
@@ -2820,18 +2852,18 @@ function applyStateFast(next, target, keyFn) {
2820
2852
  if (start > newEnd || start > end) {
2821
2853
  for (j = start; j <= newEnd; j++) {
2822
2854
  changed = true;
2823
- target[STORE_NODE][j] && setSignal(target[STORE_NODE][j], wrap(next[j], target));
2855
+ arrayNodes?.[j] && setSignal(arrayNodes[j], wrap(next[j], target));
2824
2856
  }
2825
2857
  for (; j < next.length; j++) {
2826
2858
  changed = true;
2827
2859
  const wrapped = wrap(temp[j], target);
2828
- target[STORE_NODE][j] && setSignal(target[STORE_NODE][j], wrapped);
2860
+ arrayNodes?.[j] && setSignal(arrayNodes[j], wrapped);
2829
2861
  applyState(next[j], wrapped, keyFn);
2830
2862
  }
2831
- changed && target[STORE_NODE][$TRACK] && setSignal(target[STORE_NODE][$TRACK], void 0);
2863
+ changed && notifySelf(target);
2832
2864
  prevLength !== next.length &&
2833
- target[STORE_NODE].length &&
2834
- setSignal(target[STORE_NODE].length, next.length);
2865
+ arrayNodes?.length &&
2866
+ setSignal(arrayNodes.length, next.length);
2835
2867
  return;
2836
2868
  }
2837
2869
  newIndicesNext = new Array(newEnd + 1);
@@ -2855,24 +2887,26 @@ function applyStateFast(next, target, keyFn) {
2855
2887
  for (j = start; j < next.length; j++) {
2856
2888
  if (j in temp) {
2857
2889
  const wrapped = wrap(temp[j], target);
2858
- target[STORE_NODE][j] && setSignal(target[STORE_NODE][j], wrapped);
2890
+ arrayNodes?.[j] && setSignal(arrayNodes[j], wrapped);
2859
2891
  applyState(next[j], wrapped, keyFn);
2860
- } else target[STORE_NODE][j] && setSignal(target[STORE_NODE][j], wrap(next[j], target));
2892
+ } else arrayNodes?.[j] && setSignal(arrayNodes[j], wrap(next[j], target));
2861
2893
  }
2862
2894
  if (start < next.length) changed = true;
2863
2895
  } else if (next.length) {
2864
2896
  for (let i = 0, len = next.length; i < len; i++) {
2865
2897
  const item = previous[i];
2866
- isWrappable(item)
2867
- ? applyState(next[i], wrap(item, target), keyFn)
2868
- : target[STORE_NODE][i] && setSignal(target[STORE_NODE][i], next[i]);
2898
+ if (isWrappable(item)) applyState(next[i], wrap(item, target), keyFn);
2899
+ else {
2900
+ if (item !== next[i]) changed = true;
2901
+ arrayNodes?.[i] && setSignal(arrayNodes[i], next[i]);
2902
+ }
2869
2903
  }
2870
2904
  }
2871
2905
  if (prevLength !== next.length) {
2872
2906
  changed = true;
2873
- target[STORE_NODE].length && setSignal(target[STORE_NODE].length, next.length);
2907
+ arrayNodes?.length && setSignal(arrayNodes.length, next.length);
2874
2908
  }
2875
- changed && target[STORE_NODE][$TRACK] && setSignal(target[STORE_NODE][$TRACK], void 0);
2909
+ changed && notifySelf(target);
2876
2910
  return;
2877
2911
  }
2878
2912
  let nodes = target[STORE_NODE];
@@ -2941,18 +2975,17 @@ function applyStateSlow(next, target, keyFn) {
2941
2975
  if (start > newEnd || start > end) {
2942
2976
  for (j = start; j <= newEnd; j++) {
2943
2977
  changed = true;
2944
- target[STORE_NODE][j] && setSignal(target[STORE_NODE][j], wrap(next[j], target));
2978
+ nodes?.[j] && setSignal(nodes[j], wrap(next[j], target));
2945
2979
  }
2946
2980
  for (; j < next.length; j++) {
2947
2981
  changed = true;
2948
2982
  const wrapped = wrap(temp[j], target);
2949
- target[STORE_NODE][j] && setSignal(target[STORE_NODE][j], wrapped);
2983
+ nodes?.[j] && setSignal(nodes[j], wrapped);
2950
2984
  applyState(next[j], wrapped, keyFn);
2951
2985
  }
2952
- changed && target[STORE_NODE][$TRACK] && setSignal(target[STORE_NODE][$TRACK], void 0);
2953
- prevLength !== next.length &&
2954
- target[STORE_NODE].length &&
2955
- setSignal(target[STORE_NODE].length, next.length);
2986
+ const nextLength = next.length;
2987
+ changed && notifySelf(target);
2988
+ prevLength !== nextLength && nodes?.length && setSignal(nodes.length, nextLength);
2956
2989
  return;
2957
2990
  }
2958
2991
  newIndicesNext = new Array(newEnd + 1);
@@ -2976,24 +3009,27 @@ function applyStateSlow(next, target, keyFn) {
2976
3009
  for (j = start; j < next.length; j++) {
2977
3010
  if (j in temp) {
2978
3011
  const wrapped = wrap(temp[j], target);
2979
- target[STORE_NODE][j] && setSignal(target[STORE_NODE][j], wrapped);
3012
+ nodes?.[j] && setSignal(nodes[j], wrapped);
2980
3013
  applyState(next[j], wrapped, keyFn);
2981
- } else target[STORE_NODE][j] && setSignal(target[STORE_NODE][j], wrap(next[j], target));
3014
+ } else nodes?.[j] && setSignal(nodes[j], wrap(next[j], target));
2982
3015
  }
2983
3016
  if (start < next.length) changed = true;
2984
3017
  } else if (next.length) {
2985
3018
  for (let i = 0, len = next.length; i < len; i++) {
2986
3019
  const item = getOverrideValue(previous, override, i, optOverride);
2987
- isWrappable(item)
2988
- ? applyState(next[i], wrap(item, target), keyFn)
2989
- : target[STORE_NODE][i] && setSignal(target[STORE_NODE][i], next[i]);
3020
+ if (isWrappable(item)) applyState(next[i], wrap(item, target), keyFn);
3021
+ else {
3022
+ if (item !== next[i]) changed = true;
3023
+ nodes?.[i] && setSignal(nodes[i], next[i]);
3024
+ }
2990
3025
  }
2991
3026
  }
2992
- if (prevLength !== next.length) {
3027
+ const nextLength = next.length;
3028
+ if (prevLength !== nextLength) {
2993
3029
  changed = true;
2994
- target[STORE_NODE].length && setSignal(target[STORE_NODE].length, next.length);
3030
+ nodes?.length && setSignal(nodes.length, nextLength);
2995
3031
  }
2996
- changed && target[STORE_NODE][$TRACK] && setSignal(target[STORE_NODE][$TRACK], void 0);
3032
+ changed && notifySelf(target);
2997
3033
  return;
2998
3034
  }
2999
3035
  if (nodes) {
@@ -3029,7 +3065,7 @@ function reconcile(value, key) {
3029
3065
  if (state == null) throw new Error("Cannot reconcile null or undefined state");
3030
3066
  const keyFn = typeof key === "string" ? item => item[key] : key;
3031
3067
  const eq = keyFn(state);
3032
- if (eq !== undefined && keyFn(value) !== keyFn(state))
3068
+ if (eq !== undefined && keyFn(value) !== eq)
3033
3069
  throw new Error("Cannot reconcile states with different identity");
3034
3070
  applyState(value, state, keyFn);
3035
3071
  };
@@ -3068,13 +3104,13 @@ function createProjectionInternal(fn, seed, options) {
3068
3104
  function createProjection(fn, seed, options) {
3069
3105
  return createProjectionInternal(fn, seed, options).store;
3070
3106
  }
3071
- function runProjectionComputed(wrappedStore, fn, key, wrapCommit) {
3107
+ function runProjectionComputed(wrappedStore, fn, key, wrapCommit, onDraftWrite) {
3072
3108
  const owner = getOwner();
3073
3109
  let settled = false;
3074
3110
  let result;
3075
3111
  const draft = new Proxy(
3076
3112
  wrappedStore,
3077
- createWriteTraps(() => !settled || owner._inFlight === result)
3113
+ createWriteTraps(() => !settled || owner._inFlight === result, onDraftWrite)
3078
3114
  );
3079
3115
  storeSetter(draft, s => {
3080
3116
  result = fn(s);
@@ -3088,7 +3124,7 @@ function runProjectionComputed(wrappedStore, fn, key, wrapCommit) {
3088
3124
  });
3089
3125
  return owner;
3090
3126
  }
3091
- function createWriteTraps(isActive) {
3127
+ function createWriteTraps(isActive, onDraftWrite) {
3092
3128
  const traps = {
3093
3129
  get(_, prop) {
3094
3130
  let value;
@@ -3100,6 +3136,7 @@ function createWriteTraps(isActive) {
3100
3136
  setWriteOverride(false);
3101
3137
  setProjectionWriteActive(false);
3102
3138
  }
3139
+ if (prop === $TARGET) return value;
3103
3140
  return typeof value === "object" && value !== null ? new Proxy(value, traps) : value;
3104
3141
  },
3105
3142
  has(_, prop) {
@@ -3120,6 +3157,7 @@ function createWriteTraps(isActive) {
3120
3157
  setProjectionWriteActive(true);
3121
3158
  try {
3122
3159
  _[prop] = value;
3160
+ onDraftWrite?.();
3123
3161
  } finally {
3124
3162
  setWriteOverride(false);
3125
3163
  setProjectionWriteActive(false);
@@ -3132,6 +3170,7 @@ function createWriteTraps(isActive) {
3132
3170
  setProjectionWriteActive(true);
3133
3171
  try {
3134
3172
  delete _[prop];
3173
+ onDraftWrite?.();
3135
3174
  } finally {
3136
3175
  setWriteOverride(false);
3137
3176
  setProjectionWriteActive(false);
@@ -3155,6 +3194,7 @@ const STORE_VALUE = "v",
3155
3194
  STORE_LOOKUP = "l",
3156
3195
  STORE_FIREWALL = "f",
3157
3196
  STORE_OPTIMISTIC = "p";
3197
+ const STORE_SELF_PENDING = Symbol("STORE_SELF_PENDING");
3158
3198
  function createStoreProxy(value, traps = storeTraps, extend) {
3159
3199
  let newTarget;
3160
3200
  if (Array.isArray(value)) {
@@ -3189,8 +3229,25 @@ function setWriteOverride(value) {
3189
3229
  function writeOnly(proxy) {
3190
3230
  return writeOverride || !!Writing?.has(proxy);
3191
3231
  }
3192
- function unwrapStoreValue(value) {
3193
- return value?.[$TARGET]?.[STORE_VALUE] ?? value;
3232
+ function unwrapStoreValue(value, map, lookup) {
3233
+ const target = value?.[$TARGET] || lookup?.get(value)?.[$TARGET];
3234
+ if (!target) return value;
3235
+ const override = target[STORE_OVERRIDE];
3236
+ if (!override) return target[STORE_VALUE];
3237
+ if (!map) map = new Map();
3238
+ if (map.has(value)) return map.get(value);
3239
+ const source = target[STORE_VALUE];
3240
+ const isArray = Array.isArray(source);
3241
+ const result = isArray ? [] : Object.create(Object.getPrototypeOf(source));
3242
+ map.set(value, result);
3243
+ lookup = target[STORE_LOOKUP] ?? storeLookup;
3244
+ for (const key of getKeys(source, override)) {
3245
+ if (isArray && key === "length") continue;
3246
+ const next = key in override ? override[key] : source[key];
3247
+ if (next !== $DELETED) result[key] = unwrapStoreValue(next, map, lookup);
3248
+ }
3249
+ if (isArray) result.length = override.length ?? source.length;
3250
+ return result;
3194
3251
  }
3195
3252
  function isPrototypePollutionKey$1(property) {
3196
3253
  return property === "__proto__" || property === "constructor" || property === "prototype";
@@ -3261,6 +3318,14 @@ function trackSelf(target, symbol = $TRACK) {
3261
3318
  )
3262
3319
  );
3263
3320
  }
3321
+ function notifySelf(target) {
3322
+ const node = target[STORE_NODE]?.[$TRACK];
3323
+ node &&
3324
+ setSignal(
3325
+ node,
3326
+ target[STORE_OPTIMISTIC] && !projectionWriteActive ? STORE_SELF_PENDING : undefined
3327
+ );
3328
+ }
3264
3329
  function getKeys(source, override, enumerable = true) {
3265
3330
  const baseKeys = untrack(() => (enumerable ? Object.keys(source) : Reflect.ownKeys(source)));
3266
3331
  if (!override) return baseKeys;
@@ -3353,7 +3418,7 @@ function notifyStoreProperty(target, property, mode, value, prev, prevHas) {
3353
3418
  setSignal(node, undefined);
3354
3419
  }
3355
3420
  }
3356
- nodes[$TRACK] && setSignal(nodes[$TRACK], undefined);
3421
+ notifySelf(target);
3357
3422
  }
3358
3423
  let Writing = null;
3359
3424
  const storeTraps = {
@@ -3365,8 +3430,9 @@ const storeTraps = {
3365
3430
  trackSelf(target);
3366
3431
  return receiver;
3367
3432
  }
3433
+ const selfRead = getObserver() === target[STORE_FIREWALL];
3368
3434
  const nodes = getNodes(target, STORE_NODE);
3369
- const tracked = nodes[property];
3435
+ const tracked = selfRead ? undefined : nodes[property];
3370
3436
  const source = target[STORE_VALUE];
3371
3437
  if (
3372
3438
  !tracked &&
@@ -3378,6 +3444,7 @@ const storeTraps = {
3378
3444
  !source[$TARGET] &&
3379
3445
  !(property in source) &&
3380
3446
  getObserver() &&
3447
+ !selfRead &&
3381
3448
  !writeOnly(receiver)
3382
3449
  ) {
3383
3450
  return read(getNode(nodes, property, undefined, target[STORE_FIREWALL]));
@@ -3433,7 +3500,7 @@ const storeTraps = {
3433
3500
  proto !== Object.prototype
3434
3501
  ? value.bind(storeValue)
3435
3502
  : value;
3436
- } else if (getObserver()) {
3503
+ } else if (getObserver() && !selfRead) {
3437
3504
  return read(
3438
3505
  getNode(
3439
3506
  nodes,
@@ -3471,7 +3538,7 @@ const storeTraps = {
3471
3538
  : target[STORE_OVERRIDE] && property in target[STORE_OVERRIDE]
3472
3539
  ? target[STORE_OVERRIDE][property] !== $DELETED
3473
3540
  : property in target[STORE_VALUE];
3474
- if (writeOnly(target[$PROXY])) return has;
3541
+ if (writeOnly(target[$PROXY]) || getObserver() === target[STORE_FIREWALL]) return has;
3475
3542
  const nodes = getNodes(target, STORE_HAS);
3476
3543
  if (nodes[property]) return read(nodes[property]);
3477
3544
  if (getObserver()) {
@@ -3599,7 +3666,7 @@ const storeTraps = {
3599
3666
  return true;
3600
3667
  },
3601
3668
  ownKeys(target) {
3602
- trackSelf(target);
3669
+ if (getObserver() !== target[STORE_FIREWALL]) trackSelf(target);
3603
3670
  let keys = getKeys(target[STORE_VALUE], target[STORE_OVERRIDE], false);
3604
3671
  if (target[STORE_OPTIMISTIC_OVERRIDE]) {
3605
3672
  const keySet = new Set(keys);
@@ -3664,7 +3731,10 @@ function createStore(first, second, options) {
3664
3731
  return [
3665
3732
  wrappedStore,
3666
3733
  derived
3667
- ? fn => (storeSetter(wrappedStore, fn), suppressComputedRecompute(wrappedStore[$REFRESH]))
3734
+ ? fn => {
3735
+ suppressComputedRecompute(wrappedStore[$REFRESH]);
3736
+ storeSetter(wrappedStore, fn);
3737
+ }
3668
3738
  : fn => storeSetter(wrappedStore, fn)
3669
3739
  ];
3670
3740
  }
@@ -3679,31 +3749,50 @@ function createOptimisticStore(first, second, options) {
3679
3749
  function clearOptimisticStore(store) {
3680
3750
  const target = store[$TARGET];
3681
3751
  if (!target || !target[STORE_OPTIMISTIC_OVERRIDE]) return;
3752
+ clearOptimisticOverride(target);
3753
+ }
3754
+ function clearOptimisticOverride(target) {
3682
3755
  const override = target[STORE_OPTIMISTIC_OVERRIDE];
3756
+ if (!override) return;
3683
3757
  const nodes = target[STORE_NODE];
3758
+ delete target[STORE_OPTIMISTIC_OVERRIDE];
3759
+ const wasProjectionWriteActive = projectionWriteActive;
3684
3760
  setProjectionWriteActive(true);
3685
3761
  try {
3686
3762
  if (nodes) {
3687
3763
  for (const key of Reflect.ownKeys(override)) {
3688
3764
  if (nodes[key]) {
3689
- nodes[key]._optimisticLane = undefined;
3765
+ const node = nodes[key];
3766
+ node._optimisticLane = undefined;
3690
3767
  const baseValue =
3691
3768
  target[STORE_OVERRIDE] && key in target[STORE_OVERRIDE]
3692
3769
  ? target[STORE_OVERRIDE][key]
3693
3770
  : target[STORE_VALUE][key];
3694
3771
  const value = baseValue === $DELETED ? undefined : baseValue;
3695
- setSignal(nodes[key], isWrappable(value) ? wrap(value, target) : value);
3772
+ 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;
3779
+ node._overrideValue = NOT_PENDING;
3780
+ node._pendingValue = NOT_PENDING;
3781
+ node._value = next;
3782
+ if (!node._equals || !node._equals(prev, next)) {
3783
+ insertSubs(node, true);
3784
+ schedule();
3785
+ }
3696
3786
  }
3697
3787
  }
3698
3788
  if (nodes[$TRACK]) {
3699
3789
  nodes[$TRACK]._optimisticLane = undefined;
3700
- setSignal(nodes[$TRACK], undefined);
3790
+ notifySelf(target);
3701
3791
  }
3702
3792
  }
3703
3793
  } finally {
3704
- setProjectionWriteActive(false);
3794
+ setProjectionWriteActive(wasProjectionWriteActive);
3705
3795
  }
3706
- delete target[STORE_OPTIMISTIC_OVERRIDE];
3707
3796
  }
3708
3797
  function createOptimisticProjectionInternal(fn, initialValue, options) {
3709
3798
  let node;
@@ -3728,19 +3817,31 @@ function createOptimisticProjectionInternal(fn, initialValue, options) {
3728
3817
  };
3729
3818
  const wrappedStore = wrapProjection(initialValue);
3730
3819
  if (fn) {
3820
+ const clearProjectionOverride = () => {
3821
+ const target = wrappedStore[$TARGET];
3822
+ if (target?.[STORE_OPTIMISTIC_OVERRIDE]) clearOptimisticOverride(target);
3823
+ };
3731
3824
  const wrapCommit = write => {
3825
+ const wasProjectionWriteActive = projectionWriteActive;
3732
3826
  setProjectionWriteActive(true);
3733
3827
  try {
3734
3828
  write();
3829
+ clearProjectionOverride();
3735
3830
  } finally {
3736
- setProjectionWriteActive(false);
3831
+ setProjectionWriteActive(wasProjectionWriteActive);
3737
3832
  }
3738
3833
  };
3739
3834
  node = computed(
3740
3835
  () => {
3741
3836
  setProjectionWriteActive(true);
3742
3837
  try {
3743
- runProjectionComputed(wrappedStore, fn, options?.key || "id", wrapCommit);
3838
+ runProjectionComputed(
3839
+ wrappedStore,
3840
+ fn,
3841
+ options?.key || "id",
3842
+ wrapCommit,
3843
+ clearProjectionOverride
3844
+ );
3744
3845
  } finally {
3745
3846
  setProjectionWriteActive(false);
3746
3847
  }
@@ -3842,13 +3943,13 @@ function snapshotImpl(item, track, map, lookup) {
3842
3943
  : target[STORE_VALUE]
3843
3944
  );
3844
3945
  item = target[STORE_VALUE];
3845
- lookup = storeLookup;
3946
+ lookup = target[STORE_LOOKUP] ?? storeLookup;
3846
3947
  } else {
3847
3948
  isArray = Array.isArray(item);
3848
3949
  map.set(item, item);
3849
3950
  }
3850
3951
  if (isArray) {
3851
- const len = override?.length || item.length;
3952
+ const len = override?.length ?? item.length;
3852
3953
  for (let i = 0; i < len; i++) {
3853
3954
  v = override && i in override ? override[i] : item[i];
3854
3955
  if (v === $DELETED) continue;
@@ -4220,6 +4321,7 @@ function updateRepeat() {
4220
4321
  this._nodes = [];
4221
4322
  this._mappings = [];
4222
4323
  this._len = 0;
4324
+ this._offset = 0;
4223
4325
  }
4224
4326
  if (this._fallback && !this._mappings[0]) {
4225
4327
  this._mappings[0] = runWithOwner((this._nodes[0] = createOwner()), this._fallback);
@@ -4231,10 +4333,10 @@ function updateRepeat() {
4231
4333
  if (this._len === 0 && this._nodes[0]) this._nodes[0].dispose();
4232
4334
  for (let i = to; i < prevTo; i++) this._nodes[i - this._offset].dispose();
4233
4335
  if (this._offset < from) {
4234
- let i = this._offset;
4235
- while (i < from && i < this._len) this._nodes[i++].dispose();
4236
- this._nodes.splice(0, from - this._offset);
4237
- this._mappings.splice(0, from - this._offset);
4336
+ const removed = from - this._offset;
4337
+ for (let i = 0; i < removed && i < this._len; i++) this._nodes[i].dispose();
4338
+ this._nodes.splice(0, removed);
4339
+ this._mappings.splice(0, removed);
4238
4340
  } else if (this._offset > from) {
4239
4341
  let i = prevTo - this._offset - 1;
4240
4342
  let difference = this._offset - from;
@@ -4694,7 +4796,6 @@ export {
4694
4796
  isDisposed,
4695
4797
  isEqual,
4696
4798
  isPending,
4697
- isRefreshing,
4698
4799
  isWrappable,
4699
4800
  latest,
4700
4801
  mapArray,