sibujs 4.1.0 → 4.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 (80) hide show
  1. package/README.md +24 -0
  2. package/dist/browser.cjs +13 -21
  3. package/dist/browser.js +6 -6
  4. package/dist/build.cjs +307 -111
  5. package/dist/build.js +15 -15
  6. package/dist/cdn.dev.global.js +398 -0
  7. package/dist/cdn.global.js +10 -10
  8. package/dist/{chunk-ANGSYNPX.js → chunk-2LSY4WDM.js} +86 -44
  9. package/dist/{chunk-VPP2FONR.js → chunk-2WLZ6757.js} +17 -10
  10. package/dist/{chunk-DCDS2PQ6.js → chunk-3E5YNK2F.js} +2 -2
  11. package/dist/{chunk-TIRZCERI.js → chunk-5DXA2J44.js} +1 -1
  12. package/dist/{chunk-PFTDGEPZ.js → chunk-7BJLKDBI.js} +3 -3
  13. package/dist/{chunk-XSZRJW76.js → chunk-7BPN4MXR.js} +6 -6
  14. package/dist/{chunk-BMSN6NWQ.js → chunk-7GQIRV27.js} +6 -6
  15. package/dist/{chunk-SHDVWATN.js → chunk-7UBG6LDP.js} +7 -8
  16. package/dist/{chunk-MRAMKDHQ.js → chunk-7UK6BSAT.js} +1 -1
  17. package/dist/{chunk-LOFZHP6V.js → chunk-AAHT6AKT.js} +7 -8
  18. package/dist/{chunk-FMHIQNMP.js → chunk-G7GPNB6N.js} +5 -5
  19. package/dist/{chunk-XIHMS2Y6.js → chunk-GZYQNIPS.js} +8 -8
  20. package/dist/{chunk-5INI7D2L.js → chunk-IXKSNWV5.js} +74 -11
  21. package/dist/{chunk-KSOEJGFO.js → chunk-IYHM4FWD.js} +3 -3
  22. package/dist/{chunk-AW6HPJ3L.js → chunk-KKLW7YWL.js} +1 -1
  23. package/dist/{chunk-5GJ5RTHA.js → chunk-L4B3Y3OM.js} +7 -8
  24. package/dist/{chunk-UFSQEO7P.js → chunk-MYA5HEK5.js} +7 -8
  25. package/dist/{chunk-HYCCIYNS.js → chunk-NIOYEGBQ.js} +13 -14
  26. package/dist/{chunk-DHDZ7IVN.js → chunk-QKRPLZ2V.js} +7 -8
  27. package/dist/{chunk-FB7KQXZI.js → chunk-R4EF7V3K.js} +4 -4
  28. package/dist/{chunk-IM7N5WR4.js → chunk-RE6KLGMV.js} +2 -2
  29. package/dist/{chunk-D3SZ4LVS.js → chunk-TSL64O5L.js} +5 -6
  30. package/dist/{chunk-DAKLOMKS.js → chunk-UD6YE2GW.js} +3 -3
  31. package/dist/{chunk-4U7KD3RY.js → chunk-USS5ENJ2.js} +3 -3
  32. package/dist/{chunk-I3VI34DP.js → chunk-XGCZ45NH.js} +149 -33
  33. package/dist/{chunk-4RH6D7GR.js → chunk-ZVYNIUOG.js} +6 -6
  34. package/dist/{customElement-CKLoO63w.d.ts → customElement-CNZxEB9G.d.cts} +77 -0
  35. package/dist/{customElement-CKLoO63w.d.cts → customElement-CNZxEB9G.d.ts} +77 -0
  36. package/dist/data.cjs +15 -24
  37. package/dist/data.js +9 -9
  38. package/dist/devtools.cjs +18 -22
  39. package/dist/devtools.d.cts +1 -1
  40. package/dist/devtools.d.ts +1 -1
  41. package/dist/devtools.js +8 -8
  42. package/dist/{dispose-4FZ6OFXR.js → dispose-46BOMMQJ.js} +2 -2
  43. package/dist/ecosystem.cjs +222 -67
  44. package/dist/ecosystem.js +11 -11
  45. package/dist/extras.cjs +243 -86
  46. package/dist/extras.d.cts +2 -2
  47. package/dist/extras.d.ts +2 -2
  48. package/dist/extras.js +25 -25
  49. package/dist/index.cjs +301 -105
  50. package/dist/index.d.cts +190 -37
  51. package/dist/index.d.ts +190 -37
  52. package/dist/index.js +15 -15
  53. package/dist/{introspect-RjLfIFpL.d.cts → introspect-D5xF-0Es.d.cts} +7 -0
  54. package/dist/{introspect-DOZfmC-4.d.ts → introspect-rSBIxEQi.d.ts} +7 -0
  55. package/dist/motion.cjs +13 -22
  56. package/dist/motion.js +5 -5
  57. package/dist/patterns.cjs +16 -24
  58. package/dist/patterns.d.cts +8 -0
  59. package/dist/patterns.d.ts +8 -0
  60. package/dist/patterns.js +7 -7
  61. package/dist/performance.cjs +16 -27
  62. package/dist/performance.js +9 -9
  63. package/dist/plugins.cjs +263 -88
  64. package/dist/plugins.d.cts +102 -2
  65. package/dist/plugins.d.ts +102 -2
  66. package/dist/plugins.js +21 -19
  67. package/dist/{ssr-JFP5535P.js → ssr-Y7XOEPEN.js} +5 -5
  68. package/dist/ssr.cjs +233 -79
  69. package/dist/ssr.js +12 -12
  70. package/dist/testing.cjs +11 -19
  71. package/dist/testing.js +5 -5
  72. package/dist/ui.cjs +98 -43
  73. package/dist/ui.d.cts +7 -1
  74. package/dist/ui.d.ts +7 -1
  75. package/dist/ui.js +10 -10
  76. package/dist/widgets.cjs +13 -21
  77. package/dist/widgets.d.cts +8 -0
  78. package/dist/widgets.d.ts +8 -0
  79. package/dist/widgets.js +9 -9
  80. package/package.json +5 -2
@@ -1,33 +1,33 @@
1
1
  import {
2
2
  bindAttribute,
3
3
  setSafeAttribute
4
- } from "./chunk-SHDVWATN.js";
4
+ } from "./chunk-7UBG6LDP.js";
5
5
  import {
6
6
  derived
7
- } from "./chunk-DCDS2PQ6.js";
7
+ } from "./chunk-3E5YNK2F.js";
8
8
  import {
9
9
  isEventHandlerAttr
10
- } from "./chunk-5INI7D2L.js";
10
+ } from "./chunk-IXKSNWV5.js";
11
11
  import {
12
12
  globalSingleton
13
13
  } from "./chunk-7ZHH77QA.js";
14
14
  import {
15
15
  effect
16
- } from "./chunk-PFTDGEPZ.js";
16
+ } from "./chunk-7BJLKDBI.js";
17
17
  import {
18
18
  dispose,
19
19
  registerDisposer,
20
20
  replaceChildrenSafely
21
- } from "./chunk-DHDZ7IVN.js";
21
+ } from "./chunk-QKRPLZ2V.js";
22
22
  import {
23
23
  signal
24
- } from "./chunk-UFSQEO7P.js";
24
+ } from "./chunk-MYA5HEK5.js";
25
25
  import {
26
26
  track
27
- } from "./chunk-D3SZ4LVS.js";
27
+ } from "./chunk-TSL64O5L.js";
28
28
  import {
29
29
  reportError
30
- } from "./chunk-VPP2FONR.js";
30
+ } from "./chunk-2WLZ6757.js";
31
31
 
32
32
  // src/ui/form.ts
33
33
  function required(message = "This field is required") {
@@ -1,3 +1,7 @@
1
+ import {
2
+ devWarnLazy
3
+ } from "./chunk-2WLZ6757.js";
4
+
1
5
  // src/utils/sanitize.ts
2
6
  function stripControlChars(value) {
3
7
  return value.replace(/[\x00-\x20\x7f-\x9f]+/g, "");
@@ -94,20 +98,75 @@ function decodeCssEscapes(value) {
94
98
  }
95
99
  return out;
96
100
  }
97
- function sanitizeCSSValue(value) {
98
- if (!CSS_DANGER_GATE.test(value)) return value;
101
+ var BLOCKED_CSS_NEEDLES = [
102
+ "url(",
103
+ "expression(",
104
+ "javascript:",
105
+ "vbscript:",
106
+ "-moz-binding",
107
+ "behavior:",
108
+ "@import",
109
+ "image-set(",
110
+ "filter:progid"
111
+ ];
112
+ function describeElement(el) {
113
+ if (!el) return "an element";
114
+ let out = el.tagName.toLowerCase();
115
+ const id = el.getAttribute("id");
116
+ if (id) out += `#${id}`;
117
+ const cls = el.getAttribute("class");
118
+ if (cls) out += `.${cls.trim().split(/\s+/).slice(0, 3).join(".")}`;
119
+ return `<${out}>`;
120
+ }
121
+ var warnedDeclarations = /* @__PURE__ */ new Set();
122
+ var MAX_WARNED_DECLARATIONS = 100;
123
+ var declarationCapAnnounced = false;
124
+ function warnDroppedDeclaration(value, reason, ctx) {
125
+ devWarnLazy(() => {
126
+ const reasons = [
127
+ "url() in an inline style is an exfiltration channel: the browser fetches it immediately and the URL's path or query can carry page data off-origin",
128
+ "expression() executes arbitrary script in legacy engines",
129
+ "the javascript: scheme executes script",
130
+ "the vbscript: scheme executes script",
131
+ "-moz-binding loads and runs remote XBL",
132
+ "behavior: loads and runs a remote HTC script",
133
+ "@import pulls in a remote stylesheet",
134
+ "image-set() fetches remote images, the same exfiltration channel as url()",
135
+ "filter:progid activates legacy scriptable filters"
136
+ ];
137
+ const declaration = ctx?.property ? `${ctx.property}: ${value}` : value;
138
+ const where = describeElement(ctx?.element);
139
+ const key = `${where}|${declaration}`;
140
+ if (warnedDeclarations.has(key)) return "";
141
+ if (warnedDeclarations.size >= MAX_WARNED_DECLARATIONS) {
142
+ if (declarationCapAnnounced) return "";
143
+ declarationCapAnnounced = true;
144
+ return `${MAX_WARNED_DECLARATIONS} distinct dropped style declarations have been reported; suppressing further ones for the rest of this session so they cannot flood the console. The declarations are still dropped \u2014 only the reporting stops. Fix the reported ones and reload to see any that remain.`;
145
+ }
146
+ warnedDeclarations.add(key);
147
+ return `style declaration "${declaration}" was dropped by the style sanitizer on ${where} \u2014 ${reasons[reason]}. The element renders without it, which usually looks like a missing image rather than an error. Sanctioned alternatives: for a content image use an <img> element (or a <picture>); for decoration, put the rule in a stylesheet and set a class instead \u2014 stylesheet CSS is not sanitized, only inline style attributes are. If this declaration is not yours, it came from untrusted data and the drop just prevented an exfiltration.`;
148
+ });
149
+ }
150
+ function blockedCssReason(value) {
151
+ if (!CSS_DANGER_GATE.test(value)) return -1;
99
152
  const normalized = value.includes("\\") ? decodeCssEscapes(value) : value;
100
153
  const lower = normalized.toLowerCase().replace(/\s+/g, "");
101
- if (lower.includes("url(") || lower.includes("expression(") || lower.includes("javascript:") || lower.includes("vbscript:") || lower.includes("-moz-binding") || lower.includes("behavior:") || lower.includes("@import") || lower.includes("image-set(") || lower.includes("filter:progid")) {
102
- return "";
154
+ for (let i = 0; i < BLOCKED_CSS_NEEDLES.length; i++) {
155
+ if (lower.includes(BLOCKED_CSS_NEEDLES[i])) return i;
103
156
  }
104
- return value;
157
+ return -1;
158
+ }
159
+ function sanitizeCSSValue(value, context) {
160
+ const reason = blockedCssReason(value);
161
+ if (reason === -1) return value;
162
+ warnDroppedDeclaration(value, reason, context);
163
+ return "";
105
164
  }
106
- function sanitizeStyleAttribute(cssText) {
165
+ function sanitizeStyleAttribute(cssText, context) {
107
166
  const input = String(cssText);
108
167
  if (input.trim() === "") return "";
109
168
  if (typeof document === "undefined") {
110
- return sanitizeCSSValue(input) === "" ? "" : input;
169
+ return sanitizeCSSValue(input, context) === "" ? "" : input;
111
170
  }
112
171
  const probe = document.createElement("div");
113
172
  try {
@@ -119,8 +178,12 @@ function sanitizeStyleAttribute(cssText) {
119
178
  for (let i = 0; i < probe.style.length; i++) {
120
179
  const property = probe.style[i];
121
180
  const value = probe.style.getPropertyValue(property);
122
- if (sanitizeCSSValue(value) === "") continue;
123
- if (sanitizeCSSValue(`${property}:${value}`) === "") continue;
181
+ let reason = blockedCssReason(value);
182
+ if (reason === -1) reason = blockedCssReason(`${property}:${value}`);
183
+ if (reason !== -1) {
184
+ warnDroppedDeclaration(value, reason, { property, element: context?.element });
185
+ continue;
186
+ }
124
187
  const priority = probe.style.getPropertyPriority(property);
125
188
  declarations.push(`${property}: ${value}${priority ? ` !${priority}` : ""}`);
126
189
  }
@@ -171,11 +234,11 @@ function isPolicyAttribute(name) {
171
234
  const lower = name.toLowerCase();
172
235
  return lower === "style" || URL_ATTRIBUTES.has(lower);
173
236
  }
174
- function sanitizeAttributeString(attr, value) {
237
+ function sanitizeAttributeString(attr, value, context) {
175
238
  const lower = attr.toLowerCase();
176
239
  if (lower === "srcset") return sanitizeSrcset(value);
177
240
  if (URL_ATTRIBUTES.has(lower)) return sanitizeUrl(value);
178
- if (lower === "style") return sanitizeStyleAttribute(value);
241
+ if (lower === "style") return sanitizeStyleAttribute(value, context);
179
242
  return value;
180
243
  }
181
244
 
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  isSSR
3
- } from "./chunk-TIRZCERI.js";
3
+ } from "./chunk-5DXA2J44.js";
4
4
  import {
5
5
  resumeTracking,
6
6
  suspendTracking,
7
7
  track
8
- } from "./chunk-D3SZ4LVS.js";
8
+ } from "./chunk-TSL64O5L.js";
9
9
  import {
10
10
  devAssert
11
- } from "./chunk-VPP2FONR.js";
11
+ } from "./chunk-2WLZ6757.js";
12
12
 
13
13
  // src/core/signals/watch.ts
14
14
  function watch(getter, callback) {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  renderToString
3
- } from "./chunk-HYCCIYNS.js";
3
+ } from "./chunk-NIOYEGBQ.js";
4
4
 
5
5
  // src/plugins/modular.ts
6
6
  function createModuleRegistry() {
@@ -1,20 +1,19 @@
1
1
  import {
2
2
  isSSR
3
- } from "./chunk-TIRZCERI.js";
3
+ } from "./chunk-5DXA2J44.js";
4
4
  import {
5
5
  signal
6
- } from "./chunk-UFSQEO7P.js";
6
+ } from "./chunk-MYA5HEK5.js";
7
7
  import {
8
- devWarn,
9
- isDev
10
- } from "./chunk-VPP2FONR.js";
8
+ DEV,
9
+ devWarn
10
+ } from "./chunk-2WLZ6757.js";
11
11
 
12
12
  // src/core/rendering/context.ts
13
- var _isDev = isDev();
14
13
  function context(defaultValue) {
15
14
  const [getValue, setValue] = signal(defaultValue);
16
15
  const warnIfSSR = (method) => {
17
- if (!_isDev || !isSSR()) return;
16
+ if (!DEV || !isSSR()) return;
18
17
  devWarn(
19
18
  `context.${method}() called during SSR. SibuJS context() is application-global \u2014 it is NOT isolated per request, so a concurrent request can observe this value. Do not use context() for request-specific SSR data; pass it explicitly or use request-scoped storage instead.`
20
19
  );
@@ -42,7 +41,7 @@ function context(defaultValue) {
42
41
  setValue(value);
43
42
  try {
44
43
  const result = fn();
45
- if (_isDev && result !== null && typeof result?.then === "function") {
44
+ if (DEV && result !== null && typeof result?.then === "function") {
46
45
  devWarn(
47
46
  "context.withContext() received an async callback. Scoping is synchronous only \u2014 the previous value is restored as soon as the callback returns its promise, so anything after an `await` runs outside the scope."
48
47
  );
@@ -3,10 +3,10 @@ import {
3
3
  notifySubscribers,
4
4
  queueSignalNotification,
5
5
  recordDependency
6
- } from "./chunk-D3SZ4LVS.js";
6
+ } from "./chunk-TSL64O5L.js";
7
7
  import {
8
- isDev
9
- } from "./chunk-VPP2FONR.js";
8
+ DEV
9
+ } from "./chunk-2WLZ6757.js";
10
10
 
11
11
  // src/reactivity/batch.ts
12
12
  var batchDepth = 0;
@@ -60,7 +60,6 @@ var isBatching = API.isBatching;
60
60
 
61
61
  // src/core/signals/signal.ts
62
62
  var _g = globalThis;
63
- var _isDev = isDev();
64
63
  function signal(initial, options) {
65
64
  const state = {
66
65
  value: initial,
@@ -73,7 +72,7 @@ function signal(initial, options) {
73
72
  _d: false,
74
73
  _validate: void 0
75
74
  };
76
- const debugName = _isDev ? options?.name : void 0;
75
+ const debugName = DEV ? options?.name : void 0;
77
76
  const equalsFn = options?.equals;
78
77
  if (debugName) state.__name = debugName;
79
78
  function get() {
@@ -90,7 +89,7 @@ function signal(initial, options) {
90
89
  if (equalsFn(prev, newValue)) return;
91
90
  state.value = newValue;
92
91
  state.__v++;
93
- if (_isDev) {
92
+ if (DEV) {
94
93
  const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
95
94
  if (hook) hook.emit("signal:update", { signal: state, name: debugName, oldValue: prev, newValue });
96
95
  }
@@ -98,7 +97,7 @@ function signal(initial, options) {
98
97
  notifySubscribers(state);
99
98
  }
100
99
  };
101
- } else if (_isDev) {
100
+ } else if (DEV) {
102
101
  set = (next) => {
103
102
  const prev = state.value;
104
103
  const newValue = typeof next === "function" ? next(prev) : next;
@@ -123,7 +122,7 @@ function signal(initial, options) {
123
122
  }
124
123
  };
125
124
  }
126
- if (_isDev) {
125
+ if (DEV) {
127
126
  const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
128
127
  if (hook) hook.emit("signal:create", { signal: state, name: debugName, getter: get, initial });
129
128
  }
@@ -6,17 +6,17 @@ import {
6
6
  sanitizeAttributeString,
7
7
  sanitizeUrl,
8
8
  stripControlChars
9
- } from "./chunk-5INI7D2L.js";
9
+ } from "./chunk-IXKSNWV5.js";
10
10
  import {
11
11
  getSSRStore
12
- } from "./chunk-TIRZCERI.js";
12
+ } from "./chunk-5DXA2J44.js";
13
13
  import {
14
14
  dispose,
15
15
  replaceChildrenSafely
16
- } from "./chunk-DHDZ7IVN.js";
16
+ } from "./chunk-QKRPLZ2V.js";
17
17
  import {
18
- isDev
19
- } from "./chunk-VPP2FONR.js";
18
+ DEV
19
+ } from "./chunk-2WLZ6757.js";
20
20
 
21
21
  // src/utils/metaRefresh.ts
22
22
  function isAsciiWhitespace(ch) {
@@ -185,13 +185,12 @@ function isForbiddenSsrAttr(lowerName) {
185
185
  function sanitizeSsrAttributeValue(lowerName, value) {
186
186
  return sanitizeAttributeString(lowerName, value);
187
187
  }
188
- var _isDev = isDev();
189
188
  var SAFE_ATTR_NAME = /^[A-Za-z_:][-A-Za-z0-9_.:]*$/;
190
189
  function isSafeAttrName(name) {
191
190
  return SAFE_ATTR_NAME.test(name);
192
191
  }
193
192
  function ssrErrorComment(err) {
194
- if (_isDev) {
193
+ if (DEV) {
195
194
  const msg = escapeHtml(err instanceof Error ? err.message : String(err));
196
195
  return `<!--SSR error: ${safeCommentText(msg)}-->`;
197
196
  }
@@ -237,10 +236,10 @@ function renderToString(element) {
237
236
  }
238
237
  const tag = element.tagName.toLowerCase();
239
238
  if (tag === "script" || tag === "style") {
240
- return _isDev ? `<!--ssr:${tag}-stripped-->` : "";
239
+ return DEV ? `<!--ssr:${tag}-stripped-->` : "";
241
240
  }
242
241
  if (!/^[a-z][a-z0-9-]*$/i.test(tag)) {
243
- return _isDev ? "<!--ssr:invalid-tag-->" : "";
242
+ return DEV ? "<!--ssr:invalid-tag-->" : "";
244
243
  }
245
244
  let html = `<${tag}`;
246
245
  for (const attr of Array.from(element.attributes)) {
@@ -282,7 +281,7 @@ function hydrate(component, container, options = {}) {
282
281
  const first = mismatches[0];
283
282
  if (options.onMismatch) {
284
283
  options.onMismatch(first);
285
- } else if (_isDev) {
284
+ } else if (DEV) {
286
285
  console.warn(
287
286
  `[SibuJS hydration] ${first.message}
288
287
  at ${first.path}
@@ -483,11 +482,11 @@ async function* renderToStream(element) {
483
482
  }
484
483
  const tag = element.tagName.toLowerCase();
485
484
  if (tag === "script" || tag === "style") {
486
- if (_isDev) yield `<!--ssr:${tag}-stripped-->`;
485
+ if (DEV) yield `<!--ssr:${tag}-stripped-->`;
487
486
  return;
488
487
  }
489
488
  if (!/^[a-z][a-z0-9-]*$/i.test(tag)) {
490
- if (_isDev) yield "<!--ssr:invalid-tag-->";
489
+ if (DEV) yield "<!--ssr:invalid-tag-->";
491
490
  return;
492
491
  }
493
492
  let openTag = `<${tag}`;
@@ -630,7 +629,7 @@ function ssrSuspense(props) {
630
629
  },
631
630
  (err) => {
632
631
  if (timer) clearTimeout(timer);
633
- if (_isDev) console.warn("[SibuJS SSR] ssrSuspense rejected:", err);
632
+ if (DEV) console.warn("[SibuJS SSR] ssrSuspense rejected:", err);
634
633
  return { id, html: fallbackHtml };
635
634
  }
636
635
  );
@@ -676,7 +675,7 @@ function serializeState(state, nonce, options) {
676
675
  }
677
676
  function deserializeState(validate) {
678
677
  if (typeof window === "undefined") return void 0;
679
- if (_isDev && !validate) {
678
+ if (DEV && !validate) {
680
679
  console.warn(
681
680
  "[SibuJS SSR] deserializeState() called without a validate guard \u2014 tampered SSR payloads will not be detected."
682
681
  );
@@ -1,8 +1,8 @@
1
1
  import {
2
+ DEV,
2
3
  devWarn,
3
- isDev,
4
4
  reportError
5
- } from "./chunk-VPP2FONR.js";
5
+ } from "./chunk-2WLZ6757.js";
6
6
 
7
7
  // src/core/rendering/dispose.ts
8
8
  var elementDisposers = /* @__PURE__ */ new WeakMap();
@@ -14,7 +14,6 @@ function reportDrainRunaway(label, executed, remaining) {
14
14
  { executed, remaining }
15
15
  );
16
16
  }
17
- var _isDev = isDev();
18
17
  var activeBindingCount = 0;
19
18
  function registerDisposer(node, teardown) {
20
19
  let disposers = elementDisposers.get(node);
@@ -23,7 +22,7 @@ function registerDisposer(node, teardown) {
23
22
  elementDisposers.set(node, disposers);
24
23
  }
25
24
  disposers.push(teardown);
26
- if (_isDev) activeBindingCount++;
25
+ if (DEV) activeBindingCount++;
27
26
  }
28
27
  function unregisterDisposer(node, teardown) {
29
28
  const disposers = elementDisposers.get(node);
@@ -31,7 +30,7 @@ function unregisterDisposer(node, teardown) {
31
30
  const index = disposers.indexOf(teardown);
32
31
  if (index === -1) return;
33
32
  disposers.splice(index, 1);
34
- if (_isDev) activeBindingCount--;
33
+ if (DEV) activeBindingCount--;
35
34
  if (disposers.length === 0) elementDisposers.delete(node);
36
35
  }
37
36
  function dispose(node) {
@@ -55,13 +54,13 @@ function dispose(node) {
55
54
  if (!pending || pending.length === 0) break;
56
55
  const snapshot = pending.slice();
57
56
  elementDisposers.delete(current);
58
- if (_isDev) activeBindingCount -= snapshot.length;
57
+ if (DEV) activeBindingCount -= snapshot.length;
59
58
  for (let i2 = 0; i2 < snapshot.length; i2++) {
60
59
  if (executed >= MAX_DRAIN_TEARDOWNS) {
61
60
  const rest = snapshot.slice(i2);
62
61
  const added = elementDisposers.get(current);
63
62
  elementDisposers.set(current, added ? rest.concat(added) : rest);
64
- if (_isDev) activeBindingCount += rest.length;
63
+ if (DEV) activeBindingCount += rest.length;
65
64
  reportDrainRunaway("dispose", executed, rest.length + (added?.length ?? 0));
66
65
  runaway = true;
67
66
  break;
@@ -89,7 +88,7 @@ function replaceChildrenSafely(parent, ...next) {
89
88
  parent.replaceChildren(...next);
90
89
  }
91
90
  function checkLeaks(warnThreshold = 0) {
92
- if (!_isDev) return 0;
91
+ if (!DEV) return 0;
93
92
  if (warnThreshold > 0 && activeBindingCount > warnThreshold) {
94
93
  devWarn(
95
94
  `checkLeaks: ${activeBindingCount} active DOM bindings detected. Expected \u2264${warnThreshold}. This may indicate a component was removed from the DOM without calling dispose().`
@@ -3,17 +3,17 @@ import {
3
3
  } from "./chunk-WWV3SJ3L.js";
4
4
  import {
5
5
  tagFactory
6
- } from "./chunk-I3VI34DP.js";
6
+ } from "./chunk-XGCZ45NH.js";
7
7
  import {
8
8
  derived
9
- } from "./chunk-DCDS2PQ6.js";
9
+ } from "./chunk-3E5YNK2F.js";
10
10
  import {
11
11
  effect
12
- } from "./chunk-PFTDGEPZ.js";
12
+ } from "./chunk-7BJLKDBI.js";
13
13
  import {
14
14
  batch,
15
15
  signal
16
- } from "./chunk-UFSQEO7P.js";
16
+ } from "./chunk-MYA5HEK5.js";
17
17
 
18
18
  // src/ecosystem/adapters/mobx.ts
19
19
  function mobXAdapter(options) {
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  registerDisposer
3
- } from "./chunk-DHDZ7IVN.js";
3
+ } from "./chunk-QKRPLZ2V.js";
4
4
  import {
5
5
  signal
6
- } from "./chunk-UFSQEO7P.js";
6
+ } from "./chunk-MYA5HEK5.js";
7
7
 
8
8
  // src/ui/transition.ts
9
9
  function transition(element, options = {}) {
@@ -1,8 +1,8 @@
1
1
  import {
2
+ DEV,
2
3
  devWarn,
3
- isDev,
4
4
  reportError
5
- } from "./chunk-VPP2FONR.js";
5
+ } from "./chunk-2WLZ6757.js";
6
6
 
7
7
  // src/reactivity/track-core.ts
8
8
  var POOL_MAX = 4096;
@@ -460,17 +460,16 @@ function forEachSubscriber(signal, visit) {
460
460
  }
461
461
 
462
462
  // src/reactivity/track.ts
463
- var _isDev = isDev();
464
- var _runtimeVersion = true ? "4.1.0" : "dev";
463
+ var _runtimeVersion = true ? "4.3.0" : "dev";
465
464
  var REGISTRY_KEY = /* @__PURE__ */ Symbol.for("sibujs.reactive.v1");
466
465
  function resolveReactiveApi() {
467
466
  const g = globalThis;
468
467
  const existing = g[REGISTRY_KEY];
469
468
  if (existing) {
470
- if (_isDev && !existing.__dupWarned) {
469
+ if (DEV && !existing.__dupWarned) {
471
470
  existing.__dupWarned = true;
472
471
  devWarn(
473
- `Multiple instances of the reactive runtime detected on this page (active: ${existing.version}, duplicate: ${_runtimeVersion}). Reactivity still works \u2014 all copies share the first one \u2014 but de-duplicate sibujs in your bundler (e.g. Vite optimizeDeps.exclude: ['sibujs'] or resolve.dedupe: ['sibujs']).`
472
+ `Multiple instances of the reactive runtime detected on this page (active: ${existing.version}, duplicate: ${_runtimeVersion}). Reactivity is NOT broken and no bundler configuration is required: every copy routes through the first one via a global registry, so signal writes still reach subscribers registered by any copy. This is only a SIZE issue \u2014 the duplicate copy's bytes are downloaded and parsed for nothing. If you want them back, de-duplicate sibujs in your bundler (Vite: resolve.dedupe: ['sibujs']). Mismatched VERSIONS above are worth fixing regardless, since only the first one loaded is used.`
474
473
  );
475
474
  }
476
475
  return existing;
@@ -6,14 +6,14 @@ import {
6
6
  } from "./chunk-52XFPGSN.js";
7
7
  import {
8
8
  effect
9
- } from "./chunk-PFTDGEPZ.js";
9
+ } from "./chunk-7BJLKDBI.js";
10
10
  import {
11
11
  batch,
12
12
  signal
13
- } from "./chunk-UFSQEO7P.js";
13
+ } from "./chunk-MYA5HEK5.js";
14
14
  import {
15
15
  reportError
16
- } from "./chunk-VPP2FONR.js";
16
+ } from "./chunk-2WLZ6757.js";
17
17
 
18
18
  // src/browser/media.ts
19
19
  function media(query) {
@@ -4,14 +4,14 @@ import {
4
4
  } from "./chunk-H3SRKIYX.js";
5
5
  import {
6
6
  derived
7
- } from "./chunk-DCDS2PQ6.js";
7
+ } from "./chunk-3E5YNK2F.js";
8
8
  import {
9
9
  effect
10
- } from "./chunk-PFTDGEPZ.js";
10
+ } from "./chunk-7BJLKDBI.js";
11
11
  import {
12
12
  batch,
13
13
  signal
14
- } from "./chunk-UFSQEO7P.js";
14
+ } from "./chunk-MYA5HEK5.js";
15
15
 
16
16
  // src/patterns/machine.ts
17
17
  function machine(config) {