yuustate 0.0.1 → 3.9.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,519 @@
1
+ import { type InitStoreOptions, type SetStateInput } from "yuustate/vanilla";
2
+ import type { StoreKey } from "./create-stores.mjs";
3
+ /**
4
+ * Represents the state of a query.
5
+ *
6
+ * @remarks
7
+ * A query manages cached results of an async operation with lifecycle awareness.
8
+ *
9
+ * State variants:
10
+ * - `INITIAL` → no execution has occurred yet
11
+ * - `SUCCESS` → execution completed successfully
12
+ * - `ERROR` → initial execution failed (no data available)
13
+ * - `SUCCESS_BUT_REVALIDATION_ERROR` → data exists, but a revalidation failed
14
+ *
15
+ * Flags:
16
+ * - `isPending` → an execution is currently in progress
17
+ * - `isRevalidating` → re-executing while already having data
18
+ * - `isRetrying` → retrying after a failure
19
+ *
20
+ * @remarks
21
+ * - Data and error are mutually exclusive except in `SUCCESS_BUT_REVALIDATION_ERROR`.
22
+ */
23
+ export type QueryState<TData, TError> = {
24
+ isPending: boolean;
25
+ isRevalidating: boolean;
26
+ willRetryAt: undefined | number;
27
+ isRetrying: boolean;
28
+ retryCount: number;
29
+ } & ({
30
+ state: "INITIAL";
31
+ isSuccess: false;
32
+ isError: false;
33
+ data: undefined;
34
+ dataUpdatedAt: undefined;
35
+ dataStaleAt: undefined;
36
+ error: undefined;
37
+ errorUpdatedAt: undefined;
38
+ } | {
39
+ state: "SUCCESS";
40
+ isSuccess: true;
41
+ isError: false;
42
+ data: TData;
43
+ dataUpdatedAt: number;
44
+ dataStaleAt: undefined | number;
45
+ error: undefined;
46
+ errorUpdatedAt: undefined;
47
+ } | {
48
+ state: "ERROR";
49
+ isSuccess: false;
50
+ isError: true;
51
+ data: undefined;
52
+ dataUpdatedAt: undefined;
53
+ dataStaleAt: undefined;
54
+ error: TError;
55
+ errorUpdatedAt: number;
56
+ } | {
57
+ state: "SUCCESS_BUT_REVALIDATION_ERROR";
58
+ isSuccess: true;
59
+ isError: true;
60
+ data: TData;
61
+ dataUpdatedAt: number;
62
+ dataStaleAt: undefined | number;
63
+ error: TError;
64
+ errorUpdatedAt: number;
65
+ });
66
+ type Internal<TData, TError> = {
67
+ isInvalidated?: boolean;
68
+ promise?: Promise<QueryState<TData, TError>> | undefined;
69
+ promiseResolver?: ((value: QueryState<TData, TError> | PromiseLike<QueryState<TData, TError>>) => void) | undefined;
70
+ retryTimeoutId?: number;
71
+ retryResolver?: ((value: QueryState<TData, TError> | PromiseLike<QueryState<TData, TError>>) => void) | undefined;
72
+ garbageCollectionTimeoutId?: number;
73
+ rollbackData?: TData | undefined;
74
+ };
75
+ type AdditionalStoreApi<TData, TError> = {
76
+ /**
77
+ * A deterministic hash string derived from the query variable.
78
+ *
79
+ * Used as the unique identifier for this query instance in the internal cache.
80
+ *
81
+ * @remarks
82
+ * - Structurally identical variables will produce the same hash.
83
+ */
84
+ variableHash: string;
85
+ /**
86
+ * Sets initial data for the query if it has not been initialized.
87
+ *
88
+ * @param data - Initial data
89
+ * @param revalidate - Whether to mark the data as invalidated (will trigger revalidation)
90
+ *
91
+ * @returns `true` if the data was set, `false` otherwise
92
+ *
93
+ * @remarks
94
+ * - Only applies when the query is in the `INITIAL` state.
95
+ * - Useful for hydration or preloaded data.
96
+ */
97
+ setInitialData: (data: TData, revalidate?: boolean) => boolean;
98
+ /**
99
+ * Executes the query function.
100
+ *
101
+ * @param options - Execution options
102
+ * @param options.overwriteOngoingExecution - Whether to start a new execution instead of reusing an ongoing one (default: `true`)
103
+ *
104
+ * @returns A promise resolving to the latest query state
105
+ *
106
+ * @remarks
107
+ * - By default, each call **starts a new execution** even if one is already in progress.
108
+ * - Set `overwriteOngoingExecution: false` to reuse an ongoing execution (deduplication).
109
+ * - Handles:
110
+ * - Pending state
111
+ * - Success state
112
+ * - Error state
113
+ * - Retry logic
114
+ */
115
+ execute: (options?: {
116
+ overwriteOngoingExecution?: boolean;
117
+ }) => Promise<QueryState<TData, TError>>;
118
+ /**
119
+ * Re-executes the query if needed based on freshness or invalidation.
120
+ *
121
+ * @param options - Revalidation options
122
+ * @param options.overwriteOngoingExecution - Whether to overwrite an ongoing execution (default: `true`)
123
+ *
124
+ * @returns The current state if still fresh, otherwise a promise of the new state
125
+ *
126
+ * @remarks
127
+ * - Skips execution if data is still fresh (`staleTime`) **AND** the query has not been invalidated.
128
+ * - If execution is not skipped, by default it will start a new execution even if one is already in progress.
129
+ * - Set `overwriteOngoingExecution: false` to reuse an ongoing execution (deduplication).
130
+ */
131
+ revalidate: (options?: {
132
+ overwriteOngoingExecution?: boolean;
133
+ }) => Promise<QueryState<TData, TError>>;
134
+ /**
135
+ * Marks the query as invalidated and optionally triggers re-execution.
136
+ *
137
+ * @param options - Invalidation options
138
+ * @param options.overwriteOngoingExecution - Whether to overwrite an ongoing execution (default: `true`)
139
+ *
140
+ * @returns `true` if execution was triggered, `false` otherwise
141
+ *
142
+ * @remarks
143
+ * - Invalidated queries are treated as stale regardless of `staleTime`.
144
+ * - The next `revalidate` will always execute until a successful result clears the invalidation.
145
+ * - If there are active subscribers: Execution is triggered immediately.
146
+ * - Otherwise: The query remains invalidated and will execute on the next revalidation.
147
+ * - By default, starts a new execution even if one is already in progress.
148
+ * - Set `overwriteOngoingExecution: false` to reuse an ongoing execution (deduplication).
149
+ */
150
+ invalidate: (options?: {
151
+ overwriteOngoingExecution?: boolean;
152
+ }) => boolean;
153
+ /**
154
+ * Resets the query state to its initial state.
155
+ *
156
+ * @remarks
157
+ * - Cancels retry logic and ignores any ongoing execution results.
158
+ */
159
+ reset: () => void;
160
+ /**
161
+ * Deletes the query store for the current variable.
162
+ *
163
+ * @returns `true` if deleted, `false` otherwise
164
+ *
165
+ * @remarks
166
+ * - Cannot delete while there are active subscribers.
167
+ */
168
+ delete: () => boolean;
169
+ /**
170
+ * Performs an optimistic update on the query data.
171
+ *
172
+ * @param data - Optimistic data to set
173
+ *
174
+ * @returns Controls for managing the optimistic update
175
+ *
176
+ * @remarks
177
+ * - Temporarily replaces the current data.
178
+ * - Stores previous data for rollback.
179
+ * - Commonly used with mutations for instant UI updates.
180
+ *
181
+ * @example
182
+ * const { rollback, revalidate } = query.optimisticUpdate(newData);
183
+ */
184
+ optimisticUpdate: (data: TData) => {
185
+ revalidate: () => Promise<QueryState<TData, TError>>;
186
+ rollback: () => TData;
187
+ };
188
+ /**
189
+ * Restores the data before the last optimistic update.
190
+ *
191
+ * @returns The restored data
192
+ *
193
+ * @remarks
194
+ * - Should be used if an optimistic update fails.
195
+ */
196
+ rollbackOptimisticUpdate: () => TData;
197
+ /**
198
+ * Internal data, do not mutate!
199
+ */
200
+ internal: Readonly<Internal<TData, TError>>;
201
+ };
202
+ /**
203
+ * Configuration options for a query.
204
+ *
205
+ * @remarks
206
+ * Controls caching, retry behavior, lifecycle, and side effects of an async operation.
207
+ */
208
+ export type QueryOptions<TData, TVariable extends StoreKey, TError = Error> = InitStoreOptions<QueryState<TData, TError>, AdditionalStoreApi<TData, TError>> & {
209
+ /**
210
+ * Time (in milliseconds) that data is considered fresh.
211
+ *
212
+ * While fresh, revalidation will be skipped unless explicitly invalidated.
213
+ *
214
+ * @default 2500 ms (2.5 seconds)
215
+ */
216
+ staleTime?: number;
217
+ /**
218
+ * Time (in milliseconds) before unused queries are garbage collected.
219
+ *
220
+ * Starts counting after the last subscriber unsubscribes.
221
+ *
222
+ * @default 5 minutes
223
+ */
224
+ gcTime?: number;
225
+ /**
226
+ * Whether to revalidate when the window gains focus.
227
+ *
228
+ * @default true
229
+ */
230
+ revalidateOnFocus?: boolean;
231
+ /**
232
+ * Whether to revalidate when the network reconnects.
233
+ *
234
+ * @default true
235
+ */
236
+ revalidateOnReconnect?: boolean;
237
+ /**
238
+ * Called when the query succeeds.
239
+ */
240
+ onSuccess?: (data: TData, variable: TVariable, stateBeforeExecute: QueryState<TData, TError>) => void;
241
+ /**
242
+ * Called when the query fails and will not retry.
243
+ */
244
+ onError?: (error: TError, variable: TVariable, stateBeforeExecute: QueryState<TData, TError>) => void;
245
+ /**
246
+ * Called after the query settles (success or final failure).
247
+ */
248
+ onSettled?: (variable: TVariable, stateBeforeExecute: QueryState<TData, TError>) => void;
249
+ /**
250
+ * Determines whether a failed query should retry.
251
+ *
252
+ * @returns
253
+ * - `[true, delay]` to retry after `delay` milliseconds
254
+ * - `[false]` to stop retrying
255
+ *
256
+ * @default Retries once after 1500ms
257
+ *
258
+ * @example
259
+ * shouldRetry: (error, state) => {
260
+ * if (error?.status === 401 || error?.code === 'UNAUTHORIZED') return [false];
261
+ * if (state.retryCount < 3) return [true, 1000 * 2 ** state.retryCount];
262
+ * return [false];
263
+ * }
264
+ */
265
+ shouldRetry?: (error: TError, currentState: QueryState<TData, TError>) => [true, number] | [false];
266
+ };
267
+ /**
268
+ * Creates a query factory for managing cached async operations.
269
+ *
270
+ * @param queryFn - Async function to resolve data
271
+ * @param options - Optional configuration for caching, retry, and lifecycle
272
+ *
273
+ * @returns A function to retrieve or create a query instance by variable
274
+ *
275
+ * @remarks
276
+ * - Queries are **keyed by variable** (via deterministic hashing).
277
+ * - Each unique variable maps to its own store instance.
278
+ *
279
+ * Core features:
280
+ * - Caching via `staleTime`
281
+ * - Explicit invalidation (independent of freshness)
282
+ * - Retry logic via `shouldRetry`
283
+ * - Background revalidation (focus / reconnect)
284
+ * - Garbage collection via `gcTime`
285
+ *
286
+ * Execution behavior:
287
+ * - By default, executions **overwrite ongoing executions**
288
+ * - Set `overwriteOngoingExecution: false` to enable deduplication
289
+ * - Internal revalidation (focus/reconnect) uses deduplication by default
290
+ *
291
+ * @example
292
+ * const userQuery = createQuery<UserDetail, { id: string }>(async ({ id }) => {
293
+ * return api.getUser(id);
294
+ * });
295
+ *
296
+ * function MyComponent({ id }: { id: string }) {
297
+ * const useUserQuery = userQuery({ id });
298
+ * const state = useUserQuery();
299
+ * // ...
300
+ * }
301
+ *
302
+ * @see https://yuustate.vercel.app/docs/query
303
+ */
304
+ export declare const createQuery: <TData, TVariable extends StoreKey = never, TError = Error>(queryFn: (variable: TVariable, currentState: QueryState<TData, TError>, variableHash: string) => Promise<TData>, options?: QueryOptions<TData, TVariable, TError>) => ((variable?: TVariable) => ((options?: {
305
+ /**
306
+ * Whether the query should be ravalidated automatically on mount.
307
+ *
308
+ * Revalidate means execute the queryFn **if stale/invalidated**.
309
+ *
310
+ * @default true
311
+ */
312
+ revalidateOnMount?: boolean;
313
+ /**
314
+ * Whether to keep previous successful data while a new variable is loading.
315
+ *
316
+ * @remarks
317
+ * - Only applies when the query is in the `INITIAL` state (no data & no error).
318
+ * - Intended for variable changes:
319
+ * when switching from one variable to another, the previous data is temporarily shown
320
+ * while the new execution is in progress.
321
+ * - Once the new execution resolves (success or error), the previous data is no longer used.
322
+ * - Prevents UI flicker (e.g. empty/loading state) during transitions.
323
+ *
324
+ * @example
325
+ * // Switching from userId=1 → userId=2
326
+ * // While loading userId=2, still show userId=1 data
327
+ * useQuery({ id: userId }, { keepPreviousData: true });
328
+ */ keepPreviousData?: boolean;
329
+ } & ({
330
+ /**
331
+ * Initial data used on first render (and will also update the store state right after that)
332
+ *
333
+ * If provided, `initialData` will be applied **once per query-store instance**
334
+ */
335
+ initialData: TData;
336
+ /**
337
+ * Whether the provided `initialData` should be treated as stale.
338
+ *
339
+ * @remarks
340
+ * - If `true`, a revalidation (refetch) will be triggered immediately.
341
+ * - If `false` (default), `initialData` is treated as fresh and will not be revalidated.
342
+ *
343
+ * @default false
344
+ *
345
+ * @example
346
+ * useQuery({
347
+ * initialData: dataFromSSR,
348
+ * initialDataIsStale: true, // force refetch
349
+ * });
350
+ */
351
+ initialDataIsStale?: boolean;
352
+ } | {
353
+ initialData?: never;
354
+ initialDataIsStale?: never;
355
+ })) => QueryState<TData, TError>) & {
356
+ setState: (value: SetStateInput<QueryState<TData, TError>>) => void;
357
+ getState: () => QueryState<TData, TError>;
358
+ subscribe: (subscriber: import("../vanilla.d.mts").Subscriber<QueryState<TData, TError>>) => () => void;
359
+ getSubscriberCount: () => number;
360
+ /**
361
+ * A deterministic hash string derived from the query variable.
362
+ *
363
+ * Used as the unique identifier for this query instance in the internal cache.
364
+ *
365
+ * @remarks
366
+ * - Structurally identical variables will produce the same hash.
367
+ */
368
+ variableHash: string;
369
+ /**
370
+ * Sets initial data for the query if it has not been initialized.
371
+ *
372
+ * @param data - Initial data
373
+ * @param revalidate - Whether to mark the data as invalidated (will trigger revalidation)
374
+ *
375
+ * @returns `true` if the data was set, `false` otherwise
376
+ *
377
+ * @remarks
378
+ * - Only applies when the query is in the `INITIAL` state.
379
+ * - Useful for hydration or preloaded data.
380
+ */
381
+ setInitialData: (data: TData, revalidate?: boolean) => boolean;
382
+ /**
383
+ * Executes the query function.
384
+ *
385
+ * @param options - Execution options
386
+ * @param options.overwriteOngoingExecution - Whether to start a new execution instead of reusing an ongoing one (default: `true`)
387
+ *
388
+ * @returns A promise resolving to the latest query state
389
+ *
390
+ * @remarks
391
+ * - By default, each call **starts a new execution** even if one is already in progress.
392
+ * - Set `overwriteOngoingExecution: false` to reuse an ongoing execution (deduplication).
393
+ * - Handles:
394
+ * - Pending state
395
+ * - Success state
396
+ * - Error state
397
+ * - Retry logic
398
+ */
399
+ execute: (options?: {
400
+ overwriteOngoingExecution?: boolean;
401
+ }) => Promise<QueryState<TData, TError>>;
402
+ /**
403
+ * Re-executes the query if needed based on freshness or invalidation.
404
+ *
405
+ * @param options - Revalidation options
406
+ * @param options.overwriteOngoingExecution - Whether to overwrite an ongoing execution (default: `true`)
407
+ *
408
+ * @returns The current state if still fresh, otherwise a promise of the new state
409
+ *
410
+ * @remarks
411
+ * - Skips execution if data is still fresh (`staleTime`) **AND** the query has not been invalidated.
412
+ * - If execution is not skipped, by default it will start a new execution even if one is already in progress.
413
+ * - Set `overwriteOngoingExecution: false` to reuse an ongoing execution (deduplication).
414
+ */
415
+ revalidate: (options?: {
416
+ overwriteOngoingExecution?: boolean;
417
+ }) => Promise<QueryState<TData, TError>>;
418
+ /**
419
+ * Marks the query as invalidated and optionally triggers re-execution.
420
+ *
421
+ * @param options - Invalidation options
422
+ * @param options.overwriteOngoingExecution - Whether to overwrite an ongoing execution (default: `true`)
423
+ *
424
+ * @returns `true` if execution was triggered, `false` otherwise
425
+ *
426
+ * @remarks
427
+ * - Invalidated queries are treated as stale regardless of `staleTime`.
428
+ * - The next `revalidate` will always execute until a successful result clears the invalidation.
429
+ * - If there are active subscribers: Execution is triggered immediately.
430
+ * - Otherwise: The query remains invalidated and will execute on the next revalidation.
431
+ * - By default, starts a new execution even if one is already in progress.
432
+ * - Set `overwriteOngoingExecution: false` to reuse an ongoing execution (deduplication).
433
+ */
434
+ invalidate: (options?: {
435
+ overwriteOngoingExecution?: boolean;
436
+ }) => boolean;
437
+ /**
438
+ * Resets the query state to its initial state.
439
+ *
440
+ * @remarks
441
+ * - Cancels retry logic and ignores any ongoing execution results.
442
+ */
443
+ reset: () => void;
444
+ /**
445
+ * Deletes the query store for the current variable.
446
+ *
447
+ * @returns `true` if deleted, `false` otherwise
448
+ *
449
+ * @remarks
450
+ * - Cannot delete while there are active subscribers.
451
+ */
452
+ delete: () => boolean;
453
+ /**
454
+ * Performs an optimistic update on the query data.
455
+ *
456
+ * @param data - Optimistic data to set
457
+ *
458
+ * @returns Controls for managing the optimistic update
459
+ *
460
+ * @remarks
461
+ * - Temporarily replaces the current data.
462
+ * - Stores previous data for rollback.
463
+ * - Commonly used with mutations for instant UI updates.
464
+ *
465
+ * @example
466
+ * const { rollback, revalidate } = query.optimisticUpdate(newData);
467
+ */
468
+ optimisticUpdate: (data: TData) => {
469
+ revalidate: () => Promise<QueryState<TData, TError>>;
470
+ rollback: () => TData;
471
+ };
472
+ /**
473
+ * Restores the data before the last optimistic update.
474
+ *
475
+ * @returns The restored data
476
+ *
477
+ * @remarks
478
+ * - Should be used if an optimistic update fails.
479
+ */
480
+ rollbackOptimisticUpdate: () => TData;
481
+ /**
482
+ * Internal data, do not mutate!
483
+ */
484
+ internal: Readonly<Internal<TData, TError>>;
485
+ }) & {
486
+ /**
487
+ * Executes all query instances.
488
+ *
489
+ * @remarks
490
+ * - Useful for bulk refetching.
491
+ */
492
+ executeAll: (options?: {
493
+ overwriteOngoingExecution?: boolean;
494
+ }) => void;
495
+ /**
496
+ * Revalidates all query instances.
497
+ *
498
+ * @remarks
499
+ * - Only re-fetches stale queries.
500
+ */
501
+ revalidateAll: (options?: {
502
+ overwriteOngoingExecution?: boolean;
503
+ }) => void;
504
+ /**
505
+ * Invalidates all query instances.
506
+ *
507
+ * @remarks
508
+ * - Marks all queries as invalidated and triggers revalidation if active.
509
+ * - Invalidated queries bypass `staleTime` until successfully executed again.
510
+ */
511
+ invalidateAll: (options?: {
512
+ overwriteOngoingExecution?: boolean;
513
+ }) => void;
514
+ /**
515
+ * Resets all query instances.
516
+ */
517
+ resetAll: () => void;
518
+ };
519
+ export {};
@@ -0,0 +1,35 @@
1
+ import { type InitStoreOptions } from "yuustate/vanilla";
2
+ /**
3
+ * Creates a single store with a bound React hook.
4
+ *
5
+ * @param initialState - The initial state of the store
6
+ * @param options - Optional lifecycle hooks
7
+ *
8
+ * @returns A function that acts as both:
9
+ * - A React hook for subscribing to the store
10
+ * - The store API (getState, setState, subscribe, etc.)
11
+ *
12
+ * @remarks
13
+ * - Combines the vanilla store with React integration.
14
+ * - The returned function can be used directly as a hook.
15
+ * - The hook uses Proxy-based tracking to automatically detect which state fields are used.
16
+ * - Components will only re-render when the accessed values change.
17
+ *
18
+ * @example
19
+ * const useMyStore = createStore({ foo: 1, bar: 2 });
20
+ *
21
+ * function Component() {
22
+ * const state = useMyStore();
23
+ * return <div>{state.foo}</div>;
24
+ * }
25
+ *
26
+ * useMyStore.setState({ foo: 2 }); // only components using foo will re-render
27
+ *
28
+ * @see https://yuustate.vercel.app/docs/store
29
+ */
30
+ export declare const createStore: <TState extends Record<string, any>>(initialState: TState, options?: InitStoreOptions<TState>) => ((options?: {
31
+ /**
32
+ * Initial state used on first render (and will also update the store state right after that)
33
+ */
34
+ initialState?: Partial<TState>;
35
+ }) => TState) & import("../vanilla.d.mts").StoreApi<TState>;
@@ -0,0 +1,76 @@
1
+ import { type InitStoreOptions, type StoreApi } from "yuustate/vanilla";
2
+ type GoodInputForHash = string | number | boolean | null | Date;
3
+ export type StoreKey = GoodInputForHash | {
4
+ [key: string | number]: StoreKey | StoreKey[];
5
+ };
6
+ type AdditionalStoreApi<TKey> = {
7
+ /**
8
+ * The original key used to identify this store instance.\
9
+ * This value is not hashed and is preserved as-is.
10
+ */
11
+ key: TKey;
12
+ /**
13
+ * A deterministic hash string derived from {@link key}.
14
+ *
15
+ * Used internally as the unique identifier for caching and retrieving store instances.
16
+ *
17
+ * @remarks
18
+ * - Guarantees that structurally identical keys produce the same hash.
19
+ */
20
+ keyHash: string;
21
+ /**
22
+ * Deletes this store instance from the internal cache.
23
+ *
24
+ * @returns `true` if the store was successfully deleted, otherwise `false`.
25
+ *
26
+ * @remarks
27
+ * - If there are active subscribers, the deletion is ignored and `false` is returned.
28
+ * - When deletion succeeds:
29
+ * - The store is removed from the cache.
30
+ * - Its state is reset to the initial state.
31
+ * - Intended for manual cleanup of unused or ephemeral stores.
32
+ */
33
+ delete: () => boolean;
34
+ };
35
+ /**
36
+ * Creates a factory for multiple stores identified by a key.
37
+ *
38
+ * @param initialState - The initial state for each store instance
39
+ * @param options - Optional lifecycle hooks
40
+ *
41
+ * @returns A function to retrieve or create a store by key
42
+ *
43
+ * @remarks
44
+ * - Each unique key maps to a separate store instance.
45
+ * - Keys are deterministically hashed, ensuring stable identity.
46
+ * - Stores are lazily created and cached.
47
+ * - Each store has its own state, subscribers, and lifecycle.
48
+ * - Each returned store includes:
49
+ * - React hook (with Proxy-based tracking)
50
+ * - Store API methods
51
+ * - `delete()` for manual cleanup
52
+ * - Useful for scenarios like:
53
+ * - Query caches
54
+ * - Entity-based state
55
+ * - Dynamic instances
56
+ *
57
+ * @example
58
+ * const userStore = createStores<{ name: string }, { id: number }>({ name: '' });
59
+ *
60
+ * function Component() {
61
+ * const useUserStore = userStore({ id: 1 });
62
+ * const state = useUserStore();
63
+ * return <div>{state.name}</div>;
64
+ * }
65
+ *
66
+ * @see https://yuustate.vercel.app/docs/stores
67
+ */
68
+ export declare const createStores: <TState extends Record<string, any>, TKey extends StoreKey>(initialState: TState, options?: InitStoreOptions<TState, AdditionalStoreApi<TKey>>) => (key?: TKey) => ((options?: {
69
+ /**
70
+ * Initial state used on first render (and will also update the store state right after that)
71
+ *
72
+ * If provided, `initialState` will be applied **once per store instance**
73
+ */
74
+ initialState?: Partial<TState>;
75
+ }) => TState) & StoreApi<TState> & AdditionalStoreApi<TKey>;
76
+ export {};