@solidjs/signals 0.10.7 → 0.11.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
@@ -601,8 +601,8 @@ function handleAsync(el, result, setter) {
601
601
  if (!equals || !equals(value, prevValue)) {
602
602
  el._value = value;
603
603
  el._time = clock;
604
- if (el._pendingValueComputed) {
605
- setSignal(el._pendingValueComputed, value);
604
+ if (el._latestValueComputed) {
605
+ setSignal(el._latestValueComputed, value);
606
606
  }
607
607
  insertSubs(el, true);
608
608
  }
@@ -869,7 +869,7 @@ function formatId(prefix, id) {
869
869
  return prefix + (len ? String.fromCharCode(64 + len) : "") + num;
870
870
  }
871
871
  function getObserver() {
872
- if (pendingCheckActive || pendingReadActive) return PENDING_OWNER;
872
+ if (pendingCheckActive || latestReadActive) return PENDING_OWNER;
873
873
  return tracking ? context : null;
874
874
  }
875
875
  function getOwner() {
@@ -1010,7 +1010,7 @@ function trackedEffect(fn, options) {
1010
1010
  }
1011
1011
  },
1012
1012
  undefined,
1013
- { ...options, lazy: true, pureWrite: true }
1013
+ { ...options, lazy: true }
1014
1014
  );
1015
1015
  node._cleanup = undefined;
1016
1016
  node._modified = true;
@@ -1028,7 +1028,7 @@ let stale = false;
1028
1028
  let refreshing = false;
1029
1029
  let pendingCheckActive = false;
1030
1030
  let foundPending = false;
1031
- let pendingReadActive = false;
1031
+ let latestReadActive = false;
1032
1032
  let context = null;
1033
1033
  let currentOptimisticLane = null;
1034
1034
  let snapshotCaptureActive = false;
@@ -1306,9 +1306,25 @@ function optimisticComputed(fn, initialValue, options) {
1306
1306
  function isEqual(a, b) {
1307
1307
  return a === b;
1308
1308
  }
1309
+ let strictRead = false;
1310
+ function setStrictRead(v) {
1311
+ const prev = strictRead;
1312
+ strictRead = v;
1313
+ return prev;
1314
+ }
1309
1315
  function untrack(fn) {
1310
- if (!tracking) return fn();
1316
+ if (!tracking && !strictRead) return fn();
1311
1317
  tracking = false;
1318
+ if (strictRead) {
1319
+ const prev = strictRead;
1320
+ strictRead = false;
1321
+ try {
1322
+ return fn();
1323
+ } finally {
1324
+ tracking = true;
1325
+ strictRead = prev;
1326
+ }
1327
+ }
1312
1328
  try {
1313
1329
  return fn();
1314
1330
  } finally {
@@ -1316,10 +1332,10 @@ function untrack(fn) {
1316
1332
  }
1317
1333
  }
1318
1334
  function read(el) {
1319
- if (pendingReadActive) {
1320
- const pendingComputed = getPendingValueComputed(el);
1321
- const prevPending = pendingReadActive;
1322
- pendingReadActive = false;
1335
+ if (latestReadActive) {
1336
+ const pendingComputed = getLatestValueComputed(el);
1337
+ const prevPending = latestReadActive;
1338
+ latestReadActive = false;
1323
1339
  let value;
1324
1340
  try {
1325
1341
  value = read(pendingComputed);
@@ -1327,7 +1343,7 @@ function read(el) {
1327
1343
  if (!context && e instanceof NotReadyError) return el._value;
1328
1344
  throw e;
1329
1345
  } finally {
1330
- pendingReadActive = prevPending;
1346
+ latestReadActive = prevPending;
1331
1347
  }
1332
1348
  if (pendingComputed._statusFlags & STATUS_PENDING) return el._value;
1333
1349
  if (stale && currentOptimisticLane && pendingComputed._optimisticLane) {
@@ -1406,6 +1422,10 @@ function read(el) {
1406
1422
  return snapshot;
1407
1423
  }
1408
1424
  }
1425
+ if (strictRead && !tracking)
1426
+ console.warn(
1427
+ `Untracked reactive read in ${strictRead}. This value won't update — use untrack() if intentional.`
1428
+ );
1409
1429
  return !c ||
1410
1430
  currentOptimisticLane !== null ||
1411
1431
  el._pendingValue === NOT_PENDING ||
@@ -1414,7 +1434,7 @@ function read(el) {
1414
1434
  : el._pendingValue;
1415
1435
  }
1416
1436
  function setSignal(el, v) {
1417
- if (!el._pureWrite && context && el._firewall !== context)
1437
+ if (!el._pureWrite && !leafEffectActive && context && el._firewall !== context)
1418
1438
  console.warn("A Signal was written to in an owned scope.");
1419
1439
  if (el._transition && activeTransition !== el._transition)
1420
1440
  globalQueue.initTransition(el._transition);
@@ -1453,8 +1473,8 @@ function setSignal(el, v) {
1453
1473
  el._pendingValue = v;
1454
1474
  }
1455
1475
  updatePendingSignal(el);
1456
- if (el._pendingValueComputed) {
1457
- setSignal(el._pendingValueComputed, v);
1476
+ if (el._latestValueComputed) {
1477
+ setSignal(el._latestValueComputed, v);
1458
1478
  }
1459
1479
  el._time = clock;
1460
1480
  insertSubs(el, isOptimistic);
@@ -1515,21 +1535,21 @@ function updatePendingSignal(el) {
1515
1535
  }
1516
1536
  }
1517
1537
  }
1518
- function getPendingValueComputed(el) {
1519
- if (!el._pendingValueComputed) {
1520
- const prevPending = pendingReadActive;
1521
- pendingReadActive = false;
1538
+ function getLatestValueComputed(el) {
1539
+ if (!el._latestValueComputed) {
1540
+ const prevPending = latestReadActive;
1541
+ latestReadActive = false;
1522
1542
  const prevCheck = pendingCheckActive;
1523
1543
  pendingCheckActive = false;
1524
1544
  const prevContext = context;
1525
1545
  context = null;
1526
- el._pendingValueComputed = optimisticComputed(() => read(el));
1527
- el._pendingValueComputed._parentSource = el;
1546
+ el._latestValueComputed = optimisticComputed(() => read(el));
1547
+ el._latestValueComputed._parentSource = el;
1528
1548
  context = prevContext;
1529
1549
  pendingCheckActive = prevCheck;
1530
- pendingReadActive = prevPending;
1550
+ latestReadActive = prevPending;
1531
1551
  }
1532
- return el._pendingValueComputed;
1552
+ return el._latestValueComputed;
1533
1553
  }
1534
1554
  function staleValues(fn, set = true) {
1535
1555
  const prevStale = stale;
@@ -1540,13 +1560,13 @@ function staleValues(fn, set = true) {
1540
1560
  stale = prevStale;
1541
1561
  }
1542
1562
  }
1543
- function pending(fn) {
1544
- const prevPending = pendingReadActive;
1545
- pendingReadActive = true;
1563
+ function latest(fn) {
1564
+ const prevLatest = latestReadActive;
1565
+ latestReadActive = true;
1546
1566
  try {
1547
1567
  return fn();
1548
1568
  } finally {
1549
- pendingReadActive = prevPending;
1569
+ latestReadActive = prevLatest;
1550
1570
  }
1551
1571
  }
1552
1572
  function isPending(fn) {
@@ -2121,6 +2141,10 @@ const storeTraps = {
2121
2141
  );
2122
2142
  }
2123
2143
  }
2144
+ if (strictRead && !tracking && typeof property === "string")
2145
+ console.warn(
2146
+ `Untracked reactive read in ${strictRead}. This value won't update — use untrack() if intentional.`
2147
+ );
2124
2148
  return isWrappable(value) ? wrap(value, target) : value;
2125
2149
  },
2126
2150
  has(target, property) {
@@ -2441,6 +2465,71 @@ function createOptimisticProjectionInternal(fn, initialValue = {}, options) {
2441
2465
  }
2442
2466
  return { store: wrappedStore, node: node };
2443
2467
  }
2468
+ const DELETE = Symbol("STORE_PATH_DELETE");
2469
+ function updatePath(current, args, i = 0) {
2470
+ let part,
2471
+ prev = current;
2472
+ if (i < args.length - 1) {
2473
+ part = args[i];
2474
+ const partType = typeof part;
2475
+ const isArray = Array.isArray(current);
2476
+ if (Array.isArray(part)) {
2477
+ for (let j = 0; j < part.length; j++) {
2478
+ args[i] = part[j];
2479
+ updatePath(current, args, i);
2480
+ }
2481
+ args[i] = part;
2482
+ return;
2483
+ } else if (isArray && partType === "function") {
2484
+ for (let j = 0; j < current.length; j++) {
2485
+ if (part(current[j], j)) {
2486
+ args[i] = j;
2487
+ updatePath(current, args, i);
2488
+ }
2489
+ }
2490
+ args[i] = part;
2491
+ return;
2492
+ } else if (isArray && partType === "object") {
2493
+ const { from: from = 0, to: to = current.length - 1, by: by = 1 } = part;
2494
+ for (let j = from; j <= to; j += by) {
2495
+ args[i] = j;
2496
+ updatePath(current, args, i);
2497
+ }
2498
+ args[i] = part;
2499
+ return;
2500
+ } else if (i < args.length - 2) {
2501
+ updatePath(current[part], args, i + 1);
2502
+ return;
2503
+ }
2504
+ prev = current[part];
2505
+ }
2506
+ let value = args[args.length - 1];
2507
+ if (typeof value === "function") {
2508
+ value = value(prev);
2509
+ if (value === prev) return;
2510
+ }
2511
+ if (part === undefined && value == undefined) return;
2512
+ if (value === DELETE) {
2513
+ delete current[part];
2514
+ } else if (
2515
+ part === undefined ||
2516
+ (isWrappable(prev) && isWrappable(value) && !Array.isArray(value))
2517
+ ) {
2518
+ const target = part !== undefined ? current[part] : current;
2519
+ const keys = Object.keys(value);
2520
+ for (let i = 0; i < keys.length; i++) target[keys[i]] = value[keys[i]];
2521
+ } else {
2522
+ current[part] = value;
2523
+ }
2524
+ }
2525
+ const storePath = Object.assign(
2526
+ function storePath(...args) {
2527
+ return state => {
2528
+ updatePath(state, args);
2529
+ };
2530
+ },
2531
+ { DELETE: DELETE }
2532
+ );
2444
2533
  function snapshot(item, map, lookup) {
2445
2534
  let target, isArray, override, result, unwrapped, v;
2446
2535
  if (!isWrappable(item)) return item;
@@ -2624,18 +2713,29 @@ function omit(props, ...keys) {
2624
2713
  }
2625
2714
  function mapArray(list, map, options) {
2626
2715
  const keyFn = typeof options?.keyed === "function" ? options.keyed : undefined;
2716
+ const indexes = map.length > 1;
2717
+ const wrappedMap = options?.name
2718
+ ? (...args) => {
2719
+ setStrictRead(options.name);
2720
+ try {
2721
+ return map(...args);
2722
+ } finally {
2723
+ setStrictRead(false);
2724
+ }
2725
+ }
2726
+ : map;
2627
2727
  return createMemo(
2628
2728
  updateKeyedMap.bind({
2629
2729
  _owner: createOwner(),
2630
2730
  _len: 0,
2631
2731
  _list: list,
2632
2732
  _items: [],
2633
- _map: map,
2733
+ _map: wrappedMap,
2634
2734
  _mappings: [],
2635
2735
  _nodes: [],
2636
2736
  _key: keyFn,
2637
2737
  _rows: keyFn || options?.keyed === false ? [] : undefined,
2638
- _indexes: map.length > 1 ? [] : undefined,
2738
+ _indexes: indexes ? [] : undefined,
2639
2739
  _fallback: options?.fallback
2640
2740
  })
2641
2741
  );
@@ -2767,12 +2867,22 @@ function updateKeyedMap() {
2767
2867
  return this._mappings;
2768
2868
  }
2769
2869
  function repeat(count, map, options) {
2870
+ const wrappedMap = options?.name
2871
+ ? i => {
2872
+ setStrictRead(options.name);
2873
+ try {
2874
+ return map(i);
2875
+ } finally {
2876
+ setStrictRead(false);
2877
+ }
2878
+ }
2879
+ : map;
2770
2880
  return updateRepeat.bind({
2771
2881
  _owner: createOwner(),
2772
2882
  _len: 0,
2773
2883
  _offset: 0,
2774
2884
  _count: count,
2775
- _map: map,
2885
+ _map: wrappedMap,
2776
2886
  _nodes: [],
2777
2887
  _mappings: [],
2778
2888
  _from: options?.from,
@@ -3014,6 +3124,7 @@ export {
3014
3124
  isPending,
3015
3125
  isRefreshing,
3016
3126
  isWrappable,
3127
+ latest,
3017
3128
  mapArray,
3018
3129
  markSnapshotScope,
3019
3130
  merge,
@@ -3021,7 +3132,6 @@ export {
3021
3132
  onCleanup,
3022
3133
  onSettled,
3023
3134
  peekNextChildId,
3024
- pending,
3025
3135
  reconcile,
3026
3136
  refresh,
3027
3137
  releaseSnapshotScope,
@@ -3030,6 +3140,8 @@ export {
3030
3140
  runWithOwner,
3031
3141
  setContext,
3032
3142
  setSnapshotCapture,
3143
+ setStrictRead,
3033
3144
  snapshot,
3145
+ storePath,
3034
3146
  untrack
3035
3147
  };