convex-route-query 0.0.1 → 0.1.0
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 +254 -29
- package/dist/index.cjs +38 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +38 -4
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +38 -4
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +39 -3
- package/dist/index.mjs.map +1 -1
- package/package.json +15 -5
package/README.md
CHANGED
|
@@ -1,72 +1,297 @@
|
|
|
1
1
|
# convex-route-query
|
|
2
2
|
|
|
3
|
-
Type-safe Convex query helpers for TanStack Router loaders and React Query
|
|
3
|
+
Type-safe Convex query helpers for TanStack Router loaders and React Query
|
|
4
|
+
Suspense.
|
|
5
|
+
|
|
6
|
+
`convex-route-query` lets a route preload a Convex query once, return the typed
|
|
7
|
+
query args as loader data, and then read the same query from the route component
|
|
8
|
+
without rebuilding params or search state.
|
|
4
9
|
|
|
5
10
|
```ts
|
|
6
|
-
import {
|
|
11
|
+
import { createFileRoute } from "@tanstack/react-router";
|
|
12
|
+
import { createConvexRouteQueries } from "convex-route-query";
|
|
7
13
|
import { api } from "../convex/_generated/api";
|
|
8
14
|
|
|
9
|
-
const listExperiences =
|
|
10
|
-
api.resume.queries.listExperiences,
|
|
11
|
-
);
|
|
15
|
+
const { listExperiences } = createConvexRouteQueries({
|
|
16
|
+
listExperiences: api.resume.queries.listExperiences,
|
|
17
|
+
});
|
|
12
18
|
|
|
13
19
|
export const Route = createFileRoute("/experience/")({
|
|
14
|
-
loader: async (
|
|
15
|
-
await listExperiences.
|
|
16
|
-
},
|
|
20
|
+
loader: async (ctx) => ({
|
|
21
|
+
...(await listExperiences.prefetchRoute(ctx)),
|
|
22
|
+
}),
|
|
17
23
|
component: ExperiencePage,
|
|
18
24
|
});
|
|
19
25
|
|
|
20
26
|
function ExperiencePage() {
|
|
21
|
-
const { data } = listExperiences.
|
|
27
|
+
const { data } = listExperiences.useSuspenseRouteQuery(Route);
|
|
22
28
|
|
|
23
29
|
return <ExperienceList experiences={data} />;
|
|
24
30
|
}
|
|
25
31
|
```
|
|
26
32
|
|
|
27
|
-
|
|
33
|
+
## Why this exists
|
|
34
|
+
|
|
35
|
+
Convex, TanStack Router, and TanStack Query fit together beautifully, but route
|
|
36
|
+
data loading can still get repetitive:
|
|
37
|
+
|
|
38
|
+
- The loader has the route params, validated search params, and `QueryClient`.
|
|
39
|
+
- The component needs the same Convex args again to call `useSuspenseQuery`.
|
|
40
|
+
- Convex query args should stay inferred from the generated `api`.
|
|
41
|
+
- `queryKey`, `queryFn`, and `staleTime` should come from `convexQuery(...)`, not
|
|
42
|
+
be rewritten by hand.
|
|
43
|
+
|
|
44
|
+
This package gives each query a stable typed route key:
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
const getPost = createConvexRouteQuery("getPost", api.blog.queries.getPost);
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The loader returns the key by spreading `prefetchRoute(...)`, and the component
|
|
51
|
+
uses that key with `useSuspenseRouteQuery(Route)`. TypeScript makes sure those
|
|
52
|
+
two sides match.
|
|
53
|
+
|
|
54
|
+
## Table of contents
|
|
55
|
+
|
|
56
|
+
- [Install](#install)
|
|
57
|
+
- [Before you start](#before-you-start)
|
|
58
|
+
- [Basic usage](#basic-usage)
|
|
59
|
+
- [Search params](#search-params)
|
|
60
|
+
- [Path params and loader work](#path-params-and-loader-work)
|
|
61
|
+
- [Non-suspense usage](#non-suspense-usage)
|
|
62
|
+
- [API reference](#api-reference)
|
|
63
|
+
- [Notes](#notes)
|
|
64
|
+
|
|
65
|
+
## Install
|
|
66
|
+
|
|
67
|
+
```sh
|
|
68
|
+
bun add convex-route-query
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
```sh
|
|
72
|
+
npm install convex-route-query
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
`convex-route-query` expects these peer dependencies to be installed in your app:
|
|
76
|
+
|
|
77
|
+
```sh
|
|
78
|
+
bun add @convex-dev/react-query @tanstack/react-query convex react
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Before you start
|
|
82
|
+
|
|
83
|
+
This package assumes Convex is already configured with TanStack Query and that
|
|
84
|
+
your TanStack Router context exposes a `queryClient` to route loaders.
|
|
85
|
+
|
|
86
|
+
If you have not wired that up yet, start with the official Convex docs:
|
|
87
|
+
|
|
88
|
+
- [Convex with TanStack Query](https://docs.convex.dev/client/tanstack/tanstack-query/)
|
|
89
|
+
- [TanStack Start quickstart](https://docs.convex.dev/quickstart/tanstack-start)
|
|
90
|
+
- [TanStack Start with Convex](https://docs.convex.dev/client/tanstack/tanstack-start/)
|
|
91
|
+
|
|
92
|
+
Once that setup is in place, `convex-route-query` gives you route-level helpers
|
|
93
|
+
on top of it.
|
|
94
|
+
|
|
95
|
+
## Basic usage
|
|
96
|
+
|
|
97
|
+
Use `createConvexRouteQueries(...)` when you want keys inferred from object
|
|
98
|
+
property names.
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
import { createFileRoute } from "@tanstack/react-router";
|
|
102
|
+
import { createConvexRouteQueries } from "convex-route-query";
|
|
103
|
+
import { api } from "../convex/_generated/api";
|
|
104
|
+
|
|
105
|
+
const { listPosts } = createConvexRouteQueries({
|
|
106
|
+
listPosts: api.blog.queries.listPosts,
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
export const Route = createFileRoute("/blog/")({
|
|
110
|
+
loader: async (ctx) => ({
|
|
111
|
+
...(await listPosts.prefetchRoute(ctx)),
|
|
112
|
+
}),
|
|
113
|
+
component: BlogIndexPage,
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
function BlogIndexPage() {
|
|
117
|
+
const { data: posts } = listPosts.useSuspenseRouteQuery(Route);
|
|
118
|
+
|
|
119
|
+
return <PostList posts={posts} />;
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
`prefetchRoute(ctx)` warms the TanStack Query cache and returns a small typed
|
|
124
|
+
loader-data fragment. `useSuspenseRouteQuery(Route)` reads that fragment from
|
|
125
|
+
`Route.useLoaderData()` and subscribes to the same Convex query.
|
|
126
|
+
|
|
127
|
+
## Search params
|
|
128
|
+
|
|
129
|
+
When search params drive the query, put the exact Convex args in
|
|
130
|
+
`loaderDeps`. TanStack Router will reload when those deps change, and
|
|
131
|
+
`prefetchRoute(ctx)` can use `ctx.deps` automatically.
|
|
28
132
|
|
|
29
133
|
```ts
|
|
30
|
-
|
|
134
|
+
import { createFileRoute } from "@tanstack/react-router";
|
|
135
|
+
import { z } from "zod";
|
|
136
|
+
import { createConvexRouteQueries } from "convex-route-query";
|
|
137
|
+
import { api } from "../convex/_generated/api";
|
|
138
|
+
|
|
139
|
+
const postsSearchSchema = z.object({
|
|
140
|
+
page: z.number().catch(1),
|
|
141
|
+
tag: z.string().catch("all"),
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
const { listPosts } = createConvexRouteQueries({
|
|
145
|
+
listPosts: api.blog.queries.listPosts,
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
export const Route = createFileRoute("/blog/")({
|
|
149
|
+
validateSearch: postsSearchSchema,
|
|
150
|
+
loaderDeps: ({ search }) => ({
|
|
151
|
+
page: search.page,
|
|
152
|
+
tag: search.tag,
|
|
153
|
+
}),
|
|
154
|
+
loader: async (ctx) => ({
|
|
155
|
+
...(await listPosts.prefetchRoute(ctx)),
|
|
156
|
+
}),
|
|
157
|
+
component: BlogIndexPage,
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
function BlogIndexPage() {
|
|
161
|
+
const { data: posts } = listPosts.useSuspenseRouteQuery(Route);
|
|
162
|
+
|
|
163
|
+
return <PostList posts={posts} />;
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
The component does not call `Route.useSearch()` or rebuild the query args. The
|
|
168
|
+
loader already serialized the typed query args for this route match.
|
|
169
|
+
|
|
170
|
+
## Path params and loader work
|
|
171
|
+
|
|
172
|
+
Use an explicit key when you only need one query, or when you prefer to name it
|
|
173
|
+
directly.
|
|
174
|
+
|
|
175
|
+
```ts
|
|
176
|
+
const getPost = createConvexRouteQuery("getPost", api.blog.queries.getPost);
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
For path params, or any loader that needs to combine params with other data, pass
|
|
180
|
+
the Convex args to `fetchRoute` or `prefetchRoute` explicitly. The component
|
|
181
|
+
still reads them from loader data.
|
|
182
|
+
|
|
183
|
+
```ts
|
|
184
|
+
import { createFileRoute, notFound } from "@tanstack/react-router";
|
|
185
|
+
import { createConvexRouteQuery } from "convex-route-query";
|
|
186
|
+
import { api } from "../convex/_generated/api";
|
|
187
|
+
|
|
188
|
+
const getPost = createConvexRouteQuery("getPost", api.blog.queries.getPost);
|
|
31
189
|
|
|
32
190
|
export const Route = createFileRoute("/blog/$slug")({
|
|
33
|
-
loader: async (
|
|
34
|
-
const post = await getPost.
|
|
35
|
-
slug: params.slug,
|
|
191
|
+
loader: async (ctx) => {
|
|
192
|
+
const post = await getPost.fetchRoute(ctx, {
|
|
193
|
+
slug: ctx.params.slug,
|
|
36
194
|
});
|
|
37
195
|
|
|
38
|
-
if (!post) {
|
|
196
|
+
if (!post.data) {
|
|
39
197
|
throw notFound();
|
|
40
198
|
}
|
|
41
199
|
|
|
42
|
-
return {
|
|
200
|
+
return {
|
|
201
|
+
...post.routeData,
|
|
202
|
+
title: post.data.title,
|
|
203
|
+
};
|
|
43
204
|
},
|
|
44
205
|
component: BlogPostPage,
|
|
45
206
|
});
|
|
46
207
|
|
|
47
208
|
function BlogPostPage() {
|
|
48
|
-
const {
|
|
49
|
-
const {
|
|
209
|
+
const { data: post } = getPost.useSuspenseRouteQuery(Route);
|
|
210
|
+
const { title } = Route.useLoaderData();
|
|
50
211
|
|
|
51
|
-
return <Post post={post} />;
|
|
212
|
+
return <Post post={post} title={title} />;
|
|
52
213
|
}
|
|
53
214
|
```
|
|
54
215
|
|
|
55
|
-
|
|
216
|
+
Your loader can keep doing normal loader work: auth, redirects, extra prefetches,
|
|
217
|
+
metadata, and anything else. Just include the route data returned by
|
|
218
|
+
`prefetchRoute(...)` or `fetchRoute(...).routeData`.
|
|
56
219
|
|
|
57
|
-
|
|
58
|
-
|
|
220
|
+
## Non-suspense usage
|
|
221
|
+
|
|
222
|
+
Use `useQuery` when a component should render its own pending state.
|
|
223
|
+
|
|
224
|
+
```ts
|
|
225
|
+
function DraftPostPage() {
|
|
226
|
+
const { slug } = Route.useParams();
|
|
227
|
+
const { data: post, isPending } = getPost.useQuery(
|
|
228
|
+
{ slug },
|
|
229
|
+
{ enabled: Boolean(slug) },
|
|
230
|
+
);
|
|
231
|
+
|
|
232
|
+
if (isPending) {
|
|
233
|
+
return <Spinner />;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return <PostEditor post={post} />;
|
|
237
|
+
}
|
|
59
238
|
```
|
|
60
239
|
|
|
61
|
-
|
|
240
|
+
`useQuery` accepts normal TanStack Query options except the generated Convex
|
|
241
|
+
options owned by this package: `queryKey`, `queryFn`, and `staleTime`.
|
|
242
|
+
|
|
243
|
+
## API reference
|
|
62
244
|
|
|
63
245
|
### `createConvexRouteQuery(query)`
|
|
64
246
|
|
|
65
|
-
|
|
247
|
+
```ts
|
|
248
|
+
const query = createConvexRouteQuery(api.someModule.someQuery);
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
Creates the low-level helper. The runtime route key is derived from the Convex
|
|
252
|
+
function name, but TypeScript only sees a general `string` key.
|
|
253
|
+
|
|
254
|
+
### `createConvexRouteQuery(id, query)`
|
|
255
|
+
|
|
256
|
+
```ts
|
|
257
|
+
const getPost = createConvexRouteQuery("getPost", api.blog.queries.getPost);
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
Creates a route-aware helper with an explicit typed key.
|
|
261
|
+
|
|
262
|
+
### `createConvexRouteQueries(queries)`
|
|
263
|
+
|
|
264
|
+
```ts
|
|
265
|
+
const { getPost, listPosts } = createConvexRouteQueries({
|
|
266
|
+
getPost: api.blog.queries.getPost,
|
|
267
|
+
listPosts: api.blog.queries.listPosts,
|
|
268
|
+
});
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
Creates route-aware helpers whose typed keys are inferred from the object keys.
|
|
272
|
+
|
|
273
|
+
### Helpers
|
|
274
|
+
|
|
275
|
+
| Helper | Use it when | Returns |
|
|
276
|
+
| ------------------------------------- | -------------------------------------------------------------- | ------------------------------------ |
|
|
277
|
+
| `options(...args)` | You need the underlying `convexQuery(...)` options. | Convex query options |
|
|
278
|
+
| `fetchQuery(queryClient, ...args)` | A loader or utility needs the query result directly. | `Promise<FunctionReturnType<Query>>` |
|
|
279
|
+
| `prefetchQuery(queryClient, ...args)` | A loader or utility should warm the cache directly. | `Promise<void>` |
|
|
280
|
+
| `fetchRoute(ctx, ...args?)` | A loader needs the result and a typed route-data fragment. | `{ data, routeData }` |
|
|
281
|
+
| `prefetchRoute(ctx, ...args?)` | A loader should warm the cache and return route data. | Typed route-data fragment |
|
|
282
|
+
| `useSuspenseRouteQuery(Route)` | A route component should read the query args from loader data. | Suspense query result |
|
|
283
|
+
| `useQuery(...args, queryOptions)` | A component wants non-suspense query state. | Query result |
|
|
284
|
+
| `useSuspenseQuery(...args)` | A component already has the args available. | Suspense query result |
|
|
285
|
+
|
|
286
|
+
The route helpers need `ctx.context.queryClient`. If no args are passed to
|
|
287
|
+
`fetchRoute` or `prefetchRoute`, the helper uses `ctx.deps`.
|
|
66
288
|
|
|
67
|
-
|
|
68
|
-
- `fetchQuery(queryClient, ...args)` - calls `queryClient.fetchQuery(...)`.
|
|
69
|
-
- `prefetchQuery(queryClient, ...args)` - calls `queryClient.prefetchQuery(...)`.
|
|
70
|
-
- `useSuspenseQuery(...args)` - calls React Query's `useSuspenseQuery(...)`.
|
|
289
|
+
## Notes
|
|
71
290
|
|
|
72
|
-
|
|
291
|
+
- This package is intentionally small. It wraps Convex queries for route loading
|
|
292
|
+
and component reads; mutations and actions should use the normal Convex and
|
|
293
|
+
TanStack Query APIs.
|
|
294
|
+
- The internal loader-data key is stable and typed from your explicit key or from
|
|
295
|
+
`createConvexRouteQueries(...)` object keys.
|
|
296
|
+
- Convex query options are generated by `@convex-dev/react-query`, including the
|
|
297
|
+
query key and infinite stale time.
|
package/dist/index.cjs
CHANGED
|
@@ -1,10 +1,21 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
let _convex_dev_react_query = require("@convex-dev/react-query");
|
|
3
3
|
let _tanstack_react_query = require("@tanstack/react-query");
|
|
4
|
+
let convex_server = require("convex/server");
|
|
4
5
|
//#region src/index.ts
|
|
5
|
-
|
|
6
|
+
const routeDataKeyPrefix = "__convexRouteQuery:";
|
|
7
|
+
function createConvexRouteQuery(idOrQuery, maybeQuery) {
|
|
8
|
+
const query = maybeQuery ?? idOrQuery;
|
|
9
|
+
const id = typeof idOrQuery === "string" ? idOrQuery : (0, convex_server.getFunctionName)(idOrQuery);
|
|
10
|
+
const loaderDataKey = `${routeDataKeyPrefix}${id}`;
|
|
6
11
|
const createOptions = _convex_dev_react_query.convexQuery;
|
|
7
12
|
const options = (...args) => createOptions(query, ...args);
|
|
13
|
+
const createLoaderData = (args) => Object.fromEntries([[loaderDataKey, args]]);
|
|
14
|
+
const getRouteArgs = (routeContext, args) => args.length > 0 ? args[0] : "deps" in routeContext && routeContext.deps !== void 0 ? routeContext.deps : {};
|
|
15
|
+
const getLoaderDataArgs = (loaderData) => {
|
|
16
|
+
if (typeof loaderData !== "object" || loaderData === null || !(loaderDataKey in loaderData)) throw new Error(`Missing convex-route-query loader data for "${String(id)}". Return the result of prefetchRoute(...) from this route's loader.`);
|
|
17
|
+
return loaderData[loaderDataKey];
|
|
18
|
+
};
|
|
8
19
|
return {
|
|
9
20
|
options,
|
|
10
21
|
fetchQuery(queryClient, ...args) {
|
|
@@ -13,12 +24,38 @@ function createConvexRouteQuery(query) {
|
|
|
13
24
|
prefetchQuery(queryClient, ...args) {
|
|
14
25
|
return queryClient.prefetchQuery(options(...args));
|
|
15
26
|
},
|
|
27
|
+
async fetchRoute(routeContext, ...args) {
|
|
28
|
+
const queryArgs = getRouteArgs(routeContext, args);
|
|
29
|
+
return {
|
|
30
|
+
data: await routeContext.context.queryClient.fetchQuery(options(...[queryArgs])),
|
|
31
|
+
routeData: createLoaderData(queryArgs)
|
|
32
|
+
};
|
|
33
|
+
},
|
|
34
|
+
async prefetchRoute(routeContext, ...args) {
|
|
35
|
+
const queryArgs = getRouteArgs(routeContext, args);
|
|
36
|
+
await routeContext.context.queryClient.prefetchQuery(options(...[queryArgs]));
|
|
37
|
+
return createLoaderData(queryArgs);
|
|
38
|
+
},
|
|
39
|
+
useQuery(...args) {
|
|
40
|
+
const [queryArgs, queryOptions] = args;
|
|
41
|
+
return (0, _tanstack_react_query.useQuery)({
|
|
42
|
+
...queryOptions,
|
|
43
|
+
...options(...[queryArgs])
|
|
44
|
+
});
|
|
45
|
+
},
|
|
46
|
+
useSuspenseRouteQuery(route) {
|
|
47
|
+
return (0, _tanstack_react_query.useSuspenseQuery)(options(...[getLoaderDataArgs(route.useLoaderData())]));
|
|
48
|
+
},
|
|
16
49
|
useSuspenseQuery(...args) {
|
|
17
50
|
return (0, _tanstack_react_query.useSuspenseQuery)(options(...args));
|
|
18
51
|
}
|
|
19
52
|
};
|
|
20
53
|
}
|
|
54
|
+
function createConvexRouteQueries(queries) {
|
|
55
|
+
return Object.fromEntries(Object.entries(queries).map(([id, query]) => [id, createConvexRouteQuery(id, query)]));
|
|
56
|
+
}
|
|
21
57
|
//#endregion
|
|
58
|
+
exports.createConvexRouteQueries = createConvexRouteQueries;
|
|
22
59
|
exports.createConvexRouteQuery = createConvexRouteQuery;
|
|
23
60
|
|
|
24
61
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["convexQuery"],"sources":["../src/index.ts"],"sourcesContent":["import { convexQuery } from \"@convex-dev/react-query\";\nimport {\n useSuspenseQuery as useTanStackSuspenseQuery,\n type UseSuspenseQueryResult,\n} from \"@tanstack/react-query\";\nimport type {\n FunctionArgs,\n FunctionReference,\n FunctionReturnType,\n OptionalRestArgs,\n} from \"convex/server\";\n\nexport type ConvexRouteQueryOptions<Query extends FunctionReference<\"query\">> =\n {\n queryKey: [\"convexQuery\", Query, FunctionArgs<Query>];\n staleTime: number;\n };\n\nexport type ConvexRouteQuery<Query extends FunctionReference<\"query\">> = {\n options: (...args: OptionalRestArgs<Query>) => ConvexRouteQueryOptions<Query>;\n fetchQuery: (\n queryClient: ConvexRouteQueryClient<Query>,\n ...args: OptionalRestArgs<Query>\n ) => Promise<FunctionReturnType<Query>>;\n prefetchQuery: (\n queryClient: ConvexRouteQueryClient<Query>,\n ...args: OptionalRestArgs<Query>\n ) => Promise<void>;\n useSuspenseQuery: (\n ...args: OptionalRestArgs<Query>\n ) => UseSuspenseQueryResult<FunctionReturnType<Query>, Error>;\n};\n\nexport type ConvexRouteQueryClient<Query extends FunctionReference<\"query\">> = {\n fetchQuery: (options: ConvexRouteQueryOptions<Query>) => Promise<unknown>;\n prefetchQuery: (options: ConvexRouteQueryOptions<Query>) => Promise<void>;\n};\n\ntype CreateConvexQueryOptions<Query extends FunctionReference<\"query\">> = (\n query: Query,\n ...args: OptionalRestArgs<Query>\n) => ConvexRouteQueryOptions<Query>;\n\nexport function createConvexRouteQuery<\n Query extends FunctionReference<\"query\">,\n>(query: Query): ConvexRouteQuery<Query> {\n const createOptions =\n convexQuery as unknown as CreateConvexQueryOptions<Query>;\n const options = (...args: OptionalRestArgs<Query>) =>\n createOptions(query, ...args);\n\n return {\n options,\n fetchQuery(queryClient, ...args) {\n return queryClient.fetchQuery(options(...args)) as Promise<\n FunctionReturnType<Query>\n >;\n },\n prefetchQuery(queryClient, ...args) {\n return queryClient.prefetchQuery(options(...args));\n },\n useSuspenseQuery(...args) {\n return useTanStackSuspenseQuery(options(...args));\n },\n };\n}\n"],"mappings":";;;;AA2CA,SAAgB,uBAEd,OAAuC;CACvC,MAAM,gBACJA,wBAAAA;CACF,MAAM,WAAW,GAAG,SAClB,cAAc,OAAO,GAAG,IAAI;CAE9B,OAAO;EACL;EACA,WAAW,aAAa,GAAG,MAAM;GAC/B,OAAO,YAAY,WAAW,QAAQ,GAAG,IAAI,CAAC;EAGhD;EACA,cAAc,aAAa,GAAG,MAAM;GAClC,OAAO,YAAY,cAAc,QAAQ,GAAG,IAAI,CAAC;EACnD;EACA,iBAAiB,GAAG,MAAM;GACxB,QAAA,GAAA,sBAAA,iBAAA,CAAgC,QAAQ,GAAG,IAAI,CAAC;EAClD;CACF;AACF"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["convexQuery","routeArgs"],"sources":["../src/index.ts"],"sourcesContent":["import { convexQuery } from \"@convex-dev/react-query\";\nimport {\n useQuery as useTanStackQuery,\n useSuspenseQuery as useTanStackSuspenseQuery,\n type UseQueryOptions,\n type UseQueryResult,\n type UseSuspenseQueryResult,\n} from \"@tanstack/react-query\";\nimport {\n getFunctionName,\n type ArgsAndOptions,\n type FunctionArgs,\n type FunctionReference,\n type FunctionReturnType,\n type OptionalRestArgs,\n} from \"convex/server\";\n\nconst routeDataKeyPrefix = \"__convexRouteQuery:\";\n\nexport type ConvexRouteQueryLoaderKey<Id extends string> =\n `${typeof routeDataKeyPrefix}${Id}`;\n\nexport type ConvexRouteQueryLoaderData<\n Id extends string,\n Query extends FunctionReference<\"query\">,\n> = Record<ConvexRouteQueryLoaderKey<Id>, FunctionArgs<Query>>;\n\nexport type ConvexRouteQueryOptions<Query extends FunctionReference<\"query\">> =\n {\n queryKey: [\"convexQuery\", Query, FunctionArgs<Query>];\n staleTime: number;\n };\n\nexport type ConvexRouteUseQueryOptions<\n Query extends FunctionReference<\"query\">,\n Data = FunctionReturnType<Query>,\n> = Omit<\n UseQueryOptions<\n FunctionReturnType<Query>,\n Error,\n Data,\n ConvexRouteQueryOptions<Query>[\"queryKey\"]\n >,\n \"queryKey\" | \"queryFn\" | \"staleTime\"\n>;\n\nexport type ConvexRouteQuery<\n Query extends FunctionReference<\"query\">,\n Id extends string = string,\n> = {\n options: (...args: OptionalRestArgs<Query>) => ConvexRouteQueryOptions<Query>;\n fetchQuery: (\n queryClient: ConvexRouteQueryClient<Query>,\n ...args: OptionalRestArgs<Query>\n ) => Promise<FunctionReturnType<Query>>;\n prefetchQuery: (\n queryClient: ConvexRouteQueryClient<Query>,\n ...args: OptionalRestArgs<Query>\n ) => Promise<void>;\n fetchRoute: {\n (\n routeContext: ConvexRouteQueryRouteContext<Query>,\n ): Promise<ConvexRouteQueryFetchRouteResult<Id, Query>>;\n (\n routeContext: ConvexRouteQueryClientContext<Query>,\n ...args: OptionalRestArgs<Query>\n ): Promise<ConvexRouteQueryFetchRouteResult<Id, Query>>;\n };\n prefetchRoute: {\n (\n routeContext: ConvexRouteQueryRouteContext<Query>,\n ): Promise<ConvexRouteQueryLoaderData<Id, Query>>;\n (\n routeContext: ConvexRouteQueryClientContext<Query>,\n ...args: OptionalRestArgs<Query>\n ): Promise<ConvexRouteQueryLoaderData<Id, Query>>;\n };\n useQuery: <Data = FunctionReturnType<Query>>(\n ...args: ArgsAndOptions<Query, ConvexRouteUseQueryOptions<Query, Data>>\n ) => UseQueryResult<Data, Error>;\n useSuspenseRouteQuery: (\n route: ConvexRouteQueryRoute<Id, Query>,\n ) => UseSuspenseQueryResult<FunctionReturnType<Query>, Error>;\n useSuspenseQuery: (\n ...args: OptionalRestArgs<Query>\n ) => UseSuspenseQueryResult<FunctionReturnType<Query>, Error>;\n};\n\nexport type ConvexRouteQueryClient<Query extends FunctionReference<\"query\">> = {\n fetchQuery: (options: ConvexRouteQueryOptions<Query>) => Promise<unknown>;\n prefetchQuery: (options: ConvexRouteQueryOptions<Query>) => Promise<void>;\n};\n\nexport type ConvexRouteQueryClientContext<\n Query extends FunctionReference<\"query\">,\n> = {\n context: {\n queryClient: ConvexRouteQueryClient<Query>;\n };\n};\n\ntype ConvexRouteQueryRouteDeps<Query extends FunctionReference<\"query\">> =\n keyof FunctionArgs<Query> extends never\n ? {\n deps?: FunctionArgs<Query>;\n }\n : {\n deps: FunctionArgs<Query>;\n };\n\nexport type ConvexRouteQueryRouteContext<\n Query extends FunctionReference<\"query\">,\n> = ConvexRouteQueryClientContext<Query> & ConvexRouteQueryRouteDeps<Query>;\n\nexport type ConvexRouteQueryFetchRouteResult<\n Id extends string,\n Query extends FunctionReference<\"query\">,\n> = {\n data: FunctionReturnType<Query>;\n routeData: ConvexRouteQueryLoaderData<Id, Query>;\n};\n\nexport type ConvexRouteQueryRoute<\n Id extends string,\n Query extends FunctionReference<\"query\">,\n> = {\n useLoaderData: () => ConvexRouteQueryLoaderData<Id, Query>;\n};\n\ntype CreateConvexQueryOptions<Query extends FunctionReference<\"query\">> = (\n query: Query,\n ...args: OptionalRestArgs<Query>\n) => ConvexRouteQueryOptions<Query>;\n\nexport function createConvexRouteQuery<\n Query extends FunctionReference<\"query\">,\n>(query: Query): ConvexRouteQuery<Query>;\nexport function createConvexRouteQuery<\n const Id extends string,\n Query extends FunctionReference<\"query\">,\n>(id: Id, query: Query): ConvexRouteQuery<Query, Id>;\nexport function createConvexRouteQuery<\n const Id extends string,\n Query extends FunctionReference<\"query\">,\n>(\n idOrQuery: Id | Query,\n maybeQuery?: Query,\n): ConvexRouteQuery<Query, Id | string> {\n const query = (maybeQuery ?? idOrQuery) as Query;\n const id =\n typeof idOrQuery === \"string\"\n ? idOrQuery\n : getFunctionName(idOrQuery as Query);\n const loaderDataKey =\n `${routeDataKeyPrefix}${id}` as ConvexRouteQueryLoaderKey<Id | string>;\n const createOptions =\n convexQuery as unknown as CreateConvexQueryOptions<Query>;\n const options = (...args: OptionalRestArgs<Query>) =>\n createOptions(query, ...args);\n const createLoaderData = (args: FunctionArgs<Query>) =>\n Object.fromEntries([\n [loaderDataKey, args],\n ]) as unknown as ConvexRouteQueryLoaderData<Id | string, Query>;\n const getRouteArgs = (\n routeContext:\n | ConvexRouteQueryClientContext<Query>\n | ConvexRouteQueryRouteContext<Query>,\n args: OptionalRestArgs<Query>,\n ) =>\n (args.length > 0\n ? args[0]\n : \"deps\" in routeContext && routeContext.deps !== undefined\n ? routeContext.deps\n : {}) as FunctionArgs<Query>;\n const getLoaderDataArgs = (\n loaderData: ConvexRouteQueryLoaderData<Id, Query>,\n ) => {\n if (\n typeof loaderData !== \"object\" ||\n loaderData === null ||\n !(loaderDataKey in loaderData)\n ) {\n throw new Error(\n `Missing convex-route-query loader data for \"${String(id)}\". Return the result of prefetchRoute(...) from this route's loader.`,\n );\n }\n\n return loaderData[\n loaderDataKey as keyof typeof loaderData\n ] as FunctionArgs<Query>;\n };\n\n return {\n options,\n fetchQuery(queryClient, ...args) {\n return queryClient.fetchQuery(options(...args)) as Promise<\n FunctionReturnType<Query>\n >;\n },\n prefetchQuery(queryClient, ...args) {\n return queryClient.prefetchQuery(options(...args));\n },\n async fetchRoute(routeContext, ...args) {\n const routeArgs = args as OptionalRestArgs<Query>;\n const queryArgs = getRouteArgs(routeContext, routeArgs);\n const data = await routeContext.context.queryClient.fetchQuery(\n options(...([queryArgs] as OptionalRestArgs<Query>)),\n );\n\n return {\n data: data as FunctionReturnType<Query>,\n routeData: createLoaderData(queryArgs),\n };\n },\n async prefetchRoute(routeContext, ...args) {\n const routeArgs = args as OptionalRestArgs<Query>;\n const queryArgs = getRouteArgs(routeContext, routeArgs);\n\n await routeContext.context.queryClient.prefetchQuery(\n options(...([queryArgs] as OptionalRestArgs<Query>)),\n );\n\n return createLoaderData(queryArgs);\n },\n useQuery(...args) {\n const [queryArgs, queryOptions] = args;\n\n return useTanStackQuery({\n ...queryOptions,\n ...options(...([queryArgs] as OptionalRestArgs<Query>)),\n });\n },\n useSuspenseRouteQuery(route) {\n const loaderData = route.useLoaderData();\n const queryArgs = getLoaderDataArgs(loaderData);\n\n return useTanStackSuspenseQuery(\n options(...([queryArgs] as OptionalRestArgs<Query>)),\n );\n },\n useSuspenseQuery(...args) {\n return useTanStackSuspenseQuery(options(...args));\n },\n };\n}\n\nexport function createConvexRouteQueries<\n const Queries extends Record<string, FunctionReference<\"query\">>,\n>(\n queries: Queries,\n): {\n [Id in keyof Queries & string]: ConvexRouteQuery<Queries[Id], Id>;\n} {\n return Object.fromEntries(\n Object.entries(queries).map(([id, query]) => [\n id,\n createConvexRouteQuery(id, query),\n ]),\n ) as unknown as {\n [Id in keyof Queries & string]: ConvexRouteQuery<Queries[Id], Id>;\n };\n}\n"],"mappings":";;;;;AAiBA,MAAM,qBAAqB;AA4H3B,SAAgB,uBAId,WACA,YACsC;CACtC,MAAM,QAAS,cAAc;CAC7B,MAAM,KACJ,OAAO,cAAc,WACjB,aAAA,GAAA,cAAA,gBAAA,CACgB,SAAkB;CACxC,MAAM,gBACJ,GAAG,qBAAqB;CAC1B,MAAM,gBACJA,wBAAAA;CACF,MAAM,WAAW,GAAG,SAClB,cAAc,OAAO,GAAG,IAAI;CAC9B,MAAM,oBAAoB,SACxB,OAAO,YAAY,CACjB,CAAC,eAAe,IAAI,CACtB,CAAC;CACH,MAAM,gBACJ,cAGA,SAEC,KAAK,SAAS,IACX,KAAK,KACL,UAAU,gBAAgB,aAAa,SAAS,KAAA,IAC9C,aAAa,OACb,CAAC;CACT,MAAM,qBACJ,eACG;EACH,IACE,OAAO,eAAe,YACtB,eAAe,QACf,EAAE,iBAAiB,aAEnB,MAAM,IAAI,MACR,+CAA+C,OAAO,EAAE,EAAE,qEAC5D;EAGF,OAAO,WACL;CAEJ;CAEA,OAAO;EACL;EACA,WAAW,aAAa,GAAG,MAAM;GAC/B,OAAO,YAAY,WAAW,QAAQ,GAAG,IAAI,CAAC;EAGhD;EACA,cAAc,aAAa,GAAG,MAAM;GAClC,OAAO,YAAY,cAAc,QAAQ,GAAG,IAAI,CAAC;EACnD;EACA,MAAM,WAAW,cAAc,GAAG,MAAM;GAEtC,MAAM,YAAY,aAAa,cAAcC,IAAS;GAKtD,OAAO;IACL,MAAM,MALW,aAAa,QAAQ,YAAY,WAClD,QAAQ,GAAI,CAAC,SAAS,CAA6B,CACrD;IAIE,WAAW,iBAAiB,SAAS;GACvC;EACF;EACA,MAAM,cAAc,cAAc,GAAG,MAAM;GAEzC,MAAM,YAAY,aAAa,cAAcA,IAAS;GAEtD,MAAM,aAAa,QAAQ,YAAY,cACrC,QAAQ,GAAI,CAAC,SAAS,CAA6B,CACrD;GAEA,OAAO,iBAAiB,SAAS;EACnC;EACA,SAAS,GAAG,MAAM;GAChB,MAAM,CAAC,WAAW,gBAAgB;GAElC,QAAA,GAAA,sBAAA,SAAA,CAAwB;IACtB,GAAG;IACH,GAAG,QAAQ,GAAI,CAAC,SAAS,CAA6B;GACxD,CAAC;EACH;EACA,sBAAsB,OAAO;GAI3B,QAAA,GAAA,sBAAA,iBAAA,CACE,QAAQ,GAAI,CAHI,kBADC,MAAM,cACoB,CAGtB,CAAC,CAA6B,CACrD;EACF;EACA,iBAAiB,GAAG,MAAM;GACxB,QAAA,GAAA,sBAAA,iBAAA,CAAgC,QAAQ,GAAG,IAAI,CAAC;EAClD;CACF;AACF;AAEA,SAAgB,yBAGd,SAGA;CACA,OAAO,OAAO,YACZ,OAAO,QAAQ,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,WAAW,CAC3C,IACA,uBAAuB,IAAI,KAAK,CAClC,CAAC,CACH;AAGF"}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,22 +1,56 @@
|
|
|
1
|
-
import { UseSuspenseQueryResult } from "@tanstack/react-query";
|
|
2
|
-
import { FunctionArgs, FunctionReference, FunctionReturnType, OptionalRestArgs } from "convex/server";
|
|
1
|
+
import { UseQueryOptions, UseQueryResult, UseSuspenseQueryResult } from "@tanstack/react-query";
|
|
2
|
+
import { ArgsAndOptions, FunctionArgs, FunctionReference, FunctionReturnType, OptionalRestArgs } from "convex/server";
|
|
3
3
|
|
|
4
4
|
//#region src/index.d.ts
|
|
5
|
+
declare const routeDataKeyPrefix = "__convexRouteQuery:";
|
|
6
|
+
type ConvexRouteQueryLoaderKey<Id extends string> = `${typeof routeDataKeyPrefix}${Id}`;
|
|
7
|
+
type ConvexRouteQueryLoaderData<Id extends string, Query extends FunctionReference<"query">> = Record<ConvexRouteQueryLoaderKey<Id>, FunctionArgs<Query>>;
|
|
5
8
|
type ConvexRouteQueryOptions<Query extends FunctionReference<"query">> = {
|
|
6
9
|
queryKey: ["convexQuery", Query, FunctionArgs<Query>];
|
|
7
10
|
staleTime: number;
|
|
8
11
|
};
|
|
9
|
-
type
|
|
12
|
+
type ConvexRouteUseQueryOptions<Query extends FunctionReference<"query">, Data = FunctionReturnType<Query>> = Omit<UseQueryOptions<FunctionReturnType<Query>, Error, Data, ConvexRouteQueryOptions<Query>["queryKey"]>, "queryKey" | "queryFn" | "staleTime">;
|
|
13
|
+
type ConvexRouteQuery<Query extends FunctionReference<"query">, Id extends string = string> = {
|
|
10
14
|
options: (...args: OptionalRestArgs<Query>) => ConvexRouteQueryOptions<Query>;
|
|
11
15
|
fetchQuery: (queryClient: ConvexRouteQueryClient<Query>, ...args: OptionalRestArgs<Query>) => Promise<FunctionReturnType<Query>>;
|
|
12
16
|
prefetchQuery: (queryClient: ConvexRouteQueryClient<Query>, ...args: OptionalRestArgs<Query>) => Promise<void>;
|
|
17
|
+
fetchRoute: {
|
|
18
|
+
(routeContext: ConvexRouteQueryRouteContext<Query>): Promise<ConvexRouteQueryFetchRouteResult<Id, Query>>;
|
|
19
|
+
(routeContext: ConvexRouteQueryClientContext<Query>, ...args: OptionalRestArgs<Query>): Promise<ConvexRouteQueryFetchRouteResult<Id, Query>>;
|
|
20
|
+
};
|
|
21
|
+
prefetchRoute: {
|
|
22
|
+
(routeContext: ConvexRouteQueryRouteContext<Query>): Promise<ConvexRouteQueryLoaderData<Id, Query>>;
|
|
23
|
+
(routeContext: ConvexRouteQueryClientContext<Query>, ...args: OptionalRestArgs<Query>): Promise<ConvexRouteQueryLoaderData<Id, Query>>;
|
|
24
|
+
};
|
|
25
|
+
useQuery: <Data = FunctionReturnType<Query>>(...args: ArgsAndOptions<Query, ConvexRouteUseQueryOptions<Query, Data>>) => UseQueryResult<Data, Error>;
|
|
26
|
+
useSuspenseRouteQuery: (route: ConvexRouteQueryRoute<Id, Query>) => UseSuspenseQueryResult<FunctionReturnType<Query>, Error>;
|
|
13
27
|
useSuspenseQuery: (...args: OptionalRestArgs<Query>) => UseSuspenseQueryResult<FunctionReturnType<Query>, Error>;
|
|
14
28
|
};
|
|
15
29
|
type ConvexRouteQueryClient<Query extends FunctionReference<"query">> = {
|
|
16
30
|
fetchQuery: (options: ConvexRouteQueryOptions<Query>) => Promise<unknown>;
|
|
17
31
|
prefetchQuery: (options: ConvexRouteQueryOptions<Query>) => Promise<void>;
|
|
18
32
|
};
|
|
33
|
+
type ConvexRouteQueryClientContext<Query extends FunctionReference<"query">> = {
|
|
34
|
+
context: {
|
|
35
|
+
queryClient: ConvexRouteQueryClient<Query>;
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
type ConvexRouteQueryRouteDeps<Query extends FunctionReference<"query">> = keyof FunctionArgs<Query> extends never ? {
|
|
39
|
+
deps?: FunctionArgs<Query>;
|
|
40
|
+
} : {
|
|
41
|
+
deps: FunctionArgs<Query>;
|
|
42
|
+
};
|
|
43
|
+
type ConvexRouteQueryRouteContext<Query extends FunctionReference<"query">> = ConvexRouteQueryClientContext<Query> & ConvexRouteQueryRouteDeps<Query>;
|
|
44
|
+
type ConvexRouteQueryFetchRouteResult<Id extends string, Query extends FunctionReference<"query">> = {
|
|
45
|
+
data: FunctionReturnType<Query>;
|
|
46
|
+
routeData: ConvexRouteQueryLoaderData<Id, Query>;
|
|
47
|
+
};
|
|
48
|
+
type ConvexRouteQueryRoute<Id extends string, Query extends FunctionReference<"query">> = {
|
|
49
|
+
useLoaderData: () => ConvexRouteQueryLoaderData<Id, Query>;
|
|
50
|
+
};
|
|
19
51
|
declare function createConvexRouteQuery<Query extends FunctionReference<"query">>(query: Query): ConvexRouteQuery<Query>;
|
|
52
|
+
declare function createConvexRouteQuery<const Id extends string, Query extends FunctionReference<"query">>(id: Id, query: Query): ConvexRouteQuery<Query, Id>;
|
|
53
|
+
declare function createConvexRouteQueries<const Queries extends Record<string, FunctionReference<"query">>>(queries: Queries): { [Id in keyof Queries & string]: ConvexRouteQuery<Queries[Id], Id> };
|
|
20
54
|
//#endregion
|
|
21
|
-
export { ConvexRouteQuery, ConvexRouteQueryClient, ConvexRouteQueryOptions, createConvexRouteQuery };
|
|
55
|
+
export { ConvexRouteQuery, ConvexRouteQueryClient, ConvexRouteQueryClientContext, ConvexRouteQueryFetchRouteResult, ConvexRouteQueryLoaderData, ConvexRouteQueryLoaderKey, ConvexRouteQueryOptions, ConvexRouteQueryRoute, ConvexRouteQueryRouteContext, ConvexRouteUseQueryOptions, createConvexRouteQueries, createConvexRouteQuery };
|
|
22
56
|
//# sourceMappingURL=index.d.cts.map
|
package/dist/index.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/index.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/index.ts"],"mappings":"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"}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,22 +1,56 @@
|
|
|
1
|
-
import { UseSuspenseQueryResult } from "@tanstack/react-query";
|
|
2
|
-
import { FunctionArgs, FunctionReference, FunctionReturnType, OptionalRestArgs } from "convex/server";
|
|
1
|
+
import { UseQueryOptions, UseQueryResult, UseSuspenseQueryResult } from "@tanstack/react-query";
|
|
2
|
+
import { ArgsAndOptions, FunctionArgs, FunctionReference, FunctionReturnType, OptionalRestArgs } from "convex/server";
|
|
3
3
|
|
|
4
4
|
//#region src/index.d.ts
|
|
5
|
+
declare const routeDataKeyPrefix = "__convexRouteQuery:";
|
|
6
|
+
type ConvexRouteQueryLoaderKey<Id extends string> = `${typeof routeDataKeyPrefix}${Id}`;
|
|
7
|
+
type ConvexRouteQueryLoaderData<Id extends string, Query extends FunctionReference<"query">> = Record<ConvexRouteQueryLoaderKey<Id>, FunctionArgs<Query>>;
|
|
5
8
|
type ConvexRouteQueryOptions<Query extends FunctionReference<"query">> = {
|
|
6
9
|
queryKey: ["convexQuery", Query, FunctionArgs<Query>];
|
|
7
10
|
staleTime: number;
|
|
8
11
|
};
|
|
9
|
-
type
|
|
12
|
+
type ConvexRouteUseQueryOptions<Query extends FunctionReference<"query">, Data = FunctionReturnType<Query>> = Omit<UseQueryOptions<FunctionReturnType<Query>, Error, Data, ConvexRouteQueryOptions<Query>["queryKey"]>, "queryKey" | "queryFn" | "staleTime">;
|
|
13
|
+
type ConvexRouteQuery<Query extends FunctionReference<"query">, Id extends string = string> = {
|
|
10
14
|
options: (...args: OptionalRestArgs<Query>) => ConvexRouteQueryOptions<Query>;
|
|
11
15
|
fetchQuery: (queryClient: ConvexRouteQueryClient<Query>, ...args: OptionalRestArgs<Query>) => Promise<FunctionReturnType<Query>>;
|
|
12
16
|
prefetchQuery: (queryClient: ConvexRouteQueryClient<Query>, ...args: OptionalRestArgs<Query>) => Promise<void>;
|
|
17
|
+
fetchRoute: {
|
|
18
|
+
(routeContext: ConvexRouteQueryRouteContext<Query>): Promise<ConvexRouteQueryFetchRouteResult<Id, Query>>;
|
|
19
|
+
(routeContext: ConvexRouteQueryClientContext<Query>, ...args: OptionalRestArgs<Query>): Promise<ConvexRouteQueryFetchRouteResult<Id, Query>>;
|
|
20
|
+
};
|
|
21
|
+
prefetchRoute: {
|
|
22
|
+
(routeContext: ConvexRouteQueryRouteContext<Query>): Promise<ConvexRouteQueryLoaderData<Id, Query>>;
|
|
23
|
+
(routeContext: ConvexRouteQueryClientContext<Query>, ...args: OptionalRestArgs<Query>): Promise<ConvexRouteQueryLoaderData<Id, Query>>;
|
|
24
|
+
};
|
|
25
|
+
useQuery: <Data = FunctionReturnType<Query>>(...args: ArgsAndOptions<Query, ConvexRouteUseQueryOptions<Query, Data>>) => UseQueryResult<Data, Error>;
|
|
26
|
+
useSuspenseRouteQuery: (route: ConvexRouteQueryRoute<Id, Query>) => UseSuspenseQueryResult<FunctionReturnType<Query>, Error>;
|
|
13
27
|
useSuspenseQuery: (...args: OptionalRestArgs<Query>) => UseSuspenseQueryResult<FunctionReturnType<Query>, Error>;
|
|
14
28
|
};
|
|
15
29
|
type ConvexRouteQueryClient<Query extends FunctionReference<"query">> = {
|
|
16
30
|
fetchQuery: (options: ConvexRouteQueryOptions<Query>) => Promise<unknown>;
|
|
17
31
|
prefetchQuery: (options: ConvexRouteQueryOptions<Query>) => Promise<void>;
|
|
18
32
|
};
|
|
33
|
+
type ConvexRouteQueryClientContext<Query extends FunctionReference<"query">> = {
|
|
34
|
+
context: {
|
|
35
|
+
queryClient: ConvexRouteQueryClient<Query>;
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
type ConvexRouteQueryRouteDeps<Query extends FunctionReference<"query">> = keyof FunctionArgs<Query> extends never ? {
|
|
39
|
+
deps?: FunctionArgs<Query>;
|
|
40
|
+
} : {
|
|
41
|
+
deps: FunctionArgs<Query>;
|
|
42
|
+
};
|
|
43
|
+
type ConvexRouteQueryRouteContext<Query extends FunctionReference<"query">> = ConvexRouteQueryClientContext<Query> & ConvexRouteQueryRouteDeps<Query>;
|
|
44
|
+
type ConvexRouteQueryFetchRouteResult<Id extends string, Query extends FunctionReference<"query">> = {
|
|
45
|
+
data: FunctionReturnType<Query>;
|
|
46
|
+
routeData: ConvexRouteQueryLoaderData<Id, Query>;
|
|
47
|
+
};
|
|
48
|
+
type ConvexRouteQueryRoute<Id extends string, Query extends FunctionReference<"query">> = {
|
|
49
|
+
useLoaderData: () => ConvexRouteQueryLoaderData<Id, Query>;
|
|
50
|
+
};
|
|
19
51
|
declare function createConvexRouteQuery<Query extends FunctionReference<"query">>(query: Query): ConvexRouteQuery<Query>;
|
|
52
|
+
declare function createConvexRouteQuery<const Id extends string, Query extends FunctionReference<"query">>(id: Id, query: Query): ConvexRouteQuery<Query, Id>;
|
|
53
|
+
declare function createConvexRouteQueries<const Queries extends Record<string, FunctionReference<"query">>>(queries: Queries): { [Id in keyof Queries & string]: ConvexRouteQuery<Queries[Id], Id> };
|
|
20
54
|
//#endregion
|
|
21
|
-
export { ConvexRouteQuery, ConvexRouteQueryClient, ConvexRouteQueryOptions, createConvexRouteQuery };
|
|
55
|
+
export { ConvexRouteQuery, ConvexRouteQueryClient, ConvexRouteQueryClientContext, ConvexRouteQueryFetchRouteResult, ConvexRouteQueryLoaderData, ConvexRouteQueryLoaderKey, ConvexRouteQueryOptions, ConvexRouteQueryRoute, ConvexRouteQueryRouteContext, ConvexRouteUseQueryOptions, createConvexRouteQueries, createConvexRouteQuery };
|
|
22
56
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
import { convexQuery } from "@convex-dev/react-query";
|
|
2
|
-
import { useSuspenseQuery } from "@tanstack/react-query";
|
|
2
|
+
import { useQuery, useSuspenseQuery } from "@tanstack/react-query";
|
|
3
|
+
import { getFunctionName } from "convex/server";
|
|
3
4
|
//#region src/index.ts
|
|
4
|
-
|
|
5
|
+
const routeDataKeyPrefix = "__convexRouteQuery:";
|
|
6
|
+
function createConvexRouteQuery(idOrQuery, maybeQuery) {
|
|
7
|
+
const query = maybeQuery ?? idOrQuery;
|
|
8
|
+
const id = typeof idOrQuery === "string" ? idOrQuery : getFunctionName(idOrQuery);
|
|
9
|
+
const loaderDataKey = `${routeDataKeyPrefix}${id}`;
|
|
5
10
|
const createOptions = convexQuery;
|
|
6
11
|
const options = (...args) => createOptions(query, ...args);
|
|
12
|
+
const createLoaderData = (args) => Object.fromEntries([[loaderDataKey, args]]);
|
|
13
|
+
const getRouteArgs = (routeContext, args) => args.length > 0 ? args[0] : "deps" in routeContext && routeContext.deps !== void 0 ? routeContext.deps : {};
|
|
14
|
+
const getLoaderDataArgs = (loaderData) => {
|
|
15
|
+
if (typeof loaderData !== "object" || loaderData === null || !(loaderDataKey in loaderData)) throw new Error(`Missing convex-route-query loader data for "${String(id)}". Return the result of prefetchRoute(...) from this route's loader.`);
|
|
16
|
+
return loaderData[loaderDataKey];
|
|
17
|
+
};
|
|
7
18
|
return {
|
|
8
19
|
options,
|
|
9
20
|
fetchQuery(queryClient, ...args) {
|
|
@@ -12,12 +23,37 @@ function createConvexRouteQuery(query) {
|
|
|
12
23
|
prefetchQuery(queryClient, ...args) {
|
|
13
24
|
return queryClient.prefetchQuery(options(...args));
|
|
14
25
|
},
|
|
26
|
+
async fetchRoute(routeContext, ...args) {
|
|
27
|
+
const queryArgs = getRouteArgs(routeContext, args);
|
|
28
|
+
return {
|
|
29
|
+
data: await routeContext.context.queryClient.fetchQuery(options(...[queryArgs])),
|
|
30
|
+
routeData: createLoaderData(queryArgs)
|
|
31
|
+
};
|
|
32
|
+
},
|
|
33
|
+
async prefetchRoute(routeContext, ...args) {
|
|
34
|
+
const queryArgs = getRouteArgs(routeContext, args);
|
|
35
|
+
await routeContext.context.queryClient.prefetchQuery(options(...[queryArgs]));
|
|
36
|
+
return createLoaderData(queryArgs);
|
|
37
|
+
},
|
|
38
|
+
useQuery(...args) {
|
|
39
|
+
const [queryArgs, queryOptions] = args;
|
|
40
|
+
return useQuery({
|
|
41
|
+
...queryOptions,
|
|
42
|
+
...options(...[queryArgs])
|
|
43
|
+
});
|
|
44
|
+
},
|
|
45
|
+
useSuspenseRouteQuery(route) {
|
|
46
|
+
return useSuspenseQuery(options(...[getLoaderDataArgs(route.useLoaderData())]));
|
|
47
|
+
},
|
|
15
48
|
useSuspenseQuery(...args) {
|
|
16
49
|
return useSuspenseQuery(options(...args));
|
|
17
50
|
}
|
|
18
51
|
};
|
|
19
52
|
}
|
|
53
|
+
function createConvexRouteQueries(queries) {
|
|
54
|
+
return Object.fromEntries(Object.entries(queries).map(([id, query]) => [id, createConvexRouteQuery(id, query)]));
|
|
55
|
+
}
|
|
20
56
|
//#endregion
|
|
21
|
-
export { createConvexRouteQuery };
|
|
57
|
+
export { createConvexRouteQueries, createConvexRouteQuery };
|
|
22
58
|
|
|
23
59
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["useTanStackSuspenseQuery"],"sources":["../src/index.ts"],"sourcesContent":["import { convexQuery } from \"@convex-dev/react-query\";\nimport {\n useSuspenseQuery as useTanStackSuspenseQuery,\n type UseSuspenseQueryResult,\n} from \"@tanstack/react-query\";\nimport type {\n FunctionArgs,\n FunctionReference,\n FunctionReturnType,\n OptionalRestArgs,\n} from \"convex/server\";\n\nexport type ConvexRouteQueryOptions<Query extends FunctionReference<\"query\">> =\n {\n queryKey: [\"convexQuery\", Query, FunctionArgs<Query>];\n staleTime: number;\n };\n\nexport type ConvexRouteQuery<Query extends FunctionReference<\"query\">> = {\n options: (...args: OptionalRestArgs<Query>) => ConvexRouteQueryOptions<Query>;\n fetchQuery: (\n queryClient: ConvexRouteQueryClient<Query>,\n ...args: OptionalRestArgs<Query>\n ) => Promise<FunctionReturnType<Query>>;\n prefetchQuery: (\n queryClient: ConvexRouteQueryClient<Query>,\n ...args: OptionalRestArgs<Query>\n ) => Promise<void>;\n useSuspenseQuery: (\n ...args: OptionalRestArgs<Query>\n ) => UseSuspenseQueryResult<FunctionReturnType<Query>, Error>;\n};\n\nexport type ConvexRouteQueryClient<Query extends FunctionReference<\"query\">> = {\n fetchQuery: (options: ConvexRouteQueryOptions<Query>) => Promise<unknown>;\n prefetchQuery: (options: ConvexRouteQueryOptions<Query>) => Promise<void>;\n};\n\ntype CreateConvexQueryOptions<Query extends FunctionReference<\"query\">> = (\n query: Query,\n ...args: OptionalRestArgs<Query>\n) => ConvexRouteQueryOptions<Query>;\n\nexport function createConvexRouteQuery<\n Query extends FunctionReference<\"query\">,\n>(query: Query): ConvexRouteQuery<Query> {\n const createOptions =\n convexQuery as unknown as CreateConvexQueryOptions<Query>;\n const options = (...args: OptionalRestArgs<Query>) =>\n createOptions(query, ...args);\n\n return {\n options,\n fetchQuery(queryClient, ...args) {\n return queryClient.fetchQuery(options(...args)) as Promise<\n FunctionReturnType<Query>\n >;\n },\n prefetchQuery(queryClient, ...args) {\n return queryClient.prefetchQuery(options(...args));\n },\n useSuspenseQuery(...args) {\n return useTanStackSuspenseQuery(options(...args));\n },\n };\n}\n"],"mappings":";;;AA2CA,SAAgB,uBAEd,OAAuC;CACvC,MAAM,gBACJ;CACF,MAAM,WAAW,GAAG,SAClB,cAAc,OAAO,GAAG,IAAI;CAE9B,OAAO;EACL;EACA,WAAW,aAAa,GAAG,MAAM;GAC/B,OAAO,YAAY,WAAW,QAAQ,GAAG,IAAI,CAAC;EAGhD;EACA,cAAc,aAAa,GAAG,MAAM;GAClC,OAAO,YAAY,cAAc,QAAQ,GAAG,IAAI,CAAC;EACnD;EACA,iBAAiB,GAAG,MAAM;GACxB,OAAOA,iBAAyB,QAAQ,GAAG,IAAI,CAAC;EAClD;CACF;AACF"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["routeArgs","useTanStackQuery","useTanStackSuspenseQuery"],"sources":["../src/index.ts"],"sourcesContent":["import { convexQuery } from \"@convex-dev/react-query\";\nimport {\n useQuery as useTanStackQuery,\n useSuspenseQuery as useTanStackSuspenseQuery,\n type UseQueryOptions,\n type UseQueryResult,\n type UseSuspenseQueryResult,\n} from \"@tanstack/react-query\";\nimport {\n getFunctionName,\n type ArgsAndOptions,\n type FunctionArgs,\n type FunctionReference,\n type FunctionReturnType,\n type OptionalRestArgs,\n} from \"convex/server\";\n\nconst routeDataKeyPrefix = \"__convexRouteQuery:\";\n\nexport type ConvexRouteQueryLoaderKey<Id extends string> =\n `${typeof routeDataKeyPrefix}${Id}`;\n\nexport type ConvexRouteQueryLoaderData<\n Id extends string,\n Query extends FunctionReference<\"query\">,\n> = Record<ConvexRouteQueryLoaderKey<Id>, FunctionArgs<Query>>;\n\nexport type ConvexRouteQueryOptions<Query extends FunctionReference<\"query\">> =\n {\n queryKey: [\"convexQuery\", Query, FunctionArgs<Query>];\n staleTime: number;\n };\n\nexport type ConvexRouteUseQueryOptions<\n Query extends FunctionReference<\"query\">,\n Data = FunctionReturnType<Query>,\n> = Omit<\n UseQueryOptions<\n FunctionReturnType<Query>,\n Error,\n Data,\n ConvexRouteQueryOptions<Query>[\"queryKey\"]\n >,\n \"queryKey\" | \"queryFn\" | \"staleTime\"\n>;\n\nexport type ConvexRouteQuery<\n Query extends FunctionReference<\"query\">,\n Id extends string = string,\n> = {\n options: (...args: OptionalRestArgs<Query>) => ConvexRouteQueryOptions<Query>;\n fetchQuery: (\n queryClient: ConvexRouteQueryClient<Query>,\n ...args: OptionalRestArgs<Query>\n ) => Promise<FunctionReturnType<Query>>;\n prefetchQuery: (\n queryClient: ConvexRouteQueryClient<Query>,\n ...args: OptionalRestArgs<Query>\n ) => Promise<void>;\n fetchRoute: {\n (\n routeContext: ConvexRouteQueryRouteContext<Query>,\n ): Promise<ConvexRouteQueryFetchRouteResult<Id, Query>>;\n (\n routeContext: ConvexRouteQueryClientContext<Query>,\n ...args: OptionalRestArgs<Query>\n ): Promise<ConvexRouteQueryFetchRouteResult<Id, Query>>;\n };\n prefetchRoute: {\n (\n routeContext: ConvexRouteQueryRouteContext<Query>,\n ): Promise<ConvexRouteQueryLoaderData<Id, Query>>;\n (\n routeContext: ConvexRouteQueryClientContext<Query>,\n ...args: OptionalRestArgs<Query>\n ): Promise<ConvexRouteQueryLoaderData<Id, Query>>;\n };\n useQuery: <Data = FunctionReturnType<Query>>(\n ...args: ArgsAndOptions<Query, ConvexRouteUseQueryOptions<Query, Data>>\n ) => UseQueryResult<Data, Error>;\n useSuspenseRouteQuery: (\n route: ConvexRouteQueryRoute<Id, Query>,\n ) => UseSuspenseQueryResult<FunctionReturnType<Query>, Error>;\n useSuspenseQuery: (\n ...args: OptionalRestArgs<Query>\n ) => UseSuspenseQueryResult<FunctionReturnType<Query>, Error>;\n};\n\nexport type ConvexRouteQueryClient<Query extends FunctionReference<\"query\">> = {\n fetchQuery: (options: ConvexRouteQueryOptions<Query>) => Promise<unknown>;\n prefetchQuery: (options: ConvexRouteQueryOptions<Query>) => Promise<void>;\n};\n\nexport type ConvexRouteQueryClientContext<\n Query extends FunctionReference<\"query\">,\n> = {\n context: {\n queryClient: ConvexRouteQueryClient<Query>;\n };\n};\n\ntype ConvexRouteQueryRouteDeps<Query extends FunctionReference<\"query\">> =\n keyof FunctionArgs<Query> extends never\n ? {\n deps?: FunctionArgs<Query>;\n }\n : {\n deps: FunctionArgs<Query>;\n };\n\nexport type ConvexRouteQueryRouteContext<\n Query extends FunctionReference<\"query\">,\n> = ConvexRouteQueryClientContext<Query> & ConvexRouteQueryRouteDeps<Query>;\n\nexport type ConvexRouteQueryFetchRouteResult<\n Id extends string,\n Query extends FunctionReference<\"query\">,\n> = {\n data: FunctionReturnType<Query>;\n routeData: ConvexRouteQueryLoaderData<Id, Query>;\n};\n\nexport type ConvexRouteQueryRoute<\n Id extends string,\n Query extends FunctionReference<\"query\">,\n> = {\n useLoaderData: () => ConvexRouteQueryLoaderData<Id, Query>;\n};\n\ntype CreateConvexQueryOptions<Query extends FunctionReference<\"query\">> = (\n query: Query,\n ...args: OptionalRestArgs<Query>\n) => ConvexRouteQueryOptions<Query>;\n\nexport function createConvexRouteQuery<\n Query extends FunctionReference<\"query\">,\n>(query: Query): ConvexRouteQuery<Query>;\nexport function createConvexRouteQuery<\n const Id extends string,\n Query extends FunctionReference<\"query\">,\n>(id: Id, query: Query): ConvexRouteQuery<Query, Id>;\nexport function createConvexRouteQuery<\n const Id extends string,\n Query extends FunctionReference<\"query\">,\n>(\n idOrQuery: Id | Query,\n maybeQuery?: Query,\n): ConvexRouteQuery<Query, Id | string> {\n const query = (maybeQuery ?? idOrQuery) as Query;\n const id =\n typeof idOrQuery === \"string\"\n ? idOrQuery\n : getFunctionName(idOrQuery as Query);\n const loaderDataKey =\n `${routeDataKeyPrefix}${id}` as ConvexRouteQueryLoaderKey<Id | string>;\n const createOptions =\n convexQuery as unknown as CreateConvexQueryOptions<Query>;\n const options = (...args: OptionalRestArgs<Query>) =>\n createOptions(query, ...args);\n const createLoaderData = (args: FunctionArgs<Query>) =>\n Object.fromEntries([\n [loaderDataKey, args],\n ]) as unknown as ConvexRouteQueryLoaderData<Id | string, Query>;\n const getRouteArgs = (\n routeContext:\n | ConvexRouteQueryClientContext<Query>\n | ConvexRouteQueryRouteContext<Query>,\n args: OptionalRestArgs<Query>,\n ) =>\n (args.length > 0\n ? args[0]\n : \"deps\" in routeContext && routeContext.deps !== undefined\n ? routeContext.deps\n : {}) as FunctionArgs<Query>;\n const getLoaderDataArgs = (\n loaderData: ConvexRouteQueryLoaderData<Id, Query>,\n ) => {\n if (\n typeof loaderData !== \"object\" ||\n loaderData === null ||\n !(loaderDataKey in loaderData)\n ) {\n throw new Error(\n `Missing convex-route-query loader data for \"${String(id)}\". Return the result of prefetchRoute(...) from this route's loader.`,\n );\n }\n\n return loaderData[\n loaderDataKey as keyof typeof loaderData\n ] as FunctionArgs<Query>;\n };\n\n return {\n options,\n fetchQuery(queryClient, ...args) {\n return queryClient.fetchQuery(options(...args)) as Promise<\n FunctionReturnType<Query>\n >;\n },\n prefetchQuery(queryClient, ...args) {\n return queryClient.prefetchQuery(options(...args));\n },\n async fetchRoute(routeContext, ...args) {\n const routeArgs = args as OptionalRestArgs<Query>;\n const queryArgs = getRouteArgs(routeContext, routeArgs);\n const data = await routeContext.context.queryClient.fetchQuery(\n options(...([queryArgs] as OptionalRestArgs<Query>)),\n );\n\n return {\n data: data as FunctionReturnType<Query>,\n routeData: createLoaderData(queryArgs),\n };\n },\n async prefetchRoute(routeContext, ...args) {\n const routeArgs = args as OptionalRestArgs<Query>;\n const queryArgs = getRouteArgs(routeContext, routeArgs);\n\n await routeContext.context.queryClient.prefetchQuery(\n options(...([queryArgs] as OptionalRestArgs<Query>)),\n );\n\n return createLoaderData(queryArgs);\n },\n useQuery(...args) {\n const [queryArgs, queryOptions] = args;\n\n return useTanStackQuery({\n ...queryOptions,\n ...options(...([queryArgs] as OptionalRestArgs<Query>)),\n });\n },\n useSuspenseRouteQuery(route) {\n const loaderData = route.useLoaderData();\n const queryArgs = getLoaderDataArgs(loaderData);\n\n return useTanStackSuspenseQuery(\n options(...([queryArgs] as OptionalRestArgs<Query>)),\n );\n },\n useSuspenseQuery(...args) {\n return useTanStackSuspenseQuery(options(...args));\n },\n };\n}\n\nexport function createConvexRouteQueries<\n const Queries extends Record<string, FunctionReference<\"query\">>,\n>(\n queries: Queries,\n): {\n [Id in keyof Queries & string]: ConvexRouteQuery<Queries[Id], Id>;\n} {\n return Object.fromEntries(\n Object.entries(queries).map(([id, query]) => [\n id,\n createConvexRouteQuery(id, query),\n ]),\n ) as unknown as {\n [Id in keyof Queries & string]: ConvexRouteQuery<Queries[Id], Id>;\n };\n}\n"],"mappings":";;;;AAiBA,MAAM,qBAAqB;AA4H3B,SAAgB,uBAId,WACA,YACsC;CACtC,MAAM,QAAS,cAAc;CAC7B,MAAM,KACJ,OAAO,cAAc,WACjB,YACA,gBAAgB,SAAkB;CACxC,MAAM,gBACJ,GAAG,qBAAqB;CAC1B,MAAM,gBACJ;CACF,MAAM,WAAW,GAAG,SAClB,cAAc,OAAO,GAAG,IAAI;CAC9B,MAAM,oBAAoB,SACxB,OAAO,YAAY,CACjB,CAAC,eAAe,IAAI,CACtB,CAAC;CACH,MAAM,gBACJ,cAGA,SAEC,KAAK,SAAS,IACX,KAAK,KACL,UAAU,gBAAgB,aAAa,SAAS,KAAA,IAC9C,aAAa,OACb,CAAC;CACT,MAAM,qBACJ,eACG;EACH,IACE,OAAO,eAAe,YACtB,eAAe,QACf,EAAE,iBAAiB,aAEnB,MAAM,IAAI,MACR,+CAA+C,OAAO,EAAE,EAAE,qEAC5D;EAGF,OAAO,WACL;CAEJ;CAEA,OAAO;EACL;EACA,WAAW,aAAa,GAAG,MAAM;GAC/B,OAAO,YAAY,WAAW,QAAQ,GAAG,IAAI,CAAC;EAGhD;EACA,cAAc,aAAa,GAAG,MAAM;GAClC,OAAO,YAAY,cAAc,QAAQ,GAAG,IAAI,CAAC;EACnD;EACA,MAAM,WAAW,cAAc,GAAG,MAAM;GAEtC,MAAM,YAAY,aAAa,cAAcA,IAAS;GAKtD,OAAO;IACL,MAAM,MALW,aAAa,QAAQ,YAAY,WAClD,QAAQ,GAAI,CAAC,SAAS,CAA6B,CACrD;IAIE,WAAW,iBAAiB,SAAS;GACvC;EACF;EACA,MAAM,cAAc,cAAc,GAAG,MAAM;GAEzC,MAAM,YAAY,aAAa,cAAcA,IAAS;GAEtD,MAAM,aAAa,QAAQ,YAAY,cACrC,QAAQ,GAAI,CAAC,SAAS,CAA6B,CACrD;GAEA,OAAO,iBAAiB,SAAS;EACnC;EACA,SAAS,GAAG,MAAM;GAChB,MAAM,CAAC,WAAW,gBAAgB;GAElC,OAAOC,SAAiB;IACtB,GAAG;IACH,GAAG,QAAQ,GAAI,CAAC,SAAS,CAA6B;GACxD,CAAC;EACH;EACA,sBAAsB,OAAO;GAI3B,OAAOC,iBACL,QAAQ,GAAI,CAHI,kBADC,MAAM,cACoB,CAGtB,CAAC,CAA6B,CACrD;EACF;EACA,iBAAiB,GAAG,MAAM;GACxB,OAAOA,iBAAyB,QAAQ,GAAG,IAAI,CAAC;EAClD;CACF;AACF;AAEA,SAAgB,yBAGd,SAGA;CACA,OAAO,OAAO,YACZ,OAAO,QAAQ,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,WAAW,CAC3C,IACA,uBAAuB,IAAI,KAAK,CAClC,CAAC,CACH;AAGF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "convex-route-query",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "Type-safe Convex query helpers for TanStack Router loaders and React Query Suspense.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -26,7 +26,8 @@
|
|
|
26
26
|
"build": "concurrently --raw --names tsdown \"bun run build:tsdown\"",
|
|
27
27
|
"build:tsdown": "tsdown",
|
|
28
28
|
"ci": "bun run ci:test && bun run build && bun run lint:pkg",
|
|
29
|
-
"ci:test": "concurrently --raw --names runtime,types,xo \"bun run ci:test:runtime\" \"bun run ci:test:types\" \"bun run ci:test:xo\"",
|
|
29
|
+
"ci:test": "concurrently --raw --names runtime,types,e2e,xo \"bun run ci:test:runtime\" \"bun run ci:test:types\" \"bun run ci:test:e2e\" \"bun run ci:test:xo\"",
|
|
30
|
+
"ci:test:e2e": "bun run test:e2e:tanstack-start",
|
|
30
31
|
"ci:test:runtime": "vitest run",
|
|
31
32
|
"ci:test:types": "tsc --noEmit",
|
|
32
33
|
"ci:test:xo": "xo",
|
|
@@ -37,7 +38,8 @@
|
|
|
37
38
|
"lint:pkg:publint": "publint",
|
|
38
39
|
"prepublishOnly": "bun run ci",
|
|
39
40
|
"release": "bun run build && changeset publish",
|
|
40
|
-
"test": "concurrently --raw --names runtime,types,xo \"bun run test:runtime\" \"bun run test:types\" \"bun run test:xo\"",
|
|
41
|
+
"test": "concurrently --raw --names runtime,types,e2e,xo \"bun run test:runtime\" \"bun run test:types\" \"bun run test:e2e:tanstack-start\" \"bun run test:xo\"",
|
|
42
|
+
"test:e2e:tanstack-start": "tsc -p e2e/tanstack-start/tsconfig.json --noEmit",
|
|
41
43
|
"test:runtime": "vitest run",
|
|
42
44
|
"test:types": "tsc --noEmit",
|
|
43
45
|
"test:xo": "xo",
|
|
@@ -63,7 +65,8 @@
|
|
|
63
65
|
"url": "https://github.com/ludicroushq/convex-route-query/issues"
|
|
64
66
|
},
|
|
65
67
|
"publishConfig": {
|
|
66
|
-
"access": "public"
|
|
68
|
+
"access": "public",
|
|
69
|
+
"provenance": true
|
|
67
70
|
},
|
|
68
71
|
"engines": {
|
|
69
72
|
"node": ">=20.0.0"
|
|
@@ -80,7 +83,11 @@
|
|
|
80
83
|
"@changesets/cli": "^2.31.0",
|
|
81
84
|
"@convex-dev/react-query": "^0.1.0",
|
|
82
85
|
"@tanstack/react-query": "^5.101.0",
|
|
86
|
+
"@tanstack/react-router": "^1.170.17",
|
|
87
|
+
"@tanstack/react-start": "^1.168.27",
|
|
83
88
|
"@types/react": "^19.2.7",
|
|
89
|
+
"@types/react-dom": "^19.2.3",
|
|
90
|
+
"@vitejs/plugin-react": "^6.0.3",
|
|
84
91
|
"concurrently": "^10.0.3",
|
|
85
92
|
"convex": "^1.41.0",
|
|
86
93
|
"expect-type": "^1.3.0",
|
|
@@ -88,9 +95,12 @@
|
|
|
88
95
|
"prettier": "^3.8.4",
|
|
89
96
|
"publint": "^0.3.21",
|
|
90
97
|
"react": "^19.2.7",
|
|
98
|
+
"react-dom": "^19.2.7",
|
|
91
99
|
"tsdown": "^0.22.2",
|
|
92
100
|
"typescript": "^6.0.3",
|
|
101
|
+
"vite": "^8.1.4",
|
|
93
102
|
"vitest": "^4.1.8",
|
|
94
|
-
"xo": "^2.0.2"
|
|
103
|
+
"xo": "^2.0.2",
|
|
104
|
+
"zod": "^4.4.3"
|
|
95
105
|
}
|
|
96
106
|
}
|