@solidjs/signals 0.4.11 → 0.6.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
@@ -269,11 +269,33 @@ var Transition = class _Transition {
269
269
  }
270
270
  ActiveTransition = this;
271
271
  try {
272
- const result = fn();
273
- const transition2 = ActiveTransition;
272
+ let result = fn();
273
+ let transition2 = ActiveTransition;
274
+ if (result?.next) {
275
+ (async function() {
276
+ let temp, value;
277
+ while (!(temp = result.next(value)).done) {
278
+ if (temp.value instanceof Promise) {
279
+ transition2._promises.add(temp.value);
280
+ try {
281
+ value = await temp.value;
282
+ } finally {
283
+ while (transition2._done instanceof _Transition)
284
+ transition2 = transition2._done;
285
+ transition2._promises.delete(temp.value);
286
+ }
287
+ ActiveTransition = transition2;
288
+ } else
289
+ value = temp.value;
290
+ }
291
+ finishTransition(transition2);
292
+ })();
293
+ }
274
294
  if (result instanceof Promise) {
275
295
  transition2._promises.add(result);
276
296
  result.finally(() => {
297
+ while (transition2._done instanceof _Transition)
298
+ transition2 = transition2._done;
277
299
  transition2._promises.delete(result);
278
300
  finishTransition(transition2);
279
301
  });
@@ -1155,18 +1177,152 @@ function runTop(node) {
1155
1177
  }
1156
1178
  }
1157
1179
 
1180
+ // src/store/reconcile.ts
1181
+ function unwrap(value) {
1182
+ return value?.[$TARGET]?.[STORE_NODE] ?? value;
1183
+ }
1184
+ function getOverrideValue(value, override, key) {
1185
+ return override && key in override ? override[key] : value[key];
1186
+ }
1187
+ function getAllKeys(value, override, next) {
1188
+ const keys = getKeys(value, override);
1189
+ const nextKeys = Object.keys(next);
1190
+ return Array.from(/* @__PURE__ */ new Set([...keys, ...nextKeys]));
1191
+ }
1192
+ function applyState(next, state, keyFn, all) {
1193
+ const target = state?.[$TARGET];
1194
+ if (!target)
1195
+ return;
1196
+ const previous = target[STORE_VALUE];
1197
+ const override = target[STORE_OVERRIDE];
1198
+ if (next === previous && !override)
1199
+ return;
1200
+ (target[STORE_LOOKUP] || storeLookup).set(next, target[$PROXY]);
1201
+ target[STORE_VALUE] = next;
1202
+ target[STORE_OVERRIDE] = void 0;
1203
+ if (Array.isArray(previous)) {
1204
+ let changed = false;
1205
+ const prevLength = getOverrideValue(previous, override, "length");
1206
+ if (next.length && prevLength && next[0] && keyFn(next[0]) != null) {
1207
+ let i, j, start, end, newEnd, item, newIndicesNext, keyVal;
1208
+ for (start = 0, end = Math.min(prevLength, next.length); start < end && ((item = getOverrideValue(previous, override, start)) === next[start] || item && next[start] && keyFn(item) === keyFn(next[start])); start++) {
1209
+ applyState(next[start], wrap(item, target), keyFn, all);
1210
+ }
1211
+ const temp = new Array(next.length), newIndices = /* @__PURE__ */ new Map();
1212
+ for (end = prevLength - 1, newEnd = next.length - 1; end >= start && newEnd >= start && ((item = getOverrideValue(previous, override, end)) === next[newEnd] || item && next[newEnd] && keyFn(item) === keyFn(next[newEnd])); end--, newEnd--) {
1213
+ temp[newEnd] = item;
1214
+ }
1215
+ if (start > newEnd || start > end) {
1216
+ for (j = start; j <= newEnd; j++) {
1217
+ changed = true;
1218
+ target[STORE_NODE][j]?.write(wrap(next[j], target));
1219
+ }
1220
+ for (; j < next.length; j++) {
1221
+ changed = true;
1222
+ const wrapped = wrap(temp[j], target);
1223
+ target[STORE_NODE][j]?.write(wrapped);
1224
+ applyState(next[j], wrapped, keyFn, all);
1225
+ }
1226
+ changed && target[STORE_NODE][$TRACK]?.write(void 0);
1227
+ prevLength !== next.length && target[STORE_NODE].length?.write(next.length);
1228
+ return;
1229
+ }
1230
+ newIndicesNext = new Array(newEnd + 1);
1231
+ for (j = newEnd; j >= start; j--) {
1232
+ item = next[j];
1233
+ keyVal = item ? keyFn(item) : item;
1234
+ i = newIndices.get(keyVal);
1235
+ newIndicesNext[j] = i === void 0 ? -1 : i;
1236
+ newIndices.set(keyVal, j);
1237
+ }
1238
+ for (i = start; i <= end; i++) {
1239
+ item = getOverrideValue(previous, override, i);
1240
+ keyVal = item ? keyFn(item) : item;
1241
+ j = newIndices.get(keyVal);
1242
+ if (j !== void 0 && j !== -1) {
1243
+ temp[j] = item;
1244
+ j = newIndicesNext[j];
1245
+ newIndices.set(keyVal, j);
1246
+ }
1247
+ }
1248
+ for (j = start; j < next.length; j++) {
1249
+ if (j in temp) {
1250
+ const wrapped = wrap(temp[j], target);
1251
+ target[STORE_NODE][j]?.write(wrapped);
1252
+ applyState(next[j], wrapped, keyFn, all);
1253
+ } else
1254
+ target[STORE_NODE][j]?.write(wrap(next[j], target));
1255
+ }
1256
+ if (start < next.length)
1257
+ changed = true;
1258
+ } else if (prevLength && next.length) {
1259
+ for (let i = 0, len = next.length; i < len; i++) {
1260
+ const item = getOverrideValue(previous, override, i);
1261
+ isWrappable(item) && applyState(next[i], wrap(item, target), keyFn, all);
1262
+ }
1263
+ }
1264
+ if (prevLength !== next.length) {
1265
+ changed = true;
1266
+ target[STORE_NODE].length?.write(next.length);
1267
+ }
1268
+ changed && target[STORE_NODE][$TRACK]?.write(void 0);
1269
+ return;
1270
+ }
1271
+ let nodes = target[STORE_NODE];
1272
+ if (nodes) {
1273
+ const tracked = nodes[$TRACK];
1274
+ const keys = tracked || all ? getAllKeys(previous, override, next) : Object.keys(nodes);
1275
+ for (let i = 0, len = keys.length; i < len; i++) {
1276
+ const key = keys[i];
1277
+ const node = nodes[key];
1278
+ const previousValue = unwrap(getOverrideValue(previous, override, key));
1279
+ let nextValue = unwrap(next[key]);
1280
+ if (previousValue === nextValue)
1281
+ continue;
1282
+ if (!previousValue || !isWrappable(previousValue) || keyFn(previousValue) != null && keyFn(previousValue) !== keyFn(nextValue)) {
1283
+ tracked?.write(void 0);
1284
+ node?.write(isWrappable(nextValue) ? wrap(nextValue, target) : nextValue);
1285
+ } else
1286
+ applyState(nextValue, wrap(previousValue, target), keyFn, all);
1287
+ }
1288
+ }
1289
+ if (nodes = target[STORE_HAS]) {
1290
+ const keys = Object.keys(nodes);
1291
+ for (let i = 0, len = keys.length; i < len; i++) {
1292
+ nodes[keys[i]].write(keys[i] in next);
1293
+ }
1294
+ }
1295
+ }
1296
+ function reconcile(value, key, all = false) {
1297
+ return (state) => {
1298
+ if (state == null)
1299
+ throw new Error("Cannot reconcile null or undefined state");
1300
+ const keyFn = typeof key === "string" ? (item) => item[key] : key;
1301
+ const eq = keyFn(state);
1302
+ if (eq !== void 0 && keyFn(value) !== keyFn(state))
1303
+ throw new Error("Cannot reconcile states with different identity");
1304
+ applyState(value, state, keyFn, all);
1305
+ };
1306
+ }
1307
+
1158
1308
  // src/store/projection.ts
1159
- function createProjection(fn, initialValue = {}) {
1309
+ function createProjection(fn, initialValue = {}, options) {
1160
1310
  let wrappedStore;
1161
1311
  const node = new FirewallComputation(() => {
1162
- storeSetter(wrappedStore, fn);
1312
+ storeSetter(wrappedStore, (s) => {
1313
+ const value = fn(s);
1314
+ if (value !== s && value !== void 0) {
1315
+ reconcile(value, options?.key || "id", options?.all)(s);
1316
+ }
1317
+ });
1163
1318
  });
1164
1319
  const wrappedMap = /* @__PURE__ */ new WeakMap();
1165
1320
  const traps = {
1166
1321
  ...storeTraps,
1167
1322
  get(target, property, receiver) {
1168
1323
  const o = getOwner();
1169
- (!o || o !== node) && node.wait();
1324
+ const n = getTransitionSource(node);
1325
+ (!o || o !== n) && n.wait();
1170
1326
  return storeTraps.get(target, property, receiver);
1171
1327
  }
1172
1328
  };
@@ -1387,14 +1543,29 @@ function storeSetter(store, fn) {
1387
1543
  Writing = /* @__PURE__ */ new Set();
1388
1544
  Writing.add(store);
1389
1545
  try {
1390
- fn(store);
1546
+ const value = fn(store);
1547
+ if (value !== store && value !== void 0) {
1548
+ if (Array.isArray(value)) {
1549
+ for (let i = 0, len = value.length; i < len; i++)
1550
+ store[i] = value[i];
1551
+ store.length = value.length;
1552
+ } else {
1553
+ const keys = /* @__PURE__ */ new Set([...Object.keys(store), ...Object.keys(value)]);
1554
+ keys.forEach((key) => {
1555
+ if (key in value)
1556
+ store[key] = value[key];
1557
+ else
1558
+ delete store[key];
1559
+ });
1560
+ }
1561
+ }
1391
1562
  } finally {
1392
1563
  Writing.clear();
1393
1564
  Writing = prevWriting;
1394
1565
  }
1395
1566
  }
1396
- function createStore(first, second) {
1397
- const derived = typeof first === "function", wrappedStore = derived ? createProjection(first, second) : wrap(first);
1567
+ function createStore(first, second, options) {
1568
+ const derived = typeof first === "function", wrappedStore = derived ? createProjection(first, second, options) : wrap(first);
1398
1569
  return [wrappedStore, (fn) => storeSetter(wrappedStore, fn)];
1399
1570
  }
1400
1571
  function recursivelyNotify(state, lookup) {
@@ -1458,134 +1629,6 @@ function deep(store) {
1458
1629
  return store[$DEEP];
1459
1630
  }
1460
1631
 
1461
- // src/store/reconcile.ts
1462
- function unwrap(value) {
1463
- return value?.[$TARGET]?.[STORE_NODE] ?? value;
1464
- }
1465
- function getOverrideValue(value, override, key) {
1466
- return override && key in override ? override[key] : value[key];
1467
- }
1468
- function getAllKeys(value, override, next) {
1469
- const keys = getKeys(value, override);
1470
- const nextKeys = Object.keys(next);
1471
- return Array.from(/* @__PURE__ */ new Set([...keys, ...nextKeys]));
1472
- }
1473
- function applyState(next, state, keyFn, all) {
1474
- const target = state?.[$TARGET];
1475
- if (!target)
1476
- return;
1477
- const previous = target[STORE_VALUE];
1478
- const override = target[STORE_OVERRIDE];
1479
- if (next === previous && !override)
1480
- return;
1481
- (target[STORE_LOOKUP] || storeLookup).set(next, target[$PROXY]);
1482
- target[STORE_VALUE] = next;
1483
- target[STORE_OVERRIDE] = void 0;
1484
- if (Array.isArray(previous)) {
1485
- let changed = false;
1486
- const prevLength = getOverrideValue(previous, override, "length");
1487
- if (next.length && prevLength && next[0] && keyFn(next[0]) != null) {
1488
- let i, j, start, end, newEnd, item, newIndicesNext, keyVal;
1489
- for (start = 0, end = Math.min(prevLength, next.length); start < end && ((item = getOverrideValue(previous, override, start)) === next[start] || item && next[start] && keyFn(item) === keyFn(next[start])); start++) {
1490
- applyState(next[start], wrap(item, target), keyFn, all);
1491
- }
1492
- const temp = new Array(next.length), newIndices = /* @__PURE__ */ new Map();
1493
- for (end = prevLength - 1, newEnd = next.length - 1; end >= start && newEnd >= start && ((item = getOverrideValue(previous, override, end)) === next[newEnd] || item && next[newEnd] && keyFn(item) === keyFn(next[newEnd])); end--, newEnd--) {
1494
- temp[newEnd] = item;
1495
- }
1496
- if (start > newEnd || start > end) {
1497
- for (j = start; j <= newEnd; j++) {
1498
- changed = true;
1499
- target[STORE_NODE][j]?.write(wrap(next[j], target));
1500
- }
1501
- for (; j < next.length; j++) {
1502
- changed = true;
1503
- const wrapped = wrap(temp[j], target);
1504
- target[STORE_NODE][j]?.write(wrapped);
1505
- applyState(next[j], wrapped, keyFn, all);
1506
- }
1507
- changed && target[STORE_NODE][$TRACK]?.write(void 0);
1508
- prevLength !== next.length && target[STORE_NODE].length?.write(next.length);
1509
- return;
1510
- }
1511
- newIndicesNext = new Array(newEnd + 1);
1512
- for (j = newEnd; j >= start; j--) {
1513
- item = next[j];
1514
- keyVal = item ? keyFn(item) : item;
1515
- i = newIndices.get(keyVal);
1516
- newIndicesNext[j] = i === void 0 ? -1 : i;
1517
- newIndices.set(keyVal, j);
1518
- }
1519
- for (i = start; i <= end; i++) {
1520
- item = getOverrideValue(previous, override, i);
1521
- keyVal = item ? keyFn(item) : item;
1522
- j = newIndices.get(keyVal);
1523
- if (j !== void 0 && j !== -1) {
1524
- temp[j] = item;
1525
- j = newIndicesNext[j];
1526
- newIndices.set(keyVal, j);
1527
- }
1528
- }
1529
- for (j = start; j < next.length; j++) {
1530
- if (j in temp) {
1531
- const wrapped = wrap(temp[j], target);
1532
- target[STORE_NODE][j]?.write(wrapped);
1533
- applyState(next[j], wrapped, keyFn, all);
1534
- } else
1535
- target[STORE_NODE][j]?.write(wrap(next[j], target));
1536
- }
1537
- if (start < next.length)
1538
- changed = true;
1539
- } else if (prevLength && next.length) {
1540
- for (let i = 0, len = next.length; i < len; i++) {
1541
- const item = getOverrideValue(previous, override, i);
1542
- isWrappable(item) && applyState(next[i], wrap(item, target), keyFn, all);
1543
- }
1544
- }
1545
- if (prevLength !== next.length) {
1546
- changed = true;
1547
- target[STORE_NODE].length?.write(next.length);
1548
- }
1549
- changed && target[STORE_NODE][$TRACK]?.write(void 0);
1550
- return;
1551
- }
1552
- let nodes = target[STORE_NODE];
1553
- if (nodes) {
1554
- const tracked = nodes[$TRACK];
1555
- const keys = tracked || all ? getAllKeys(previous, override, next) : Object.keys(nodes);
1556
- for (let i = 0, len = keys.length; i < len; i++) {
1557
- const key = keys[i];
1558
- const node = nodes[key];
1559
- const previousValue = unwrap(getOverrideValue(previous, override, key));
1560
- let nextValue = unwrap(next[key]);
1561
- if (previousValue === nextValue)
1562
- continue;
1563
- if (!previousValue || !isWrappable(previousValue) || keyFn(previousValue) != null && keyFn(previousValue) !== keyFn(nextValue)) {
1564
- tracked?.write(void 0);
1565
- node?.write(isWrappable(nextValue) ? wrap(nextValue, target) : nextValue);
1566
- } else
1567
- applyState(nextValue, wrap(previousValue, target), keyFn, all);
1568
- }
1569
- }
1570
- if (nodes = target[STORE_HAS]) {
1571
- const keys = Object.keys(nodes);
1572
- for (let i = 0, len = keys.length; i < len; i++) {
1573
- nodes[keys[i]].write(keys[i] in next);
1574
- }
1575
- }
1576
- }
1577
- function reconcile(value, key, all = false) {
1578
- return (state) => {
1579
- if (state == null)
1580
- throw new Error("Cannot reconcile null or undefined state");
1581
- const keyFn = typeof key === "string" ? (item) => item[key] : key;
1582
- const eq = keyFn(state);
1583
- if (eq !== void 0 && keyFn(value) !== keyFn(state))
1584
- throw new Error("Cannot reconcile states with different identity");
1585
- applyState(value, state, keyFn, all);
1586
- };
1587
- }
1588
-
1589
1632
  // src/store/utils.ts
1590
1633
  function snapshot(item, map, lookup) {
1591
1634
  let target, isArray, override, result, unwrapped, v;
@@ -1844,14 +1887,16 @@ function createAsync(compute2, value, options) {
1844
1887
  }
1845
1888
  let abort = false;
1846
1889
  onCleanup(() => abort = true);
1847
- const transition2 = ActiveTransition;
1890
+ let transition2 = ActiveTransition;
1848
1891
  if (isPromise) {
1849
1892
  source.then(
1850
1893
  (value3) => {
1851
1894
  if (abort)
1852
1895
  return;
1853
1896
  if (transition2)
1854
- return transition2.runTransition(() => node.write(value3, 0, true), true);
1897
+ return transition2.runTransition(() => {
1898
+ node.write(value3, 0, true);
1899
+ }, true);
1855
1900
  node.write(value3, 0, true);
1856
1901
  },
1857
1902
  (error) => {
@@ -1868,12 +1913,22 @@ function createAsync(compute2, value, options) {
1868
1913
  for await (let value3 of source) {
1869
1914
  if (abort)
1870
1915
  return;
1916
+ if (transition2)
1917
+ return transition2.runTransition(() => {
1918
+ node.write(value3, 0, true);
1919
+ transition2 = null;
1920
+ }, true);
1871
1921
  node.write(value3, 0, true);
1872
1922
  }
1873
1923
  } catch (error) {
1874
1924
  if (abort)
1875
1925
  return;
1876
- node.write(error, ERROR_BIT);
1926
+ if (transition2)
1927
+ return transition2.runTransition(() => {
1928
+ node._setError(error);
1929
+ transition2 = null;
1930
+ }, true);
1931
+ node._setError(error);
1877
1932
  }
1878
1933
  })();
1879
1934
  }
@@ -1931,70 +1986,56 @@ function resolve(fn) {
1931
1986
  });
1932
1987
  });
1933
1988
  }
1934
- function tryCatch(fn) {
1935
- try {
1936
- const v = fn();
1937
- if (v instanceof Promise) {
1938
- return v.then(
1939
- (v2) => [void 0, v2],
1940
- (e) => {
1941
- if (e instanceof NotReadyError)
1942
- throw e;
1943
- return [e];
1944
- }
1945
- );
1946
- }
1947
- return [void 0, v];
1948
- } catch (e) {
1949
- if (e instanceof NotReadyError)
1950
- throw e;
1951
- return [e];
1989
+ function createPending() {
1990
+ const node = new Computation(false, null);
1991
+ const reset = () => node.write(false);
1992
+ function write(v) {
1993
+ if (!ActiveTransition)
1994
+ return v;
1995
+ ActiveTransition.addOptimistic(reset);
1996
+ queueMicrotask(() => reset._transition && node.write(v));
1997
+ }
1998
+ function read() {
1999
+ node.read();
2000
+ return !ActiveTransition;
1952
2001
  }
2002
+ return [read, write];
1953
2003
  }
1954
- function createOptimistic(initial, compute2, key) {
1955
- if (!compute2) {
1956
- let write2 = function(v) {
1957
- if (!ActiveTransition)
1958
- throw new Error("createOptimistic can only be updated inside a transition");
1959
- ActiveTransition.addOptimistic(reset2);
1960
- queueMicrotask(() => reset2._transition && node.write(v));
1961
- };
1962
- var write = write2;
1963
- const node = new Computation(initial, null);
1964
- const reset2 = () => node.write(initial);
1965
- return [node.read.bind(node), write2];
2004
+ function useTransition() {
2005
+ const [pending, setPending] = createPending();
2006
+ function start(fn) {
2007
+ transition((resume) => {
2008
+ setPending(true);
2009
+ return fn(resume);
2010
+ });
1966
2011
  }
2012
+ return [pending, start];
2013
+ }
2014
+ function createOptimistic(first, second, options) {
1967
2015
  let store, setStore;
1968
- if (typeof initial === "function") {
1969
- [store, setStore] = createStore(
1970
- (s) => {
1971
- const value = initial();
1972
- if (!ActiveTransition)
1973
- reconcile({ value }, key)(s);
1974
- },
1975
- { value: void 0 }
1976
- );
2016
+ if (typeof first === "function") {
2017
+ [store, setStore] = createStore((s) => {
2018
+ const value = first(s);
2019
+ if (!ActiveTransition)
2020
+ return value;
2021
+ ActiveTransition.addOptimistic(reset);
2022
+ }, {});
1977
2023
  } else
1978
- [store, setStore] = createStore({ value: initial });
2024
+ [store, setStore] = createStore(first);
1979
2025
  const reset = () => setStore(
1980
2026
  (s) => reconcile(
1981
- { value: typeof initial === "function" ? initial() : initial },
1982
- key
2027
+ { value: typeof first === "function" ? first(second) : first },
2028
+ options?.key || "id",
2029
+ options?.all
1983
2030
  )(s)
1984
2031
  );
1985
- let lastChange = void 0;
1986
2032
  function write(v) {
1987
2033
  if (!ActiveTransition)
1988
2034
  throw new Error("createOptimistic can only be updated inside a transition");
1989
2035
  ActiveTransition.addOptimistic(reset);
1990
- queueMicrotask(
1991
- () => reset._transition && setStore((s) => {
1992
- lastChange = typeof v === "function" ? v(lastChange) : v;
1993
- compute2(s.value, lastChange);
1994
- })
1995
- );
2036
+ queueMicrotask(() => reset._transition && setStore(v));
1996
2037
  }
1997
- return [() => store.value, write];
2038
+ return [store, write];
1998
2039
  }
1999
2040
 
2000
2041
  // src/map.ts
@@ -2404,4 +2445,4 @@ function flattenArray(children, results = [], options) {
2404
2445
  return needsUnwrap;
2405
2446
  }
2406
2447
 
2407
- export { $PROXY, $TARGET, $TRACK, Computation, ContextNotFoundError, NoOwnerError, NotReadyError, Owner, Queue, SUPPORTS_PROXY, createAsync, createBoundary, createContext, createEffect, createErrorBoundary, createMemo, createOptimistic, createProjection, createRenderEffect, createRoot, createSignal, createStore, createSuspense, deep, flatten, flush, getContext, getObserver, getOwner, hasContext, hasUpdated, isEqual, isPending, isWrappable, latest, mapArray, merge, omit, onCleanup, reconcile, repeat, resolve, runWithObserver, runWithOwner, setContext, snapshot, transition, tryCatch, untrack };
2448
+ export { $PROXY, $TARGET, $TRACK, Computation, ContextNotFoundError, NoOwnerError, NotReadyError, Owner, Queue, SUPPORTS_PROXY, createAsync, createBoundary, createContext, createEffect, createErrorBoundary, createMemo, createOptimistic, createProjection, createRenderEffect, createRoot, createSignal, createStore, createSuspense, deep, flatten, flush, getContext, getObserver, getOwner, hasContext, hasUpdated, isEqual, isPending, isWrappable, latest, mapArray, merge, omit, onCleanup, reconcile, repeat, resolve, runWithObserver, runWithOwner, setContext, snapshot, transition, untrack, useTransition };