@solidjs/signals 0.2.5 → 0.3.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
@@ -50,6 +50,7 @@ function schedule() {
50
50
  queueMicrotask(flushSync);
51
51
  }
52
52
  var Queue = class {
53
+ _parent = null;
53
54
  _running = false;
54
55
  _queues = [[], [], []];
55
56
  _children = [];
@@ -75,8 +76,8 @@ var Queue = class {
75
76
  for (let i = 0; i < this._children.length; i++) {
76
77
  rerun = this._children[i].run(type) || rerun;
77
78
  }
78
- if (type === EFFECT_PURE && this._queues[type].length)
79
- return true;
79
+ if (type === EFFECT_PURE)
80
+ return rerun || !!this._queues[type].length;
80
81
  }
81
82
  flush() {
82
83
  if (this._running)
@@ -95,12 +96,18 @@ var Queue = class {
95
96
  }
96
97
  addChild(child) {
97
98
  this._children.push(child);
99
+ child._parent = this;
98
100
  }
99
101
  removeChild(child) {
100
102
  const index = this._children.indexOf(child);
101
103
  if (index >= 0)
102
104
  this._children.splice(index, 1);
103
105
  }
106
+ notify(...args) {
107
+ if (this._parent)
108
+ return this._parent.notify(...args);
109
+ return false;
110
+ }
104
111
  };
105
112
  var globalQueue = new Queue();
106
113
  function flushSync() {
@@ -138,6 +145,26 @@ function runEffectQueue(queue) {
138
145
  function isUndefined(value) {
139
146
  return typeof value === "undefined";
140
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
+ }
167
+ }
141
168
 
142
169
  // src/core/owner.ts
143
170
  var currentOwner = null;
@@ -150,6 +177,10 @@ function setOwner(owner) {
150
177
  currentOwner = owner;
151
178
  return out;
152
179
  }
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
+ }
153
184
  var Owner = class {
154
185
  // We flatten the owner tree into a linked list so that we don't need a pointer to .firstChild
155
186
  // However, the children are actually added in reverse creation order
@@ -160,11 +191,16 @@ var Owner = class {
160
191
  _state = STATE_CLEAN;
161
192
  _disposal = null;
162
193
  _context = defaultContext;
163
- _handlers = null;
164
194
  _queue = globalQueue;
165
- constructor(signal = false) {
166
- if (currentOwner && !signal)
167
- currentOwner.append(this);
195
+ _childCount = 0;
196
+ id = null;
197
+ constructor(id = null, skipAppend = false) {
198
+ this.id = id;
199
+ if (currentOwner) {
200
+ if (!id && currentOwner.id)
201
+ this.id = currentOwner.getNextChildId();
202
+ !skipAppend && currentOwner.append(this);
203
+ }
168
204
  }
169
205
  append(child) {
170
206
  child._parent = this;
@@ -176,9 +212,6 @@ var Owner = class {
176
212
  if (child._context !== this._context) {
177
213
  child._context = { ...this._context, ...child._context };
178
214
  }
179
- if (this._handlers) {
180
- child._handlers = !child._handlers ? this._handlers : [...child._handlers, ...this._handlers];
181
- }
182
215
  if (this._queue)
183
216
  child._queue = this._queue;
184
217
  }
@@ -193,6 +226,7 @@ var Owner = class {
193
226
  current._nextSibling = null;
194
227
  current = next;
195
228
  }
229
+ this._childCount = 0;
196
230
  if (self)
197
231
  this._disposeNode();
198
232
  if (current)
@@ -206,7 +240,6 @@ var Owner = class {
206
240
  this._parent = null;
207
241
  this._prevSibling = null;
208
242
  this._context = defaultContext;
209
- this._handlers = null;
210
243
  this._state = STATE_DISPOSED;
211
244
  this.emptyDisposal();
212
245
  }
@@ -223,20 +256,10 @@ var Owner = class {
223
256
  }
224
257
  this._disposal = null;
225
258
  }
226
- handleError(error) {
227
- if (!this._handlers)
228
- throw error;
229
- let i = 0, len = this._handlers.length;
230
- for (i = 0; i < len; i++) {
231
- try {
232
- this._handlers[i](error, this);
233
- break;
234
- } catch (e) {
235
- error = e;
236
- }
237
- }
238
- if (i === len)
239
- throw error;
259
+ getNextChildId() {
260
+ if (this.id)
261
+ return formatId(this.id, this._childCount++);
262
+ throw new Error("Cannot get child id from owner without an id");
240
263
  }
241
264
  };
242
265
  function createContext(defaultValue, description) {
@@ -316,11 +339,10 @@ var Computation = class extends Owner {
316
339
  _stateFlags = 0;
317
340
  /** Which flags raised by sources are handled, vs. being passed through. */
318
341
  _handlerMask = DEFAULT_FLAGS;
319
- _loading = null;
320
342
  _time = -1;
321
343
  _forceNotify = false;
322
344
  constructor(initialValue, compute2, options) {
323
- super(compute2 === null);
345
+ super(null, compute2 === null);
324
346
  this._compute = compute2;
325
347
  this._state = compute2 ? STATE_DIRTY : STATE_CLEAN;
326
348
  this._stateFlags = compute2 && initialValue === void 0 ? UNINITIALIZED_BIT : 0;
@@ -338,8 +360,7 @@ var Computation = class extends Owner {
338
360
  else
339
361
  this._updateIfNecessary();
340
362
  }
341
- if (!this._compute || this._sources?.length)
342
- track(this);
363
+ track(this);
343
364
  newFlags |= this._stateFlags & ~currentMask;
344
365
  if (this._stateFlags & ERROR_BIT) {
345
366
  throw this._error;
@@ -364,31 +385,22 @@ var Computation = class extends Owner {
364
385
  wait() {
365
386
  if (this._compute && this._stateFlags & ERROR_BIT && this._time <= getClock()) {
366
387
  update(this);
388
+ } else {
389
+ this._updateIfNecessary();
367
390
  }
368
- if ((notStale || this._stateFlags & UNINITIALIZED_BIT) && this.loading()) {
391
+ track(this);
392
+ if ((notStale || this._stateFlags & UNINITIALIZED_BIT) && this._stateFlags & LOADING_BIT) {
369
393
  throw new NotReadyError();
370
394
  }
371
- if (staleCheck && this.loading())
395
+ if (staleCheck && this._stateFlags & LOADING_BIT) {
372
396
  staleCheck._value = true;
373
- return this._read();
374
- }
375
- /**
376
- * Return true if the computation is the value is dependent on an unresolved promise
377
- * Triggers re-execution of the computation when the loading state changes
378
- *
379
- * This is useful especially when effects want to re-execute when a computation's
380
- * loading state changes
381
- */
382
- loading() {
383
- if (this._loading === null) {
384
- this._loading = loadingState(this);
385
397
  }
386
- return this._loading.read();
398
+ return this._read();
387
399
  }
388
400
  /** Update the computation with a new value. */
389
401
  write(value, flags = 0, raw = false) {
390
402
  const newValue = !raw && typeof value === "function" ? value(this._value) : value;
391
- const valueChanged = newValue !== UNCHANGED && (!!(this._stateFlags & UNINITIALIZED_BIT) || this._equals === false || !this._equals(this._value, newValue));
403
+ const valueChanged = newValue !== UNCHANGED && (!!(this._stateFlags & UNINITIALIZED_BIT) || this._stateFlags & LOADING_BIT & ~flags || this._equals === false || !this._equals(this._value, newValue));
392
404
  if (valueChanged) {
393
405
  this._value = newValue;
394
406
  this._error = void 0;
@@ -461,8 +473,11 @@ var Computation = class extends Owner {
461
473
  * This function will ensure that the value and states we read from the computation are up to date
462
474
  */
463
475
  _updateIfNecessary() {
476
+ if (!this._compute) {
477
+ return;
478
+ }
464
479
  if (this._state === STATE_DISPOSED) {
465
- throw new Error("Tried to read a disposed computation");
480
+ return;
466
481
  }
467
482
  if (this._state === STATE_CLEAN) {
468
483
  return;
@@ -495,22 +510,6 @@ var Computation = class extends Owner {
495
510
  super._disposeNode();
496
511
  }
497
512
  };
498
- function loadingState(node) {
499
- const prevOwner = setOwner(node._parent);
500
- const options = { name: node._name ? `loading ${node._name}` : "loading" } ;
501
- const computation = new Computation(
502
- void 0,
503
- () => {
504
- track(node);
505
- node._updateIfNecessary();
506
- return !!(node._stateFlags & LOADING_BIT);
507
- },
508
- options
509
- );
510
- computation._handlerMask = ERROR_BIT | LOADING_BIT;
511
- setOwner(prevOwner);
512
- return computation;
513
- }
514
513
  function track(computation) {
515
514
  if (currentObserver) {
516
515
  if (!newSources && currentObserver._sources && currentObserver._sources[newSourcesIndex] === computation) {
@@ -604,8 +603,7 @@ function hasUpdated(fn) {
604
603
  updateCheck = current;
605
604
  }
606
605
  }
607
- function isPending(fn, loadingValue) {
608
- const argLength = arguments.length;
606
+ function pendingCheck(fn, loadingValue) {
609
607
  const current = staleCheck;
610
608
  staleCheck = { _value: false };
611
609
  try {
@@ -614,13 +612,20 @@ function isPending(fn, loadingValue) {
614
612
  } catch (err) {
615
613
  if (!(err instanceof NotReadyError))
616
614
  return false;
617
- if (argLength > 1)
615
+ if (loadingValue !== void 0)
618
616
  return loadingValue;
619
617
  throw err;
620
618
  } finally {
621
619
  staleCheck = current;
622
620
  }
623
621
  }
622
+ function isPending(fn, loadingValue) {
623
+ if (!currentObserver)
624
+ return pendingCheck(fn, loadingValue);
625
+ const c = new Computation(void 0, () => pendingCheck(fn, loadingValue));
626
+ c._handlerMask |= LOADING_BIT;
627
+ return c.read();
628
+ }
624
629
  function latest(fn, fallback) {
625
630
  const argLength = arguments.length;
626
631
  const prevFlags = newFlags;
@@ -637,15 +642,6 @@ function latest(fn, fallback) {
637
642
  notStale = prevNotStale;
638
643
  }
639
644
  }
640
- function catchError(fn) {
641
- try {
642
- fn();
643
- } catch (e) {
644
- if (e instanceof NotReadyError)
645
- throw e;
646
- return e;
647
- }
648
- }
649
645
  function runWithObserver(observer, run) {
650
646
  const prevSources = newSources, prevSourcesIndex = newSourcesIndex, prevFlags = newFlags;
651
647
  newSources = null;
@@ -762,13 +758,6 @@ function flattenArray(children, results = [], options) {
762
758
  throw notReady;
763
759
  return needsUnwrap;
764
760
  }
765
- function createBoundary(fn, queue) {
766
- const owner = new Owner();
767
- const parentQueue = owner._queue;
768
- parentQueue.addChild(owner._queue = queue);
769
- onCleanup(() => parentQueue.removeChild(owner._queue));
770
- return compute(owner, fn, null);
771
- }
772
761
 
773
762
  // src/core/effect.ts
774
763
  var Effect = class extends Computation {
@@ -794,10 +783,10 @@ var Effect = class extends Computation {
794
783
  }
795
784
  write(value, flags = 0) {
796
785
  if (this._state == STATE_DIRTY) {
797
- const currentFlags = this._stateFlags;
786
+ this._stateFlags;
798
787
  this._stateFlags = flags;
799
- if (this._type === EFFECT_RENDER && (flags & LOADING_BIT) !== (currentFlags & LOADING_BIT)) {
800
- this._queue._update?.(this);
788
+ if (this._type === EFFECT_RENDER) {
789
+ this._queue.notify(this, LOADING_BIT | ERROR_BIT, flags);
801
790
  }
802
791
  }
803
792
  if (value === UNCHANGED)
@@ -814,10 +803,9 @@ var Effect = class extends Computation {
814
803
  this._state = state;
815
804
  }
816
805
  _setError(error) {
806
+ this._error = error;
817
807
  this._cleanup?.();
818
- if (this._stateFlags & LOADING_BIT) {
819
- this._queue._update?.(this);
820
- }
808
+ this._queue.notify(this, LOADING_BIT, 0);
821
809
  this._stateFlags = ERROR_BIT;
822
810
  if (this._type === EFFECT_USER) {
823
811
  try {
@@ -826,7 +814,8 @@ var Effect = class extends Computation {
826
814
  error = e;
827
815
  }
828
816
  }
829
- this.handleError(error);
817
+ if (!this._queue.notify(this, ERROR_BIT, ERROR_BIT))
818
+ throw error;
830
819
  }
831
820
  _disposeNode() {
832
821
  if (this._state === STATE_DISPOSED)
@@ -844,7 +833,8 @@ var Effect = class extends Computation {
844
833
  try {
845
834
  this._cleanup = this._effect(this._value, this._prevValue);
846
835
  } catch (e) {
847
- this.handleError(e);
836
+ if (!this._queue.notify(this, ERROR_BIT, ERROR_BIT))
837
+ throw e;
848
838
  } finally {
849
839
  this._prevValue = this._value;
850
840
  this._modified = false;
@@ -869,65 +859,144 @@ var EagerComputation = class extends Computation {
869
859
  };
870
860
  var ProjectionComputation = class extends Computation {
871
861
  constructor(compute2) {
872
- super(null, compute2);
862
+ super(void 0, compute2);
873
863
  if (!this._parent)
874
864
  console.warn("Eager Computations created outside a reactive context will never be disposed");
875
865
  }
876
866
  _notify(state, skipQueue) {
877
867
  if (this._state >= state && !this._forceNotify)
878
868
  return;
879
- if (this._state === STATE_CLEAN && !skipQueue)
869
+ if (!skipQueue && (this._state === STATE_CLEAN || this._state === STATE_CHECK && this._forceNotify))
880
870
  this._queue.enqueue(EFFECT_PURE, this);
881
871
  super._notify(state, true);
872
+ this._forceNotify = !!skipQueue;
882
873
  }
883
874
  };
884
875
 
885
- // src/core/suspense.ts
886
- var SuspenseQueue = class extends Queue {
887
- _nodes = /* @__PURE__ */ new Set();
888
- _fallback = false;
889
- _signal = new Computation(false, null);
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
+ }
890
913
  run(type) {
891
- if (type && this._fallback)
914
+ if (type && this._disabled.read())
892
915
  return;
893
916
  return super.run(type);
894
917
  }
895
- _update(node) {
896
- if (node._stateFlags & LOADING_BIT) {
897
- this._nodes.add(node);
898
- if (!this._fallback) {
899
- this._fallback = true;
900
- this._signal.write(true);
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);
901
922
  }
902
- } else {
903
- this._nodes.delete(node);
904
- if (this._nodes.size === 0) {
905
- this._fallback = false;
906
- this._signal.write(false);
923
+ if (type === ERROR_BIT) {
924
+ flags & ERROR_BIT ? this._errorNodes.add(node) : this._errorNodes.delete(node);
907
925
  }
926
+ return true;
908
927
  }
928
+ return super.notify(node, type, flags);
909
929
  }
910
930
  };
911
- var LiveComputation = class extends EagerComputation {
912
- write(value, flags = 0) {
913
- const currentFlags = this._stateFlags;
914
- const dirty = this._state === STATE_DIRTY;
915
- super.write(value, flags);
916
- if (dirty && (flags & LOADING_BIT) !== (currentFlags & LOADING_BIT)) {
917
- this._queue._update?.(this);
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
+ }
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);
918
950
  }
919
- return this._value;
951
+ type &= ~this._collectionType;
952
+ return type ? super.notify(node, type, flags) : true;
920
953
  }
921
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
+ }
922
985
  function createSuspense(fn, fallback) {
923
- const queue = new SuspenseQueue();
924
- const tree = createBoundary(() => {
925
- const child = new Computation(null, fn);
926
- return new LiveComputation(null, () => flatten(child.wait()));
927
- }, queue);
928
- const equality = new Computation(null, () => queue._signal.read() || queue._fallback);
929
- const comp = new Computation(null, () => equality.read() ? fallback() : tree.read());
930
- return comp.read.bind(comp);
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
+ );
931
1000
  }
932
1001
 
933
1002
  // src/signals.ts
@@ -955,77 +1024,64 @@ function createMemo(compute2, value, options) {
955
1024
  let resolvedValue;
956
1025
  return () => {
957
1026
  if (node) {
1027
+ if (node._state === STATE_DISPOSED) {
1028
+ node = void 0;
1029
+ return resolvedValue;
1030
+ }
958
1031
  resolvedValue = node.wait();
959
1032
  if (!node._sources?.length && node._nextSibling?._parent !== node) {
960
1033
  node.dispose();
961
1034
  node = void 0;
962
- } else if (!node._parent && !node._observers?.length) {
963
- node.dispose();
964
- node._state = STATE_DIRTY;
965
1035
  }
966
1036
  }
967
1037
  return resolvedValue;
968
1038
  };
969
1039
  }
970
1040
  function createAsync(compute2, value, options) {
971
- let uninitialized = value === void 0;
972
- const lhs = new EagerComputation(
973
- {
974
- _value: value
975
- },
1041
+ const node = new EagerComputation(
1042
+ value,
976
1043
  (p) => {
977
- const value2 = p?._value;
978
- const source = compute2(value2);
1044
+ const source = compute2(p);
979
1045
  const isPromise = source instanceof Promise;
980
1046
  const iterator = source[Symbol.asyncIterator];
981
1047
  if (!isPromise && !iterator) {
982
- return {
983
- wait() {
984
- return source;
985
- },
986
- _value: source
987
- };
1048
+ return source;
988
1049
  }
989
- const signal = new Computation(value2, null, iterator ? { ...options, equals: false } : options);
990
- const w = signal.wait;
991
- signal.wait = function() {
992
- if (signal._stateFlags & ERROR_BIT && signal._time <= getClock()) {
993
- lhs._notify(STATE_DIRTY);
994
- throw new NotReadyError();
995
- }
996
- return w.call(this);
997
- };
998
- signal.write(UNCHANGED, LOADING_BIT | (uninitialized ? UNINITIALIZED_BIT : 0));
1050
+ let abort = false;
1051
+ onCleanup(() => abort = true);
999
1052
  if (isPromise) {
1000
1053
  source.then(
1001
1054
  (value3) => {
1002
- uninitialized = false;
1003
- signal.write(value3, 0, true);
1055
+ if (abort)
1056
+ return;
1057
+ node.write(value3, 0, true);
1004
1058
  },
1005
1059
  (error) => {
1006
- uninitialized = true;
1007
- signal._setError(error);
1060
+ if (abort)
1061
+ return;
1062
+ node._setError(error);
1008
1063
  }
1009
1064
  );
1010
1065
  } else {
1011
- let abort = false;
1012
- onCleanup(() => abort = true);
1013
1066
  (async () => {
1014
1067
  try {
1015
1068
  for await (let value3 of source) {
1016
1069
  if (abort)
1017
1070
  return;
1018
- signal.write(value3, 0, true);
1071
+ node.write(value3, 0, true);
1019
1072
  }
1020
1073
  } catch (error) {
1021
- signal.write(error, ERROR_BIT);
1074
+ if (abort)
1075
+ return;
1076
+ node.write(error, ERROR_BIT);
1022
1077
  }
1023
1078
  })();
1024
1079
  }
1025
- return signal;
1026
- }
1080
+ throw new NotReadyError();
1081
+ },
1082
+ options
1027
1083
  );
1028
- return () => lhs.wait().wait();
1084
+ return node.wait.bind(node);
1029
1085
  }
1030
1086
  function createEffect(compute2, effect, error, value, options) {
1031
1087
  void new Effect(
@@ -1042,62 +1098,13 @@ function createRenderEffect(compute2, effect, value, options) {
1042
1098
  ...{ ...options, name: options?.name ?? "effect" }
1043
1099
  });
1044
1100
  }
1045
- function createRoot(init) {
1046
- const owner = new Owner();
1101
+ function createRoot(init, options) {
1102
+ const owner = new Owner(options?.id);
1047
1103
  return compute(owner, !init.length ? init : () => init(() => owner.dispose()), null);
1048
1104
  }
1049
1105
  function runWithOwner(owner, run) {
1050
1106
  return compute(owner, run, null);
1051
1107
  }
1052
- function createErrorBoundary(fn, fallback) {
1053
- const owner = new Owner();
1054
- const error = new Computation(void 0, null);
1055
- const nodes = /* @__PURE__ */ new Set();
1056
- function handler(err, node) {
1057
- if (nodes.has(node))
1058
- return;
1059
- compute(
1060
- node,
1061
- () => onCleanup(() => {
1062
- nodes.delete(node);
1063
- if (!nodes.size)
1064
- error.write(void 0);
1065
- }),
1066
- null
1067
- );
1068
- nodes.add(node);
1069
- if (nodes.size === 1)
1070
- error.write({ _error: err });
1071
- }
1072
- owner._handlers = owner._handlers ? [handler, ...owner._handlers] : [handler];
1073
- const guarded = compute(
1074
- owner,
1075
- () => {
1076
- const c = new Computation(void 0, fn);
1077
- const f = new EagerComputation(void 0, () => flatten(c.read()), { defer: true });
1078
- f._setError = function(error2) {
1079
- this.handleError(error2);
1080
- };
1081
- return f;
1082
- },
1083
- null
1084
- );
1085
- const decision = new Computation(null, () => {
1086
- if (!error.read()) {
1087
- const resolved = guarded.read();
1088
- if (!error.read())
1089
- return resolved;
1090
- }
1091
- return fallback(error.read()._error, () => {
1092
- incrementClock();
1093
- for (let node of nodes) {
1094
- node._state = STATE_DIRTY;
1095
- node._queue?.enqueue(node._type, node);
1096
- }
1097
- });
1098
- });
1099
- return decision.read.bind(decision);
1100
- }
1101
1108
  function resolve(fn) {
1102
1109
  return new Promise((res, rej) => {
1103
1110
  createRoot((dispose) => {
@@ -1243,7 +1250,7 @@ function ownKeys(target) {
1243
1250
  trackSelf(target);
1244
1251
  return Reflect.ownKeys(target[STORE_VALUE]);
1245
1252
  }
1246
- var Writing = /* @__PURE__ */ new Set();
1253
+ var Writing = null;
1247
1254
  var proxyTraps = {
1248
1255
  get(target, property, receiver) {
1249
1256
  if (property === $TARGET)
@@ -1264,7 +1271,7 @@ var proxyTraps = {
1264
1271
  if (desc && desc.get)
1265
1272
  return desc.get.call(receiver);
1266
1273
  }
1267
- if (Writing.has(storeValue)) {
1274
+ if (Writing?.has(storeValue)) {
1268
1275
  const value2 = tracked ? tracked._value : storeValue[property];
1269
1276
  return isWrappable(value2) ? (Writing.add(value2[$RAW] || value2), wrap2(value2)) : value2;
1270
1277
  }
@@ -1287,11 +1294,11 @@ var proxyTraps = {
1287
1294
  return has;
1288
1295
  },
1289
1296
  set(target, property, value) {
1290
- Writing.has(target[STORE_VALUE]) && setProperty(target[STORE_VALUE], property, unwrap(value, false));
1297
+ Writing?.has(target[STORE_VALUE]) && setProperty(target[STORE_VALUE], property, unwrap(value, false));
1291
1298
  return true;
1292
1299
  },
1293
1300
  deleteProperty(target, property) {
1294
- Writing.has(target[STORE_VALUE]) && setProperty(target[STORE_VALUE], property, void 0, true);
1301
+ Writing?.has(target[STORE_VALUE]) && setProperty(target[STORE_VALUE], property, void 0, true);
1295
1302
  return true;
1296
1303
  },
1297
1304
  ownKeys,
@@ -1374,11 +1381,14 @@ function createStore(first, second) {
1374
1381
  const unwrappedStore = unwrap(store);
1375
1382
  let wrappedStore = wrap2(unwrappedStore);
1376
1383
  const setStore = (fn) => {
1384
+ const prevWriting = Writing;
1385
+ Writing = /* @__PURE__ */ new Set();
1386
+ Writing.add(unwrappedStore);
1377
1387
  try {
1378
- Writing.add(unwrappedStore);
1379
1388
  fn(wrappedStore);
1380
1389
  } finally {
1381
1390
  Writing.clear();
1391
+ Writing = prevWriting;
1382
1392
  }
1383
1393
  };
1384
1394
  if (derived)
@@ -1848,4 +1858,4 @@ function compare(key, a, b) {
1848
1858
  return key ? key(a) === key(b) : true;
1849
1859
  }
1850
1860
 
1851
- export { $PROXY, $RAW, $TARGET, $TRACK, Computation, ContextNotFoundError, NoOwnerError, NotReadyError, Owner, Queue, SUPPORTS_PROXY, catchError, 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, untrack, unwrap };
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 };