@bquery/bquery 1.0.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 (80) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +266 -0
  3. package/dist/component/index.d.ts +155 -0
  4. package/dist/component/index.d.ts.map +1 -0
  5. package/dist/component.es.mjs +128 -0
  6. package/dist/component.es.mjs.map +1 -0
  7. package/dist/core/collection.d.ts +198 -0
  8. package/dist/core/collection.d.ts.map +1 -0
  9. package/dist/core/element.d.ts +301 -0
  10. package/dist/core/element.d.ts.map +1 -0
  11. package/dist/core/index.d.ts +5 -0
  12. package/dist/core/index.d.ts.map +1 -0
  13. package/dist/core/selector.d.ts +11 -0
  14. package/dist/core/selector.d.ts.map +1 -0
  15. package/dist/core/shared.d.ts +7 -0
  16. package/dist/core/shared.d.ts.map +1 -0
  17. package/dist/core/utils.d.ts +300 -0
  18. package/dist/core/utils.d.ts.map +1 -0
  19. package/dist/core.es.mjs +1015 -0
  20. package/dist/core.es.mjs.map +1 -0
  21. package/dist/full.d.ts +48 -0
  22. package/dist/full.d.ts.map +1 -0
  23. package/dist/full.es.mjs +43 -0
  24. package/dist/full.es.mjs.map +1 -0
  25. package/dist/full.iife.js +2 -0
  26. package/dist/full.iife.js.map +1 -0
  27. package/dist/full.umd.js +2 -0
  28. package/dist/full.umd.js.map +1 -0
  29. package/dist/index.d.ts +16 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.es.mjs +43 -0
  32. package/dist/index.es.mjs.map +1 -0
  33. package/dist/motion/index.d.ts +145 -0
  34. package/dist/motion/index.d.ts.map +1 -0
  35. package/dist/motion.es.mjs +104 -0
  36. package/dist/motion.es.mjs.map +1 -0
  37. package/dist/platform/buckets.d.ts +44 -0
  38. package/dist/platform/buckets.d.ts.map +1 -0
  39. package/dist/platform/cache.d.ts +71 -0
  40. package/dist/platform/cache.d.ts.map +1 -0
  41. package/dist/platform/index.d.ts +15 -0
  42. package/dist/platform/index.d.ts.map +1 -0
  43. package/dist/platform/notifications.d.ts +52 -0
  44. package/dist/platform/notifications.d.ts.map +1 -0
  45. package/dist/platform/storage.d.ts +69 -0
  46. package/dist/platform/storage.d.ts.map +1 -0
  47. package/dist/platform.es.mjs +245 -0
  48. package/dist/platform.es.mjs.map +1 -0
  49. package/dist/reactive/index.d.ts +8 -0
  50. package/dist/reactive/index.d.ts.map +1 -0
  51. package/dist/reactive/signal.d.ts +204 -0
  52. package/dist/reactive/signal.d.ts.map +1 -0
  53. package/dist/reactive.es.mjs +123 -0
  54. package/dist/reactive.es.mjs.map +1 -0
  55. package/dist/security/index.d.ts +8 -0
  56. package/dist/security/index.d.ts.map +1 -0
  57. package/dist/security/sanitize.d.ts +99 -0
  58. package/dist/security/sanitize.d.ts.map +1 -0
  59. package/dist/security.es.mjs +194 -0
  60. package/dist/security.es.mjs.map +1 -0
  61. package/package.json +120 -0
  62. package/src/component/index.ts +360 -0
  63. package/src/core/collection.ts +339 -0
  64. package/src/core/element.ts +493 -0
  65. package/src/core/index.ts +4 -0
  66. package/src/core/selector.ts +29 -0
  67. package/src/core/shared.ts +13 -0
  68. package/src/core/utils.ts +425 -0
  69. package/src/full.ts +101 -0
  70. package/src/index.ts +27 -0
  71. package/src/motion/index.ts +365 -0
  72. package/src/platform/buckets.ts +115 -0
  73. package/src/platform/cache.ts +130 -0
  74. package/src/platform/index.ts +18 -0
  75. package/src/platform/notifications.ts +87 -0
  76. package/src/platform/storage.ts +208 -0
  77. package/src/reactive/index.ts +9 -0
  78. package/src/reactive/signal.ts +347 -0
  79. package/src/security/index.ts +18 -0
  80. package/src/security/sanitize.ts +446 -0
@@ -0,0 +1,425 @@
1
+ /**
2
+ * Utility helpers used across the framework.
3
+ * These are intentionally small and framework-agnostic to keep the core tiny.
4
+ *
5
+ * @module bquery/core/utils
6
+ */
7
+
8
+ /**
9
+ * Utility object containing common helper functions.
10
+ * All utilities are designed to be tree-shakeable and have zero dependencies.
11
+ */
12
+ export const utils = {
13
+ /**
14
+ * Creates a deep clone using structuredClone if available, otherwise fallback to JSON.
15
+ *
16
+ * @template T - The type of value being cloned
17
+ * @param value - The value to clone
18
+ * @returns A deep copy of the value
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * const original = { nested: { value: 1 } };
23
+ * const copy = utils.clone(original);
24
+ * copy.nested.value = 2;
25
+ * console.log(original.nested.value); // 1
26
+ * ```
27
+ */
28
+ clone<T>(value: T): T {
29
+ if (typeof structuredClone === 'function') {
30
+ return structuredClone(value);
31
+ }
32
+ return JSON.parse(JSON.stringify(value)) as T;
33
+ },
34
+
35
+ /**
36
+ * Deep-merges plain objects into a new object.
37
+ * Later sources override earlier ones for primitive values.
38
+ * Objects are recursively merged.
39
+ *
40
+ * @template T - The type of the merged object
41
+ * @param sources - Objects to merge
42
+ * @returns A new object with all sources merged
43
+ *
44
+ * @example
45
+ * ```ts
46
+ * const result = utils.merge(
47
+ * { a: 1, nested: { x: 1 } },
48
+ * { b: 2, nested: { y: 2 } }
49
+ * );
50
+ * // Result: { a: 1, b: 2, nested: { x: 1, y: 2 } }
51
+ * ```
52
+ */
53
+ merge<T extends Record<string, unknown>>(...sources: T[]): T {
54
+ const result: Record<string, unknown> = {};
55
+ for (const source of sources) {
56
+ for (const [key, value] of Object.entries(source)) {
57
+ if (utils.isPlainObject(value) && utils.isPlainObject(result[key])) {
58
+ result[key] = utils.merge(
59
+ result[key] as Record<string, unknown>,
60
+ value as Record<string, unknown>
61
+ );
62
+ } else {
63
+ result[key] = value;
64
+ }
65
+ }
66
+ }
67
+ return result as T;
68
+ },
69
+
70
+ /**
71
+ * Creates a debounced function that delays execution until after
72
+ * the specified delay has elapsed since the last call.
73
+ *
74
+ * @template TArgs - The argument types of the function
75
+ * @param fn - The function to debounce
76
+ * @param delayMs - Delay in milliseconds
77
+ * @returns A debounced version of the function
78
+ *
79
+ * @example
80
+ * ```ts
81
+ * const search = utils.debounce((query: string) => {
82
+ * console.log('Searching:', query);
83
+ * }, 300);
84
+ *
85
+ * search('h');
86
+ * search('he');
87
+ * search('hello'); // Only this call executes after 300ms
88
+ * ```
89
+ */
90
+ debounce<TArgs extends unknown[]>(
91
+ fn: (...args: TArgs) => void,
92
+ delayMs: number
93
+ ): (...args: TArgs) => void {
94
+ let timeoutId: ReturnType<typeof setTimeout> | undefined;
95
+ return (...args: TArgs) => {
96
+ if (timeoutId) {
97
+ clearTimeout(timeoutId);
98
+ }
99
+ timeoutId = setTimeout(() => fn(...args), delayMs);
100
+ };
101
+ },
102
+
103
+ /**
104
+ * Creates a throttled function that runs at most once per interval.
105
+ *
106
+ * @template TArgs - The argument types of the function
107
+ * @param fn - The function to throttle
108
+ * @param intervalMs - Minimum interval between calls in milliseconds
109
+ * @returns A throttled version of the function
110
+ *
111
+ * @example
112
+ * ```ts
113
+ * const handleScroll = utils.throttle(() => {
114
+ * console.log('Scroll position:', window.scrollY);
115
+ * }, 100);
116
+ *
117
+ * window.addEventListener('scroll', handleScroll);
118
+ * ```
119
+ */
120
+ throttle<TArgs extends unknown[]>(
121
+ fn: (...args: TArgs) => void,
122
+ intervalMs: number
123
+ ): (...args: TArgs) => void {
124
+ let lastRun = 0;
125
+ return (...args: TArgs) => {
126
+ const now = Date.now();
127
+ if (now - lastRun >= intervalMs) {
128
+ lastRun = now;
129
+ fn(...args);
130
+ }
131
+ };
132
+ },
133
+
134
+ /**
135
+ * Creates a stable unique ID for DOM usage.
136
+ *
137
+ * @param prefix - Optional prefix for the ID (default: 'bQuery')
138
+ * @returns A unique identifier string
139
+ *
140
+ * @example
141
+ * ```ts
142
+ * const id = utils.uid('modal'); // 'modal_x7k2m9p'
143
+ * ```
144
+ */
145
+ uid(prefix = 'bQuery'): string {
146
+ return `${prefix}_${Math.random().toString(36).slice(2, 9)}`;
147
+ },
148
+
149
+ /**
150
+ * Checks if a value is a DOM Element.
151
+ *
152
+ * @param value - The value to check
153
+ * @returns True if the value is an Element
154
+ */
155
+ isElement(value: unknown): value is Element {
156
+ return value instanceof Element;
157
+ },
158
+
159
+ /**
160
+ * Checks if a value is a BQueryCollection-like object.
161
+ *
162
+ * @param value - The value to check
163
+ * @returns True if the value has an elements array property
164
+ */
165
+ isCollection(value: unknown): value is { elements: Element[] } {
166
+ return Boolean(value && typeof value === 'object' && 'elements' in (value as object));
167
+ },
168
+
169
+ /**
170
+ * Checks for emptiness across common value types.
171
+ *
172
+ * @param value - The value to check
173
+ * @returns True if the value is empty (null, undefined, empty string, empty array, or empty object)
174
+ *
175
+ * @example
176
+ * ```ts
177
+ * utils.isEmpty(''); // true
178
+ * utils.isEmpty([]); // true
179
+ * utils.isEmpty({}); // true
180
+ * utils.isEmpty(null); // true
181
+ * utils.isEmpty('hello'); // false
182
+ * utils.isEmpty([1, 2]); // false
183
+ * ```
184
+ */
185
+ isEmpty(value: unknown): boolean {
186
+ if (value == null) return true;
187
+ if (typeof value === 'string') return value.trim().length === 0;
188
+ if (Array.isArray(value)) return value.length === 0;
189
+ if (typeof value === 'object') return Object.keys(value as object).length === 0;
190
+ return false;
191
+ },
192
+
193
+ /**
194
+ * Checks if a value is a plain object (not null, array, or class instance).
195
+ *
196
+ * @param value - The value to check
197
+ * @returns True if the value is a plain object
198
+ */
199
+ isPlainObject(value: unknown): value is Record<string, unknown> {
200
+ return Object.prototype.toString.call(value) === '[object Object]';
201
+ },
202
+
203
+ /**
204
+ * Checks if a value is a function.
205
+ *
206
+ * @param value - The value to check
207
+ * @returns True if the value is a function
208
+ */
209
+ isFunction(value: unknown): value is (...args: unknown[]) => unknown {
210
+ return typeof value === 'function';
211
+ },
212
+
213
+ /**
214
+ * Checks if a value is a string.
215
+ *
216
+ * @param value - The value to check
217
+ * @returns True if the value is a string
218
+ */
219
+ isString(value: unknown): value is string {
220
+ return typeof value === 'string';
221
+ },
222
+
223
+ /**
224
+ * Checks if a value is a number (excluding NaN).
225
+ *
226
+ * @param value - The value to check
227
+ * @returns True if the value is a valid number
228
+ */
229
+ isNumber(value: unknown): value is number {
230
+ return typeof value === 'number' && !Number.isNaN(value);
231
+ },
232
+
233
+ /**
234
+ * Checks if a value is a boolean.
235
+ *
236
+ * @param value - The value to check
237
+ * @returns True if the value is a boolean
238
+ */
239
+ isBoolean(value: unknown): value is boolean {
240
+ return typeof value === 'boolean';
241
+ },
242
+
243
+ /**
244
+ * Checks if a value is an array.
245
+ *
246
+ * @template T - The type of array elements
247
+ * @param value - The value to check
248
+ * @returns True if the value is an array
249
+ */
250
+ isArray<T = unknown>(value: unknown): value is T[] {
251
+ return Array.isArray(value);
252
+ },
253
+
254
+ /**
255
+ * Safely parses a JSON string, returning a default value on error.
256
+ *
257
+ * @template T - The expected type of the parsed value
258
+ * @param json - The JSON string to parse
259
+ * @param fallback - The default value if parsing fails
260
+ * @returns The parsed value or the fallback
261
+ *
262
+ * @example
263
+ * ```ts
264
+ * utils.parseJson('{"name":"bQuery"}', {}); // { name: 'bQuery' }
265
+ * utils.parseJson('invalid', {}); // {}
266
+ * ```
267
+ */
268
+ parseJson<T>(json: string, fallback: T): T {
269
+ try {
270
+ return JSON.parse(json) as T;
271
+ } catch {
272
+ return fallback;
273
+ }
274
+ },
275
+
276
+ /**
277
+ * Picks specified keys from an object.
278
+ *
279
+ * @template T - The object type
280
+ * @template K - The key type
281
+ * @param obj - The source object
282
+ * @param keys - Keys to pick
283
+ * @returns A new object with only the specified keys
284
+ *
285
+ * @example
286
+ * ```ts
287
+ * const user = { name: 'John', age: 30, email: 'john@example.com' };
288
+ * utils.pick(user, ['name', 'email']); // { name: 'John', email: 'john@example.com' }
289
+ * ```
290
+ */
291
+ pick<T extends Record<string, unknown>, K extends keyof T>(obj: T, keys: K[]): Pick<T, K> {
292
+ const result = {} as Pick<T, K>;
293
+ for (const key of keys) {
294
+ if (key in obj) {
295
+ result[key] = obj[key];
296
+ }
297
+ }
298
+ return result;
299
+ },
300
+
301
+ /**
302
+ * Omits specified keys from an object.
303
+ *
304
+ * @template T - The object type
305
+ * @template K - The key type
306
+ * @param obj - The source object
307
+ * @param keys - Keys to omit
308
+ * @returns A new object without the specified keys
309
+ *
310
+ * @example
311
+ * ```ts
312
+ * const user = { name: 'John', age: 30, password: 'secret' };
313
+ * utils.omit(user, ['password']); // { name: 'John', age: 30 }
314
+ * ```
315
+ */
316
+ omit<T extends Record<string, unknown>, K extends keyof T>(obj: T, keys: K[]): Omit<T, K> {
317
+ const result = { ...obj };
318
+ for (const key of keys) {
319
+ delete result[key];
320
+ }
321
+ return result as Omit<T, K>;
322
+ },
323
+
324
+ /**
325
+ * Delays execution for a specified number of milliseconds.
326
+ *
327
+ * @param ms - Milliseconds to delay
328
+ * @returns A promise that resolves after the delay
329
+ *
330
+ * @example
331
+ * ```ts
332
+ * await utils.sleep(1000); // Wait 1 second
333
+ * console.log('Done!');
334
+ * ```
335
+ */
336
+ sleep(ms: number): Promise<void> {
337
+ return new Promise((resolve) => setTimeout(resolve, ms));
338
+ },
339
+
340
+ /**
341
+ * Generates a random integer between min and max (inclusive).
342
+ *
343
+ * @param min - Minimum value
344
+ * @param max - Maximum value
345
+ * @returns A random integer in the range [min, max]
346
+ *
347
+ * @example
348
+ * ```ts
349
+ * const roll = utils.randomInt(1, 6); // Random dice roll
350
+ * ```
351
+ */
352
+ randomInt(min: number, max: number): number {
353
+ return Math.floor(Math.random() * (max - min + 1)) + min;
354
+ },
355
+
356
+ /**
357
+ * Clamps a number between a minimum and maximum value.
358
+ *
359
+ * @param value - The value to clamp
360
+ * @param min - Minimum value
361
+ * @param max - Maximum value
362
+ * @returns The clamped value
363
+ *
364
+ * @example
365
+ * ```ts
366
+ * utils.clamp(150, 0, 100); // 100
367
+ * utils.clamp(-10, 0, 100); // 0
368
+ * utils.clamp(50, 0, 100); // 50
369
+ * ```
370
+ */
371
+ clamp(value: number, min: number, max: number): number {
372
+ return Math.min(Math.max(value, min), max);
373
+ },
374
+
375
+ /**
376
+ * Capitalizes the first letter of a string.
377
+ *
378
+ * @param str - The string to capitalize
379
+ * @returns The capitalized string
380
+ *
381
+ * @example
382
+ * ```ts
383
+ * utils.capitalize('hello'); // 'Hello'
384
+ * ```
385
+ */
386
+ capitalize(str: string): string {
387
+ if (!str) return str;
388
+ return str.charAt(0).toUpperCase() + str.slice(1);
389
+ },
390
+
391
+ /**
392
+ * Converts a string to kebab-case.
393
+ *
394
+ * @param str - The string to convert
395
+ * @returns The kebab-cased string
396
+ *
397
+ * @example
398
+ * ```ts
399
+ * utils.toKebabCase('myVariableName'); // 'my-variable-name'
400
+ * ```
401
+ */
402
+ toKebabCase(str: string): string {
403
+ return str
404
+ .replace(/([a-z])([A-Z])/g, '$1-$2')
405
+ .replace(/[\s_]+/g, '-')
406
+ .toLowerCase();
407
+ },
408
+
409
+ /**
410
+ * Converts a string to camelCase.
411
+ *
412
+ * @param str - The string to convert
413
+ * @returns The camelCased string
414
+ *
415
+ * @example
416
+ * ```ts
417
+ * utils.toCamelCase('my-variable-name'); // 'myVariableName'
418
+ * ```
419
+ */
420
+ toCamelCase(str: string): string {
421
+ return str
422
+ .replace(/[-_\s]+(.)?/g, (_, char) => (char ? char.toUpperCase() : ''))
423
+ .replace(/^[A-Z]/, (char) => char.toLowerCase());
424
+ },
425
+ };
package/src/full.ts ADDED
@@ -0,0 +1,101 @@
1
+ /**
2
+ * bQuery.js — Full Bundle
3
+ *
4
+ * This is the complete bundle containing all modules for CDN usage.
5
+ * Use this when you want all features without tree-shaking concerns.
6
+ *
7
+ * @module bquery/full
8
+ *
9
+ * @example CDN Usage (ES Modules)
10
+ * ```html
11
+ * <script type="module">
12
+ * import { $, signal, component } from 'https://unpkg.com/bquery@1/dist/full.es.mjs';
13
+ *
14
+ * const count = signal(0);
15
+ * $('#counter').text(count.value);
16
+ * </script>
17
+ * ```
18
+ *
19
+ * @example CDN Usage (UMD/Global)
20
+ * ```html
21
+ * <script src="https://unpkg.com/bquery@1/dist/full.umd.js"></script>
22
+ * <script>
23
+ * const { $, signal } = bQuery;
24
+ * const count = signal(0);
25
+ * </script>
26
+ * ```
27
+ *
28
+ * @example CDN Usage (IIFE)
29
+ * ```html
30
+ * <script src="https://unpkg.com/bquery@1/dist/full.iife.js"></script>
31
+ * <script>
32
+ * // bQuery is available as a global variable
33
+ * const { $, $$ } = bQuery;
34
+ * </script>
35
+ * ```
36
+ */
37
+
38
+ // ============================================================================
39
+ // Core Module: Selectors, DOM operations, events, utilities
40
+ // ============================================================================
41
+ export { $, $$, BQueryCollection, BQueryElement, utils } from './core/index';
42
+
43
+ // ============================================================================
44
+ // Reactive Module: Signals, computed values, effects, batching
45
+ // ============================================================================
46
+ export {
47
+ Computed,
48
+ Signal,
49
+ batch,
50
+ computed,
51
+ effect,
52
+ persistedSignal,
53
+ signal,
54
+ } from './reactive/index';
55
+ export type { CleanupFn, Observer } from './reactive/index';
56
+
57
+ // ============================================================================
58
+ // Component Module: Web Components helper with Shadow DOM
59
+ // ============================================================================
60
+ export { component, html, safeHtml } from './component/index';
61
+ export type { ComponentDefinition, PropDefinition } from './component/index';
62
+
63
+ // ============================================================================
64
+ // Motion Module: View transitions, FLIP animations, springs
65
+ // ============================================================================
66
+ export { capturePosition, flip, flipList, spring, springPresets, transition } from './motion/index';
67
+ export type {
68
+ ElementBounds,
69
+ FlipOptions,
70
+ Spring,
71
+ SpringConfig,
72
+ TransitionOptions,
73
+ } from './motion/index';
74
+
75
+ // ============================================================================
76
+ // Security Module: Sanitization, CSP compatibility, Trusted Types
77
+ // ============================================================================
78
+ export {
79
+ createTrustedHtml,
80
+ escapeHtml,
81
+ generateNonce,
82
+ getTrustedTypesPolicy,
83
+ hasCSPDirective,
84
+ isTrustedTypesSupported,
85
+ sanitize,
86
+ sanitizeHtml,
87
+ stripTags,
88
+ } from './security/index';
89
+ export type { SanitizeOptions } from './security/index';
90
+
91
+ // ============================================================================
92
+ // Platform Module: Storage, buckets, notifications, cache
93
+ // ============================================================================
94
+ export { buckets, cache, notifications, storage } from './platform/index';
95
+ export type {
96
+ Bucket,
97
+ CacheHandle,
98
+ IndexedDBOptions,
99
+ NotificationOptions,
100
+ StorageAdapter,
101
+ } from './platform/index';
package/src/index.ts ADDED
@@ -0,0 +1,27 @@
1
+ /**
2
+ * bQuery.js — The jQuery for the Modern Web Platform
3
+ *
4
+ * A zero-build, TypeScript-first library that bridges vanilla JavaScript
5
+ * and build-step frameworks with modern features.
6
+ *
7
+ * @module bquery
8
+ * @see https://github.com/your-org/bquery
9
+ */
10
+
11
+ // Core module: selectors, DOM ops, events, utils
12
+ export * from './core/index';
13
+
14
+ // Reactive module: signals, computed, effects, binding
15
+ export * from './reactive/index';
16
+
17
+ // Component module: Web Components helper
18
+ export * from './component/index';
19
+
20
+ // Motion module: view transitions, FLIP, springs
21
+ export * from './motion/index';
22
+
23
+ // Security module: sanitizer, CSP, Trusted Types
24
+ export * from './security/index';
25
+
26
+ // Platform module: storage, buckets, notifications, cache
27
+ export * from './platform/index';