@spoosh/react 0.6.0 → 0.7.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 +2 -24
- package/dist/index.d.mts +67 -86
- package/dist/index.d.ts +67 -86
- package/dist/index.js +116 -173
- package/dist/index.mjs +115 -182
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @spoosh/react
|
|
2
2
|
|
|
3
|
-
React hooks for Spoosh - `useRead`, `
|
|
3
|
+
React hooks for Spoosh - `useRead`, `useWrite`, and `useInfiniteRead`.
|
|
4
4
|
|
|
5
5
|
**[Documentation](https://spoosh.dev/docs/integrations/react)** · **Requirements:** TypeScript >= 5.0, React >= 18.0
|
|
6
6
|
|
|
@@ -23,8 +23,7 @@ const spoosh = new Spoosh<ApiSchema, Error>("/api").use([
|
|
|
23
23
|
cachePlugin({ staleTime: 5000 }),
|
|
24
24
|
]);
|
|
25
25
|
|
|
26
|
-
export const { useRead,
|
|
27
|
-
createReactSpoosh(spoosh);
|
|
26
|
+
export const { useRead, useWrite, useInfiniteRead } = createReactSpoosh(spoosh);
|
|
28
27
|
```
|
|
29
28
|
|
|
30
29
|
### useRead
|
|
@@ -63,27 +62,6 @@ const { data: user } = useRead(
|
|
|
63
62
|
);
|
|
64
63
|
```
|
|
65
64
|
|
|
66
|
-
### useLazyRead
|
|
67
|
-
|
|
68
|
-
Lazy data fetching for print/download/export scenarios. Does not auto-fetch on mount.
|
|
69
|
-
|
|
70
|
-
```typescript
|
|
71
|
-
function PrintOrder() {
|
|
72
|
-
const { trigger, loading } = useLazyRead((api) => api("orders/:id").GET);
|
|
73
|
-
|
|
74
|
-
const handlePrint = async (orderId: string) => {
|
|
75
|
-
const { data } = await trigger({ params: { id: orderId } });
|
|
76
|
-
if (data) printReceipt(data);
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
return (
|
|
80
|
-
<button onClick={() => handlePrint("123")} disabled={loading}>
|
|
81
|
-
{loading ? "Loading..." : "Print"}
|
|
82
|
-
</button>
|
|
83
|
-
);
|
|
84
|
-
}
|
|
85
|
-
```
|
|
86
|
-
|
|
87
65
|
### useWrite
|
|
88
66
|
|
|
89
67
|
Trigger mutations with loading and error states.
|
package/dist/index.d.mts
CHANGED
|
@@ -27,8 +27,11 @@ type BaseReadOptions = {
|
|
|
27
27
|
* @template TData - The response data type
|
|
28
28
|
* @template TError - The error type
|
|
29
29
|
* @template TMeta - Plugin-provided metadata fields
|
|
30
|
+
* @template TTriggerOptions - Options that can be passed to trigger()
|
|
30
31
|
*/
|
|
31
|
-
type BaseReadResult<TData, TError, TMeta = Record<string, unknown
|
|
32
|
+
type BaseReadResult<TData, TError, TMeta = Record<string, unknown>, TTriggerOptions = {
|
|
33
|
+
force?: boolean;
|
|
34
|
+
}> = {
|
|
32
35
|
/** True during the initial load (no data yet) */
|
|
33
36
|
loading: boolean;
|
|
34
37
|
/** True during any fetch operation */
|
|
@@ -41,8 +44,12 @@ type BaseReadResult<TData, TError, TMeta = Record<string, unknown>> = {
|
|
|
41
44
|
meta: TMeta;
|
|
42
45
|
/** Abort the current fetch operation */
|
|
43
46
|
abort: () => void;
|
|
44
|
-
/**
|
|
45
|
-
|
|
47
|
+
/**
|
|
48
|
+
* Manually trigger a fetch.
|
|
49
|
+
*
|
|
50
|
+
* @param options - Optional override options (query, body, params) to use for this specific request
|
|
51
|
+
*/
|
|
52
|
+
trigger: (options?: TTriggerOptions) => Promise<SpooshResponse<TData, TError>>;
|
|
46
53
|
};
|
|
47
54
|
/**
|
|
48
55
|
* Result returned by `useWrite` hook.
|
|
@@ -66,25 +73,6 @@ type BaseWriteResult<TData, TError, TOptions, TMeta = Record<string, unknown>> =
|
|
|
66
73
|
/** Abort the current mutation */
|
|
67
74
|
abort: () => void;
|
|
68
75
|
};
|
|
69
|
-
/**
|
|
70
|
-
* Result returned by `useLazyRead` hook.
|
|
71
|
-
*
|
|
72
|
-
* @template TData - The response data type
|
|
73
|
-
* @template TError - The error type
|
|
74
|
-
* @template TOptions - The trigger options type
|
|
75
|
-
*/
|
|
76
|
-
type BaseLazyReadResult<TData, TError, TOptions> = {
|
|
77
|
-
/** Execute the fetch with optional options */
|
|
78
|
-
trigger: (options?: TOptions) => Promise<SpooshResponse<TData, TError>>;
|
|
79
|
-
/** True while the fetch is in progress */
|
|
80
|
-
loading: boolean;
|
|
81
|
-
/** Response data from the API */
|
|
82
|
-
data: TData | undefined;
|
|
83
|
-
/** Error from the last failed request */
|
|
84
|
-
error: TError | undefined;
|
|
85
|
-
/** Abort the current fetch */
|
|
86
|
-
abort: () => void;
|
|
87
|
-
};
|
|
88
76
|
type OptionalQueryField<TQuery> = [TQuery] extends [never] ? object : undefined extends TQuery ? {
|
|
89
77
|
query?: Exclude<TQuery, undefined>;
|
|
90
78
|
} : {
|
|
@@ -123,7 +111,6 @@ type ExtractMethodError<T> = T extends (...args: never[]) => infer R ? ErrorResp
|
|
|
123
111
|
error: infer E;
|
|
124
112
|
} ? E : unknown : unknown;
|
|
125
113
|
type ExtractMethodOptions<T> = T extends (...args: infer A) => unknown ? A[0] : never;
|
|
126
|
-
type ExtractCoreMethodOptions<T> = T extends (...args: infer A) => unknown ? A[0] extends object ? Pick<A[0], Extract<keyof A[0], "query" | "params" | "body">> : object : object;
|
|
127
114
|
type ExtractMethodQuery<T> = ExtractMethodOptions<T> extends {
|
|
128
115
|
query: infer Q;
|
|
129
116
|
} ? Q : never;
|
|
@@ -147,6 +134,33 @@ type ExtractResponseParamNames<T> = SuccessReturnType<T> extends {
|
|
|
147
134
|
params: Record<infer K, unknown>;
|
|
148
135
|
};
|
|
149
136
|
} ? K extends string ? K : never : never;
|
|
137
|
+
type TriggerAwaitedReturn<T> = T extends (...args: never[]) => infer R ? Awaited<R> : never;
|
|
138
|
+
type ExtractInputFromResponse<T> = T extends {
|
|
139
|
+
input: infer I;
|
|
140
|
+
} ? I : never;
|
|
141
|
+
type ExtractTriggerQuery<I> = I extends {
|
|
142
|
+
query: infer Q;
|
|
143
|
+
} ? {
|
|
144
|
+
query?: Q;
|
|
145
|
+
} : unknown;
|
|
146
|
+
type ExtractTriggerBody<I> = I extends {
|
|
147
|
+
body: infer B;
|
|
148
|
+
} ? {
|
|
149
|
+
body?: B;
|
|
150
|
+
} : unknown;
|
|
151
|
+
type ExtractTriggerParams<I> = I extends {
|
|
152
|
+
params: infer P;
|
|
153
|
+
} ? {
|
|
154
|
+
params?: P;
|
|
155
|
+
} : unknown;
|
|
156
|
+
type TriggerOptions<T> = ExtractInputFromResponse<TriggerAwaitedReturn<T>> extends infer I ? [I] extends [never] ? {
|
|
157
|
+
force?: boolean;
|
|
158
|
+
} : ExtractTriggerQuery<I> & ExtractTriggerBody<I> & ExtractTriggerParams<I> & {
|
|
159
|
+
/** Force refetch even if data is cached */
|
|
160
|
+
force?: boolean;
|
|
161
|
+
} : {
|
|
162
|
+
force?: boolean;
|
|
163
|
+
};
|
|
150
164
|
type QueryField<TQuery> = [TQuery] extends [never] ? object : undefined extends TQuery ? {
|
|
151
165
|
query?: Exclude<TQuery, undefined>;
|
|
152
166
|
} : {
|
|
@@ -269,21 +283,12 @@ type InferError<T, TDefaultError> = [T] extends [unknown] ? TDefaultError : T;
|
|
|
269
283
|
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>>;
|
|
270
284
|
type ResolvedWriteOptions<TSchema, TPlugins extends PluginArray, TMethod, TDefaultError> = ResolveTypes<MergePluginOptions<TPlugins>["write"], WriteResolverContext<TSchema, TMethod, TDefaultError>>;
|
|
271
285
|
type UseReadFn<TDefaultError, TSchema, TPlugins extends PluginArray> = {
|
|
272
|
-
<TReadFn extends (api: ReadApiClient<TSchema, TDefaultError>) => Promise<
|
|
273
|
-
|
|
274
|
-
error?: unknown;
|
|
275
|
-
}>, 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>> & ResponseInputFields<ExtractResponseQuery<TReadFn>, ExtractResponseBody<TReadFn>, ExtractResponseParamNames<TReadFn>>;
|
|
276
|
-
<TReadFn extends (api: ReadApiClient<TSchema, TDefaultError>) => Promise<{
|
|
277
|
-
data?: unknown;
|
|
278
|
-
error?: unknown;
|
|
279
|
-
}>>(readFn: TReadFn): BaseReadResult<ExtractMethodData<TReadFn>, InferError<ExtractMethodError<TReadFn>, TDefaultError>, MergePluginResults<TPlugins>["read"]> & ResponseInputFields<ExtractResponseQuery<TReadFn>, ExtractResponseBody<TReadFn>, ExtractResponseParamNames<TReadFn>>;
|
|
286
|
+
<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>>;
|
|
287
|
+
<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>>;
|
|
280
288
|
};
|
|
281
289
|
type UseWriteFn<TDefaultError, TSchema, TPlugins extends PluginArray> = {
|
|
282
290
|
<TMethod extends (...args: never) => Promise<SpooshResponse<unknown, unknown>>>(writeFn: (api: WriteApiClient<TSchema, TDefaultError>) => TMethod): BaseWriteResult<ExtractMethodData<TMethod>, InferError<ExtractMethodError<TMethod>, TDefaultError>, Parameters<TMethod>[0] & ResolvedWriteOptions<TSchema, TPlugins, TMethod, TDefaultError>, MergePluginResults<TPlugins>["write"]> & WriteResponseInputFields<ExtractMethodQuery<TMethod>, ExtractMethodBody<TMethod>, ExtractResponseParamNames<TMethod>>;
|
|
283
291
|
};
|
|
284
|
-
type UseLazyReadFn<TDefaultError, TSchema> = {
|
|
285
|
-
<TMethod extends (...args: never) => Promise<SpooshResponse<unknown, unknown>>>(readFn: (api: ReadApiClient<TSchema, TDefaultError>) => TMethod): BaseLazyReadResult<ExtractMethodData<TMethod>, InferError<ExtractMethodError<TMethod>, TDefaultError>, ExtractCoreMethodOptions<TMethod>> & WriteResponseInputFields<ExtractResponseQuery<TMethod>, ExtractResponseBody<TMethod>, ExtractResponseParamNames<TMethod>>;
|
|
286
|
-
};
|
|
287
292
|
type InfiniteReadResolverContext<TSchema, TData, TError, TRequest> = ResolverContext<TSchema, TData, TError, TRequest extends {
|
|
288
293
|
query: infer Q;
|
|
289
294
|
} ? Q : never, TRequest extends {
|
|
@@ -336,23 +341,6 @@ type SpooshReactHooks<TDefaultError, TSchema, TPlugins extends PluginArray> = {
|
|
|
336
341
|
* ```
|
|
337
342
|
*/
|
|
338
343
|
useWrite: UseWriteFn<TDefaultError, TSchema, TPlugins>;
|
|
339
|
-
/**
|
|
340
|
-
* React hook for lazy GET requests with manual triggering (does not auto-fetch on mount).
|
|
341
|
-
*
|
|
342
|
-
* @param readFn - Function that selects the API endpoint (e.g., `(api) => api("posts").GET`)
|
|
343
|
-
* @returns Object containing `trigger`, `data`, `error`, `loading`, and `abort`
|
|
344
|
-
*
|
|
345
|
-
* @example
|
|
346
|
-
* ```tsx
|
|
347
|
-
* const { trigger, loading, data } = useLazyRead((api) => api("posts/:id").GET);
|
|
348
|
-
*
|
|
349
|
-
* const handleClick = async (id) => {
|
|
350
|
-
* const { data, error } = await trigger({ params: { id } });
|
|
351
|
-
* if (data) console.log('Fetched:', data);
|
|
352
|
-
* };
|
|
353
|
-
* ```
|
|
354
|
-
*/
|
|
355
|
-
useLazyRead: UseLazyReadFn<TDefaultError, TSchema>;
|
|
356
344
|
/**
|
|
357
345
|
* React hook for infinite/paginated data fetching with automatic pagination control.
|
|
358
346
|
*
|
|
@@ -416,40 +404,33 @@ type SpooshInstanceShape<TApi, TSchema, TDefaultError, TPlugins> = {
|
|
|
416
404
|
*/
|
|
417
405
|
declare function createReactSpoosh<TSchema, TDefaultError, TPlugins extends PluginArray, TApi>(instance: SpooshInstanceShape<TApi, TSchema, TDefaultError, TPlugins>): SpooshReactHooks<TDefaultError, TSchema, TPlugins>;
|
|
418
406
|
|
|
419
|
-
declare function createUseRead<TSchema, TDefaultError, TPlugins extends readonly SpooshPlugin<PluginTypeConfig>[]>(options: Omit<SpooshInstanceShape<unknown, TSchema, TDefaultError, TPlugins>, "_types">): {
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
error: infer E;
|
|
447
|
-
}> ? E : unknown] extends [unknown] ? TDefaultError : TReadFn extends (...args: unknown[]) => Promise<{
|
|
448
|
-
error: infer E;
|
|
449
|
-
}> ? E : unknown, MergePluginResults<TPlugins>["read"]> & ResponseInputFields<ExtractResponseQuery<TReadFn>, ExtractResponseBody<TReadFn>, ExtractResponseParamNames<TReadFn>>;
|
|
450
|
-
};
|
|
451
|
-
|
|
452
|
-
declare function createUseLazyRead<TSchema, TDefaultError, TPlugins extends readonly SpooshPlugin<PluginTypeConfig>[]>(options: Omit<SpooshInstanceShape<unknown, TSchema, TDefaultError, TPlugins>, "_types">): <TMethod extends (...args: never[]) => Promise<SpooshResponse<unknown, unknown>>>(readFn: (api: ReadApiClient<TSchema, TDefaultError>) => TMethod) => BaseLazyReadResult<ExtractMethodData<TMethod>, [ExtractMethodError<TMethod>] extends [unknown] ? TDefaultError : ExtractMethodError<TMethod>, ExtractCoreMethodOptions<TMethod>> & WriteResponseInputFields<ExtractResponseQuery<TMethod>, ExtractResponseBody<TMethod>, ExtractResponseParamNames<TMethod>>;
|
|
407
|
+
declare function createUseRead<TSchema, TDefaultError, TPlugins extends readonly SpooshPlugin<PluginTypeConfig>[]>(options: Omit<SpooshInstanceShape<unknown, TSchema, TDefaultError, TPlugins>, "_types">): <TReadFn extends (api: ReadApiClient<TSchema, TDefaultError>) => Promise<SpooshResponse<unknown, unknown>>, TReadOpts extends BaseReadOptions & ResolveTypes<((TPlugins[number] extends infer T ? T extends TPlugins[number] ? T extends SpooshPlugin<infer Types extends PluginTypeConfig> ? Types extends {
|
|
408
|
+
readOptions: infer R;
|
|
409
|
+
} ? R : object : object : never : never) extends infer T_1 ? T_1 extends (TPlugins[number] extends infer T_2 ? T_2 extends TPlugins[number] ? T_2 extends SpooshPlugin<infer Types extends PluginTypeConfig> ? Types extends {
|
|
410
|
+
readOptions: infer R;
|
|
411
|
+
} ? R : object : object : never : never) ? T_1 extends unknown ? (x: T_1) => void : never : never : never) extends (x: infer I) => void ? I : never, ResolverContext<TSchema, TReadFn extends (...args: unknown[]) => Promise<{
|
|
412
|
+
data: infer D;
|
|
413
|
+
}> ? D : unknown, [TReadFn extends (...args: unknown[]) => Promise<{
|
|
414
|
+
error: infer E;
|
|
415
|
+
}> ? E : unknown] extends [unknown] ? TDefaultError : TReadFn extends (...args: unknown[]) => Promise<{
|
|
416
|
+
error: infer E;
|
|
417
|
+
}> ? E : unknown, ExtractResponseQuery<TReadFn>, ExtractResponseBody<TReadFn>, ExtractResponseParamNames<TReadFn> extends never ? never : Record<ExtractResponseParamNames<TReadFn>, string | number>>> = BaseReadOptions & ResolveTypes<((TPlugins[number] extends infer T_3 ? T_3 extends TPlugins[number] ? T_3 extends SpooshPlugin<infer Types extends PluginTypeConfig> ? Types extends {
|
|
418
|
+
readOptions: infer R;
|
|
419
|
+
} ? R : object : object : never : never) extends infer T_4 ? T_4 extends (TPlugins[number] extends infer T_5 ? T_5 extends TPlugins[number] ? T_5 extends SpooshPlugin<infer Types extends PluginTypeConfig> ? Types extends {
|
|
420
|
+
readOptions: infer R;
|
|
421
|
+
} ? R : object : object : never : never) ? T_4 extends unknown ? (x: T_4) => void : never : never : never) extends (x: infer I) => void ? I : never, ResolverContext<TSchema, TReadFn extends (...args: unknown[]) => Promise<{
|
|
422
|
+
data: infer D;
|
|
423
|
+
}> ? D : unknown, [TReadFn extends (...args: unknown[]) => Promise<{
|
|
424
|
+
error: infer E;
|
|
425
|
+
}> ? E : unknown] extends [unknown] ? TDefaultError : TReadFn extends (...args: unknown[]) => Promise<{
|
|
426
|
+
error: infer E;
|
|
427
|
+
}> ? E : unknown, ExtractResponseQuery<TReadFn>, ExtractResponseBody<TReadFn>, ExtractResponseParamNames<TReadFn> extends never ? never : Record<ExtractResponseParamNames<TReadFn>, string | number>>>>(readFn: TReadFn, readOptions?: TReadOpts) => BaseReadResult<TReadFn extends (...args: unknown[]) => Promise<{
|
|
428
|
+
data: infer D;
|
|
429
|
+
}> ? D : unknown, [TReadFn extends (...args: unknown[]) => Promise<{
|
|
430
|
+
error: infer E;
|
|
431
|
+
}> ? E : unknown] extends [unknown] ? TDefaultError : TReadFn extends (...args: unknown[]) => Promise<{
|
|
432
|
+
error: infer E;
|
|
433
|
+
}> ? E : unknown, ResolveResultTypes<MergePluginResults<TPlugins>["read"], TReadOpts>, TriggerOptions<TReadFn>> & ResponseInputFields<ExtractResponseQuery<TReadFn>, ExtractResponseBody<TReadFn>, ExtractResponseParamNames<TReadFn>>;
|
|
453
434
|
|
|
454
435
|
declare function createUseWrite<TSchema, TDefaultError, TPlugins extends readonly SpooshPlugin<PluginTypeConfig>[]>(options: Omit<SpooshInstanceShape<unknown, TSchema, TDefaultError, TPlugins>, "_types">): <TMethod extends (...args: never[]) => Promise<SpooshResponse<unknown, unknown>>>(writeFn: (api: WriteApiClient<TSchema, TDefaultError>) => TMethod) => BaseWriteResult<ExtractMethodData<TMethod>, [ExtractMethodError<TMethod>] extends [unknown] ? TDefaultError : ExtractMethodError<TMethod>, ExtractMethodOptions<TMethod> & ResolveTypes<((TPlugins[number] extends infer T ? T extends TPlugins[number] ? T extends SpooshPlugin<infer Types extends PluginTypeConfig> ? Types extends {
|
|
455
436
|
writeOptions: infer W;
|
|
@@ -467,4 +448,4 @@ declare function createUseInfiniteRead<TSchema, TDefaultError, TPlugins extends
|
|
|
467
448
|
readResult: infer R;
|
|
468
449
|
} ? R : object : object : never : never) ? T_1 extends unknown ? (x: T_1) => void : never : never : never) extends (x: infer I) => void ? I : never>;
|
|
469
450
|
|
|
470
|
-
export { type BaseInfiniteReadOptions, type BaseInfiniteReadResult, type
|
|
451
|
+
export { type BaseInfiniteReadOptions, type BaseInfiniteReadResult, type BaseReadOptions, type BaseReadResult, type BaseWriteResult, type PluginHooksConfig, type SpooshReactHooks, type UseInfiniteReadResult, type UseReadResult, type UseWriteResult, createReactSpoosh, createUseInfiniteRead, createUseRead, createUseWrite };
|
package/dist/index.d.ts
CHANGED
|
@@ -27,8 +27,11 @@ type BaseReadOptions = {
|
|
|
27
27
|
* @template TData - The response data type
|
|
28
28
|
* @template TError - The error type
|
|
29
29
|
* @template TMeta - Plugin-provided metadata fields
|
|
30
|
+
* @template TTriggerOptions - Options that can be passed to trigger()
|
|
30
31
|
*/
|
|
31
|
-
type BaseReadResult<TData, TError, TMeta = Record<string, unknown
|
|
32
|
+
type BaseReadResult<TData, TError, TMeta = Record<string, unknown>, TTriggerOptions = {
|
|
33
|
+
force?: boolean;
|
|
34
|
+
}> = {
|
|
32
35
|
/** True during the initial load (no data yet) */
|
|
33
36
|
loading: boolean;
|
|
34
37
|
/** True during any fetch operation */
|
|
@@ -41,8 +44,12 @@ type BaseReadResult<TData, TError, TMeta = Record<string, unknown>> = {
|
|
|
41
44
|
meta: TMeta;
|
|
42
45
|
/** Abort the current fetch operation */
|
|
43
46
|
abort: () => void;
|
|
44
|
-
/**
|
|
45
|
-
|
|
47
|
+
/**
|
|
48
|
+
* Manually trigger a fetch.
|
|
49
|
+
*
|
|
50
|
+
* @param options - Optional override options (query, body, params) to use for this specific request
|
|
51
|
+
*/
|
|
52
|
+
trigger: (options?: TTriggerOptions) => Promise<SpooshResponse<TData, TError>>;
|
|
46
53
|
};
|
|
47
54
|
/**
|
|
48
55
|
* Result returned by `useWrite` hook.
|
|
@@ -66,25 +73,6 @@ type BaseWriteResult<TData, TError, TOptions, TMeta = Record<string, unknown>> =
|
|
|
66
73
|
/** Abort the current mutation */
|
|
67
74
|
abort: () => void;
|
|
68
75
|
};
|
|
69
|
-
/**
|
|
70
|
-
* Result returned by `useLazyRead` hook.
|
|
71
|
-
*
|
|
72
|
-
* @template TData - The response data type
|
|
73
|
-
* @template TError - The error type
|
|
74
|
-
* @template TOptions - The trigger options type
|
|
75
|
-
*/
|
|
76
|
-
type BaseLazyReadResult<TData, TError, TOptions> = {
|
|
77
|
-
/** Execute the fetch with optional options */
|
|
78
|
-
trigger: (options?: TOptions) => Promise<SpooshResponse<TData, TError>>;
|
|
79
|
-
/** True while the fetch is in progress */
|
|
80
|
-
loading: boolean;
|
|
81
|
-
/** Response data from the API */
|
|
82
|
-
data: TData | undefined;
|
|
83
|
-
/** Error from the last failed request */
|
|
84
|
-
error: TError | undefined;
|
|
85
|
-
/** Abort the current fetch */
|
|
86
|
-
abort: () => void;
|
|
87
|
-
};
|
|
88
76
|
type OptionalQueryField<TQuery> = [TQuery] extends [never] ? object : undefined extends TQuery ? {
|
|
89
77
|
query?: Exclude<TQuery, undefined>;
|
|
90
78
|
} : {
|
|
@@ -123,7 +111,6 @@ type ExtractMethodError<T> = T extends (...args: never[]) => infer R ? ErrorResp
|
|
|
123
111
|
error: infer E;
|
|
124
112
|
} ? E : unknown : unknown;
|
|
125
113
|
type ExtractMethodOptions<T> = T extends (...args: infer A) => unknown ? A[0] : never;
|
|
126
|
-
type ExtractCoreMethodOptions<T> = T extends (...args: infer A) => unknown ? A[0] extends object ? Pick<A[0], Extract<keyof A[0], "query" | "params" | "body">> : object : object;
|
|
127
114
|
type ExtractMethodQuery<T> = ExtractMethodOptions<T> extends {
|
|
128
115
|
query: infer Q;
|
|
129
116
|
} ? Q : never;
|
|
@@ -147,6 +134,33 @@ type ExtractResponseParamNames<T> = SuccessReturnType<T> extends {
|
|
|
147
134
|
params: Record<infer K, unknown>;
|
|
148
135
|
};
|
|
149
136
|
} ? K extends string ? K : never : never;
|
|
137
|
+
type TriggerAwaitedReturn<T> = T extends (...args: never[]) => infer R ? Awaited<R> : never;
|
|
138
|
+
type ExtractInputFromResponse<T> = T extends {
|
|
139
|
+
input: infer I;
|
|
140
|
+
} ? I : never;
|
|
141
|
+
type ExtractTriggerQuery<I> = I extends {
|
|
142
|
+
query: infer Q;
|
|
143
|
+
} ? {
|
|
144
|
+
query?: Q;
|
|
145
|
+
} : unknown;
|
|
146
|
+
type ExtractTriggerBody<I> = I extends {
|
|
147
|
+
body: infer B;
|
|
148
|
+
} ? {
|
|
149
|
+
body?: B;
|
|
150
|
+
} : unknown;
|
|
151
|
+
type ExtractTriggerParams<I> = I extends {
|
|
152
|
+
params: infer P;
|
|
153
|
+
} ? {
|
|
154
|
+
params?: P;
|
|
155
|
+
} : unknown;
|
|
156
|
+
type TriggerOptions<T> = ExtractInputFromResponse<TriggerAwaitedReturn<T>> extends infer I ? [I] extends [never] ? {
|
|
157
|
+
force?: boolean;
|
|
158
|
+
} : ExtractTriggerQuery<I> & ExtractTriggerBody<I> & ExtractTriggerParams<I> & {
|
|
159
|
+
/** Force refetch even if data is cached */
|
|
160
|
+
force?: boolean;
|
|
161
|
+
} : {
|
|
162
|
+
force?: boolean;
|
|
163
|
+
};
|
|
150
164
|
type QueryField<TQuery> = [TQuery] extends [never] ? object : undefined extends TQuery ? {
|
|
151
165
|
query?: Exclude<TQuery, undefined>;
|
|
152
166
|
} : {
|
|
@@ -269,21 +283,12 @@ type InferError<T, TDefaultError> = [T] extends [unknown] ? TDefaultError : T;
|
|
|
269
283
|
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>>;
|
|
270
284
|
type ResolvedWriteOptions<TSchema, TPlugins extends PluginArray, TMethod, TDefaultError> = ResolveTypes<MergePluginOptions<TPlugins>["write"], WriteResolverContext<TSchema, TMethod, TDefaultError>>;
|
|
271
285
|
type UseReadFn<TDefaultError, TSchema, TPlugins extends PluginArray> = {
|
|
272
|
-
<TReadFn extends (api: ReadApiClient<TSchema, TDefaultError>) => Promise<
|
|
273
|
-
|
|
274
|
-
error?: unknown;
|
|
275
|
-
}>, 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>> & ResponseInputFields<ExtractResponseQuery<TReadFn>, ExtractResponseBody<TReadFn>, ExtractResponseParamNames<TReadFn>>;
|
|
276
|
-
<TReadFn extends (api: ReadApiClient<TSchema, TDefaultError>) => Promise<{
|
|
277
|
-
data?: unknown;
|
|
278
|
-
error?: unknown;
|
|
279
|
-
}>>(readFn: TReadFn): BaseReadResult<ExtractMethodData<TReadFn>, InferError<ExtractMethodError<TReadFn>, TDefaultError>, MergePluginResults<TPlugins>["read"]> & ResponseInputFields<ExtractResponseQuery<TReadFn>, ExtractResponseBody<TReadFn>, ExtractResponseParamNames<TReadFn>>;
|
|
286
|
+
<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>>;
|
|
287
|
+
<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>>;
|
|
280
288
|
};
|
|
281
289
|
type UseWriteFn<TDefaultError, TSchema, TPlugins extends PluginArray> = {
|
|
282
290
|
<TMethod extends (...args: never) => Promise<SpooshResponse<unknown, unknown>>>(writeFn: (api: WriteApiClient<TSchema, TDefaultError>) => TMethod): BaseWriteResult<ExtractMethodData<TMethod>, InferError<ExtractMethodError<TMethod>, TDefaultError>, Parameters<TMethod>[0] & ResolvedWriteOptions<TSchema, TPlugins, TMethod, TDefaultError>, MergePluginResults<TPlugins>["write"]> & WriteResponseInputFields<ExtractMethodQuery<TMethod>, ExtractMethodBody<TMethod>, ExtractResponseParamNames<TMethod>>;
|
|
283
291
|
};
|
|
284
|
-
type UseLazyReadFn<TDefaultError, TSchema> = {
|
|
285
|
-
<TMethod extends (...args: never) => Promise<SpooshResponse<unknown, unknown>>>(readFn: (api: ReadApiClient<TSchema, TDefaultError>) => TMethod): BaseLazyReadResult<ExtractMethodData<TMethod>, InferError<ExtractMethodError<TMethod>, TDefaultError>, ExtractCoreMethodOptions<TMethod>> & WriteResponseInputFields<ExtractResponseQuery<TMethod>, ExtractResponseBody<TMethod>, ExtractResponseParamNames<TMethod>>;
|
|
286
|
-
};
|
|
287
292
|
type InfiniteReadResolverContext<TSchema, TData, TError, TRequest> = ResolverContext<TSchema, TData, TError, TRequest extends {
|
|
288
293
|
query: infer Q;
|
|
289
294
|
} ? Q : never, TRequest extends {
|
|
@@ -336,23 +341,6 @@ type SpooshReactHooks<TDefaultError, TSchema, TPlugins extends PluginArray> = {
|
|
|
336
341
|
* ```
|
|
337
342
|
*/
|
|
338
343
|
useWrite: UseWriteFn<TDefaultError, TSchema, TPlugins>;
|
|
339
|
-
/**
|
|
340
|
-
* React hook for lazy GET requests with manual triggering (does not auto-fetch on mount).
|
|
341
|
-
*
|
|
342
|
-
* @param readFn - Function that selects the API endpoint (e.g., `(api) => api("posts").GET`)
|
|
343
|
-
* @returns Object containing `trigger`, `data`, `error`, `loading`, and `abort`
|
|
344
|
-
*
|
|
345
|
-
* @example
|
|
346
|
-
* ```tsx
|
|
347
|
-
* const { trigger, loading, data } = useLazyRead((api) => api("posts/:id").GET);
|
|
348
|
-
*
|
|
349
|
-
* const handleClick = async (id) => {
|
|
350
|
-
* const { data, error } = await trigger({ params: { id } });
|
|
351
|
-
* if (data) console.log('Fetched:', data);
|
|
352
|
-
* };
|
|
353
|
-
* ```
|
|
354
|
-
*/
|
|
355
|
-
useLazyRead: UseLazyReadFn<TDefaultError, TSchema>;
|
|
356
344
|
/**
|
|
357
345
|
* React hook for infinite/paginated data fetching with automatic pagination control.
|
|
358
346
|
*
|
|
@@ -416,40 +404,33 @@ type SpooshInstanceShape<TApi, TSchema, TDefaultError, TPlugins> = {
|
|
|
416
404
|
*/
|
|
417
405
|
declare function createReactSpoosh<TSchema, TDefaultError, TPlugins extends PluginArray, TApi>(instance: SpooshInstanceShape<TApi, TSchema, TDefaultError, TPlugins>): SpooshReactHooks<TDefaultError, TSchema, TPlugins>;
|
|
418
406
|
|
|
419
|
-
declare function createUseRead<TSchema, TDefaultError, TPlugins extends readonly SpooshPlugin<PluginTypeConfig>[]>(options: Omit<SpooshInstanceShape<unknown, TSchema, TDefaultError, TPlugins>, "_types">): {
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
error: infer E;
|
|
447
|
-
}> ? E : unknown] extends [unknown] ? TDefaultError : TReadFn extends (...args: unknown[]) => Promise<{
|
|
448
|
-
error: infer E;
|
|
449
|
-
}> ? E : unknown, MergePluginResults<TPlugins>["read"]> & ResponseInputFields<ExtractResponseQuery<TReadFn>, ExtractResponseBody<TReadFn>, ExtractResponseParamNames<TReadFn>>;
|
|
450
|
-
};
|
|
451
|
-
|
|
452
|
-
declare function createUseLazyRead<TSchema, TDefaultError, TPlugins extends readonly SpooshPlugin<PluginTypeConfig>[]>(options: Omit<SpooshInstanceShape<unknown, TSchema, TDefaultError, TPlugins>, "_types">): <TMethod extends (...args: never[]) => Promise<SpooshResponse<unknown, unknown>>>(readFn: (api: ReadApiClient<TSchema, TDefaultError>) => TMethod) => BaseLazyReadResult<ExtractMethodData<TMethod>, [ExtractMethodError<TMethod>] extends [unknown] ? TDefaultError : ExtractMethodError<TMethod>, ExtractCoreMethodOptions<TMethod>> & WriteResponseInputFields<ExtractResponseQuery<TMethod>, ExtractResponseBody<TMethod>, ExtractResponseParamNames<TMethod>>;
|
|
407
|
+
declare function createUseRead<TSchema, TDefaultError, TPlugins extends readonly SpooshPlugin<PluginTypeConfig>[]>(options: Omit<SpooshInstanceShape<unknown, TSchema, TDefaultError, TPlugins>, "_types">): <TReadFn extends (api: ReadApiClient<TSchema, TDefaultError>) => Promise<SpooshResponse<unknown, unknown>>, TReadOpts extends BaseReadOptions & ResolveTypes<((TPlugins[number] extends infer T ? T extends TPlugins[number] ? T extends SpooshPlugin<infer Types extends PluginTypeConfig> ? Types extends {
|
|
408
|
+
readOptions: infer R;
|
|
409
|
+
} ? R : object : object : never : never) extends infer T_1 ? T_1 extends (TPlugins[number] extends infer T_2 ? T_2 extends TPlugins[number] ? T_2 extends SpooshPlugin<infer Types extends PluginTypeConfig> ? Types extends {
|
|
410
|
+
readOptions: infer R;
|
|
411
|
+
} ? R : object : object : never : never) ? T_1 extends unknown ? (x: T_1) => void : never : never : never) extends (x: infer I) => void ? I : never, ResolverContext<TSchema, TReadFn extends (...args: unknown[]) => Promise<{
|
|
412
|
+
data: infer D;
|
|
413
|
+
}> ? D : unknown, [TReadFn extends (...args: unknown[]) => Promise<{
|
|
414
|
+
error: infer E;
|
|
415
|
+
}> ? E : unknown] extends [unknown] ? TDefaultError : TReadFn extends (...args: unknown[]) => Promise<{
|
|
416
|
+
error: infer E;
|
|
417
|
+
}> ? E : unknown, ExtractResponseQuery<TReadFn>, ExtractResponseBody<TReadFn>, ExtractResponseParamNames<TReadFn> extends never ? never : Record<ExtractResponseParamNames<TReadFn>, string | number>>> = BaseReadOptions & ResolveTypes<((TPlugins[number] extends infer T_3 ? T_3 extends TPlugins[number] ? T_3 extends SpooshPlugin<infer Types extends PluginTypeConfig> ? Types extends {
|
|
418
|
+
readOptions: infer R;
|
|
419
|
+
} ? R : object : object : never : never) extends infer T_4 ? T_4 extends (TPlugins[number] extends infer T_5 ? T_5 extends TPlugins[number] ? T_5 extends SpooshPlugin<infer Types extends PluginTypeConfig> ? Types extends {
|
|
420
|
+
readOptions: infer R;
|
|
421
|
+
} ? R : object : object : never : never) ? T_4 extends unknown ? (x: T_4) => void : never : never : never) extends (x: infer I) => void ? I : never, ResolverContext<TSchema, TReadFn extends (...args: unknown[]) => Promise<{
|
|
422
|
+
data: infer D;
|
|
423
|
+
}> ? D : unknown, [TReadFn extends (...args: unknown[]) => Promise<{
|
|
424
|
+
error: infer E;
|
|
425
|
+
}> ? E : unknown] extends [unknown] ? TDefaultError : TReadFn extends (...args: unknown[]) => Promise<{
|
|
426
|
+
error: infer E;
|
|
427
|
+
}> ? E : unknown, ExtractResponseQuery<TReadFn>, ExtractResponseBody<TReadFn>, ExtractResponseParamNames<TReadFn> extends never ? never : Record<ExtractResponseParamNames<TReadFn>, string | number>>>>(readFn: TReadFn, readOptions?: TReadOpts) => BaseReadResult<TReadFn extends (...args: unknown[]) => Promise<{
|
|
428
|
+
data: infer D;
|
|
429
|
+
}> ? D : unknown, [TReadFn extends (...args: unknown[]) => Promise<{
|
|
430
|
+
error: infer E;
|
|
431
|
+
}> ? E : unknown] extends [unknown] ? TDefaultError : TReadFn extends (...args: unknown[]) => Promise<{
|
|
432
|
+
error: infer E;
|
|
433
|
+
}> ? E : unknown, ResolveResultTypes<MergePluginResults<TPlugins>["read"], TReadOpts>, TriggerOptions<TReadFn>> & ResponseInputFields<ExtractResponseQuery<TReadFn>, ExtractResponseBody<TReadFn>, ExtractResponseParamNames<TReadFn>>;
|
|
453
434
|
|
|
454
435
|
declare function createUseWrite<TSchema, TDefaultError, TPlugins extends readonly SpooshPlugin<PluginTypeConfig>[]>(options: Omit<SpooshInstanceShape<unknown, TSchema, TDefaultError, TPlugins>, "_types">): <TMethod extends (...args: never[]) => Promise<SpooshResponse<unknown, unknown>>>(writeFn: (api: WriteApiClient<TSchema, TDefaultError>) => TMethod) => BaseWriteResult<ExtractMethodData<TMethod>, [ExtractMethodError<TMethod>] extends [unknown] ? TDefaultError : ExtractMethodError<TMethod>, ExtractMethodOptions<TMethod> & ResolveTypes<((TPlugins[number] extends infer T ? T extends TPlugins[number] ? T extends SpooshPlugin<infer Types extends PluginTypeConfig> ? Types extends {
|
|
455
436
|
writeOptions: infer W;
|
|
@@ -467,4 +448,4 @@ declare function createUseInfiniteRead<TSchema, TDefaultError, TPlugins extends
|
|
|
467
448
|
readResult: infer R;
|
|
468
449
|
} ? R : object : object : never : never) ? T_1 extends unknown ? (x: T_1) => void : never : never : never) extends (x: infer I) => void ? I : never>;
|
|
469
450
|
|
|
470
|
-
export { type BaseInfiniteReadOptions, type BaseInfiniteReadResult, type
|
|
451
|
+
export { type BaseInfiniteReadOptions, type BaseInfiniteReadResult, type BaseReadOptions, type BaseReadResult, type BaseWriteResult, type PluginHooksConfig, type SpooshReactHooks, type UseInfiniteReadResult, type UseReadResult, type UseWriteResult, createReactSpoosh, createUseInfiniteRead, createUseRead, createUseWrite };
|