@solidjs/signals 0.3.2 → 0.4.1

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._run.bind(this)) : this._run(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._run.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,19 +730,22 @@ 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
+ _run(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
  };
841
751
  var EagerComputation = class extends Computation {
@@ -849,11 +759,15 @@ var EagerComputation = class extends Computation {
849
759
  if (this._state >= state && !this._forceNotify)
850
760
  return;
851
761
  if (!skipQueue && (this._state === STATE_CLEAN || this._state === STATE_CHECK && this._forceNotify))
852
- this._queue.enqueue(EFFECT_PURE, this);
762
+ this._queue.enqueue(EFFECT_PURE, this._run.bind(this));
853
763
  super._notify(state, skipQueue);
854
764
  }
765
+ _run() {
766
+ this._state !== STATE_CLEAN && runTop(this);
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,25 @@ 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, this._run.bind(this));
867
781
  super._notify(state, true);
868
782
  this._forceNotify = !!skipQueue;
869
783
  }
870
- };
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;
784
+ _run() {
785
+ this._state !== STATE_CLEAN && runTop(this);
886
786
  }
887
787
  };
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;
788
+ function runTop(node) {
789
+ const ancestors = [];
790
+ for (let current = node; current !== null; current = current._parent) {
791
+ if (current._state !== STATE_CLEAN) {
792
+ ancestors.push(current);
923
793
  }
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
794
  }
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;
795
+ for (let i = ancestors.length - 1; i >= 0; i--) {
796
+ if (ancestors[i]._state !== STATE_DISPOSED)
797
+ ancestors[i]._updateIfNecessary();
954
798
  }
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
799
  }
1002
800
 
1003
801
  // src/signals.ts
@@ -1013,7 +811,13 @@ function createSignal(first, second, third) {
1013
811
  });
1014
812
  return [() => memo()[0](), (value) => memo()[1](value)];
1015
813
  }
1016
- const node = new Computation(first, null, second);
814
+ const o = getOwner();
815
+ const needsId = o?.id != null;
816
+ const node = new Computation(
817
+ first,
818
+ null,
819
+ needsId ? { id: o.getNextChildId(), ...second } : second
820
+ );
1017
821
  return [node.read.bind(node), node.write.bind(node)];
1018
822
  }
1019
823
  function createMemo(compute2, value, options) {
@@ -1039,10 +843,12 @@ function createMemo(compute2, value, options) {
1039
843
  };
1040
844
  }
1041
845
  function createAsync(compute2, value, options) {
846
+ let refreshing = false;
1042
847
  const node = new EagerComputation(
1043
848
  value,
1044
849
  (p) => {
1045
- const source = compute2(p);
850
+ const source = compute2(p, refreshing);
851
+ refreshing = false;
1046
852
  const isPromise = source instanceof Promise;
1047
853
  const iterator = source[Symbol.asyncIterator];
1048
854
  if (!isPromise && !iterator) {
@@ -1082,14 +888,20 @@ function createAsync(compute2, value, options) {
1082
888
  },
1083
889
  options
1084
890
  );
1085
- return node.wait.bind(node);
891
+ const read = node.wait.bind(node);
892
+ read.refresh = () => {
893
+ node._state = STATE_DIRTY;
894
+ refreshing = true;
895
+ node._updateIfNecessary();
896
+ };
897
+ return read;
1086
898
  }
1087
- function createEffect(compute2, effect, error, value, options) {
899
+ function createEffect(compute2, effect, value, options) {
1088
900
  void new Effect(
1089
901
  value,
1090
902
  compute2,
1091
- effect,
1092
- error,
903
+ effect.effect ? effect.effect : effect,
904
+ effect.error,
1093
905
  { ...options, name: options?.name ?? "effect" }
1094
906
  );
1095
907
  }
@@ -1122,101 +934,97 @@ function resolve(fn) {
1122
934
  });
1123
935
  });
1124
936
  }
937
+ function tryCatch(fn) {
938
+ try {
939
+ const v = fn();
940
+ if (v instanceof Promise) {
941
+ return v.then(
942
+ (v2) => [void 0, v2],
943
+ (e) => {
944
+ if (e instanceof NotReadyError)
945
+ throw e;
946
+ return [e];
947
+ }
948
+ );
949
+ }
950
+ return [void 0, v];
951
+ } catch (e) {
952
+ if (e instanceof NotReadyError)
953
+ throw e;
954
+ return [e];
955
+ }
956
+ }
957
+ function transition(fn) {
958
+ }
959
+ function createOptimistic(initial, compute2, options) {
960
+ return [];
961
+ }
1125
962
 
1126
963
  // src/store/projection.ts
1127
964
  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);
965
+ let wrappedStore;
966
+ const node = new FirewallComputation(() => {
967
+ storeSetter(wrappedStore, fn);
1134
968
  });
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");
969
+ const wrappedMap = /* @__PURE__ */ new WeakMap();
970
+ const traps = {
971
+ ...storeTraps,
972
+ get(target, property, receiver) {
973
+ const o = getOwner();
974
+ (!o || o !== node) && node.wait();
975
+ return storeTraps.get(target, property, receiver);
1152
976
  }
1153
- });
1154
- wrapped.set(source, wrap3);
1155
- return wrap3;
977
+ };
978
+ function wrapProjection(source) {
979
+ if (wrappedMap.has(source))
980
+ return wrappedMap.get(source);
981
+ if (source[$TARGET]?.[STORE_WRAP] === wrapProjection)
982
+ return source;
983
+ const wrapped = createStoreProxy(source, traps, {
984
+ [STORE_WRAP]: wrapProjection,
985
+ [STORE_LOOKUP]: wrappedMap
986
+ });
987
+ wrappedMap.set(source, wrapped);
988
+ return wrapped;
989
+ }
990
+ return wrappedStore = wrapProjection(initialValue);
1156
991
  }
1157
992
 
1158
993
  // src/store/store.ts
1159
- var $RAW = Symbol("STORE_RAW" );
1160
994
  var $TRACK = Symbol("STORE_TRACK" );
1161
995
  var $DEEP = Symbol("STORE_DEEP" );
1162
996
  var $TARGET = Symbol("STORE_TARGET" );
1163
997
  var $PROXY = Symbol("STORE_PROXY" );
998
+ var $DELETED = Symbol("STORE_DELETED" );
1164
999
  var PARENTS = /* @__PURE__ */ new WeakMap();
1165
1000
  var STORE_VALUE = "v";
1001
+ var STORE_OVERRIDE = "o";
1166
1002
  var STORE_NODE = "n";
1167
1003
  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
- }
1004
+ var STORE_WRAP = "w";
1005
+ var STORE_LOOKUP = "l";
1006
+ function createStoreProxy(value, traps = storeTraps, extend) {
1007
+ let newTarget;
1008
+ if (Array.isArray(value)) {
1009
+ newTarget = [];
1010
+ newTarget.v = value;
1011
+ } else
1012
+ newTarget = { v: value };
1013
+ extend && Object.assign(newTarget, extend);
1014
+ return newTarget[$PROXY] = new Proxy(newTarget, traps);
1015
+ }
1016
+ var storeLookup = /* @__PURE__ */ new WeakMap();
1017
+ function wrap(value, target) {
1018
+ if (target?.[STORE_WRAP])
1019
+ return target[STORE_WRAP](value, target);
1020
+ let p = value[$PROXY] || storeLookup.get(value);
1021
+ if (!p)
1022
+ storeLookup.set(value, p = createStoreProxy(value));
1182
1023
  return p;
1183
1024
  }
1184
1025
  function isWrappable(obj) {
1185
1026
  return obj != null && typeof obj === "object" && !Object.isFrozen(obj);
1186
1027
  }
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
1028
  function getNodes(target, type) {
1221
1029
  let nodes = target[type];
1222
1030
  if (!nodes)
@@ -1233,31 +1041,38 @@ function getNode(nodes, property, value, equals = isEqual) {
1233
1041
  }
1234
1042
  });
1235
1043
  }
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
1044
  function trackSelf(target, symbol = $TRACK) {
1248
1045
  getObserver() && getNode(getNodes(target, STORE_NODE), symbol, void 0, false).read();
1249
1046
  }
1250
- function ownKeys(target) {
1251
- trackSelf(target);
1252
- return Reflect.ownKeys(target[STORE_VALUE]);
1047
+ function getKeys(source, override, enumerable = true) {
1048
+ const baseKeys = untrack(() => enumerable ? Object.keys(source) : Reflect.ownKeys(source));
1049
+ if (!override)
1050
+ return baseKeys;
1051
+ const keys = new Set(baseKeys);
1052
+ const overrides = Reflect.ownKeys(override);
1053
+ for (const key of overrides) {
1054
+ if (override[key] !== $DELETED)
1055
+ keys.add(key);
1056
+ else
1057
+ keys.delete(key);
1058
+ }
1059
+ return Array.from(keys);
1060
+ }
1061
+ function getPropertyDescriptor(source, override, property) {
1062
+ let value = source;
1063
+ if (override && property in override) {
1064
+ if (value[property] === $DELETED)
1065
+ return void 0;
1066
+ if (!(property in value))
1067
+ value = override;
1068
+ }
1069
+ return Reflect.getOwnPropertyDescriptor(value, property);
1253
1070
  }
1254
1071
  var Writing = null;
1255
- var proxyTraps = {
1072
+ var storeTraps = {
1256
1073
  get(target, property, receiver) {
1257
1074
  if (property === $TARGET)
1258
1075
  return target;
1259
- if (property === $RAW)
1260
- return target[STORE_VALUE];
1261
1076
  if (property === $PROXY)
1262
1077
  return receiver;
1263
1078
  if (property === $TRACK || property === $DEEP) {
@@ -1265,92 +1080,156 @@ var proxyTraps = {
1265
1080
  return receiver;
1266
1081
  }
1267
1082
  const nodes = getNodes(target, STORE_NODE);
1268
- const storeValue = target[STORE_VALUE];
1269
1083
  const tracked = nodes[property];
1084
+ const overridden = target[STORE_OVERRIDE] && property in target[STORE_OVERRIDE];
1085
+ const proxySource = !!target[STORE_VALUE][$TARGET];
1086
+ const storeValue = overridden ? target[STORE_OVERRIDE] : target[STORE_VALUE];
1270
1087
  if (!tracked) {
1271
1088
  const desc = Object.getOwnPropertyDescriptor(storeValue, property);
1272
1089
  if (desc && desc.get)
1273
1090
  return desc.get.call(receiver);
1274
1091
  }
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];
1092
+ if (Writing?.has(receiver)) {
1093
+ let value2 = tracked && (overridden || !proxySource) ? tracked._value : storeValue[property];
1094
+ value2 === $DELETED && (value2 = void 0);
1095
+ if (!isWrappable(value2))
1096
+ return value2;
1097
+ const wrapped = wrap(value2, target);
1098
+ Writing.add(wrapped);
1099
+ return wrapped;
1100
+ }
1101
+ let value = tracked ? overridden || !proxySource ? nodes[property].read() : (nodes[property].read(), storeValue[property]) : storeValue[property];
1102
+ value === $DELETED && (value = void 0);
1280
1103
  if (!tracked) {
1281
- if (typeof value === "function" && !storeValue.hasOwnProperty(property)) {
1104
+ if (!overridden && typeof value === "function" && !storeValue.hasOwnProperty(property)) {
1282
1105
  let proto;
1283
- return !Array.isArray(storeValue) && (proto = Object.getPrototypeOf(storeValue)) && proto !== Object.prototype ? value.bind(storeValue) : value;
1106
+ return !Array.isArray(target[STORE_VALUE]) && (proto = Object.getPrototypeOf(target[STORE_VALUE])) && proto !== Object.prototype ? value.bind(storeValue) : value;
1284
1107
  } else if (getObserver()) {
1285
- return getNode(nodes, property, isWrappable(value) ? wrap2(value) : value).read();
1108
+ return getNode(nodes, property, isWrappable(value) ? wrap(value, target) : value).read();
1286
1109
  }
1287
1110
  }
1288
- return isWrappable(value) ? wrap2(value) : value;
1111
+ return isWrappable(value) ? wrap(value, target) : value;
1289
1112
  },
1290
1113
  has(target, property) {
1291
- if (property === $RAW || property === $PROXY || property === $TRACK || property === "__proto__")
1114
+ if (property === $PROXY || property === $TRACK || property === "__proto__")
1292
1115
  return true;
1293
- const has = property in target[STORE_VALUE];
1116
+ const has = target[STORE_OVERRIDE] && property in target[STORE_OVERRIDE] ? target[STORE_OVERRIDE][property] !== $DELETED : property in target[STORE_VALUE];
1294
1117
  getObserver() && getNode(getNodes(target, STORE_HAS), property, has).read();
1295
1118
  return has;
1296
1119
  },
1297
- set(target, property, value) {
1298
- Writing?.has(target[STORE_VALUE]) && setProperty(target[STORE_VALUE], property, unwrap(value, false));
1120
+ set(target, property, rawValue) {
1121
+ const store = target[$PROXY];
1122
+ if (Writing?.has(target[$PROXY])) {
1123
+ untrack(() => {
1124
+ const state = target[STORE_VALUE];
1125
+ const base = state[property];
1126
+ const prev = target[STORE_OVERRIDE]?.[property] || base;
1127
+ const value = rawValue?.[$TARGET]?.[STORE_VALUE] ?? rawValue;
1128
+ if (prev === value)
1129
+ return true;
1130
+ const len = target[STORE_OVERRIDE]?.length || state.length;
1131
+ if (value !== void 0 && value === base)
1132
+ delete target[STORE_OVERRIDE][property];
1133
+ else
1134
+ (target[STORE_OVERRIDE] || (target[STORE_OVERRIDE] = /* @__PURE__ */ Object.create(null)))[property] = value;
1135
+ const wrappable = isWrappable(value);
1136
+ if (isWrappable(prev)) {
1137
+ const parents = PARENTS.get(prev);
1138
+ parents && (parents instanceof Set ? parents.delete(store) : PARENTS.delete(prev));
1139
+ }
1140
+ if (recursivelyNotify(store, storeLookup) && wrappable)
1141
+ recursivelyAddParent(value, store);
1142
+ target[STORE_HAS]?.[property]?.write(true);
1143
+ const nodes = getNodes(target, STORE_NODE);
1144
+ nodes[property]?.write(wrappable ? wrap(value, target) : value);
1145
+ if (Array.isArray(state)) {
1146
+ const index = parseInt(property) + 1;
1147
+ if (index > len)
1148
+ nodes.length?.write(index);
1149
+ }
1150
+ nodes[$TRACK]?.write(void 0);
1151
+ });
1152
+ }
1299
1153
  return true;
1300
1154
  },
1301
1155
  deleteProperty(target, property) {
1302
- Writing?.has(target[STORE_VALUE]) && setProperty(target[STORE_VALUE], property, void 0, true);
1156
+ if (Writing?.has(target[$PROXY]) && target[STORE_OVERRIDE]?.[property] !== $DELETED) {
1157
+ untrack(() => {
1158
+ const prev = target[STORE_OVERRIDE]?.[property] || target[STORE_VALUE][property];
1159
+ if (property in target[STORE_VALUE]) {
1160
+ (target[STORE_OVERRIDE] || (target[STORE_OVERRIDE] = /* @__PURE__ */ Object.create(null)))[property] = $DELETED;
1161
+ } else if (target[STORE_OVERRIDE] && property in target[STORE_OVERRIDE]) {
1162
+ delete target[STORE_OVERRIDE][property];
1163
+ } else
1164
+ return true;
1165
+ if (isWrappable(prev)) {
1166
+ const parents = PARENTS.get(prev);
1167
+ parents && (parents instanceof Set ? parents.delete(target) : PARENTS.delete(prev));
1168
+ }
1169
+ target[STORE_HAS]?.[property]?.write(false);
1170
+ const nodes = getNodes(target, STORE_NODE);
1171
+ nodes[property]?.write(void 0);
1172
+ nodes[$TRACK]?.write(void 0);
1173
+ });
1174
+ }
1303
1175
  return true;
1304
1176
  },
1305
- ownKeys,
1306
- getOwnPropertyDescriptor: proxyDescriptor,
1177
+ ownKeys(target) {
1178
+ trackSelf(target);
1179
+ return getKeys(target[STORE_VALUE], target[STORE_OVERRIDE], false);
1180
+ },
1181
+ getOwnPropertyDescriptor(target, property) {
1182
+ if (property === $PROXY)
1183
+ return { value: target[$PROXY], writable: true, configurable: true };
1184
+ return getPropertyDescriptor(target[STORE_VALUE], target[STORE_OVERRIDE], property);
1185
+ },
1307
1186
  getPrototypeOf(target) {
1308
1187
  return Object.getPrototypeOf(target[STORE_VALUE]);
1309
1188
  }
1310
1189
  };
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];
1190
+ function storeSetter(store, fn) {
1191
+ const prevWriting = Writing;
1192
+ Writing = /* @__PURE__ */ new Set();
1193
+ Writing.add(store);
1194
+ try {
1195
+ fn(store);
1196
+ } finally {
1197
+ Writing.clear();
1198
+ Writing = prevWriting;
1199
+ }
1200
+ }
1201
+ function createStore(first, second) {
1202
+ const derived = typeof first === "function", wrappedStore = derived ? createProjection(first, second) : wrap(first);
1203
+ return [wrappedStore, (fn) => storeSetter(wrappedStore, fn)];
1204
+ }
1205
+ function recursivelyNotify(state, lookup) {
1206
+ let target = state[$TARGET] || lookup?.get(state)?.[$TARGET];
1341
1207
  let notified = false;
1342
- target && (getNodes(target, STORE_NODE)[$DEEP]?.write(void 0), notified = true);
1343
- const parents = PARENTS.get(state);
1208
+ if (target) {
1209
+ const deep2 = getNodes(target, STORE_NODE)[$DEEP];
1210
+ if (deep2) {
1211
+ deep2.write(void 0);
1212
+ notified = true;
1213
+ }
1214
+ lookup = target[STORE_LOOKUP] || lookup;
1215
+ }
1216
+ const parents = PARENTS.get(target?.[STORE_VALUE] || state);
1344
1217
  if (!parents)
1345
1218
  return notified;
1346
1219
  if (parents instanceof Set) {
1347
1220
  for (let parent of parents)
1348
- notified = recursivelyNotify(parent) || notified;
1221
+ notified = recursivelyNotify(parent, lookup) || notified;
1349
1222
  } else
1350
- notified = recursivelyNotify(parents) || notified;
1223
+ notified = recursivelyNotify(parents, lookup) || notified;
1351
1224
  return notified;
1352
1225
  }
1353
1226
  function recursivelyAddParent(state, parent) {
1227
+ let override;
1228
+ const target = state[$TARGET];
1229
+ if (target) {
1230
+ override = target[STORE_OVERRIDE];
1231
+ state = target[STORE_VALUE];
1232
+ }
1354
1233
  if (parent) {
1355
1234
  let parents = PARENTS.get(state);
1356
1235
  if (!parents)
@@ -1365,80 +1244,73 @@ function recursivelyAddParent(state, parent) {
1365
1244
  return;
1366
1245
  }
1367
1246
  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);
1247
+ const len = override?.length || state.length;
1248
+ for (let i = 0; i < len; i++) {
1249
+ const item = override && i in override ? override[i] : state[i];
1250
+ isWrappable(item) && recursivelyAddParent(item, state);
1371
1251
  }
1372
1252
  } else {
1373
- const keys = Object.keys(state);
1253
+ const keys = getKeys(state, override);
1374
1254
  for (let i = 0; i < keys.length; i++) {
1375
- const item = state[keys[i]];
1376
- isWrappable(item) && recursivelyAddParent(item[$RAW] || item, state);
1255
+ const key = keys[i];
1256
+ const item = override && key in override ? override[key] : state[key];
1257
+ isWrappable(item) && recursivelyAddParent(item, state);
1377
1258
  }
1378
1259
  }
1379
1260
  }
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
1261
  function deep(store) {
1400
- recursivelyAddParent(store[$RAW] || store);
1262
+ recursivelyAddParent(store);
1401
1263
  return store[$DEEP];
1402
1264
  }
1403
1265
 
1404
1266
  // src/store/reconcile.ts
1405
- function applyState(next, state, keyFn) {
1267
+ function unwrap(value) {
1268
+ return value?.[$TARGET]?.[STORE_NODE] ?? value;
1269
+ }
1270
+ function getOverrideValue(value, override, key) {
1271
+ return override && key in override ? override[key] : value[key];
1272
+ }
1273
+ function getAllKeys(value, override, next) {
1274
+ const keys = getKeys(value, override);
1275
+ const nextKeys = Object.keys(next);
1276
+ return Array.from(/* @__PURE__ */ new Set([...keys, ...nextKeys]));
1277
+ }
1278
+ function applyState(next, state, keyFn, all) {
1406
1279
  const target = state?.[$TARGET];
1407
1280
  if (!target)
1408
1281
  return;
1409
1282
  const previous = target[STORE_VALUE];
1410
- if (next === previous)
1283
+ const override = target[STORE_OVERRIDE];
1284
+ if (next === previous && !override)
1411
1285
  return;
1412
- Object.defineProperty(next, $PROXY, {
1413
- value: previous[$PROXY],
1414
- writable: true
1415
- });
1416
- previous[$PROXY] = null;
1286
+ (target[STORE_LOOKUP] || storeLookup).set(next, target[$PROXY]);
1417
1287
  target[STORE_VALUE] = next;
1288
+ target[STORE_OVERRIDE] = void 0;
1418
1289
  if (Array.isArray(previous)) {
1419
1290
  let changed = false;
1420
- if (next.length && previous.length && next[0] && keyFn(next[0]) != null) {
1291
+ const prevLength = getOverrideValue(previous, override, "length");
1292
+ if (next.length && prevLength && next[0] && keyFn(next[0]) != null) {
1421
1293
  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);
1294
+ 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++) {
1295
+ applyState(next[start], wrap(item, target), keyFn, all);
1424
1296
  }
1425
1297
  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];
1298
+ 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--) {
1299
+ temp[newEnd] = item;
1428
1300
  }
1429
1301
  if (start > newEnd || start > end) {
1430
1302
  for (j = start; j <= newEnd; j++) {
1431
1303
  changed = true;
1432
- target[STORE_NODE][j]?.write(wrap2(next[j]));
1304
+ target[STORE_NODE][j]?.write(wrap(next[j], target));
1433
1305
  }
1434
1306
  for (; j < next.length; j++) {
1435
1307
  changed = true;
1436
- const wrapped = wrap2(temp[j]);
1308
+ const wrapped = wrap(temp[j], target);
1437
1309
  target[STORE_NODE][j]?.write(wrapped);
1438
- applyState(next[j], wrapped, keyFn);
1310
+ applyState(next[j], wrapped, keyFn, all);
1439
1311
  }
1440
1312
  changed && target[STORE_NODE][$TRACK]?.write(void 0);
1441
- previous.length !== next.length && target[STORE_NODE].length?.write(next.length);
1313
+ prevLength !== next.length && target[STORE_NODE].length?.write(next.length);
1442
1314
  return;
1443
1315
  }
1444
1316
  newIndicesNext = new Array(newEnd + 1);
@@ -1450,31 +1322,32 @@ function applyState(next, state, keyFn) {
1450
1322
  newIndices.set(keyVal, j);
1451
1323
  }
1452
1324
  for (i = start; i <= end; i++) {
1453
- item = previous[i];
1325
+ item = getOverrideValue(previous, override, i);
1454
1326
  keyVal = item ? keyFn(item) : item;
1455
1327
  j = newIndices.get(keyVal);
1456
1328
  if (j !== void 0 && j !== -1) {
1457
- temp[j] = previous[i];
1329
+ temp[j] = item;
1458
1330
  j = newIndicesNext[j];
1459
1331
  newIndices.set(keyVal, j);
1460
1332
  }
1461
1333
  }
1462
1334
  for (j = start; j < next.length; j++) {
1463
1335
  if (j in temp) {
1464
- const wrapped = wrap2(temp[j]);
1336
+ const wrapped = wrap(temp[j], target);
1465
1337
  target[STORE_NODE][j]?.write(wrapped);
1466
- applyState(next[j], wrapped, keyFn);
1338
+ applyState(next[j], wrapped, keyFn, all);
1467
1339
  } else
1468
- target[STORE_NODE][j]?.write(wrap2(next[j]));
1340
+ target[STORE_NODE][j]?.write(wrap(next[j], target));
1469
1341
  }
1470
1342
  if (start < next.length)
1471
1343
  changed = true;
1472
- } else if (previous.length && next.length) {
1344
+ } else if (prevLength && next.length) {
1473
1345
  for (let i = 0, len = next.length; i < len; i++) {
1474
- isWrappable(previous[i]) && applyState(next[i], wrap2(previous[i]), keyFn);
1346
+ const item = getOverrideValue(previous, override, i);
1347
+ isWrappable(item) && applyState(next[i], wrap(item, target), keyFn, all);
1475
1348
  }
1476
1349
  }
1477
- if (previous.length !== next.length) {
1350
+ if (prevLength !== next.length) {
1478
1351
  changed = true;
1479
1352
  target[STORE_NODE].length?.write(next.length);
1480
1353
  }
@@ -1483,17 +1356,20 @@ function applyState(next, state, keyFn) {
1483
1356
  }
1484
1357
  let nodes = target[STORE_NODE];
1485
1358
  if (nodes) {
1486
- const keys = Object.keys(nodes);
1359
+ const tracked = nodes[$TRACK];
1360
+ const keys = tracked || all ? getAllKeys(previous, override, next) : Object.keys(nodes);
1487
1361
  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);
1362
+ const key = keys[i];
1363
+ const node = nodes[key];
1364
+ const previousValue = unwrap(getOverrideValue(previous, override, key));
1365
+ let nextValue = unwrap(next[key]);
1491
1366
  if (previousValue === nextValue)
1492
1367
  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);
1368
+ if (!previousValue || !isWrappable(previousValue) || keyFn(previousValue) != null && keyFn(previousValue) !== keyFn(nextValue)) {
1369
+ tracked?.write(void 0);
1370
+ node?.write(isWrappable(nextValue) ? wrap(nextValue, target) : nextValue);
1371
+ } else
1372
+ applyState(nextValue, wrap(previousValue, target), keyFn, all);
1497
1373
  }
1498
1374
  }
1499
1375
  if (nodes = target[STORE_HAS]) {
@@ -1503,17 +1379,69 @@ function applyState(next, state, keyFn) {
1503
1379
  }
1504
1380
  }
1505
1381
  }
1506
- function reconcile(value, key) {
1382
+ function reconcile(value, key, all = false) {
1507
1383
  return (state) => {
1508
1384
  const keyFn = typeof key === "string" ? (item) => item[key] : key;
1509
- if (keyFn(value) !== keyFn(state))
1385
+ const eq = keyFn(state);
1386
+ if (eq !== void 0 && keyFn(value) !== keyFn(state))
1510
1387
  throw new Error("Cannot reconcile states with different identity");
1511
- applyState(value, state, keyFn);
1512
- return state;
1388
+ applyState(value, state, keyFn, all);
1513
1389
  };
1514
1390
  }
1515
1391
 
1516
1392
  // src/store/utils.ts
1393
+ function snapshot(item, map, lookup) {
1394
+ let target, isArray, override, result, unwrapped, v;
1395
+ if (!isWrappable(item))
1396
+ return item;
1397
+ if (map && map.has(item))
1398
+ return map.get(item);
1399
+ if (!map)
1400
+ map = /* @__PURE__ */ new Map();
1401
+ if (target = item[$TARGET] || lookup?.get(item)?.[$TARGET]) {
1402
+ override = target[STORE_OVERRIDE];
1403
+ isArray = Array.isArray(target[STORE_VALUE]);
1404
+ map.set(
1405
+ item,
1406
+ override ? result = isArray ? [] : Object.create(Object.getPrototypeOf(target[STORE_VALUE])) : target[STORE_VALUE]
1407
+ );
1408
+ item = target[STORE_VALUE];
1409
+ lookup = storeLookup;
1410
+ } else {
1411
+ isArray = Array.isArray(item);
1412
+ map.set(item, item);
1413
+ }
1414
+ if (isArray) {
1415
+ const len = override?.length || item.length;
1416
+ for (let i = 0; i < len; i++) {
1417
+ v = override && i in override ? override[i] : item[i];
1418
+ if (v === $DELETED)
1419
+ continue;
1420
+ if ((unwrapped = snapshot(v, map, lookup)) !== v || result) {
1421
+ if (!result)
1422
+ map.set(item, result = [...item]);
1423
+ result[i] = unwrapped;
1424
+ }
1425
+ }
1426
+ } else {
1427
+ const keys = getKeys(item, override);
1428
+ for (let i = 0, l = keys.length; i < l; i++) {
1429
+ let prop = keys[i];
1430
+ const desc = getPropertyDescriptor(item, override, prop);
1431
+ if (desc.get)
1432
+ continue;
1433
+ v = override && prop in override ? override[prop] : item[prop];
1434
+ if ((unwrapped = snapshot(v, map, lookup)) !== item[prop] || result) {
1435
+ if (!result) {
1436
+ result = Object.create(Object.getPrototypeOf(item));
1437
+ Object.assign(result, item);
1438
+ }
1439
+ result[prop] = unwrapped;
1440
+ }
1441
+ }
1442
+ }
1443
+ return result || item;
1444
+ }
1517
1445
  function trueFn() {
1518
1446
  return true;
1519
1447
  }
@@ -1678,20 +1606,21 @@ function mapArray(list, map, options) {
1678
1606
  _fallback: options?.fallback
1679
1607
  });
1680
1608
  }
1609
+ var pureOptions = { pureWrite: true };
1681
1610
  function updateKeyedMap() {
1682
1611
  const newItems = this._list() || [], newLen = newItems.length;
1683
1612
  newItems[$TRACK];
1684
1613
  runWithOwner(this._owner, () => {
1685
1614
  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));
1615
+ this._rows[j] = new Computation(newItems[j], null, pureOptions);
1616
+ this._indexes && (this._indexes[j] = new Computation(j, null, pureOptions));
1688
1617
  return this._map(
1689
1618
  Computation.prototype.read.bind(this._rows[j]),
1690
1619
  this._indexes ? Computation.prototype.read.bind(this._indexes[j]) : void 0
1691
1620
  );
1692
1621
  } : this._indexes ? () => {
1693
1622
  const item = newItems[j];
1694
- this._indexes[j] = new Computation(j, null);
1623
+ this._indexes[j] = new Computation(j, null, pureOptions);
1695
1624
  return this._map(() => item, Computation.prototype.read.bind(this._indexes[j]));
1696
1625
  } : () => {
1697
1626
  const item = newItems[j];
@@ -1859,4 +1788,198 @@ function compare(key, a, b) {
1859
1788
  return key ? key(a) === key(b) : true;
1860
1789
  }
1861
1790
 
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 };
1791
+ // src/boundaries.ts
1792
+ var BoundaryComputation = class extends EagerComputation {
1793
+ _propagationMask;
1794
+ constructor(compute2, propagationMask) {
1795
+ super(void 0, compute2, { defer: true });
1796
+ this._propagationMask = propagationMask;
1797
+ }
1798
+ write(value, flags) {
1799
+ super.write(value, flags & ~this._propagationMask);
1800
+ if (this._propagationMask & LOADING_BIT && !(this._stateFlags & UNINITIALIZED_BIT)) {
1801
+ flags &= ~LOADING_BIT;
1802
+ }
1803
+ this._queue.notify(this, this._propagationMask, flags);
1804
+ return this._value;
1805
+ }
1806
+ };
1807
+ function createBoundChildren(owner, fn, queue, mask) {
1808
+ const parentQueue = owner._queue;
1809
+ parentQueue.addChild(owner._queue = queue);
1810
+ onCleanup(() => parentQueue.removeChild(owner._queue));
1811
+ return compute(
1812
+ owner,
1813
+ () => {
1814
+ const c = new Computation(void 0, fn);
1815
+ return new BoundaryComputation(() => flatten(c.wait()), mask);
1816
+ },
1817
+ null
1818
+ );
1819
+ }
1820
+ var ConditionalQueue = class extends Queue {
1821
+ _disabled;
1822
+ _errorNodes = /* @__PURE__ */ new Set();
1823
+ _pendingNodes = /* @__PURE__ */ new Set();
1824
+ constructor(disabled) {
1825
+ super();
1826
+ this._disabled = disabled;
1827
+ }
1828
+ run(type) {
1829
+ if (!type || this._disabled.read())
1830
+ return;
1831
+ return super.run(type);
1832
+ }
1833
+ notify(node, type, flags) {
1834
+ if (this._disabled.read()) {
1835
+ if (type & LOADING_BIT) {
1836
+ if (flags & LOADING_BIT) {
1837
+ this._pendingNodes.add(node);
1838
+ type &= ~LOADING_BIT;
1839
+ } else if (this._pendingNodes.delete(node))
1840
+ type &= ~LOADING_BIT;
1841
+ }
1842
+ if (type & ERROR_BIT) {
1843
+ if (flags & ERROR_BIT) {
1844
+ this._errorNodes.add(node);
1845
+ type &= ~ERROR_BIT;
1846
+ } else if (this._errorNodes.delete(node))
1847
+ type &= ~ERROR_BIT;
1848
+ }
1849
+ }
1850
+ return type ? super.notify(node, type, flags) : true;
1851
+ }
1852
+ };
1853
+ var CollectionQueue = class extends Queue {
1854
+ _collectionType;
1855
+ _nodes = /* @__PURE__ */ new Set();
1856
+ _disabled = new Computation(false, null, { pureWrite: true });
1857
+ constructor(type) {
1858
+ super();
1859
+ this._collectionType = type;
1860
+ }
1861
+ run(type) {
1862
+ if (!type || this._disabled.read())
1863
+ return;
1864
+ return super.run(type);
1865
+ }
1866
+ notify(node, type, flags) {
1867
+ if (!(type & this._collectionType))
1868
+ return super.notify(node, type, flags);
1869
+ if (flags & this._collectionType) {
1870
+ this._nodes.add(node);
1871
+ if (this._nodes.size === 1)
1872
+ this._disabled.write(true);
1873
+ } else {
1874
+ this._nodes.delete(node);
1875
+ if (this._nodes.size === 0)
1876
+ this._disabled.write(false);
1877
+ }
1878
+ type &= ~this._collectionType;
1879
+ return type ? super.notify(node, type, flags) : true;
1880
+ }
1881
+ };
1882
+ function createBoundary(fn, condition) {
1883
+ const owner = new Owner();
1884
+ const queue = new ConditionalQueue(
1885
+ new Computation(void 0, () => condition() === "hidden" /* HIDDEN */)
1886
+ );
1887
+ const tree = createBoundChildren(owner, fn, queue, 0);
1888
+ new EagerComputation(void 0, () => {
1889
+ const disabled = queue._disabled.read();
1890
+ tree._propagationMask = disabled ? ERROR_BIT | LOADING_BIT : 0;
1891
+ if (!disabled) {
1892
+ queue._pendingNodes.forEach((node) => queue.notify(node, LOADING_BIT, LOADING_BIT));
1893
+ queue._errorNodes.forEach((node) => queue.notify(node, ERROR_BIT, ERROR_BIT));
1894
+ queue._pendingNodes.clear();
1895
+ queue._errorNodes.clear();
1896
+ }
1897
+ });
1898
+ return () => queue._disabled.read() ? void 0 : tree.read();
1899
+ }
1900
+ function createCollectionBoundary(type, fn, fallback) {
1901
+ const owner = new Owner();
1902
+ const queue = new CollectionQueue(type);
1903
+ const tree = createBoundChildren(owner, fn, queue, type);
1904
+ const decision = new Computation(void 0, () => {
1905
+ if (!queue._disabled.read()) {
1906
+ const resolved = tree.read();
1907
+ if (!queue._disabled.read())
1908
+ return resolved;
1909
+ }
1910
+ return fallback(queue);
1911
+ });
1912
+ return decision.read.bind(decision);
1913
+ }
1914
+ function createSuspense(fn, fallback) {
1915
+ return createCollectionBoundary(LOADING_BIT, fn, () => fallback());
1916
+ }
1917
+ function createErrorBoundary(fn, fallback) {
1918
+ return createCollectionBoundary(
1919
+ ERROR_BIT,
1920
+ fn,
1921
+ (queue) => fallback(queue._nodes.values().next().value._error, () => {
1922
+ incrementClock();
1923
+ for (let node of queue._nodes) {
1924
+ node._state = STATE_DIRTY;
1925
+ node._queue?.enqueue(node._type, node._run.bind(node));
1926
+ }
1927
+ })
1928
+ );
1929
+ }
1930
+ function flatten(children, options) {
1931
+ if (typeof children === "function" && !children.length) {
1932
+ if (options?.doNotUnwrap)
1933
+ return children;
1934
+ do {
1935
+ children = children();
1936
+ } while (typeof children === "function" && !children.length);
1937
+ }
1938
+ if (options?.skipNonRendered && (children == null || children === true || children === false || children === ""))
1939
+ return;
1940
+ if (Array.isArray(children)) {
1941
+ let results = [];
1942
+ if (flattenArray(children, results, options)) {
1943
+ return () => {
1944
+ let nested = [];
1945
+ flattenArray(results, nested, { ...options, doNotUnwrap: false });
1946
+ return nested;
1947
+ };
1948
+ }
1949
+ return results;
1950
+ }
1951
+ return children;
1952
+ }
1953
+ function flattenArray(children, results = [], options) {
1954
+ let notReady = null;
1955
+ let needsUnwrap = false;
1956
+ for (let i = 0; i < children.length; i++) {
1957
+ try {
1958
+ let child = children[i];
1959
+ if (typeof child === "function" && !child.length) {
1960
+ if (options?.doNotUnwrap) {
1961
+ results.push(child);
1962
+ needsUnwrap = true;
1963
+ continue;
1964
+ }
1965
+ do {
1966
+ child = child();
1967
+ } while (typeof child === "function" && !child.length);
1968
+ }
1969
+ if (Array.isArray(child)) {
1970
+ needsUnwrap = flattenArray(child, results, options);
1971
+ } else if (options?.skipNonRendered && (child == null || child === true || child === false || child === "")) {
1972
+ } else
1973
+ results.push(child);
1974
+ } catch (e) {
1975
+ if (!(e instanceof NotReadyError))
1976
+ throw e;
1977
+ notReady = e;
1978
+ }
1979
+ }
1980
+ if (notReady)
1981
+ throw notReady;
1982
+ return needsUnwrap;
1983
+ }
1984
+
1985
+ 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 };