@solidjs/signals 0.3.1 → 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,45 +38,41 @@ function schedule() {
47
38
  return;
48
39
  scheduled = true;
49
40
  if (!globalQueue._running)
50
- queueMicrotask(flushSync);
41
+ queueMicrotask(flush);
51
42
  }
43
+ var pureQueue = [];
52
44
  var Queue = class {
53
45
  _parent = null;
54
46
  _running = false;
55
- _queues = [[], [], []];
47
+ _queues = [[], []];
56
48
  _children = [];
57
49
  created = clock;
58
- enqueue(type, node) {
59
- this._queues[0].push(node);
50
+ enqueue(type, fn) {
51
+ pureQueue.push(fn);
60
52
  if (type)
61
- this._queues[type].push(node);
53
+ this._queues[type - 1].push(fn);
62
54
  schedule();
63
55
  }
64
56
  run(type) {
65
- if (this._queues[type].length) {
66
- if (type === EFFECT_PURE) {
67
- runPureQueue(this._queues[type]);
68
- this._queues[type] = [];
69
- } else {
70
- const effects = this._queues[type];
71
- this._queues[type] = [];
72
- runEffectQueue(effects);
73
- }
57
+ if (type === EFFECT_PURE) {
58
+ pureQueue.length && runQueue(pureQueue, type);
59
+ pureQueue = [];
60
+ return;
61
+ } else if (this._queues[type - 1].length) {
62
+ const effects = this._queues[type - 1];
63
+ this._queues[type - 1] = [];
64
+ runQueue(effects, type);
74
65
  }
75
- let rerun = false;
76
66
  for (let i = 0; i < this._children.length; i++) {
77
- rerun = this._children[i].run(type) || rerun;
67
+ this._children[i].run(type);
78
68
  }
79
- if (type === EFFECT_PURE)
80
- return rerun || !!this._queues[type].length;
81
69
  }
82
70
  flush() {
83
71
  if (this._running)
84
72
  return;
85
73
  this._running = true;
86
74
  try {
87
- while (this.run(EFFECT_PURE)) {
88
- }
75
+ this.run(EFFECT_PURE);
89
76
  incrementClock();
90
77
  scheduled = false;
91
78
  this.run(EFFECT_RENDER);
@@ -110,7 +97,7 @@ var Queue = class {
110
97
  }
111
98
  };
112
99
  var globalQueue = new Queue();
113
- function flushSync() {
100
+ function flush() {
114
101
  let count = 0;
115
102
  while (scheduled) {
116
103
  if (++count === 1e5)
@@ -118,52 +105,9 @@ function flushSync() {
118
105
  globalQueue.flush();
119
106
  }
120
107
  }
121
- function runTop(node) {
122
- const ancestors = [];
123
- for (let current = node; current !== null; current = current._parent) {
124
- if (current._state !== STATE_CLEAN) {
125
- ancestors.push(current);
126
- }
127
- }
128
- for (let i = ancestors.length - 1; i >= 0; i--) {
129
- if (ancestors[i]._state !== STATE_DISPOSED)
130
- ancestors[i]._updateIfNecessary();
131
- }
132
- }
133
- function runPureQueue(queue) {
134
- for (let i = 0; i < queue.length; i++) {
135
- if (queue[i]._state !== STATE_CLEAN)
136
- runTop(queue[i]);
137
- }
138
- }
139
- function runEffectQueue(queue) {
108
+ function runQueue(queue, type) {
140
109
  for (let i = 0; i < queue.length; i++)
141
- queue[i]._runEffect();
142
- }
143
-
144
- // src/core/utils.ts
145
- function isUndefined(value) {
146
- return typeof value === "undefined";
147
- }
148
- function tryCatch(fn) {
149
- try {
150
- const v = fn();
151
- if (v instanceof Promise) {
152
- return v.then(
153
- (v2) => [void 0, v2],
154
- (e) => {
155
- if (e instanceof NotReadyError)
156
- throw e;
157
- return [e];
158
- }
159
- );
160
- }
161
- return [void 0, v];
162
- } catch (e) {
163
- if (e instanceof NotReadyError)
164
- throw e;
165
- return [e];
166
- }
110
+ queue[i](type);
167
111
  }
168
112
 
169
113
  // src/core/owner.ts
@@ -177,10 +121,6 @@ function setOwner(owner) {
177
121
  currentOwner = owner;
178
122
  return out;
179
123
  }
180
- function formatId(prefix, id) {
181
- const num = id.toString(36), len = num.length - 1;
182
- return prefix + (len ? String.fromCharCode(64 + len) : "") + num;
183
- }
184
124
  var Owner = class {
185
125
  // We flatten the owner tree into a linked list so that we don't need a pointer to .firstChild
186
126
  // However, the children are actually added in reverse creation order
@@ -197,8 +137,6 @@ var Owner = class {
197
137
  constructor(id = null, skipAppend = false) {
198
138
  this.id = id;
199
139
  if (currentOwner) {
200
- if (!id && currentOwner.id)
201
- this.id = currentOwner.getNextChildId();
202
140
  !skipAppend && currentOwner.append(this);
203
141
  }
204
142
  }
@@ -209,6 +147,8 @@ var Owner = class {
209
147
  this._nextSibling._prevSibling = child;
210
148
  child._nextSibling = this._nextSibling;
211
149
  this._nextSibling = child;
150
+ if (this.id != null && child.id == null)
151
+ child.id = this.getNextChildId();
212
152
  if (child._context !== this._context) {
213
153
  child._context = { ...this._context, ...child._context };
214
154
  }
@@ -257,7 +197,7 @@ var Owner = class {
257
197
  this._disposal = null;
258
198
  }
259
199
  getNextChildId() {
260
- if (this.id)
200
+ if (this.id != null)
261
201
  return formatId(this.id, this._childCount++);
262
202
  throw new Error("Cannot get child id from owner without an id");
263
203
  }
@@ -300,6 +240,13 @@ function onCleanup(fn) {
300
240
  }
301
241
  return fn;
302
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
+ }
303
250
 
304
251
  // src/core/flags.ts
305
252
  var ERROR_OFFSET = 0;
@@ -316,6 +263,7 @@ var currentMask = DEFAULT_FLAGS;
316
263
  var newSources = null;
317
264
  var newSourcesIndex = 0;
318
265
  var newFlags = 0;
266
+ var unobserved = [];
319
267
  var notStale = false;
320
268
  var updateCheck = null;
321
269
  var staleCheck = null;
@@ -335,6 +283,7 @@ var Computation = class extends Owner {
335
283
  // which could enable more efficient DIRTY notification
336
284
  _equals = isEqual;
337
285
  _unobserved;
286
+ _pureWrite = false;
338
287
  /** Whether the computation is an error or has ancestors that are unresolved */
339
288
  _stateFlags = 0;
340
289
  /** Which flags raised by sources are handled, vs. being passed through. */
@@ -342,7 +291,7 @@ var Computation = class extends Owner {
342
291
  _time = -1;
343
292
  _forceNotify = false;
344
293
  constructor(initialValue, compute2, options) {
345
- super(null, compute2 === null);
294
+ super(options?.id, compute2 === null);
346
295
  this._compute = compute2;
347
296
  this._state = compute2 ? STATE_DIRTY : STATE_CLEAN;
348
297
  this._stateFlags = compute2 && initialValue === void 0 ? UNINITIALIZED_BIT : 0;
@@ -350,6 +299,8 @@ var Computation = class extends Owner {
350
299
  this._name = options?.name ?? (this._compute ? "computed" : "signal");
351
300
  if (options?.equals !== void 0)
352
301
  this._equals = options.equals;
302
+ if (options?.pureWrite)
303
+ this._pureWrite = true;
353
304
  if (options?.unobserved)
354
305
  this._unobserved = options?.unobserved;
355
306
  }
@@ -399,8 +350,11 @@ var Computation = class extends Owner {
399
350
  }
400
351
  /** Update the computation with a new value. */
401
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.");
402
355
  const newValue = !raw && typeof value === "function" ? value(this._value) : value;
403
- 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));
404
358
  if (valueChanged) {
405
359
  this._value = newValue;
406
360
  this._error = void 0;
@@ -564,6 +518,7 @@ function update(node) {
564
518
  removeSourceObservers(node, newSourcesIndex);
565
519
  node._sources.length = newSourcesIndex;
566
520
  }
521
+ unobserved.length && notifyUnobserved();
567
522
  newSources = prevSources;
568
523
  newSourcesIndex = prevSourcesIndex;
569
524
  newFlags = prevFlags;
@@ -581,10 +536,18 @@ function removeSourceObservers(node, index) {
581
536
  source._observers[swap] = source._observers[source._observers.length - 1];
582
537
  source._observers.pop();
583
538
  if (!source._observers.length)
584
- source._unobserved?.();
539
+ unobserved.push(source);
585
540
  }
586
541
  }
587
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
+ }
588
551
  function isEqual(a, b) {
589
552
  return a === b;
590
553
  }
@@ -696,68 +659,6 @@ function compute(owner, fn, observer) {
696
659
  notStale = prevNotStale;
697
660
  }
698
661
  }
699
- function flatten(children, options) {
700
- try {
701
- if (typeof children === "function" && !children.length) {
702
- if (options?.doNotUnwrap)
703
- return children;
704
- do {
705
- children = children();
706
- } while (typeof children === "function" && !children.length);
707
- }
708
- if (options?.skipNonRendered && (children == null || children === true || children === false || children === ""))
709
- return;
710
- if (Array.isArray(children)) {
711
- let results = [];
712
- if (flattenArray(children, results, options)) {
713
- return () => {
714
- let nested = [];
715
- flattenArray(results, nested, { ...options, doNotUnwrap: false });
716
- return nested;
717
- };
718
- }
719
- return results;
720
- }
721
- return children;
722
- } catch (e) {
723
- if (options?.skipNonRendered && e instanceof NotReadyError) {
724
- newFlags |= LOADING_BIT;
725
- return void 0;
726
- }
727
- throw e;
728
- }
729
- }
730
- function flattenArray(children, results = [], options) {
731
- let notReady = null;
732
- let needsUnwrap = false;
733
- for (let i = 0; i < children.length; i++) {
734
- try {
735
- let child = children[i];
736
- if (typeof child === "function" && !child.length) {
737
- if (options?.doNotUnwrap) {
738
- results.push(child);
739
- needsUnwrap = true;
740
- continue;
741
- }
742
- do {
743
- child = child();
744
- } while (typeof child === "function" && !child.length);
745
- }
746
- if (Array.isArray(child)) {
747
- needsUnwrap = flattenArray(child, results, options);
748
- } else if (options?.skipNonRendered && (child == null || child === true || child === false || child === "")) {
749
- } else
750
- results.push(child);
751
- } catch (e) {
752
- if (!(e instanceof NotReadyError))
753
- throw e;
754
- notReady = e;
755
- }
756
- }
757
- if (notReady)
758
- throw notReady;
759
- return needsUnwrap;
760
- }
761
662
 
762
663
  // src/core/effect.ts
763
664
  var Effect = class extends Computation {
@@ -777,7 +678,7 @@ var Effect = class extends Computation {
777
678
  this._compute = (p) => getClock() > this._queue.created && !(this._stateFlags & ERROR_BIT) ? latest(() => compute2(p)) : compute2(p);
778
679
  }
779
680
  this._updateIfNecessary();
780
- !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));
781
682
  if (!this._parent)
782
683
  console.warn("Effects created outside a reactive context will never be disposed");
783
684
  }
@@ -799,17 +700,19 @@ var Effect = class extends Computation {
799
700
  if (this._state >= state || skipQueue)
800
701
  return;
801
702
  if (this._state === STATE_CLEAN)
802
- this._queue.enqueue(this._type, this);
703
+ this._queue.enqueue(this._type, this._runEffect.bind(this));
803
704
  this._state = state;
804
705
  }
805
706
  _setError(error) {
806
707
  this._error = error;
807
- this._cleanup?.();
808
708
  this._queue.notify(this, LOADING_BIT, 0);
809
709
  this._stateFlags = ERROR_BIT;
810
710
  if (this._type === EFFECT_USER) {
811
711
  try {
812
- 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);
813
716
  } catch (e) {
814
717
  error = e;
815
718
  }
@@ -827,21 +730,27 @@ var Effect = class extends Computation {
827
730
  this._cleanup = void 0;
828
731
  super._disposeNode();
829
732
  }
830
- _runEffect() {
831
- if (this._modified && this._state !== STATE_DISPOSED) {
832
- this._cleanup?.();
833
- try {
834
- this._cleanup = this._effect(this._value, this._prevValue);
835
- } catch (e) {
836
- if (!this._queue.notify(this, ERROR_BIT, ERROR_BIT))
837
- throw e;
838
- } finally {
839
- this._prevValue = this._value;
840
- 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
+ }
841
746
  }
842
- }
747
+ } else
748
+ this._state !== STATE_CLEAN && runTop(this);
843
749
  }
844
750
  };
751
+ function runComputation() {
752
+ this._state !== STATE_CLEAN && runTop(this);
753
+ }
845
754
  var EagerComputation = class extends Computation {
846
755
  constructor(initialValue, compute2, options) {
847
756
  super(initialValue, compute2, options);
@@ -852,12 +761,13 @@ var EagerComputation = class extends Computation {
852
761
  _notify(state, skipQueue) {
853
762
  if (this._state >= state && !this._forceNotify)
854
763
  return;
855
- if (this._state === STATE_CLEAN && !skipQueue)
856
- this._queue.enqueue(EFFECT_PURE, this);
764
+ if (!skipQueue && (this._state === STATE_CLEAN || this._state === STATE_CHECK && this._forceNotify))
765
+ this._queue.enqueue(EFFECT_PURE, runComputation.bind(this));
857
766
  super._notify(state, skipQueue);
858
767
  }
859
768
  };
860
- var ProjectionComputation = class extends Computation {
769
+ var FirewallComputation = class extends Computation {
770
+ firewall = true;
861
771
  constructor(compute2) {
862
772
  super(void 0, compute2);
863
773
  if (!this._parent)
@@ -867,136 +777,22 @@ var ProjectionComputation = class extends Computation {
867
777
  if (this._state >= state && !this._forceNotify)
868
778
  return;
869
779
  if (!skipQueue && (this._state === STATE_CLEAN || this._state === STATE_CHECK && this._forceNotify))
870
- this._queue.enqueue(EFFECT_PURE, this);
780
+ this._queue.enqueue(EFFECT_PURE, runComputation.bind(this));
871
781
  super._notify(state, true);
872
782
  this._forceNotify = !!skipQueue;
873
783
  }
874
784
  };
875
-
876
- // src/core/boundaries.ts
877
- var BoundaryComputation = class extends EagerComputation {
878
- _propagationMask;
879
- constructor(compute2, propagationMask) {
880
- super(void 0, compute2, { defer: true });
881
- this._propagationMask = propagationMask;
882
- }
883
- write(value, flags) {
884
- super.write(value, flags & ~this._propagationMask);
885
- if (this._propagationMask & LOADING_BIT && !(this._stateFlags & UNINITIALIZED_BIT)) {
886
- flags &= ~LOADING_BIT;
887
- }
888
- this._queue.notify(this, this._propagationMask, flags);
889
- return this._value;
890
- }
891
- };
892
- function createBoundChildren(owner, fn, queue, mask) {
893
- const parentQueue = owner._queue;
894
- parentQueue.addChild(owner._queue = queue);
895
- onCleanup(() => parentQueue.removeChild(owner._queue));
896
- return compute(
897
- owner,
898
- () => {
899
- const c = new Computation(void 0, fn);
900
- return new BoundaryComputation(() => flatten(c.wait()), mask);
901
- },
902
- null
903
- );
904
- }
905
- var ConditionalQueue = class extends Queue {
906
- _disabled;
907
- _errorNodes = /* @__PURE__ */ new Set();
908
- _pendingNodes = /* @__PURE__ */ new Set();
909
- constructor(disabled) {
910
- super();
911
- this._disabled = disabled;
912
- }
913
- run(type) {
914
- if (type && this._disabled.read())
915
- return;
916
- return super.run(type);
917
- }
918
- notify(node, type, flags) {
919
- if (this._disabled.read()) {
920
- if (type === LOADING_BIT) {
921
- flags & LOADING_BIT ? this._pendingNodes.add(node) : this._pendingNodes.delete(node);
922
- }
923
- if (type === ERROR_BIT) {
924
- flags & ERROR_BIT ? this._errorNodes.add(node) : this._errorNodes.delete(node);
925
- }
926
- 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);
927
790
  }
928
- return super.notify(node, type, flags);
929
- }
930
- };
931
- var CollectionQueue = class extends Queue {
932
- _collectionType;
933
- _nodes = /* @__PURE__ */ new Set();
934
- _disabled = new Computation(false, null);
935
- constructor(type) {
936
- super();
937
- this._collectionType = type;
938
791
  }
939
- notify(node, type, flags) {
940
- if (!(type & this._collectionType))
941
- return super.notify(node, type, flags);
942
- if (flags & this._collectionType) {
943
- this._nodes.add(node);
944
- if (this._nodes.size === 1)
945
- this._disabled.write(true);
946
- } else {
947
- this._nodes.delete(node);
948
- if (this._nodes.size === 0)
949
- this._disabled.write(false);
950
- }
951
- type &= ~this._collectionType;
952
- 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();
953
795
  }
954
- };
955
- function createBoundary(fn, condition) {
956
- const owner = new Owner();
957
- const queue = new ConditionalQueue(new Computation(void 0, () => condition() === "hidden" /* HIDDEN */));
958
- const tree = createBoundChildren(owner, fn, queue, 0);
959
- new EagerComputation(void 0, () => {
960
- const disabled = queue._disabled.read();
961
- tree._propagationMask = disabled ? ERROR_BIT | LOADING_BIT : 0;
962
- if (!disabled) {
963
- queue._pendingNodes.forEach((node) => queue.notify(node, LOADING_BIT, LOADING_BIT));
964
- queue._errorNodes.forEach((node) => queue.notify(node, ERROR_BIT, ERROR_BIT));
965
- queue._pendingNodes.clear();
966
- queue._errorNodes.clear();
967
- }
968
- });
969
- return () => queue._disabled.read() ? void 0 : tree.read();
970
- }
971
- function createCollectionBoundary(type, fn, fallback) {
972
- const owner = new Owner();
973
- const queue = new CollectionQueue(type);
974
- const tree = createBoundChildren(owner, fn, queue, type);
975
- const decision = new Computation(void 0, () => {
976
- if (!queue._disabled.read()) {
977
- const resolved = tree.read();
978
- if (!queue._disabled.read())
979
- return resolved;
980
- }
981
- return fallback(queue);
982
- });
983
- return decision.read.bind(decision);
984
- }
985
- function createSuspense(fn, fallback) {
986
- return createCollectionBoundary(LOADING_BIT, fn, () => fallback());
987
- }
988
- function createErrorBoundary(fn, fallback) {
989
- return createCollectionBoundary(
990
- ERROR_BIT,
991
- fn,
992
- (queue) => fallback(queue._nodes.values().next().value._error, () => {
993
- incrementClock();
994
- for (let node of queue._nodes) {
995
- node._state = STATE_DIRTY;
996
- node._queue?.enqueue(node._type, node);
997
- }
998
- })
999
- );
1000
796
  }
1001
797
 
1002
798
  // src/signals.ts
@@ -1012,7 +808,13 @@ function createSignal(first, second, third) {
1012
808
  });
1013
809
  return [() => memo()[0](), (value) => memo()[1](value)];
1014
810
  }
1015
- 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
+ );
1016
818
  return [node.read.bind(node), node.write.bind(node)];
1017
819
  }
1018
820
  function createMemo(compute2, value, options) {
@@ -1038,10 +840,12 @@ function createMemo(compute2, value, options) {
1038
840
  };
1039
841
  }
1040
842
  function createAsync(compute2, value, options) {
843
+ let refreshing = false;
1041
844
  const node = new EagerComputation(
1042
845
  value,
1043
846
  (p) => {
1044
- const source = compute2(p);
847
+ const source = compute2(p, refreshing);
848
+ refreshing = false;
1045
849
  const isPromise = source instanceof Promise;
1046
850
  const iterator = source[Symbol.asyncIterator];
1047
851
  if (!isPromise && !iterator) {
@@ -1081,14 +885,20 @@ function createAsync(compute2, value, options) {
1081
885
  },
1082
886
  options
1083
887
  );
1084
- 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;
1085
895
  }
1086
- function createEffect(compute2, effect, error, value, options) {
896
+ function createEffect(compute2, effect, value, options) {
1087
897
  void new Effect(
1088
898
  value,
1089
899
  compute2,
1090
- effect,
1091
- error,
900
+ effect.effect ? effect.effect : effect,
901
+ effect.error,
1092
902
  { ...options, name: options?.name ?? "effect" }
1093
903
  );
1094
904
  }
@@ -1121,101 +931,97 @@ function resolve(fn) {
1121
931
  });
1122
932
  });
1123
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
+ }
1124
959
 
1125
960
  // src/store/projection.ts
1126
961
  function createProjection(fn, initialValue = {}) {
1127
- const [store] = createStore(fn, initialValue);
1128
- return store;
1129
- }
1130
- function wrapProjection(fn, store, setStore) {
1131
- const node = new ProjectionComputation(() => {
1132
- setStore(fn);
962
+ let wrappedStore;
963
+ const node = new FirewallComputation(() => {
964
+ storeSetter(wrappedStore, fn);
1133
965
  });
1134
- const wrapped = /* @__PURE__ */ new WeakMap();
1135
- return [wrap(store, node, wrapped), setStore];
1136
- }
1137
- function wrap(source, node, wrapped) {
1138
- if (wrapped.has(source))
1139
- return wrapped.get(source);
1140
- const wrap3 = new Proxy(source, {
1141
- get(target, property) {
1142
- node.read();
1143
- const v = target[property];
1144
- return isWrappable(v) ? wrap3(v, node, wrapped) : v;
1145
- },
1146
- set() {
1147
- throw new Error("Projections are readonly");
1148
- },
1149
- deleteProperty() {
1150
- 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);
1151
973
  }
1152
- });
1153
- wrapped.set(source, wrap3);
1154
- 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);
1155
988
  }
1156
989
 
1157
990
  // src/store/store.ts
1158
- var $RAW = Symbol("STORE_RAW" );
1159
991
  var $TRACK = Symbol("STORE_TRACK" );
1160
992
  var $DEEP = Symbol("STORE_DEEP" );
1161
993
  var $TARGET = Symbol("STORE_TARGET" );
1162
994
  var $PROXY = Symbol("STORE_PROXY" );
995
+ var $DELETED = Symbol("STORE_DELETED" );
1163
996
  var PARENTS = /* @__PURE__ */ new WeakMap();
1164
997
  var STORE_VALUE = "v";
998
+ var STORE_OVERRIDE = "o";
1165
999
  var STORE_NODE = "n";
1166
1000
  var STORE_HAS = "h";
1167
- function wrap2(value) {
1168
- let p = value[$PROXY];
1169
- if (!p) {
1170
- let target;
1171
- if (Array.isArray(value)) {
1172
- target = [];
1173
- target.v = value;
1174
- } else
1175
- target = { v: value };
1176
- Object.defineProperty(value, $PROXY, {
1177
- value: p = new Proxy(target, proxyTraps),
1178
- writable: true
1179
- });
1180
- }
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));
1181
1020
  return p;
1182
1021
  }
1183
1022
  function isWrappable(obj) {
1184
1023
  return obj != null && typeof obj === "object" && !Object.isFrozen(obj);
1185
1024
  }
1186
- function unwrap(item, deep2 = true, set) {
1187
- let result, unwrapped, v, prop;
1188
- if (result = item != null && item[$RAW])
1189
- return result;
1190
- if (!deep2)
1191
- return item;
1192
- if (!isWrappable(item) || set?.has(item))
1193
- return item;
1194
- if (!set)
1195
- set = /* @__PURE__ */ new Set();
1196
- set.add(item);
1197
- if (Array.isArray(item)) {
1198
- for (let i = 0, l = item.length; i < l; i++) {
1199
- v = item[i];
1200
- if ((unwrapped = unwrap(v, deep2, set)) !== v)
1201
- item[i] = unwrapped;
1202
- }
1203
- } else {
1204
- if (!deep2)
1205
- return item;
1206
- const keys = Object.keys(item);
1207
- for (let i = 0, l = keys.length; i < l; i++) {
1208
- prop = keys[i];
1209
- const desc = Object.getOwnPropertyDescriptor(item, prop);
1210
- if (desc.get)
1211
- continue;
1212
- v = item[prop];
1213
- if ((unwrapped = unwrap(v, deep2, set)) !== v)
1214
- item[prop] = unwrapped;
1215
- }
1216
- }
1217
- return item;
1218
- }
1219
1025
  function getNodes(target, type) {
1220
1026
  let nodes = target[type];
1221
1027
  if (!nodes)
@@ -1232,31 +1038,38 @@ function getNode(nodes, property, value, equals = isEqual) {
1232
1038
  }
1233
1039
  });
1234
1040
  }
1235
- function proxyDescriptor(target, property) {
1236
- if (property === $PROXY)
1237
- return { value: target[$PROXY], writable: true, configurable: true };
1238
- const desc = Reflect.getOwnPropertyDescriptor(target[STORE_VALUE], property);
1239
- if (!desc || desc.get || !desc.configurable)
1240
- return desc;
1241
- delete desc.value;
1242
- delete desc.writable;
1243
- desc.get = () => target[STORE_VALUE][$PROXY][property];
1244
- return desc;
1245
- }
1246
1041
  function trackSelf(target, symbol = $TRACK) {
1247
1042
  getObserver() && getNode(getNodes(target, STORE_NODE), symbol, void 0, false).read();
1248
1043
  }
1249
- function ownKeys(target) {
1250
- trackSelf(target);
1251
- 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);
1252
1067
  }
1253
1068
  var Writing = null;
1254
- var proxyTraps = {
1069
+ var storeTraps = {
1255
1070
  get(target, property, receiver) {
1256
1071
  if (property === $TARGET)
1257
1072
  return target;
1258
- if (property === $RAW)
1259
- return target[STORE_VALUE];
1260
1073
  if (property === $PROXY)
1261
1074
  return receiver;
1262
1075
  if (property === $TRACK || property === $DEEP) {
@@ -1264,92 +1077,156 @@ var proxyTraps = {
1264
1077
  return receiver;
1265
1078
  }
1266
1079
  const nodes = getNodes(target, STORE_NODE);
1267
- const storeValue = target[STORE_VALUE];
1268
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];
1269
1084
  if (!tracked) {
1270
1085
  const desc = Object.getOwnPropertyDescriptor(storeValue, property);
1271
1086
  if (desc && desc.get)
1272
1087
  return desc.get.call(receiver);
1273
1088
  }
1274
- if (Writing?.has(storeValue)) {
1275
- const value2 = tracked ? tracked._value : storeValue[property];
1276
- return isWrappable(value2) ? (Writing.add(value2[$RAW] || value2), wrap2(value2)) : value2;
1277
- }
1278
- 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);
1279
1100
  if (!tracked) {
1280
- if (typeof value === "function" && !storeValue.hasOwnProperty(property)) {
1101
+ if (!overridden && typeof value === "function" && !storeValue.hasOwnProperty(property)) {
1281
1102
  let proto;
1282
- 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;
1283
1104
  } else if (getObserver()) {
1284
- return getNode(nodes, property, isWrappable(value) ? wrap2(value) : value).read();
1105
+ return getNode(nodes, property, isWrappable(value) ? wrap(value, target) : value).read();
1285
1106
  }
1286
1107
  }
1287
- return isWrappable(value) ? wrap2(value) : value;
1108
+ return isWrappable(value) ? wrap(value, target) : value;
1288
1109
  },
1289
1110
  has(target, property) {
1290
- if (property === $RAW || property === $PROXY || property === $TRACK || property === "__proto__")
1111
+ if (property === $PROXY || property === $TRACK || property === "__proto__")
1291
1112
  return true;
1292
- 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];
1293
1114
  getObserver() && getNode(getNodes(target, STORE_HAS), property, has).read();
1294
1115
  return has;
1295
1116
  },
1296
- set(target, property, value) {
1297
- 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
+ }
1298
1150
  return true;
1299
1151
  },
1300
1152
  deleteProperty(target, property) {
1301
- 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
+ }
1302
1172
  return true;
1303
1173
  },
1304
- ownKeys,
1305
- 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
+ },
1306
1183
  getPrototypeOf(target) {
1307
1184
  return Object.getPrototypeOf(target[STORE_VALUE]);
1308
1185
  }
1309
1186
  };
1310
- function setProperty(state, property, value, deleting = false) {
1311
- const prev = state[property];
1312
- if (!deleting && prev === value)
1313
- return;
1314
- const len = state.length;
1315
- if (deleting)
1316
- delete state[property];
1317
- else
1318
- state[property] = value;
1319
- const wrappable = isWrappable(value);
1320
- if (isWrappable(prev)) {
1321
- const parents = PARENTS.get(prev);
1322
- parents && (parents instanceof Set ? parents.delete(state) : PARENTS.delete(prev));
1323
- }
1324
- if (recursivelyNotify(state) && wrappable)
1325
- recursivelyAddParent(value[$RAW] || value, state);
1326
- const target = state[$PROXY]?.[$TARGET];
1327
- if (!target)
1328
- return;
1329
- if (deleting)
1330
- target[STORE_HAS]?.[property]?.write(false);
1331
- else
1332
- target[STORE_HAS]?.[property]?.write(true);
1333
- const nodes = getNodes(target, STORE_NODE);
1334
- nodes[property]?.write(wrappable ? wrap2(value) : value);
1335
- Array.isArray(state) && state.length !== len && nodes.length?.write(state.length);
1336
- nodes[$TRACK]?.write(void 0);
1337
- }
1338
- function recursivelyNotify(state) {
1339
- 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];
1340
1204
  let notified = false;
1341
- target && (getNodes(target, STORE_NODE)[$DEEP]?.write(void 0), notified = true);
1342
- 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);
1343
1214
  if (!parents)
1344
1215
  return notified;
1345
1216
  if (parents instanceof Set) {
1346
1217
  for (let parent of parents)
1347
- notified = recursivelyNotify(parent) || notified;
1218
+ notified = recursivelyNotify(parent, lookup) || notified;
1348
1219
  } else
1349
- notified = recursivelyNotify(parents) || notified;
1220
+ notified = recursivelyNotify(parents, lookup) || notified;
1350
1221
  return notified;
1351
1222
  }
1352
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
+ }
1353
1230
  if (parent) {
1354
1231
  let parents = PARENTS.get(state);
1355
1232
  if (!parents)
@@ -1364,80 +1241,73 @@ function recursivelyAddParent(state, parent) {
1364
1241
  return;
1365
1242
  }
1366
1243
  if (Array.isArray(state)) {
1367
- for (let i = 0; i < state.length; i++) {
1368
- const item = state[i];
1369
- 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);
1370
1248
  }
1371
1249
  } else {
1372
- const keys = Object.keys(state);
1250
+ const keys = getKeys(state, override);
1373
1251
  for (let i = 0; i < keys.length; i++) {
1374
- const item = state[keys[i]];
1375
- 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);
1376
1255
  }
1377
1256
  }
1378
1257
  }
1379
- function createStore(first, second) {
1380
- const derived = typeof first === "function", store = derived ? second : first;
1381
- const unwrappedStore = unwrap(store);
1382
- let wrappedStore = wrap2(unwrappedStore);
1383
- const setStore = (fn) => {
1384
- const prevWriting = Writing;
1385
- Writing = /* @__PURE__ */ new Set();
1386
- Writing.add(unwrappedStore);
1387
- try {
1388
- fn(wrappedStore);
1389
- } finally {
1390
- Writing.clear();
1391
- Writing = prevWriting;
1392
- }
1393
- };
1394
- if (derived)
1395
- return wrapProjection(first, wrappedStore, setStore);
1396
- return [wrappedStore, setStore];
1397
- }
1398
1258
  function deep(store) {
1399
- recursivelyAddParent(store[$RAW] || store);
1259
+ recursivelyAddParent(store);
1400
1260
  return store[$DEEP];
1401
1261
  }
1402
1262
 
1403
1263
  // src/store/reconcile.ts
1404
- 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) {
1405
1276
  const target = state?.[$TARGET];
1406
1277
  if (!target)
1407
1278
  return;
1408
1279
  const previous = target[STORE_VALUE];
1409
- if (next === previous)
1280
+ const override = target[STORE_OVERRIDE];
1281
+ if (next === previous && !override)
1410
1282
  return;
1411
- Object.defineProperty(next, $PROXY, {
1412
- value: previous[$PROXY],
1413
- writable: true
1414
- });
1415
- previous[$PROXY] = null;
1283
+ (target[STORE_LOOKUP] || storeLookup).set(next, target[$PROXY]);
1416
1284
  target[STORE_VALUE] = next;
1285
+ target[STORE_OVERRIDE] = void 0;
1417
1286
  if (Array.isArray(previous)) {
1418
1287
  let changed = false;
1419
- 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) {
1420
1290
  let i, j, start, end, newEnd, item, newIndicesNext, keyVal;
1421
- 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++) {
1422
- 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);
1423
1293
  }
1424
1294
  const temp = new Array(next.length), newIndices = /* @__PURE__ */ new Map();
1425
- 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--) {
1426
- 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;
1427
1297
  }
1428
1298
  if (start > newEnd || start > end) {
1429
1299
  for (j = start; j <= newEnd; j++) {
1430
1300
  changed = true;
1431
- target[STORE_NODE][j]?.write(wrap2(next[j]));
1301
+ target[STORE_NODE][j]?.write(wrap(next[j], target));
1432
1302
  }
1433
1303
  for (; j < next.length; j++) {
1434
1304
  changed = true;
1435
- const wrapped = wrap2(temp[j]);
1305
+ const wrapped = wrap(temp[j], target);
1436
1306
  target[STORE_NODE][j]?.write(wrapped);
1437
- applyState(next[j], wrapped, keyFn);
1307
+ applyState(next[j], wrapped, keyFn, all);
1438
1308
  }
1439
1309
  changed && target[STORE_NODE][$TRACK]?.write(void 0);
1440
- previous.length !== next.length && target[STORE_NODE].length?.write(next.length);
1310
+ prevLength !== next.length && target[STORE_NODE].length?.write(next.length);
1441
1311
  return;
1442
1312
  }
1443
1313
  newIndicesNext = new Array(newEnd + 1);
@@ -1449,31 +1319,32 @@ function applyState(next, state, keyFn) {
1449
1319
  newIndices.set(keyVal, j);
1450
1320
  }
1451
1321
  for (i = start; i <= end; i++) {
1452
- item = previous[i];
1322
+ item = getOverrideValue(previous, override, i);
1453
1323
  keyVal = item ? keyFn(item) : item;
1454
1324
  j = newIndices.get(keyVal);
1455
1325
  if (j !== void 0 && j !== -1) {
1456
- temp[j] = previous[i];
1326
+ temp[j] = item;
1457
1327
  j = newIndicesNext[j];
1458
1328
  newIndices.set(keyVal, j);
1459
1329
  }
1460
1330
  }
1461
1331
  for (j = start; j < next.length; j++) {
1462
1332
  if (j in temp) {
1463
- const wrapped = wrap2(temp[j]);
1333
+ const wrapped = wrap(temp[j], target);
1464
1334
  target[STORE_NODE][j]?.write(wrapped);
1465
- applyState(next[j], wrapped, keyFn);
1335
+ applyState(next[j], wrapped, keyFn, all);
1466
1336
  } else
1467
- target[STORE_NODE][j]?.write(wrap2(next[j]));
1337
+ target[STORE_NODE][j]?.write(wrap(next[j], target));
1468
1338
  }
1469
1339
  if (start < next.length)
1470
1340
  changed = true;
1471
- } else if (previous.length && next.length) {
1341
+ } else if (prevLength && next.length) {
1472
1342
  for (let i = 0, len = next.length; i < len; i++) {
1473
- 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);
1474
1345
  }
1475
1346
  }
1476
- if (previous.length !== next.length) {
1347
+ if (prevLength !== next.length) {
1477
1348
  changed = true;
1478
1349
  target[STORE_NODE].length?.write(next.length);
1479
1350
  }
@@ -1482,17 +1353,20 @@ function applyState(next, state, keyFn) {
1482
1353
  }
1483
1354
  let nodes = target[STORE_NODE];
1484
1355
  if (nodes) {
1485
- const keys = Object.keys(nodes);
1356
+ const tracked = nodes[$TRACK];
1357
+ const keys = tracked || all ? getAllKeys(previous, override, next) : Object.keys(nodes);
1486
1358
  for (let i = 0, len = keys.length; i < len; i++) {
1487
- const node = nodes[keys[i]];
1488
- const previousValue = unwrap(previous[keys[i]], false);
1489
- 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]);
1490
1363
  if (previousValue === nextValue)
1491
1364
  continue;
1492
- if (!previousValue || !isWrappable(previousValue) || keyFn(previousValue) != null && keyFn(previousValue) !== keyFn(nextValue))
1493
- node.write(isWrappable(nextValue) ? wrap2(nextValue) : nextValue);
1494
- else
1495
- 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);
1496
1370
  }
1497
1371
  }
1498
1372
  if (nodes = target[STORE_HAS]) {
@@ -1502,17 +1376,69 @@ function applyState(next, state, keyFn) {
1502
1376
  }
1503
1377
  }
1504
1378
  }
1505
- function reconcile(value, key) {
1379
+ function reconcile(value, key, all = false) {
1506
1380
  return (state) => {
1507
1381
  const keyFn = typeof key === "string" ? (item) => item[key] : key;
1508
- if (keyFn(value) !== keyFn(state))
1382
+ const eq = keyFn(state);
1383
+ if (eq !== void 0 && keyFn(value) !== keyFn(state))
1509
1384
  throw new Error("Cannot reconcile states with different identity");
1510
- applyState(value, state, keyFn);
1511
- return state;
1385
+ applyState(value, state, keyFn, all);
1512
1386
  };
1513
1387
  }
1514
1388
 
1515
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
+ }
1516
1442
  function trueFn() {
1517
1443
  return true;
1518
1444
  }
@@ -1677,20 +1603,21 @@ function mapArray(list, map, options) {
1677
1603
  _fallback: options?.fallback
1678
1604
  });
1679
1605
  }
1606
+ var pureOptions = { pureWrite: true };
1680
1607
  function updateKeyedMap() {
1681
1608
  const newItems = this._list() || [], newLen = newItems.length;
1682
1609
  newItems[$TRACK];
1683
1610
  runWithOwner(this._owner, () => {
1684
1611
  let i, j, mapper = this._rows ? () => {
1685
- this._rows[j] = new Computation(newItems[j], null);
1686
- 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));
1687
1614
  return this._map(
1688
1615
  Computation.prototype.read.bind(this._rows[j]),
1689
1616
  this._indexes ? Computation.prototype.read.bind(this._indexes[j]) : void 0
1690
1617
  );
1691
1618
  } : this._indexes ? () => {
1692
1619
  const item = newItems[j];
1693
- this._indexes[j] = new Computation(j, null);
1620
+ this._indexes[j] = new Computation(j, null, pureOptions);
1694
1621
  return this._map(() => item, Computation.prototype.read.bind(this._indexes[j]));
1695
1622
  } : () => {
1696
1623
  const item = newItems[j];
@@ -1858,4 +1785,198 @@ function compare(key, a, b) {
1858
1785
  return key ? key(a) === key(b) : true;
1859
1786
  }
1860
1787
 
1861
- 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 };