@gettersethya/mira-tanstack-adapter 0.1.0-alpha.3 → 0.1.0-alpha.31

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 CHANGED
@@ -1,136 +1,158 @@
1
- # @gettersethya/mira-tanstack-adapter
2
-
3
- > **Early pre-alpha.** Breaking changes may occur without notice.
4
-
5
- TanStack Query adapters for [@gettersethya/mira-client](https://www.npmjs.com/package/@gettersethya/mira-client). Wraps collection client methods with `queryOptions` and `mutationOptions`, with structured query keys for fine-grained cache invalidation.
6
-
7
- Supports React, Svelte, and Solid via separate entry points.
8
-
9
- ## Installation
10
-
11
- ```bash
12
- # React
13
- npm install @gettersethya/mira-tanstack-adapter @tanstack/react-query
14
-
15
- # Svelte
16
- npm install @gettersethya/mira-tanstack-adapter @tanstack/svelte-query
17
-
18
- # Solid
19
- npm install @gettersethya/mira-tanstack-adapter @tanstack/solid-query
20
- ```
21
-
22
- `@gettersethya/mira-client` is a required peer dependency. Only install the TanStack package for the framework you use.
23
-
24
- ## Setup
25
-
26
- ```typescript
27
- import { createMiraClient } from "@gettersethya/mira-client"
28
- import { collectionAdapter } from "@gettersethya/mira-tanstack-adapter/react"
29
- // import { collectionAdapter } from "@gettersethya/mira-tanstack-adapter/svelte"
30
- // import { collectionAdapter } from "@gettersethya/mira-tanstack-adapter/solid"
31
- import { Posts } from "./collections.js"
32
-
33
- const mira = createMiraClient("/api").withCollections({ posts: Posts })
34
- const postsApi = collectionAdapter(mira, "posts")
35
- ```
36
-
37
- ## Queries
38
-
39
- ```tsx
40
- import { useQuery } from "@tanstack/react-query"
41
- import { postsApi } from "./setup.js"
42
-
43
- function PostList() {
44
- const { data, isLoading } = useQuery(
45
- postsApi.getList({
46
- filter: (f) => f.field("published").eq(true),
47
- limit: 10,
48
- }).queryOptions
49
- )
50
-
51
- if (isLoading) return <p>Loading...</p>
52
- return <ul>{data?.items.map(p => <li key={p.id}>{p.title}</li>)}</ul>
53
- }
54
-
55
- function PostDetail({ id }: { id: string }) {
56
- const { data } = useQuery(postsApi.getOne(id).queryOptions)
57
- return <h1>{data?.title}</h1>
58
- }
59
- ```
60
-
61
- ## Mutations
62
-
63
- ```tsx
64
- import { useMutation, useQueryClient } from "@tanstack/react-query"
65
- import { postsApi } from "./setup.js"
66
-
67
- function PostActions() {
68
- const queryClient = useQueryClient()
69
-
70
- const create = useMutation({
71
- ...postsApi.create().mutationOptions,
72
- onSuccess: () => postsApi.invalidateAll(queryClient),
73
- })
74
-
75
- const update = useMutation({
76
- ...postsApi.update().mutationOptions,
77
- onSuccess: (post) => postsApi.invalidateOne(queryClient, post.id),
78
- })
79
-
80
- const remove = useMutation({
81
- ...postsApi.delete().mutationOptions,
82
- onSuccess: () => postsApi.invalidateAll(queryClient),
83
- })
84
-
85
- return (
86
- <button onClick={() => create.mutate({ title: "New Post", published: false })}>
87
- Create
88
- </button>
89
- )
90
- }
91
- ```
92
-
93
- ## Svelte and Solid
94
-
95
- The API is identical across all three frameworks. Only the import path changes.
96
-
97
- ```typescript
98
- // Svelte
99
- import { collectionAdapter } from "@gettersethya/mira-tanstack-adapter/svelte"
100
- // use with createQuery / createMutation from @tanstack/svelte-query
101
-
102
- // Solid
103
- import { collectionAdapter } from "@gettersethya/mira-tanstack-adapter/solid"
104
- // use with createQuery / createMutation from @tanstack/solid-query
105
- ```
106
-
107
- ## Query key structure
108
-
109
- The adapter produces structured query keys for fine-grained cache invalidation:
110
-
111
- ```typescript
112
- // ["posts", "getList", { limit, filter, sort, order, cursor, select, expand }]
113
- // ["posts", "getOne", "post-id"]
114
- // ["posts", "getFirstOrNone", { filter, sort, order, select, expand }]
115
- // ["posts", "getFullList", { limit, filter, sort, order, select, expand }]
116
-
117
- // Invalidate all queries for a collection
118
- queryClient.invalidateQueries({ queryKey: ["posts"] })
119
-
120
- // Invalidate only list queries
121
- queryClient.invalidateQueries({ queryKey: ["posts", "getList"] })
122
-
123
- // Invalidate a specific record
124
- queryClient.invalidateQueries({ queryKey: ["posts", "getOne", "post-id"] })
125
- ```
126
-
127
- The adapter also exposes two helpers:
128
-
129
- ```typescript
130
- postsApi.invalidateAll(queryClient) // invalidates all posts queries
131
- postsApi.invalidateOne(queryClient, postId) // invalidates the getOne query for postId
132
- ```
133
-
134
- ## More
135
-
136
- See the [Mira root README](https://github.com/gettersethya/mira) for collection definitions, field types, rules, and client usage.
1
+ # @gettersethya/mira-tanstack-adapter
2
+
3
+ [![npm](https://img.shields.io/npm/v/@gettersethya/mira-tanstack-adapter)](https://www.npmjs.com/package/@gettersethya/mira-tanstack-adapter)
4
+
5
+ > **Early pre-alpha.** Breaking changes may occur without notice.
6
+
7
+ Framework-agnostic TanStack Query adapter for
8
+ [@gettersethya/mira-client](https://www.npmjs.com/package/@gettersethya/mira-client).
9
+ Wraps a collection client's methods with `queryOptions` and `mutationOptions`,
10
+ with structured query keys for fine-grained cache invalidation.
11
+
12
+ The option objects are plain `{ queryKey, queryFn }` / `{ mutationFn }` shapes,
13
+ so this package has **no runtime dependency on TanStack** — `useQuery` /
14
+ `useMutation` (React, Solid) and `createQuery` / `createMutation` (Svelte) all
15
+ accept them and infer `data`.
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ npm install @gettersethya/mira-tanstack-adapter
21
+ ```
22
+
23
+ `@gettersethya/mira-client` is a required peer dependency. Install whichever
24
+ TanStack Query package your framework uses separately.
25
+
26
+ ## Setup
27
+
28
+ Pass `collectionAdapter` to `withCollections` and every accessor is enriched in
29
+ one call:
30
+
31
+ ```typescript
32
+ import { createMiraClient } from "@gettersethya/mira-client"
33
+ import { collectionAdapter } from "@gettersethya/mira-tanstack-adapter"
34
+ import { Posts, Users } from "./collections.js"
35
+
36
+ export const client = createMiraClient("/api").withCollections(
37
+ { posts: Posts, users: Users },
38
+ { adapter: collectionAdapter },
39
+ )
40
+ ```
41
+
42
+ ## Queries
43
+
44
+ ```tsx
45
+ import { useQuery } from "@tanstack/react-query"
46
+ import { client } from "./setup.js"
47
+
48
+ function PostList() {
49
+ const { data, isLoading } = useQuery(
50
+ client.posts.getList({
51
+ filter: (f) => f.field("published").eq(true),
52
+ limit: 10,
53
+ }).queryOptions
54
+ )
55
+
56
+ if (isLoading) return <p>Loading...</p>
57
+ return <ul>{data?.items.map(p => <li key={p.id}>{p.title}</li>)}</ul>
58
+ }
59
+
60
+ function PostDetail({ id }: { id: string }) {
61
+ const { data } = useQuery(client.posts.getOne(id).queryOptions)
62
+ return <h1>{data?.title}</h1>
63
+ }
64
+ ```
65
+
66
+ ## Mutations
67
+
68
+ ```tsx
69
+ import { useMutation, useQueryClient } from "@tanstack/react-query"
70
+ import { client } from "./setup.js"
71
+
72
+ function PostActions() {
73
+ const queryClient = useQueryClient()
74
+
75
+ const create = useMutation({
76
+ ...client.posts.create().mutationOptions,
77
+ onSuccess: () => client.posts.invalidateAll(queryClient),
78
+ })
79
+
80
+ const update = useMutation({
81
+ ...client.posts.update().mutationOptions,
82
+ onSuccess: (post) => client.posts.invalidateOne(queryClient, post.id),
83
+ })
84
+
85
+ const remove = useMutation({
86
+ ...client.posts.delete().mutationOptions,
87
+ onSuccess: () => client.posts.invalidateAll(queryClient),
88
+ })
89
+
90
+ return (
91
+ <button onClick={() => create.mutate({ title: "New Post", published: false })}>
92
+ Create
93
+ </button>
94
+ )
95
+ }
96
+ ```
97
+
98
+ ## Solid and Svelte
99
+
100
+ The same call shape works everywhere — the adapter is framework-agnostic:
101
+
102
+ ```typescript
103
+ // Solid — createQuery / createMutation from @tanstack/solid-query
104
+ createQuery(() => client.posts.getList({ limit: 10 }).queryOptions)
105
+
106
+ // Svelte — reactive getters from @tanstack/svelte-query
107
+ createQuery(() => client.posts.getList({ limit: 10 }).queryOptions)
108
+ ```
109
+
110
+ ## Per-collection usage
111
+
112
+ If you prefer to adapt a single collection (for example with `createMiraClient().collection(def)`),
113
+ call the adapter directly:
114
+
115
+ ```typescript
116
+ import { collectionAdapter } from "@gettersethya/mira-tanstack-adapter"
117
+
118
+ const postsApi = collectionAdapter(client.collection(Posts), Posts.name, Posts.schema["x-collection-kind"])
119
+ ```
120
+
121
+ Or build one yourself with the framework-agnostic factory:
122
+
123
+ ```typescript
124
+ import { createCollectionAdapter } from "@gettersethya/mira-tanstack-adapter"
125
+
126
+ const collectionAdapter = createCollectionAdapter()
127
+ ```
128
+
129
+ ## Query key structure
130
+
131
+ The adapter produces structured query keys for fine-grained cache invalidation:
132
+
133
+ ```typescript
134
+ // ["posts", "getList", { limit, filter, sort, order, cursor, select, expand }]
135
+ // ["posts", "getOne", "post-id", {}]
136
+ // ["posts", "getFirstOrNone", { filter, sort, order, select, expand }]
137
+ // ["posts", "getFullList", { limit, filter, sort, order, select, expand }]
138
+
139
+ // Invalidate all queries for a collection
140
+ queryClient.invalidateQueries({ queryKey: ["posts"] })
141
+
142
+ // Invalidate only list queries
143
+ queryClient.invalidateQueries({ queryKey: ["posts", "getList"] })
144
+
145
+ // Invalidate a specific record
146
+ queryClient.invalidateQueries({ queryKey: ["posts", "getOne", "post-id"] })
147
+ ```
148
+
149
+ The adapter also exposes two helpers:
150
+
151
+ ```typescript
152
+ client.posts.invalidateAll(queryClient) // invalidates all posts queries
153
+ client.posts.invalidateOne(queryClient, postId) // invalidates the getOne query for postId
154
+ ```
155
+
156
+ ## More
157
+
158
+ See the [Mira root README](https://github.com/gettersethya/mira) for collection definitions, field types, rules, and client usage.
@@ -0,0 +1,128 @@
1
+ import type { AdaptedCollectionClient, AdaptedMutationOptions, AdaptedQueryOptions, CollectionClient, CollectionKind, FieldsMap } 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 = ["todos", "getList", { limit: 10 }]
8
+ * ```
9
+ */
10
+ export type QueryKey = ReadonlyArray<unknown>;
11
+ /**
12
+ * Shape expected by TanStack Query's `useQuery` for a query returning `T`.
13
+ *
14
+ * The adapter produces plain objects of this shape (it does not import the
15
+ * framework): `useQuery` / `createQuery` accept them directly and infer `data`.
16
+ */
17
+ export type QueryOptionsShape<T> = AdaptedQueryOptions<T>;
18
+ /**
19
+ * Shape expected by TanStack Query's `useMutation` for a mutation consuming
20
+ * `TInput` and returning `TData`.
21
+ */
22
+ export type MutationOptionsShape<TData, TInput> = AdaptedMutationOptions<TData, TInput>;
23
+ /**
24
+ * A map of human-readable action names to their string key values.
25
+ * Used internally to build structured query keys that include the action being performed.
26
+ *
27
+ * @example
28
+ * ```ts
29
+ * ActionKeys.GetList // => "getList"
30
+ * ActionKeys.GetOne // => "getOne"
31
+ * ```
32
+ */
33
+ export declare const ActionKeys: {
34
+ readonly GetList: "getList";
35
+ readonly GetOne: "getOne";
36
+ readonly GetFirstOrNone: "getFirstOrNone";
37
+ readonly GetFullList: "getFullList";
38
+ readonly Me: "me";
39
+ };
40
+ /**
41
+ * Union of all valid action key string values derived from {@link ActionKeys}.
42
+ */
43
+ export type ActionKey = (typeof ActionKeys)[keyof typeof ActionKeys];
44
+ /**
45
+ * Extends a query handler with a `queryKey` and pre-built `queryOptions` object.
46
+ *
47
+ * The returned handler retains all original methods (e.g. `raw()`, `toEffect()`)
48
+ * with `queryKey` and `queryOptions` added as extra properties via `Object.assign`.
49
+ *
50
+ * @template T - The data type returned by the underlying handler.
51
+ * @template H - The handler type, constrained to objects with a zero-arg `raw()` method returning `Promise<T>`.
52
+ * @param handler - The original handler (e.g. from `client.getList()`).
53
+ * @param key - The query key array to associate with this query.
54
+ * @returns The original handler augmented with `queryKey` and `queryOptions`.
55
+ * @see enrichMutation For the mutation equivalent.
56
+ */
57
+ export declare function enrichQuery<H extends {
58
+ raw(): Promise<unknown>;
59
+ }>(handler: H, key: QueryKey): H & {
60
+ queryKey: QueryKey;
61
+ queryOptions: {
62
+ queryKey: QueryKey;
63
+ queryFn: H["raw"];
64
+ };
65
+ };
66
+ /**
67
+ * Extends a mutation handler with a pre-built `mutationOptions` object.
68
+ *
69
+ * @template TData - The data type returned by the mutation handler.
70
+ * @template TInput - The input data type consumed by the mutation handler.
71
+ * @template H - The handler type, constrained to objects with a single-arg `raw(input)` method.
72
+ * @param handler - The original handler (e.g. from `client.create()`).
73
+ * @returns The original handler augmented with `mutationOptions`.
74
+ * @see enrichQuery For the query equivalent.
75
+ */
76
+ export declare function enrichMutation<H extends {
77
+ raw(input: never): Promise<unknown>;
78
+ }>(handler: H): H & {
79
+ mutationOptions: {
80
+ mutationFn: H["raw"];
81
+ };
82
+ };
83
+ /**
84
+ * Creates a framework-agnostic collection adapter.
85
+ *
86
+ * The adapter wraps a `CollectionClient` and enriches every query method
87
+ * (getList, getOne, getFirstOrNone, getFullList) with `queryKey` and
88
+ * `queryOptions`, and every mutation method (create, update, delete, register)
89
+ * with `mutationOptions`. The produced option objects are plain
90
+ * `{ queryKey, queryFn }` / `{ mutationFn }` shapes, accepted by TanStack Query
91
+ * in every framework — so the package has no runtime dependency on TanStack.
92
+ *
93
+ * Query keys follow a structured pattern: `[collectionName, actionKey, ...params]`,
94
+ * enabling fine-grained cache invalidation (e.g. `[name, "getOne", id]`).
95
+ *
96
+ * The returned object also exposes `invalidateAll(queryClient)` and
97
+ * `invalidateOne(queryClient, id)` helpers.
98
+ *
99
+ * @returns An adapter function that takes a `CollectionClient` and collection
100
+ * name, and returns an enhanced client with query/mutation metadata.
101
+ *
102
+ * @example
103
+ * ```ts
104
+ * import { collectionAdapter } from "@gettersethya/mira-tanstack-adapter"
105
+ * import { createMiraClient } from "@gettersethya/mira-client"
106
+ *
107
+ * const client = createMiraClient("/api").withCollections(
108
+ * { posts: PostCollection },
109
+ * { adapter: collectionAdapter },
110
+ * )
111
+ *
112
+ * const { data } = useQuery(client.posts.getList({ limit: 10 }).queryOptions)
113
+ * const mutation = useMutation(client.posts.create().mutationOptions)
114
+ * ```
115
+ *
116
+ * @see enrichQuery
117
+ * @see enrichMutation
118
+ */
119
+ export declare function createCollectionAdapter(): <F extends FieldsMap, K extends CollectionKind = "base">(client: CollectionClient<F, K>, name: string, kind: K) => AdaptedCollectionClient<F, K>;
120
+ /**
121
+ * A pre-built {@link createCollectionAdapter | collection adapter}.
122
+ *
123
+ * Framework-agnostic — the option objects it produces satisfy TanStack Query's
124
+ * `useQuery` / `useMutation` (React, Solid) and `createQuery` / `createMutation`
125
+ * (Svelte) inputs.
126
+ */
127
+ export declare const collectionAdapter: <F extends FieldsMap, K extends CollectionKind = "base">(client: CollectionClient<F, K>, name: string, kind: K) => AdaptedCollectionClient<F, K>;
128
+ //# sourceMappingURL=_core.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_core.d.ts","sourceRoot":"","sources":["../src/_core.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,uBAAuB,EAEvB,sBAAsB,EACtB,mBAAmB,EACnB,gBAAgB,EAChB,cAAc,EACd,SAAS,EAOV,MAAM,2BAA2B,CAAA;AAElC;;;;;;;GAOG;AACH,MAAM,MAAM,QAAQ,GAAG,aAAa,CAAC,OAAO,CAAC,CAAA;AAE7C;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,CAAC,CAAC,IAAI,mBAAmB,CAAC,CAAC,CAAC,CAAA;AAEzD;;;GAGG;AACH,MAAM,MAAM,oBAAoB,CAAC,KAAK,EAAE,MAAM,IAAI,sBAAsB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;AAEvF;;;;;;;;;GASG;AACH,eAAO,MAAM,UAAU;;;;;;CAMb,CAAA;AAEV;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,OAAO,UAAU,CAAC,CAAA;AAEpE;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS;IAAE,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,CAAA;CAAE,EAC/D,OAAO,EAAE,CAAC,EACV,GAAG,EAAE,QAAQ,GACZ,CAAC,GAAG;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,YAAY,EAAE;QAAE,QAAQ,EAAE,QAAQ,CAAC;QAAC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAA;KAAE,CAAA;CAAE,CAKrF;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS;IAAE,GAAG,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CAAE,EAC9E,OAAO,EAAE,CAAC,GACT,CAAC,GAAG;IAAE,eAAe,EAAE;QAAE,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAA;KAAE,CAAA;CAAE,CAInD;AAeD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,uBAAuB,KACC,CAAC,SAAS,SAAS,EAAE,CAAC,SAAS,cAAc,GAAG,MAAM,EAC1F,QAAQ,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,EAC9B,MAAM,MAAM,EACZ,MAAM,CAAC,KACN,uBAAuB,CAAC,CAAC,EAAE,CAAC,CAAC,CAsDjC;AAED;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,GAnEU,CAAC,SAAS,SAAS,EAAE,CAAC,SAAS,cAAc,mBACzE,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,QACxB,MAAM,QACN,CAAC,KACN,uBAAuB,CAAC,CAAC,EAAE,CAAC,CA+DyB,CAAA"}
package/dist/_core.js ADDED
@@ -0,0 +1,132 @@
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
+ Me: "me",
17
+ };
18
+ /**
19
+ * Extends a query handler with a `queryKey` and pre-built `queryOptions` object.
20
+ *
21
+ * The returned handler retains all original methods (e.g. `raw()`, `toEffect()`)
22
+ * with `queryKey` and `queryOptions` added as extra properties via `Object.assign`.
23
+ *
24
+ * @template T - The data type returned by the underlying handler.
25
+ * @template H - The handler type, constrained to objects with a zero-arg `raw()` method returning `Promise<T>`.
26
+ * @param handler - The original handler (e.g. from `client.getList()`).
27
+ * @param key - The query key array to associate with this query.
28
+ * @returns The original handler augmented with `queryKey` and `queryOptions`.
29
+ * @see enrichMutation For the mutation equivalent.
30
+ */
31
+ export function enrichQuery(handler, key) {
32
+ return Object.assign(handler, {
33
+ queryKey: key,
34
+ queryOptions: { queryKey: key, queryFn: () => handler.raw() }
35
+ });
36
+ }
37
+ /**
38
+ * Extends a mutation handler with a pre-built `mutationOptions` object.
39
+ *
40
+ * @template TData - The data type returned by the mutation handler.
41
+ * @template TInput - The input data type consumed by the mutation handler.
42
+ * @template H - The handler type, constrained to objects with a single-arg `raw(input)` method.
43
+ * @param handler - The original handler (e.g. from `client.create()`).
44
+ * @returns The original handler augmented with `mutationOptions`.
45
+ * @see enrichQuery For the query equivalent.
46
+ */
47
+ export function enrichMutation(handler) {
48
+ return Object.assign(handler, {
49
+ mutationOptions: { mutationFn: (input) => handler.raw(input) }
50
+ });
51
+ }
52
+ /**
53
+ * Creates a framework-agnostic collection adapter.
54
+ *
55
+ * The adapter wraps a `CollectionClient` and enriches every query method
56
+ * (getList, getOne, getFirstOrNone, getFullList) with `queryKey` and
57
+ * `queryOptions`, and every mutation method (create, update, delete, register)
58
+ * with `mutationOptions`. The produced option objects are plain
59
+ * `{ queryKey, queryFn }` / `{ mutationFn }` shapes, accepted by TanStack Query
60
+ * in every framework — so the package has no runtime dependency on TanStack.
61
+ *
62
+ * Query keys follow a structured pattern: `[collectionName, actionKey, ...params]`,
63
+ * enabling fine-grained cache invalidation (e.g. `[name, "getOne", id]`).
64
+ *
65
+ * The returned object also exposes `invalidateAll(queryClient)` and
66
+ * `invalidateOne(queryClient, id)` helpers.
67
+ *
68
+ * @returns An adapter function that takes a `CollectionClient` and collection
69
+ * name, and returns an enhanced client with query/mutation metadata.
70
+ *
71
+ * @example
72
+ * ```ts
73
+ * import { collectionAdapter } from "@gettersethya/mira-tanstack-adapter"
74
+ * import { createMiraClient } from "@gettersethya/mira-client"
75
+ *
76
+ * const client = createMiraClient("/api").withCollections(
77
+ * { posts: PostCollection },
78
+ * { adapter: collectionAdapter },
79
+ * )
80
+ *
81
+ * const { data } = useQuery(client.posts.getList({ limit: 10 }).queryOptions)
82
+ * const mutation = useMutation(client.posts.create().mutationOptions)
83
+ * ```
84
+ *
85
+ * @see enrichQuery
86
+ * @see enrichMutation
87
+ */
88
+ export function createCollectionAdapter() {
89
+ return function adaptCollectionClient(client, name, kind) {
90
+ const kindAuthAdapters = {
91
+ base: () => ({}),
92
+ view: () => ({}),
93
+ auth: (authClient) => ({
94
+ authWithPassword: () => enrichMutation(authClient.authWithPassword()),
95
+ register: () => enrichMutation(authClient.register()),
96
+ me: () => enrichQuery(authClient.me(), [name, ActionKeys.Me]),
97
+ }),
98
+ };
99
+ const authExtras = kindAuthAdapters[kind](client, name);
100
+ const common = {
101
+ fields: client.fields,
102
+ getList: (options) => enrichQuery(client.getList(options), [name, ActionKeys.GetList, options ?? {}]),
103
+ getOne: (id, options) => enrichQuery(client.getOne(id, options), [name, ActionKeys.GetOne, id, options ?? {}]),
104
+ getFirstOrNone: (filter, options) => enrichQuery(client.getFirstOrNone(filter, options), [name, ActionKeys.GetFirstOrNone, options ?? {}]),
105
+ getFullList: (options) => enrichQuery(client.getFullList(options), [name, ActionKeys.GetFullList, options ?? {}]),
106
+ create: () => enrichMutation(client.create()),
107
+ update: () => enrichMutation(client.update()),
108
+ delete: () => enrichMutation(client.delete()),
109
+ /**
110
+ * Invalidates all cached queries for this collection.
111
+ * Calls `queryClient.invalidateQueries` with key prefix `[name]`.
112
+ */
113
+ invalidateAll: (queryClient) => queryClient.invalidateQueries({ queryKey: [name] }),
114
+ /**
115
+ * Invalidates only the `getOne` cache entry for a specific record.
116
+ */
117
+ invalidateOne: (queryClient, id) => queryClient.invalidateQueries({ queryKey: [name, ActionKeys.GetOne, id] })
118
+ };
119
+ // Spread of the concrete head and the generic per-kind extras yields exactly
120
+ // `AdaptedCommon<F, K> & AdaptedAuthByKind<F>[K]` == AdaptedCollectionClient<F, K>.
121
+ return { ...common, ...authExtras };
122
+ };
123
+ }
124
+ /**
125
+ * A pre-built {@link createCollectionAdapter | collection adapter}.
126
+ *
127
+ * Framework-agnostic — the option objects it produces satisfy TanStack Query's
128
+ * `useQuery` / `useMutation` (React, Solid) and `createQuery` / `createMutation`
129
+ * (Svelte) inputs.
130
+ */
131
+ export const collectionAdapter = createCollectionAdapter();
132
+ //# 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,3 @@
1
+ export type { ActionKey, MutationOptionsShape, QueryKey, QueryOptionsShape } from "./_core.js";
2
+ export { ActionKeys, collectionAdapter, createCollectionAdapter, enrichMutation, enrichQuery } from "./_core.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,SAAS,EACT,oBAAoB,EACpB,QAAQ,EACR,iBAAiB,EAClB,MAAM,YAAY,CAAA;AACnB,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,uBAAuB,EACvB,cAAc,EACd,WAAW,EACZ,MAAM,YAAY,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export { ActionKeys, collectionAdapter, createCollectionAdapter, enrichMutation, enrichQuery } from "./_core.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,uBAAuB,EACvB,cAAc,EACd,WAAW,EACZ,MAAM,YAAY,CAAA"}
package/package.json CHANGED
@@ -1,56 +1,35 @@
1
1
  {
2
2
  "name": "@gettersethya/mira-tanstack-adapter",
3
- "version": "0.1.0-alpha.3",
3
+ "version": "0.1.0-alpha.31",
4
4
  "type": "module",
5
- "description": "TanStack Query adapters for @gettersethya/mira client SDK",
5
+ "description": "Framework-agnostic TanStack Query adapter for the @gettersethya/mira client SDK",
6
6
  "author": "Getter Sethya",
7
7
  "license": "MIT",
8
8
  "files": [
9
9
  "dist"
10
10
  ],
11
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"
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "default": "./dist/index.js"
23
15
  }
24
16
  },
25
17
  "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
- }
18
+ "@gettersethya/mira-client": "*"
41
19
  },
42
20
  "devDependencies": {
43
- "@tanstack/react-query": "^5.0.0",
21
+ "effect": "^4.0.0",
44
22
  "typescript": "^6.0.3",
45
- "vitest": "^4.1.6",
46
- "@gettersethya/mira-client": "0.1.0-alpha.3"
23
+ "vitest": "^5.0.0",
24
+ "@gettersethya/mira-client": "0.1.0-alpha.31"
47
25
  },
48
26
  "publishConfig": {
49
27
  "access": "public"
50
28
  },
51
29
  "scripts": {
52
- "build": "tsc",
30
+ "build": "node scripts/clean-dist.ts && tsc -p tsconfig.build.json && node scripts/check-exports.ts",
53
31
  "typecheck": "tsc --noEmit",
54
- "test": "vitest run"
32
+ "test": "vitest run",
33
+ "check:pack": "node scripts/check-exports.ts"
55
34
  }
56
35
  }
@@ -1,270 +0,0 @@
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
@@ -1 +0,0 @@
1
- {"version":3,"file":"_core.d.ts","sourceRoot":"","sources":["../../src/_core.ts"],"names":[],"mappings":"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"}
package/dist/src/_core.js DELETED
@@ -1,160 +0,0 @@
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
@@ -1 +0,0 @@
1
- {"version":3,"file":"_core.js","sourceRoot":"","sources":["../../src/_core.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=tanstack-core.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"tanstack-core.test.d.ts","sourceRoot":"","sources":["../../tests/tanstack-core.test.ts"],"names":[],"mappings":""}
@@ -1,123 +0,0 @@
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
@@ -1 +0,0 @@
1
- {"version":3,"file":"tanstack-core.test.js","sourceRoot":"","sources":["../../tests/tanstack-core.test.ts"],"names":[],"mappings":"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"}