@bquery/bquery 1.1.1 → 1.2.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.
@@ -0,0 +1,288 @@
1
+ /**
2
+ * Minimal state management built on signals.
3
+ *
4
+ * This module provides a lightweight store pattern inspired by Pinia/Vuex
5
+ * but built entirely on bQuery's reactive primitives. Features include:
6
+ * - Signal-based reactive state
7
+ * - Computed getters
8
+ * - Actions with async support
9
+ * - Devtools hooks for debugging
10
+ * - Plugin system for extensions
11
+ *
12
+ * @module bquery/store
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * import { createStore } from 'bquery/store';
17
+ * import { effect } from 'bquery/reactive';
18
+ *
19
+ * const counterStore = createStore({
20
+ * id: 'counter',
21
+ * state: () => ({ count: 0 }),
22
+ * getters: {
23
+ * doubled: (state) => state.count * 2,
24
+ * isPositive: (state) => state.count > 0,
25
+ * },
26
+ * actions: {
27
+ * increment() {
28
+ * this.count++;
29
+ * },
30
+ * async fetchAndSet(url: string) {
31
+ * const response = await fetch(url);
32
+ * const data = await response.json();
33
+ * this.count = data.count;
34
+ * },
35
+ * },
36
+ * });
37
+ *
38
+ * effect(() => {
39
+ * console.log('Count:', counterStore.count);
40
+ * console.log('Doubled:', counterStore.doubled);
41
+ * });
42
+ *
43
+ * counterStore.increment();
44
+ * ```
45
+ */
46
+ /**
47
+ * Store state factory function.
48
+ */
49
+ export type StateFactory<S> = () => S;
50
+ /**
51
+ * Getter definition - derives computed values from state.
52
+ */
53
+ export type Getters<S, G> = {
54
+ [K in keyof G]: (state: S, getters: G) => G[K];
55
+ };
56
+ /**
57
+ * Action definition - methods that can modify state.
58
+ */
59
+ export type Actions<S, A> = {
60
+ [K in keyof A]: A[K] extends (...args: infer P) => infer R ? (this: S & A, ...args: P) => R : never;
61
+ };
62
+ /**
63
+ * Store definition for createStore.
64
+ */
65
+ export type StoreDefinition<S extends Record<string, unknown> = Record<string, unknown>, G extends Record<string, unknown> = Record<string, unknown>, A extends Record<string, (...args: any[]) => any> = Record<string, never>> = {
66
+ /** Unique store identifier for devtools */
67
+ id: string;
68
+ /** State factory function */
69
+ state: StateFactory<S>;
70
+ /** Computed getters */
71
+ getters?: Getters<S, G>;
72
+ /** Action methods */
73
+ actions?: A;
74
+ };
75
+ /**
76
+ * The returned store instance with state, getters, and actions merged.
77
+ */
78
+ export type Store<S extends Record<string, unknown>, G extends Record<string, unknown>, A extends Record<string, (...args: any[]) => any>> = S & G & A & {
79
+ /** Store identifier */
80
+ $id: string;
81
+ /** Reset state to initial values */
82
+ $reset: () => void;
83
+ /** Subscribe to state changes */
84
+ $subscribe: (callback: (state: S) => void) => () => void;
85
+ /** Patch multiple state properties at once (shallow) */
86
+ $patch: (partial: Partial<S> | ((state: S) => void)) => void;
87
+ /**
88
+ * Patch with deep reactivity support.
89
+ * Unlike $patch, this method deep-clones nested objects before mutation,
90
+ * ensuring that all changes trigger reactive updates.
91
+ */
92
+ $patchDeep: (partial: Partial<S> | ((state: S) => void)) => void;
93
+ /** Get raw state object (non-reactive snapshot) */
94
+ $state: S;
95
+ };
96
+ /**
97
+ * Plugin that can extend store functionality.
98
+ */
99
+ export type StorePlugin<S = unknown> = (context: {
100
+ store: Store<any, any, any>;
101
+ options: StoreDefinition<any, any, any>;
102
+ }) => Partial<S> | void;
103
+ /** @internal Devtools hook */
104
+ declare global {
105
+ interface Window {
106
+ __BQUERY_DEVTOOLS__?: {
107
+ stores: Map<string, unknown>;
108
+ onStoreCreated?: (id: string, store: unknown) => void;
109
+ onStateChange?: (id: string, state: unknown) => void;
110
+ };
111
+ }
112
+ }
113
+ /**
114
+ * Creates a reactive store with state, getters, and actions.
115
+ *
116
+ * @template S - State type
117
+ * @template G - Getters type
118
+ * @template A - Actions type
119
+ * @param definition - Store definition
120
+ * @returns The reactive store instance
121
+ *
122
+ * @example
123
+ * ```ts
124
+ * import { createStore } from 'bquery/store';
125
+ *
126
+ * // Simple counter store
127
+ * const useCounter = createStore({
128
+ * id: 'counter',
129
+ * state: () => ({ count: 0, step: 1 }),
130
+ * getters: {
131
+ * doubled: (state) => state.count * 2,
132
+ * next: (state) => state.count + state.step,
133
+ * },
134
+ * actions: {
135
+ * increment() {
136
+ * this.count += this.step;
137
+ * },
138
+ * decrement() {
139
+ * this.count -= this.step;
140
+ * },
141
+ * setStep(newStep: number) {
142
+ * this.step = newStep;
143
+ * },
144
+ * async loadFromServer() {
145
+ * const res = await fetch('/api/counter');
146
+ * const data = await res.json();
147
+ * this.count = data.count;
148
+ * },
149
+ * },
150
+ * });
151
+ *
152
+ * // Use the store
153
+ * useCounter.increment();
154
+ * console.log(useCounter.count); // 1
155
+ * console.log(useCounter.doubled); // 2
156
+ * ```
157
+ */
158
+ export declare const createStore: <S extends Record<string, unknown>, G extends Record<string, unknown> = Record<string, never>, A extends Record<string, (...args: any[]) => any> = Record<string, never>>(definition: StoreDefinition<S, G, A>) => Store<S, G, A>;
159
+ /**
160
+ * Retrieves an existing store by its ID.
161
+ *
162
+ * @param id - The store identifier
163
+ * @returns The store instance or undefined if not found
164
+ *
165
+ * @example
166
+ * ```ts
167
+ * import { getStore } from 'bquery/store';
168
+ *
169
+ * const counter = getStore('counter');
170
+ * if (counter) {
171
+ * counter.increment();
172
+ * }
173
+ * ```
174
+ */
175
+ export declare const getStore: <T = unknown>(id: string) => T | undefined;
176
+ /**
177
+ * Lists all registered store IDs.
178
+ *
179
+ * @returns Array of store IDs
180
+ *
181
+ * @example
182
+ * ```ts
183
+ * import { listStores } from 'bquery/store';
184
+ *
185
+ * console.log('Active stores:', listStores());
186
+ * ```
187
+ */
188
+ export declare const listStores: () => string[];
189
+ /**
190
+ * Removes a store from the registry.
191
+ *
192
+ * @param id - The store identifier
193
+ *
194
+ * @example
195
+ * ```ts
196
+ * import { destroyStore } from 'bquery/store';
197
+ *
198
+ * destroyStore('counter');
199
+ * ```
200
+ */
201
+ export declare const destroyStore: (id: string) => void;
202
+ /**
203
+ * Registers a plugin that extends all stores.
204
+ *
205
+ * @param plugin - The plugin function
206
+ *
207
+ * @example
208
+ * ```ts
209
+ * import { registerPlugin } from 'bquery/store';
210
+ *
211
+ * // Add localStorage persistence
212
+ * registerPlugin(({ store, options }) => {
213
+ * const key = `bquery-store-${options.id}`;
214
+ *
215
+ * // Load saved state
216
+ * const saved = localStorage.getItem(key);
217
+ * if (saved) {
218
+ * store.$patch(JSON.parse(saved));
219
+ * }
220
+ *
221
+ * // Save on changes
222
+ * store.$subscribe((state) => {
223
+ * localStorage.setItem(key, JSON.stringify(state));
224
+ * });
225
+ * });
226
+ * ```
227
+ */
228
+ export declare const registerPlugin: (plugin: StorePlugin) => void;
229
+ /**
230
+ * Creates a store with automatic persistence to localStorage.
231
+ *
232
+ * @param definition - Store definition
233
+ * @param storageKey - Optional custom storage key
234
+ * @returns The reactive store instance
235
+ *
236
+ * @example
237
+ * ```ts
238
+ * import { createPersistedStore } from 'bquery/store';
239
+ *
240
+ * const settings = createPersistedStore({
241
+ * id: 'settings',
242
+ * state: () => ({
243
+ * theme: 'dark',
244
+ * language: 'en',
245
+ * }),
246
+ * });
247
+ *
248
+ * // State is automatically saved/loaded from localStorage
249
+ * settings.theme = 'light';
250
+ * ```
251
+ */
252
+ export declare const createPersistedStore: <S extends Record<string, unknown>, G extends Record<string, unknown> = Record<string, never>, A extends Record<string, (...args: unknown[]) => unknown> = Record<string, never>>(definition: StoreDefinition<S, G, A>, storageKey?: string) => Store<S, G, A>;
253
+ /**
254
+ * Maps store state properties to a reactive object for use in components.
255
+ *
256
+ * @param store - The store instance
257
+ * @param keys - State keys to map
258
+ * @returns Object with mapped properties
259
+ *
260
+ * @example
261
+ * ```ts
262
+ * import { mapState } from 'bquery/store';
263
+ *
264
+ * const counter = useCounter();
265
+ * const { count, step } = mapState(counter, ['count', 'step']);
266
+ * ```
267
+ */
268
+ export declare const mapState: <S extends Record<string, unknown>, K extends keyof S>(store: S, keys: K[]) => Pick<S, K>;
269
+ /**
270
+ * Maps store actions to an object for easier destructuring.
271
+ *
272
+ * @param store - The store instance
273
+ * @param keys - Action keys to map
274
+ * @returns Object with mapped actions
275
+ *
276
+ * @example
277
+ * ```ts
278
+ * import { mapActions } from 'bquery/store';
279
+ *
280
+ * const counter = useCounter();
281
+ * const { increment, decrement } = mapActions(counter, ['increment', 'decrement']);
282
+ *
283
+ * // Use directly
284
+ * increment();
285
+ * ```
286
+ */
287
+ export declare const mapActions: <A extends Record<string, (...args: unknown[]) => unknown>, K extends keyof A>(store: A, keys: K[]) => Pick<A, K>;
288
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/store/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,229 @@
1
+ import { signal as D, computed as P, batch as m } from "./reactive.es.mjs";
2
+ const p = /* @__PURE__ */ new Map(), A = (e) => e !== null && typeof e == "object" && Object.getPrototypeOf(e) === Object.prototype, d = (e) => {
3
+ if (e === null || typeof e != "object")
4
+ return e;
5
+ if (Array.isArray(e))
6
+ return e.map(d);
7
+ if (e instanceof Date)
8
+ return new Date(e.getTime());
9
+ if (e instanceof Map)
10
+ return new Map(Array.from(e.entries()).map(([o, c]) => [o, d(c)]));
11
+ if (e instanceof Set)
12
+ return new Set(Array.from(e).map(d));
13
+ const n = {};
14
+ for (const o of Object.keys(e))
15
+ n[o] = d(e[o]);
16
+ return n;
17
+ }, v = (e, n) => {
18
+ if (e === n) return !0;
19
+ if (e === null || n === null || typeof e != "object" || typeof n != "object") return !1;
20
+ if (Array.isArray(e) && Array.isArray(n))
21
+ return e.length !== n.length ? !1 : e.every((i, u) => v(i, n[u]));
22
+ if (Array.isArray(e) !== Array.isArray(n)) return !1;
23
+ const o = Object.keys(e), c = Object.keys(n);
24
+ return o.length !== c.length ? !1 : o.every(
25
+ (i) => v(e[i], n[i])
26
+ );
27
+ }, V = (e, n, o) => {
28
+ const c = [];
29
+ for (const i of Object.keys(n)) {
30
+ const u = e[i], s = n[i];
31
+ o.get(i) === s && // Same reference as signal
32
+ A(u) && A(s) && !v(u, s) && c.push(i);
33
+ }
34
+ return c;
35
+ }, S = (() => {
36
+ try {
37
+ const e = globalThis.process;
38
+ return typeof e < "u" && e.env?.NODE_ENV !== "production";
39
+ } catch {
40
+ return !0;
41
+ }
42
+ })(), j = [], x = (e) => {
43
+ const { id: n, state: o, getters: c = {}, actions: i = {} } = e;
44
+ if (p.has(n))
45
+ return console.warn(`bQuery store: Store "${n}" already exists. Returning existing instance.`), p.get(n);
46
+ const u = o(), s = /* @__PURE__ */ new Map();
47
+ for (const t of Object.keys(u))
48
+ s.set(t, D(u[t]));
49
+ const _ = [], w = () => {
50
+ const t = O();
51
+ for (const r of _)
52
+ r(t);
53
+ typeof window < "u" && window.__BQUERY_DEVTOOLS__?.onStateChange && window.__BQUERY_DEVTOOLS__.onStateChange(n, t);
54
+ }, k = new Proxy({}, {
55
+ get: (t, r) => {
56
+ const a = r;
57
+ if (s.has(a))
58
+ return s.get(a).value;
59
+ },
60
+ ownKeys: () => Array.from(s.keys()),
61
+ getOwnPropertyDescriptor: (t, r) => {
62
+ if (s.has(r))
63
+ return { enumerable: !0, configurable: !0 };
64
+ },
65
+ has: (t, r) => s.has(r)
66
+ }), O = () => ({ ...k }), b = /* @__PURE__ */ new Map(), y = {};
67
+ for (const t of Object.keys(u))
68
+ Object.defineProperty(y, t, {
69
+ get: () => s.get(t).value,
70
+ set: (r) => {
71
+ s.get(t).value = r, w();
72
+ },
73
+ enumerable: !0,
74
+ configurable: !1
75
+ });
76
+ for (const t of Object.keys(c)) {
77
+ const r = c[t], a = P(() => {
78
+ const g = k, l = new Proxy({}, {
79
+ get: (f, h) => {
80
+ const E = h;
81
+ if (b.has(E))
82
+ return b.get(E).value;
83
+ }
84
+ });
85
+ return r(g, l);
86
+ });
87
+ b.set(t, a), Object.defineProperty(y, t, {
88
+ get: () => a.value,
89
+ enumerable: !0,
90
+ configurable: !1
91
+ });
92
+ }
93
+ for (const t of Object.keys(i)) {
94
+ const r = i[t];
95
+ y[t] = function(...a) {
96
+ const g = new Proxy(y, {
97
+ get: (l, f) => typeof f == "string" && s.has(f) ? s.get(f).value : l[f],
98
+ set: (l, f, h) => typeof f == "string" && s.has(f) ? (s.get(f).value = h, w(), !0) : !1
99
+ });
100
+ return r.apply(g, a);
101
+ };
102
+ }
103
+ Object.defineProperties(y, {
104
+ $id: {
105
+ value: n,
106
+ writable: !1,
107
+ enumerable: !1
108
+ },
109
+ $reset: {
110
+ value: () => {
111
+ const t = o();
112
+ m(() => {
113
+ for (const [r, a] of s)
114
+ a.value = t[r];
115
+ }), w();
116
+ },
117
+ writable: !1,
118
+ enumerable: !1
119
+ },
120
+ $subscribe: {
121
+ value: (t) => (_.push(t), () => {
122
+ const r = _.indexOf(t);
123
+ r > -1 && _.splice(r, 1);
124
+ }),
125
+ writable: !1,
126
+ enumerable: !1
127
+ },
128
+ $patch: {
129
+ value: (t) => {
130
+ m(() => {
131
+ if (typeof t == "function") {
132
+ const r = S ? d(O()) : null, a = S ? new Map(Array.from(s.entries()).map(([l, f]) => [l, f.value])) : null, g = O();
133
+ if (t(g), S && r && a) {
134
+ const l = V(r, g, a);
135
+ l.length > 0 && console.warn(
136
+ `[bQuery store "${n}"] Nested mutation detected in $patch() for keys: ${l.map(String).join(", ")}.
137
+ Nested object mutations do not trigger reactive updates because the store uses shallow reactivity.
138
+ To fix this, either:
139
+ 1. Replace the entire object: state.user = { ...state.user, name: "New" }
140
+ 2. Use $patchDeep() for automatic deep cloning
141
+ See: https://bquery.dev/guide/store#deep-reactivity`
142
+ );
143
+ }
144
+ for (const [l, f] of Object.entries(g))
145
+ s.has(l) && (s.get(l).value = f);
146
+ } else
147
+ for (const [r, a] of Object.entries(t))
148
+ s.has(r) && (s.get(r).value = a);
149
+ }), w();
150
+ },
151
+ writable: !1,
152
+ enumerable: !1
153
+ },
154
+ $patchDeep: {
155
+ value: (t) => {
156
+ m(() => {
157
+ if (typeof t == "function") {
158
+ const r = d(O());
159
+ t(r);
160
+ for (const [a, g] of Object.entries(r))
161
+ s.has(a) && (s.get(a).value = g);
162
+ } else
163
+ for (const [r, a] of Object.entries(t))
164
+ s.has(r) && (s.get(r).value = d(a));
165
+ }), w();
166
+ },
167
+ writable: !1,
168
+ enumerable: !1
169
+ },
170
+ $state: {
171
+ get: () => O(),
172
+ enumerable: !1
173
+ }
174
+ }), p.set(n, y);
175
+ for (const t of j) {
176
+ const r = t({ store: y, options: e });
177
+ r && Object.assign(y, r);
178
+ }
179
+ return typeof window < "u" && (window.__BQUERY_DEVTOOLS__ || (window.__BQUERY_DEVTOOLS__ = { stores: /* @__PURE__ */ new Map() }), window.__BQUERY_DEVTOOLS__.stores.set(n, y), window.__BQUERY_DEVTOOLS__.onStoreCreated?.(n, y)), y;
180
+ }, B = (e) => p.get(e), R = () => Array.from(p.keys()), T = (e) => {
181
+ p.delete(e), typeof window < "u" && window.__BQUERY_DEVTOOLS__ && window.__BQUERY_DEVTOOLS__.stores.delete(e);
182
+ }, Q = (e) => {
183
+ j.push(e);
184
+ }, U = (e, n) => {
185
+ const o = n ?? `bquery-store-${e.id}`, c = e.state;
186
+ e.state = () => {
187
+ const u = c();
188
+ if (typeof window < "u")
189
+ try {
190
+ const s = localStorage.getItem(o);
191
+ if (s)
192
+ return { ...u, ...JSON.parse(s) };
193
+ } catch {
194
+ }
195
+ return u;
196
+ };
197
+ const i = x(e);
198
+ return i.$subscribe((u) => {
199
+ if (typeof window < "u")
200
+ try {
201
+ localStorage.setItem(o, JSON.stringify(u));
202
+ } catch {
203
+ }
204
+ }), i;
205
+ }, L = (e, n) => {
206
+ const o = {};
207
+ for (const c of n)
208
+ Object.defineProperty(o, c, {
209
+ get: () => e[c],
210
+ enumerable: !0
211
+ });
212
+ return o;
213
+ }, M = (e, n) => {
214
+ const o = {};
215
+ for (const c of n)
216
+ o[c] = (...i) => e[c](...i);
217
+ return o;
218
+ };
219
+ export {
220
+ U as createPersistedStore,
221
+ x as createStore,
222
+ T as destroyStore,
223
+ B as getStore,
224
+ R as listStores,
225
+ M as mapActions,
226
+ L as mapState,
227
+ Q as registerPlugin
228
+ };
229
+ //# sourceMappingURL=store.es.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.es.mjs","sources":["../src/store/index.ts"],"sourcesContent":["/**\r\n * Minimal state management built on signals.\r\n *\r\n * This module provides a lightweight store pattern inspired by Pinia/Vuex\r\n * but built entirely on bQuery's reactive primitives. Features include:\r\n * - Signal-based reactive state\r\n * - Computed getters\r\n * - Actions with async support\r\n * - Devtools hooks for debugging\r\n * - Plugin system for extensions\r\n *\r\n * @module bquery/store\r\n *\r\n * @example\r\n * ```ts\r\n * import { createStore } from 'bquery/store';\r\n * import { effect } from 'bquery/reactive';\r\n *\r\n * const counterStore = createStore({\r\n * id: 'counter',\r\n * state: () => ({ count: 0 }),\r\n * getters: {\r\n * doubled: (state) => state.count * 2,\r\n * isPositive: (state) => state.count > 0,\r\n * },\r\n * actions: {\r\n * increment() {\r\n * this.count++;\r\n * },\r\n * async fetchAndSet(url: string) {\r\n * const response = await fetch(url);\r\n * const data = await response.json();\r\n * this.count = data.count;\r\n * },\r\n * },\r\n * });\r\n *\r\n * effect(() => {\r\n * console.log('Count:', counterStore.count);\r\n * console.log('Doubled:', counterStore.doubled);\r\n * });\r\n *\r\n * counterStore.increment();\r\n * ```\r\n */\r\n\r\nimport { batch, computed, signal, type ReadonlySignal, type Signal } from '../reactive/index';\r\n\r\n// ============================================================================\r\n// Types\r\n// ============================================================================\r\n\r\n/**\r\n * Store state factory function.\r\n */\r\nexport type StateFactory<S> = () => S;\r\n\r\n/**\r\n * Getter definition - derives computed values from state.\r\n */\r\nexport type Getters<S, G> = {\r\n [K in keyof G]: (state: S, getters: G) => G[K];\r\n};\r\n\r\n/**\r\n * Action definition - methods that can modify state.\r\n */\r\nexport type Actions<S, A> = {\r\n [K in keyof A]: A[K] extends (...args: infer P) => infer R\r\n ? (this: S & A, ...args: P) => R\r\n : never;\r\n};\r\n\r\n/**\r\n * Store definition for createStore.\r\n */\r\nexport type StoreDefinition<\r\n S extends Record<string, unknown> = Record<string, unknown>,\r\n G extends Record<string, unknown> = Record<string, unknown>,\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n A extends Record<string, (...args: any[]) => any> = Record<string, never>,\r\n> = {\r\n /** Unique store identifier for devtools */\r\n id: string;\r\n /** State factory function */\r\n state: StateFactory<S>;\r\n /** Computed getters */\r\n getters?: Getters<S, G>;\r\n /** Action methods */\r\n actions?: A;\r\n};\r\n\r\n/**\r\n * The returned store instance with state, getters, and actions merged.\r\n */\r\nexport type Store<\r\n S extends Record<string, unknown>,\r\n G extends Record<string, unknown>,\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n A extends Record<string, (...args: any[]) => any>,\r\n> = S &\r\n G &\r\n A & {\r\n /** Store identifier */\r\n $id: string;\r\n /** Reset state to initial values */\r\n $reset: () => void;\r\n /** Subscribe to state changes */\r\n $subscribe: (callback: (state: S) => void) => () => void;\r\n /** Patch multiple state properties at once (shallow) */\r\n $patch: (partial: Partial<S> | ((state: S) => void)) => void;\r\n /**\r\n * Patch with deep reactivity support.\r\n * Unlike $patch, this method deep-clones nested objects before mutation,\r\n * ensuring that all changes trigger reactive updates.\r\n */\r\n $patchDeep: (partial: Partial<S> | ((state: S) => void)) => void;\r\n /** Get raw state object (non-reactive snapshot) */\r\n $state: S;\r\n };\r\n\r\n/**\r\n * Plugin that can extend store functionality.\r\n */\r\nexport type StorePlugin<S = unknown> = (context: {\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n store: Store<any, any, any>;\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n options: StoreDefinition<any, any, any>;\r\n}) => Partial<S> | void;\r\n\r\n// ============================================================================\r\n// Internal State\r\n// ============================================================================\r\n\r\n/** @internal Registry of all stores for devtools */\r\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\r\nconst storeRegistry = new Map<string, Store<any, any, any>>();\r\n\r\n// ============================================================================\r\n// Internal Utilities\r\n// ============================================================================\r\n\r\n/**\r\n * Check if a value is a plain object (not array, null, Date, etc.).\r\n * @internal\r\n */\r\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => {\r\n return (\r\n value !== null && typeof value === 'object' && Object.getPrototypeOf(value) === Object.prototype\r\n );\r\n};\r\n\r\n/**\r\n * Deep clones an object. Used for deep reactivity support.\r\n * @internal\r\n */\r\nconst deepClone = <T>(obj: T): T => {\r\n if (obj === null || typeof obj !== 'object') {\r\n return obj;\r\n }\r\n\r\n if (Array.isArray(obj)) {\r\n return obj.map(deepClone) as T;\r\n }\r\n\r\n if (obj instanceof Date) {\r\n return new Date(obj.getTime()) as T;\r\n }\r\n\r\n if (obj instanceof Map) {\r\n return new Map(Array.from(obj.entries()).map(([k, v]) => [k, deepClone(v)])) as T;\r\n }\r\n\r\n if (obj instanceof Set) {\r\n return new Set(Array.from(obj).map(deepClone)) as T;\r\n }\r\n\r\n const cloned = {} as T;\r\n for (const key of Object.keys(obj)) {\r\n (cloned as Record<string, unknown>)[key] = deepClone((obj as Record<string, unknown>)[key]);\r\n }\r\n return cloned;\r\n};\r\n\r\n/**\r\n * Compares two values for deep equality.\r\n * @internal\r\n */\r\nconst deepEqual = (a: unknown, b: unknown): boolean => {\r\n if (a === b) return true;\r\n if (a === null || b === null) return false;\r\n if (typeof a !== 'object' || typeof b !== 'object') return false;\r\n\r\n if (Array.isArray(a) && Array.isArray(b)) {\r\n if (a.length !== b.length) return false;\r\n return a.every((item, i) => deepEqual(item, b[i]));\r\n }\r\n\r\n if (Array.isArray(a) !== Array.isArray(b)) return false;\r\n\r\n const keysA = Object.keys(a as object);\r\n const keysB = Object.keys(b as object);\r\n\r\n if (keysA.length !== keysB.length) return false;\r\n\r\n return keysA.every((key) =>\r\n deepEqual((a as Record<string, unknown>)[key], (b as Record<string, unknown>)[key])\r\n );\r\n};\r\n\r\n/**\r\n * Detects if nested objects were mutated but the reference stayed the same.\r\n * Returns the keys where nested mutations were detected.\r\n * @internal\r\n */\r\nconst detectNestedMutations = <S extends Record<string, unknown>>(\r\n before: S,\r\n after: S,\r\n signalValues: Map<keyof S, unknown>\r\n): Array<keyof S> => {\r\n const mutatedKeys: Array<keyof S> = [];\r\n\r\n for (const key of Object.keys(after) as Array<keyof S>) {\r\n const beforeValue = before[key];\r\n const afterValue = after[key];\r\n const signalValue = signalValues.get(key);\r\n\r\n // Check if it's the same reference but content changed\r\n if (\r\n signalValue === afterValue && // Same reference as signal\r\n isPlainObject(beforeValue) &&\r\n isPlainObject(afterValue) &&\r\n !deepEqual(beforeValue, afterValue)\r\n ) {\r\n mutatedKeys.push(key);\r\n }\r\n }\r\n\r\n return mutatedKeys;\r\n};\r\n\r\n/** @internal Flag to enable/disable development warnings */\r\nconst __DEV__ = (() => {\r\n try {\r\n // Check for Node.js environment\r\n const globalProcess = (globalThis as { process?: { env?: { NODE_ENV?: string } } }).process;\r\n return typeof globalProcess !== 'undefined' && globalProcess.env?.NODE_ENV !== 'production';\r\n } catch {\r\n return true; // Default to dev mode if detection fails\r\n }\r\n})();\r\n\r\n/** @internal Registered plugins */\r\nconst plugins: StorePlugin[] = [];\r\n\r\n/** @internal Devtools hook */\r\ndeclare global {\r\n interface Window {\r\n __BQUERY_DEVTOOLS__?: {\r\n stores: Map<string, unknown>;\r\n onStoreCreated?: (id: string, store: unknown) => void;\r\n onStateChange?: (id: string, state: unknown) => void;\r\n };\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// Store Creation\r\n// ============================================================================\r\n\r\n/**\r\n * Creates a reactive store with state, getters, and actions.\r\n *\r\n * @template S - State type\r\n * @template G - Getters type\r\n * @template A - Actions type\r\n * @param definition - Store definition\r\n * @returns The reactive store instance\r\n *\r\n * @example\r\n * ```ts\r\n * import { createStore } from 'bquery/store';\r\n *\r\n * // Simple counter store\r\n * const useCounter = createStore({\r\n * id: 'counter',\r\n * state: () => ({ count: 0, step: 1 }),\r\n * getters: {\r\n * doubled: (state) => state.count * 2,\r\n * next: (state) => state.count + state.step,\r\n * },\r\n * actions: {\r\n * increment() {\r\n * this.count += this.step;\r\n * },\r\n * decrement() {\r\n * this.count -= this.step;\r\n * },\r\n * setStep(newStep: number) {\r\n * this.step = newStep;\r\n * },\r\n * async loadFromServer() {\r\n * const res = await fetch('/api/counter');\r\n * const data = await res.json();\r\n * this.count = data.count;\r\n * },\r\n * },\r\n * });\r\n *\r\n * // Use the store\r\n * useCounter.increment();\r\n * console.log(useCounter.count); // 1\r\n * console.log(useCounter.doubled); // 2\r\n * ```\r\n */\r\nexport const createStore = <\r\n S extends Record<string, unknown>,\r\n G extends Record<string, unknown> = Record<string, never>,\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n A extends Record<string, (...args: any[]) => any> = Record<string, never>,\r\n>(\r\n definition: StoreDefinition<S, G, A>\r\n): Store<S, G, A> => {\r\n const { id, state: stateFactory, getters = {} as Getters<S, G>, actions = {} as A } = definition;\r\n\r\n // Check for duplicate store IDs\r\n if (storeRegistry.has(id)) {\r\n console.warn(`bQuery store: Store \"${id}\" already exists. Returning existing instance.`);\r\n return storeRegistry.get(id) as Store<S, G, A>;\r\n }\r\n\r\n // Create initial state\r\n const initialState = stateFactory();\r\n\r\n // Create signals for each state property\r\n const stateSignals = new Map<keyof S, Signal<unknown>>();\r\n for (const key of Object.keys(initialState) as Array<keyof S>) {\r\n stateSignals.set(key, signal(initialState[key]));\r\n }\r\n\r\n // Subscribers for $subscribe\r\n const subscribers: Array<(state: S) => void> = [];\r\n\r\n /**\r\n * Notifies subscribers of state changes.\r\n * @internal\r\n */\r\n const notifySubscribers = (): void => {\r\n const currentState = getCurrentState();\r\n for (const callback of subscribers) {\r\n callback(currentState);\r\n }\r\n\r\n // Notify devtools\r\n if (typeof window !== 'undefined' && window.__BQUERY_DEVTOOLS__?.onStateChange) {\r\n window.__BQUERY_DEVTOOLS__.onStateChange(id, currentState);\r\n }\r\n };\r\n\r\n /**\r\n * Cached state proxy that lazily reads signal values.\r\n * Uses a Proxy to avoid creating new objects on each access.\r\n *\r\n * **Note:** This returns a shallow snapshot of the state. Nested object\r\n * mutations will NOT trigger reactive updates. For nested reactivity,\r\n * replace the entire object or use signals for nested properties.\r\n *\r\n * @internal\r\n */\r\n const stateProxy = new Proxy({} as S, {\r\n get: (_, prop: string | symbol) => {\r\n const key = prop as keyof S;\r\n if (stateSignals.has(key)) {\r\n return stateSignals.get(key)!.value;\r\n }\r\n return undefined;\r\n },\r\n ownKeys: () => Array.from(stateSignals.keys()) as string[],\r\n getOwnPropertyDescriptor: (_, prop) => {\r\n if (stateSignals.has(prop as keyof S)) {\r\n return { enumerable: true, configurable: true };\r\n }\r\n return undefined;\r\n },\r\n has: (_, prop) => stateSignals.has(prop as keyof S),\r\n });\r\n\r\n /**\r\n * Gets the current state.\r\n *\r\n * For subscriber notifications (where a plain object snapshot is needed),\r\n * this creates a shallow copy. For internal reads, use stateProxy directly.\r\n *\r\n * **Note:** Returns a shallow snapshot. Nested object mutations will NOT\r\n * trigger reactive updates. This differs from frameworks like Pinia that\r\n * use deep reactivity. To update nested state, replace the entire object:\r\n *\r\n * @example\r\n * ```ts\r\n * // ❌ Won't trigger updates\r\n * store.user.name = 'New Name';\r\n *\r\n * // ✅ Will trigger updates\r\n * store.user = { ...store.user, name: 'New Name' };\r\n * ```\r\n *\r\n * @internal\r\n */\r\n const getCurrentState = (): S => ({ ...stateProxy });\r\n\r\n // Create computed getters\r\n const getterComputed = new Map<keyof G, ReadonlySignal<unknown>>();\r\n\r\n // Build the store proxy\r\n const store = {} as Store<S, G, A>;\r\n\r\n // Define state properties with getters/setters\r\n for (const key of Object.keys(initialState) as Array<keyof S>) {\r\n Object.defineProperty(store, key, {\r\n get: () => stateSignals.get(key)!.value,\r\n set: (value: unknown) => {\r\n stateSignals.get(key)!.value = value;\r\n notifySubscribers();\r\n },\r\n enumerable: true,\r\n configurable: false,\r\n });\r\n }\r\n\r\n // Define getters as computed properties\r\n for (const key of Object.keys(getters) as Array<keyof G>) {\r\n const getterFn = getters[key];\r\n\r\n // Create computed that reads from state signals via proxy (more efficient)\r\n const computedGetter = computed(() => {\r\n const state = stateProxy;\r\n // For getter dependencies, pass a proxy that reads from computed getters\r\n const getterProxy = new Proxy({} as G, {\r\n get: (_, prop: string | symbol) => {\r\n const propKey = prop as keyof G;\r\n if (getterComputed.has(propKey)) {\r\n return getterComputed.get(propKey)!.value;\r\n }\r\n return undefined;\r\n },\r\n });\r\n return getterFn(state, getterProxy);\r\n });\r\n\r\n getterComputed.set(key, computedGetter as unknown as ReadonlySignal<unknown>);\r\n\r\n Object.defineProperty(store, key, {\r\n get: () => computedGetter.value,\r\n enumerable: true,\r\n configurable: false,\r\n });\r\n }\r\n\r\n // Bind actions to the store context\r\n for (const key of Object.keys(actions) as Array<keyof A>) {\r\n const actionFn = actions[key];\r\n\r\n // Wrap action to enable 'this' binding\r\n (store as Record<string, unknown>)[key as string] = function (...args: unknown[]) {\r\n // Create a context that allows 'this.property' access\r\n const context = new Proxy(store, {\r\n get: (target, prop) => {\r\n if (typeof prop === 'string' && stateSignals.has(prop as keyof S)) {\r\n return stateSignals.get(prop as keyof S)!.value;\r\n }\r\n return (target as Record<string, unknown>)[prop as string];\r\n },\r\n set: (_target, prop, value) => {\r\n if (typeof prop === 'string' && stateSignals.has(prop as keyof S)) {\r\n stateSignals.get(prop as keyof S)!.value = value;\r\n notifySubscribers();\r\n return true;\r\n }\r\n return false;\r\n },\r\n });\r\n\r\n return actionFn.apply(context, args);\r\n };\r\n }\r\n\r\n // Add store utility methods\r\n Object.defineProperties(store, {\r\n $id: {\r\n value: id,\r\n writable: false,\r\n enumerable: false,\r\n },\r\n $reset: {\r\n value: () => {\r\n const fresh = stateFactory();\r\n batch(() => {\r\n for (const [key, sig] of stateSignals) {\r\n sig.value = fresh[key];\r\n }\r\n });\r\n notifySubscribers();\r\n },\r\n writable: false,\r\n enumerable: false,\r\n },\r\n $subscribe: {\r\n value: (callback: (state: S) => void) => {\r\n subscribers.push(callback);\r\n return () => {\r\n const index = subscribers.indexOf(callback);\r\n if (index > -1) subscribers.splice(index, 1);\r\n };\r\n },\r\n writable: false,\r\n enumerable: false,\r\n },\r\n $patch: {\r\n value: (partial: Partial<S> | ((state: S) => void)) => {\r\n batch(() => {\r\n if (typeof partial === 'function') {\r\n // Capture state before mutation for nested mutation detection\r\n const stateBefore = __DEV__ ? deepClone(getCurrentState()) : null;\r\n const signalValuesBefore = __DEV__\r\n ? new Map(Array.from(stateSignals.entries()).map(([k, s]) => [k, s.value]))\r\n : null;\r\n\r\n // Mutation function\r\n const state = getCurrentState();\r\n partial(state);\r\n\r\n // Detect nested mutations in development mode\r\n if (__DEV__ && stateBefore && signalValuesBefore) {\r\n const mutatedKeys = detectNestedMutations(stateBefore, state, signalValuesBefore);\r\n if (mutatedKeys.length > 0) {\r\n console.warn(\r\n `[bQuery store \"${id}\"] Nested mutation detected in $patch() for keys: ${mutatedKeys.map(String).join(', ')}.\\n` +\r\n 'Nested object mutations do not trigger reactive updates because the store uses shallow reactivity.\\n' +\r\n 'To fix this, either:\\n' +\r\n ' 1. Replace the entire object: state.user = { ...state.user, name: \"New\" }\\n' +\r\n ' 2. Use $patchDeep() for automatic deep cloning\\n' +\r\n 'See: https://bquery.dev/guide/store#deep-reactivity'\r\n );\r\n }\r\n }\r\n\r\n for (const [key, value] of Object.entries(state) as Array<[keyof S, unknown]>) {\r\n if (stateSignals.has(key)) {\r\n stateSignals.get(key)!.value = value;\r\n }\r\n }\r\n } else {\r\n // Partial object\r\n for (const [key, value] of Object.entries(partial) as Array<[keyof S, unknown]>) {\r\n if (stateSignals.has(key)) {\r\n stateSignals.get(key)!.value = value;\r\n }\r\n }\r\n }\r\n });\r\n notifySubscribers();\r\n },\r\n writable: false,\r\n enumerable: false,\r\n },\r\n $patchDeep: {\r\n value: (partial: Partial<S> | ((state: S) => void)) => {\r\n batch(() => {\r\n if (typeof partial === 'function') {\r\n // Deep clone state before mutation to ensure new references\r\n const state = deepClone(getCurrentState());\r\n partial(state);\r\n\r\n for (const [key, value] of Object.entries(state) as Array<[keyof S, unknown]>) {\r\n if (stateSignals.has(key)) {\r\n stateSignals.get(key)!.value = value;\r\n }\r\n }\r\n } else {\r\n // Deep clone each value in partial to ensure new references\r\n for (const [key, value] of Object.entries(partial) as Array<[keyof S, unknown]>) {\r\n if (stateSignals.has(key)) {\r\n stateSignals.get(key)!.value = deepClone(value);\r\n }\r\n }\r\n }\r\n });\r\n notifySubscribers();\r\n },\r\n writable: false,\r\n enumerable: false,\r\n },\r\n $state: {\r\n get: () => getCurrentState(),\r\n enumerable: false,\r\n },\r\n });\r\n\r\n // Register store\r\n storeRegistry.set(id, store);\r\n\r\n // Apply plugins\r\n for (const plugin of plugins) {\r\n const extension = plugin({ store, options: definition });\r\n if (extension) {\r\n Object.assign(store, extension);\r\n }\r\n }\r\n\r\n // Notify devtools\r\n if (typeof window !== 'undefined') {\r\n if (!window.__BQUERY_DEVTOOLS__) {\r\n window.__BQUERY_DEVTOOLS__ = { stores: new Map() };\r\n }\r\n window.__BQUERY_DEVTOOLS__.stores.set(id, store);\r\n window.__BQUERY_DEVTOOLS__.onStoreCreated?.(id, store);\r\n }\r\n\r\n return store;\r\n};\r\n\r\n// ============================================================================\r\n// Store Utilities\r\n// ============================================================================\r\n\r\n/**\r\n * Retrieves an existing store by its ID.\r\n *\r\n * @param id - The store identifier\r\n * @returns The store instance or undefined if not found\r\n *\r\n * @example\r\n * ```ts\r\n * import { getStore } from 'bquery/store';\r\n *\r\n * const counter = getStore('counter');\r\n * if (counter) {\r\n * counter.increment();\r\n * }\r\n * ```\r\n */\r\nexport const getStore = <T = unknown>(id: string): T | undefined => {\r\n return storeRegistry.get(id) as T | undefined;\r\n};\r\n\r\n/**\r\n * Lists all registered store IDs.\r\n *\r\n * @returns Array of store IDs\r\n *\r\n * @example\r\n * ```ts\r\n * import { listStores } from 'bquery/store';\r\n *\r\n * console.log('Active stores:', listStores());\r\n * ```\r\n */\r\nexport const listStores = (): string[] => {\r\n return Array.from(storeRegistry.keys());\r\n};\r\n\r\n/**\r\n * Removes a store from the registry.\r\n *\r\n * @param id - The store identifier\r\n *\r\n * @example\r\n * ```ts\r\n * import { destroyStore } from 'bquery/store';\r\n *\r\n * destroyStore('counter');\r\n * ```\r\n */\r\nexport const destroyStore = (id: string): void => {\r\n storeRegistry.delete(id);\r\n if (typeof window !== 'undefined' && window.__BQUERY_DEVTOOLS__) {\r\n window.__BQUERY_DEVTOOLS__.stores.delete(id);\r\n }\r\n};\r\n\r\n/**\r\n * Registers a plugin that extends all stores.\r\n *\r\n * @param plugin - The plugin function\r\n *\r\n * @example\r\n * ```ts\r\n * import { registerPlugin } from 'bquery/store';\r\n *\r\n * // Add localStorage persistence\r\n * registerPlugin(({ store, options }) => {\r\n * const key = `bquery-store-${options.id}`;\r\n *\r\n * // Load saved state\r\n * const saved = localStorage.getItem(key);\r\n * if (saved) {\r\n * store.$patch(JSON.parse(saved));\r\n * }\r\n *\r\n * // Save on changes\r\n * store.$subscribe((state) => {\r\n * localStorage.setItem(key, JSON.stringify(state));\r\n * });\r\n * });\r\n * ```\r\n */\r\nexport const registerPlugin = (plugin: StorePlugin): void => {\r\n plugins.push(plugin);\r\n};\r\n\r\n// ============================================================================\r\n// Composition Helpers\r\n// ============================================================================\r\n\r\n/**\r\n * Creates a store with automatic persistence to localStorage.\r\n *\r\n * @param definition - Store definition\r\n * @param storageKey - Optional custom storage key\r\n * @returns The reactive store instance\r\n *\r\n * @example\r\n * ```ts\r\n * import { createPersistedStore } from 'bquery/store';\r\n *\r\n * const settings = createPersistedStore({\r\n * id: 'settings',\r\n * state: () => ({\r\n * theme: 'dark',\r\n * language: 'en',\r\n * }),\r\n * });\r\n *\r\n * // State is automatically saved/loaded from localStorage\r\n * settings.theme = 'light';\r\n * ```\r\n */\r\nexport const createPersistedStore = <\r\n S extends Record<string, unknown>,\r\n G extends Record<string, unknown> = Record<string, never>,\r\n A extends Record<string, (...args: unknown[]) => unknown> = Record<string, never>,\r\n>(\r\n definition: StoreDefinition<S, G, A>,\r\n storageKey?: string\r\n): Store<S, G, A> => {\r\n const key = storageKey ?? `bquery-store-${definition.id}`;\r\n\r\n // Wrap state factory to load from storage\r\n const originalStateFactory = definition.state;\r\n definition.state = () => {\r\n const defaultState = originalStateFactory();\r\n\r\n if (typeof window !== 'undefined') {\r\n try {\r\n const saved = localStorage.getItem(key);\r\n if (saved) {\r\n return { ...defaultState, ...JSON.parse(saved) };\r\n }\r\n } catch {\r\n // Ignore parse errors\r\n }\r\n }\r\n\r\n return defaultState;\r\n };\r\n\r\n const store = createStore(definition);\r\n\r\n // Subscribe to save changes\r\n store.$subscribe((state) => {\r\n if (typeof window !== 'undefined') {\r\n try {\r\n localStorage.setItem(key, JSON.stringify(state));\r\n } catch {\r\n // Ignore quota errors\r\n }\r\n }\r\n });\r\n\r\n return store;\r\n};\r\n\r\n/**\r\n * Maps store state properties to a reactive object for use in components.\r\n *\r\n * @param store - The store instance\r\n * @param keys - State keys to map\r\n * @returns Object with mapped properties\r\n *\r\n * @example\r\n * ```ts\r\n * import { mapState } from 'bquery/store';\r\n *\r\n * const counter = useCounter();\r\n * const { count, step } = mapState(counter, ['count', 'step']);\r\n * ```\r\n */\r\nexport const mapState = <S extends Record<string, unknown>, K extends keyof S>(\r\n store: S,\r\n keys: K[]\r\n): Pick<S, K> => {\r\n const mapped = {} as Pick<S, K>;\r\n\r\n for (const key of keys) {\r\n Object.defineProperty(mapped, key, {\r\n get: () => store[key],\r\n enumerable: true,\r\n });\r\n }\r\n\r\n return mapped;\r\n};\r\n\r\n/**\r\n * Maps store actions to an object for easier destructuring.\r\n *\r\n * @param store - The store instance\r\n * @param keys - Action keys to map\r\n * @returns Object with mapped actions\r\n *\r\n * @example\r\n * ```ts\r\n * import { mapActions } from 'bquery/store';\r\n *\r\n * const counter = useCounter();\r\n * const { increment, decrement } = mapActions(counter, ['increment', 'decrement']);\r\n *\r\n * // Use directly\r\n * increment();\r\n * ```\r\n */\r\nexport const mapActions = <\r\n A extends Record<string, (...args: unknown[]) => unknown>,\r\n K extends keyof A,\r\n>(\r\n store: A,\r\n keys: K[]\r\n): Pick<A, K> => {\r\n const mapped = {} as Pick<A, K>;\r\n\r\n for (const key of keys) {\r\n (mapped as Record<string, unknown>)[key as string] = (...args: unknown[]) =>\r\n (store[key] as (...args: unknown[]) => unknown)(...args);\r\n }\r\n\r\n return mapped;\r\n};\r\n"],"names":["storeRegistry","isPlainObject","value","deepClone","obj","k","v","cloned","key","deepEqual","a","b","item","i","keysA","keysB","detectNestedMutations","before","after","signalValues","mutatedKeys","beforeValue","afterValue","__DEV__","globalProcess","plugins","createStore","definition","id","stateFactory","getters","actions","initialState","stateSignals","signal","subscribers","notifySubscribers","currentState","getCurrentState","callback","stateProxy","_","prop","getterComputed","store","getterFn","computedGetter","computed","state","getterProxy","propKey","actionFn","args","context","target","_target","fresh","batch","sig","index","partial","stateBefore","signalValuesBefore","s","plugin","extension","getStore","listStores","destroyStore","registerPlugin","createPersistedStore","storageKey","originalStateFactory","defaultState","saved","mapState","keys","mapped","mapActions"],"mappings":"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"}