@bquery/bquery 1.0.1 → 1.1.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 (41) hide show
  1. package/README.md +79 -25
  2. package/dist/component/index.d.ts +8 -0
  3. package/dist/component/index.d.ts.map +1 -1
  4. package/dist/component.es.mjs +80 -53
  5. package/dist/component.es.mjs.map +1 -1
  6. package/dist/core/collection.d.ts +46 -0
  7. package/dist/core/collection.d.ts.map +1 -1
  8. package/dist/core/element.d.ts +124 -22
  9. package/dist/core/element.d.ts.map +1 -1
  10. package/dist/core/utils.d.ts +13 -0
  11. package/dist/core/utils.d.ts.map +1 -1
  12. package/dist/core.es.mjs +298 -55
  13. package/dist/core.es.mjs.map +1 -1
  14. package/dist/full.d.ts +2 -2
  15. package/dist/full.d.ts.map +1 -1
  16. package/dist/full.es.mjs +38 -33
  17. package/dist/full.iife.js +1 -1
  18. package/dist/full.iife.js.map +1 -1
  19. package/dist/full.umd.js +1 -1
  20. package/dist/full.umd.js.map +1 -1
  21. package/dist/index.d.ts +1 -1
  22. package/dist/index.es.mjs +38 -33
  23. package/dist/reactive/index.d.ts +2 -2
  24. package/dist/reactive/index.d.ts.map +1 -1
  25. package/dist/reactive/signal.d.ts +107 -0
  26. package/dist/reactive/signal.d.ts.map +1 -1
  27. package/dist/reactive.es.mjs +92 -55
  28. package/dist/reactive.es.mjs.map +1 -1
  29. package/dist/security/sanitize.d.ts.map +1 -1
  30. package/dist/security.es.mjs +136 -66
  31. package/dist/security.es.mjs.map +1 -1
  32. package/package.json +120 -120
  33. package/src/component/index.ts +414 -360
  34. package/src/core/collection.ts +454 -339
  35. package/src/core/element.ts +740 -493
  36. package/src/core/utils.ts +444 -425
  37. package/src/full.ts +106 -101
  38. package/src/index.ts +27 -27
  39. package/src/reactive/index.ts +22 -9
  40. package/src/reactive/signal.ts +506 -347
  41. package/src/security/sanitize.ts +553 -446
package/README.md CHANGED
@@ -1,12 +1,19 @@
1
- # bQuery.js
1
+ <p align="center">
2
+ <img src="assets/bquerry-logo.svg" alt="bQuery.js Logo" width="120" />
3
+ </p>
2
4
 
3
- [![Repo](https://img.shields.io/badge/github-bquery%2Fbquery-24292f?logo=github)](https://github.com/bquery/bquery)
4
- [![Stars](https://img.shields.io/github/stars/bquery/bquery?style=flat&logo=github)](https://github.com/bquery/bquery/stargazers)
5
- [![Issues](https://img.shields.io/github/issues/bquery/bquery?style=flat&logo=github)](https://github.com/bquery/bquery/issues)
6
- [![License](https://img.shields.io/github/license/bquery/bquery?style=flat)](https://github.com/bquery/bquery/blob/main/LICENSE.md)
5
+ <h1 align="center">bQuery.js</h1>
6
+
7
+ <p align="center">
8
+
9
+ [![Repo](https://img.shields.io/badge/github-bquery%2Fbquery-24292f?logo=github)](https://github.com/bQuery/bQuery)
10
+ [![Stars](https://img.shields.io/github/stars/bquery/bquery?style=flat&logo=github)](https://github.com/bQuery/bQuery/stargazers)
11
+ [![Issues](https://img.shields.io/github/issues/bquery/bquery?style=flat&logo=github)](https://github.com/bQuery/bQuery/issues)
12
+ [![License](https://img.shields.io/github/license/bquery/bquery?style=flat)](https://github.com/bQuery/bQuery/blob/main/LICENSE.md)
7
13
  [![npm](https://img.shields.io/npm/v/@bquery/bquery)](https://www.npmjs.com/package/@bquery/bquery)
8
14
  [![Bundle Size](https://img.shields.io/bundlephobia/minzip/@bquery/bquery)](https://bundlephobia.com/package/@bquery/bquery)
9
15
  [![unpkg](https://img.shields.io/badge/unpkg-browse-blue?logo=unpkg)](https://unpkg.com/@bquery/bquery)
16
+ [![CodeFactor](https://www.codefactor.io/repository/github/bquery/bquery/badge)](https://www.codefactor.io/repository/github/bquery/bquery)
10
17
 
11
18
  **The jQuery for the modern Web Platform.**
12
19
 
@@ -26,13 +33,13 @@ bQuery.js is a slim, TypeScript-first library that combines jQuery's direct DOM
26
33
 
27
34
  ```bash
28
35
  # npm
29
- npm install bquery
36
+ npm install @bquery/bquery
30
37
 
31
38
  # bun
32
- bun add bquery
39
+ bun add @bquery/bquery
33
40
 
34
41
  # pnpm
35
- pnpm add bquery
42
+ pnpm add @bquery/bquery
36
43
  ```
37
44
 
38
45
  ### Via CDN (Zero-build)
@@ -41,7 +48,7 @@ pnpm add bquery
41
48
 
42
49
  ```html
43
50
  <script type="module">
44
- import { $, signal } from 'https://unpkg.com/bquery@1/dist/full.es.mjs';
51
+ import { $, signal } from 'https://unpkg.com/@bquery/bquery@1/dist/full.es.mjs';
45
52
 
46
53
  const count = signal(0);
47
54
  $('#counter').text(`Count: ${count.value}`);
@@ -51,7 +58,7 @@ pnpm add bquery
51
58
  #### UMD (global variable)
52
59
 
53
60
  ```html
54
- <script src="https://unpkg.com/bquery@1/dist/full.umd.js"></script>
61
+ <script src="https://unpkg.com/@bquery/bquery@1/dist/full.umd.js"></script>
55
62
  <script>
56
63
  const { $, signal } = bQuery;
57
64
  const count = signal(0);
@@ -61,7 +68,7 @@ pnpm add bquery
61
68
  #### IIFE (self-executing)
62
69
 
63
70
  ```html
64
- <script src="https://unpkg.com/bquery@1/dist/full.iife.js"></script>
71
+ <script src="https://unpkg.com/@bquery/bquery@1/dist/full.iife.js"></script>
65
72
  <script>
66
73
  const { $, $$ } = bQuery;
67
74
  $$('.items').addClass('loaded');
@@ -72,17 +79,17 @@ pnpm add bquery
72
79
 
73
80
  ```ts
74
81
  // Full bundle (all modules)
75
- import { $, signal, component } from 'bquery';
82
+ import { $, signal, component } from '@bquery/bquery';
76
83
 
77
84
  // Core only
78
- import { $, $$ } from 'bquery/core';
85
+ import { $, $$ } from '@bquery/bquery/core';
79
86
 
80
87
  // À la carte (individual modules)
81
- import { signal, computed, effect } from 'bquery/reactive';
82
- import { component, html } from 'bquery/component';
83
- import { transition, spring } from 'bquery/motion';
84
- import { sanitize } from 'bquery/security';
85
- import { storage, cache } from 'bquery/platform';
88
+ import { signal, computed, effect } from '@bquery/bquery/reactive';
89
+ import { component, html } from '@bquery/bquery/component';
90
+ import { transition, spring } from '@bquery/bquery/motion';
91
+ import { sanitize } from '@bquery/bquery/security';
92
+ import { storage, cache } from '@bquery/bquery/platform';
86
93
  ```
87
94
 
88
95
  ## Modules at a glance
@@ -101,16 +108,32 @@ import { storage, cache } from 'bquery/platform';
101
108
  ### Core – DOM & events
102
109
 
103
110
  ```ts
104
- import { $, $$ } from 'bquery/core';
111
+ import { $, $$ } from '@bquery/bquery/core';
105
112
 
106
113
  // jQuery-style selectors
107
114
  $('#save').on('click', (event) => {
108
115
  console.log('Saved', event.type);
109
116
  });
110
117
 
118
+ // Event delegation for dynamic content
119
+ $('#list').delegate('click', '.item', (event, target) => {
120
+ console.log('Item clicked', target.textContent);
121
+ });
122
+
111
123
  // Method chaining
112
124
  $('#box').addClass('active').css({ opacity: '0.8' }).attr('data-state', 'ready');
113
125
 
126
+ // DOM manipulation
127
+ $('#content').wrap('<div class="wrapper"></div>');
128
+ $('#wrapper').unwrap(); // Remove parent wrapper
129
+
130
+ // Smooth scrolling
131
+ $('#section').scrollTo({ behavior: 'smooth' });
132
+
133
+ // Form serialization
134
+ const formData = $('form').serialize(); // Returns object
135
+ const queryString = $('form').serializeString(); // Returns URL-encoded string
136
+
114
137
  // Collections
115
138
  $$('.items').addClass('highlight');
116
139
  ```
@@ -118,7 +141,7 @@ $$('.items').addClass('highlight');
118
141
  ### Reactive – signals
119
142
 
120
143
  ```ts
121
- import { signal, computed, effect, batch } from 'bquery/reactive';
144
+ import { signal, computed, effect, batch, watch, readonly } from '@bquery/bquery/reactive';
122
145
 
123
146
  const count = signal(0);
124
147
  const doubled = computed(() => count.value * 2);
@@ -127,6 +150,14 @@ effect(() => {
127
150
  console.log('Count changed', count.value);
128
151
  });
129
152
 
153
+ // Watch with cleanup support
154
+ const stop = watch(count, (newVal, oldVal) => {
155
+ console.log(`Changed from ${oldVal} to ${newVal}`);
156
+ });
157
+
158
+ // Read-only signal wrapper
159
+ const readOnlyCount = readonly(count);
160
+
130
161
  // Batch updates for performance
131
162
  batch(() => {
132
163
  count.value++;
@@ -137,11 +168,26 @@ batch(() => {
137
168
  ### Components – Web Components
138
169
 
139
170
  ```ts
140
- import { component, html } from 'bquery/component';
171
+ import { component, html } from '@bquery/bquery/component';
141
172
 
142
173
  component('user-card', {
143
174
  props: {
144
175
  username: { type: String, required: true },
176
+ age: { type: Number, validator: (v) => v >= 0 && v <= 150 },
177
+ },
178
+ // Extended lifecycle hooks
179
+ beforeMount() {
180
+ console.log('About to mount');
181
+ },
182
+ connected() {
183
+ console.log('Mounted');
184
+ },
185
+ beforeUpdate(props) {
186
+ // Return false to prevent update
187
+ return props.username !== '';
188
+ },
189
+ onError(error) {
190
+ console.error('Component error:', error);
145
191
  },
146
192
  render({ props }) {
147
193
  return html`<div>Hello ${props.username}</div>`;
@@ -152,7 +198,7 @@ component('user-card', {
152
198
  ### Motion – animations
153
199
 
154
200
  ```ts
155
- import { transition, spring } from 'bquery/motion';
201
+ import { transition, spring } from '@bquery/bquery/motion';
156
202
 
157
203
  // View transitions (with fallback)
158
204
  await transition(() => {
@@ -170,11 +216,17 @@ await x.to(100);
170
216
  ### Security – sanitizing
171
217
 
172
218
  ```ts
173
- import { sanitize, escapeHtml } from 'bquery/security';
219
+ import { sanitize, escapeHtml } from '@bquery/bquery/security';
174
220
 
175
- // Sanitize HTML (removes dangerous elements)
221
+ // Sanitize HTML (removes dangerous elements like script, iframe, svg)
176
222
  const safeHtml = sanitize(userInput);
177
223
 
224
+ // DOM clobbering protection (reserved IDs are blocked)
225
+ const safe = sanitize('<form id="cookie">...</form>'); // id stripped
226
+
227
+ // Unicode bypass protection in URLs
228
+ const urlSafe = sanitize('<a href="java\u200Bscript:alert(1)">click</a>');
229
+
178
230
  // Escape for text display
179
231
  const escaped = escapeHtml('<script>alert(1)</script>');
180
232
  ```
@@ -182,7 +234,7 @@ const escaped = escapeHtml('<script>alert(1)</script>');
182
234
  ### Platform – storage & APIs
183
235
 
184
236
  ```ts
185
- import { storage, notifications } from 'bquery/platform';
237
+ import { storage, notifications } from '@bquery/bquery/platform';
186
238
 
187
239
  // Unified storage API
188
240
  const local = storage.local();
@@ -213,10 +265,12 @@ if (permission === 'granted') {
213
265
 
214
266
  - **Getting Started**: [docs/guide/getting-started.md](docs/guide/getting-started.md)
215
267
  - **Core API**: [docs/guide/api-core.md](docs/guide/api-core.md)
268
+ - **Agents**: [docs/guide/agents.md](docs/guide/agents.md)
216
269
  - **Components**: [docs/guide/components.md](docs/guide/components.md)
217
270
  - **Reactivity**: [docs/guide/reactive.md](docs/guide/reactive.md)
218
271
  - **Motion**: [docs/guide/motion.md](docs/guide/motion.md)
219
272
  - **Security**: [docs/guide/security.md](docs/guide/security.md)
273
+ - **Platform**: [docs/guide/platform.md](docs/guide/platform.md)
220
274
 
221
275
  ## Local Development
222
276
 
@@ -57,6 +57,8 @@ export type PropDefinition<T = unknown> = {
57
57
  required?: boolean;
58
58
  /** Default value when prop is not provided */
59
59
  default?: T;
60
+ /** Optional validator function to validate prop values */
61
+ validator?: (value: T) => boolean;
60
62
  };
61
63
  /**
62
64
  * Complete component definition including props, state, styles, and lifecycle.
@@ -70,12 +72,18 @@ export type ComponentDefinition<TProps extends Record<string, unknown> = Record<
70
72
  state?: Record<string, unknown>;
71
73
  /** CSS styles scoped to the component's shadow DOM */
72
74
  styles?: string;
75
+ /** Lifecycle hook called before the component mounts (before first render) */
76
+ beforeMount?: () => void;
73
77
  /** Lifecycle hook called when component is added to DOM */
74
78
  connected?: () => void;
75
79
  /** Lifecycle hook called when component is removed from DOM */
76
80
  disconnected?: () => void;
81
+ /** Lifecycle hook called before an update render; return false to prevent */
82
+ beforeUpdate?: (props: TProps) => boolean | void;
77
83
  /** Lifecycle hook called after reactive updates trigger a render */
78
84
  updated?: () => void;
85
+ /** Error handler for errors during rendering or lifecycle */
86
+ onError?: (error: Error) => void;
79
87
  /** Render function returning HTML string */
80
88
  render: (context: {
81
89
  props: TProps;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/component/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,cAAc,CAAC,CAAC,GAAG,OAAO,IAAI;IACxC,0DAA0D;IAC1D,IAAI,EACA,iBAAiB,GACjB,iBAAiB,GACjB,kBAAkB,GAClB,iBAAiB,GACjB,gBAAgB,GAChB;QAAE,KAAK,KAAK,EAAE,OAAO,GAAG,CAAC,CAAA;KAAE,GAC3B,CAAC,CAAC,KAAK,EAAE,OAAO,KAAK,CAAC,CAAC,CAAC;IAC5B,wCAAwC;IACxC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,8CAA8C;IAC9C,OAAO,CAAC,EAAE,CAAC,CAAC;CACb,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAC9F;IACE,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,MAAM,EAAE,cAAc,CAAC,CAAC;IAC7C,6BAA6B;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,sDAAsD;IACtD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,+DAA+D;IAC/D,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,oEAAoE;IACpE,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,4CAA4C;IAC5C,MAAM,EAAE,CAAC,OAAO,EAAE;QAChB,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC/B,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;KACjD,KAAK,MAAM,CAAC;CACd,CAAC;AAsDJ;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,IAAI,GAAI,SAAS,oBAAoB,EAAE,GAAG,QAAQ,OAAO,EAAE,KAAG,MAE1E,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,QAAQ,GAAI,SAAS,oBAAoB,EAAE,GAAG,QAAQ,OAAO,EAAE,KAAG,MAgB9E,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,eAAO,MAAM,SAAS,GAAI,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9D,SAAS,MAAM,EACf,YAAY,mBAAmB,CAAC,MAAM,CAAC,KACtC,IA0HF,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/component/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,cAAc,CAAC,CAAC,GAAG,OAAO,IAAI;IACxC,0DAA0D;IAC1D,IAAI,EACA,iBAAiB,GACjB,iBAAiB,GACjB,kBAAkB,GAClB,iBAAiB,GACjB,gBAAgB,GAChB;QAAE,KAAK,KAAK,EAAE,OAAO,GAAG,CAAC,CAAA;KAAE,GAC3B,CAAC,CAAC,KAAK,EAAE,OAAO,KAAK,CAAC,CAAC,CAAC;IAC5B,wCAAwC;IACxC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,8CAA8C;IAC9C,OAAO,CAAC,EAAE,CAAC,CAAC;IACZ,0DAA0D;IAC1D,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,CAAC;CACnC,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAC9F;IACE,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,MAAM,EAAE,cAAc,CAAC,CAAC;IAC7C,6BAA6B;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,sDAAsD;IACtD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,+DAA+D;IAC/D,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,6EAA6E;IAC7E,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,GAAG,IAAI,CAAC;IACjD,oEAAoE;IACpE,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,6DAA6D;IAC7D,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,4CAA4C;IAC5C,MAAM,EAAE,CAAC,OAAO,EAAE;QAChB,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC/B,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;KACjD,KAAK,MAAM,CAAC;CACd,CAAC;AAsDJ;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,IAAI,GAAI,SAAS,oBAAoB,EAAE,GAAG,QAAQ,OAAO,EAAE,KAAG,MAE1E,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,QAAQ,GAAI,SAAS,oBAAoB,EAAE,GAAG,QAAQ,OAAO,EAAE,KAAG,MAgB9E,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,eAAO,MAAM,SAAS,GAAI,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9D,SAAS,MAAM,EACf,YAAY,mBAAmB,CAAC,MAAM,CAAC,KACtC,IAwKF,CAAC"}
@@ -1,30 +1,30 @@
1
- const i = (t, e) => {
2
- const { type: o } = e;
3
- if (o === String) return t;
1
+ const u = (e, r) => {
2
+ const { type: o } = r;
3
+ if (o === String) return e;
4
4
  if (o === Number) {
5
- const s = Number(t);
6
- return Number.isNaN(s) ? t : s;
5
+ const s = Number(e);
6
+ return Number.isNaN(s) ? e : s;
7
7
  }
8
8
  if (o === Boolean) {
9
- const s = t.trim().toLowerCase();
10
- return s === "" || s === "true" || s === "1" ? !0 : s === "false" || s === "0" ? !1 : !!t;
9
+ const s = e.trim().toLowerCase();
10
+ return s === "" || s === "true" || s === "1" ? !0 : s === "false" || s === "0" ? !1 : !!e;
11
11
  }
12
12
  if (o === Object || o === Array)
13
13
  try {
14
- return JSON.parse(t);
14
+ return JSON.parse(e);
15
15
  } catch {
16
- return t;
16
+ return e;
17
17
  }
18
18
  if (typeof o == "function") {
19
- const s = o, r = o;
19
+ const s = o, t = o;
20
20
  try {
21
- return s(t);
21
+ return s(e);
22
22
  } catch {
23
- return new r(t);
23
+ return new t(e);
24
24
  }
25
25
  }
26
- return t;
27
- }, l = (t, ...e) => t.reduce((o, s, r) => `${o}${s}${e[r] ?? ""}`, ""), h = (t, ...e) => {
26
+ return e;
27
+ }, p = (e, ...r) => e.reduce((o, s, t) => `${o}${s}${r[t] ?? ""}`, ""), i = (e, ...r) => {
28
28
  const o = {
29
29
  "&": "&amp;",
30
30
  "<": "&lt;",
@@ -32,36 +32,55 @@ const i = (t, e) => {
32
32
  '"': "&quot;",
33
33
  "'": "&#x27;",
34
34
  "`": "&#x60;"
35
- }, s = (r) => String(r ?? "").replace(/[&<>"'`]/g, (c) => o[c]);
36
- return t.reduce((r, n, c) => `${r}${n}${s(e[c])}`, "");
37
- }, d = (t, e) => {
35
+ }, s = (t) => String(t ?? "").replace(/[&<>"'`]/g, (n) => o[n]);
36
+ return e.reduce((t, c, n) => `${t}${c}${s(r[n])}`, "");
37
+ }, d = (e, r) => {
38
38
  class o extends HTMLElement {
39
39
  constructor() {
40
- super(), this.state = { ...e.state ?? {} }, this.props = {}, this.attachShadow({ mode: "open" }), this.syncProps();
40
+ super(), this.state = { ...r.state ?? {} }, this.props = {}, this.attachShadow({ mode: "open" }), this.syncProps();
41
41
  }
42
42
  /**
43
43
  * Returns the list of attributes to observe for changes.
44
44
  */
45
45
  static get observedAttributes() {
46
- return Object.keys(e.props ?? {});
46
+ return Object.keys(r.props ?? {});
47
47
  }
48
48
  /**
49
49
  * Called when the element is added to the DOM.
50
50
  */
51
51
  connectedCallback() {
52
- e.connected?.call(this), this.render();
52
+ try {
53
+ r.beforeMount?.call(this), r.connected?.call(this), this.render();
54
+ } catch (t) {
55
+ this.handleError(t);
56
+ }
53
57
  }
54
58
  /**
55
59
  * Called when the element is removed from the DOM.
56
60
  */
57
61
  disconnectedCallback() {
58
- e.disconnected?.call(this);
62
+ try {
63
+ r.disconnected?.call(this);
64
+ } catch (t) {
65
+ this.handleError(t);
66
+ }
59
67
  }
60
68
  /**
61
69
  * Called when an observed attribute changes.
62
70
  */
63
71
  attributeChangedCallback() {
64
- this.syncProps(), this.render(!0);
72
+ try {
73
+ this.syncProps(), this.render(!0);
74
+ } catch (t) {
75
+ this.handleError(t);
76
+ }
77
+ }
78
+ /**
79
+ * Handles errors during component lifecycle.
80
+ * @internal
81
+ */
82
+ handleError(t) {
83
+ r.onError ? r.onError.call(this, t) : console.error(`bQuery component error in <${e}>:`, t);
65
84
  }
66
85
  /**
67
86
  * Updates a state property and triggers a re-render.
@@ -69,8 +88,8 @@ const i = (t, e) => {
69
88
  * @param key - The state property key
70
89
  * @param value - The new value
71
90
  */
72
- setState(r, n) {
73
- this.state[r] = n, this.render(!0);
91
+ setState(t, c) {
92
+ this.state[t] = c, this.render(!0);
74
93
  }
75
94
  /**
76
95
  * Gets a state property value.
@@ -78,51 +97,59 @@ const i = (t, e) => {
78
97
  * @param key - The state property key
79
98
  * @returns The current value
80
99
  */
81
- getState(r) {
82
- return this.state[r];
100
+ getState(t) {
101
+ return this.state[t];
83
102
  }
84
103
  /**
85
104
  * Synchronizes props from attributes.
86
105
  * @internal
87
106
  */
88
107
  syncProps() {
89
- const r = e.props ?? {};
90
- for (const [n, c] of Object.entries(r)) {
91
- const u = this.getAttribute(n);
92
- if (u == null) {
93
- if (c.required && c.default === void 0)
94
- throw new Error(`bQuery component: missing required prop "${n}"`);
95
- this.props[n] = c.default ?? void 0;
96
- continue;
97
- }
98
- this.props[n] = i(
99
- u,
100
- c
101
- );
108
+ const t = r.props ?? {};
109
+ for (const [c, n] of Object.entries(t)) {
110
+ const l = this.getAttribute(c);
111
+ let a;
112
+ if (l == null) {
113
+ if (n.required && n.default === void 0)
114
+ throw new Error(`bQuery component: missing required prop "${c}"`);
115
+ a = n.default ?? void 0;
116
+ } else
117
+ a = u(l, n);
118
+ if (n.validator && a !== void 0 && !n.validator(a))
119
+ throw new Error(
120
+ `bQuery component: validation failed for prop "${c}" with value ${JSON.stringify(a)}`
121
+ );
122
+ this.props[c] = a;
102
123
  }
103
124
  }
104
125
  /**
105
126
  * Renders the component to its shadow root.
106
127
  * @internal
107
128
  */
108
- render(r = !1) {
109
- const n = (p, a) => {
110
- this.dispatchEvent(new CustomEvent(p, { detail: a, bubbles: !0, composed: !0 }));
111
- };
112
- if (!this.shadowRoot) return;
113
- const c = e.render({
114
- props: this.props,
115
- state: this.state,
116
- emit: n
117
- }), u = e.styles ? `<style>${e.styles}</style>` : "";
118
- this.shadowRoot.innerHTML = `${u}${c}`, r && e.updated?.call(this);
129
+ render(t = !1) {
130
+ try {
131
+ if (t && r.beforeUpdate && r.beforeUpdate.call(this, this.props) === !1)
132
+ return;
133
+ const c = (a, h) => {
134
+ this.dispatchEvent(new CustomEvent(a, { detail: h, bubbles: !0, composed: !0 }));
135
+ };
136
+ if (!this.shadowRoot) return;
137
+ const n = r.render({
138
+ props: this.props,
139
+ state: this.state,
140
+ emit: c
141
+ }), l = r.styles ? `<style>${r.styles}</style>` : "";
142
+ this.shadowRoot.innerHTML = `${l}${n}`, t && r.updated?.call(this);
143
+ } catch (c) {
144
+ this.handleError(c);
145
+ }
119
146
  }
120
147
  }
121
- customElements.get(t) || customElements.define(t, o);
148
+ customElements.get(e) || customElements.define(e, o);
122
149
  };
123
150
  export {
124
151
  d as component,
125
- l as html,
126
- h as safeHtml
152
+ p as html,
153
+ i as safeHtml
127
154
  };
128
155
  //# sourceMappingURL=component.es.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"component.es.mjs","sources":["../src/component/index.ts"],"sourcesContent":["/**\n * Minimal Web Component helper for building custom elements.\n *\n * This module provides a declarative API for defining Web Components\n * without complex build steps. Features include:\n * - Type-safe props with automatic attribute coercion\n * - Reactive state management\n * - Shadow DOM encapsulation with scoped styles\n * - Lifecycle hooks (connected, disconnected)\n * - Event emission helpers\n *\n * @module bquery/component\n *\n * @example\n * ```ts\n * import { component, html } from 'bquery/component';\n *\n * component('user-card', {\n * props: {\n * username: { type: String, required: true },\n * avatar: { type: String, default: '/default-avatar.png' },\n * },\n * styles: `\n * .card { padding: 1rem; border: 1px solid #ccc; }\n * `,\n * render({ props }) {\n * return html`\n * <div class=\"card\">\n * <img src=\"${props.avatar}\" alt=\"${props.username}\" />\n * <h3>${props.username}</h3>\n * </div>\n * `;\n * },\n * });\n * ```\n */\n\n/**\n * Defines a single prop's type and configuration.\n *\n * @template T - The TypeScript type of the prop value\n *\n * @example\n * ```ts\n * const myProp: PropDefinition<number> = {\n * type: Number,\n * required: false,\n * default: 0,\n * };\n * ```\n */\nexport type PropDefinition<T = unknown> = {\n /** Constructor or converter function for the prop type */\n type:\n | StringConstructor\n | NumberConstructor\n | BooleanConstructor\n | ObjectConstructor\n | ArrayConstructor\n | { new (value: unknown): T }\n | ((value: unknown) => T);\n /** Whether the prop must be provided */\n required?: boolean;\n /** Default value when prop is not provided */\n default?: T;\n};\n\n/**\n * Complete component definition including props, state, styles, and lifecycle.\n *\n * @template TProps - Type of the component's props\n */\nexport type ComponentDefinition<TProps extends Record<string, unknown> = Record<string, unknown>> =\n {\n /** Prop definitions with types and defaults */\n props?: Record<keyof TProps, PropDefinition>;\n /** Initial internal state */\n state?: Record<string, unknown>;\n /** CSS styles scoped to the component's shadow DOM */\n styles?: string;\n /** Lifecycle hook called when component is added to DOM */\n connected?: () => void;\n /** Lifecycle hook called when component is removed from DOM */\n disconnected?: () => void;\n /** Lifecycle hook called after reactive updates trigger a render */\n updated?: () => void;\n /** Render function returning HTML string */\n render: (context: {\n props: TProps;\n state: Record<string, unknown>;\n emit: (event: string, detail?: unknown) => void;\n }) => string;\n };\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 */\nconst 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 const parsed = Number(rawValue);\n return (Number.isNaN(parsed) ? rawValue : parsed) 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 try {\n return callable(rawValue);\n } catch {\n return new constructable(rawValue);\n }\n }\n\n return rawValue as T;\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\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 * console.log('Counter mounted');\n * },\n * render({ props, state, emit }) {\n * return html`\n * <button onclick=\"this.getRootNode().host.increment()\">\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 /**\n * Internal Web Component class created for each component definition.\n * @internal\n */\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\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 definition.connected?.call(this);\n this.render();\n }\n\n /**\n * Called when the element is removed from the DOM.\n */\n disconnectedCallback(): void {\n definition.disconnected?.call(this);\n }\n\n /**\n * Called when an observed attribute changes.\n */\n attributeChangedCallback(): void {\n this.syncProps();\n this.render(true);\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 if (attrValue == null) {\n if (config.required && config.default === undefined) {\n throw new Error(`bQuery component: missing required prop \"${key}\"`);\n }\n (this.props as Record<string, unknown>)[key] = config.default ?? undefined;\n continue;\n }\n (this.props as Record<string, unknown>)[key] = coercePropValue(\n attrValue,\n config\n ) as TProps[keyof TProps];\n }\n }\n\n /**\n * Renders the component to its shadow root.\n * @internal\n */\n private render(triggerUpdated = false): void {\n /**\n * Emits a custom event from the component.\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 styles = definition.styles ? `<style>${definition.styles}</style>` : '';\n this.shadowRoot.innerHTML = `${styles}${markup}`;\n\n if (triggerUpdated) {\n definition.updated?.call(this);\n }\n }\n }\n\n if (!customElements.get(tagName)) {\n customElements.define(tagName, BQueryComponent);\n }\n};\n"],"names":["coercePropValue","rawValue","config","type","parsed","normalized","callable","constructable","html","strings","values","acc","part","index","safeHtml","escapeMap","escape","value","char","component","tagName","definition","BQueryComponent","key","props","attrValue","triggerUpdated","emit","event","detail","markup","styles"],"mappings":"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"}
1
+ {"version":3,"file":"component.es.mjs","sources":["../src/component/index.ts"],"sourcesContent":["/**\r\n * Minimal Web Component helper for building custom elements.\r\n *\r\n * This module provides a declarative API for defining Web Components\r\n * without complex build steps. Features include:\r\n * - Type-safe props with automatic attribute coercion\r\n * - Reactive state management\r\n * - Shadow DOM encapsulation with scoped styles\r\n * - Lifecycle hooks (connected, disconnected)\r\n * - Event emission helpers\r\n *\r\n * @module bquery/component\r\n *\r\n * @example\r\n * ```ts\r\n * import { component, html } from 'bquery/component';\r\n *\r\n * component('user-card', {\r\n * props: {\r\n * username: { type: String, required: true },\r\n * avatar: { type: String, default: '/default-avatar.png' },\r\n * },\r\n * styles: `\r\n * .card { padding: 1rem; border: 1px solid #ccc; }\r\n * `,\r\n * render({ props }) {\r\n * return html`\r\n * <div class=\"card\">\r\n * <img src=\"${props.avatar}\" alt=\"${props.username}\" />\r\n * <h3>${props.username}</h3>\r\n * </div>\r\n * `;\r\n * },\r\n * });\r\n * ```\r\n */\r\n\r\n/**\r\n * Defines a single prop's type and configuration.\r\n *\r\n * @template T - The TypeScript type of the prop value\r\n *\r\n * @example\r\n * ```ts\r\n * const myProp: PropDefinition<number> = {\r\n * type: Number,\r\n * required: false,\r\n * default: 0,\r\n * };\r\n * ```\r\n */\r\nexport type PropDefinition<T = unknown> = {\r\n /** Constructor or converter function for the prop type */\r\n type:\r\n | StringConstructor\r\n | NumberConstructor\r\n | BooleanConstructor\r\n | ObjectConstructor\r\n | ArrayConstructor\r\n | { new (value: unknown): T }\r\n | ((value: unknown) => T);\r\n /** Whether the prop must be provided */\r\n required?: boolean;\r\n /** Default value when prop is not provided */\r\n default?: T;\r\n /** Optional validator function to validate prop values */\r\n validator?: (value: T) => boolean;\r\n};\r\n\r\n/**\r\n * Complete component definition including props, state, styles, and lifecycle.\r\n *\r\n * @template TProps - Type of the component's props\r\n */\r\nexport type ComponentDefinition<TProps extends Record<string, unknown> = Record<string, unknown>> =\r\n {\r\n /** Prop definitions with types and defaults */\r\n props?: Record<keyof TProps, PropDefinition>;\r\n /** Initial internal state */\r\n state?: Record<string, unknown>;\r\n /** CSS styles scoped to the component's shadow DOM */\r\n styles?: string;\r\n /** Lifecycle hook called before the component mounts (before first render) */\r\n beforeMount?: () => void;\r\n /** Lifecycle hook called when component is added to DOM */\r\n connected?: () => void;\r\n /** Lifecycle hook called when component is removed from DOM */\r\n disconnected?: () => void;\r\n /** Lifecycle hook called before an update render; return false to prevent */\r\n beforeUpdate?: (props: TProps) => boolean | void;\r\n /** Lifecycle hook called after reactive updates trigger a render */\r\n updated?: () => void;\r\n /** Error handler for errors during rendering or lifecycle */\r\n onError?: (error: Error) => void;\r\n /** Render function returning HTML string */\r\n render: (context: {\r\n props: TProps;\r\n state: Record<string, unknown>;\r\n emit: (event: string, detail?: unknown) => void;\r\n }) => string;\r\n };\r\n\r\n/**\r\n * Coerces a string attribute value into a typed prop value.\r\n * Supports String, Number, Boolean, Object, Array, and custom converters.\r\n *\r\n * @internal\r\n * @template T - The target type\r\n * @param rawValue - The raw string value from the attribute\r\n * @param config - The prop definition with type information\r\n * @returns The coerced value of type T\r\n */\r\nconst coercePropValue = <T>(rawValue: string, config: PropDefinition<T>): T => {\r\n const { type } = config;\r\n\r\n if (type === String) return rawValue as T;\r\n\r\n if (type === Number) {\r\n const parsed = Number(rawValue);\r\n return (Number.isNaN(parsed) ? rawValue : parsed) as T;\r\n }\r\n\r\n if (type === Boolean) {\r\n const normalized = rawValue.trim().toLowerCase();\r\n if (normalized === '' || normalized === 'true' || normalized === '1') {\r\n return true as T;\r\n }\r\n if (normalized === 'false' || normalized === '0') {\r\n return false as T;\r\n }\r\n return Boolean(rawValue) as T;\r\n }\r\n\r\n if (type === Object || type === Array) {\r\n try {\r\n return JSON.parse(rawValue) as T;\r\n } catch {\r\n return rawValue as T;\r\n }\r\n }\r\n\r\n if (typeof type === 'function') {\r\n const callable = type as (value: unknown) => T;\r\n const constructable = type as new (value: unknown) => T;\r\n try {\r\n return callable(rawValue);\r\n } catch {\r\n return new constructable(rawValue);\r\n }\r\n }\r\n\r\n return rawValue as T;\r\n};\r\n\r\n/**\r\n * Tagged template literal for creating HTML strings.\r\n *\r\n * This function handles interpolation of values into HTML templates,\r\n * converting null/undefined to empty strings.\r\n *\r\n * @param strings - Template literal string parts\r\n * @param values - Interpolated values\r\n * @returns Combined HTML string\r\n *\r\n * @example\r\n * ```ts\r\n * const name = 'World';\r\n * const greeting = html`<h1>Hello, ${name}!</h1>`;\r\n * // Result: '<h1>Hello, World!</h1>'\r\n * ```\r\n */\r\nexport const html = (strings: TemplateStringsArray, ...values: unknown[]): string => {\r\n return strings.reduce((acc, part, index) => `${acc}${part}${values[index] ?? ''}`, '');\r\n};\r\n\r\n/**\r\n * Escapes HTML entities in interpolated values for XSS prevention.\r\n * Use this when you need to safely embed user content in templates.\r\n *\r\n * @param strings - Template literal string parts\r\n * @param values - Interpolated values to escape\r\n * @returns Combined HTML string with escaped values\r\n *\r\n * @example\r\n * ```ts\r\n * const userInput = '<script>alert(\"xss\")</script>';\r\n * const safe = safeHtml`<div>${userInput}</div>`;\r\n * // Result: '<div>&lt;script&gt;alert(\"xss\")&lt;/script&gt;</div>'\r\n * ```\r\n */\r\nexport const safeHtml = (strings: TemplateStringsArray, ...values: unknown[]): string => {\r\n const escapeMap: Record<string, string> = {\r\n '&': '&amp;',\r\n '<': '&lt;',\r\n '>': '&gt;',\r\n '\"': '&quot;',\r\n \"'\": '&#x27;',\r\n '`': '&#x60;',\r\n };\r\n\r\n const escape = (value: unknown): string => {\r\n const str = String(value ?? '');\r\n return str.replace(/[&<>\"'`]/g, (char) => escapeMap[char]);\r\n };\r\n\r\n return strings.reduce((acc, part, index) => `${acc}${part}${escape(values[index])}`, '');\r\n};\r\n\r\n/**\r\n * Defines and registers a custom Web Component.\r\n *\r\n * This function creates a new custom element with the given tag name\r\n * and configuration. The component uses Shadow DOM for encapsulation\r\n * and automatically re-renders when observed attributes change.\r\n *\r\n * @template TProps - Type of the component's props\r\n * @param tagName - The custom element tag name (must contain a hyphen)\r\n * @param definition - The component configuration\r\n *\r\n * @example\r\n * ```ts\r\n * component('counter-button', {\r\n * props: {\r\n * start: { type: Number, default: 0 },\r\n * },\r\n * state: { count: 0 },\r\n * styles: `\r\n * button { padding: 0.5rem 1rem; }\r\n * `,\r\n * connected() {\r\n * console.log('Counter mounted');\r\n * },\r\n * render({ props, state, emit }) {\r\n * return html`\r\n * <button onclick=\"this.getRootNode().host.increment()\">\r\n * Count: ${state.count}\r\n * </button>\r\n * `;\r\n * },\r\n * });\r\n * ```\r\n */\r\nexport const component = <TProps extends Record<string, unknown>>(\r\n tagName: string,\r\n definition: ComponentDefinition<TProps>\r\n): void => {\r\n /**\r\n * Internal Web Component class created for each component definition.\r\n * @internal\r\n */\r\n class BQueryComponent extends HTMLElement {\r\n /** Internal state object for the component */\r\n private readonly state = { ...(definition.state ?? {}) };\r\n /** Typed props object populated from attributes */\r\n private props = {} as TProps;\r\n\r\n constructor() {\r\n super();\r\n this.attachShadow({ mode: 'open' });\r\n this.syncProps();\r\n }\r\n\r\n /**\r\n * Returns the list of attributes to observe for changes.\r\n */\r\n static get observedAttributes(): string[] {\r\n return Object.keys(definition.props ?? {});\r\n }\r\n\r\n /**\r\n * Called when the element is added to the DOM.\r\n */\r\n connectedCallback(): void {\r\n try {\r\n definition.beforeMount?.call(this);\r\n definition.connected?.call(this);\r\n this.render();\r\n } catch (error) {\r\n this.handleError(error as Error);\r\n }\r\n }\r\n\r\n /**\r\n * Called when the element is removed from the DOM.\r\n */\r\n disconnectedCallback(): void {\r\n try {\r\n definition.disconnected?.call(this);\r\n } catch (error) {\r\n this.handleError(error as Error);\r\n }\r\n }\r\n\r\n /**\r\n * Called when an observed attribute changes.\r\n */\r\n attributeChangedCallback(): void {\r\n try {\r\n this.syncProps();\r\n this.render(true);\r\n } catch (error) {\r\n this.handleError(error as Error);\r\n }\r\n }\r\n\r\n /**\r\n * Handles errors during component lifecycle.\r\n * @internal\r\n */\r\n private handleError(error: Error): void {\r\n if (definition.onError) {\r\n definition.onError.call(this, error);\r\n } else {\r\n console.error(`bQuery component error in <${tagName}>:`, error);\r\n }\r\n }\r\n\r\n /**\r\n * Updates a state property and triggers a re-render.\r\n *\r\n * @param key - The state property key\r\n * @param value - The new value\r\n */\r\n setState(key: string, value: unknown): void {\r\n this.state[key] = value;\r\n this.render(true);\r\n }\r\n\r\n /**\r\n * Gets a state property value.\r\n *\r\n * @param key - The state property key\r\n * @returns The current value\r\n */\r\n getState<T = unknown>(key: string): T {\r\n return this.state[key] as T;\r\n }\r\n\r\n /**\r\n * Synchronizes props from attributes.\r\n * @internal\r\n */\r\n private syncProps(): void {\r\n const props = definition.props ?? {};\r\n for (const [key, config] of Object.entries(props) as [string, PropDefinition][]) {\r\n const attrValue = this.getAttribute(key);\r\n let value: unknown;\r\n\r\n if (attrValue == null) {\r\n if (config.required && config.default === undefined) {\r\n throw new Error(`bQuery component: missing required prop \"${key}\"`);\r\n }\r\n value = config.default ?? undefined;\r\n } else {\r\n value = coercePropValue(attrValue, config);\r\n }\r\n\r\n // Validate the prop value if a validator is provided\r\n if (config.validator && value !== undefined) {\r\n const isValid = config.validator(value);\r\n if (!isValid) {\r\n throw new Error(\r\n `bQuery component: validation failed for prop \"${key}\" with value ${JSON.stringify(value)}`\r\n );\r\n }\r\n }\r\n\r\n (this.props as Record<string, unknown>)[key] = value;\r\n }\r\n }\r\n\r\n /**\r\n * Renders the component to its shadow root.\r\n * @internal\r\n */\r\n private render(triggerUpdated = false): void {\r\n try {\r\n // Check beforeUpdate hook if this is an update\r\n if (triggerUpdated && definition.beforeUpdate) {\r\n const shouldUpdate = definition.beforeUpdate.call(this, this.props);\r\n if (shouldUpdate === false) return;\r\n }\r\n\r\n /**\r\n * Emits a custom event from the component.\r\n */\r\n const emit = (event: string, detail?: unknown): void => {\r\n this.dispatchEvent(new CustomEvent(event, { detail, bubbles: true, composed: true }));\r\n };\r\n\r\n if (!this.shadowRoot) return;\r\n\r\n const markup = definition.render({\r\n props: this.props,\r\n state: this.state,\r\n emit,\r\n });\r\n\r\n const styles = definition.styles ? `<style>${definition.styles}</style>` : '';\r\n this.shadowRoot.innerHTML = `${styles}${markup}`;\r\n\r\n if (triggerUpdated) {\r\n definition.updated?.call(this);\r\n }\r\n } catch (error) {\r\n this.handleError(error as Error);\r\n }\r\n }\r\n }\r\n\r\n if (!customElements.get(tagName)) {\r\n customElements.define(tagName, BQueryComponent);\r\n }\r\n};\r\n"],"names":["coercePropValue","rawValue","config","type","parsed","normalized","callable","constructable","html","strings","values","acc","part","index","safeHtml","escapeMap","escape","value","char","component","tagName","definition","BQueryComponent","error","key","props","attrValue","triggerUpdated","emit","event","detail","markup","styles"],"mappings":"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"}
@@ -18,6 +18,13 @@ import { BQueryElement } from './element';
18
18
  */
19
19
  export declare class BQueryCollection {
20
20
  readonly elements: Element[];
21
+ /**
22
+ * Stores delegated event handlers for cleanup via undelegate().
23
+ * Outer map: element -> (key -> (handler -> wrapper))
24
+ * Key format: `${event}:${selector}`
25
+ * @internal
26
+ */
27
+ private readonly delegatedHandlers;
21
28
  /**
22
29
  * Creates a new collection wrapper.
23
30
  * @param elements - Array of DOM elements to wrap
@@ -182,6 +189,45 @@ export declare class BQueryCollection {
182
189
  * @returns The instance for method chaining
183
190
  */
184
191
  trigger(event: string, detail?: unknown): this;
192
+ /**
193
+ * Adds a delegated event listener to all elements.
194
+ * Events are delegated to matching descendants.
195
+ *
196
+ * Use `undelegate()` to remove the listener later.
197
+ *
198
+ * @param event - Event type to listen for
199
+ * @param selector - CSS selector to match against event targets
200
+ * @param handler - Event handler function
201
+ * @returns The instance for method chaining
202
+ *
203
+ * @example
204
+ * ```ts
205
+ * const handler = (e, target) => console.log('Clicked:', target.textContent);
206
+ * $$('.container').delegate('click', '.item', handler);
207
+ *
208
+ * // Later, remove the delegated listener:
209
+ * $$('.container').undelegate('click', '.item', handler);
210
+ * ```
211
+ */
212
+ delegate(event: string, selector: string, handler: (event: Event, target: Element) => void): this;
213
+ /**
214
+ * Removes a delegated event listener previously added with `delegate()`.
215
+ *
216
+ * @param event - Event type that was registered
217
+ * @param selector - CSS selector that was used
218
+ * @param handler - The original handler function passed to delegate()
219
+ * @returns The instance for method chaining
220
+ *
221
+ * @example
222
+ * ```ts
223
+ * const handler = (e, target) => console.log('Clicked:', target.textContent);
224
+ * $$('.container').delegate('click', '.item', handler);
225
+ *
226
+ * // Remove the delegated listener:
227
+ * $$('.container').undelegate('click', '.item', handler);
228
+ * ```
229
+ */
230
+ undelegate(event: string, selector: string, handler: (event: Event, target: Element) => void): this;
185
231
  /**
186
232
  * Removes all elements from the DOM.
187
233
  *
@@ -1 +1 @@
1
- {"version":3,"file":"collection.d.ts","sourceRoot":"","sources":["../../src/core/collection.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"collection.d.ts","sourceRoot":"","sources":["../../src/core/collection.ts"],"names":[],"mappings":"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"}