@solidjs/signals 0.0.3 → 0.0.5

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
@@ -3,34 +3,87 @@ var NotReadyError = class extends Error {
3
3
  };
4
4
  var NoOwnerError = class extends Error {
5
5
  constructor() {
6
- super(
7
- "No root owner exists at time of call. Make sure `getContext` is called within an owner or create one first via `createRoot`."
8
- );
6
+ super("Context can only be accessed under a reactive root." );
9
7
  }
10
8
  };
11
9
  var ContextNotFoundError = class extends Error {
12
10
  constructor() {
13
11
  super(
14
- "Must provide either a default context value or set one via `setContext` before getting."
12
+ "Context must either be created with a default value or a value must be provided before accessing it."
15
13
  );
16
14
  }
17
15
  };
18
16
 
19
- // src/utils.ts
20
- function isUndefined(value) {
21
- return typeof value === "undefined";
22
- }
23
-
24
17
  // src/core/constants.ts
25
18
  var STATE_CLEAN = 0;
26
19
  var STATE_CHECK = 1;
27
20
  var STATE_DIRTY = 2;
28
- var STATE_DISPOSED = 3;
21
+ var STATE_UNINITIALIZED = 3;
22
+ var STATE_DISPOSED = 4;
29
23
  var EFFECT_PURE = 0;
30
24
  var EFFECT_RENDER = 1;
31
25
  var EFFECT_USER = 2;
32
26
  var SUPPORTS_PROXY = typeof Proxy === "function";
33
27
 
28
+ // src/core/utils.ts
29
+ function isUndefined(value) {
30
+ return typeof value === "undefined";
31
+ }
32
+ function flatten(children, options) {
33
+ if (typeof children === "function" && !children.length) {
34
+ if (options?.doNotUnwrap)
35
+ return children;
36
+ do {
37
+ children = children();
38
+ } while (typeof children === "function" && !children.length);
39
+ }
40
+ if (options?.skipNonRendered && (children == null || children === true || children === false || children === ""))
41
+ return;
42
+ if (Array.isArray(children)) {
43
+ let results = [];
44
+ if (flattenArray(children, results, options)) {
45
+ return () => {
46
+ let nested = [];
47
+ flattenArray(results, nested, { ...options, doNotUnwrap: false });
48
+ return nested;
49
+ };
50
+ }
51
+ return results;
52
+ }
53
+ return children;
54
+ }
55
+ function flattenArray(children, results = [], options) {
56
+ let notReady = null;
57
+ let needsUnwrap = false;
58
+ for (let i = 0; i < children.length; i++) {
59
+ try {
60
+ let child = children[i];
61
+ if (typeof child === "function" && !child.length) {
62
+ if (options?.doNotUnwrap) {
63
+ results.push(child);
64
+ needsUnwrap = true;
65
+ continue;
66
+ }
67
+ do {
68
+ child = child();
69
+ } while (typeof child === "function" && !child.length);
70
+ }
71
+ if (Array.isArray(child)) {
72
+ needsUnwrap = flattenArray(child, results, options);
73
+ } else if (options?.skipNonRendered && (child == null || child === true || child === false || child === "")) {
74
+ } else
75
+ results.push(child);
76
+ } catch (e) {
77
+ if (!(e instanceof NotReadyError))
78
+ throw e;
79
+ notReady = e;
80
+ }
81
+ }
82
+ if (notReady)
83
+ throw notReady;
84
+ return needsUnwrap;
85
+ }
86
+
34
87
  // src/core/owner.ts
35
88
  var currentOwner = null;
36
89
  var defaultContext = {};
@@ -156,17 +209,18 @@ function setContext(context, value, owner = currentOwner) {
156
209
  function hasContext(context, owner = currentOwner) {
157
210
  return !isUndefined(owner?._context[context.id]);
158
211
  }
159
- function onCleanup(disposable) {
212
+ function onCleanup(fn) {
160
213
  if (!currentOwner)
161
- return;
214
+ return fn;
162
215
  const node = currentOwner;
163
216
  if (!node._disposal) {
164
- node._disposal = disposable;
217
+ node._disposal = fn;
165
218
  } else if (Array.isArray(node._disposal)) {
166
- node._disposal.push(disposable);
219
+ node._disposal.push(fn);
167
220
  } else {
168
- node._disposal = [node._disposal, disposable];
221
+ node._disposal = [node._disposal, fn];
169
222
  }
223
+ return fn;
170
224
  }
171
225
 
172
226
  // src/core/flags.ts
@@ -213,7 +267,7 @@ var Computation = class extends Owner {
213
267
  constructor(initialValue, compute2, options) {
214
268
  super(compute2 === null);
215
269
  this._compute = compute2;
216
- this._state = compute2 ? STATE_DIRTY : STATE_CLEAN;
270
+ this._state = compute2 ? STATE_UNINITIALIZED : STATE_CLEAN;
217
271
  this._value = initialValue;
218
272
  this._name = options?.name ?? (this._compute ? "computed" : "signal");
219
273
  if (options?.equals !== void 0)
@@ -224,7 +278,7 @@ var Computation = class extends Owner {
224
278
  _read() {
225
279
  if (this._compute)
226
280
  this._updateIfNecessary();
227
- if (!this._sources || this._sources.length)
281
+ if (!this._compute || this._sources?.length)
228
282
  track(this);
229
283
  newFlags |= this._stateFlags & ~currentMask;
230
284
  if (this._stateFlags & ERROR_BIT) {
@@ -279,7 +333,7 @@ var Computation = class extends Owner {
279
333
  /** Update the computation with a new value. */
280
334
  write(value, flags = 0, raw = false) {
281
335
  const newValue = !raw && typeof value === "function" ? value(this._value) : value;
282
- const valueChanged = newValue !== UNCHANGED && (!!(flags & ERROR_BIT) || this._equals === false || !this._equals(this._value, newValue));
336
+ const valueChanged = newValue !== UNCHANGED && (!!(flags & ERROR_BIT) || this._state === STATE_UNINITIALIZED || this._equals === false || !this._equals(this._value, newValue));
283
337
  if (valueChanged)
284
338
  this._value = newValue;
285
339
  const changedFlagsMask = this._stateFlags ^ flags, changedFlags = changedFlagsMask & flags;
@@ -364,7 +418,7 @@ var Computation = class extends Owner {
364
418
  }
365
419
  }
366
420
  }
367
- if (this._state === STATE_DIRTY) {
421
+ if (this._state === STATE_DIRTY || this._state === STATE_UNINITIALIZED) {
368
422
  update(this);
369
423
  } else {
370
424
  this.write(UNCHANGED, observerFlags);
@@ -544,7 +598,8 @@ function schedule() {
544
598
  if (scheduled)
545
599
  return;
546
600
  scheduled = true;
547
- queueMicrotask(flushSync);
601
+ if (!globalQueue._running)
602
+ queueMicrotask(flushSync);
548
603
  }
549
604
  var Queue = class {
550
605
  _running = false;
@@ -578,6 +633,7 @@ var Queue = class {
578
633
  try {
579
634
  this.run(EFFECT_PURE);
580
635
  incrementClock();
636
+ scheduled = false;
581
637
  this.run(EFFECT_RENDER);
582
638
  this.run(EFFECT_USER);
583
639
  } finally {
@@ -594,9 +650,21 @@ var Queue = class {
594
650
  }
595
651
  };
596
652
  var globalQueue = new Queue();
653
+ var globalTasks = [];
597
654
  function flushSync() {
598
- globalQueue.flush();
599
- scheduled = false;
655
+ let count = 0;
656
+ while (scheduled) {
657
+ if (++count === 1e5)
658
+ throw new Error("Potential Infinite Loop Detected.");
659
+ globalQueue.flush();
660
+ for (let i = 0; i < globalTasks.length; i++)
661
+ globalTasks[i]();
662
+ globalTasks.length = 0;
663
+ }
664
+ }
665
+ function queueTask(fn) {
666
+ globalTasks.push(fn);
667
+ schedule();
600
668
  }
601
669
  function createBoundary(fn, queue) {
602
670
  const owner = new Owner();
@@ -643,11 +711,13 @@ var Effect = class extends Computation {
643
711
  this._queue = getOwner()?._queue || globalQueue;
644
712
  this._updateIfNecessary();
645
713
  this._type === EFFECT_USER ? this._queue.enqueue(this._type, this) : this._runEffect();
714
+ if (!this._parent)
715
+ console.warn("Effects created outside a reactive context will never be disposed");
646
716
  }
647
717
  write(value, flags = 0) {
648
718
  const currentFlags = this._stateFlags;
649
719
  this._stateFlags = flags;
650
- if ((flags & LOADING_BIT) !== (currentFlags & LOADING_BIT)) {
720
+ if (this._type === EFFECT_RENDER && (flags & LOADING_BIT) !== (currentFlags & LOADING_BIT)) {
651
721
  this._queue._update?.(this);
652
722
  }
653
723
  if (value === UNCHANGED)
@@ -685,6 +755,8 @@ var EagerComputation = class extends Computation {
685
755
  super(initialValue, compute2, options);
686
756
  this._queue = getOwner()?._queue || globalQueue;
687
757
  this._updateIfNecessary();
758
+ if (!this._parent)
759
+ console.warn("Eager Computations created outside a reactive context will never be disposed");
688
760
  }
689
761
  _notify(state) {
690
762
  if (this._state >= state)
@@ -710,22 +782,35 @@ var SuspenseQueue = class extends Queue {
710
782
  this._nodes.add(node);
711
783
  if (!this._fallback) {
712
784
  this._fallback = true;
713
- queueMicrotask(() => this._signal.write(true));
785
+ queueTask(() => this._signal.write(true));
714
786
  }
715
787
  } else {
716
788
  this._nodes.delete(node);
717
789
  if (this._nodes.size === 0) {
718
790
  this._fallback = false;
719
- queueMicrotask(() => this._signal.write(false));
791
+ queueTask(() => this._signal.write(false));
720
792
  }
721
793
  }
722
794
  }
723
795
  };
796
+ var LiveComputation = class extends EagerComputation {
797
+ write(value, flags = 0) {
798
+ const currentFlags = this._stateFlags;
799
+ super.write(value, flags);
800
+ if ((flags & LOADING_BIT) !== (currentFlags & LOADING_BIT)) {
801
+ this._queue._update?.(this);
802
+ }
803
+ return this._value;
804
+ }
805
+ };
724
806
  function createSuspense(fn, fallbackFn) {
725
807
  const queue = new SuspenseQueue();
726
- const tree = createBoundary(fn, queue);
808
+ const tree = createBoundary(() => {
809
+ const child = new Computation(null, fn);
810
+ return new LiveComputation(null, () => flatten(child.wait()));
811
+ }, queue);
727
812
  const equality = new Computation(null, () => queue._signal.read() || queue._fallback);
728
- const comp = new Computation(null, () => equality.read() ? untrack(fallbackFn) : tree);
813
+ const comp = new Computation(null, () => equality.read() ? untrack(fallbackFn) : tree.read());
729
814
  return comp.read.bind(comp);
730
815
  }
731
816
 
@@ -745,14 +830,35 @@ function createSignal(first, second, third) {
745
830
  const node = new Computation(first, null, second);
746
831
  return [node.read.bind(node), node.write.bind(node)];
747
832
  }
748
- function createAsync(fn, initial, options) {
833
+ function createMemo(compute2, value, options) {
834
+ let node = new Computation(
835
+ value,
836
+ compute2,
837
+ options
838
+ );
839
+ let resolvedValue;
840
+ return () => {
841
+ if (node) {
842
+ resolvedValue = node.wait();
843
+ if (!node._sources?.length && node._nextSibling?._parent !== node) {
844
+ node.dispose();
845
+ node = void 0;
846
+ } else if (!node._parent && !node._observers?.length) {
847
+ node.dispose();
848
+ node._state = STATE_UNINITIALIZED;
849
+ }
850
+ }
851
+ return resolvedValue;
852
+ };
853
+ }
854
+ function createAsync(compute2, value, options) {
749
855
  const lhs = new EagerComputation(
750
856
  {
751
- _value: initial
857
+ _value: value
752
858
  },
753
859
  (p) => {
754
- const value = p?._value;
755
- const source = fn(value);
860
+ const value2 = p?._value;
861
+ const source = compute2(value2);
756
862
  const isPromise = source instanceof Promise;
757
863
  const iterator = source[Symbol.asyncIterator];
758
864
  if (!isPromise && !iterator) {
@@ -763,12 +869,12 @@ function createAsync(fn, initial, options) {
763
869
  _value: source
764
870
  };
765
871
  }
766
- const signal = new Computation(value, null, options);
872
+ const signal = new Computation(value2, null, options);
767
873
  signal.write(UNCHANGED, LOADING_BIT);
768
874
  if (isPromise) {
769
875
  source.then(
770
- (value2) => {
771
- signal.write(value2, 0);
876
+ (value3) => {
877
+ signal.write(value3, 0, true);
772
878
  },
773
879
  (error) => {
774
880
  signal.write(error, ERROR_BIT);
@@ -779,10 +885,10 @@ function createAsync(fn, initial, options) {
779
885
  onCleanup(() => abort = true);
780
886
  (async () => {
781
887
  try {
782
- for await (let value2 of source) {
888
+ for await (let value3 of source) {
783
889
  if (abort)
784
890
  return;
785
- signal.write(value2, 0);
891
+ signal.write(value3, 0, true);
786
892
  }
787
893
  } catch (error) {
788
894
  signal.write(error, ERROR_BIT);
@@ -794,28 +900,16 @@ function createAsync(fn, initial, options) {
794
900
  );
795
901
  return () => lhs.wait().wait();
796
902
  }
797
- function createMemo(compute2, initialValue, options) {
798
- let node = new Computation(initialValue, compute2, options);
799
- let value;
800
- return () => {
801
- if (node) {
802
- value = node.wait();
803
- if (!node._sources?.length)
804
- node = void 0;
805
- }
806
- return value;
807
- };
808
- }
809
- function createEffect(compute2, effect, initialValue, options) {
903
+ function createEffect(compute2, effect, value, options) {
810
904
  void new Effect(
811
- initialValue,
905
+ value,
812
906
  compute2,
813
907
  effect,
814
908
  { name: options?.name ?? "effect" }
815
909
  );
816
910
  }
817
- function createRenderEffect(compute2, effect, initialValue, options) {
818
- void new Effect(initialValue, compute2, effect, {
911
+ function createRenderEffect(compute2, effect, value, options) {
912
+ void new Effect(value, compute2, effect, {
819
913
  render: true,
820
914
  ...{ name: options?.name ?? "effect" }
821
915
  });
@@ -836,7 +930,7 @@ function catchError(fn, handler) {
836
930
  const owner = new Owner();
837
931
  owner._handlers = owner._handlers ? [handler, ...owner._handlers] : [handler];
838
932
  try {
839
- compute(owner, fn, null);
933
+ return compute(owner, fn, null);
840
934
  } catch (error) {
841
935
  owner.handleError(error);
842
936
  }
@@ -1344,7 +1438,11 @@ function updateKeyedMap() {
1344
1438
  this._indexes && (this._indexes = []);
1345
1439
  }
1346
1440
  if (this._fallback && !this._mappings[0]) {
1347
- this._mappings[0] = compute(this._nodes[0] = new Owner(), this._fallback, null);
1441
+ this._mappings[0] = compute(
1442
+ this._nodes[0] = new Owner(),
1443
+ this._fallback,
1444
+ null
1445
+ );
1348
1446
  }
1349
1447
  } else if (this._len === 0) {
1350
1448
  if (this._nodes[0])
@@ -1416,4 +1514,4 @@ function compare(key, a, b) {
1416
1514
  return key ? key(a) === key(b) : true;
1417
1515
  }
1418
1516
 
1419
- export { $PROXY, $RAW, $TARGET, $TRACK, Computation, ContextNotFoundError, NoOwnerError, NotReadyError, Owner, Queue, SUPPORTS_PROXY, catchError, createAsync, createBoundary, createContext, createEffect, createMemo, createProjection, createRenderEffect, createRoot, createSignal, createStore, createSuspense, flushSync, getContext, getObserver, getOwner, hasContext, hasUpdated, isEqual, isPending, isWrappable, latest, mapArray, merge, omit, onCleanup, reconcile, runWithOwner, setContext, untrack, unwrap };
1517
+ export { $PROXY, $RAW, $TARGET, $TRACK, Computation, ContextNotFoundError, NoOwnerError, NotReadyError, Owner, Queue, SUPPORTS_PROXY, catchError, createAsync, createBoundary, createContext, createEffect, createMemo, createProjection, createRenderEffect, createRoot, createSignal, createStore, createSuspense, flatten, flushSync, getContext, getObserver, getOwner, hasContext, hasUpdated, isEqual, isPending, isWrappable, latest, mapArray, merge, omit, onCleanup, reconcile, runWithOwner, setContext, untrack, unwrap };