@spoosh/react 0.10.1 → 0.12.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 +58 -41
- package/dist/index.d.mts +178 -90
- package/dist/index.d.ts +178 -90
- package/dist/index.js +132 -51
- package/dist/index.mjs +137 -52
- package/package.json +4 -4
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ReadClient, TagMode, SpooshResponse, SpooshPlugin, PluginTypeConfig, MergePluginResults, WriteSelectorClient, SpooshBody, StateManager, EventEmitter, PluginExecutor, PluginArray, ResolveTypes, MergePluginOptions, ResolverContext, ResolveResultTypes, MergePluginInstanceApi, SpooshOptions } from '@spoosh/core';
|
|
1
|
+
import { ReadClient, TagMode, SpooshResponse, ExtractTriggerQuery as ExtractTriggerQuery$2, ExtractTriggerBody as ExtractTriggerBody$2, ExtractTriggerParams as ExtractTriggerParams$2, SpooshPlugin, PluginTypeConfig, MergePluginResults, WriteSelectorClient, SpooshBody, QueueSelectorClient, QueueItem, QueueStats, InfiniteRequestOptions, InfiniteNextContext, InfinitePage, InfinitePrevContext, StateManager, EventEmitter, PluginExecutor, PluginArray, ResolveTypes, MergePluginOptions, ResolverContext, ResolveResultTypes, MergePluginInstanceApi, SpooshOptions } from '@spoosh/core';
|
|
2
2
|
|
|
3
3
|
type SuccessResponse<T> = Extract<T, {
|
|
4
4
|
data: unknown;
|
|
@@ -81,28 +81,13 @@ type ResponseInputFields<TQuery, TBody, TParamNames extends string> = [
|
|
|
81
81
|
] extends [never, never, never] ? object : {
|
|
82
82
|
input: ReadInputFields<TQuery, TBody, TParamNames>;
|
|
83
83
|
};
|
|
84
|
-
type TriggerAwaitedReturn$
|
|
85
|
-
type ExtractInputFromResponse$
|
|
84
|
+
type TriggerAwaitedReturn$3<T> = T extends (...args: never[]) => infer R ? Awaited<R> : never;
|
|
85
|
+
type ExtractInputFromResponse$3<T> = T extends {
|
|
86
86
|
input: infer I;
|
|
87
87
|
} ? I : never;
|
|
88
|
-
type
|
|
89
|
-
query: infer Q;
|
|
90
|
-
} ? {
|
|
91
|
-
query?: Q;
|
|
92
|
-
} : unknown;
|
|
93
|
-
type ExtractTriggerBody$1<I> = I extends {
|
|
94
|
-
body: infer B;
|
|
95
|
-
} ? {
|
|
96
|
-
body?: B;
|
|
97
|
-
} : unknown;
|
|
98
|
-
type ExtractTriggerParams$1<I> = I extends {
|
|
99
|
-
params: infer P;
|
|
100
|
-
} ? {
|
|
101
|
-
params?: P;
|
|
102
|
-
} : unknown;
|
|
103
|
-
type TriggerOptions<T> = ExtractInputFromResponse$1<TriggerAwaitedReturn$1<T>> extends infer I ? [I] extends [never] ? {
|
|
88
|
+
type TriggerOptions<T> = ExtractInputFromResponse$3<TriggerAwaitedReturn$3<T>> extends infer I ? [I] extends [never] ? {
|
|
104
89
|
force?: boolean;
|
|
105
|
-
} : ExtractTriggerQuery$
|
|
90
|
+
} : ExtractTriggerQuery$2<I> & ExtractTriggerBody$2<I> & ExtractTriggerParams$2<I> & {
|
|
106
91
|
/** Force refetch even if data is cached */
|
|
107
92
|
force?: boolean;
|
|
108
93
|
} : {
|
|
@@ -160,30 +145,30 @@ type InputFields<TQuery, TBody, TParamNames extends string> = OptionalQueryField
|
|
|
160
145
|
type WriteResponseInputFields<TQuery, TBody, TParamNames extends string> = [TQuery, TBody, TParamNames] extends [never, never, never] ? object : {
|
|
161
146
|
input: InputFields<TQuery, TBody, TParamNames> | undefined;
|
|
162
147
|
};
|
|
163
|
-
type TriggerAwaitedReturn<T> = T extends (...args: any[]) => infer R ? Awaited<R> : never;
|
|
164
|
-
type ExtractInputFromResponse<T> = T extends {
|
|
148
|
+
type TriggerAwaitedReturn$2<T> = T extends (...args: any[]) => infer R ? Awaited<R> : never;
|
|
149
|
+
type ExtractInputFromResponse$2<T> = T extends {
|
|
165
150
|
input: infer I;
|
|
166
151
|
} ? I : never;
|
|
167
|
-
type ExtractTriggerQuery<I> = I extends {
|
|
152
|
+
type ExtractTriggerQuery$1<I> = I extends {
|
|
168
153
|
query: infer Q;
|
|
169
154
|
} ? undefined extends Q ? {
|
|
170
155
|
query?: Exclude<Q, undefined>;
|
|
171
156
|
} : {
|
|
172
157
|
query: Q;
|
|
173
158
|
} : unknown;
|
|
174
|
-
type ExtractTriggerBody<I> = I extends {
|
|
159
|
+
type ExtractTriggerBody$1<I> = I extends {
|
|
175
160
|
body: infer B;
|
|
176
161
|
} ? undefined extends B ? {
|
|
177
162
|
body?: Exclude<B, undefined> | SpooshBody<Exclude<B, undefined>>;
|
|
178
163
|
} : {
|
|
179
164
|
body: B | SpooshBody<B>;
|
|
180
165
|
} : unknown;
|
|
181
|
-
type ExtractTriggerParams<I> = I extends {
|
|
166
|
+
type ExtractTriggerParams$1<I> = I extends {
|
|
182
167
|
params: infer P;
|
|
183
168
|
} ? {
|
|
184
169
|
params: P;
|
|
185
170
|
} : unknown;
|
|
186
|
-
type WriteTriggerInput<T> = ExtractInputFromResponse<TriggerAwaitedReturn<T>> extends infer I ? [I] extends [never] ? object : ExtractTriggerQuery<I> & ExtractTriggerBody<I> & ExtractTriggerParams<I> : object;
|
|
171
|
+
type WriteTriggerInput<T> = ExtractInputFromResponse$2<TriggerAwaitedReturn$2<T>> extends infer I ? [I] extends [never] ? object : ExtractTriggerQuery$1<I> & ExtractTriggerBody$1<I> & ExtractTriggerParams$1<I> : object;
|
|
187
172
|
/**
|
|
188
173
|
* Result returned by `useWrite` hook.
|
|
189
174
|
*
|
|
@@ -209,42 +194,93 @@ type BaseWriteResult<TData, TError, TOptions, TMeta = Record<string, unknown>> =
|
|
|
209
194
|
type UseWriteResult<TData, TError, TOptions, TMeta, TPlugins extends readonly SpooshPlugin<PluginTypeConfig>[]> = BaseWriteResult<TData, TError, TOptions, TMeta> & MergePluginResults<TPlugins>["write"];
|
|
210
195
|
type WriteApiClient<TSchema, TDefaultError> = WriteSelectorClient<TSchema, TDefaultError>;
|
|
211
196
|
|
|
212
|
-
type
|
|
213
|
-
type
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
197
|
+
type TriggerAwaitedReturn$1<T> = T extends (...args: any[]) => infer R ? Awaited<R> : never;
|
|
198
|
+
type ExtractInputFromResponse$1<T> = T extends {
|
|
199
|
+
input: infer I;
|
|
200
|
+
} ? I : never;
|
|
201
|
+
type ExtractTriggerQuery<I> = I extends {
|
|
202
|
+
query: infer Q;
|
|
203
|
+
} ? undefined extends Q ? {
|
|
204
|
+
query?: Exclude<Q, undefined>;
|
|
205
|
+
} : {
|
|
206
|
+
query: Q;
|
|
207
|
+
} : unknown;
|
|
208
|
+
type ExtractTriggerBody<I> = I extends {
|
|
209
|
+
body: infer B;
|
|
210
|
+
} ? undefined extends B ? {
|
|
211
|
+
body?: Exclude<B, undefined> | SpooshBody<Exclude<B, undefined>>;
|
|
212
|
+
} : {
|
|
213
|
+
body: B | SpooshBody<B>;
|
|
214
|
+
} : unknown;
|
|
215
|
+
type ExtractTriggerParams<I> = I extends {
|
|
216
|
+
params: infer P;
|
|
217
|
+
} ? {
|
|
218
|
+
params: P;
|
|
219
|
+
} : unknown;
|
|
220
|
+
type QueueTriggerBase = {
|
|
221
|
+
/** Custom ID for this queue item. If not provided, one will be auto-generated. */
|
|
222
|
+
id?: string;
|
|
217
223
|
};
|
|
224
|
+
type QueueTriggerInput<T> = ExtractInputFromResponse$1<TriggerAwaitedReturn$1<T>> extends infer I ? [I] extends [never] ? QueueTriggerBase : QueueTriggerBase & ExtractTriggerQuery<I> & ExtractTriggerBody<I> & ExtractTriggerParams<I> : QueueTriggerBase;
|
|
218
225
|
/**
|
|
219
|
-
*
|
|
226
|
+
* Options for useQueue hook.
|
|
220
227
|
*/
|
|
221
|
-
|
|
222
|
-
/**
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
+
interface UseQueueOptions {
|
|
229
|
+
/** Maximum concurrent operations. Defaults to 3. */
|
|
230
|
+
concurrency?: number;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Result returned by useQueue hook.
|
|
234
|
+
*
|
|
235
|
+
* @template TData - The response data type
|
|
236
|
+
* @template TError - The error type
|
|
237
|
+
* @template TTriggerInput - The trigger input type
|
|
238
|
+
* @template TMeta - Plugin-contributed metadata on queue items
|
|
239
|
+
*/
|
|
240
|
+
type UseQueueResult<TData, TError, TTriggerInput, TMeta = object> = {
|
|
241
|
+
/** Add item to queue and execute. Returns promise for this item. */
|
|
242
|
+
trigger: (input?: TTriggerInput) => Promise<SpooshResponse<TData, TError>>;
|
|
243
|
+
/** All tasks in queue with their current status */
|
|
244
|
+
tasks: QueueItem<TData, TError, TMeta>[];
|
|
245
|
+
/** Queue statistics (pending/loading/settled/success/failed/total/percentage) */
|
|
246
|
+
stats: QueueStats;
|
|
247
|
+
/** Abort task by ID, or all tasks if no ID */
|
|
248
|
+
abort: (id?: string) => void;
|
|
249
|
+
/** Retry failed task by ID, or all failed if no ID */
|
|
250
|
+
retry: (id?: string) => Promise<void>;
|
|
251
|
+
/** Remove specific task by ID (aborts if active) */
|
|
252
|
+
remove: (id: string) => void;
|
|
253
|
+
/** Remove all settled tasks (success, error, aborted). Keeps pending/running. */
|
|
254
|
+
removeSettled: () => void;
|
|
255
|
+
/** Abort all and clear queue */
|
|
256
|
+
clear: () => void;
|
|
228
257
|
};
|
|
229
258
|
/**
|
|
230
|
-
*
|
|
259
|
+
* API client type for queue selector.
|
|
260
|
+
* Supports all HTTP methods (GET, POST, PUT, PATCH, DELETE).
|
|
231
261
|
*/
|
|
232
|
-
type
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
262
|
+
type QueueApiClient<TSchema, TDefaultError> = QueueSelectorClient<TSchema, TDefaultError>;
|
|
263
|
+
|
|
264
|
+
type TagModeInArray = "all" | "self";
|
|
265
|
+
type TriggerAwaitedReturn<T> = T extends (...args: never[]) => infer R ? Awaited<R> : never;
|
|
266
|
+
type ExtractInputFromResponse<T> = T extends {
|
|
267
|
+
input: infer I;
|
|
268
|
+
} ? I : never;
|
|
269
|
+
type BaseTriggerOptions = {
|
|
270
|
+
/** Bypass cache and force refetch. Default: true */
|
|
271
|
+
force?: boolean;
|
|
239
272
|
};
|
|
273
|
+
type PagesTriggerOptions<TReadFn> = ExtractInputFromResponse<TriggerAwaitedReturn<TReadFn>> extends infer I ? [I] extends [never] ? BaseTriggerOptions : ExtractTriggerQuery$2<I> & ExtractTriggerBody$2<I> & ExtractTriggerParams$2<I> & BaseTriggerOptions : BaseTriggerOptions;
|
|
240
274
|
/**
|
|
241
|
-
* Options for `
|
|
275
|
+
* Options for `usePages` hook.
|
|
242
276
|
*
|
|
243
277
|
* @template TData - The response data type for each page
|
|
244
278
|
* @template TItem - The item type after merging all responses
|
|
279
|
+
* @template TError - The error type
|
|
245
280
|
* @template TRequest - The request options type (query, params, body)
|
|
281
|
+
* @template TMeta - Plugin metadata type
|
|
246
282
|
*/
|
|
247
|
-
type
|
|
283
|
+
type BasePagesOptions<TData, TItem, TError = unknown, TRequest = InfiniteRequestOptions, TMeta = Record<string, unknown>> = {
|
|
248
284
|
/** Whether to fetch automatically on mount. Default: true */
|
|
249
285
|
enabled?: boolean;
|
|
250
286
|
/**
|
|
@@ -255,30 +291,66 @@ type BaseInfiniteReadOptions<TData, TItem, TRequest = AnyInfiniteRequestOptions>
|
|
|
255
291
|
* - 'none' should only be used as string (use `tags: 'none'` not in array)
|
|
256
292
|
*/
|
|
257
293
|
tags?: TagMode | (TagModeInArray | (string & {}))[];
|
|
258
|
-
/**
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
294
|
+
/**
|
|
295
|
+
* Callback to determine if there's a next page to fetch.
|
|
296
|
+
* Receives the last page to check for pagination indicators.
|
|
297
|
+
* Default: `() => false` (no next page fetching)
|
|
298
|
+
*
|
|
299
|
+
* @example
|
|
300
|
+
* ```ts
|
|
301
|
+
* canFetchNext: ({ lastPage }) => lastPage?.data?.nextCursor != null
|
|
302
|
+
* ```
|
|
303
|
+
*/
|
|
304
|
+
canFetchNext?: (ctx: InfiniteNextContext<TData, TError, TRequest, TMeta>) => boolean;
|
|
305
|
+
/**
|
|
306
|
+
* Callback to build the request options for the next page.
|
|
307
|
+
* Return only the fields that change - they will be **merged** with the initial request.
|
|
308
|
+
* Default: `() => ({})` (no changes to request)
|
|
309
|
+
*
|
|
310
|
+
* @example
|
|
311
|
+
* ```ts
|
|
312
|
+
* // Initial: { query: { cursor: 0, limit: 10 } }
|
|
313
|
+
* // Only return cursor - limit is preserved automatically
|
|
314
|
+
* nextPageRequest: ({ lastPage }) => ({
|
|
315
|
+
* query: { cursor: lastPage?.data?.nextCursor }
|
|
316
|
+
* })
|
|
317
|
+
* ```
|
|
318
|
+
*/
|
|
319
|
+
nextPageRequest?: (ctx: InfiniteNextContext<TData, TError, TRequest, TMeta>) => Partial<TRequest>;
|
|
320
|
+
/**
|
|
321
|
+
* Callback to merge all pages into a single array of items.
|
|
322
|
+
*
|
|
323
|
+
* @example
|
|
324
|
+
* ```ts
|
|
325
|
+
* merger: (pages) => pages.flatMap(p => p.data?.items ?? [])
|
|
326
|
+
* ```
|
|
327
|
+
*/
|
|
328
|
+
merger: (pages: InfinitePage<TData, TError, TMeta>[]) => TItem[];
|
|
329
|
+
/**
|
|
330
|
+
* Callback to determine if there's a previous page to fetch.
|
|
331
|
+
* Receives the first page to check for pagination indicators.
|
|
332
|
+
*/
|
|
333
|
+
canFetchPrev?: (ctx: InfinitePrevContext<TData, TError, TRequest, TMeta>) => boolean;
|
|
334
|
+
/**
|
|
335
|
+
* Callback to build the request options for the previous page.
|
|
336
|
+
* Return only the fields that change - they will be **merged** with the initial request.
|
|
337
|
+
*/
|
|
338
|
+
prevPageRequest?: (ctx: InfinitePrevContext<TData, TError, TRequest, TMeta>) => Partial<TRequest>;
|
|
268
339
|
};
|
|
269
340
|
/**
|
|
270
|
-
* Result returned by `
|
|
341
|
+
* Result returned by `usePages` hook.
|
|
271
342
|
*
|
|
272
343
|
* @template TData - The response data type for each page
|
|
273
344
|
* @template TError - The error type
|
|
274
345
|
* @template TItem - The item type after merging all responses
|
|
275
346
|
* @template TPluginResult - Plugin-provided result fields
|
|
347
|
+
* @template TTriggerOptions - Options that can be passed to trigger()
|
|
276
348
|
*/
|
|
277
|
-
type
|
|
278
|
-
/** Merged items from all fetched
|
|
349
|
+
type BasePagesResult<TData, TError, TItem, TPluginResult = Record<string, unknown>, TTriggerOptions = object> = {
|
|
350
|
+
/** Merged items from all fetched pages */
|
|
279
351
|
data: TItem[] | undefined;
|
|
280
|
-
/** Array of all
|
|
281
|
-
|
|
352
|
+
/** Array of all pages with status, data, error, and meta per page */
|
|
353
|
+
pages: InfinitePage<TData, TError, TPluginResult>[];
|
|
282
354
|
/** True during the initial load (no data yet) */
|
|
283
355
|
loading: boolean;
|
|
284
356
|
/** True during any fetch operation */
|
|
@@ -291,26 +363,27 @@ type BaseInfiniteReadResult<TData, TError, TItem, TPluginResult = Record<string,
|
|
|
291
363
|
canFetchNext: boolean;
|
|
292
364
|
/** Whether there's a previous page available to fetch */
|
|
293
365
|
canFetchPrev: boolean;
|
|
294
|
-
/** Plugin-provided metadata */
|
|
295
|
-
meta: TPluginResult;
|
|
296
366
|
/** Fetch the next page */
|
|
297
367
|
fetchNext: () => Promise<void>;
|
|
298
368
|
/** Fetch the previous page */
|
|
299
369
|
fetchPrev: () => Promise<void>;
|
|
300
|
-
/** Trigger refetch of all pages from the beginning */
|
|
301
|
-
trigger: () => Promise<void>;
|
|
370
|
+
/** Trigger refetch of all pages from the beginning, optionally with new request options */
|
|
371
|
+
trigger: (options?: TTriggerOptions) => Promise<void>;
|
|
302
372
|
/** Abort the current fetch operation */
|
|
303
373
|
abort: () => void;
|
|
304
374
|
/** Error from the last failed request */
|
|
305
375
|
error: TError | undefined;
|
|
306
376
|
};
|
|
307
|
-
type
|
|
308
|
-
type
|
|
377
|
+
type UsePagesResult<TData, TError, TItem, TPlugins extends readonly SpooshPlugin<PluginTypeConfig>[], TTriggerOptions = object> = BasePagesResult<TData, TError, TItem, MergePluginResults<TPlugins>["read"], TTriggerOptions>;
|
|
378
|
+
type PagesApiClient<TSchema, TDefaultError> = ReadClient<TSchema, TDefaultError>;
|
|
309
379
|
|
|
310
380
|
type InferError<T, TDefaultError> = [T] extends [unknown] ? TDefaultError : T;
|
|
311
381
|
type WriteResolverContext<TSchema, TMethod, TDefaultError> = ResolverContext<TSchema, ExtractMethodData<TMethod>, InferError<ExtractMethodError<TMethod>, TDefaultError>, ExtractMethodQuery<TMethod>, ExtractMethodBody<TMethod>, ExtractResponseParamNames<TMethod> extends never ? never : Record<ExtractResponseParamNames<TMethod>, string | number>>;
|
|
312
382
|
type ResolvedWriteOptions<TSchema, TPlugins extends PluginArray, TMethod, TDefaultError> = ResolveTypes<MergePluginOptions<TPlugins>["write"], WriteResolverContext<TSchema, TMethod, TDefaultError>>;
|
|
313
383
|
type ResolvedWriteTriggerOptions<TSchema, TPlugins extends PluginArray, TMethod, TDefaultError> = ResolveTypes<MergePluginOptions<TPlugins>["writeTrigger"], WriteResolverContext<TSchema, TMethod, TDefaultError>>;
|
|
384
|
+
type QueueResolverContext<TSchema, TMethod, TDefaultError> = ResolverContext<TSchema, ExtractMethodData<TMethod>, InferError<ExtractMethodError<TMethod>, TDefaultError>, ExtractMethodQuery<TMethod>, ExtractMethodBody<TMethod>, ExtractResponseParamNames<TMethod> extends never ? never : Record<ExtractResponseParamNames<TMethod>, string | number>>;
|
|
385
|
+
type ResolvedQueueOptions<TSchema, TPlugins extends PluginArray, TMethod, TDefaultError> = ResolveTypes<MergePluginOptions<TPlugins>["queue"], QueueResolverContext<TSchema, TMethod, TDefaultError>>;
|
|
386
|
+
type ResolvedQueueTriggerOptions<TSchema, TPlugins extends PluginArray, TMethod, TDefaultError> = ResolveTypes<MergePluginOptions<TPlugins>["queueTrigger"], QueueResolverContext<TSchema, TMethod, TDefaultError>>;
|
|
314
387
|
type UseReadFn<TDefaultError, TSchema, TPlugins extends PluginArray> = {
|
|
315
388
|
<TReadFn extends (api: ReadApiClient<TSchema, TDefaultError>) => Promise<SpooshResponse<unknown, unknown>>, TReadOpts>(readFn: TReadFn, readOptions: TReadOpts & BaseReadOptions & ResolveTypes<MergePluginOptions<TPlugins>["read"], ResolverContext<TSchema, ExtractMethodData<TReadFn>, InferError<ExtractMethodError<TReadFn>, TDefaultError>, ExtractResponseQuery<TReadFn>, ExtractResponseBody<TReadFn>, ExtractResponseParamNames<TReadFn> extends never ? never : Record<ExtractResponseParamNames<TReadFn>, string | number>>>): BaseReadResult<ExtractMethodData<TReadFn>, InferError<ExtractMethodError<TReadFn>, TDefaultError>, ResolveResultTypes<MergePluginResults<TPlugins>["read"], TReadOpts>, TriggerOptions<TReadFn>> & ResponseInputFields<ExtractResponseQuery<TReadFn>, ExtractResponseBody<TReadFn>, ExtractResponseParamNames<TReadFn>>;
|
|
316
389
|
<TReadFn extends (api: ReadApiClient<TSchema, TDefaultError>) => Promise<SpooshResponse<unknown, unknown>>>(readFn: TReadFn): BaseReadResult<ExtractMethodData<TReadFn>, InferError<ExtractMethodError<TReadFn>, TDefaultError>, MergePluginResults<TPlugins>["read"], TriggerOptions<TReadFn>> & ResponseInputFields<ExtractResponseQuery<TReadFn>, ExtractResponseBody<TReadFn>, ExtractResponseParamNames<TReadFn>>;
|
|
@@ -318,17 +391,12 @@ type UseReadFn<TDefaultError, TSchema, TPlugins extends PluginArray> = {
|
|
|
318
391
|
type UseWriteFn<TDefaultError, TSchema, TPlugins extends PluginArray> = {
|
|
319
392
|
<TWriteFn extends (api: WriteApiClient<TSchema, TDefaultError>) => Promise<SpooshResponse<unknown, unknown>>, TWriteOpts extends ResolvedWriteOptions<TSchema, TPlugins, TWriteFn, TDefaultError> = ResolvedWriteOptions<TSchema, TPlugins, TWriteFn, TDefaultError>>(writeFn: TWriteFn, writeOptions?: TWriteOpts): BaseWriteResult<ExtractMethodData<TWriteFn>, InferError<ExtractMethodError<TWriteFn>, TDefaultError>, WriteTriggerInput<TWriteFn> & ResolvedWriteTriggerOptions<TSchema, TPlugins, TWriteFn, TDefaultError>, ResolveResultTypes<MergePluginResults<TPlugins>["write"], TWriteOpts>> & WriteResponseInputFields<ExtractMethodQuery<TWriteFn>, ExtractMethodBody<TWriteFn>, ExtractResponseParamNames<TWriteFn>>;
|
|
320
393
|
};
|
|
321
|
-
type
|
|
322
|
-
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
} ? B : never, TRequest extends {
|
|
326
|
-
params: infer P;
|
|
327
|
-
} ? P : never>;
|
|
328
|
-
type ResolvedInfiniteReadOptions<TSchema, TPlugins extends PluginArray, TData, TError, TRequest> = ResolveTypes<MergePluginOptions<TPlugins>["infiniteRead"], InfiniteReadResolverContext<TSchema, TData, TError, TRequest>>;
|
|
329
|
-
type UseInfiniteReadFn<TDefaultError, TSchema, TPlugins extends PluginArray> = <TData, TItem, TError = TDefaultError, TRequest extends AnyInfiniteRequestOptions = AnyInfiniteRequestOptions>(readFn: (api: InfiniteReadApiClient<TSchema, TDefaultError>) => Promise<SpooshResponse<TData, TError>>, readOptions: BaseInfiniteReadOptions<TData, TItem, TRequest> & ResolvedInfiniteReadOptions<TSchema, TPlugins, TData, TError, TRequest>) => BaseInfiniteReadResult<TData, TError, TItem, MergePluginResults<TPlugins>["read"]>;
|
|
394
|
+
type UseQueueFn<TDefaultError, TSchema, TPlugins extends PluginArray> = {
|
|
395
|
+
<TQueueFn extends (api: QueueApiClient<TSchema, TDefaultError>) => Promise<SpooshResponse<unknown, unknown>>>(queueFn: TQueueFn, queueOptions?: ResolvedQueueOptions<TSchema, TPlugins, TQueueFn, TDefaultError> & UseQueueOptions): UseQueueResult<ExtractMethodData<TQueueFn>, InferError<ExtractMethodError<TQueueFn>, TDefaultError>, QueueTriggerInput<TQueueFn> & ResolvedQueueTriggerOptions<TSchema, TPlugins, TQueueFn, TDefaultError>, ResolveResultTypes<MergePluginResults<TPlugins>["queue"], ResolvedQueueOptions<TSchema, TPlugins, TQueueFn, TDefaultError> & UseQueueOptions>>;
|
|
396
|
+
};
|
|
397
|
+
type UsePagesFn<TDefaultError, TSchema, TPlugins extends PluginArray> = <TReadFn extends (api: PagesApiClient<TSchema, TDefaultError>) => Promise<SpooshResponse<unknown, unknown>>, TRequest extends InfiniteRequestOptions = InfiniteRequestOptions, TItem = unknown>(readFn: TReadFn, readOptions: BasePagesOptions<ExtractMethodData<TReadFn>, TItem, InferError<ExtractMethodError<TReadFn>, TDefaultError>, TRequest, MergePluginResults<TPlugins>["read"]> & ResolveTypes<MergePluginOptions<TPlugins>["pages"], ResolverContext<TSchema, ExtractMethodData<TReadFn>, InferError<ExtractMethodError<TReadFn>, TDefaultError>>>) => BasePagesResult<ExtractMethodData<TReadFn>, InferError<ExtractMethodError<TReadFn>, TDefaultError>, TItem, MergePluginResults<TPlugins>["read"], PagesTriggerOptions<TReadFn>>;
|
|
330
398
|
/**
|
|
331
|
-
* Spoosh React hooks interface containing useRead, useWrite, and
|
|
399
|
+
* Spoosh React hooks interface containing useRead, useWrite, and usePages.
|
|
332
400
|
*
|
|
333
401
|
* @template TDefaultError - The default error type
|
|
334
402
|
* @template TSchema - The API schema type
|
|
@@ -375,21 +443,41 @@ type SpooshReactHooks<TDefaultError, TSchema, TPlugins extends PluginArray> = {
|
|
|
375
443
|
*
|
|
376
444
|
* @param readFn - Function that selects the API endpoint to call
|
|
377
445
|
* @param readOptions - Configuration including `canFetchNext`, `nextPageRequest`, `merger`, and optional `canFetchPrev`/`prevPageRequest`
|
|
378
|
-
* @returns Object containing `data`, `
|
|
446
|
+
* @returns Object containing `data`, `pages`, `fetchNext`, `fetchPrev`, `canFetchNext`, `canFetchPrev`, `loading`, `fetching`, and pagination states
|
|
379
447
|
*
|
|
380
448
|
* @example
|
|
381
449
|
* ```tsx
|
|
382
|
-
* const { data, fetchNext, canFetchNext, loading } =
|
|
450
|
+
* const { data, fetchNext, canFetchNext, loading } = usePages(
|
|
383
451
|
* (api) => api("posts").GET(),
|
|
384
452
|
* {
|
|
385
|
-
* canFetchNext: ({
|
|
386
|
-
* nextPageRequest: ({
|
|
387
|
-
* merger: (
|
|
453
|
+
* canFetchNext: ({ lastPage }) => !!lastPage?.data?.nextCursor,
|
|
454
|
+
* nextPageRequest: ({ lastPage }) => ({ query: { cursor: lastPage?.data?.nextCursor } }),
|
|
455
|
+
* merger: (pages) => pages.flatMap(p => p.data?.items ?? [])
|
|
388
456
|
* }
|
|
389
457
|
* );
|
|
390
458
|
* ```
|
|
391
459
|
*/
|
|
392
|
-
|
|
460
|
+
usePages: UsePagesFn<TDefaultError, TSchema, TPlugins>;
|
|
461
|
+
/**
|
|
462
|
+
* React hook for queued operations with concurrency control.
|
|
463
|
+
*
|
|
464
|
+
* @param queueFn - Function that selects the API endpoint
|
|
465
|
+
* @param queueOptions - Optional configuration including `concurrency`
|
|
466
|
+
* @returns Object containing `trigger`, `queue`, `progress`, `abort`, `retry`, `remove`, `clear`
|
|
467
|
+
*
|
|
468
|
+
* @example
|
|
469
|
+
* ```tsx
|
|
470
|
+
* const { trigger, queue, progress } = useQueue(
|
|
471
|
+
* (api) => api("uploads").POST(),
|
|
472
|
+
* { concurrency: 2 }
|
|
473
|
+
* );
|
|
474
|
+
*
|
|
475
|
+
* for (const file of files) {
|
|
476
|
+
* trigger({ body: form({ file }) });
|
|
477
|
+
* }
|
|
478
|
+
* ```
|
|
479
|
+
*/
|
|
480
|
+
useQueue: UseQueueFn<TDefaultError, TSchema, TPlugins>;
|
|
393
481
|
} & MergePluginInstanceApi<TPlugins, TSchema>;
|
|
394
482
|
/**
|
|
395
483
|
* Shape of a Spoosh instance required for creating React hooks.
|
|
@@ -412,18 +500,18 @@ type SpooshInstanceShape<TApi, TSchema, TDefaultError, TPlugins> = {
|
|
|
412
500
|
};
|
|
413
501
|
|
|
414
502
|
/**
|
|
415
|
-
* Creates React hooks (useRead, useWrite,
|
|
503
|
+
* Creates React hooks (useRead, useWrite, usePages) from a Spoosh instance.
|
|
416
504
|
*
|
|
417
505
|
* @template TSchema - The API schema type
|
|
418
506
|
* @template TDefaultError - The default error type
|
|
419
507
|
* @template TPlugins - The plugins array type
|
|
420
508
|
* @template TApi - The API type
|
|
421
509
|
* @param instance - The Spoosh instance containing api, stateManager, eventEmitter, and pluginExecutor
|
|
422
|
-
* @returns An object containing useRead, useWrite,
|
|
510
|
+
* @returns An object containing useRead, useWrite, usePages hooks and plugin instance APIs
|
|
423
511
|
*
|
|
424
512
|
* @example
|
|
425
513
|
* ```ts
|
|
426
|
-
* const { useRead, useWrite,
|
|
514
|
+
* const { useRead, useWrite, usePages } = create(spooshInstance);
|
|
427
515
|
*
|
|
428
516
|
* function MyComponent() {
|
|
429
517
|
* const { data, loading } = useRead((api) => api("posts").GET());
|
|
@@ -439,4 +527,4 @@ type PluginHooksConfig<TPlugins extends readonly SpooshPlugin<PluginTypeConfig>[
|
|
|
439
527
|
plugins: TPlugins;
|
|
440
528
|
};
|
|
441
529
|
|
|
442
|
-
export { type
|
|
530
|
+
export { type BasePagesOptions, type BasePagesResult, type BaseReadOptions, type BaseReadResult, type BaseWriteResult, type ExtractCoreMethodOptions, type ExtractMethodBody, type ExtractMethodData, type ExtractMethodError, type ExtractMethodOptions, type ExtractMethodQuery, type ExtractResponseBody, type ExtractResponseParamNames, type ExtractResponseQuery, type ExtractResponseRequestOptions, type PagesApiClient, type PagesTriggerOptions, type PluginHooksConfig, type QueueApiClient, type QueueTriggerInput, type ReadApiClient, type ResponseInputFields, type SpooshReactHooks, type TriggerOptions, type UsePagesResult, type UseQueueOptions, type UseQueueResult, type UseReadResult, type UseWriteResult, type WriteApiClient, type WriteResponseInputFields, create };
|