sibujs 4.7.0 → 4.9.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 (83) hide show
  1. package/dist/browser.cjs +48 -6
  2. package/dist/browser.d.cts +26 -2
  3. package/dist/browser.d.ts +26 -2
  4. package/dist/browser.js +6 -5
  5. package/dist/build.cjs +539 -96
  6. package/dist/build.d.cts +22 -8
  7. package/dist/build.d.ts +22 -8
  8. package/dist/build.js +68 -21
  9. package/dist/cdn.dev.global.js +15 -13
  10. package/dist/cdn.full.dev.global.js +15 -13
  11. package/dist/cdn.full.global.js +14 -12
  12. package/dist/cdn.global.js +14 -12
  13. package/dist/{chunk-Z3OHK6QT.js → chunk-2K3Z3XO4.js} +5 -5
  14. package/dist/chunk-3ACAAQIN.js +224 -0
  15. package/dist/{chunk-WOLJZUFQ.js → chunk-562UVHMM.js} +32 -15
  16. package/dist/{chunk-UOL2ECCS.js → chunk-5MLWTIQE.js} +18 -12
  17. package/dist/{chunk-H3SRKIYX.js → chunk-62BDYGAG.js} +8 -0
  18. package/dist/{chunk-3QWBSL5R.js → chunk-7OV5Q2UU.js} +8 -5
  19. package/dist/{chunk-SLM3IA34.js → chunk-CDBKFGXN.js} +1 -1
  20. package/dist/{chunk-4AWA2PVD.js → chunk-CF2KCWRE.js} +10 -5
  21. package/dist/{chunk-BSY63EM6.js → chunk-DRMLIF6M.js} +20 -5
  22. package/dist/{chunk-2INLLLMZ.js → chunk-EXXSN3BW.js} +202 -26
  23. package/dist/{chunk-HURREPU2.js → chunk-FC6KCJSA.js} +87 -150
  24. package/dist/{chunk-BC2SECJD.js → chunk-FHCZMHHE.js} +1 -1
  25. package/dist/{chunk-XYV3EDB7.js → chunk-FNOK662L.js} +63 -38
  26. package/dist/{chunk-JWKYU5GV.js → chunk-G2WHYEL7.js} +1 -1
  27. package/dist/{chunk-DKXRACVN.js → chunk-K6K5ACO6.js} +6 -6
  28. package/dist/{chunk-VZSG24LS.js → chunk-KG25XMGP.js} +45 -17
  29. package/dist/{chunk-FNJXNGYZ.js → chunk-MPWDSTYK.js} +58 -6
  30. package/dist/{chunk-UNWRJRKC.js → chunk-NQMKWBKU.js} +1 -1
  31. package/dist/{chunk-7LUJQAOJ.js → chunk-QBKCK6MJ.js} +1 -1
  32. package/dist/{chunk-WEQ3DMVL.js → chunk-SBTZEYNI.js} +1 -1
  33. package/dist/{chunk-FQRUXCEE.js → chunk-SYHGGDNW.js} +1 -1
  34. package/dist/{chunk-XZR4PXRE.js → chunk-TV464N2M.js} +13 -10
  35. package/dist/{chunk-RUSSKG6G.js → chunk-X7NRHFZR.js} +1 -1
  36. package/dist/{chunk-2BPG2XDA.js → chunk-XJVTQUIV.js} +18 -36
  37. package/dist/{chunk-ZVL7TY4K.js → chunk-YW6HQKGO.js} +25 -10
  38. package/dist/{customElement-MmInOW1U.d.ts → customElement-pYDKUzWl.d.cts} +11 -3
  39. package/dist/{customElement-MmInOW1U.d.cts → customElement-pYDKUzWl.d.ts} +11 -3
  40. package/dist/data.cjs +29 -9
  41. package/dist/data.d.cts +23 -4
  42. package/dist/data.d.ts +23 -4
  43. package/dist/data.js +6 -6
  44. package/dist/devtools.cjs +1 -1
  45. package/dist/devtools.js +5 -5
  46. package/dist/ecosystem.cjs +400 -37
  47. package/dist/ecosystem.js +9 -8
  48. package/dist/extras.cjs +672 -269
  49. package/dist/extras.d.cts +2 -2
  50. package/dist/extras.d.ts +2 -2
  51. package/dist/extras.js +24 -23
  52. package/dist/index.cjs +490 -88
  53. package/dist/index.d.cts +34 -2
  54. package/dist/index.d.ts +34 -2
  55. package/dist/index.js +16 -12
  56. package/dist/motion.cjs +1 -1
  57. package/dist/motion.js +3 -3
  58. package/dist/patterns.cjs +10 -7
  59. package/dist/patterns.js +6 -6
  60. package/dist/performance.cjs +31 -2
  61. package/dist/performance.d.cts +12 -2
  62. package/dist/performance.d.ts +12 -2
  63. package/dist/performance.js +8 -6
  64. package/dist/plugins.cjs +571 -240
  65. package/dist/plugins.d.cts +14 -3
  66. package/dist/plugins.d.ts +14 -3
  67. package/dist/plugins.js +35 -37
  68. package/dist/{ssr-XOTUASDO.js → ssr-5OWAH3U2.js} +4 -2
  69. package/dist/{ssr-Bli9XRW5.d.ts → ssr-C8hgIAw7.d.cts} +6 -0
  70. package/dist/{ssr-Bli9XRW5.d.cts → ssr-C8hgIAw7.d.ts} +6 -0
  71. package/dist/ssr.cjs +484 -138
  72. package/dist/ssr.d.cts +59 -5
  73. package/dist/ssr.d.ts +59 -5
  74. package/dist/ssr.js +11 -9
  75. package/dist/testing.cjs +3 -3
  76. package/dist/testing.js +4 -4
  77. package/dist/ui.cjs +609 -241
  78. package/dist/ui.d.cts +1 -1
  79. package/dist/ui.d.ts +1 -1
  80. package/dist/ui.js +9 -8
  81. package/dist/widgets.cjs +1 -1
  82. package/dist/widgets.js +7 -7
  83. package/package.json +5 -4
@@ -0,0 +1,224 @@
1
+ import {
2
+ canonicalAttrName,
3
+ isEventHandlerAttr,
4
+ isHtmlContentAttribute,
5
+ isUrlAttribute,
6
+ sanitizeUrl,
7
+ stripControlChars
8
+ } from "./chunk-EXXSN3BW.js";
9
+ import {
10
+ DEV
11
+ } from "./chunk-NYNYSPK7.js";
12
+
13
+ // src/utils/metaRefresh.ts
14
+ function isAsciiWhitespace(ch) {
15
+ return ch === " " || ch === " " || ch === "\n" || ch === "\r" || ch === "\f";
16
+ }
17
+ function trimAsciiWhitespace(value) {
18
+ let start = 0;
19
+ let end = value.length;
20
+ while (start < end && isAsciiWhitespace(value[start])) start++;
21
+ while (end > start && isAsciiWhitespace(value[end - 1])) end--;
22
+ return value.slice(start, end);
23
+ }
24
+ var forbidden = (reason) => ({ kind: "forbidden", reason });
25
+ function parseMetaRefreshContent(content) {
26
+ const raw = trimAsciiWhitespace(stripControlChars(content));
27
+ if (raw === "") return forbidden(DEV ? "empty content" : "");
28
+ let i = 0;
29
+ while (i < raw.length && raw[i] >= "0" && raw[i] <= "9") i++;
30
+ if (i === 0) return forbidden(DEV ? "missing or non-numeric delay" : "");
31
+ const delay = Number.parseInt(raw.slice(0, i), 10);
32
+ if (!Number.isFinite(delay)) return forbidden(DEV ? "unparseable delay" : "");
33
+ while (i < raw.length && isAsciiWhitespace(raw[i])) i++;
34
+ if (i === raw.length) return { kind: "delay-only", delay };
35
+ if (raw[i] !== ";" && raw[i] !== ",") return forbidden(DEV ? "unexpected text after delay" : "");
36
+ i++;
37
+ while (i < raw.length && isAsciiWhitespace(raw[i])) i++;
38
+ const keyStart = i;
39
+ while (i < raw.length && !isAsciiWhitespace(raw[i]) && raw[i] !== "=") i++;
40
+ const key = raw.slice(keyStart, i).toLowerCase();
41
+ if (key !== "url") return forbidden(DEV ? `unsupported refresh key ${JSON.stringify(key)}` : "");
42
+ while (i < raw.length && isAsciiWhitespace(raw[i])) i++;
43
+ if (raw[i] !== "=") return forbidden(DEV ? "missing '=' after url" : "");
44
+ i++;
45
+ while (i < raw.length && isAsciiWhitespace(raw[i])) i++;
46
+ let destination;
47
+ const quote = raw[i];
48
+ if (quote === '"' || quote === "'") {
49
+ const close = raw.indexOf(quote, i + 1);
50
+ if (close === -1) return forbidden(DEV ? "unterminated quoted destination" : "");
51
+ destination = raw.slice(i + 1, close);
52
+ const rest = trimAsciiWhitespace(raw.slice(close + 1));
53
+ if (rest !== "") return forbidden(DEV ? "trailing text after quoted destination" : "");
54
+ } else {
55
+ destination = trimAsciiWhitespace(raw.slice(i));
56
+ if (/[;,]/.test(destination)) return forbidden(DEV ? "multiple refresh assignments" : "");
57
+ }
58
+ if (destination === "") return forbidden(DEV ? "empty destination" : "");
59
+ const sanitizedDestination = sanitizeUrl(destination);
60
+ if (sanitizedDestination === "") return forbidden(DEV ? "destination uses a disallowed protocol" : "");
61
+ return { kind: "allowed", delay, destination, sanitizedDestination };
62
+ }
63
+ function resolveMetaRefreshPolicy(attributes) {
64
+ let httpEquiv;
65
+ let content;
66
+ let duplicateName;
67
+ const seen = /* @__PURE__ */ new Set();
68
+ for (const [key, value] of attributes) {
69
+ const canonical = canonicalAttrName(key);
70
+ if (seen.has(canonical)) duplicateName = canonical;
71
+ seen.add(canonical);
72
+ if (canonical === "http-equiv") httpEquiv = value;
73
+ else if (canonical === "content") content = value;
74
+ }
75
+ if (duplicateName !== void 0) {
76
+ return forbidden(DEV ? `duplicate case-insensitive attribute ${JSON.stringify(duplicateName)}` : "");
77
+ }
78
+ if (typeof httpEquiv !== "string") return { kind: "not-refresh" };
79
+ if (trimAsciiWhitespace(stripControlChars(httpEquiv)).toLowerCase() !== "refresh") {
80
+ return { kind: "not-refresh" };
81
+ }
82
+ if (typeof content !== "string") return { kind: "not-refresh" };
83
+ return parseMetaRefreshContent(content);
84
+ }
85
+ function normalizeMetaAttributes(props) {
86
+ const out = /* @__PURE__ */ new Map();
87
+ const seen = /* @__PURE__ */ new Set();
88
+ for (const key of Object.keys(props)) {
89
+ const canonical = canonicalAttrName(key);
90
+ if (seen.has(canonical)) return null;
91
+ seen.add(canonical);
92
+ out.set(key, props[key]);
93
+ }
94
+ return out;
95
+ }
96
+ function isForbiddenMetaEntry(props) {
97
+ const normalized = normalizeMetaAttributes(props);
98
+ if (normalized === null) return true;
99
+ return resolveMetaRefreshPolicy(normalized).kind === "forbidden";
100
+ }
101
+
102
+ // src/utils/elementPolicy.ts
103
+ var HTML_NS = "http://www.w3.org/1999/xhtml";
104
+ var SVG_NS = "http://www.w3.org/2000/svg";
105
+ var BLOCKED_ELEMENTS = /* @__PURE__ */ new Set(["script", "iframe", "object", "embed", "frame", "frameset"]);
106
+ function canonicalTagName(tag) {
107
+ return canonicalAttrName(tag);
108
+ }
109
+ function isBlockedElement(tag) {
110
+ return BLOCKED_ELEMENTS.has(canonicalTagName(tag));
111
+ }
112
+ var CODE_TEXT_ELEMENTS = /* @__PURE__ */ new Set(["script", "style"]);
113
+ function isCodeTextElement(tag) {
114
+ return CODE_TEXT_ELEMENTS.has(canonicalTagName(tag));
115
+ }
116
+ var ContextualRefusal = {
117
+ None: 0,
118
+ /** The element would carry a refresh directive the shared policy forbids. */
119
+ MetaRefreshForbidden: 1,
120
+ /** A `<meta>` with a reactive binding may not carry any refresh directive. */
121
+ MetaRefreshReactive: 2,
122
+ /** A runtime value may not choose which program a `<script>` runs. */
123
+ ScriptSource: 3,
124
+ /** An SVG animation may not target a URL, handler or document attribute. */
125
+ AnimationTarget: 4,
126
+ /** A runtime-written `href` may not become an applied stylesheet. */
127
+ StylesheetSource: 5
128
+ };
129
+ var SCRIPT_SOURCE_ATTRIBUTES = /* @__PURE__ */ new Set(["src", "href", "xlink:href", "type", "language"]);
130
+ var SVG_ANIMATION_ELEMENTS = /* @__PURE__ */ new Set(["animate", "set", "animateMotion", "animateTransform", "animateColor"]);
131
+ var reactiveMetaElements = /* @__PURE__ */ new WeakSet();
132
+ function isHtmlNamespace(el) {
133
+ return el.namespaceURI === HTML_NS || el.namespaceURI === null;
134
+ }
135
+ function metaSnapshot(el, canonical, value) {
136
+ const snapshot = /* @__PURE__ */ new Map();
137
+ const attrs = el.attributes;
138
+ for (let i = 0; i < attrs.length; i++) {
139
+ const attr = attrs[i];
140
+ if (attr.name === canonical) continue;
141
+ snapshot.set(attr.name, attr.value);
142
+ }
143
+ if (canonical !== null && value !== null) snapshot.set(canonical, value);
144
+ return snapshot;
145
+ }
146
+ function claimReactiveMeta(el) {
147
+ if (reactiveMetaElements.has(el)) return;
148
+ reactiveMetaElements.add(el);
149
+ if (el.getAttribute("content") === null) return;
150
+ if (resolveMetaRefreshPolicy(metaSnapshot(el, null, null)).kind !== "not-refresh") {
151
+ el.removeAttribute("content");
152
+ }
153
+ }
154
+ function metaRefusal(el, name, value, origin) {
155
+ if (!isHtmlNamespace(el)) return ContextualRefusal.None;
156
+ const canonical = canonicalAttrName(name);
157
+ if (canonical !== "http-equiv" && canonical !== "content") return ContextualRefusal.None;
158
+ if (origin === "reactive") claimReactiveMeta(el);
159
+ if (value === null) return ContextualRefusal.None;
160
+ if (canonical === "content" && !el.hasAttribute("http-equiv")) return ContextualRefusal.None;
161
+ const decision = resolveMetaRefreshPolicy(metaSnapshot(el, canonical, value));
162
+ if (decision.kind === "forbidden") return ContextualRefusal.MetaRefreshForbidden;
163
+ if (decision.kind !== "not-refresh" && reactiveMetaElements.has(el)) return ContextualRefusal.MetaRefreshReactive;
164
+ return ContextualRefusal.None;
165
+ }
166
+ function animationRefusal(name, value) {
167
+ if (value === null || canonicalAttrName(name) !== "attributename") return ContextualRefusal.None;
168
+ const target = stripControlChars(value);
169
+ return isUrlAttribute(target) || isEventHandlerAttr(target) || isHtmlContentAttribute(target) ? ContextualRefusal.AnimationTarget : ContextualRefusal.None;
170
+ }
171
+ var runtimeHrefLinks = /* @__PURE__ */ new WeakSet();
172
+ function relHasStylesheet(rel) {
173
+ if (rel === null) return false;
174
+ const lower = canonicalAttrName(rel);
175
+ if (!lower.includes("stylesheet")) return false;
176
+ const tokens = lower.split(/[\t\n\f\r ]+/);
177
+ for (let i = 0; i < tokens.length; i++) if (tokens[i] === "stylesheet") return true;
178
+ return false;
179
+ }
180
+ function stylesheetRefusal(el, name, value, origin) {
181
+ if (!isHtmlNamespace(el)) return ContextualRefusal.None;
182
+ const canonical = canonicalAttrName(name);
183
+ if (canonical === "href") {
184
+ if (origin === "static" || value === null) return ContextualRefusal.None;
185
+ if (relHasStylesheet(el.getAttribute("rel"))) return ContextualRefusal.StylesheetSource;
186
+ runtimeHrefLinks.add(el);
187
+ return ContextualRefusal.None;
188
+ }
189
+ if (canonical === "rel") {
190
+ if (!relHasStylesheet(value)) return ContextualRefusal.None;
191
+ return runtimeHrefLinks.has(el) && el.hasAttribute("href") ? ContextualRefusal.StylesheetSource : ContextualRefusal.None;
192
+ }
193
+ return ContextualRefusal.None;
194
+ }
195
+ function contextualAttributeRefusal(el, name, value, origin) {
196
+ const local = el.localName;
197
+ if (local === "meta") return metaRefusal(el, name, value, origin);
198
+ if (local === "link") return stylesheetRefusal(el, name, value, origin);
199
+ if (local === "script") {
200
+ if (origin === "static" || value === null) return ContextualRefusal.None;
201
+ return SCRIPT_SOURCE_ATTRIBUTES.has(canonicalAttrName(name)) ? ContextualRefusal.ScriptSource : ContextualRefusal.None;
202
+ }
203
+ if (SVG_ANIMATION_ELEMENTS.has(local) && el.namespaceURI === SVG_NS) return animationRefusal(name, value);
204
+ return ContextualRefusal.None;
205
+ }
206
+ function settleAttributeProvenance(el, name, origin) {
207
+ if (el.localName !== "link" || canonicalAttrName(name) !== "href") return;
208
+ if (origin !== "static" && el.hasAttribute("href")) runtimeHrefLinks.add(el);
209
+ else runtimeHrefLinks.delete(el);
210
+ }
211
+ function isForbiddenMetaSnapshot(attributes) {
212
+ return resolveMetaRefreshPolicy(attributes).kind === "forbidden";
213
+ }
214
+
215
+ export {
216
+ resolveMetaRefreshPolicy,
217
+ isForbiddenMetaEntry,
218
+ isBlockedElement,
219
+ isCodeTextElement,
220
+ ContextualRefusal,
221
+ contextualAttributeRefusal,
222
+ settleAttributeProvenance,
223
+ isForbiddenMetaSnapshot
224
+ };
@@ -1,25 +1,25 @@
1
1
  import {
2
2
  derived
3
- } from "./chunk-RUSSKG6G.js";
4
- import {
5
- sanitizeUrl
6
- } from "./chunk-2INLLLMZ.js";
3
+ } from "./chunk-X7NRHFZR.js";
7
4
  import {
8
5
  globalSingleton
9
6
  } from "./chunk-7ZHH77QA.js";
10
7
  import {
11
8
  effect
12
- } from "./chunk-WEQ3DMVL.js";
9
+ } from "./chunk-SBTZEYNI.js";
10
+ import {
11
+ sanitizeUrl
12
+ } from "./chunk-EXXSN3BW.js";
13
13
  import {
14
14
  getRequestScopedCache
15
15
  } from "./chunk-7XHATCIH.js";
16
16
  import {
17
17
  batch,
18
18
  signal
19
- } from "./chunk-FQRUXCEE.js";
19
+ } from "./chunk-SYHGGDNW.js";
20
20
  import {
21
21
  untracked
22
- } from "./chunk-JWKYU5GV.js";
22
+ } from "./chunk-G2WHYEL7.js";
23
23
  import {
24
24
  reportError
25
25
  } from "./chunk-NYNYSPK7.js";
@@ -173,7 +173,11 @@ function reconcile(prev, next, depth, walk, newRoot) {
173
173
  const nextChild = nextRecord[key];
174
174
  const hasPrev = Object.hasOwn(prevRecord, key);
175
175
  const shared = hasPrev ? reconcile(prevRecord[key], nextChild, depth + 1, walk, false) : nextChild;
176
- copy[key] = shared;
176
+ if (key === "__proto__") {
177
+ Object.defineProperty(copy, key, { value: shared, writable: true, enumerable: true, configurable: true });
178
+ } else {
179
+ copy[key] = shared;
180
+ }
177
181
  if (!hasPrev || !Object.is(shared, prevRecord[key])) allFromPrev = false;
178
182
  if (!Object.is(shared, nextChild)) allFromNext = false;
179
183
  }
@@ -264,6 +268,8 @@ function query(key, fetcher, options = {}) {
264
268
  structuralSharing = true
265
269
  } = options;
266
270
  const resolveKey = typeof key === "function" ? key : () => key;
271
+ const enabledGate = typeof enabled === "function" ? derived(() => Boolean(enabled())) : null;
272
+ const isEnabled = enabledGate ?? (() => enabled);
267
273
  const cache = getActiveQueryCache();
268
274
  const [data, setData] = signal(initialData);
269
275
  const [isFetching, setIsFetching] = signal(false);
@@ -378,7 +384,7 @@ function query(key, fetcher, options = {}) {
378
384
  }
379
385
  }
380
386
  async function doFetch() {
381
- if (disposed || !currentKey || !enabled) return;
387
+ if (disposed || !currentKey || !untracked(isEnabled)) return;
382
388
  const key2 = currentKey;
383
389
  const entry = getOrCreateEntry(cache, key2);
384
390
  attachToEntry(entry, key2);
@@ -480,10 +486,17 @@ function query(key, fetcher, options = {}) {
480
486
  }
481
487
  const effectCleanup = effect(() => {
482
488
  const key2 = resolveKey();
489
+ const on = isEnabled();
483
490
  const keyChanged = currentKey !== key2;
484
491
  currentKey = key2;
492
+ if (key2 === "") {
493
+ detachFromEntry();
494
+ setIsFetching(false);
495
+ return;
496
+ }
485
497
  const entry = getOrCreateEntry(cache, key2, initialData);
486
498
  attachToEntry(entry, key2);
499
+ if (keyChanged) setIsFetching(entry.promise !== null);
487
500
  if (entry.data !== void 0) {
488
501
  const view = viewOf(entry);
489
502
  batch(() => {
@@ -494,17 +507,17 @@ function query(key, fetcher, options = {}) {
494
507
  }
495
508
  if (!keyChanged && currentKey === key2 && entry.data !== void 0) {
496
509
  const isDataStale2 = entry.dataUpdatedAt === 0 || Date.now() - entry.dataUpdatedAt >= staleTime;
497
- if (enabled && isDataStale2 && !entry.promise) doFetch();
510
+ if (on && isDataStale2 && !entry.promise) doFetch();
498
511
  return;
499
512
  }
500
513
  const isDataStale = entry.dataUpdatedAt === 0 || Date.now() - entry.dataUpdatedAt >= staleTime;
501
- if (enabled && (entry.data === void 0 || isDataStale)) {
514
+ if (on && (entry.data === void 0 || isDataStale)) {
502
515
  doFetch();
503
516
  }
504
517
  });
505
518
  if (refetchInterval && refetchInterval > 0) {
506
519
  intervalTimer = setInterval(() => {
507
- if (!disposed && currentKey && enabled) doFetch();
520
+ if (!disposed && currentKey) doFetch();
508
521
  }, refetchInterval);
509
522
  }
510
523
  let focusHandler = null;
@@ -512,13 +525,13 @@ function query(key, fetcher, options = {}) {
512
525
  if (typeof globalThis !== "undefined" && typeof globalThis.addEventListener === "function") {
513
526
  if (refetchOnWindowFocus) {
514
527
  focusHandler = () => {
515
- if (!disposed && currentKey && enabled) doFetch();
528
+ if (!disposed && currentKey) doFetch();
516
529
  };
517
530
  globalThis.addEventListener("focus", focusHandler);
518
531
  }
519
532
  if (refetchOnReconnect) {
520
533
  onlineHandler = () => {
521
- if (!disposed && currentKey && enabled) doFetch();
534
+ if (!disposed && currentKey) doFetch();
522
535
  };
523
536
  globalThis.addEventListener("online", onlineHandler);
524
537
  }
@@ -530,6 +543,7 @@ function query(key, fetcher, options = {}) {
530
543
  stopSelect?.();
531
544
  loading.dispose();
532
545
  isStale.dispose();
546
+ enabledGate?.dispose();
533
547
  if (intervalTimer) clearInterval(intervalTimer);
534
548
  detachFromEntry();
535
549
  if (focusHandler && typeof globalThis.removeEventListener === "function") {
@@ -709,6 +723,8 @@ function infiniteQuery(key, fetcher, options) {
709
723
  onError
710
724
  } = options;
711
725
  const resolveKey = typeof key === "function" ? key : () => key;
726
+ const enabledGate = typeof enabled === "function" ? derived(() => Boolean(enabled())) : null;
727
+ const isEnabled = enabledGate ?? (() => enabled);
712
728
  const [pages, setPages] = signal([]);
713
729
  const [isFetching, setIsFetching] = signal(false);
714
730
  const [isFetchingNext, setIsFetchingNext] = signal(false);
@@ -787,7 +803,7 @@ function infiniteQuery(key, fetcher, options) {
787
803
  }
788
804
  const effectCleanup = effect(() => {
789
805
  resolveKey();
790
- if (enabled) {
806
+ if (isEnabled()) {
791
807
  abortController?.abort();
792
808
  batch(() => {
793
809
  setPages([]);
@@ -828,6 +844,7 @@ function infiniteQuery(key, fetcher, options) {
828
844
  loading.dispose();
829
845
  hasNextPage.dispose();
830
846
  hasPreviousPage.dispose();
847
+ enabledGate?.dispose();
831
848
  }
832
849
  return {
833
850
  data,
@@ -1,15 +1,18 @@
1
1
  import {
2
2
  bindAttribute,
3
3
  setSafeAttribute
4
- } from "./chunk-FNJXNGYZ.js";
4
+ } from "./chunk-MPWDSTYK.js";
5
+ import {
6
+ isBlockedElement
7
+ } from "./chunk-3ACAAQIN.js";
5
8
  import {
6
9
  isEventHandlerAttr,
7
- sanitizeCSSValue,
10
+ sanitizeCSSDeclaration,
8
11
  sanitizeStyleAttribute
9
- } from "./chunk-2INLLLMZ.js";
12
+ } from "./chunk-EXXSN3BW.js";
10
13
  import {
11
14
  reactiveBinding
12
- } from "./chunk-JWKYU5GV.js";
15
+ } from "./chunk-G2WHYEL7.js";
13
16
  import {
14
17
  DEV,
15
18
  devWarn,
@@ -189,10 +192,6 @@ function bindChildNode(placeholder, getter) {
189
192
 
190
193
  // src/core/rendering/tagFactory.ts
191
194
  var SVG_NS = "http://www.w3.org/2000/svg";
192
- var BLOCKED_TAGS = /* @__PURE__ */ new Set(["script", "iframe", "object", "embed", "frame", "frameset"]);
193
- function isBlockedTag(tag) {
194
- return BLOCKED_TAGS.has(tag.toLowerCase());
195
- }
196
195
  var CLOBBER_RISKY_IDS = /* @__PURE__ */ new Set([
197
196
  "config",
198
197
  "location",
@@ -237,11 +236,12 @@ function applyStyle(el, style) {
237
236
  }
238
237
  const next = [];
239
238
  for (const prop in value) {
239
+ if (!Object.hasOwn(value, prop)) continue;
240
240
  const val = value[prop];
241
241
  if (val == null) continue;
242
242
  const name = toKebab(prop);
243
243
  next.push(name);
244
- decl.setProperty(name, sanitizeCSSValue(String(val), { property: name, element: el }));
244
+ decl.setProperty(name, sanitizeCSSDeclaration(name, String(val), { element: el }));
245
245
  }
246
246
  for (let i = 0; i < written.length; i++) {
247
247
  if (next.indexOf(written[i]) === -1) decl.removeProperty(written[i]);
@@ -257,16 +257,17 @@ function applyStyle(el, style) {
257
257
  }
258
258
  const htmlEl = el;
259
259
  for (const prop in style) {
260
+ if (!Object.hasOwn(style, prop)) continue;
260
261
  const val = style[prop];
261
262
  const name = toKebab(prop);
262
263
  if (typeof val === "function") {
263
264
  const getter = val;
264
265
  const teardown = reactiveBinding(() => {
265
- htmlEl.style.setProperty(name, sanitizeCSSValue(String(getter()), { property: name, element: el }));
266
+ htmlEl.style.setProperty(name, sanitizeCSSDeclaration(name, String(getter()), { element: el }));
266
267
  }, el);
267
268
  registerDisposer(el, teardown);
268
269
  } else {
269
- htmlEl.style.setProperty(name, sanitizeCSSValue(String(val), { property: name, element: el }));
270
+ htmlEl.style.setProperty(name, sanitizeCSSDeclaration(name, String(val), { element: el }));
270
271
  }
271
272
  }
272
273
  }
@@ -276,6 +277,7 @@ function resolveClassValue(cls) {
276
277
  if (!cls) return "";
277
278
  let out = "";
278
279
  for (const name in cls) {
280
+ if (!Object.hasOwn(cls, name)) continue;
279
281
  const val = cls[name];
280
282
  const active = typeof val === "function" ? val() : val;
281
283
  if (active) out = out ? `${out} ${name}` : name;
@@ -300,6 +302,7 @@ function applyClass(el, cls) {
300
302
  let hasReactive = false;
301
303
  let result = "";
302
304
  for (const name in obj) {
305
+ if (!Object.hasOwn(obj, name)) continue;
303
306
  const val = obj[name];
304
307
  if (typeof val === "function") {
305
308
  hasReactive = true;
@@ -311,6 +314,7 @@ function applyClass(el, cls) {
311
314
  const update = () => {
312
315
  let r = "";
313
316
  for (const name in obj) {
317
+ if (!Object.hasOwn(obj, name)) continue;
314
318
  const val = obj[name];
315
319
  const active = typeof val === "function" ? val() : val;
316
320
  if (active) r = r ? `${r} ${name}` : name;
@@ -374,7 +378,7 @@ function appendChildren(el, nodes) {
374
378
  }
375
379
  }
376
380
  function tagFactory(tag, ns) {
377
- const blocked = isBlockedTag(tag);
381
+ const blocked = isBlockedElement(tag);
378
382
  return (first, second) => {
379
383
  if (blocked) {
380
384
  throw new Error(`tagFactory: refusing to create <${tag}> \u2014 tag is blocked for security reasons.`);
@@ -437,6 +441,7 @@ function tagFactory(tag, ns) {
437
441
  const pOn = props.on;
438
442
  if (pOn) {
439
443
  for (const ev in pOn) {
444
+ if (!Object.hasOwn(pOn, ev)) continue;
440
445
  const handler = pOn[ev];
441
446
  if (typeof handler === "function") {
442
447
  el.addEventListener(ev, handler);
@@ -463,6 +468,7 @@ function tagFactory(tag, ns) {
463
468
  continue;
464
469
  // already handled above / below
465
470
  default: {
471
+ if (!Object.hasOwn(props, key)) continue;
466
472
  const value = props[key];
467
473
  if (value == null) continue;
468
474
  if (isEventHandlerAttr(key)) continue;
@@ -3,6 +3,13 @@ var UNSAFE_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototyp
3
3
  function isUnsafeKey(key) {
4
4
  return UNSAFE_KEYS.has(key);
5
5
  }
6
+ function readOwnGlobal(key) {
7
+ if (typeof window === "undefined") return void 0;
8
+ if (!Object.hasOwn(window, key)) return void 0;
9
+ const value = window[key];
10
+ if (typeof Node !== "undefined" && value instanceof Node) return void 0;
11
+ return value;
12
+ }
6
13
  function stripUnsafeKeys(obj) {
7
14
  const out = {};
8
15
  for (const k of Object.keys(obj)) {
@@ -13,5 +20,6 @@ function stripUnsafeKeys(obj) {
13
20
 
14
21
  export {
15
22
  isUnsafeKey,
23
+ readOwnGlobal,
16
24
  stripUnsafeKeys
17
25
  };
@@ -3,20 +3,23 @@ import {
3
3
  } from "./chunk-J6FW5TV6.js";
4
4
  import {
5
5
  tagFactory
6
- } from "./chunk-UOL2ECCS.js";
6
+ } from "./chunk-5MLWTIQE.js";
7
7
  import {
8
8
  derived
9
- } from "./chunk-RUSSKG6G.js";
9
+ } from "./chunk-X7NRHFZR.js";
10
10
  import {
11
11
  globalSingleton
12
12
  } from "./chunk-7ZHH77QA.js";
13
13
  import {
14
14
  effect
15
- } from "./chunk-WEQ3DMVL.js";
15
+ } from "./chunk-SBTZEYNI.js";
16
+ import {
17
+ sanitizeCSSDeclaration
18
+ } from "./chunk-EXXSN3BW.js";
16
19
  import {
17
20
  batch,
18
21
  signal
19
- } from "./chunk-FQRUXCEE.js";
22
+ } from "./chunk-SYHGGDNW.js";
20
23
 
21
24
  // src/ecosystem/adapters/mobx.ts
22
25
  function mobXAdapter(options) {
@@ -121,7 +124,7 @@ var _themeLayers = globalSingleton(
121
124
  function commitThemeProperty(root, name, record) {
122
125
  const top = record.layers[record.layers.length - 1];
123
126
  if (top) {
124
- root.style.setProperty(name, top.value);
127
+ root.style.setProperty(name, sanitizeCSSDeclaration(name, String(top.value), { element: root }));
125
128
  return;
126
129
  }
127
130
  _themeLayers.get(root)?.delete(name);
@@ -5,7 +5,7 @@ import {
5
5
  resumeTracking,
6
6
  suspendTracking,
7
7
  track
8
- } from "./chunk-JWKYU5GV.js";
8
+ } from "./chunk-G2WHYEL7.js";
9
9
  import {
10
10
  devAssert
11
11
  } from "./chunk-NYNYSPK7.js";
@@ -1,9 +1,12 @@
1
1
  import {
2
2
  renderToString
3
- } from "./chunk-HURREPU2.js";
3
+ } from "./chunk-FC6KCJSA.js";
4
4
  import {
5
5
  globalSingleton
6
6
  } from "./chunk-7ZHH77QA.js";
7
+ import {
8
+ sanitizeUrl
9
+ } from "./chunk-EXXSN3BW.js";
7
10
  import {
8
11
  reportError
9
12
  } from "./chunk-NYNYSPK7.js";
@@ -167,7 +170,7 @@ var CDN_ENTRY_POINTS = {
167
170
  };
168
171
  var packageInfo = {
169
172
  name: "sibujs",
170
- version: true ? "4.7.0" : "dev",
173
+ version: true ? "4.9.0" : "dev",
171
174
  entryPoints: MODULE_ENTRY_POINTS,
172
175
  /**
173
176
  * Generate the package.json `exports` map. Module entries resolve to the
@@ -312,7 +315,7 @@ var env = {
312
315
  };
313
316
 
314
317
  // src/plugins/versioning.ts
315
- var VERSION = true ? "4.7.0" : "dev";
318
+ var VERSION = true ? "4.9.0" : "dev";
316
319
  var NUM = "(?:0|[1-9]\\d*)";
317
320
  var PRE_ID = `(?:${NUM}|\\d*[a-zA-Z-][0-9a-zA-Z-]*)`;
318
321
  var BUILD_ID = "[0-9a-zA-Z-]+";
@@ -595,12 +598,14 @@ function extractRangeTarget(range) {
595
598
  function preloadCritical(resources) {
596
599
  if (typeof document === "undefined") return;
597
600
  for (const resource of resources) {
598
- const safeHref = typeof CSS !== "undefined" && typeof CSS.escape === "function" ? CSS.escape(resource.href) : resource.href.replace(/["\\]/g, "\\$&");
601
+ const href = sanitizeUrl(resource.href);
602
+ if (!href) continue;
603
+ const safeHref = typeof CSS !== "undefined" && typeof CSS.escape === "function" ? CSS.escape(href) : href.replace(/["\\]/g, "\\$&");
599
604
  const existing = document.querySelector(`link[rel="preload"][href="${safeHref}"]`);
600
605
  if (existing) continue;
601
606
  const link = document.createElement("link");
602
607
  link.rel = "preload";
603
- link.href = resource.href;
608
+ link.href = href;
604
609
  link.setAttribute("as", resource.as);
605
610
  if (resource.type) {
606
611
  link.type = resource.type;
@@ -1,15 +1,18 @@
1
1
  import {
2
- sanitizeUrl
3
- } from "./chunk-2INLLLMZ.js";
2
+ isBlockedElement
3
+ } from "./chunk-3ACAAQIN.js";
4
4
  import {
5
5
  globalSingleton
6
6
  } from "./chunk-7ZHH77QA.js";
7
7
  import {
8
8
  effect
9
- } from "./chunk-WEQ3DMVL.js";
9
+ } from "./chunk-SBTZEYNI.js";
10
+ import {
11
+ sanitizeUrl
12
+ } from "./chunk-EXXSN3BW.js";
10
13
  import {
11
14
  signal
12
- } from "./chunk-FQRUXCEE.js";
15
+ } from "./chunk-SYHGGDNW.js";
13
16
  import {
14
17
  DEV,
15
18
  devWarn,
@@ -239,6 +242,9 @@ var DOMPool = class {
239
242
  * Get a recycled element or create a new one.
240
243
  */
241
244
  acquire(tag) {
245
+ if (isBlockedElement(tag)) {
246
+ throw new Error(`DOMPool: refusing to create <${tag}> \u2014 tag is blocked for security reasons.`);
247
+ }
242
248
  const pool = this.pools.get(tag);
243
249
  if (pool && pool.length > 0) {
244
250
  const el = pool.pop();
@@ -344,10 +350,19 @@ function prefetch(url) {
344
350
  }
345
351
  function preloadImage(src) {
346
352
  return new Promise((resolve, reject) => {
353
+ const safe = sanitizeUrl(String(src));
354
+ if (!safe) {
355
+ reject(
356
+ new Error(
357
+ String(src).trim() === "" ? "preloadImage: no image URL was given." : "preloadImage: refusing an image URL outside the URL policy."
358
+ )
359
+ );
360
+ return;
361
+ }
347
362
  const img = new Image();
348
363
  img.onload = () => resolve(img);
349
364
  img.onerror = reject;
350
- img.src = src;
365
+ img.src = safe;
351
366
  });
352
367
  }
353
368