@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.
- package/README.md +3 -0
- package/dist/index.d.mts +794 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +1005 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +43 -0
package/dist/index.d.mts
ADDED
|
@@ -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
|