sibujs 1.1.0 → 1.3.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 (94) hide show
  1. package/README.md +29 -25
  2. package/dist/browser.cjs +804 -2
  3. package/dist/browser.d.cts +591 -1
  4. package/dist/browser.d.ts +591 -1
  5. package/dist/browser.js +50 -8
  6. package/dist/build.cjs +706 -161
  7. package/dist/build.js +21 -12
  8. package/dist/cdn.global.js +188 -7
  9. package/dist/chunk-2BYQDGN3.js +742 -0
  10. package/dist/chunk-32DY64NT.js +282 -0
  11. package/dist/chunk-3AIRKM3B.js +1263 -0
  12. package/dist/chunk-3X2YG6YM.js +505 -0
  13. package/dist/chunk-5X6PP2UK.js +28 -0
  14. package/dist/chunk-77L6NL3X.js +1097 -0
  15. package/dist/chunk-B7SWRFUT.js +332 -0
  16. package/dist/chunk-BGN5ZMP4.js +26 -0
  17. package/dist/chunk-BTU3TJDS.js +365 -0
  18. package/dist/chunk-CHF5OHIA.js +61 -0
  19. package/dist/chunk-CMBFNA7L.js +27 -0
  20. package/dist/chunk-DAHRH4ON.js +331 -0
  21. package/dist/chunk-EBGIRKQY.js +616 -0
  22. package/dist/chunk-EUZND3CB.js +27 -0
  23. package/dist/chunk-F3FA4F32.js +292 -0
  24. package/dist/chunk-GCOK2LC3.js +282 -0
  25. package/dist/chunk-JAKHTMQU.js +1000 -0
  26. package/dist/chunk-JCI5M6U6.js +956 -0
  27. package/dist/chunk-KQPDEVVS.js +398 -0
  28. package/dist/chunk-NEKUBFPT.js +60 -0
  29. package/dist/chunk-NYVAC6P5.js +37 -0
  30. package/dist/chunk-OUZZEE4S.js +365 -0
  31. package/dist/chunk-P6W3STU4.js +2249 -0
  32. package/dist/chunk-PTQJDMRT.js +146 -0
  33. package/dist/chunk-QWZG56ET.js +2744 -0
  34. package/dist/chunk-TSOKIX5Z.js +654 -0
  35. package/dist/chunk-VMVDTCXB.js +712 -0
  36. package/dist/chunk-VRW3FULF.js +725 -0
  37. package/dist/chunk-WZSPOOER.js +84 -0
  38. package/dist/chunk-YT6HQ6AM.js +14 -0
  39. package/dist/chunk-ZD6OAMTH.js +277 -0
  40. package/dist/contracts-DDrwxvJ-.d.cts +245 -0
  41. package/dist/contracts-DDrwxvJ-.d.ts +245 -0
  42. package/dist/data.cjs +35 -2
  43. package/dist/data.d.cts +7 -0
  44. package/dist/data.d.ts +7 -0
  45. package/dist/data.js +9 -8
  46. package/dist/devtools.cjs +122 -0
  47. package/dist/devtools.d.cts +69 -461
  48. package/dist/devtools.d.ts +69 -461
  49. package/dist/devtools.js +127 -6
  50. package/dist/ecosystem.cjs +68 -23
  51. package/dist/ecosystem.d.cts +1 -1
  52. package/dist/ecosystem.d.ts +1 -1
  53. package/dist/ecosystem.js +10 -9
  54. package/dist/extras.cjs +1252 -82
  55. package/dist/extras.d.cts +5 -5
  56. package/dist/extras.d.ts +5 -5
  57. package/dist/extras.js +69 -24
  58. package/dist/index.cjs +708 -161
  59. package/dist/index.d.cts +397 -17
  60. package/dist/index.d.ts +397 -17
  61. package/dist/index.js +39 -17
  62. package/dist/introspect-BumjnBKr.d.cts +477 -0
  63. package/dist/introspect-CZrlcaYy.d.ts +477 -0
  64. package/dist/introspect-Cb0zgpi2.d.cts +477 -0
  65. package/dist/introspect-Y2xNXGSf.d.ts +477 -0
  66. package/dist/motion.js +4 -4
  67. package/dist/patterns.cjs +51 -2
  68. package/dist/patterns.d.cts +18 -8
  69. package/dist/patterns.d.ts +18 -8
  70. package/dist/patterns.js +7 -7
  71. package/dist/performance.js +4 -4
  72. package/dist/plugins.cjs +473 -98
  73. package/dist/plugins.d.cts +27 -4
  74. package/dist/plugins.d.ts +27 -4
  75. package/dist/plugins.js +156 -37
  76. package/dist/ssr-4PBXAOO3.js +40 -0
  77. package/dist/ssr-Do_SiVoL.d.cts +201 -0
  78. package/dist/ssr-Do_SiVoL.d.ts +201 -0
  79. package/dist/ssr.cjs +357 -77
  80. package/dist/ssr.d.cts +10 -1
  81. package/dist/ssr.d.ts +10 -1
  82. package/dist/ssr.js +13 -10
  83. package/dist/tagFactory-DaJ0YWX6.d.cts +47 -0
  84. package/dist/tagFactory-DaJ0YWX6.d.ts +47 -0
  85. package/dist/testing.cjs +233 -2
  86. package/dist/testing.d.cts +42 -1
  87. package/dist/testing.d.ts +42 -1
  88. package/dist/testing.js +129 -2
  89. package/dist/ui.cjs +374 -3
  90. package/dist/ui.d.cts +252 -2
  91. package/dist/ui.d.ts +252 -2
  92. package/dist/ui.js +328 -8
  93. package/dist/widgets.js +7 -7
  94. package/package.json +1 -1
package/dist/build.cjs CHANGED
@@ -1059,12 +1059,14 @@ var index_exports = {};
1059
1059
  __export(index_exports, {
1060
1060
  DynamicComponent: () => DynamicComponent,
1061
1061
  ErrorBoundary: () => ErrorBoundary,
1062
+ ErrorDisplay: () => ErrorDisplay,
1062
1063
  Fragment: () => Fragment,
1063
1064
  KeepAlive: () => KeepAlive,
1064
1065
  Loading: () => Loading,
1065
1066
  Portal: () => Portal,
1066
1067
  SVG_NS: () => SVG_NS,
1067
1068
  Suspense: () => Suspense,
1069
+ __resetIdCounter: () => __resetIdCounter,
1068
1070
  a: () => a,
1069
1071
  abbr: () => abbr,
1070
1072
  action: () => action,
@@ -1073,6 +1075,7 @@ __export(index_exports, {
1073
1075
  array: () => array,
1074
1076
  article: () => article,
1075
1077
  aside: () => aside,
1078
+ asyncDerived: () => asyncDerived,
1076
1079
  audio: () => audio,
1077
1080
  autoResize: () => autoResize,
1078
1081
  b: () => b,
@@ -1100,12 +1103,14 @@ __export(index_exports, {
1100
1103
  colgroup: () => colgroup,
1101
1104
  context: () => context,
1102
1105
  copyOnClick: () => copyOnClick,
1106
+ createId: () => createId,
1103
1107
  customElement: () => customElement,
1104
1108
  data: () => data,
1105
1109
  datalist: () => datalist,
1106
1110
  dd: () => dd,
1107
1111
  deepEqual: () => deepEqual,
1108
1112
  deepSignal: () => deepSignal,
1113
+ defer: () => defer,
1109
1114
  defs: () => defs,
1110
1115
  del: () => del,
1111
1116
  derived: () => derived,
@@ -1173,6 +1178,7 @@ __export(index_exports, {
1173
1178
  meter: () => meter,
1174
1179
  mount: () => mount,
1175
1180
  nav: () => nav,
1181
+ nextTick: () => nextTick,
1176
1182
  noscript: () => noscript,
1177
1183
  object: () => object,
1178
1184
  ol: () => ol,
@@ -1218,6 +1224,8 @@ __export(index_exports, {
1218
1224
  span: () => span,
1219
1225
  stop: () => stop,
1220
1226
  store: () => store,
1227
+ strict: () => strict,
1228
+ strictEffect: () => strictEffect,
1221
1229
  strong: () => strong,
1222
1230
  style: () => style,
1223
1231
  sub: () => sub,
@@ -1239,6 +1247,7 @@ __export(index_exports, {
1239
1247
  title: () => title,
1240
1248
  tr: () => tr,
1241
1249
  track: () => track2,
1250
+ transition: () => transition,
1242
1251
  trapFocus: () => trapFocus,
1243
1252
  tspan: () => tspan,
1244
1253
  u: () => u,
@@ -1557,7 +1566,20 @@ function cleanup(subscriber) {
1557
1566
 
1558
1567
  // src/reactivity/bindAttribute.ts
1559
1568
  var _isDev3 = isDev();
1569
+ function isEventHandlerAttr(name) {
1570
+ if (name.length < 3) return false;
1571
+ const lower = name.toLowerCase();
1572
+ return lower[0] === "o" && lower[1] === "n" && lower.charCodeAt(2) >= 97 && lower.charCodeAt(2) <= 122;
1573
+ }
1560
1574
  function bindAttribute(el, attr, getter) {
1575
+ if (isEventHandlerAttr(attr)) {
1576
+ if (_isDev3)
1577
+ devWarn(
1578
+ `bindAttribute: refusing to bind event-handler attribute "${attr}". Use on:{ ${attr.slice(2)}: fn } instead.`
1579
+ );
1580
+ return () => {
1581
+ };
1582
+ }
1561
1583
  function commit() {
1562
1584
  let value;
1563
1585
  try {
@@ -1637,11 +1659,11 @@ function bindChildNode(placeholder, getter) {
1637
1659
  if (_isDev4) devWarn(`bindChildNode: getter threw: ${err instanceof Error ? err.message : String(err)}`);
1638
1660
  return;
1639
1661
  }
1640
- for (let i2 = 0; i2 < lastNodes.length; i2++) {
1641
- const node = lastNodes[i2];
1642
- if (node.parentNode) node.parentNode.removeChild(node);
1643
- }
1644
1662
  if (result == null || typeof result === "boolean") {
1663
+ for (let i2 = 0; i2 < lastNodes.length; i2++) {
1664
+ const node = lastNodes[i2];
1665
+ if (node.parentNode) node.parentNode.removeChild(node);
1666
+ }
1645
1667
  lastNodes.length = 0;
1646
1668
  return;
1647
1669
  }
@@ -1650,24 +1672,46 @@ function bindChildNode(placeholder, getter) {
1650
1672
  lastNodes.length = 0;
1651
1673
  return;
1652
1674
  }
1653
- const anchor = placeholder.nextSibling;
1654
- let count = 0;
1675
+ let newNodes;
1655
1676
  if (Array.isArray(result)) {
1656
- if (lastNodes.length < result.length) lastNodes = new Array(result.length);
1677
+ newNodes = [];
1657
1678
  for (let i2 = 0; i2 < result.length; i2++) {
1658
1679
  const item = result[i2];
1659
1680
  if (item == null || typeof item === "boolean") continue;
1660
- const node = item instanceof Node ? item : document.createTextNode(String(item));
1661
- parent.insertBefore(node, anchor);
1662
- lastNodes[count++] = node;
1681
+ newNodes.push(item instanceof Node ? item : document.createTextNode(String(item)));
1663
1682
  }
1664
1683
  } else {
1665
- if (lastNodes.length < 1) lastNodes = [null];
1666
1684
  const node = result instanceof Node ? result : document.createTextNode(String(result));
1667
- parent.insertBefore(node, anchor);
1668
- lastNodes[count++] = node;
1685
+ newNodes = [node];
1686
+ }
1687
+ const reused = lastNodes.length > 0 && newNodes.length > 0 ? /* @__PURE__ */ new Set() : void 0;
1688
+ if (reused) {
1689
+ for (let i2 = 0; i2 < newNodes.length; i2++) {
1690
+ for (let j = 0; j < lastNodes.length; j++) {
1691
+ if (newNodes[i2] === lastNodes[j]) {
1692
+ reused.add(newNodes[i2]);
1693
+ break;
1694
+ }
1695
+ }
1696
+ }
1697
+ }
1698
+ for (let i2 = 0; i2 < lastNodes.length; i2++) {
1699
+ const node = lastNodes[i2];
1700
+ if (reused?.has(node)) continue;
1701
+ if (node.parentNode) node.parentNode.removeChild(node);
1702
+ }
1703
+ const anchor = placeholder.nextSibling;
1704
+ for (let i2 = 0; i2 < newNodes.length; i2++) {
1705
+ const node = newNodes[i2];
1706
+ if (reused?.has(node) && node.parentNode === parent) {
1707
+ if (node.nextSibling !== anchor) {
1708
+ parent.insertBefore(node, anchor);
1709
+ }
1710
+ } else {
1711
+ parent.insertBefore(node, anchor);
1712
+ }
1669
1713
  }
1670
- lastNodes.length = count;
1714
+ lastNodes = newNodes;
1671
1715
  }
1672
1716
  return track(commit);
1673
1717
  }
@@ -1845,16 +1889,20 @@ function appendChildren(el, nodes) {
1845
1889
  var tagFactory = (tag, ns) => (first, second) => {
1846
1890
  const el = ns ? document.createElementNS(ns, tag) : document.createElement(tag);
1847
1891
  if (first === void 0) return el;
1848
- if (second === void 0 && typeof first === "string") {
1892
+ if (typeof first === "string") {
1893
+ if (second !== void 0) {
1894
+ el.setAttribute("class", first);
1895
+ appendChildren(el, second);
1896
+ return el;
1897
+ }
1849
1898
  el.textContent = first;
1850
1899
  return el;
1851
1900
  }
1852
- if (second !== void 0) {
1853
- el.setAttribute("class", first);
1854
- appendChildren(el, second);
1901
+ if (typeof first === "number") {
1902
+ el.textContent = String(first);
1855
1903
  return el;
1856
1904
  }
1857
- if (Array.isArray(first) || first instanceof Node) {
1905
+ if (Array.isArray(first) || first instanceof Node || typeof first === "function") {
1858
1906
  appendChildren(el, first);
1859
1907
  return el;
1860
1908
  }
@@ -1863,7 +1911,7 @@ var tagFactory = (tag, ns) => (first, second) => {
1863
1911
  if (pClass != null) applyClass(el, pClass);
1864
1912
  const pId = props.id;
1865
1913
  if (pId != null) el.id = pId;
1866
- const pNodes = props.nodes;
1914
+ const pNodes = second !== void 0 ? second : props.nodes;
1867
1915
  if (pNodes != null) appendChildren(el, pNodes);
1868
1916
  const pOn = props.on;
1869
1917
  if (pOn) {
@@ -1888,12 +1936,18 @@ var tagFactory = (tag, ns) => (first, second) => {
1888
1936
  // already handled above / below
1889
1937
  default: {
1890
1938
  const value = props[key];
1891
- if (value == null || value === false) continue;
1939
+ if (value == null) continue;
1892
1940
  if (key[0] === "o" && key[1] === "n") continue;
1893
1941
  if (typeof value === "function") {
1894
1942
  registerDisposer(el, bindAttribute(el, key, value));
1895
- } else if (value === true) {
1896
- el.setAttribute(key, "");
1943
+ } else if (typeof value === "boolean") {
1944
+ if (key in el && (key === "checked" || key === "disabled" || key === "selected")) {
1945
+ el[key] = value;
1946
+ } else if (value) {
1947
+ el.setAttribute(key, "");
1948
+ } else {
1949
+ el.removeAttribute(key);
1950
+ }
1897
1951
  } else {
1898
1952
  const str = String(value);
1899
1953
  el.setAttribute(key, isUrlAttribute(key) ? sanitizeUrl(str) : str);
@@ -2941,6 +2995,16 @@ function setGlobalErrorHandler(handler) {
2941
2995
  globalErrorHandler = handler;
2942
2996
  }
2943
2997
 
2998
+ // src/core/rendering/createId.ts
2999
+ var idCounter = 0;
3000
+ function createId(prefix = "sibu") {
3001
+ idCounter++;
3002
+ return `${prefix}-${idCounter}`;
3003
+ }
3004
+ function __resetIdCounter() {
3005
+ idCounter = 0;
3006
+ }
3007
+
2944
3008
  // src/reactivity/batch.ts
2945
3009
  var batchDepth = 0;
2946
3010
  var pendingSignals = /* @__PURE__ */ new Set();
@@ -3021,11 +3085,12 @@ function disableSSR() {
3021
3085
  ssrMode = false;
3022
3086
  }
3023
3087
  function withSSR(fn) {
3088
+ const wasSSR = ssrMode;
3024
3089
  enableSSR();
3025
3090
  try {
3026
3091
  return fn();
3027
3092
  } finally {
3028
- disableSSR();
3093
+ if (!wasSSR) disableSSR();
3029
3094
  }
3030
3095
  }
3031
3096
 
@@ -3475,6 +3540,47 @@ function writable(get, set, options) {
3475
3540
  return [getter, setter];
3476
3541
  }
3477
3542
 
3543
+ // src/core/signals/asyncDerived.ts
3544
+ function asyncDerived(factory, initial) {
3545
+ const [value, setValue] = signal(initial);
3546
+ const [loading, setLoading] = signal(false);
3547
+ const [error, setError] = signal(null);
3548
+ const [tick, setTick] = signal(0);
3549
+ let runId = 0;
3550
+ effect(() => {
3551
+ tick();
3552
+ const currentRun = ++runId;
3553
+ setLoading(true);
3554
+ setError(null);
3555
+ let promise;
3556
+ try {
3557
+ promise = factory();
3558
+ } catch (err) {
3559
+ setError(err);
3560
+ setLoading(false);
3561
+ return;
3562
+ }
3563
+ promise.then(
3564
+ (result) => {
3565
+ if (currentRun !== runId) return;
3566
+ setValue(result);
3567
+ setLoading(false);
3568
+ },
3569
+ (err) => {
3570
+ if (currentRun !== runId) return;
3571
+ setError(err);
3572
+ setLoading(false);
3573
+ }
3574
+ );
3575
+ });
3576
+ return {
3577
+ value,
3578
+ loading,
3579
+ error,
3580
+ refresh: () => setTick((n) => n + 1)
3581
+ };
3582
+ }
3583
+
3478
3584
  // src/core/rendering/lifecycle.ts
3479
3585
  function safeCall(cb, hookName) {
3480
3586
  try {
@@ -3553,6 +3659,116 @@ function context(defaultValue) {
3553
3659
  };
3554
3660
  }
3555
3661
 
3662
+ // src/core/strict.ts
3663
+ function strict(fn) {
3664
+ const result = fn();
3665
+ if (isDev()) {
3666
+ queueMicrotask(() => {
3667
+ try {
3668
+ fn();
3669
+ } catch (err) {
3670
+ console.warn("[Sibu strict] second run threw:", err);
3671
+ }
3672
+ });
3673
+ }
3674
+ return result;
3675
+ }
3676
+ function strictEffect(fn) {
3677
+ if (!isDev()) {
3678
+ return effect(fn);
3679
+ }
3680
+ const firstTeardown = effect(fn);
3681
+ let secondTeardown = null;
3682
+ queueMicrotask(() => {
3683
+ try {
3684
+ secondTeardown = effect(fn);
3685
+ } catch (err) {
3686
+ console.warn("[Sibu strictEffect] second run threw:", err);
3687
+ }
3688
+ });
3689
+ return () => {
3690
+ firstTeardown();
3691
+ if (secondTeardown) secondTeardown();
3692
+ };
3693
+ }
3694
+
3695
+ // src/reactivity/nextTick.ts
3696
+ function nextTick() {
3697
+ return new Promise((resolve) => {
3698
+ queueMicrotask(() => {
3699
+ if (typeof requestAnimationFrame === "function") {
3700
+ requestAnimationFrame(() => resolve());
3701
+ } else {
3702
+ resolve();
3703
+ }
3704
+ });
3705
+ });
3706
+ }
3707
+
3708
+ // src/reactivity/concurrent.ts
3709
+ function defer(getter) {
3710
+ const [value, setValue] = signal(getter());
3711
+ let pending = false;
3712
+ let latest = value();
3713
+ const flush = () => {
3714
+ pending = false;
3715
+ setValue(latest);
3716
+ };
3717
+ const schedule = () => {
3718
+ if (pending) return;
3719
+ pending = true;
3720
+ queueMicrotask(() => {
3721
+ if (typeof requestAnimationFrame === "function") {
3722
+ requestAnimationFrame(flush);
3723
+ } else {
3724
+ flush();
3725
+ }
3726
+ });
3727
+ };
3728
+ track(() => {
3729
+ latest = getter();
3730
+ schedule();
3731
+ });
3732
+ return value;
3733
+ }
3734
+ var IDLE_FALLBACK_MS = 16;
3735
+ function scheduleIdle(fn) {
3736
+ const g2 = globalThis;
3737
+ if (typeof g2.requestIdleCallback === "function") {
3738
+ g2.requestIdleCallback(fn, { timeout: IDLE_FALLBACK_MS * 4 });
3739
+ return;
3740
+ }
3741
+ if (typeof requestAnimationFrame === "function") {
3742
+ requestAnimationFrame(() => fn());
3743
+ return;
3744
+ }
3745
+ setTimeout(fn, IDLE_FALLBACK_MS);
3746
+ }
3747
+ function transition() {
3748
+ const [pending, setPending] = signal(false);
3749
+ function start(fn) {
3750
+ setPending(true);
3751
+ scheduleIdle(() => {
3752
+ let result;
3753
+ try {
3754
+ result = fn();
3755
+ } catch {
3756
+ setPending(false);
3757
+ return;
3758
+ }
3759
+ if (result && typeof result.then === "function") {
3760
+ result.then(
3761
+ () => setPending(false),
3762
+ () => setPending(false)
3763
+ );
3764
+ } else {
3765
+ setPending(false);
3766
+ }
3767
+ });
3768
+ }
3769
+ return { pending, start };
3770
+ }
3771
+
3556
3772
  // src/core/rendering/lazy.ts
3557
3773
  function lazy(importFn) {
3558
3774
  let cached = null;
@@ -3611,8 +3827,446 @@ function Suspense({ nodes, fallback }) {
3611
3827
  return container;
3612
3828
  }
3613
3829
 
3614
- // src/components/ErrorBoundary.ts
3830
+ // src/components/ErrorDisplay.ts
3615
3831
  var _isDev8 = isDev();
3832
+ var STYLES = `
3833
+ .sibu-error-display {
3834
+ border: 1px solid var(--sibu-err-border, #e5484d);
3835
+ border-radius: 10px;
3836
+ margin: 12px 0;
3837
+ background: #0f0f1a;
3838
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
3839
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
3840
+ color: #e5e7eb;
3841
+ overflow: hidden;
3842
+ }
3843
+ .sibu-error-display[data-severity="warning"] { --sibu-err-border: #d97706; --sibu-err-accent: #d97706; }
3844
+ .sibu-error-display[data-severity="info"] { --sibu-err-border: #3b82f6; --sibu-err-accent: #3b82f6; }
3845
+ .sibu-error-display { --sibu-err-accent: #e5484d; }
3846
+
3847
+ .sibu-error-display .sibu-err-header {
3848
+ display: flex;
3849
+ align-items: center;
3850
+ gap: 10px;
3851
+ padding: 12px 18px;
3852
+ background: var(--sibu-err-accent);
3853
+ color: white;
3854
+ user-select: none;
3855
+ }
3856
+ .sibu-error-display .sibu-err-icon {
3857
+ font-family: 'SF Mono', 'JetBrains Mono', 'Fira Code', monospace;
3858
+ font-weight: bold;
3859
+ font-size: 1.05em;
3860
+ padding: 2px 8px;
3861
+ background: rgba(0, 0, 0, 0.22);
3862
+ border-radius: 4px;
3863
+ letter-spacing: 0.02em;
3864
+ }
3865
+ .sibu-error-display .sibu-err-title {
3866
+ margin: 0;
3867
+ font-size: 0.98em;
3868
+ font-weight: 600;
3869
+ flex: 1;
3870
+ text-overflow: ellipsis;
3871
+ overflow: hidden;
3872
+ white-space: nowrap;
3873
+ }
3874
+ .sibu-error-display .sibu-err-timestamp {
3875
+ font-size: 0.75em;
3876
+ opacity: 0.85;
3877
+ font-family: 'SF Mono', 'JetBrains Mono', monospace;
3878
+ }
3879
+
3880
+ .sibu-error-display .sibu-err-body {
3881
+ padding: 16px 18px;
3882
+ }
3883
+ .sibu-error-display .sibu-err-message {
3884
+ font-family: 'SF Mono', 'JetBrains Mono', 'Fira Code', monospace;
3885
+ margin: 0 0 14px;
3886
+ color: #fecaca;
3887
+ word-break: break-word;
3888
+ font-size: 0.9em;
3889
+ line-height: 1.55;
3890
+ padding: 10px 12px;
3891
+ background: rgba(229, 72, 77, 0.08);
3892
+ border-left: 3px solid var(--sibu-err-accent);
3893
+ border-radius: 4px;
3894
+ }
3895
+
3896
+ .sibu-error-display .sibu-err-section {
3897
+ margin-top: 14px;
3898
+ border-radius: 6px;
3899
+ border: 1px solid #2a2a3e;
3900
+ background: #0a0a14;
3901
+ overflow: hidden;
3902
+ }
3903
+ .sibu-error-display .sibu-err-section-head {
3904
+ display: flex;
3905
+ align-items: center;
3906
+ justify-content: space-between;
3907
+ padding: 6px 12px;
3908
+ background: #16162a;
3909
+ border-bottom: 1px solid #2a2a3e;
3910
+ font-size: 0.72em;
3911
+ color: #8b8fa3;
3912
+ text-transform: uppercase;
3913
+ letter-spacing: 0.08em;
3914
+ font-weight: 600;
3915
+ }
3916
+ .sibu-error-display .sibu-err-copy-btn {
3917
+ background: transparent;
3918
+ border: 1px solid #3a3a4e;
3919
+ border-radius: 4px;
3920
+ color: #a0a3b8;
3921
+ cursor: pointer;
3922
+ padding: 2px 10px;
3923
+ font-size: 0.95em;
3924
+ font-family: inherit;
3925
+ transition: all 0.12s ease;
3926
+ }
3927
+ .sibu-error-display .sibu-err-copy-btn:hover {
3928
+ background: #2a2a3e;
3929
+ color: #e5e7eb;
3930
+ border-color: #4a4a5e;
3931
+ }
3932
+
3933
+ .sibu-error-display .sibu-err-stack {
3934
+ margin: 0;
3935
+ padding: 10px 12px;
3936
+ overflow-x: auto;
3937
+ font-family: 'SF Mono', 'JetBrains Mono', monospace;
3938
+ font-size: 0.8em;
3939
+ line-height: 1.7;
3940
+ }
3941
+ .sibu-error-display .sibu-err-frame {
3942
+ display: flex;
3943
+ gap: 10px;
3944
+ padding: 1px 0;
3945
+ }
3946
+ .sibu-error-display .sibu-err-line {
3947
+ display: inline-block;
3948
+ min-width: 2.2ch;
3949
+ color: #4b5066;
3950
+ text-align: right;
3951
+ user-select: none;
3952
+ flex-shrink: 0;
3953
+ }
3954
+ .sibu-error-display .sibu-err-fn {
3955
+ color: #7dd3fc;
3956
+ font-weight: 500;
3957
+ }
3958
+ .sibu-error-display .sibu-err-loc {
3959
+ color: #6b7280;
3960
+ white-space: nowrap;
3961
+ }
3962
+ .sibu-error-display .sibu-err-cause-label {
3963
+ margin: 12px 0 6px;
3964
+ color: #a0a3b8;
3965
+ font-size: 0.75em;
3966
+ text-transform: uppercase;
3967
+ letter-spacing: 0.05em;
3968
+ }
3969
+
3970
+ .sibu-error-display .sibu-err-meta {
3971
+ margin: 0;
3972
+ padding: 10px 12px;
3973
+ font-family: 'SF Mono', 'JetBrains Mono', monospace;
3974
+ font-size: 0.78em;
3975
+ color: #a0a3b8;
3976
+ display: grid;
3977
+ grid-template-columns: minmax(120px, auto) 1fr;
3978
+ gap: 4px 16px;
3979
+ }
3980
+ .sibu-error-display .sibu-err-meta dt { color: #6b7280; }
3981
+ .sibu-error-display .sibu-err-meta dd { margin: 0; color: #d1d5db; word-break: break-word; }
3982
+
3983
+ .sibu-error-display .sibu-err-actions {
3984
+ display: flex;
3985
+ gap: 8px;
3986
+ margin-top: 16px;
3987
+ }
3988
+ .sibu-error-display .sibu-err-btn {
3989
+ display: inline-flex;
3990
+ align-items: center;
3991
+ gap: 6px;
3992
+ padding: 8px 18px;
3993
+ border: none;
3994
+ border-radius: 6px;
3995
+ cursor: pointer;
3996
+ font-size: 13px;
3997
+ font-weight: 500;
3998
+ transition: all 0.12s ease;
3999
+ font-family: inherit;
4000
+ }
4001
+ .sibu-error-display .sibu-err-btn-retry {
4002
+ background: var(--sibu-err-accent);
4003
+ color: white;
4004
+ }
4005
+ .sibu-error-display .sibu-err-btn-retry:hover { filter: brightness(1.1); }
4006
+ .sibu-error-display .sibu-err-btn-reload {
4007
+ background: #1f2133;
4008
+ color: #d1d5db;
4009
+ border: 1px solid #3a3a4e;
4010
+ }
4011
+ .sibu-error-display .sibu-err-btn-reload:hover { background: #2a2b40; }
4012
+ `;
4013
+ var _stylesInjected = false;
4014
+ function injectStyles() {
4015
+ if (_stylesInjected || typeof document === "undefined") return;
4016
+ const el = style({ nodes: STYLES });
4017
+ document.head.appendChild(el);
4018
+ _stylesInjected = true;
4019
+ }
4020
+ function parseStack(stack) {
4021
+ const frames = [];
4022
+ const lines = stack.split("\n");
4023
+ for (const raw of lines) {
4024
+ const line2 = raw.trim();
4025
+ const chrome = line2.match(/^at\s+(?:(.+?)\s+\((.+)\)|(.+))$/);
4026
+ if (chrome) {
4027
+ frames.push({ fn: chrome[1] || "(anonymous)", loc: chrome[2] || chrome[3] || "" });
4028
+ continue;
4029
+ }
4030
+ const ff = line2.match(/^(.+?)@(.+)$/);
4031
+ if (ff) {
4032
+ frames.push({ fn: ff[1] || "(anonymous)", loc: ff[2] || "" });
4033
+ }
4034
+ }
4035
+ return frames;
4036
+ }
4037
+ function normalizeError(err) {
4038
+ if (err instanceof Error) {
4039
+ const code2 = err.code ?? err.name ?? "ERROR";
4040
+ const message = err.message || "Unknown error";
4041
+ const stack = err.stack ?? "";
4042
+ const frames = parseStack(stack);
4043
+ const rawCause = err.cause;
4044
+ const cause = rawCause != null ? normalizeError(rawCause) : null;
4045
+ return { code: code2, message, stack, frames, cause };
4046
+ }
4047
+ return {
4048
+ code: "NON_ERROR",
4049
+ message: typeof err === "string" ? err : JSON.stringify(err),
4050
+ stack: "",
4051
+ frames: [],
4052
+ cause: null
4053
+ };
4054
+ }
4055
+ function buildCopyText(err, meta2) {
4056
+ const lines = [];
4057
+ lines.push(`[${err.code}] ${err.message}`);
4058
+ if (err.stack) {
4059
+ lines.push("");
4060
+ lines.push(err.stack);
4061
+ }
4062
+ if (err.cause) {
4063
+ lines.push("");
4064
+ lines.push("Caused by:");
4065
+ lines.push(` [${err.cause.code}] ${err.cause.message}`);
4066
+ if (err.cause.stack) {
4067
+ const indented = err.cause.stack.split("\n").map((l) => ` ${l}`).join("\n");
4068
+ lines.push(indented);
4069
+ }
4070
+ }
4071
+ if (meta2 && Object.keys(meta2).length > 0) {
4072
+ lines.push("");
4073
+ lines.push("Metadata:");
4074
+ for (const [k, v] of Object.entries(meta2)) {
4075
+ lines.push(` ${k}: ${String(v)}`);
4076
+ }
4077
+ }
4078
+ lines.push("");
4079
+ lines.push(`At: ${(/* @__PURE__ */ new Date()).toISOString()}`);
4080
+ if (typeof navigator !== "undefined" && navigator.userAgent) {
4081
+ lines.push(`UA: ${navigator.userAgent}`);
4082
+ }
4083
+ return lines.join("\n");
4084
+ }
4085
+ function renderFrames(frames) {
4086
+ const rows = frames.map(
4087
+ (f, i2) => div({
4088
+ class: "sibu-err-frame",
4089
+ nodes: [
4090
+ span({ class: "sibu-err-line", nodes: String(i2 + 1) }),
4091
+ span({ class: "sibu-err-fn", nodes: f.fn }),
4092
+ span({ class: "sibu-err-loc", nodes: ` \u2014 ${f.loc}` })
4093
+ ]
4094
+ })
4095
+ );
4096
+ return pre({ class: "sibu-err-stack", nodes: rows });
4097
+ }
4098
+ function renderCauseChain(cause) {
4099
+ if (!cause) return [];
4100
+ return [
4101
+ div({ class: "sibu-err-cause-label", nodes: "Caused by" }),
4102
+ div({
4103
+ class: "sibu-err-section",
4104
+ nodes: [
4105
+ div({
4106
+ class: "sibu-err-section-head",
4107
+ nodes: [span({ nodes: `[${cause.code}] ${cause.message}` }), span({ nodes: "" })]
4108
+ }),
4109
+ cause.frames.length > 0 ? renderFrames(cause.frames) : div({ class: "sibu-err-stack", nodes: "(no stack)" })
4110
+ ]
4111
+ }),
4112
+ ...renderCauseChain(cause.cause)
4113
+ ];
4114
+ }
4115
+ function renderMetadata(meta2) {
4116
+ const rows = [];
4117
+ for (const [k, v] of Object.entries(meta2)) {
4118
+ rows.push(document.createElement("dt"));
4119
+ rows[rows.length - 1].textContent = k;
4120
+ const dd2 = document.createElement("dd");
4121
+ dd2.textContent = v == null ? "(null)" : String(v);
4122
+ rows.push(dd2);
4123
+ }
4124
+ const dl2 = document.createElement("dl");
4125
+ dl2.className = "sibu-err-meta";
4126
+ for (const r of rows) dl2.appendChild(r);
4127
+ return dl2;
4128
+ }
4129
+ function ErrorDisplay(props) {
4130
+ injectStyles();
4131
+ const severity = props.severity ?? "error";
4132
+ const normalized = normalizeError(props.error);
4133
+ const showDetails = props.alwaysShowDetails ?? _isDev8;
4134
+ const headline = props.title ?? normalized.message;
4135
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19);
4136
+ const [copyLabel, setCopyLabel] = signal("Copy");
4137
+ const copyBtn = button({
4138
+ class: "sibu-err-copy-btn",
4139
+ nodes: () => copyLabel(),
4140
+ on: {
4141
+ click: () => {
4142
+ const text2 = buildCopyText(normalized, props.metadata);
4143
+ if (typeof navigator !== "undefined" && navigator.clipboard) {
4144
+ navigator.clipboard.writeText(text2).then(
4145
+ () => {
4146
+ setCopyLabel("Copied!");
4147
+ setTimeout(() => setCopyLabel("Copy"), 1500);
4148
+ },
4149
+ () => {
4150
+ setCopyLabel("Copy failed");
4151
+ setTimeout(() => setCopyLabel("Copy"), 1500);
4152
+ }
4153
+ );
4154
+ }
4155
+ }
4156
+ }
4157
+ });
4158
+ const header2 = div({
4159
+ class: "sibu-err-header",
4160
+ nodes: [
4161
+ code({ class: "sibu-err-icon", nodes: normalized.code }),
4162
+ h3({ class: "sibu-err-title", nodes: headline }),
4163
+ span({ class: "sibu-err-timestamp", nodes: timestamp })
4164
+ ]
4165
+ });
4166
+ const bodyChildren = [p({ class: "sibu-err-message", nodes: normalized.message })];
4167
+ if (showDetails && normalized.frames.length > 0) {
4168
+ bodyChildren.push(
4169
+ div({
4170
+ class: "sibu-err-section",
4171
+ nodes: [
4172
+ div({
4173
+ class: "sibu-err-section-head",
4174
+ nodes: [span({ nodes: "Stack Trace" }), copyBtn]
4175
+ }),
4176
+ renderFrames(normalized.frames)
4177
+ ]
4178
+ })
4179
+ );
4180
+ } else if (showDetails) {
4181
+ bodyChildren.push(
4182
+ div({
4183
+ class: "sibu-err-section",
4184
+ nodes: [
4185
+ div({
4186
+ class: "sibu-err-section-head",
4187
+ nodes: [span({ nodes: "Details" }), copyBtn]
4188
+ }),
4189
+ div({ class: "sibu-err-stack", nodes: "(no stack available)" })
4190
+ ]
4191
+ })
4192
+ );
4193
+ }
4194
+ if (showDetails) {
4195
+ bodyChildren.push(...renderCauseChain(normalized.cause));
4196
+ }
4197
+ if (showDetails && props.metadata && Object.keys(props.metadata).length > 0) {
4198
+ bodyChildren.push(
4199
+ div({
4200
+ class: "sibu-err-section",
4201
+ nodes: [
4202
+ div({ class: "sibu-err-section-head", nodes: [span({ nodes: "Metadata" })] }),
4203
+ renderMetadata(props.metadata)
4204
+ ]
4205
+ })
4206
+ );
4207
+ }
4208
+ if (showDetails && typeof navigator !== "undefined" && navigator.userAgent) {
4209
+ bodyChildren.push(
4210
+ div({
4211
+ class: "sibu-err-section",
4212
+ nodes: [
4213
+ div({ class: "sibu-err-section-head", nodes: [span({ nodes: "Environment" })] }),
4214
+ div({
4215
+ class: "sibu-err-meta",
4216
+ nodes: (() => {
4217
+ const dl2 = document.createElement("dl");
4218
+ dl2.className = "sibu-err-meta";
4219
+ const entries = [
4220
+ ["User Agent", navigator.userAgent],
4221
+ ["URL", typeof location !== "undefined" ? location.href : "(n/a)"],
4222
+ ["Timestamp", (/* @__PURE__ */ new Date()).toISOString()]
4223
+ ];
4224
+ for (const [k, v] of entries) {
4225
+ const dt2 = document.createElement("dt");
4226
+ dt2.textContent = k;
4227
+ const dd2 = document.createElement("dd");
4228
+ dd2.textContent = v;
4229
+ dl2.appendChild(dt2);
4230
+ dl2.appendChild(dd2);
4231
+ }
4232
+ return dl2;
4233
+ })()
4234
+ })
4235
+ ]
4236
+ })
4237
+ );
4238
+ }
4239
+ const actionButtons = [];
4240
+ if (props.onRetry) {
4241
+ actionButtons.push(
4242
+ button({
4243
+ class: "sibu-err-btn sibu-err-btn-retry",
4244
+ nodes: props.retryLabel ?? "Retry",
4245
+ on: { click: props.onRetry }
4246
+ })
4247
+ );
4248
+ }
4249
+ if (!props.hideReload && typeof location !== "undefined") {
4250
+ actionButtons.push(
4251
+ button({
4252
+ class: "sibu-err-btn sibu-err-btn-reload",
4253
+ nodes: "Reload Page",
4254
+ on: { click: () => location.reload() }
4255
+ })
4256
+ );
4257
+ }
4258
+ if (actionButtons.length > 0) {
4259
+ bodyChildren.push(div({ class: "sibu-err-actions", nodes: actionButtons }));
4260
+ }
4261
+ const body2 = div({ class: "sibu-err-body", nodes: bodyChildren });
4262
+ return div({
4263
+ class: "sibu-error-display",
4264
+ "data-severity": severity,
4265
+ nodes: [header2, body2]
4266
+ });
4267
+ }
4268
+
4269
+ // src/components/ErrorBoundary.ts
3616
4270
  var errorBoundaryStyles = `
3617
4271
  .sibu-error-boundary {
3618
4272
  position: relative;
@@ -3769,7 +4423,7 @@ var errorBoundaryStyles = `
3769
4423
  }
3770
4424
  `;
3771
4425
  var stylesInjected = false;
3772
- function injectStyles() {
4426
+ function injectStyles2() {
3773
4427
  if (!stylesInjected && typeof document !== "undefined") {
3774
4428
  const styleElement = style({ nodes: errorBoundaryStyles });
3775
4429
  document.head.appendChild(styleElement);
@@ -3789,37 +4443,8 @@ function getMemoizedFallback(fallbackFn, error, retry) {
3789
4443
  }
3790
4444
  return cache2.get(key);
3791
4445
  }
3792
- function parseStack(err) {
3793
- const stack = err.stack || "";
3794
- const lines = stack.split("\n");
3795
- const frames = [];
3796
- let source2 = "";
3797
- for (const line2 of lines) {
3798
- const trimmed = line2.trim();
3799
- const chromeMatch = trimmed.match(/^at\s+(?:(.+?)\s+\((.+)\)|(.+))$/);
3800
- if (chromeMatch) {
3801
- const fn = chromeMatch[1] || "(anonymous)";
3802
- const loc = chromeMatch[2] || chromeMatch[3] || "";
3803
- frames.push({ fn, loc });
3804
- if (!source2 && fn !== "(anonymous)" && !fn.startsWith("Object.") && !fn.startsWith("Module.")) {
3805
- source2 = fn;
3806
- }
3807
- continue;
3808
- }
3809
- const firefoxMatch = trimmed.match(/^(.+?)@(.+)$/);
3810
- if (firefoxMatch) {
3811
- const fn = firefoxMatch[1] || "(anonymous)";
3812
- const loc = firefoxMatch[2] || "";
3813
- frames.push({ fn, loc });
3814
- if (!source2 && fn !== "(anonymous)") {
3815
- source2 = fn;
3816
- }
3817
- }
3818
- }
3819
- return { source: source2, frames };
3820
- }
3821
- function ErrorBoundary({ nodes, fallback, onError }) {
3822
- injectStyles();
4446
+ function ErrorBoundary({ nodes, fallback, onError, resetKeys }) {
4447
+ injectStyles2();
3823
4448
  const [error, setError] = signal(null);
3824
4449
  const retry = () => {
3825
4450
  if (fallback) {
@@ -3827,6 +4452,22 @@ function ErrorBoundary({ nodes, fallback, onError }) {
3827
4452
  }
3828
4453
  setError(null);
3829
4454
  };
4455
+ if (resetKeys && resetKeys.length > 0) {
4456
+ let initialized = false;
4457
+ effect(() => {
4458
+ for (const k of resetKeys) {
4459
+ try {
4460
+ k();
4461
+ } catch {
4462
+ }
4463
+ }
4464
+ if (!initialized) {
4465
+ initialized = true;
4466
+ return;
4467
+ }
4468
+ if (error() !== null) retry();
4469
+ });
4470
+ }
3830
4471
  const handleError = (e) => {
3831
4472
  const errorObj = e instanceof Error ? e : new Error(String(e));
3832
4473
  setError(errorObj);
@@ -3834,110 +4475,7 @@ function ErrorBoundary({ nodes, fallback, onError }) {
3834
4475
  return errorObj;
3835
4476
  };
3836
4477
  const defaultFallback = (err, retryFn) => {
3837
- if (!_isDev8) {
3838
- return div({
3839
- class: "sibu-error-fallback",
3840
- nodes: [
3841
- div({
3842
- class: "sibu-error-header",
3843
- nodes: [h3({ nodes: "Something went wrong", class: "sibu-error-title" })]
3844
- }),
3845
- div({
3846
- class: "sibu-error-body",
3847
- nodes: [
3848
- p({ nodes: "An unexpected error occurred. Please try again.", class: "sibu-error-message" }),
3849
- div({
3850
- class: "sibu-error-actions",
3851
- nodes: [
3852
- button({
3853
- nodes: "Retry",
3854
- class: "sibu-error-btn sibu-error-btn-retry",
3855
- on: { click: retryFn }
3856
- }),
3857
- button({
3858
- nodes: "Reload Page",
3859
- class: "sibu-error-btn sibu-error-btn-reload",
3860
- on: { click: () => location.reload() }
3861
- })
3862
- ]
3863
- })
3864
- ]
3865
- })
3866
- ]
3867
- });
3868
- }
3869
- const { source: source2, frames } = parseStack(err);
3870
- const fullText = `${err.message}
3871
-
3872
- ${err.stack || ""}`;
3873
- const copyBtn = button({
3874
- nodes: "Copy",
3875
- class: "sibu-error-copy-btn",
3876
- on: {
3877
- click: () => {
3878
- navigator.clipboard.writeText(fullText).then(() => {
3879
- copyBtn.textContent = "Copied!";
3880
- setTimeout(() => {
3881
- copyBtn.textContent = "Copy";
3882
- }, 1500);
3883
- });
3884
- }
3885
- }
3886
- });
3887
- const stackLines = frames.map(
3888
- (f, i2) => div({
3889
- nodes: [
3890
- span({ class: "sibu-line-num", nodes: String(i2 + 1) }),
3891
- span({ class: "sibu-stack-fn", nodes: f.fn }),
3892
- span({ class: "sibu-stack-loc", nodes: ` ${f.loc}` })
3893
- ]
3894
- })
3895
- );
3896
- return div({
3897
- class: "sibu-error-fallback",
3898
- nodes: [
3899
- div({
3900
- class: "sibu-error-header",
3901
- nodes: [
3902
- h3({ nodes: source2 ? `Error in ${source2}` : "Something went wrong", class: "sibu-error-title" }),
3903
- ...source2 ? [] : [span()]
3904
- ]
3905
- }),
3906
- div({
3907
- class: "sibu-error-body",
3908
- nodes: [
3909
- p({ nodes: err.message, class: "sibu-error-message" }),
3910
- ...frames.length > 0 ? [
3911
- div({
3912
- class: "sibu-error-stack-container",
3913
- nodes: [
3914
- div({
3915
- class: "sibu-error-stack-label",
3916
- nodes: [span({ nodes: "Stack Trace" }), copyBtn]
3917
- }),
3918
- div({ class: "sibu-error-stack", nodes: [pre({ nodes: stackLines })] })
3919
- ]
3920
- })
3921
- ] : [],
3922
- div({
3923
- class: "sibu-error-actions",
3924
- nodes: [
3925
- button({
3926
- nodes: "Retry",
3927
- class: "sibu-error-btn sibu-error-btn-retry",
3928
- on: { click: retryFn }
3929
- }),
3930
- button({
3931
- nodes: "Reload Page",
3932
- class: "sibu-error-btn sibu-error-btn-reload",
3933
- on: { click: () => location.reload() }
3934
- })
3935
- ]
3936
- })
3937
- ]
3938
- })
3939
- ]
3940
- });
4478
+ return ErrorDisplay({ error: err, severity: "error", onRetry: retryFn });
3941
4479
  };
3942
4480
  const tryRenderFallback = (err) => {
3943
4481
  const fn = fallback || defaultFallback;
@@ -4686,6 +5224,13 @@ var lintRules = {
4686
5224
  const line2 = lines[lineIdx];
4687
5225
  const trimmed = line2.trim();
4688
5226
  if (trimmed.startsWith("//") || trimmed.startsWith("*")) continue;
5227
+ if (lineIdx > 0) {
5228
+ const prevTrimmed = lines[lineIdx - 1].trim();
5229
+ if (prevTrimmed.includes("sibujs-disable-next-line") && (prevTrimmed.includes("no-direct-dom-mutation") || !prevTrimmed.includes(" ", prevTrimmed.indexOf("sibujs-disable-next-line") + 25))) {
5230
+ continue;
5231
+ }
5232
+ }
5233
+ if (line2.includes("sibujs-disable") && !line2.includes("sibujs-disable-next-line")) continue;
4689
5234
  for (const { pattern: pattern2, name, suggestion } of mutationPatterns) {
4690
5235
  pattern2.lastIndex = 0;
4691
5236
  const match2 = pattern2.exec(line2);