katanakit-js 4.0.2 → 4.0.4
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 +54 -55
- package/dist/adapters/angular/index.d.ts +1 -0
- package/dist/adapters/angular/index.d.ts.map +1 -1
- package/dist/adapters/angular/index.js +1 -0
- package/dist/adapters/angular/index.js.map +1 -1
- package/dist/adapters/angular/query.d.ts +56 -73
- package/dist/adapters/angular/query.d.ts.map +1 -1
- package/dist/adapters/angular/query.js +66 -129
- package/dist/adapters/angular/query.js.map +1 -1
- package/dist/adapters/react/index.d.ts +1 -0
- package/dist/adapters/react/index.d.ts.map +1 -1
- package/dist/adapters/react/index.js +1 -0
- package/dist/adapters/react/index.js.map +1 -1
- package/dist/adapters/react/query.d.ts +27 -72
- package/dist/adapters/react/query.d.ts.map +1 -1
- package/dist/adapters/react/query.js +51 -165
- package/dist/adapters/react/query.js.map +1 -1
- package/dist/adapters/solid/index.d.ts +1 -0
- package/dist/adapters/solid/index.d.ts.map +1 -1
- package/dist/adapters/solid/index.js +1 -0
- package/dist/adapters/solid/index.js.map +1 -1
- package/dist/adapters/solid/query.d.ts +32 -74
- package/dist/adapters/solid/query.d.ts.map +1 -1
- package/dist/adapters/solid/query.js +56 -131
- package/dist/adapters/solid/query.js.map +1 -1
- package/dist/adapters/svelte/index.d.ts +1 -0
- package/dist/adapters/svelte/index.d.ts.map +1 -1
- package/dist/adapters/svelte/index.js +1 -0
- package/dist/adapters/svelte/index.js.map +1 -1
- package/dist/adapters/svelte/query.d.ts +24 -72
- package/dist/adapters/svelte/query.d.ts.map +1 -1
- package/dist/adapters/svelte/query.js +41 -135
- package/dist/adapters/svelte/query.js.map +1 -1
- package/dist/adapters/vanilla/index.d.ts +3 -0
- package/dist/adapters/vanilla/index.d.ts.map +1 -0
- package/dist/adapters/vanilla/index.js +3 -0
- package/dist/adapters/vanilla/index.js.map +1 -0
- package/dist/adapters/vanilla/query.d.ts +69 -0
- package/dist/adapters/vanilla/query.d.ts.map +1 -0
- package/dist/adapters/vanilla/query.js +76 -0
- package/dist/adapters/vanilla/query.js.map +1 -0
- package/dist/adapters/vue/index.d.ts +1 -0
- package/dist/adapters/vue/index.d.ts.map +1 -1
- package/dist/adapters/vue/index.js +1 -0
- package/dist/adapters/vue/index.js.map +1 -1
- package/dist/adapters/vue/query.d.ts +35 -86
- package/dist/adapters/vue/query.d.ts.map +1 -1
- package/dist/adapters/vue/query.js +57 -168
- package/dist/adapters/vue/query.js.map +1 -1
- package/dist/core/services/query.service.d.ts +87 -134
- package/dist/core/services/query.service.d.ts.map +1 -1
- package/dist/core/services/query.service.js +99 -378
- package/dist/core/services/query.service.js.map +1 -1
- package/package.json +10 -3
|
@@ -1,93 +1,60 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { MutationObserver, QueryObserver, } from "@tanstack/query-core";
|
|
2
|
+
import { createEffect, onCleanup } from "solid-js";
|
|
3
|
+
import { createStore } from "solid-js/store";
|
|
4
|
+
import { useQueryClient } from "../../core/services/query.service.js";
|
|
3
5
|
/**
|
|
4
|
-
* Solid primitive
|
|
5
|
-
* Integrates with the API manager — your `queryFn` typically calls `useGetApi`
|
|
6
|
-
* or `useFetch` and returns the Safe Result.
|
|
6
|
+
* Solid primitive for a cached query, backed by TanStack Query Core.
|
|
7
7
|
*
|
|
8
|
-
* @
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* Returns a reactive {@link QueryObserverResult} store — read `query.data`,
|
|
9
|
+
* `query.isPending`, `query.isError`, `query.status`, etc. directly. Pass a
|
|
10
|
+
* getter (`() => ({ queryKey, queryFn })`) to react to key changes.
|
|
11
|
+
*
|
|
12
|
+
* Call it inside a component or `createRoot` so `onCleanup` disposes the observer.
|
|
13
|
+
*
|
|
14
|
+
* @param options - TanStack query options, or a getter returning them.
|
|
15
|
+
* @param client - Optional {@link QueryClient} (defaults to the shared singleton).
|
|
16
|
+
* @returns A reactive {@link QueryObserverResult} store.
|
|
11
17
|
*
|
|
12
18
|
* @example
|
|
13
19
|
* ```tsx
|
|
14
|
-
* import {
|
|
20
|
+
* import { Show } from "solid-js";
|
|
21
|
+
* import { useQuery, useSafeQueryFn } from "katanakit-js/adapters/solid";
|
|
15
22
|
* import { useGetApi } from "katanakit-js";
|
|
16
23
|
*
|
|
17
24
|
* function Pokemon() {
|
|
18
|
-
* const
|
|
25
|
+
* const query = useQuery(() => ({
|
|
19
26
|
* queryKey: ["pokemon", 25],
|
|
20
|
-
* queryFn: () => useGetApi("pokeapi", "pokemonById", { params: { id: 25 } }),
|
|
21
|
-
* });
|
|
22
|
-
* return
|
|
23
|
-
* <
|
|
24
|
-
*
|
|
27
|
+
* queryFn: useSafeQueryFn(() => useGetApi("pokeapi", "pokemonById", { params: { id: 25 } })),
|
|
28
|
+
* }));
|
|
29
|
+
* return (
|
|
30
|
+
* <Show when={!query.isPending} fallback={<div>Loading…</div>}>
|
|
31
|
+
* <div>{query.data?.name}</div>
|
|
32
|
+
* </Show>
|
|
33
|
+
* );
|
|
25
34
|
* }
|
|
26
35
|
* ```
|
|
27
36
|
*/
|
|
28
|
-
export function useQuery(
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
const
|
|
32
|
-
const [
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
const sync = (state) => {
|
|
38
|
-
// Updater form avoids Solid's "function as value" ambiguity for generic T.
|
|
39
|
-
setData(() => state.data);
|
|
40
|
-
setError(state.error);
|
|
41
|
-
setIsLoading(state.isLoading);
|
|
42
|
-
setIsSuccess(state.isSuccess);
|
|
43
|
-
setIsError(state.isError);
|
|
44
|
-
setIsStale(state.isStale);
|
|
45
|
-
setStatus(state.status);
|
|
46
|
-
};
|
|
37
|
+
export function useQuery(options, client) {
|
|
38
|
+
const queryClient = client ?? useQueryClient();
|
|
39
|
+
const getOptions = typeof options === "function" ? options : () => options;
|
|
40
|
+
const observer = new QueryObserver(queryClient, queryClient.defaultQueryOptions(getOptions()));
|
|
41
|
+
const [state, setState] = createStore(observer.getCurrentResult());
|
|
42
|
+
const unsubscribe = observer.subscribe((result) => {
|
|
43
|
+
setState(result);
|
|
44
|
+
});
|
|
45
|
+
// Re-apply options whenever the reactive getter's dependencies change.
|
|
47
46
|
createEffect(() => {
|
|
48
|
-
|
|
49
|
-
const unsubscribe = qc.subscribe(qKey, (next) => sync(next));
|
|
50
|
-
const existing = qc.getQueryState(qKey);
|
|
51
|
-
if (existing)
|
|
52
|
-
sync(existing);
|
|
53
|
-
if (config.enabled !== false) {
|
|
54
|
-
void qc
|
|
55
|
-
.fetchQuery({
|
|
56
|
-
queryKey: qKey,
|
|
57
|
-
queryFn: config.queryFn,
|
|
58
|
-
staleTime: config.staleTime,
|
|
59
|
-
cacheTime: config.cacheTime,
|
|
60
|
-
retry: config.retry,
|
|
61
|
-
retryDelay: config.retryDelay,
|
|
62
|
-
})
|
|
63
|
-
.catch(() => {
|
|
64
|
-
// Error is already reflected in the cache state.
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
onCleanup(unsubscribe);
|
|
47
|
+
observer.setOptions(queryClient.defaultQueryOptions(getOptions()));
|
|
68
48
|
});
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
.fetchQuery({
|
|
72
|
-
queryKey: config.queryKey,
|
|
73
|
-
queryFn: config.queryFn,
|
|
74
|
-
staleTime: 0,
|
|
75
|
-
cacheTime: config.cacheTime,
|
|
76
|
-
retry: config.retry,
|
|
77
|
-
retryDelay: config.retryDelay,
|
|
78
|
-
})
|
|
79
|
-
.catch(() => {
|
|
80
|
-
// Error is already reflected in the cache state.
|
|
81
|
-
});
|
|
82
|
-
};
|
|
83
|
-
return { data, error, isLoading, isSuccess, isError, isStale, status, refetch };
|
|
49
|
+
onCleanup(unsubscribe);
|
|
50
|
+
return state;
|
|
84
51
|
}
|
|
85
52
|
/**
|
|
86
|
-
* Solid primitive for
|
|
87
|
-
* Does not cache — returns a `mutate` function that executes the mutation.
|
|
53
|
+
* Solid primitive for a mutation, backed by TanStack Query Core.
|
|
88
54
|
*
|
|
89
|
-
* @param
|
|
90
|
-
* @
|
|
55
|
+
* @param options - TanStack mutation options, or a getter returning them.
|
|
56
|
+
* @param client - Optional {@link QueryClient} (defaults to the shared singleton).
|
|
57
|
+
* @returns A reactive {@link MutationObserverResult} store.
|
|
91
58
|
*
|
|
92
59
|
* @example
|
|
93
60
|
* ```tsx
|
|
@@ -96,68 +63,26 @@ export function useQuery(config, client) {
|
|
|
96
63
|
*
|
|
97
64
|
* function CreateUser() {
|
|
98
65
|
* const qc = useQueryClient();
|
|
99
|
-
* const
|
|
66
|
+
* const mutation = useMutation(() => ({
|
|
100
67
|
* mutationFn: (name: string) => usePost("api", "createUser", { name }),
|
|
101
68
|
* onSuccess: () => qc.invalidateQueries({ queryKey: ["users"] }),
|
|
102
|
-
* });
|
|
103
|
-
* return <button disabled={
|
|
69
|
+
* }));
|
|
70
|
+
* return <button disabled={mutation.isPending} onClick={() => mutation.mutate("Ada")}>Create</button>;
|
|
104
71
|
* }
|
|
105
72
|
* ```
|
|
106
73
|
*/
|
|
107
|
-
export function useMutation(
|
|
108
|
-
const
|
|
109
|
-
const
|
|
110
|
-
const
|
|
111
|
-
const [
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
const result = await config.mutationFn(variables);
|
|
121
|
-
if (result.ok) {
|
|
122
|
-
setData(() => result.data);
|
|
123
|
-
setError(null);
|
|
124
|
-
setIsSuccess(true);
|
|
125
|
-
setStatus("success");
|
|
126
|
-
config.onSuccess?.(result.data, variables);
|
|
127
|
-
config.onSettled?.(result.data, null, variables);
|
|
128
|
-
}
|
|
129
|
-
else {
|
|
130
|
-
setData(null);
|
|
131
|
-
setError(result.error);
|
|
132
|
-
setIsError(true);
|
|
133
|
-
setStatus("error");
|
|
134
|
-
config.onError?.(result.error, variables);
|
|
135
|
-
config.onSettled?.(null, result.error, variables);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
catch (caught) {
|
|
139
|
-
const apiError = caught instanceof Error
|
|
140
|
-
? { message: caught.message, status: 0 }
|
|
141
|
-
: { message: String(caught), status: 0 };
|
|
142
|
-
setData(null);
|
|
143
|
-
setError(apiError);
|
|
144
|
-
setIsError(true);
|
|
145
|
-
setStatus("error");
|
|
146
|
-
config.onError?.(apiError, variables);
|
|
147
|
-
config.onSettled?.(null, apiError, variables);
|
|
148
|
-
}
|
|
149
|
-
finally {
|
|
150
|
-
setIsLoading(false);
|
|
151
|
-
}
|
|
152
|
-
};
|
|
153
|
-
const reset = () => {
|
|
154
|
-
setData(null);
|
|
155
|
-
setError(null);
|
|
156
|
-
setIsLoading(false);
|
|
157
|
-
setIsSuccess(false);
|
|
158
|
-
setIsError(false);
|
|
159
|
-
setStatus("idle");
|
|
160
|
-
};
|
|
161
|
-
return { data, error, isLoading, isSuccess, isError, status, mutate, reset };
|
|
74
|
+
export function useMutation(options, client) {
|
|
75
|
+
const queryClient = client ?? useQueryClient();
|
|
76
|
+
const getOptions = typeof options === "function" ? options : () => options;
|
|
77
|
+
const observer = new MutationObserver(queryClient, getOptions());
|
|
78
|
+
const [state, setState] = createStore(observer.getCurrentResult());
|
|
79
|
+
const unsubscribe = observer.subscribe((result) => {
|
|
80
|
+
setState(result);
|
|
81
|
+
});
|
|
82
|
+
createEffect(() => {
|
|
83
|
+
observer.setOptions(getOptions());
|
|
84
|
+
});
|
|
85
|
+
onCleanup(unsubscribe);
|
|
86
|
+
return state;
|
|
162
87
|
}
|
|
163
88
|
//# sourceMappingURL=query.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query.js","sourceRoot":"","sources":["../../../src/adapters/solid/query.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"query.js","sourceRoot":"","sources":["../../../src/adapters/solid/query.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,gBAAgB,EAIhB,aAAa,GAGb,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAOtE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,UAAU,QAAQ,CACvB,OAAuD,EACvD,MAAoB;IAEpB,MAAM,WAAW,GAAG,MAAM,IAAI,cAAc,EAAE,CAAC;IAC/C,MAAM,UAAU,GAAG,OAAO,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAmB,EAAE,CAAC,OAAO,CAAC;IAE3F,MAAM,QAAQ,GAAG,IAAI,aAAa,CAAC,WAAW,EAAE,WAAW,CAAC,mBAAmB,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;IAE/F,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,WAAW,CACpC,QAAQ,CAAC,gBAAgB,EAAE,CAC3B,CAAC;IAEF,MAAM,WAAW,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,MAAM,EAAE,EAAE;QACjD,QAAQ,CAAC,MAAM,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,uEAAuE;IACvE,YAAY,CAAC,GAAG,EAAE;QACjB,QAAQ,CAAC,UAAU,CAAC,WAAW,CAAC,mBAAmB,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,WAAW,CAAC,CAAC;IAEvB,OAAO,KAAK,CAAC;AACd,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,WAAW,CAC1B,OAEuE,EACvE,MAAoB;IAEpB,MAAM,WAAW,GAAG,MAAM,IAAI,cAAc,EAAE,CAAC;IAC/C,MAAM,UAAU,GAAG,OAAO,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAmB,EAAE,CAAC,OAAO,CAAC;IAE3F,MAAM,QAAQ,GAAG,IAAI,gBAAgB,CAAC,WAAW,EAAE,UAAU,EAAE,CAAC,CAAC;IAEjE,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,WAAW,CACpC,QAAQ,CAAC,gBAAgB,EAAE,CAC3B,CAAC;IAEF,MAAM,WAAW,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,MAAM,EAAE,EAAE;QACjD,QAAQ,CAAC,MAAM,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,YAAY,CAAC,GAAG,EAAE;QACjB,QAAQ,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,WAAW,CAAC,CAAC;IAEvB,OAAO,KAAK,CAAC;AACd,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/svelte/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/svelte/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,oBAAoB,EACpB,kBAAkB,EAClB,cAAc,EACd,cAAc,GACd,MAAM,sCAAsC,CAAC;AAC9C,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/svelte/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/svelte/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,oBAAoB,EACpB,kBAAkB,EAClB,cAAc,EACd,cAAc,GACd,MAAM,sCAAsC,CAAC;AAC9C,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC"}
|
|
@@ -1,94 +1,44 @@
|
|
|
1
|
+
import { type MutationObserverOptions, type MutationObserverResult, type QueryClient, type QueryObserverOptions, type QueryObserverResult } from "@tanstack/query-core";
|
|
1
2
|
import { type Readable } from "svelte/store";
|
|
2
|
-
import { type QueryClient, type QueryKey, type QueryState } from "../../core/services/query.service.js";
|
|
3
|
-
import type { ApiError, FetchResult } from "../../types/index.js";
|
|
4
|
-
/** Configuration for `useQuery` (Svelte store factory). */
|
|
5
|
-
export interface UseQueryConfig<T = unknown> {
|
|
6
|
-
/** Cache key (stable array). */
|
|
7
|
-
queryKey: QueryKey;
|
|
8
|
-
/** Fetcher function returning a Safe Result. */
|
|
9
|
-
queryFn: () => Promise<FetchResult<T>>;
|
|
10
|
-
/** Time in ms before cached data is stale (default: 0). */
|
|
11
|
-
staleTime?: number;
|
|
12
|
-
/** Time in ms to keep unused data (default: 5 min). */
|
|
13
|
-
cacheTime?: number;
|
|
14
|
-
/** Retry count on failure (default: 3). */
|
|
15
|
-
retry?: number;
|
|
16
|
-
/** Base delay for exponential backoff (default: 1000). */
|
|
17
|
-
retryDelay?: number;
|
|
18
|
-
/** Whether the query is enabled (default: true). */
|
|
19
|
-
enabled?: boolean;
|
|
20
|
-
}
|
|
21
|
-
/** Reactive return value of `useQuery` (Svelte readable stores). */
|
|
22
|
-
export interface UseQueryReturn<T = unknown> {
|
|
23
|
-
data: Readable<T | null>;
|
|
24
|
-
error: Readable<ApiError | null>;
|
|
25
|
-
isLoading: Readable<boolean>;
|
|
26
|
-
isSuccess: Readable<boolean>;
|
|
27
|
-
isError: Readable<boolean>;
|
|
28
|
-
isStale: Readable<boolean>;
|
|
29
|
-
status: Readable<QueryState<T>["status"]>;
|
|
30
|
-
/** Manually refetch the query. */
|
|
31
|
-
refetch: () => Promise<void>;
|
|
32
|
-
}
|
|
33
|
-
/** Configuration for `useMutation`. */
|
|
34
|
-
export interface UseMutationConfig<TData = unknown, TVariables = unknown> {
|
|
35
|
-
mutationFn: (variables: TVariables) => Promise<FetchResult<TData>>;
|
|
36
|
-
onSuccess?: (data: TData, variables: TVariables) => void;
|
|
37
|
-
onError?: (error: ApiError, variables: TVariables) => void;
|
|
38
|
-
onSettled?: (data: TData | null, error: ApiError | null, variables: TVariables) => void;
|
|
39
|
-
}
|
|
40
|
-
/** Reactive return value of `useMutation`. */
|
|
41
|
-
export interface UseMutationReturn<TData = unknown, TVariables = unknown> {
|
|
42
|
-
data: Readable<TData | null>;
|
|
43
|
-
error: Readable<ApiError | null>;
|
|
44
|
-
isLoading: Readable<boolean>;
|
|
45
|
-
isSuccess: Readable<boolean>;
|
|
46
|
-
isError: Readable<boolean>;
|
|
47
|
-
status: Readable<"idle" | "loading" | "success" | "error">;
|
|
48
|
-
/** Execute the mutation. */
|
|
49
|
-
mutate: (variables: TVariables) => Promise<void>;
|
|
50
|
-
/** Reset the mutation state. */
|
|
51
|
-
reset: () => void;
|
|
52
|
-
}
|
|
53
3
|
/**
|
|
54
|
-
* Svelte store factory
|
|
55
|
-
* Integrates with the API manager — your `queryFn` typically calls `useGetApi`
|
|
56
|
-
* or `useFetch` and returns the Safe Result.
|
|
4
|
+
* Svelte store factory for a cached query, backed by TanStack Query Core.
|
|
57
5
|
*
|
|
58
|
-
*
|
|
6
|
+
* Returns a `Readable` of TanStack's {@link QueryObserverResult}. Subscribe
|
|
7
|
+
* with `$query` — `$query.data`, `$query.isPending`, `$query.isError`,
|
|
8
|
+
* `$query.status`, etc.
|
|
59
9
|
*
|
|
60
|
-
* @param
|
|
61
|
-
* @param client - Optional QueryClient
|
|
62
|
-
* @returns
|
|
10
|
+
* @param options - TanStack query options (`queryKey`, `queryFn`, `staleTime`, …).
|
|
11
|
+
* @param client - Optional {@link QueryClient} (defaults to the shared singleton).
|
|
12
|
+
* @returns A `Readable` of the TanStack {@link QueryObserverResult}.
|
|
63
13
|
*
|
|
64
14
|
* @example
|
|
65
15
|
* ```svelte
|
|
66
16
|
* <script lang="ts">
|
|
67
|
-
* import { useQuery } from "katanakit-js/adapters/svelte";
|
|
17
|
+
* import { useQuery, useSafeQueryFn } from "katanakit-js/adapters/svelte";
|
|
68
18
|
* import { useGetApi } from "katanakit-js";
|
|
69
19
|
*
|
|
70
|
-
* const
|
|
20
|
+
* const query = useQuery({
|
|
71
21
|
* queryKey: ["pokemon", 25],
|
|
72
|
-
* queryFn: () => useGetApi("pokeapi", "pokemonById", { params: { id: 25 } }),
|
|
22
|
+
* queryFn: useSafeQueryFn(() => useGetApi("pokeapi", "pokemonById", { params: { id: 25 } })),
|
|
73
23
|
* });
|
|
74
24
|
* </script>
|
|
75
25
|
*
|
|
76
|
-
* {#if $
|
|
26
|
+
* {#if $query.isPending}
|
|
77
27
|
* <div>Loading…</div>
|
|
78
|
-
* {:else if $
|
|
79
|
-
* <div>{$error
|
|
28
|
+
* {:else if $query.isError}
|
|
29
|
+
* <div>{$query.error?.message}</div>
|
|
80
30
|
* {:else}
|
|
81
|
-
* <div>{$data?.name}</div>
|
|
31
|
+
* <div>{$query.data?.name}</div>
|
|
82
32
|
* {/if}
|
|
83
33
|
* ```
|
|
84
34
|
*/
|
|
85
|
-
export declare function useQuery<
|
|
35
|
+
export declare function useQuery<TQueryFnData = unknown, TError = Error, TData = TQueryFnData>(options: QueryObserverOptions<TQueryFnData, TError, TData>, client?: QueryClient): Readable<QueryObserverResult<TData, TError>>;
|
|
86
36
|
/**
|
|
87
|
-
* Svelte store factory for
|
|
88
|
-
* Does not cache — returns a `mutate` function that executes the mutation.
|
|
37
|
+
* Svelte store factory for a mutation, backed by TanStack Query Core.
|
|
89
38
|
*
|
|
90
|
-
* @param
|
|
91
|
-
* @
|
|
39
|
+
* @param options - TanStack mutation options (`mutationFn`, `onSuccess`, …).
|
|
40
|
+
* @param client - Optional {@link QueryClient} (defaults to the shared singleton).
|
|
41
|
+
* @returns A `Readable` of the TanStack {@link MutationObserverResult}.
|
|
92
42
|
*
|
|
93
43
|
* @example
|
|
94
44
|
* ```svelte
|
|
@@ -97,12 +47,14 @@ export declare function useQuery<T>(config: UseQueryConfig<T>, client?: QueryCli
|
|
|
97
47
|
* import { usePost } from "katanakit-js";
|
|
98
48
|
*
|
|
99
49
|
* const qc = useQueryClient();
|
|
100
|
-
* const
|
|
50
|
+
* const mutation = useMutation({
|
|
101
51
|
* mutationFn: (name: string) => usePost("api", "createUser", { name }),
|
|
102
52
|
* onSuccess: () => qc.invalidateQueries({ queryKey: ["users"] }),
|
|
103
53
|
* });
|
|
104
54
|
* </script>
|
|
55
|
+
*
|
|
56
|
+
* <button disabled={$mutation.isPending} on:click={() => $mutation.mutate("Ada")}>Create</button>
|
|
105
57
|
* ```
|
|
106
58
|
*/
|
|
107
|
-
export declare function useMutation<TData = unknown, TVariables = unknown>(
|
|
59
|
+
export declare function useMutation<TData = unknown, TError = Error, TVariables = void, TContext = unknown>(options: MutationObserverOptions<TData, TError, TVariables, TContext>, client?: QueryClient): Readable<MutationObserverResult<TData, TError, TVariables, TContext>>;
|
|
108
60
|
//# sourceMappingURL=query.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../../src/adapters/svelte/query.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../../src/adapters/svelte/query.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,EAC3B,KAAK,WAAW,EAEhB,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,KAAK,QAAQ,EAAY,MAAM,cAAc,CAAC;AAIvD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,QAAQ,CAAC,YAAY,GAAG,OAAO,EAAE,MAAM,GAAG,KAAK,EAAE,KAAK,GAAG,YAAY,EACpF,OAAO,EAAE,oBAAoB,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,CAAC,EAC1D,MAAM,CAAC,EAAE,WAAW,GAClB,QAAQ,CAAC,mBAAmB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAS9C;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,WAAW,CAAC,KAAK,GAAG,OAAO,EAAE,MAAM,GAAG,KAAK,EAAE,UAAU,GAAG,IAAI,EAAE,QAAQ,GAAG,OAAO,EACjG,OAAO,EAAE,uBAAuB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,CAAC,EACrE,MAAM,CAAC,EAAE,WAAW,GAClB,QAAQ,CAAC,sBAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC,CAavE"}
|
|
@@ -1,103 +1,53 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { useQueryClient
|
|
1
|
+
import { MutationObserver, QueryObserver, } from "@tanstack/query-core";
|
|
2
|
+
import { readable } from "svelte/store";
|
|
3
|
+
import { useQueryClient } from "../../core/services/query.service.js";
|
|
4
4
|
/**
|
|
5
|
-
* Svelte store factory
|
|
6
|
-
* Integrates with the API manager — your `queryFn` typically calls `useGetApi`
|
|
7
|
-
* or `useFetch` and returns the Safe Result.
|
|
5
|
+
* Svelte store factory for a cached query, backed by TanStack Query Core.
|
|
8
6
|
*
|
|
9
|
-
*
|
|
7
|
+
* Returns a `Readable` of TanStack's {@link QueryObserverResult}. Subscribe
|
|
8
|
+
* with `$query` — `$query.data`, `$query.isPending`, `$query.isError`,
|
|
9
|
+
* `$query.status`, etc.
|
|
10
10
|
*
|
|
11
|
-
* @param
|
|
12
|
-
* @param client - Optional QueryClient
|
|
13
|
-
* @returns
|
|
11
|
+
* @param options - TanStack query options (`queryKey`, `queryFn`, `staleTime`, …).
|
|
12
|
+
* @param client - Optional {@link QueryClient} (defaults to the shared singleton).
|
|
13
|
+
* @returns A `Readable` of the TanStack {@link QueryObserverResult}.
|
|
14
14
|
*
|
|
15
15
|
* @example
|
|
16
16
|
* ```svelte
|
|
17
17
|
* <script lang="ts">
|
|
18
|
-
* import { useQuery } from "katanakit-js/adapters/svelte";
|
|
18
|
+
* import { useQuery, useSafeQueryFn } from "katanakit-js/adapters/svelte";
|
|
19
19
|
* import { useGetApi } from "katanakit-js";
|
|
20
20
|
*
|
|
21
|
-
* const
|
|
21
|
+
* const query = useQuery({
|
|
22
22
|
* queryKey: ["pokemon", 25],
|
|
23
|
-
* queryFn: () => useGetApi("pokeapi", "pokemonById", { params: { id: 25 } }),
|
|
23
|
+
* queryFn: useSafeQueryFn(() => useGetApi("pokeapi", "pokemonById", { params: { id: 25 } })),
|
|
24
24
|
* });
|
|
25
25
|
* </script>
|
|
26
26
|
*
|
|
27
|
-
* {#if $
|
|
27
|
+
* {#if $query.isPending}
|
|
28
28
|
* <div>Loading…</div>
|
|
29
|
-
* {:else if $
|
|
30
|
-
* <div>{$error
|
|
29
|
+
* {:else if $query.isError}
|
|
30
|
+
* <div>{$query.error?.message}</div>
|
|
31
31
|
* {:else}
|
|
32
|
-
* <div>{$data?.name}</div>
|
|
32
|
+
* <div>{$query.data?.name}</div>
|
|
33
33
|
* {/if}
|
|
34
34
|
* ```
|
|
35
35
|
*/
|
|
36
|
-
export function useQuery(
|
|
37
|
-
const
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
const status = writable("idle");
|
|
45
|
-
const sync = (state) => {
|
|
46
|
-
data.set(state.data);
|
|
47
|
-
error.set(state.error);
|
|
48
|
-
isLoading.set(state.isLoading);
|
|
49
|
-
isSuccess.set(state.isSuccess);
|
|
50
|
-
isError.set(state.isError);
|
|
51
|
-
isStale.set(state.isStale);
|
|
52
|
-
status.set(state.status);
|
|
53
|
-
};
|
|
54
|
-
const qKey = config.queryKey;
|
|
55
|
-
const unsubscribe = qc.subscribe(qKey, (next) => sync(next));
|
|
56
|
-
const existing = qc.getQueryState(qKey);
|
|
57
|
-
if (existing)
|
|
58
|
-
sync(existing);
|
|
59
|
-
if (config.enabled !== false) {
|
|
60
|
-
void qc
|
|
61
|
-
.fetchQuery({
|
|
62
|
-
queryKey: qKey,
|
|
63
|
-
queryFn: config.queryFn,
|
|
64
|
-
staleTime: config.staleTime,
|
|
65
|
-
cacheTime: config.cacheTime,
|
|
66
|
-
retry: config.retry,
|
|
67
|
-
retryDelay: config.retryDelay,
|
|
68
|
-
})
|
|
69
|
-
.catch(() => {
|
|
70
|
-
// Error is already reflected in the cache state.
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
try {
|
|
74
|
-
onDestroy(unsubscribe);
|
|
75
|
-
}
|
|
76
|
-
catch {
|
|
77
|
-
// Not inside a component init — the caller owns teardown.
|
|
78
|
-
}
|
|
79
|
-
const refetch = async () => {
|
|
80
|
-
await qc
|
|
81
|
-
.fetchQuery({
|
|
82
|
-
queryKey: config.queryKey,
|
|
83
|
-
queryFn: config.queryFn,
|
|
84
|
-
staleTime: 0,
|
|
85
|
-
cacheTime: config.cacheTime,
|
|
86
|
-
retry: config.retry,
|
|
87
|
-
retryDelay: config.retryDelay,
|
|
88
|
-
})
|
|
89
|
-
.catch(() => {
|
|
90
|
-
// Error is already reflected in the cache state.
|
|
91
|
-
});
|
|
92
|
-
};
|
|
93
|
-
return { data, error, isLoading, isSuccess, isError, isStale, status, refetch };
|
|
36
|
+
export function useQuery(options, client) {
|
|
37
|
+
const queryClient = client ?? useQueryClient();
|
|
38
|
+
const observer = new QueryObserver(queryClient, queryClient.defaultQueryOptions(options));
|
|
39
|
+
return readable(observer.getCurrentResult(), (set) => {
|
|
40
|
+
const unsubscribe = observer.subscribe((result) => set(result));
|
|
41
|
+
set(observer.getCurrentResult());
|
|
42
|
+
return () => unsubscribe();
|
|
43
|
+
});
|
|
94
44
|
}
|
|
95
45
|
/**
|
|
96
|
-
* Svelte store factory for
|
|
97
|
-
* Does not cache — returns a `mutate` function that executes the mutation.
|
|
46
|
+
* Svelte store factory for a mutation, backed by TanStack Query Core.
|
|
98
47
|
*
|
|
99
|
-
* @param
|
|
100
|
-
* @
|
|
48
|
+
* @param options - TanStack mutation options (`mutationFn`, `onSuccess`, …).
|
|
49
|
+
* @param client - Optional {@link QueryClient} (defaults to the shared singleton).
|
|
50
|
+
* @returns A `Readable` of the TanStack {@link MutationObserverResult}.
|
|
101
51
|
*
|
|
102
52
|
* @example
|
|
103
53
|
* ```svelte
|
|
@@ -106,67 +56,23 @@ export function useQuery(config, client) {
|
|
|
106
56
|
* import { usePost } from "katanakit-js";
|
|
107
57
|
*
|
|
108
58
|
* const qc = useQueryClient();
|
|
109
|
-
* const
|
|
59
|
+
* const mutation = useMutation({
|
|
110
60
|
* mutationFn: (name: string) => usePost("api", "createUser", { name }),
|
|
111
61
|
* onSuccess: () => qc.invalidateQueries({ queryKey: ["users"] }),
|
|
112
62
|
* });
|
|
113
63
|
* </script>
|
|
64
|
+
*
|
|
65
|
+
* <button disabled={$mutation.isPending} on:click={() => $mutation.mutate("Ada")}>Create</button>
|
|
114
66
|
* ```
|
|
115
67
|
*/
|
|
116
|
-
export function useMutation(
|
|
117
|
-
const
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
isSuccess.set(false);
|
|
126
|
-
isError.set(false);
|
|
127
|
-
status.set("loading");
|
|
128
|
-
try {
|
|
129
|
-
const result = await config.mutationFn(variables);
|
|
130
|
-
if (result.ok) {
|
|
131
|
-
data.set(result.data);
|
|
132
|
-
error.set(null);
|
|
133
|
-
isSuccess.set(true);
|
|
134
|
-
status.set("success");
|
|
135
|
-
config.onSuccess?.(result.data, variables);
|
|
136
|
-
config.onSettled?.(result.data, null, variables);
|
|
137
|
-
}
|
|
138
|
-
else {
|
|
139
|
-
data.set(null);
|
|
140
|
-
error.set(result.error);
|
|
141
|
-
isError.set(true);
|
|
142
|
-
status.set("error");
|
|
143
|
-
config.onError?.(result.error, variables);
|
|
144
|
-
config.onSettled?.(null, result.error, variables);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
catch (caught) {
|
|
148
|
-
const apiError = caught instanceof Error
|
|
149
|
-
? { message: caught.message, status: 0 }
|
|
150
|
-
: { message: String(caught), status: 0 };
|
|
151
|
-
data.set(null);
|
|
152
|
-
error.set(apiError);
|
|
153
|
-
isError.set(true);
|
|
154
|
-
status.set("error");
|
|
155
|
-
config.onError?.(apiError, variables);
|
|
156
|
-
config.onSettled?.(null, apiError, variables);
|
|
157
|
-
}
|
|
158
|
-
finally {
|
|
159
|
-
isLoading.set(false);
|
|
160
|
-
}
|
|
161
|
-
};
|
|
162
|
-
const reset = () => {
|
|
163
|
-
data.set(null);
|
|
164
|
-
error.set(null);
|
|
165
|
-
isLoading.set(false);
|
|
166
|
-
isSuccess.set(false);
|
|
167
|
-
isError.set(false);
|
|
168
|
-
status.set("idle");
|
|
169
|
-
};
|
|
170
|
-
return { data, error, isLoading, isSuccess, isError, status, mutate, reset };
|
|
68
|
+
export function useMutation(options, client) {
|
|
69
|
+
const queryClient = client ?? useQueryClient();
|
|
70
|
+
const observer = new MutationObserver(queryClient, options);
|
|
71
|
+
return readable(observer.getCurrentResult(), (set) => {
|
|
72
|
+
const unsubscribe = observer.subscribe((result) => set(result));
|
|
73
|
+
// Stores are lazy: re-sync the latest result on every (re)subscribe.
|
|
74
|
+
set(observer.getCurrentResult());
|
|
75
|
+
return () => unsubscribe();
|
|
76
|
+
});
|
|
171
77
|
}
|
|
172
78
|
//# sourceMappingURL=query.js.map
|