@solidjs/signals 0.0.2 → 0.0.4

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
@@ -4,14 +4,14 @@ var NotReadyError = class extends Error {
4
4
  var NoOwnerError = class extends Error {
5
5
  constructor() {
6
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`."
7
+ "Context can only be accessed under a reactive root."
8
8
  );
9
9
  }
10
10
  };
11
11
  var ContextNotFoundError = class extends Error {
12
12
  constructor() {
13
13
  super(
14
- "Must provide either a default context value or set one via `setContext` before getting."
14
+ "Context must either be created with a default value or a value must be provided before accessing it."
15
15
  );
16
16
  }
17
17
  };
@@ -25,7 +25,8 @@ function isUndefined(value) {
25
25
  var STATE_CLEAN = 0;
26
26
  var STATE_CHECK = 1;
27
27
  var STATE_DIRTY = 2;
28
- var STATE_DISPOSED = 3;
28
+ var STATE_UNINITIALIZED = 3;
29
+ var STATE_DISPOSED = 4;
29
30
  var EFFECT_PURE = 0;
30
31
  var EFFECT_RENDER = 1;
31
32
  var EFFECT_USER = 2;
@@ -156,17 +157,18 @@ function setContext(context, value, owner = currentOwner) {
156
157
  function hasContext(context, owner = currentOwner) {
157
158
  return !isUndefined(owner?._context[context.id]);
158
159
  }
159
- function onCleanup(disposable) {
160
+ function onCleanup(fn) {
160
161
  if (!currentOwner)
161
- return;
162
+ return fn;
162
163
  const node = currentOwner;
163
164
  if (!node._disposal) {
164
- node._disposal = disposable;
165
+ node._disposal = fn;
165
166
  } else if (Array.isArray(node._disposal)) {
166
- node._disposal.push(disposable);
167
+ node._disposal.push(fn);
167
168
  } else {
168
- node._disposal = [node._disposal, disposable];
169
+ node._disposal = [node._disposal, fn];
169
170
  }
171
+ return fn;
170
172
  }
171
173
 
172
174
  // src/core/flags.ts
@@ -213,7 +215,7 @@ var Computation = class extends Owner {
213
215
  constructor(initialValue, compute2, options) {
214
216
  super(compute2 === null);
215
217
  this._compute = compute2;
216
- this._state = compute2 ? STATE_DIRTY : STATE_CLEAN;
218
+ this._state = compute2 ? STATE_UNINITIALIZED : STATE_CLEAN;
217
219
  this._value = initialValue;
218
220
  this._name = options?.name ?? (this._compute ? "computed" : "signal");
219
221
  if (options?.equals !== void 0)
@@ -279,7 +281,7 @@ var Computation = class extends Owner {
279
281
  /** Update the computation with a new value. */
280
282
  write(value, flags = 0, raw = false) {
281
283
  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));
284
+ const valueChanged = newValue !== UNCHANGED && (!!(flags & ERROR_BIT) || this._state === STATE_UNINITIALIZED || this._equals === false || !this._equals(this._value, newValue));
283
285
  if (valueChanged)
284
286
  this._value = newValue;
285
287
  const changedFlagsMask = this._stateFlags ^ flags, changedFlags = changedFlagsMask & flags;
@@ -364,7 +366,7 @@ var Computation = class extends Owner {
364
366
  }
365
367
  }
366
368
  }
367
- if (this._state === STATE_DIRTY) {
369
+ if (this._state === STATE_DIRTY || this._state === STATE_UNINITIALIZED) {
368
370
  update(this);
369
371
  } else {
370
372
  this.write(UNCHANGED, observerFlags);
@@ -544,7 +546,8 @@ function schedule() {
544
546
  if (scheduled)
545
547
  return;
546
548
  scheduled = true;
547
- queueMicrotask(flushSync);
549
+ if (!globalQueue._running)
550
+ queueMicrotask(flushSync);
548
551
  }
549
552
  var Queue = class {
550
553
  _running = false;
@@ -578,6 +581,7 @@ var Queue = class {
578
581
  try {
579
582
  this.run(EFFECT_PURE);
580
583
  incrementClock();
584
+ scheduled = false;
581
585
  this.run(EFFECT_RENDER);
582
586
  this.run(EFFECT_USER);
583
587
  } finally {
@@ -595,8 +599,12 @@ var Queue = class {
595
599
  };
596
600
  var globalQueue = new Queue();
597
601
  function flushSync() {
598
- globalQueue.flush();
599
- scheduled = false;
602
+ let count = 0;
603
+ while (scheduled) {
604
+ if (++count === 1e5)
605
+ throw new Error("Potential Infinite Loop Detected.");
606
+ globalQueue.flush();
607
+ }
600
608
  }
601
609
  function createBoundary(fn, queue) {
602
610
  const owner = new Owner();
@@ -643,6 +651,8 @@ var Effect = class extends Computation {
643
651
  this._queue = getOwner()?._queue || globalQueue;
644
652
  this._updateIfNecessary();
645
653
  this._type === EFFECT_USER ? this._queue.enqueue(this._type, this) : this._runEffect();
654
+ if (!this._parent)
655
+ console.warn("Effects created outside a reactive context will never be disposed");
646
656
  }
647
657
  write(value, flags = 0) {
648
658
  const currentFlags = this._stateFlags;
@@ -685,6 +695,8 @@ var EagerComputation = class extends Computation {
685
695
  super(initialValue, compute2, options);
686
696
  this._queue = getOwner()?._queue || globalQueue;
687
697
  this._updateIfNecessary();
698
+ if (!this._parent)
699
+ console.warn("Eager Computations created outside a reactive context will never be disposed");
688
700
  }
689
701
  _notify(state) {
690
702
  if (this._state >= state)
@@ -745,14 +757,35 @@ function createSignal(first, second, third) {
745
757
  const node = new Computation(first, null, second);
746
758
  return [node.read.bind(node), node.write.bind(node)];
747
759
  }
748
- function createAsync(fn, initial, options) {
760
+ function createMemo(compute2, value, options) {
761
+ let node = new Computation(
762
+ value,
763
+ compute2,
764
+ options
765
+ );
766
+ let resolvedValue;
767
+ return () => {
768
+ if (node) {
769
+ resolvedValue = node.wait();
770
+ if (!node._sources?.length) {
771
+ node.dispose();
772
+ node = void 0;
773
+ } else if (!node._parent && !node._observers?.length) {
774
+ node.dispose();
775
+ node._state = STATE_UNINITIALIZED;
776
+ }
777
+ }
778
+ return resolvedValue;
779
+ };
780
+ }
781
+ function createAsync(compute2, value, options) {
749
782
  const lhs = new EagerComputation(
750
783
  {
751
- _value: initial
784
+ _value: value
752
785
  },
753
786
  (p) => {
754
- const value = p?._value;
755
- const source = fn(value);
787
+ const value2 = p?._value;
788
+ const source = compute2(value2);
756
789
  const isPromise = source instanceof Promise;
757
790
  const iterator = source[Symbol.asyncIterator];
758
791
  if (!isPromise && !iterator) {
@@ -763,12 +796,12 @@ function createAsync(fn, initial, options) {
763
796
  _value: source
764
797
  };
765
798
  }
766
- const signal = new Computation(value, null, options);
799
+ const signal = new Computation(value2, null, options);
767
800
  signal.write(UNCHANGED, LOADING_BIT);
768
801
  if (isPromise) {
769
802
  source.then(
770
- (value2) => {
771
- signal.write(value2, 0);
803
+ (value3) => {
804
+ signal.write(value3, 0);
772
805
  },
773
806
  (error) => {
774
807
  signal.write(error, ERROR_BIT);
@@ -779,10 +812,10 @@ function createAsync(fn, initial, options) {
779
812
  onCleanup(() => abort = true);
780
813
  (async () => {
781
814
  try {
782
- for await (let value2 of source) {
815
+ for await (let value3 of source) {
783
816
  if (abort)
784
817
  return;
785
- signal.write(value2, 0);
818
+ signal.write(value3, 0);
786
819
  }
787
820
  } catch (error) {
788
821
  signal.write(error, ERROR_BIT);
@@ -794,28 +827,16 @@ function createAsync(fn, initial, options) {
794
827
  );
795
828
  return () => lhs.wait().wait();
796
829
  }
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) {
830
+ function createEffect(compute2, effect, value, options) {
810
831
  void new Effect(
811
- initialValue,
832
+ value,
812
833
  compute2,
813
834
  effect,
814
835
  { name: options?.name ?? "effect" }
815
836
  );
816
837
  }
817
- function createRenderEffect(compute2, effect, initialValue, options) {
818
- void new Effect(initialValue, compute2, effect, {
838
+ function createRenderEffect(compute2, effect, value, options) {
839
+ void new Effect(value, compute2, effect, {
819
840
  render: true,
820
841
  ...{ name: options?.name ?? "effect" }
821
842
  });
@@ -852,15 +873,22 @@ var STORE_NODE = "n";
852
873
  var STORE_HAS = "h";
853
874
  function wrap(value) {
854
875
  let p = value[$PROXY];
855
- if (!p)
876
+ if (!p) {
877
+ let target;
878
+ if (Array.isArray(value)) {
879
+ target = [];
880
+ target.v = value;
881
+ } else
882
+ target = { v: value };
856
883
  Object.defineProperty(value, $PROXY, {
857
- value: p = new Proxy({ v: value }, proxyTraps),
884
+ value: p = new Proxy(target, proxyTraps),
858
885
  writable: true
859
886
  });
887
+ }
860
888
  return p;
861
889
  }
862
890
  function isWrappable(obj) {
863
- return obj != null && typeof obj === "object";
891
+ return obj != null && typeof obj === "object" && !Object.isFrozen(obj);
864
892
  }
865
893
  function unwrap(item, deep = true, set) {
866
894
  let result, unwrapped, v, prop;
@@ -912,8 +940,10 @@ function getNode(nodes, property, value, equals = isEqual) {
912
940
  });
913
941
  }
914
942
  function proxyDescriptor(target, property) {
943
+ if (property === $PROXY)
944
+ return { value: target[$PROXY], writable: true, configurable: true };
915
945
  const desc = Reflect.getOwnPropertyDescriptor(target[STORE_VALUE], property);
916
- if (!desc || desc.get || !desc.configurable || property === $PROXY)
946
+ if (!desc || desc.get || !desc.configurable)
917
947
  return desc;
918
948
  delete desc.value;
919
949
  delete desc.writable;
@@ -979,7 +1009,10 @@ var proxyTraps = {
979
1009
  return true;
980
1010
  },
981
1011
  ownKeys,
982
- getOwnPropertyDescriptor: proxyDescriptor
1012
+ getOwnPropertyDescriptor: proxyDescriptor,
1013
+ getPrototypeOf(target) {
1014
+ return Object.getPrototypeOf(target[STORE_VALUE]);
1015
+ }
983
1016
  };
984
1017
  function setProperty(state, property, value, deleting = false) {
985
1018
  const prev = state[property];
@@ -1133,6 +1166,7 @@ function reconcile(value, key) {
1133
1166
  if (keyFn(value) !== keyFn(state))
1134
1167
  throw new Error("Cannot reconcile states with different identity");
1135
1168
  applyState(value, state, keyFn);
1169
+ return state;
1136
1170
  };
1137
1171
  }
1138
1172
 
@@ -1287,24 +1321,19 @@ function omit(props, ...keys) {
1287
1321
  // src/map.ts
1288
1322
  function mapArray(list, map, options) {
1289
1323
  const keyFn = typeof options?.keyed === "function" ? options.keyed : void 0;
1290
- return Computation.prototype.read.bind(
1291
- new Computation(
1292
- [],
1293
- updateKeyedMap.bind({
1294
- _owner: new Owner(),
1295
- _len: 0,
1296
- _list: list,
1297
- _items: [],
1298
- _map: map,
1299
- _mappings: [],
1300
- _nodes: [],
1301
- _key: keyFn,
1302
- _rows: keyFn || options?.keyed === false ? [] : void 0,
1303
- _indexes: map.length > 1 ? [] : void 0
1304
- }),
1305
- options
1306
- )
1307
- );
1324
+ return updateKeyedMap.bind({
1325
+ _owner: new Owner(),
1326
+ _len: 0,
1327
+ _list: list,
1328
+ _items: [],
1329
+ _map: map,
1330
+ _mappings: [],
1331
+ _nodes: [],
1332
+ _key: keyFn,
1333
+ _rows: keyFn || options?.keyed === false ? [] : void 0,
1334
+ _indexes: map.length > 1 ? [] : void 0,
1335
+ _fallback: options?.fallback
1336
+ });
1308
1337
  }
1309
1338
  function updateKeyedMap() {
1310
1339
  const newItems = this._list() || [], newLen = newItems.length;
@@ -1335,7 +1364,16 @@ function updateKeyedMap() {
1335
1364
  this._rows && (this._rows = []);
1336
1365
  this._indexes && (this._indexes = []);
1337
1366
  }
1367
+ if (this._fallback && !this._mappings[0]) {
1368
+ this._mappings[0] = compute(
1369
+ this._nodes[0] = new Owner(),
1370
+ this._fallback,
1371
+ null
1372
+ );
1373
+ }
1338
1374
  } else if (this._len === 0) {
1375
+ if (this._nodes[0])
1376
+ this._nodes[0].dispose();
1339
1377
  this._mappings = new Array(newLen);
1340
1378
  for (j = 0; j < newLen; j++) {
1341
1379
  this._items[j] = newItems[j];
@@ -1403,4 +1441,4 @@ function compare(key, a, b) {
1403
1441
  return key ? key(a) === key(b) : true;
1404
1442
  }
1405
1443
 
1406
- export { $PROXY, $RAW, $TARGET, $TRACK, Computation, ContextNotFoundError, NoOwnerError, NotReadyError, Owner, Queue, 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 };
1444
+ 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 };