@gettersethya/mira-tanstack-adapter 0.1.0-alpha.2
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/LICENSE +21 -0
- package/dist/src/_core.d.ts +270 -0
- package/dist/src/_core.d.ts.map +1 -0
- package/dist/src/_core.js +160 -0
- package/dist/src/_core.js.map +1 -0
- package/dist/tests/tanstack-core.test.d.ts +2 -0
- package/dist/tests/tanstack-core.test.d.ts.map +1 -0
- package/dist/tests/tanstack-core.test.js +123 -0
- package/dist/tests/tanstack-core.test.js.map +1 -0
- package/package.json +56 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Getter Sethya
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
import type { CollectionClient, FieldsMap, FilterBuilder, FilterNode } from "@gettersethya/mira-client";
|
|
2
|
+
/**
|
|
3
|
+
* A readonly array of unknown values used as a TanStack Query query key.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```ts
|
|
7
|
+
* const key: QueryKey = ["posts", "getList", { limit: 10 }]
|
|
8
|
+
* ```
|
|
9
|
+
*/
|
|
10
|
+
export type QueryKey = ReadonlyArray<unknown>;
|
|
11
|
+
/**
|
|
12
|
+
* Shape expected by TanStack Query's `queryOptions` for a query returning `T`.
|
|
13
|
+
*
|
|
14
|
+
* @template T - The data type returned by the query function.
|
|
15
|
+
*/
|
|
16
|
+
export type QueryOptionsShape<T> = {
|
|
17
|
+
queryKey: QueryKey;
|
|
18
|
+
queryFn: () => Promise<T>;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Shape expected by TanStack Query's `mutationOptions` for a mutation consuming `TInput` and returning `TData`.
|
|
22
|
+
*
|
|
23
|
+
* @template TData - The data type returned by the mutation function.
|
|
24
|
+
* @template TInput - The input data type consumed by the mutation function.
|
|
25
|
+
*/
|
|
26
|
+
export type MutationOptionsShape<TData, TInput> = {
|
|
27
|
+
mutationFn: (input: TInput) => Promise<TData>;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Signature for the framework-provided `queryOptions` factory.
|
|
31
|
+
* TanStack Query in each framework exports a `queryOptions` function that accepts
|
|
32
|
+
* a {@link QueryOptionsShape} and returns a framework-specific options object.
|
|
33
|
+
*/
|
|
34
|
+
export type MakeQueryOptions = <T>(opts: QueryOptionsShape<T>) => QueryOptionsShape<T>;
|
|
35
|
+
/**
|
|
36
|
+
* Signature for the framework-provided `mutationOptions` factory.
|
|
37
|
+
* TanStack Query in each framework exports a `mutationOptions` function that accepts
|
|
38
|
+
* a {@link MutationOptionsShape} and returns a framework-specific options object.
|
|
39
|
+
*/
|
|
40
|
+
export type MakeMutationOptions = <TData, TInput>(opts: MutationOptionsShape<TData, TInput>) => MutationOptionsShape<TData, TInput>;
|
|
41
|
+
/**
|
|
42
|
+
* A map of human-readable action names to their string key values.
|
|
43
|
+
* Used internally to build structured query keys that include the action being performed.
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```ts
|
|
47
|
+
* ActionKeys.GetList // => "getList"
|
|
48
|
+
* ActionKeys.GetOne // => "getOne"
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export declare const ActionKeys: {
|
|
52
|
+
readonly GetList: "getList";
|
|
53
|
+
readonly GetOne: "getOne";
|
|
54
|
+
readonly GetFirstOrNone: "getFirstOrNone";
|
|
55
|
+
readonly GetFullList: "getFullList";
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Union of all valid action key string values derived from {@link ActionKeys}.
|
|
59
|
+
*/
|
|
60
|
+
export type ActionKey = (typeof ActionKeys)[keyof typeof ActionKeys];
|
|
61
|
+
/**
|
|
62
|
+
* Extends a query handler with a `queryKey` and pre-built `queryOptions` object.
|
|
63
|
+
*
|
|
64
|
+
* Uses the provided {@link MakeQueryOptions} factory to convert the handler into
|
|
65
|
+
* a TanStack Query-compatible options object. The returned handler retains all
|
|
66
|
+
* original methods (e.g. `raw()`, `toEffect()`) with `queryKey` and `queryOptions`
|
|
67
|
+
* added as extra properties via `Object.assign`.
|
|
68
|
+
*
|
|
69
|
+
* @template T - The data type returned by the underlying handler.
|
|
70
|
+
* @template H - The handler type, constrained to objects with a zero-arg `raw()` method returning `Promise<T>`.
|
|
71
|
+
* @param handler - The original handler (e.g. from `client.getList()`).
|
|
72
|
+
* @param key - The query key array to associate with this query.
|
|
73
|
+
* @param makeQueryOptions - Framework-specific `queryOptions` factory.
|
|
74
|
+
* @returns The original handler augmented with `queryKey` and `queryOptions`.
|
|
75
|
+
* @see enrichMutation For the mutation equivalent.
|
|
76
|
+
*/
|
|
77
|
+
export declare function enrichQuery<T, H extends {
|
|
78
|
+
raw(): Promise<T>;
|
|
79
|
+
}>(handler: H, key: QueryKey, makeQueryOptions: MakeQueryOptions): H & {
|
|
80
|
+
queryKey: QueryKey;
|
|
81
|
+
queryOptions: QueryOptionsShape<T>;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Extends a mutation handler with a pre-built `mutationOptions` object.
|
|
85
|
+
*
|
|
86
|
+
* Uses the provided {@link MakeMutationOptions} factory to convert the handler into
|
|
87
|
+
* a TanStack Query-compatible mutation options object. The returned handler retains all
|
|
88
|
+
* original methods with `mutationOptions` added as an extra property via `Object.assign`.
|
|
89
|
+
*
|
|
90
|
+
* @template TData - The data type returned by the mutation handler.
|
|
91
|
+
* @template TInput - The input data type consumed by the mutation handler.
|
|
92
|
+
* @template H - The handler type, constrained to objects with a single-arg `raw(input)` method returning `Promise<TData>`.
|
|
93
|
+
* @param handler - The original handler (e.g. from `client.create()`).
|
|
94
|
+
* @param makeMutationOptions - Framework-specific `mutationOptions` factory.
|
|
95
|
+
* @returns The original handler augmented with `mutationOptions`.
|
|
96
|
+
* @see enrichQuery For the query equivalent.
|
|
97
|
+
*/
|
|
98
|
+
export declare function enrichMutation<TData, TInput, H extends {
|
|
99
|
+
raw(input: TInput): Promise<TData>;
|
|
100
|
+
}>(handler: H, makeMutationOptions: MakeMutationOptions): H & {
|
|
101
|
+
mutationOptions: MutationOptionsShape<TData, TInput>;
|
|
102
|
+
};
|
|
103
|
+
/**
|
|
104
|
+
* Creates a TanStack Query adapter for any {@link CollectionClient}.
|
|
105
|
+
*
|
|
106
|
+
* Returns a function that wraps a `CollectionClient` and enriches every query method
|
|
107
|
+
* (getList, getOne, getFirstOrNone, getFullList) with `queryKey` and `queryOptions`,
|
|
108
|
+
* and every mutation method (create, update, delete) with `mutationOptions`.
|
|
109
|
+
*
|
|
110
|
+
* Query keys follow a structured pattern: `[collectionName, actionKey, ...params]`.
|
|
111
|
+
* This enables fine-grained cache invalidation — for example, invalidating only
|
|
112
|
+
* `getOne` queries for a specific record by referencing key `["posts", "getOne", id]`.
|
|
113
|
+
*
|
|
114
|
+
* The returned object also exposes `invalidateAll(queryClient)` and
|
|
115
|
+
* `invalidateOne(queryClient, id)` convenience methods that call
|
|
116
|
+
* `queryClient.invalidateQueries` with the appropriate key prefix.
|
|
117
|
+
*
|
|
118
|
+
* @param makeQueryOptions - Framework-specific `queryOptions` factory
|
|
119
|
+
* (e.g. from `@tanstack/react-query`, `@tanstack/svelte-query`, or `@tanstack/solid-query`).
|
|
120
|
+
* @param makeMutationOptions - Framework-specific `mutationOptions` factory.
|
|
121
|
+
* @returns An adapter function that takes a `CollectionClient` and collection name,
|
|
122
|
+
* and returns an enhanced client with query/mutation metadata.
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* ```ts
|
|
126
|
+
* import { queryOptions, mutationOptions } from "@tanstack/react-query"
|
|
127
|
+
* import { createMiraClient } from "@gettersethya/mira-client"
|
|
128
|
+
* import { createCollectionAdapter } from "@gettersethya/mira-tanstack-adapter"
|
|
129
|
+
*
|
|
130
|
+
* const adapt = createCollectionAdapter(queryOptions, mutationOptions)
|
|
131
|
+
* const client = createMiraClient({ url: "/api" }).withCollections({ posts: PostCollection })
|
|
132
|
+
* const adapted = adapt(client, "posts")
|
|
133
|
+
*
|
|
134
|
+
* // Use in a React component:
|
|
135
|
+
* const { data } = useQuery(adapted.getList({ limit: 10 }).queryOptions)
|
|
136
|
+
* const mutation = useMutation(adapted.create().mutationOptions)
|
|
137
|
+
*
|
|
138
|
+
* // Invalidate after mutation:
|
|
139
|
+
* adapted.invalidateAll(queryClient)
|
|
140
|
+
* adapted.invalidateOne(queryClient, recordId)
|
|
141
|
+
* ```
|
|
142
|
+
*
|
|
143
|
+
* @see enrichQuery
|
|
144
|
+
* @see enrichMutation
|
|
145
|
+
* @see MakeQueryOptions
|
|
146
|
+
* @see MakeMutationOptions
|
|
147
|
+
*/
|
|
148
|
+
export declare function createCollectionAdapter(makeQueryOptions: MakeQueryOptions, makeMutationOptions: MakeMutationOptions): <F extends FieldsMap>(client: CollectionClient<F>, name: string) => {
|
|
149
|
+
/**
|
|
150
|
+
* Enriched version of `getList` that also returns `queryKey` and `queryOptions`.
|
|
151
|
+
* Query key: `[name, "getList", options]`.
|
|
152
|
+
*/
|
|
153
|
+
getList: (options?: Parameters<CollectionClient<F>["getList"]>[0]) => {
|
|
154
|
+
raw(): Promise<{
|
|
155
|
+
items: import("@gettersethya/mira-client").WithExpand<F, readonly import("@gettersethya/mira-client").RelationKeys<F>[]>[];
|
|
156
|
+
nextCursor: number | null;
|
|
157
|
+
}>;
|
|
158
|
+
toEffect(): import("effect/Effect").Effect<{
|
|
159
|
+
items: import("@gettersethya/mira-client").WithExpand<F, readonly import("@gettersethya/mira-client").RelationKeys<F>[]>[];
|
|
160
|
+
nextCursor: number | null;
|
|
161
|
+
}, import("@gettersethya/mira-client").MiraError, import("@effect/platform/HttpClient").HttpClient>;
|
|
162
|
+
} & {
|
|
163
|
+
queryKey: QueryKey;
|
|
164
|
+
queryOptions: QueryOptionsShape<unknown>;
|
|
165
|
+
};
|
|
166
|
+
/**
|
|
167
|
+
* Enriched version of `getOne` that also returns `queryKey` and `queryOptions`.
|
|
168
|
+
* Query key: `[name, "getOne", id, options]`.
|
|
169
|
+
*/
|
|
170
|
+
getOne: (id: string, options?: Parameters<CollectionClient<F>["getOne"]>[1]) => {
|
|
171
|
+
raw(): Promise<import("@gettersethya/mira-client").WithExpand<F, readonly import("@gettersethya/mira-client").RelationKeys<F>[]>>;
|
|
172
|
+
toEffect(): import("effect/Effect").Effect<import("@gettersethya/mira-client").WithExpand<F, readonly import("@gettersethya/mira-client").RelationKeys<F>[]>, import("@gettersethya/mira-client").MiraError, import("@effect/platform/HttpClient").HttpClient>;
|
|
173
|
+
} & {
|
|
174
|
+
queryKey: QueryKey;
|
|
175
|
+
queryOptions: QueryOptionsShape<unknown>;
|
|
176
|
+
};
|
|
177
|
+
/**
|
|
178
|
+
* Enriched version of `getFirstOrNone` that also returns `queryKey` and `queryOptions`.
|
|
179
|
+
* Query key: `[name, "getFirstOrNone", options]`.
|
|
180
|
+
*/
|
|
181
|
+
getFirstOrNone: (filter: (f: FilterBuilder<F>) => FilterNode, options?: Parameters<CollectionClient<F>["getFirstOrNone"]>[1]) => {
|
|
182
|
+
raw(): Promise<import("effect/Option").Option<import("@gettersethya/mira-client").WithExpand<F, readonly import("@gettersethya/mira-client").RelationKeys<F>[]>>>;
|
|
183
|
+
toEffect(): import("effect/Effect").Effect<import("effect/Option").Option<import("@gettersethya/mira-client").WithExpand<F, readonly import("@gettersethya/mira-client").RelationKeys<F>[]>>, import("@gettersethya/mira-client").MiraError, import("@effect/platform/HttpClient").HttpClient>;
|
|
184
|
+
} & {
|
|
185
|
+
queryKey: QueryKey;
|
|
186
|
+
queryOptions: QueryOptionsShape<unknown>;
|
|
187
|
+
};
|
|
188
|
+
/**
|
|
189
|
+
* Enriched version of `getFullList` that also returns `queryKey` and `queryOptions`.
|
|
190
|
+
* Query key: `[name, "getFullList", options]`.
|
|
191
|
+
*/
|
|
192
|
+
getFullList: (options?: Parameters<CollectionClient<F>["getFullList"]>[0]) => {
|
|
193
|
+
raw(): Promise<import("@gettersethya/mira-client").WithExpand<F, readonly import("@gettersethya/mira-client").RelationKeys<F>[]>[]>;
|
|
194
|
+
toEffect(): import("effect/Effect").Effect<import("@gettersethya/mira-client").WithExpand<F, readonly import("@gettersethya/mira-client").RelationKeys<F>[]>[], import("@gettersethya/mira-client").MiraError, import("@effect/platform/HttpClient").HttpClient>;
|
|
195
|
+
} & {
|
|
196
|
+
queryKey: QueryKey;
|
|
197
|
+
queryOptions: QueryOptionsShape<unknown>;
|
|
198
|
+
};
|
|
199
|
+
/**
|
|
200
|
+
* Enriched mutation for creating records. Call `raw(input)` to execute.
|
|
201
|
+
*/
|
|
202
|
+
create: () => import("@gettersethya/mira-client").ClientHandler<import("@gettersethya/mira-client").InferRecord<F>, import("@gettersethya/mira-client").InferMutationInput<F>> & {
|
|
203
|
+
mutationOptions: MutationOptionsShape<unknown, unknown>;
|
|
204
|
+
};
|
|
205
|
+
/**
|
|
206
|
+
* Enriched mutation for updating records. Call `raw(input)` to execute.
|
|
207
|
+
*/
|
|
208
|
+
update: () => {
|
|
209
|
+
raw(input: {
|
|
210
|
+
id: string;
|
|
211
|
+
data: Partial<import("@gettersethya/mira-client").InferMutationInput<F>>;
|
|
212
|
+
}): Promise<import("@gettersethya/mira-client").InferRecord<F>>;
|
|
213
|
+
toEffect(input: {
|
|
214
|
+
id: string;
|
|
215
|
+
data: Partial<import("@gettersethya/mira-client").InferMutationInput<F>>;
|
|
216
|
+
}): import("effect/Effect").Effect<import("@gettersethya/mira-client").InferRecord<F>, import("@gettersethya/mira-client").MiraError, import("@effect/platform/HttpClient").HttpClient>;
|
|
217
|
+
} & {
|
|
218
|
+
mutationOptions: MutationOptionsShape<unknown, unknown>;
|
|
219
|
+
};
|
|
220
|
+
/**
|
|
221
|
+
* Enriched mutation for deleting records. Call `raw(input)` to execute.
|
|
222
|
+
*/
|
|
223
|
+
delete: () => {
|
|
224
|
+
raw(input: string): Promise<void>;
|
|
225
|
+
toEffect(input: string): import("effect/Effect").Effect<void, import("@gettersethya/mira-client").MiraError, import("@effect/platform/HttpClient").HttpClient>;
|
|
226
|
+
} & {
|
|
227
|
+
mutationOptions: MutationOptionsShape<unknown, unknown>;
|
|
228
|
+
};
|
|
229
|
+
/**
|
|
230
|
+
* Invalidates all cached queries for this collection.
|
|
231
|
+
* Calls `queryClient.invalidateQueries` with key prefix `[name]`.
|
|
232
|
+
*
|
|
233
|
+
* @param queryClient - Any TanStack Query client with `invalidateQueries`.
|
|
234
|
+
*/
|
|
235
|
+
invalidateAll: (queryClient: {
|
|
236
|
+
invalidateQueries(opts: {
|
|
237
|
+
queryKey: QueryKey;
|
|
238
|
+
}): unknown;
|
|
239
|
+
}) => unknown;
|
|
240
|
+
/**
|
|
241
|
+
* Invalidates only the `getOne` cache entry for a specific record.
|
|
242
|
+
* Calls `queryClient.invalidateQueries` with key `[name, "getOne", id]`.
|
|
243
|
+
*
|
|
244
|
+
* @param queryClient - Any TanStack Query client with `invalidateQueries`.
|
|
245
|
+
* @param id - The record ID whose cached `getOne` entry should be invalidated.
|
|
246
|
+
*/
|
|
247
|
+
invalidateOne: (queryClient: {
|
|
248
|
+
invalidateQueries(opts: {
|
|
249
|
+
queryKey: QueryKey;
|
|
250
|
+
}): unknown;
|
|
251
|
+
}, id: string) => unknown;
|
|
252
|
+
authWithPassword?(): {
|
|
253
|
+
raw(input: {
|
|
254
|
+
email: string;
|
|
255
|
+
password: string;
|
|
256
|
+
}): Promise<{
|
|
257
|
+
token: string;
|
|
258
|
+
record: import("@gettersethya/mira-client").InferRecord<F>;
|
|
259
|
+
}>;
|
|
260
|
+
toEffect(input: {
|
|
261
|
+
email: string;
|
|
262
|
+
password: string;
|
|
263
|
+
}): import("effect/Effect").Effect<{
|
|
264
|
+
token: string;
|
|
265
|
+
record: import("@gettersethya/mira-client").InferRecord<F>;
|
|
266
|
+
}, import("@gettersethya/mira-client").MiraError, import("@effect/platform/HttpClient").HttpClient>;
|
|
267
|
+
};
|
|
268
|
+
fields: import("@gettersethya/mira-client").CollectionFileFields<F>;
|
|
269
|
+
};
|
|
270
|
+
//# sourceMappingURL=_core.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_core.d.ts","sourceRoot":"","sources":["../../src/_core.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A map of human-readable action names to their string key values.
|
|
3
|
+
* Used internally to build structured query keys that include the action being performed.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```ts
|
|
7
|
+
* ActionKeys.GetList // => "getList"
|
|
8
|
+
* ActionKeys.GetOne // => "getOne"
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
11
|
+
export const ActionKeys = {
|
|
12
|
+
GetList: "getList",
|
|
13
|
+
GetOne: "getOne",
|
|
14
|
+
GetFirstOrNone: "getFirstOrNone",
|
|
15
|
+
GetFullList: "getFullList",
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Extends a query handler with a `queryKey` and pre-built `queryOptions` object.
|
|
19
|
+
*
|
|
20
|
+
* Uses the provided {@link MakeQueryOptions} factory to convert the handler into
|
|
21
|
+
* a TanStack Query-compatible options object. The returned handler retains all
|
|
22
|
+
* original methods (e.g. `raw()`, `toEffect()`) with `queryKey` and `queryOptions`
|
|
23
|
+
* added as extra properties via `Object.assign`.
|
|
24
|
+
*
|
|
25
|
+
* @template T - The data type returned by the underlying handler.
|
|
26
|
+
* @template H - The handler type, constrained to objects with a zero-arg `raw()` method returning `Promise<T>`.
|
|
27
|
+
* @param handler - The original handler (e.g. from `client.getList()`).
|
|
28
|
+
* @param key - The query key array to associate with this query.
|
|
29
|
+
* @param makeQueryOptions - Framework-specific `queryOptions` factory.
|
|
30
|
+
* @returns The original handler augmented with `queryKey` and `queryOptions`.
|
|
31
|
+
* @see enrichMutation For the mutation equivalent.
|
|
32
|
+
*/
|
|
33
|
+
export function enrichQuery(handler, key, makeQueryOptions) {
|
|
34
|
+
return Object.assign(handler, {
|
|
35
|
+
queryKey: key,
|
|
36
|
+
queryOptions: makeQueryOptions({ queryKey: key, queryFn: () => handler.raw() }),
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Extends a mutation handler with a pre-built `mutationOptions` object.
|
|
41
|
+
*
|
|
42
|
+
* Uses the provided {@link MakeMutationOptions} factory to convert the handler into
|
|
43
|
+
* a TanStack Query-compatible mutation options object. The returned handler retains all
|
|
44
|
+
* original methods with `mutationOptions` added as an extra property via `Object.assign`.
|
|
45
|
+
*
|
|
46
|
+
* @template TData - The data type returned by the mutation handler.
|
|
47
|
+
* @template TInput - The input data type consumed by the mutation handler.
|
|
48
|
+
* @template H - The handler type, constrained to objects with a single-arg `raw(input)` method returning `Promise<TData>`.
|
|
49
|
+
* @param handler - The original handler (e.g. from `client.create()`).
|
|
50
|
+
* @param makeMutationOptions - Framework-specific `mutationOptions` factory.
|
|
51
|
+
* @returns The original handler augmented with `mutationOptions`.
|
|
52
|
+
* @see enrichQuery For the query equivalent.
|
|
53
|
+
*/
|
|
54
|
+
export function enrichMutation(handler, makeMutationOptions) {
|
|
55
|
+
return Object.assign(handler, {
|
|
56
|
+
mutationOptions: makeMutationOptions({
|
|
57
|
+
mutationFn: (input) => handler.raw(input),
|
|
58
|
+
}),
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Creates a TanStack Query adapter for any {@link CollectionClient}.
|
|
63
|
+
*
|
|
64
|
+
* Returns a function that wraps a `CollectionClient` and enriches every query method
|
|
65
|
+
* (getList, getOne, getFirstOrNone, getFullList) with `queryKey` and `queryOptions`,
|
|
66
|
+
* and every mutation method (create, update, delete) with `mutationOptions`.
|
|
67
|
+
*
|
|
68
|
+
* Query keys follow a structured pattern: `[collectionName, actionKey, ...params]`.
|
|
69
|
+
* This enables fine-grained cache invalidation — for example, invalidating only
|
|
70
|
+
* `getOne` queries for a specific record by referencing key `["posts", "getOne", id]`.
|
|
71
|
+
*
|
|
72
|
+
* The returned object also exposes `invalidateAll(queryClient)` and
|
|
73
|
+
* `invalidateOne(queryClient, id)` convenience methods that call
|
|
74
|
+
* `queryClient.invalidateQueries` with the appropriate key prefix.
|
|
75
|
+
*
|
|
76
|
+
* @param makeQueryOptions - Framework-specific `queryOptions` factory
|
|
77
|
+
* (e.g. from `@tanstack/react-query`, `@tanstack/svelte-query`, or `@tanstack/solid-query`).
|
|
78
|
+
* @param makeMutationOptions - Framework-specific `mutationOptions` factory.
|
|
79
|
+
* @returns An adapter function that takes a `CollectionClient` and collection name,
|
|
80
|
+
* and returns an enhanced client with query/mutation metadata.
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```ts
|
|
84
|
+
* import { queryOptions, mutationOptions } from "@tanstack/react-query"
|
|
85
|
+
* import { createMiraClient } from "@gettersethya/mira-client"
|
|
86
|
+
* import { createCollectionAdapter } from "@gettersethya/mira-tanstack-adapter"
|
|
87
|
+
*
|
|
88
|
+
* const adapt = createCollectionAdapter(queryOptions, mutationOptions)
|
|
89
|
+
* const client = createMiraClient({ url: "/api" }).withCollections({ posts: PostCollection })
|
|
90
|
+
* const adapted = adapt(client, "posts")
|
|
91
|
+
*
|
|
92
|
+
* // Use in a React component:
|
|
93
|
+
* const { data } = useQuery(adapted.getList({ limit: 10 }).queryOptions)
|
|
94
|
+
* const mutation = useMutation(adapted.create().mutationOptions)
|
|
95
|
+
*
|
|
96
|
+
* // Invalidate after mutation:
|
|
97
|
+
* adapted.invalidateAll(queryClient)
|
|
98
|
+
* adapted.invalidateOne(queryClient, recordId)
|
|
99
|
+
* ```
|
|
100
|
+
*
|
|
101
|
+
* @see enrichQuery
|
|
102
|
+
* @see enrichMutation
|
|
103
|
+
* @see MakeQueryOptions
|
|
104
|
+
* @see MakeMutationOptions
|
|
105
|
+
*/
|
|
106
|
+
export function createCollectionAdapter(makeQueryOptions, makeMutationOptions) {
|
|
107
|
+
return function adaptCollectionClient(client, name) {
|
|
108
|
+
return {
|
|
109
|
+
...client,
|
|
110
|
+
/**
|
|
111
|
+
* Enriched version of `getList` that also returns `queryKey` and `queryOptions`.
|
|
112
|
+
* Query key: `[name, "getList", options]`.
|
|
113
|
+
*/
|
|
114
|
+
getList: (options) => enrichQuery(client.getList(options), [name, ActionKeys.GetList, options ?? {}], makeQueryOptions),
|
|
115
|
+
/**
|
|
116
|
+
* Enriched version of `getOne` that also returns `queryKey` and `queryOptions`.
|
|
117
|
+
* Query key: `[name, "getOne", id, options]`.
|
|
118
|
+
*/
|
|
119
|
+
getOne: (id, options) => enrichQuery(client.getOne(id, options), [name, ActionKeys.GetOne, id, options ?? {}], makeQueryOptions),
|
|
120
|
+
/**
|
|
121
|
+
* Enriched version of `getFirstOrNone` that also returns `queryKey` and `queryOptions`.
|
|
122
|
+
* Query key: `[name, "getFirstOrNone", options]`.
|
|
123
|
+
*/
|
|
124
|
+
getFirstOrNone: (filter, options) => enrichQuery(client.getFirstOrNone(filter, options), [name, ActionKeys.GetFirstOrNone, options ?? {}], makeQueryOptions),
|
|
125
|
+
/**
|
|
126
|
+
* Enriched version of `getFullList` that also returns `queryKey` and `queryOptions`.
|
|
127
|
+
* Query key: `[name, "getFullList", options]`.
|
|
128
|
+
*/
|
|
129
|
+
getFullList: (options) => enrichQuery(client.getFullList(options), [name, ActionKeys.GetFullList, options ?? {}], makeQueryOptions),
|
|
130
|
+
/**
|
|
131
|
+
* Enriched mutation for creating records. Call `raw(input)` to execute.
|
|
132
|
+
*/
|
|
133
|
+
create: () => enrichMutation(client.create(), makeMutationOptions),
|
|
134
|
+
/**
|
|
135
|
+
* Enriched mutation for updating records. Call `raw(input)` to execute.
|
|
136
|
+
*/
|
|
137
|
+
update: () => enrichMutation(client.update(), makeMutationOptions),
|
|
138
|
+
/**
|
|
139
|
+
* Enriched mutation for deleting records. Call `raw(input)` to execute.
|
|
140
|
+
*/
|
|
141
|
+
delete: () => enrichMutation(client.delete(), makeMutationOptions),
|
|
142
|
+
/**
|
|
143
|
+
* Invalidates all cached queries for this collection.
|
|
144
|
+
* Calls `queryClient.invalidateQueries` with key prefix `[name]`.
|
|
145
|
+
*
|
|
146
|
+
* @param queryClient - Any TanStack Query client with `invalidateQueries`.
|
|
147
|
+
*/
|
|
148
|
+
invalidateAll: (queryClient) => queryClient.invalidateQueries({ queryKey: [name] }),
|
|
149
|
+
/**
|
|
150
|
+
* Invalidates only the `getOne` cache entry for a specific record.
|
|
151
|
+
* Calls `queryClient.invalidateQueries` with key `[name, "getOne", id]`.
|
|
152
|
+
*
|
|
153
|
+
* @param queryClient - Any TanStack Query client with `invalidateQueries`.
|
|
154
|
+
* @param id - The record ID whose cached `getOne` entry should be invalidated.
|
|
155
|
+
*/
|
|
156
|
+
invalidateOne: (queryClient, id) => queryClient.invalidateQueries({ queryKey: [name, ActionKeys.GetOne, id] }),
|
|
157
|
+
};
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=_core.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_core.js","sourceRoot":"","sources":["../../src/_core.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tanstack-core.test.d.ts","sourceRoot":"","sources":["../../tests/tanstack-core.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { Effect } from "effect";
|
|
3
|
+
import { MutableRef } from "effect";
|
|
4
|
+
import { ActionKeys, createCollectionAdapter, enrichMutation, enrichQuery } from "../src/_core.js";
|
|
5
|
+
import { makeClientHandler, makeMutationHandler } from "@gettersethya/mira-client";
|
|
6
|
+
import { makeCollectionClient } from "@gettersethya/mira-client";
|
|
7
|
+
import { BaseCollection } from "@gettersethya/mira-client";
|
|
8
|
+
import { Field } from "@gettersethya/mira-client";
|
|
9
|
+
const Posts = BaseCollection.define("posts", { title: Field.text() });
|
|
10
|
+
function makeTestClient() {
|
|
11
|
+
const execute = (req) => Effect.gen(function* () {
|
|
12
|
+
if (req.method === "DELETE")
|
|
13
|
+
return undefined;
|
|
14
|
+
if (req.url.includes("auth-with-password"))
|
|
15
|
+
return { token: "tok", record: { id: "1", created: "", updated: "", title: "" } };
|
|
16
|
+
if (req.method === "GET")
|
|
17
|
+
return { items: [], nextCursor: null };
|
|
18
|
+
return { id: "1", created: "", updated: "", title: "test" };
|
|
19
|
+
});
|
|
20
|
+
return makeCollectionClient({
|
|
21
|
+
collectionName: "posts",
|
|
22
|
+
schema: Posts.schema,
|
|
23
|
+
fields: Posts.fields,
|
|
24
|
+
execute,
|
|
25
|
+
baseUrl: "http://localhost",
|
|
26
|
+
authTokenRef: null,
|
|
27
|
+
loggedInRef: null,
|
|
28
|
+
fileTokenCacheRef: MutableRef.make(new Map()),
|
|
29
|
+
isAuth: false,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
const identity = (opts) => opts;
|
|
33
|
+
const adapter = createCollectionAdapter(identity, identity);
|
|
34
|
+
describe("ActionKeys", () => {
|
|
35
|
+
it("has the correct constant values", () => {
|
|
36
|
+
expect(ActionKeys.GetList).toBe("getList");
|
|
37
|
+
expect(ActionKeys.GetOne).toBe("getOne");
|
|
38
|
+
expect(ActionKeys.GetFirstOrNone).toBe("getFirstOrNone");
|
|
39
|
+
expect(ActionKeys.GetFullList).toBe("getFullList");
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
describe("enrichQuery", () => {
|
|
43
|
+
it("attaches queryKey and queryOptions to handler", async () => {
|
|
44
|
+
const handler = makeClientHandler(Effect.succeed(42));
|
|
45
|
+
const enriched = enrichQuery(handler, ["col", "getList", {}], identity);
|
|
46
|
+
expect(enriched.queryKey).toEqual(["col", "getList", {}]);
|
|
47
|
+
expect(enriched.queryOptions.queryKey).toEqual(["col", "getList", {}]);
|
|
48
|
+
expect(await enriched.queryOptions.queryFn()).toBe(42);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
describe("enrichMutation", () => {
|
|
52
|
+
it("attaches mutationOptions to handler", async () => {
|
|
53
|
+
const handler = makeMutationHandler((x) => Effect.succeed(x.toUpperCase()));
|
|
54
|
+
const enriched = enrichMutation(handler, identity);
|
|
55
|
+
expect(await enriched.mutationOptions.mutationFn("hello")).toBe("HELLO");
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
describe("createCollectionAdapter", () => {
|
|
59
|
+
const client = makeTestClient();
|
|
60
|
+
const adapted = adapter(client, "posts");
|
|
61
|
+
it("getList — query key shape [name, GetList, options]", () => {
|
|
62
|
+
const handler = adapted.getList({ limit: 5 });
|
|
63
|
+
expect(handler.queryKey).toEqual(["posts", ActionKeys.GetList, { limit: 5 }]);
|
|
64
|
+
});
|
|
65
|
+
it("getList with no options — options defaults to {}", () => {
|
|
66
|
+
const handler = adapted.getList();
|
|
67
|
+
expect(handler.queryKey).toEqual(["posts", ActionKeys.GetList, {}]);
|
|
68
|
+
});
|
|
69
|
+
it("getList — queryOptions.queryKey matches queryKey", () => {
|
|
70
|
+
const handler = adapted.getList();
|
|
71
|
+
expect(handler.queryOptions.queryKey).toEqual(handler.queryKey);
|
|
72
|
+
});
|
|
73
|
+
it("getList — queryOptions.queryFn resolves the raw value", async () => {
|
|
74
|
+
const handler = adapted.getList();
|
|
75
|
+
const result = await handler.queryOptions.queryFn();
|
|
76
|
+
expect(result).toEqual({ items: [], nextCursor: null });
|
|
77
|
+
});
|
|
78
|
+
it("getOne — query key shape [name, GetOne, id, options]", () => {
|
|
79
|
+
const handler = adapted.getOne("abc123");
|
|
80
|
+
expect(handler.queryKey[0]).toBe("posts");
|
|
81
|
+
expect(handler.queryKey[1]).toBe(ActionKeys.GetOne);
|
|
82
|
+
expect(handler.queryKey[2]).toBe("abc123");
|
|
83
|
+
});
|
|
84
|
+
it("getFirstOrNone — query key shape includes options", () => {
|
|
85
|
+
const handler = adapted.getFirstOrNone((f) => f.field("title").eq("hi"), { sort: "title" });
|
|
86
|
+
expect(handler.queryKey[1]).toBe(ActionKeys.GetFirstOrNone);
|
|
87
|
+
expect(handler.queryKey[2]).toEqual({ sort: "title" });
|
|
88
|
+
});
|
|
89
|
+
it("getFullList — query key shape", () => {
|
|
90
|
+
const handler = adapted.getFullList();
|
|
91
|
+
expect(handler.queryKey).toEqual(["posts", ActionKeys.GetFullList, {}]);
|
|
92
|
+
});
|
|
93
|
+
it("create — mutationOptions.mutationFn delegates to handler.raw", async () => {
|
|
94
|
+
const result = await adapted.create().mutationOptions.mutationFn({ title: "hi" });
|
|
95
|
+
expect(result).toMatchObject({ id: "1" });
|
|
96
|
+
});
|
|
97
|
+
it("update — mutationOptions.mutationFn delegates to handler.raw", async () => {
|
|
98
|
+
const result = await adapted.update().mutationOptions.mutationFn({ id: "x", data: { title: "new" } });
|
|
99
|
+
expect(result).toMatchObject({ id: "1" });
|
|
100
|
+
});
|
|
101
|
+
it("delete — mutationOptions.mutationFn delegates to handler.raw", async () => {
|
|
102
|
+
const result = await adapted.delete().mutationOptions.mutationFn("abc");
|
|
103
|
+
expect(result).toBeUndefined();
|
|
104
|
+
});
|
|
105
|
+
it("invalidateAll calls invalidateQueries with collection key", () => {
|
|
106
|
+
const calls = [];
|
|
107
|
+
const mockQC = { invalidateQueries: (opts) => { calls.push(opts); } };
|
|
108
|
+
adapted.invalidateAll(mockQC);
|
|
109
|
+
expect(calls[0]).toEqual({ queryKey: ["posts"] });
|
|
110
|
+
});
|
|
111
|
+
it("invalidateOne calls invalidateQueries with [name, GetOne, id]", () => {
|
|
112
|
+
const calls = [];
|
|
113
|
+
const mockQC = { invalidateQueries: (opts) => { calls.push(opts); } };
|
|
114
|
+
adapted.invalidateOne(mockQC, "rec-1");
|
|
115
|
+
expect(calls[0]).toEqual({ queryKey: ["posts", ActionKeys.GetOne, "rec-1"] });
|
|
116
|
+
});
|
|
117
|
+
it("non-overridden fields pass through from original client", () => {
|
|
118
|
+
const original = makeTestClient();
|
|
119
|
+
const wrapped = adapter(original, "posts");
|
|
120
|
+
expect(wrapped.fields).toBe(original.fields);
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
//# sourceMappingURL=tanstack-core.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tanstack-core.test.js","sourceRoot":"","sources":["../../tests/tanstack-core.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@gettersethya/mira-tanstack-adapter",
|
|
3
|
+
"version": "0.1.0-alpha.2",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "TanStack Query adapters for @gettersethya/mira client SDK",
|
|
6
|
+
"author": "Getter Sethya",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist"
|
|
10
|
+
],
|
|
11
|
+
"exports": {
|
|
12
|
+
"./react": {
|
|
13
|
+
"types": "./dist/react.d.ts",
|
|
14
|
+
"default": "./dist/react.js"
|
|
15
|
+
},
|
|
16
|
+
"./svelte": {
|
|
17
|
+
"types": "./dist/svelte.d.ts",
|
|
18
|
+
"default": "./dist/svelte.js"
|
|
19
|
+
},
|
|
20
|
+
"./solid": {
|
|
21
|
+
"types": "./dist/solid.d.ts",
|
|
22
|
+
"default": "./dist/solid.js"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"peerDependencies": {
|
|
26
|
+
"@gettersethya/mira-client": "*",
|
|
27
|
+
"@tanstack/react-query": ">=5.0.0",
|
|
28
|
+
"@tanstack/svelte-query": ">=5.0.0",
|
|
29
|
+
"@tanstack/solid-query": ">=5.0.0"
|
|
30
|
+
},
|
|
31
|
+
"peerDependenciesMeta": {
|
|
32
|
+
"@tanstack/react-query": {
|
|
33
|
+
"optional": true
|
|
34
|
+
},
|
|
35
|
+
"@tanstack/svelte-query": {
|
|
36
|
+
"optional": true
|
|
37
|
+
},
|
|
38
|
+
"@tanstack/solid-query": {
|
|
39
|
+
"optional": true
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@tanstack/react-query": "^5.0.0",
|
|
44
|
+
"typescript": "^6.0.3",
|
|
45
|
+
"vitest": "^4.1.6",
|
|
46
|
+
"@gettersethya/mira-client": "0.1.0-alpha.2"
|
|
47
|
+
},
|
|
48
|
+
"publishConfig": {
|
|
49
|
+
"access": "public"
|
|
50
|
+
},
|
|
51
|
+
"scripts": {
|
|
52
|
+
"build": "tsc",
|
|
53
|
+
"typecheck": "tsc --noEmit",
|
|
54
|
+
"test": "vitest run"
|
|
55
|
+
}
|
|
56
|
+
}
|