@bquery/bquery 1.4.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/README.md +139 -120
  2. package/dist/component/component.d.ts.map +1 -1
  3. package/dist/component/index.d.ts +2 -0
  4. package/dist/component/index.d.ts.map +1 -1
  5. package/dist/component/library.d.ts +34 -0
  6. package/dist/component/library.d.ts.map +1 -0
  7. package/dist/component/types.d.ts +10 -6
  8. package/dist/component/types.d.ts.map +1 -1
  9. package/dist/component-CY5MVoYN.js +531 -0
  10. package/dist/component-CY5MVoYN.js.map +1 -0
  11. package/dist/component.es.mjs +6 -184
  12. package/dist/config-DRmZZno3.js +40 -0
  13. package/dist/config-DRmZZno3.js.map +1 -0
  14. package/dist/core-CK2Mfpf4.js +648 -0
  15. package/dist/core-CK2Mfpf4.js.map +1 -0
  16. package/dist/core-DPdbItcq.js +112 -0
  17. package/dist/core-DPdbItcq.js.map +1 -0
  18. package/dist/core.es.mjs +45 -1261
  19. package/dist/full.d.ts +6 -6
  20. package/dist/full.d.ts.map +1 -1
  21. package/dist/full.es.mjs +98 -92
  22. package/dist/full.iife.js +173 -3
  23. package/dist/full.iife.js.map +1 -1
  24. package/dist/full.umd.js +173 -3
  25. package/dist/full.umd.js.map +1 -1
  26. package/dist/index.es.mjs +143 -139
  27. package/dist/motion/transition.d.ts +1 -1
  28. package/dist/motion/transition.d.ts.map +1 -1
  29. package/dist/motion/types.d.ts +11 -1
  30. package/dist/motion/types.d.ts.map +1 -1
  31. package/dist/motion-C5DRdPnO.js +415 -0
  32. package/dist/motion-C5DRdPnO.js.map +1 -0
  33. package/dist/motion.es.mjs +25 -361
  34. package/dist/object-qGpWr6-J.js +38 -0
  35. package/dist/object-qGpWr6-J.js.map +1 -0
  36. package/dist/platform/announcer.d.ts +59 -0
  37. package/dist/platform/announcer.d.ts.map +1 -0
  38. package/dist/platform/config.d.ts +92 -0
  39. package/dist/platform/config.d.ts.map +1 -0
  40. package/dist/platform/cookies.d.ts +45 -0
  41. package/dist/platform/cookies.d.ts.map +1 -0
  42. package/dist/platform/index.d.ts +8 -0
  43. package/dist/platform/index.d.ts.map +1 -1
  44. package/dist/platform/meta.d.ts +62 -0
  45. package/dist/platform/meta.d.ts.map +1 -0
  46. package/dist/platform-B7JhGBc7.js +361 -0
  47. package/dist/platform-B7JhGBc7.js.map +1 -0
  48. package/dist/platform.es.mjs +11 -248
  49. package/dist/reactive/async-data.d.ts +114 -0
  50. package/dist/reactive/async-data.d.ts.map +1 -0
  51. package/dist/reactive/index.d.ts +2 -2
  52. package/dist/reactive/index.d.ts.map +1 -1
  53. package/dist/reactive/signal.d.ts +2 -0
  54. package/dist/reactive/signal.d.ts.map +1 -1
  55. package/dist/reactive-BDya-ia8.js +253 -0
  56. package/dist/reactive-BDya-ia8.js.map +1 -0
  57. package/dist/reactive.es.mjs +18 -34
  58. package/dist/router-CijiICxt.js +188 -0
  59. package/dist/router-CijiICxt.js.map +1 -0
  60. package/dist/router.es.mjs +11 -200
  61. package/dist/sanitize-jyJ2ryE2.js +302 -0
  62. package/dist/sanitize-jyJ2ryE2.js.map +1 -0
  63. package/dist/security/constants.d.ts.map +1 -1
  64. package/dist/security.es.mjs +10 -56
  65. package/dist/store-CPK9E62U.js +262 -0
  66. package/dist/store-CPK9E62U.js.map +1 -0
  67. package/dist/store.es.mjs +12 -25
  68. package/dist/view-Cdi0g-qo.js +396 -0
  69. package/dist/view-Cdi0g-qo.js.map +1 -0
  70. package/dist/view.es.mjs +10 -430
  71. package/package.json +15 -11
  72. package/src/component/component.ts +319 -289
  73. package/src/component/index.ts +42 -40
  74. package/src/component/library.ts +504 -0
  75. package/src/component/types.ts +91 -85
  76. package/src/core/collection.ts +628 -628
  77. package/src/core/element.ts +774 -774
  78. package/src/core/index.ts +48 -48
  79. package/src/core/utils/function.ts +151 -151
  80. package/src/full.ts +223 -187
  81. package/src/motion/animate.ts +113 -113
  82. package/src/motion/flip.ts +176 -176
  83. package/src/motion/scroll.ts +57 -57
  84. package/src/motion/spring.ts +150 -150
  85. package/src/motion/timeline.ts +246 -246
  86. package/src/motion/transition.ts +53 -7
  87. package/src/motion/types.ts +208 -198
  88. package/src/platform/announcer.ts +208 -0
  89. package/src/platform/config.ts +163 -0
  90. package/src/platform/cookies.ts +165 -0
  91. package/src/platform/index.ts +39 -18
  92. package/src/platform/meta.ts +168 -0
  93. package/src/platform/storage.ts +215 -215
  94. package/src/reactive/async-data.ts +486 -0
  95. package/src/reactive/core.ts +114 -114
  96. package/src/reactive/effect.ts +54 -54
  97. package/src/reactive/index.ts +37 -23
  98. package/src/reactive/internals.ts +122 -122
  99. package/src/reactive/signal.ts +29 -20
  100. package/src/security/constants.ts +211 -209
  101. package/src/security/sanitize-core.ts +364 -364
  102. package/src/view/evaluate.ts +290 -290
  103. package/dist/batch-x7b2eZST.js +0 -13
  104. package/dist/batch-x7b2eZST.js.map +0 -1
  105. package/dist/component.es.mjs.map +0 -1
  106. package/dist/core-BhpuvPhy.js +0 -170
  107. package/dist/core-BhpuvPhy.js.map +0 -1
  108. package/dist/core.es.mjs.map +0 -1
  109. package/dist/full.es.mjs.map +0 -1
  110. package/dist/index.es.mjs.map +0 -1
  111. package/dist/motion.es.mjs.map +0 -1
  112. package/dist/persisted-DHoi3uEs.js +0 -278
  113. package/dist/persisted-DHoi3uEs.js.map +0 -1
  114. package/dist/platform.es.mjs.map +0 -1
  115. package/dist/reactive.es.mjs.map +0 -1
  116. package/dist/router.es.mjs.map +0 -1
  117. package/dist/sanitize-Cxvxa-DX.js +0 -283
  118. package/dist/sanitize-Cxvxa-DX.js.map +0 -1
  119. package/dist/security.es.mjs.map +0 -1
  120. package/dist/store.es.mjs.map +0 -1
  121. package/dist/type-guards-BdKlYYlS.js +0 -32
  122. package/dist/type-guards-BdKlYYlS.js.map +0 -1
  123. package/dist/untrack-DNnnqdlR.js +0 -6
  124. package/dist/untrack-DNnnqdlR.js.map +0 -1
  125. package/dist/view.es.mjs.map +0 -1
  126. package/dist/watch-DXXv3iAI.js +0 -58
  127. package/dist/watch-DXXv3iAI.js.map +0 -1
@@ -1,278 +0,0 @@
1
- import { s as P, c as j } from "./core-BhpuvPhy.js";
2
- import { u as x } from "./untrack-DNnnqdlR.js";
3
- import { b as S } from "./batch-x7b2eZST.js";
4
- const V = () => {
5
- if (!(typeof window > "u"))
6
- return window.__BQUERY_DEVTOOLS__ || (window.__BQUERY_DEVTOOLS__ = { stores: /* @__PURE__ */ new Map() }), window.__BQUERY_DEVTOOLS__;
7
- }, $ = (e, t) => {
8
- const o = V();
9
- o && (o.stores.set(e, t), o.onStoreCreated?.(e, t));
10
- }, T = (e) => {
11
- typeof window > "u" || !window.__BQUERY_DEVTOOLS__ || window.__BQUERY_DEVTOOLS__.stores.delete(e);
12
- }, R = (e, t) => {
13
- typeof window > "u" || window.__BQUERY_DEVTOOLS__?.onStateChange?.(e, t);
14
- }, E = [], F = (e) => {
15
- E.push(e);
16
- }, B = (e, t) => {
17
- for (const o of E) {
18
- const a = o({ store: e, options: t });
19
- a && Object.assign(e, a);
20
- }
21
- }, v = /* @__PURE__ */ new Map(), M = (e) => v.has(e), Q = (e, t) => {
22
- v.set(e, t);
23
- }, N = (e) => v.get(e), K = () => Array.from(v.keys()), q = (e) => {
24
- v.delete(e), T(e);
25
- }, A = (e) => e !== null && typeof e == "object" && Object.getPrototypeOf(e) === Object.prototype, p = (e) => {
26
- if (e === null || typeof e != "object")
27
- return e;
28
- if (Array.isArray(e))
29
- return e.map(p);
30
- if (e instanceof Date)
31
- return new Date(e.getTime());
32
- if (e instanceof Map)
33
- return new Map(Array.from(e.entries()).map(([o, a]) => [o, p(a)]));
34
- if (e instanceof Set)
35
- return new Set(Array.from(e).map(p));
36
- const t = {};
37
- for (const o of Object.keys(e))
38
- t[o] = p(e[o]);
39
- return t;
40
- }, h = (e, t) => {
41
- if (e === t) return !0;
42
- if (e === null || t === null || typeof e != "object" || typeof t != "object") return !1;
43
- if (e instanceof Date && t instanceof Date)
44
- return e.getTime() === t.getTime();
45
- if (e instanceof Map && t instanceof Map) {
46
- if (e.size !== t.size) return !1;
47
- for (const [c, f] of e.entries())
48
- if (!t.has(c) || !h(f, t.get(c))) return !1;
49
- return !0;
50
- }
51
- if (e instanceof Set && t instanceof Set) {
52
- if (e.size !== t.size) return !1;
53
- for (const c of e.values()) {
54
- let f = !1;
55
- for (const r of t.values())
56
- if (h(c, r)) {
57
- f = !0;
58
- break;
59
- }
60
- if (!f) return !1;
61
- }
62
- return !0;
63
- }
64
- if (Array.isArray(e) && Array.isArray(t))
65
- return e.length !== t.length ? !1 : e.every((c, f) => h(c, t[f]));
66
- if (Array.isArray(e) !== Array.isArray(t)) return !1;
67
- const o = Object.keys(e), a = Object.keys(t);
68
- return o.length !== a.length ? !1 : o.every(
69
- (c) => h(e[c], t[c])
70
- );
71
- }, U = (e, t, o) => {
72
- const a = [];
73
- for (const c of Object.keys(t)) {
74
- const f = e[c], r = t[c];
75
- o.get(c) === r && A(f) && A(r) && !h(f, r) && a.push(c);
76
- }
77
- return a;
78
- }, b = (() => {
79
- try {
80
- const e = globalThis.process;
81
- return !(typeof e < "u" && e.env?.NODE_ENV === "production");
82
- } catch {
83
- return !0;
84
- }
85
- })(), C = (e) => {
86
- const { id: t, state: o, getters: a = {}, actions: c = {} } = e;
87
- if (M(t))
88
- return console.warn(`bQuery store: Store "${t}" already exists. Returning existing instance.`), N(t);
89
- const f = o(), r = /* @__PURE__ */ new Map();
90
- for (const n of Object.keys(f))
91
- r.set(n, P(f[n]));
92
- const y = [], w = () => x(() => ({ ...k })), m = () => {
93
- const n = typeof window < "u" && typeof window.__BQUERY_DEVTOOLS__?.onStateChange == "function";
94
- if (y.length === 0 && !n)
95
- return;
96
- const s = w();
97
- for (const i of y)
98
- i(s);
99
- R(t, s);
100
- }, k = new Proxy({}, {
101
- get: (n, s) => {
102
- const i = s;
103
- if (r.has(i))
104
- return r.get(i).value;
105
- },
106
- ownKeys: () => Array.from(r.keys()),
107
- getOwnPropertyDescriptor: (n, s) => {
108
- if (r.has(s))
109
- return { enumerable: !0, configurable: !0 };
110
- },
111
- has: (n, s) => r.has(s)
112
- }), _ = /* @__PURE__ */ new Map(), g = {};
113
- for (const n of Object.keys(f))
114
- Object.defineProperty(g, n, {
115
- get: () => r.get(n).value,
116
- set: (s) => {
117
- r.get(n).value = s, m();
118
- },
119
- enumerable: !0,
120
- configurable: !1
121
- });
122
- for (const n of Object.keys(a)) {
123
- const s = a[n], i = j(() => {
124
- const d = k, l = new Proxy({}, {
125
- get: (u, O) => {
126
- const D = O;
127
- if (_.has(D))
128
- return _.get(D).value;
129
- }
130
- });
131
- return s(d, l);
132
- });
133
- _.set(n, i), Object.defineProperty(g, n, {
134
- get: () => i.value,
135
- enumerable: !0,
136
- configurable: !1
137
- });
138
- }
139
- for (const n of Object.keys(c)) {
140
- const s = c[n];
141
- g[n] = function(...i) {
142
- const d = new Proxy(g, {
143
- get: (l, u) => typeof u == "string" && r.has(u) ? r.get(u).value : l[u],
144
- set: (l, u, O) => typeof u == "string" && r.has(u) ? (r.get(u).value = O, m(), !0) : Reflect.set(l, u, O)
145
- });
146
- return s.apply(d, i);
147
- };
148
- }
149
- return Object.defineProperties(g, {
150
- $id: {
151
- value: t,
152
- writable: !1,
153
- enumerable: !1
154
- },
155
- $reset: {
156
- value: () => {
157
- const n = o();
158
- S(() => {
159
- for (const [s, i] of r)
160
- i.value = n[s];
161
- }), m();
162
- },
163
- writable: !1,
164
- enumerable: !1
165
- },
166
- $subscribe: {
167
- value: (n) => (y.push(n), () => {
168
- const s = y.indexOf(n);
169
- s > -1 && y.splice(s, 1);
170
- }),
171
- writable: !1,
172
- enumerable: !1
173
- },
174
- $patch: {
175
- value: (n) => {
176
- S(() => {
177
- if (typeof n == "function") {
178
- const s = b ? p(w()) : null, i = b ? new Map(Array.from(r.entries()).map(([l, u]) => [l, u.value])) : null, d = w();
179
- if (n(d), b && s && i) {
180
- const l = U(s, d, i);
181
- l.length > 0 && console.warn(
182
- `[bQuery store "${t}"] Nested mutation detected in $patch() for keys: ${l.map(String).join(", ")}.
183
- Nested object mutations do not trigger reactive updates because the store uses shallow reactivity.
184
- To fix this, either:
185
- 1. Replace the entire object: state.user = { ...state.user, name: "New" }
186
- 2. Use $patchDeep() for automatic deep cloning
187
- See: https://bquery.dev/guide/store#deep-reactivity`
188
- );
189
- }
190
- for (const [l, u] of Object.entries(d))
191
- r.has(l) && (r.get(l).value = u);
192
- } else
193
- for (const [s, i] of Object.entries(n))
194
- r.has(s) && (r.get(s).value = i);
195
- }), m();
196
- },
197
- writable: !1,
198
- enumerable: !1
199
- },
200
- $patchDeep: {
201
- value: (n) => {
202
- S(() => {
203
- if (typeof n == "function") {
204
- const s = p(w());
205
- n(s);
206
- for (const [i, d] of Object.entries(s))
207
- r.has(i) && (r.get(i).value = d);
208
- } else
209
- for (const [s, i] of Object.entries(n))
210
- r.has(s) && (r.get(s).value = p(i));
211
- }), m();
212
- },
213
- writable: !1,
214
- enumerable: !1
215
- },
216
- $state: {
217
- get: () => w(),
218
- enumerable: !1
219
- }
220
- }), Q(t, g), B(g, e), $(t, g), g;
221
- }, G = (e, t) => {
222
- const o = {};
223
- for (const a of t)
224
- Object.defineProperty(o, a, {
225
- get: () => e[a],
226
- enumerable: !0
227
- });
228
- return o;
229
- }, I = (e, t) => {
230
- const o = {};
231
- for (const a of t)
232
- Object.defineProperty(o, a, {
233
- get: () => e[a],
234
- enumerable: !0
235
- });
236
- return o;
237
- }, J = (e, t) => {
238
- const o = {};
239
- for (const a of t)
240
- o[a] = (...c) => e[a](...c);
241
- return o;
242
- }, H = (e, t) => {
243
- const o = t ?? `bquery-store-${e.id}`, a = e.state, c = {
244
- ...e,
245
- state: () => {
246
- const r = a();
247
- if (typeof window < "u")
248
- try {
249
- const y = localStorage.getItem(o);
250
- if (y)
251
- return { ...r, ...JSON.parse(y) };
252
- } catch {
253
- }
254
- return r;
255
- }
256
- }, f = C(c);
257
- return f.$subscribe((r) => {
258
- if (typeof window < "u")
259
- try {
260
- localStorage.setItem(o, JSON.stringify(r));
261
- } catch {
262
- }
263
- }), f;
264
- };
265
- export {
266
- C as a,
267
- G as b,
268
- H as c,
269
- q as d,
270
- I as e,
271
- h as f,
272
- N as g,
273
- M as h,
274
- K as l,
275
- J as m,
276
- F as r
277
- };
278
- //# sourceMappingURL=persisted-DHoi3uEs.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"persisted-DHoi3uEs.js","sources":["../src/store/devtools.ts","../src/store/plugins.ts","../src/store/registry.ts","../src/store/utils.ts","../src/store/create-store.ts","../src/store/mapping.ts","../src/store/persisted.ts"],"sourcesContent":["/**\n * Devtools integration for stores.\n * @internal\n */\n\ndeclare global {\n interface Window {\n __BQUERY_DEVTOOLS__?: {\n stores: Map<string, unknown>;\n onStoreCreated?: (id: string, store: unknown) => void;\n onStateChange?: (id: string, state: unknown) => void;\n };\n }\n}\n\nexport type DevtoolsHook = {\n stores: Map<string, unknown>;\n onStoreCreated?: (id: string, store: unknown) => void;\n onStateChange?: (id: string, state: unknown) => void;\n};\n\nconst ensureDevtools = (): DevtoolsHook | undefined => {\n if (typeof window === 'undefined') return undefined;\n if (!window.__BQUERY_DEVTOOLS__) {\n window.__BQUERY_DEVTOOLS__ = { stores: new Map() };\n }\n return window.__BQUERY_DEVTOOLS__;\n};\n\nexport const registerDevtoolsStore = (id: string, store: unknown): void => {\n const devtools = ensureDevtools();\n if (!devtools) return;\n devtools.stores.set(id, store);\n devtools.onStoreCreated?.(id, store);\n};\n\nexport const unregisterDevtoolsStore = (id: string): void => {\n if (typeof window === 'undefined' || !window.__BQUERY_DEVTOOLS__) return;\n window.__BQUERY_DEVTOOLS__.stores.delete(id);\n};\n\nexport const notifyDevtoolsStateChange = (id: string, state: unknown): void => {\n if (typeof window === 'undefined') return;\n window.__BQUERY_DEVTOOLS__?.onStateChange?.(id, state);\n};\n","/**\n * Store plugins API.\n */\n\nimport type { Store, StoreDefinition, StorePlugin } from './types';\n\n/** @internal Registered plugins */\nconst plugins: StorePlugin[] = [];\n\n/**\n * Registers a plugin that extends all stores.\n *\n * @param plugin - The plugin function\n */\nexport const registerPlugin = (plugin: StorePlugin): void => {\n plugins.push(plugin);\n};\n\n/** @internal */\nexport const applyPlugins = (\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n store: Store<any, any, any>,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n options: StoreDefinition<any, any, any>\n): void => {\n for (const plugin of plugins) {\n const extension = plugin({ store, options });\n if (extension) {\n Object.assign(store, extension);\n }\n }\n};\n","/**\n * Store registry utilities.\n */\n\nimport { unregisterDevtoolsStore } from './devtools';\nimport type { Store } from './types';\n\n/** @internal Registry of all stores for devtools */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst storeRegistry = new Map<string, Store<any, any, any>>();\n\n/** @internal */\nexport const hasStore = (id: string): boolean => storeRegistry.has(id);\n\n/** @internal */\nexport const registerStore = (\n id: string,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n store: Store<any, any, any>\n): void => {\n storeRegistry.set(id, store);\n};\n\n/**\n * Retrieves an existing store by its ID.\n *\n * @param id - The store identifier\n * @returns The store instance or undefined if not found\n */\nexport const getStore = <T = unknown>(id: string): T | undefined => {\n return storeRegistry.get(id) as T | undefined;\n};\n\n/**\n * Lists all registered store IDs.\n *\n * @returns Array of store IDs\n */\nexport const listStores = (): string[] => {\n return Array.from(storeRegistry.keys());\n};\n\n/**\n * Removes a store from the registry.\n *\n * @param id - The store identifier\n */\nexport const destroyStore = (id: string): void => {\n storeRegistry.delete(id);\n unregisterDevtoolsStore(id);\n};\n","/**\n * Internal utilities for the store module.\n * @internal\n */\n\n/**\n * Check if a value is a plain object (not array, null, Date, etc.).\n * @internal\n */\nexport const isPlainObject = (value: unknown): value is Record<string, unknown> => {\n return (\n value !== null && typeof value === 'object' && Object.getPrototypeOf(value) === Object.prototype\n );\n};\n\n/**\n * Deep clones an object. Used for deep reactivity support.\n * @internal\n */\nexport const deepClone = <T>(obj: T): T => {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map(deepClone) as T;\n }\n\n if (obj instanceof Date) {\n return new Date(obj.getTime()) as T;\n }\n\n if (obj instanceof Map) {\n return new Map(Array.from(obj.entries()).map(([k, v]) => [k, deepClone(v)])) as T;\n }\n\n if (obj instanceof Set) {\n return new Set(Array.from(obj).map(deepClone)) as T;\n }\n\n const cloned = {} as T;\n for (const key of Object.keys(obj)) {\n (cloned as Record<string, unknown>)[key] = deepClone((obj as Record<string, unknown>)[key]);\n }\n return cloned;\n};\n\n/**\n * Compares two values for deep equality.\n * @internal\n */\nexport const deepEqual = (a: unknown, b: unknown): boolean => {\n if (a === b) return true;\n if (a === null || b === null) return false;\n if (typeof a !== 'object' || typeof b !== 'object') return false;\n\n if (a instanceof Date && b instanceof Date) {\n return a.getTime() === b.getTime();\n }\n\n if (a instanceof Map && b instanceof Map) {\n if (a.size !== b.size) return false;\n for (const [key, value] of a.entries()) {\n if (!b.has(key) || !deepEqual(value, b.get(key))) return false;\n }\n return true;\n }\n\n if (a instanceof Set && b instanceof Set) {\n if (a.size !== b.size) return false;\n for (const value of a.values()) {\n let found = false;\n for (const candidate of b.values()) {\n if (deepEqual(value, candidate)) {\n found = true;\n break;\n }\n }\n if (!found) return false;\n }\n return true;\n }\n\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) return false;\n return a.every((item, i) => deepEqual(item, b[i]));\n }\n\n if (Array.isArray(a) !== Array.isArray(b)) return false;\n\n const keysA = Object.keys(a as object);\n const keysB = Object.keys(b as object);\n\n if (keysA.length !== keysB.length) return false;\n\n return keysA.every((key) =>\n deepEqual((a as Record<string, unknown>)[key], (b as Record<string, unknown>)[key])\n );\n};\n\n/**\n * Detects if nested objects were mutated but the reference stayed the same.\n * Returns the keys where nested mutations were detected.\n * @internal\n */\nexport const detectNestedMutations = <S extends Record<string, unknown>>(\n before: S,\n after: S,\n signalValues: Map<keyof S, unknown>\n): Array<keyof S> => {\n const mutatedKeys: Array<keyof S> = [];\n\n for (const key of Object.keys(after) as Array<keyof S>) {\n const beforeValue = before[key];\n const afterValue = after[key];\n const signalValue = signalValues.get(key);\n\n // Check if it's the same reference but content changed\n if (\n signalValue === afterValue &&\n isPlainObject(beforeValue) &&\n isPlainObject(afterValue) &&\n !deepEqual(beforeValue, afterValue)\n ) {\n mutatedKeys.push(key);\n }\n }\n\n return mutatedKeys;\n};\n\n/** @internal Flag to enable/disable development warnings */\nexport const isDev = (() => {\n try {\n const globalProcess = (globalThis as { process?: { env?: { NODE_ENV?: string } } }).process;\n // Default to dev mode unless explicitly set to production\n return !(typeof globalProcess !== 'undefined' && globalProcess.env?.NODE_ENV === 'production');\n } catch {\n return true;\n }\n})();\n","/**\n * Store creation logic.\n */\n\nimport {\n batch,\n computed,\n signal,\n untrack,\n type ReadonlySignal,\n type Signal,\n} from '../reactive/index';\nimport { notifyDevtoolsStateChange, registerDevtoolsStore } from './devtools';\nimport { applyPlugins } from './plugins';\nimport { getStore, hasStore, registerStore } from './registry';\nimport type { Getters, Store, StoreDefinition, StoreSubscriber } from './types';\nimport { deepClone, detectNestedMutations, isDev } from './utils';\n\n/**\n * Creates a reactive store with state, getters, and actions.\n *\n * @template S - State type\n * @template G - Getters type\n * @template A - Actions type\n * @param definition - Store definition\n * @returns The reactive store instance\n */\nexport const createStore = <\n S extends Record<string, unknown>,\n G extends Record<string, unknown> = Record<string, never>,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n A extends Record<string, (...args: any[]) => any> = Record<string, never>,\n>(\n definition: StoreDefinition<S, G, A>\n): Store<S, G, A> => {\n const { id, state: stateFactory, getters = {} as Getters<S, G>, actions = {} as A } = definition;\n\n // Check for duplicate store IDs\n if (hasStore(id)) {\n console.warn(`bQuery store: Store \"${id}\" already exists. Returning existing instance.`);\n return getStore(id) as Store<S, G, A>;\n }\n\n // Create initial state\n const initialState = stateFactory();\n\n // Create signals for each state property\n const stateSignals = new Map<keyof S, Signal<unknown>>();\n for (const key of Object.keys(initialState) as Array<keyof S>) {\n stateSignals.set(key, signal(initialState[key]));\n }\n\n // Subscribers for $subscribe\n const subscribers: Array<StoreSubscriber<S>> = [];\n\n /**\n * Gets the current state.\n *\n * For subscriber notifications (where a plain object snapshot is needed),\n * this creates a shallow copy. For internal reads, use stateProxy directly.\n *\n * **Note:** Returns a shallow snapshot. Nested object mutations will NOT\n * trigger reactive updates. This differs from frameworks like Pinia that\n * use deep reactivity. To update nested state, replace the entire object.\n *\n * Uses `untrack()` to prevent accidental dependency tracking when called\n * from within reactive contexts (e.g., `effect()` or `computed()`).\n *\n * @internal\n */\n const getCurrentState = (): S =>\n untrack(() => {\n return { ...stateProxy };\n });\n\n /**\n * Notifies subscribers of state changes.\n * Short-circuits if there are no subscribers and devtools aren't active\n * to avoid unnecessary snapshot overhead.\n * @internal\n */\n const notifySubscribers = (): void => {\n // Early return if no subscribers and no devtools hook\n const hasDevtools =\n typeof window !== 'undefined' &&\n typeof window.__BQUERY_DEVTOOLS__?.onStateChange === 'function';\n if (subscribers.length === 0 && !hasDevtools) {\n return;\n }\n\n const currentState = getCurrentState();\n for (const callback of subscribers) {\n callback(currentState);\n }\n\n notifyDevtoolsStateChange(id, currentState);\n };\n\n /**\n * Cached state proxy that lazily reads signal values.\n * Uses a Proxy to avoid creating new objects on each access.\n *\n * **Note:** This returns a shallow snapshot of the state. Nested object\n * mutations will NOT trigger reactive updates. For nested reactivity,\n * replace the entire object or use signals for nested properties.\n *\n * @internal\n */\n const stateProxy = new Proxy({} as S, {\n get: (_, prop: string | symbol) => {\n const key = prop as keyof S;\n if (stateSignals.has(key)) {\n return stateSignals.get(key)!.value;\n }\n return undefined;\n },\n ownKeys: () => Array.from(stateSignals.keys()) as string[],\n getOwnPropertyDescriptor: (_, prop) => {\n if (stateSignals.has(prop as keyof S)) {\n return { enumerable: true, configurable: true };\n }\n return undefined;\n },\n has: (_, prop) => stateSignals.has(prop as keyof S),\n });\n\n // Create computed getters\n const getterComputed = new Map<keyof G, ReadonlySignal<unknown>>();\n\n // Build the store proxy\n const store = {} as Store<S, G, A>;\n\n // Define state properties with getters/setters\n for (const key of Object.keys(initialState) as Array<keyof S>) {\n Object.defineProperty(store, key, {\n get: () => stateSignals.get(key)!.value,\n set: (value: unknown) => {\n stateSignals.get(key)!.value = value;\n notifySubscribers();\n },\n enumerable: true,\n configurable: false,\n });\n }\n\n // Define getters as computed properties\n for (const key of Object.keys(getters) as Array<keyof G>) {\n const getterFn = getters[key];\n\n // Create computed that reads from state signals via proxy (more efficient)\n const computedGetter = computed(() => {\n const state = stateProxy;\n // For getter dependencies, pass a proxy that reads from computed getters\n const getterProxy = new Proxy({} as G, {\n get: (_, prop: string | symbol) => {\n const propKey = prop as keyof G;\n if (getterComputed.has(propKey)) {\n return getterComputed.get(propKey)!.value;\n }\n return undefined;\n },\n });\n return getterFn(state, getterProxy);\n });\n\n getterComputed.set(key, computedGetter as unknown as ReadonlySignal<unknown>);\n\n Object.defineProperty(store, key, {\n get: () => computedGetter.value,\n enumerable: true,\n configurable: false,\n });\n }\n\n // Bind actions to the store context\n for (const key of Object.keys(actions) as Array<keyof A>) {\n const actionFn = actions[key];\n\n // Wrap action to enable 'this' binding\n (store as Record<string, unknown>)[key as string] = function (...args: unknown[]) {\n // Create a context that allows 'this.property' access\n const context = new Proxy(store, {\n get: (target, prop) => {\n if (typeof prop === 'string' && stateSignals.has(prop as keyof S)) {\n return stateSignals.get(prop as keyof S)!.value;\n }\n return (target as Record<string, unknown>)[prop as string];\n },\n set: (target, prop, value) => {\n if (typeof prop === 'string' && stateSignals.has(prop as keyof S)) {\n stateSignals.get(prop as keyof S)!.value = value;\n notifySubscribers();\n return true;\n }\n // Allow non-state property assignments (e.g., temporary variables in actions)\n // by delegating to the target object rather than returning false\n return Reflect.set(target, prop, value);\n },\n });\n\n return actionFn.apply(context, args);\n };\n }\n\n // Add store utility methods\n Object.defineProperties(store, {\n $id: {\n value: id,\n writable: false,\n enumerable: false,\n },\n $reset: {\n value: () => {\n const fresh = stateFactory();\n batch(() => {\n for (const [key, sig] of stateSignals) {\n sig.value = fresh[key];\n }\n });\n notifySubscribers();\n },\n writable: false,\n enumerable: false,\n },\n $subscribe: {\n value: (callback: StoreSubscriber<S>) => {\n subscribers.push(callback);\n return () => {\n const index = subscribers.indexOf(callback);\n if (index > -1) subscribers.splice(index, 1);\n };\n },\n writable: false,\n enumerable: false,\n },\n $patch: {\n value: (partial: Partial<S> | ((state: S) => void)) => {\n batch(() => {\n if (typeof partial === 'function') {\n // Capture state before mutation for nested mutation detection\n const stateBefore = isDev ? deepClone(getCurrentState()) : null;\n const signalValuesBefore = isDev\n ? new Map(Array.from(stateSignals.entries()).map(([k, s]) => [k, s.value]))\n : null;\n\n // Mutation function\n const state = getCurrentState();\n partial(state);\n\n // Detect nested mutations in development mode\n if (isDev && stateBefore && signalValuesBefore) {\n const mutatedKeys = detectNestedMutations(stateBefore, state, signalValuesBefore);\n if (mutatedKeys.length > 0) {\n console.warn(\n `[bQuery store \"${id}\"] Nested mutation detected in $patch() for keys: ${mutatedKeys\n .map(String)\n .join(', ')}.\\n` +\n 'Nested object mutations do not trigger reactive updates because the store uses shallow reactivity.\\n' +\n 'To fix this, either:\\n' +\n ' 1. Replace the entire object: state.user = { ...state.user, name: \"New\" }\\n' +\n ' 2. Use $patchDeep() for automatic deep cloning\\n' +\n 'See: https://bquery.dev/guide/store#deep-reactivity'\n );\n }\n }\n\n for (const [key, value] of Object.entries(state) as Array<[keyof S, unknown]>) {\n if (stateSignals.has(key)) {\n stateSignals.get(key)!.value = value;\n }\n }\n } else {\n // Partial object\n for (const [key, value] of Object.entries(partial) as Array<[keyof S, unknown]>) {\n if (stateSignals.has(key)) {\n stateSignals.get(key)!.value = value;\n }\n }\n }\n });\n notifySubscribers();\n },\n writable: false,\n enumerable: false,\n },\n $patchDeep: {\n value: (partial: Partial<S> | ((state: S) => void)) => {\n batch(() => {\n if (typeof partial === 'function') {\n // Deep clone state before mutation to ensure new references\n const state = deepClone(getCurrentState());\n partial(state);\n\n for (const [key, value] of Object.entries(state) as Array<[keyof S, unknown]>) {\n if (stateSignals.has(key)) {\n stateSignals.get(key)!.value = value;\n }\n }\n } else {\n // Deep clone each value in partial to ensure new references\n for (const [key, value] of Object.entries(partial) as Array<[keyof S, unknown]>) {\n if (stateSignals.has(key)) {\n stateSignals.get(key)!.value = deepClone(value);\n }\n }\n }\n });\n notifySubscribers();\n },\n writable: false,\n enumerable: false,\n },\n $state: {\n get: () => getCurrentState(),\n enumerable: false,\n },\n });\n\n // Register store\n registerStore(id, store);\n\n // Apply plugins\n applyPlugins(store, definition);\n\n // Notify devtools\n registerDevtoolsStore(id, store);\n\n return store;\n};\n","/**\n * Mapping helpers for store state and actions.\n */\n\n/**\n * Maps store state properties to a reactive object for use in components.\n *\n * @param store - The store instance\n * @param keys - State keys to map\n * @returns Object with mapped properties\n */\nexport const mapState = <S extends Record<string, unknown>, K extends keyof S>(\n store: S,\n keys: K[]\n): Pick<S, K> => {\n const mapped = {} as Pick<S, K>;\n\n for (const key of keys) {\n Object.defineProperty(mapped, key, {\n get: () => store[key],\n enumerable: true,\n });\n }\n\n return mapped;\n};\n\n/**\n * Maps store getters to a reactive object for use in components.\n *\n * @param store - The store instance\n * @param keys - Getter keys to map\n * @returns Object with mapped getters\n */\nexport const mapGetters = <G extends Record<string, unknown>, K extends keyof G>(\n store: G,\n keys: K[]\n): Pick<G, K> => {\n const mapped = {} as Pick<G, K>;\n\n for (const key of keys) {\n Object.defineProperty(mapped, key, {\n get: () => store[key],\n enumerable: true,\n });\n }\n\n return mapped;\n};\n\n/**\n * Maps store actions to an object for easier destructuring.\n *\n * @param store - The store instance\n * @param keys - Action keys to map\n * @returns Object with mapped actions\n */\nexport const mapActions = <\n A extends Record<string, (...args: unknown[]) => unknown>,\n K extends keyof A,\n>(\n store: A,\n keys: K[]\n): Pick<A, K> => {\n const mapped = {} as Pick<A, K>;\n\n for (const key of keys) {\n (mapped as Record<string, unknown>)[key as string] = (...args: unknown[]) =>\n (store[key] as (...args: unknown[]) => unknown)(...args);\n }\n\n return mapped;\n};\n","/**\n * Store persistence helpers.\n */\n\nimport { createStore } from './create-store';\nimport type { Store, StoreDefinition } from './types';\n\n/**\n * Creates a store with automatic persistence to localStorage.\n *\n * @param definition - Store definition\n * @param storageKey - Optional custom storage key\n * @returns The reactive store instance\n */\nexport const createPersistedStore = <\n S extends Record<string, unknown>,\n G extends Record<string, unknown> = Record<string, never>,\n A extends Record<string, (...args: unknown[]) => unknown> = Record<string, never>,\n>(\n definition: StoreDefinition<S, G, A>,\n storageKey?: string\n): Store<S, G, A> => {\n const key = storageKey ?? `bquery-store-${definition.id}`;\n\n const originalStateFactory = definition.state;\n\n const wrappedDefinition: StoreDefinition<S, G, A> = {\n ...definition,\n state: () => {\n const defaultState = originalStateFactory();\n\n if (typeof window !== 'undefined') {\n try {\n const saved = localStorage.getItem(key);\n if (saved) {\n return { ...defaultState, ...JSON.parse(saved) } as S;\n }\n } catch {\n // Ignore parse errors\n }\n }\n\n return defaultState;\n },\n };\n\n const store = createStore(wrappedDefinition);\n\n // Subscribe to save changes\n store.$subscribe((state) => {\n if (typeof window !== 'undefined') {\n try {\n localStorage.setItem(key, JSON.stringify(state));\n } catch {\n // Ignore quota errors\n }\n }\n });\n\n return store;\n};\n"],"names":["ensureDevtools","registerDevtoolsStore","id","store","devtools","unregisterDevtoolsStore","notifyDevtoolsStateChange","state","plugins","registerPlugin","plugin","applyPlugins","options","extension","storeRegistry","hasStore","registerStore","getStore","listStores","destroyStore","isPlainObject","value","deepClone","obj","k","v","cloned","key","deepEqual","a","b","found","candidate","item","i","keysA","keysB","detectNestedMutations","before","after","signalValues","mutatedKeys","beforeValue","afterValue","isDev","globalProcess","createStore","definition","stateFactory","getters","actions","initialState","stateSignals","signal","subscribers","getCurrentState","untrack","stateProxy","notifySubscribers","hasDevtools","currentState","callback","_","prop","getterComputed","getterFn","computedGetter","computed","getterProxy","propKey","actionFn","args","context","target","fresh","batch","sig","index","partial","stateBefore","signalValuesBefore","s","mapState","keys","mapped","mapGetters","mapActions","createPersistedStore","storageKey","originalStateFactory","wrappedDefinition","defaultState","saved"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"platform.es.mjs","sources":["../src/platform/buckets.ts","../src/platform/cache.ts","../src/platform/notifications.ts","../src/platform/storage.ts"],"sourcesContent":["/**\n * Storage Buckets API wrapper.\n * Provides a simplified interface for storing blobs and binary data.\n * Falls back to IndexedDB when Storage Buckets API is not available.\n */\n\n/**\n * Bucket interface for blob storage operations.\n */\nexport interface Bucket {\n /**\n * Store a blob in the bucket.\n * @param key - Unique identifier for the blob\n * @param data - Blob data to store\n */\n put(key: string, data: Blob): Promise<void>;\n\n /**\n * Retrieve a blob from the bucket.\n * @param key - Blob identifier\n * @returns The stored blob or null if not found\n */\n get(key: string): Promise<Blob | null>;\n\n /**\n * Remove a blob from the bucket.\n * @param key - Blob identifier\n */\n remove(key: string): Promise<void>;\n\n /**\n * List all keys in the bucket.\n * @returns Array of blob keys\n */\n keys(): Promise<string[]>;\n}\n\n/**\n * IndexedDB-based bucket implementation.\n * Used as fallback when Storage Buckets API is unavailable.\n */\nclass IndexedDBBucket implements Bucket {\n private dbPromise: Promise<IDBDatabase> | null = null;\n private readonly storeName = 'blobs';\n\n constructor(private readonly bucketName: string) {}\n\n private openDB(): Promise<IDBDatabase> {\n if (this.dbPromise) return this.dbPromise;\n\n const dbName = `bquery-bucket-${this.bucketName}`;\n this.dbPromise = new Promise((resolve, reject) => {\n const request = indexedDB.open(dbName, 1);\n\n request.onupgradeneeded = () => {\n const db = request.result;\n if (!db.objectStoreNames.contains(this.storeName)) {\n db.createObjectStore(this.storeName);\n }\n };\n\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => reject(request.error);\n });\n\n return this.dbPromise;\n }\n\n private async withStore<T>(\n mode: IDBTransactionMode,\n operation: (store: IDBObjectStore) => IDBRequest<T>\n ): Promise<T> {\n const db = await this.openDB();\n return new Promise((resolve, reject) => {\n const tx = db.transaction(this.storeName, mode);\n const store = tx.objectStore(this.storeName);\n const request = operation(store);\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => reject(request.error);\n });\n }\n\n async put(key: string, data: Blob): Promise<void> {\n await this.withStore('readwrite', (store) => store.put(data, key));\n }\n\n async get(key: string): Promise<Blob | null> {\n const result = await this.withStore<Blob | undefined>('readonly', (store) => store.get(key));\n return result ?? null;\n }\n\n async remove(key: string): Promise<void> {\n await this.withStore('readwrite', (store) => store.delete(key));\n }\n\n async keys(): Promise<string[]> {\n const result = await this.withStore<IDBValidKey[]>('readonly', (store) => store.getAllKeys());\n return result.map((key) => String(key));\n }\n}\n\n/**\n * Bucket manager for creating and accessing storage buckets.\n */\nexport const buckets = {\n /**\n * Open or create a storage bucket.\n * @param name - Bucket name\n * @returns Bucket instance for blob operations\n */\n async open(name: string): Promise<Bucket> {\n // Storage Buckets API is experimental; use IndexedDB fallback\n return new IndexedDBBucket(name);\n },\n};\n","/**\n * Cache Storage API wrapper.\n * Provides a simplified interface for caching responses and assets.\n */\n\n/**\n * Cache handle interface for managing cached resources.\n */\nexport interface CacheHandle {\n /**\n * Add a resource to the cache by URL.\n * Fetches the resource and stores the response.\n * @param url - URL to fetch and cache\n */\n add(url: string): Promise<void>;\n\n /**\n * Add multiple resources to the cache.\n * @param urls - Array of URLs to fetch and cache\n */\n addAll(urls: string[]): Promise<void>;\n\n /**\n * Store a custom response in the cache.\n * @param url - URL key for the cached response\n * @param response - Response object to cache\n */\n put(url: string, response: Response): Promise<void>;\n\n /**\n * Retrieve a cached response.\n * @param url - URL to look up\n * @returns Cached Response or undefined if not found\n */\n match(url: string): Promise<Response | undefined>;\n\n /**\n * Remove a cached response.\n * @param url - URL to remove from cache\n * @returns True if the entry was deleted\n */\n remove(url: string): Promise<boolean>;\n\n /**\n * Get all cached request URLs.\n * @returns Array of cached URLs\n */\n keys(): Promise<string[]>;\n}\n\n/**\n * Internal cache handle implementation.\n */\nclass CacheHandleImpl implements CacheHandle {\n constructor(private readonly cache: Cache) {}\n\n async add(url: string): Promise<void> {\n await this.cache.add(url);\n }\n\n async addAll(urls: string[]): Promise<void> {\n await this.cache.addAll(urls);\n }\n\n async put(url: string, response: Response): Promise<void> {\n await this.cache.put(url, response);\n }\n\n async match(url: string): Promise<Response | undefined> {\n return this.cache.match(url);\n }\n\n async remove(url: string): Promise<boolean> {\n return this.cache.delete(url);\n }\n\n async keys(): Promise<string[]> {\n const requests = await this.cache.keys();\n return requests.map((req) => req.url);\n }\n}\n\n/**\n * Cache manager for accessing the Cache Storage API.\n */\nexport const cache = {\n /**\n * Check if Cache Storage API is supported.\n * @returns True if caches API is available\n */\n isSupported(): boolean {\n return 'caches' in window;\n },\n\n /**\n * Open or create a named cache.\n * @param name - Cache name\n * @returns CacheHandle for cache operations\n */\n async open(name: string): Promise<CacheHandle> {\n if (!this.isSupported()) {\n throw new Error('bQuery: Cache Storage API not supported');\n }\n const c = await caches.open(name);\n return new CacheHandleImpl(c);\n },\n\n /**\n * Delete a named cache.\n * @param name - Cache name to delete\n * @returns True if the cache was deleted\n */\n async delete(name: string): Promise<boolean> {\n if (!this.isSupported()) {\n return false;\n }\n return caches.delete(name);\n },\n\n /**\n * List all cache names.\n * @returns Array of cache names\n */\n async keys(): Promise<string[]> {\n if (!this.isSupported()) {\n return [];\n }\n return caches.keys();\n },\n};\n","/**\n * Web Notifications API wrapper.\n * Provides a simplified interface for browser notifications.\n */\n\n/**\n * Notification options matching the standard NotificationOptions interface.\n */\nexport interface NotificationOptions {\n /** Body text of the notification */\n body?: string;\n /** Icon URL for the notification */\n icon?: string;\n /** Badge icon for mobile devices */\n badge?: string;\n /** Tag for grouping notifications */\n tag?: string;\n /** Whether to require user interaction */\n requireInteraction?: boolean;\n /** Vibration pattern for mobile devices */\n vibrate?: number[];\n /** Additional data attached to the notification */\n data?: unknown;\n}\n\n/**\n * Notifications manager providing a clean interface for web notifications.\n */\nexport const notifications = {\n /**\n * Check if notifications are supported.\n * @returns True if Notification API is available\n */\n isSupported(): boolean {\n return 'Notification' in window;\n },\n\n /**\n * Get current permission status.\n * @returns Current permission state\n */\n getPermission(): NotificationPermission {\n if (!this.isSupported()) return 'denied';\n return Notification.permission;\n },\n\n /**\n * Request notification permission from the user.\n * @returns Promise resolving to the permission result\n */\n async requestPermission(): Promise<NotificationPermission> {\n if (!this.isSupported()) {\n return 'denied';\n }\n\n if (Notification.permission === 'granted') {\n return 'granted';\n }\n\n if (Notification.permission === 'denied') {\n return 'denied';\n }\n\n return Notification.requestPermission();\n },\n\n /**\n * Send a notification.\n * Requires 'granted' permission.\n * @param title - Notification title\n * @param options - Optional notification settings\n * @returns The Notification instance or null if not permitted\n */\n send(title: string, options?: NotificationOptions): Notification | null {\n if (!this.isSupported()) {\n console.warn('bQuery: Notifications not supported in this browser');\n return null;\n }\n\n if (Notification.permission !== 'granted') {\n console.warn('bQuery: Notification permission not granted');\n return null;\n }\n\n return new Notification(title, options);\n },\n};\n","/**\r\n * Unified storage adapters for web platform storage APIs.\r\n * Provides a consistent, promise-based interface with predictable errors.\r\n */\r\n\r\n/**\r\n * Common interface for all storage adapters.\r\n * All methods return promises for a unified async API.\r\n */\r\nexport interface StorageAdapter {\r\n /**\r\n * Retrieve a value by key.\r\n * @param key - The storage key\r\n * @returns The stored value or null if not found\r\n */\r\n get<T>(key: string): Promise<T | null>;\r\n\r\n /**\r\n * Store a value by key.\r\n * @param key - The storage key\r\n * @param value - The value to store\r\n */\r\n set<T>(key: string, value: T): Promise<void>;\r\n\r\n /**\r\n * Remove a value by key.\r\n * @param key - The storage key\r\n */\r\n remove(key: string): Promise<void>;\r\n\r\n /**\r\n * Clear all stored values.\r\n */\r\n clear(): Promise<void>;\r\n\r\n /**\r\n * Get all storage keys.\r\n * @returns Array of all keys\r\n */\r\n keys(): Promise<string[]>;\r\n}\r\n\r\n/**\r\n * Abstract base class for web storage adapters (localStorage/sessionStorage).\r\n * Implements DRY principle by sharing common logic.\r\n */\r\nabstract class WebStorageAdapter implements StorageAdapter {\r\n constructor(protected readonly storage: Storage) {}\r\n\r\n async get<T>(key: string): Promise<T | null> {\r\n const raw = this.storage.getItem(key);\r\n if (raw === null) return null;\r\n try {\r\n return JSON.parse(raw) as T;\r\n } catch {\r\n return raw as unknown as T;\r\n }\r\n }\r\n\r\n async set<T>(key: string, value: T): Promise<void> {\r\n const serialized = typeof value === 'string' ? value : JSON.stringify(value);\r\n this.storage.setItem(key, serialized);\r\n }\r\n\r\n async remove(key: string): Promise<void> {\r\n this.storage.removeItem(key);\r\n }\r\n\r\n async clear(): Promise<void> {\r\n this.storage.clear();\r\n }\r\n\r\n async keys(): Promise<string[]> {\r\n const result: string[] = [];\r\n for (let i = 0; i < this.storage.length; i++) {\r\n const key = this.storage.key(i);\r\n if (key !== null) {\r\n result.push(key);\r\n }\r\n }\r\n return result;\r\n }\r\n}\r\n\r\n/**\r\n * localStorage adapter with async interface.\r\n */\r\nclass LocalStorageAdapter extends WebStorageAdapter {\r\n constructor() {\r\n super(localStorage);\r\n }\r\n}\r\n\r\n/**\r\n * sessionStorage adapter with async interface.\r\n */\r\nclass SessionStorageAdapter extends WebStorageAdapter {\r\n constructor() {\r\n super(sessionStorage);\r\n }\r\n}\r\n\r\n/**\r\n * IndexedDB configuration options.\r\n */\r\nexport interface IndexedDBOptions {\r\n /** Database name */\r\n name: string;\r\n /** Object store name */\r\n store: string;\r\n /** Database version (optional) */\r\n version?: number;\r\n}\r\n\r\n/**\r\n * IndexedDB key-value adapter.\r\n * Wraps IndexedDB with a simple key-value interface.\r\n */\r\nclass IndexedDBAdapter implements StorageAdapter {\r\n private dbPromise: Promise<IDBDatabase> | null = null;\r\n\r\n constructor(private readonly options: IndexedDBOptions) {}\r\n\r\n /**\r\n * Opens or creates the IndexedDB database.\r\n */\r\n private openDB(): Promise<IDBDatabase> {\r\n if (this.dbPromise) return this.dbPromise;\r\n\r\n this.dbPromise = new Promise((resolve, reject) => {\r\n const request = indexedDB.open(this.options.name, this.options.version ?? 1);\r\n\r\n request.onupgradeneeded = () => {\r\n const db = request.result;\r\n if (!db.objectStoreNames.contains(this.options.store)) {\r\n db.createObjectStore(this.options.store);\r\n }\r\n };\r\n\r\n request.onsuccess = () => resolve(request.result);\r\n request.onerror = () => reject(request.error);\r\n });\r\n\r\n return this.dbPromise;\r\n }\r\n\r\n /**\r\n * Executes a transaction on the object store.\r\n */\r\n private async withStore<T>(\r\n mode: IDBTransactionMode,\r\n operation: (store: IDBObjectStore) => IDBRequest<T>\r\n ): Promise<T> {\r\n const db = await this.openDB();\r\n return new Promise((resolve, reject) => {\r\n const tx = db.transaction(this.options.store, mode);\r\n const store = tx.objectStore(this.options.store);\r\n const request = operation(store);\r\n request.onsuccess = () => resolve(request.result);\r\n request.onerror = () => reject(request.error);\r\n });\r\n }\r\n\r\n async get<T>(key: string): Promise<T | null> {\r\n const result = await this.withStore<T | undefined>('readonly', (store) => store.get(key));\r\n return result ?? null;\r\n }\r\n\r\n async set<T>(key: string, value: T): Promise<void> {\r\n await this.withStore('readwrite', (store) => store.put(value, key));\r\n }\r\n\r\n async remove(key: string): Promise<void> {\r\n await this.withStore('readwrite', (store) => store.delete(key));\r\n }\r\n\r\n async clear(): Promise<void> {\r\n await this.withStore('readwrite', (store) => store.clear());\r\n }\r\n\r\n async keys(): Promise<string[]> {\r\n const result = await this.withStore<IDBValidKey[]>('readonly', (store) => store.getAllKeys());\r\n return result.map((key) => String(key));\r\n }\r\n}\r\n\r\n/**\r\n * Storage factory providing access to different storage adapters.\r\n */\r\nexport const storage = {\r\n /**\r\n * Create a localStorage adapter.\r\n * @returns StorageAdapter wrapping localStorage\r\n */\r\n local(): StorageAdapter {\r\n return new LocalStorageAdapter();\r\n },\r\n\r\n /**\r\n * Create a sessionStorage adapter.\r\n * @returns StorageAdapter wrapping sessionStorage\r\n */\r\n session(): StorageAdapter {\r\n return new SessionStorageAdapter();\r\n },\r\n\r\n /**\r\n * Create an IndexedDB adapter with key-value interface.\r\n * @param options - Database and store configuration\r\n * @returns StorageAdapter wrapping IndexedDB\r\n */\r\n indexedDB(options: IndexedDBOptions): StorageAdapter {\r\n return new IndexedDBAdapter(options);\r\n },\r\n};\r\n"],"names":["IndexedDBBucket","bucketName","dbName","resolve","reject","request","db","mode","operation","store","key","data","buckets","name","CacheHandleImpl","cache","url","urls","response","req","c","notifications","title","options","WebStorageAdapter","storage","raw","value","serialized","result","i","LocalStorageAdapter","SessionStorageAdapter","IndexedDBAdapter"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"reactive.es.mjs","sources":["../src/reactive/linked.ts"],"sourcesContent":["/**\n * Linked (writable) computed helpers.\n */\n\nimport { computed, Computed } from './computed';\n\n/**\n * A writable computed-like signal.\n */\nexport interface LinkedSignal<T> {\n /** Gets or sets the current value with dependency tracking. */\n value: T;\n /** Gets the current value without dependency tracking. */\n peek(): T;\n}\n\n/**\n * Creates a writable computed signal by linking a getter and setter.\n *\n * @template T - The derived value type\n * @param getValue - Getter that derives the current value\n * @param setValue - Setter that writes back to underlying signals\n * @returns A writable computed-like signal\n *\n * @example\n * ```ts\n * const first = signal('Ada');\n * const last = signal('Lovelace');\n * const fullName = linkedSignal(\n * () => `${first.value} ${last.value}`,\n * (next) => {\n * const [a, b] = next.split(' ');\n * first.value = a ?? '';\n * last.value = b ?? '';\n * }\n * );\n * ```\n */\nexport const linkedSignal = <T>(\n getValue: () => T,\n setValue: (value: T) => void\n): LinkedSignal<T> => {\n const derived: Computed<T> = computed(getValue);\n\n return {\n get value(): T {\n return derived.value;\n },\n set value(next: T) {\n setValue(next);\n },\n peek(): T {\n return derived.peek();\n },\n };\n};\n"],"names":["linkedSignal","getValue","setValue","derived","computed","next"],"mappings":";;;;;;AAsCO,MAAMA,IAAe,CAC1BC,GACAC,MACoB;AACpB,QAAMC,IAAuBC,EAASH,CAAQ;AAE9C,SAAO;AAAA,IACL,IAAI,QAAW;AACb,aAAOE,EAAQ;AAAA,IACjB;AAAA,IACA,IAAI,MAAME,GAAS;AACjB,MAAAH,EAASG,CAAI;AAAA,IACf;AAAA,IACA,OAAU;AACR,aAAOF,EAAQ,KAAA;AAAA,IACjB;AAAA,EAAA;AAEJ;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"router.es.mjs","sources":["../src/router/state.ts","../src/router/navigation.ts","../src/router/links.ts","../src/router/query.ts","../src/router/match.ts","../src/router/utils.ts","../src/router/router.ts"],"sourcesContent":["/**\n * Internal router state (active router and current route signal).\n * @module bquery/router\n */\n\nimport { computed, signal, type ReadonlySignal, type Signal } from '../reactive/index';\nimport type { Route, Router } from './types';\n\n// ============================================================================\n// Internal State\n// ============================================================================\n\n/** @internal */\nlet activeRouter: Router | null = null;\n\n/** @internal */\nexport const routeSignal: Signal<Route> = signal<Route>({\n path: '',\n params: {},\n query: {},\n matched: null,\n hash: '',\n});\n\n/**\n * Reactive signal containing the current route.\n *\n * @example\n * ```ts\n * import { currentRoute } from 'bquery/router';\n * import { effect } from 'bquery/reactive';\n *\n * effect(() => {\n * document.title = `Page: ${currentRoute.value.path}`;\n * });\n * ```\n */\nexport const currentRoute: ReadonlySignal<Route> = computed(() => routeSignal.value);\n\n/** @internal */\nexport const getActiveRouter = (): Router | null => activeRouter;\n\n/** @internal */\nexport const setActiveRouter = (router: Router | null): void => {\n activeRouter = router;\n};\n","/**\n * Navigation helpers and global router access.\n * @module bquery/router\n */\n\nimport { getActiveRouter } from './state';\n\n/**\n * Navigates to a new path.\n *\n * @param path - The path to navigate to\n * @param options - Navigation options\n *\n * @example\n * ```ts\n * import { navigate } from 'bquery/router';\n *\n * // Push to history\n * await navigate('/dashboard');\n *\n * // Replace current entry\n * await navigate('/login', { replace: true });\n * ```\n */\nexport const navigate = async (\n path: string,\n options: { replace?: boolean } = {}\n): Promise<void> => {\n const activeRouter = getActiveRouter();\n if (!activeRouter) {\n throw new Error('bQuery router: No router initialized. Call createRouter() first.');\n }\n\n await activeRouter[options.replace ? 'replace' : 'push'](path);\n};\n\n/**\n * Programmatically go back in history.\n *\n * @example\n * ```ts\n * import { back } from 'bquery/router';\n * back();\n * ```\n */\nexport const back = (): void => {\n const activeRouter = getActiveRouter();\n if (activeRouter) {\n activeRouter.back();\n } else {\n history.back();\n }\n};\n\n/**\n * Programmatically go forward in history.\n *\n * @example\n * ```ts\n * import { forward } from 'bquery/router';\n * forward();\n * ```\n */\nexport const forward = (): void => {\n const activeRouter = getActiveRouter();\n if (activeRouter) {\n activeRouter.forward();\n } else {\n history.forward();\n }\n};\n","/**\n * Link helpers for client-side navigation.\n * @module bquery/router\n */\n\nimport { getActiveRouter } from './state';\nimport { navigate } from './navigation';\n\n// ============================================================================\n// Router Link Helper\n// ============================================================================\n\n/**\n * Creates click handler for router links.\n * Attach to anchor elements to enable client-side navigation.\n *\n * @param path - Target path\n * @param options - Navigation options\n * @returns Click event handler\n *\n * @example\n * ```ts\n * import { link } from 'bquery/router';\n * import { $ } from 'bquery/core';\n *\n * $('#nav-home').on('click', link('/'));\n * $('#nav-about').on('click', link('/about'));\n * ```\n */\nexport const link = (path: string, options: { replace?: boolean } = {}): ((e: Event) => void) => {\n return (e: Event) => {\n e.preventDefault();\n void navigate(path, options).catch((err) => {\n console.error('Navigation failed:', err);\n });\n };\n};\n\n/**\n * Intercepts all link clicks within a container for client-side routing.\n * Only intercepts links with matching origins and no target attribute.\n *\n * @param container - The container element to intercept links in\n * @returns Cleanup function to remove the listener\n *\n * @example\n * ```ts\n * import { interceptLinks } from 'bquery/router';\n *\n * // Intercept all links in the app\n * const cleanup = interceptLinks(document.body);\n *\n * // Later, remove the interceptor\n * cleanup();\n * ```\n */\nexport const interceptLinks = (container?: Element): (() => void) => {\n // Provide safe default in DOM environments only\n const targetContainer = container ?? (typeof document !== 'undefined' ? document.body : null);\n if (!targetContainer) {\n // No container available (SSR or invalid input)\n return () => undefined;\n }\n\n const handler = (e: Event) => {\n // Only intercept standard left-clicks without modifier keys\n if (!(e instanceof MouseEvent)) return;\n if (e.defaultPrevented) return; // Already handled\n if (e.button !== 0) return; // Not left-click (middle-click opens new tab, right-click shows context menu)\n if (e.ctrlKey || e.metaKey || e.shiftKey || e.altKey) return; // Modifier keys (Ctrl/Cmd-click = new tab)\n\n // Guard against non-Element targets and non-DOM environments\n if (typeof Element === 'undefined' || !(e.target instanceof Element)) return;\n const target = e.target as HTMLElement;\n const anchor = target.closest('a');\n\n if (!anchor) return;\n\n // Cross-realm compatible anchor check: use owner document's constructor if available\n const anchorWindow = anchor.ownerDocument.defaultView;\n const AnchorConstructor = anchorWindow?.HTMLAnchorElement ?? HTMLAnchorElement;\n if (!(anchor instanceof AnchorConstructor)) return;\n\n if (anchor.target) return; // Has target attribute\n if (anchor.hasAttribute('download')) return;\n if (typeof window === 'undefined') return; // Non-window environment\n if (anchor.origin !== window.location.origin) return; // External link\n\n // Get active router config to handle base paths correctly.\n // If no router is active, proceed with no base/hash; navigate() will throw a\n // \"No router initialized\" error, which is caught and logged below.\n const router = getActiveRouter();\n if (!router) {\n // No active router - trigger navigate(), allowing its error to be logged here\n e.preventDefault();\n void navigate(anchor.pathname + anchor.search + anchor.hash).catch((err) => {\n console.error('Navigation failed:', err);\n });\n return;\n }\n\n const base = router.base;\n const useHash = router.hash;\n\n // Detect hash-routing mode: links written as href=\"#/page\"\n // In this case, anchor.hash contains the route path\n let path: string;\n if (useHash && anchor.hash && anchor.hash.startsWith('#/')) {\n // Hash-routing mode: extract path from the hash\n // e.g., href=\"#/page?foo=bar\" → path = \"/page?foo=bar\"\n path = anchor.hash.slice(1); // Remove leading #\n } else {\n // History mode: use pathname + search + hash\n // Strip base from pathname to avoid duplication (router.push() re-adds it)\n let pathname = anchor.pathname;\n if (base && base !== '/' && pathname.startsWith(base)) {\n pathname = pathname.slice(base.length) || '/';\n }\n path = pathname + anchor.search + anchor.hash;\n }\n\n e.preventDefault();\n void navigate(path).catch((err) => {\n console.error('Navigation failed:', err);\n });\n };\n\n targetContainer.addEventListener('click', handler);\n return () => targetContainer.removeEventListener('click', handler);\n};\n","/**\n * Query string helpers.\n * @module bquery/router\n */\n\n/**\n * Parses query string into an object.\n * Single values are stored as strings, duplicate keys become arrays.\n * @internal\n *\n * @example\n * parseQuery('?foo=1') // { foo: '1' }\n * parseQuery('?tag=a&tag=b') // { tag: ['a', 'b'] }\n * parseQuery('?x=1&y=2&x=3') // { x: ['1', '3'], y: '2' }\n */\nexport const parseQuery = (search: string): Record<string, string | string[]> => {\n const query: Record<string, string | string[]> = {};\n const params = new URLSearchParams(search);\n\n params.forEach((value, key) => {\n const existing = query[key];\n if (existing === undefined) {\n // First occurrence: store as string\n query[key] = value;\n } else if (Array.isArray(existing)) {\n // Already an array: append\n existing.push(value);\n } else {\n // Second occurrence: convert to array\n query[key] = [existing, value];\n }\n });\n\n return query;\n};\n","/**\n * Route matching helpers.\n * @module bquery/router\n */\n\nimport { parseQuery } from './query';\nimport type { Route, RouteDefinition } from './types';\n\n// ============================================================================\n// Route Matching\n// ============================================================================\n\n/**\n * Converts a route path pattern to a RegExp for matching.\n * Uses placeholder approach to preserve :param and * patterns during escaping.\n * Returns positional capture groups for maximum compatibility.\n * @internal\n */\nconst pathToRegex = (path: string): RegExp => {\n // Handle wildcard-only route\n if (path === '*') {\n return /^.*$/;\n }\n\n // Unique placeholders using null chars (won't appear in normal paths)\n const PARAM_MARKER = '\\u0000P\\u0000';\n const WILDCARD_MARKER = '\\u0000W\\u0000';\n\n // Step 1: Extract :param patterns before escaping\n let pattern = path.replace(/:([a-zA-Z_][a-zA-Z0-9_]*)/g, () => {\n return PARAM_MARKER;\n });\n\n // Step 2: Extract * wildcards before escaping\n pattern = pattern.replace(/\\*/g, WILDCARD_MARKER);\n\n // Step 3: Escape ALL regex metacharacters: \\ ^ $ . * + ? ( ) [ ] { } |\n pattern = pattern.replace(/[\\\\^$.*+?()[\\]{}|]/g, '\\\\$&');\n\n // Step 4: Restore param capture groups (positional, not named)\n pattern = pattern.replace(/\\u0000P\\u0000/g, () => `([^/]+)`);\n\n // Step 5: Restore wildcards as .*\n pattern = pattern.replace(/\\u0000W\\u0000/g, '.*');\n\n return new RegExp(`^${pattern}$`);\n};\n\n/**\n * Extracts param names from a route path.\n * @internal\n */\nconst extractParamNames = (path: string): string[] => {\n const matches = path.match(/:([a-zA-Z_][a-zA-Z0-9_]*)/g);\n return matches ? matches.map((m) => m.slice(1)) : [];\n};\n\n/**\n * Matches a path against route definitions and extracts params.\n * Uses positional captures for maximum compatibility.\n * @internal\n */\nexport const matchRoute = (\n path: string,\n routes: RouteDefinition[]\n): { matched: RouteDefinition; params: Record<string, string> } | null => {\n for (const route of routes) {\n const regex = pathToRegex(route.path);\n const match = path.match(regex);\n\n if (match) {\n const paramNames = extractParamNames(route.path);\n const params: Record<string, string> = {};\n\n // Map positional captures to param names\n paramNames.forEach((name, index) => {\n params[name] = match[index + 1] || '';\n });\n\n return { matched: route, params };\n }\n }\n\n return null;\n};\n\n/**\n * Creates a Route object from the current URL.\n * @internal\n */\nexport const createRoute = (\n pathname: string,\n search: string,\n hash: string,\n routes: RouteDefinition[]\n): Route => {\n const result = matchRoute(pathname, routes);\n\n return {\n path: pathname,\n params: result?.params ?? {},\n query: parseQuery(search),\n matched: result?.matched ?? null,\n hash: hash.replace(/^#/, ''),\n };\n};\n","/**\n * Router utilities.\n * @module bquery/router\n */\n\nimport { computed, type ReadonlySignal } from '../reactive/index';\nimport { getActiveRouter, routeSignal } from './state';\nimport type { RouteDefinition } from './types';\n\n// ============================================================================\n// Utilities\n// ============================================================================\n\n/**\n * Flattens nested routes into a single array with full paths.\n * Does NOT include the router base - base is only for browser history.\n * @internal\n */\nexport const flattenRoutes = (routes: RouteDefinition[], parentPath = ''): RouteDefinition[] => {\n const result: RouteDefinition[] = [];\n\n for (const route of routes) {\n const fullPath = route.path === '*' ? '*' : `${parentPath}${route.path}`.replace(/\\/+/g, '/');\n\n result.push({\n ...route,\n path: fullPath,\n });\n\n if (route.children) {\n result.push(...flattenRoutes(route.children, fullPath));\n }\n }\n\n return result;\n};\n\n/**\n * Resolves a route by name and params.\n *\n * @param name - The route name\n * @param params - Route params to interpolate\n * @returns The resolved path\n *\n * @example\n * ```ts\n * import { resolve } from 'bquery/router';\n *\n * const path = resolve('user', { id: '42' });\n * // Returns '/user/42' if route is defined as { name: 'user', path: '/user/:id' }\n * ```\n */\nexport const resolve = (name: string, params: Record<string, string> = {}): string => {\n const activeRouter = getActiveRouter();\n if (!activeRouter) {\n throw new Error('bQuery router: No router initialized.');\n }\n\n const route = activeRouter.routes.find((r) => r.name === name);\n if (!route) {\n throw new Error(`bQuery router: Route \"${name}\" not found.`);\n }\n\n let path = route.path;\n for (const [key, value] of Object.entries(params)) {\n path = path.replace(`:${key}`, encodeURIComponent(value));\n }\n\n return path;\n};\n\n/**\n * Checks if a path matches the current route.\n *\n * @param path - Path to check\n * @param exact - Whether to match exactly (default: false)\n * @returns True if the path matches\n *\n * @example\n * ```ts\n * import { isActive } from 'bquery/router';\n *\n * if (isActive('/dashboard')) {\n * // Highlight nav item\n * }\n * ```\n */\nexport const isActive = (path: string, exact = false): boolean => {\n const current = routeSignal.value.path;\n return exact ? current === path : current.startsWith(path);\n};\n\n/**\n * Creates a computed signal that checks if a path is active.\n *\n * @param path - Path to check\n * @param exact - Whether to match exactly\n * @returns A reactive signal\n *\n * @example\n * ```ts\n * import { isActiveSignal } from 'bquery/router';\n * import { effect } from 'bquery/reactive';\n *\n * const dashboardActive = isActiveSignal('/dashboard');\n * effect(() => {\n * navItem.classList.toggle('active', dashboardActive.value);\n * });\n * ```\n */\nexport const isActiveSignal = (path: string, exact = false): ReadonlySignal<boolean> => {\n return computed(() => {\n const current = routeSignal.value.path;\n return exact ? current === path : current.startsWith(path);\n });\n};\n","/**\n * Router creation and lifecycle management.\n * @module bquery/router\n */\n\nimport { createRoute } from './match';\nimport { currentRoute, getActiveRouter, routeSignal, setActiveRouter } from './state';\nimport type { NavigationGuard, Route, Router, RouterOptions } from './types';\nimport { flattenRoutes } from './utils';\n\n// ============================================================================\n// Router Creation\n// ============================================================================\n\n/**\n * Creates and initializes a router instance.\n *\n * @param options - Router configuration\n * @returns The router instance\n *\n * @example\n * ```ts\n * import { createRouter } from 'bquery/router';\n *\n * const router = createRouter({\n * routes: [\n * { path: '/', component: () => import('./pages/Home') },\n * { path: '/about', component: () => import('./pages/About') },\n * { path: '/user/:id', component: () => import('./pages/User') },\n * { path: '*', component: () => import('./pages/NotFound') },\n * ],\n * base: '/app',\n * });\n *\n * router.beforeEach((to, from) => {\n * if (to.path === '/admin' && !isAuthenticated()) {\n * return false; // Cancel navigation\n * }\n * });\n * ```\n */\nexport const createRouter = (options: RouterOptions): Router => {\n // Clean up any existing router to prevent guard leakage\n const existingRouter = getActiveRouter();\n if (existingRouter) {\n existingRouter.destroy();\n }\n\n const { routes, base = '', hash: useHash = false } = options;\n\n // Instance-specific guards and hooks (not shared globally)\n const beforeGuards: NavigationGuard[] = [];\n const afterHooks: Array<(to: Route, from: Route) => void> = [];\n\n // Flatten nested routes (base-relative, not including the base path)\n const flatRoutes = flattenRoutes(routes);\n\n /**\n * Gets the current path from the URL.\n */\n const getCurrentPath = (): { pathname: string; search: string; hash: string } => {\n if (useHash) {\n const hashPath = window.location.hash.slice(1) || '/';\n // In hash routing, URL structure is #/path?query#fragment\n // Extract hash fragment first (after the second #)\n const [pathWithQuery, hashPart = ''] = hashPath.split('#');\n // Then extract query from the path\n const [pathname, search = ''] = pathWithQuery.split('?');\n return {\n pathname,\n search: search ? `?${search}` : '',\n hash: hashPart ? `#${hashPart}` : '',\n };\n }\n\n let pathname = window.location.pathname;\n if (base && (pathname === base || pathname.startsWith(base + '/'))) {\n pathname = pathname.slice(base.length) || '/';\n }\n\n return {\n pathname,\n search: window.location.search,\n hash: window.location.hash,\n };\n };\n\n /**\n * Updates the route signal with current URL state.\n */\n const syncRoute = (): void => {\n const { pathname, search, hash } = getCurrentPath();\n const newRoute = createRoute(pathname, search, hash, flatRoutes);\n routeSignal.value = newRoute;\n };\n\n /**\n * Performs navigation with guards.\n */\n const performNavigation = async (\n path: string,\n method: 'pushState' | 'replaceState'\n ): Promise<void> => {\n const { pathname, search, hash } = getCurrentPath();\n const from = createRoute(pathname, search, hash, flatRoutes);\n\n // Parse the target path\n const url = new URL(path, window.location.origin);\n const to = createRoute(url.pathname, url.search, url.hash, flatRoutes);\n\n // Run beforeEach guards\n for (const guard of beforeGuards) {\n const result = await guard(to, from);\n if (result === false) {\n return; // Cancel navigation\n }\n }\n\n // Update browser history\n const fullPath = useHash ? `#${path}` : `${base}${path}`;\n history[method]({}, '', fullPath);\n\n // Update route signal\n syncRoute();\n\n // Run afterEach hooks\n for (const hook of afterHooks) {\n hook(routeSignal.value, from);\n }\n };\n\n /**\n * Handle popstate events (back/forward).\n */\n const handlePopState = async (): Promise<void> => {\n const { pathname, search, hash } = getCurrentPath();\n const from = routeSignal.value;\n const to = createRoute(pathname, search, hash, flatRoutes);\n\n // Run beforeEach guards (supports async guards)\n for (const guard of beforeGuards) {\n const result = await guard(to, from);\n if (result === false) {\n // Restore previous state with full URL (including query/hash)\n const queryString = new URLSearchParams(\n Object.entries(from.query).flatMap(([key, value]) =>\n Array.isArray(value) ? value.map((v) => [key, v]) : [[key, value]]\n )\n ).toString();\n const search = queryString ? `?${queryString}` : '';\n const hash = from.hash ? `#${from.hash}` : '';\n const restorePath = useHash\n ? `#${from.path}${search}${hash}`\n : `${base}${from.path}${search}${hash}`;\n history.replaceState({}, '', restorePath);\n return;\n }\n }\n\n syncRoute();\n\n for (const hook of afterHooks) {\n hook(routeSignal.value, from);\n }\n };\n\n // Attach popstate listener\n window.addEventListener('popstate', handlePopState);\n\n // Initialize route\n syncRoute();\n\n const router: Router = {\n push: (path: string) => performNavigation(path, 'pushState'),\n replace: (path: string) => performNavigation(path, 'replaceState'),\n back: () => history.back(),\n forward: () => history.forward(),\n go: (delta: number) => history.go(delta),\n\n beforeEach: (guard: NavigationGuard) => {\n beforeGuards.push(guard);\n return () => {\n const index = beforeGuards.indexOf(guard);\n if (index > -1) beforeGuards.splice(index, 1);\n };\n },\n\n afterEach: (hook: (to: Route, from: Route) => void) => {\n afterHooks.push(hook);\n return () => {\n const index = afterHooks.indexOf(hook);\n if (index > -1) afterHooks.splice(index, 1);\n };\n },\n\n currentRoute,\n routes: flatRoutes,\n base,\n hash: useHash,\n\n destroy: () => {\n window.removeEventListener('popstate', handlePopState);\n beforeGuards.length = 0;\n afterHooks.length = 0;\n setActiveRouter(null);\n },\n };\n\n setActiveRouter(router);\n return router;\n};\n"],"names":["activeRouter","routeSignal","signal","currentRoute","computed","getActiveRouter","setActiveRouter","router","navigate","path","options","back","forward","link","e","err","interceptLinks","container","targetContainer","handler","anchor","AnchorConstructor","base","useHash","pathname","parseQuery","search","query","value","key","existing","pathToRegex","PARAM_MARKER","WILDCARD_MARKER","pattern","extractParamNames","matches","m","matchRoute","routes","route","regex","match","paramNames","params","name","index","createRoute","hash","result","flattenRoutes","parentPath","fullPath","resolve","r","isActive","exact","current","isActiveSignal","createRouter","existingRouter","beforeGuards","afterHooks","flatRoutes","getCurrentPath","hashPath","pathWithQuery","hashPart","syncRoute","newRoute","performNavigation","method","from","url","to","guard","hook","handlePopState","queryString","v","restorePath","delta"],"mappings":"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"}