@bquery/bquery 1.3.0 → 1.5.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 (138) hide show
  1. package/README.md +546 -501
  2. package/dist/component/component.d.ts.map +1 -1
  3. package/dist/component/index.d.ts +2 -0
  4. package/dist/component/index.d.ts.map +1 -1
  5. package/dist/component/library.d.ts +34 -0
  6. package/dist/component/library.d.ts.map +1 -0
  7. package/dist/component/types.d.ts +10 -6
  8. package/dist/component/types.d.ts.map +1 -1
  9. package/dist/component-CY5MVoYN.js +531 -0
  10. package/dist/component-CY5MVoYN.js.map +1 -0
  11. package/dist/component.es.mjs +6 -184
  12. package/dist/config-DRmZZno3.js +40 -0
  13. package/dist/config-DRmZZno3.js.map +1 -0
  14. package/dist/core/collection.d.ts +19 -3
  15. package/dist/core/collection.d.ts.map +1 -1
  16. package/dist/core/element.d.ts +23 -4
  17. package/dist/core/element.d.ts.map +1 -1
  18. package/dist/core/index.d.ts +1 -0
  19. package/dist/core/index.d.ts.map +1 -1
  20. package/dist/core/utils/function.d.ts +21 -4
  21. package/dist/core/utils/function.d.ts.map +1 -1
  22. package/dist/core-CK2Mfpf4.js +648 -0
  23. package/dist/core-CK2Mfpf4.js.map +1 -0
  24. package/dist/core-DPdbItcq.js +112 -0
  25. package/dist/core-DPdbItcq.js.map +1 -0
  26. package/dist/core.es.mjs +45 -1218
  27. package/dist/full.d.ts +6 -6
  28. package/dist/full.d.ts.map +1 -1
  29. package/dist/full.es.mjs +98 -92
  30. package/dist/full.iife.js +173 -3
  31. package/dist/full.iife.js.map +1 -1
  32. package/dist/full.umd.js +173 -3
  33. package/dist/full.umd.js.map +1 -1
  34. package/dist/index.es.mjs +143 -139
  35. package/dist/motion/transition.d.ts +1 -1
  36. package/dist/motion/transition.d.ts.map +1 -1
  37. package/dist/motion/types.d.ts +11 -1
  38. package/dist/motion/types.d.ts.map +1 -1
  39. package/dist/motion-C5DRdPnO.js +415 -0
  40. package/dist/motion-C5DRdPnO.js.map +1 -0
  41. package/dist/motion.es.mjs +25 -361
  42. package/dist/object-qGpWr6-J.js +38 -0
  43. package/dist/object-qGpWr6-J.js.map +1 -0
  44. package/dist/platform/announcer.d.ts +59 -0
  45. package/dist/platform/announcer.d.ts.map +1 -0
  46. package/dist/platform/config.d.ts +92 -0
  47. package/dist/platform/config.d.ts.map +1 -0
  48. package/dist/platform/cookies.d.ts +45 -0
  49. package/dist/platform/cookies.d.ts.map +1 -0
  50. package/dist/platform/index.d.ts +8 -0
  51. package/dist/platform/index.d.ts.map +1 -1
  52. package/dist/platform/meta.d.ts +62 -0
  53. package/dist/platform/meta.d.ts.map +1 -0
  54. package/dist/platform/storage.d.ts.map +1 -1
  55. package/dist/platform-B7JhGBc7.js +361 -0
  56. package/dist/platform-B7JhGBc7.js.map +1 -0
  57. package/dist/platform.es.mjs +11 -243
  58. package/dist/reactive/async-data.d.ts +114 -0
  59. package/dist/reactive/async-data.d.ts.map +1 -0
  60. package/dist/reactive/core.d.ts +12 -0
  61. package/dist/reactive/core.d.ts.map +1 -1
  62. package/dist/reactive/effect.d.ts.map +1 -1
  63. package/dist/reactive/index.d.ts +2 -2
  64. package/dist/reactive/index.d.ts.map +1 -1
  65. package/dist/reactive/internals.d.ts +6 -0
  66. package/dist/reactive/internals.d.ts.map +1 -1
  67. package/dist/reactive/signal.d.ts +2 -0
  68. package/dist/reactive/signal.d.ts.map +1 -1
  69. package/dist/reactive-BDya-ia8.js +253 -0
  70. package/dist/reactive-BDya-ia8.js.map +1 -0
  71. package/dist/reactive.es.mjs +18 -34
  72. package/dist/router-CijiICxt.js +188 -0
  73. package/dist/router-CijiICxt.js.map +1 -0
  74. package/dist/router.es.mjs +11 -200
  75. package/dist/sanitize-jyJ2ryE2.js +302 -0
  76. package/dist/sanitize-jyJ2ryE2.js.map +1 -0
  77. package/dist/security/constants.d.ts.map +1 -1
  78. package/dist/security/sanitize-core.d.ts.map +1 -1
  79. package/dist/security.es.mjs +10 -56
  80. package/dist/store-CPK9E62U.js +262 -0
  81. package/dist/store-CPK9E62U.js.map +1 -0
  82. package/dist/store.es.mjs +12 -25
  83. package/dist/view/evaluate.d.ts.map +1 -1
  84. package/dist/view-Cdi0g-qo.js +396 -0
  85. package/dist/view-Cdi0g-qo.js.map +1 -0
  86. package/dist/view.es.mjs +10 -424
  87. package/package.json +136 -132
  88. package/src/component/component.ts +319 -289
  89. package/src/component/index.ts +42 -40
  90. package/src/component/library.ts +504 -0
  91. package/src/component/types.ts +91 -85
  92. package/src/core/collection.ts +44 -4
  93. package/src/core/element.ts +33 -5
  94. package/src/core/index.ts +1 -0
  95. package/src/core/utils/function.ts +56 -15
  96. package/src/full.ts +223 -187
  97. package/src/motion/transition.ts +97 -51
  98. package/src/motion/types.ts +208 -198
  99. package/src/platform/announcer.ts +208 -0
  100. package/src/platform/config.ts +163 -0
  101. package/src/platform/cookies.ts +165 -0
  102. package/src/platform/index.ts +39 -18
  103. package/src/platform/meta.ts +168 -0
  104. package/src/platform/storage.ts +8 -1
  105. package/src/reactive/async-data.ts +486 -0
  106. package/src/reactive/core.ts +21 -0
  107. package/src/reactive/effect.ts +18 -7
  108. package/src/reactive/index.ts +37 -23
  109. package/src/reactive/internals.ts +18 -1
  110. package/src/reactive/signal.ts +29 -20
  111. package/src/security/constants.ts +211 -209
  112. package/src/security/sanitize-core.ts +22 -1
  113. package/src/view/evaluate.ts +29 -13
  114. package/dist/batch-4LAvfLE7.js +0 -13
  115. package/dist/batch-4LAvfLE7.js.map +0 -1
  116. package/dist/component.es.mjs.map +0 -1
  117. package/dist/core-COenAZjD.js +0 -145
  118. package/dist/core-COenAZjD.js.map +0 -1
  119. package/dist/core.es.mjs.map +0 -1
  120. package/dist/full.es.mjs.map +0 -1
  121. package/dist/index.es.mjs.map +0 -1
  122. package/dist/motion.es.mjs.map +0 -1
  123. package/dist/persisted-Dz_ryNuC.js +0 -278
  124. package/dist/persisted-Dz_ryNuC.js.map +0 -1
  125. package/dist/platform.es.mjs.map +0 -1
  126. package/dist/reactive.es.mjs.map +0 -1
  127. package/dist/router.es.mjs.map +0 -1
  128. package/dist/sanitize-1FBEPAFH.js +0 -272
  129. package/dist/sanitize-1FBEPAFH.js.map +0 -1
  130. package/dist/security.es.mjs.map +0 -1
  131. package/dist/store.es.mjs.map +0 -1
  132. package/dist/type-guards-DRma3-Kc.js +0 -16
  133. package/dist/type-guards-DRma3-Kc.js.map +0 -1
  134. package/dist/untrack-BuEQKH7_.js +0 -6
  135. package/dist/untrack-BuEQKH7_.js.map +0 -1
  136. package/dist/view.es.mjs.map +0 -1
  137. package/dist/watch-CXyaBC_9.js +0 -58
  138. package/dist/watch-CXyaBC_9.js.map +0 -1
@@ -1,20 +1,29 @@
1
- /**
2
- * Reactive primitives inspired by fine-grained reactivity.
3
- *
4
- * @module bquery/reactive
5
- */
6
-
7
- export { batch } from './batch';
8
- export { Computed, computed } from './computed';
9
- export { Signal, signal } from './core';
10
- export { effect } from './effect';
11
- export { linkedSignal } from './linked';
12
- export { persistedSignal } from './persisted';
13
- export { readonly } from './readonly';
14
- export { isComputed, isSignal } from './type-guards';
15
- export { untrack } from './untrack';
16
- export { watch } from './watch';
17
-
18
- export type { CleanupFn, Observer } from './internals';
19
- export type { LinkedSignal } from './linked';
20
- export type { ReadonlySignal } from './readonly';
1
+ /**
2
+ * Reactive primitives inspired by fine-grained reactivity.
3
+ *
4
+ * @module bquery/reactive
5
+ */
6
+
7
+ export { batch } from './batch';
8
+ export { createUseFetch, useAsyncData, useFetch } from './async-data';
9
+ export { Computed, computed } from './computed';
10
+ export { Signal, signal } from './core';
11
+ export { effect } from './effect';
12
+ export { linkedSignal } from './linked';
13
+ export { persistedSignal } from './persisted';
14
+ export { readonly } from './readonly';
15
+ export { isComputed, isSignal } from './type-guards';
16
+ export { untrack } from './untrack';
17
+ export { watch } from './watch';
18
+
19
+ export type { CleanupFn, Observer } from './internals';
20
+ export type {
21
+ AsyncDataState,
22
+ AsyncDataStatus,
23
+ AsyncWatchSource,
24
+ FetchInput,
25
+ UseAsyncDataOptions,
26
+ UseFetchOptions,
27
+ } from './async-data';
28
+ export type { LinkedSignal } from './linked';
29
+ export type { ReadonlySignal } from './readonly';
@@ -1,209 +1,211 @@
1
- /**
2
- * Security constants and safe lists.
3
- *
4
- * @module bquery/security
5
- */
6
-
7
- /**
8
- * Trusted Types policy name.
9
- */
10
- export const POLICY_NAME = 'bquery-sanitizer';
11
-
12
- /**
13
- * Default allowed HTML tags considered safe.
14
- */
15
- export const DEFAULT_ALLOWED_TAGS = new Set([
16
- 'a',
17
- 'abbr',
18
- 'address',
19
- 'article',
20
- 'aside',
21
- 'b',
22
- 'bdi',
23
- 'bdo',
24
- 'blockquote',
25
- 'br',
26
- 'button',
27
- 'caption',
28
- 'cite',
29
- 'code',
30
- 'col',
31
- 'colgroup',
32
- 'data',
33
- 'dd',
34
- 'del',
35
- 'details',
36
- 'dfn',
37
- 'div',
38
- 'dl',
39
- 'dt',
40
- 'em',
41
- 'figcaption',
42
- 'figure',
43
- 'footer',
44
- 'form',
45
- 'h1',
46
- 'h2',
47
- 'h3',
48
- 'h4',
49
- 'h5',
50
- 'h6',
51
- 'header',
52
- 'hgroup',
53
- 'hr',
54
- 'i',
55
- 'img',
56
- 'input',
57
- 'ins',
58
- 'kbd',
59
- 'label',
60
- 'legend',
61
- 'li',
62
- 'main',
63
- 'mark',
64
- 'nav',
65
- 'ol',
66
- 'optgroup',
67
- 'option',
68
- 'p',
69
- 'picture',
70
- 'pre',
71
- 'progress',
72
- 'q',
73
- 'rp',
74
- 'rt',
75
- 'ruby',
76
- 's',
77
- 'samp',
78
- 'section',
79
- 'select',
80
- 'small',
81
- 'source',
82
- 'span',
83
- 'strong',
84
- 'sub',
85
- 'summary',
86
- 'sup',
87
- 'table',
88
- 'tbody',
89
- 'td',
90
- 'textarea',
91
- 'tfoot',
92
- 'th',
93
- 'thead',
94
- 'time',
95
- 'tr',
96
- 'u',
97
- 'ul',
98
- 'var',
99
- 'wbr',
100
- ]);
101
-
102
- /**
103
- * Explicitly dangerous tags that should never be allowed.
104
- * These are checked even if somehow added to allowTags.
105
- */
106
- export const DANGEROUS_TAGS = new Set([
107
- 'script',
108
- 'iframe',
109
- 'frame',
110
- 'frameset',
111
- 'object',
112
- 'embed',
113
- 'applet',
114
- 'link',
115
- 'meta',
116
- 'style',
117
- 'base',
118
- 'template',
119
- 'slot',
120
- 'math',
121
- 'svg',
122
- 'foreignobject',
123
- 'noscript',
124
- ]);
125
-
126
- /**
127
- * Reserved IDs that could cause DOM clobbering attacks.
128
- * These are prevented to avoid overwriting global browser objects.
129
- */
130
- export const RESERVED_IDS = new Set([
131
- // Global objects
132
- 'document',
133
- 'window',
134
- 'location',
135
- 'top',
136
- 'self',
137
- 'parent',
138
- 'frames',
139
- 'history',
140
- 'navigator',
141
- 'screen',
142
- // Dangerous functions
143
- 'alert',
144
- 'confirm',
145
- 'prompt',
146
- 'eval',
147
- 'function',
148
- // Document properties
149
- 'cookie',
150
- 'domain',
151
- 'referrer',
152
- 'body',
153
- 'head',
154
- 'forms',
155
- 'images',
156
- 'links',
157
- 'scripts',
158
- // DOM traversal properties
159
- 'children',
160
- 'parentnode',
161
- 'firstchild',
162
- 'lastchild',
163
- // Content manipulation
164
- 'innerhtml',
165
- 'outerhtml',
166
- 'textcontent',
167
- ]);
168
-
169
- /**
170
- * Default allowed attributes considered safe.
171
- * Note: 'style' is excluded by default because inline CSS can be abused for:
172
- * - UI redressing attacks
173
- * - Data exfiltration via url() in CSS
174
- * - CSS injection vectors
175
- * If you need to allow inline styles, add 'style' to allowAttributes in your
176
- * sanitizeHtml options, but ensure you implement proper CSS value validation.
177
- */
178
- export const DEFAULT_ALLOWED_ATTRIBUTES = new Set([
179
- 'alt',
180
- 'class',
181
- 'dir',
182
- 'height',
183
- 'hidden',
184
- 'href',
185
- 'id',
186
- 'lang',
187
- 'loading',
188
- 'name',
189
- 'rel',
190
- 'role',
191
- 'src',
192
- 'srcset',
193
- 'tabindex',
194
- 'target',
195
- 'title',
196
- 'type',
197
- 'width',
198
- 'aria-*',
199
- ]);
200
-
201
- /**
202
- * Dangerous attribute prefixes to always remove.
203
- */
204
- export const DANGEROUS_ATTR_PREFIXES = ['on', 'formaction', 'xlink:', 'xmlns:'];
205
-
206
- /**
207
- * Dangerous URL protocols to block.
208
- */
209
- export const DANGEROUS_PROTOCOLS = ['javascript:', 'data:', 'vbscript:', 'file:'];
1
+ /**
2
+ * Security constants and safe lists.
3
+ *
4
+ * @module bquery/security
5
+ */
6
+
7
+ /**
8
+ * Trusted Types policy name.
9
+ */
10
+ export const POLICY_NAME = 'bquery-sanitizer';
11
+
12
+ /**
13
+ * Default allowed HTML tags considered safe.
14
+ */
15
+ export const DEFAULT_ALLOWED_TAGS = new Set([
16
+ 'a',
17
+ 'abbr',
18
+ 'address',
19
+ 'article',
20
+ 'aside',
21
+ 'b',
22
+ 'bdi',
23
+ 'bdo',
24
+ 'blockquote',
25
+ 'br',
26
+ 'button',
27
+ 'caption',
28
+ 'cite',
29
+ 'code',
30
+ 'col',
31
+ 'colgroup',
32
+ 'data',
33
+ 'dd',
34
+ 'del',
35
+ 'details',
36
+ 'dfn',
37
+ 'div',
38
+ 'dl',
39
+ 'dt',
40
+ 'em',
41
+ 'figcaption',
42
+ 'figure',
43
+ 'footer',
44
+ 'form',
45
+ 'h1',
46
+ 'h2',
47
+ 'h3',
48
+ 'h4',
49
+ 'h5',
50
+ 'h6',
51
+ 'header',
52
+ 'hgroup',
53
+ 'hr',
54
+ 'i',
55
+ 'img',
56
+ 'input',
57
+ 'ins',
58
+ 'kbd',
59
+ 'label',
60
+ 'legend',
61
+ 'li',
62
+ 'main',
63
+ 'mark',
64
+ 'nav',
65
+ 'ol',
66
+ 'optgroup',
67
+ 'option',
68
+ 'p',
69
+ 'picture',
70
+ 'pre',
71
+ 'progress',
72
+ 'q',
73
+ 'rp',
74
+ 'rt',
75
+ 'ruby',
76
+ 's',
77
+ 'samp',
78
+ 'section',
79
+ 'select',
80
+ 'small',
81
+ 'source',
82
+ 'span',
83
+ 'strong',
84
+ 'sub',
85
+ 'summary',
86
+ 'sup',
87
+ 'table',
88
+ 'tbody',
89
+ 'td',
90
+ 'textarea',
91
+ 'tfoot',
92
+ 'th',
93
+ 'thead',
94
+ 'time',
95
+ 'tr',
96
+ 'u',
97
+ 'ul',
98
+ 'var',
99
+ 'wbr',
100
+ ]);
101
+
102
+ /**
103
+ * Explicitly dangerous tags that should never be allowed.
104
+ * These are checked even if somehow added to allowTags.
105
+ */
106
+ export const DANGEROUS_TAGS = new Set([
107
+ 'script',
108
+ 'iframe',
109
+ 'frame',
110
+ 'frameset',
111
+ 'object',
112
+ 'embed',
113
+ 'applet',
114
+ 'link',
115
+ 'meta',
116
+ 'style',
117
+ 'base',
118
+ 'template',
119
+ // 'slot' is intentionally excluded here so component shadow markup can opt in
120
+ // via sanitizeHtml(..., { allowTags: ['slot'] }). It remains disallowed by default
121
+ // for general HTML writes, because DEFAULT_ALLOWED_TAGS does not include it.
122
+ 'math',
123
+ 'svg',
124
+ 'foreignobject',
125
+ 'noscript',
126
+ ]);
127
+
128
+ /**
129
+ * Reserved IDs that could cause DOM clobbering attacks.
130
+ * These are prevented to avoid overwriting global browser objects.
131
+ */
132
+ export const RESERVED_IDS = new Set([
133
+ // Global objects
134
+ 'document',
135
+ 'window',
136
+ 'location',
137
+ 'top',
138
+ 'self',
139
+ 'parent',
140
+ 'frames',
141
+ 'history',
142
+ 'navigator',
143
+ 'screen',
144
+ // Dangerous functions
145
+ 'alert',
146
+ 'confirm',
147
+ 'prompt',
148
+ 'eval',
149
+ 'function',
150
+ // Document properties
151
+ 'cookie',
152
+ 'domain',
153
+ 'referrer',
154
+ 'body',
155
+ 'head',
156
+ 'forms',
157
+ 'images',
158
+ 'links',
159
+ 'scripts',
160
+ // DOM traversal properties
161
+ 'children',
162
+ 'parentnode',
163
+ 'firstchild',
164
+ 'lastchild',
165
+ // Content manipulation
166
+ 'innerhtml',
167
+ 'outerhtml',
168
+ 'textcontent',
169
+ ]);
170
+
171
+ /**
172
+ * Default allowed attributes considered safe.
173
+ * Note: 'style' is excluded by default because inline CSS can be abused for:
174
+ * - UI redressing attacks
175
+ * - Data exfiltration via url() in CSS
176
+ * - CSS injection vectors
177
+ * If you need to allow inline styles, add 'style' to allowAttributes in your
178
+ * sanitizeHtml options, but ensure you implement proper CSS value validation.
179
+ */
180
+ export const DEFAULT_ALLOWED_ATTRIBUTES = new Set([
181
+ 'alt',
182
+ 'class',
183
+ 'dir',
184
+ 'height',
185
+ 'hidden',
186
+ 'href',
187
+ 'id',
188
+ 'lang',
189
+ 'loading',
190
+ 'name',
191
+ 'rel',
192
+ 'role',
193
+ 'src',
194
+ 'srcset',
195
+ 'tabindex',
196
+ 'target',
197
+ 'title',
198
+ 'type',
199
+ 'width',
200
+ 'aria-*',
201
+ ]);
202
+
203
+ /**
204
+ * Dangerous attribute prefixes to always remove.
205
+ */
206
+ export const DANGEROUS_ATTR_PREFIXES = ['on', 'formaction', 'xlink:', 'xmlns:'];
207
+
208
+ /**
209
+ * Dangerous URL protocols to block.
210
+ */
211
+ export const DANGEROUS_PROTOCOLS = ['javascript:', 'data:', 'vbscript:', 'file:'];
@@ -80,6 +80,21 @@ const isSafeUrl = (value: string): boolean => {
80
80
  return true;
81
81
  };
82
82
 
83
+ /**
84
+ * Check if a srcset attribute value is safe.
85
+ * srcset contains comma-separated entries of "url [descriptor]".
86
+ * Each individual URL must be validated.
87
+ * @internal
88
+ */
89
+ const isSafeSrcset = (value: string): boolean => {
90
+ const entries = value.split(',');
91
+ for (const entry of entries) {
92
+ const url = entry.trim().split(/\s+/)[0];
93
+ if (url && !isSafeUrl(url)) return false;
94
+ }
95
+ return true;
96
+ };
97
+
83
98
  /**
84
99
  * Check if a URL is external (different origin).
85
100
  * @internal
@@ -275,10 +290,16 @@ export const sanitizeHtmlCore = (html: string, options: SanitizeOptions = {}): s
275
290
 
276
291
  // Validate URL attributes
277
292
  if (
278
- (attrName === 'href' || attrName === 'src' || attrName === 'srcset') &&
293
+ (attrName === 'href' || attrName === 'src' || attrName === 'action') &&
279
294
  !isSafeUrl(attr.value)
280
295
  ) {
281
296
  attrsToRemove.push(attr.name);
297
+ continue;
298
+ }
299
+
300
+ // Validate srcset URLs individually
301
+ if (attrName === 'srcset' && !isSafeSrcset(attr.value)) {
302
+ attrsToRemove.push(attr.name);
282
303
  }
283
304
  }
284
305
 
@@ -188,14 +188,23 @@ export const parseObjectExpression = (expression: string): Record<string, string
188
188
 
189
189
  for (let i = 0; i < inner.length; i++) {
190
190
  const char = inner[i];
191
- const prevChar = i > 0 ? inner[i - 1] : '';
192
191
 
193
- // Handle string literals (including escape sequences)
194
- if ((char === '"' || char === "'" || char === '`') && prevChar !== '\\') {
195
- if (inString === null) {
196
- inString = char;
197
- } else if (inString === char) {
198
- inString = null;
192
+ // Handle string literals: count consecutive backslashes before a quote
193
+ // to correctly distinguish escaped quotes from end-of-string
194
+ if (char === '"' || char === "'" || char === '`') {
195
+ let backslashCount = 0;
196
+ let j = i - 1;
197
+ while (j >= 0 && inner[j] === '\\') {
198
+ backslashCount++;
199
+ j--;
200
+ }
201
+ // Quote is escaped only if preceded by an odd number of backslashes
202
+ if (backslashCount % 2 === 0) {
203
+ if (inString === null) {
204
+ inString = char;
205
+ } else if (inString === char) {
206
+ inString = null;
207
+ }
199
208
  }
200
209
  current += char;
201
210
  continue;
@@ -237,13 +246,20 @@ export const parseObjectExpression = (expression: string): Record<string, string
237
246
 
238
247
  for (let i = 0; i < part.length; i++) {
239
248
  const char = part[i];
240
- const prevChar = i > 0 ? part[i - 1] : '';
241
249
 
242
- if ((char === '"' || char === "'" || char === '`') && prevChar !== '\\') {
243
- if (partInString === null) {
244
- partInString = char;
245
- } else if (partInString === char) {
246
- partInString = null;
250
+ if (char === '"' || char === "'" || char === '`') {
251
+ let backslashCount = 0;
252
+ let j = i - 1;
253
+ while (j >= 0 && part[j] === '\\') {
254
+ backslashCount++;
255
+ j--;
256
+ }
257
+ if (backslashCount % 2 === 0) {
258
+ if (partInString === null) {
259
+ partInString = char;
260
+ } else if (partInString === char) {
261
+ partInString = null;
262
+ }
247
263
  }
248
264
  continue;
249
265
  }
@@ -1,13 +0,0 @@
1
- import { e as t, b } from "./core-COenAZjD.js";
2
- const e = (a) => {
3
- b();
4
- try {
5
- a();
6
- } finally {
7
- t();
8
- }
9
- };
10
- export {
11
- e as b
12
- };
13
- //# sourceMappingURL=batch-4LAvfLE7.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"batch-4LAvfLE7.js","sources":["../src/reactive/batch.ts"],"sourcesContent":["/**\n * Batched reactive updates.\n */\n\nimport { beginBatch, endBatch } from './internals';\n\n/**\n * Batches multiple signal updates into a single notification cycle.\n *\n * Updates made inside the batch function are deferred until the batch\n * completes, preventing intermediate re-renders and improving performance.\n *\n * @param fn - Function containing multiple signal updates\n */\nexport const batch = (fn: () => void): void => {\n beginBatch();\n try {\n fn();\n } finally {\n endBatch();\n }\n};\n"],"names":["batch","fn","beginBatch","endBatch"],"mappings":";AAcO,MAAMA,IAAQ,CAACC,MAAyB;AAC7C,EAAAC,EAAA;AACA,MAAI;AACF,IAAAD,EAAA;AAAA,EACF,UAAA;AACE,IAAAE,EAAA;AAAA,EACF;AACF;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"component.es.mjs","sources":["../src/component/props.ts","../src/component/component.ts","../src/component/html.ts"],"sourcesContent":["/**\n * Prop coercion utilities.\n *\n * @module bquery/component\n */\n\nimport type { PropDefinition } from './types';\n\n/**\n * Coerces a string attribute value into a typed prop value.\n * Supports String, Number, Boolean, Object, Array, and custom converters.\n *\n * @internal\n * @template T - The target type\n * @param rawValue - The raw string value from the attribute\n * @param config - The prop definition with type information\n * @returns The coerced value of type T\n */\nexport const coercePropValue = <T>(rawValue: string, config: PropDefinition<T>): T => {\n const { type } = config;\n\n if (type === String) return rawValue as T;\n\n if (type === Number) {\n return Number(rawValue) as T;\n }\n\n if (type === Boolean) {\n const normalized = rawValue.trim().toLowerCase();\n if (normalized === '' || normalized === 'true' || normalized === '1') {\n return true as T;\n }\n if (normalized === 'false' || normalized === '0') {\n return false as T;\n }\n return Boolean(rawValue) as T;\n }\n\n if (type === Object || type === Array) {\n try {\n return JSON.parse(rawValue) as T;\n } catch {\n return rawValue as T;\n }\n }\n\n if (typeof type === 'function') {\n const callable = type as (value: unknown) => T;\n const constructable = type as new (value: unknown) => T;\n\n // Explicit construct mode takes precedence\n if (config.construct === true) {\n return Reflect.construct(constructable, [rawValue]) as T;\n }\n if (config.construct === false) {\n return callable(rawValue);\n }\n\n // Auto-detect: Check if type is constructable\n // A function is considered constructable if:\n // 1. It has a prototype with properties beyond just constructor, OR\n // 2. Its prototype.constructor is not itself (inherited), OR\n // 3. It's a class (toString starts with \"class\")\n const hasPrototype = type.prototype !== undefined && type.prototype !== null;\n const prototypeProps = hasPrototype ? Object.getOwnPropertyNames(type.prototype) : [];\n const hasPrototypeMethods = prototypeProps.length > 1;\n const hasInheritedConstructor = hasPrototype && type.prototype.constructor !== type;\n const isClassSyntax = /^class\\s/.test(Function.prototype.toString.call(type));\n\n const isConstructable = hasPrototypeMethods || hasInheritedConstructor || isClassSyntax;\n\n // For constructable types (e.g. Date, custom classes), prefer `new` to avoid\n // silent wrong-type returns (Date() returns string, new Date() returns Date)\n if (isConstructable) {\n try {\n return Reflect.construct(constructable, [rawValue]) as T;\n } catch {\n // Fall back to calling as function if construction fails\n return callable(rawValue);\n }\n }\n\n // For non-constructable types (arrow functions, plain functions), call directly\n // but fall back to constructor if result is undefined (common for function constructors)\n try {\n const result = callable(rawValue);\n\n // If calling without `new` returned undefined and the function has a prototype,\n // it's likely a function constructor that should be called with `new`\n if (result === undefined && hasPrototype) {\n try {\n return Reflect.construct(constructable, [rawValue]) as T;\n } catch {\n // Construction also failed, return the undefined\n return result as T;\n }\n }\n\n return result as T;\n } catch (error) {\n // Fall back to constructor if error indicates 'new' is required\n const isNewRequired =\n error instanceof TypeError &&\n /cannot be invoked without 'new'|is not a function/i.test(error.message);\n\n if (isNewRequired) {\n return Reflect.construct(constructable, [rawValue]) as T;\n }\n\n // Rethrow original error for non-constructable converters\n throw error;\n }\n }\n\n return rawValue as T;\n};\n","/**\n * Web Component factory and registry.\n *\n * @module bquery/component\n */\n\nimport { sanitizeHtml } from '../security/sanitize';\nimport { coercePropValue } from './props';\nimport type { ComponentDefinition, PropDefinition } from './types';\n\n/**\n * Creates a custom element class for a component definition.\n *\n * This is useful when you want to extend or register the class manually\n * (e.g. with different tag names in tests or custom registries).\n *\n * @template TProps - Type of the component's props\n * @param tagName - The custom element tag name (used for diagnostics)\n * @param definition - The component configuration\n */\nexport const defineComponent = <TProps extends Record<string, unknown>>(\n tagName: string,\n definition: ComponentDefinition<TProps>\n): typeof HTMLElement => {\n class BQueryComponent extends HTMLElement {\n /** Internal state object for the component */\n private readonly state = { ...(definition.state ?? {}) };\n /** Typed props object populated from attributes */\n private props = {} as TProps;\n /** Tracks missing required props for validation during connectedCallback */\n private missingRequiredProps = new Set<string>();\n /** Tracks whether the component has completed its initial mount */\n private hasMounted = false;\n\n constructor() {\n super();\n this.attachShadow({ mode: 'open' });\n this.syncProps();\n }\n\n /**\n * Returns the list of attributes to observe for changes.\n */\n static get observedAttributes(): string[] {\n return Object.keys(definition.props ?? {});\n }\n\n /**\n * Called when the element is added to the DOM.\n */\n connectedCallback(): void {\n try {\n // Defer initial render until all required props are present\n // This allows attributes to be set after element creation\n if (this.missingRequiredProps.size > 0) {\n // Component will mount once all required props are satisfied\n // via attributeChangedCallback\n return;\n }\n this.mount();\n } catch (error) {\n this.handleError(error as Error);\n }\n }\n\n /**\n * Performs the initial mount of the component.\n * Called when the element is connected and all required props are present.\n * @internal\n */\n private mount(): void {\n if (this.hasMounted) return;\n definition.beforeMount?.call(this);\n definition.connected?.call(this);\n this.render();\n this.hasMounted = true;\n }\n\n /**\n * Called when the element is removed from the DOM.\n */\n disconnectedCallback(): void {\n try {\n definition.disconnected?.call(this);\n } catch (error) {\n this.handleError(error as Error);\n }\n }\n\n /**\n * Called when an observed attribute changes.\n */\n attributeChangedCallback(\n _name: string,\n _oldValue: string | null,\n _newValue: string | null\n ): void {\n try {\n this.syncProps();\n\n if (this.hasMounted) {\n // Component already mounted - trigger update render\n this.render(true);\n } else if (this.isConnected && this.missingRequiredProps.size === 0) {\n // All required props are now satisfied and element is connected\n // Trigger the deferred initial mount\n this.mount();\n }\n } catch (error) {\n this.handleError(error as Error);\n }\n }\n\n /**\n * Handles errors during component lifecycle.\n * @internal\n */\n private handleError(error: Error): void {\n if (definition.onError) {\n definition.onError.call(this, error);\n } else {\n console.error(`bQuery component error in <${tagName}>:`, error);\n }\n }\n\n /**\n * Updates a state property and triggers a re-render.\n *\n * @param key - The state property key\n * @param value - The new value\n */\n setState(key: string, value: unknown): void {\n this.state[key] = value;\n this.render(true);\n }\n\n /**\n * Gets a state property value.\n *\n * @param key - The state property key\n * @returns The current value\n */\n getState<T = unknown>(key: string): T {\n return this.state[key] as T;\n }\n\n /**\n * Synchronizes props from attributes.\n * @internal\n */\n private syncProps(): void {\n const props = definition.props ?? {};\n for (const [key, config] of Object.entries(props) as [string, PropDefinition][]) {\n const attrValue = this.getAttribute(key);\n let value: unknown;\n\n if (attrValue == null) {\n if (config.required && config.default === undefined) {\n // Mark as missing instead of throwing - validate during connectedCallback\n this.missingRequiredProps.add(key);\n value = undefined;\n } else {\n value = config.default ?? undefined;\n }\n } else {\n // Attribute is present, remove from missing set if it was there\n if (this.missingRequiredProps.has(key)) {\n this.missingRequiredProps.delete(key);\n }\n value = coercePropValue(attrValue, config);\n }\n\n if (config.validator && value !== undefined) {\n const isValid = config.validator(value);\n if (!isValid) {\n throw new Error(\n `bQuery component: validation failed for prop \"${key}\" with value ${JSON.stringify(value)}`\n );\n }\n }\n\n (this.props as Record<string, unknown>)[key] = value;\n }\n }\n\n /**\n * Renders the component to its shadow root.\n * @internal\n */\n private render(triggerUpdated = false): void {\n try {\n if (triggerUpdated && definition.beforeUpdate) {\n const shouldUpdate = definition.beforeUpdate.call(this, this.props);\n if (shouldUpdate === false) return;\n }\n\n const emit = (event: string, detail?: unknown): void => {\n this.dispatchEvent(new CustomEvent(event, { detail, bubbles: true, composed: true }));\n };\n\n if (!this.shadowRoot) return;\n\n const markup = definition.render({\n props: this.props,\n state: this.state,\n emit,\n });\n\n const sanitizedMarkup = sanitizeHtml(markup);\n this.shadowRoot.innerHTML = sanitizedMarkup;\n\n if (definition.styles) {\n const styleElement = document.createElement('style');\n styleElement.textContent = definition.styles;\n this.shadowRoot.prepend(styleElement);\n }\n\n if (triggerUpdated) {\n definition.updated?.call(this);\n }\n } catch (error) {\n this.handleError(error as Error);\n }\n }\n }\n\n return BQueryComponent;\n};\n\n/**\n * Defines and registers a custom Web Component.\n *\n * This function creates a new custom element with the given tag name\n * and configuration. The component uses Shadow DOM for encapsulation\n * and automatically re-renders when observed attributes change.\n *\n * @template TProps - Type of the component's props\n * @param tagName - The custom element tag name (must contain a hyphen)\n * @param definition - The component configuration\n *\n * @example\n * ```ts\n * component('counter-button', {\n * props: {\n * start: { type: Number, default: 0 },\n * },\n * state: { count: 0 },\n * styles: `\n * button { padding: 0.5rem 1rem; }\n * `,\n * connected() {\n * // Use event delegation on shadow root so handler survives re-renders\n * const handleClick = (event: Event) => {\n * const target = event.target as HTMLElement | null;\n * if (target?.matches('button')) {\n * this.setState('count', (this.getState('count') as number) + 1);\n * }\n * };\n * this.shadowRoot?.addEventListener('click', handleClick);\n * // Store handler for cleanup\n * (this as any)._handleClick = handleClick;\n * },\n * disconnected() {\n * // Clean up event listener to prevent memory leaks\n * const handleClick = (this as any)._handleClick;\n * if (handleClick) {\n * this.shadowRoot?.removeEventListener('click', handleClick);\n * }\n * },\n * render({ props, state }) {\n * return html`\n * <button>\n * Count: ${state.count}\n * </button>\n * `;\n * },\n * });\n * ```\n */\nexport const component = <TProps extends Record<string, unknown>>(\n tagName: string,\n definition: ComponentDefinition<TProps>\n): void => {\n const elementClass = defineComponent(tagName, definition);\n\n if (!customElements.get(tagName)) {\n customElements.define(tagName, elementClass);\n }\n};\n","/**\n * Tagged template literal for creating HTML strings.\n *\n * This function handles interpolation of values into HTML templates,\n * converting null/undefined to empty strings.\n *\n * @param strings - Template literal string parts\n * @param values - Interpolated values\n * @returns Combined HTML string\n *\n * @example\n * ```ts\n * const name = 'World';\n * const greeting = html`<h1>Hello, ${name}!</h1>`;\n * // Result: '<h1>Hello, World!</h1>'\n * ```\n */\nexport const html = (strings: TemplateStringsArray, ...values: unknown[]): string => {\n return strings.reduce((acc, part, index) => `${acc}${part}${values[index] ?? ''}`, '');\n};\n\n/**\n * Escapes HTML entities in interpolated values for XSS prevention.\n * Use this when you need to safely embed user content in templates.\n *\n * @param strings - Template literal string parts\n * @param values - Interpolated values to escape\n * @returns Combined HTML string with escaped values\n *\n * @example\n * ```ts\n * const userInput = '<script>alert(\"xss\")</script>';\n * const safe = safeHtml`<div>${userInput}</div>`;\n * // Result: '<div>&lt;script&gt;alert(\"xss\")&lt;/script&gt;</div>'\n * ```\n */\nexport const safeHtml = (strings: TemplateStringsArray, ...values: unknown[]): string => {\n const escapeMap: Record<string, string> = {\n '&': '&amp;',\n '<': '&lt;',\n '>': '&gt;',\n '\"': '&quot;',\n \"'\": '&#x27;',\n '`': '&#x60;',\n };\n\n const escape = (value: unknown): string => {\n const str = String(value ?? '');\n return str.replace(/[&<>\"'`]/g, (char) => escapeMap[char]);\n };\n\n return strings.reduce((acc, part, index) => `${acc}${part}${escape(values[index])}`, '');\n};\n"],"names":["coercePropValue","rawValue","config","type","normalized","callable","constructable","hasPrototype","hasPrototypeMethods","hasInheritedConstructor","isClassSyntax","result","error","defineComponent","tagName","definition","BQueryComponent","_name","_oldValue","_newValue","key","value","props","attrValue","triggerUpdated","emit","event","detail","markup","sanitizedMarkup","sanitizeHtml","styleElement","component","elementClass","html","strings","values","acc","part","index","safeHtml","escapeMap","escape","char"],"mappings":"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"}