floppy-disk 2.16.0 → 3.0.0-alpha.2

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 (75) hide show
  1. package/README.md +0 -835
  2. package/esm/index.d.mts +1 -0
  3. package/esm/index.mjs +1 -0
  4. package/esm/react/create-mutation.d.mts +135 -0
  5. package/esm/react/create-query.d.mts +319 -0
  6. package/esm/react/create-store.d.mts +25 -0
  7. package/esm/react/create-stores.d.mts +32 -0
  8. package/esm/react/use-isomorphic-layout-effect.d.mts +6 -0
  9. package/esm/react/use-store.d.mts +18 -0
  10. package/esm/react.d.mts +6 -0
  11. package/esm/react.mjs +503 -0
  12. package/esm/vanilla/basic.d.mts +21 -0
  13. package/esm/vanilla/hash.d.mts +7 -0
  14. package/esm/vanilla/shallow.d.mts +6 -0
  15. package/esm/vanilla/store.d.mts +75 -0
  16. package/esm/vanilla.d.mts +4 -0
  17. package/esm/vanilla.mjs +109 -0
  18. package/index.d.ts +1 -0
  19. package/index.js +12 -0
  20. package/package.json +50 -45
  21. package/react/create-mutation.d.ts +135 -0
  22. package/react/create-query.d.ts +319 -0
  23. package/react/create-store.d.ts +25 -0
  24. package/react/create-stores.d.ts +32 -0
  25. package/react/use-isomorphic-layout-effect.d.ts +6 -0
  26. package/react/use-store.d.ts +18 -0
  27. package/{lib/index.d.ts → react.d.ts} +2 -4
  28. package/react.js +511 -0
  29. package/ts_version_4.5_and_above_is_required.d.ts +0 -0
  30. package/vanilla/basic.d.ts +21 -0
  31. package/vanilla/hash.d.ts +7 -0
  32. package/vanilla/shallow.d.ts +6 -0
  33. package/vanilla/store.d.ts +75 -0
  34. package/vanilla.d.ts +4 -0
  35. package/vanilla.js +118 -0
  36. package/esm/fetcher.d.ts +0 -27
  37. package/esm/fetcher.js +0 -95
  38. package/esm/index.d.ts +0 -8
  39. package/esm/index.js +0 -8
  40. package/esm/react/create-bi-direction-query.d.ts +0 -166
  41. package/esm/react/create-bi-direction-query.js +0 -74
  42. package/esm/react/create-mutation.d.ts +0 -39
  43. package/esm/react/create-mutation.js +0 -56
  44. package/esm/react/create-query.d.ts +0 -319
  45. package/esm/react/create-query.js +0 -434
  46. package/esm/react/create-store.d.ts +0 -51
  47. package/esm/react/create-store.js +0 -38
  48. package/esm/react/create-stores.d.ts +0 -77
  49. package/esm/react/create-stores.js +0 -125
  50. package/esm/react/with-context.d.ts +0 -5
  51. package/esm/react/with-context.js +0 -14
  52. package/esm/store.d.ts +0 -24
  53. package/esm/store.js +0 -51
  54. package/esm/utils.d.ts +0 -24
  55. package/esm/utils.js +0 -31
  56. package/lib/fetcher.d.ts +0 -27
  57. package/lib/fetcher.js +0 -99
  58. package/lib/index.js +0 -11
  59. package/lib/react/create-bi-direction-query.d.ts +0 -166
  60. package/lib/react/create-bi-direction-query.js +0 -78
  61. package/lib/react/create-mutation.d.ts +0 -39
  62. package/lib/react/create-mutation.js +0 -60
  63. package/lib/react/create-query.d.ts +0 -319
  64. package/lib/react/create-query.js +0 -438
  65. package/lib/react/create-store.d.ts +0 -51
  66. package/lib/react/create-store.js +0 -42
  67. package/lib/react/create-stores.d.ts +0 -77
  68. package/lib/react/create-stores.js +0 -130
  69. package/lib/react/with-context.d.ts +0 -5
  70. package/lib/react/with-context.js +0 -18
  71. package/lib/store.d.ts +0 -24
  72. package/lib/store.js +0 -55
  73. package/lib/utils.d.ts +0 -24
  74. package/lib/utils.js +0 -39
  75. package/utils/package.json +0 -6
@@ -0,0 +1 @@
1
+ export * from 'floppy-disk/vanilla';
package/esm/index.mjs ADDED
@@ -0,0 +1 @@
1
+ export * from 'floppy-disk/vanilla';
@@ -0,0 +1,135 @@
1
+ import { type InitStoreOptions, type SetState } from 'floppy-disk/vanilla';
2
+ /**
3
+ * Represents the state of a mutation.
4
+ *
5
+ * @remarks
6
+ * A mutation does not cache results and only tracks the latest execution.
7
+ *
8
+ * The state transitions are:
9
+ * - `INITIAL` → before any execution
10
+ * - `SUCCESS` → when mutation resolves successfully
11
+ * - `ERROR` → when mutation fails
12
+ *
13
+ * Unlike queries:
14
+ * - No retry mechanism
15
+ * - No caching across executions
16
+ */
17
+ export type MutationState<TData, TVariable> = {
18
+ isPending: boolean;
19
+ } & ({
20
+ state: 'INITIAL';
21
+ isSuccess: false;
22
+ isError: false;
23
+ variable: undefined;
24
+ data: undefined;
25
+ dataUpdatedAt: undefined;
26
+ error: undefined;
27
+ errorUpdatedAt: undefined;
28
+ } | {
29
+ state: 'SUCCESS';
30
+ isSuccess: true;
31
+ isError: false;
32
+ variable: TVariable;
33
+ data: TData;
34
+ dataUpdatedAt: number;
35
+ error: undefined;
36
+ errorUpdatedAt: undefined;
37
+ } | {
38
+ state: 'ERROR';
39
+ isSuccess: false;
40
+ isError: true;
41
+ variable: TVariable;
42
+ data: undefined;
43
+ dataUpdatedAt: undefined;
44
+ error: any;
45
+ errorUpdatedAt: number;
46
+ });
47
+ /**
48
+ * Configuration options for a mutation.
49
+ *
50
+ * @remarks
51
+ * Lifecycle callbacks are triggered for each execution.
52
+ */
53
+ export type MutationOptions<TData, TVariable> = InitStoreOptions<MutationState<TData, TVariable>> & {
54
+ /**
55
+ * Called when the mutation succeeds.
56
+ */
57
+ onSuccess?: (data: TData, variable: TVariable, stateBeforeExecute: MutationState<TData, TVariable>) => void;
58
+ /**
59
+ * Called when the mutation fails.
60
+ */
61
+ onError?: (error: any, variable: TVariable, stateBeforeExecute: MutationState<TData, TVariable>) => void;
62
+ /**
63
+ * Called after the mutation settles (either success or error).
64
+ */
65
+ onSettled?: (variable: TVariable, stateBeforeExecute: MutationState<TData, TVariable>) => void;
66
+ };
67
+ /**
68
+ * Creates a mutation store for handling async operations that modify data.
69
+ *
70
+ * @param mutationFn - Async function that performs the mutation
71
+ * @param options - Optional configuration and lifecycle callbacks
72
+ *
73
+ * @returns A function that acts as both:
74
+ * - A React hook for subscribing to mutation state
75
+ * - A mutation controller (execute, reset, etc.)
76
+ *
77
+ * @remarks
78
+ * - Mutations are **not cached** and only track the latest execution.
79
+ * - Designed for operations that change data (e.g. create, update, delete).
80
+ * - No retry mechanism is provided by default.
81
+ * - Each execution overwrites the previous state.
82
+ * - The mutation always resolves (never throws): the result contains either `data` or `error`.
83
+ *
84
+ * @example
85
+ * const useCreateUser = createMutation(async (input) => {
86
+ * return api.createUser(input);
87
+ * });
88
+ *
89
+ * const { isPending } = useCreateUser();
90
+ * const result = await useCreateUser.execute({ name: 'John' });
91
+ */
92
+ export declare const createMutation: <TData, TVariable = undefined>(mutationFn: (variable: TVariable, stateBeforeExecute: MutationState<TData, TVariable>) => Promise<TData>, options?: MutationOptions<TData, TVariable>) => (<TStateSlice = MutationState<TData, TVariable>>(selector?: (state: MutationState<TData, TVariable>) => TStateSlice) => TStateSlice) & {
93
+ subscribe: (subscriber: import("../vanilla.d.mts").Subscriber<MutationState<TData, TVariable>>) => () => void;
94
+ getSubscribers: () => Set<import("../vanilla.d.mts").Subscriber<MutationState<TData, TVariable>>>;
95
+ getState: () => MutationState<TData, TVariable>;
96
+ /**
97
+ * Manually updates the mutation state.
98
+ *
99
+ * @remarks
100
+ * - Intended for advanced use cases.
101
+ * - Prefer using provided mutation actions (`execute`, `reset`) instead.
102
+ */
103
+ setState: (value: SetState<MutationState<TData, TVariable>>) => void;
104
+ /**
105
+ * Executes the mutation.
106
+ *
107
+ * @param variable - Input passed to the mutation function
108
+ *
109
+ * @returns A promise that always resolves with:
110
+ * - `{ data, variable }` on success
111
+ * - `{ error, variable }` on failure
112
+ *
113
+ * @remarks
114
+ * - If a mutation is already in progress, a warning is logged.
115
+ * - Concurrent executions are allowed but may lead to race conditions.
116
+ * - The promise never rejects to simplify async handling.
117
+ */
118
+ execute: TVariable extends undefined ? () => Promise<{
119
+ variable: undefined;
120
+ data?: TData;
121
+ error?: any;
122
+ }> : (variable: TVariable) => Promise<{
123
+ variable: TVariable;
124
+ data?: TData;
125
+ error?: any;
126
+ }>;
127
+ /**
128
+ * Resets the mutation state back to its initial state.
129
+ *
130
+ * @remarks
131
+ * - Does not cancel any ongoing request.
132
+ * - If a request is still pending, its result may override the reset state.
133
+ */
134
+ reset: () => void;
135
+ };
@@ -0,0 +1,319 @@
1
+ import { type InitStoreOptions, type SetState } from 'floppy-disk/vanilla';
2
+ /**
3
+ * Represents the state of a query.
4
+ *
5
+ * @remarks
6
+ * A query manages cached results of an async operation with lifecycle awareness.
7
+ *
8
+ * State variants:
9
+ * - `INITIAL` → no execution has occurred yet
10
+ * - `SUCCESS` → execution completed successfully
11
+ * - `ERROR` → initial execution failed (no data available)
12
+ * - `SUCCESS_BUT_REVALIDATION_ERROR` → data exists, but a revalidation failed
13
+ *
14
+ * Flags:
15
+ * - `isPending` → an execution is currently in progress
16
+ * - `isRevalidating` → re-executing while already having data
17
+ * - `isRetrying` → retrying after a failure
18
+ *
19
+ * @remarks
20
+ * - Data and error are mutually exclusive except in `SUCCESS_BUT_REVALIDATION_ERROR`.
21
+ */
22
+ export type QueryState<TData> = {
23
+ isPending: boolean;
24
+ isRevalidating: boolean;
25
+ isRetrying: boolean;
26
+ retryCount: number;
27
+ } & ({
28
+ state: 'INITIAL';
29
+ isSuccess: false;
30
+ isError: false;
31
+ data: undefined;
32
+ dataUpdatedAt: undefined;
33
+ error: undefined;
34
+ errorUpdatedAt: undefined;
35
+ } | {
36
+ state: 'SUCCESS';
37
+ isSuccess: true;
38
+ isError: false;
39
+ data: TData;
40
+ dataUpdatedAt: number;
41
+ error: undefined;
42
+ errorUpdatedAt: undefined;
43
+ } | {
44
+ state: 'ERROR';
45
+ isSuccess: false;
46
+ isError: true;
47
+ data: undefined;
48
+ dataUpdatedAt: undefined;
49
+ error: any;
50
+ errorUpdatedAt: number;
51
+ } | {
52
+ state: 'SUCCESS_BUT_REVALIDATION_ERROR';
53
+ isSuccess: true;
54
+ isError: false;
55
+ data: TData;
56
+ dataUpdatedAt: number;
57
+ error: any;
58
+ errorUpdatedAt: number;
59
+ });
60
+ /**
61
+ * Configuration options for a query.
62
+ *
63
+ * @remarks
64
+ * Controls caching, retry behavior, lifecycle, and side effects of an async operation.
65
+ */
66
+ export type QueryOptions<TData, TVariable extends Record<string, any>> = InitStoreOptions<QueryState<TData>> & {
67
+ /**
68
+ * Time (in milliseconds) that data is considered fresh.
69
+ *
70
+ * While fresh, revalidation will be skipped.
71
+ *
72
+ * @default 2500 ms (2.5 minutes)
73
+ */
74
+ staleTime?: number;
75
+ /**
76
+ * Time (in milliseconds) before unused queries are garbage collected.
77
+ *
78
+ * Starts counting after the last subscriber unsubscribes.
79
+ *
80
+ * @default 5 minutes
81
+ */
82
+ gcTime?: number;
83
+ /**
84
+ * Whether to revalidate when the window gains focus.
85
+ *
86
+ * @default true
87
+ */
88
+ revalidateOnFocus?: boolean;
89
+ /**
90
+ * Whether to revalidate when the network reconnects.
91
+ *
92
+ * @default true
93
+ */
94
+ revalidateOnReconnect?: boolean;
95
+ /**
96
+ * Called when the query succeeds.
97
+ */
98
+ onSuccess?: (data: TData, variable: TVariable, stateBeforeExecute: QueryState<TData>) => void;
99
+ /**
100
+ * Called when the query fails and will not retry.
101
+ */
102
+ onError?: (error: any, variable: TVariable, stateBeforeExecute: QueryState<TData>) => void;
103
+ /**
104
+ * Called after the query settles (success or final failure).
105
+ */
106
+ onSettled?: (variable: TVariable, stateBeforeExecute: QueryState<TData>) => void;
107
+ /**
108
+ * Determines whether a failed query should retry.
109
+ *
110
+ * @returns
111
+ * - `[true, delay]` to retry after `delay` milliseconds
112
+ * - `[false]` to stop retrying
113
+ *
114
+ * @default Retries once after 1500ms
115
+ *
116
+ * @example
117
+ * shouldRetry: (error, state) => {
118
+ * if (error?.status === 401 || error?.code === 'UNAUTHORIZED') return [false];
119
+ * if (state.retryCount < 3) return [true, 1000 * 2 ** state.retryCount];
120
+ * return [false];
121
+ * }
122
+ */
123
+ shouldRetry?: (error: any, currentState: QueryState<TData>) => [true, number] | [false];
124
+ };
125
+ /**
126
+ * Creates a query factory for managing cached async operations.
127
+ *
128
+ * @param queryFn - Async function to resolve data
129
+ * @param options - Optional configuration for caching, retry, and lifecycle
130
+ *
131
+ * @returns A function to retrieve or create a query instance by variable
132
+ *
133
+ * @remarks
134
+ * - Queries are cached by a deterministic key derived from `variable`.
135
+ * - Each unique variable maps to its own store instance.
136
+ * - Queries support:
137
+ * - Caching with `staleTime`
138
+ * - Explicit invalidation independent of freshness
139
+ * - Automatic garbage collection (`gcTime`)
140
+ * - Retry logic via `shouldRetry`
141
+ * - Background revalidation (focus / reconnect)
142
+ * - Execution is deduplicated: multiple calls share the same in-flight promise.
143
+ * - Ongoing executions can be optionally overwritten.
144
+ *
145
+ * @example
146
+ * const userQuery = createQuery<UserDetail, { id: string }>(async ({ id }) => {
147
+ * return api.getUser(id);
148
+ * });
149
+ *
150
+ * function MyComponent({ id }: { id: string }) {
151
+ * const useUserQuery = userQuery({ id });
152
+ * const state = useUserQuery();
153
+ * // ...
154
+ * }
155
+ */
156
+ export declare const createQuery: <TData, TVariable extends Record<string, any> = never>(queryFn: (variable: TVariable, currentState: QueryState<TData>) => Promise<TData>, options?: QueryOptions<TData, TVariable>) => ((variable?: TVariable) => (<TStateSlice = QueryState<TData>>(options?: {
157
+ /**
158
+ * Whether the query should execute automatically on mount.
159
+ *
160
+ * @default true
161
+ */
162
+ enabled?: boolean;
163
+ /**
164
+ * Whether to keep previous successful data while a new variable is loading.
165
+ *
166
+ * @remarks
167
+ * - Only applies when the query is in the `INITIAL` state (no data & no error).
168
+ * - Intended for variable changes:
169
+ * when switching from one variable to another, the previous data is temporarily shown
170
+ * while the new execution is in progress.
171
+ * - Once the new execution resolves (success or error), the previous data is no longer used.
172
+ * - Prevents UI flicker (e.g. empty/loading state) during transitions.
173
+ *
174
+ * @example
175
+ * // Switching from userId=1 → userId=2
176
+ * // While loading userId=2, still show userId=1 data
177
+ * useQuery({ id: userId }, { keepPreviousData: true });
178
+ */ keepPreviousData?: boolean;
179
+ }, selector?: (state: QueryState<TData>) => TStateSlice) => TStateSlice) & {
180
+ metadata: {
181
+ isInvalidated?: boolean;
182
+ promise?: Promise<QueryState<TData>> | undefined;
183
+ promiseResolver?: ((value: QueryState<TData> | PromiseLike<QueryState<TData>>) => void) | undefined;
184
+ retryTimeoutId?: number;
185
+ retryResolver?: ((value: QueryState<TData> | PromiseLike<QueryState<TData>>) => void) | undefined;
186
+ garbageCollectionTimeoutId?: number;
187
+ rollbackData?: TData | undefined;
188
+ };
189
+ /**
190
+ * Sets initial data for the query if it has not been initialized.
191
+ *
192
+ * @param data - Initial data
193
+ * @param revalidate - Whether to mark the data as invalidated (will trigger revalidation)
194
+ *
195
+ * @returns `true` if the data was set, `false` otherwise
196
+ *
197
+ * @remarks
198
+ * - Only applies when the query is in the `INITIAL` state.
199
+ * - Useful for hydration or preloaded data.
200
+ */
201
+ setInitialData: (data: TData, revalidate?: boolean) => boolean;
202
+ /**
203
+ * Executes the query function.
204
+ *
205
+ * @param overwriteOngoingExecution - Whether to start a new execution instead of reusing an ongoing one
206
+ *
207
+ * @returns A promise resolving to the latest query state
208
+ *
209
+ * @remarks
210
+ * - Deduplicates concurrent executions by default.
211
+ * - If `overwriteOngoingExecution` is true, a new execution replaces the current one.
212
+ * - Handles:
213
+ * - Pending state
214
+ * - Success state
215
+ * - Error state
216
+ * - Retry logic
217
+ */
218
+ execute: (overwriteOngoingExecution?: boolean) => Promise<QueryState<TData>>;
219
+ /**
220
+ * Re-executes the query if the data is stale.
221
+ *
222
+ * @param overwriteOngoingExecution - Whether to overwrite an ongoing execution
223
+ *
224
+ * @returns The current state if still fresh, otherwise a promise of the new state
225
+ *
226
+ * @remarks
227
+ * - Skips execution if data is still fresh (`staleTime`) and the query has not been invalidated.
228
+ * - Used for automatic revalidation (e.g. focus or reconnect).
229
+ */
230
+ revalidate: (overwriteOngoingExecution?: boolean) => Promise<QueryState<TData>>;
231
+ /**
232
+ * Marks the query as invalidated and optionally triggers re-execution.
233
+ *
234
+ * @param overwriteOngoingExecution - Whether to overwrite an ongoing execution
235
+ *
236
+ * @returns `true` if execution was triggered, `false` otherwise
237
+ *
238
+ * @remarks
239
+ * - Invalidated queries are treated as stale regardless of `staleTime`.
240
+ * - The next `revalidate` will always execute until a successful result clears the invalidation.
241
+ * - If there are active subscribers, execution will be triggered immediately.
242
+ */
243
+ invalidate: (overwriteOngoingExecution?: boolean) => boolean;
244
+ /**
245
+ * Resets the query state to its initial state.
246
+ *
247
+ * @remarks
248
+ * - Cancels retry logic and ignores any ongoing execution results.
249
+ */
250
+ reset: () => void;
251
+ /**
252
+ * Deletes the query store for the current variable.
253
+ *
254
+ * @returns `true` if deleted, `false` otherwise
255
+ *
256
+ * @remarks
257
+ * - Cannot delete while there are active subscribers.
258
+ */
259
+ delete: () => boolean;
260
+ /**
261
+ * Performs an optimistic update on the query data.
262
+ *
263
+ * @param data - Optimistic data to set
264
+ *
265
+ * @returns Controls for managing the optimistic update
266
+ *
267
+ * @remarks
268
+ * - Temporarily replaces the current data.
269
+ * - Stores previous data for rollback.
270
+ * - Commonly used with mutations for instant UI updates.
271
+ *
272
+ * @example
273
+ * const { rollback, revalidate } = query.optimisticUpdate(newData);
274
+ */
275
+ optimisticUpdate: (data: TData) => {
276
+ revalidate: () => Promise<QueryState<TData>>;
277
+ rollback: () => TData;
278
+ };
279
+ /**
280
+ * Restores the data before the last optimistic update.
281
+ *
282
+ * @returns The restored data
283
+ *
284
+ * @remarks
285
+ * - Should be used if an optimistic update fails.
286
+ */
287
+ rollbackOptimisticUpdate: () => TData;
288
+ subscribe: (subscriber: import("../vanilla.d.mts").Subscriber<QueryState<TData>>) => () => void;
289
+ getSubscribers: () => Set<import("../vanilla.d.mts").Subscriber<QueryState<TData>>>;
290
+ getState: () => QueryState<TData>;
291
+ setState: (value: SetState<QueryState<TData>>) => void;
292
+ }) & {
293
+ /**
294
+ * Executes all query instances.
295
+ *
296
+ * @remarks
297
+ * - Useful for bulk refetching.
298
+ */
299
+ executeAll: (overwriteOngoingExecution?: boolean) => void;
300
+ /**
301
+ * Revalidates all query instances.
302
+ *
303
+ * @remarks
304
+ * - Only re-fetches stale queries.
305
+ */
306
+ revalidateAll: (overwriteOngoingExecution?: boolean) => void;
307
+ /**
308
+ * Invalidates all query instances.
309
+ *
310
+ * @remarks
311
+ * - Marks all queries as invalidated and triggers revalidation if active.
312
+ * - Invalidated queries bypass `staleTime` until successfully executed again.
313
+ */
314
+ invalidateAll: (overwriteOngoingExecution?: boolean) => void;
315
+ /**
316
+ * Resets all query instances.
317
+ */
318
+ resetAll: () => void;
319
+ };
@@ -0,0 +1,25 @@
1
+ import { type InitStoreOptions } from 'floppy-disk/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
+ *
16
+ * @example
17
+ * const useCounter = createStore({ count: 0 });
18
+ *
19
+ * function Component() {
20
+ * const count = useCounter((s) => s.count);
21
+ * }
22
+ *
23
+ * useCounter.setState({ count: 1 });
24
+ */
25
+ export declare const createStore: <TState extends Record<string, any>>(initialState: TState, options?: InitStoreOptions<TState>) => (<TStateSlice = TState>(selector?: (state: TState) => TStateSlice) => TStateSlice) & import("../vanilla.d.mts").StoreApi<TState>;
@@ -0,0 +1,32 @@
1
+ import { type InitStoreOptions } from 'floppy-disk/vanilla';
2
+ /**
3
+ * Creates a factory for multiple stores identified by a key.
4
+ *
5
+ * @param initialState - The initial state for each store instance
6
+ * @param options - Optional lifecycle hooks
7
+ *
8
+ * @returns A function to retrieve or create a store by key
9
+ *
10
+ * @remarks
11
+ * - Each unique key maps to a separate store instance.
12
+ * - Keys are deterministically hashed, ensuring stable identity.
13
+ * - Stores are lazily created and cached.
14
+ * - Each store has its own state, subscribers, and lifecycle.
15
+ * - Useful for scenarios like:
16
+ * - Query caches
17
+ * - Entity-based state
18
+ * - Dynamic instances
19
+ *
20
+ * @example
21
+ * const getUserStore = createStores({ name: '' });
22
+ *
23
+ * const userStore = getUserStore({ id: 1 });
24
+ * const name = userStore((s) => s.name);
25
+ */
26
+ export declare const createStores: <TState extends Record<string, any>, TKey extends Record<string, any>>(initialState: TState, options?: InitStoreOptions<TState>) => (key?: TKey) => (<TStateSlice = TState>(selector?: (state: TState) => TStateSlice) => TStateSlice) & {
27
+ delete: () => boolean;
28
+ setState: (value: import("../vanilla.d.mts").SetState<TState>) => void;
29
+ getState: () => TState;
30
+ subscribe: (subscriber: import("../vanilla.d.mts").Subscriber<TState>) => () => void;
31
+ getSubscribers: () => Set<import("../vanilla.d.mts").Subscriber<TState>>;
32
+ };
@@ -0,0 +1,6 @@
1
+ import { useLayoutEffect } from 'react';
2
+ /**
3
+ * Does exactly same as `useLayoutEffect`.\
4
+ * It will use `useEffect` in **server-side** to prevent warning when executed on server-side.
5
+ */
6
+ export declare const useIsomorphicLayoutEffect: typeof useLayoutEffect;
@@ -0,0 +1,18 @@
1
+ import { type StoreApi } from 'floppy-disk/vanilla';
2
+ export declare const useStoreUpdateNotifier: <TState extends Record<string, any>, TStateSlice = TState>(store: StoreApi<TState>, selector: (state: TState) => TStateSlice) => void;
3
+ /**
4
+ * React hook for subscribing to a store with optional state selection.
5
+ *
6
+ * @param store - The store instance to subscribe to
7
+ * @param selector - Optional selector to derive a slice of state
8
+ *
9
+ * @returns The selected state slice (or full state if no selector is provided)
10
+ *
11
+ * @remarks
12
+ * - The selector does **not** need to be memoized.
13
+ * - The hook internally keeps the latest selector reference to avoid re-subscription.
14
+ *
15
+ * @example
16
+ * const count = useStoreState(store, (s) => s.count);
17
+ */
18
+ export declare const useStoreState: <TState extends Record<string, any>, TStateSlice = TState>(store: StoreApi<TState>, selector?: (state: TState) => TStateSlice) => TStateSlice;
@@ -0,0 +1,6 @@
1
+ export * from './react/use-isomorphic-layout-effect.mjs';
2
+ export * from './react/use-store.mjs';
3
+ export * from './react/create-store.mjs';
4
+ export * from './react/create-stores.mjs';
5
+ export * from './react/create-query.mjs';
6
+ export * from './react/create-mutation.mjs';