@questpie/tanstack-query 1.1.1 → 3.0.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 CHANGED
@@ -1,12 +1,15 @@
1
1
  # @questpie/tanstack-query
2
2
 
3
- Type-safe TanStack React Query integration for QUESTPIE.
3
+ Type-safe TanStack Query option builders for QUESTPIE — collections, globals, app routes, and realtime streaming.
4
4
 
5
5
  ## Features
6
6
 
7
- - **Query Options Factory** - Pre-built query/mutation options using `queryOptions()` and `mutationOptions()` from TanStack Query
8
- - **SSR Ready** - Prefetch data on server, hydrate on client
9
- - **Type-Safe** - Full TypeScript inference from your CMS schema
7
+ - **Query Options Factory** — Pre-built `queryOptions()` and `mutationOptions()` for all CRUD operations
8
+ - **Route Query Options** — Typed `query()` / `mutation()` builders for app routes with nested path support
9
+ - **Realtime Streaming** — `streamedQuery`-based options for SSE live updates on collections and globals
10
+ - **Batch Operations** — `updateMany` and `deleteMany` mutation builders
11
+ - **SSR Ready** — Prefetch data on the server, hydrate on the client
12
+ - **Full Type Inference** — Types flow from your app schema through to query results
10
13
 
11
14
  ## Installation
12
15
 
@@ -18,285 +21,223 @@ bun add @questpie/tanstack-query questpie @tanstack/react-query
18
21
 
19
22
  ### 1. Create Query Options
20
23
 
21
- ```typescript
22
- // src/lib/queries.ts
24
+ ```ts
23
25
  import { createClient } from "questpie/client";
24
26
  import { createQuestpieQueryOptions } from "@questpie/tanstack-query";
25
- import type { AppCMS } from "@/cms";
27
+ import type { AppConfig } from "#questpie";
26
28
 
27
- const cmsClient = createClient<AppCMS>({
28
- baseURL: "http://localhost:3000",
29
- basePath: "/api/cms",
29
+ const appClient = createClient<AppConfig>({
30
+ baseURL: "http://localhost:3000",
31
+ basePath: "/api",
30
32
  });
31
33
 
32
- export const q = createQuestpieQueryOptions(cmsClient, {
33
- keyPrefix: ["cms"], // Optional: prefix for all query keys
34
- });
34
+ export const appQueries = createQuestpieQueryOptions(appClient);
35
35
  ```
36
36
 
37
37
  ### 2. Use in Components
38
38
 
39
- ```typescript
40
- import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"
41
- import { q } from "@/lib/queries"
39
+ ```tsx
40
+ import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
41
+ import { appQueries } from "@/lib/queries";
42
42
 
43
43
  function PostsList() {
44
- // Queries
45
- const { data: posts } = useQuery(q.collections.posts.find({ limit: 10 }))
46
-
47
- // Mutations
48
- const queryClient = useQueryClient()
49
-
50
- const createPost = useMutation({
51
- ...q.collections.posts.create(),
52
- onSuccess: () => {
53
- queryClient.invalidateQueries({ queryKey: ["cms", "collections", "posts"] })
54
- },
55
- })
56
-
57
- return (
58
- <div>
59
- {posts?.docs.map((post) => (
60
- <div key={post.id}>{post.title}</div>
61
- ))}
62
- <button onClick={() => createPost.mutate({ title: "New Post" })}>
63
- Create Post
64
- </button>
65
- </div>
66
- )
44
+ const { data } = useQuery(appQueries.collections.posts.find({ limit: 10 }));
45
+
46
+ const queryClient = useQueryClient();
47
+ const createPost = useMutation({
48
+ ...appQueries.collections.posts.create(),
49
+ onSuccess: () => {
50
+ queryClient.invalidateQueries({
51
+ queryKey: appQueries.collections.posts.key(),
52
+ });
53
+ },
54
+ });
55
+
56
+ return (
57
+ <div>
58
+ {data?.docs.map((post) => (
59
+ <div key={post.id}>{post.title}</div>
60
+ ))}
61
+ <button onClick={() => createPost.mutate({ title: "New Post" })}>
62
+ Create
63
+ </button>
64
+ </div>
65
+ );
67
66
  }
68
67
  ```
69
68
 
70
- ## Query Options API
71
-
72
- ### Collections
69
+ ## Collections
73
70
 
74
- ```typescript
75
- // Find many
76
- q.collections.posts.find({
77
- where: { published: { eq: true } },
78
- orderBy: { createdAt: "desc" },
79
- limit: 10,
80
- offset: 0,
81
- with: { author: true },
71
+ ```ts
72
+ // Find many (paginated)
73
+ appQueries.collections.posts.find({
74
+ where: { published: { eq: true } },
75
+ orderBy: { createdAt: "desc" },
76
+ limit: 10,
77
+ offset: 0,
78
+ with: { author: true },
82
79
  });
83
80
 
84
81
  // Find one
85
- q.collections.posts.findOne({
86
- where: { id: "post-id" },
87
- with: { author: true, comments: true },
82
+ appQueries.collections.posts.findOne({
83
+ where: { id: "post-id" },
84
+ with: { author: true },
88
85
  });
89
86
 
90
- // Create
91
- q.collections.posts.create();
92
- // Usage: mutation.mutate({ title: "...", content: "..." })
87
+ // Count
88
+ appQueries.collections.posts.count({
89
+ where: { published: { eq: true } },
90
+ });
91
+
92
+ // Create (mutation)
93
+ appQueries.collections.posts.create();
94
+
95
+ // Update (mutation)
96
+ appQueries.collections.posts.update();
93
97
 
94
- // Update
95
- q.collections.posts.update();
96
- // Usage: mutation.mutate({ id: "...", data: { title: "..." } })
98
+ // Delete (mutation)
99
+ appQueries.collections.posts.delete();
97
100
 
98
- // Delete
99
- q.collections.posts.delete();
100
- // Usage: mutation.mutate({ id: "..." })
101
+ // Update many (mutation)
102
+ appQueries.collections.posts.updateMany();
101
103
 
102
- // Restore (soft delete)
103
- q.collections.posts.restore();
104
- // Usage: mutation.mutate({ id: "..." })
104
+ // Delete many (mutation)
105
+ appQueries.collections.posts.deleteMany();
106
+
107
+ // Restore soft-deleted (mutation)
108
+ appQueries.collections.posts.restore();
109
+
110
+ // Query key for invalidation
111
+ appQueries.collections.posts.key();
105
112
  ```
106
113
 
107
- ### Globals
114
+ ## Globals
108
115
 
109
- ```typescript
110
- // Get
111
- q.globals.siteSettings.get();
116
+ ```ts
117
+ // Get global value
118
+ appQueries.globals.siteSettings.get();
112
119
 
113
- // Update
114
- q.globals.siteSettings.update();
115
- // Usage: mutation.mutate({ data: { siteName: "..." } })
120
+ // Update global (mutation)
121
+ appQueries.globals.siteSettings.update();
122
+
123
+ // Query key
124
+ appQueries.globals.siteSettings.key();
116
125
  ```
117
126
 
118
- ### Custom Queries
127
+ ## Routes
128
+
129
+ Full type-safe query/mutation options for app routes:
119
130
 
120
- ```typescript
121
- const searchQuery = q.custom.query({
122
- key: ["search", query],
123
- queryFn: () => fetch(`/api/search?q=${query}`).then((r) => r.json()),
131
+ ```ts
132
+ // Query options from route
133
+ const { data } = useQuery(
134
+ appQueries.routes.dashboard.getStats.query({ period: "week" }),
135
+ );
136
+
137
+ // Mutation options from route
138
+ const publish = useMutation(appQueries.routes.posts.publish.mutation());
139
+ publish.mutate({ id: "post_123" });
140
+
141
+ // Query key for invalidation/prefetch
142
+ queryClient.invalidateQueries({
143
+ queryKey: appQueries.routes.dashboard.getStats.key({ period: "week" }),
124
144
  });
145
+ ```
146
+
147
+ ## Realtime Streaming
148
+
149
+ Collection queries support SSE-based live updates via `streamedQuery`:
150
+
151
+ ```ts
152
+ // Enable realtime on a query
153
+ const { data } = useQuery(
154
+ appQueries.collections.posts.find({ limit: 10 }, { realtime: true }),
155
+ );
156
+ ```
157
+
158
+ Topic helpers for manual subscription:
125
159
 
126
- useQuery(searchQuery);
160
+ ```ts
161
+ import {
162
+ buildCollectionTopic,
163
+ buildGlobalTopic,
164
+ } from "@questpie/tanstack-query";
165
+
166
+ const postsTopic = buildCollectionTopic("posts");
167
+ const settingsTopic = buildGlobalTopic("siteSettings");
127
168
  ```
128
169
 
129
170
  ## SSR Prefetching
130
171
 
131
172
  ### TanStack Start
132
173
 
133
- ```typescript
134
- // src/routes/posts.tsx
135
- import { createFileRoute } from "@tanstack/react-router"
136
- import { useSuspenseQuery } from "@tanstack/react-query"
137
- import { q } from "@/lib/queries"
174
+ ```tsx
175
+ import { createFileRoute } from "@tanstack/react-router";
176
+ import { useSuspenseQuery } from "@tanstack/react-query";
177
+ import { appQueries } from "@/lib/queries";
138
178
 
139
179
  export const Route = createFileRoute("/posts")({
140
- loader: async ({ context }) => {
141
- await context.queryClient.ensureQueryData(
142
- q.collections.posts.find({ limit: 10 })
143
- )
144
- },
145
- component: PostsPage,
146
- })
180
+ loader: async ({ context }) => {
181
+ await context.queryClient.ensureQueryData(
182
+ appQueries.collections.posts.find({ limit: 10 }),
183
+ );
184
+ },
185
+ component: PostsPage,
186
+ });
147
187
 
148
188
  function PostsPage() {
149
- const { data: posts } = useSuspenseQuery(
150
- q.collections.posts.find({ limit: 10 })
151
- )
152
-
153
- return (
154
- <ul>
155
- {posts.docs.map((post) => (
156
- <li key={post.id}>{post.title}</li>
157
- ))}
158
- </ul>
159
- )
189
+ const { data } = useSuspenseQuery(
190
+ appQueries.collections.posts.find({ limit: 10 }),
191
+ );
192
+ return (
193
+ <ul>
194
+ {data.docs.map((post) => (
195
+ <li key={post.id}>{post.title}</li>
196
+ ))}
197
+ </ul>
198
+ );
160
199
  }
161
200
  ```
162
201
 
163
202
  ### Next.js
164
203
 
165
- ```typescript
166
- // app/posts/page.tsx
167
- import { HydrationBoundary, dehydrate } from "@tanstack/react-query"
168
- import { getQueryClient } from "@/lib/query-client"
169
- import { q } from "@/lib/queries"
170
- import { PostsList } from "./posts-list"
204
+ ```tsx
205
+ import { HydrationBoundary, dehydrate } from "@tanstack/react-query";
206
+ import { getQueryClient } from "@/lib/query-client";
207
+ import { appQueries } from "@/lib/queries";
171
208
 
172
209
  export default async function PostsPage() {
173
- const queryClient = getQueryClient()
174
-
175
- await queryClient.prefetchQuery(
176
- q.collections.posts.find({ limit: 10 })
177
- )
178
-
179
- return (
180
- <HydrationBoundary state={dehydrate(queryClient)}>
181
- <PostsList />
182
- </HydrationBoundary>
183
- )
184
- }
185
- ```
186
-
187
- ## Optimistic Updates
188
-
189
- ```typescript
190
- const queryClient = useQueryClient();
191
-
192
- const updatePost = useMutation({
193
- ...q.collections.posts.update(),
194
- onMutate: async ({ id, data }) => {
195
- await queryClient.cancelQueries({
196
- queryKey: ["cms", "collections", "posts"],
197
- });
198
-
199
- const previousPosts = queryClient.getQueryData([
200
- "cms",
201
- "collections",
202
- "posts",
203
- ]);
204
-
205
- queryClient.setQueryData(["cms", "collections", "posts"], (old) => ({
206
- ...old,
207
- docs: old.docs.map((post) =>
208
- post.id === id ? { ...post, ...data } : post,
209
- ),
210
- }));
211
-
212
- return { previousPosts };
213
- },
214
- onError: (err, variables, context) => {
215
- queryClient.setQueryData(
216
- ["cms", "collections", "posts"],
217
- context?.previousPosts,
218
- );
219
- },
220
- onSettled: () => {
221
- queryClient.invalidateQueries({
222
- queryKey: ["cms", "collections", "posts"],
223
- });
224
- },
225
- });
226
- ```
227
-
228
- ## Infinite Queries
229
-
230
- ```typescript
231
- import { useInfiniteQuery } from "@tanstack/react-query"
232
- import { cmsClient } from "@/lib/cms-client"
233
-
234
- function InfinitePosts() {
235
- const { data, fetchNextPage, hasNextPage } = useInfiniteQuery({
236
- queryKey: ["cms", "collections", "posts", "infinite"],
237
- queryFn: ({ pageParam = 0 }) =>
238
- cmsClient.collections.posts.find({
239
- limit: 10,
240
- offset: pageParam,
241
- }),
242
- getNextPageParam: (lastPage, allPages) => {
243
- const totalFetched = allPages.flatMap((p) => p.docs).length
244
- return lastPage.docs.length === 10 ? totalFetched : undefined
245
- },
246
- initialPageParam: 0,
247
- })
248
-
249
- return (
250
- <div>
251
- {data?.pages.flatMap((page) =>
252
- page.docs.map((post) => <div key={post.id}>{post.title}</div>)
253
- )}
254
- {hasNextPage && (
255
- <button onClick={() => fetchNextPage()}>Load More</button>
256
- )}
257
- </div>
258
- )
210
+ const queryClient = getQueryClient();
211
+ await queryClient.prefetchQuery(
212
+ appQueries.collections.posts.find({ limit: 10 }),
213
+ );
214
+ return (
215
+ <HydrationBoundary state={dehydrate(queryClient)}>
216
+ <PostsList />
217
+ </HydrationBoundary>
218
+ );
259
219
  }
260
220
  ```
261
221
 
262
222
  ## Query Key Structure
263
223
 
264
- All query keys follow this structure:
265
-
266
- ```typescript
224
+ ```ts
267
225
  // Collections
268
- [...keyPrefix, "collections", collectionName, "find", options]
269
- [...keyPrefix, "collections", collectionName, "findOne", options]
226
+ ["collections", collectionName, "find", options]
227
+ ["collections", collectionName, "findOne", options]
228
+ ["collections", collectionName, "count", options]
270
229
 
271
230
  // Globals
272
- [...keyPrefix, "globals", globalName, "get", options]
273
-
274
- // Custom
275
- [...keyPrefix, ...customKey]
276
- ```
277
-
278
- ## TypeScript
279
-
280
- Full type inference from your CMS schema:
281
-
282
- ```typescript
283
- import type { CollectionSelect } from "questpie";
284
- import type { AppCMS } from "@/cms";
285
-
286
- // Collection item type
287
- type Post = CollectionSelect<AppCMS["config"]["collections"]["posts"]>;
231
+ ["globals", globalName, "get"]
288
232
 
289
- // Query result types are automatically inferred
290
- const { data } = useQuery(q.collections.posts.find({ limit: 10 }));
291
- // ^? { docs: Post[], totalDocs: number, ... }
233
+ // Routes
234
+ ["routes", ...segments, "query", input]
235
+ ["routes", ...segments, "mutation"]
292
236
  ```
293
237
 
294
- ## Related Packages
238
+ ## Documentation
295
239
 
296
- - [`questpie`](../questpie) - Core CMS engine
297
- - [`@questpie/hono`](../hono) - Hono adapter
298
- - [`@questpie/elysia`](../elysia) - Elysia adapter
299
- - [`@questpie/next`](../next) - Next.js adapter
240
+ Full documentation: [https://questpie.com/docs/client/tanstack-query](https://questpie.com/docs/client/tanstack-query)
300
241
 
301
242
  ## License
302
243
 
package/dist/index.d.mts CHANGED
@@ -1,6 +1,5 @@
1
1
  import { DefaultError, QueryKey, UseMutationOptions, UseQueryOptions } from "@tanstack/react-query";
2
- import { Questpie } from "questpie";
3
- import { QuestpieClient } from "questpie/client";
2
+ import { QuestpieApp, QuestpieClient, RealtimeAPI, TopicConfig, buildCollectionTopic, buildGlobalTopic } from "questpie/client";
4
3
 
5
4
  //#region src/index.d.ts
6
5
  type QuestpieQueryErrorMap = (error: unknown) => unknown;
@@ -8,56 +7,93 @@ type QuestpieQueryOptionsConfig = {
8
7
  keyPrefix?: QueryKey;
9
8
  errorMap?: QuestpieQueryErrorMap;
10
9
  locale?: string;
10
+ stage?: string;
11
11
  };
12
12
  type AnyAsyncFn = (...args: any[]) => Promise<any>;
13
13
  type QueryData<TFn extends AnyAsyncFn> = Awaited<ReturnType<TFn>>;
14
14
  type FirstArg<TFn extends AnyAsyncFn> = Parameters<TFn> extends [infer TFirst, ...any[]] ? TFirst : never;
15
15
  type HasArgs<TFn extends AnyAsyncFn> = Parameters<TFn> extends [] ? false : true;
16
16
  type QueryBuilder<TFn extends AnyAsyncFn> = HasArgs<TFn> extends false ? () => UseQueryOptions<QueryData<TFn>> : undefined extends FirstArg<TFn> ? (options?: FirstArg<TFn>) => UseQueryOptions<QueryData<TFn>> : (options: FirstArg<TFn>) => UseQueryOptions<QueryData<TFn>>;
17
+ type KeyBuilder<TFn extends AnyAsyncFn> = HasArgs<TFn> extends false ? () => QueryKey : undefined extends FirstArg<TFn> ? (options?: FirstArg<TFn>) => QueryKey : (options: FirstArg<TFn>) => QueryKey;
18
+ type MutationVariables<TFn extends AnyAsyncFn> = HasArgs<TFn> extends false ? void : undefined extends FirstArg<TFn> ? FirstArg<TFn> | void : FirstArg<TFn>;
17
19
  type MutationBuilder<TVariables, TData> = () => UseMutationOptions<TData, DefaultError, TVariables>;
18
20
  /** Extract collection keys from QuestpieClient */
19
- type CollectionKeys<T extends Questpie<any>> = Extract<keyof QuestpieClient<T>["collections"], string>;
21
+ type CollectionKeys<TApp extends QuestpieApp> = Extract<keyof QuestpieClient<TApp>["collections"], string>;
20
22
  /** Extract global keys from QuestpieClient */
21
- type GlobalKeys<T extends Questpie<any>> = Extract<keyof QuestpieClient<T>["globals"], string>;
22
- type CollectionFind<T extends Questpie<any>, K$1 extends CollectionKeys<T>> = QuestpieClient<T>["collections"][K$1]["find"];
23
- type CollectionCount<T extends Questpie<any>, K$1 extends CollectionKeys<T>> = QuestpieClient<T>["collections"][K$1]["count"];
24
- type CollectionFindOne<T extends Questpie<any>, K$1 extends CollectionKeys<T>> = QuestpieClient<T>["collections"][K$1]["findOne"];
25
- type CollectionCreate<T extends Questpie<any>, K$1 extends CollectionKeys<T>> = QuestpieClient<T>["collections"][K$1]["create"];
26
- type CollectionUpdate<T extends Questpie<any>, K$1 extends CollectionKeys<T>> = QuestpieClient<T>["collections"][K$1]["update"];
27
- type CollectionDelete<T extends Questpie<any>, K$1 extends CollectionKeys<T>> = QuestpieClient<T>["collections"][K$1]["delete"];
28
- type CollectionRestore<T extends Questpie<any>, K$1 extends CollectionKeys<T>> = QuestpieClient<T>["collections"][K$1]["restore"];
29
- type GlobalGet<T extends Questpie<any>, K$1 extends GlobalKeys<T>> = QuestpieClient<T>["globals"][K$1] extends {
23
+ type GlobalKeys<TApp extends QuestpieApp> = Extract<keyof QuestpieClient<TApp>["globals"], string>;
24
+ type CollectionFind<TApp extends QuestpieApp, K$1 extends CollectionKeys<TApp>> = QuestpieClient<TApp>["collections"][K$1]["find"];
25
+ type CollectionCount<TApp extends QuestpieApp, K$1 extends CollectionKeys<TApp>> = QuestpieClient<TApp>["collections"][K$1]["count"];
26
+ type CollectionFindOne<TApp extends QuestpieApp, K$1 extends CollectionKeys<TApp>> = QuestpieClient<TApp>["collections"][K$1]["findOne"];
27
+ type CollectionCreate<TApp extends QuestpieApp, K$1 extends CollectionKeys<TApp>> = QuestpieClient<TApp>["collections"][K$1]["create"];
28
+ type CollectionUpdate<TApp extends QuestpieApp, K$1 extends CollectionKeys<TApp>> = QuestpieClient<TApp>["collections"][K$1]["update"];
29
+ type CollectionDelete<TApp extends QuestpieApp, K$1 extends CollectionKeys<TApp>> = QuestpieClient<TApp>["collections"][K$1]["delete"];
30
+ type CollectionRestore<TApp extends QuestpieApp, K$1 extends CollectionKeys<TApp>> = QuestpieClient<TApp>["collections"][K$1]["restore"];
31
+ type CollectionFindVersions<TApp extends QuestpieApp, K$1 extends CollectionKeys<TApp>> = QuestpieClient<TApp>["collections"][K$1]["findVersions"];
32
+ type CollectionRevertToVersion<TApp extends QuestpieApp, K$1 extends CollectionKeys<TApp>> = QuestpieClient<TApp>["collections"][K$1]["revertToVersion"];
33
+ type CollectionTransitionStage<TApp extends QuestpieApp, K$1 extends CollectionKeys<TApp>> = QuestpieClient<TApp>["collections"][K$1]["transitionStage"];
34
+ type GlobalGet<TApp extends QuestpieApp, K$1 extends GlobalKeys<TApp>> = QuestpieClient<TApp>["globals"][K$1] extends {
30
35
  get: infer TGet;
31
36
  } ? TGet extends AnyAsyncFn ? TGet : never : never;
32
- type GlobalUpdate<T extends Questpie<any>, K$1 extends GlobalKeys<T>> = QuestpieClient<T>["globals"][K$1] extends {
37
+ type GlobalUpdate<TApp extends QuestpieApp, K$1 extends GlobalKeys<TApp>> = QuestpieClient<TApp>["globals"][K$1] extends {
33
38
  update: infer TUpdate;
34
39
  } ? TUpdate extends AnyAsyncFn ? TUpdate : never : never;
35
- type CollectionQueryOptionsAPI<T extends Questpie<any>, K$1 extends CollectionKeys<T>> = {
36
- find: QueryBuilder<CollectionFind<T, K$1>>;
37
- count: QueryBuilder<CollectionCount<T, K$1>>;
38
- findOne: QueryBuilder<CollectionFindOne<T, K$1>>;
39
- create: MutationBuilder<FirstArg<CollectionCreate<T, K$1>>, QueryData<CollectionCreate<T, K$1>>>;
40
- update: MutationBuilder<{
41
- id: Parameters<CollectionUpdate<T, K$1>>[0];
42
- data: Parameters<CollectionUpdate<T, K$1>>[1];
43
- }, QueryData<CollectionUpdate<T, K$1>>>;
44
- delete: MutationBuilder<{
45
- id: Parameters<CollectionDelete<T, K$1>>[0];
46
- }, QueryData<CollectionDelete<T, K$1>>>;
47
- restore: MutationBuilder<{
48
- id: Parameters<CollectionRestore<T, K$1>>[0];
49
- }, QueryData<CollectionRestore<T, K$1>>>;
40
+ type GlobalFindVersions<TApp extends QuestpieApp, K$1 extends GlobalKeys<TApp>> = QuestpieClient<TApp>["globals"][K$1] extends {
41
+ findVersions: infer TFindVersions;
42
+ } ? TFindVersions extends AnyAsyncFn ? TFindVersions : never : never;
43
+ type GlobalRevertToVersion<TApp extends QuestpieApp, K$1 extends GlobalKeys<TApp>> = QuestpieClient<TApp>["globals"][K$1] extends {
44
+ revertToVersion: infer TRevert;
45
+ } ? TRevert extends AnyAsyncFn ? TRevert : never : never;
46
+ type GlobalTransitionStage<TApp extends QuestpieApp, K$1 extends GlobalKeys<TApp>> = QuestpieClient<TApp>["globals"][K$1] extends {
47
+ transitionStage: infer TTransition;
48
+ } ? TTransition extends AnyAsyncFn ? TTransition : never : never;
49
+ type RouteLeafQueryOptionsAPI<TFn extends AnyAsyncFn> = {
50
+ query: QueryBuilder<TFn>;
51
+ mutation: MutationBuilder<MutationVariables<TFn>, QueryData<TFn>>;
52
+ key: KeyBuilder<TFn>;
53
+ };
54
+ type RoutesQueryOptionsAPI<TNode> = TNode extends AnyAsyncFn ? RouteLeafQueryOptionsAPI<TNode> : TNode extends Record<string, any> ? { [K in keyof TNode]: RoutesQueryOptionsAPI<TNode[K]> } : never;
55
+ type CollectionQueryOptionsAPI<TApp extends QuestpieApp, K$1 extends CollectionKeys<TApp>> = {
56
+ find: QueryBuilder<CollectionFind<TApp, K$1>>;
57
+ count: QueryBuilder<CollectionCount<TApp, K$1>>;
58
+ findOne: QueryBuilder<CollectionFindOne<TApp, K$1>>;
59
+ create: MutationBuilder<FirstArg<CollectionCreate<TApp, K$1>>, QueryData<CollectionCreate<TApp, K$1>>>;
60
+ update: MutationBuilder<FirstArg<CollectionUpdate<TApp, K$1>>, QueryData<CollectionUpdate<TApp, K$1>>>;
61
+ delete: MutationBuilder<FirstArg<CollectionDelete<TApp, K$1>>, QueryData<CollectionDelete<TApp, K$1>>>;
62
+ restore: MutationBuilder<FirstArg<CollectionRestore<TApp, K$1>>, QueryData<CollectionRestore<TApp, K$1>>>;
63
+ findVersions: QueryBuilder<CollectionFindVersions<TApp, K$1>>;
64
+ revertToVersion: MutationBuilder<FirstArg<CollectionRevertToVersion<TApp, K$1>>, QueryData<CollectionRevertToVersion<TApp, K$1>>>;
65
+ transitionStage: MutationBuilder<FirstArg<CollectionTransitionStage<TApp, K$1>>, QueryData<CollectionTransitionStage<TApp, K$1>>>;
66
+ updateMany: MutationBuilder<{
67
+ where: any;
68
+ data: any;
69
+ }, QueryData<CollectionUpdate<TApp, K$1>>>;
70
+ deleteMany: MutationBuilder<{
71
+ where: any;
72
+ }, {
73
+ success: boolean;
74
+ count: number;
75
+ }>;
50
76
  };
51
- type GlobalQueryOptionsAPI<T extends Questpie<any>, K$1 extends GlobalKeys<T>> = {
52
- get: QueryBuilder<GlobalGet<T, K$1>>;
77
+ type GlobalQueryOptionsAPI<TApp extends QuestpieApp, K$1 extends GlobalKeys<TApp>> = {
78
+ get: QueryBuilder<GlobalGet<TApp, K$1>>;
53
79
  update: MutationBuilder<{
54
- data: Parameters<GlobalUpdate<T, K$1>>[0];
55
- options?: Parameters<GlobalUpdate<T, K$1>>[1];
56
- }, QueryData<GlobalUpdate<T, K$1>>>;
80
+ data: Parameters<GlobalUpdate<TApp, K$1>>[0];
81
+ options?: Parameters<GlobalUpdate<TApp, K$1>>[1];
82
+ }, QueryData<GlobalUpdate<TApp, K$1>>>;
83
+ findVersions: QueryBuilder<GlobalFindVersions<TApp, K$1>>;
84
+ revertToVersion: MutationBuilder<{
85
+ params: Parameters<GlobalRevertToVersion<TApp, K$1>>[0];
86
+ options?: Parameters<GlobalRevertToVersion<TApp, K$1>>[1];
87
+ }, QueryData<GlobalRevertToVersion<TApp, K$1>>>;
88
+ transitionStage: MutationBuilder<{
89
+ params: Parameters<GlobalTransitionStage<TApp, K$1>>[0];
90
+ options?: Parameters<GlobalTransitionStage<TApp, K$1>>[1];
91
+ }, QueryData<GlobalTransitionStage<TApp, K$1>>>;
57
92
  };
58
- type QuestpieQueryOptionsProxy<T extends Questpie<any>> = {
59
- collections: { [K in CollectionKeys<T>]: CollectionQueryOptionsAPI<T, K> };
60
- globals: { [K in GlobalKeys<T>]: GlobalQueryOptionsAPI<T, K> };
93
+ type QuestpieQueryOptionsProxy<TApp extends QuestpieApp = QuestpieApp> = {
94
+ collections: { [K in CollectionKeys<TApp>]: CollectionQueryOptionsAPI<TApp, K> };
95
+ globals: { [K in GlobalKeys<TApp>]: GlobalQueryOptionsAPI<TApp, K> };
96
+ routes: RoutesQueryOptionsAPI<QuestpieClient<TApp>["routes"]>;
61
97
  custom: {
62
98
  query: <TData>(config: {
63
99
  key: QueryKey;
@@ -77,17 +113,21 @@ type QuestpieQueryOptionsProxy<T extends Questpie<any>> = {
77
113
  * ```ts
78
114
  * import { createQuestpieQueryOptions } from "@questpie/tanstack-query"
79
115
  * import { createClient } from "questpie/client"
116
+ * import type { App, AppRpc } from "@/app"
80
117
  *
81
- * const client = createClient<typeof cms>({ baseURL: "http://localhost:3000" })
82
- * const qpo = createQuestpieQueryOptions(client)
118
+ * const client = createClient<App, AppRpc>({ baseURL: "http://localhost:3000" })
119
+ * const cmsQueries = createQuestpieQueryOptions(client)
83
120
  *
84
121
  * // Use with useQuery
85
- * const { data } = useQuery(qpo.collections.posts.find({ limit: 10 }))
122
+ * const { data } = useQuery(cmsQueries.collections.posts.find({ limit: 10 }))
86
123
  *
87
124
  * // Use with useMutation
88
- * const mutation = useMutation(qpo.collections.posts.create())
125
+ * const mutation = useMutation(cmsQueries.collections.posts.create())
126
+ *
127
+ * // Use with routes
128
+ * const stats = useQuery(cmsQueries.routes.dashboard.getStats.query({ period: "week" }))
89
129
  * ```
90
130
  */
91
- declare function createQuestpieQueryOptions<T extends Questpie<any>>(client: QuestpieClient<T>, config?: QuestpieQueryOptionsConfig): QuestpieQueryOptionsProxy<T>;
131
+ declare function createQuestpieQueryOptions<TApp extends QuestpieApp = QuestpieApp>(client: QuestpieClient<TApp>, config?: QuestpieQueryOptionsConfig): QuestpieQueryOptionsProxy<TApp>;
92
132
  //#endregion
93
- export { type DefaultError, type QueryKey, QuestpieQueryErrorMap, QuestpieQueryOptionsConfig, QuestpieQueryOptionsProxy, type UseMutationOptions, type UseQueryOptions, createQuestpieQueryOptions };
133
+ export { type DefaultError, type QueryKey, QuestpieQueryErrorMap, QuestpieQueryOptionsConfig, QuestpieQueryOptionsProxy, type RealtimeAPI, type TopicConfig, type UseMutationOptions, type UseQueryOptions, buildCollectionTopic, buildGlobalTopic, createQuestpieQueryOptions };
package/dist/index.mjs CHANGED
@@ -1,4 +1,5 @@
1
- import { mutationOptions, queryOptions } from "@tanstack/react-query";
1
+ import { experimental_streamedQuery, mutationOptions, queryOptions } from "@tanstack/react-query";
2
+ import { buildCollectionTopic, buildCollectionTopic as buildCollectionTopic$1, buildGlobalTopic, buildGlobalTopic as buildGlobalTopic$1 } from "questpie/client";
2
3
 
3
4
  //#region src/index.ts
4
5
  const defaultErrorMap = (error) => error instanceof Error ? error : new Error(typeof error === "string" ? error : "Unknown error");
@@ -44,114 +45,334 @@ const wrapMutationFn = (mutationFn, errorMap) => {
44
45
  * ```ts
45
46
  * import { createQuestpieQueryOptions } from "@questpie/tanstack-query"
46
47
  * import { createClient } from "questpie/client"
48
+ * import type { App, AppRpc } from "@/app"
47
49
  *
48
- * const client = createClient<typeof cms>({ baseURL: "http://localhost:3000" })
49
- * const qpo = createQuestpieQueryOptions(client)
50
+ * const client = createClient<App, AppRpc>({ baseURL: "http://localhost:3000" })
51
+ * const cmsQueries = createQuestpieQueryOptions(client)
50
52
  *
51
53
  * // Use with useQuery
52
- * const { data } = useQuery(qpo.collections.posts.find({ limit: 10 }))
54
+ * const { data } = useQuery(cmsQueries.collections.posts.find({ limit: 10 }))
53
55
  *
54
56
  * // Use with useMutation
55
- * const mutation = useMutation(qpo.collections.posts.create())
57
+ * const mutation = useMutation(cmsQueries.collections.posts.create())
58
+ *
59
+ * // Use with routes
60
+ * const stats = useQuery(cmsQueries.routes.dashboard.getStats.query({ period: "week" }))
56
61
  * ```
57
62
  */
58
63
  function createQuestpieQueryOptions(client, config = {}) {
59
64
  const keyPrefix = config.keyPrefix ?? ["questpie"];
60
65
  const errorMap = config.errorMap ?? defaultErrorMap;
61
66
  const locale = config.locale;
62
- return {
63
- collections: new Proxy({}, { get: (_target, collectionName) => {
64
- if (typeof collectionName !== "string") return void 0;
65
- const collection = client.collections[collectionName];
66
- const baseKey = ["collections", collectionName];
67
- return {
68
- find: (options) => queryOptions({
69
- queryKey: buildKey(keyPrefix, [
70
- ...baseKey,
71
- "find",
72
- locale,
73
- normalizeQueryKeyOptions(options)
74
- ]),
67
+ const stage = config.stage;
68
+ const collections = new Proxy({}, { get: (_target, collectionName) => {
69
+ if (typeof collectionName !== "string") return void 0;
70
+ const collection = client.collections[collectionName];
71
+ const baseKey = ["collections", collectionName];
72
+ return {
73
+ find: (options, queryConfig) => {
74
+ const qKey = buildKey(keyPrefix, [
75
+ ...baseKey,
76
+ "find",
77
+ locale,
78
+ stage,
79
+ normalizeQueryKeyOptions(options)
80
+ ]);
81
+ if (queryConfig?.realtime && client.realtime) {
82
+ const topic = buildCollectionTopic$1(collectionName, options);
83
+ return queryOptions({
84
+ queryKey: qKey,
85
+ queryFn: experimental_streamedQuery({
86
+ streamFn: ({ signal }) => client.realtime.stream(topic, signal),
87
+ reducer: (_, chunk) => chunk,
88
+ initialValue: void 0,
89
+ refetchMode: "append"
90
+ })
91
+ });
92
+ }
93
+ return queryOptions({
94
+ queryKey: qKey,
75
95
  queryFn: wrapQueryFn(() => collection.find(options), errorMap)
76
- }),
77
- count: (options) => queryOptions({
78
- queryKey: buildKey(keyPrefix, [
79
- ...baseKey,
80
- "count",
81
- locale,
82
- normalizeQueryKeyOptions(options)
83
- ]),
96
+ });
97
+ },
98
+ count: (options, queryConfig) => {
99
+ const qKey = buildKey(keyPrefix, [
100
+ ...baseKey,
101
+ "count",
102
+ locale,
103
+ stage,
104
+ normalizeQueryKeyOptions(options)
105
+ ]);
106
+ if (queryConfig?.realtime && client.realtime) {
107
+ const topic = buildCollectionTopic$1(collectionName, options);
108
+ return queryOptions({
109
+ queryKey: qKey,
110
+ queryFn: experimental_streamedQuery({
111
+ streamFn: ({ signal }) => client.realtime.stream(topic, signal),
112
+ reducer: (_, chunk) => typeof chunk?.totalDocs === "number" ? chunk.totalDocs : chunk,
113
+ initialValue: void 0,
114
+ refetchMode: "append"
115
+ })
116
+ });
117
+ }
118
+ return queryOptions({
119
+ queryKey: qKey,
84
120
  queryFn: wrapQueryFn(() => collection.count(options), errorMap)
85
- }),
86
- findOne: (options) => queryOptions({
87
- queryKey: buildKey(keyPrefix, [
88
- ...baseKey,
89
- "findOne",
90
- locale,
91
- normalizeQueryKeyOptions(options)
92
- ]),
93
- queryFn: wrapQueryFn(() => collection.findOne(options), errorMap)
94
- }),
95
- create: () => mutationOptions({
96
- mutationKey: buildKey(keyPrefix, [
97
- ...baseKey,
98
- "create",
99
- locale
100
- ]),
101
- mutationFn: wrapMutationFn((data) => collection.create(data, locale ? { locale } : void 0), errorMap)
102
- }),
103
- update: () => mutationOptions({
104
- mutationKey: buildKey(keyPrefix, [
105
- ...baseKey,
106
- "update",
107
- locale
108
- ]),
109
- mutationFn: wrapMutationFn((variables) => collection.update(variables.id, variables.data, locale ? { locale } : void 0), errorMap)
110
- }),
111
- delete: () => mutationOptions({
112
- mutationKey: buildKey(keyPrefix, [
113
- ...baseKey,
114
- "delete",
115
- locale
116
- ]),
117
- mutationFn: wrapMutationFn((variables) => collection.delete(variables.id, locale ? { locale } : void 0), errorMap)
118
- }),
119
- restore: () => mutationOptions({
120
- mutationKey: buildKey(keyPrefix, [
121
- ...baseKey,
122
- "restore",
123
- locale
124
- ]),
125
- mutationFn: wrapMutationFn((variables) => collection.restore(variables.id, locale ? { locale } : void 0), errorMap)
126
- })
127
- };
128
- } }),
129
- globals: new Proxy({}, { get: (_target, globalName) => {
130
- if (typeof globalName !== "string") return void 0;
131
- const global = client.globals[globalName];
132
- const baseKey = ["globals", globalName];
133
- return {
134
- get: (options) => queryOptions({
135
- queryKey: buildKey(keyPrefix, [
136
- ...baseKey,
137
- "get",
138
- locale,
139
- normalizeQueryKeyOptions(options)
140
- ]),
121
+ });
122
+ },
123
+ findOne: (options) => queryOptions({
124
+ queryKey: buildKey(keyPrefix, [
125
+ ...baseKey,
126
+ "findOne",
127
+ locale,
128
+ stage,
129
+ normalizeQueryKeyOptions(options)
130
+ ]),
131
+ queryFn: wrapQueryFn(() => collection.findOne(options), errorMap)
132
+ }),
133
+ create: () => mutationOptions({
134
+ mutationKey: buildKey(keyPrefix, [
135
+ ...baseKey,
136
+ "create",
137
+ locale,
138
+ stage
139
+ ]),
140
+ mutationFn: wrapMutationFn((data) => collection.create(data, locale || stage ? {
141
+ ...locale ? { locale } : {},
142
+ ...stage ? { stage } : {}
143
+ } : void 0), errorMap)
144
+ }),
145
+ update: () => mutationOptions({
146
+ mutationKey: buildKey(keyPrefix, [
147
+ ...baseKey,
148
+ "update",
149
+ locale,
150
+ stage
151
+ ]),
152
+ mutationFn: wrapMutationFn((variables) => collection.update(variables, locale || stage ? {
153
+ ...locale ? { locale } : {},
154
+ ...stage ? { stage } : {}
155
+ } : void 0), errorMap)
156
+ }),
157
+ delete: () => mutationOptions({
158
+ mutationKey: buildKey(keyPrefix, [
159
+ ...baseKey,
160
+ "delete",
161
+ locale,
162
+ stage
163
+ ]),
164
+ mutationFn: wrapMutationFn((variables) => collection.delete(variables, locale || stage ? {
165
+ ...locale ? { locale } : {},
166
+ ...stage ? { stage } : {}
167
+ } : void 0), errorMap)
168
+ }),
169
+ restore: () => mutationOptions({
170
+ mutationKey: buildKey(keyPrefix, [
171
+ ...baseKey,
172
+ "restore",
173
+ locale,
174
+ stage
175
+ ]),
176
+ mutationFn: wrapMutationFn((variables) => collection.restore(variables, locale || stage ? {
177
+ ...locale ? { locale } : {},
178
+ ...stage ? { stage } : {}
179
+ } : void 0), errorMap)
180
+ }),
181
+ findVersions: (params) => queryOptions({
182
+ queryKey: buildKey(keyPrefix, [
183
+ ...baseKey,
184
+ "findVersions",
185
+ locale,
186
+ stage,
187
+ normalizeQueryKeyOptions(params)
188
+ ]),
189
+ queryFn: wrapQueryFn(() => collection.findVersions(params, locale || stage ? {
190
+ ...locale ? { locale } : {},
191
+ ...stage ? { stage } : {}
192
+ } : void 0), errorMap)
193
+ }),
194
+ revertToVersion: () => mutationOptions({
195
+ mutationKey: buildKey(keyPrefix, [
196
+ ...baseKey,
197
+ "revertToVersion",
198
+ locale,
199
+ stage
200
+ ]),
201
+ mutationFn: wrapMutationFn((variables) => collection.revertToVersion(variables, locale || stage ? {
202
+ ...locale ? { locale } : {},
203
+ ...stage ? { stage } : {}
204
+ } : void 0), errorMap)
205
+ }),
206
+ transitionStage: () => mutationOptions({
207
+ mutationKey: buildKey(keyPrefix, [
208
+ ...baseKey,
209
+ "transitionStage",
210
+ locale,
211
+ stage
212
+ ]),
213
+ mutationFn: wrapMutationFn((variables) => collection.transitionStage(variables, locale || stage ? {
214
+ ...locale ? { locale } : {},
215
+ ...stage ? { stage } : {}
216
+ } : void 0), errorMap)
217
+ }),
218
+ updateMany: () => mutationOptions({
219
+ mutationKey: buildKey(keyPrefix, [
220
+ ...baseKey,
221
+ "updateMany",
222
+ locale,
223
+ stage
224
+ ]),
225
+ mutationFn: wrapMutationFn((variables) => collection.updateMany(variables, locale || stage ? {
226
+ ...locale ? { locale } : {},
227
+ ...stage ? { stage } : {}
228
+ } : void 0), errorMap)
229
+ }),
230
+ deleteMany: () => mutationOptions({
231
+ mutationKey: buildKey(keyPrefix, [
232
+ ...baseKey,
233
+ "deleteMany",
234
+ locale,
235
+ stage
236
+ ]),
237
+ mutationFn: wrapMutationFn((variables) => collection.deleteMany(variables, locale || stage ? {
238
+ ...locale ? { locale } : {},
239
+ ...stage ? { stage } : {}
240
+ } : void 0), errorMap)
241
+ })
242
+ };
243
+ } });
244
+ const globals = new Proxy({}, { get: (_target, globalName) => {
245
+ if (typeof globalName !== "string") return void 0;
246
+ const global = client.globals[globalName];
247
+ const baseKey = ["globals", globalName];
248
+ return {
249
+ get: (options, queryConfig) => {
250
+ const qKey = buildKey(keyPrefix, [
251
+ ...baseKey,
252
+ "get",
253
+ locale,
254
+ stage,
255
+ normalizeQueryKeyOptions(options)
256
+ ]);
257
+ if (queryConfig?.realtime && client.realtime) {
258
+ const topic = buildGlobalTopic$1(globalName, options);
259
+ return queryOptions({
260
+ queryKey: qKey,
261
+ queryFn: experimental_streamedQuery({
262
+ streamFn: ({ signal }) => client.realtime.stream(topic, signal),
263
+ reducer: (_, chunk) => chunk,
264
+ initialValue: void 0,
265
+ refetchMode: "append"
266
+ })
267
+ });
268
+ }
269
+ return queryOptions({
270
+ queryKey: qKey,
141
271
  queryFn: wrapQueryFn(() => global.get(options), errorMap)
142
- }),
143
- update: () => mutationOptions({
144
- mutationKey: buildKey(keyPrefix, [
145
- ...baseKey,
146
- "update",
147
- locale
148
- ]),
149
- mutationFn: wrapMutationFn((variables) => global.update(variables.data, {
150
- ...variables.options,
151
- ...locale ? { locale } : void 0
152
- }), errorMap)
153
- })
154
- };
272
+ });
273
+ },
274
+ update: () => mutationOptions({
275
+ mutationKey: buildKey(keyPrefix, [
276
+ ...baseKey,
277
+ "update",
278
+ locale,
279
+ stage
280
+ ]),
281
+ mutationFn: wrapMutationFn((variables) => global.update(variables.data, {
282
+ ...variables.options,
283
+ ...locale ? { locale } : void 0,
284
+ ...stage ? { stage } : void 0
285
+ }), errorMap)
286
+ }),
287
+ findVersions: (options) => queryOptions({
288
+ queryKey: buildKey(keyPrefix, [
289
+ ...baseKey,
290
+ "findVersions",
291
+ locale,
292
+ stage,
293
+ normalizeQueryKeyOptions(options)
294
+ ]),
295
+ queryFn: wrapQueryFn(() => global.findVersions({
296
+ ...options,
297
+ ...locale ? { locale } : void 0,
298
+ ...stage ? { stage } : void 0
299
+ }), errorMap)
300
+ }),
301
+ revertToVersion: () => mutationOptions({
302
+ mutationKey: buildKey(keyPrefix, [
303
+ ...baseKey,
304
+ "revertToVersion",
305
+ locale,
306
+ stage
307
+ ]),
308
+ mutationFn: wrapMutationFn((variables) => global.revertToVersion(variables.params, {
309
+ ...variables.options,
310
+ ...locale ? { locale } : void 0,
311
+ ...stage ? { stage } : void 0
312
+ }), errorMap)
313
+ }),
314
+ transitionStage: () => mutationOptions({
315
+ mutationKey: buildKey(keyPrefix, [
316
+ ...baseKey,
317
+ "transitionStage",
318
+ locale,
319
+ stage
320
+ ]),
321
+ mutationFn: wrapMutationFn((variables) => global.transitionStage(variables.params, {
322
+ ...variables.options,
323
+ ...locale ? { locale } : void 0
324
+ }), errorMap)
325
+ })
326
+ };
327
+ } });
328
+ /**
329
+ * Resolve a nested route caller from the client by traversing dot segments.
330
+ */
331
+ const callRoute = async (segments, input) => {
332
+ let current = client.routes;
333
+ for (const segment of segments) current = current?.[segment];
334
+ if (typeof current !== "function") throw new Error(`Route not found at path: ${segments.join(".") || "<root>"}`);
335
+ if (input === void 0) return current();
336
+ return current(input);
337
+ };
338
+ const createRouteNodeProxy = (segments) => {
339
+ return new Proxy({}, { get: (_target, prop) => {
340
+ if (prop === "query") return (input) => queryOptions({
341
+ queryKey: buildKey(keyPrefix, [
342
+ "routes",
343
+ ...segments,
344
+ "query",
345
+ locale,
346
+ normalizeQueryKeyOptions(input)
347
+ ]),
348
+ queryFn: wrapQueryFn(() => callRoute(segments, input), errorMap)
349
+ });
350
+ if (prop === "mutation") return () => mutationOptions({
351
+ mutationKey: buildKey(keyPrefix, [
352
+ "routes",
353
+ ...segments,
354
+ "mutation",
355
+ locale
356
+ ]),
357
+ mutationFn: wrapMutationFn((variables) => callRoute(segments, variables), errorMap)
358
+ });
359
+ if (prop === "key") return (input) => buildKey(keyPrefix, [
360
+ "routes",
361
+ ...segments,
362
+ "query",
363
+ locale,
364
+ normalizeQueryKeyOptions(input)
365
+ ]);
366
+ if (typeof prop !== "string") return void 0;
367
+ return createRouteNodeProxy([...segments, prop]);
368
+ } });
369
+ };
370
+ return {
371
+ collections,
372
+ globals,
373
+ routes: new Proxy({}, { get: (_target, prop) => {
374
+ if (typeof prop !== "string") return void 0;
375
+ return createRouteNodeProxy([prop]);
155
376
  } }),
156
377
  custom: {
157
378
  query: (customConfig) => queryOptions({
@@ -168,4 +389,4 @@ function createQuestpieQueryOptions(client, config = {}) {
168
389
  }
169
390
 
170
391
  //#endregion
171
- export { createQuestpieQueryOptions };
392
+ export { buildCollectionTopic, buildGlobalTopic, createQuestpieQueryOptions };
package/package.json CHANGED
@@ -1,15 +1,35 @@
1
1
  {
2
2
  "name": "@questpie/tanstack-query",
3
- "version": "1.1.1",
4
- "type": "module",
3
+ "version": "3.0.0",
5
4
  "repository": {
6
5
  "type": "git",
7
- "url": "https://github.com/questpie/questpie-cms.git",
6
+ "url": "https://github.com/questpie/questpie.git",
8
7
  "directory": "packages/tanstack-query"
9
8
  },
10
9
  "files": [
11
10
  "dist"
12
11
  ],
12
+ "type": "module",
13
+ "main": "./dist/index.mjs",
14
+ "module": "./dist/index.mjs",
15
+ "types": "./dist/index.d.mts",
16
+ "exports": {
17
+ ".": {
18
+ "types": "./dist/index.d.mts",
19
+ "default": "./dist/index.mjs"
20
+ },
21
+ "./package.json": "./package.json"
22
+ },
23
+ "publishConfig": {
24
+ "access": "public",
25
+ "exports": {
26
+ ".": {
27
+ "types": "./dist/index.d.mts",
28
+ "default": "./dist/index.mjs"
29
+ },
30
+ "./package.json": "./package.json"
31
+ }
32
+ },
13
33
  "scripts": {
14
34
  "build": "tsdown",
15
35
  "check-types": "tsc --noEmit"
@@ -19,16 +39,7 @@
19
39
  "tsdown": "^0.18.3"
20
40
  },
21
41
  "peerDependencies": {
22
- "questpie": "^1.0.0",
23
- "@tanstack/react-query": "^5.0.0"
24
- },
25
- "exports": {
26
- ".": {
27
- "import": "./dist/index.mjs",
28
- "types": "./dist/index.d.mts"
29
- }
30
- },
31
- "publishConfig": {
32
- "access": "public"
42
+ "@tanstack/react-query": "^5.0.0",
43
+ "questpie": "^3.0.0"
33
44
  }
34
45
  }