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.
- package/README.md +0 -835
- package/esm/index.d.mts +1 -0
- package/esm/index.mjs +1 -0
- package/esm/react/create-mutation.d.mts +135 -0
- package/esm/react/create-query.d.mts +319 -0
- package/esm/react/create-store.d.mts +25 -0
- package/esm/react/create-stores.d.mts +32 -0
- package/esm/react/use-isomorphic-layout-effect.d.mts +6 -0
- package/esm/react/use-store.d.mts +18 -0
- package/esm/react.d.mts +6 -0
- package/esm/react.mjs +503 -0
- package/esm/vanilla/basic.d.mts +21 -0
- package/esm/vanilla/hash.d.mts +7 -0
- package/esm/vanilla/shallow.d.mts +6 -0
- package/esm/vanilla/store.d.mts +75 -0
- package/esm/vanilla.d.mts +4 -0
- package/esm/vanilla.mjs +109 -0
- package/index.d.ts +1 -0
- package/index.js +12 -0
- package/package.json +50 -45
- package/react/create-mutation.d.ts +135 -0
- package/react/create-query.d.ts +319 -0
- package/react/create-store.d.ts +25 -0
- package/react/create-stores.d.ts +32 -0
- package/react/use-isomorphic-layout-effect.d.ts +6 -0
- package/react/use-store.d.ts +18 -0
- package/{lib/index.d.ts → react.d.ts} +2 -4
- package/react.js +511 -0
- package/ts_version_4.5_and_above_is_required.d.ts +0 -0
- package/vanilla/basic.d.ts +21 -0
- package/vanilla/hash.d.ts +7 -0
- package/vanilla/shallow.d.ts +6 -0
- package/vanilla/store.d.ts +75 -0
- package/vanilla.d.ts +4 -0
- package/vanilla.js +118 -0
- package/esm/fetcher.d.ts +0 -27
- package/esm/fetcher.js +0 -95
- package/esm/index.d.ts +0 -8
- package/esm/index.js +0 -8
- package/esm/react/create-bi-direction-query.d.ts +0 -166
- package/esm/react/create-bi-direction-query.js +0 -74
- package/esm/react/create-mutation.d.ts +0 -39
- package/esm/react/create-mutation.js +0 -56
- package/esm/react/create-query.d.ts +0 -319
- package/esm/react/create-query.js +0 -434
- package/esm/react/create-store.d.ts +0 -51
- package/esm/react/create-store.js +0 -38
- package/esm/react/create-stores.d.ts +0 -77
- package/esm/react/create-stores.js +0 -125
- package/esm/react/with-context.d.ts +0 -5
- package/esm/react/with-context.js +0 -14
- package/esm/store.d.ts +0 -24
- package/esm/store.js +0 -51
- package/esm/utils.d.ts +0 -24
- package/esm/utils.js +0 -31
- package/lib/fetcher.d.ts +0 -27
- package/lib/fetcher.js +0 -99
- package/lib/index.js +0 -11
- package/lib/react/create-bi-direction-query.d.ts +0 -166
- package/lib/react/create-bi-direction-query.js +0 -78
- package/lib/react/create-mutation.d.ts +0 -39
- package/lib/react/create-mutation.js +0 -60
- package/lib/react/create-query.d.ts +0 -319
- package/lib/react/create-query.js +0 -438
- package/lib/react/create-store.d.ts +0 -51
- package/lib/react/create-store.js +0 -42
- package/lib/react/create-stores.d.ts +0 -77
- package/lib/react/create-stores.js +0 -130
- package/lib/react/with-context.d.ts +0 -5
- package/lib/react/with-context.js +0 -18
- package/lib/store.d.ts +0 -24
- package/lib/store.js +0 -55
- package/lib/utils.d.ts +0 -24
- package/lib/utils.js +0 -39
- package/utils/package.json +0 -6
package/esm/index.d.mts
ADDED
|
@@ -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,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;
|
package/esm/react.d.mts
ADDED
|
@@ -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';
|