@solidjs/signals 0.5.0 → 0.6.1

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
  };
@@ -1408,8 +1564,8 @@ function storeSetter(store, fn) {
1408
1564
  Writing = prevWriting;
1409
1565
  }
1410
1566
  }
1411
- function createStore(first, second) {
1412
- 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);
1413
1569
  return [wrappedStore, (fn) => storeSetter(wrappedStore, fn)];
1414
1570
  }
1415
1571
  function recursivelyNotify(state, lookup) {
@@ -1473,134 +1629,6 @@ function deep(store) {
1473
1629
  return store[$DEEP];
1474
1630
  }
1475
1631
 
1476
- // src/store/reconcile.ts
1477
- function unwrap(value) {
1478
- return value?.[$TARGET]?.[STORE_NODE] ?? value;
1479
- }
1480
- function getOverrideValue(value, override, key) {
1481
- return override && key in override ? override[key] : value[key];
1482
- }
1483
- function getAllKeys(value, override, next) {
1484
- const keys = getKeys(value, override);
1485
- const nextKeys = Object.keys(next);
1486
- return Array.from(/* @__PURE__ */ new Set([...keys, ...nextKeys]));
1487
- }
1488
- function applyState(next, state, keyFn, all) {
1489
- const target = state?.[$TARGET];
1490
- if (!target)
1491
- return;
1492
- const previous = target[STORE_VALUE];
1493
- const override = target[STORE_OVERRIDE];
1494
- if (next === previous && !override)
1495
- return;
1496
- (target[STORE_LOOKUP] || storeLookup).set(next, target[$PROXY]);
1497
- target[STORE_VALUE] = next;
1498
- target[STORE_OVERRIDE] = void 0;
1499
- if (Array.isArray(previous)) {
1500
- let changed = false;
1501
- const prevLength = getOverrideValue(previous, override, "length");
1502
- if (next.length && prevLength && next[0] && keyFn(next[0]) != null) {
1503
- let i, j, start, end, newEnd, item, newIndicesNext, keyVal;
1504
- 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++) {
1505
- applyState(next[start], wrap(item, target), keyFn, all);
1506
- }
1507
- const temp = new Array(next.length), newIndices = /* @__PURE__ */ new Map();
1508
- 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--) {
1509
- temp[newEnd] = item;
1510
- }
1511
- if (start > newEnd || start > end) {
1512
- for (j = start; j <= newEnd; j++) {
1513
- changed = true;
1514
- target[STORE_NODE][j]?.write(wrap(next[j], target));
1515
- }
1516
- for (; j < next.length; j++) {
1517
- changed = true;
1518
- const wrapped = wrap(temp[j], target);
1519
- target[STORE_NODE][j]?.write(wrapped);
1520
- applyState(next[j], wrapped, keyFn, all);
1521
- }
1522
- changed && target[STORE_NODE][$TRACK]?.write(void 0);
1523
- prevLength !== next.length && target[STORE_NODE].length?.write(next.length);
1524
- return;
1525
- }
1526
- newIndicesNext = new Array(newEnd + 1);
1527
- for (j = newEnd; j >= start; j--) {
1528
- item = next[j];
1529
- keyVal = item ? keyFn(item) : item;
1530
- i = newIndices.get(keyVal);
1531
- newIndicesNext[j] = i === void 0 ? -1 : i;
1532
- newIndices.set(keyVal, j);
1533
- }
1534
- for (i = start; i <= end; i++) {
1535
- item = getOverrideValue(previous, override, i);
1536
- keyVal = item ? keyFn(item) : item;
1537
- j = newIndices.get(keyVal);
1538
- if (j !== void 0 && j !== -1) {
1539
- temp[j] = item;
1540
- j = newIndicesNext[j];
1541
- newIndices.set(keyVal, j);
1542
- }
1543
- }
1544
- for (j = start; j < next.length; j++) {
1545
- if (j in temp) {
1546
- const wrapped = wrap(temp[j], target);
1547
- target[STORE_NODE][j]?.write(wrapped);
1548
- applyState(next[j], wrapped, keyFn, all);
1549
- } else
1550
- target[STORE_NODE][j]?.write(wrap(next[j], target));
1551
- }
1552
- if (start < next.length)
1553
- changed = true;
1554
- } else if (prevLength && next.length) {
1555
- for (let i = 0, len = next.length; i < len; i++) {
1556
- const item = getOverrideValue(previous, override, i);
1557
- isWrappable(item) && applyState(next[i], wrap(item, target), keyFn, all);
1558
- }
1559
- }
1560
- if (prevLength !== next.length) {
1561
- changed = true;
1562
- target[STORE_NODE].length?.write(next.length);
1563
- }
1564
- changed && target[STORE_NODE][$TRACK]?.write(void 0);
1565
- return;
1566
- }
1567
- let nodes = target[STORE_NODE];
1568
- if (nodes) {
1569
- const tracked = nodes[$TRACK];
1570
- const keys = tracked || all ? getAllKeys(previous, override, next) : Object.keys(nodes);
1571
- for (let i = 0, len = keys.length; i < len; i++) {
1572
- const key = keys[i];
1573
- const node = nodes[key];
1574
- const previousValue = unwrap(getOverrideValue(previous, override, key));
1575
- let nextValue = unwrap(next[key]);
1576
- if (previousValue === nextValue)
1577
- continue;
1578
- if (!previousValue || !isWrappable(previousValue) || keyFn(previousValue) != null && keyFn(previousValue) !== keyFn(nextValue)) {
1579
- tracked?.write(void 0);
1580
- node?.write(isWrappable(nextValue) ? wrap(nextValue, target) : nextValue);
1581
- } else
1582
- applyState(nextValue, wrap(previousValue, target), keyFn, all);
1583
- }
1584
- }
1585
- if (nodes = target[STORE_HAS]) {
1586
- const keys = Object.keys(nodes);
1587
- for (let i = 0, len = keys.length; i < len; i++) {
1588
- nodes[keys[i]].write(keys[i] in next);
1589
- }
1590
- }
1591
- }
1592
- function reconcile(value, key, all = false) {
1593
- return (state) => {
1594
- if (state == null)
1595
- throw new Error("Cannot reconcile null or undefined state");
1596
- const keyFn = typeof key === "string" ? (item) => item[key] : key;
1597
- const eq = keyFn(state);
1598
- if (eq !== void 0 && keyFn(value) !== keyFn(state))
1599
- throw new Error("Cannot reconcile states with different identity");
1600
- applyState(value, state, keyFn, all);
1601
- };
1602
- }
1603
-
1604
1632
  // src/store/utils.ts
1605
1633
  function snapshot(item, map, lookup) {
1606
1634
  let target, isArray, override, result, unwrapped, v;
@@ -1859,14 +1887,16 @@ function createAsync(compute2, value, options) {
1859
1887
  }
1860
1888
  let abort = false;
1861
1889
  onCleanup(() => abort = true);
1862
- const transition2 = ActiveTransition;
1890
+ let transition2 = ActiveTransition;
1863
1891
  if (isPromise) {
1864
1892
  source.then(
1865
1893
  (value3) => {
1866
1894
  if (abort)
1867
1895
  return;
1868
1896
  if (transition2)
1869
- return transition2.runTransition(() => node.write(value3, 0, true), true);
1897
+ return transition2.runTransition(() => {
1898
+ node.write(value3, 0, true);
1899
+ }, true);
1870
1900
  node.write(value3, 0, true);
1871
1901
  },
1872
1902
  (error) => {
@@ -1883,12 +1913,22 @@ function createAsync(compute2, value, options) {
1883
1913
  for await (let value3 of source) {
1884
1914
  if (abort)
1885
1915
  return;
1916
+ if (transition2)
1917
+ return transition2.runTransition(() => {
1918
+ node.write(value3, 0, true);
1919
+ transition2 = null;
1920
+ }, true);
1886
1921
  node.write(value3, 0, true);
1887
1922
  }
1888
1923
  } catch (error) {
1889
1924
  if (abort)
1890
1925
  return;
1891
- 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);
1892
1932
  }
1893
1933
  })();
1894
1934
  }
@@ -1946,55 +1986,56 @@ function resolve(fn) {
1946
1986
  });
1947
1987
  });
1948
1988
  }
1949
- function tryCatch(fn) {
1950
- try {
1951
- const v = fn();
1952
- if (v instanceof Promise) {
1953
- return v.then(
1954
- (v2) => [void 0, v2],
1955
- (e) => {
1956
- if (e instanceof NotReadyError)
1957
- throw e;
1958
- return [e];
1959
- }
1960
- );
1961
- }
1962
- return [void 0, v];
1963
- } catch (e) {
1964
- if (e instanceof NotReadyError)
1965
- throw e;
1966
- return [e];
1967
- }
1968
- }
1969
- function createOptimistic(initial) {
1970
- const node = new Computation(initial, null);
1971
- const reset = () => node.write(initial);
1972
- function write(v) {
1989
+ function createPending() {
1990
+ const node = new Computation(false, null);
1991
+ const reset = () => node.write(false);
1992
+ function write() {
1973
1993
  if (!ActiveTransition)
1974
- throw new Error("createOptimistic can only be updated inside a transition");
1994
+ return false;
1975
1995
  ActiveTransition.addOptimistic(reset);
1976
- queueMicrotask(() => reset._transition && node.write(v));
1996
+ queueMicrotask(() => reset._transition && node.write(true));
1997
+ }
1998
+ function read() {
1999
+ const v = node.read();
2000
+ return ActiveTransition ? false : v;
1977
2001
  }
1978
- return [node.read.bind(node), write];
2002
+ return [read, write];
1979
2003
  }
1980
- function createOptimisticStore(first, second) {
2004
+ function useTransition() {
2005
+ const [pending, setPending] = createPending();
2006
+ function start(fn) {
2007
+ transition((resume) => {
2008
+ setPending(true);
2009
+ return fn(resume);
2010
+ });
2011
+ }
2012
+ return [pending, start];
2013
+ }
2014
+ function createOptimistic(first, second, options) {
1981
2015
  let store, setStore;
1982
2016
  if (typeof first === "function") {
1983
2017
  [store, setStore] = createStore((s) => {
1984
2018
  const value = first(s);
1985
2019
  if (!ActiveTransition)
1986
2020
  return value;
2021
+ ActiveTransition.addOptimistic(reset);
1987
2022
  }, {});
1988
2023
  } else
1989
2024
  [store, setStore] = createStore(first);
1990
- const reset = () => setStore(() => typeof first === "function" ? first(second) : first);
2025
+ const reset = () => setStore(
2026
+ (s) => reconcile(
2027
+ { value: typeof first === "function" ? first(second) : first },
2028
+ options?.key || "id",
2029
+ options?.all
2030
+ )(s)
2031
+ );
1991
2032
  function write(v) {
1992
2033
  if (!ActiveTransition)
1993
2034
  throw new Error("createOptimistic can only be updated inside a transition");
1994
2035
  ActiveTransition.addOptimistic(reset);
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, createOptimisticStore, 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 };