@bquery/bquery 1.3.0 → 1.4.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 (71) hide show
  1. package/README.md +527 -501
  2. package/dist/{batch-4LAvfLE7.js → batch-x7b2eZST.js} +2 -2
  3. package/dist/{batch-4LAvfLE7.js.map → batch-x7b2eZST.js.map} +1 -1
  4. package/dist/component.es.mjs +1 -1
  5. package/dist/core/collection.d.ts +19 -3
  6. package/dist/core/collection.d.ts.map +1 -1
  7. package/dist/core/element.d.ts +23 -4
  8. package/dist/core/element.d.ts.map +1 -1
  9. package/dist/core/index.d.ts +1 -0
  10. package/dist/core/index.d.ts.map +1 -1
  11. package/dist/core/utils/function.d.ts +21 -4
  12. package/dist/core/utils/function.d.ts.map +1 -1
  13. package/dist/{core-COenAZjD.js → core-BhpuvPhy.js} +62 -37
  14. package/dist/core-BhpuvPhy.js.map +1 -0
  15. package/dist/core.es.mjs +174 -131
  16. package/dist/core.es.mjs.map +1 -1
  17. package/dist/full.es.mjs +7 -7
  18. package/dist/full.iife.js +2 -2
  19. package/dist/full.iife.js.map +1 -1
  20. package/dist/full.umd.js +2 -2
  21. package/dist/full.umd.js.map +1 -1
  22. package/dist/index.es.mjs +7 -7
  23. package/dist/motion.es.mjs.map +1 -1
  24. package/dist/{persisted-Dz_ryNuC.js → persisted-DHoi3uEs.js} +4 -4
  25. package/dist/{persisted-Dz_ryNuC.js.map → persisted-DHoi3uEs.js.map} +1 -1
  26. package/dist/platform/storage.d.ts.map +1 -1
  27. package/dist/platform.es.mjs +12 -7
  28. package/dist/platform.es.mjs.map +1 -1
  29. package/dist/reactive/core.d.ts +12 -0
  30. package/dist/reactive/core.d.ts.map +1 -1
  31. package/dist/reactive/effect.d.ts.map +1 -1
  32. package/dist/reactive/internals.d.ts +6 -0
  33. package/dist/reactive/internals.d.ts.map +1 -1
  34. package/dist/reactive.es.mjs +6 -6
  35. package/dist/router.es.mjs +1 -1
  36. package/dist/{sanitize-1FBEPAFH.js → sanitize-Cxvxa-DX.js} +50 -39
  37. package/dist/sanitize-Cxvxa-DX.js.map +1 -0
  38. package/dist/security/sanitize-core.d.ts.map +1 -1
  39. package/dist/security.es.mjs +2 -2
  40. package/dist/store.es.mjs +2 -2
  41. package/dist/type-guards-BdKlYYlS.js +32 -0
  42. package/dist/type-guards-BdKlYYlS.js.map +1 -0
  43. package/dist/untrack-DNnnqdlR.js +6 -0
  44. package/dist/{untrack-BuEQKH7_.js.map → untrack-DNnnqdlR.js.map} +1 -1
  45. package/dist/view/evaluate.d.ts.map +1 -1
  46. package/dist/view.es.mjs +157 -151
  47. package/dist/view.es.mjs.map +1 -1
  48. package/dist/{watch-CXyaBC_9.js → watch-DXXv3iAI.js} +3 -3
  49. package/dist/{watch-CXyaBC_9.js.map → watch-DXXv3iAI.js.map} +1 -1
  50. package/package.json +132 -132
  51. package/src/core/collection.ts +628 -588
  52. package/src/core/element.ts +774 -746
  53. package/src/core/index.ts +48 -47
  54. package/src/core/utils/function.ts +151 -110
  55. package/src/motion/animate.ts +113 -113
  56. package/src/motion/flip.ts +176 -176
  57. package/src/motion/scroll.ts +57 -57
  58. package/src/motion/spring.ts +150 -150
  59. package/src/motion/timeline.ts +246 -246
  60. package/src/motion/transition.ts +51 -51
  61. package/src/platform/storage.ts +215 -208
  62. package/src/reactive/core.ts +114 -93
  63. package/src/reactive/effect.ts +54 -43
  64. package/src/reactive/internals.ts +122 -105
  65. package/src/security/sanitize-core.ts +364 -343
  66. package/src/view/evaluate.ts +290 -274
  67. package/dist/core-COenAZjD.js.map +0 -1
  68. package/dist/sanitize-1FBEPAFH.js.map +0 -1
  69. package/dist/type-guards-DRma3-Kc.js +0 -16
  70. package/dist/type-guards-DRma3-Kc.js.map +0 -1
  71. package/dist/untrack-BuEQKH7_.js +0 -6
@@ -43,6 +43,18 @@ export declare class Signal<T> implements ReactiveSource {
43
43
  * @param updater - Function that receives current value and returns new value
44
44
  */
45
45
  update(updater: (current: T) => T): void;
46
+ /**
47
+ * Removes all subscribers from this signal.
48
+ * Use this when a signal is no longer needed to prevent memory leaks.
49
+ *
50
+ * @example
51
+ * ```ts
52
+ * const count = signal(0);
53
+ * effect(() => console.log(count.value));
54
+ * count.dispose(); // All subscribers removed
55
+ * ```
56
+ */
57
+ dispose(): void;
46
58
  /**
47
59
  * Removes an observer from this signal's subscriber set.
48
60
  * @internal
@@ -1 +1 @@
1
- {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/reactive/core.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAIL,KAAK,cAAc,EACpB,MAAM,aAAa,CAAC;AAErB;;;;;;;;GAQG;AACH,qBAAa,MAAM,CAAC,CAAC,CAAE,YAAW,cAAc;IAOlC,OAAO,CAAC,MAAM;IAN1B,OAAO,CAAC,WAAW,CAAyB;IAE5C;;;OAGG;gBACiB,MAAM,EAAE,CAAC;IAE7B;;;OAGG;IACH,IAAI,KAAK,IAAI,CAAC,CAOb;IAED;;;OAGG;IACH,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,EAQhB;IAED;;;;;OAKG;IACH,IAAI,IAAI,CAAC;IAIT;;;;;OAKG;IACH,MAAM,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,GAAG,IAAI;IAIxC;;;OAGG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI;CAGxC;AAED;;;;;;GAMG;AACH,eAAO,MAAM,MAAM,GAAI,CAAC,EAAE,OAAO,CAAC,KAAG,MAAM,CAAC,CAAC,CAAsB,CAAC"}
1
+ {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/reactive/core.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAKL,KAAK,cAAc,EACpB,MAAM,aAAa,CAAC;AAErB;;;;;;;;GAQG;AACH,qBAAa,MAAM,CAAC,CAAC,CAAE,YAAW,cAAc;IAOlC,OAAO,CAAC,MAAM;IAN1B,OAAO,CAAC,WAAW,CAAyB;IAE5C;;;OAGG;gBACiB,MAAM,EAAE,CAAC;IAE7B;;;OAGG;IACH,IAAI,KAAK,IAAI,CAAC,CAOb;IAED;;;OAGG;IACH,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,EAQhB;IAED;;;;;OAKG;IACH,IAAI,IAAI,CAAC;IAIT;;;;;OAKG;IACH,MAAM,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,GAAG,IAAI;IAIxC;;;;;;;;;;OAUG;IACH,OAAO,IAAI,IAAI;IASf;;;OAGG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI;CAGxC;AAED;;;;;;GAMG;AACH,eAAO,MAAM,MAAM,GAAI,CAAC,EAAE,OAAO,CAAC,KAAG,MAAM,CAAC,CAAC,CAAsB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"effect.d.ts","sourceRoot":"","sources":["../../src/reactive/effect.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAsC,MAAM,aAAa,CAAC;AAE5E;;;;;;;;GAQG;AACH,eAAO,MAAM,MAAM,GAAI,IAAI,MAAM,IAAI,GAAG,SAAS,KAAG,SA2BnD,CAAC"}
1
+ {"version":3,"file":"effect.d.ts","sourceRoot":"","sources":["../../src/reactive/effect.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAsC,MAAM,aAAa,CAAC;AAE5E;;;;;;;;GAQG;AACH,eAAO,MAAM,MAAM,GAAI,IAAI,MAAM,IAAI,GAAG,SAAS,KAAG,SAsCnD,CAAC"}
@@ -28,6 +28,12 @@ export declare const endBatch: () => void;
28
28
  * @internal
29
29
  */
30
30
  export declare const registerDependency: (observer: Observer, source: ReactiveSource) => void;
31
+ /**
32
+ * Removes a specific source from an observer's dependency set.
33
+ * Used when a source (e.g. Signal) is disposed to prevent stale references.
34
+ * @internal
35
+ */
36
+ export declare const removeDependency: (observer: Observer, source: ReactiveSource) => void;
31
37
  /**
32
38
  * Clears all dependencies for an observer, unsubscribing from all sources.
33
39
  * @internal
@@ -1 +1 @@
1
- {"version":3,"file":"internals.d.ts","sourceRoot":"","sources":["../../src/reactive/internals.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC;AAClC,MAAM,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC;AAEnC;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,WAAW,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;CACvC;AASD,eAAO,MAAM,KAAK,GAAI,CAAC,EAAE,UAAU,QAAQ,EAAE,IAAI,MAAM,CAAC,KAAG,CAO1D,CAAC;AAEF,eAAO,MAAM,kBAAkB,QAAO,QAAQ,GAAG,SACR,CAAC;AAE1C;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,GAAI,CAAC,EAAE,IAAI,MAAM,CAAC,KAAG,CAUvD,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,UAAU,QAAQ,KAAG,IAMrD,CAAC;AASF,eAAO,MAAM,UAAU,QAAO,IAE7B,CAAC;AAEF,eAAO,MAAM,QAAQ,QAAO,IAK3B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,GAAI,UAAU,QAAQ,EAAE,QAAQ,cAAc,KAAG,IAO/E,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,iBAAiB,GAAI,UAAU,QAAQ,KAAG,IAQtD,CAAC"}
1
+ {"version":3,"file":"internals.d.ts","sourceRoot":"","sources":["../../src/reactive/internals.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC;AAClC,MAAM,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC;AAEnC;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,WAAW,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;CACvC;AASD,eAAO,MAAM,KAAK,GAAI,CAAC,EAAE,UAAU,QAAQ,EAAE,IAAI,MAAM,CAAC,KAAG,CAO1D,CAAC;AAEF,eAAO,MAAM,kBAAkB,QAAO,QAAQ,GAAG,SACR,CAAC;AAE1C;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,GAAI,CAAC,EAAE,IAAI,MAAM,CAAC,KAAG,CAUvD,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,UAAU,QAAQ,KAAG,IAMrD,CAAC;AAaF,eAAO,MAAM,UAAU,QAAO,IAE7B,CAAC;AAEF,eAAO,MAAM,QAAQ,QAAO,IAM3B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,GAAI,UAAU,QAAQ,EAAE,QAAQ,cAAc,KAAG,IAO/E,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,UAAU,QAAQ,EAAE,QAAQ,cAAc,KAAG,IAK7E,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,iBAAiB,GAAI,UAAU,QAAQ,KAAG,IAQtD,CAAC"}
@@ -1,9 +1,9 @@
1
- import { c as s } from "./core-COenAZjD.js";
2
- import { C as u, S as l, s as m } from "./core-COenAZjD.js";
3
- import { b as d } from "./batch-4LAvfLE7.js";
4
- import { e as g, i as x, a as S } from "./type-guards-DRma3-Kc.js";
5
- import { p as v, r as C, w as b } from "./watch-CXyaBC_9.js";
6
- import { u as w } from "./untrack-BuEQKH7_.js";
1
+ import { c as s } from "./core-BhpuvPhy.js";
2
+ import { C as u, S as l, s as m } from "./core-BhpuvPhy.js";
3
+ import { b as d } from "./batch-x7b2eZST.js";
4
+ import { e as g, i as x, a as S } from "./type-guards-BdKlYYlS.js";
5
+ import { p as v, r as C, w as b } from "./watch-DXXv3iAI.js";
6
+ import { u as w } from "./untrack-DNnnqdlR.js";
7
7
  const p = (a, r) => {
8
8
  const e = s(a);
9
9
  return {
@@ -1,4 +1,4 @@
1
- import { c as N, s as D } from "./core-COenAZjD.js";
1
+ import { c as N, s as D } from "./core-BhpuvPhy.js";
2
2
  let M = null;
3
3
  const w = D({
4
4
  path: "",
@@ -1,4 +1,4 @@
1
- const z = "bquery-sanitizer", v = /* @__PURE__ */ new Set([
1
+ const P = "bquery-sanitizer", N = /* @__PURE__ */ new Set([
2
2
  "a",
3
3
  "abbr",
4
4
  "address",
@@ -101,7 +101,7 @@ const z = "bquery-sanitizer", v = /* @__PURE__ */ new Set([
101
101
  "svg",
102
102
  "foreignobject",
103
103
  "noscript"
104
- ]), N = /* @__PURE__ */ new Set([
104
+ ]), D = /* @__PURE__ */ new Set([
105
105
  // Global objects
106
106
  "document",
107
107
  "window",
@@ -138,7 +138,7 @@ const z = "bquery-sanitizer", v = /* @__PURE__ */ new Set([
138
138
  "innerhtml",
139
139
  "outerhtml",
140
140
  "textcontent"
141
- ]), D = /* @__PURE__ */ new Set([
141
+ ]), F = /* @__PURE__ */ new Set([
142
142
  "alt",
143
143
  "class",
144
144
  "dir",
@@ -159,20 +159,27 @@ const z = "bquery-sanitizer", v = /* @__PURE__ */ new Set([
159
159
  "type",
160
160
  "width",
161
161
  "aria-*"
162
- ]), F = ["on", "formaction", "xlink:", "xmlns:"], O = ["javascript:", "data:", "vbscript:", "file:"], R = (t, e, r) => {
162
+ ]), O = ["on", "formaction", "xlink:", "xmlns:"], R = ["javascript:", "data:", "vbscript:", "file:"], W = (t, e, r) => {
163
163
  const s = t.toLowerCase();
164
- for (const c of F)
164
+ for (const c of O)
165
165
  if (s.startsWith(c)) return !1;
166
166
  return r && s.startsWith("data-") || s.startsWith("aria-") ? !0 : e.has(s);
167
- }, W = (t) => {
167
+ }, U = (t) => {
168
168
  const e = t.toLowerCase().trim();
169
- return !N.has(e);
170
- }, U = (t) => t.replace(/[\u0000-\u001F\u007F]+/g, "").replace(/[\u200B-\u200D\uFEFF\u2028\u2029]+/g, "").replace(/\\u[\da-fA-F]{4}/g, "").replace(/\s+/g, "").toLowerCase(), _ = (t) => {
171
- const e = U(t);
172
- for (const r of O)
169
+ return !D.has(e);
170
+ }, _ = (t) => t.replace(/[\u0000-\u001F\u007F]+/g, "").replace(/[\u200B-\u200D\uFEFF\u2028\u2029]+/g, "").replace(/\\u[\da-fA-F]{4}/g, "").replace(/\s+/g, "").toLowerCase(), E = (t) => {
171
+ const e = _(t);
172
+ for (const r of R)
173
173
  if (e.startsWith(r)) return !1;
174
174
  return !0;
175
175
  }, k = (t) => {
176
+ const e = t.split(",");
177
+ for (const r of e) {
178
+ const s = r.trim().split(/\s+/)[0];
179
+ if (s && !E(s)) return !1;
180
+ }
181
+ return !0;
182
+ }, H = (t) => {
176
183
  try {
177
184
  const e = t.trim();
178
185
  if (e.startsWith("//"))
@@ -182,63 +189,67 @@ const z = "bquery-sanitizer", v = /* @__PURE__ */ new Set([
182
189
  } catch {
183
190
  return !0;
184
191
  }
185
- }, H = (t) => new DOMParser().parseFromString(t, "text/html"), S = (t) => {
192
+ }, z = (t) => new DOMParser().parseFromString(t, "text/html"), S = (t) => {
186
193
  const e = (typeof t == "string" ? t : String(t ?? "")).trim(), r = document.createDocumentFragment();
187
194
  if (e.length === 0)
188
195
  return r;
189
196
  if (!(e.includes("<") || e.includes(">")))
190
197
  return r.appendChild(document.createTextNode(e)), r;
191
- const l = H(e).body;
198
+ const l = z(e).body;
192
199
  if (!l)
193
200
  return r;
194
201
  for (; l.firstChild; )
195
202
  r.appendChild(l.firstChild);
196
203
  return r;
197
- }, E = (t, e = {}) => {
204
+ }, T = (t, e = {}) => {
198
205
  const {
199
206
  allowTags: r = [],
200
207
  allowAttributes: s = [],
201
208
  allowDataAttributes: c = !0,
202
209
  stripAllTags: l = !1
203
- } = e, T = new Set(
204
- [...v, ...r.map((o) => o.toLowerCase())].filter(
210
+ } = e, y = new Set(
211
+ [...N, ...r.map((o) => o.toLowerCase())].filter(
205
212
  (o) => !A.has(o)
206
213
  )
207
214
  ), L = /* @__PURE__ */ new Set([
208
- ...D,
215
+ ...F,
209
216
  ...s.map((o) => o.toLowerCase())
210
- ]), u = S(t);
217
+ ]), d = S(t);
211
218
  if (l)
212
- return u.textContent ?? "";
213
- const p = document.createTreeWalker(u, NodeFilter.SHOW_ELEMENT), f = [];
219
+ return d.textContent ?? "";
220
+ const p = document.createTreeWalker(d, NodeFilter.SHOW_ELEMENT), f = [];
214
221
  for (; p.nextNode(); ) {
215
222
  const o = p.currentNode, i = o.tagName.toLowerCase();
216
223
  if (A.has(i)) {
217
224
  f.push(o);
218
225
  continue;
219
226
  }
220
- if (!T.has(i)) {
227
+ if (!y.has(i)) {
221
228
  f.push(o);
222
229
  continue;
223
230
  }
224
- const d = [];
231
+ const u = [];
225
232
  for (const n of Array.from(o.attributes)) {
226
233
  const a = n.name.toLowerCase();
227
- if (!R(a, L, c)) {
228
- d.push(n.name);
234
+ if (!W(a, L, c)) {
235
+ u.push(n.name);
236
+ continue;
237
+ }
238
+ if ((a === "id" || a === "name") && !U(n.value)) {
239
+ u.push(n.name);
229
240
  continue;
230
241
  }
231
- if ((a === "id" || a === "name") && !W(n.value)) {
232
- d.push(n.name);
242
+ if ((a === "href" || a === "src" || a === "action") && !E(n.value)) {
243
+ u.push(n.name);
233
244
  continue;
234
245
  }
235
- (a === "href" || a === "src" || a === "srcset") && !_(n.value) && d.push(n.name);
246
+ a === "srcset" && !k(n.value) && u.push(n.name);
236
247
  }
237
- for (const n of d)
248
+ for (const n of u)
238
249
  o.removeAttribute(n);
239
250
  if (i === "a") {
240
- const n = o.getAttribute("href"), y = o.getAttribute("target")?.toLowerCase() === "_blank", C = n && k(n);
241
- if (y || C) {
251
+ const n = o.getAttribute("href"), C = o.getAttribute("target")?.toLowerCase() === "_blank", v = n && H(n);
252
+ if (C || v) {
242
253
  const b = o.getAttribute("rel"), m = new Set(b ? b.split(/\s+/).filter(Boolean) : []);
243
254
  m.add("noopener"), m.add("noreferrer"), o.setAttribute("rel", Array.from(m).join(" "));
244
255
  }
@@ -249,9 +260,9 @@ const z = "bquery-sanitizer", v = /* @__PURE__ */ new Set([
249
260
  const h = (o) => {
250
261
  const i = document.createElement("div");
251
262
  return i.appendChild(o.cloneNode(!0)), i.innerHTML;
252
- }, g = h(u), x = S(g), w = h(x);
253
- return g !== w ? u.textContent ?? "" : w;
254
- }, P = (t, e = {}) => E(t, e), j = (t) => {
263
+ }, g = h(d), x = S(g), w = h(x);
264
+ return g !== w ? d.textContent ?? "" : w;
265
+ }, j = (t, e = {}) => T(t, e), G = (t) => {
255
266
  const e = {
256
267
  "&": "&amp;",
257
268
  "<": "&lt;",
@@ -261,12 +272,12 @@ const z = "bquery-sanitizer", v = /* @__PURE__ */ new Set([
261
272
  "`": "&#x60;"
262
273
  };
263
274
  return t.replace(/[&<>"'`]/g, (r) => e[r]);
264
- }, G = (t) => E(t, { stripAllTags: !0 });
275
+ }, I = (t) => T(t, { stripAllTags: !0 });
265
276
  export {
266
- z as P,
267
- G as a,
268
- E as b,
269
- j as e,
270
- P as s
277
+ P,
278
+ I as a,
279
+ T as b,
280
+ G as e,
281
+ j as s
271
282
  };
272
- //# sourceMappingURL=sanitize-1FBEPAFH.js.map
283
+ //# sourceMappingURL=sanitize-Cxvxa-DX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitize-Cxvxa-DX.js","sources":["../src/security/constants.ts","../src/security/sanitize-core.ts","../src/security/sanitize.ts"],"sourcesContent":["/**\n * Security constants and safe lists.\n *\n * @module bquery/security\n */\n\n/**\n * Trusted Types policy name.\n */\nexport const POLICY_NAME = 'bquery-sanitizer';\n\n/**\n * Default allowed HTML tags considered safe.\n */\nexport const DEFAULT_ALLOWED_TAGS = new Set([\n 'a',\n 'abbr',\n 'address',\n 'article',\n 'aside',\n 'b',\n 'bdi',\n 'bdo',\n 'blockquote',\n 'br',\n 'button',\n 'caption',\n 'cite',\n 'code',\n 'col',\n 'colgroup',\n 'data',\n 'dd',\n 'del',\n 'details',\n 'dfn',\n 'div',\n 'dl',\n 'dt',\n 'em',\n 'figcaption',\n 'figure',\n 'footer',\n 'form',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'header',\n 'hgroup',\n 'hr',\n 'i',\n 'img',\n 'input',\n 'ins',\n 'kbd',\n 'label',\n 'legend',\n 'li',\n 'main',\n 'mark',\n 'nav',\n 'ol',\n 'optgroup',\n 'option',\n 'p',\n 'picture',\n 'pre',\n 'progress',\n 'q',\n 'rp',\n 'rt',\n 'ruby',\n 's',\n 'samp',\n 'section',\n 'select',\n 'small',\n 'source',\n 'span',\n 'strong',\n 'sub',\n 'summary',\n 'sup',\n 'table',\n 'tbody',\n 'td',\n 'textarea',\n 'tfoot',\n 'th',\n 'thead',\n 'time',\n 'tr',\n 'u',\n 'ul',\n 'var',\n 'wbr',\n]);\n\n/**\n * Explicitly dangerous tags that should never be allowed.\n * These are checked even if somehow added to allowTags.\n */\nexport const DANGEROUS_TAGS = new Set([\n 'script',\n 'iframe',\n 'frame',\n 'frameset',\n 'object',\n 'embed',\n 'applet',\n 'link',\n 'meta',\n 'style',\n 'base',\n 'template',\n 'slot',\n 'math',\n 'svg',\n 'foreignobject',\n 'noscript',\n]);\n\n/**\n * Reserved IDs that could cause DOM clobbering attacks.\n * These are prevented to avoid overwriting global browser objects.\n */\nexport const RESERVED_IDS = new Set([\n // Global objects\n 'document',\n 'window',\n 'location',\n 'top',\n 'self',\n 'parent',\n 'frames',\n 'history',\n 'navigator',\n 'screen',\n // Dangerous functions\n 'alert',\n 'confirm',\n 'prompt',\n 'eval',\n 'function',\n // Document properties\n 'cookie',\n 'domain',\n 'referrer',\n 'body',\n 'head',\n 'forms',\n 'images',\n 'links',\n 'scripts',\n // DOM traversal properties\n 'children',\n 'parentnode',\n 'firstchild',\n 'lastchild',\n // Content manipulation\n 'innerhtml',\n 'outerhtml',\n 'textcontent',\n]);\n\n/**\n * Default allowed attributes considered safe.\n * Note: 'style' is excluded by default because inline CSS can be abused for:\n * - UI redressing attacks\n * - Data exfiltration via url() in CSS\n * - CSS injection vectors\n * If you need to allow inline styles, add 'style' to allowAttributes in your\n * sanitizeHtml options, but ensure you implement proper CSS value validation.\n */\nexport const DEFAULT_ALLOWED_ATTRIBUTES = new Set([\n 'alt',\n 'class',\n 'dir',\n 'height',\n 'hidden',\n 'href',\n 'id',\n 'lang',\n 'loading',\n 'name',\n 'rel',\n 'role',\n 'src',\n 'srcset',\n 'tabindex',\n 'target',\n 'title',\n 'type',\n 'width',\n 'aria-*',\n]);\n\n/**\n * Dangerous attribute prefixes to always remove.\n */\nexport const DANGEROUS_ATTR_PREFIXES = ['on', 'formaction', 'xlink:', 'xmlns:'];\n\n/**\n * Dangerous URL protocols to block.\n */\nexport const DANGEROUS_PROTOCOLS = ['javascript:', 'data:', 'vbscript:', 'file:'];\n","/**\r\n * Core HTML sanitization logic.\r\n *\r\n * @module bquery/security\r\n * @internal\r\n */\r\n\r\nimport {\r\n DANGEROUS_ATTR_PREFIXES,\r\n DANGEROUS_PROTOCOLS,\r\n DANGEROUS_TAGS,\r\n DEFAULT_ALLOWED_ATTRIBUTES,\r\n DEFAULT_ALLOWED_TAGS,\r\n RESERVED_IDS,\r\n} from './constants';\r\nimport type { SanitizeOptions } from './types';\r\n\r\n/**\r\n * Check if an attribute name is allowed.\r\n * @internal\r\n */\r\nconst isAllowedAttribute = (\r\n name: string,\r\n allowedSet: Set<string>,\r\n allowDataAttrs: boolean\r\n): boolean => {\r\n const lowerName = name.toLowerCase();\r\n\r\n // Check dangerous prefixes\r\n for (const prefix of DANGEROUS_ATTR_PREFIXES) {\r\n if (lowerName.startsWith(prefix)) return false;\r\n }\r\n\r\n // Check data attributes\r\n if (allowDataAttrs && lowerName.startsWith('data-')) return true;\r\n\r\n // Check aria attributes (allowed by default)\r\n if (lowerName.startsWith('aria-')) return true;\r\n\r\n // Check explicit allow list\r\n return allowedSet.has(lowerName);\r\n};\r\n\r\n/**\r\n * Check if an ID/name value could cause DOM clobbering.\r\n * @internal\r\n */\r\nconst isSafeIdOrName = (value: string): boolean => {\r\n const lowerValue = value.toLowerCase().trim();\r\n return !RESERVED_IDS.has(lowerValue);\r\n};\r\n\r\n/**\r\n * Normalize URL by removing control characters, whitespace, and Unicode tricks.\r\n * Enhanced to prevent various bypass techniques.\r\n * @internal\r\n */\r\nconst normalizeUrl = (value: string): string =>\r\n value\r\n // Remove null bytes and control characters\r\n .replace(/[\\u0000-\\u001F\\u007F]+/g, '')\r\n // Remove zero-width characters that could hide malicious content\r\n .replace(/[\\u200B-\\u200D\\uFEFF\\u2028\\u2029]+/g, '')\r\n // Remove escaped Unicode sequences\r\n .replace(/\\\\u[\\da-fA-F]{4}/g, '')\r\n // Remove whitespace\r\n .replace(/\\s+/g, '')\r\n // Normalize case\r\n .toLowerCase();\r\n\r\n/**\r\n * Check if a URL value is safe.\r\n * @internal\r\n */\r\nconst isSafeUrl = (value: string): boolean => {\r\n const normalized = normalizeUrl(value);\r\n for (const protocol of DANGEROUS_PROTOCOLS) {\r\n if (normalized.startsWith(protocol)) return false;\r\n }\r\n return true;\r\n};\r\n\r\n/**\r\n * Check if a srcset attribute value is safe.\r\n * srcset contains comma-separated entries of \"url [descriptor]\".\r\n * Each individual URL must be validated.\r\n * @internal\r\n */\r\nconst isSafeSrcset = (value: string): boolean => {\r\n const entries = value.split(',');\r\n for (const entry of entries) {\r\n const url = entry.trim().split(/\\s+/)[0];\r\n if (url && !isSafeUrl(url)) return false;\r\n }\r\n return true;\r\n};\r\n\r\n/**\r\n * Check if a URL is external (different origin).\r\n * @internal\r\n */\r\nconst isExternalUrl = (url: string): boolean => {\r\n try {\r\n // Normalize URL by trimming whitespace\r\n const trimmedUrl = url.trim();\r\n\r\n // Protocol-relative URLs (//example.com) are always external.\r\n // CRITICAL: This check must run before the relative-URL check below;\r\n // otherwise, a protocol-relative URL like \"//evil.com\" would be treated\r\n // as a non-http(s) relative URL and incorrectly classified as same-origin.\r\n // Handling them up front guarantees correct security classification.\r\n if (trimmedUrl.startsWith('//')) {\r\n return true;\r\n }\r\n\r\n // Normalize URL for case-insensitive protocol checks\r\n const lowerUrl = trimmedUrl.toLowerCase();\r\n\r\n // Check for non-http(s) protocols which are considered external/special\r\n // (mailto:, tel:, ftp:, etc.)\r\n const hasProtocol = /^[a-z][a-z0-9+.-]*:/i.test(trimmedUrl);\r\n if (hasProtocol && !lowerUrl.startsWith('http://') && !lowerUrl.startsWith('https://')) {\r\n // These are special protocols, not traditional \"external\" links\r\n // but we treat them as external for security consistency\r\n return true;\r\n }\r\n\r\n // Relative URLs are not external\r\n if (!lowerUrl.startsWith('http://') && !lowerUrl.startsWith('https://')) {\r\n return false;\r\n }\r\n\r\n // In non-browser environments (e.g., Node.js), treat all absolute URLs as external\r\n if (typeof window === 'undefined' || !window.location) {\r\n return true;\r\n }\r\n\r\n const urlObj = new URL(trimmedUrl, window.location.href);\r\n return urlObj.origin !== window.location.origin;\r\n } catch {\r\n // If URL parsing fails, treat as potentially external for safety\r\n return true;\r\n }\r\n};\r\n\r\n/**\r\n * Parse an HTML string into a Document using DOMParser.\r\n * This helper is intentionally separated to make the control-flow around HTML parsing\r\n * explicit for static analysis tools. It should ONLY be called when the input is\r\n * known to contain HTML syntax (angle brackets).\r\n *\r\n * DOMParser creates an inert document where scripts don't execute, making it safe\r\n * for parsing untrusted HTML that will subsequently be sanitized.\r\n *\r\n * @param htmlContent - A string that is known to contain HTML markup (has < or >)\r\n * @returns The parsed Document\r\n * @internal\r\n */\r\nconst parseHtmlDocument = (htmlContent: string): Document => {\r\n const parser = new DOMParser();\r\n // Parse as a full HTML document in an inert context; scripts won't execute\r\n return parser.parseFromString(htmlContent, 'text/html');\r\n};\r\n\r\n/**\r\n * Safely parse HTML string into a DocumentFragment using DOMParser.\r\n * DOMParser is preferred over innerHTML for security as it creates an inert document\r\n * where scripts don't execute and provides better static analysis recognition.\r\n *\r\n * This function includes input normalization to satisfy static analysis tools:\r\n * - Coerces input to string and trims whitespace\r\n * - For plain text (no HTML tags), creates a Text node directly without parsing\r\n * - Only invokes DOMParser for actual HTML-like content via parseHtmlDocument\r\n *\r\n * The separation between plain text handling and HTML parsing is intentional:\r\n * DOM text that contains no HTML syntax is never fed into an HTML parser,\r\n * preventing \"DOM text reinterpreted as HTML\" issues.\r\n *\r\n * @internal\r\n */\r\nconst parseHtmlSafely = (html: string): DocumentFragment => {\r\n // Step 1: Normalize input - coerce to string and trim\r\n // This defensive check handles edge cases even though TypeScript says it's a string\r\n const normalizedHtml = (typeof html === 'string' ? html : String(html ?? '')).trim();\r\n\r\n // Step 2: Create the fragment that will hold our result\r\n const fragment = document.createDocumentFragment();\r\n\r\n // Step 3: Early return for empty input\r\n if (normalizedHtml.length === 0) {\r\n return fragment;\r\n }\r\n\r\n // Step 4: If input contains no angle brackets, it's plain text - no HTML parsing needed.\r\n // Plain text is handled as a Text node, never passed to an HTML parser.\r\n // This explicitly prevents \"DOM text reinterpreted as HTML\" for purely textual inputs.\r\n const containsHtmlSyntax = normalizedHtml.includes('<') || normalizedHtml.includes('>');\r\n if (!containsHtmlSyntax) {\r\n fragment.appendChild(document.createTextNode(normalizedHtml));\r\n return fragment;\r\n }\r\n\r\n // Step 5: Input contains HTML syntax - parse it via the dedicated HTML parsing helper.\r\n // This separation makes the data-flow explicit: only strings with HTML syntax\r\n // are passed to DOMParser, satisfying static analysis requirements.\r\n const doc = parseHtmlDocument(normalizedHtml);\r\n\r\n // Move all children from the document body into the fragment.\r\n // This avoids interpolating untrusted HTML into an outer wrapper string.\r\n const body = doc.body;\r\n\r\n if (!body) {\r\n return fragment;\r\n }\r\n\r\n while (body.firstChild) {\r\n fragment.appendChild(body.firstChild);\r\n }\r\n\r\n return fragment;\r\n};\r\n\r\n/**\r\n * Core sanitization logic (without Trusted Types wrapper).\r\n * @internal\r\n */\r\nexport const sanitizeHtmlCore = (html: string, options: SanitizeOptions = {}): string => {\r\n const {\r\n allowTags = [],\r\n allowAttributes = [],\r\n allowDataAttributes = true,\r\n stripAllTags = false,\r\n } = options;\r\n\r\n // Build combined allow sets (excluding dangerous tags even if specified)\r\n const allowedTags = new Set(\r\n [...DEFAULT_ALLOWED_TAGS, ...allowTags.map((t) => t.toLowerCase())].filter(\r\n (tag) => !DANGEROUS_TAGS.has(tag)\r\n )\r\n );\r\n const allowedAttrs = new Set([\r\n ...DEFAULT_ALLOWED_ATTRIBUTES,\r\n ...allowAttributes.map((a) => a.toLowerCase()),\r\n ]);\r\n\r\n // Use DOMParser for safe HTML parsing (inert context, no script execution)\r\n const fragment = parseHtmlSafely(html);\r\n\r\n if (stripAllTags) {\r\n return fragment.textContent ?? '';\r\n }\r\n\r\n // Walk the DOM tree\r\n const walker = document.createTreeWalker(fragment, NodeFilter.SHOW_ELEMENT);\r\n\r\n const toRemove: Element[] = [];\r\n\r\n while (walker.nextNode()) {\r\n const el = walker.currentNode as Element;\r\n const tagName = el.tagName.toLowerCase();\r\n\r\n // Remove explicitly dangerous tags even if in allow list\r\n if (DANGEROUS_TAGS.has(tagName)) {\r\n toRemove.push(el);\r\n continue;\r\n }\r\n\r\n // Remove disallowed tags entirely\r\n if (!allowedTags.has(tagName)) {\r\n toRemove.push(el);\r\n continue;\r\n }\r\n\r\n // Process attributes\r\n const attrsToRemove: string[] = [];\r\n for (const attr of Array.from(el.attributes)) {\r\n const attrName = attr.name.toLowerCase();\r\n\r\n // Check if attribute is allowed\r\n if (!isAllowedAttribute(attrName, allowedAttrs, allowDataAttributes)) {\r\n attrsToRemove.push(attr.name);\r\n continue;\r\n }\r\n\r\n // Check for DOM clobbering on id and name attributes\r\n if ((attrName === 'id' || attrName === 'name') && !isSafeIdOrName(attr.value)) {\r\n attrsToRemove.push(attr.name);\r\n continue;\r\n }\r\n\r\n // Validate URL attributes\r\n if (\r\n (attrName === 'href' || attrName === 'src' || attrName === 'action') &&\r\n !isSafeUrl(attr.value)\r\n ) {\r\n attrsToRemove.push(attr.name);\r\n continue;\r\n }\r\n\r\n // Validate srcset URLs individually\r\n if (attrName === 'srcset' && !isSafeSrcset(attr.value)) {\r\n attrsToRemove.push(attr.name);\r\n }\r\n }\r\n\r\n // Remove disallowed attributes\r\n for (const attrName of attrsToRemove) {\r\n el.removeAttribute(attrName);\r\n }\r\n\r\n // Add rel=\"noopener noreferrer\" to external links for security\r\n if (tagName === 'a') {\r\n const href = el.getAttribute('href');\r\n const target = el.getAttribute('target');\r\n const hasTargetBlank = target?.toLowerCase() === '_blank';\r\n const isExternal = href && isExternalUrl(href);\r\n\r\n // Add security attributes to links opening in new window or external links\r\n if (hasTargetBlank || isExternal) {\r\n const existingRel = el.getAttribute('rel');\r\n const relValues = new Set(existingRel ? existingRel.split(/\\s+/).filter(Boolean) : []);\r\n\r\n // Add noopener and noreferrer\r\n relValues.add('noopener');\r\n relValues.add('noreferrer');\r\n\r\n el.setAttribute('rel', Array.from(relValues).join(' '));\r\n }\r\n }\r\n }\r\n\r\n // Remove disallowed elements\r\n for (const el of toRemove) {\r\n el.remove();\r\n }\r\n\r\n // Serialize the sanitized fragment to HTML string.\r\n // We use a temporary container to get the innerHTML of the fragment.\r\n const serializeFragment = (frag: DocumentFragment): string => {\r\n const container = document.createElement('div');\r\n container.appendChild(frag.cloneNode(true));\r\n return container.innerHTML;\r\n };\r\n\r\n // Double-parse to prevent mutation XSS (mXSS).\r\n // Browsers may normalize HTML during serialization in ways that could create\r\n // new dangerous content when re-parsed. By re-parsing the sanitized output\r\n // and verifying stability, we ensure the final HTML is safe.\r\n const firstPass = serializeFragment(fragment);\r\n\r\n // Re-parse through DOMParser for mXSS detection.\r\n // Using DOMParser instead of innerHTML for security.\r\n const verifyFragment = parseHtmlSafely(firstPass);\r\n const secondPass = serializeFragment(verifyFragment);\r\n\r\n // Verify stability: if content mutates between parses, it indicates mXSS attempt\r\n if (firstPass !== secondPass) {\r\n // Content mutated during re-parse - potential mXSS detected.\r\n // Return safely escaped text content as fallback.\r\n return fragment.textContent ?? '';\r\n }\r\n\r\n return secondPass;\r\n};\r\n","/**\n * Security utilities for HTML sanitization.\n * All DOM writes are sanitized by default to prevent XSS attacks.\n *\n * @module bquery/security\n */\n\nimport { sanitizeHtmlCore } from './sanitize-core';\nimport type { SanitizeOptions } from './types';\nexport { generateNonce } from './csp';\nexport { isTrustedTypesSupported } from './trusted-types';\n\n/**\n * Sanitize HTML string, removing dangerous elements and attributes.\n * Uses Trusted Types when available for CSP compliance.\n *\n * @param html - The HTML string to sanitize\n * @param options - Sanitization options\n * @returns Sanitized HTML string\n *\n * @example\n * ```ts\n * const safe = sanitizeHtml('<div onclick=\"alert(1)\">Hello</div>');\n * // Returns: '<div>Hello</div>'\n * ```\n */\nexport const sanitizeHtml = (html: string, options: SanitizeOptions = {}): string => {\n return sanitizeHtmlCore(html, options);\n};\n\n/**\n * Escape HTML entities to prevent XSS.\n * Use this for displaying user content as text.\n *\n * @param text - The text to escape\n * @returns Escaped HTML string\n *\n * @example\n * ```ts\n * escapeHtml('<script>alert(1)</script>');\n * // Returns: '&lt;script&gt;alert(1)&lt;/script&gt;'\n * ```\n */\nexport const escapeHtml = (text: string): string => {\n const escapeMap: Record<string, string> = {\n '&': '&amp;',\n '<': '&lt;',\n '>': '&gt;',\n '\"': '&quot;',\n \"'\": '&#x27;',\n '`': '&#x60;',\n };\n return text.replace(/[&<>\"'`]/g, (char) => escapeMap[char]);\n};\n\n/**\n * Strip all HTML tags and return plain text.\n *\n * @param html - The HTML string to strip\n * @returns Plain text content\n */\nexport const stripTags = (html: string): string => {\n return sanitizeHtmlCore(html, { stripAllTags: true });\n};\n\nexport type { SanitizeOptions } from './types';\n"],"names":["POLICY_NAME","DEFAULT_ALLOWED_TAGS","DANGEROUS_TAGS","RESERVED_IDS","DEFAULT_ALLOWED_ATTRIBUTES","DANGEROUS_ATTR_PREFIXES","DANGEROUS_PROTOCOLS","isAllowedAttribute","name","allowedSet","allowDataAttrs","lowerName","prefix","isSafeIdOrName","value","lowerValue","normalizeUrl","isSafeUrl","normalized","protocol","isSafeSrcset","entries","entry","url","isExternalUrl","trimmedUrl","lowerUrl","parseHtmlDocument","htmlContent","parseHtmlSafely","html","normalizedHtml","fragment","body","sanitizeHtmlCore","options","allowTags","allowAttributes","allowDataAttributes","stripAllTags","allowedTags","t","tag","allowedAttrs","a","walker","toRemove","el","tagName","attrsToRemove","attr","attrName","href","hasTargetBlank","isExternal","existingRel","relValues","serializeFragment","frag","container","firstPass","verifyFragment","secondPass","sanitizeHtml","escapeHtml","text","escapeMap","char","stripTags"],"mappings":"AASO,MAAMA,IAAc,oBAKdC,wBAA2B,IAAI;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC,GAMYC,wBAAqB,IAAI;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC,GAMYC,wBAAmB,IAAI;AAAA;AAAA,EAElC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;A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"}
@@ -1 +1 @@
1
- {"version":3,"file":"sanitize-core.d.ts","sourceRoot":"","sources":["../../src/security/sanitize-core.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAgM/C;;;GAGG;AACH,eAAO,MAAM,gBAAgB,GAAI,MAAM,MAAM,EAAE,UAAS,eAAoB,KAAG,MAmI9E,CAAC"}
1
+ {"version":3,"file":"sanitize-core.d.ts","sourceRoot":"","sources":["../../src/security/sanitize-core.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAUH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AA+M/C;;;GAGG;AACH,eAAO,MAAM,gBAAgB,GAAI,MAAM,MAAM,EAAE,UAAS,eAAoB,KAAG,MAyI9E,CAAC"}
@@ -1,5 +1,5 @@
1
- import { b as u, P as i } from "./sanitize-1FBEPAFH.js";
2
- import { e as h, s as b, s as N, a as C } from "./sanitize-1FBEPAFH.js";
1
+ import { b as u, P as i } from "./sanitize-Cxvxa-DX.js";
2
+ import { e as h, s as b, s as N, a as C } from "./sanitize-Cxvxa-DX.js";
3
3
  const s = 1024, a = 8192, p = (t = 16) => {
4
4
  if (!Number.isInteger(t) || t < 1)
5
5
  throw new RangeError("generateNonce length must be a positive integer");
package/dist/store.es.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { h as c, g as m, a as S, f as p } from "./persisted-Dz_ryNuC.js";
2
- import { c as h, d as q, l as v, m as x, e as P, b as $, r as j } from "./persisted-Dz_ryNuC.js";
1
+ import { h as c, g as m, a as S, f as p } from "./persisted-DHoi3uEs.js";
2
+ import { c as h, d as q, l as v, m as x, e as P, b as $, r as j } from "./persisted-DHoi3uEs.js";
3
3
  const d = (e, t) => () => c(e) ? m(e) : S({ id: e, ...t }), g = (e, t, o, s = {}) => {
4
4
  const i = s.equals ?? (s.deep ? p : Object.is);
5
5
  let r = t(e.$state);
@@ -0,0 +1,32 @@
1
+ import { a, t as c, C as i, S as f } from "./core-BhpuvPhy.js";
2
+ const u = (e) => {
3
+ let r, n = !1;
4
+ const s = () => {
5
+ if (r) {
6
+ try {
7
+ r();
8
+ } catch (o) {
9
+ console.error("bQuery reactive: Error in effect cleanup", o);
10
+ }
11
+ r = void 0;
12
+ }
13
+ }, t = () => {
14
+ if (!n) {
15
+ s(), a(t);
16
+ try {
17
+ r = c(t, e);
18
+ } catch (o) {
19
+ console.error("bQuery reactive: Error in effect", o);
20
+ }
21
+ }
22
+ };
23
+ return t(), () => {
24
+ n = !0, s(), a(t);
25
+ };
26
+ }, p = (e) => e instanceof f, d = (e) => e instanceof i;
27
+ export {
28
+ p as a,
29
+ u as e,
30
+ d as i
31
+ };
32
+ //# sourceMappingURL=type-guards-BdKlYYlS.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"type-guards-BdKlYYlS.js","sources":["../src/reactive/effect.ts","../src/reactive/type-guards.ts"],"sourcesContent":["/**\r\n * Reactive effects.\r\n */\r\n\r\nimport { CleanupFn, Observer, track, clearDependencies } from './internals';\r\n\r\n/**\r\n * Creates a side effect that automatically re-runs when dependencies change.\r\n *\r\n * The effect runs immediately upon creation and then re-runs whenever\r\n * any signal or computed value read inside it changes.\r\n *\r\n * @param fn - The effect function to run\r\n * @returns A cleanup function to stop the effect\r\n */\r\nexport const effect = (fn: () => void | CleanupFn): CleanupFn => {\r\n let cleanupFn: CleanupFn | void;\r\n let isDisposed = false;\r\n\r\n const runCleanup = (): void => {\r\n if (cleanupFn) {\r\n try {\r\n cleanupFn();\r\n } catch (error) {\r\n console.error('bQuery reactive: Error in effect cleanup', error);\r\n }\r\n cleanupFn = undefined;\r\n }\r\n };\r\n\r\n const observer: Observer = () => {\r\n if (isDisposed) return;\r\n\r\n runCleanup();\r\n\r\n // Clear old dependencies before running to avoid stale subscriptions\r\n clearDependencies(observer);\r\n\r\n try {\r\n cleanupFn = track(observer, fn);\r\n } catch (error) {\r\n console.error('bQuery reactive: Error in effect', error);\r\n }\r\n };\r\n\r\n observer();\r\n\r\n return () => {\r\n isDisposed = true;\r\n runCleanup();\r\n // Clean up all dependencies when effect is disposed\r\n clearDependencies(observer);\r\n };\r\n};\r\n","/**\n * Type guards for reactive primitives.\n */\n\nimport { Computed } from './computed';\nimport { Signal } from './core';\n\n/**\n * Type guard to check if a value is a Signal instance.\n *\n * @param value - The value to check\n * @returns True if the value is a Signal\n */\nexport const isSignal = (value: unknown): value is Signal<unknown> => value instanceof Signal;\n\n/**\n * Type guard to check if a value is a Computed instance.\n *\n * @param value - The value to check\n * @returns True if the value is a Computed\n */\nexport const isComputed = (value: unknown): value is Computed<unknown> => value instanceof Computed;\n"],"names":["effect","fn","cleanupFn","isDisposed","runCleanup","error","observer","clearDependencies","track","isSignal","value","Signal","isComputed","Computed"],"mappings":";AAeO,MAAMA,IAAS,CAACC,MAA0C;AAC/D,MAAIC,GACAC,IAAa;AAEjB,QAAMC,IAAa,MAAY;AAC7B,QAAIF,GAAW;AACb,UAAI;AACF,QAAAA,EAAA;AAAA,MACF,SAASG,GAAO;AACd,gBAAQ,MAAM,4CAA4CA,CAAK;AAAA,MACjE;AACA,MAAAH,IAAY;AAAA,IACd;AAAA,EACF,GAEMI,IAAqB,MAAM;AAC/B,QAAI,CAAAH,GAEJ;AAAA,MAAAC,EAAA,GAGAG,EAAkBD,CAAQ;AAE1B,UAAI;AACF,QAAAJ,IAAYM,EAAMF,GAAUL,CAAE;AAAA,MAChC,SAASI,GAAO;AACd,gBAAQ,MAAM,oCAAoCA,CAAK;AAAA,MACzD;AAAA;AAAA,EACF;AAEA,SAAAC,EAAA,GAEO,MAAM;AACX,IAAAH,IAAa,IACbC,EAAA,GAEAG,EAAkBD,CAAQ;AAAA,EAC5B;AACF,GCxCaG,IAAW,CAACC,MAA6CA,aAAiBC,GAQ1EC,IAAa,CAACF,MAA+CA,aAAiBG;"}
@@ -0,0 +1,6 @@
1
+ import { w as t } from "./core-BhpuvPhy.js";
2
+ const e = (r) => t(r);
3
+ export {
4
+ e as u
5
+ };
6
+ //# sourceMappingURL=untrack-DNnnqdlR.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"untrack-BuEQKH7_.js","sources":["../src/reactive/untrack.ts"],"sourcesContent":["/**\n * Dependency tracking control helpers.\n */\n\nimport { withoutCurrentObserver } from './internals';\n\n/**\n * Executes a function without tracking any signal dependencies.\n * Useful when reading a signal value without creating a reactive dependency.\n *\n * This implementation temporarily hides the current observer rather than\n * disabling tracking globally. This ensures that nested reactive internals\n * (e.g., computed recomputation triggered during untrack) can still properly\n * track their own dependencies.\n *\n * @template T - The return type of the function\n * @param fn - The function to execute without tracking\n * @returns The result of the function\n *\n * @example\n * ```ts\n * const count = signal(0);\n * effect(() => {\n * // This read creates a dependency\n * console.log(count.value);\n * // This read does not create a dependency\n * const snapshot = untrack(() => count.value);\n * });\n * ```\n */\nexport const untrack = <T>(fn: () => T): T => withoutCurrentObserver(fn);\n"],"names":["untrack","fn","withoutCurrentObserver"],"mappings":";AA8BO,MAAMA,IAAU,CAAIC,MAAmBC,EAAuBD,CAAE;"}
1
+ {"version":3,"file":"untrack-DNnnqdlR.js","sources":["../src/reactive/untrack.ts"],"sourcesContent":["/**\n * Dependency tracking control helpers.\n */\n\nimport { withoutCurrentObserver } from './internals';\n\n/**\n * Executes a function without tracking any signal dependencies.\n * Useful when reading a signal value without creating a reactive dependency.\n *\n * This implementation temporarily hides the current observer rather than\n * disabling tracking globally. This ensures that nested reactive internals\n * (e.g., computed recomputation triggered during untrack) can still properly\n * track their own dependencies.\n *\n * @template T - The return type of the function\n * @param fn - The function to execute without tracking\n * @returns The result of the function\n *\n * @example\n * ```ts\n * const count = signal(0);\n * effect(() => {\n * // This read creates a dependency\n * console.log(count.value);\n * // This read does not create a dependency\n * const snapshot = untrack(() => count.value);\n * });\n * ```\n */\nexport const untrack = <T>(fn: () => T): T => withoutCurrentObserver(fn);\n"],"names":["untrack","fn","withoutCurrentObserver"],"mappings":";AA8BO,MAAMA,IAAU,CAAIC,MAAmBC,EAAuBD,CAAE;"}
@@ -1 +1 @@
1
- {"version":3,"file":"evaluate.d.ts","sourceRoot":"","sources":["../../src/view/evaluate.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AA4D9C;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,oBAAoB,QAAO,IAGvC,CAAC;AA8BF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,QAAQ,GAAI,CAAC,GAAG,OAAO,EAAE,YAAY,MAAM,EAAE,SAAS,cAAc,KAAG,CAoBnF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GAAI,CAAC,GAAG,OAAO,EAAE,YAAY,MAAM,EAAE,SAAS,cAAc,KAAG,CAiBtF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,GAAI,YAAY,MAAM,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAqG/E,CAAC"}
1
+ {"version":3,"file":"evaluate.d.ts","sourceRoot":"","sources":["../../src/view/evaluate.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AA4D9C;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,oBAAoB,QAAO,IAGvC,CAAC;AA8BF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,QAAQ,GAAI,CAAC,GAAG,OAAO,EAAE,YAAY,MAAM,EAAE,SAAS,cAAc,KAAG,CAoBnF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GAAI,CAAC,GAAG,OAAO,EAAE,YAAY,MAAM,EAAE,SAAS,cAAc,KAAG,CAiBtF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,GAAI,YAAY,MAAM,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAqH/E,CAAC"}