@solidjs/signals 0.3.2 → 0.4.0

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
@@ -13,15 +13,6 @@ var ContextNotFoundError = class extends Error {
13
13
  );
14
14
  }
15
15
  };
16
- var EffectError = class extends Error {
17
- constructor(effect, cause) {
18
- super(`Uncaught error while running effect:
19
-
20
- ${effect.toString()}
21
- ` );
22
- this.cause = cause;
23
- }
24
- };
25
16
 
26
17
  // src/core/constants.ts
27
18
  var STATE_CLEAN = 0;
@@ -47,7 +38,7 @@ function schedule() {
47
38
  return;
48
39
  scheduled = true;
49
40
  if (!globalQueue._running)
50
- queueMicrotask(flushSync);
41
+ queueMicrotask(flush);
51
42
  }
52
43
  var pureQueue = [];
53
44
  var Queue = class {
@@ -56,21 +47,21 @@ var Queue = class {
56
47
  _queues = [[], []];
57
48
  _children = [];
58
49
  created = clock;
59
- enqueue(type, node) {
60
- pureQueue.push(node);
50
+ enqueue(type, fn) {
51
+ pureQueue.push(fn);
61
52
  if (type)
62
- this._queues[type - 1].push(node);
53
+ this._queues[type - 1].push(fn);
63
54
  schedule();
64
55
  }
65
56
  run(type) {
66
57
  if (type === EFFECT_PURE) {
67
- pureQueue.length && runPureQueue(pureQueue);
58
+ pureQueue.length && runQueue(pureQueue, type);
68
59
  pureQueue = [];
69
60
  return;
70
61
  } else if (this._queues[type - 1].length) {
71
62
  const effects = this._queues[type - 1];
72
63
  this._queues[type - 1] = [];
73
- runEffectQueue(effects);
64
+ runQueue(effects, type);
74
65
  }
75
66
  for (let i = 0; i < this._children.length; i++) {
76
67
  this._children[i].run(type);
@@ -106,7 +97,7 @@ var Queue = class {
106
97
  }
107
98
  };
108
99
  var globalQueue = new Queue();
109
- function flushSync() {
100
+ function flush() {
110
101
  let count = 0;
111
102
  while (scheduled) {
112
103
  if (++count === 1e5)
@@ -114,52 +105,9 @@ function flushSync() {
114
105
  globalQueue.flush();
115
106
  }
116
107
  }
117
- function runTop(node) {
118
- const ancestors = [];
119
- for (let current = node; current !== null; current = current._parent) {
120
- if (current._state !== STATE_CLEAN) {
121
- ancestors.push(current);
122
- }
123
- }
124
- for (let i = ancestors.length - 1; i >= 0; i--) {
125
- if (ancestors[i]._state !== STATE_DISPOSED)
126
- ancestors[i]._updateIfNecessary();
127
- }
128
- }
129
- function runPureQueue(queue) {
130
- for (let i = 0; i < queue.length; i++) {
131
- if (queue[i]._state !== STATE_CLEAN)
132
- runTop(queue[i]);
133
- }
134
- }
135
- function runEffectQueue(queue) {
108
+ function runQueue(queue, type) {
136
109
  for (let i = 0; i < queue.length; i++)
137
- queue[i]._runEffect();
138
- }
139
-
140
- // src/core/utils.ts
141
- function isUndefined(value) {
142
- return typeof value === "undefined";
143
- }
144
- function tryCatch(fn) {
145
- try {
146
- const v = fn();
147
- if (v instanceof Promise) {
148
- return v.then(
149
- (v2) => [void 0, v2],
150
- (e) => {
151
- if (e instanceof NotReadyError)
152
- throw e;
153
- return [e];
154
- }
155
- );
156
- }
157
- return [void 0, v];
158
- } catch (e) {
159
- if (e instanceof NotReadyError)
160
- throw e;
161
- return [e];
162
- }
110
+ queue[i](type);
163
111
  }
164
112
 
165
113
  // src/core/owner.ts
@@ -173,10 +121,6 @@ function setOwner(owner) {
173
121
  currentOwner = owner;
174
122
  return out;
175
123
  }
176
- function formatId(prefix, id) {
177
- const num = id.toString(36), len = num.length - 1;
178
- return prefix + (len ? String.fromCharCode(64 + len) : "") + num;
179
- }
180
124
  var Owner = class {
181
125
  // We flatten the owner tree into a linked list so that we don't need a pointer to .firstChild
182
126
  // However, the children are actually added in reverse creation order
@@ -193,8 +137,6 @@ var Owner = class {
193
137
  constructor(id = null, skipAppend = false) {
194
138
  this.id = id;
195
139
  if (currentOwner) {
196
- if (id == null && currentOwner.id != null)
197
- this.id = currentOwner.getNextChildId();
198
140
  !skipAppend && currentOwner.append(this);
199
141
  }
200
142
  }
@@ -205,6 +147,8 @@ var Owner = class {
205
147
  this._nextSibling._prevSibling = child;
206
148
  child._nextSibling = this._nextSibling;
207
149
  this._nextSibling = child;
150
+ if (this.id != null && child.id == null)
151
+ child.id = this.getNextChildId();
208
152
  if (child._context !== this._context) {
209
153
  child._context = { ...this._context, ...child._context };
210
154
  }
@@ -296,6 +240,13 @@ function onCleanup(fn) {
296
240
  }
297
241
  return fn;
298
242
  }
243
+ function formatId(prefix, id) {
244
+ const num = id.toString(36), len = num.length - 1;
245
+ return prefix + (len ? String.fromCharCode(64 + len) : "") + num;
246
+ }
247
+ function isUndefined(value) {
248
+ return typeof value === "undefined";
249
+ }
299
250
 
300
251
  // src/core/flags.ts
301
252
  var ERROR_OFFSET = 0;
@@ -312,6 +263,7 @@ var currentMask = DEFAULT_FLAGS;
312
263
  var newSources = null;
313
264
  var newSourcesIndex = 0;
314
265
  var newFlags = 0;
266
+ var unobserved = [];
315
267
  var notStale = false;
316
268
  var updateCheck = null;
317
269
  var staleCheck = null;
@@ -331,6 +283,7 @@ var Computation = class extends Owner {
331
283
  // which could enable more efficient DIRTY notification
332
284
  _equals = isEqual;
333
285
  _unobserved;
286
+ _pureWrite = false;
334
287
  /** Whether the computation is an error or has ancestors that are unresolved */
335
288
  _stateFlags = 0;
336
289
  /** Which flags raised by sources are handled, vs. being passed through. */
@@ -338,7 +291,7 @@ var Computation = class extends Owner {
338
291
  _time = -1;
339
292
  _forceNotify = false;
340
293
  constructor(initialValue, compute2, options) {
341
- super(null, compute2 === null);
294
+ super(options?.id, compute2 === null);
342
295
  this._compute = compute2;
343
296
  this._state = compute2 ? STATE_DIRTY : STATE_CLEAN;
344
297
  this._stateFlags = compute2 && initialValue === void 0 ? UNINITIALIZED_BIT : 0;
@@ -346,6 +299,8 @@ var Computation = class extends Owner {
346
299
  this._name = options?.name ?? (this._compute ? "computed" : "signal");
347
300
  if (options?.equals !== void 0)
348
301
  this._equals = options.equals;
302
+ if (options?.pureWrite)
303
+ this._pureWrite = true;
349
304
  if (options?.unobserved)
350
305
  this._unobserved = options?.unobserved;
351
306
  }
@@ -395,8 +350,11 @@ var Computation = class extends Owner {
395
350
  }
396
351
  /** Update the computation with a new value. */
397
352
  write(value, flags = 0, raw = false) {
353
+ if (!this._compute && !this._pureWrite && getOwner() && !getOwner().firewall)
354
+ console.warn("A Signal was written to in an owned scope.");
398
355
  const newValue = !raw && typeof value === "function" ? value(this._value) : value;
399
- const valueChanged = newValue !== UNCHANGED && (!!(this._stateFlags & UNINITIALIZED_BIT) || this._stateFlags & LOADING_BIT & ~flags || this._equals === false || !this._equals(this._value, newValue));
356
+ const valueChanged = newValue !== UNCHANGED && (!!(this._stateFlags & UNINITIALIZED_BIT) || // this._stateFlags & LOADING_BIT & ~flags ||
357
+ this._equals === false || !this._equals(this._value, newValue));
400
358
  if (valueChanged) {
401
359
  this._value = newValue;
402
360
  this._error = void 0;
@@ -560,6 +518,7 @@ function update(node) {
560
518
  removeSourceObservers(node, newSourcesIndex);
561
519
  node._sources.length = newSourcesIndex;
562
520
  }
521
+ unobserved.length && notifyUnobserved();
563
522
  newSources = prevSources;
564
523
  newSourcesIndex = prevSourcesIndex;
565
524
  newFlags = prevFlags;
@@ -577,10 +536,18 @@ function removeSourceObservers(node, index) {
577
536
  source._observers[swap] = source._observers[source._observers.length - 1];
578
537
  source._observers.pop();
579
538
  if (!source._observers.length)
580
- source._unobserved?.();
539
+ unobserved.push(source);
581
540
  }
582
541
  }
583
542
  }
543
+ function notifyUnobserved() {
544
+ for (let i = 0; i < unobserved.length; i++) {
545
+ const source = unobserved[i];
546
+ if (!source._observers || !source._observers.length)
547
+ unobserved[i]._unobserved?.();
548
+ }
549
+ unobserved = [];
550
+ }
584
551
  function isEqual(a, b) {
585
552
  return a === b;
586
553
  }
@@ -692,68 +659,6 @@ function compute(owner, fn, observer) {
692
659
  notStale = prevNotStale;
693
660
  }
694
661
  }
695
- function flatten(children, options) {
696
- try {
697
- if (typeof children === "function" && !children.length) {
698
- if (options?.doNotUnwrap)
699
- return children;
700
- do {
701
- children = children();
702
- } while (typeof children === "function" && !children.length);
703
- }
704
- if (options?.skipNonRendered && (children == null || children === true || children === false || children === ""))
705
- return;
706
- if (Array.isArray(children)) {
707
- let results = [];
708
- if (flattenArray(children, results, options)) {
709
- return () => {
710
- let nested = [];
711
- flattenArray(results, nested, { ...options, doNotUnwrap: false });
712
- return nested;
713
- };
714
- }
715
- return results;
716
- }
717
- return children;
718
- } catch (e) {
719
- if (options?.skipNonRendered && e instanceof NotReadyError) {
720
- newFlags |= LOADING_BIT;
721
- return void 0;
722
- }
723
- throw e;
724
- }
725
- }
726
- function flattenArray(children, results = [], options) {
727
- let notReady = null;
728
- let needsUnwrap = false;
729
- for (let i = 0; i < children.length; i++) {
730
- try {
731
- let child = children[i];
732
- if (typeof child === "function" && !child.length) {
733
- if (options?.doNotUnwrap) {
734
- results.push(child);
735
- needsUnwrap = true;
736
- continue;
737
- }
738
- do {
739
- child = child();
740
- } while (typeof child === "function" && !child.length);
741
- }
742
- if (Array.isArray(child)) {
743
- needsUnwrap = flattenArray(child, results, options);
744
- } else if (options?.skipNonRendered && (child == null || child === true || child === false || child === "")) {
745
- } else
746
- results.push(child);
747
- } catch (e) {
748
- if (!(e instanceof NotReadyError))
749
- throw e;
750
- notReady = e;
751
- }
752
- }
753
- if (notReady)
754
- throw notReady;
755
- return needsUnwrap;
756
- }
757
662
 
758
663
  // src/core/effect.ts
759
664
  var Effect = class extends Computation {
@@ -773,7 +678,7 @@ var Effect = class extends Computation {
773
678
  this._compute = (p) => getClock() > this._queue.created && !(this._stateFlags & ERROR_BIT) ? latest(() => compute2(p)) : compute2(p);
774
679
  }
775
680
  this._updateIfNecessary();
776
- !options?.defer && (this._type === EFFECT_USER ? this._queue.enqueue(this._type, this) : this._runEffect());
681
+ !options?.defer && (this._type === EFFECT_USER ? this._queue.enqueue(this._type, this._runEffect.bind(this)) : this._runEffect(this._type));
777
682
  if (!this._parent)
778
683
  console.warn("Effects created outside a reactive context will never be disposed");
779
684
  }
@@ -795,17 +700,19 @@ var Effect = class extends Computation {
795
700
  if (this._state >= state || skipQueue)
796
701
  return;
797
702
  if (this._state === STATE_CLEAN)
798
- this._queue.enqueue(this._type, this);
703
+ this._queue.enqueue(this._type, this._runEffect.bind(this));
799
704
  this._state = state;
800
705
  }
801
706
  _setError(error) {
802
707
  this._error = error;
803
- this._cleanup?.();
804
708
  this._queue.notify(this, LOADING_BIT, 0);
805
709
  this._stateFlags = ERROR_BIT;
806
710
  if (this._type === EFFECT_USER) {
807
711
  try {
808
- return this._onerror ? this._cleanup = this._onerror(error) : console.error(new EffectError(this._effect, error));
712
+ return this._onerror ? this._onerror(error, () => {
713
+ this._cleanup?.();
714
+ this._cleanup = void 0;
715
+ }) : console.error(error);
809
716
  } catch (e) {
810
717
  error = e;
811
718
  }
@@ -823,21 +730,27 @@ var Effect = class extends Computation {
823
730
  this._cleanup = void 0;
824
731
  super._disposeNode();
825
732
  }
826
- _runEffect() {
827
- if (this._modified && this._state !== STATE_DISPOSED) {
828
- this._cleanup?.();
829
- try {
830
- this._cleanup = this._effect(this._value, this._prevValue);
831
- } catch (e) {
832
- if (!this._queue.notify(this, ERROR_BIT, ERROR_BIT))
833
- throw e;
834
- } finally {
835
- this._prevValue = this._value;
836
- this._modified = false;
733
+ _runEffect(type) {
734
+ if (type) {
735
+ if (this._modified && this._state !== STATE_DISPOSED) {
736
+ this._cleanup?.();
737
+ try {
738
+ this._cleanup = this._effect(this._value, this._prevValue);
739
+ } catch (e) {
740
+ if (!this._queue.notify(this, ERROR_BIT, ERROR_BIT))
741
+ throw e;
742
+ } finally {
743
+ this._prevValue = this._value;
744
+ this._modified = false;
745
+ }
837
746
  }
838
- }
747
+ } else
748
+ this._state !== STATE_CLEAN && runTop(this);
839
749
  }
840
750
  };
751
+ function runComputation() {
752
+ this._state !== STATE_CLEAN && runTop(this);
753
+ }
841
754
  var EagerComputation = class extends Computation {
842
755
  constructor(initialValue, compute2, options) {
843
756
  super(initialValue, compute2, options);
@@ -849,11 +762,12 @@ var EagerComputation = class extends Computation {
849
762
  if (this._state >= state && !this._forceNotify)
850
763
  return;
851
764
  if (!skipQueue && (this._state === STATE_CLEAN || this._state === STATE_CHECK && this._forceNotify))
852
- this._queue.enqueue(EFFECT_PURE, this);
765
+ this._queue.enqueue(EFFECT_PURE, runComputation.bind(this));
853
766
  super._notify(state, skipQueue);
854
767
  }
855
768
  };
856
- var ProjectionComputation = class extends Computation {
769
+ var FirewallComputation = class extends Computation {
770
+ firewall = true;
857
771
  constructor(compute2) {
858
772
  super(void 0, compute2);
859
773
  if (!this._parent)
@@ -863,141 +777,22 @@ var ProjectionComputation = class extends Computation {
863
777
  if (this._state >= state && !this._forceNotify)
864
778
  return;
865
779
  if (!skipQueue && (this._state === STATE_CLEAN || this._state === STATE_CHECK && this._forceNotify))
866
- this._queue.enqueue(EFFECT_PURE, this);
780
+ this._queue.enqueue(EFFECT_PURE, runComputation.bind(this));
867
781
  super._notify(state, true);
868
782
  this._forceNotify = !!skipQueue;
869
783
  }
870
784
  };
871
-
872
- // src/core/boundaries.ts
873
- var BoundaryComputation = class extends EagerComputation {
874
- _propagationMask;
875
- constructor(compute2, propagationMask) {
876
- super(void 0, compute2, { defer: true });
877
- this._propagationMask = propagationMask;
878
- }
879
- write(value, flags) {
880
- super.write(value, flags & ~this._propagationMask);
881
- if (this._propagationMask & LOADING_BIT && !(this._stateFlags & UNINITIALIZED_BIT)) {
882
- flags &= ~LOADING_BIT;
883
- }
884
- this._queue.notify(this, this._propagationMask, flags);
885
- return this._value;
886
- }
887
- };
888
- function createBoundChildren(owner, fn, queue, mask) {
889
- const parentQueue = owner._queue;
890
- parentQueue.addChild(owner._queue = queue);
891
- onCleanup(() => parentQueue.removeChild(owner._queue));
892
- return compute(
893
- owner,
894
- () => {
895
- const c = new Computation(void 0, fn);
896
- return new BoundaryComputation(() => flatten(c.wait()), mask);
897
- },
898
- null
899
- );
900
- }
901
- var ConditionalQueue = class extends Queue {
902
- _disabled;
903
- _errorNodes = /* @__PURE__ */ new Set();
904
- _pendingNodes = /* @__PURE__ */ new Set();
905
- constructor(disabled) {
906
- super();
907
- this._disabled = disabled;
908
- }
909
- run(type) {
910
- if (!type || this._disabled.read())
911
- return;
912
- return super.run(type);
913
- }
914
- notify(node, type, flags) {
915
- if (this._disabled.read()) {
916
- if (type === LOADING_BIT) {
917
- flags & LOADING_BIT ? this._pendingNodes.add(node) : this._pendingNodes.delete(node);
918
- }
919
- if (type === ERROR_BIT) {
920
- flags & ERROR_BIT ? this._errorNodes.add(node) : this._errorNodes.delete(node);
921
- }
922
- return true;
785
+ function runTop(node) {
786
+ const ancestors = [];
787
+ for (let current = node; current !== null; current = current._parent) {
788
+ if (current._state !== STATE_CLEAN) {
789
+ ancestors.push(current);
923
790
  }
924
- return super.notify(node, type, flags);
925
- }
926
- };
927
- var CollectionQueue = class extends Queue {
928
- _collectionType;
929
- _nodes = /* @__PURE__ */ new Set();
930
- _disabled = new Computation(false, null);
931
- constructor(type) {
932
- super();
933
- this._collectionType = type;
934
- }
935
- run(type) {
936
- if (!type || this._disabled.read())
937
- return;
938
- return super.run(type);
939
791
  }
940
- notify(node, type, flags) {
941
- if (!(type & this._collectionType))
942
- return super.notify(node, type, flags);
943
- if (flags & this._collectionType) {
944
- this._nodes.add(node);
945
- if (this._nodes.size === 1)
946
- this._disabled.write(true);
947
- } else {
948
- this._nodes.delete(node);
949
- if (this._nodes.size === 0)
950
- this._disabled.write(false);
951
- }
952
- type &= ~this._collectionType;
953
- return type ? super.notify(node, type, flags) : true;
792
+ for (let i = ancestors.length - 1; i >= 0; i--) {
793
+ if (ancestors[i]._state !== STATE_DISPOSED)
794
+ ancestors[i]._updateIfNecessary();
954
795
  }
955
- };
956
- function createBoundary(fn, condition) {
957
- const owner = new Owner();
958
- const queue = new ConditionalQueue(new Computation(void 0, () => condition() === "hidden" /* HIDDEN */));
959
- const tree = createBoundChildren(owner, fn, queue, 0);
960
- new EagerComputation(void 0, () => {
961
- const disabled = queue._disabled.read();
962
- tree._propagationMask = disabled ? ERROR_BIT | LOADING_BIT : 0;
963
- if (!disabled) {
964
- queue._pendingNodes.forEach((node) => queue.notify(node, LOADING_BIT, LOADING_BIT));
965
- queue._errorNodes.forEach((node) => queue.notify(node, ERROR_BIT, ERROR_BIT));
966
- queue._pendingNodes.clear();
967
- queue._errorNodes.clear();
968
- }
969
- });
970
- return () => queue._disabled.read() ? void 0 : tree.read();
971
- }
972
- function createCollectionBoundary(type, fn, fallback) {
973
- const owner = new Owner();
974
- const queue = new CollectionQueue(type);
975
- const tree = createBoundChildren(owner, fn, queue, type);
976
- const decision = new Computation(void 0, () => {
977
- if (!queue._disabled.read()) {
978
- const resolved = tree.read();
979
- if (!queue._disabled.read())
980
- return resolved;
981
- }
982
- return fallback(queue);
983
- });
984
- return decision.read.bind(decision);
985
- }
986
- function createSuspense(fn, fallback) {
987
- return createCollectionBoundary(LOADING_BIT, fn, () => fallback());
988
- }
989
- function createErrorBoundary(fn, fallback) {
990
- return createCollectionBoundary(
991
- ERROR_BIT,
992
- fn,
993
- (queue) => fallback(queue._nodes.values().next().value._error, () => {
994
- incrementClock();
995
- for (let node of queue._nodes) {
996
- node._state = STATE_DIRTY;
997
- node._queue?.enqueue(node._type, node);
998
- }
999
- })
1000
- );
1001
796
  }
1002
797
 
1003
798
  // src/signals.ts
@@ -1013,7 +808,13 @@ function createSignal(first, second, third) {
1013
808
  });
1014
809
  return [() => memo()[0](), (value) => memo()[1](value)];
1015
810
  }
1016
- const node = new Computation(first, null, second);
811
+ const o = getOwner();
812
+ const needsId = o?.id != null;
813
+ const node = new Computation(
814
+ first,
815
+ null,
816
+ needsId ? { id: o.getNextChildId(), ...second } : second
817
+ );
1017
818
  return [node.read.bind(node), node.write.bind(node)];
1018
819
  }
1019
820
  function createMemo(compute2, value, options) {
@@ -1039,10 +840,12 @@ function createMemo(compute2, value, options) {
1039
840
  };
1040
841
  }
1041
842
  function createAsync(compute2, value, options) {
843
+ let refreshing = false;
1042
844
  const node = new EagerComputation(
1043
845
  value,
1044
846
  (p) => {
1045
- const source = compute2(p);
847
+ const source = compute2(p, refreshing);
848
+ refreshing = false;
1046
849
  const isPromise = source instanceof Promise;
1047
850
  const iterator = source[Symbol.asyncIterator];
1048
851
  if (!isPromise && !iterator) {
@@ -1082,14 +885,20 @@ function createAsync(compute2, value, options) {
1082
885
  },
1083
886
  options
1084
887
  );
1085
- return node.wait.bind(node);
888
+ const read = node.wait.bind(node);
889
+ read.refresh = () => {
890
+ node._state = STATE_DIRTY;
891
+ refreshing = true;
892
+ node._updateIfNecessary();
893
+ };
894
+ return read;
1086
895
  }
1087
- function createEffect(compute2, effect, error, value, options) {
896
+ function createEffect(compute2, effect, value, options) {
1088
897
  void new Effect(
1089
898
  value,
1090
899
  compute2,
1091
- effect,
1092
- error,
900
+ effect.effect ? effect.effect : effect,
901
+ effect.error,
1093
902
  { ...options, name: options?.name ?? "effect" }
1094
903
  );
1095
904
  }
@@ -1122,101 +931,97 @@ function resolve(fn) {
1122
931
  });
1123
932
  });
1124
933
  }
934
+ function tryCatch(fn) {
935
+ try {
936
+ const v = fn();
937
+ if (v instanceof Promise) {
938
+ return v.then(
939
+ (v2) => [void 0, v2],
940
+ (e) => {
941
+ if (e instanceof NotReadyError)
942
+ throw e;
943
+ return [e];
944
+ }
945
+ );
946
+ }
947
+ return [void 0, v];
948
+ } catch (e) {
949
+ if (e instanceof NotReadyError)
950
+ throw e;
951
+ return [e];
952
+ }
953
+ }
954
+ function transition(fn) {
955
+ }
956
+ function createOptimistic(initial, compute2, options) {
957
+ return [];
958
+ }
1125
959
 
1126
960
  // src/store/projection.ts
1127
961
  function createProjection(fn, initialValue = {}) {
1128
- const [store] = createStore(fn, initialValue);
1129
- return store;
1130
- }
1131
- function wrapProjection(fn, store, setStore) {
1132
- const node = new ProjectionComputation(() => {
1133
- setStore(fn);
962
+ let wrappedStore;
963
+ const node = new FirewallComputation(() => {
964
+ storeSetter(wrappedStore, fn);
1134
965
  });
1135
- const wrapped = /* @__PURE__ */ new WeakMap();
1136
- return [wrap(store, node, wrapped), setStore];
1137
- }
1138
- function wrap(source, node, wrapped) {
1139
- if (wrapped.has(source))
1140
- return wrapped.get(source);
1141
- const wrap3 = new Proxy(source, {
1142
- get(target, property) {
1143
- node.read();
1144
- const v = target[property];
1145
- return isWrappable(v) ? wrap3(v, node, wrapped) : v;
1146
- },
1147
- set() {
1148
- throw new Error("Projections are readonly");
1149
- },
1150
- deleteProperty() {
1151
- throw new Error("Projections are readonly");
966
+ const wrappedMap = /* @__PURE__ */ new WeakMap();
967
+ const traps = {
968
+ ...storeTraps,
969
+ get(target, property, receiver) {
970
+ const o = getOwner();
971
+ (!o || o !== node) && node.wait();
972
+ return storeTraps.get(target, property, receiver);
1152
973
  }
1153
- });
1154
- wrapped.set(source, wrap3);
1155
- return wrap3;
974
+ };
975
+ function wrapProjection(source) {
976
+ if (wrappedMap.has(source))
977
+ return wrappedMap.get(source);
978
+ if (source[$TARGET]?.[STORE_WRAP] === wrapProjection)
979
+ return source;
980
+ const wrapped = createStoreProxy(source, traps, {
981
+ [STORE_WRAP]: wrapProjection,
982
+ [STORE_LOOKUP]: wrappedMap
983
+ });
984
+ wrappedMap.set(source, wrapped);
985
+ return wrapped;
986
+ }
987
+ return wrappedStore = wrapProjection(initialValue);
1156
988
  }
1157
989
 
1158
990
  // src/store/store.ts
1159
- var $RAW = Symbol("STORE_RAW" );
1160
991
  var $TRACK = Symbol("STORE_TRACK" );
1161
992
  var $DEEP = Symbol("STORE_DEEP" );
1162
993
  var $TARGET = Symbol("STORE_TARGET" );
1163
994
  var $PROXY = Symbol("STORE_PROXY" );
995
+ var $DELETED = Symbol("STORE_DELETED" );
1164
996
  var PARENTS = /* @__PURE__ */ new WeakMap();
1165
997
  var STORE_VALUE = "v";
998
+ var STORE_OVERRIDE = "o";
1166
999
  var STORE_NODE = "n";
1167
1000
  var STORE_HAS = "h";
1168
- function wrap2(value) {
1169
- let p = value[$PROXY];
1170
- if (!p) {
1171
- let target;
1172
- if (Array.isArray(value)) {
1173
- target = [];
1174
- target.v = value;
1175
- } else
1176
- target = { v: value };
1177
- Object.defineProperty(value, $PROXY, {
1178
- value: p = new Proxy(target, proxyTraps),
1179
- writable: true
1180
- });
1181
- }
1001
+ var STORE_WRAP = "w";
1002
+ var STORE_LOOKUP = "l";
1003
+ function createStoreProxy(value, traps = storeTraps, extend) {
1004
+ let newTarget;
1005
+ if (Array.isArray(value)) {
1006
+ newTarget = [];
1007
+ newTarget.v = value;
1008
+ } else
1009
+ newTarget = { v: value };
1010
+ extend && Object.assign(newTarget, extend);
1011
+ return newTarget[$PROXY] = new Proxy(newTarget, traps);
1012
+ }
1013
+ var storeLookup = /* @__PURE__ */ new WeakMap();
1014
+ function wrap(value, target) {
1015
+ if (target?.[STORE_WRAP])
1016
+ return target[STORE_WRAP](value, target);
1017
+ let p = value[$PROXY] || storeLookup.get(value);
1018
+ if (!p)
1019
+ storeLookup.set(value, p = createStoreProxy(value));
1182
1020
  return p;
1183
1021
  }
1184
1022
  function isWrappable(obj) {
1185
1023
  return obj != null && typeof obj === "object" && !Object.isFrozen(obj);
1186
1024
  }
1187
- function unwrap(item, deep2 = true, set) {
1188
- let result, unwrapped, v, prop;
1189
- if (result = item != null && item[$RAW])
1190
- return result;
1191
- if (!deep2)
1192
- return item;
1193
- if (!isWrappable(item) || set?.has(item))
1194
- return item;
1195
- if (!set)
1196
- set = /* @__PURE__ */ new Set();
1197
- set.add(item);
1198
- if (Array.isArray(item)) {
1199
- for (let i = 0, l = item.length; i < l; i++) {
1200
- v = item[i];
1201
- if ((unwrapped = unwrap(v, deep2, set)) !== v)
1202
- item[i] = unwrapped;
1203
- }
1204
- } else {
1205
- if (!deep2)
1206
- return item;
1207
- const keys = Object.keys(item);
1208
- for (let i = 0, l = keys.length; i < l; i++) {
1209
- prop = keys[i];
1210
- const desc = Object.getOwnPropertyDescriptor(item, prop);
1211
- if (desc.get)
1212
- continue;
1213
- v = item[prop];
1214
- if ((unwrapped = unwrap(v, deep2, set)) !== v)
1215
- item[prop] = unwrapped;
1216
- }
1217
- }
1218
- return item;
1219
- }
1220
1025
  function getNodes(target, type) {
1221
1026
  let nodes = target[type];
1222
1027
  if (!nodes)
@@ -1233,31 +1038,38 @@ function getNode(nodes, property, value, equals = isEqual) {
1233
1038
  }
1234
1039
  });
1235
1040
  }
1236
- function proxyDescriptor(target, property) {
1237
- if (property === $PROXY)
1238
- return { value: target[$PROXY], writable: true, configurable: true };
1239
- const desc = Reflect.getOwnPropertyDescriptor(target[STORE_VALUE], property);
1240
- if (!desc || desc.get || !desc.configurable)
1241
- return desc;
1242
- delete desc.value;
1243
- delete desc.writable;
1244
- desc.get = () => target[STORE_VALUE][$PROXY][property];
1245
- return desc;
1246
- }
1247
1041
  function trackSelf(target, symbol = $TRACK) {
1248
1042
  getObserver() && getNode(getNodes(target, STORE_NODE), symbol, void 0, false).read();
1249
1043
  }
1250
- function ownKeys(target) {
1251
- trackSelf(target);
1252
- return Reflect.ownKeys(target[STORE_VALUE]);
1044
+ function getKeys(source, override, enumerable = true) {
1045
+ const baseKeys = untrack(() => enumerable ? Object.keys(source) : Reflect.ownKeys(source));
1046
+ if (!override)
1047
+ return baseKeys;
1048
+ const keys = new Set(baseKeys);
1049
+ const overrides = Reflect.ownKeys(override);
1050
+ for (const key of overrides) {
1051
+ if (override[key] !== $DELETED)
1052
+ keys.add(key);
1053
+ else
1054
+ keys.delete(key);
1055
+ }
1056
+ return Array.from(keys);
1057
+ }
1058
+ function getPropertyDescriptor(source, override, property) {
1059
+ let value = source;
1060
+ if (override && property in override) {
1061
+ if (value[property] === $DELETED)
1062
+ return void 0;
1063
+ if (!(property in value))
1064
+ value = override;
1065
+ }
1066
+ return Reflect.getOwnPropertyDescriptor(value, property);
1253
1067
  }
1254
1068
  var Writing = null;
1255
- var proxyTraps = {
1069
+ var storeTraps = {
1256
1070
  get(target, property, receiver) {
1257
1071
  if (property === $TARGET)
1258
1072
  return target;
1259
- if (property === $RAW)
1260
- return target[STORE_VALUE];
1261
1073
  if (property === $PROXY)
1262
1074
  return receiver;
1263
1075
  if (property === $TRACK || property === $DEEP) {
@@ -1265,92 +1077,156 @@ var proxyTraps = {
1265
1077
  return receiver;
1266
1078
  }
1267
1079
  const nodes = getNodes(target, STORE_NODE);
1268
- const storeValue = target[STORE_VALUE];
1269
1080
  const tracked = nodes[property];
1081
+ const overridden = target[STORE_OVERRIDE] && property in target[STORE_OVERRIDE];
1082
+ const proxySource = !!target[STORE_VALUE][$TARGET];
1083
+ const storeValue = overridden ? target[STORE_OVERRIDE] : target[STORE_VALUE];
1270
1084
  if (!tracked) {
1271
1085
  const desc = Object.getOwnPropertyDescriptor(storeValue, property);
1272
1086
  if (desc && desc.get)
1273
1087
  return desc.get.call(receiver);
1274
1088
  }
1275
- if (Writing?.has(storeValue)) {
1276
- const value2 = tracked ? tracked._value : storeValue[property];
1277
- return isWrappable(value2) ? (Writing.add(value2[$RAW] || value2), wrap2(value2)) : value2;
1278
- }
1279
- let value = tracked ? nodes[property].read() : storeValue[property];
1089
+ if (Writing?.has(receiver)) {
1090
+ let value2 = tracked && (overridden || !proxySource) ? tracked._value : storeValue[property];
1091
+ value2 === $DELETED && (value2 = void 0);
1092
+ if (!isWrappable(value2))
1093
+ return value2;
1094
+ const wrapped = wrap(value2, target);
1095
+ Writing.add(wrapped);
1096
+ return wrapped;
1097
+ }
1098
+ let value = tracked ? overridden || !proxySource ? nodes[property].read() : (nodes[property].read(), storeValue[property]) : storeValue[property];
1099
+ value === $DELETED && (value = void 0);
1280
1100
  if (!tracked) {
1281
- if (typeof value === "function" && !storeValue.hasOwnProperty(property)) {
1101
+ if (!overridden && typeof value === "function" && !storeValue.hasOwnProperty(property)) {
1282
1102
  let proto;
1283
- return !Array.isArray(storeValue) && (proto = Object.getPrototypeOf(storeValue)) && proto !== Object.prototype ? value.bind(storeValue) : value;
1103
+ return !Array.isArray(target[STORE_VALUE]) && (proto = Object.getPrototypeOf(target[STORE_VALUE])) && proto !== Object.prototype ? value.bind(storeValue) : value;
1284
1104
  } else if (getObserver()) {
1285
- return getNode(nodes, property, isWrappable(value) ? wrap2(value) : value).read();
1105
+ return getNode(nodes, property, isWrappable(value) ? wrap(value, target) : value).read();
1286
1106
  }
1287
1107
  }
1288
- return isWrappable(value) ? wrap2(value) : value;
1108
+ return isWrappable(value) ? wrap(value, target) : value;
1289
1109
  },
1290
1110
  has(target, property) {
1291
- if (property === $RAW || property === $PROXY || property === $TRACK || property === "__proto__")
1111
+ if (property === $PROXY || property === $TRACK || property === "__proto__")
1292
1112
  return true;
1293
- const has = property in target[STORE_VALUE];
1113
+ const has = target[STORE_OVERRIDE] && property in target[STORE_OVERRIDE] ? target[STORE_OVERRIDE][property] !== $DELETED : property in target[STORE_VALUE];
1294
1114
  getObserver() && getNode(getNodes(target, STORE_HAS), property, has).read();
1295
1115
  return has;
1296
1116
  },
1297
- set(target, property, value) {
1298
- Writing?.has(target[STORE_VALUE]) && setProperty(target[STORE_VALUE], property, unwrap(value, false));
1117
+ set(target, property, rawValue) {
1118
+ const store = target[$PROXY];
1119
+ if (Writing?.has(target[$PROXY])) {
1120
+ untrack(() => {
1121
+ const state = target[STORE_VALUE];
1122
+ const base = state[property];
1123
+ const prev = target[STORE_OVERRIDE]?.[property] || base;
1124
+ const value = rawValue?.[$TARGET]?.[STORE_VALUE] ?? rawValue;
1125
+ if (prev === value)
1126
+ return true;
1127
+ const len = target[STORE_OVERRIDE]?.length || state.length;
1128
+ if (value !== void 0 && value === base)
1129
+ delete target[STORE_OVERRIDE][property];
1130
+ else
1131
+ (target[STORE_OVERRIDE] || (target[STORE_OVERRIDE] = /* @__PURE__ */ Object.create(null)))[property] = value;
1132
+ const wrappable = isWrappable(value);
1133
+ if (isWrappable(prev)) {
1134
+ const parents = PARENTS.get(prev);
1135
+ parents && (parents instanceof Set ? parents.delete(store) : PARENTS.delete(prev));
1136
+ }
1137
+ if (recursivelyNotify(store, storeLookup) && wrappable)
1138
+ recursivelyAddParent(value, store);
1139
+ target[STORE_HAS]?.[property]?.write(true);
1140
+ const nodes = getNodes(target, STORE_NODE);
1141
+ nodes[property]?.write(wrappable ? wrap(value, target) : value);
1142
+ if (Array.isArray(state)) {
1143
+ const index = parseInt(property) + 1;
1144
+ if (index > len)
1145
+ nodes.length?.write(index);
1146
+ }
1147
+ nodes[$TRACK]?.write(void 0);
1148
+ });
1149
+ }
1299
1150
  return true;
1300
1151
  },
1301
1152
  deleteProperty(target, property) {
1302
- Writing?.has(target[STORE_VALUE]) && setProperty(target[STORE_VALUE], property, void 0, true);
1153
+ if (Writing?.has(target[$PROXY]) && target[STORE_OVERRIDE]?.[property] !== $DELETED) {
1154
+ untrack(() => {
1155
+ const prev = target[STORE_OVERRIDE]?.[property] || target[STORE_VALUE][property];
1156
+ if (property in target[STORE_VALUE]) {
1157
+ (target[STORE_OVERRIDE] || (target[STORE_OVERRIDE] = /* @__PURE__ */ Object.create(null)))[property] = $DELETED;
1158
+ } else if (target[STORE_OVERRIDE] && property in target[STORE_OVERRIDE]) {
1159
+ delete target[STORE_OVERRIDE][property];
1160
+ } else
1161
+ return true;
1162
+ if (isWrappable(prev)) {
1163
+ const parents = PARENTS.get(prev);
1164
+ parents && (parents instanceof Set ? parents.delete(target) : PARENTS.delete(prev));
1165
+ }
1166
+ target[STORE_HAS]?.[property]?.write(false);
1167
+ const nodes = getNodes(target, STORE_NODE);
1168
+ nodes[property]?.write(void 0);
1169
+ nodes[$TRACK]?.write(void 0);
1170
+ });
1171
+ }
1303
1172
  return true;
1304
1173
  },
1305
- ownKeys,
1306
- getOwnPropertyDescriptor: proxyDescriptor,
1174
+ ownKeys(target) {
1175
+ trackSelf(target);
1176
+ return getKeys(target[STORE_VALUE], target[STORE_OVERRIDE], false);
1177
+ },
1178
+ getOwnPropertyDescriptor(target, property) {
1179
+ if (property === $PROXY)
1180
+ return { value: target[$PROXY], writable: true, configurable: true };
1181
+ return getPropertyDescriptor(target[STORE_VALUE], target[STORE_OVERRIDE], property);
1182
+ },
1307
1183
  getPrototypeOf(target) {
1308
1184
  return Object.getPrototypeOf(target[STORE_VALUE]);
1309
1185
  }
1310
1186
  };
1311
- function setProperty(state, property, value, deleting = false) {
1312
- const prev = state[property];
1313
- if (!deleting && prev === value)
1314
- return;
1315
- const len = state.length;
1316
- if (deleting)
1317
- delete state[property];
1318
- else
1319
- state[property] = value;
1320
- const wrappable = isWrappable(value);
1321
- if (isWrappable(prev)) {
1322
- const parents = PARENTS.get(prev);
1323
- parents && (parents instanceof Set ? parents.delete(state) : PARENTS.delete(prev));
1324
- }
1325
- if (recursivelyNotify(state) && wrappable)
1326
- recursivelyAddParent(value[$RAW] || value, state);
1327
- const target = state[$PROXY]?.[$TARGET];
1328
- if (!target)
1329
- return;
1330
- if (deleting)
1331
- target[STORE_HAS]?.[property]?.write(false);
1332
- else
1333
- target[STORE_HAS]?.[property]?.write(true);
1334
- const nodes = getNodes(target, STORE_NODE);
1335
- nodes[property]?.write(wrappable ? wrap2(value) : value);
1336
- Array.isArray(state) && state.length !== len && nodes.length?.write(state.length);
1337
- nodes[$TRACK]?.write(void 0);
1338
- }
1339
- function recursivelyNotify(state) {
1340
- let target = state[$PROXY]?.[$TARGET];
1187
+ function storeSetter(store, fn) {
1188
+ const prevWriting = Writing;
1189
+ Writing = /* @__PURE__ */ new Set();
1190
+ Writing.add(store);
1191
+ try {
1192
+ fn(store);
1193
+ } finally {
1194
+ Writing.clear();
1195
+ Writing = prevWriting;
1196
+ }
1197
+ }
1198
+ function createStore(first, second) {
1199
+ const derived = typeof first === "function", wrappedStore = derived ? createProjection(first, second) : wrap(first);
1200
+ return [wrappedStore, (fn) => storeSetter(wrappedStore, fn)];
1201
+ }
1202
+ function recursivelyNotify(state, lookup) {
1203
+ let target = state[$TARGET] || lookup?.get(state)?.[$TARGET];
1341
1204
  let notified = false;
1342
- target && (getNodes(target, STORE_NODE)[$DEEP]?.write(void 0), notified = true);
1343
- const parents = PARENTS.get(state);
1205
+ if (target) {
1206
+ const deep2 = getNodes(target, STORE_NODE)[$DEEP];
1207
+ if (deep2) {
1208
+ deep2.write(void 0);
1209
+ notified = true;
1210
+ }
1211
+ lookup = target[STORE_LOOKUP] || lookup;
1212
+ }
1213
+ const parents = PARENTS.get(target?.[STORE_VALUE] || state);
1344
1214
  if (!parents)
1345
1215
  return notified;
1346
1216
  if (parents instanceof Set) {
1347
1217
  for (let parent of parents)
1348
- notified = recursivelyNotify(parent) || notified;
1218
+ notified = recursivelyNotify(parent, lookup) || notified;
1349
1219
  } else
1350
- notified = recursivelyNotify(parents) || notified;
1220
+ notified = recursivelyNotify(parents, lookup) || notified;
1351
1221
  return notified;
1352
1222
  }
1353
1223
  function recursivelyAddParent(state, parent) {
1224
+ let override;
1225
+ const target = state[$TARGET];
1226
+ if (target) {
1227
+ override = target[STORE_OVERRIDE];
1228
+ state = target[STORE_VALUE];
1229
+ }
1354
1230
  if (parent) {
1355
1231
  let parents = PARENTS.get(state);
1356
1232
  if (!parents)
@@ -1365,80 +1241,73 @@ function recursivelyAddParent(state, parent) {
1365
1241
  return;
1366
1242
  }
1367
1243
  if (Array.isArray(state)) {
1368
- for (let i = 0; i < state.length; i++) {
1369
- const item = state[i];
1370
- isWrappable(item) && recursivelyAddParent(item[$RAW] || item, state);
1244
+ const len = override?.length || state.length;
1245
+ for (let i = 0; i < len; i++) {
1246
+ const item = override && i in override ? override[i] : state[i];
1247
+ isWrappable(item) && recursivelyAddParent(item, state);
1371
1248
  }
1372
1249
  } else {
1373
- const keys = Object.keys(state);
1250
+ const keys = getKeys(state, override);
1374
1251
  for (let i = 0; i < keys.length; i++) {
1375
- const item = state[keys[i]];
1376
- isWrappable(item) && recursivelyAddParent(item[$RAW] || item, state);
1252
+ const key = keys[i];
1253
+ const item = override && key in override ? override[key] : state[key];
1254
+ isWrappable(item) && recursivelyAddParent(item, state);
1377
1255
  }
1378
1256
  }
1379
1257
  }
1380
- function createStore(first, second) {
1381
- const derived = typeof first === "function", store = derived ? second : first;
1382
- const unwrappedStore = unwrap(store);
1383
- let wrappedStore = wrap2(unwrappedStore);
1384
- const setStore = (fn) => {
1385
- const prevWriting = Writing;
1386
- Writing = /* @__PURE__ */ new Set();
1387
- Writing.add(unwrappedStore);
1388
- try {
1389
- fn(wrappedStore);
1390
- } finally {
1391
- Writing.clear();
1392
- Writing = prevWriting;
1393
- }
1394
- };
1395
- if (derived)
1396
- return wrapProjection(first, wrappedStore, setStore);
1397
- return [wrappedStore, setStore];
1398
- }
1399
1258
  function deep(store) {
1400
- recursivelyAddParent(store[$RAW] || store);
1259
+ recursivelyAddParent(store);
1401
1260
  return store[$DEEP];
1402
1261
  }
1403
1262
 
1404
1263
  // src/store/reconcile.ts
1405
- function applyState(next, state, keyFn) {
1264
+ function unwrap(value) {
1265
+ return value?.[$TARGET]?.[STORE_NODE] ?? value;
1266
+ }
1267
+ function getOverrideValue(value, override, key) {
1268
+ return override && key in override ? override[key] : value[key];
1269
+ }
1270
+ function getAllKeys(value, override, next) {
1271
+ const keys = getKeys(value, override);
1272
+ const nextKeys = Object.keys(next);
1273
+ return Array.from(/* @__PURE__ */ new Set([...keys, ...nextKeys]));
1274
+ }
1275
+ function applyState(next, state, keyFn, all) {
1406
1276
  const target = state?.[$TARGET];
1407
1277
  if (!target)
1408
1278
  return;
1409
1279
  const previous = target[STORE_VALUE];
1410
- if (next === previous)
1280
+ const override = target[STORE_OVERRIDE];
1281
+ if (next === previous && !override)
1411
1282
  return;
1412
- Object.defineProperty(next, $PROXY, {
1413
- value: previous[$PROXY],
1414
- writable: true
1415
- });
1416
- previous[$PROXY] = null;
1283
+ (target[STORE_LOOKUP] || storeLookup).set(next, target[$PROXY]);
1417
1284
  target[STORE_VALUE] = next;
1285
+ target[STORE_OVERRIDE] = void 0;
1418
1286
  if (Array.isArray(previous)) {
1419
1287
  let changed = false;
1420
- if (next.length && previous.length && next[0] && keyFn(next[0]) != null) {
1288
+ const prevLength = getOverrideValue(previous, override, "length");
1289
+ if (next.length && prevLength && next[0] && keyFn(next[0]) != null) {
1421
1290
  let i, j, start, end, newEnd, item, newIndicesNext, keyVal;
1422
- for (start = 0, end = Math.min(previous.length, next.length); start < end && (previous[start] === next[start] || previous[start] && next[start] && keyFn(previous[start]) === keyFn(next[start])); start++) {
1423
- applyState(next[start], wrap2(previous[start]), keyFn);
1291
+ for (start = 0, end = Math.min(prevLength, next.length); start < end && ((item = getOverrideValue(previous, override, start)) === next[start] || item && next[start] && keyFn(item) === keyFn(next[start])); start++) {
1292
+ applyState(next[start], wrap(item, target), keyFn, all);
1424
1293
  }
1425
1294
  const temp = new Array(next.length), newIndices = /* @__PURE__ */ new Map();
1426
- for (end = previous.length - 1, newEnd = next.length - 1; end >= start && newEnd >= start && (previous[end] === next[newEnd] || previous[end] && next[newEnd] && keyFn(previous[end]) === keyFn(next[newEnd])); end--, newEnd--) {
1427
- temp[newEnd] = previous[end];
1295
+ for (end = prevLength - 1, newEnd = next.length - 1; end >= start && newEnd >= start && ((item = getOverrideValue(previous, override, end)) === next[newEnd] || item && next[newEnd] && keyFn(item) === keyFn(next[newEnd])); end--, newEnd--) {
1296
+ temp[newEnd] = item;
1428
1297
  }
1429
1298
  if (start > newEnd || start > end) {
1430
1299
  for (j = start; j <= newEnd; j++) {
1431
1300
  changed = true;
1432
- target[STORE_NODE][j]?.write(wrap2(next[j]));
1301
+ target[STORE_NODE][j]?.write(wrap(next[j], target));
1433
1302
  }
1434
1303
  for (; j < next.length; j++) {
1435
1304
  changed = true;
1436
- const wrapped = wrap2(temp[j]);
1305
+ const wrapped = wrap(temp[j], target);
1437
1306
  target[STORE_NODE][j]?.write(wrapped);
1438
- applyState(next[j], wrapped, keyFn);
1307
+ applyState(next[j], wrapped, keyFn, all);
1439
1308
  }
1440
1309
  changed && target[STORE_NODE][$TRACK]?.write(void 0);
1441
- previous.length !== next.length && target[STORE_NODE].length?.write(next.length);
1310
+ prevLength !== next.length && target[STORE_NODE].length?.write(next.length);
1442
1311
  return;
1443
1312
  }
1444
1313
  newIndicesNext = new Array(newEnd + 1);
@@ -1450,31 +1319,32 @@ function applyState(next, state, keyFn) {
1450
1319
  newIndices.set(keyVal, j);
1451
1320
  }
1452
1321
  for (i = start; i <= end; i++) {
1453
- item = previous[i];
1322
+ item = getOverrideValue(previous, override, i);
1454
1323
  keyVal = item ? keyFn(item) : item;
1455
1324
  j = newIndices.get(keyVal);
1456
1325
  if (j !== void 0 && j !== -1) {
1457
- temp[j] = previous[i];
1326
+ temp[j] = item;
1458
1327
  j = newIndicesNext[j];
1459
1328
  newIndices.set(keyVal, j);
1460
1329
  }
1461
1330
  }
1462
1331
  for (j = start; j < next.length; j++) {
1463
1332
  if (j in temp) {
1464
- const wrapped = wrap2(temp[j]);
1333
+ const wrapped = wrap(temp[j], target);
1465
1334
  target[STORE_NODE][j]?.write(wrapped);
1466
- applyState(next[j], wrapped, keyFn);
1335
+ applyState(next[j], wrapped, keyFn, all);
1467
1336
  } else
1468
- target[STORE_NODE][j]?.write(wrap2(next[j]));
1337
+ target[STORE_NODE][j]?.write(wrap(next[j], target));
1469
1338
  }
1470
1339
  if (start < next.length)
1471
1340
  changed = true;
1472
- } else if (previous.length && next.length) {
1341
+ } else if (prevLength && next.length) {
1473
1342
  for (let i = 0, len = next.length; i < len; i++) {
1474
- isWrappable(previous[i]) && applyState(next[i], wrap2(previous[i]), keyFn);
1343
+ const item = getOverrideValue(previous, override, i);
1344
+ isWrappable(item) && applyState(next[i], wrap(item, target), keyFn, all);
1475
1345
  }
1476
1346
  }
1477
- if (previous.length !== next.length) {
1347
+ if (prevLength !== next.length) {
1478
1348
  changed = true;
1479
1349
  target[STORE_NODE].length?.write(next.length);
1480
1350
  }
@@ -1483,17 +1353,20 @@ function applyState(next, state, keyFn) {
1483
1353
  }
1484
1354
  let nodes = target[STORE_NODE];
1485
1355
  if (nodes) {
1486
- const keys = Object.keys(nodes);
1356
+ const tracked = nodes[$TRACK];
1357
+ const keys = tracked || all ? getAllKeys(previous, override, next) : Object.keys(nodes);
1487
1358
  for (let i = 0, len = keys.length; i < len; i++) {
1488
- const node = nodes[keys[i]];
1489
- const previousValue = unwrap(previous[keys[i]], false);
1490
- let nextValue = unwrap(next[keys[i]], false);
1359
+ const key = keys[i];
1360
+ const node = nodes[key];
1361
+ const previousValue = unwrap(getOverrideValue(previous, override, key));
1362
+ let nextValue = unwrap(next[key]);
1491
1363
  if (previousValue === nextValue)
1492
1364
  continue;
1493
- if (!previousValue || !isWrappable(previousValue) || keyFn(previousValue) != null && keyFn(previousValue) !== keyFn(nextValue))
1494
- node.write(isWrappable(nextValue) ? wrap2(nextValue) : nextValue);
1495
- else
1496
- applyState(nextValue, wrap2(previousValue), keyFn);
1365
+ if (!previousValue || !isWrappable(previousValue) || keyFn(previousValue) != null && keyFn(previousValue) !== keyFn(nextValue)) {
1366
+ tracked?.write(void 0);
1367
+ node?.write(isWrappable(nextValue) ? wrap(nextValue, target) : nextValue);
1368
+ } else
1369
+ applyState(nextValue, wrap(previousValue, target), keyFn, all);
1497
1370
  }
1498
1371
  }
1499
1372
  if (nodes = target[STORE_HAS]) {
@@ -1503,17 +1376,69 @@ function applyState(next, state, keyFn) {
1503
1376
  }
1504
1377
  }
1505
1378
  }
1506
- function reconcile(value, key) {
1379
+ function reconcile(value, key, all = false) {
1507
1380
  return (state) => {
1508
1381
  const keyFn = typeof key === "string" ? (item) => item[key] : key;
1509
- if (keyFn(value) !== keyFn(state))
1382
+ const eq = keyFn(state);
1383
+ if (eq !== void 0 && keyFn(value) !== keyFn(state))
1510
1384
  throw new Error("Cannot reconcile states with different identity");
1511
- applyState(value, state, keyFn);
1512
- return state;
1385
+ applyState(value, state, keyFn, all);
1513
1386
  };
1514
1387
  }
1515
1388
 
1516
1389
  // src/store/utils.ts
1390
+ function snapshot(item, map, lookup) {
1391
+ let target, isArray, override, result, unwrapped, v;
1392
+ if (!isWrappable(item))
1393
+ return item;
1394
+ if (map && map.has(item))
1395
+ return map.get(item);
1396
+ if (!map)
1397
+ map = /* @__PURE__ */ new Map();
1398
+ if (target = item[$TARGET] || lookup?.get(item)?.[$TARGET]) {
1399
+ override = target[STORE_OVERRIDE];
1400
+ isArray = Array.isArray(target[STORE_VALUE]);
1401
+ map.set(
1402
+ item,
1403
+ override ? result = isArray ? [] : Object.create(Object.getPrototypeOf(target[STORE_VALUE])) : target[STORE_VALUE]
1404
+ );
1405
+ item = target[STORE_VALUE];
1406
+ lookup = storeLookup;
1407
+ } else {
1408
+ isArray = Array.isArray(item);
1409
+ map.set(item, item);
1410
+ }
1411
+ if (isArray) {
1412
+ const len = override?.length || item.length;
1413
+ for (let i = 0; i < len; i++) {
1414
+ v = override && i in override ? override[i] : item[i];
1415
+ if (v === $DELETED)
1416
+ continue;
1417
+ if ((unwrapped = snapshot(v, map, lookup)) !== v || result) {
1418
+ if (!result)
1419
+ map.set(item, result = [...item]);
1420
+ result[i] = unwrapped;
1421
+ }
1422
+ }
1423
+ } else {
1424
+ const keys = getKeys(item, override);
1425
+ for (let i = 0, l = keys.length; i < l; i++) {
1426
+ let prop = keys[i];
1427
+ const desc = getPropertyDescriptor(item, override, prop);
1428
+ if (desc.get)
1429
+ continue;
1430
+ v = override && prop in override ? override[prop] : item[prop];
1431
+ if ((unwrapped = snapshot(v, map, lookup)) !== item[prop] || result) {
1432
+ if (!result) {
1433
+ result = Object.create(Object.getPrototypeOf(item));
1434
+ Object.assign(result, item);
1435
+ }
1436
+ result[prop] = unwrapped;
1437
+ }
1438
+ }
1439
+ }
1440
+ return result || item;
1441
+ }
1517
1442
  function trueFn() {
1518
1443
  return true;
1519
1444
  }
@@ -1678,20 +1603,21 @@ function mapArray(list, map, options) {
1678
1603
  _fallback: options?.fallback
1679
1604
  });
1680
1605
  }
1606
+ var pureOptions = { pureWrite: true };
1681
1607
  function updateKeyedMap() {
1682
1608
  const newItems = this._list() || [], newLen = newItems.length;
1683
1609
  newItems[$TRACK];
1684
1610
  runWithOwner(this._owner, () => {
1685
1611
  let i, j, mapper = this._rows ? () => {
1686
- this._rows[j] = new Computation(newItems[j], null);
1687
- this._indexes && (this._indexes[j] = new Computation(j, null));
1612
+ this._rows[j] = new Computation(newItems[j], null, pureOptions);
1613
+ this._indexes && (this._indexes[j] = new Computation(j, null, pureOptions));
1688
1614
  return this._map(
1689
1615
  Computation.prototype.read.bind(this._rows[j]),
1690
1616
  this._indexes ? Computation.prototype.read.bind(this._indexes[j]) : void 0
1691
1617
  );
1692
1618
  } : this._indexes ? () => {
1693
1619
  const item = newItems[j];
1694
- this._indexes[j] = new Computation(j, null);
1620
+ this._indexes[j] = new Computation(j, null, pureOptions);
1695
1621
  return this._map(() => item, Computation.prototype.read.bind(this._indexes[j]));
1696
1622
  } : () => {
1697
1623
  const item = newItems[j];
@@ -1859,4 +1785,198 @@ function compare(key, a, b) {
1859
1785
  return key ? key(a) === key(b) : true;
1860
1786
  }
1861
1787
 
1862
- export { $PROXY, $RAW, $TARGET, $TRACK, Computation, ContextNotFoundError, NoOwnerError, NotReadyError, Owner, Queue, SUPPORTS_PROXY, createAsync, createBoundary, createContext, createEffect, createErrorBoundary, createMemo, createProjection, createRenderEffect, createRoot, createSignal, createStore, createSuspense, deep, flatten, flushSync, getContext, getObserver, getOwner, hasContext, hasUpdated, isEqual, isPending, isWrappable, latest, mapArray, merge, omit, onCleanup, reconcile, repeat, resolve, runWithObserver, runWithOwner, setContext, tryCatch, untrack, unwrap };
1788
+ // src/boundaries.ts
1789
+ var BoundaryComputation = class extends EagerComputation {
1790
+ _propagationMask;
1791
+ constructor(compute2, propagationMask) {
1792
+ super(void 0, compute2, { defer: true });
1793
+ this._propagationMask = propagationMask;
1794
+ }
1795
+ write(value, flags) {
1796
+ super.write(value, flags & ~this._propagationMask);
1797
+ if (this._propagationMask & LOADING_BIT && !(this._stateFlags & UNINITIALIZED_BIT)) {
1798
+ flags &= ~LOADING_BIT;
1799
+ }
1800
+ this._queue.notify(this, this._propagationMask, flags);
1801
+ return this._value;
1802
+ }
1803
+ };
1804
+ function createBoundChildren(owner, fn, queue, mask) {
1805
+ const parentQueue = owner._queue;
1806
+ parentQueue.addChild(owner._queue = queue);
1807
+ onCleanup(() => parentQueue.removeChild(owner._queue));
1808
+ return compute(
1809
+ owner,
1810
+ () => {
1811
+ const c = new Computation(void 0, fn);
1812
+ return new BoundaryComputation(() => flatten(c.wait()), mask);
1813
+ },
1814
+ null
1815
+ );
1816
+ }
1817
+ var ConditionalQueue = class extends Queue {
1818
+ _disabled;
1819
+ _errorNodes = /* @__PURE__ */ new Set();
1820
+ _pendingNodes = /* @__PURE__ */ new Set();
1821
+ constructor(disabled) {
1822
+ super();
1823
+ this._disabled = disabled;
1824
+ }
1825
+ run(type) {
1826
+ if (!type || this._disabled.read())
1827
+ return;
1828
+ return super.run(type);
1829
+ }
1830
+ notify(node, type, flags) {
1831
+ if (this._disabled.read()) {
1832
+ if (type & LOADING_BIT) {
1833
+ if (flags & LOADING_BIT) {
1834
+ this._pendingNodes.add(node);
1835
+ type &= ~LOADING_BIT;
1836
+ } else if (this._pendingNodes.delete(node))
1837
+ type &= ~LOADING_BIT;
1838
+ }
1839
+ if (type & ERROR_BIT) {
1840
+ if (flags & ERROR_BIT) {
1841
+ this._errorNodes.add(node);
1842
+ type &= ~ERROR_BIT;
1843
+ } else if (this._errorNodes.delete(node))
1844
+ type &= ~ERROR_BIT;
1845
+ }
1846
+ }
1847
+ return type ? super.notify(node, type, flags) : true;
1848
+ }
1849
+ };
1850
+ var CollectionQueue = class extends Queue {
1851
+ _collectionType;
1852
+ _nodes = /* @__PURE__ */ new Set();
1853
+ _disabled = new Computation(false, null, { pureWrite: true });
1854
+ constructor(type) {
1855
+ super();
1856
+ this._collectionType = type;
1857
+ }
1858
+ run(type) {
1859
+ if (!type || this._disabled.read())
1860
+ return;
1861
+ return super.run(type);
1862
+ }
1863
+ notify(node, type, flags) {
1864
+ if (!(type & this._collectionType))
1865
+ return super.notify(node, type, flags);
1866
+ if (flags & this._collectionType) {
1867
+ this._nodes.add(node);
1868
+ if (this._nodes.size === 1)
1869
+ this._disabled.write(true);
1870
+ } else {
1871
+ this._nodes.delete(node);
1872
+ if (this._nodes.size === 0)
1873
+ this._disabled.write(false);
1874
+ }
1875
+ type &= ~this._collectionType;
1876
+ return type ? super.notify(node, type, flags) : true;
1877
+ }
1878
+ };
1879
+ function createBoundary(fn, condition) {
1880
+ const owner = new Owner();
1881
+ const queue = new ConditionalQueue(
1882
+ new Computation(void 0, () => condition() === "hidden" /* HIDDEN */)
1883
+ );
1884
+ const tree = createBoundChildren(owner, fn, queue, 0);
1885
+ new EagerComputation(void 0, () => {
1886
+ const disabled = queue._disabled.read();
1887
+ tree._propagationMask = disabled ? ERROR_BIT | LOADING_BIT : 0;
1888
+ if (!disabled) {
1889
+ queue._pendingNodes.forEach((node) => queue.notify(node, LOADING_BIT, LOADING_BIT));
1890
+ queue._errorNodes.forEach((node) => queue.notify(node, ERROR_BIT, ERROR_BIT));
1891
+ queue._pendingNodes.clear();
1892
+ queue._errorNodes.clear();
1893
+ }
1894
+ });
1895
+ return () => queue._disabled.read() ? void 0 : tree.read();
1896
+ }
1897
+ function createCollectionBoundary(type, fn, fallback) {
1898
+ const owner = new Owner();
1899
+ const queue = new CollectionQueue(type);
1900
+ const tree = createBoundChildren(owner, fn, queue, type);
1901
+ const decision = new Computation(void 0, () => {
1902
+ if (!queue._disabled.read()) {
1903
+ const resolved = tree.read();
1904
+ if (!queue._disabled.read())
1905
+ return resolved;
1906
+ }
1907
+ return fallback(queue);
1908
+ });
1909
+ return decision.read.bind(decision);
1910
+ }
1911
+ function createSuspense(fn, fallback) {
1912
+ return createCollectionBoundary(LOADING_BIT, fn, () => fallback());
1913
+ }
1914
+ function createErrorBoundary(fn, fallback) {
1915
+ return createCollectionBoundary(
1916
+ ERROR_BIT,
1917
+ fn,
1918
+ (queue) => fallback(queue._nodes.values().next().value._error, () => {
1919
+ incrementClock();
1920
+ for (let node of queue._nodes) {
1921
+ node._state = STATE_DIRTY;
1922
+ node._queue?.enqueue(node._type, node);
1923
+ }
1924
+ })
1925
+ );
1926
+ }
1927
+ function flatten(children, options) {
1928
+ if (typeof children === "function" && !children.length) {
1929
+ if (options?.doNotUnwrap)
1930
+ return children;
1931
+ do {
1932
+ children = children();
1933
+ } while (typeof children === "function" && !children.length);
1934
+ }
1935
+ if (options?.skipNonRendered && (children == null || children === true || children === false || children === ""))
1936
+ return;
1937
+ if (Array.isArray(children)) {
1938
+ let results = [];
1939
+ if (flattenArray(children, results, options)) {
1940
+ return () => {
1941
+ let nested = [];
1942
+ flattenArray(results, nested, { ...options, doNotUnwrap: false });
1943
+ return nested;
1944
+ };
1945
+ }
1946
+ return results;
1947
+ }
1948
+ return children;
1949
+ }
1950
+ function flattenArray(children, results = [], options) {
1951
+ let notReady = null;
1952
+ let needsUnwrap = false;
1953
+ for (let i = 0; i < children.length; i++) {
1954
+ try {
1955
+ let child = children[i];
1956
+ if (typeof child === "function" && !child.length) {
1957
+ if (options?.doNotUnwrap) {
1958
+ results.push(child);
1959
+ needsUnwrap = true;
1960
+ continue;
1961
+ }
1962
+ do {
1963
+ child = child();
1964
+ } while (typeof child === "function" && !child.length);
1965
+ }
1966
+ if (Array.isArray(child)) {
1967
+ needsUnwrap = flattenArray(child, results, options);
1968
+ } else if (options?.skipNonRendered && (child == null || child === true || child === false || child === "")) {
1969
+ } else
1970
+ results.push(child);
1971
+ } catch (e) {
1972
+ if (!(e instanceof NotReadyError))
1973
+ throw e;
1974
+ notReady = e;
1975
+ }
1976
+ }
1977
+ if (notReady)
1978
+ throw notReady;
1979
+ return needsUnwrap;
1980
+ }
1981
+
1982
+ export { $PROXY, $TARGET, $TRACK, Computation, ContextNotFoundError, NoOwnerError, NotReadyError, Owner, Queue, SUPPORTS_PROXY, createAsync, createBoundary, createContext, createEffect, createErrorBoundary, createMemo, createOptimistic, createProjection, createRenderEffect, createRoot, createSignal, createStore, createSuspense, deep, flatten, flush, getContext, getObserver, getOwner, hasContext, hasUpdated, isEqual, isPending, isWrappable, latest, mapArray, merge, omit, onCleanup, reconcile, repeat, resolve, runWithObserver, runWithOwner, setContext, snapshot, transition, tryCatch, untrack };