@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.
@@ -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 };