@kimesh/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,794 @@
1
+ import * as _tanstack_vue_query0 from "@tanstack/vue-query";
2
+ import { QueryClient, QueryClient as QueryClient$1, QueryKey, QueryKey as QueryKey$1, UseInfiniteQueryReturnType, UseQueryReturnType, VueQueryPlugin, VueQueryPluginOptions, queryOptions, useInfiniteQuery, useMutation, useQuery, useQueryClient } from "@tanstack/vue-query";
3
+ import { FetchContext, FetchContext as FetchContext$1, FetchError, FetchResponse, FetchResponse as FetchResponse$1 } from "ofetch";
4
+ import * as vue0 from "vue";
5
+ import { ComputedRef, MaybeRefOrGetter, Plugin, Ref, WatchSource } from "vue";
6
+ import { RouteLocationNormalized, Router } from "vue-router";
7
+
8
+ //#region src/plugin.d.ts
9
+ /**
10
+ * Options for KimeshQueryPlugin
11
+ */
12
+ interface KimeshQueryPluginOptions extends Omit<VueQueryPluginOptions, 'queryClient'> {
13
+ /** Custom QueryClient instance */
14
+ queryClient?: QueryClient$1;
15
+ /** Default stale time in ms (default: 5s) */
16
+ staleTime?: number;
17
+ /** Default GC time in ms (default: 5 min) */
18
+ gcTime?: number;
19
+ /** Number of retries on error (default: 1) */
20
+ retry?: number;
21
+ /** Refetch on window focus (default: false) */
22
+ refetchOnWindowFocus?: boolean;
23
+ }
24
+ /**
25
+ * Create a QueryClient with Kimesh-optimized defaults
26
+ *
27
+ * Defaults are designed for typical SPA usage:
28
+ * - Short stale time (5s) for responsive UX
29
+ * - Longer GC time (5min) to preserve cache during navigation
30
+ * - Single retry to recover from transient errors
31
+ * - No refetch on focus to reduce unnecessary requests
32
+ */
33
+ declare function createKimeshQueryClient(options?: KimeshQueryPluginOptions): QueryClient$1;
34
+ /**
35
+ * KimeshQueryPlugin - Centralized query plugin with sensible defaults
36
+ *
37
+ * @example
38
+ * ```ts
39
+ * import { KimeshQueryPlugin } from '@kimesh/query'
40
+ *
41
+ * // Basic usage with defaults
42
+ * app.use(KimeshQueryPlugin)
43
+ *
44
+ * // With custom options
45
+ * app.use(KimeshQueryPlugin, {
46
+ * staleTime: 10 * 1000,
47
+ * retry: 2,
48
+ * })
49
+ *
50
+ * // With custom QueryClient
51
+ * app.use(KimeshQueryPlugin, {
52
+ * queryClient: myCustomQueryClient,
53
+ * })
54
+ * ```
55
+ */
56
+ declare const KimeshQueryPlugin: Plugin<KimeshQueryPluginOptions | undefined>;
57
+ //#endregion
58
+ //#region src/fetch/types.d.ts
59
+ /**
60
+ * Configuration options for creating or configuring a fetch instance.
61
+ * Used both for instance creation and runtime config.
62
+ */
63
+ interface KmFetchConfig {
64
+ baseURL?: string;
65
+ headers?: Record<string, string>;
66
+ timeout?: number;
67
+ retry?: number | false;
68
+ retryDelay?: number;
69
+ credentials?: RequestCredentials;
70
+ onRequest?: (context: FetchContext$1) => void | Promise<void>;
71
+ onRequestError?: (context: FetchContext$1 & {
72
+ error: Error;
73
+ }) => void | Promise<void>;
74
+ onResponse?: (context: FetchContext$1 & {
75
+ response: FetchResponse$1<unknown>;
76
+ }) => void | Promise<void>;
77
+ onResponseError?: (context: FetchContext$1 & {
78
+ response: FetchResponse$1<unknown>;
79
+ }) => void | Promise<void>;
80
+ }
81
+ /**
82
+ * Options for individual fetch requests.
83
+ */
84
+ interface KmFetchRequestOptions extends KmFetchConfig {
85
+ method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS';
86
+ query?: Record<string, unknown>;
87
+ params?: Record<string, unknown>;
88
+ body?: unknown;
89
+ responseType?: 'json' | 'text' | 'blob' | 'arrayBuffer' | 'stream';
90
+ }
91
+ /**
92
+ * A configured fetch instance with chainable creation.
93
+ */
94
+ interface KmFetchInstance {
95
+ <T = unknown>(url: string, options?: KmFetchRequestOptions): Promise<T>;
96
+ raw<T = unknown>(url: string, options?: KmFetchRequestOptions): Promise<FetchResponse$1<T>>;
97
+ create(defaults: KmFetchConfig): KmFetchInstance;
98
+ }
99
+ type KmFetchCreateOptions = KmFetchConfig;
100
+ type FetchRuntimeConfig = KmFetchConfig;
101
+ //#endregion
102
+ //#region src/fetch/create-fetch.d.ts
103
+ /**
104
+ * Create a configured fetch instance.
105
+ *
106
+ * @example
107
+ * ```ts
108
+ * const api = createKmFetch({
109
+ * baseURL: 'https://api.example.com',
110
+ * timeout: 5000,
111
+ * })
112
+ *
113
+ * const users = await api('/users')
114
+ * ```
115
+ */
116
+ declare function createKmFetch(config?: KmFetchConfig): KmFetchInstance;
117
+ //#endregion
118
+ //#region src/fetch/fetch-plugin.d.ts
119
+ interface FetchPluginOptions {
120
+ config?: KmFetchConfig;
121
+ key?: string;
122
+ disableLayerAware?: boolean;
123
+ }
124
+ interface KimeshAppContext {
125
+ $config: Record<string, unknown>;
126
+ $layersConfig: Record<string, Record<string, unknown>>;
127
+ router: {
128
+ beforeEach: (guard: (to: {
129
+ matched: Array<{
130
+ path: string;
131
+ meta: {
132
+ __kimeshLayer?: string;
133
+ };
134
+ }>;
135
+ }) => void) => void;
136
+ };
137
+ hooks: {
138
+ hook: (name: string, callback: (ctx: {
139
+ to: {
140
+ matched: Array<{
141
+ path: string;
142
+ meta: {
143
+ __kimeshLayer?: string;
144
+ };
145
+ }>;
146
+ };
147
+ }) => void) => void;
148
+ };
149
+ provide: <T>(name: string, value: T) => void;
150
+ }
151
+ /**
152
+ * Create a Kimesh runtime plugin for $fetch.
153
+ *
154
+ * @example Basic usage
155
+ * ```typescript
156
+ * import { fetchPlugin } from '@kimesh/query'
157
+ * export default fetchPlugin()
158
+ * ```
159
+ *
160
+ * @example With custom config
161
+ * ```typescript
162
+ * import { fetchPlugin } from '@kimesh/query'
163
+ * export default fetchPlugin({
164
+ * config: {
165
+ * onRequest: ({ options }) => {
166
+ * options.headers = { ...options.headers, 'X-Custom': 'value' }
167
+ * },
168
+ * },
169
+ * })
170
+ * ```
171
+ */
172
+ declare function fetchPlugin(options?: FetchPluginOptions): (app: KimeshAppContext) => {
173
+ provide: {
174
+ [x: string]: KmFetchInstance;
175
+ };
176
+ };
177
+ /**
178
+ * Create a named fetch plugin for multi-instance scenarios.
179
+ *
180
+ * @example
181
+ * ```typescript
182
+ * export const blogFetch = createNamedFetchPlugin('blogFetch', {
183
+ * baseURL: 'https://blog-api.example.com',
184
+ * })
185
+ * ```
186
+ */
187
+ declare function createNamedFetchPlugin(name: string, config?: KmFetchConfig): (app: KimeshAppContext) => {
188
+ provide: {
189
+ [x: string]: KmFetchInstance;
190
+ };
191
+ };
192
+ interface LayerFetchPluginOptions {
193
+ layer: string;
194
+ onRequest?: (ctx: {
195
+ request: string;
196
+ options: Record<string, unknown>;
197
+ }) => void;
198
+ onResponse?: (ctx: {
199
+ request: string;
200
+ response: {
201
+ status: number;
202
+ };
203
+ }) => void;
204
+ }
205
+ /**
206
+ * Create a layer-specific fetch interceptor plugin.
207
+ * Use this in layer plugins to add logging or modify requests for that layer only.
208
+ *
209
+ * @example
210
+ * ```typescript
211
+ * // blog/src/plugins/01.fetch.ts
212
+ * import { layerFetchPlugin } from '@kimesh/query'
213
+ *
214
+ * export default layerFetchPlugin({
215
+ * layer: 'blog',
216
+ * onRequest: ({ request }) => console.log(`[Blog] Fetching: ${request}`),
217
+ * })
218
+ * ```
219
+ */
220
+ declare function layerFetchPlugin(options: LayerFetchPluginOptions): () => void;
221
+ //#endregion
222
+ //#region src/fetch/layer-fetch.d.ts
223
+ /**
224
+ * Initialize the layer-aware fetch system.
225
+ */
226
+ declare function initLayerFetch(configs: {
227
+ layers: Record<string, KmFetchConfig>;
228
+ default: KmFetchConfig;
229
+ }): void;
230
+ declare function setCurrentLayer(layer: string): void;
231
+ declare function getCurrentLayer(): string;
232
+ /**
233
+ * Get fetch instance for a specific layer.
234
+ * Falls back to 'app' layer if the requested layer is not found.
235
+ */
236
+ declare function getLayerFetch(layer?: string): KmFetchInstance;
237
+ declare function isLayerFetchInitialized(): boolean;
238
+ /**
239
+ * Layer-aware $fetch proxy.
240
+ *
241
+ * Automatically routes requests through the current layer's fetch instance.
242
+ * When navigating to /blog/*, the current layer becomes 'blog' and uses
243
+ * the blog layer's configuration.
244
+ *
245
+ * @example
246
+ * ```ts
247
+ * // In a blog route component - uses blog layer's baseURL
248
+ * const posts = await $fetch('/posts')
249
+ *
250
+ * // Force specific layer
251
+ * const hostData = await getLayerFetch('app')('/data')
252
+ * ```
253
+ */
254
+ declare const $fetch: KmFetchInstance;
255
+ //#endregion
256
+ //#region src/fetch/global-fetch.d.ts
257
+ /**
258
+ * Initialize the global $fetch instance with runtime config.
259
+ * Called automatically by Kimesh during app initialization.
260
+ */
261
+ declare function initGlobalFetch(config: {
262
+ apiBase?: string;
263
+ fetch?: KmFetchConfig;
264
+ }): KmFetchInstance;
265
+ /**
266
+ * Get the global fetch instance. Creates a default instance if not initialized.
267
+ */
268
+ declare function useGlobalFetch(): KmFetchInstance;
269
+ //#endregion
270
+ //#region src/loader.d.ts
271
+ /**
272
+ * Loader definition for route data prefetching
273
+ */
274
+ interface LoaderDefinition<TData = unknown> {
275
+ queryKey: QueryKey$1;
276
+ queryFn: () => Promise<TData>;
277
+ staleTime?: number;
278
+ gcTime?: number;
279
+ }
280
+ /**
281
+ * Loader function signature for route components
282
+ */
283
+ type LoaderFn<TData = unknown> = (to: RouteLocationNormalized) => LoaderDefinition<TData> | LoaderDefinition<TData>[] | null;
284
+ /**
285
+ * Route component with loader support
286
+ */
287
+ interface LoadableComponent {
288
+ loader: LoaderFn;
289
+ }
290
+ /**
291
+ * Execute a loader and prefetch data
292
+ */
293
+ declare function executeLoader(queryClient: QueryClient$1, loader: LoaderDefinition | LoaderDefinition[]): Promise<void>;
294
+ /**
295
+ * Type guard to check if a component has a loader function
296
+ */
297
+ declare function hasLoader(component: unknown): component is LoadableComponent;
298
+ /**
299
+ * Extract loaders from route matched components
300
+ */
301
+ declare function extractLoaders(to: RouteLocationNormalized): LoaderDefinition[];
302
+ //#endregion
303
+ //#region src/prefetch.d.ts
304
+ /**
305
+ * Options for setupQueryPrefetching
306
+ */
307
+ interface QueryPrefetchOptions {
308
+ /** Called when prefetching starts */
309
+ onStart?: (to: RouteLocationNormalized, loaders: LoaderDefinition[]) => void;
310
+ /** Called when prefetching completes */
311
+ onComplete?: (to: RouteLocationNormalized, loaders: LoaderDefinition[]) => void;
312
+ /** Called on prefetch error */
313
+ onError?: (error: unknown, to: RouteLocationNormalized) => void;
314
+ /** Skip prefetching for these paths (regex or string) */
315
+ exclude?: (string | RegExp)[];
316
+ /** Only prefetch for these paths */
317
+ include?: (string | RegExp)[];
318
+ }
319
+ /**
320
+ * Setup query prefetching on route navigation
321
+ *
322
+ * @example
323
+ * ```ts
324
+ * import { setupQueryPrefetching } from '@kimesh/query'
325
+ *
326
+ * const router = createRouter({ ... })
327
+ * const queryClient = new QueryClient()
328
+ *
329
+ * setupQueryPrefetching(router, queryClient, {
330
+ * onStart: (to) => console.log('Prefetching', to.path),
331
+ * onError: (error) => console.error('Prefetch failed', error),
332
+ * })
333
+ * ```
334
+ *
335
+ * @returns Function to remove the guard
336
+ */
337
+ declare function setupQueryPrefetching(router: Router, queryClient: QueryClient$1, options?: QueryPrefetchOptions): () => void;
338
+ /**
339
+ * Create a prefetch function for manual prefetching (e.g., on hover)
340
+ *
341
+ * @example
342
+ * ```ts
343
+ * const prefetch = createPrefetcher(queryClient, router)
344
+ *
345
+ * // Prefetch on hover
346
+ * <RouterLink :to="{ name: 'user' }" @mouseenter="prefetch('/user/123')">
347
+ * ```
348
+ */
349
+ declare function createPrefetcher(queryClient: QueryClient$1, router: Router): (path: string) => Promise<void>;
350
+ //#endregion
351
+ //#region src/types.d.ts
352
+ /**
353
+ * Return type for Nuxt-style composables.
354
+ */
355
+ interface KmAsyncDataResult<T> {
356
+ /** Fetched data */
357
+ data: Ref<T | undefined>;
358
+ /** Loading state */
359
+ pending: ComputedRef<boolean>;
360
+ /** Error if any */
361
+ error: Ref<Error | null>;
362
+ /** Status string */
363
+ status: ComputedRef<'idle' | 'pending' | 'success' | 'error'>;
364
+ /** Refetch data */
365
+ refresh: () => Promise<void>;
366
+ /** Alias for refresh */
367
+ execute: () => Promise<void>;
368
+ /** Clear cache and reset */
369
+ clear: () => void;
370
+ }
371
+ /**
372
+ * Query key factory result type.
373
+ */
374
+ type QueryKeyFactory<TRoot extends string, TKeys extends Record<string, ((arg: never) => unknown) | null>> = {
375
+ all: () => readonly [TRoot];
376
+ } & { [K in keyof TKeys]: TKeys[K] extends null ? () => readonly [TRoot, K] : TKeys[K] extends ((arg: infer A) => infer R) ? (arg: A) => readonly [TRoot, K, R] : never };
377
+ //#endregion
378
+ //#region src/composables/useKmFetch.d.ts
379
+ /**
380
+ * Options for useKmFetch composable.
381
+ */
382
+ interface UseKmFetchOptions<T> {
383
+ /** HTTP method */
384
+ method?: MaybeRefOrGetter<'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH'>;
385
+ /** Query parameters */
386
+ query?: MaybeRefOrGetter<Record<string, unknown>>;
387
+ /** Alias for query */
388
+ params?: MaybeRefOrGetter<Record<string, unknown>>;
389
+ /** Request body (auto-serialized) */
390
+ body?: MaybeRefOrGetter<unknown>;
391
+ /** Request headers */
392
+ headers?: MaybeRefOrGetter<Record<string, string>>;
393
+ /** Base URL (overrides global config) */
394
+ baseURL?: MaybeRefOrGetter<string>;
395
+ /** Timeout in milliseconds */
396
+ timeout?: MaybeRefOrGetter<number>;
397
+ /** Called before each request */
398
+ onRequest?: (context: FetchContext) => void | Promise<void>;
399
+ /** Called when request fails */
400
+ onRequestError?: (context: FetchContext & {
401
+ error: Error;
402
+ }) => void | Promise<void>;
403
+ /** Called after each response */
404
+ onResponse?: (context: FetchContext & {
405
+ response: FetchResponse<unknown>;
406
+ }) => void | Promise<void>;
407
+ /** Called when response has error status */
408
+ onResponseError?: (context: FetchContext & {
409
+ response: FetchResponse<unknown>;
410
+ }) => void | Promise<void>;
411
+ /** Custom cache key (auto-generated if not provided) */
412
+ key?: string;
413
+ /** Execute immediately (default: true) */
414
+ immediate?: boolean;
415
+ /** Watch sources for auto-refetch (false to disable) */
416
+ watch?: WatchSource[] | false;
417
+ /** Transform response data */
418
+ transform?: (data: unknown) => T;
419
+ /** Default value factory */
420
+ default?: () => T;
421
+ /** Stale time in ms */
422
+ staleTime?: number;
423
+ /** GC time in ms */
424
+ gcTime?: number;
425
+ /** Custom $fetch instance (uses global if not provided) */
426
+ $fetch?: KmFetchInstance;
427
+ }
428
+ /**
429
+ * Nuxt-style fetch composable built on $fetch and TanStack Query.
430
+ *
431
+ * @example
432
+ * ```ts
433
+ * // Simple GET
434
+ * const { data, pending, error } = useKmFetch('/api/users')
435
+ *
436
+ * // With query params
437
+ * const { data } = useKmFetch('/api/users', {
438
+ * query: { page: 1, limit: 10 },
439
+ * })
440
+ *
441
+ * // POST with body
442
+ * const { data } = useKmFetch('/api/users', {
443
+ * method: 'POST',
444
+ * body: { name: 'John' },
445
+ * })
446
+ *
447
+ * // With interceptors
448
+ * const { data } = useKmFetch('/api/protected', {
449
+ * onRequest({ options }) {
450
+ * options.headers.set('Authorization', `Bearer ${token}`)
451
+ * },
452
+ * })
453
+ *
454
+ * // Reactive URL
455
+ * const userId = ref(1)
456
+ * const { data } = useKmFetch(() => `/api/users/${userId.value}`)
457
+ * ```
458
+ */
459
+ declare function useKmFetch<T>(url: MaybeRefOrGetter<string>, options?: UseKmFetchOptions<T>): KmAsyncDataResult<T>;
460
+ /**
461
+ * Lazy variant - starts fetching immediately (non-blocking pattern).
462
+ *
463
+ * Note: Despite the "lazy" name (Nuxt convention), this starts immediately.
464
+ * Use this when data loading shouldn't block rendering.
465
+ */
466
+ declare function useLazyKmFetch<T>(url: MaybeRefOrGetter<string>, options?: UseKmFetchOptions<T>): KmAsyncDataResult<T>;
467
+ //#endregion
468
+ //#region src/composables/useKmAsyncData.d.ts
469
+ /**
470
+ * Context passed to async data handler.
471
+ */
472
+ interface KmAsyncDataContext {
473
+ /** Global $fetch instance */
474
+ $fetch: KmFetchInstance;
475
+ }
476
+ /**
477
+ * Options for useKmAsyncData composable.
478
+ */
479
+ interface UseKmAsyncDataOptions<T> {
480
+ /** Execute immediately (default: true) */
481
+ immediate?: boolean;
482
+ /** Watch sources for auto-refetch */
483
+ watch?: WatchSource[];
484
+ /** Transform response data */
485
+ transform?: (data: unknown) => T;
486
+ /** Default value factory */
487
+ default?: () => T;
488
+ /** Stale time in ms */
489
+ staleTime?: number;
490
+ /** GC time in ms */
491
+ gcTime?: number;
492
+ /** Custom $fetch instance */
493
+ $fetch?: KmFetchInstance;
494
+ }
495
+ /**
496
+ * Generic async data composable.
497
+ *
498
+ * @example
499
+ * ```ts
500
+ * // Basic usage
501
+ * const { data, pending } = useKmAsyncData('currentUser', async () => {
502
+ * return await api.users.getCurrentUser()
503
+ * })
504
+ *
505
+ * // With $fetch from context
506
+ * const { data } = useKmAsyncData('users', async ({ $fetch }) => {
507
+ * return await $fetch('/api/users')
508
+ * })
509
+ *
510
+ * // With transform
511
+ * const { data } = useKmAsyncData('posts', fetchPosts, {
512
+ * transform: (data) => data.items,
513
+ * })
514
+ * ```
515
+ */
516
+ declare function useKmAsyncData<T>(key: string, handler: (ctx: KmAsyncDataContext) => Promise<T>, options?: UseKmAsyncDataOptions<T>): KmAsyncDataResult<T>;
517
+ /**
518
+ * Lazy variant - starts fetching immediately (non-blocking pattern).
519
+ *
520
+ * Note: Despite the "lazy" name (Nuxt convention), this starts immediately.
521
+ * Use this when data loading shouldn't block rendering.
522
+ */
523
+ declare function useLazyKmAsyncData<T>(key: string, handler: (ctx: KmAsyncDataContext) => Promise<T>, options?: UseKmAsyncDataOptions<T>): KmAsyncDataResult<T>;
524
+ //#endregion
525
+ //#region src/composables/useKmData.d.ts
526
+ /**
527
+ * Access cached data by key
528
+ *
529
+ * @example
530
+ * ```ts
531
+ * const user = useKmData<User>('currentUser')
532
+ * // Can also update
533
+ * user.value = { ...user.value, name: 'New Name' }
534
+ * ```
535
+ */
536
+ declare function useKmData<T>(key: string): vue0.WritableComputedRef<T | undefined, T | undefined>;
537
+ //#endregion
538
+ //#region src/define-query.d.ts
539
+ /**
540
+ * Shared query timing options
541
+ */
542
+ interface QueryTimingOptions {
543
+ /** Time in ms before data is considered stale */
544
+ staleTime?: number;
545
+ /** Time in ms before unused data is garbage collected */
546
+ gcTime?: number;
547
+ }
548
+ /**
549
+ * Query options input with Pinia Colada naming
550
+ */
551
+ interface QueryOptionsInput<TData, TQueryKey extends QueryKey$1 = QueryKey$1> extends QueryTimingOptions {
552
+ /** Query key (unique identifier for cache) */
553
+ key: TQueryKey;
554
+ /** Query function - Pinia Colada style naming */
555
+ query?: () => Promise<TData>;
556
+ /** Query function - TanStack style naming (alias for query) */
557
+ queryFn?: () => Promise<TData>;
558
+ /** Whether the query is enabled */
559
+ enabled?: boolean;
560
+ }
561
+ /**
562
+ * Output type for defineQueryOptions - compatible with both Pinia Colada and TanStack Query
563
+ */
564
+ interface QueryOptionsOutput<TData, TQueryKey extends QueryKey$1 = QueryKey$1> extends QueryTimingOptions {
565
+ key: TQueryKey;
566
+ query: () => Promise<TData>;
567
+ queryKey: TQueryKey;
568
+ queryFn: () => Promise<TData>;
569
+ enabled?: boolean;
570
+ }
571
+ /**
572
+ * Define static query options (Pinia Colada style)
573
+ *
574
+ * @example
575
+ * ```ts
576
+ * // Pinia Colada naming (preferred)
577
+ * export const postsListQuery = defineQueryOptions({
578
+ * key: ['posts', 'list'],
579
+ * query: () => api.posts.getAll(),
580
+ * staleTime: 5 * 60 * 1000,
581
+ * })
582
+ *
583
+ * // TanStack naming (also supported)
584
+ * export const postsListQuery = defineQueryOptions({
585
+ * key: ['posts', 'list'],
586
+ * queryFn: () => api.posts.getAll(),
587
+ * })
588
+ *
589
+ * // Usage with useQuery
590
+ * const { data } = useQuery(postsListQuery)
591
+ * ```
592
+ */
593
+ declare function defineQueryOptions<TData, TQueryKey extends QueryKey$1 = QueryKey$1>(options: QueryOptionsInput<TData, TQueryKey>): QueryOptionsOutput<TData, TQueryKey>;
594
+ /**
595
+ * Create a reusable query composable (Pinia Colada style)
596
+ *
597
+ * @example
598
+ * ```ts
599
+ * export const useCurrentUser = defineQuery({
600
+ * key: ['user', 'current'],
601
+ * query: () => api.users.getCurrentUser(),
602
+ * })
603
+ *
604
+ * // State is shared across components!
605
+ * const { data: user } = useCurrentUser()
606
+ * ```
607
+ */
608
+ declare function defineQuery<TData>(options: {
609
+ key: QueryKey$1;
610
+ query?: () => Promise<TData>;
611
+ queryFn?: () => Promise<TData>;
612
+ staleTime?: number;
613
+ gcTime?: number;
614
+ }): () => _tanstack_vue_query0.UseQueryReturnType<TData, Error>;
615
+ //#endregion
616
+ //#region src/define-mutation.d.ts
617
+ /**
618
+ * Options for defineMutation
619
+ */
620
+ interface MutationOptions<TData, TVariables, TError = Error> {
621
+ /** The mutation function that performs the actual operation */
622
+ mutation: (variables: TVariables) => Promise<TData>;
623
+ /** Called on successful mutation */
624
+ onSuccess?: (data: TData, variables: TVariables) => void;
625
+ /** Called on mutation error */
626
+ onError?: (error: TError, variables: TVariables) => void;
627
+ /** Called after mutation settles (success or error) */
628
+ onSettled?: (data: TData | undefined, error: TError | null, variables: TVariables) => void;
629
+ }
630
+ /**
631
+ * Define a reusable mutation composable (Pinia Colada style)
632
+ *
633
+ * Creates a composable that can be imported and used across multiple components.
634
+ * The mutation configuration is defined once and reused everywhere.
635
+ *
636
+ * @example
637
+ * ```ts
638
+ * // Define the mutation
639
+ * export const useCreatePost = defineMutation({
640
+ * mutation: (data: { title: string; body: string }) => api.posts.create(data),
641
+ * onSuccess: (data, variables) => {
642
+ * queryClient.invalidateQueries({ queryKey: ['posts'] })
643
+ * },
644
+ * })
645
+ *
646
+ * // Use in component
647
+ * const { mutate, mutateAsync, isPending } = useCreatePost()
648
+ * mutate({ title: 'New Post', body: 'Content...' })
649
+ * ```
650
+ */
651
+ declare function defineMutation<TData, TVariables, TError = Error>(options: MutationOptions<TData, TVariables, TError>): () => _tanstack_vue_query0.UseMutationReturnType<TData, TError, TVariables, unknown, Omit<_tanstack_vue_query0.MutationObserverIdleResult<TData, TError, TVariables, unknown>, "mutate" | "reset"> | Omit<_tanstack_vue_query0.MutationObserverLoadingResult<TData, TError, TVariables, unknown>, "mutate" | "reset"> | Omit<_tanstack_vue_query0.MutationObserverErrorResult<TData, TError, TVariables, unknown>, "mutate" | "reset"> | Omit<_tanstack_vue_query0.MutationObserverSuccessResult<TData, TError, TVariables, unknown>, "mutate" | "reset">>;
652
+ //#endregion
653
+ //#region src/query-keys.d.ts
654
+ /**
655
+ * Result type for a query key factory
656
+ */
657
+ type QueryKeyFactoryResult<TRoot extends string, TKeys extends Record<string, ((arg: never) => unknown) | null>> = {
658
+ all: () => readonly [TRoot];
659
+ } & { [K in keyof TKeys]: TKeys[K] extends null ? () => readonly [TRoot, K] : TKeys[K] extends ((arg: infer A) => infer R) ? (arg: A) => readonly [TRoot, K, R] : never };
660
+ /**
661
+ * Create a type-safe query key factory
662
+ *
663
+ * Creates a factory object with methods that generate consistent, hierarchical
664
+ * query keys. This helps maintain cache invalidation patterns and ensures
665
+ * type safety across your application.
666
+ *
667
+ * @example
668
+ * ```ts
669
+ * export const postKeys = createQueryKeyFactory('posts', {
670
+ * lists: null, // () => ['posts', 'lists']
671
+ * list: (filters: { page: number }) => filters, // (f) => ['posts', 'list', f]
672
+ * details: null, // () => ['posts', 'details']
673
+ * detail: (id: string) => id, // (id) => ['posts', 'detail', id]
674
+ * })
675
+ *
676
+ * // Usage
677
+ * postKeys.all() // ['posts']
678
+ * postKeys.lists() // ['posts', 'lists']
679
+ * postKeys.list({ page: 1 }) // ['posts', 'list', { page: 1 }]
680
+ * postKeys.detail('123') // ['posts', 'detail', '123']
681
+ *
682
+ * // Invalidation example
683
+ * queryClient.invalidateQueries({ queryKey: postKeys.all() })
684
+ * ```
685
+ */
686
+ declare function createQueryKeyFactory<TRoot extends string, TKeys extends Record<string, ((arg: never) => unknown) | null>>(root: TRoot, keys: TKeys): QueryKeyFactoryResult<TRoot, TKeys>;
687
+ //#endregion
688
+ //#region src/defer.d.ts
689
+ /**
690
+ * Query options compatible with defer functions
691
+ */
692
+ interface DeferrableQueryOptions {
693
+ queryKey: QueryKey$1;
694
+ queryFn: () => Promise<unknown>;
695
+ staleTime?: number;
696
+ gcTime?: number;
697
+ }
698
+ /**
699
+ * Start fetching queries without blocking navigation (fire-and-forget).
700
+ *
701
+ * Use this in route loaders for non-critical data. The queries will start
702
+ * fetching in the background, and components using useSuspenseQuery will
703
+ * suspend until the data is ready.
704
+ *
705
+ * @example
706
+ * ```ts
707
+ * export const Route = createFileRoute('/users/:userId')({
708
+ * loader: async ({ params, context }) => {
709
+ * const { queryClient } = context
710
+ *
711
+ * // Critical - blocks navigation until ready
712
+ * await queryClient.ensureQueryData(userQuery(params.userId))
713
+ *
714
+ * // Deferred - starts fetching without blocking navigation
715
+ * defer(queryClient,
716
+ * userActivityQuery(params.userId),
717
+ * userRecommendationsQuery(params.userId),
718
+ * )
719
+ * },
720
+ * })
721
+ * ```
722
+ */
723
+ declare function defer(queryClient: QueryClient$1, ...queries: DeferrableQueryOptions[]): void;
724
+ /**
725
+ * Start fetching queries and return promises for optional awaiting.
726
+ *
727
+ * Unlike defer(), this returns the prefetch promises, allowing you to
728
+ * optionally await them later (e.g., for analytics or debugging).
729
+ *
730
+ * @example
731
+ * ```ts
732
+ * // Start fetching
733
+ * const promises = deferWithPromises(queryClient, slowQuery1, slowQuery2)
734
+ *
735
+ * // Continue with other work...
736
+ *
737
+ * // Later, if you need to know when they complete:
738
+ * await Promise.all(promises)
739
+ * ```
740
+ */
741
+ declare function deferWithPromises(queryClient: QueryClient$1, ...queries: DeferrableQueryOptions[]): Promise<void>[];
742
+ //#endregion
743
+ //#region src/suspense.d.ts
744
+ /**
745
+ * Infer TData from QueryOptionsOutput
746
+ */
747
+ type InferQueryData<T> = T extends QueryOptionsOutput<infer TData, QueryKey$1> ? TData : never;
748
+ /**
749
+ * Return type for useSuspenseQuery with guaranteed data (not undefined after suspense resolves)
750
+ */
751
+ interface UseSuspenseQueryResult<TData> {
752
+ data: Ref<TData>;
753
+ error: Ref<Error | null>;
754
+ isLoading: Ref<boolean>;
755
+ isFetching: Ref<boolean>;
756
+ isError: Ref<boolean>;
757
+ isSuccess: Ref<boolean>;
758
+ refetch: () => Promise<TData>;
759
+ }
760
+ /**
761
+ * Suspense-compatible query hook for Vue.
762
+ *
763
+ * Returns a Promise that resolves to the query result when data is ready.
764
+ * Use with top-level await in <script setup> to trigger Suspense.
765
+ *
766
+ * @example
767
+ * ```vue
768
+ * <script setup>
769
+ * import { useSuspenseQuery } from '@kimesh/query'
770
+ * import { postsQuery } from './posts.data'
771
+ *
772
+ * // Awaiting triggers Suspense - component suspends until data ready
773
+ * // data is typed as Ref<Post[]> (not Ref<Post[] | undefined>)
774
+ * const { data: posts } = await useSuspenseQuery(postsQuery)
775
+ * </script>
776
+ *
777
+ * <template>
778
+ * <div v-for="post in posts" :key="post.id">{{ post.title }}</div>
779
+ * </template>
780
+ * ```
781
+ */
782
+ declare function useSuspenseQuery<T extends QueryOptionsOutput<unknown, QueryKey$1>>(options: T): Promise<UseSuspenseQueryResult<InferQueryData<T>>>;
783
+ /**
784
+ * Suspense-compatible infinite query hook for Vue.
785
+ *
786
+ * Note: This is a basic implementation. For full infinite query support,
787
+ * you may need to extend the options interface to include initialPageParam
788
+ * and getNextPageParam configuration.
789
+ */
790
+ declare function useSuspenseInfiniteQuery<T extends QueryOptionsOutput<unknown, QueryKey$1>>(options: T): Promise<UseInfiniteQueryReturnType<InferQueryData<T>, Error>>;
791
+ type UseSuspenseQueryReturnType<TData = unknown> = UseSuspenseQueryResult<TData>;
792
+ //#endregion
793
+ export { $fetch, type DeferrableQueryOptions, type FetchContext, type FetchError, type FetchPluginOptions, type FetchResponse, type FetchRuntimeConfig, KimeshQueryPlugin, type KimeshQueryPluginOptions, type KmAsyncDataContext, type KmAsyncDataResult, type KmFetchCreateOptions, type KmFetchInstance, type KmFetchRequestOptions, type LayerFetchPluginOptions, type LoadableComponent, type LoaderDefinition, QueryClient, type QueryKey, type QueryKeyFactory, type QueryPrefetchOptions, type UseKmAsyncDataOptions, type UseKmFetchOptions, type UseQueryReturnType, type UseSuspenseQueryReturnType, VueQueryPlugin, createKimeshQueryClient, createKmFetch, createNamedFetchPlugin, createPrefetcher, createQueryKeyFactory, defer, deferWithPromises, defineMutation, defineQuery, defineQueryOptions, executeLoader, extractLoaders, fetchPlugin, getCurrentLayer, getLayerFetch, hasLoader, initGlobalFetch, initLayerFetch, isLayerFetchInitialized, layerFetchPlugin, queryOptions, setCurrentLayer, setupQueryPrefetching, useGlobalFetch, useInfiniteQuery, useKmAsyncData, useKmData, useKmFetch, useLazyKmAsyncData, useLazyKmFetch, useMutation, useQuery, useQueryClient, useSuspenseInfiniteQuery, useSuspenseQuery };
794
+ //# sourceMappingURL=index.d.mts.map