@bquery/bquery 1.5.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.
- package/README.md +586 -546
- package/dist/component/component.d.ts +13 -5
- package/dist/component/component.d.ts.map +1 -1
- package/dist/component/html.d.ts +40 -3
- package/dist/component/html.d.ts.map +1 -1
- package/dist/component/index.d.ts +2 -2
- package/dist/component/index.d.ts.map +1 -1
- package/dist/component/library.d.ts.map +1 -1
- package/dist/component/types.d.ts +131 -16
- package/dist/component/types.d.ts.map +1 -1
- package/dist/component-BEQgt5hl.js +600 -0
- package/dist/component-BEQgt5hl.js.map +1 -0
- package/dist/component.es.mjs +7 -6
- package/dist/config-DRmZZno3.js.map +1 -1
- package/dist/core-BGQJVw0-.js +35 -0
- package/dist/core-BGQJVw0-.js.map +1 -0
- package/dist/{core-CK2Mfpf4.js → core-CCEabVHl.js} +2 -2
- package/dist/{core-CK2Mfpf4.js.map → core-CCEabVHl.js.map} +1 -1
- package/dist/core.es.mjs +1 -1
- package/dist/effect-AFRW_Plg.js +84 -0
- package/dist/effect-AFRW_Plg.js.map +1 -0
- package/dist/full.d.ts +4 -4
- package/dist/full.d.ts.map +1 -1
- package/dist/full.es.mjs +98 -94
- package/dist/full.iife.js +14 -14
- package/dist/full.iife.js.map +1 -1
- package/dist/full.umd.js +14 -14
- package/dist/full.umd.js.map +1 -1
- package/dist/index.es.mjs +143 -139
- package/dist/{motion-C5DRdPnO.js → motion-D9TcHxOF.js} +1 -1
- package/dist/{motion-C5DRdPnO.js.map → motion-D9TcHxOF.js.map} +1 -1
- package/dist/motion.es.mjs +1 -1
- package/dist/{platform-B7JhGBc7.js → platform-Dr9b6fsq.js} +21 -20
- package/dist/platform-Dr9b6fsq.js.map +1 -0
- package/dist/platform.es.mjs +1 -1
- package/dist/{reactive-BDya-ia8.js → reactive-DSkct0dO.js} +51 -50
- package/dist/reactive-DSkct0dO.js.map +1 -0
- package/dist/reactive.es.mjs +19 -17
- package/dist/{router-CijiICxt.js → router-CbDhl8rS.js} +3 -3
- package/dist/{router-CijiICxt.js.map → router-CbDhl8rS.js.map} +1 -1
- package/dist/router.es.mjs +1 -1
- package/dist/{sanitize-jyJ2ryE2.js → sanitize-Bs2dkMby.js} +94 -83
- package/dist/sanitize-Bs2dkMby.js.map +1 -0
- package/dist/security/index.d.ts +4 -2
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/sanitize.d.ts +4 -1
- package/dist/security/sanitize.d.ts.map +1 -1
- package/dist/security/trusted-html.d.ts +53 -0
- package/dist/security/trusted-html.d.ts.map +1 -0
- package/dist/security.es.mjs +10 -9
- package/dist/store/define-store.d.ts +1 -1
- package/dist/store/define-store.d.ts.map +1 -1
- package/dist/store/mapping.d.ts +1 -1
- package/dist/store/mapping.d.ts.map +1 -1
- package/dist/store/persisted.d.ts +1 -1
- package/dist/store/persisted.d.ts.map +1 -1
- package/dist/store/types.d.ts +2 -2
- package/dist/store/types.d.ts.map +1 -1
- package/dist/store/watch.d.ts +1 -1
- package/dist/store/watch.d.ts.map +1 -1
- package/dist/{store-CPK9E62U.js → store-BwDvI45q.js} +49 -48
- package/dist/{store-CPK9E62U.js.map → store-BwDvI45q.js.map} +1 -1
- package/dist/store.es.mjs +1 -1
- package/dist/storybook/index.d.ts +37 -0
- package/dist/storybook/index.d.ts.map +1 -0
- package/dist/storybook.es.mjs +151 -0
- package/dist/storybook.es.mjs.map +1 -0
- package/dist/untrack-B0rVscTc.js +7 -0
- package/dist/untrack-B0rVscTc.js.map +1 -0
- package/dist/{view-Cdi0g-qo.js → view-C70lA3vf.js} +29 -28
- package/dist/{view-Cdi0g-qo.js.map → view-C70lA3vf.js.map} +1 -1
- package/dist/view.es.mjs +9 -8
- package/package.json +141 -136
- package/src/component/component.ts +259 -54
- package/src/component/html.ts +153 -53
- package/src/component/index.ts +10 -2
- package/src/component/library.ts +42 -28
- package/src/component/types.ts +184 -19
- package/src/full.ts +8 -2
- package/src/motion/transition.ts +97 -97
- package/src/motion/types.ts +208 -208
- package/src/platform/announcer.ts +208 -208
- package/src/platform/config.ts +163 -163
- package/src/platform/cookies.ts +165 -165
- package/src/platform/index.ts +39 -39
- package/src/platform/meta.ts +168 -168
- package/src/reactive/async-data.ts +486 -486
- package/src/reactive/index.ts +37 -37
- package/src/reactive/signal.ts +29 -29
- package/src/security/constants.ts +211 -211
- package/src/security/index.ts +17 -10
- package/src/security/sanitize.ts +70 -66
- package/src/security/trusted-html.ts +71 -0
- package/src/store/define-store.ts +49 -48
- package/src/store/mapping.ts +74 -73
- package/src/store/persisted.ts +62 -61
- package/src/store/types.ts +92 -94
- package/src/store/watch.ts +53 -52
- package/src/storybook/index.ts +479 -0
- package/dist/component-CY5MVoYN.js +0 -531
- package/dist/component-CY5MVoYN.js.map +0 -1
- package/dist/core-DPdbItcq.js +0 -112
- package/dist/core-DPdbItcq.js.map +0 -1
- package/dist/platform-B7JhGBc7.js.map +0 -1
- package/dist/reactive-BDya-ia8.js.map +0 -1
- package/dist/sanitize-jyJ2ryE2.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,546 +1,586 @@
|
|
|
1
|
-
<p align="center">
|
|
2
|
-
<img src="assets/bquerry-logo.svg" alt="bQuery.js Logo" width="120" />
|
|
3
|
-
</p>
|
|
4
|
-
|
|
5
|
-
<h1 align="center">bQuery.js</h1>
|
|
6
|
-
|
|
7
|
-
<p align="center">
|
|
8
|
-
|
|
9
|
-
[](https://github.com/bQuery/bQuery)
|
|
10
|
-
[](https://github.com/bQuery/bQuery/stargazers)
|
|
11
|
-
[](https://github.com/bQuery/bQuery/issues)
|
|
12
|
-
[](https://github.com/bQuery/bQuery/blob/main/LICENSE.md)
|
|
13
|
-
[](https://www.npmjs.com/package/@bquery/bquery)
|
|
14
|
-
[](https://bundlephobia.com/package/@bquery/bquery)
|
|
15
|
-
[](https://unpkg.com/@bquery/bquery)
|
|
16
|
-
[](https://www.codefactor.io/repository/github/bquery/bquery)
|
|
17
|
-
[](https://www.jsdelivr.com/package/npm/@bquery/bquery)
|
|
18
|
-
|
|
19
|
-
</p>
|
|
20
|
-
|
|
21
|
-
**The jQuery for the modern Web Platform.**
|
|
22
|
-
|
|
23
|
-
bQuery.js is a slim, TypeScript-first library that combines jQuery's direct DOM workflow with modern features like reactivity, async data composables, Web Components, motion utilities, routing, stores, and declarative views — without a mandatory build step.
|
|
24
|
-
|
|
25
|
-
## Highlights
|
|
26
|
-
|
|
27
|
-
- **Zero-build capable**: runs directly in the browser; build tools are optional.
|
|
28
|
-
- **Async data built-in**: fetch and async state composables integrate directly with signals.
|
|
29
|
-
- **Security-focused**: DOM writes are sanitized by default; Trusted Types supported.
|
|
30
|
-
- **Modular**: the core stays small; extra modules are opt-in.
|
|
31
|
-
- **TypeScript-first**: clear types and strong IDE support.
|
|
32
|
-
- **Tree-shakeable**: import only what you need.
|
|
33
|
-
- **Storybook-ready**: default components can be previewed and developed in Storybook.
|
|
34
|
-
|
|
35
|
-
## Installation
|
|
36
|
-
|
|
37
|
-
### Via npm/bun/pnpm
|
|
38
|
-
|
|
39
|
-
```bash
|
|
40
|
-
# npm
|
|
41
|
-
npm install @bquery/bquery
|
|
42
|
-
|
|
43
|
-
# bun
|
|
44
|
-
bun add @bquery/bquery
|
|
45
|
-
|
|
46
|
-
# pnpm
|
|
47
|
-
pnpm add @bquery/bquery
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
### Via CDN (Zero-build)
|
|
51
|
-
|
|
52
|
-
#### ES Modules (recommended)
|
|
53
|
-
|
|
54
|
-
```html
|
|
55
|
-
<script type="module">
|
|
56
|
-
import { $, signal } from 'https://unpkg.com/@bquery/bquery@1/dist/full.es.mjs';
|
|
57
|
-
|
|
58
|
-
const count = signal(0);
|
|
59
|
-
$('#counter').text(`Count: ${count.value}`);
|
|
60
|
-
</script>
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
#### UMD (global variable)
|
|
64
|
-
|
|
65
|
-
```html
|
|
66
|
-
<script src="https://unpkg.com/@bquery/bquery@1/dist/full.umd.js"></script>
|
|
67
|
-
<script>
|
|
68
|
-
const { $, signal } = bQuery;
|
|
69
|
-
const count = signal(0);
|
|
70
|
-
</script>
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
#### IIFE (self-executing)
|
|
74
|
-
|
|
75
|
-
```html
|
|
76
|
-
<script src="https://unpkg.com/@bquery/bquery@1/dist/full.iife.js"></script>
|
|
77
|
-
<script>
|
|
78
|
-
const { $, $$ } = bQuery;
|
|
79
|
-
$$('.items').addClass('loaded');
|
|
80
|
-
</script>
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
## Import Strategies
|
|
84
|
-
|
|
85
|
-
```ts
|
|
86
|
-
// Full bundle (all modules)
|
|
87
|
-
import {
|
|
88
|
-
$,
|
|
89
|
-
signal,
|
|
90
|
-
component,
|
|
91
|
-
registerDefaultComponents,
|
|
92
|
-
defineBqueryConfig,
|
|
93
|
-
} from '@bquery/bquery';
|
|
94
|
-
|
|
95
|
-
// Core only
|
|
96
|
-
import { $, $$ } from '@bquery/bquery/core';
|
|
97
|
-
|
|
98
|
-
// Core utilities (named exports, tree-shakeable)
|
|
99
|
-
import { debounce, merge, uid, once, utils } from '@bquery/bquery/core';
|
|
100
|
-
|
|
101
|
-
// Reactive only
|
|
102
|
-
import {
|
|
103
|
-
signal,
|
|
104
|
-
computed,
|
|
105
|
-
effect,
|
|
106
|
-
linkedSignal,
|
|
107
|
-
persistedSignal,
|
|
108
|
-
useAsyncData,
|
|
109
|
-
useFetch,
|
|
110
|
-
createUseFetch,
|
|
111
|
-
} from '@bquery/bquery/reactive';
|
|
112
|
-
|
|
113
|
-
// Components only
|
|
114
|
-
import {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
import {
|
|
133
|
-
import {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
|
143
|
-
|
|
|
144
|
-
| **
|
|
145
|
-
| **
|
|
146
|
-
| **
|
|
147
|
-
| **
|
|
148
|
-
| **
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
)
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
const
|
|
237
|
-
baseUrl: 'https://api.example.com',
|
|
238
|
-
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
},
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
},
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
console.
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
});
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
});
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
const
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
}
|
|
385
|
-
});
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
})
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="assets/bquerry-logo.svg" alt="bQuery.js Logo" width="120" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">bQuery.js</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
|
|
9
|
+
[](https://github.com/bQuery/bQuery)
|
|
10
|
+
[](https://github.com/bQuery/bQuery/stargazers)
|
|
11
|
+
[](https://github.com/bQuery/bQuery/issues)
|
|
12
|
+
[](https://github.com/bQuery/bQuery/blob/main/LICENSE.md)
|
|
13
|
+
[](https://www.npmjs.com/package/@bquery/bquery)
|
|
14
|
+
[](https://bundlephobia.com/package/@bquery/bquery)
|
|
15
|
+
[](https://unpkg.com/@bquery/bquery)
|
|
16
|
+
[](https://www.codefactor.io/repository/github/bquery/bquery)
|
|
17
|
+
[](https://www.jsdelivr.com/package/npm/@bquery/bquery)
|
|
18
|
+
|
|
19
|
+
</p>
|
|
20
|
+
|
|
21
|
+
**The jQuery for the modern Web Platform.**
|
|
22
|
+
|
|
23
|
+
bQuery.js is a slim, TypeScript-first library that combines jQuery's direct DOM workflow with modern features like reactivity, async data composables, Web Components, motion utilities, routing, stores, and declarative views — without a mandatory build step.
|
|
24
|
+
|
|
25
|
+
## Highlights
|
|
26
|
+
|
|
27
|
+
- **Zero-build capable**: runs directly in the browser; build tools are optional.
|
|
28
|
+
- **Async data built-in**: fetch and async state composables integrate directly with signals.
|
|
29
|
+
- **Security-focused**: DOM writes are sanitized by default; Trusted Types supported.
|
|
30
|
+
- **Modular**: the core stays small; extra modules are opt-in.
|
|
31
|
+
- **TypeScript-first**: clear types and strong IDE support.
|
|
32
|
+
- **Tree-shakeable**: import only what you need.
|
|
33
|
+
- **Storybook-ready**: default components can be previewed and developed in Storybook with dedicated story template helpers.
|
|
34
|
+
|
|
35
|
+
## Installation
|
|
36
|
+
|
|
37
|
+
### Via npm/bun/pnpm
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# npm
|
|
41
|
+
npm install @bquery/bquery
|
|
42
|
+
|
|
43
|
+
# bun
|
|
44
|
+
bun add @bquery/bquery
|
|
45
|
+
|
|
46
|
+
# pnpm
|
|
47
|
+
pnpm add @bquery/bquery
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Via CDN (Zero-build)
|
|
51
|
+
|
|
52
|
+
#### ES Modules (recommended)
|
|
53
|
+
|
|
54
|
+
```html
|
|
55
|
+
<script type="module">
|
|
56
|
+
import { $, signal } from 'https://unpkg.com/@bquery/bquery@1/dist/full.es.mjs';
|
|
57
|
+
|
|
58
|
+
const count = signal(0);
|
|
59
|
+
$('#counter').text(`Count: ${count.value}`);
|
|
60
|
+
</script>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
#### UMD (global variable)
|
|
64
|
+
|
|
65
|
+
```html
|
|
66
|
+
<script src="https://unpkg.com/@bquery/bquery@1/dist/full.umd.js"></script>
|
|
67
|
+
<script>
|
|
68
|
+
const { $, signal } = bQuery;
|
|
69
|
+
const count = signal(0);
|
|
70
|
+
</script>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
#### IIFE (self-executing)
|
|
74
|
+
|
|
75
|
+
```html
|
|
76
|
+
<script src="https://unpkg.com/@bquery/bquery@1/dist/full.iife.js"></script>
|
|
77
|
+
<script>
|
|
78
|
+
const { $, $$ } = bQuery;
|
|
79
|
+
$$('.items').addClass('loaded');
|
|
80
|
+
</script>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Import Strategies
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
// Full bundle (all modules)
|
|
87
|
+
import {
|
|
88
|
+
$,
|
|
89
|
+
signal,
|
|
90
|
+
component,
|
|
91
|
+
registerDefaultComponents,
|
|
92
|
+
defineBqueryConfig,
|
|
93
|
+
} from '@bquery/bquery';
|
|
94
|
+
|
|
95
|
+
// Core only
|
|
96
|
+
import { $, $$ } from '@bquery/bquery/core';
|
|
97
|
+
|
|
98
|
+
// Core utilities (named exports, tree-shakeable)
|
|
99
|
+
import { debounce, merge, uid, once, utils } from '@bquery/bquery/core';
|
|
100
|
+
|
|
101
|
+
// Reactive only
|
|
102
|
+
import {
|
|
103
|
+
signal,
|
|
104
|
+
computed,
|
|
105
|
+
effect,
|
|
106
|
+
linkedSignal,
|
|
107
|
+
persistedSignal,
|
|
108
|
+
useAsyncData,
|
|
109
|
+
useFetch,
|
|
110
|
+
createUseFetch,
|
|
111
|
+
} from '@bquery/bquery/reactive';
|
|
112
|
+
|
|
113
|
+
// Components only
|
|
114
|
+
import {
|
|
115
|
+
bool,
|
|
116
|
+
component,
|
|
117
|
+
defineComponent,
|
|
118
|
+
html,
|
|
119
|
+
registerDefaultComponents,
|
|
120
|
+
} from '@bquery/bquery/component';
|
|
121
|
+
|
|
122
|
+
// Motion only
|
|
123
|
+
import { transition, spring, animate, timeline } from '@bquery/bquery/motion';
|
|
124
|
+
|
|
125
|
+
// Security only
|
|
126
|
+
import { sanitize, sanitizeHtml, trusted } from '@bquery/bquery/security';
|
|
127
|
+
|
|
128
|
+
// Platform only
|
|
129
|
+
import { storage, cache, useCookie, definePageMeta, useAnnouncer } from '@bquery/bquery/platform';
|
|
130
|
+
|
|
131
|
+
// Router, Store, View
|
|
132
|
+
import { createRouter, navigate } from '@bquery/bquery/router';
|
|
133
|
+
import { createStore, defineStore } from '@bquery/bquery/store';
|
|
134
|
+
import { mount, createTemplate } from '@bquery/bquery/view';
|
|
135
|
+
|
|
136
|
+
// Storybook helpers
|
|
137
|
+
import { storyHtml, when } from '@bquery/bquery/storybook';
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Modules at a glance
|
|
141
|
+
|
|
142
|
+
| Module | Description | Size (gzip) |
|
|
143
|
+
| ------------- | -------------------------------------------------- | ----------- |
|
|
144
|
+
| **Core** | Selectors, DOM manipulation, events, utilities | ~11.3 KB |
|
|
145
|
+
| **Reactive** | `signal`, `computed`, `effect`, async data/fetch | ~0.3 KB |
|
|
146
|
+
| **Component** | Lightweight Web Components with props + defaults | ~1.9 KB |
|
|
147
|
+
| **Motion** | View transitions, FLIP, timelines, scroll, springs | ~4.0 KB |
|
|
148
|
+
| **Security** | HTML sanitizing, Trusted Types, CSP | ~0.7 KB |
|
|
149
|
+
| **Platform** | Storage, cache, cookies, meta, announcers, config | ~2.2 KB |
|
|
150
|
+
| **Router** | SPA routing, navigation guards, history API | ~2.2 KB |
|
|
151
|
+
| **Store** | Signal-based state management, persistence | ~0.3 KB |
|
|
152
|
+
| **View** | Declarative DOM bindings, directives | ~4.3 KB |
|
|
153
|
+
|
|
154
|
+
Storybook authoring helpers are also available as a dedicated entry point via `@bquery/bquery/storybook`.
|
|
155
|
+
|
|
156
|
+
## Quick examples
|
|
157
|
+
|
|
158
|
+
### Core – DOM & events
|
|
159
|
+
|
|
160
|
+
```ts
|
|
161
|
+
import { $, $$ } from '@bquery/bquery/core';
|
|
162
|
+
|
|
163
|
+
$('#save').on('click', (event) => {
|
|
164
|
+
console.log('Saved', event.type);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
$('#list').delegate('click', '.item', (event, target) => {
|
|
168
|
+
console.log('Item clicked', target.textContent);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
$('#box').addClass('active').css({ opacity: '0.8' }).attr('data-state', 'ready');
|
|
172
|
+
|
|
173
|
+
const color = $('#box').css('color');
|
|
174
|
+
|
|
175
|
+
if ($('#el').is('.active')) {
|
|
176
|
+
console.log('Element is active');
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
$$('.container').find('.item').addClass('found');
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Reactive – signals
|
|
183
|
+
|
|
184
|
+
```ts
|
|
185
|
+
import {
|
|
186
|
+
signal,
|
|
187
|
+
computed,
|
|
188
|
+
effect,
|
|
189
|
+
batch,
|
|
190
|
+
watch,
|
|
191
|
+
readonly,
|
|
192
|
+
linkedSignal,
|
|
193
|
+
} from '@bquery/bquery/reactive';
|
|
194
|
+
|
|
195
|
+
const count = signal(0);
|
|
196
|
+
const doubled = computed(() => count.value * 2);
|
|
197
|
+
|
|
198
|
+
effect(() => {
|
|
199
|
+
console.log('Count changed', count.value);
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
watch(count, (newVal, oldVal) => {
|
|
203
|
+
console.log(`Changed from ${oldVal} to ${newVal}`);
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
const readOnlyCount = readonly(count);
|
|
207
|
+
|
|
208
|
+
batch(() => {
|
|
209
|
+
count.value++;
|
|
210
|
+
count.value++;
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
count.dispose();
|
|
214
|
+
|
|
215
|
+
const first = signal('Ada');
|
|
216
|
+
const last = signal('Lovelace');
|
|
217
|
+
const fullName = linkedSignal(
|
|
218
|
+
() => `${first.value} ${last.value}`,
|
|
219
|
+
(next) => {
|
|
220
|
+
const [nextFirst, nextLast] = next.split(' ');
|
|
221
|
+
first.value = nextFirst ?? '';
|
|
222
|
+
last.value = nextLast ?? '';
|
|
223
|
+
}
|
|
224
|
+
);
|
|
225
|
+
|
|
226
|
+
fullName.value = 'Grace Hopper';
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Reactive – async data & fetch
|
|
230
|
+
|
|
231
|
+
```ts
|
|
232
|
+
import { signal, useFetch, createUseFetch } from '@bquery/bquery/reactive';
|
|
233
|
+
|
|
234
|
+
const userId = signal(1);
|
|
235
|
+
|
|
236
|
+
const user = useFetch<{ id: number; name: string }>(() => `/users/${userId.value}`, {
|
|
237
|
+
baseUrl: 'https://api.example.com',
|
|
238
|
+
watch: [userId],
|
|
239
|
+
query: { include: 'profile' },
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
const useApiFetch = createUseFetch({
|
|
243
|
+
baseUrl: 'https://api.example.com',
|
|
244
|
+
headers: { 'x-client': 'bquery-readme' },
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
const settings = useApiFetch<{ theme: string }>('/settings');
|
|
248
|
+
|
|
249
|
+
console.log(user.pending.value, user.data.value, settings.error.value);
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### Components – Web Components
|
|
253
|
+
|
|
254
|
+
```ts
|
|
255
|
+
import {
|
|
256
|
+
bool,
|
|
257
|
+
component,
|
|
258
|
+
defineComponent,
|
|
259
|
+
html,
|
|
260
|
+
registerDefaultComponents,
|
|
261
|
+
safeHtml,
|
|
262
|
+
} from '@bquery/bquery/component';
|
|
263
|
+
import { sanitizeHtml, trusted } from '@bquery/bquery/security';
|
|
264
|
+
|
|
265
|
+
const badge = trusted(sanitizeHtml('<span class="badge">Active</span>'));
|
|
266
|
+
|
|
267
|
+
component('user-card', {
|
|
268
|
+
props: {
|
|
269
|
+
username: { type: String, required: true },
|
|
270
|
+
age: { type: Number, validator: (v) => v >= 0 && v <= 150 },
|
|
271
|
+
},
|
|
272
|
+
state: { count: 0 },
|
|
273
|
+
beforeMount() {
|
|
274
|
+
console.log('About to mount');
|
|
275
|
+
},
|
|
276
|
+
connected() {
|
|
277
|
+
console.log('Mounted');
|
|
278
|
+
},
|
|
279
|
+
beforeUpdate(newProps, oldProps) {
|
|
280
|
+
return newProps.username !== oldProps.username;
|
|
281
|
+
},
|
|
282
|
+
updated(change) {
|
|
283
|
+
console.log('Updated because of', change?.name ?? 'state/signal change');
|
|
284
|
+
},
|
|
285
|
+
onError(error) {
|
|
286
|
+
console.error('Component error:', error);
|
|
287
|
+
},
|
|
288
|
+
render({ props, state }) {
|
|
289
|
+
return safeHtml`
|
|
290
|
+
<button class="user-card" ${bool('disabled', state.count > 3)}>
|
|
291
|
+
${badge}
|
|
292
|
+
<span>Hello ${props.username}</span>
|
|
293
|
+
</button>
|
|
294
|
+
`;
|
|
295
|
+
},
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
const UserCard = defineComponent('user-card-manual', {
|
|
299
|
+
props: { username: { type: String, required: true } },
|
|
300
|
+
render: ({ props }) => html`<div>Hello ${props.username}</div>`,
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
customElements.define('user-card-manual', UserCard);
|
|
304
|
+
|
|
305
|
+
const tags = registerDefaultComponents({ prefix: 'ui' });
|
|
306
|
+
console.log(tags.button); // ui-button
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
### Storybook – authoring helpers
|
|
310
|
+
|
|
311
|
+
```ts
|
|
312
|
+
import { storyHtml, when } from '@bquery/bquery/storybook';
|
|
313
|
+
|
|
314
|
+
export const Primary = {
|
|
315
|
+
args: { disabled: false, label: 'Save' },
|
|
316
|
+
render: ({ disabled, label }) =>
|
|
317
|
+
storyHtml`
|
|
318
|
+
<ui-card>
|
|
319
|
+
<ui-button ?disabled=${disabled}>${label}</ui-button>
|
|
320
|
+
${when(!disabled, '<small>Ready to submit</small>')}
|
|
321
|
+
</ui-card>
|
|
322
|
+
`,
|
|
323
|
+
};
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
### Motion – animations
|
|
327
|
+
|
|
328
|
+
```ts
|
|
329
|
+
import { animate, keyframePresets, spring, transition } from '@bquery/bquery/motion';
|
|
330
|
+
|
|
331
|
+
await transition({
|
|
332
|
+
update: () => {
|
|
333
|
+
$('#content').text('Updated');
|
|
334
|
+
},
|
|
335
|
+
classes: ['page-transition'],
|
|
336
|
+
types: ['navigation'],
|
|
337
|
+
skipOnReducedMotion: true,
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
await animate(card, {
|
|
341
|
+
keyframes: keyframePresets.pop(),
|
|
342
|
+
options: { duration: 240, easing: 'ease-out' },
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
const x = spring(0, { stiffness: 120, damping: 14 });
|
|
346
|
+
x.onChange((value) => {
|
|
347
|
+
element.style.transform = `translateX(${value}px)`;
|
|
348
|
+
});
|
|
349
|
+
await x.to(100);
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
### Security – sanitizing
|
|
353
|
+
|
|
354
|
+
```ts
|
|
355
|
+
import { sanitize, escapeHtml, sanitizeHtml, trusted } from '@bquery/bquery/security';
|
|
356
|
+
import { safeHtml } from '@bquery/bquery/component';
|
|
357
|
+
|
|
358
|
+
const safeMarkup = sanitize(userInput);
|
|
359
|
+
const safe = sanitize('<form id="cookie">...</form>');
|
|
360
|
+
const urlSafe = sanitize('<a href="java\u200Bscript:alert(1)">click</a>');
|
|
361
|
+
const secureLink = sanitize('<a href="https://external.com" target="_blank">Link</a>');
|
|
362
|
+
const safeSrcset = sanitize('<img srcset="safe.jpg 1x, javascript:alert(1) 2x">');
|
|
363
|
+
const safeForm = sanitize('<form action="javascript:alert(1)">...</form>');
|
|
364
|
+
const escaped = escapeHtml('<script>alert(1)</script>');
|
|
365
|
+
const icon = trusted(sanitizeHtml('<span class="icon">♥</span>'));
|
|
366
|
+
const button = safeHtml`<button>${icon}<span>Save</span></button>`;
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
### Platform – config, cookies & accessibility
|
|
370
|
+
|
|
371
|
+
```ts
|
|
372
|
+
import {
|
|
373
|
+
defineBqueryConfig,
|
|
374
|
+
useCookie,
|
|
375
|
+
definePageMeta,
|
|
376
|
+
useAnnouncer,
|
|
377
|
+
storage,
|
|
378
|
+
notifications,
|
|
379
|
+
} from '@bquery/bquery/platform';
|
|
380
|
+
|
|
381
|
+
defineBqueryConfig({
|
|
382
|
+
fetch: { baseUrl: 'https://api.example.com' },
|
|
383
|
+
transitions: { skipOnReducedMotion: true, classes: ['page-transition'] },
|
|
384
|
+
components: { prefix: 'ui' },
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
const theme = useCookie<'light' | 'dark'>('theme', { defaultValue: 'light' });
|
|
388
|
+
const cleanupMeta = definePageMeta({ title: 'Dashboard' });
|
|
389
|
+
const announcer = useAnnouncer();
|
|
390
|
+
|
|
391
|
+
theme.value = 'dark';
|
|
392
|
+
announcer.announce('Preferences saved');
|
|
393
|
+
cleanupMeta();
|
|
394
|
+
|
|
395
|
+
const local = storage.local();
|
|
396
|
+
await local.set('theme', theme.value);
|
|
397
|
+
|
|
398
|
+
const permission = await notifications.requestPermission();
|
|
399
|
+
if (permission === 'granted') {
|
|
400
|
+
notifications.send('Build complete', {
|
|
401
|
+
body: 'Your docs are ready.',
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
### Router – SPA navigation
|
|
407
|
+
|
|
408
|
+
```ts
|
|
409
|
+
import { effect } from '@bquery/bquery/reactive';
|
|
410
|
+
import { createRouter, navigate, currentRoute } from '@bquery/bquery/router';
|
|
411
|
+
|
|
412
|
+
const router = createRouter({
|
|
413
|
+
routes: [
|
|
414
|
+
{ path: '/', name: 'home', component: HomePage },
|
|
415
|
+
{ path: '/user/:id', name: 'user', component: UserPage },
|
|
416
|
+
{ path: '*', component: NotFound },
|
|
417
|
+
],
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
router.beforeEach(async (to) => {
|
|
421
|
+
if (to.path === '/admin' && !isAuthenticated()) {
|
|
422
|
+
await navigate('/login');
|
|
423
|
+
return false;
|
|
424
|
+
}
|
|
425
|
+
});
|
|
426
|
+
|
|
427
|
+
effect(() => {
|
|
428
|
+
console.log('Current path:', currentRoute.value.path);
|
|
429
|
+
});
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
### Store – state management
|
|
433
|
+
|
|
434
|
+
```ts
|
|
435
|
+
import {
|
|
436
|
+
createStore,
|
|
437
|
+
createPersistedStore,
|
|
438
|
+
defineStore,
|
|
439
|
+
mapGetters,
|
|
440
|
+
watchStore,
|
|
441
|
+
} from '@bquery/bquery/store';
|
|
442
|
+
|
|
443
|
+
const counterStore = createStore({
|
|
444
|
+
id: 'counter',
|
|
445
|
+
state: () => ({ count: 0, name: 'Counter' }),
|
|
446
|
+
getters: {
|
|
447
|
+
doubled: (state) => state.count * 2,
|
|
448
|
+
},
|
|
449
|
+
actions: {
|
|
450
|
+
increment() {
|
|
451
|
+
this.count++;
|
|
452
|
+
},
|
|
453
|
+
},
|
|
454
|
+
});
|
|
455
|
+
|
|
456
|
+
const settingsStore = createPersistedStore({
|
|
457
|
+
id: 'settings',
|
|
458
|
+
state: () => ({ theme: 'dark', language: 'en' }),
|
|
459
|
+
});
|
|
460
|
+
|
|
461
|
+
const useCounter = defineStore('counter', {
|
|
462
|
+
state: () => ({ count: 0 }),
|
|
463
|
+
getters: {
|
|
464
|
+
doubled: (state) => state.count * 2,
|
|
465
|
+
},
|
|
466
|
+
actions: {
|
|
467
|
+
increment() {
|
|
468
|
+
this.count++;
|
|
469
|
+
},
|
|
470
|
+
},
|
|
471
|
+
});
|
|
472
|
+
|
|
473
|
+
const counter = useCounter();
|
|
474
|
+
const getters = mapGetters(counter, ['doubled']);
|
|
475
|
+
|
|
476
|
+
watchStore(
|
|
477
|
+
counter,
|
|
478
|
+
(state) => state.count,
|
|
479
|
+
(value) => {
|
|
480
|
+
console.log('Count changed:', value, getters.doubled);
|
|
481
|
+
}
|
|
482
|
+
);
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
### View – declarative bindings
|
|
486
|
+
|
|
487
|
+
```ts
|
|
488
|
+
import { mount, createTemplate } from '@bquery/bquery/view';
|
|
489
|
+
import { signal } from '@bquery/bquery/reactive';
|
|
490
|
+
|
|
491
|
+
const count = signal(0);
|
|
492
|
+
const items = signal(['Apple', 'Banana', 'Cherry']);
|
|
493
|
+
|
|
494
|
+
mount('#app', {
|
|
495
|
+
count,
|
|
496
|
+
items,
|
|
497
|
+
increment: () => count.value++,
|
|
498
|
+
});
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
## Browser Support
|
|
502
|
+
|
|
503
|
+
| Browser | Version | Support |
|
|
504
|
+
| ------- | ------- | ------- |
|
|
505
|
+
| Chrome | 90+ | ✅ Full |
|
|
506
|
+
| Firefox | 90+ | ✅ Full |
|
|
507
|
+
| Safari | 15+ | ✅ Full |
|
|
508
|
+
| Edge | 90+ | ✅ Full |
|
|
509
|
+
|
|
510
|
+
> **No IE support** by design.
|
|
511
|
+
|
|
512
|
+
## Documentation
|
|
513
|
+
|
|
514
|
+
- **Getting Started**: [docs/guide/getting-started.md](docs/guide/getting-started.md)
|
|
515
|
+
- **Core API**: [docs/guide/api-core.md](docs/guide/api-core.md)
|
|
516
|
+
- **Agents**: [docs/guide/agents.md](docs/guide/agents.md)
|
|
517
|
+
- **Components**: [docs/guide/components.md](docs/guide/components.md)
|
|
518
|
+
- **Reactivity**: [docs/guide/reactive.md](docs/guide/reactive.md)
|
|
519
|
+
- **Motion**: [docs/guide/motion.md](docs/guide/motion.md)
|
|
520
|
+
- **Security**: [docs/guide/security.md](docs/guide/security.md)
|
|
521
|
+
- **Platform**: [docs/guide/platform.md](docs/guide/platform.md)
|
|
522
|
+
- **Router**: [docs/guide/router.md](docs/guide/router.md)
|
|
523
|
+
- **Store**: [docs/guide/store.md](docs/guide/store.md)
|
|
524
|
+
- **View**: [docs/guide/view.md](docs/guide/view.md)
|
|
525
|
+
|
|
526
|
+
## Local Development
|
|
527
|
+
|
|
528
|
+
```bash
|
|
529
|
+
# Install dependencies
|
|
530
|
+
bun install
|
|
531
|
+
|
|
532
|
+
# Start VitePress docs
|
|
533
|
+
bun run dev
|
|
534
|
+
|
|
535
|
+
# Run Storybook
|
|
536
|
+
bun run storybook
|
|
537
|
+
|
|
538
|
+
# Run tests
|
|
539
|
+
bun test
|
|
540
|
+
|
|
541
|
+
# Build library
|
|
542
|
+
bun run build
|
|
543
|
+
|
|
544
|
+
# Build docs
|
|
545
|
+
bun run build:docs
|
|
546
|
+
|
|
547
|
+
# Generate API documentation
|
|
548
|
+
bun run docs:api
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
## Project Structure
|
|
552
|
+
|
|
553
|
+
```text
|
|
554
|
+
bQuery.js
|
|
555
|
+
├── src/
|
|
556
|
+
│ ├── core/ # Selectors, DOM ops, events, utils
|
|
557
|
+
│ ├── reactive/ # Signals, computed, effects, async data
|
|
558
|
+
│ ├── component/ # Web Components helper + default library
|
|
559
|
+
│ ├── motion/ # View transitions, FLIP, springs
|
|
560
|
+
│ ├── security/ # Sanitizer, CSP, Trusted Types
|
|
561
|
+
│ ├── platform/ # Storage, cache, cookies, meta, config
|
|
562
|
+
│ ├── router/ # SPA routing, navigation guards
|
|
563
|
+
│ ├── store/ # State management, persistence
|
|
564
|
+
│ └── view/ # Declarative DOM bindings
|
|
565
|
+
├── docs/ # VitePress documentation
|
|
566
|
+
├── .storybook/ # Storybook config
|
|
567
|
+
├── stories/ # Component stories
|
|
568
|
+
├── tests/ # bun:test suites
|
|
569
|
+
└── dist/ # Built files (ESM, UMD, IIFE)
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
## Contributing
|
|
573
|
+
|
|
574
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
|
|
575
|
+
|
|
576
|
+
## AI Agent Support
|
|
577
|
+
|
|
578
|
+
This project provides dedicated context files for AI coding agents:
|
|
579
|
+
|
|
580
|
+
- **[AGENT.md](AGENT.md)** — Architecture, module API reference, coding conventions, common tasks
|
|
581
|
+
- **[llms.txt](llms.txt)** — Compact LLM-optimized project summary
|
|
582
|
+
- **[.github/copilot-instructions.md](.github/copilot-instructions.md)** — GitHub Copilot context
|
|
583
|
+
|
|
584
|
+
## License
|
|
585
|
+
|
|
586
|
+
MIT – See [LICENSE.md](LICENSE.md) for details.
|