sibujs 4.5.0 → 4.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.
Files changed (109) hide show
  1. package/dist/browser.cjs +309 -129
  2. package/dist/browser.d.cts +46 -14
  3. package/dist/browser.d.ts +46 -14
  4. package/dist/browser.js +8 -6
  5. package/dist/build.cjs +184 -72
  6. package/dist/build.js +15 -16
  7. package/dist/cdn.dev.global.js +12 -12
  8. package/dist/cdn.full.dev.global.js +11 -11
  9. package/dist/cdn.full.global.js +10 -10
  10. package/dist/cdn.global.js +12 -12
  11. package/dist/{chunk-IXKSNWV5.js → chunk-2INLLLMZ.js} +1 -1
  12. package/dist/chunk-3ISI6ACU.js +44 -0
  13. package/dist/{chunk-ONOHFDLG.js → chunk-47M47FOM.js} +3 -3
  14. package/dist/chunk-5HZXGZ6T.js +24 -0
  15. package/dist/{chunk-KKLW7YWL.js → chunk-5MT6SJ3P.js} +275 -144
  16. package/dist/{chunk-UGRX3S57.js → chunk-5Q4R7HCL.js} +12 -3
  17. package/dist/{chunk-S373NSMK.js → chunk-7GQCWFOE.js} +150 -59
  18. package/dist/{chunk-FTIR4QW2.js → chunk-7NCARGJW.js} +6 -8
  19. package/dist/{chunk-5DXA2J44.js → chunk-7XHATCIH.js} +5 -2
  20. package/dist/{chunk-VZKNK2V7.js → chunk-AIF3Z2T7.js} +296 -38
  21. package/dist/{chunk-4PMLNECI.js → chunk-BAAG6ZTI.js} +98 -29
  22. package/dist/{chunk-XZZOBQAY.js → chunk-D33YTSX5.js} +2 -2
  23. package/dist/{chunk-TBYTO6BS.js → chunk-DKGBBKOF.js} +136 -80
  24. package/dist/{chunk-NIOYEGBQ.js → chunk-HURREPU2.js} +27 -13
  25. package/dist/{chunk-GW3SCCZG.js → chunk-HYXDKS4N.js} +153 -110
  26. package/dist/chunk-J6FW5TV6.js +233 -0
  27. package/dist/{chunk-PCT43HW3.js → chunk-JSXPZCET.js} +1 -1
  28. package/dist/chunk-NYNYSPK7.js +318 -0
  29. package/dist/{chunk-RJE2BNI4.js → chunk-ORMZXBKQ.js} +108 -45
  30. package/dist/{chunk-OMJJM3KM.js → chunk-OXUY2A6L.js} +287 -130
  31. package/dist/{chunk-3JZ4L5TJ.js → chunk-PK6FK2G2.js} +181 -66
  32. package/dist/{chunk-RBTPLM32.js → chunk-QE4TTDU3.js} +2 -2
  33. package/dist/{chunk-2DCGACUU.js → chunk-SXXVZMKZ.js} +251 -66
  34. package/dist/{chunk-R25EFXXC.js → chunk-TUCPL2HB.js} +3 -3
  35. package/dist/{chunk-7LN645I6.js → chunk-UZQ6ALFS.js} +3 -3
  36. package/dist/{chunk-KEISJXBU.js → chunk-VVWPJ543.js} +6 -8
  37. package/dist/{chunk-RIXRAYIU.js → chunk-XC4MEKGA.js} +3 -3
  38. package/dist/{chunk-B3WHI2QA.js → chunk-XRRZKZYX.js} +55 -31
  39. package/dist/{contracts-DBdg9J_a.d.cts → contracts-DRIuclVT.d.cts} +10 -2
  40. package/dist/{contracts-DBdg9J_a.d.ts → contracts-DRIuclVT.d.ts} +10 -2
  41. package/dist/{customElement-OB9CIsc5.d.cts → customElement-MmInOW1U.d.cts} +21 -0
  42. package/dist/{customElement-OB9CIsc5.d.ts → customElement-MmInOW1U.d.ts} +21 -0
  43. package/dist/data.cjs +213 -117
  44. package/dist/data.d.cts +47 -9
  45. package/dist/data.d.ts +47 -9
  46. package/dist/data.js +12 -9
  47. package/dist/devtools.cjs +81 -57
  48. package/dist/devtools.js +7 -8
  49. package/dist/dispose-GEIG2KOF.js +28 -0
  50. package/dist/ecosystem.cjs +309 -104
  51. package/dist/ecosystem.d.cts +19 -3
  52. package/dist/ecosystem.d.ts +19 -3
  53. package/dist/ecosystem.js +12 -12
  54. package/dist/extras.cjs +2133 -863
  55. package/dist/extras.d.cts +10 -9
  56. package/dist/extras.d.ts +10 -9
  57. package/dist/extras.js +39 -28
  58. package/dist/index.cjs +184 -72
  59. package/dist/index.d.cts +22 -5
  60. package/dist/index.d.ts +22 -5
  61. package/dist/index.js +24 -27
  62. package/dist/motion.cjs +107 -41
  63. package/dist/motion.js +5 -5
  64. package/dist/patterns.cjs +317 -39
  65. package/dist/patterns.d.cts +27 -9
  66. package/dist/patterns.d.ts +27 -9
  67. package/dist/patterns.js +8 -8
  68. package/dist/performance.cjs +308 -216
  69. package/dist/performance.d.cts +2 -2
  70. package/dist/performance.d.ts +2 -2
  71. package/dist/performance.js +8 -9
  72. package/dist/plugin-DVgSnTfK.d.cts +112 -0
  73. package/dist/plugin-DVgSnTfK.d.ts +112 -0
  74. package/dist/plugins.cjs +549 -202
  75. package/dist/plugins.d.cts +3 -3
  76. package/dist/plugins.d.ts +3 -3
  77. package/dist/plugins.js +35 -23
  78. package/dist/signal-EotCj4hS.d.cts +110 -0
  79. package/dist/signal-EotCj4hS.d.ts +110 -0
  80. package/dist/{ssr-BiPRdZ6n.d.cts → ssr-Bli9XRW5.d.cts} +5 -0
  81. package/dist/{ssr-BiPRdZ6n.d.ts → ssr-Bli9XRW5.d.ts} +5 -0
  82. package/dist/{ssr-Y7XOEPEN.js → ssr-XOTUASDO.js} +4 -5
  83. package/dist/ssr.cjs +176 -72
  84. package/dist/ssr.d.cts +9 -3
  85. package/dist/ssr.d.ts +9 -3
  86. package/dist/ssr.js +11 -12
  87. package/dist/{startup-BMpaiMhP.d.ts → startup-BLfSeL15.d.cts} +73 -22
  88. package/dist/{startup-BMpaiMhP.d.cts → startup-BLfSeL15.d.ts} +73 -22
  89. package/dist/{tagFactory-DVoDpHye.d.ts → tagFactory-DFstCLQV.d.cts} +2 -100
  90. package/dist/{tagFactory-DVoDpHye.d.cts → tagFactory-DkaNVUNV.d.ts} +2 -100
  91. package/dist/testing.cjs +2484 -2185
  92. package/dist/testing.d.cts +56 -5
  93. package/dist/testing.d.ts +56 -5
  94. package/dist/testing.js +580 -307
  95. package/dist/ui.cjs +707 -317
  96. package/dist/ui.d.cts +40 -7
  97. package/dist/ui.d.ts +40 -7
  98. package/dist/ui.js +151 -56
  99. package/dist/widgets.cjs +246 -278
  100. package/dist/widgets.js +9 -10
  101. package/package.json +1 -1
  102. package/dist/chunk-2WLZ6757.js +0 -149
  103. package/dist/chunk-CCSJMTRN.js +0 -15
  104. package/dist/chunk-QKRPLZ2V.js +0 -108
  105. package/dist/chunk-VUF4ALSW.js +0 -60
  106. package/dist/chunk-WWV3SJ3L.js +0 -131
  107. package/dist/dispose-46BOMMQJ.js +0 -19
  108. package/dist/plugin-D30wlGW5.d.cts +0 -71
  109. package/dist/plugin-D30wlGW5.d.ts +0 -71
package/dist/patterns.cjs CHANGED
@@ -147,6 +147,25 @@ function reportError(error, context) {
147
147
  });
148
148
  }
149
149
 
150
+ // src/core/rendering/dispose.ts
151
+ function resolveCapture(capture) {
152
+ let frame = capture;
153
+ while (frame?.closed) frame = frame.forwardTo;
154
+ return frame ?? null;
155
+ }
156
+ var registrationCaptures = [];
157
+ function currentDisposerCapture() {
158
+ return resolveCapture(registrationCaptures[registrationCaptures.length - 1]);
159
+ }
160
+ function beginDisposerCapture(capture) {
161
+ if (capture === null && registrationCaptures.length === 0) return false;
162
+ registrationCaptures.push(resolveCapture(capture));
163
+ return true;
164
+ }
165
+ function endDisposerCapture() {
166
+ registrationCaptures.pop();
167
+ }
168
+
150
169
  // src/reactivity/track-core.ts
151
170
  var POOL_MAX = 4096;
152
171
  var nodePool = [];
@@ -305,6 +324,7 @@ function retrack(effectFn, subscriber) {
305
324
  }
306
325
  currentSubscriber = subscriber;
307
326
  const sub = subscriber;
327
+ if (sub._cap === void 0) sub._cap = currentDisposerCapture();
308
328
  const epoch = ++subscriberEpochCounter;
309
329
  sub._epoch = epoch;
310
330
  sub._structDirty = false;
@@ -496,7 +516,12 @@ function drainQueue() {
496
516
  quarantined.add(sub);
497
517
  continue;
498
518
  }
499
- safeInvoke(sub);
519
+ const pushed = beginDisposerCapture(sub._cap ?? null);
520
+ try {
521
+ safeInvoke(sub);
522
+ } finally {
523
+ if (pushed) endDisposerCapture();
524
+ }
500
525
  }
501
526
  }
502
527
  function drainNotificationQueue() {
@@ -632,7 +657,7 @@ function forEachSubscriber(signal2, visit) {
632
657
  }
633
658
 
634
659
  // src/reactivity/track.ts
635
- var _runtimeVersion = true ? "4.5.0" : "dev";
660
+ var _runtimeVersion = true ? "4.6.0" : "dev";
636
661
  var REGISTRY_KEY = /* @__PURE__ */ Symbol.for("sibujs.reactive.v1");
637
662
  function resolveReactiveApi() {
638
663
  const g = globalThis;
@@ -826,12 +851,24 @@ function stripUnsafeKeys(obj) {
826
851
  function machine(config) {
827
852
  const [state2, setState] = signal(config.initial);
828
853
  const [context, setContext] = signal(config.context || {});
829
- const initialDef = config.states[config.initial];
830
- if (initialDef?.entry) {
831
- initialDef.entry(context());
854
+ let currentState = config.initial;
855
+ let currentContext = context();
856
+ const queue = [];
857
+ let processing = false;
858
+ function drain() {
859
+ processing = true;
860
+ try {
861
+ while (queue.length > 0) {
862
+ step(queue.shift());
863
+ }
864
+ } catch (err) {
865
+ queue.length = 0;
866
+ throw err;
867
+ } finally {
868
+ processing = false;
869
+ }
832
870
  }
833
- function send(event) {
834
- const currentState = state2();
871
+ function step(event) {
835
872
  const stateDef = config.states[currentState];
836
873
  if (!stateDef?.on) return;
837
874
  const transition = stateDef.on[event];
@@ -846,28 +883,51 @@ function machine(config) {
846
883
  guard = transition.guard;
847
884
  action = transition.action;
848
885
  }
849
- const ctx = context();
886
+ const ctx = currentContext;
850
887
  if (guard && !guard(ctx)) return;
851
888
  if (stateDef.exit) {
852
889
  stateDef.exit(ctx);
853
890
  }
891
+ let nextContext = ctx;
854
892
  if (action) {
855
893
  const rawPatch = action(ctx);
856
- const next = { ...ctx, ...stripUnsafeKeys(rawPatch) };
857
- setContext(next);
894
+ nextContext = { ...ctx, ...stripUnsafeKeys(rawPatch) };
858
895
  }
859
- setState(target);
896
+ currentState = target;
897
+ currentContext = nextContext;
898
+ batch(() => {
899
+ if (action) setContext(nextContext);
900
+ setState(target);
901
+ });
860
902
  const targetDef = config.states[target];
861
903
  if (targetDef?.entry) {
862
- targetDef.entry(context());
904
+ targetDef.entry(currentContext);
863
905
  }
864
906
  }
907
+ function send(event) {
908
+ queue.push(event);
909
+ if (processing) return;
910
+ drain();
911
+ }
912
+ const initialDef = config.states[config.initial];
913
+ if (initialDef?.entry) {
914
+ processing = true;
915
+ try {
916
+ initialDef.entry(currentContext);
917
+ } catch (err) {
918
+ queue.length = 0;
919
+ throw err;
920
+ } finally {
921
+ processing = false;
922
+ }
923
+ if (queue.length > 0) drain();
924
+ }
865
925
  function matches(s) {
866
926
  return state2() === s;
867
927
  }
868
928
  function can(event) {
869
- const currentState = state2();
870
- const stateDef = config.states[currentState];
929
+ const currentState2 = state2();
930
+ const stateDef = config.states[currentState2];
871
931
  if (!stateDef?.on) return false;
872
932
  const transition = stateDef.on[event];
873
933
  if (!transition) return false;
@@ -1523,6 +1583,9 @@ function derived(getter, options) {
1523
1583
 
1524
1584
  // src/patterns/timeTravel.ts
1525
1585
  function timeline(initial, maxHistory = 100) {
1586
+ if (!Number.isSafeInteger(maxHistory) || maxHistory < 1) {
1587
+ throw new RangeError(`[timeline] maxHistory must be a positive safe integer, got ${maxHistory}`);
1588
+ }
1526
1589
  const [history, setHistory] = signal([initial]);
1527
1590
  const [index, setIndex] = signal(0);
1528
1591
  const value = derived(() => history()[index()]);
@@ -1577,6 +1640,120 @@ function timeline(initial, maxHistory = 100) {
1577
1640
  return { value, set, undo, redo, canUndo, canRedo, history, index, reset, jumpTo, dispose };
1578
1641
  }
1579
1642
 
1643
+ // src/utils/adoption.ts
1644
+ var nativeThen = Promise.prototype.then;
1645
+ function probeNative(target, onRejected, onOpen) {
1646
+ let decided = false;
1647
+ const decide = (rejected) => {
1648
+ if (decided) return;
1649
+ decided = true;
1650
+ (rejected ? onRejected : onOpen)();
1651
+ };
1652
+ try {
1653
+ Reflect.apply(nativeThen, target, [void 0, () => decide(true)]);
1654
+ } catch {
1655
+ queueMicrotask(() => decide(true));
1656
+ return;
1657
+ }
1658
+ queueMicrotask(() => decide(false));
1659
+ }
1660
+ function adopt(value) {
1661
+ if (value === null || typeof value !== "object" && typeof value !== "function") return null;
1662
+ let then;
1663
+ try {
1664
+ then = value.then;
1665
+ } catch (error) {
1666
+ return {
1667
+ promise: Promise.reject(error),
1668
+ failedEarly: true,
1669
+ probe: (onRejected) => queueMicrotask(onRejected)
1670
+ };
1671
+ }
1672
+ if (typeof then !== "function") return null;
1673
+ let resolvePromise;
1674
+ let rejectPromise;
1675
+ const promise = new Promise((resolve, reject) => {
1676
+ resolvePromise = resolve;
1677
+ rejectPromise = reject;
1678
+ });
1679
+ let state2 = "invoking";
1680
+ let nativeTarget;
1681
+ const waiters = [];
1682
+ const transition = (next) => {
1683
+ state2 = next;
1684
+ if (next === "invoking") return;
1685
+ for (const waiter of waiters.splice(0)) waiter();
1686
+ };
1687
+ const fulfil = (result) => {
1688
+ resolvePromise(result);
1689
+ transition("fulfilled");
1690
+ };
1691
+ const fail = (error) => {
1692
+ rejectPromise(error);
1693
+ transition("rejected");
1694
+ };
1695
+ const follow = (result) => {
1696
+ if (result === promise) {
1697
+ fail(new TypeError("adopt: a thenable resolved to its own adoption"));
1698
+ return;
1699
+ }
1700
+ if (result === null || typeof result !== "object" && typeof result !== "function") {
1701
+ fulfil(result);
1702
+ return;
1703
+ }
1704
+ let nextThen;
1705
+ try {
1706
+ nextThen = result.then;
1707
+ } catch (error) {
1708
+ fail(error);
1709
+ return;
1710
+ }
1711
+ if (typeof nextThen !== "function") {
1712
+ fulfil(result);
1713
+ return;
1714
+ }
1715
+ invokeLater(result, nextThen);
1716
+ };
1717
+ const invokeLater = (target, targetThen) => {
1718
+ if (targetThen === nativeThen) {
1719
+ nativeTarget = target;
1720
+ transition("native");
1721
+ } else {
1722
+ transition("invoking");
1723
+ }
1724
+ queueMicrotask(() => {
1725
+ let done = false;
1726
+ const onResolve = (result) => {
1727
+ if (done) return;
1728
+ done = true;
1729
+ follow(result);
1730
+ };
1731
+ const onReject = (error) => {
1732
+ if (done) return;
1733
+ done = true;
1734
+ fail(error);
1735
+ };
1736
+ try {
1737
+ Reflect.apply(targetThen, target, [onResolve, onReject]);
1738
+ } catch (error) {
1739
+ onReject(error);
1740
+ }
1741
+ if (!done && state2 === "invoking") transition("pending");
1742
+ });
1743
+ };
1744
+ invokeLater(value, then);
1745
+ const probe = (onRejected, onOpen) => {
1746
+ const decide = () => {
1747
+ if (state2 === "native") probeNative(nativeTarget, onRejected, onOpen);
1748
+ else (state2 === "rejected" ? onRejected : onOpen)();
1749
+ };
1750
+ if (state2 === "native") probeNative(nativeTarget, onRejected, onOpen);
1751
+ else if (state2 === "invoking") waiters.push(decide);
1752
+ else queueMicrotask(state2 === "rejected" ? onRejected : onOpen);
1753
+ };
1754
+ return { promise, failedEarly: false, probe };
1755
+ }
1756
+
1580
1757
  // src/patterns/globalStore.ts
1581
1758
  function deepClone(value) {
1582
1759
  if (typeof structuredClone === "function") {
@@ -1611,8 +1788,51 @@ function deepClone(value) {
1611
1788
  function globalStore(config) {
1612
1789
  const initialState = deepClone(config.state);
1613
1790
  const [getState, setState] = signal({ ...initialState });
1614
- const listeners = /* @__PURE__ */ new Set();
1791
+ const subscriptions = /* @__PURE__ */ new Map();
1615
1792
  const middlewares = config.middleware || [];
1793
+ function notifyListeners(state2) {
1794
+ if (subscriptions.size === 0) return;
1795
+ for (const subscription of Array.from(subscriptions.values())) {
1796
+ if (!subscription.active) continue;
1797
+ try {
1798
+ subscription.callback(state2);
1799
+ } catch (err) {
1800
+ reportError(err, { phase: "event", name: "globalStore(subscribe)" });
1801
+ }
1802
+ }
1803
+ }
1804
+ const operations = [];
1805
+ let running = false;
1806
+ function perform(operation, rethrowOwn = true) {
1807
+ operations.push(operation);
1808
+ if (running) return;
1809
+ running = true;
1810
+ let callerError;
1811
+ let callerFailed = false;
1812
+ try {
1813
+ let first = true;
1814
+ let cursor = 0;
1815
+ while (cursor < operations.length) {
1816
+ const next = operations[cursor];
1817
+ operations[cursor++] = void 0;
1818
+ try {
1819
+ next();
1820
+ } catch (err) {
1821
+ if (first && rethrowOwn) {
1822
+ callerFailed = true;
1823
+ callerError = err;
1824
+ } else {
1825
+ reportError(err, { phase: "event", name: "globalStore(dispatch)" });
1826
+ }
1827
+ }
1828
+ first = false;
1829
+ }
1830
+ } finally {
1831
+ operations.length = 0;
1832
+ running = false;
1833
+ }
1834
+ if (callerFailed) throw callerError;
1835
+ }
1616
1836
  function dispatch(action, payload) {
1617
1837
  const actionFn = config.actions[action];
1618
1838
  if (!actionFn) throw new Error(`Unknown action: ${String(action)}`);
@@ -1621,38 +1841,96 @@ function globalStore(config) {
1621
1841
  const rawPatch = actionFn(current, payload);
1622
1842
  const patch = stripUnsafeKeys(rawPatch);
1623
1843
  setState({ ...current, ...patch });
1624
- const newState = getState();
1625
- for (const listener of listeners) {
1626
- listener(newState);
1627
- }
1844
+ notifyListeners(getState());
1628
1845
  };
1629
- if (middlewares.length === 0) {
1630
- execute();
1631
- return;
1632
- }
1633
- let index = 0;
1634
- const next = () => {
1635
- if (index < middlewares.length) {
1636
- const mw = middlewares[index++];
1637
- mw(getState(), String(action), payload, next);
1638
- } else {
1846
+ perform(() => {
1847
+ if (middlewares.length === 0) {
1639
1848
  execute();
1849
+ return;
1640
1850
  }
1641
- };
1642
- next();
1851
+ const runFrom = (index) => {
1852
+ if (index >= middlewares.length) {
1853
+ execute();
1854
+ return;
1855
+ }
1856
+ let called = false;
1857
+ let failed = false;
1858
+ let synchronous = true;
1859
+ const next = () => {
1860
+ if (failed && !called) {
1861
+ if (DEV)
1862
+ devWarn(
1863
+ `globalStore: middleware ${index} next() called after it failed for "${String(action)}"; ignored.`
1864
+ );
1865
+ called = true;
1866
+ return;
1867
+ }
1868
+ if (called) {
1869
+ if (DEV)
1870
+ devWarn(
1871
+ `globalStore: middleware ${index} next() called more than once for "${String(action)}"; ignored.`
1872
+ );
1873
+ return;
1874
+ }
1875
+ called = true;
1876
+ if (synchronous) {
1877
+ runFrom(index + 1);
1878
+ return;
1879
+ }
1880
+ const proceed = () => perform(() => runFrom(index + 1), false);
1881
+ if (!adoption) {
1882
+ proceed();
1883
+ return;
1884
+ }
1885
+ adoption.probe(() => {
1886
+ failed = true;
1887
+ if (DEV)
1888
+ devWarn(
1889
+ `globalStore: middleware ${index} next() called after it failed for "${String(action)}"; ignored.`
1890
+ );
1891
+ }, proceed);
1892
+ };
1893
+ let adoption = null;
1894
+ try {
1895
+ adoption = adopt(middlewares[index](getState(), String(action), payload, next));
1896
+ } catch (err) {
1897
+ failed = true;
1898
+ throw err;
1899
+ } finally {
1900
+ synchronous = false;
1901
+ }
1902
+ if (adoption) {
1903
+ if (adoption.failedEarly) failed = true;
1904
+ adoption.promise.then(void 0, (err) => {
1905
+ failed = true;
1906
+ reportError(err, { phase: "async", name: "globalStore(middleware)" });
1907
+ });
1908
+ }
1909
+ };
1910
+ runFrom(0);
1911
+ });
1643
1912
  }
1644
1913
  function select(selector) {
1645
1914
  return () => selector(getState());
1646
1915
  }
1647
1916
  function subscribe(callback) {
1648
- listeners.add(callback);
1649
- return () => listeners.delete(callback);
1917
+ let subscription = subscriptions.get(callback);
1918
+ if (!subscription) {
1919
+ subscription = { callback, active: true };
1920
+ subscriptions.set(callback, subscription);
1921
+ }
1922
+ const own = subscription;
1923
+ return () => {
1924
+ if (subscriptions.get(callback) !== own) return;
1925
+ own.active = false;
1926
+ subscriptions.delete(callback);
1927
+ };
1650
1928
  }
1651
1929
  function reset() {
1652
- setState({ ...initialState });
1653
- for (const listener of listeners) {
1654
- listener(getState());
1655
- }
1930
+ perform(() => {
1931
+ setState({ ...initialState });
1932
+ notifyListeners(getState());
1933
+ });
1656
1934
  }
1657
1935
  return { getState, select, dispatch, subscribe, reset };
1658
1936
  }
@@ -1776,7 +2054,7 @@ function validateProps(props, schema) {
1776
2054
  const errors = [];
1777
2055
  for (const [key, def] of Object.entries(schema)) {
1778
2056
  const propDef = typeof def === "function" ? { type: def } : def;
1779
- if (result[key] == null && propDef.default !== void 0) {
2057
+ if (result[key] === void 0 && propDef.default !== void 0) {
1780
2058
  result[key] = typeof propDef.default === "function" ? propDef.default() : propDef.default;
1781
2059
  }
1782
2060
  if (propDef.required && result[key] == null) {
@@ -1802,7 +2080,7 @@ ${errors.map((e) => ` - ${e}`).join("\n")}`);
1802
2080
  for (const [key, def] of Object.entries(schema)) {
1803
2081
  if (typeof def === "function") continue;
1804
2082
  const fallback = def.default;
1805
- if (result[key] == null && fallback !== void 0) {
2083
+ if (result[key] === void 0 && fallback !== void 0) {
1806
2084
  result[key] = typeof fallback === "function" ? fallback() : fallback;
1807
2085
  }
1808
2086
  }
@@ -1,4 +1,4 @@
1
- export { C as ComponentProps, P as PropDef, a as PropSchema, R as RenderProp, V as Validator, b as assertType, c as compose, d as createGuard, e as createSlots, f as defineComponent, g as defineSlottedComponent, h as defineStrictComponent, v as validateProps, i as validators, w as withBoundary, j as withDefaults, k as withProps, l as withWrapper } from './contracts-DBdg9J_a.cjs';
1
+ export { C as ComponentProps, P as PropDef, a as PropSchema, R as RenderProp, V as Validator, W as WithDefaultsProps, b as assertType, c as compose, d as createGuard, e as createSlots, f as defineComponent, g as defineSlottedComponent, h as defineStrictComponent, v as validateProps, i as validators, w as withBoundary, j as withDefaults, k as withProps, l as withWrapper } from './contracts-DRIuclVT.cjs';
2
2
 
3
3
  interface MachineConfig<S extends string, E extends string, C extends object = Record<string, unknown>> {
4
4
  initial: S;
@@ -36,10 +36,10 @@ declare function machine<S extends string, E extends string, C extends object =
36
36
  * @param key Storage key
37
37
  * @param initial Default value when no persisted value exists
38
38
  * @param options Storage options
39
- * @returns The same `[getter, setter]` tuple as `signal()`. For localStorage
40
- * (cross-tab sync on), the setter additionally carries a non-enumerable
41
- * `dispose()` method — call `setter.dispose()` on unmount to remove the
42
- * `storage` event listener; otherwise it lives for the page's lifetime.
39
+ * @returns The same `[getter, setter]` tuple as `signal()`. The setter also
40
+ * carries a non-enumerable `dispose()` method — call `setter.dispose()` on
41
+ * unmount to stop persisting and remove the cross-tab `storage` listener;
42
+ * otherwise both live for the page's lifetime.
43
43
  *
44
44
  * @example
45
45
  * ```ts
@@ -94,15 +94,21 @@ interface PersistOptions<T = unknown> {
94
94
  * Must be synchronous — see `encrypt` docs. */
95
95
  decrypt?: (value: string) => string;
96
96
  }
97
+ /** Setter returned by {@link persisted}: writes like a `signal()` setter, released with `dispose()`. */
98
+ type PersistedSetter<T> = ((next: T | ((prev: T) => T)) => void) & {
99
+ /** Stop persisting changes and remove the cross-tab `storage` listener. */
100
+ dispose(): void;
101
+ };
97
102
  /**
98
103
  * A signal mirrored into persistent storage, rehydrated on creation.
99
104
  *
100
105
  * @param key Storage key.
101
106
  * @param initial Value used when storage holds nothing (or holds junk).
102
107
  * @param options Storage backend, serializer and version/migration settings.
103
- * @returns A `[accessor, setter]` pair with the same shape as `signal`.
108
+ * @returns A `[accessor, setter]` pair with the same shape as `signal`; the
109
+ * setter carries `dispose()`.
104
110
  */
105
- declare function persisted<T>(key: string, initial: T, options?: PersistOptions<T>): [() => T, (next: T | ((prev: T) => T)) => void];
111
+ declare function persisted<T>(key: string, initial: T, options?: PersistOptions<T>): [() => T, PersistedSetter<T>];
106
112
 
107
113
  /**
108
114
  * optimistic provides optimistic UI updates that can be reverted on failure.
@@ -210,10 +216,22 @@ interface TimeTravelReturn<T> {
210
216
  }
211
217
  /**
212
218
  * timeline wraps a state value with undo/redo history.
219
+ *
220
+ * @param maxHistory How many entries (including the current one) to keep. Must
221
+ * be a positive safe integer — `0`, negative, fractional, `NaN` or infinite
222
+ * capacities throw a `RangeError`, since they would evict the current value
223
+ * and break the index invariant.
213
224
  */
214
225
  declare function timeline<T>(initial: T, maxHistory?: number): TimeTravelReturn<T>;
215
226
 
216
- type Middleware<S> = (state: S, action: string, payload: unknown, next: () => void) => void;
227
+ /**
228
+ * Store middleware. Call `next()` once to continue the chain — synchronously or
229
+ * later (after an `await`, from a timer). A middleware may be `async`: a
230
+ * rejection is reported through the runtime error handler, and a middleware
231
+ * that fails (throws, or rejects) before calling `next()` never continues —
232
+ * a later `next()` from it is ignored.
233
+ */
234
+ type Middleware<S> = (state: S, action: string, payload: unknown, next: () => void) => void | PromiseLike<void>;
217
235
  type Selector<S, R> = (state: S) => R;
218
236
  /**
219
237
  * Action-map constraint.
@@ -247,4 +265,4 @@ declare function globalStore<S extends object, A extends StoreActionMap<S>>(conf
247
265
  middleware?: Middleware<S>[];
248
266
  }): GlobalStore<S, A>;
249
267
 
250
- export { type GlobalStore, type MachineConfig, type MachineReturn, type Middleware, type PersistOptions, type Selector, type StoreActionMap, type TimeTravelReturn, globalStore, machine, optimistic, optimisticList, persisted, timeline };
268
+ export { type GlobalStore, type MachineConfig, type MachineReturn, type Middleware, type PersistOptions, type PersistedSetter, type Selector, type StoreActionMap, type TimeTravelReturn, globalStore, machine, optimistic, optimisticList, persisted, timeline };
@@ -1,4 +1,4 @@
1
- export { C as ComponentProps, P as PropDef, a as PropSchema, R as RenderProp, V as Validator, b as assertType, c as compose, d as createGuard, e as createSlots, f as defineComponent, g as defineSlottedComponent, h as defineStrictComponent, v as validateProps, i as validators, w as withBoundary, j as withDefaults, k as withProps, l as withWrapper } from './contracts-DBdg9J_a.js';
1
+ export { C as ComponentProps, P as PropDef, a as PropSchema, R as RenderProp, V as Validator, W as WithDefaultsProps, b as assertType, c as compose, d as createGuard, e as createSlots, f as defineComponent, g as defineSlottedComponent, h as defineStrictComponent, v as validateProps, i as validators, w as withBoundary, j as withDefaults, k as withProps, l as withWrapper } from './contracts-DRIuclVT.js';
2
2
 
3
3
  interface MachineConfig<S extends string, E extends string, C extends object = Record<string, unknown>> {
4
4
  initial: S;
@@ -36,10 +36,10 @@ declare function machine<S extends string, E extends string, C extends object =
36
36
  * @param key Storage key
37
37
  * @param initial Default value when no persisted value exists
38
38
  * @param options Storage options
39
- * @returns The same `[getter, setter]` tuple as `signal()`. For localStorage
40
- * (cross-tab sync on), the setter additionally carries a non-enumerable
41
- * `dispose()` method — call `setter.dispose()` on unmount to remove the
42
- * `storage` event listener; otherwise it lives for the page's lifetime.
39
+ * @returns The same `[getter, setter]` tuple as `signal()`. The setter also
40
+ * carries a non-enumerable `dispose()` method — call `setter.dispose()` on
41
+ * unmount to stop persisting and remove the cross-tab `storage` listener;
42
+ * otherwise both live for the page's lifetime.
43
43
  *
44
44
  * @example
45
45
  * ```ts
@@ -94,15 +94,21 @@ interface PersistOptions<T = unknown> {
94
94
  * Must be synchronous — see `encrypt` docs. */
95
95
  decrypt?: (value: string) => string;
96
96
  }
97
+ /** Setter returned by {@link persisted}: writes like a `signal()` setter, released with `dispose()`. */
98
+ type PersistedSetter<T> = ((next: T | ((prev: T) => T)) => void) & {
99
+ /** Stop persisting changes and remove the cross-tab `storage` listener. */
100
+ dispose(): void;
101
+ };
97
102
  /**
98
103
  * A signal mirrored into persistent storage, rehydrated on creation.
99
104
  *
100
105
  * @param key Storage key.
101
106
  * @param initial Value used when storage holds nothing (or holds junk).
102
107
  * @param options Storage backend, serializer and version/migration settings.
103
- * @returns A `[accessor, setter]` pair with the same shape as `signal`.
108
+ * @returns A `[accessor, setter]` pair with the same shape as `signal`; the
109
+ * setter carries `dispose()`.
104
110
  */
105
- declare function persisted<T>(key: string, initial: T, options?: PersistOptions<T>): [() => T, (next: T | ((prev: T) => T)) => void];
111
+ declare function persisted<T>(key: string, initial: T, options?: PersistOptions<T>): [() => T, PersistedSetter<T>];
106
112
 
107
113
  /**
108
114
  * optimistic provides optimistic UI updates that can be reverted on failure.
@@ -210,10 +216,22 @@ interface TimeTravelReturn<T> {
210
216
  }
211
217
  /**
212
218
  * timeline wraps a state value with undo/redo history.
219
+ *
220
+ * @param maxHistory How many entries (including the current one) to keep. Must
221
+ * be a positive safe integer — `0`, negative, fractional, `NaN` or infinite
222
+ * capacities throw a `RangeError`, since they would evict the current value
223
+ * and break the index invariant.
213
224
  */
214
225
  declare function timeline<T>(initial: T, maxHistory?: number): TimeTravelReturn<T>;
215
226
 
216
- type Middleware<S> = (state: S, action: string, payload: unknown, next: () => void) => void;
227
+ /**
228
+ * Store middleware. Call `next()` once to continue the chain — synchronously or
229
+ * later (after an `await`, from a timer). A middleware may be `async`: a
230
+ * rejection is reported through the runtime error handler, and a middleware
231
+ * that fails (throws, or rejects) before calling `next()` never continues —
232
+ * a later `next()` from it is ignored.
233
+ */
234
+ type Middleware<S> = (state: S, action: string, payload: unknown, next: () => void) => void | PromiseLike<void>;
217
235
  type Selector<S, R> = (state: S) => R;
218
236
  /**
219
237
  * Action-map constraint.
@@ -247,4 +265,4 @@ declare function globalStore<S extends object, A extends StoreActionMap<S>>(conf
247
265
  middleware?: Middleware<S>[];
248
266
  }): GlobalStore<S, A>;
249
267
 
250
- export { type GlobalStore, type MachineConfig, type MachineReturn, type Middleware, type PersistOptions, type Selector, type StoreActionMap, type TimeTravelReturn, globalStore, machine, optimistic, optimisticList, persisted, timeline };
268
+ export { type GlobalStore, type MachineConfig, type MachineReturn, type Middleware, type PersistOptions, type PersistedSetter, type Selector, type StoreActionMap, type TimeTravelReturn, globalStore, machine, optimistic, optimisticList, persisted, timeline };
package/dist/patterns.js CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  optimisticList,
6
6
  persisted,
7
7
  timeline
8
- } from "./chunk-VZKNK2V7.js";
8
+ } from "./chunk-AIF3Z2T7.js";
9
9
  import {
10
10
  RenderProp,
11
11
  assertType,
@@ -21,14 +21,14 @@ import {
21
21
  withDefaults,
22
22
  withProps,
23
23
  withWrapper
24
- } from "./chunk-R25EFXXC.js";
24
+ } from "./chunk-TUCPL2HB.js";
25
25
  import "./chunk-H3SRKIYX.js";
26
- import "./chunk-RBTPLM32.js";
27
- import "./chunk-RIXRAYIU.js";
28
- import "./chunk-5DXA2J44.js";
29
- import "./chunk-XZZOBQAY.js";
30
- import "./chunk-UGRX3S57.js";
31
- import "./chunk-2WLZ6757.js";
26
+ import "./chunk-QE4TTDU3.js";
27
+ import "./chunk-XC4MEKGA.js";
28
+ import "./chunk-7XHATCIH.js";
29
+ import "./chunk-D33YTSX5.js";
30
+ import "./chunk-5Q4R7HCL.js";
31
+ import "./chunk-NYNYSPK7.js";
32
32
  export {
33
33
  RenderProp,
34
34
  assertType,