sibujs 3.4.1 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +118 -15
  3. package/dist/browser.cjs +410 -101
  4. package/dist/browser.d.cts +50 -5
  5. package/dist/browser.d.ts +50 -5
  6. package/dist/browser.js +8 -6
  7. package/dist/build.cjs +784 -392
  8. package/dist/build.js +15 -15
  9. package/dist/cdn.global.js +11 -7
  10. package/dist/{chunk-PBZWJQNY.js → chunk-52ERIVFD.js} +8 -8
  11. package/dist/chunk-52XFPGSN.js +123 -0
  12. package/dist/{chunk-Y22QAKJX.js → chunk-5BVKQX2F.js} +4 -4
  13. package/dist/chunk-5INI7D2L.js +194 -0
  14. package/dist/{chunk-4I3M326N.js → chunk-AD5YSZAN.js} +19 -25
  15. package/dist/{chunk-F7HW2NI5.js → chunk-AW6HPJ3L.js} +1 -1
  16. package/dist/chunk-DHDZ7IVN.js +109 -0
  17. package/dist/{chunk-VQZDHAEK.js → chunk-E72G5JSK.js} +1 -1
  18. package/dist/{chunk-MPE75KOA.js → chunk-HPXTUPJD.js} +259 -124
  19. package/dist/{chunk-EX77FXTT.js → chunk-HYCCIYNS.js} +228 -51
  20. package/dist/{chunk-FWFEBYQ6.js → chunk-IKVUUE7D.js} +115 -41
  21. package/dist/{chunk-5MFF5EPT.js → chunk-J4WZMCIW.js} +5 -5
  22. package/dist/{chunk-BQLVTAUZ.js → chunk-JYXQCELN.js} +57 -22
  23. package/dist/{chunk-WEZ5SP7L.js → chunk-PHB3MCK4.js} +73 -34
  24. package/dist/chunk-PHRH66Y7.js +147 -0
  25. package/dist/{chunk-S2VW4NBA.js → chunk-PJDSI2K7.js} +295 -198
  26. package/dist/{chunk-QHPUFNHZ.js → chunk-PTLJ7NQX.js} +3 -3
  27. package/dist/{chunk-NXR2YFZB.js → chunk-QD4I7ZGZ.js} +24 -34
  28. package/dist/{chunk-S3NFJO6L.js → chunk-TIRZCERI.js} +36 -5
  29. package/dist/{chunk-7PNKW3FJ.js → chunk-TNEHT3NG.js} +232 -67
  30. package/dist/{chunk-335KJEN2.js → chunk-TVURNWDK.js} +5 -3
  31. package/dist/{chunk-CV7FAQ2R.js → chunk-UNAYBND2.js} +9 -3
  32. package/dist/chunk-VPP2FONR.js +142 -0
  33. package/dist/{chunk-X4JS367G.js → chunk-XDOMTQHM.js} +14 -10
  34. package/dist/chunk-XET2RUJF.js +61 -0
  35. package/dist/{chunk-3FFCUIGV.js → chunk-XZMCVZW6.js} +309 -188
  36. package/dist/{chunk-YDWP3ZOU.js → chunk-YLV26GAJ.js} +228 -86
  37. package/dist/{contracts-ey_Qh8ef.d.ts → contracts-Hg6ITAEF.d.cts} +6 -6
  38. package/dist/{contracts-ey_Qh8ef.d.cts → contracts-Hg6ITAEF.d.ts} +6 -6
  39. package/dist/{customElement-CPfIrbvg.d.cts → customElement-CKLoO63w.d.cts} +73 -11
  40. package/dist/{customElement-CPfIrbvg.d.ts → customElement-CKLoO63w.d.ts} +73 -11
  41. package/dist/data.cjs +483 -205
  42. package/dist/data.d.cts +139 -7
  43. package/dist/data.d.ts +139 -7
  44. package/dist/data.js +9 -9
  45. package/dist/devtools.cjs +222 -87
  46. package/dist/devtools.js +8 -8
  47. package/dist/dispose-4FZ6OFXR.js +19 -0
  48. package/dist/ecosystem.cjs +426 -182
  49. package/dist/ecosystem.js +11 -11
  50. package/dist/extras.cjs +1988 -772
  51. package/dist/extras.d.cts +7 -7
  52. package/dist/extras.d.ts +7 -7
  53. package/dist/extras.js +29 -26
  54. package/dist/index.cjs +791 -392
  55. package/dist/index.d.cts +299 -28
  56. package/dist/index.d.ts +299 -28
  57. package/dist/index.js +33 -18
  58. package/dist/motion.cjs +180 -50
  59. package/dist/motion.d.cts +26 -0
  60. package/dist/motion.d.ts +26 -0
  61. package/dist/motion.js +5 -5
  62. package/dist/patterns.cjs +437 -170
  63. package/dist/patterns.d.cts +60 -13
  64. package/dist/patterns.d.ts +60 -13
  65. package/dist/patterns.js +7 -7
  66. package/dist/performance.cjs +333 -148
  67. package/dist/performance.d.cts +55 -7
  68. package/dist/performance.d.ts +55 -7
  69. package/dist/performance.js +9 -9
  70. package/dist/plugins.cjs +1378 -583
  71. package/dist/plugins.d.cts +227 -9
  72. package/dist/plugins.d.ts +227 -9
  73. package/dist/plugins.js +610 -321
  74. package/dist/{ssr-D62yFwuw.d.cts → ssr-BiPRdZ6n.d.cts} +44 -15
  75. package/dist/{ssr-D62yFwuw.d.ts → ssr-BiPRdZ6n.d.ts} +44 -15
  76. package/dist/{ssr-2PPULEK2.js → ssr-JFP5535P.js} +5 -4
  77. package/dist/ssr.cjs +1111 -450
  78. package/dist/ssr.d.cts +230 -20
  79. package/dist/ssr.d.ts +230 -20
  80. package/dist/ssr.js +15 -12
  81. package/dist/{startup-0Qv6aosO.d.cts → startup-BMpaiMhP.d.cts} +1 -1
  82. package/dist/{startup-0Qv6aosO.d.ts → startup-BMpaiMhP.d.ts} +1 -1
  83. package/dist/testing.cjs +205 -63
  84. package/dist/testing.d.cts +1 -1
  85. package/dist/testing.d.ts +1 -1
  86. package/dist/testing.js +8 -10
  87. package/dist/ui.cjs +640 -199
  88. package/dist/ui.d.cts +2 -2
  89. package/dist/ui.d.ts +2 -2
  90. package/dist/ui.js +10 -10
  91. package/dist/widgets.cjs +207 -82
  92. package/dist/widgets.js +9 -9
  93. package/package.json +12 -7
  94. package/dist/chunk-5VGSK6D2.js +0 -80
  95. package/dist/chunk-6CAJU5TP.js +0 -38
  96. package/dist/chunk-COY6PUD2.js +0 -34
  97. package/dist/chunk-DLBFEAIS.js +0 -96
  98. package/dist/chunk-L3GAGWCC.js +0 -111
@@ -0,0 +1,123 @@
1
+ import {
2
+ globalSingleton
3
+ } from "./chunk-7ZHH77QA.js";
4
+
5
+ // src/utils/singletonResource.ts
6
+ function singletonResource(io) {
7
+ let original = null;
8
+ let captured = false;
9
+ const stack = [];
10
+ function apply() {
11
+ if (stack.length > 0) {
12
+ io.write(stack[stack.length - 1].value);
13
+ return;
14
+ }
15
+ if (captured) {
16
+ io.write(original);
17
+ captured = false;
18
+ original = null;
19
+ }
20
+ }
21
+ return {
22
+ acquire(value) {
23
+ if (!captured) {
24
+ original = io.read();
25
+ captured = true;
26
+ }
27
+ const entry = { value, released: false };
28
+ stack.push(entry);
29
+ apply();
30
+ return {
31
+ set(next) {
32
+ if (entry.released) return;
33
+ entry.value = next;
34
+ apply();
35
+ },
36
+ release() {
37
+ if (entry.released) return;
38
+ entry.released = true;
39
+ const index = stack.indexOf(entry);
40
+ if (index !== -1) stack.splice(index, 1);
41
+ apply();
42
+ }
43
+ };
44
+ },
45
+ ownerCount() {
46
+ return stack.length;
47
+ }
48
+ };
49
+ }
50
+
51
+ // src/utils/documentResources.ts
52
+ var INERT_LEASE = {
53
+ set() {
54
+ },
55
+ release() {
56
+ }
57
+ };
58
+ function inertLease() {
59
+ return INERT_LEASE;
60
+ }
61
+ var titleResource = globalSingleton(
62
+ /* @__PURE__ */ Symbol.for("sibujs.documentTitle.v1"),
63
+ () => singletonResource({
64
+ read: () => document.title,
65
+ write: (value) => {
66
+ document.title = value;
67
+ }
68
+ })
69
+ );
70
+ var baseResource = globalSingleton(
71
+ /* @__PURE__ */ Symbol.for("sibujs.documentBase.v1"),
72
+ () => singletonResource({
73
+ read: () => {
74
+ const el = document.head.querySelector("base");
75
+ if (!el) return null;
76
+ return {
77
+ href: el.getAttribute("href") ?? void 0,
78
+ target: el.getAttribute("target") ?? void 0
79
+ };
80
+ },
81
+ write: (spec) => {
82
+ const existing = document.head.querySelector("base");
83
+ if (spec === null) {
84
+ existing?.remove();
85
+ return;
86
+ }
87
+ const el = existing ?? document.head.appendChild(document.createElement("base"));
88
+ if (spec.href === void 0) el.removeAttribute("href");
89
+ else el.setAttribute("href", spec.href);
90
+ if (spec.target === void 0) el.removeAttribute("target");
91
+ else el.setAttribute("target", spec.target);
92
+ }
93
+ })
94
+ );
95
+ var scrollRestorationResource = globalSingleton(
96
+ /* @__PURE__ */ Symbol.for("sibujs.historyScrollRestoration.v1"),
97
+ () => singletonResource({
98
+ read: () => history.scrollRestoration,
99
+ write: (mode) => {
100
+ history.scrollRestoration = mode;
101
+ }
102
+ })
103
+ );
104
+ function acquireScrollRestorationMode(mode) {
105
+ if (typeof history === "undefined" || !("scrollRestoration" in history)) {
106
+ return inertLease();
107
+ }
108
+ return scrollRestorationResource.acquire(mode);
109
+ }
110
+ function acquireTitle(value) {
111
+ if (typeof document === "undefined") return inertLease();
112
+ return titleResource.acquire(value);
113
+ }
114
+ function acquireBase(spec) {
115
+ if (typeof document === "undefined") return inertLease();
116
+ return baseResource.acquire(spec);
117
+ }
118
+
119
+ export {
120
+ acquireScrollRestorationMode,
121
+ acquireTitle,
122
+ acquireBase
123
+ };
@@ -3,17 +3,17 @@ import {
3
3
  } from "./chunk-WWV3SJ3L.js";
4
4
  import {
5
5
  tagFactory
6
- } from "./chunk-NXR2YFZB.js";
6
+ } from "./chunk-QD4I7ZGZ.js";
7
7
  import {
8
8
  derived
9
- } from "./chunk-4I3M326N.js";
9
+ } from "./chunk-AD5YSZAN.js";
10
10
  import {
11
11
  effect
12
- } from "./chunk-X4JS367G.js";
12
+ } from "./chunk-XDOMTQHM.js";
13
13
  import {
14
14
  batch,
15
15
  signal
16
- } from "./chunk-335KJEN2.js";
16
+ } from "./chunk-TVURNWDK.js";
17
17
 
18
18
  // src/ecosystem/adapters/mobx.ts
19
19
  function mobXAdapter(options) {
@@ -0,0 +1,194 @@
1
+ // src/utils/sanitize.ts
2
+ function stripControlChars(value) {
3
+ return value.replace(/[\x00-\x20\x7f-\x9f]+/g, "");
4
+ }
5
+ function canonicalAttrName(name) {
6
+ return name.replace(/[A-Z]/g, (ch) => String.fromCharCode(ch.charCodeAt(0) + 32));
7
+ }
8
+ function isEventHandlerAttr(name) {
9
+ if (name.length < 3) return false;
10
+ const lower = name.toLowerCase();
11
+ return lower[0] === "o" && lower[1] === "n" && lower.charCodeAt(2) >= 97 && lower.charCodeAt(2) <= 122;
12
+ }
13
+ var SAFE_URL_PROTOCOLS = ["http:", "https:", "mailto:", "tel:", "ftp:"];
14
+ var OUTER_TRIM = /^[\x00-\x20\x7f-\x9f]+|[\x00-\x20\x7f-\x9f]+$/g;
15
+ function sanitizeUrl(url) {
16
+ const probe = stripControlChars(url).trim();
17
+ if (!probe) return "";
18
+ const output = url.replace(OUTER_TRIM, "");
19
+ const lower = probe.toLowerCase();
20
+ let schemeEnd = -1;
21
+ for (let i = 0; i < lower.length; i++) {
22
+ const ch = lower.charCodeAt(i);
23
+ if (ch === 58) {
24
+ schemeEnd = i;
25
+ break;
26
+ }
27
+ if (ch === 47 || ch === 63 || ch === 35) break;
28
+ }
29
+ if (schemeEnd === -1) return output;
30
+ const scheme = lower.slice(0, schemeEnd + 1);
31
+ if (!/^[a-z][a-z0-9+.-]*:$/.test(scheme)) return output;
32
+ if (SAFE_URL_PROTOCOLS.indexOf(scheme) === -1) return "";
33
+ return output;
34
+ }
35
+ var SRCSET_DESCRIPTOR = /^\s+\d+(\.\d+)?[wx]$/;
36
+ function sanitizeSrcset(value) {
37
+ const parts = value.split(",");
38
+ const out = [];
39
+ for (let i = 0; i < parts.length; i++) {
40
+ const part = parts[i].trim();
41
+ if (!part) continue;
42
+ const m = part.match(/^(\S+)(\s+.+)?$/);
43
+ if (!m) continue;
44
+ if (m[2] !== void 0 && !SRCSET_DESCRIPTOR.test(m[2])) continue;
45
+ const safe = sanitizeUrl(m[1]);
46
+ if (!safe) continue;
47
+ out.push(m[2] ? `${safe}${m[2]}` : safe);
48
+ }
49
+ return out.join(", ");
50
+ }
51
+ var CSS_DANGER_GATE = /[(:@\\]/;
52
+ function isCssWhitespace(ch) {
53
+ return ch === " " || ch === " " || ch === "\n" || ch === "\r" || ch === "\f";
54
+ }
55
+ function isHexDigit(ch) {
56
+ return ch >= "0" && ch <= "9" || ch >= "a" && ch <= "f" || ch >= "A" && ch <= "F";
57
+ }
58
+ function decodeCssEscapes(value) {
59
+ let out = "";
60
+ for (let i = 0; i < value.length; i++) {
61
+ const ch = value[i];
62
+ if (ch !== "\\") {
63
+ out += ch;
64
+ continue;
65
+ }
66
+ if (i + 1 >= value.length) break;
67
+ const next = value[i + 1];
68
+ if (next === "\n" || next === "\f") {
69
+ i += 1;
70
+ continue;
71
+ }
72
+ if (next === "\r") {
73
+ i += value[i + 2] === "\n" ? 2 : 1;
74
+ continue;
75
+ }
76
+ if (isHexDigit(next)) {
77
+ let hex = "";
78
+ let j = i + 1;
79
+ while (j < value.length && hex.length < 6 && isHexDigit(value[j])) {
80
+ hex += value[j];
81
+ j++;
82
+ }
83
+ if (j < value.length && isCssWhitespace(value[j])) {
84
+ j += value[j] === "\r" && value[j + 1] === "\n" ? 2 : 1;
85
+ }
86
+ const code = Number.parseInt(hex, 16);
87
+ const invalid = code === 0 || code > 1114111 || code >= 55296 && code <= 57343;
88
+ out += invalid ? "\uFFFD" : String.fromCodePoint(code);
89
+ i = j - 1;
90
+ continue;
91
+ }
92
+ out += next;
93
+ i += 1;
94
+ }
95
+ return out;
96
+ }
97
+ function sanitizeCSSValue(value) {
98
+ if (!CSS_DANGER_GATE.test(value)) return value;
99
+ const normalized = value.includes("\\") ? decodeCssEscapes(value) : value;
100
+ 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 "";
103
+ }
104
+ return value;
105
+ }
106
+ function sanitizeStyleAttribute(cssText) {
107
+ const input = String(cssText);
108
+ if (input.trim() === "") return "";
109
+ if (typeof document === "undefined") {
110
+ return sanitizeCSSValue(input) === "" ? "" : input;
111
+ }
112
+ const probe = document.createElement("div");
113
+ try {
114
+ probe.style.cssText = input;
115
+ } catch {
116
+ return "";
117
+ }
118
+ const declarations = [];
119
+ for (let i = 0; i < probe.style.length; i++) {
120
+ const property = probe.style[i];
121
+ const value = probe.style.getPropertyValue(property);
122
+ if (sanitizeCSSValue(value) === "") continue;
123
+ if (sanitizeCSSValue(`${property}:${value}`) === "") continue;
124
+ const priority = probe.style.getPropertyPriority(property);
125
+ declarations.push(`${property}: ${value}${priority ? ` !${priority}` : ""}`);
126
+ }
127
+ return declarations.join("; ");
128
+ }
129
+ function stripHtml(html) {
130
+ const input = String(html);
131
+ if (typeof DOMParser !== "undefined") {
132
+ try {
133
+ return new DOMParser().parseFromString(input, "text/html").body.textContent ?? "";
134
+ } catch {
135
+ }
136
+ }
137
+ let prev;
138
+ let out = input;
139
+ do {
140
+ prev = out;
141
+ out = out.replace(/<[^>]*>/g, "");
142
+ } while (out !== prev);
143
+ return out.replace(/<[^>]*$/, "");
144
+ }
145
+ var URL_ATTRIBUTES = /* @__PURE__ */ new Set([
146
+ "href",
147
+ "xlink:href",
148
+ "src",
149
+ "action",
150
+ "formaction",
151
+ "formtarget",
152
+ "cite",
153
+ "poster",
154
+ "background",
155
+ "srcset",
156
+ "ping",
157
+ "data",
158
+ // `<html manifest>` is a URL sink too. It was carried only by the SSR
159
+ // serializers' private copy of this set; folding that copy into this one would
160
+ // otherwise have silently dropped its coverage.
161
+ "manifest"
162
+ ]);
163
+ var HTML_CONTENT_ATTRIBUTES = /* @__PURE__ */ new Set(["srcdoc"]);
164
+ function isHtmlContentAttribute(name) {
165
+ return HTML_CONTENT_ATTRIBUTES.has(name.toLowerCase());
166
+ }
167
+ function isUrlAttribute(attr) {
168
+ return URL_ATTRIBUTES.has(attr.toLowerCase());
169
+ }
170
+ function isPolicyAttribute(name) {
171
+ const lower = name.toLowerCase();
172
+ return lower === "style" || URL_ATTRIBUTES.has(lower);
173
+ }
174
+ function sanitizeAttributeString(attr, value) {
175
+ const lower = attr.toLowerCase();
176
+ if (lower === "srcset") return sanitizeSrcset(value);
177
+ if (URL_ATTRIBUTES.has(lower)) return sanitizeUrl(value);
178
+ if (lower === "style") return sanitizeStyleAttribute(value);
179
+ return value;
180
+ }
181
+
182
+ export {
183
+ stripControlChars,
184
+ canonicalAttrName,
185
+ isEventHandlerAttr,
186
+ sanitizeUrl,
187
+ sanitizeCSSValue,
188
+ sanitizeStyleAttribute,
189
+ stripHtml,
190
+ isHtmlContentAttribute,
191
+ isUrlAttribute,
192
+ isPolicyAttribute,
193
+ sanitizeAttributeString
194
+ };
@@ -3,10 +3,10 @@ import {
3
3
  recordDependency,
4
4
  retrack,
5
5
  track
6
- } from "./chunk-BQLVTAUZ.js";
6
+ } from "./chunk-JYXQCELN.js";
7
7
  import {
8
8
  devAssert
9
- } from "./chunk-COY6PUD2.js";
9
+ } from "./chunk-VPP2FONR.js";
10
10
 
11
11
  // src/core/signals/derived.ts
12
12
  function derived(getter, options) {
@@ -43,6 +43,21 @@ function derived(getter, options) {
43
43
  }, markDirty);
44
44
  const hook = globalThis.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
45
45
  let evaluating = false;
46
+ const validate = () => {
47
+ if (!cs._d) return;
48
+ const oldValue = cs._v;
49
+ evaluating = true;
50
+ try {
51
+ retrack(recompute, markDirty);
52
+ if (!Object.is(oldValue, cs._v)) cs.__v++;
53
+ } finally {
54
+ evaluating = false;
55
+ }
56
+ if (hook && !Object.is(oldValue, cs._v)) {
57
+ hook.emit("computed:update", { signal: cs, oldValue, newValue: cs._v });
58
+ }
59
+ };
60
+ cs._validate = validate;
46
61
  function computedGetter() {
47
62
  if (evaluating) {
48
63
  throw new Error(
@@ -50,32 +65,11 @@ function derived(getter, options) {
50
65
  );
51
66
  }
52
67
  if (isTrackingSuspended()) {
53
- if (cs._d) {
54
- const prev = cs._v;
55
- evaluating = true;
56
- try {
57
- retrack(recompute, markDirty);
58
- if (!Object.is(prev, cs._v)) cs.__v++;
59
- } finally {
60
- evaluating = false;
61
- }
62
- }
68
+ if (cs._d) validate();
63
69
  return cs._v;
64
70
  }
71
+ if (cs._d) validate();
65
72
  recordDependency(cs);
66
- if (cs._d) {
67
- const oldValue = cs._v;
68
- evaluating = true;
69
- try {
70
- retrack(recompute, markDirty);
71
- if (!Object.is(oldValue, cs._v)) cs.__v++;
72
- } finally {
73
- evaluating = false;
74
- }
75
- if (hook && oldValue !== cs._v) {
76
- hook.emit("computed:update", { signal: cs, oldValue, newValue: cs._v });
77
- }
78
- }
79
73
  return cs._v;
80
74
  }
81
75
  if (debugName) {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  renderToString
3
- } from "./chunk-EX77FXTT.js";
3
+ } from "./chunk-HYCCIYNS.js";
4
4
 
5
5
  // src/plugins/modular.ts
6
6
  function createModuleRegistry() {
@@ -0,0 +1,109 @@
1
+ import {
2
+ devWarn,
3
+ isDev,
4
+ reportError
5
+ } from "./chunk-VPP2FONR.js";
6
+
7
+ // src/core/rendering/dispose.ts
8
+ var elementDisposers = /* @__PURE__ */ new WeakMap();
9
+ var MAX_DRAIN_TEARDOWNS = 1e4;
10
+ function reportDrainRunaway(label, executed, remaining) {
11
+ if (typeof console === "undefined") return;
12
+ console.error(
13
+ `[SibuJS ${label}] runaway cleanup: stopped after running ${executed} teardowns with ${remaining} still queued. Cleanup production did not stabilize before the teardown safety ceiling was reached \u2014 the remaining work was NOT run.`,
14
+ { executed, remaining }
15
+ );
16
+ }
17
+ var _isDev = isDev();
18
+ var activeBindingCount = 0;
19
+ function registerDisposer(node, teardown) {
20
+ let disposers = elementDisposers.get(node);
21
+ if (!disposers) {
22
+ disposers = [];
23
+ elementDisposers.set(node, disposers);
24
+ }
25
+ disposers.push(teardown);
26
+ if (_isDev) activeBindingCount++;
27
+ }
28
+ function unregisterDisposer(node, teardown) {
29
+ const disposers = elementDisposers.get(node);
30
+ if (!disposers) return;
31
+ const index = disposers.indexOf(teardown);
32
+ if (index === -1) return;
33
+ disposers.splice(index, 1);
34
+ if (_isDev) activeBindingCount--;
35
+ if (disposers.length === 0) elementDisposers.delete(node);
36
+ }
37
+ function dispose(node) {
38
+ const stack = [node];
39
+ const order = [];
40
+ while (stack.length > 0) {
41
+ const current = stack.pop();
42
+ order.push(current);
43
+ const children = Array.from(current.childNodes);
44
+ for (let i = 0; i < children.length; i++) {
45
+ stack.push(children[i]);
46
+ }
47
+ }
48
+ for (let i = order.length - 1; i >= 0; i--) {
49
+ const current = order[i];
50
+ if (elementDisposers.has(current)) {
51
+ let executed = 0;
52
+ let runaway = false;
53
+ while (!runaway) {
54
+ const pending = elementDisposers.get(current);
55
+ if (!pending || pending.length === 0) break;
56
+ const snapshot = pending.slice();
57
+ elementDisposers.delete(current);
58
+ if (_isDev) activeBindingCount -= snapshot.length;
59
+ for (let i2 = 0; i2 < snapshot.length; i2++) {
60
+ if (executed >= MAX_DRAIN_TEARDOWNS) {
61
+ const rest = snapshot.slice(i2);
62
+ const added = elementDisposers.get(current);
63
+ elementDisposers.set(current, added ? rest.concat(added) : rest);
64
+ if (_isDev) activeBindingCount += rest.length;
65
+ reportDrainRunaway("dispose", executed, rest.length + (added?.length ?? 0));
66
+ runaway = true;
67
+ break;
68
+ }
69
+ executed++;
70
+ try {
71
+ snapshot[i2]();
72
+ } catch (err) {
73
+ reportError(err, { phase: "cleanup", name: "disposer" });
74
+ }
75
+ }
76
+ }
77
+ }
78
+ }
79
+ }
80
+ function replaceChildrenSafely(parent, ...next) {
81
+ for (let i = 0; i < next.length; i++) {
82
+ const node = next[i];
83
+ node.parentNode?.removeChild(node);
84
+ }
85
+ const current = Array.from(parent.childNodes);
86
+ for (let i = 0; i < current.length; i++) {
87
+ dispose(current[i]);
88
+ }
89
+ parent.replaceChildren(...next);
90
+ }
91
+ function checkLeaks(warnThreshold = 0) {
92
+ if (!_isDev) return 0;
93
+ if (warnThreshold > 0 && activeBindingCount > warnThreshold) {
94
+ devWarn(
95
+ `checkLeaks: ${activeBindingCount} active DOM bindings detected. Expected \u2264${warnThreshold}. This may indicate a component was removed from the DOM without calling dispose().`
96
+ );
97
+ }
98
+ return activeBindingCount;
99
+ }
100
+
101
+ export {
102
+ MAX_DRAIN_TEARDOWNS,
103
+ reportDrainRunaway,
104
+ registerDisposer,
105
+ unregisterDisposer,
106
+ dispose,
107
+ replaceChildrenSafely,
108
+ checkLeaks
109
+ };
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  SVG_NS,
3
3
  tagFactory
4
- } from "./chunk-NXR2YFZB.js";
4
+ } from "./chunk-QD4I7ZGZ.js";
5
5
 
6
6
  // src/core/rendering/html.ts
7
7
  var html = tagFactory("html");