@tuyau/react-query 0.0.1-next.0 → 0.0.1-next.1

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/build/index.d.ts CHANGED
@@ -21,7 +21,7 @@ interface TuyauReactQueryOptions<EDef extends EndpointDef, TParams = Record<stri
21
21
  } | SkipToken, opts?: UndefinedTuyauQueryOptionsIn<UnionFromSuccessStatuses<EDef['response']>, TData, any>): UndefinedTuyauQueryOptionsOut<UnionFromSuccessStatuses<EDef['response']>, TData, any>;
22
22
  }
23
23
  /**
24
- * Interface for query function decorators (queryOptions, queryKey, queryFilter)
24
+ * Interface for query function decorators
25
25
  */
26
26
  interface DecorateQueryFn<EDef extends EndpointDef, TParams = Record<string, string | number>> extends TypeHelper<EDef> {
27
27
  queryOptions: TuyauReactQueryOptions<EDef, TParams>;
@@ -45,14 +45,17 @@ interface DecorateMutationFn<EDef extends EndpointDef, TParams = Record<string,
45
45
  /**
46
46
  * Output type for mutation options
47
47
  */
48
- interface TuyauMutationOptionsOut<TInput, TError, TOutput, TContext, TParams = Record<string, string | number>> extends UseMutationOptions<TOutput, TError, {
48
+ interface TuyauMutationOptionsOut<TInput, TError, TOutput, TContext, TParams = Record<string, string | number>> extends UseMutationOptions<TOutput, TError, TInput extends undefined | {} | Record<string, never> ? {
49
+ payload?: TInput;
50
+ params?: TParams;
51
+ } : {
49
52
  payload: TInput;
50
53
  params?: TParams;
51
54
  }, TContext> {
52
55
  mutationKey: TuyauMutationKey;
53
56
  }
54
57
  /**
55
- * Type definition for mutation options with params and payload support
58
+ * Type definition for mutation options
56
59
  */
57
60
  interface TuyauReactMutationOptions<TDef extends EndpointDef, TParams = Record<string, string | number>> {
58
61
  <TContext = unknown>(opts?: TuyauMutationOptionsIn<TDef['request'], any, UnionFromSuccessStatuses<TDef['response']>, TContext, TParams>): TuyauMutationOptionsOut<TDef['request'], any, UnionFromSuccessStatuses<TDef['response']>, TContext, TParams>;
@@ -95,38 +98,38 @@ type WithRequired<T, K extends keyof T> = T & Required<Pick<T, K>>;
95
98
  /**
96
99
  * Query options with defined initial data
97
100
  */
98
- interface DefinedTuyauQueryOptionsIn<TQueryFnData, TData, TError> extends DistributiveOmit<DefinedInitialDataOptions<TQueryFnData, TError, TData, TuyauQueryKey>, 'queryKey' | 'queryFn' | 'queryHashFn' | 'queryHash'> {
101
+ interface DefinedTuyauQueryOptionsIn<TQueryFnData, TData, TError> extends DistributiveOmit<DefinedInitialDataOptions<TQueryFnData, TError, TData, TuyauQueryKey>, 'queryKey' | 'queryFn' | 'queryHashFn' | 'queryHash'>, TuyauQueryBaseOptions {
99
102
  }
100
103
  /**
101
104
  * Query options with undefined initial data
102
105
  */
103
- interface UndefinedTuyauQueryOptionsIn<TQueryFnData, TData, TError> extends DistributiveOmit<UndefinedInitialDataOptions<TQueryFnData, TError, TData, TuyauQueryKey>, 'queryKey' | 'queryFn' | 'queryHashFn' | 'queryHash'> {
106
+ interface UndefinedTuyauQueryOptionsIn<TQueryFnData, TData, TError> extends DistributiveOmit<UndefinedInitialDataOptions<TQueryFnData, TError, TData, TuyauQueryKey>, 'queryKey' | 'queryFn' | 'queryHashFn' | 'queryHash'>, TuyauQueryBaseOptions {
104
107
  }
105
108
  /**
106
109
  * Query options with unused skip token
107
110
  */
108
- interface UnusedSkipTokenTuyauQueryOptionsIn<TQueryFnData, TData, TError> extends DistributiveOmit<UnusedSkipTokenOptions<TQueryFnData, TError, TData, TuyauQueryKey>, 'queryKey' | 'queryFn' | 'queryHashFn' | 'queryHash'> {
111
+ interface UnusedSkipTokenTuyauQueryOptionsIn<TQueryFnData, TData, TError> extends DistributiveOmit<UnusedSkipTokenOptions<TQueryFnData, TError, TData, TuyauQueryKey>, 'queryKey' | 'queryFn' | 'queryHashFn' | 'queryHash'>, TuyauQueryBaseOptions {
109
112
  }
110
113
  /**
111
114
  * Output type for query options with defined initial data
112
115
  */
113
- interface DefinedTuyauQueryOptionsOut<TQueryFnData, TData, TError> extends DefinedInitialDataOptions<TQueryFnData, TError, TData, TuyauQueryKey> {
116
+ interface DefinedTuyauQueryOptionsOut<TQueryFnData, TData, TError> extends DefinedInitialDataOptions<TQueryFnData, TError, TData, TuyauQueryKey>, TuyauQueryOptionsResult {
114
117
  queryKey: DataTag<TuyauQueryKey, TData, TError>;
115
118
  }
116
119
  /**
117
120
  * Output type for query options with undefined initial data
118
121
  */
119
- interface UndefinedTuyauQueryOptionsOut<TQueryFnData, TData, TError> extends UndefinedInitialDataOptions<TQueryFnData, TError, TData, TuyauQueryKey> {
122
+ interface UndefinedTuyauQueryOptionsOut<TQueryFnData, TData, TError> extends UndefinedInitialDataOptions<TQueryFnData, TError, TData, TuyauQueryKey>, TuyauQueryOptionsResult {
120
123
  queryKey: DataTag<TuyauQueryKey, TData, TError>;
121
124
  }
122
125
  /**
123
126
  * Output type for query options with unused skip token
124
127
  */
125
- interface UnusedSkipTokenTuyauQueryOptionsOut<TQueryFnData, TData, TError> extends UnusedSkipTokenOptions<TQueryFnData, TError, TData, TuyauQueryKey> {
128
+ interface UnusedSkipTokenTuyauQueryOptionsOut<TQueryFnData, TData, TError> extends UnusedSkipTokenOptions<TQueryFnData, TError, TData, TuyauQueryKey>, TuyauQueryOptionsResult {
126
129
  queryKey: DataTag<TuyauQueryKey, TData, TError>;
127
130
  }
128
131
  /**
129
- * Input type for mutation options with params and payload support
132
+ * Input type for mutation options
130
133
  */
131
134
  interface TuyauMutationOptionsIn<TInput, TError, TOutput, TContext, TParams = Record<string, string | number>> extends DistributiveOmit<UseMutationOptions<TOutput, TError, {
132
135
  payload: TInput;
@@ -161,6 +164,33 @@ type InferRequestType<Endpoint extends DecorateQueryFn<any> | DecorateMutationFn
161
164
  * Infer response type from an endpoint
162
165
  */
163
166
  type InferResponseType<Endpoint extends DecorateQueryFn<any> | DecorateMutationFn<any>> = Endpoint['~types']['response'];
167
+ /**
168
+ * Tuyau-specific request options for React Query integration
169
+ */
170
+ interface TuyauReactRequestOptions {
171
+ /**
172
+ * Opt out or into aborting request on unmount
173
+ */
174
+ abortOnUnmount?: boolean;
175
+ }
176
+ /**
177
+ * Base options for Tuyau queries
178
+ */
179
+ interface TuyauQueryBaseOptions {
180
+ /**
181
+ * Tuyau-related options
182
+ */
183
+ tuyau?: TuyauReactRequestOptions;
184
+ }
185
+ /**
186
+ * Result interface for Tuyau query options
187
+ */
188
+ interface TuyauQueryOptionsResult {
189
+ tuyau: {
190
+ path: string[];
191
+ type: 'query';
192
+ };
193
+ }
164
194
 
165
195
  /**
166
196
  * Reserved infinite query options that should not be overridden
@@ -176,17 +206,21 @@ type TuyauInfiniteData<TData> = {
176
206
  /**
177
207
  * Infinite query options with undefined initial data
178
208
  */
179
- interface UndefinedTuyauInfiniteQueryOptionsIn<TQueryFnData, TData, TError> extends DistributiveOmit<UndefinedInitialDataInfiniteOptions<TQueryFnData, TError, TuyauInfiniteData<TData>, TuyauQueryKey, unknown>, InfiniteQueryReservedOptions> {
209
+ interface UndefinedTuyauInfiniteQueryOptionsIn<TQueryFnData, TData, TError, TRequest, TPageParamKey extends keyof TRequest> extends DistributiveOmit<UndefinedInitialDataInfiniteOptions<TQueryFnData, TError, TuyauInfiniteData<TData>, TuyauQueryKey, ExtractPageParamType<TRequest, TPageParamKey> | null>, InfiniteQueryReservedOptions>, TuyauQueryBaseOptions {
210
+ pageParamKey: TPageParamKey;
180
211
  }
181
212
  /**
182
213
  * Infinite query options with defined initial data
183
214
  */
184
- interface DefinedTuyauInfiniteQueryOptionsIn<TQueryFnData, TData, TError> extends DistributiveOmit<DefinedInitialDataInfiniteOptions<TQueryFnData, TError, TuyauInfiniteData<TData>, TuyauQueryKey, unknown>, InfiniteQueryReservedOptions> {
215
+ interface DefinedTuyauInfiniteQueryOptionsIn<TQueryFnData, TData, TError, TRequest, TPageParamKey extends keyof TRequest> extends DistributiveOmit<DefinedInitialDataInfiniteOptions<TQueryFnData, TError, TuyauInfiniteData<TData>, TuyauQueryKey, ExtractPageParamType<TRequest, TPageParamKey> | null>, InfiniteQueryReservedOptions>, TuyauQueryBaseOptions {
216
+ pageParamKey: TPageParamKey;
185
217
  }
218
+ type ExtractPageParamType<TRequest, TPageParamKey extends keyof TRequest> = TRequest[TPageParamKey];
186
219
  /**
187
220
  * Infinite query options with unused skip token
188
221
  */
189
- interface UnusedSkipTokenTuyauInfiniteQueryOptionsIn<TQueryFnData, TData, TError> extends DistributiveOmit<UnusedSkipTokenInfiniteOptions<TQueryFnData, TError, TuyauInfiniteData<TData>, TuyauQueryKey, unknown>, InfiniteQueryReservedOptions> {
222
+ interface UnusedSkipTokenTuyauInfiniteQueryOptionsIn<TQueryFnData, TData, TError, TRequest, TPageParamKey extends keyof TRequest> extends DistributiveOmit<UnusedSkipTokenInfiniteOptions<TQueryFnData, TError, TuyauInfiniteData<TData>, TuyauQueryKey, ExtractPageParamType<TRequest, TPageParamKey>>, InfiniteQueryReservedOptions>, TuyauQueryBaseOptions {
223
+ pageParamKey: TPageParamKey;
190
224
  }
191
225
  /**
192
226
  * Output type for infinite query options with undefined initial data
@@ -222,18 +256,18 @@ interface UnusedSkipTokenTuyauInfiniteQueryOptionsOut<TQueryFnData, TData, TErro
222
256
  * Type definition for infinite query options with overloads for different scenarios
223
257
  */
224
258
  interface TuyauReactInfiniteQueryOptions<EDef extends EndpointDef, TParams = Record<string, string | number>> {
225
- <TData = UnionFromSuccessStatuses<EDef['response']>>(input: {
226
- payload?: EDef['request'];
259
+ <TData = UnionFromSuccessStatuses<EDef['response']>, TPageParamKey extends keyof EDef['request'] = string>(input: {
260
+ payload?: Omit<EDef['request'], TPageParamKey>;
227
261
  params?: TParams;
228
- } | SkipToken, opts: DefinedTuyauInfiniteQueryOptionsIn<UnionFromSuccessStatuses<EDef['response']>, TData, any>): DefinedTuyauInfiniteQueryOptionsOut<UnionFromSuccessStatuses<EDef['response']>, TData, any>;
229
- <TData = UnionFromSuccessStatuses<EDef['response']>>(input: {
230
- payload?: EDef['request'];
262
+ } | SkipToken, opts: DefinedTuyauInfiniteQueryOptionsIn<UnionFromSuccessStatuses<EDef['response']>, TData, any, EDef['request'], TPageParamKey>): DefinedTuyauInfiniteQueryOptionsOut<UnionFromSuccessStatuses<EDef['response']>, TData, any>;
263
+ <TData = UnionFromSuccessStatuses<EDef['response']>, TPageParamKey extends keyof EDef['request'] = string>(input: {
264
+ payload?: Omit<EDef['request'], TPageParamKey>;
231
265
  params?: TParams;
232
- }, opts: UnusedSkipTokenTuyauInfiniteQueryOptionsIn<UnionFromSuccessStatuses<EDef['response']>, TData, any>): UnusedSkipTokenTuyauInfiniteQueryOptionsOut<UnionFromSuccessStatuses<EDef['response']>, TData, any>;
233
- <TData = UnionFromSuccessStatuses<EDef['response']>>(input?: {
234
- payload?: EDef['request'];
266
+ }, opts: UnusedSkipTokenTuyauInfiniteQueryOptionsIn<UnionFromSuccessStatuses<EDef['response']>, TData, any, EDef['request'], TPageParamKey>): UnusedSkipTokenTuyauInfiniteQueryOptionsOut<UnionFromSuccessStatuses<EDef['response']>, TData, any>;
267
+ <TData = UnionFromSuccessStatuses<EDef['response']>, TPageParamKey extends keyof EDef['request'] = string>(input?: {
268
+ payload?: Omit<EDef['request'], TPageParamKey>;
235
269
  params?: TParams;
236
- } | SkipToken, opts?: UndefinedTuyauInfiniteQueryOptionsIn<UnionFromSuccessStatuses<EDef['response']>, TData, any>): UndefinedTuyauInfiniteQueryOptionsOut<UnionFromSuccessStatuses<EDef['response']>, TData, any>;
270
+ } | SkipToken, opts?: UndefinedTuyauInfiniteQueryOptionsIn<UnionFromSuccessStatuses<EDef['response']>, TData, any, EDef['request'], TPageParamKey>): UndefinedTuyauInfiniteQueryOptionsOut<UnionFromSuccessStatuses<EDef['response']>, TData, any>;
237
271
  }
238
272
  /**
239
273
  * Interface for infinite query function decorators
@@ -251,12 +285,20 @@ interface DecorateInfiniteQueryFn<EDef extends EndpointDef, TParams = Record<str
251
285
  }
252
286
 
253
287
  /**
254
- * Create the Tuyau React Query client
288
+ * Options for configuring the Tuyau React Query client
255
289
  */
256
- declare function createTuyauReactQueryClient<D extends Record<string, any>, R extends GeneratedRoutes>(options: {
290
+ interface TuyauReactQueryClientOptions<D extends Record<string, any>, R extends GeneratedRoutes> {
257
291
  client: TuyauClient<D, R>;
258
292
  queryClient: QueryClient | (() => QueryClient);
259
- }): TuyauReactQuery<D> & DecorateRouterKeyable;
293
+ /**
294
+ * Global Tuyau-specific request options
295
+ */
296
+ globalOptions?: TuyauReactRequestOptions;
297
+ }
298
+ /**
299
+ * Create the Tuyau React Query client
300
+ */
301
+ declare function createTuyauReactQueryClient<D extends Record<string, any>, R extends GeneratedRoutes>(options: TuyauReactQueryClientOptions<D, R>): TuyauReactQuery<D> & DecorateRouterKeyable;
260
302
  /**
261
303
  * Main type for the Tuyau React Query client
262
304
  * Maps route definitions to appropriate query or mutation decorators
@@ -288,7 +330,7 @@ type CreateParamFunction<Route extends Record<string, any>, Path extends string,
288
330
  * Create the parameter property mappings
289
331
  */
290
332
  type CreateParamProperties<Route extends Record<string, any>, Path extends string, NotProvidedParams> = {
291
- [K in keyof Route as K extends `:${string}` ? K : never]: TuyauReactQuery<Route[K], NotProvidedParams & PathParamToObject<Path>>;
333
+ [K in keyof Route as K extends `:${string}` ? K : never]: TuyauReactQuery<Route[K], NotProvidedParams & PathParamToObject<Path>> & DecorateRouterKeyable;
292
334
  };
293
335
  /**
294
336
  * Type for handling route parameters
package/build/index.js CHANGED
@@ -69,11 +69,24 @@ function getQueryKeyInternal(path, input, type) {
69
69
  ];
70
70
  }
71
71
  function tuyauQueryOptions(options) {
72
- const { input, opts, queryKey, path, client } = options;
72
+ const { input, opts, queryKey, path, client, globalOptions } = options;
73
73
  const inputIsSkipToken = input === skipToken;
74
- const queryFn = inputIsSkipToken ? skipToken : async () => {
74
+ const queryFn = inputIsSkipToken ? skipToken : async (queryFnContext) => {
75
75
  const { payload, requestPath } = extractInputAndPath(input, path);
76
- return await client.$fetch({ paths: requestPath, input: payload });
76
+ const effectiveAbortOnUnmount = opts?.tuyau?.abortOnUnmount ?? globalOptions?.abortOnUnmount ?? false;
77
+ const actualOpts = {
78
+ ...opts,
79
+ tuyau: {
80
+ ...globalOptions,
81
+ ...opts?.tuyau,
82
+ ...effectiveAbortOnUnmount ? { signal: queryFnContext.signal } : { signal: null }
83
+ }
84
+ };
85
+ return await client.$fetch({
86
+ paths: requestPath,
87
+ input: payload,
88
+ queryOptions: actualOpts
89
+ });
77
90
  };
78
91
  return Object.assign(queryOptions({ ...opts, queryKey, queryFn }), {
79
92
  tuyau: { path, type: "query" }
@@ -93,21 +106,44 @@ import {
93
106
  infiniteQueryOptions,
94
107
  skipToken as skipToken2
95
108
  } from "@tanstack/react-query";
96
- function extractInfiniteInputAndPath(input, path) {
109
+ function extractInfiniteInputAndPath(input, path, pageParamKey, pageParam) {
97
110
  if (typeof input !== "object" || input === null || !("payload" in input) && !("params" in input)) {
98
111
  const payload2 = typeof input === "object" && input !== null ? input : {};
99
- return { payload: payload2, requestPath: path };
112
+ const enhancedPayload2 = { ...payload2, [pageParamKey]: pageParam };
113
+ return { payload: enhancedPayload2, requestPath: path };
100
114
  }
101
115
  const { payload, params } = input;
102
116
  const requestPath = buildRequestPath(path, params);
103
- return { payload, requestPath };
117
+ const enhancedPayload = { ...payload, [pageParamKey]: pageParam };
118
+ return { payload: enhancedPayload, requestPath };
104
119
  }
105
120
  function tuyauInfiniteQueryOptions(options) {
106
- const { input, opts, queryKey, path, client } = options;
121
+ const { input, opts, queryKey, path, client, globalOptions } = options;
107
122
  const inputIsSkipToken = input === skipToken2;
108
- const queryFn = inputIsSkipToken ? skipToken2 : async () => {
109
- const { payload, requestPath } = extractInfiniteInputAndPath(input, path);
110
- return await client.$fetch({ paths: requestPath, input: payload });
123
+ if (!opts?.pageParamKey) {
124
+ throw new Error("pageParamKey is required for infinite queries");
125
+ }
126
+ const queryFn = inputIsSkipToken ? skipToken2 : async (queryFnContext) => {
127
+ const { payload, requestPath } = extractInfiniteInputAndPath(
128
+ input,
129
+ path,
130
+ opts.pageParamKey,
131
+ queryFnContext.pageParam
132
+ );
133
+ const effectiveAbortOnUnmount = opts?.tuyau?.abortOnUnmount ?? globalOptions?.abortOnUnmount ?? false;
134
+ const actualOpts = {
135
+ ...opts,
136
+ tuyau: {
137
+ ...globalOptions,
138
+ ...opts?.tuyau,
139
+ ...effectiveAbortOnUnmount ? { signal: queryFnContext.signal } : { signal: null }
140
+ }
141
+ };
142
+ return await client.$fetch({
143
+ paths: requestPath,
144
+ input: payload,
145
+ queryOptions: actualOpts
146
+ });
111
147
  };
112
148
  return Object.assign(
113
149
  infiniteQueryOptions({
@@ -176,7 +212,8 @@ function createTuyauReactQueryClient(options) {
176
212
  queryKey: getQueryKeyInternal(patternPath, arg1, "query"),
177
213
  queryClient: unwrapLazyArg(options.queryClient),
178
214
  client: options.client,
179
- path
215
+ path,
216
+ globalOptions: options.globalOptions
180
217
  });
181
218
  }
182
219
  if (fnName === "infiniteQueryOptions") {
@@ -186,7 +223,8 @@ function createTuyauReactQueryClient(options) {
186
223
  queryKey: getQueryKeyInternal(patternPath, arg1, "infinite"),
187
224
  queryClient: unwrapLazyArg(options.queryClient),
188
225
  client: options.client,
189
- path
226
+ path,
227
+ globalOptions: options.globalOptions
190
228
  });
191
229
  }
192
230
  if (fnName === "queryKey") return getQueryKeyInternal(patternPath, arg1, "query");
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tuyau/react-query",
3
3
  "type": "module",
4
- "version": "0.0.1-next.0",
4
+ "version": "0.0.1-next.1",
5
5
  "description": "React Query plugin for Tuyau",
6
6
  "author": "Julien Ripouteau <julien@ripouteau.com>",
7
7
  "license": "ISC",
@@ -29,7 +29,7 @@
29
29
  "@vinejs/vine": "^3.0.1",
30
30
  "nock": "^14.0.4",
31
31
  "react": "^19.1.0",
32
- "@tuyau/client": "0.2.11-next.0"
32
+ "@tuyau/client": "0.2.11-next.2"
33
33
  },
34
34
  "tsup": {
35
35
  "entry": [