@demokit-ai/tanstack-query 0.0.1
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/dist/index.cjs +348 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +432 -0
- package/dist/index.d.ts +432 -0
- package/dist/index.js +333 -0
- package/dist/index.js.map +1 -0
- package/package.json +64 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,432 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { QueryKey as QueryKey$1, QueryClient, UseMutationOptions, UseMutationResult, QueryClientConfig } from '@tanstack/react-query';
|
|
3
|
+
import { QueryKey, QueryKeyMatchResult } from '@demokit-ai/core';
|
|
4
|
+
export { matchQueryKey } from '@demokit-ai/core';
|
|
5
|
+
import { ReactNode } from 'react';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Context provided to query fixture handlers
|
|
9
|
+
*/
|
|
10
|
+
interface QueryFixtureContext {
|
|
11
|
+
/**
|
|
12
|
+
* The full query key
|
|
13
|
+
*/
|
|
14
|
+
queryKey: QueryKey$1;
|
|
15
|
+
/**
|
|
16
|
+
* Extracted parameters from pattern matching
|
|
17
|
+
*/
|
|
18
|
+
params: Record<string, unknown>;
|
|
19
|
+
/**
|
|
20
|
+
* The match result from pattern matching
|
|
21
|
+
*/
|
|
22
|
+
match: QueryKeyMatchResult;
|
|
23
|
+
/**
|
|
24
|
+
* Signal for aborting the query
|
|
25
|
+
*/
|
|
26
|
+
signal?: AbortSignal;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* A query fixture handler can be:
|
|
30
|
+
* - A static value (object, array, primitive)
|
|
31
|
+
* - A function that receives context and returns data
|
|
32
|
+
* - An async function for dynamic fixtures
|
|
33
|
+
*/
|
|
34
|
+
type QueryFixtureHandler<TData = unknown> = TData | ((context: QueryFixtureContext) => TData) | ((context: QueryFixtureContext) => Promise<TData>);
|
|
35
|
+
/**
|
|
36
|
+
* Map of query key patterns to fixture handlers
|
|
37
|
+
*/
|
|
38
|
+
type QueryFixtureMap = Map<QueryKey, QueryFixtureHandler>;
|
|
39
|
+
/**
|
|
40
|
+
* Context provided to mutation fixture handlers
|
|
41
|
+
*/
|
|
42
|
+
interface MutationFixtureContext<TVariables = unknown> {
|
|
43
|
+
/**
|
|
44
|
+
* The mutation key (if defined)
|
|
45
|
+
*/
|
|
46
|
+
mutationKey?: QueryKey$1;
|
|
47
|
+
/**
|
|
48
|
+
* Variables passed to the mutation
|
|
49
|
+
*/
|
|
50
|
+
variables: TVariables;
|
|
51
|
+
/**
|
|
52
|
+
* The query client for cache manipulation
|
|
53
|
+
*/
|
|
54
|
+
queryClient: QueryClient;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* A mutation fixture handler
|
|
58
|
+
*/
|
|
59
|
+
type MutationFixtureHandler<TData = unknown, TVariables = unknown> = TData | ((context: MutationFixtureContext<TVariables>) => TData) | ((context: MutationFixtureContext<TVariables>) => Promise<TData>);
|
|
60
|
+
/**
|
|
61
|
+
* Map of mutation keys to fixture handlers
|
|
62
|
+
*/
|
|
63
|
+
type MutationFixtureMap = Map<string, MutationFixtureHandler>;
|
|
64
|
+
/**
|
|
65
|
+
* Configuration for DemoQueryProvider
|
|
66
|
+
*/
|
|
67
|
+
interface DemoQueryProviderConfig {
|
|
68
|
+
/**
|
|
69
|
+
* Query fixtures - map of query key patterns to handlers
|
|
70
|
+
*/
|
|
71
|
+
queries?: QueryFixtureMap | QueryFixtureMapObject;
|
|
72
|
+
/**
|
|
73
|
+
* Mutation fixtures - map of mutation names to handlers
|
|
74
|
+
*/
|
|
75
|
+
mutations?: MutationFixtureMap | MutationFixtureMapObject;
|
|
76
|
+
/**
|
|
77
|
+
* Whether demo mode is enabled
|
|
78
|
+
* If not provided, reads from DemoKitProvider context
|
|
79
|
+
*/
|
|
80
|
+
enabled?: boolean;
|
|
81
|
+
/**
|
|
82
|
+
* Delay in ms before returning fixture data (simulates network latency)
|
|
83
|
+
* @default 0
|
|
84
|
+
*/
|
|
85
|
+
delay?: number;
|
|
86
|
+
/**
|
|
87
|
+
* Whether to pre-populate the query cache on mount
|
|
88
|
+
* Only applies to fixtures with static values (not functions)
|
|
89
|
+
* @default false
|
|
90
|
+
*/
|
|
91
|
+
prepopulateCache?: boolean;
|
|
92
|
+
/**
|
|
93
|
+
* Fallback query function for unmatched queries
|
|
94
|
+
* If not provided, will use fetch-based approach
|
|
95
|
+
*/
|
|
96
|
+
fallbackQueryFn?: (context: {
|
|
97
|
+
queryKey: QueryKey$1;
|
|
98
|
+
signal?: AbortSignal;
|
|
99
|
+
}) => Promise<unknown>;
|
|
100
|
+
/**
|
|
101
|
+
* staleTime for demo queries
|
|
102
|
+
* @default Infinity
|
|
103
|
+
*/
|
|
104
|
+
staleTime?: number;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Object-based query fixture map (easier to define)
|
|
108
|
+
* Keys are JSON-stringified query key patterns
|
|
109
|
+
*/
|
|
110
|
+
type QueryFixtureMapObject = Record<string, QueryFixtureHandler>;
|
|
111
|
+
/**
|
|
112
|
+
* Object-based mutation fixture map
|
|
113
|
+
*/
|
|
114
|
+
type MutationFixtureMapObject = Record<string, MutationFixtureHandler>;
|
|
115
|
+
/**
|
|
116
|
+
* Props for DemoQueryProvider
|
|
117
|
+
*/
|
|
118
|
+
interface DemoQueryProviderProps extends DemoQueryProviderConfig {
|
|
119
|
+
/**
|
|
120
|
+
* Child components
|
|
121
|
+
*/
|
|
122
|
+
children: ReactNode;
|
|
123
|
+
/**
|
|
124
|
+
* Existing QueryClient to wrap
|
|
125
|
+
* If not provided, creates a new one
|
|
126
|
+
*/
|
|
127
|
+
client?: QueryClient;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Return type of useDemoQuery hook
|
|
131
|
+
*/
|
|
132
|
+
interface DemoQueryState {
|
|
133
|
+
/**
|
|
134
|
+
* Whether demo mode is enabled
|
|
135
|
+
*/
|
|
136
|
+
isDemoMode: boolean;
|
|
137
|
+
/**
|
|
138
|
+
* Add or update a query fixture
|
|
139
|
+
*/
|
|
140
|
+
setQueryFixture: (pattern: QueryKey, handler: QueryFixtureHandler) => void;
|
|
141
|
+
/**
|
|
142
|
+
* Remove a query fixture
|
|
143
|
+
*/
|
|
144
|
+
removeQueryFixture: (pattern: QueryKey) => void;
|
|
145
|
+
/**
|
|
146
|
+
* Add or update a mutation fixture
|
|
147
|
+
*/
|
|
148
|
+
setMutationFixture: (name: string, handler: MutationFixtureHandler) => void;
|
|
149
|
+
/**
|
|
150
|
+
* Remove a mutation fixture
|
|
151
|
+
*/
|
|
152
|
+
removeMutationFixture: (name: string) => void;
|
|
153
|
+
/**
|
|
154
|
+
* Invalidate all demo queries (triggers refetch)
|
|
155
|
+
*/
|
|
156
|
+
invalidateAll: () => void;
|
|
157
|
+
/**
|
|
158
|
+
* Reset query cache to initial demo state
|
|
159
|
+
*/
|
|
160
|
+
resetCache: () => void;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Provider component for DemoKit TanStack Query integration
|
|
165
|
+
*
|
|
166
|
+
* Wraps QueryClientProvider and intercepts queries when demo mode is enabled.
|
|
167
|
+
*
|
|
168
|
+
* @example
|
|
169
|
+
* // With new QueryClient
|
|
170
|
+
* <DemoQueryProvider
|
|
171
|
+
* queries={{
|
|
172
|
+
* '["users"]': [{ id: '1', name: 'Demo User' }],
|
|
173
|
+
* '["users", ":id"]': ({ params }) => ({ id: params.id, name: 'Demo User' }),
|
|
174
|
+
* }}
|
|
175
|
+
* >
|
|
176
|
+
* <App />
|
|
177
|
+
* </DemoQueryProvider>
|
|
178
|
+
*
|
|
179
|
+
* @example
|
|
180
|
+
* // With existing QueryClient
|
|
181
|
+
* const queryClient = new QueryClient()
|
|
182
|
+
*
|
|
183
|
+
* <DemoQueryProvider client={queryClient} queries={...}>
|
|
184
|
+
* <App />
|
|
185
|
+
* </DemoQueryProvider>
|
|
186
|
+
*
|
|
187
|
+
* @example
|
|
188
|
+
* // With DemoKitProvider (auto-detects demo mode)
|
|
189
|
+
* <DemoKitProvider fixtures={...}>
|
|
190
|
+
* <DemoQueryProvider queries={...}>
|
|
191
|
+
* <App />
|
|
192
|
+
* </DemoQueryProvider>
|
|
193
|
+
* </DemoKitProvider>
|
|
194
|
+
*/
|
|
195
|
+
declare function DemoQueryProvider({ children, client, ...config }: DemoQueryProviderProps): react_jsx_runtime.JSX.Element;
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Hook to access DemoQuery state and controls
|
|
199
|
+
*
|
|
200
|
+
* @returns DemoQuery context value
|
|
201
|
+
* @throws Error if used outside of DemoQueryProvider
|
|
202
|
+
*
|
|
203
|
+
* @example
|
|
204
|
+
* function MyComponent() {
|
|
205
|
+
* const { isDemoMode, setQueryFixture, invalidateAll } = useDemoQuery()
|
|
206
|
+
*
|
|
207
|
+
* // Dynamically add a fixture
|
|
208
|
+
* const handleAddFixture = () => {
|
|
209
|
+
* setQueryFixture(['users', 'custom'], { id: 'custom', name: 'Custom User' })
|
|
210
|
+
* invalidateAll() // Trigger refetch
|
|
211
|
+
* }
|
|
212
|
+
*
|
|
213
|
+
* return (
|
|
214
|
+
* <button onClick={handleAddFixture}>Add Custom Fixture</button>
|
|
215
|
+
* )
|
|
216
|
+
* }
|
|
217
|
+
*/
|
|
218
|
+
declare function useDemoQuery(): DemoQueryState;
|
|
219
|
+
/**
|
|
220
|
+
* Hook to check if demo mode is enabled
|
|
221
|
+
* Shorthand for useDemoQuery().isDemoMode
|
|
222
|
+
*
|
|
223
|
+
* @example
|
|
224
|
+
* function MyComponent() {
|
|
225
|
+
* const isDemoMode = useIsDemoQueryMode()
|
|
226
|
+
*
|
|
227
|
+
* return isDemoMode ? <DemoBadge /> : null
|
|
228
|
+
* }
|
|
229
|
+
*/
|
|
230
|
+
declare function useIsDemoQueryMode(): boolean;
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Options for useDemoMutation hook
|
|
234
|
+
*/
|
|
235
|
+
interface UseDemoMutationOptions<TData, TError, TVariables, TContext> extends Omit<UseMutationOptions<TData, TError, TVariables, TContext>, 'mutationFn'> {
|
|
236
|
+
/**
|
|
237
|
+
* The real mutation function to use when demo mode is disabled
|
|
238
|
+
*/
|
|
239
|
+
mutationFn: (variables: TVariables) => Promise<TData>;
|
|
240
|
+
/**
|
|
241
|
+
* Name used to look up the demo fixture
|
|
242
|
+
* If not provided, uses mutationKey as string
|
|
243
|
+
*/
|
|
244
|
+
demoName?: string;
|
|
245
|
+
/**
|
|
246
|
+
* Demo fixture handler for this mutation
|
|
247
|
+
* If provided, overrides the fixture from DemoQueryProvider
|
|
248
|
+
*/
|
|
249
|
+
demoFixture?: MutationFixtureHandler<TData, TVariables>;
|
|
250
|
+
/**
|
|
251
|
+
* Delay in ms before returning demo data
|
|
252
|
+
* @default 0
|
|
253
|
+
*/
|
|
254
|
+
demoDelay?: number;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* A mutation hook that automatically uses demo fixtures when demo mode is enabled
|
|
258
|
+
*
|
|
259
|
+
* @example
|
|
260
|
+
* const createUser = useDemoMutation({
|
|
261
|
+
* mutationFn: async (data) => api.createUser(data),
|
|
262
|
+
* demoName: 'createUser',
|
|
263
|
+
* demoFixture: ({ variables, queryClient }) => {
|
|
264
|
+
* // Create demo user
|
|
265
|
+
* const newUser = { id: crypto.randomUUID(), ...variables }
|
|
266
|
+
*
|
|
267
|
+
* // Update the users query cache
|
|
268
|
+
* queryClient.setQueryData(['users'], (old: User[] = []) => [...old, newUser])
|
|
269
|
+
*
|
|
270
|
+
* return newUser
|
|
271
|
+
* },
|
|
272
|
+
* onSuccess: (data) => {
|
|
273
|
+
* console.log('Created user:', data)
|
|
274
|
+
* },
|
|
275
|
+
* })
|
|
276
|
+
*
|
|
277
|
+
* // Use like normal useMutation
|
|
278
|
+
* createUser.mutate({ name: 'New User', email: 'user@example.com' })
|
|
279
|
+
*/
|
|
280
|
+
declare function useDemoMutation<TData = unknown, TError = unknown, TVariables = void, TContext = unknown>(options: UseDemoMutationOptions<TData, TError, TVariables, TContext>): UseMutationResult<TData, TError, TVariables, TContext>;
|
|
281
|
+
/**
|
|
282
|
+
* Create a set of demo mutations with fixtures
|
|
283
|
+
*
|
|
284
|
+
* @example
|
|
285
|
+
* const mutations = createDemoMutations({
|
|
286
|
+
* createUser: {
|
|
287
|
+
* mutationFn: api.createUser,
|
|
288
|
+
* fixture: ({ variables, queryClient }) => {
|
|
289
|
+
* const newUser = { id: 'demo-1', ...variables }
|
|
290
|
+
* queryClient.setQueryData(['users'], (old = []) => [...old, newUser])
|
|
291
|
+
* return newUser
|
|
292
|
+
* },
|
|
293
|
+
* },
|
|
294
|
+
* deleteUser: {
|
|
295
|
+
* mutationFn: api.deleteUser,
|
|
296
|
+
* fixture: ({ variables, queryClient }) => {
|
|
297
|
+
* queryClient.setQueryData(['users'], (old: User[] = []) =>
|
|
298
|
+
* old.filter(u => u.id !== variables.id)
|
|
299
|
+
* )
|
|
300
|
+
* return { success: true }
|
|
301
|
+
* },
|
|
302
|
+
* },
|
|
303
|
+
* })
|
|
304
|
+
*
|
|
305
|
+
* // Use in components
|
|
306
|
+
* const { createUser, deleteUser } = mutations
|
|
307
|
+
*/
|
|
308
|
+
type DemoMutationConfig<TData, TVariables> = {
|
|
309
|
+
mutationFn: (variables: TVariables) => Promise<TData>;
|
|
310
|
+
fixture: MutationFixtureHandler<TData, TVariables>;
|
|
311
|
+
delay?: number;
|
|
312
|
+
};
|
|
313
|
+
/**
|
|
314
|
+
* Helper to create mutation options with demo fixture
|
|
315
|
+
*/
|
|
316
|
+
declare function createMutationOptions<TData, TVariables>(config: DemoMutationConfig<TData, TVariables>): Pick<UseDemoMutationOptions<TData, unknown, TVariables, unknown>, 'mutationFn' | 'demoFixture' | 'demoDelay'>;
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Configuration for creating a demo-aware QueryClient
|
|
320
|
+
*/
|
|
321
|
+
interface DemoQueryClientConfig extends DemoQueryProviderConfig {
|
|
322
|
+
/**
|
|
323
|
+
* Base QueryClient config to extend
|
|
324
|
+
*/
|
|
325
|
+
queryClientConfig?: QueryClientConfig;
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Create a demo-aware query function
|
|
329
|
+
*
|
|
330
|
+
* This wraps the default query function to intercept demo queries
|
|
331
|
+
* and return fixture data when demo mode is enabled.
|
|
332
|
+
*/
|
|
333
|
+
declare function createDemoQueryFn(config: {
|
|
334
|
+
fixtures: QueryFixtureMap;
|
|
335
|
+
delay?: number;
|
|
336
|
+
fallbackQueryFn?: DemoQueryProviderConfig['fallbackQueryFn'];
|
|
337
|
+
isEnabled: () => boolean;
|
|
338
|
+
}): ({ queryKey, signal, }: {
|
|
339
|
+
queryKey: readonly unknown[];
|
|
340
|
+
signal?: AbortSignal;
|
|
341
|
+
}) => Promise<any>;
|
|
342
|
+
/**
|
|
343
|
+
* Create a demo-aware QueryClient
|
|
344
|
+
*
|
|
345
|
+
* This creates a QueryClient configured to intercept queries when demo mode
|
|
346
|
+
* is enabled and return fixture data instead of making real API calls.
|
|
347
|
+
*
|
|
348
|
+
* @example
|
|
349
|
+
* const { client, enable, disable, isEnabled } = createDemoQueryClient({
|
|
350
|
+
* queries: {
|
|
351
|
+
* '["users"]': [{ id: '1', name: 'Demo User' }],
|
|
352
|
+
* '["users", ":id"]': ({ params }) => ({ id: params.id, name: 'Demo User' }),
|
|
353
|
+
* },
|
|
354
|
+
* delay: 100, // Simulate 100ms latency
|
|
355
|
+
* })
|
|
356
|
+
*
|
|
357
|
+
* // Use with QueryClientProvider
|
|
358
|
+
* <QueryClientProvider client={client}>
|
|
359
|
+
* <App />
|
|
360
|
+
* </QueryClientProvider>
|
|
361
|
+
*/
|
|
362
|
+
declare function createDemoQueryClient(config?: DemoQueryClientConfig): {
|
|
363
|
+
/**
|
|
364
|
+
* The QueryClient instance
|
|
365
|
+
*/
|
|
366
|
+
client: QueryClient;
|
|
367
|
+
/**
|
|
368
|
+
* Enable demo mode
|
|
369
|
+
*/
|
|
370
|
+
enable: () => void;
|
|
371
|
+
/**
|
|
372
|
+
* Disable demo mode
|
|
373
|
+
*/
|
|
374
|
+
disable: () => void;
|
|
375
|
+
/**
|
|
376
|
+
* Check if demo mode is enabled
|
|
377
|
+
*/
|
|
378
|
+
isEnabled: () => boolean;
|
|
379
|
+
/**
|
|
380
|
+
* Get the fixture map
|
|
381
|
+
*/
|
|
382
|
+
getFixtures: () => QueryFixtureMap;
|
|
383
|
+
/**
|
|
384
|
+
* Add or update a fixture
|
|
385
|
+
*/
|
|
386
|
+
setFixture: (pattern: QueryKey, handler: QueryFixtureHandler) => void;
|
|
387
|
+
/**
|
|
388
|
+
* Remove a fixture
|
|
389
|
+
*/
|
|
390
|
+
removeFixture: (pattern: QueryKey) => void;
|
|
391
|
+
/**
|
|
392
|
+
* Clear all query cache
|
|
393
|
+
*/
|
|
394
|
+
clearCache: () => void;
|
|
395
|
+
/**
|
|
396
|
+
* Invalidate all queries
|
|
397
|
+
*/
|
|
398
|
+
invalidateAll: () => void;
|
|
399
|
+
};
|
|
400
|
+
type DemoQueryClient = ReturnType<typeof createDemoQueryClient>;
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* Convert TanStack Query key to DemoKit QueryKey
|
|
404
|
+
* TanStack Query keys can contain any value, so we normalize them
|
|
405
|
+
*/
|
|
406
|
+
declare function normalizeQueryKey(queryKey: QueryKey$1): QueryKey;
|
|
407
|
+
/**
|
|
408
|
+
* Parse a JSON string pattern into a QueryKey
|
|
409
|
+
* Handles both array notation and simple string patterns
|
|
410
|
+
*
|
|
411
|
+
* @example
|
|
412
|
+
* parsePatternString('["users"]') // ['users']
|
|
413
|
+
* parsePatternString('["users", ":id"]') // ['users', ':id']
|
|
414
|
+
* parsePatternString('users') // ['users']
|
|
415
|
+
*/
|
|
416
|
+
declare function parsePatternString(pattern: string): QueryKey;
|
|
417
|
+
/**
|
|
418
|
+
* Convert object-based fixture map to Map-based fixture map
|
|
419
|
+
*/
|
|
420
|
+
declare function normalizeFixtureMap(fixtures: QueryFixtureMapObject | QueryFixtureMap): QueryFixtureMap;
|
|
421
|
+
/**
|
|
422
|
+
* Find a matching fixture for a query key
|
|
423
|
+
*
|
|
424
|
+
* @param fixtures - Map of query key patterns to handlers
|
|
425
|
+
* @param queryKey - The query key to match
|
|
426
|
+
* @returns Tuple of [handler, match result] or null if no match
|
|
427
|
+
*/
|
|
428
|
+
declare function findMatchingFixture(fixtures: QueryFixtureMap, queryKey: QueryKey$1): [QueryFixtureHandler, {
|
|
429
|
+
params: Record<string, unknown>;
|
|
430
|
+
}] | null;
|
|
431
|
+
|
|
432
|
+
export { type DemoMutationConfig, type DemoQueryClient, DemoQueryProvider, type DemoQueryProviderConfig, type DemoQueryProviderProps, type DemoQueryState, type MutationFixtureContext, type MutationFixtureHandler, type MutationFixtureMap, type MutationFixtureMapObject, type QueryFixtureContext, type QueryFixtureHandler, type QueryFixtureMap, type QueryFixtureMapObject, type UseDemoMutationOptions, createDemoQueryClient, createDemoQueryFn, createMutationOptions, findMatchingFixture, normalizeFixtureMap, normalizeQueryKey, parsePatternString, useDemoMutation, useDemoQuery, useIsDemoQueryMode };
|