@bquery/bquery 1.4.0 → 1.6.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 (164) hide show
  1. package/README.md +586 -527
  2. package/dist/component/component.d.ts +13 -5
  3. package/dist/component/component.d.ts.map +1 -1
  4. package/dist/component/html.d.ts +40 -3
  5. package/dist/component/html.d.ts.map +1 -1
  6. package/dist/component/index.d.ts +4 -2
  7. package/dist/component/index.d.ts.map +1 -1
  8. package/dist/component/library.d.ts +34 -0
  9. package/dist/component/library.d.ts.map +1 -0
  10. package/dist/component/types.d.ts +132 -13
  11. package/dist/component/types.d.ts.map +1 -1
  12. package/dist/component-BEQgt5hl.js +600 -0
  13. package/dist/component-BEQgt5hl.js.map +1 -0
  14. package/dist/component.es.mjs +7 -184
  15. package/dist/config-DRmZZno3.js +40 -0
  16. package/dist/config-DRmZZno3.js.map +1 -0
  17. package/dist/core-BGQJVw0-.js +35 -0
  18. package/dist/core-BGQJVw0-.js.map +1 -0
  19. package/dist/core-CCEabVHl.js +648 -0
  20. package/dist/core-CCEabVHl.js.map +1 -0
  21. package/dist/core.es.mjs +45 -1261
  22. package/dist/effect-AFRW_Plg.js +84 -0
  23. package/dist/effect-AFRW_Plg.js.map +1 -0
  24. package/dist/full.d.ts +8 -8
  25. package/dist/full.d.ts.map +1 -1
  26. package/dist/full.es.mjs +101 -91
  27. package/dist/full.iife.js +173 -3
  28. package/dist/full.iife.js.map +1 -1
  29. package/dist/full.umd.js +173 -3
  30. package/dist/full.umd.js.map +1 -1
  31. package/dist/index.es.mjs +147 -139
  32. package/dist/motion/transition.d.ts +1 -1
  33. package/dist/motion/transition.d.ts.map +1 -1
  34. package/dist/motion/types.d.ts +11 -1
  35. package/dist/motion/types.d.ts.map +1 -1
  36. package/dist/motion-D9TcHxOF.js +415 -0
  37. package/dist/motion-D9TcHxOF.js.map +1 -0
  38. package/dist/motion.es.mjs +25 -361
  39. package/dist/object-qGpWr6-J.js +38 -0
  40. package/dist/object-qGpWr6-J.js.map +1 -0
  41. package/dist/platform/announcer.d.ts +59 -0
  42. package/dist/platform/announcer.d.ts.map +1 -0
  43. package/dist/platform/config.d.ts +92 -0
  44. package/dist/platform/config.d.ts.map +1 -0
  45. package/dist/platform/cookies.d.ts +45 -0
  46. package/dist/platform/cookies.d.ts.map +1 -0
  47. package/dist/platform/index.d.ts +8 -0
  48. package/dist/platform/index.d.ts.map +1 -1
  49. package/dist/platform/meta.d.ts +62 -0
  50. package/dist/platform/meta.d.ts.map +1 -0
  51. package/dist/platform-Dr9b6fsq.js +362 -0
  52. package/dist/platform-Dr9b6fsq.js.map +1 -0
  53. package/dist/platform.es.mjs +11 -248
  54. package/dist/reactive/async-data.d.ts +114 -0
  55. package/dist/reactive/async-data.d.ts.map +1 -0
  56. package/dist/reactive/index.d.ts +2 -2
  57. package/dist/reactive/index.d.ts.map +1 -1
  58. package/dist/reactive/signal.d.ts +2 -0
  59. package/dist/reactive/signal.d.ts.map +1 -1
  60. package/dist/reactive-DSkct0dO.js +254 -0
  61. package/dist/reactive-DSkct0dO.js.map +1 -0
  62. package/dist/reactive.es.mjs +18 -32
  63. package/dist/router-CbDhl8rS.js +188 -0
  64. package/dist/router-CbDhl8rS.js.map +1 -0
  65. package/dist/router.es.mjs +11 -200
  66. package/dist/sanitize-Bs2dkMby.js +313 -0
  67. package/dist/sanitize-Bs2dkMby.js.map +1 -0
  68. package/dist/security/constants.d.ts.map +1 -1
  69. package/dist/security/index.d.ts +4 -2
  70. package/dist/security/index.d.ts.map +1 -1
  71. package/dist/security/sanitize.d.ts +4 -1
  72. package/dist/security/sanitize.d.ts.map +1 -1
  73. package/dist/security/trusted-html.d.ts +53 -0
  74. package/dist/security/trusted-html.d.ts.map +1 -0
  75. package/dist/security.es.mjs +11 -56
  76. package/dist/store/define-store.d.ts +1 -1
  77. package/dist/store/define-store.d.ts.map +1 -1
  78. package/dist/store/mapping.d.ts +1 -1
  79. package/dist/store/mapping.d.ts.map +1 -1
  80. package/dist/store/persisted.d.ts +1 -1
  81. package/dist/store/persisted.d.ts.map +1 -1
  82. package/dist/store/types.d.ts +2 -2
  83. package/dist/store/types.d.ts.map +1 -1
  84. package/dist/store/watch.d.ts +1 -1
  85. package/dist/store/watch.d.ts.map +1 -1
  86. package/dist/store-BwDvI45q.js +263 -0
  87. package/dist/store-BwDvI45q.js.map +1 -0
  88. package/dist/store.es.mjs +12 -25
  89. package/dist/storybook/index.d.ts +37 -0
  90. package/dist/storybook/index.d.ts.map +1 -0
  91. package/dist/storybook.es.mjs +151 -0
  92. package/dist/storybook.es.mjs.map +1 -0
  93. package/dist/untrack-B0rVscTc.js +7 -0
  94. package/dist/untrack-B0rVscTc.js.map +1 -0
  95. package/dist/view-C70lA3vf.js +397 -0
  96. package/dist/view-C70lA3vf.js.map +1 -0
  97. package/dist/view.es.mjs +11 -430
  98. package/package.json +141 -132
  99. package/src/component/component.ts +524 -289
  100. package/src/component/html.ts +153 -53
  101. package/src/component/index.ts +50 -40
  102. package/src/component/library.ts +518 -0
  103. package/src/component/types.ts +256 -85
  104. package/src/core/collection.ts +628 -628
  105. package/src/core/element.ts +774 -774
  106. package/src/core/index.ts +48 -48
  107. package/src/core/utils/function.ts +151 -151
  108. package/src/full.ts +229 -187
  109. package/src/motion/animate.ts +113 -113
  110. package/src/motion/flip.ts +176 -176
  111. package/src/motion/scroll.ts +57 -57
  112. package/src/motion/spring.ts +150 -150
  113. package/src/motion/timeline.ts +246 -246
  114. package/src/motion/transition.ts +97 -51
  115. package/src/motion/types.ts +11 -1
  116. package/src/platform/announcer.ts +208 -0
  117. package/src/platform/config.ts +163 -0
  118. package/src/platform/cookies.ts +165 -0
  119. package/src/platform/index.ts +21 -0
  120. package/src/platform/meta.ts +168 -0
  121. package/src/platform/storage.ts +215 -215
  122. package/src/reactive/async-data.ts +486 -0
  123. package/src/reactive/core.ts +114 -114
  124. package/src/reactive/effect.ts +54 -54
  125. package/src/reactive/index.ts +15 -1
  126. package/src/reactive/internals.ts +122 -122
  127. package/src/reactive/signal.ts +9 -0
  128. package/src/security/constants.ts +3 -1
  129. package/src/security/index.ts +17 -10
  130. package/src/security/sanitize-core.ts +364 -364
  131. package/src/security/sanitize.ts +70 -66
  132. package/src/security/trusted-html.ts +71 -0
  133. package/src/store/define-store.ts +49 -48
  134. package/src/store/mapping.ts +74 -73
  135. package/src/store/persisted.ts +62 -61
  136. package/src/store/types.ts +92 -94
  137. package/src/store/watch.ts +53 -52
  138. package/src/storybook/index.ts +479 -0
  139. package/src/view/evaluate.ts +290 -290
  140. package/dist/batch-x7b2eZST.js +0 -13
  141. package/dist/batch-x7b2eZST.js.map +0 -1
  142. package/dist/component.es.mjs.map +0 -1
  143. package/dist/core-BhpuvPhy.js +0 -170
  144. package/dist/core-BhpuvPhy.js.map +0 -1
  145. package/dist/core.es.mjs.map +0 -1
  146. package/dist/full.es.mjs.map +0 -1
  147. package/dist/index.es.mjs.map +0 -1
  148. package/dist/motion.es.mjs.map +0 -1
  149. package/dist/persisted-DHoi3uEs.js +0 -278
  150. package/dist/persisted-DHoi3uEs.js.map +0 -1
  151. package/dist/platform.es.mjs.map +0 -1
  152. package/dist/reactive.es.mjs.map +0 -1
  153. package/dist/router.es.mjs.map +0 -1
  154. package/dist/sanitize-Cxvxa-DX.js +0 -283
  155. package/dist/sanitize-Cxvxa-DX.js.map +0 -1
  156. package/dist/security.es.mjs.map +0 -1
  157. package/dist/store.es.mjs.map +0 -1
  158. package/dist/type-guards-BdKlYYlS.js +0 -32
  159. package/dist/type-guards-BdKlYYlS.js.map +0 -1
  160. package/dist/untrack-DNnnqdlR.js +0 -6
  161. package/dist/untrack-DNnnqdlR.js.map +0 -1
  162. package/dist/view.es.mjs.map +0 -1
  163. package/dist/watch-DXXv3iAI.js +0 -58
  164. package/dist/watch-DXXv3iAI.js.map +0 -1
@@ -1,283 +0,0 @@
1
- const P = "bquery-sanitizer", N = /* @__PURE__ */ new Set([
2
- "a",
3
- "abbr",
4
- "address",
5
- "article",
6
- "aside",
7
- "b",
8
- "bdi",
9
- "bdo",
10
- "blockquote",
11
- "br",
12
- "button",
13
- "caption",
14
- "cite",
15
- "code",
16
- "col",
17
- "colgroup",
18
- "data",
19
- "dd",
20
- "del",
21
- "details",
22
- "dfn",
23
- "div",
24
- "dl",
25
- "dt",
26
- "em",
27
- "figcaption",
28
- "figure",
29
- "footer",
30
- "form",
31
- "h1",
32
- "h2",
33
- "h3",
34
- "h4",
35
- "h5",
36
- "h6",
37
- "header",
38
- "hgroup",
39
- "hr",
40
- "i",
41
- "img",
42
- "input",
43
- "ins",
44
- "kbd",
45
- "label",
46
- "legend",
47
- "li",
48
- "main",
49
- "mark",
50
- "nav",
51
- "ol",
52
- "optgroup",
53
- "option",
54
- "p",
55
- "picture",
56
- "pre",
57
- "progress",
58
- "q",
59
- "rp",
60
- "rt",
61
- "ruby",
62
- "s",
63
- "samp",
64
- "section",
65
- "select",
66
- "small",
67
- "source",
68
- "span",
69
- "strong",
70
- "sub",
71
- "summary",
72
- "sup",
73
- "table",
74
- "tbody",
75
- "td",
76
- "textarea",
77
- "tfoot",
78
- "th",
79
- "thead",
80
- "time",
81
- "tr",
82
- "u",
83
- "ul",
84
- "var",
85
- "wbr"
86
- ]), A = /* @__PURE__ */ new Set([
87
- "script",
88
- "iframe",
89
- "frame",
90
- "frameset",
91
- "object",
92
- "embed",
93
- "applet",
94
- "link",
95
- "meta",
96
- "style",
97
- "base",
98
- "template",
99
- "slot",
100
- "math",
101
- "svg",
102
- "foreignobject",
103
- "noscript"
104
- ]), D = /* @__PURE__ */ new Set([
105
- // Global objects
106
- "document",
107
- "window",
108
- "location",
109
- "top",
110
- "self",
111
- "parent",
112
- "frames",
113
- "history",
114
- "navigator",
115
- "screen",
116
- // Dangerous functions
117
- "alert",
118
- "confirm",
119
- "prompt",
120
- "eval",
121
- "function",
122
- // Document properties
123
- "cookie",
124
- "domain",
125
- "referrer",
126
- "body",
127
- "head",
128
- "forms",
129
- "images",
130
- "links",
131
- "scripts",
132
- // DOM traversal properties
133
- "children",
134
- "parentnode",
135
- "firstchild",
136
- "lastchild",
137
- // Content manipulation
138
- "innerhtml",
139
- "outerhtml",
140
- "textcontent"
141
- ]), F = /* @__PURE__ */ new Set([
142
- "alt",
143
- "class",
144
- "dir",
145
- "height",
146
- "hidden",
147
- "href",
148
- "id",
149
- "lang",
150
- "loading",
151
- "name",
152
- "rel",
153
- "role",
154
- "src",
155
- "srcset",
156
- "tabindex",
157
- "target",
158
- "title",
159
- "type",
160
- "width",
161
- "aria-*"
162
- ]), O = ["on", "formaction", "xlink:", "xmlns:"], R = ["javascript:", "data:", "vbscript:", "file:"], W = (t, e, r) => {
163
- const s = t.toLowerCase();
164
- for (const c of O)
165
- if (s.startsWith(c)) return !1;
166
- return r && s.startsWith("data-") || s.startsWith("aria-") ? !0 : e.has(s);
167
- }, U = (t) => {
168
- const e = t.toLowerCase().trim();
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
- if (e.startsWith(r)) return !1;
174
- return !0;
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) => {
183
- try {
184
- const e = t.trim();
185
- if (e.startsWith("//"))
186
- return !0;
187
- const r = e.toLowerCase();
188
- return /^[a-z][a-z0-9+.-]*:/i.test(e) && !r.startsWith("http://") && !r.startsWith("https://") ? !0 : !r.startsWith("http://") && !r.startsWith("https://") ? !1 : typeof window > "u" || !window.location ? !0 : new URL(e, window.location.href).origin !== window.location.origin;
189
- } catch {
190
- return !0;
191
- }
192
- }, z = (t) => new DOMParser().parseFromString(t, "text/html"), S = (t) => {
193
- const e = (typeof t == "string" ? t : String(t ?? "")).trim(), r = document.createDocumentFragment();
194
- if (e.length === 0)
195
- return r;
196
- if (!(e.includes("<") || e.includes(">")))
197
- return r.appendChild(document.createTextNode(e)), r;
198
- const l = z(e).body;
199
- if (!l)
200
- return r;
201
- for (; l.firstChild; )
202
- r.appendChild(l.firstChild);
203
- return r;
204
- }, T = (t, e = {}) => {
205
- const {
206
- allowTags: r = [],
207
- allowAttributes: s = [],
208
- allowDataAttributes: c = !0,
209
- stripAllTags: l = !1
210
- } = e, y = new Set(
211
- [...N, ...r.map((o) => o.toLowerCase())].filter(
212
- (o) => !A.has(o)
213
- )
214
- ), L = /* @__PURE__ */ new Set([
215
- ...F,
216
- ...s.map((o) => o.toLowerCase())
217
- ]), d = S(t);
218
- if (l)
219
- return d.textContent ?? "";
220
- const p = document.createTreeWalker(d, NodeFilter.SHOW_ELEMENT), f = [];
221
- for (; p.nextNode(); ) {
222
- const o = p.currentNode, i = o.tagName.toLowerCase();
223
- if (A.has(i)) {
224
- f.push(o);
225
- continue;
226
- }
227
- if (!y.has(i)) {
228
- f.push(o);
229
- continue;
230
- }
231
- const u = [];
232
- for (const n of Array.from(o.attributes)) {
233
- const a = n.name.toLowerCase();
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);
240
- continue;
241
- }
242
- if ((a === "href" || a === "src" || a === "action") && !E(n.value)) {
243
- u.push(n.name);
244
- continue;
245
- }
246
- a === "srcset" && !k(n.value) && u.push(n.name);
247
- }
248
- for (const n of u)
249
- o.removeAttribute(n);
250
- if (i === "a") {
251
- const n = o.getAttribute("href"), C = o.getAttribute("target")?.toLowerCase() === "_blank", v = n && H(n);
252
- if (C || v) {
253
- const b = o.getAttribute("rel"), m = new Set(b ? b.split(/\s+/).filter(Boolean) : []);
254
- m.add("noopener"), m.add("noreferrer"), o.setAttribute("rel", Array.from(m).join(" "));
255
- }
256
- }
257
- }
258
- for (const o of f)
259
- o.remove();
260
- const h = (o) => {
261
- const i = document.createElement("div");
262
- return i.appendChild(o.cloneNode(!0)), i.innerHTML;
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) => {
266
- const e = {
267
- "&": "&amp;",
268
- "<": "&lt;",
269
- ">": "&gt;",
270
- '"': "&quot;",
271
- "'": "&#x27;",
272
- "`": "&#x60;"
273
- };
274
- return t.replace(/[&<>"'`]/g, (r) => e[r]);
275
- }, I = (t) => T(t, { stripAllTags: !0 });
276
- export {
277
- P,
278
- I as a,
279
- T as b,
280
- G as e,
281
- j as s
282
- };
283
- //# sourceMappingURL=sanitize-Cxvxa-DX.js.map
@@ -1 +0,0 @@
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 +0,0 @@
1
- {"version":3,"file":"security.es.mjs","sources":["../src/security/csp.ts","../src/security/trusted-types.ts"],"sourcesContent":["/**\n * Content Security Policy helpers.\n *\n * @module bquery/security\n */\n\n/** Maximum allowed nonce length to prevent memory issues */\nconst MAX_NONCE_LENGTH = 1024;\n\n/** Chunk size for building strings to avoid argument limit in String.fromCharCode */\nconst CHUNK_SIZE = 8192;\n\n/**\n * Generate a nonce for inline scripts/styles.\n * Use with Content-Security-Policy nonce directives.\n *\n * @param length - Nonce length in bytes (default: 16, max: 1024)\n * @returns Cryptographically random nonce string\n * @throws {Error} If crypto.getRandomValues or btoa are not available\n * @throws {RangeError} If length is invalid (negative, non-integer, or exceeds maximum)\n */\nexport const generateNonce = (length: number = 16): string => {\n // Validate length parameter\n if (!Number.isInteger(length) || length < 1) {\n throw new RangeError('generateNonce length must be a positive integer');\n }\n if (length > MAX_NONCE_LENGTH) {\n throw new RangeError(`generateNonce length must not exceed ${MAX_NONCE_LENGTH}`);\n }\n\n // Check for required globals in browser/crypto environments\n if (\n typeof globalThis.crypto === 'undefined' ||\n typeof globalThis.crypto.getRandomValues !== 'function'\n ) {\n throw new Error(\n 'generateNonce requires crypto.getRandomValues (not available in this environment)'\n );\n }\n if (typeof globalThis.btoa !== 'function') {\n throw new Error('generateNonce requires btoa (not available in this environment)');\n }\n\n const array = new Uint8Array(length);\n globalThis.crypto.getRandomValues(array);\n\n // Build string in chunks to avoid argument limit in String.fromCharCode\n let binaryString = '';\n for (let i = 0; i < array.length; i += CHUNK_SIZE) {\n const chunk = array.subarray(i, Math.min(i + CHUNK_SIZE, array.length));\n binaryString += String.fromCharCode(...chunk);\n }\n\n return globalThis.btoa(binaryString).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');\n};\n\n/**\n * Check if a CSP header is present with specific directive.\n * Useful for feature detection and fallback strategies.\n *\n * @param directive - The CSP directive to check (e.g., 'script-src')\n * @returns True if the directive appears to be enforced\n */\nexport const hasCSPDirective = (directive: string): boolean => {\n // Guard for non-DOM environments (SSR, tests, etc.)\n if (typeof document === 'undefined') {\n return false;\n }\n\n // Check meta tag\n const meta = document.querySelector('meta[http-equiv=\"Content-Security-Policy\"]');\n if (meta) {\n const content = meta.getAttribute('content') ?? '';\n return content.includes(directive);\n }\n return false;\n};\n","/**\n * Trusted Types helpers for CSP compatibility.\n *\n * @module bquery/security\n */\n\nimport { POLICY_NAME } from './constants';\nimport { sanitizeHtmlCore } from './sanitize-core';\nimport type { TrustedHTML, TrustedTypePolicy, TrustedTypesWindow } from './types';\n\n/** Cached Trusted Types policy */\nlet cachedPolicy: TrustedTypePolicy | null = null;\n\n/** Whether policy initialization has been attempted (to avoid retry spam) */\nlet policyInitAttempted = false;\n\n/**\n * Check if Trusted Types API is available.\n * @returns True if Trusted Types are supported\n */\nexport const isTrustedTypesSupported = (): boolean => {\n return (\n typeof window !== 'undefined' &&\n typeof (window as TrustedTypesWindow).trustedTypes !== 'undefined'\n );\n};\n\n/**\n * Get or create the bQuery Trusted Types policy.\n * @returns The Trusted Types policy or null if unsupported\n */\nexport const getTrustedTypesPolicy = (): TrustedTypePolicy | null => {\n if (cachedPolicy) return cachedPolicy;\n if (policyInitAttempted) return null;\n\n if (typeof window === 'undefined') return null;\n\n const win = window as TrustedTypesWindow;\n if (!win.trustedTypes) return null;\n\n policyInitAttempted = true;\n\n try {\n cachedPolicy = win.trustedTypes.createPolicy(POLICY_NAME, {\n createHTML: (input: string) => sanitizeHtmlCore(input),\n });\n return cachedPolicy;\n } catch (error) {\n // Policy may already exist or be blocked by CSP\n const errorMessage = error instanceof Error ? error.message : String(error);\n console.warn(`bQuery: Could not create Trusted Types policy \"${POLICY_NAME}\": ${errorMessage}`);\n return null;\n }\n};\n\n/**\n * Create a Trusted HTML value for use with Trusted Types-enabled sites.\n * Falls back to regular string when Trusted Types are unavailable.\n *\n * @param html - The HTML string to wrap\n * @returns Trusted HTML value or sanitized string\n */\nexport const createTrustedHtml = (html: string): TrustedHTML | string => {\n const policy = getTrustedTypesPolicy();\n if (policy) {\n return policy.createHTML(html);\n }\n return sanitizeHtmlCore(html);\n};\n"],"names":["MAX_NONCE_LENGTH","CHUNK_SIZE","generateNonce","length","array","binaryString","i","chunk","hasCSPDirective","directive","meta","cachedPolicy","policyInitAttempted","isTrustedTypesSupported","getTrustedTypesPolicy","win","POLICY_NAME","input","sanitizeHtmlCore","error","errorMessage","createTrustedHtml","html","policy"],"mappings":";;AAOA,MAAMA,IAAmB,MAGnBC,IAAa,MAWNC,IAAgB,CAACC,IAAiB,OAAe;AAE5D,MAAI,CAAC,OAAO,UAAUA,CAAM,KAAKA,IAAS;AACxC,UAAM,IAAI,WAAW,iDAAiD;AAExE,MAAIA,IAASH;AACX,UAAM,IAAI,WAAW,wCAAwCA,CAAgB,EAAE;AAIjF,MACE,OAAO,WAAW,SAAW,OAC7B,OAAO,WAAW,OAAO,mBAAoB;AAE7C,UAAM,IAAI;AAAA,MACR;AAAA,IAAA;AAGJ,MAAI,OAAO,WAAW,QAAS;AAC7B,UAAM,IAAI,MAAM,iEAAiE;AAGnF,QAAMI,IAAQ,IAAI,WAAWD,CAAM;AACnC,aAAW,OAAO,gBAAgBC,CAAK;AAGvC,MAAIC,IAAe;AACnB,WAASC,IAAI,GAAGA,IAAIF,EAAM,QAAQE,KAAKL,GAAY;AACjD,UAAMM,IAAQH,EAAM,SAASE,GAAG,KAAK,IAAIA,IAAIL,GAAYG,EAAM,MAAM,CAAC;AACtE,IAAAC,KAAgB,OAAO,aAAa,GAAGE,CAAK;AAAA,EAC9C;AAEA,SAAO,WAAW,KAAKF,CAAY,EAAE,QAAQ,OAAO,GAAG,EAAE,QAAQ,OAAO,GAAG,EAAE,QAAQ,MAAM,EAAE;AAC/F,GASaG,IAAkB,CAACC,MAA+B;AAE7D,MAAI,OAAO,WAAa;AACtB,WAAO;AAIT,QAAMC,IAAO,SAAS,cAAc,4CAA4C;AAChF,SAAIA,KACcA,EAAK,aAAa,SAAS,KAAK,IACjC,SAASD,CAAS,IAE5B;AACT;ACjEA,IAAIE,IAAyC,MAGzCC,IAAsB;AAMnB,MAAMC,IAA0B,MAEnC,OAAO,SAAW,OAClB,OAAQ,OAA8B,eAAiB,KAQ9CC,IAAwB,MAAgC;AACnE,MAAIH,EAAc,QAAOA;AAGzB,MAFIC,KAEA,OAAO,SAAW,IAAa,QAAO;AAE1C,QAAMG,IAAM;AACZ,MAAI,CAACA,EAAI,aAAc,QAAO;AAE9B,EAAAH,IAAsB;AAEtB,MAAI;AACF,WAAAD,IAAeI,EAAI,aAAa,aAAaC,GAAa;AAAA,MACxD,YAAY,CAACC,MAAkBC,EAAiBD,CAAK;AAAA,IAAA,CACtD,GACMN;AAAA,EACT,SAASQ,GAAO;AAEd,UAAMC,IAAeD,aAAiB,QAAQA,EAAM,UAAU,OAAOA,CAAK;AAC1E,mBAAQ,KAAK,kDAAkDH,CAAW,MAAMI,CAAY,EAAE,GACvF;AAAA,EACT;AACF,GASaC,IAAoB,CAACC,MAAuC;AACvE,QAAMC,IAAST,EAAA;AACf,SAAIS,IACKA,EAAO,WAAWD,CAAI,IAExBJ,EAAiBI,CAAI;AAC9B;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"store.es.mjs","sources":["../src/store/define-store.ts","../src/store/watch.ts"],"sourcesContent":["/**\n * Store factory helpers.\n */\n\nimport { createStore } from './create-store';\nimport { getStore, hasStore } from './registry';\nimport type { Store, StoreDefinition } from './types';\n\n/**\n * Creates a store factory that returns the store instance.\n *\n * The store is lazily created on first call and cached in the global store\n * registry. Subsequent calls return the same instance. After calling\n * `destroyStore(id)`, the next factory call will create a fresh store.\n *\n * @param id - Store identifier\n * @param definition - Store definition without id\n * @returns A function that returns the store instance\n *\n * @example\n * ```ts\n * const useCounter = defineStore('counter', {\n * state: () => ({ count: 0 }),\n * actions: { increment() { this.count++; } },\n * });\n *\n * const counter = useCounter();\n * counter.increment();\n * ```\n */\nexport const defineStore = <\n S extends Record<string, unknown>,\n G extends Record<string, unknown> = Record<string, never>,\n A extends Record<string, (...args: unknown[]) => unknown> = Record<string, never>,\n>(\n id: string,\n definition: Omit<StoreDefinition<S, G, A>, 'id'>\n): (() => Store<S, G, A>) => {\n // Check registry first to avoid noisy warnings from createStore()\n // when the factory is called multiple times (intended usage pattern).\n // createStore() only called when store doesn't exist or was destroyed.\n return () => {\n if (hasStore(id)) {\n return getStore(id) as Store<S, G, A>;\n }\n return createStore({ id, ...definition });\n };\n};\n","/**\n * Store watch helpers.\n */\n\nimport type { Store } from './types';\nimport { deepEqual } from './utils';\n\nexport type WatchStoreOptions<T> = {\n /** Call the callback immediately with the current value. */\n immediate?: boolean;\n /** Use deep comparison when determining changes. */\n deep?: boolean;\n /** Custom equality check for selected values. */\n equals?: (a: T, b: T) => boolean;\n};\n\n/**\n * Watch a selected slice of store state.\n *\n * @param store - The store instance\n * @param selector - Function to select the watched value\n * @param callback - Called when the selected value changes\n * @param options - Watch options\n * @returns Unsubscribe function\n */\nexport const watchStore = <\n S extends Record<string, unknown>,\n G extends Record<string, unknown>,\n A extends Record<string, (...args: unknown[]) => unknown>,\n T,\n>(\n store: Store<S, G, A>,\n selector: (state: S) => T,\n callback: (value: T, previous: T | undefined) => void,\n options: WatchStoreOptions<T> = {}\n): (() => void) => {\n const equals = options.equals ?? (options.deep ? deepEqual : Object.is);\n let previous = selector(store.$state);\n\n if (options.immediate) {\n callback(previous, undefined);\n }\n\n return store.$subscribe((state) => {\n const current = selector(state);\n if (!equals(current, previous)) {\n const prev = previous;\n previous = current;\n callback(current, prev);\n }\n });\n};\n"],"names":["defineStore","id","definition","hasStore","getStore","createStore","watchStore","store","selector","callback","options","equals","deepEqual","previous","state","current","prev"],"mappings":";;AA8BO,MAAMA,IAAc,CAKzBC,GACAC,MAKO,MACDC,EAASF,CAAE,IACNG,EAASH,CAAE,IAEbI,EAAY,EAAE,IAAAJ,GAAI,GAAGC,GAAY,GCpB/BI,IAAa,CAMxBC,GACAC,GACAC,GACAC,IAAgC,CAAA,MACf;AACjB,QAAMC,IAASD,EAAQ,WAAWA,EAAQ,OAAOE,IAAY,OAAO;AACpE,MAAIC,IAAWL,EAASD,EAAM,MAAM;AAEpC,SAAIG,EAAQ,aACVD,EAASI,GAAU,MAAS,GAGvBN,EAAM,WAAW,CAACO,MAAU;AACjC,UAAMC,IAAUP,EAASM,CAAK;AAC9B,QAAI,CAACH,EAAOI,GAASF,CAAQ,GAAG;AAC9B,YAAMG,IAAOH;AACb,MAAAA,IAAWE,GACXN,EAASM,GAASC,CAAI;AAAA,IACxB;AAAA,EACF,CAAC;AACH;"}
@@ -1,32 +0,0 @@
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
@@ -1 +0,0 @@
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;"}
@@ -1,6 +0,0 @@
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 +0,0 @@
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 +0,0 @@
1
- {"version":3,"file":"view.es.mjs","sources":["../src/view/evaluate.ts","../src/view/directives/bind.ts","../src/view/directives/class.ts","../src/view/directives/for.ts","../src/view/directives/html.ts","../src/view/directives/if.ts","../src/view/directives/model.ts","../src/view/directives/on.ts","../src/view/directives/ref.ts","../src/view/directives/show.ts","../src/view/directives/style.ts","../src/view/directives/text.ts","../src/view/process.ts","../src/view/mount.ts"],"sourcesContent":["import { isComputed, isSignal, type Signal } from '../reactive/index';\r\nimport type { BindingContext } from './types';\r\n\r\n/** Maximum number of cached expression functions before LRU eviction */\r\nconst MAX_CACHE_SIZE = 500;\r\n\r\n/** Compiled function type for expression evaluation */\r\ntype CompiledFn = (ctx: BindingContext) => unknown;\r\n\r\n/**\r\n * Simple LRU cache for compiled expression functions.\r\n * Uses Map's insertion order to track recency - accessed items are re-inserted.\r\n * @internal\r\n */\r\nclass LRUCache {\r\n private cache = new Map<string, CompiledFn>();\r\n private maxSize: number;\r\n\r\n constructor(maxSize: number) {\r\n this.maxSize = maxSize;\r\n }\r\n\r\n get(key: string): CompiledFn | undefined {\r\n const value = this.cache.get(key);\r\n if (value !== undefined) {\r\n // Move to end (most recently used) by re-inserting\r\n this.cache.delete(key);\r\n this.cache.set(key, value);\r\n }\r\n return value;\r\n }\r\n\r\n set(key: string, value: CompiledFn): void {\r\n // Delete first if exists to update insertion order\r\n if (this.cache.has(key)) {\r\n this.cache.delete(key);\r\n } else if (this.cache.size >= this.maxSize) {\r\n // Evict oldest (first) entry\r\n const oldest = this.cache.keys().next().value;\r\n if (oldest !== undefined) {\r\n this.cache.delete(oldest);\r\n }\r\n }\r\n this.cache.set(key, value);\r\n }\r\n\r\n clear(): void {\r\n this.cache.clear();\r\n }\r\n\r\n get size(): number {\r\n return this.cache.size;\r\n }\r\n}\r\n\r\n/** LRU cache for compiled evaluate functions, keyed by expression string */\r\nconst evaluateCache = new LRUCache(MAX_CACHE_SIZE);\r\n\r\n/** LRU cache for compiled evaluateRaw functions, keyed by expression string */\r\nconst evaluateRawCache = new LRUCache(MAX_CACHE_SIZE);\r\n\r\n/**\r\n * Clears all cached compiled expression functions.\r\n * Call this when unmounting views or to free memory after heavy template usage.\r\n *\r\n * @example\r\n * ```ts\r\n * import { clearExpressionCache } from 'bquery/view';\r\n *\r\n * // After destroying a view or when cleaning up\r\n * clearExpressionCache();\r\n * ```\r\n */\r\nexport const clearExpressionCache = (): void => {\r\n evaluateCache.clear();\r\n evaluateRawCache.clear();\r\n};\r\n\r\n/**\r\n * Creates a proxy that lazily unwraps signals/computed only when accessed.\r\n * This avoids subscribing to signals that aren't referenced in the expression.\r\n * @internal\r\n */\r\nconst createLazyContext = (context: BindingContext): BindingContext =>\r\n new Proxy(context, {\r\n get(target, prop: string | symbol) {\r\n // Only handle string keys for BindingContext indexing\r\n if (typeof prop !== 'string') {\r\n return Reflect.get(target, prop);\r\n }\r\n const value = target[prop];\r\n // Auto-unwrap signals/computed only when actually accessed\r\n if (isSignal(value) || isComputed(value)) {\r\n return (value as Signal<unknown>).value;\r\n }\r\n return value;\r\n },\r\n has(target, prop: string | symbol) {\r\n // Required for `with` statement to resolve identifiers correctly\r\n if (typeof prop !== 'string') {\r\n return Reflect.has(target, prop);\r\n }\r\n return prop in target;\r\n },\r\n });\r\n\r\n/**\r\n * Evaluates an expression in the given context using `new Function()`.\r\n *\r\n * Signals and computed values in the context are lazily unwrapped only when\r\n * accessed by the expression, avoiding unnecessary subscriptions to unused values.\r\n *\r\n * @security **WARNING:** This function uses dynamic code execution via `new Function()`.\r\n * - NEVER pass expressions derived from user input or untrusted sources\r\n * - Expressions should only come from developer-controlled templates\r\n * - Malicious expressions can access and exfiltrate context data\r\n * - Consider this equivalent to `eval()` in terms of security implications\r\n *\r\n * @internal\r\n */\r\nexport const evaluate = <T = unknown>(expression: string, context: BindingContext): T => {\r\n try {\r\n // Create a proxy that lazily unwraps signals/computed on access\r\n const lazyContext = createLazyContext(context);\r\n\r\n // Use cached function or compile and cache a new one\r\n let fn = evaluateCache.get(expression);\r\n if (!fn) {\r\n // Use `with` to enable direct property access from proxy scope.\r\n // Note: `new Function()` runs in non-strict mode, so `with` is allowed.\r\n fn = new Function('$ctx', `with($ctx) { return (${expression}); }`) as (\r\n ctx: BindingContext\r\n ) => unknown;\r\n evaluateCache.set(expression, fn);\r\n }\r\n return fn(lazyContext) as T;\r\n } catch (error) {\r\n console.error(`bQuery view: Error evaluating \"${expression}\"`, error);\r\n return undefined as T;\r\n }\r\n};\r\n\r\n/**\r\n * Evaluates an expression and returns the raw value (for signal access).\r\n *\r\n * @security **WARNING:** Uses dynamic code execution. See {@link evaluate} for security notes.\r\n * @internal\r\n */\r\nexport const evaluateRaw = <T = unknown>(expression: string, context: BindingContext): T => {\r\n try {\r\n // Use cached function or compile and cache a new one\r\n let fn = evaluateRawCache.get(expression);\r\n if (!fn) {\r\n // Use `with` to enable direct property access from context scope.\r\n // Unlike `evaluate`, we don't use a lazy proxy - values are accessed directly.\r\n fn = new Function('$ctx', `with($ctx) { return (${expression}); }`) as (\r\n ctx: BindingContext\r\n ) => unknown;\r\n evaluateRawCache.set(expression, fn);\r\n }\r\n return fn(context) as T;\r\n } catch (error) {\r\n console.error(`bQuery view: Error evaluating \"${expression}\"`, error);\r\n return undefined as T;\r\n }\r\n};\r\n\r\n/**\r\n * Parses object expression like \"{ active: isActive, disabled: !enabled }\".\r\n * Handles nested structures like function calls, arrays, and template literals.\r\n * @internal\r\n */\r\nexport const parseObjectExpression = (expression: string): Record<string, string> => {\r\n const result: Record<string, string> = {};\r\n\r\n // Remove outer braces and trim\r\n const inner = expression\r\n .trim()\r\n .replace(/^\\{|\\}$/g, '')\r\n .trim();\r\n if (!inner) return result;\r\n\r\n // Split by comma at depth 0, respecting strings and nesting\r\n const parts: string[] = [];\r\n let current = '';\r\n let depth = 0;\r\n let inString: string | null = null;\r\n\r\n for (let i = 0; i < inner.length; i++) {\r\n const char = inner[i];\r\n\r\n // Handle string literals: count consecutive backslashes before a quote\r\n // to correctly distinguish escaped quotes from end-of-string\r\n if (char === '\"' || char === \"'\" || char === '`') {\r\n let backslashCount = 0;\r\n let j = i - 1;\r\n while (j >= 0 && inner[j] === '\\\\') {\r\n backslashCount++;\r\n j--;\r\n }\r\n // Quote is escaped only if preceded by an odd number of backslashes\r\n if (backslashCount % 2 === 0) {\r\n if (inString === null) {\r\n inString = char;\r\n } else if (inString === char) {\r\n inString = null;\r\n }\r\n }\r\n current += char;\r\n continue;\r\n }\r\n\r\n // Skip if inside string\r\n if (inString !== null) {\r\n current += char;\r\n continue;\r\n }\r\n\r\n // Track nesting depth for parentheses, brackets, and braces\r\n if (char === '(' || char === '[' || char === '{') {\r\n depth++;\r\n current += char;\r\n } else if (char === ')' || char === ']' || char === '}') {\r\n depth--;\r\n current += char;\r\n } else if (char === ',' && depth === 0) {\r\n // Top-level comma - split point\r\n parts.push(current.trim());\r\n current = '';\r\n } else {\r\n current += char;\r\n }\r\n }\r\n\r\n // Add the last part\r\n if (current.trim()) {\r\n parts.push(current.trim());\r\n }\r\n\r\n // Parse each part to extract key and value\r\n for (const part of parts) {\r\n // Find the first colon at depth 0 (to handle ternary operators in values)\r\n let colonIndex = -1;\r\n let partDepth = 0;\r\n let partInString: string | null = null;\r\n\r\n for (let i = 0; i < part.length; i++) {\r\n const char = part[i];\r\n\r\n if (char === '\"' || char === \"'\" || char === '`') {\r\n let backslashCount = 0;\r\n let j = i - 1;\r\n while (j >= 0 && part[j] === '\\\\') {\r\n backslashCount++;\r\n j--;\r\n }\r\n if (backslashCount % 2 === 0) {\r\n if (partInString === null) {\r\n partInString = char;\r\n } else if (partInString === char) {\r\n partInString = null;\r\n }\r\n }\r\n continue;\r\n }\r\n\r\n if (partInString !== null) continue;\r\n\r\n if (char === '(' || char === '[' || char === '{') {\r\n partDepth++;\r\n } else if (char === ')' || char === ']' || char === '}') {\r\n partDepth--;\r\n } else if (char === ':' && partDepth === 0) {\r\n colonIndex = i;\r\n break;\r\n }\r\n }\r\n\r\n if (colonIndex > -1) {\r\n const key = part\r\n .slice(0, colonIndex)\r\n .trim()\r\n .replace(/^['\"]|['\"]$/g, '');\r\n const value = part.slice(colonIndex + 1).trim();\r\n result[key] = value;\r\n }\r\n }\r\n\r\n return result;\r\n};\r\n","import { effect } from '../../reactive/index';\nimport { evaluate } from '../evaluate';\nimport type { DirectiveHandler } from '../types';\n\n/**\n * Handles bq-bind:attr directive - attribute binding.\n * @internal\n */\nexport const handleBind = (attrName: string): DirectiveHandler => {\n return (el, expression, context, cleanups) => {\n const cleanup = effect(() => {\n const value = evaluate(expression, context);\n if (value == null || value === false) {\n el.removeAttribute(attrName);\n } else if (value === true) {\n el.setAttribute(attrName, '');\n } else {\n el.setAttribute(attrName, String(value));\n }\n });\n cleanups.push(cleanup);\n };\n};\n","import { effect } from '../../reactive/index';\nimport { evaluate, parseObjectExpression } from '../evaluate';\nimport type { DirectiveHandler } from '../types';\n\n/**\n * Handles bq-class directive - dynamic class binding.\n * Tracks previously added classes to ensure proper cleanup when expressions change.\n * @internal\n */\nexport const handleClass: DirectiveHandler = (el, expression, context, cleanups) => {\n // Track classes added by this directive to clean them up on re-evaluation\n let previousClasses: Set<string> = new Set();\n\n const cleanup = effect(() => {\n const newClasses: Set<string> = new Set();\n\n if (expression.trimStart().startsWith('{')) {\n // Object syntax: { active: isActive, disabled: !enabled }\n const classMap = parseObjectExpression(expression);\n for (const [className, conditionExpr] of Object.entries(classMap)) {\n const condition = evaluate<boolean>(conditionExpr, context);\n el.classList.toggle(className, Boolean(condition));\n // Track class regardless of condition - toggle handles add/remove\n newClasses.add(className);\n }\n } else if (/^\\s*\\[/.test(expression)) {\n // Array literal syntax: [class1, class2]\n const classes = evaluate<string[]>(expression, context);\n if (Array.isArray(classes)) {\n for (const cls of classes) {\n if (cls) {\n el.classList.add(cls);\n newClasses.add(cls);\n }\n }\n }\n } else {\n // Single expression returning string or array\n const result = evaluate<string | string[]>(expression, context);\n if (typeof result === 'string') {\n result.split(/\\s+/).forEach((cls) => {\n if (cls) {\n el.classList.add(cls);\n newClasses.add(cls);\n }\n });\n } else if (Array.isArray(result)) {\n result.forEach((cls) => {\n if (cls) {\n el.classList.add(cls);\n newClasses.add(cls);\n }\n });\n }\n }\n\n // Remove classes that were previously added but are no longer in the new set\n // This keeps directive-managed classes in sync across all syntax forms and provides\n // defensive cleanup behavior for edge cases (e.g. external classList changes)\n for (const cls of previousClasses) {\n if (!newClasses.has(cls)) {\n el.classList.remove(cls);\n }\n }\n\n previousClasses = newClasses;\n });\n\n cleanups.push(cleanup);\n};\n","import { effect, signal, type CleanupFn, type Signal } from '../../reactive/index';\nimport { evaluate } from '../evaluate';\nimport type { BindingContext, DirectiveHandler } from '../types';\n\ntype ProcessElementFn = (\n el: Element,\n context: BindingContext,\n prefix: string,\n cleanups: CleanupFn[]\n) => void;\n\ntype ProcessChildrenFn = (\n el: Element,\n context: BindingContext,\n prefix: string,\n cleanups: CleanupFn[]\n) => void;\n\n/**\n * Represents a rendered item in bq-for with its DOM element and associated cleanup functions.\n * @internal\n */\ntype RenderedItem = {\n key: unknown;\n element: Element;\n cleanups: CleanupFn[];\n item: unknown;\n index: number;\n itemSignal: Signal<unknown>; // Reactive item value for item-dependent bindings\n indexSignal: Signal<number> | null; // Reactive index for index-dependent bindings\n};\n\n/**\n * Extracts a key from an item using the key expression or falls back to index.\n * @internal\n */\nconst getItemKey = (\n item: unknown,\n index: number,\n keyExpression: string | null,\n itemName: string,\n indexName: string | undefined,\n context: BindingContext\n): unknown => {\n if (!keyExpression) {\n return index; // Fallback to index-based keying\n }\n\n const keyContext: BindingContext = {\n ...context,\n [itemName]: item,\n };\n if (indexName) {\n keyContext[indexName] = index;\n }\n\n return evaluate(keyExpression, keyContext);\n};\n\n/**\n * Handles bq-for directive - list rendering with keyed reconciliation.\n *\n * Supports optional `:key` attribute for efficient DOM reuse:\n * ```html\n * <li bq-for=\"item in items\" :key=\"item.id\">...</li>\n * ```\n *\n * Without a key, falls back to index-based tracking (less efficient for reordering).\n *\n * @internal\n */\nexport const createForHandler = (options: {\n prefix: string;\n processElement: ProcessElementFn;\n processChildren: ProcessChildrenFn;\n}): DirectiveHandler => {\n const { prefix, processElement, processChildren } = options;\n\n return (el, expression, context, cleanups) => {\n const parent = el.parentNode;\n if (!parent) return;\n\n // Parse expression: \"item in items\" or \"(item, index) in items\"\n // Use \\S.* instead of .+ to prevent ReDoS by requiring non-whitespace start\n const match = expression.match(/^\\(?(\\w+)(?:\\s*,\\s*(\\w+))?\\)?\\s+in\\s+(\\S.*)$/);\n if (!match) {\n console.error(`bQuery view: Invalid bq-for expression \"${expression}\"`);\n return;\n }\n\n const [, itemName, indexName, listExpression] = match;\n\n // Extract :key attribute if present\n const keyExpression = el.getAttribute(':key') || el.getAttribute(`${prefix}-key`);\n\n const template = el.cloneNode(true) as Element;\n template.removeAttribute(`${prefix}-for`);\n template.removeAttribute(':key');\n template.removeAttribute(`${prefix}-key`);\n\n // Create placeholder comment\n const placeholder = document.createComment(`bq-for: ${expression}`);\n parent.replaceChild(placeholder, el);\n\n // Track rendered items by key for reconciliation\n let renderedItemsMap = new Map<unknown, RenderedItem>();\n let renderedOrder: unknown[] = [];\n\n /**\n * Creates a new DOM element for an item.\n */\n const createItemElement = (item: unknown, index: number, key: unknown): RenderedItem => {\n const clone = template.cloneNode(true) as Element;\n const itemCleanups: CleanupFn[] = [];\n\n // Create reactive signals for item and index\n const itemSig = signal(item);\n const indexSig = indexName ? signal(index) : null;\n\n const childContext: BindingContext = {\n ...context,\n [itemName]: itemSig,\n };\n if (indexName && indexSig) {\n childContext[indexName] = indexSig;\n }\n\n // Process bindings on the clone\n processElement(clone, childContext, prefix, itemCleanups);\n processChildren(clone, childContext, prefix, itemCleanups);\n\n return {\n key,\n element: clone,\n cleanups: itemCleanups,\n item,\n index,\n itemSignal: itemSig,\n indexSignal: indexSig,\n };\n };\n\n /**\n * Removes a rendered item and cleans up its effects.\n */\n const removeItem = (rendered: RenderedItem): void => {\n for (const cleanup of rendered.cleanups) {\n cleanup();\n }\n rendered.element.remove();\n };\n\n /**\n * Updates an existing item's data and index when reused.\n * Updates the reactive signals so bindings re-render.\n */\n const updateItem = (rendered: RenderedItem, newItem: unknown, newIndex: number): void => {\n // Update item if it changed\n if (!Object.is(rendered.item, newItem)) {\n rendered.item = newItem;\n rendered.itemSignal.value = newItem;\n }\n\n // Update index if it changed\n if (rendered.index !== newIndex) {\n rendered.index = newIndex;\n if (rendered.indexSignal) {\n rendered.indexSignal.value = newIndex;\n }\n }\n };\n\n const cleanup = effect(() => {\n const list = evaluate<unknown[]>(listExpression, context);\n\n if (!Array.isArray(list)) {\n // Clear all if list is invalid\n for (const rendered of renderedItemsMap.values()) {\n removeItem(rendered);\n }\n renderedItemsMap.clear();\n renderedOrder = [];\n return;\n }\n\n // Build new key order and detect changes\n const newKeys: unknown[] = [];\n const newItemsByKey = new Map<unknown, { item: unknown; index: number }>();\n const seenKeys = new Set<unknown>();\n\n list.forEach((item, index) => {\n let key = getItemKey(item, index, keyExpression, itemName, indexName, context);\n\n // Detect duplicate keys - warn developer and fall back to unique composite key\n if (seenKeys.has(key)) {\n console.warn(\n `bq-for: Duplicate key \"${String(key)}\" detected at index ${index}. ` +\n `Falling back to index-based key for this item. ` +\n `Ensure :key expressions produce unique values for each item.`\n );\n // Create a unique composite key to avoid corrupting rendered output\n key = { __bqDuplicateKey: key, __bqIndex: index };\n }\n seenKeys.add(key);\n\n newKeys.push(key);\n newItemsByKey.set(key, { item, index });\n });\n\n // Identify items to remove (in old but not in new)\n const keysToRemove: unknown[] = [];\n for (const key of renderedOrder) {\n if (!newItemsByKey.has(key)) {\n keysToRemove.push(key);\n }\n }\n\n // Remove deleted items\n for (const key of keysToRemove) {\n const rendered = renderedItemsMap.get(key);\n if (rendered) {\n removeItem(rendered);\n renderedItemsMap.delete(key);\n }\n }\n\n // Process new list: create new items, update indices, reorder\n const newRenderedMap = new Map<unknown, RenderedItem>();\n let lastInsertedElement: Element | Comment = placeholder;\n\n for (let i = 0; i < newKeys.length; i++) {\n const key = newKeys[i];\n const { item, index } = newItemsByKey.get(key)!;\n let rendered = renderedItemsMap.get(key);\n\n if (rendered) {\n // Reuse existing element\n updateItem(rendered, item, index);\n newRenderedMap.set(key, rendered);\n\n // Check if element needs to be moved\n const currentNext: ChildNode | null = lastInsertedElement.nextSibling;\n if (currentNext !== rendered.element) {\n // Move element to correct position\n lastInsertedElement.after(rendered.element);\n }\n lastInsertedElement = rendered.element;\n } else {\n // Create new element\n rendered = createItemElement(item, index, key);\n newRenderedMap.set(key, rendered);\n\n // Insert at correct position\n lastInsertedElement.after(rendered.element);\n lastInsertedElement = rendered.element;\n }\n }\n\n // Update tracking state\n renderedItemsMap = newRenderedMap;\n renderedOrder = newKeys;\n });\n\n // When the bq-for itself is cleaned up, also cleanup all rendered items\n cleanups.push(() => {\n cleanup();\n for (const rendered of renderedItemsMap.values()) {\n for (const itemCleanup of rendered.cleanups) {\n itemCleanup();\n }\n }\n renderedItemsMap.clear();\n });\n };\n};\n","import { effect } from '../../reactive/index';\nimport { sanitizeHtml } from '../../security/index';\nimport { evaluate } from '../evaluate';\nimport type { DirectiveHandler } from '../types';\n\n/**\n * Handles bq-html directive - sets innerHTML (sanitized by default).\n * @internal\n */\nexport const handleHtml = (sanitize: boolean): DirectiveHandler => {\n return (el, expression, context, cleanups) => {\n const cleanup = effect(() => {\n const value = evaluate<string>(expression, context);\n const html = String(value ?? '');\n el.innerHTML = sanitize ? sanitizeHtml(html) : html;\n });\n cleanups.push(cleanup);\n };\n};\n","import { effect } from '../../reactive/index';\nimport { evaluate } from '../evaluate';\nimport type { DirectiveHandler } from '../types';\n\n/**\n * Handles bq-if directive - conditional rendering.\n * @internal\n */\nexport const handleIf: DirectiveHandler = (el, expression, context, cleanups) => {\n const placeholder = document.createComment(`bq-if: ${expression}`);\n\n // Store original element state\n let isInserted = true;\n\n const cleanup = effect(() => {\n const condition = evaluate<boolean>(expression, context);\n\n if (condition && !isInserted) {\n // Insert element using replaceWith to handle moved elements\n placeholder.replaceWith(el);\n isInserted = true;\n } else if (!condition && isInserted) {\n // Remove element using replaceWith to handle moved elements\n el.replaceWith(placeholder);\n isInserted = false;\n }\n });\n\n cleanups.push(cleanup);\n};\n","import { effect, isSignal, type Signal } from '../../reactive/index';\nimport { evaluateRaw } from '../evaluate';\nimport type { DirectiveHandler } from '../types';\n\n/**\n * Handles bq-model directive - two-way binding.\n * @internal\n */\nexport const handleModel: DirectiveHandler = (el, expression, context, cleanups) => {\n const input = el as HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement;\n const rawValue = evaluateRaw<Signal<unknown>>(expression, context);\n\n if (!isSignal(rawValue)) {\n console.warn(`bQuery view: bq-model requires a signal, got \"${expression}\"`);\n return;\n }\n\n const sig = rawValue as Signal<unknown>;\n\n // Initial value sync\n const isCheckbox = input.type === 'checkbox';\n const isRadio = input.type === 'radio';\n\n const updateInput = () => {\n if (isCheckbox) {\n (input as HTMLInputElement).checked = Boolean(sig.value);\n } else if (isRadio) {\n (input as HTMLInputElement).checked = sig.value === input.value;\n } else {\n input.value = String(sig.value ?? '');\n }\n };\n\n // Effect to sync signal -> input\n const cleanup = effect(() => {\n updateInput();\n });\n cleanups.push(cleanup);\n\n // Event listener to sync input -> signal\n const eventType = input.tagName === 'SELECT' ? 'change' : 'input';\n const handler = () => {\n if (isCheckbox) {\n sig.value = (input as HTMLInputElement).checked;\n } else if (isRadio) {\n if ((input as HTMLInputElement).checked) {\n sig.value = input.value;\n }\n } else {\n sig.value = input.value;\n }\n };\n\n input.addEventListener(eventType, handler);\n cleanups.push(() => input.removeEventListener(eventType, handler));\n};\n","import { evaluateRaw } from '../evaluate';\nimport type { DirectiveHandler } from '../types';\n\n/**\n * Handles bq-on:event directive - event binding.\n * @internal\n */\nexport const handleOn = (eventName: string): DirectiveHandler => {\n return (el, expression, context, cleanups) => {\n const handler = (event: Event) => {\n // Add $event to context for expression evaluation\n const eventContext = { ...context, $event: event, $el: el };\n\n // Check if expression contains a function call (has parentheses)\n // If not, it might be a plain function reference like \"handleClick\"\n // Note: Method references like \"handlers.onClick\" will lose their receiver\n // when auto-invoked. For methods, use explicit calls: \"handlers.onClick($event)\"\n const containsCall = expression.includes('(');\n\n if (!containsCall) {\n // Evaluate the expression - if it returns a function, invoke it with $event\n const result = evaluateRaw<unknown>(expression, eventContext);\n if (typeof result === 'function') {\n // Auto-invoke with event. Note: `this` will be undefined for method references.\n // For proper method binding, use explicit syntax: \"obj.method($event)\"\n result(event);\n return;\n }\n // If not a function, the expression was already evaluated (e.g., \"count.value++\")\n return;\n }\n\n // Otherwise evaluate as expression using evaluateRaw to allow signal mutations\n // (e.g., \"count.value++\" or \"handleClick($event)\")\n evaluateRaw(expression, eventContext);\n };\n\n el.addEventListener(eventName, handler);\n cleanups.push(() => el.removeEventListener(eventName, handler));\n };\n};\n","import { isSignal, type Signal } from '../../reactive/index';\nimport { evaluateRaw } from '../evaluate';\nimport type { DirectiveHandler } from '../types';\n\n/**\n * Checks if an object has a writable `value` property.\n * Returns true if `value` is an own data property or an accessor with a setter.\n * @internal\n */\nfunction hasWritableValue(obj: object): obj is { value: Element | null } {\n const descriptor = Object.getOwnPropertyDescriptor(obj, 'value');\n if (!descriptor) return false;\n // Data property: check writable flag\n if ('value' in descriptor) return descriptor.writable === true;\n // Accessor property: check for setter\n return typeof descriptor.set === 'function';\n}\n\n/**\n * Handles bq-ref directive - element reference.\n * @internal\n */\nexport const handleRef: DirectiveHandler = (el, expression, context, cleanups) => {\n const rawValue = evaluateRaw<Signal<Element | null> | { value: Element | null }>(\n expression,\n context\n );\n\n if (isSignal(rawValue)) {\n rawValue.value = el;\n cleanups.push(() => {\n rawValue.value = null;\n });\n } else if (typeof rawValue === 'object' && rawValue !== null && hasWritableValue(rawValue)) {\n // Object with writable .value property (e.g., { value: null })\n rawValue.value = el;\n cleanups.push(() => {\n rawValue.value = null;\n });\n }\n};\n","import { effect } from '../../reactive/index';\nimport { evaluate } from '../evaluate';\nimport type { DirectiveHandler } from '../types';\n\n/**\n * Handles bq-show directive - toggle visibility.\n * @internal\n */\nexport const handleShow: DirectiveHandler = (el, expression, context, cleanups) => {\n const htmlEl = el as HTMLElement;\n // Capture the computed display value to properly restore visibility.\n // If inline display is 'none' or empty, we need to use the computed value.\n // Use ownerDocument.defaultView for cross-document/iframe compatibility.\n let originalDisplay = htmlEl.style.display;\n if (!originalDisplay || originalDisplay === 'none') {\n const computed = htmlEl.ownerDocument.defaultView?.getComputedStyle(htmlEl).display ?? '';\n originalDisplay = computed !== 'none' ? computed : '';\n }\n\n const cleanup = effect(() => {\n const condition = evaluate<boolean>(expression, context);\n htmlEl.style.display = condition ? originalDisplay : 'none';\n });\n\n cleanups.push(cleanup);\n};\n","import { effect } from '../../reactive/index';\nimport { evaluate, parseObjectExpression } from '../evaluate';\nimport type { DirectiveHandler } from '../types';\n\n/**\n * Handles bq-style directive - dynamic style binding.\n * @internal\n */\nexport const handleStyle: DirectiveHandler = (el, expression, context, cleanups) => {\n const htmlEl = el as HTMLElement;\n let appliedStyles: Set<string> = new Set();\n\n const cleanup = effect(() => {\n const newStyles = new Set<string>();\n\n if (expression.trimStart().startsWith('{')) {\n const styleMap = parseObjectExpression(expression);\n for (const [prop, valueExpr] of Object.entries(styleMap)) {\n const value = evaluate<string>(valueExpr, context);\n const cssProp = prop.replace(/([A-Z])/g, '-$1').toLowerCase();\n htmlEl.style.setProperty(cssProp, String(value ?? ''));\n newStyles.add(cssProp);\n }\n } else {\n const result = evaluate<Record<string, string>>(expression, context);\n if (result && typeof result === 'object') {\n for (const [prop, value] of Object.entries(result)) {\n const cssProp = prop.replace(/([A-Z])/g, '-$1').toLowerCase();\n htmlEl.style.setProperty(cssProp, String(value ?? ''));\n newStyles.add(cssProp);\n }\n }\n }\n\n // Remove styles that were previously applied but are no longer present\n for (const cssProp of appliedStyles) {\n if (!newStyles.has(cssProp)) {\n htmlEl.style.removeProperty(cssProp);\n }\n }\n\n // Update the set of applied styles\n appliedStyles = newStyles;\n });\n\n cleanups.push(cleanup);\n};\n","import { effect } from '../../reactive/index';\nimport { evaluate } from '../evaluate';\nimport type { DirectiveHandler } from '../types';\n\n/**\n * Handles bq-text directive - sets text content.\n * @internal\n */\nexport const handleText: DirectiveHandler = (el, expression, context, cleanups) => {\n const cleanup = effect(() => {\n const value = evaluate(expression, context);\n el.textContent = String(value ?? '');\n });\n cleanups.push(cleanup);\n};\n","import type { CleanupFn } from '../reactive/index';\nimport type { BindingContext, DirectiveHandler } from './types';\n\nexport type DirectiveHandlers = {\n text: DirectiveHandler;\n html: DirectiveHandler;\n if: DirectiveHandler;\n show: DirectiveHandler;\n class: DirectiveHandler;\n style: DirectiveHandler;\n model: DirectiveHandler;\n ref: DirectiveHandler;\n for: DirectiveHandler;\n bind: (attrName: string) => DirectiveHandler;\n on: (eventName: string) => DirectiveHandler;\n};\n\n/**\n * Processes a single element for directives.\n * @internal\n */\nexport const processElement = (\n el: Element,\n context: BindingContext,\n prefix: string,\n cleanups: CleanupFn[],\n handlers: DirectiveHandlers\n): void => {\n const attributes = Array.from(el.attributes);\n\n for (const attr of attributes) {\n const { name, value } = attr;\n\n if (!name.startsWith(`${prefix}-`)) continue;\n\n const directive = name.slice(prefix.length + 1); // Remove prefix and dash\n\n // Handle bq-for specially (creates new scope)\n if (directive === 'for') {\n handlers.for(el, value, context, cleanups);\n return; // Don't process children, bq-for handles it\n }\n\n // Handle other directives\n if (directive === 'text') {\n handlers.text(el, value, context, cleanups);\n } else if (directive === 'html') {\n handlers.html(el, value, context, cleanups);\n } else if (directive === 'if') {\n handlers.if(el, value, context, cleanups);\n } else if (directive === 'show') {\n handlers.show(el, value, context, cleanups);\n } else if (directive === 'class') {\n handlers.class(el, value, context, cleanups);\n } else if (directive === 'style') {\n handlers.style(el, value, context, cleanups);\n } else if (directive === 'model') {\n handlers.model(el, value, context, cleanups);\n } else if (directive === 'ref') {\n handlers.ref(el, value, context, cleanups);\n } else if (directive.startsWith('bind:')) {\n const attrName = directive.slice(5);\n handlers.bind(attrName)(el, value, context, cleanups);\n } else if (directive.startsWith('on:')) {\n const eventName = directive.slice(3);\n handlers.on(eventName)(el, value, context, cleanups);\n }\n }\n};\n\n/**\n * Recursively processes children of an element.\n * @internal\n */\nexport const processChildren = (\n el: Element,\n context: BindingContext,\n prefix: string,\n cleanups: CleanupFn[],\n handlers: DirectiveHandlers\n): void => {\n const children = Array.from(el.children);\n for (const child of children) {\n // Skip if element has bq-for (handled separately)\n if (!child.hasAttribute(`${prefix}-for`)) {\n processElement(child, context, prefix, cleanups, handlers);\n processChildren(child, context, prefix, cleanups, handlers);\n } else {\n processElement(child, context, prefix, cleanups, handlers);\n }\n }\n};\n","import type { CleanupFn } from '../reactive/index';\nimport {\n createForHandler,\n handleBind,\n handleClass,\n handleHtml,\n handleIf,\n handleModel,\n handleOn,\n handleRef,\n handleShow,\n handleStyle,\n handleText,\n} from './directives/index';\nimport { processChildren, processElement, type DirectiveHandlers } from './process';\nimport type { BindingContext, MountOptions, View } from './types';\n\n/**\n * Mounts a reactive view to an element.\n *\n * @param selector - CSS selector or Element\n * @param context - Binding context with signals, computed, and functions\n * @param options - Mount options\n * @returns The mounted View instance\n *\n * @security **WARNING:** Directive expressions (bq-text, bq-if, bq-on, etc.) are evaluated\n * using `new Function()` at runtime. This means:\n * - Template attributes must come from trusted sources only\n * - NEVER load templates containing bq-* attributes from user input or untrusted APIs\n * - If you must use external templates, validate/sanitize attribute values first\n *\n * @example\n * ```ts\n * import { mount } from 'bquery/view';\n * import { signal, computed } from 'bquery/reactive';\n *\n * const name = signal('World');\n * const greeting = computed(() => `Hello, ${name.value}!`);\n * const items = signal([\n * { id: 1, text: 'Item 1' },\n * { id: 2, text: 'Item 2' },\n * ]);\n *\n * const view = mount('#app', {\n * name,\n * greeting,\n * items,\n * addItem: () => {\n * items.value = [...items.value, { id: Date.now(), text: 'New Item' }];\n * },\n * });\n *\n * // Later, cleanup\n * view.destroy();\n * ```\n */\nexport const mount = (\n selector: string | Element,\n context: BindingContext,\n options: MountOptions = {}\n): View => {\n const { prefix = 'bq', sanitize = true } = options;\n\n const el = typeof selector === 'string' ? document.querySelector(selector) : selector;\n\n if (!el) {\n throw new Error(`bQuery view: Element \"${selector}\" not found.`);\n }\n\n // Reject if root element has bq-for directive\n // bq-for replaces the element with a placeholder comment, which would leave View.el detached\n if (el.hasAttribute(`${prefix}-for`)) {\n throw new Error(\n `bQuery view: Cannot mount on element with ${prefix}-for directive. ` +\n `Wrap the ${prefix}-for element in a container instead.`\n );\n }\n\n const cleanups: CleanupFn[] = [];\n\n const handlers: DirectiveHandlers = {\n text: handleText,\n html: handleHtml(sanitize),\n if: handleIf,\n show: handleShow,\n class: handleClass,\n style: handleStyle,\n model: handleModel,\n ref: handleRef,\n for: createForHandler({\n prefix,\n processElement: (node, nodeContext, nodePrefix, nodeCleanups) =>\n processElement(node, nodeContext, nodePrefix, nodeCleanups, handlers),\n processChildren: (node, nodeContext, nodePrefix, nodeCleanups) =>\n processChildren(node, nodeContext, nodePrefix, nodeCleanups, handlers),\n }),\n bind: handleBind,\n on: handleOn,\n };\n\n const processWithHandlers = (\n node: Element,\n nodeContext: BindingContext,\n nodeCleanups: CleanupFn[]\n ) => {\n // Check if element has bq-for before processing\n // bq-for replaces the element and handles its children internally\n const hasFor = node.hasAttribute(`${prefix}-for`);\n\n processElement(node, nodeContext, prefix, nodeCleanups, handlers);\n\n // Skip processChildren if bq-for was on this element - it handles children itself\n if (!hasFor) {\n processChildren(node, nodeContext, prefix, nodeCleanups, handlers);\n }\n };\n\n // Process the root element and its children\n processWithHandlers(el, context, cleanups);\n\n return {\n el,\n context,\n\n update: (newContext: Partial<BindingContext>) => {\n Object.assign(context, newContext);\n },\n\n destroy: () => {\n for (const cleanup of cleanups) {\n cleanup();\n }\n cleanups.length = 0;\n },\n };\n};\n\n/**\n * Creates a reactive template function.\n *\n * @param template - HTML template string\n * @returns A function that creates a mounted element with the given context\n *\n * @example\n * ```ts\n * import { createTemplate } from 'bquery/view';\n * import { signal } from 'bquery/reactive';\n *\n * const TodoItem = createTemplate(`\n * <li bq-class=\"{ completed: done }\">\n * <input type=\"checkbox\" bq-model=\"done\" />\n * <span bq-text=\"text\"></span>\n * </li>\n * `);\n *\n * const item = TodoItem({\n * done: signal(false),\n * text: 'Buy groceries',\n * });\n *\n * document.querySelector('#list').append(item.el);\n * ```\n */\nexport const createTemplate = (\n template: string,\n options: MountOptions = {}\n): ((context: BindingContext) => View) => {\n return (context: BindingContext) => {\n const container = document.createElement('div');\n container.innerHTML = template.trim();\n\n const el = container.firstElementChild;\n if (!el) {\n throw new Error('bQuery view: Template must contain a single root element.');\n }\n\n // We know at least one element exists (firstElementChild is not null above)\n // Reject if there are multiple root elements\n if (container.childElementCount > 1) {\n throw new Error(\n `bQuery view: Template must contain exactly one root element, found ${container.childElementCount}.`\n );\n }\n\n const { prefix = 'bq' } = options;\n // Reject templates with bq-for or bq-if on the root element\n // These directives replace the element with a placeholder comment, which would leave View.el detached\n // Since processing happens while el is still in the temporary container, the placeholder\n // would remain there while view.el is inserted elsewhere, causing desync on future toggles\n if (el.hasAttribute(`${prefix}-for`) || el.hasAttribute(`${prefix}-if`)) {\n const directive = el.hasAttribute(`${prefix}-for`) ? 'for' : 'if';\n throw new Error(\n `bQuery view: Template root element cannot have ${prefix}-${directive} directive. ` +\n `Wrap the ${prefix}-${directive} element in a container instead.`\n );\n }\n\n return mount(el, context, options);\n };\n};\n"],"names":["MAX_CACHE_SIZE","LRUCache","maxSize","key","value","oldest","evaluateCache","evaluateRawCache","clearExpressionCache","createLazyContext","context","target","prop","isSignal","isComputed","evaluate","expression","lazyContext","fn","error","evaluateRaw","parseObjectExpression","result","inner","parts","current","depth","inString","i","char","backslashCount","j","part","colonIndex","partDepth","partInString","handleBind","attrName","el","cleanups","cleanup","effect","handleClass","previousClasses","newClasses","classMap","className","conditionExpr","condition","classes","cls","getItemKey","item","index","keyExpression","itemName","indexName","keyContext","createForHandler","options","prefix","processElement","processChildren","parent","match","listExpression","template","placeholder","renderedItemsMap","renderedOrder","createItemElement","clone","itemCleanups","itemSig","signal","indexSig","childContext","removeItem","rendered","updateItem","newItem","newIndex","list","newKeys","newItemsByKey","seenKeys","keysToRemove","newRenderedMap","lastInsertedElement","itemCleanup","handleHtml","sanitize","html","sanitizeHtml","handleIf","isInserted","handleModel","input","rawValue","sig","isCheckbox","isRadio","updateInput","eventType","handler","handleOn","eventName","event","eventContext","hasWritableValue","obj","descriptor","handleRef","handleShow","htmlEl","originalDisplay","computed","handleStyle","appliedStyles","newStyles","styleMap","valueExpr","cssProp","handleText","handlers","attributes","attr","name","directive","children","child","mount","selector","node","nodeContext","nodePrefix","nodeCleanups","hasFor","newContext","createTemplate","container"],"mappings":"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"}
@@ -1,58 +0,0 @@
1
- import { s as c } from "./core-BhpuvPhy.js";
2
- import { e as n } from "./type-guards-BdKlYYlS.js";
3
- const m = (s, o) => {
4
- let l = !1, t = null;
5
- try {
6
- if (t = globalThis.localStorage, t) {
7
- const e = `__bquery_test_${Math.random().toString(36).slice(2, 9)}__`, a = "__test__";
8
- try {
9
- t.setItem(e, a), t.getItem(e), l = !0;
10
- } finally {
11
- try {
12
- t.removeItem(e);
13
- } catch {
14
- }
15
- }
16
- }
17
- } catch {
18
- l = !1;
19
- }
20
- let i = o;
21
- if (l && t)
22
- try {
23
- const e = t.getItem(s);
24
- e !== null && (i = JSON.parse(e));
25
- } catch {
26
- }
27
- const r = c(i);
28
- return l && t && n(() => {
29
- try {
30
- t.setItem(s, JSON.stringify(r.value));
31
- } catch {
32
- }
33
- }), r;
34
- }, g = (s) => ({
35
- get value() {
36
- return s.value;
37
- },
38
- peek() {
39
- return s.peek();
40
- }
41
- }), _ = (s, o, l = {}) => {
42
- const { immediate: t = !1, equals: i = Object.is } = l;
43
- let r, e = !0;
44
- return n(() => {
45
- const a = s.value;
46
- if (e) {
47
- e = !1, r = a, t && o(a, void 0);
48
- return;
49
- }
50
- i(a, r) || (o(a, r), r = a);
51
- });
52
- };
53
- export {
54
- m as p,
55
- g as r,
56
- _ as w
57
- };
58
- //# sourceMappingURL=watch-DXXv3iAI.js.map