@solidjs/signals 2.0.0-beta.16 → 2.0.0-beta.17

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
@@ -12,6 +12,9 @@ class StatusError extends Error {
12
12
  this.source = source;
13
13
  }
14
14
  }
15
+ function unwrapStatusError(error) {
16
+ return error instanceof StatusError ? error.cause : error;
17
+ }
15
18
  class NoOwnerError extends Error {
16
19
  constructor() {
17
20
  super("Context can only be accessed under a reactive root.");
@@ -1433,8 +1436,9 @@ function handleAsync(el, result, setter) {
1433
1436
  }
1434
1437
  if (iterator) {
1435
1438
  const it = result[Symbol.asyncIterator]();
1436
- let hadSyncValue = false;
1439
+ let hadValue = false;
1437
1440
  let completed = false;
1441
+ let initialRead = true;
1438
1442
  cleanup(() => {
1439
1443
  if (completed) return;
1440
1444
  completed = true;
@@ -1445,7 +1449,9 @@ function handleAsync(el, result, setter) {
1445
1449
  });
1446
1450
  const iterate = () => {
1447
1451
  let syncResult,
1452
+ syncError,
1448
1453
  resolved = false,
1454
+ rejected = false,
1449
1455
  isSync = true;
1450
1456
  it.next().then(
1451
1457
  r => {
@@ -1455,30 +1461,46 @@ function handleAsync(el, result, setter) {
1455
1461
  if (r.done) completed = true;
1456
1462
  } else if (el._inFlight !== result) {
1457
1463
  return;
1458
- } else if (!r.done) asyncWrite(r.value, iterate);
1459
- else {
1464
+ } else if (!r.done) {
1465
+ hadValue = true;
1466
+ asyncWrite(r.value, iterate);
1467
+ } else {
1460
1468
  completed = true;
1461
- schedule();
1462
- flush();
1469
+ if (hadValue) {
1470
+ schedule();
1471
+ flush();
1472
+ } else {
1473
+ asyncWrite(undefined);
1474
+ }
1463
1475
  }
1464
1476
  },
1465
1477
  e => {
1466
- if (!isSync && el._inFlight === result) {
1478
+ if (isSync) {
1479
+ syncError = e;
1480
+ rejected = true;
1481
+ } else if (el._inFlight === result) {
1467
1482
  completed = true;
1468
1483
  handleError(e);
1469
1484
  }
1470
1485
  }
1471
1486
  );
1472
1487
  isSync = false;
1488
+ if (rejected) {
1489
+ completed = true;
1490
+ handleError(syncError);
1491
+ if (initialRead) throw syncError;
1492
+ return true;
1493
+ }
1473
1494
  if (resolved && !syncResult.done) {
1474
1495
  syncValue = syncResult.value;
1475
- hadSyncValue = true;
1496
+ hadValue = true;
1476
1497
  return iterate();
1477
1498
  }
1478
1499
  return resolved && syncResult.done;
1479
1500
  };
1480
1501
  const immediatelyDone = iterate();
1481
- if (!hadSyncValue && !immediatelyDone) {
1502
+ initialRead = false;
1503
+ if (!hadValue && !immediatelyDone) {
1482
1504
  globalQueue.initTransition(resolveTransition(el));
1483
1505
  throw new NotReadyError(context);
1484
1506
  }
@@ -2632,8 +2654,7 @@ function notifyEffectStatus(status, error) {
2632
2654
  function runEffect(node) {
2633
2655
  if (!node._modified || node._flags & REACTIVE_DISPOSED) return;
2634
2656
  if (node._statusFlags & STATUS_ERROR && node._type === EFFECT_USER) {
2635
- const err =
2636
- node._error instanceof StatusError ? (node._error.cause ?? node._error) : node._error;
2657
+ const err = unwrapStatusError(node._error);
2637
2658
  node._prevValue = node._value;
2638
2659
  node._modified = false;
2639
2660
  try {
@@ -2739,6 +2760,9 @@ function trackedEffect(fn, options) {
2739
2760
  console.warn(message);
2740
2761
  }
2741
2762
  }
2763
+ const ACTION_CALLED_IN_OWNED_SCOPE_MESSAGE =
2764
+ "[ACTION_CALLED_IN_OWNED_SCOPE] Calling an action inside an owned scope (component, computation) is not allowed. " +
2765
+ "Call it from an event handler or another imperative scope.";
2742
2766
  function restoreTransition(transition, fn) {
2743
2767
  globalQueue.initTransition(transition);
2744
2768
  const result = fn();
@@ -2746,28 +2770,42 @@ function restoreTransition(transition, fn) {
2746
2770
  return result;
2747
2771
  }
2748
2772
  function action(genFn) {
2749
- return (...args) =>
2750
- new Promise((resolve, reject) => {
2773
+ return (...args) => {
2774
+ {
2775
+ const owner = getOwner();
2776
+ if (owner && !(owner._config & CONFIG_CHILDREN_FORBIDDEN)) {
2777
+ emitDiagnostic({
2778
+ code: "ACTION_CALLED_IN_OWNED_SCOPE",
2779
+ kind: "write",
2780
+ severity: "error",
2781
+ message: ACTION_CALLED_IN_OWNED_SCOPE_MESSAGE,
2782
+ ownerId: owner.id,
2783
+ ownerName: owner._name
2784
+ });
2785
+ throw new Error(ACTION_CALLED_IN_OWNED_SCOPE_MESSAGE);
2786
+ }
2787
+ }
2788
+ return new Promise((resolve, reject) => {
2751
2789
  const it = genFn(...args);
2752
2790
  globalQueue.initTransition();
2753
2791
  let ctx = activeTransition;
2754
2792
  ctx._actions.push(it);
2755
- const done = (v, e) => {
2793
+ const done = (v, e, failed = false) => {
2756
2794
  ctx = currentTransition(ctx);
2757
2795
  const i = ctx._actions.indexOf(it);
2758
2796
  if (i >= 0) ctx._actions.splice(i, 1);
2759
2797
  setActiveTransition(ctx);
2760
2798
  schedule();
2761
- e ? reject(e) : resolve(v);
2799
+ failed ? reject(e) : resolve(v);
2762
2800
  };
2763
2801
  const step = (v, err) => {
2764
2802
  let r;
2765
2803
  try {
2766
2804
  r = err ? it.throw(v) : it.next(v);
2767
2805
  } catch (e) {
2768
- return done(undefined, e);
2806
+ return done(undefined, e, true);
2769
2807
  }
2770
- if (isThenable(r)) return void r.then(run, e => done(undefined, e));
2808
+ if (isThenable(r)) return void r.then(run, e => done(undefined, e, true));
2771
2809
  run(r);
2772
2810
  };
2773
2811
  const run = r => {
@@ -2781,6 +2819,7 @@ function action(genFn) {
2781
2819
  };
2782
2820
  step();
2783
2821
  });
2822
+ };
2784
2823
  }
2785
2824
  function onCleanup(fn) {
2786
2825
  {
@@ -2859,11 +2898,17 @@ function createReaction(effectFn, options) {
2859
2898
  let cl = undefined;
2860
2899
  cleanup(() => cl?.());
2861
2900
  const owner = getOwner();
2901
+ let arm;
2862
2902
  return tracking => {
2903
+ if (arm) {
2904
+ dispose(arm);
2905
+ arm = undefined;
2906
+ }
2863
2907
  runWithOwner(owner, () => {
2864
2908
  effect(
2865
- () => (tracking(), getOwner()),
2909
+ () => (tracking(), (arm = getOwner())),
2866
2910
  node => {
2911
+ arm = undefined;
2867
2912
  cl?.();
2868
2913
  const cleanup = (effectFn.effect || effectFn)?.();
2869
2914
  if (true && cleanup !== undefined && typeof cleanup !== "function") {
@@ -3554,17 +3599,24 @@ function getNode(nodes, property, value, firewall, equals = isEqual, optimistic,
3554
3599
  return (nodes[property] = s);
3555
3600
  }
3556
3601
  function trackSelf(target, symbol = $TRACK) {
3557
- getObserver() &&
3558
- read(
3559
- getNode(
3560
- getNodes(target, STORE_NODE),
3561
- symbol,
3562
- undefined,
3563
- target[STORE_FIREWALL],
3564
- false,
3565
- target[STORE_OPTIMISTIC]
3566
- )
3567
- );
3602
+ if (!getObserver()) return;
3603
+ read(
3604
+ getNode(
3605
+ getNodes(target, STORE_NODE),
3606
+ symbol,
3607
+ undefined,
3608
+ target[STORE_FIREWALL],
3609
+ false,
3610
+ target[STORE_OPTIMISTIC]
3611
+ )
3612
+ );
3613
+ if (
3614
+ symbol === $TRACK &&
3615
+ !target[STORE_OVERRIDE] &&
3616
+ !target[STORE_OPTIMISTIC_OVERRIDE] &&
3617
+ target[STORE_VALUE][$TARGET]
3618
+ )
3619
+ target[STORE_VALUE][$TRACK];
3568
3620
  }
3569
3621
  function notifySelf(target) {
3570
3622
  const node = target[STORE_NODE]?.[$TRACK];
@@ -3825,9 +3877,14 @@ const storeTraps = {
3825
3877
  ? prevLayer[property] !== $DELETED
3826
3878
  : property in target[STORE_VALUE];
3827
3879
  const value = unwrapStoreValue(rawValue);
3880
+ const index = typeof property === "string" ? Number(property) : -1;
3828
3881
  const isArrayIndexWrite =
3829
- Array.isArray(state) && property !== "length" && typeof property !== "symbol";
3830
- const nextIndex = isArrayIndexWrite ? parseInt(property) + 1 : 0;
3882
+ Array.isArray(state) &&
3883
+ Number.isInteger(index) &&
3884
+ index >= 0 &&
3885
+ index < 4294967295 &&
3886
+ String(index) === property;
3887
+ const nextIndex = isArrayIndexWrite ? index + 1 : 0;
3831
3888
  const len = isArrayIndexWrite && (getOverlayLayer(target, "length") ?? state).length;
3832
3889
  const nextLength = isArrayIndexWrite && nextIndex > len ? nextIndex : undefined;
3833
3890
  if (prev === value && nextLength === undefined) return true;
@@ -4875,9 +4932,6 @@ class CollectionQueue extends Queue {
4875
4932
  this._sources.clear();
4876
4933
  }
4877
4934
  }
4878
- if (this._collectionType & STATUS_PENDING && flags & STATUS_ERROR) {
4879
- return super.notify(node, STATUS_ERROR, flags, error);
4880
- }
4881
4935
  if (this._collectionType & STATUS_PENDING && this._initialized)
4882
4936
  return super.notify(node, type, flags, error);
4883
4937
  if (flags & this._collectionType) {
@@ -4888,7 +4942,7 @@ class CollectionQueue extends Queue {
4888
4942
  this._sources.add(source);
4889
4943
  if (wasEmpty) setSignal(this._disabled, true);
4890
4944
  if (this._collectionType & STATUS_ERROR) {
4891
- setSignal(this._error, source._error?.cause ?? source._error);
4945
+ setSignal(this._error, unwrapStatusError(source._error));
4892
4946
  }
4893
4947
  }
4894
4948
  }