sibujs 4.6.0 → 4.7.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 (79) hide show
  1. package/README.md +1 -1
  2. package/dist/browser.cjs +18 -5
  3. package/dist/browser.js +4 -4
  4. package/dist/build.cjs +1956 -1007
  5. package/dist/build.d.cts +133 -44
  6. package/dist/build.d.ts +133 -44
  7. package/dist/build.js +1368 -569
  8. package/dist/cdn.dev.global.js +12 -12
  9. package/dist/cdn.full.dev.global.js +11 -11
  10. package/dist/cdn.full.global.js +10 -10
  11. package/dist/cdn.global.js +12 -12
  12. package/dist/{chunk-SXXVZMKZ.js → chunk-2BPG2XDA.js} +5 -5
  13. package/dist/{chunk-BAAG6ZTI.js → chunk-3QWBSL5R.js} +4 -4
  14. package/dist/{chunk-5MT6SJ3P.js → chunk-4AWA2PVD.js} +2 -2
  15. package/dist/{chunk-JSXPZCET.js → chunk-7LUJQAOJ.js} +1 -1
  16. package/dist/{chunk-3ISI6ACU.js → chunk-BC2SECJD.js} +1 -1
  17. package/dist/{chunk-DKGBBKOF.js → chunk-BSY63EM6.js} +2 -2
  18. package/dist/{chunk-7NCARGJW.js → chunk-DKXRACVN.js} +3 -3
  19. package/dist/{chunk-47M47FOM.js → chunk-FNJXNGYZ.js} +1 -1
  20. package/dist/{chunk-D33YTSX5.js → chunk-FQRUXCEE.js} +5 -4
  21. package/dist/{chunk-5Q4R7HCL.js → chunk-JWKYU5GV.js} +11 -2
  22. package/dist/{chunk-QE4TTDU3.js → chunk-RUSSKG6G.js} +12 -11
  23. package/dist/{chunk-UZQ6ALFS.js → chunk-SLM3IA34.js} +1 -1
  24. package/dist/{chunk-XRRZKZYX.js → chunk-UNWRJRKC.js} +1 -1
  25. package/dist/{chunk-VVWPJ543.js → chunk-UOL2ECCS.js} +40 -11
  26. package/dist/{chunk-ORMZXBKQ.js → chunk-VZSG24LS.js} +3 -3
  27. package/dist/{chunk-XC4MEKGA.js → chunk-WEQ3DMVL.js} +8 -2
  28. package/dist/{chunk-PK6FK2G2.js → chunk-WOLJZUFQ.js} +176 -27
  29. package/dist/{chunk-7GQCWFOE.js → chunk-XYV3EDB7.js} +143 -74
  30. package/dist/{chunk-AIF3Z2T7.js → chunk-XZR4PXRE.js} +3 -3
  31. package/dist/{chunk-HYXDKS4N.js → chunk-Z3OHK6QT.js} +4 -4
  32. package/dist/{chunk-OXUY2A6L.js → chunk-ZVL7TY4K.js} +2 -2
  33. package/dist/{contracts-DRIuclVT.d.ts → contracts-CLqzJnOV.d.ts} +28 -17
  34. package/dist/{contracts-DRIuclVT.d.cts → contracts-CTOJXu-x.d.cts} +28 -17
  35. package/dist/data.cjs +198 -39
  36. package/dist/data.d.cts +119 -3
  37. package/dist/data.d.ts +119 -3
  38. package/dist/data.js +5 -5
  39. package/dist/devtools.cjs +18 -5
  40. package/dist/devtools.js +4 -4
  41. package/dist/ecosystem.cjs +64 -23
  42. package/dist/ecosystem.d.cts +2 -1
  43. package/dist/ecosystem.d.ts +2 -1
  44. package/dist/ecosystem.js +7 -7
  45. package/dist/extras.cjs +236 -49
  46. package/dist/extras.d.cts +3 -2
  47. package/dist/extras.d.ts +3 -2
  48. package/dist/extras.js +20 -20
  49. package/dist/index.cjs +259 -108
  50. package/dist/index.d.cts +193 -168
  51. package/dist/index.d.ts +193 -168
  52. package/dist/index.js +10 -10
  53. package/dist/motion.cjs +12 -4
  54. package/dist/motion.js +3 -3
  55. package/dist/patterns.cjs +28 -15
  56. package/dist/patterns.d.cts +2 -1
  57. package/dist/patterns.d.ts +2 -1
  58. package/dist/patterns.js +5 -5
  59. package/dist/performance.cjs +18 -5
  60. package/dist/performance.js +4 -4
  61. package/dist/plugins.cjs +118 -34
  62. package/dist/plugins.d.cts +124 -11
  63. package/dist/plugins.d.ts +124 -11
  64. package/dist/plugins.js +68 -26
  65. package/dist/ssr.cjs +54 -13
  66. package/dist/ssr.js +7 -7
  67. package/dist/{tagFactory-DFstCLQV.d.cts → tagFactory-8qL9LCIx.d.cts} +58 -19
  68. package/dist/{tagFactory-DkaNVUNV.d.ts → tagFactory-BL2fymez.d.ts} +58 -19
  69. package/dist/testing.cjs +15 -2
  70. package/dist/testing.js +2 -2
  71. package/dist/types-CJFViL6Q.d.cts +26 -0
  72. package/dist/types-CJFViL6Q.d.ts +26 -0
  73. package/dist/ui.cjs +28 -15
  74. package/dist/ui.d.cts +2 -1
  75. package/dist/ui.d.ts +2 -1
  76. package/dist/ui.js +7 -7
  77. package/dist/widgets.cjs +22 -14
  78. package/dist/widgets.js +6 -6
  79. package/package.json +4 -2
package/dist/extras.cjs CHANGED
@@ -1077,7 +1077,7 @@ function forEachSubscriber(signal2, visit) {
1077
1077
  }
1078
1078
 
1079
1079
  // src/reactivity/track.ts
1080
- var _runtimeVersion = true ? "4.6.0" : "dev";
1080
+ var _runtimeVersion = true ? "4.7.0" : "dev";
1081
1081
  var REGISTRY_KEY = /* @__PURE__ */ Symbol.for("sibujs.reactive.v1");
1082
1082
  function resolveReactiveApi() {
1083
1083
  const g2 = globalThis;
@@ -1133,6 +1133,14 @@ var getSubscriberCount2 = API.getSubscriberCount;
1133
1133
  var getSubscriberDeps2 = API.getSubscriberDeps;
1134
1134
  var forEachSubscriber2 = API.forEachSubscriber;
1135
1135
 
1136
+ // src/core/devtoolsHook.ts
1137
+ function emitDevtools(hook, event, payload) {
1138
+ try {
1139
+ hook.emit(event, payload);
1140
+ } catch {
1141
+ }
1142
+ }
1143
+
1136
1144
  // src/core/signals/derived.ts
1137
1145
  function derived(getter, options) {
1138
1146
  devAssert(typeof getter === "function", "derived: argument must be a getter function.");
@@ -1159,17 +1167,17 @@ function derived(getter, options) {
1159
1167
  cs._d = false;
1160
1168
  cs._init = true;
1161
1169
  };
1162
- track2(() => {
1163
- let threw = true;
1164
- try {
1170
+ try {
1171
+ track2(() => {
1165
1172
  cs._v = getter();
1166
1173
  cs._d = false;
1167
1174
  cs._init = true;
1168
- threw = false;
1169
- } finally {
1170
- if (threw) cs._d = true;
1171
- }
1172
- }, markDirty);
1175
+ }, markDirty);
1176
+ } catch (err) {
1177
+ disposed = true;
1178
+ cleanup2(markDirty);
1179
+ throw err;
1180
+ }
1173
1181
  const hook = globalThis.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
1174
1182
  const validate = () => {
1175
1183
  if (!cs._d || disposed || pendingError !== void 0) return;
@@ -1188,7 +1196,7 @@ function derived(getter, options) {
1188
1196
  if (disposed) cleanup2(markDirty);
1189
1197
  }
1190
1198
  if (hook && !disposed && !Object.is(oldValue, cs._v)) {
1191
- hook.emit("computed:update", { signal: cs, oldValue, newValue: cs._v });
1199
+ emitDevtools(hook, "computed:update", { signal: cs, oldValue, newValue: cs._v });
1192
1200
  }
1193
1201
  };
1194
1202
  cs._validate = validate;
@@ -1239,7 +1247,7 @@ function derived(getter, options) {
1239
1247
  }
1240
1248
  }
1241
1249
  };
1242
- if (hook) hook.emit("computed:create", { signal: cs, name: debugName, getter: computedGetter });
1250
+ if (hook) emitDevtools(hook, "computed:create", { signal: cs, name: debugName, getter: computedGetter });
1243
1251
  return computedGetter;
1244
1252
  }
1245
1253
 
@@ -1412,12 +1420,17 @@ function effect(effectFn, options) {
1412
1420
  try {
1413
1421
  retrack2(ctx.bodyFn, ctx.subscriber);
1414
1422
  if (ctx.rerunPending) drainReruns(ctx);
1423
+ } catch (err) {
1424
+ ctx.disposed = true;
1425
+ if (ctx.userCleanups.length > 0) flushUserCleanups(ctx);
1426
+ cleanup2(ctx.subscriber);
1427
+ throw err;
1415
1428
  } finally {
1416
1429
  ctx.running = false;
1417
1430
  ctx.rerunPending = false;
1418
1431
  }
1419
1432
  const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
1420
- if (hook) hook.emit("effect:create", { effectFn });
1433
+ if (hook) emitDevtools(hook, "effect:create", { effectFn });
1421
1434
  return () => disposeEffect(ctx);
1422
1435
  }
1423
1436
 
@@ -1504,7 +1517,7 @@ function signal(initial, options) {
1504
1517
  state2.__v++;
1505
1518
  if (DEV) {
1506
1519
  const hook = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
1507
- if (hook) hook.emit("signal:update", { signal: state2, name: debugName, oldValue: prev, newValue });
1520
+ if (hook) emitDevtools(hook, "signal:update", { signal: state2, name: debugName, oldValue: prev, newValue });
1508
1521
  }
1509
1522
  if (!enqueueBatchedSignal(state2)) {
1510
1523
  notifySubscribers2(state2);
@@ -1518,7 +1531,7 @@ function signal(initial, options) {
1518
1531
  state2.value = newValue;
1519
1532
  state2.__v++;
1520
1533
  const hook = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
1521
- if (hook) hook.emit("signal:update", { signal: state2, name: debugName, oldValue: prev, newValue });
1534
+ if (hook) emitDevtools(hook, "signal:update", { signal: state2, name: debugName, oldValue: prev, newValue });
1522
1535
  if (!enqueueBatchedSignal(state2)) {
1523
1536
  notifySubscribers2(state2);
1524
1537
  }
@@ -1537,7 +1550,7 @@ function signal(initial, options) {
1537
1550
  }
1538
1551
  if (DEV) {
1539
1552
  const hook = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
1540
- if (hook) hook.emit("signal:create", { signal: state2, name: debugName, getter: get, initial });
1553
+ if (hook) emitDevtools(hook, "signal:create", { signal: state2, name: debugName, getter: get, initial });
1541
1554
  }
1542
1555
  return [get, set];
1543
1556
  }
@@ -1659,7 +1672,83 @@ function waitForRetryDelay(delay, signal2) {
1659
1672
  });
1660
1673
  }
1661
1674
 
1675
+ // src/data/structuralSharing.ts
1676
+ function isPlainObject(value) {
1677
+ if (value === null || typeof value !== "object") return false;
1678
+ const proto = Object.getPrototypeOf(value);
1679
+ return proto === Object.prototype || proto === null;
1680
+ }
1681
+ function isPlainArray(value) {
1682
+ return Array.isArray(value) && Object.getPrototypeOf(value) === Array.prototype;
1683
+ }
1684
+ function reconcile(prev, next, depth, walk, newRoot) {
1685
+ if (Object.is(prev, next)) return prev;
1686
+ const arrays = isPlainArray(prev) && isPlainArray(next);
1687
+ if (!arrays && !(isPlainObject(prev) && isPlainObject(next))) return next;
1688
+ if (Object.getPrototypeOf(prev) !== Object.getPrototypeOf(next)) return next;
1689
+ const nextObject = next;
1690
+ const seenAt = walk.path.get(nextObject);
1691
+ if (seenAt !== void 0) {
1692
+ walk.cycleTo = Math.min(walk.cycleTo, seenAt);
1693
+ return next;
1694
+ }
1695
+ const prevRecord = prev;
1696
+ const nextRecord = next;
1697
+ const nextKeys = arrays ? Array.from({ length: next.length }, (_, i2) => i2) : Object.keys(nextRecord);
1698
+ const prevSize = arrays ? prev.length : Object.keys(prevRecord).length;
1699
+ const copy = arrays ? new Array(nextKeys.length) : Object.create(Object.getPrototypeOf(next));
1700
+ let allFromPrev = prevSize === nextKeys.length;
1701
+ let allFromNext = true;
1702
+ const outerCycleTo = walk.cycleTo;
1703
+ walk.cycleTo = Number.POSITIVE_INFINITY;
1704
+ walk.path.set(nextObject, depth);
1705
+ for (const key of nextKeys) {
1706
+ if (arrays && !Object.hasOwn(nextRecord, key)) {
1707
+ if (Object.hasOwn(prevRecord, key)) allFromPrev = false;
1708
+ continue;
1709
+ }
1710
+ const nextChild = nextRecord[key];
1711
+ const hasPrev = Object.hasOwn(prevRecord, key);
1712
+ const shared = hasPrev ? reconcile(prevRecord[key], nextChild, depth + 1, walk, false) : nextChild;
1713
+ copy[key] = shared;
1714
+ if (!hasPrev || !Object.is(shared, prevRecord[key])) allFromPrev = false;
1715
+ if (!Object.is(shared, nextChild)) allFromNext = false;
1716
+ }
1717
+ walk.path.delete(nextObject);
1718
+ const reached = walk.cycleTo;
1719
+ walk.cycleTo = Math.min(outerCycleTo, reached < depth ? reached : Number.POSITIVE_INFINITY);
1720
+ if (reached <= depth) return next;
1721
+ if (allFromPrev && !newRoot) return prev;
1722
+ if (allFromNext) return next;
1723
+ return copy;
1724
+ }
1725
+ function applyStructuralSharing(option2, prev, next, explicit = false) {
1726
+ if (option2 === false || prev === void 0) return next;
1727
+ const forceNew = explicit && !Object.is(prev, next);
1728
+ if (typeof option2 === "function") {
1729
+ const shared = option2(prev, next);
1730
+ return forceNew && Object.is(shared, prev) ? next : shared;
1731
+ }
1732
+ return reconcile(prev, next, 0, { path: /* @__PURE__ */ new Map(), cycleTo: Number.POSITIVE_INFINITY }, forceNew);
1733
+ }
1734
+
1662
1735
  // src/data/query.ts
1736
+ function shareSafely(option2, prev, next, explicit) {
1737
+ const shared = untracked2(
1738
+ () => runSelect("query structuralSharing", () => applyStructuralSharing(option2, prev, next, explicit))
1739
+ );
1740
+ return shared.ok ? shared.value : next;
1741
+ }
1742
+ function sharedView(entry) {
1743
+ const raw = entry.data;
1744
+ if (raw === void 0) return void 0;
1745
+ if (entry.hasShared && Object.is(entry.sharedFrom, raw)) return entry.shared;
1746
+ const value = shareSafely(true, entry.hasShared ? entry.shared : void 0, raw, entry.explicit);
1747
+ entry.shared = value;
1748
+ entry.sharedFrom = raw;
1749
+ entry.hasShared = true;
1750
+ return value;
1751
+ }
1663
1752
  var globalQueryCache = globalSingleton(/* @__PURE__ */ Symbol.for("sibujs.query.cache.v1"), () => /* @__PURE__ */ new Map());
1664
1753
  function getActiveQueryCache() {
1665
1754
  return getRequestScopedCache("query") ?? globalQueryCache;
@@ -1685,7 +1774,11 @@ function getOrCreateEntry(cache, key, initialData) {
1685
1774
  listeners: /* @__PURE__ */ new Set(),
1686
1775
  refetchers: /* @__PURE__ */ new Set(),
1687
1776
  controller: null,
1688
- generation: 0
1777
+ generation: 0,
1778
+ explicit: false,
1779
+ shared: void 0,
1780
+ sharedFrom: void 0,
1781
+ hasShared: false
1689
1782
  };
1690
1783
  cache.set(key, entry);
1691
1784
  }
@@ -1704,13 +1797,24 @@ function query(key, fetcher, options = {}) {
1704
1797
  onSuccess,
1705
1798
  onError,
1706
1799
  onSettled,
1707
- select: select3
1800
+ select: select3,
1801
+ structuralSharing = true
1708
1802
  } = options;
1709
1803
  const resolveKey = typeof key === "function" ? key : () => key;
1710
1804
  const cache = getActiveQueryCache();
1711
1805
  const [data2, setData] = signal(initialData);
1712
1806
  const [isFetching, setIsFetching] = signal(false);
1713
1807
  const [error, setError] = signal(void 0);
1808
+ const [updatedAt, setUpdatedAt] = signal(0);
1809
+ const [base2, setBase] = signal(void 0);
1810
+ let baseEntry = null;
1811
+ let baseValue;
1812
+ let baseExplicit = false;
1813
+ let customEntry = null;
1814
+ let customFrom;
1815
+ let customValue;
1816
+ let selectedEntry = null;
1817
+ let selectedValue;
1714
1818
  let disposed = false;
1715
1819
  let currentKey = null;
1716
1820
  let attachedEntry = null;
@@ -1719,11 +1823,57 @@ function query(key, fetcher, options = {}) {
1719
1823
  const loading = derived(() => isFetching() && data2() === void 0);
1720
1824
  const isStale = derived(() => {
1721
1825
  data2();
1826
+ updatedAt();
1722
1827
  if (!currentKey) return true;
1723
1828
  const entry = cache.get(currentKey);
1724
1829
  if (!entry || entry.dataUpdatedAt === 0) return true;
1725
1830
  return Date.now() - entry.dataUpdatedAt >= staleTime;
1726
1831
  });
1832
+ function viewOf(entry) {
1833
+ const raw = entry.data;
1834
+ if (raw === void 0) return void 0;
1835
+ if (structuralSharing === false) return raw;
1836
+ if (typeof structuralSharing !== "function") return sharedView(entry);
1837
+ const sameEntry = customEntry === entry;
1838
+ if (sameEntry && Object.is(customFrom, raw)) return customValue;
1839
+ const value = shareSafely(structuralSharing, sameEntry ? customValue : void 0, raw, entry.explicit);
1840
+ customEntry = entry;
1841
+ customFrom = raw;
1842
+ customValue = value;
1843
+ return value;
1844
+ }
1845
+ function commitBase(entry, value) {
1846
+ const changed = !Object.is(value, baseValue);
1847
+ baseEntry = entry;
1848
+ baseValue = value;
1849
+ if (!select3) {
1850
+ setData(value);
1851
+ return;
1852
+ }
1853
+ if (!changed) return;
1854
+ baseExplicit = entry?.explicit === true;
1855
+ setBase(value);
1856
+ }
1857
+ const stopSelect = select3 ? effect(() => {
1858
+ const raw = base2();
1859
+ const entry = baseEntry;
1860
+ const explicit = baseExplicit;
1861
+ baseExplicit = false;
1862
+ if (entry === null && selectedEntry === null) return;
1863
+ if (raw === void 0) {
1864
+ selectedEntry = entry;
1865
+ selectedValue = void 0;
1866
+ setData(void 0);
1867
+ return;
1868
+ }
1869
+ const selected = runSelect("query select", () => select3(raw));
1870
+ if (!selected.ok) return;
1871
+ const prev = selectedEntry === entry ? selectedValue : void 0;
1872
+ const value = shareSafely(structuralSharing, prev, selected.value, explicit);
1873
+ selectedEntry = entry;
1874
+ selectedValue = value;
1875
+ setData(value);
1876
+ }) : null;
1727
1877
  function detachFromEntry() {
1728
1878
  const entry = attachedEntry;
1729
1879
  const key2 = attachedKey;
@@ -1782,7 +1932,7 @@ function query(key, fetcher, options = {}) {
1782
1932
  const settledError = entry.error;
1783
1933
  runCallback("query onError", () => onError?.(settledError));
1784
1934
  } else if (entry.data !== void 0) {
1785
- const settledData = entry.data;
1935
+ const settledData = viewOf(entry);
1786
1936
  runCallback("query onSuccess", () => onSuccess?.(settledData));
1787
1937
  }
1788
1938
  runCallback("query onSettled", () => onSettled?.());
@@ -1813,17 +1963,14 @@ function query(key, fetcher, options = {}) {
1813
1963
  entry.promise = null;
1814
1964
  entry.controller = null;
1815
1965
  entry.data = result;
1966
+ entry.explicit = false;
1816
1967
  entry.dataUpdatedAt = Date.now();
1817
1968
  entry.error = void 0;
1818
1969
  notifyListeners(entry.listeners, "query cache listener");
1819
1970
  if (disposed || currentKey !== key2) return;
1820
- const selected = runSelect("query select", () => select3 ? select3(result) : result);
1821
- batch(() => {
1822
- if (selected.ok) setData(selected.value);
1823
- setIsFetching(false);
1824
- setError(void 0);
1825
- });
1826
- runCallback("query onSuccess", () => onSuccess?.(result));
1971
+ if (!entry.listeners.has(onCacheUpdate)) onCacheUpdate();
1972
+ const committedResult = viewOf(entry);
1973
+ runCallback("query onSuccess", () => onSuccess?.(committedResult));
1827
1974
  } catch (err) {
1828
1975
  if (entry.generation !== generation) return;
1829
1976
  entry.promise = null;
@@ -1853,18 +2000,19 @@ function query(key, fetcher, options = {}) {
1853
2000
  const entry = cache.get(currentKey);
1854
2001
  if (!entry) {
1855
2002
  batch(() => {
1856
- setData(void 0);
2003
+ commitBase(null, void 0);
1857
2004
  setError(void 0);
1858
2005
  setIsFetching(false);
2006
+ setUpdatedAt(0);
1859
2007
  });
1860
2008
  return;
1861
2009
  }
1862
- const raw = entry.data;
1863
- const selected = raw !== void 0 && select3 ? runSelect("query select", () => select3(raw)) : { ok: true, value: raw };
2010
+ const view = viewOf(entry);
1864
2011
  batch(() => {
1865
- if (selected.ok) setData(selected.value);
2012
+ commitBase(entry, view);
1866
2013
  setError(entry.error);
1867
2014
  if (!entry.promise) setIsFetching(false);
2015
+ setUpdatedAt(entry.dataUpdatedAt);
1868
2016
  });
1869
2017
  }
1870
2018
  const effectCleanup = effect(() => {
@@ -1874,11 +2022,11 @@ function query(key, fetcher, options = {}) {
1874
2022
  const entry = getOrCreateEntry(cache, key2, initialData);
1875
2023
  attachToEntry(entry, key2);
1876
2024
  if (entry.data !== void 0) {
1877
- const raw = entry.data;
1878
- const selected = runSelect("query select", () => select3 ? select3(raw) : raw);
2025
+ const view = viewOf(entry);
1879
2026
  batch(() => {
1880
- if (selected.ok) setData(selected.value);
2027
+ commitBase(entry, view);
1881
2028
  setError(entry.error);
2029
+ setUpdatedAt(entry.dataUpdatedAt);
1882
2030
  });
1883
2031
  }
1884
2032
  if (!keyChanged && currentKey === key2 && entry.data !== void 0) {
@@ -1916,6 +2064,7 @@ function query(key, fetcher, options = {}) {
1916
2064
  if (disposed) return;
1917
2065
  disposed = true;
1918
2066
  effectCleanup();
2067
+ stopSelect?.();
1919
2068
  loading.dispose();
1920
2069
  isStale.dispose();
1921
2070
  if (intervalTimer) clearInterval(intervalTimer);
@@ -1947,13 +2096,15 @@ function invalidateQueries(keyOrPredicate) {
1947
2096
  }
1948
2097
  }
1949
2098
  function getQueryData(key) {
1950
- return getActiveQueryCache().get(key)?.data;
2099
+ const entry = getActiveQueryCache().get(key);
2100
+ return entry ? sharedView(entry) : void 0;
1951
2101
  }
1952
2102
  function setQueryData(key, data2) {
1953
2103
  const entry = getActiveQueryCache().get(key);
1954
2104
  if (!entry) return;
1955
- const newData = typeof data2 === "function" ? data2(entry.data) : data2;
2105
+ const newData = typeof data2 === "function" ? data2(sharedView(entry)) : data2;
1956
2106
  entry.data = newData;
2107
+ entry.explicit = true;
1957
2108
  entry.dataUpdatedAt = Date.now();
1958
2109
  notifyListeners(entry.listeners, "query cache listener");
1959
2110
  }
@@ -2337,6 +2488,15 @@ function resource(sourceOrFetcher, fetcherOrOptions, maybeOptions) {
2337
2488
  const [loading, setLoading] = signal(false);
2338
2489
  const [error, setError] = signal(void 0);
2339
2490
  let currentData = options.initialValue;
2491
+ function commitData(next, explicit) {
2492
+ const sharing = options.structuralSharing ?? true;
2493
+ const shared = untracked2(
2494
+ () => runSelect("resource structuralSharing", () => applyStructuralSharing(sharing, currentData, next, explicit))
2495
+ );
2496
+ currentData = shared.ok ? shared.value : next;
2497
+ setData(currentData);
2498
+ return currentData;
2499
+ }
2340
2500
  let abortController = null;
2341
2501
  let disposed = false;
2342
2502
  let effectCleanup = null;
@@ -2356,12 +2516,12 @@ function resource(sourceOrFetcher, fetcherOrOptions, maybeOptions) {
2356
2516
  try {
2357
2517
  const result = await withRetry(() => fetcher(sourceValue, { signal: signal2, prev }), options.retry, void 0, signal2);
2358
2518
  if (version !== fetchVersion || disposed) return;
2359
- currentData = result;
2519
+ let committed = result;
2360
2520
  batch(() => {
2361
- setData(result);
2521
+ committed = commitData(result, false);
2362
2522
  setLoading(false);
2363
2523
  });
2364
- runCallback("resource onSuccess", () => options.onSuccess?.(result));
2524
+ runCallback("resource onSuccess", () => options.onSuccess?.(committed));
2365
2525
  } catch (err) {
2366
2526
  if (version !== fetchVersion || disposed) return;
2367
2527
  if (isAbortError(err)) {
@@ -2395,8 +2555,7 @@ function resource(sourceOrFetcher, fetcherOrOptions, maybeOptions) {
2395
2555
  refetch: () => doFetch(source2 ? source2() : void 0),
2396
2556
  mutate: (value) => {
2397
2557
  const newValue = typeof value === "function" ? value(currentData) : value;
2398
- currentData = newValue;
2399
- setData(newValue);
2558
+ commitData(newValue, true);
2400
2559
  },
2401
2560
  abort: () => abortController?.abort(),
2402
2561
  dispose: () => {
@@ -10164,8 +10323,34 @@ function toKebab(prop) {
10164
10323
  }
10165
10324
  function applyStyle(el, style2) {
10166
10325
  if (typeof style2 === "function") {
10326
+ const getter = style2;
10327
+ let written = [];
10328
+ let wroteString = false;
10167
10329
  const teardown = reactiveBinding2(() => {
10168
- el.setAttribute("style", sanitizeStyleAttribute(String(style2()), { element: el }));
10330
+ const value = getter();
10331
+ if (value === null || typeof value !== "object") {
10332
+ written = [];
10333
+ wroteString = true;
10334
+ el.setAttribute("style", sanitizeStyleAttribute(String(value), { element: el }));
10335
+ return;
10336
+ }
10337
+ const decl = el.style;
10338
+ if (wroteString) {
10339
+ el.removeAttribute("style");
10340
+ wroteString = false;
10341
+ }
10342
+ const next = [];
10343
+ for (const prop in value) {
10344
+ const val = value[prop];
10345
+ if (val == null) continue;
10346
+ const name = toKebab(prop);
10347
+ next.push(name);
10348
+ decl.setProperty(name, sanitizeCSSValue(String(val), { property: name, element: el }));
10349
+ }
10350
+ for (let i2 = 0; i2 < written.length; i2++) {
10351
+ if (next.indexOf(written[i2]) === -1) decl.removeProperty(written[i2]);
10352
+ }
10353
+ written = next;
10169
10354
  }, el);
10170
10355
  registerDisposer(el, teardown);
10171
10356
  return;
@@ -10196,7 +10381,9 @@ function applyClass(el, cls) {
10196
10381
  }
10197
10382
  if (typeof cls === "function") {
10198
10383
  const teardown = reactiveBinding2(() => {
10199
- el.setAttribute("class", cls());
10384
+ const value = cls();
10385
+ if (value == null || value === false) el.removeAttribute("class");
10386
+ else el.setAttribute("class", value);
10200
10387
  }, el);
10201
10388
  registerDisposer(el, teardown);
10202
10389
  return;
@@ -10278,7 +10465,7 @@ function appendChildren(el, nodes) {
10278
10465
  }
10279
10466
  }
10280
10467
  }
10281
- var tagFactory = (tag, ns) => {
10468
+ function tagFactory(tag, ns) {
10282
10469
  const blocked = isBlockedTag(tag);
10283
10470
  return (first, second) => {
10284
10471
  if (blocked) {
@@ -10327,7 +10514,9 @@ var tagFactory = (tag, ns) => {
10327
10514
  const pClass = props.class;
10328
10515
  if (pClass != null) applyClass(el, pClass);
10329
10516
  const pId = props.id;
10330
- if (pId != null) {
10517
+ if (typeof pId === "function") {
10518
+ registerDisposer(el, bindAttribute(el, "id", pId));
10519
+ } else if (pId != null) {
10331
10520
  if (DEV && typeof pId === "string" && CLOBBER_RISKY_IDS.has(pId.toLowerCase())) {
10332
10521
  devWarn(
10333
10522
  `tagFactory: element id="${pId}" matches a common global and may cause DOM clobbering. Avoid setting ids from untrusted input.`
@@ -10377,12 +10566,10 @@ var tagFactory = (tag, ns) => {
10377
10566
  }
10378
10567
  }
10379
10568
  }
10380
- if (props.onElement && typeof props.onElement === "function") {
10381
- props.onElement(el);
10382
- }
10569
+ if (typeof props.onElement === "function") props.onElement(el);
10383
10570
  return el;
10384
10571
  };
10385
- };
10572
+ }
10386
10573
 
10387
10574
  // src/core/rendering/html.ts
10388
10575
  var html = tagFactory("html");
@@ -11393,7 +11580,7 @@ var CDN_ENTRY_POINTS = {
11393
11580
  };
11394
11581
  var packageInfo = {
11395
11582
  name: "sibujs",
11396
- version: true ? "4.6.0" : "dev",
11583
+ version: true ? "4.7.0" : "dev",
11397
11584
  entryPoints: MODULE_ENTRY_POINTS,
11398
11585
  /**
11399
11586
  * Generate the package.json `exports` map. Module entries resolve to the
@@ -11538,7 +11725,7 @@ var env = {
11538
11725
  };
11539
11726
 
11540
11727
  // src/plugins/versioning.ts
11541
- var VERSION = true ? "4.6.0" : "dev";
11728
+ var VERSION = true ? "4.7.0" : "dev";
11542
11729
  var NUM = "(?:0|[1-9]\\d*)";
11543
11730
  var PRE_ID = `(?:${NUM}|\\d*[a-zA-Z-][0-9a-zA-Z-]*)`;
11544
11731
  var BUILD_ID = "[0-9a-zA-Z-]+";
package/dist/extras.d.cts CHANGED
@@ -1,7 +1,7 @@
1
1
  export { ConflictStrategy, InfiniteQueryOptions, InfiniteQueryResult, LoaderRoute, MutationOptions, MutationResult, OfflineStore, OfflineStoreOptions, QueryOptions, QueryResult, Resource, ResourceOptions, RetryOptions, RouteLoaderFn, SyncAdapter, SyncChange, SyncConflict, SyncResult, __resetQueryCache, calculateDelay, clearQueryCache, debounce, executeLoader, getQueryData, infiniteQuery, invalidateQueries, loaderData, mutation, offlineStore, preloadRoute, previous, query, renderWithLoader, resource, setQueryData, socket, stream, syncAdapter, throttle, withLoader, withRetry } from './data.cjs';
2
2
  export { AnimationFrameOptions, BoundsRect, CurrencyFormatOptions, GamepadSnapshot, ImageLoaderState, KeyboardOptions, MouseOptions, MutationObserverOptions, SpeakOptions, SwipeDirection, SwipeOptions, TextSelectionState, UrlStateOptions, __resetSpeechCoordinator, animationFrame, battery, bounds, broadcast, clipboard, colorScheme, draggable, dropZone, favicon, formatCurrency, formatNumber, fullscreen, gamepad, geo, idle, imageLoader, keyboard, media, mouse, mutationObserver, network, online, permissions, pointerLock, resize, scroll, speech, svgFavicon, swipe, textSelection, title, urlState, vibrate, visibility, wakeLock, windowSize } from './browser.cjs';
3
3
  export { GlobalStore, MachineConfig, MachineReturn, Middleware, PersistOptions, PersistedSetter, Selector, StoreActionMap, TimeTravelReturn, globalStore, machine, optimistic, optimisticList, persisted, timeline } from './patterns.cjs';
4
- 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';
4
+ 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-CTOJXu-x.cjs';
5
5
  export { AnimationPreset, PresetOptions, SlideDirection, SpringOptions, TransitionGroup, TransitionGroupOptions, TransitionOptions, animate, bounceIn, bounceOut, fadeIn, fadeOut, flipIn, prefersReducedMotion, pulse, reducedMotion, scaleDown, scaleUp, sequence, shake, slideIn, slideOut, spring, springSignal, stagger, transition, viewTransition } from './motion.cjs';
6
6
  export { A as AttributeSource, a as AttributeValue, B as BoundFieldProps, C as CustomElementOptions, F as FieldConfig, b as FocusTrap, c as FormConfig, d as FormField, e as FormReturn, I as IntersectionResult, M as MaskOptions, P as PaginationResult, T as Toast, f as ToastInstance, V as ValidatorFn, g as VirtualList, h as VirtualListProps, _ as __resetDialogStack, i as announce, j as aria, k as bindAttrs, l as bindBoolAttr, m as bindData, n as bindField, o as creditCardMask, p as custom, q as dateMask, r as defineElement, s as dialog, t as email, u as eventBus, v as focus, w as form, x as hotkey, y as infiniteScroll, z as inputMask, D as intersection, E as lazyLoad, G as matchesPattern, H as max, J as maxLength, K as min, L as minLength, N as pagination, O as phoneMask, Q as removeScopedStyle, R as required, S as scopedStyle, U as ssnMask, W as svgElement, X as timeMask, Y as toast, Z as withScopedStyle, $ as zipMask } from './customElement-MmInOW1U.cjs';
7
7
  export { ChunkConfig, DOMPool, Features, NormalizeResult, NormalizedEntities, NormalizedSchema, NormalizedState, NormalizedStoreActions, Priority, PriorityLevel, block, cloneTemplate, conditional, createChunkRegistry, deferredValue, denormalize, devOnly, flushScheduler, getDOMPool, hoistable, lazyChunk, noSideEffect, normalize, normalizedStore, pendingTasks, precompile, prefetch, preloadImage, preloadModule, preloadModules, preloadResource, processInChunks, pure, resetIdCounter, scheduleUpdate, setIdPrefix, startTransition, staticTemplate, transitionState, uniqueId, yieldToMain } from './performance.cjs';
@@ -13,5 +13,6 @@ export { D as DevToolsEvent, a as DevtoolsOverlayOptions, P as ProfilerResult, R
13
13
  export { AccordionAriaBinding, AccordionOptions, ComboboxOptions, DatePickerOptions, FileUploadOptions, SelectOptions, SetContentOptions, TabsAriaBinding, TabsOptions, accordion, combobox, contentEditable, datePicker, fileUpload, popover, select, tabs, tooltip } from './widgets.cjs';
14
14
  export { AdaptedComponent, AdaptedComponentProps, AdapterConfig, ComponentMapping, MobXAdapterAPI, MobXAdapterOptions, MobXReactionDisposer, ReduxAdapterAPI, ReduxAdapterOptions, ReduxStore, ThemeAPI, ThemeConfig, ZustandAdapterAPI, ZustandAdapterOptions, ZustandStore, antdAdapter, chakraAdapter, componentAdapter, createTheme, materialAdapter, mobXAdapter, reduxAdapter, zustandAdapter } from './ecosystem.cjs';
15
15
  import './signal-EotCj4hS.cjs';
16
+ import './types-CJFViL6Q.cjs';
16
17
  import './signal-BnWpq6WB.cjs';
17
- import './tagFactory-DFstCLQV.cjs';
18
+ import './tagFactory-8qL9LCIx.cjs';
package/dist/extras.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export { ConflictStrategy, InfiniteQueryOptions, InfiniteQueryResult, LoaderRoute, MutationOptions, MutationResult, OfflineStore, OfflineStoreOptions, QueryOptions, QueryResult, Resource, ResourceOptions, RetryOptions, RouteLoaderFn, SyncAdapter, SyncChange, SyncConflict, SyncResult, __resetQueryCache, calculateDelay, clearQueryCache, debounce, executeLoader, getQueryData, infiniteQuery, invalidateQueries, loaderData, mutation, offlineStore, preloadRoute, previous, query, renderWithLoader, resource, setQueryData, socket, stream, syncAdapter, throttle, withLoader, withRetry } from './data.js';
2
2
  export { AnimationFrameOptions, BoundsRect, CurrencyFormatOptions, GamepadSnapshot, ImageLoaderState, KeyboardOptions, MouseOptions, MutationObserverOptions, SpeakOptions, SwipeDirection, SwipeOptions, TextSelectionState, UrlStateOptions, __resetSpeechCoordinator, animationFrame, battery, bounds, broadcast, clipboard, colorScheme, draggable, dropZone, favicon, formatCurrency, formatNumber, fullscreen, gamepad, geo, idle, imageLoader, keyboard, media, mouse, mutationObserver, network, online, permissions, pointerLock, resize, scroll, speech, svgFavicon, swipe, textSelection, title, urlState, vibrate, visibility, wakeLock, windowSize } from './browser.js';
3
3
  export { GlobalStore, MachineConfig, MachineReturn, Middleware, PersistOptions, PersistedSetter, Selector, StoreActionMap, TimeTravelReturn, globalStore, machine, optimistic, optimisticList, persisted, timeline } from './patterns.js';
4
- 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';
4
+ 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-CLqzJnOV.js';
5
5
  export { AnimationPreset, PresetOptions, SlideDirection, SpringOptions, TransitionGroup, TransitionGroupOptions, TransitionOptions, animate, bounceIn, bounceOut, fadeIn, fadeOut, flipIn, prefersReducedMotion, pulse, reducedMotion, scaleDown, scaleUp, sequence, shake, slideIn, slideOut, spring, springSignal, stagger, transition, viewTransition } from './motion.js';
6
6
  export { A as AttributeSource, a as AttributeValue, B as BoundFieldProps, C as CustomElementOptions, F as FieldConfig, b as FocusTrap, c as FormConfig, d as FormField, e as FormReturn, I as IntersectionResult, M as MaskOptions, P as PaginationResult, T as Toast, f as ToastInstance, V as ValidatorFn, g as VirtualList, h as VirtualListProps, _ as __resetDialogStack, i as announce, j as aria, k as bindAttrs, l as bindBoolAttr, m as bindData, n as bindField, o as creditCardMask, p as custom, q as dateMask, r as defineElement, s as dialog, t as email, u as eventBus, v as focus, w as form, x as hotkey, y as infiniteScroll, z as inputMask, D as intersection, E as lazyLoad, G as matchesPattern, H as max, J as maxLength, K as min, L as minLength, N as pagination, O as phoneMask, Q as removeScopedStyle, R as required, S as scopedStyle, U as ssnMask, W as svgElement, X as timeMask, Y as toast, Z as withScopedStyle, $ as zipMask } from './customElement-MmInOW1U.js';
7
7
  export { ChunkConfig, DOMPool, Features, NormalizeResult, NormalizedEntities, NormalizedSchema, NormalizedState, NormalizedStoreActions, Priority, PriorityLevel, block, cloneTemplate, conditional, createChunkRegistry, deferredValue, denormalize, devOnly, flushScheduler, getDOMPool, hoistable, lazyChunk, noSideEffect, normalize, normalizedStore, pendingTasks, precompile, prefetch, preloadImage, preloadModule, preloadModules, preloadResource, processInChunks, pure, resetIdCounter, scheduleUpdate, setIdPrefix, startTransition, staticTemplate, transitionState, uniqueId, yieldToMain } from './performance.js';
@@ -13,5 +13,6 @@ export { D as DevToolsEvent, a as DevtoolsOverlayOptions, P as ProfilerResult, R
13
13
  export { AccordionAriaBinding, AccordionOptions, ComboboxOptions, DatePickerOptions, FileUploadOptions, SelectOptions, SetContentOptions, TabsAriaBinding, TabsOptions, accordion, combobox, contentEditable, datePicker, fileUpload, popover, select, tabs, tooltip } from './widgets.js';
14
14
  export { AdaptedComponent, AdaptedComponentProps, AdapterConfig, ComponentMapping, MobXAdapterAPI, MobXAdapterOptions, MobXReactionDisposer, ReduxAdapterAPI, ReduxAdapterOptions, ReduxStore, ThemeAPI, ThemeConfig, ZustandAdapterAPI, ZustandAdapterOptions, ZustandStore, antdAdapter, chakraAdapter, componentAdapter, createTheme, materialAdapter, mobXAdapter, reduxAdapter, zustandAdapter } from './ecosystem.js';
15
15
  import './signal-EotCj4hS.js';
16
+ import './types-CJFViL6Q.js';
16
17
  import './signal-BnWpq6WB.js';
17
- import './tagFactory-DkaNVUNV.js';
18
+ import './tagFactory-BL2fymez.js';