@spoosh/react 0.10.1 → 0.11.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/dist/index.d.mts +108 -15
- package/dist/index.d.ts +108 -15
- package/dist/index.js +73 -0
- package/dist/index.mjs +76 -0
- package/package.json +3 -3
package/dist/index.d.mts
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, SpooshPlugin, PluginTypeConfig, MergePluginResults, WriteSelectorClient, SpooshBody, QueueSelectorClient, QueueItem, QueueStats, 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,28 @@ 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$2<T> = T extends (...args: never[]) => infer R ? Awaited<R> : never;
|
|
85
|
+
type ExtractInputFromResponse$2<T> = T extends {
|
|
86
86
|
input: infer I;
|
|
87
87
|
} ? I : never;
|
|
88
|
-
type ExtractTriggerQuery$
|
|
88
|
+
type ExtractTriggerQuery$2<I> = I extends {
|
|
89
89
|
query: infer Q;
|
|
90
90
|
} ? {
|
|
91
91
|
query?: Q;
|
|
92
92
|
} : unknown;
|
|
93
|
-
type ExtractTriggerBody$
|
|
93
|
+
type ExtractTriggerBody$2<I> = I extends {
|
|
94
94
|
body: infer B;
|
|
95
95
|
} ? {
|
|
96
96
|
body?: B;
|
|
97
97
|
} : unknown;
|
|
98
|
-
type ExtractTriggerParams$
|
|
98
|
+
type ExtractTriggerParams$2<I> = I extends {
|
|
99
99
|
params: infer P;
|
|
100
100
|
} ? {
|
|
101
101
|
params?: P;
|
|
102
102
|
} : unknown;
|
|
103
|
-
type TriggerOptions<T> = ExtractInputFromResponse$
|
|
103
|
+
type TriggerOptions<T> = ExtractInputFromResponse$2<TriggerAwaitedReturn$2<T>> extends infer I ? [I] extends [never] ? {
|
|
104
104
|
force?: boolean;
|
|
105
|
-
} : ExtractTriggerQuery$
|
|
105
|
+
} : ExtractTriggerQuery$2<I> & ExtractTriggerBody$2<I> & ExtractTriggerParams$2<I> & {
|
|
106
106
|
/** Force refetch even if data is cached */
|
|
107
107
|
force?: boolean;
|
|
108
108
|
} : {
|
|
@@ -160,30 +160,30 @@ type InputFields<TQuery, TBody, TParamNames extends string> = OptionalQueryField
|
|
|
160
160
|
type WriteResponseInputFields<TQuery, TBody, TParamNames extends string> = [TQuery, TBody, TParamNames] extends [never, never, never] ? object : {
|
|
161
161
|
input: InputFields<TQuery, TBody, TParamNames> | undefined;
|
|
162
162
|
};
|
|
163
|
-
type TriggerAwaitedReturn<T> = T extends (...args: any[]) => infer R ? Awaited<R> : never;
|
|
164
|
-
type ExtractInputFromResponse<T> = T extends {
|
|
163
|
+
type TriggerAwaitedReturn$1<T> = T extends (...args: any[]) => infer R ? Awaited<R> : never;
|
|
164
|
+
type ExtractInputFromResponse$1<T> = T extends {
|
|
165
165
|
input: infer I;
|
|
166
166
|
} ? I : never;
|
|
167
|
-
type ExtractTriggerQuery<I> = I extends {
|
|
167
|
+
type ExtractTriggerQuery$1<I> = I extends {
|
|
168
168
|
query: infer Q;
|
|
169
169
|
} ? undefined extends Q ? {
|
|
170
170
|
query?: Exclude<Q, undefined>;
|
|
171
171
|
} : {
|
|
172
172
|
query: Q;
|
|
173
173
|
} : unknown;
|
|
174
|
-
type ExtractTriggerBody<I> = I extends {
|
|
174
|
+
type ExtractTriggerBody$1<I> = I extends {
|
|
175
175
|
body: infer B;
|
|
176
176
|
} ? undefined extends B ? {
|
|
177
177
|
body?: Exclude<B, undefined> | SpooshBody<Exclude<B, undefined>>;
|
|
178
178
|
} : {
|
|
179
179
|
body: B | SpooshBody<B>;
|
|
180
180
|
} : unknown;
|
|
181
|
-
type ExtractTriggerParams<I> = I extends {
|
|
181
|
+
type ExtractTriggerParams$1<I> = I extends {
|
|
182
182
|
params: infer P;
|
|
183
183
|
} ? {
|
|
184
184
|
params: P;
|
|
185
185
|
} : unknown;
|
|
186
|
-
type WriteTriggerInput<T> = ExtractInputFromResponse<TriggerAwaitedReturn<T>> extends infer I ? [I] extends [never] ? object : ExtractTriggerQuery<I> & ExtractTriggerBody<I> & ExtractTriggerParams<I> : object;
|
|
186
|
+
type WriteTriggerInput<T> = ExtractInputFromResponse$1<TriggerAwaitedReturn$1<T>> extends infer I ? [I] extends [never] ? object : ExtractTriggerQuery$1<I> & ExtractTriggerBody$1<I> & ExtractTriggerParams$1<I> : object;
|
|
187
187
|
/**
|
|
188
188
|
* Result returned by `useWrite` hook.
|
|
189
189
|
*
|
|
@@ -209,6 +209,73 @@ type BaseWriteResult<TData, TError, TOptions, TMeta = Record<string, unknown>> =
|
|
|
209
209
|
type UseWriteResult<TData, TError, TOptions, TMeta, TPlugins extends readonly SpooshPlugin<PluginTypeConfig>[]> = BaseWriteResult<TData, TError, TOptions, TMeta> & MergePluginResults<TPlugins>["write"];
|
|
210
210
|
type WriteApiClient<TSchema, TDefaultError> = WriteSelectorClient<TSchema, TDefaultError>;
|
|
211
211
|
|
|
212
|
+
type TriggerAwaitedReturn<T> = T extends (...args: any[]) => infer R ? Awaited<R> : never;
|
|
213
|
+
type ExtractInputFromResponse<T> = T extends {
|
|
214
|
+
input: infer I;
|
|
215
|
+
} ? I : never;
|
|
216
|
+
type ExtractTriggerQuery<I> = I extends {
|
|
217
|
+
query: infer Q;
|
|
218
|
+
} ? undefined extends Q ? {
|
|
219
|
+
query?: Exclude<Q, undefined>;
|
|
220
|
+
} : {
|
|
221
|
+
query: Q;
|
|
222
|
+
} : unknown;
|
|
223
|
+
type ExtractTriggerBody<I> = I extends {
|
|
224
|
+
body: infer B;
|
|
225
|
+
} ? undefined extends B ? {
|
|
226
|
+
body?: Exclude<B, undefined> | SpooshBody<Exclude<B, undefined>>;
|
|
227
|
+
} : {
|
|
228
|
+
body: B | SpooshBody<B>;
|
|
229
|
+
} : unknown;
|
|
230
|
+
type ExtractTriggerParams<I> = I extends {
|
|
231
|
+
params: infer P;
|
|
232
|
+
} ? {
|
|
233
|
+
params: P;
|
|
234
|
+
} : unknown;
|
|
235
|
+
type QueueTriggerBase = {
|
|
236
|
+
/** Custom ID for this queue item. If not provided, one will be auto-generated. */
|
|
237
|
+
id?: string;
|
|
238
|
+
};
|
|
239
|
+
type QueueTriggerInput<T> = ExtractInputFromResponse<TriggerAwaitedReturn<T>> extends infer I ? [I] extends [never] ? QueueTriggerBase : QueueTriggerBase & ExtractTriggerQuery<I> & ExtractTriggerBody<I> & ExtractTriggerParams<I> : QueueTriggerBase;
|
|
240
|
+
/**
|
|
241
|
+
* Options for useQueue hook.
|
|
242
|
+
*/
|
|
243
|
+
interface UseQueueOptions {
|
|
244
|
+
/** Maximum concurrent operations. Defaults to 3. */
|
|
245
|
+
concurrency?: number;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Result returned by useQueue hook.
|
|
249
|
+
*
|
|
250
|
+
* @template TData - The response data type
|
|
251
|
+
* @template TError - The error type
|
|
252
|
+
* @template TTriggerInput - The trigger input type
|
|
253
|
+
* @template TMeta - Plugin-contributed metadata on queue items
|
|
254
|
+
*/
|
|
255
|
+
type UseQueueResult<TData, TError, TTriggerInput, TMeta = object> = {
|
|
256
|
+
/** Add item to queue and execute. Returns promise for this item. */
|
|
257
|
+
trigger: (input?: TTriggerInput) => Promise<SpooshResponse<TData, TError>>;
|
|
258
|
+
/** All tasks in queue with their current status */
|
|
259
|
+
tasks: QueueItem<TData, TError, TMeta>[];
|
|
260
|
+
/** Queue statistics (pending/loading/settled/success/failed/total/percentage) */
|
|
261
|
+
stats: QueueStats;
|
|
262
|
+
/** Abort task by ID, or all tasks if no ID */
|
|
263
|
+
abort: (id?: string) => void;
|
|
264
|
+
/** Retry failed task by ID, or all failed if no ID */
|
|
265
|
+
retry: (id?: string) => Promise<void>;
|
|
266
|
+
/** Remove specific task by ID (aborts if active) */
|
|
267
|
+
remove: (id: string) => void;
|
|
268
|
+
/** Remove all settled tasks (success, error, aborted). Keeps pending/running. */
|
|
269
|
+
removeSettled: () => void;
|
|
270
|
+
/** Abort all and clear queue */
|
|
271
|
+
clear: () => void;
|
|
272
|
+
};
|
|
273
|
+
/**
|
|
274
|
+
* API client type for queue selector.
|
|
275
|
+
* Supports all HTTP methods (GET, POST, PUT, PATCH, DELETE).
|
|
276
|
+
*/
|
|
277
|
+
type QueueApiClient<TSchema, TDefaultError> = QueueSelectorClient<TSchema, TDefaultError>;
|
|
278
|
+
|
|
212
279
|
type TagModeInArray = "all" | "self";
|
|
213
280
|
type AnyInfiniteRequestOptions = {
|
|
214
281
|
query?: Record<string, unknown>;
|
|
@@ -311,6 +378,9 @@ type InferError<T, TDefaultError> = [T] extends [unknown] ? TDefaultError : T;
|
|
|
311
378
|
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
379
|
type ResolvedWriteOptions<TSchema, TPlugins extends PluginArray, TMethod, TDefaultError> = ResolveTypes<MergePluginOptions<TPlugins>["write"], WriteResolverContext<TSchema, TMethod, TDefaultError>>;
|
|
313
380
|
type ResolvedWriteTriggerOptions<TSchema, TPlugins extends PluginArray, TMethod, TDefaultError> = ResolveTypes<MergePluginOptions<TPlugins>["writeTrigger"], WriteResolverContext<TSchema, TMethod, TDefaultError>>;
|
|
381
|
+
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>>;
|
|
382
|
+
type ResolvedQueueOptions<TSchema, TPlugins extends PluginArray, TMethod, TDefaultError> = ResolveTypes<MergePluginOptions<TPlugins>["queue"], QueueResolverContext<TSchema, TMethod, TDefaultError>>;
|
|
383
|
+
type ResolvedQueueTriggerOptions<TSchema, TPlugins extends PluginArray, TMethod, TDefaultError> = ResolveTypes<MergePluginOptions<TPlugins>["queueTrigger"], QueueResolverContext<TSchema, TMethod, TDefaultError>>;
|
|
314
384
|
type UseReadFn<TDefaultError, TSchema, TPlugins extends PluginArray> = {
|
|
315
385
|
<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
386
|
<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,6 +388,9 @@ type UseReadFn<TDefaultError, TSchema, TPlugins extends PluginArray> = {
|
|
|
318
388
|
type UseWriteFn<TDefaultError, TSchema, TPlugins extends PluginArray> = {
|
|
319
389
|
<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
390
|
};
|
|
391
|
+
type UseQueueFn<TDefaultError, TSchema, TPlugins extends PluginArray> = {
|
|
392
|
+
<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>>;
|
|
393
|
+
};
|
|
321
394
|
type InfiniteReadResolverContext<TSchema, TData, TError, TRequest> = ResolverContext<TSchema, TData, TError, TRequest extends {
|
|
322
395
|
query: infer Q;
|
|
323
396
|
} ? Q : never, TRequest extends {
|
|
@@ -390,6 +463,26 @@ type SpooshReactHooks<TDefaultError, TSchema, TPlugins extends PluginArray> = {
|
|
|
390
463
|
* ```
|
|
391
464
|
*/
|
|
392
465
|
useInfiniteRead: UseInfiniteReadFn<TDefaultError, TSchema, TPlugins>;
|
|
466
|
+
/**
|
|
467
|
+
* React hook for queued operations with concurrency control.
|
|
468
|
+
*
|
|
469
|
+
* @param queueFn - Function that selects the API endpoint
|
|
470
|
+
* @param queueOptions - Optional configuration including `concurrency`
|
|
471
|
+
* @returns Object containing `trigger`, `queue`, `progress`, `abort`, `retry`, `remove`, `clear`
|
|
472
|
+
*
|
|
473
|
+
* @example
|
|
474
|
+
* ```tsx
|
|
475
|
+
* const { trigger, queue, progress } = useQueue(
|
|
476
|
+
* (api) => api("uploads").POST(),
|
|
477
|
+
* { concurrency: 2 }
|
|
478
|
+
* );
|
|
479
|
+
*
|
|
480
|
+
* for (const file of files) {
|
|
481
|
+
* trigger({ body: form({ file }) });
|
|
482
|
+
* }
|
|
483
|
+
* ```
|
|
484
|
+
*/
|
|
485
|
+
useQueue: UseQueueFn<TDefaultError, TSchema, TPlugins>;
|
|
393
486
|
} & MergePluginInstanceApi<TPlugins, TSchema>;
|
|
394
487
|
/**
|
|
395
488
|
* Shape of a Spoosh instance required for creating React hooks.
|
|
@@ -439,4 +532,4 @@ type PluginHooksConfig<TPlugins extends readonly SpooshPlugin<PluginTypeConfig>[
|
|
|
439
532
|
plugins: TPlugins;
|
|
440
533
|
};
|
|
441
534
|
|
|
442
|
-
export { type AnyInfiniteRequestOptions, type BaseInfiniteReadOptions, type BaseInfiniteReadResult, 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 InfiniteNextContext, type InfinitePrevContext, type InfiniteReadApiClient, type PluginHooksConfig, type ReadApiClient, type ResponseInputFields, type SpooshReactHooks, type TriggerOptions, type UseInfiniteReadResult, type UseReadResult, type UseWriteResult, type WriteApiClient, type WriteResponseInputFields, create };
|
|
535
|
+
export { type AnyInfiniteRequestOptions, type BaseInfiniteReadOptions, type BaseInfiniteReadResult, 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 InfiniteNextContext, type InfinitePrevContext, type InfiniteReadApiClient, type PluginHooksConfig, type QueueApiClient, type QueueTriggerInput, type ReadApiClient, type ResponseInputFields, type SpooshReactHooks, type TriggerOptions, type UseInfiniteReadResult, type UseQueueOptions, type UseQueueResult, type UseReadResult, type UseWriteResult, type WriteApiClient, type WriteResponseInputFields, create };
|
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, SpooshPlugin, PluginTypeConfig, MergePluginResults, WriteSelectorClient, SpooshBody, QueueSelectorClient, QueueItem, QueueStats, 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,28 @@ 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$2<T> = T extends (...args: never[]) => infer R ? Awaited<R> : never;
|
|
85
|
+
type ExtractInputFromResponse$2<T> = T extends {
|
|
86
86
|
input: infer I;
|
|
87
87
|
} ? I : never;
|
|
88
|
-
type ExtractTriggerQuery$
|
|
88
|
+
type ExtractTriggerQuery$2<I> = I extends {
|
|
89
89
|
query: infer Q;
|
|
90
90
|
} ? {
|
|
91
91
|
query?: Q;
|
|
92
92
|
} : unknown;
|
|
93
|
-
type ExtractTriggerBody$
|
|
93
|
+
type ExtractTriggerBody$2<I> = I extends {
|
|
94
94
|
body: infer B;
|
|
95
95
|
} ? {
|
|
96
96
|
body?: B;
|
|
97
97
|
} : unknown;
|
|
98
|
-
type ExtractTriggerParams$
|
|
98
|
+
type ExtractTriggerParams$2<I> = I extends {
|
|
99
99
|
params: infer P;
|
|
100
100
|
} ? {
|
|
101
101
|
params?: P;
|
|
102
102
|
} : unknown;
|
|
103
|
-
type TriggerOptions<T> = ExtractInputFromResponse$
|
|
103
|
+
type TriggerOptions<T> = ExtractInputFromResponse$2<TriggerAwaitedReturn$2<T>> extends infer I ? [I] extends [never] ? {
|
|
104
104
|
force?: boolean;
|
|
105
|
-
} : ExtractTriggerQuery$
|
|
105
|
+
} : ExtractTriggerQuery$2<I> & ExtractTriggerBody$2<I> & ExtractTriggerParams$2<I> & {
|
|
106
106
|
/** Force refetch even if data is cached */
|
|
107
107
|
force?: boolean;
|
|
108
108
|
} : {
|
|
@@ -160,30 +160,30 @@ type InputFields<TQuery, TBody, TParamNames extends string> = OptionalQueryField
|
|
|
160
160
|
type WriteResponseInputFields<TQuery, TBody, TParamNames extends string> = [TQuery, TBody, TParamNames] extends [never, never, never] ? object : {
|
|
161
161
|
input: InputFields<TQuery, TBody, TParamNames> | undefined;
|
|
162
162
|
};
|
|
163
|
-
type TriggerAwaitedReturn<T> = T extends (...args: any[]) => infer R ? Awaited<R> : never;
|
|
164
|
-
type ExtractInputFromResponse<T> = T extends {
|
|
163
|
+
type TriggerAwaitedReturn$1<T> = T extends (...args: any[]) => infer R ? Awaited<R> : never;
|
|
164
|
+
type ExtractInputFromResponse$1<T> = T extends {
|
|
165
165
|
input: infer I;
|
|
166
166
|
} ? I : never;
|
|
167
|
-
type ExtractTriggerQuery<I> = I extends {
|
|
167
|
+
type ExtractTriggerQuery$1<I> = I extends {
|
|
168
168
|
query: infer Q;
|
|
169
169
|
} ? undefined extends Q ? {
|
|
170
170
|
query?: Exclude<Q, undefined>;
|
|
171
171
|
} : {
|
|
172
172
|
query: Q;
|
|
173
173
|
} : unknown;
|
|
174
|
-
type ExtractTriggerBody<I> = I extends {
|
|
174
|
+
type ExtractTriggerBody$1<I> = I extends {
|
|
175
175
|
body: infer B;
|
|
176
176
|
} ? undefined extends B ? {
|
|
177
177
|
body?: Exclude<B, undefined> | SpooshBody<Exclude<B, undefined>>;
|
|
178
178
|
} : {
|
|
179
179
|
body: B | SpooshBody<B>;
|
|
180
180
|
} : unknown;
|
|
181
|
-
type ExtractTriggerParams<I> = I extends {
|
|
181
|
+
type ExtractTriggerParams$1<I> = I extends {
|
|
182
182
|
params: infer P;
|
|
183
183
|
} ? {
|
|
184
184
|
params: P;
|
|
185
185
|
} : unknown;
|
|
186
|
-
type WriteTriggerInput<T> = ExtractInputFromResponse<TriggerAwaitedReturn<T>> extends infer I ? [I] extends [never] ? object : ExtractTriggerQuery<I> & ExtractTriggerBody<I> & ExtractTriggerParams<I> : object;
|
|
186
|
+
type WriteTriggerInput<T> = ExtractInputFromResponse$1<TriggerAwaitedReturn$1<T>> extends infer I ? [I] extends [never] ? object : ExtractTriggerQuery$1<I> & ExtractTriggerBody$1<I> & ExtractTriggerParams$1<I> : object;
|
|
187
187
|
/**
|
|
188
188
|
* Result returned by `useWrite` hook.
|
|
189
189
|
*
|
|
@@ -209,6 +209,73 @@ type BaseWriteResult<TData, TError, TOptions, TMeta = Record<string, unknown>> =
|
|
|
209
209
|
type UseWriteResult<TData, TError, TOptions, TMeta, TPlugins extends readonly SpooshPlugin<PluginTypeConfig>[]> = BaseWriteResult<TData, TError, TOptions, TMeta> & MergePluginResults<TPlugins>["write"];
|
|
210
210
|
type WriteApiClient<TSchema, TDefaultError> = WriteSelectorClient<TSchema, TDefaultError>;
|
|
211
211
|
|
|
212
|
+
type TriggerAwaitedReturn<T> = T extends (...args: any[]) => infer R ? Awaited<R> : never;
|
|
213
|
+
type ExtractInputFromResponse<T> = T extends {
|
|
214
|
+
input: infer I;
|
|
215
|
+
} ? I : never;
|
|
216
|
+
type ExtractTriggerQuery<I> = I extends {
|
|
217
|
+
query: infer Q;
|
|
218
|
+
} ? undefined extends Q ? {
|
|
219
|
+
query?: Exclude<Q, undefined>;
|
|
220
|
+
} : {
|
|
221
|
+
query: Q;
|
|
222
|
+
} : unknown;
|
|
223
|
+
type ExtractTriggerBody<I> = I extends {
|
|
224
|
+
body: infer B;
|
|
225
|
+
} ? undefined extends B ? {
|
|
226
|
+
body?: Exclude<B, undefined> | SpooshBody<Exclude<B, undefined>>;
|
|
227
|
+
} : {
|
|
228
|
+
body: B | SpooshBody<B>;
|
|
229
|
+
} : unknown;
|
|
230
|
+
type ExtractTriggerParams<I> = I extends {
|
|
231
|
+
params: infer P;
|
|
232
|
+
} ? {
|
|
233
|
+
params: P;
|
|
234
|
+
} : unknown;
|
|
235
|
+
type QueueTriggerBase = {
|
|
236
|
+
/** Custom ID for this queue item. If not provided, one will be auto-generated. */
|
|
237
|
+
id?: string;
|
|
238
|
+
};
|
|
239
|
+
type QueueTriggerInput<T> = ExtractInputFromResponse<TriggerAwaitedReturn<T>> extends infer I ? [I] extends [never] ? QueueTriggerBase : QueueTriggerBase & ExtractTriggerQuery<I> & ExtractTriggerBody<I> & ExtractTriggerParams<I> : QueueTriggerBase;
|
|
240
|
+
/**
|
|
241
|
+
* Options for useQueue hook.
|
|
242
|
+
*/
|
|
243
|
+
interface UseQueueOptions {
|
|
244
|
+
/** Maximum concurrent operations. Defaults to 3. */
|
|
245
|
+
concurrency?: number;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Result returned by useQueue hook.
|
|
249
|
+
*
|
|
250
|
+
* @template TData - The response data type
|
|
251
|
+
* @template TError - The error type
|
|
252
|
+
* @template TTriggerInput - The trigger input type
|
|
253
|
+
* @template TMeta - Plugin-contributed metadata on queue items
|
|
254
|
+
*/
|
|
255
|
+
type UseQueueResult<TData, TError, TTriggerInput, TMeta = object> = {
|
|
256
|
+
/** Add item to queue and execute. Returns promise for this item. */
|
|
257
|
+
trigger: (input?: TTriggerInput) => Promise<SpooshResponse<TData, TError>>;
|
|
258
|
+
/** All tasks in queue with their current status */
|
|
259
|
+
tasks: QueueItem<TData, TError, TMeta>[];
|
|
260
|
+
/** Queue statistics (pending/loading/settled/success/failed/total/percentage) */
|
|
261
|
+
stats: QueueStats;
|
|
262
|
+
/** Abort task by ID, or all tasks if no ID */
|
|
263
|
+
abort: (id?: string) => void;
|
|
264
|
+
/** Retry failed task by ID, or all failed if no ID */
|
|
265
|
+
retry: (id?: string) => Promise<void>;
|
|
266
|
+
/** Remove specific task by ID (aborts if active) */
|
|
267
|
+
remove: (id: string) => void;
|
|
268
|
+
/** Remove all settled tasks (success, error, aborted). Keeps pending/running. */
|
|
269
|
+
removeSettled: () => void;
|
|
270
|
+
/** Abort all and clear queue */
|
|
271
|
+
clear: () => void;
|
|
272
|
+
};
|
|
273
|
+
/**
|
|
274
|
+
* API client type for queue selector.
|
|
275
|
+
* Supports all HTTP methods (GET, POST, PUT, PATCH, DELETE).
|
|
276
|
+
*/
|
|
277
|
+
type QueueApiClient<TSchema, TDefaultError> = QueueSelectorClient<TSchema, TDefaultError>;
|
|
278
|
+
|
|
212
279
|
type TagModeInArray = "all" | "self";
|
|
213
280
|
type AnyInfiniteRequestOptions = {
|
|
214
281
|
query?: Record<string, unknown>;
|
|
@@ -311,6 +378,9 @@ type InferError<T, TDefaultError> = [T] extends [unknown] ? TDefaultError : T;
|
|
|
311
378
|
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
379
|
type ResolvedWriteOptions<TSchema, TPlugins extends PluginArray, TMethod, TDefaultError> = ResolveTypes<MergePluginOptions<TPlugins>["write"], WriteResolverContext<TSchema, TMethod, TDefaultError>>;
|
|
313
380
|
type ResolvedWriteTriggerOptions<TSchema, TPlugins extends PluginArray, TMethod, TDefaultError> = ResolveTypes<MergePluginOptions<TPlugins>["writeTrigger"], WriteResolverContext<TSchema, TMethod, TDefaultError>>;
|
|
381
|
+
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>>;
|
|
382
|
+
type ResolvedQueueOptions<TSchema, TPlugins extends PluginArray, TMethod, TDefaultError> = ResolveTypes<MergePluginOptions<TPlugins>["queue"], QueueResolverContext<TSchema, TMethod, TDefaultError>>;
|
|
383
|
+
type ResolvedQueueTriggerOptions<TSchema, TPlugins extends PluginArray, TMethod, TDefaultError> = ResolveTypes<MergePluginOptions<TPlugins>["queueTrigger"], QueueResolverContext<TSchema, TMethod, TDefaultError>>;
|
|
314
384
|
type UseReadFn<TDefaultError, TSchema, TPlugins extends PluginArray> = {
|
|
315
385
|
<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
386
|
<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,6 +388,9 @@ type UseReadFn<TDefaultError, TSchema, TPlugins extends PluginArray> = {
|
|
|
318
388
|
type UseWriteFn<TDefaultError, TSchema, TPlugins extends PluginArray> = {
|
|
319
389
|
<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
390
|
};
|
|
391
|
+
type UseQueueFn<TDefaultError, TSchema, TPlugins extends PluginArray> = {
|
|
392
|
+
<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>>;
|
|
393
|
+
};
|
|
321
394
|
type InfiniteReadResolverContext<TSchema, TData, TError, TRequest> = ResolverContext<TSchema, TData, TError, TRequest extends {
|
|
322
395
|
query: infer Q;
|
|
323
396
|
} ? Q : never, TRequest extends {
|
|
@@ -390,6 +463,26 @@ type SpooshReactHooks<TDefaultError, TSchema, TPlugins extends PluginArray> = {
|
|
|
390
463
|
* ```
|
|
391
464
|
*/
|
|
392
465
|
useInfiniteRead: UseInfiniteReadFn<TDefaultError, TSchema, TPlugins>;
|
|
466
|
+
/**
|
|
467
|
+
* React hook for queued operations with concurrency control.
|
|
468
|
+
*
|
|
469
|
+
* @param queueFn - Function that selects the API endpoint
|
|
470
|
+
* @param queueOptions - Optional configuration including `concurrency`
|
|
471
|
+
* @returns Object containing `trigger`, `queue`, `progress`, `abort`, `retry`, `remove`, `clear`
|
|
472
|
+
*
|
|
473
|
+
* @example
|
|
474
|
+
* ```tsx
|
|
475
|
+
* const { trigger, queue, progress } = useQueue(
|
|
476
|
+
* (api) => api("uploads").POST(),
|
|
477
|
+
* { concurrency: 2 }
|
|
478
|
+
* );
|
|
479
|
+
*
|
|
480
|
+
* for (const file of files) {
|
|
481
|
+
* trigger({ body: form({ file }) });
|
|
482
|
+
* }
|
|
483
|
+
* ```
|
|
484
|
+
*/
|
|
485
|
+
useQueue: UseQueueFn<TDefaultError, TSchema, TPlugins>;
|
|
393
486
|
} & MergePluginInstanceApi<TPlugins, TSchema>;
|
|
394
487
|
/**
|
|
395
488
|
* Shape of a Spoosh instance required for creating React hooks.
|
|
@@ -439,4 +532,4 @@ type PluginHooksConfig<TPlugins extends readonly SpooshPlugin<PluginTypeConfig>[
|
|
|
439
532
|
plugins: TPlugins;
|
|
440
533
|
};
|
|
441
534
|
|
|
442
|
-
export { type AnyInfiniteRequestOptions, type BaseInfiniteReadOptions, type BaseInfiniteReadResult, 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 InfiniteNextContext, type InfinitePrevContext, type InfiniteReadApiClient, type PluginHooksConfig, type ReadApiClient, type ResponseInputFields, type SpooshReactHooks, type TriggerOptions, type UseInfiniteReadResult, type UseReadResult, type UseWriteResult, type WriteApiClient, type WriteResponseInputFields, create };
|
|
535
|
+
export { type AnyInfiniteRequestOptions, type BaseInfiniteReadOptions, type BaseInfiniteReadResult, 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 InfiniteNextContext, type InfinitePrevContext, type InfiniteReadApiClient, type PluginHooksConfig, type QueueApiClient, type QueueTriggerInput, type ReadApiClient, type ResponseInputFields, type SpooshReactHooks, type TriggerOptions, type UseInfiniteReadResult, type UseQueueOptions, type UseQueueResult, type UseReadResult, type UseWriteResult, type WriteApiClient, type WriteResponseInputFields, create };
|
package/dist/index.js
CHANGED
|
@@ -588,6 +588,72 @@ function createUseInfiniteRead(options) {
|
|
|
588
588
|
};
|
|
589
589
|
}
|
|
590
590
|
|
|
591
|
+
// src/useQueue/index.ts
|
|
592
|
+
var import_react4 = require("react");
|
|
593
|
+
var import_core4 = require("@spoosh/core");
|
|
594
|
+
function createUseQueue(options) {
|
|
595
|
+
const { api, stateManager, pluginExecutor, eventEmitter } = options;
|
|
596
|
+
function useQueue(queueFn, queueOptions) {
|
|
597
|
+
(0, import_react4.useId)();
|
|
598
|
+
const selectorResultRef = (0, import_react4.useRef)({
|
|
599
|
+
call: null,
|
|
600
|
+
selector: null
|
|
601
|
+
});
|
|
602
|
+
const selectorProxy = (0, import_core4.createSelectorProxy)((result) => {
|
|
603
|
+
selectorResultRef.current = result;
|
|
604
|
+
});
|
|
605
|
+
queueFn(selectorProxy);
|
|
606
|
+
const capturedCall = selectorResultRef.current.call;
|
|
607
|
+
const capturedSelector = selectorResultRef.current.selector;
|
|
608
|
+
const captured = capturedCall ?? capturedSelector;
|
|
609
|
+
if (!captured) {
|
|
610
|
+
throw new Error(
|
|
611
|
+
'useQueue requires selecting an HTTP method. Example: useQueue((api) => api("uploads").POST())'
|
|
612
|
+
);
|
|
613
|
+
}
|
|
614
|
+
const { concurrency, ...hookOptions } = queueOptions ?? {};
|
|
615
|
+
const controllerRef = (0, import_react4.useRef)(null);
|
|
616
|
+
if (!controllerRef.current) {
|
|
617
|
+
const config = {
|
|
618
|
+
path: captured.path,
|
|
619
|
+
method: captured.method,
|
|
620
|
+
concurrency,
|
|
621
|
+
operationType: "queue",
|
|
622
|
+
hookOptions
|
|
623
|
+
};
|
|
624
|
+
controllerRef.current = (0, import_core4.createQueueController)(config, {
|
|
625
|
+
api,
|
|
626
|
+
stateManager,
|
|
627
|
+
eventEmitter,
|
|
628
|
+
pluginExecutor
|
|
629
|
+
});
|
|
630
|
+
}
|
|
631
|
+
const controller = controllerRef.current;
|
|
632
|
+
(0, import_react4.useEffect)(() => {
|
|
633
|
+
if (concurrency !== void 0) {
|
|
634
|
+
controller.setConcurrency(concurrency);
|
|
635
|
+
}
|
|
636
|
+
}, [concurrency, controller]);
|
|
637
|
+
const tasks = (0, import_react4.useSyncExternalStore)(
|
|
638
|
+
controller.subscribe,
|
|
639
|
+
controller.getQueue,
|
|
640
|
+
controller.getQueue
|
|
641
|
+
);
|
|
642
|
+
return {
|
|
643
|
+
trigger: (input) => controller.trigger(input ?? {}),
|
|
644
|
+
tasks,
|
|
645
|
+
stats: controller.getStats(),
|
|
646
|
+
abort: controller.abort,
|
|
647
|
+
retry: controller.retry,
|
|
648
|
+
remove: controller.remove,
|
|
649
|
+
removeSettled: controller.removeSettled,
|
|
650
|
+
clear: controller.clear
|
|
651
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
652
|
+
};
|
|
653
|
+
}
|
|
654
|
+
return useQueue;
|
|
655
|
+
}
|
|
656
|
+
|
|
591
657
|
// src/create/index.ts
|
|
592
658
|
function create(instance) {
|
|
593
659
|
const { api, stateManager, eventEmitter, pluginExecutor } = instance;
|
|
@@ -609,6 +675,12 @@ function create(instance) {
|
|
|
609
675
|
eventEmitter,
|
|
610
676
|
pluginExecutor
|
|
611
677
|
});
|
|
678
|
+
const useQueue = createUseQueue({
|
|
679
|
+
api,
|
|
680
|
+
stateManager,
|
|
681
|
+
eventEmitter,
|
|
682
|
+
pluginExecutor
|
|
683
|
+
});
|
|
612
684
|
const plugins = pluginExecutor.getPlugins();
|
|
613
685
|
const setupContext = {
|
|
614
686
|
stateManager,
|
|
@@ -637,6 +709,7 @@ function create(instance) {
|
|
|
637
709
|
useRead,
|
|
638
710
|
useWrite,
|
|
639
711
|
useInfiniteRead,
|
|
712
|
+
useQueue,
|
|
640
713
|
...instanceApis
|
|
641
714
|
};
|
|
642
715
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -597,6 +597,75 @@ function createUseInfiniteRead(options) {
|
|
|
597
597
|
};
|
|
598
598
|
}
|
|
599
599
|
|
|
600
|
+
// src/useQueue/index.ts
|
|
601
|
+
import { useSyncExternalStore as useSyncExternalStore4, useRef as useRef4, useId as useId4, useEffect as useEffect3 } from "react";
|
|
602
|
+
import {
|
|
603
|
+
createSelectorProxy as createSelectorProxy4,
|
|
604
|
+
createQueueController
|
|
605
|
+
} from "@spoosh/core";
|
|
606
|
+
function createUseQueue(options) {
|
|
607
|
+
const { api, stateManager, pluginExecutor, eventEmitter } = options;
|
|
608
|
+
function useQueue(queueFn, queueOptions) {
|
|
609
|
+
useId4();
|
|
610
|
+
const selectorResultRef = useRef4({
|
|
611
|
+
call: null,
|
|
612
|
+
selector: null
|
|
613
|
+
});
|
|
614
|
+
const selectorProxy = createSelectorProxy4((result) => {
|
|
615
|
+
selectorResultRef.current = result;
|
|
616
|
+
});
|
|
617
|
+
queueFn(selectorProxy);
|
|
618
|
+
const capturedCall = selectorResultRef.current.call;
|
|
619
|
+
const capturedSelector = selectorResultRef.current.selector;
|
|
620
|
+
const captured = capturedCall ?? capturedSelector;
|
|
621
|
+
if (!captured) {
|
|
622
|
+
throw new Error(
|
|
623
|
+
'useQueue requires selecting an HTTP method. Example: useQueue((api) => api("uploads").POST())'
|
|
624
|
+
);
|
|
625
|
+
}
|
|
626
|
+
const { concurrency, ...hookOptions } = queueOptions ?? {};
|
|
627
|
+
const controllerRef = useRef4(null);
|
|
628
|
+
if (!controllerRef.current) {
|
|
629
|
+
const config = {
|
|
630
|
+
path: captured.path,
|
|
631
|
+
method: captured.method,
|
|
632
|
+
concurrency,
|
|
633
|
+
operationType: "queue",
|
|
634
|
+
hookOptions
|
|
635
|
+
};
|
|
636
|
+
controllerRef.current = createQueueController(config, {
|
|
637
|
+
api,
|
|
638
|
+
stateManager,
|
|
639
|
+
eventEmitter,
|
|
640
|
+
pluginExecutor
|
|
641
|
+
});
|
|
642
|
+
}
|
|
643
|
+
const controller = controllerRef.current;
|
|
644
|
+
useEffect3(() => {
|
|
645
|
+
if (concurrency !== void 0) {
|
|
646
|
+
controller.setConcurrency(concurrency);
|
|
647
|
+
}
|
|
648
|
+
}, [concurrency, controller]);
|
|
649
|
+
const tasks = useSyncExternalStore4(
|
|
650
|
+
controller.subscribe,
|
|
651
|
+
controller.getQueue,
|
|
652
|
+
controller.getQueue
|
|
653
|
+
);
|
|
654
|
+
return {
|
|
655
|
+
trigger: (input) => controller.trigger(input ?? {}),
|
|
656
|
+
tasks,
|
|
657
|
+
stats: controller.getStats(),
|
|
658
|
+
abort: controller.abort,
|
|
659
|
+
retry: controller.retry,
|
|
660
|
+
remove: controller.remove,
|
|
661
|
+
removeSettled: controller.removeSettled,
|
|
662
|
+
clear: controller.clear
|
|
663
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
664
|
+
};
|
|
665
|
+
}
|
|
666
|
+
return useQueue;
|
|
667
|
+
}
|
|
668
|
+
|
|
600
669
|
// src/create/index.ts
|
|
601
670
|
function create(instance) {
|
|
602
671
|
const { api, stateManager, eventEmitter, pluginExecutor } = instance;
|
|
@@ -618,6 +687,12 @@ function create(instance) {
|
|
|
618
687
|
eventEmitter,
|
|
619
688
|
pluginExecutor
|
|
620
689
|
});
|
|
690
|
+
const useQueue = createUseQueue({
|
|
691
|
+
api,
|
|
692
|
+
stateManager,
|
|
693
|
+
eventEmitter,
|
|
694
|
+
pluginExecutor
|
|
695
|
+
});
|
|
621
696
|
const plugins = pluginExecutor.getPlugins();
|
|
622
697
|
const setupContext = {
|
|
623
698
|
stateManager,
|
|
@@ -646,6 +721,7 @@ function create(instance) {
|
|
|
646
721
|
useRead,
|
|
647
722
|
useWrite,
|
|
648
723
|
useInfiniteRead,
|
|
724
|
+
useQueue,
|
|
649
725
|
...instanceApis
|
|
650
726
|
};
|
|
651
727
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spoosh/react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "React hooks for Spoosh API toolkit",
|
|
6
6
|
"keywords": [
|
|
@@ -34,13 +34,13 @@
|
|
|
34
34
|
}
|
|
35
35
|
},
|
|
36
36
|
"peerDependencies": {
|
|
37
|
-
"@spoosh/core": ">=0.
|
|
37
|
+
"@spoosh/core": ">=0.14.0",
|
|
38
38
|
"react": "^18 || ^19"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@testing-library/react": "^16.0.0",
|
|
42
42
|
"jsdom": "^26.0.0",
|
|
43
|
-
"@spoosh/core": "0.
|
|
43
|
+
"@spoosh/core": "0.14.0",
|
|
44
44
|
"@spoosh/test-utils": "0.2.0"
|
|
45
45
|
},
|
|
46
46
|
"scripts": {
|