@robohall/react-query-factory 2.2.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +83 -14
- package/dist/index.d.mts +68 -31
- package/dist/index.d.ts +68 -31
- package/dist/index.js +74 -48
- package/dist/index.mjs +74 -48
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -417,6 +417,54 @@ The `.infinite()` key includes an `'infinite'` segment to keep it separate from
|
|
|
417
417
|
|
|
418
418
|
---
|
|
419
419
|
|
|
420
|
+
## Dependency injection
|
|
421
|
+
|
|
422
|
+
By default, whatever you pass as `params` is appended to the query key. That's exactly what you want for serializable inputs — but some `queryFn` inputs are **not** serializable and must not be in the key: an API client from React context, an auth token, a translator, a per-tenant SDK instance. Putting them in the key leaks them into the cache and devtools, and busts the cache every time they change identity.
|
|
423
|
+
|
|
424
|
+
Declare such inputs as an optional **third argument** to `queryFn` — a `deps` bag. It is supplied at the call site via `.inject(deps)`, is passed to `queryFn` (and `select`), and is **never** added to the query key:
|
|
425
|
+
|
|
426
|
+
```typescript
|
|
427
|
+
const describeInstances = queryFactory({
|
|
428
|
+
queryKey: ['ec2:DescribeInstances'],
|
|
429
|
+
queryFn: (
|
|
430
|
+
params: DescribeInstancesCommandInput,
|
|
431
|
+
ctx,
|
|
432
|
+
deps: { client: EC2Client }, // ← non-serializable, never keyed
|
|
433
|
+
) =>
|
|
434
|
+
deps.client.send(
|
|
435
|
+
new DescribeInstancesCommand({ ...params, NextToken: ctx.pageParam }),
|
|
436
|
+
{ abortSignal: ctx.signal },
|
|
437
|
+
),
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
function InstancesTable() {
|
|
441
|
+
const client = useContext(EC2ClientContext); // runtime dependency
|
|
442
|
+
const { data } = useQuery(
|
|
443
|
+
describeInstances({ MaxResults: 20 }).inject({ client }),
|
|
444
|
+
);
|
|
445
|
+
// query key is ['ec2:DescribeInstances', { MaxResults: 20 }] — no client in it
|
|
446
|
+
}
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
When a factory declares deps, `.inject()` is **required by the type system** — the bare call returns a `PendingInjection` that is a compile error to pass to `useQuery`/`useInfiniteQuery`:
|
|
450
|
+
|
|
451
|
+
```typescript
|
|
452
|
+
useQuery(describeInstances({ MaxResults: 20 })); // ❌ Type error — call .inject({ client })
|
|
453
|
+
useQuery(describeInstances({ MaxResults: 20 }).inject({ client })); // ✅
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
A factory that declares **no** deps is unaffected — its calls return options directly and there is no `.inject` to call. Nothing about the common path changes.
|
|
457
|
+
|
|
458
|
+
Key points:
|
|
459
|
+
|
|
460
|
+
- **`deps` never enters the query key** — that's the whole purpose. If a value should be part of cache identity, pass it as `params`, not `deps`.
|
|
461
|
+
- **One shared bag.** `queryFn` and `select` receive the _same_ `deps`; their `deps` types must agree.
|
|
462
|
+
- **Invalidation needs no deps.** The pending object still exposes the real `queryKey`, so `queryClient.invalidateQueries(describeInstances({ MaxResults: 20 }))` works without injecting anything. (`prefetchQuery`, which actually runs the `queryFn`, does require `.inject()`.)
|
|
463
|
+
- **Composition inherits the requirement.** A select-only child of a factory that declares deps inherits the deps requirement automatically.
|
|
464
|
+
- `.inject()` works the same on `.infinite()`: `describeInstances.infinite(params).inject({ client })`.
|
|
465
|
+
|
|
466
|
+
---
|
|
467
|
+
|
|
420
468
|
## Performance
|
|
421
469
|
|
|
422
470
|
TanStack Query's default `staleTime` is `0` — data is considered stale immediately, so a background refetch fires on every mount, window focus, and reconnect. For a single-page query that's one API call; for a crawling factory it's the full crawl repeated. Set `staleTime` in the factory config to match how often the underlying data actually changes:
|
|
@@ -458,19 +506,20 @@ Creates a child factory. Two overloads:
|
|
|
458
506
|
|
|
459
507
|
All fields except `reduce` and `shouldFetchNextPage` are the standard TanStack Query API — the same types and semantics you'd pass to `useQuery` or `useInfiniteQuery`. The factory doesn't reinvent them; it just requires certain combinations to be present in order to activate crawling.
|
|
460
508
|
|
|
461
|
-
| Field | Type
|
|
462
|
-
| ----------------------------------- |
|
|
463
|
-
| `queryKey` | `QueryKey`
|
|
464
|
-
| `queryFn` | `(params: TParams, ctx: QueryFunctionContext) => TData \| Promise<TData> \| AsyncIterable<TData>` | Same as TanStack, with an extra leading `params` argument. Returns an `AsyncIterable` to use iterator-based crawling.
|
|
465
|
-
| `select` | `(data: TData) => TSelected` | Exact TanStack API
|
|
466
|
-
| `getNextPageParam` | `GetNextPageParamFunction<TPageParam, TData>`
|
|
467
|
-
| `initialPageParam` | `TPageParam`
|
|
468
|
-
| `getPreviousPageParam` | `GetPreviousPageParamFunction<TPageParam, TData>`
|
|
469
|
-
| `shouldFetchNextPage` | `(combined: TSelected \| undefined, crawlOptions: TCrawlOptions) => boolean`
|
|
470
|
-
| `reduce` | `(acc: TSelected \| undefined, page: TData) => TSelected`
|
|
471
|
-
|
|
|
472
|
-
|
|
473
|
-
|
|
509
|
+
| Field | Type | Notes |
|
|
510
|
+
| ----------------------------------- | -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
511
|
+
| `queryKey` | `QueryKey` | Namespace segments. Params are appended at call time. |
|
|
512
|
+
| `queryFn` | `(params: TParams, ctx: QueryFunctionContext, deps: TDeps) => TData \| Promise<TData> \| AsyncIterable<TData>` | Same as TanStack, with an extra leading `params` argument and an optional trailing `deps` argument for non-serializable dependencies (see [Dependency injection](#dependency-injection)). Returns an `AsyncIterable` to use iterator-based crawling. |
|
|
513
|
+
| `select` | `(data: TData, deps: TDeps) => TSelected` | Exact TanStack API, plus the same injected `deps` bag as `queryFn`. Composed automatically on child factories. |
|
|
514
|
+
| `getNextPageParam` | `GetNextPageParamFunction<TPageParam, TData>` | Exact TanStack API. Required (with `shouldFetchNextPage`) to activate cursor-based crawling. Required (with `initialPageParam`) for `.infinite()`. |
|
|
515
|
+
| `initialPageParam` | `TPageParam` | Exact TanStack API. Drives `TPageParam` inference. Required for `.infinite()` to work at runtime. |
|
|
516
|
+
| `getPreviousPageParam` | `GetPreviousPageParamFunction<TPageParam, TData>` | Exact TanStack API. Passed through on `.infinite()`. |
|
|
517
|
+
| `shouldFetchNextPage` | `(combined: TSelected \| undefined, crawlOptions: TCrawlOptions) => boolean` | Library addition. **Required to activate crawling.** Called after each page — return `true` to keep fetching, `false` to stop. |
|
|
518
|
+
| `reduce` | `(acc: TSelected \| undefined, page: TData) => TSelected` | Library addition. Optional. Folds crawled pages into a single `TSelected` value; when omitted the result is an array of all fetched raw pages (`TData[]`). |
|
|
519
|
+
| `deps` (3rd `queryFn` arg) | `TDeps` | Library addition. Inferred from the optional third `queryFn` parameter. A bag of non-serializable dependencies supplied at the call site via `.inject(deps)`; passed to `queryFn`/`select` but never added to the query key. See [Dependency injection](#dependency-injection). |
|
|
520
|
+
| + all `StandardQueryOptions` fields | | `staleTime`, `gcTime`, `retry`, `enabled`, `refetchOnWindowFocus`, `placeholderData`, `initialData`, `meta`, etc. Function-form callbacks are supported wherever TanStack accepts them. |
|
|
521
|
+
|
|
522
|
+
### `QueryFactory<TParams, TData, TError, TSelected, TPageParam, TCrawlOptions, THasReduce, TDeps>`
|
|
474
523
|
|
|
475
524
|
The callable factory returned by `queryFactory()`.
|
|
476
525
|
|
|
@@ -479,6 +528,8 @@ factory(params: TParams, crawlOptions?: TCrawlOptions): ResolvedQueryOptions //
|
|
|
479
528
|
factory.infinite(params, crawlOptions?) : ResolvedInfiniteOptions // → useInfiniteQuery()
|
|
480
529
|
```
|
|
481
530
|
|
|
531
|
+
When the factory declares dependencies (`TDeps` is non-`void`), both calls instead return a `PendingInjection` and you must call `.inject(deps)` to obtain the usable options — see [Dependency injection](#dependency-injection).
|
|
532
|
+
|
|
482
533
|
### `ResolvedQueryOptions`
|
|
483
534
|
|
|
484
535
|
Return type of `factory(params)`. Pass directly to `useQuery()`. Contains an `initialPageParam?: never` field that prevents accidental use with `useInfiniteQuery`.
|
|
@@ -507,6 +558,24 @@ import type { FactoryCrawlOptions } from '@robohall/react-query-factory';
|
|
|
507
558
|
type CrawlOpts = FactoryCrawlOptions<typeof describeInstances>; // → { minResults?: number }
|
|
508
559
|
```
|
|
509
560
|
|
|
561
|
+
### `FactoryDeps<F>`
|
|
562
|
+
|
|
563
|
+
Extracts the injected-dependencies type from a factory — the argument to `.inject()`. Resolves to `void` for factories that declare no dependencies.
|
|
564
|
+
|
|
565
|
+
```typescript
|
|
566
|
+
import type { FactoryDeps } from '@robohall/react-query-factory';
|
|
567
|
+
|
|
568
|
+
type Deps = FactoryDeps<typeof describeInstances>; // → { client: EC2Client }
|
|
569
|
+
```
|
|
570
|
+
|
|
571
|
+
### `PendingInjection<TDeps, TResolved>`
|
|
572
|
+
|
|
573
|
+
Returned by `factory(params)` / `factory.infinite(params)` when the factory declares dependencies. Carries the real `queryKey` (so it can still be passed to `invalidateQueries` and other filter APIs) but its `queryFn` is branded so the object cannot be passed to `useQuery`/`useInfiniteQuery` until `.inject(deps)` supplies the dependencies. See [Dependency injection](#dependency-injection).
|
|
574
|
+
|
|
575
|
+
### `WithInjection<TDeps, TResolved>`
|
|
576
|
+
|
|
577
|
+
Resolves to `TResolved` when `TDeps` is `void`, or to `PendingInjection<TDeps, TResolved>` otherwise. This is what makes `.inject()` required exactly when — and only when — a factory declares dependencies.
|
|
578
|
+
|
|
510
579
|
---
|
|
511
580
|
|
|
512
581
|
## Running the sandbox
|
|
@@ -515,4 +584,4 @@ type CrawlOpts = FactoryCrawlOptions<typeof describeInstances>; // → { minResu
|
|
|
515
584
|
npm run sandbox
|
|
516
585
|
```
|
|
517
586
|
|
|
518
|
-
Starts a Vite dev server with interactive demos covering every pattern: basic single-page fetch, async iterator queryFns, crawl-then-render, render-while-crawling, on-demand infinite pagination, client-side search with early stopping, factory composition, and scoped cache invalidation.
|
|
587
|
+
Starts a Vite dev server with interactive demos covering every pattern: basic single-page fetch, async iterator queryFns, crawl-then-render, render-while-crawling, on-demand infinite pagination, client-side search with early stopping, factory composition, dependency injection, and scoped cache invalidation.
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { QueryKey, QueryObserverOptions, QueryFunctionContext, InfiniteData, GetNextPageParamFunction, GetPreviousPageParamFunction } from '@tanstack/react-query';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* All TanStack Query options that apply to both regular and infinite queries,
|
|
@@ -23,14 +23,18 @@ type StandardQueryOptions<TError = Error, TData = unknown> = Omit<QueryObserverO
|
|
|
23
23
|
* mirrors TanStack's own API and ensures `TPageParam` is inferred from the
|
|
24
24
|
* concrete initial value (so `ctx.pageParam` in `queryFn` is typed correctly).
|
|
25
25
|
*/
|
|
26
|
-
type QueryFactoryConfig<TParams = void, TData = unknown, TError = Error, TSelected = TData, TPageParam = unknown, TCrawlOptions extends Record<string, unknown> = Record<string, unknown
|
|
26
|
+
type QueryFactoryConfig<TParams = void, TData = unknown, TError = Error, TSelected = TData, TPageParam = unknown, TCrawlOptions extends Record<string, unknown> = Record<string, unknown>, TDeps = void> = StandardQueryOptions<TError, TData> & {
|
|
27
27
|
/** Namespace segments. Params are appended as the final element at call time,
|
|
28
28
|
* giving a full key of [...namespace, 'infinite'?, params, crawlOptions?]. */
|
|
29
29
|
queryKey: QueryKey;
|
|
30
|
+
/** The optional third argument is a bag of non-serializable runtime dependencies
|
|
31
|
+
* (an API client, a token, a translator…). It is supplied at the call site via
|
|
32
|
+
* `factory(params).inject(deps)` and is deliberately NEVER part of the queryKey.
|
|
33
|
+
* Declaring it makes `.inject()` required before the options can reach useQuery. */
|
|
30
34
|
queryFn?: (params: TParams, context: QueryFunctionContext<QueryKey, [
|
|
31
35
|
unknown
|
|
32
|
-
] extends [TPageParam] ? never : TPageParam
|
|
33
|
-
select?: (data: TData) => TSelected;
|
|
36
|
+
] extends [TPageParam] ? never : TPageParam>, deps: TDeps) => TData | Promise<TData>;
|
|
37
|
+
select?: (data: TData, deps: TDeps) => TSelected;
|
|
34
38
|
/** TanStack v5 generic order: GetNextPageParamFunction<TPageParam, TData> */
|
|
35
39
|
getNextPageParam?: GetNextPageParamFunction<TPageParam, TData>;
|
|
36
40
|
/** Drives TPageParam inference so ctx.pageParam in queryFn is typed as TPageParam.
|
|
@@ -82,6 +86,33 @@ type ResolvedInfiniteOptions<TData = unknown, TError = Error, TPageParam = unkno
|
|
|
82
86
|
/** Required so this type satisfies useInfiniteQuery, which requires initialPageParam. */
|
|
83
87
|
initialPageParam: TPageParam;
|
|
84
88
|
};
|
|
89
|
+
declare const INJECTION_REQUIRED: unique symbol;
|
|
90
|
+
/**
|
|
91
|
+
* What `factory(params)` / `factory.infinite(params)` return when the factory's
|
|
92
|
+
* `queryFn`/`select` declare a non-serializable dependency bag (the third `queryFn`
|
|
93
|
+
* argument, `TDeps`).
|
|
94
|
+
*
|
|
95
|
+
* It carries the real `queryKey` — so it can still be handed to
|
|
96
|
+
* `invalidateQueries` and other filter APIs without supplying deps — but its
|
|
97
|
+
* `queryFn` is branded with a type that is NOT assignable to TanStack's
|
|
98
|
+
* `QueryFunction`. That makes it a compile error to pass directly to
|
|
99
|
+
* `useQuery`/`useInfiniteQuery`: the only way to obtain usable options is to call
|
|
100
|
+
* `.inject(deps)`, which returns the real `TResolved`.
|
|
101
|
+
*
|
|
102
|
+
* `deps` is deliberately never part of the query key.
|
|
103
|
+
*/
|
|
104
|
+
interface PendingInjection<TDeps, TResolved> {
|
|
105
|
+
queryKey: QueryKey;
|
|
106
|
+
queryFn: {
|
|
107
|
+
readonly [INJECTION_REQUIRED]: 'Call .inject({ ...deps }) before passing this to useQuery/useInfiniteQuery';
|
|
108
|
+
};
|
|
109
|
+
inject(deps: TDeps): TResolved;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Resolves to `TResolved` when the factory declares no dependencies (`TDeps` is
|
|
113
|
+
* `void`), or to a `PendingInjection` that forces `.inject(deps)` when it does.
|
|
114
|
+
*/
|
|
115
|
+
type WithInjection<TDeps, TResolved> = [TDeps] extends [void] ? TResolved : PendingInjection<TDeps, TResolved>;
|
|
85
116
|
/**
|
|
86
117
|
* A callable factory produced by `queryFactory()`.
|
|
87
118
|
*
|
|
@@ -95,32 +126,38 @@ type ResolvedInfiniteOptions<TData = unknown, TError = Error, TPageParam = unkno
|
|
|
95
126
|
* `params` is always optional. Calling with no arguments produces just the
|
|
96
127
|
* namespace key, which is useful for broad cache invalidation:
|
|
97
128
|
* `queryClient.invalidateQueries(factory())`
|
|
129
|
+
*
|
|
130
|
+
* When `TDeps` is non-`void` (the `queryFn` declares a third argument), both calls
|
|
131
|
+
* return a `PendingInjection` and the caller must `.inject(deps)` before the
|
|
132
|
+
* options can reach `useQuery`/`useInfiniteQuery`.
|
|
98
133
|
*/
|
|
99
|
-
interface QueryFactory<TParams = void, TData = unknown, TError = Error, TSelected = TData, TPageParam = unknown, TCrawlOptions extends Record<string, unknown> = Record<string, unknown>, THasReduce extends boolean = boolean> {
|
|
100
|
-
(params?: TParams, crawlOptions?: TCrawlOptions): ResolvedQueryOptions<TData, TError, TSelected
|
|
101
|
-
infinite(params?: TParams, crawlOptions?: TCrawlOptions): ResolvedInfiniteOptions<TData, TError, TPageParam, InfiniteData<TSelected, TPageParam
|
|
134
|
+
interface QueryFactory<TParams = void, TData = unknown, TError = Error, TSelected = TData, TPageParam = unknown, TCrawlOptions extends Record<string, unknown> = Record<string, unknown>, THasReduce extends boolean = boolean, TDeps = void> {
|
|
135
|
+
(params?: TParams, crawlOptions?: TCrawlOptions): WithInjection<TDeps, ResolvedQueryOptions<TData, TError, TSelected>>;
|
|
136
|
+
infinite(params?: TParams, crawlOptions?: TCrawlOptions): WithInjection<TDeps, ResolvedInfiniteOptions<TData, TError, TPageParam, InfiniteData<TSelected, TPageParam>>>;
|
|
102
137
|
}
|
|
103
138
|
/** Extracts the params type from a factory — the first argument of a factory call. */
|
|
104
139
|
type FactoryParams<F> = F extends QueryFactory<infer TParams, any, any, any, any, any, any> ? TParams : never;
|
|
105
140
|
/** Extracts the crawl options type from a factory — the second argument of a factory call. */
|
|
106
141
|
type FactoryCrawlOptions<F> = F extends QueryFactory<any, any, any, any, any, infer TCrawlOptions, any> ? TCrawlOptions : never;
|
|
142
|
+
/** Extracts the injected-dependencies type from a factory — the argument to `.inject()`. */
|
|
143
|
+
type FactoryDeps<F> = F extends QueryFactory<any, any, any, any, any, any, any, infer TDeps> ? TDeps : never;
|
|
107
144
|
/**
|
|
108
145
|
* Creates a standalone query factory with pagination and reduce. When `reduce` is
|
|
109
146
|
* present, `shouldFetchNextPage` receives `TSelected` (never undefined) because
|
|
110
147
|
* reduce always runs before the crawl-stop check.
|
|
111
148
|
*/
|
|
112
|
-
declare function queryFactory<TParams = void, TData = unknown, TError = Error, TSelected = TData, TPageParam = unknown, TCrawlOptions extends Record<string, unknown> = Record<string, unknown
|
|
149
|
+
declare function queryFactory<TParams = void, TData = unknown, TError = Error, TSelected = TData, TPageParam = unknown, TCrawlOptions extends Record<string, unknown> = Record<string, unknown>, TDeps = void>(config: StandardQueryOptions<TError, TData> & {
|
|
113
150
|
queryKey: QueryKey;
|
|
114
151
|
queryFn?: (params: TParams, context: QueryFunctionContext<QueryKey, [
|
|
115
152
|
unknown
|
|
116
|
-
] extends [TPageParam] ? never : TPageParam
|
|
117
|
-
select?: (data: TData) => TSelected;
|
|
153
|
+
] extends [TPageParam] ? never : TPageParam>, deps: TDeps) => TData | Promise<TData>;
|
|
154
|
+
select?: (data: TData, deps: TDeps) => TSelected;
|
|
118
155
|
getNextPageParam?: GetNextPageParamFunction<TPageParam, TData>;
|
|
119
156
|
initialPageParam?: TPageParam;
|
|
120
157
|
getPreviousPageParam?: GetPreviousPageParamFunction<TPageParam, TData>;
|
|
121
158
|
reduce: (accumulator: TSelected | undefined, page: TData) => TSelected;
|
|
122
159
|
shouldFetchNextPage?: (combined: TSelected, crawlOptions: TCrawlOptions) => boolean;
|
|
123
|
-
}): QueryFactory<TParams, TData, TError, TSelected, TPageParam, TCrawlOptions, true>;
|
|
160
|
+
}): QueryFactory<TParams, TData, TError, TSelected, TPageParam, TCrawlOptions, true, TDeps>;
|
|
124
161
|
/**
|
|
125
162
|
* Creates a standalone query factory from a config object.
|
|
126
163
|
*
|
|
@@ -131,24 +168,24 @@ declare function queryFactory<TParams = void, TData = unknown, TError = Error, T
|
|
|
131
168
|
* });
|
|
132
169
|
* // useQuery(usersFactory({ page: 1 }))
|
|
133
170
|
*/
|
|
134
|
-
declare function queryFactory<TParams = void, TData = unknown, TError = Error, TSelected = TData, TPageParam = unknown, TCrawlOptions extends Record<string, unknown> = Record<string, unknown
|
|
171
|
+
declare function queryFactory<TParams = void, TData = unknown, TError = Error, TSelected = TData, TPageParam = unknown, TCrawlOptions extends Record<string, unknown> = Record<string, unknown>, TDeps = void>(config: QueryFactoryConfig<TParams, TData, TError, TSelected, TPageParam, TCrawlOptions, TDeps>): QueryFactory<TParams, TData, TError, TSelected, TPageParam, TCrawlOptions, false, TDeps>;
|
|
135
172
|
/**
|
|
136
173
|
* Creates a child factory whose queryFn returns an AsyncIterable (e.g. an AWS SDK v3
|
|
137
174
|
* paginator). Inherits the parent's key namespace. Use this overload when switching
|
|
138
175
|
* to a paginator-based fetch while keeping the same result shape and crawl options.
|
|
139
176
|
*/
|
|
140
|
-
declare function queryFactory<TChildParams extends TParentParams, TData = unknown, TError = Error, TParentSelected = TData, TChildSelected = TParentSelected, TParentParams = TChildParams, TPageParam = unknown, TCrawlOptions extends Record<string, unknown> = Record<string, unknown
|
|
177
|
+
declare function queryFactory<TChildParams extends TParentParams, TData = unknown, TError = Error, TParentSelected = TData, TChildSelected = TParentSelected, TParentParams = TChildParams, TPageParam = unknown, TCrawlOptions extends Record<string, unknown> = Record<string, unknown>, TDeps = void>(parent: QueryFactory<TParentParams, TData, any, TParentSelected, TPageParam, any, any, any>, config: StandardQueryOptions<TError, TData> & {
|
|
141
178
|
queryKey?: QueryKey;
|
|
142
179
|
queryFn: (params: TChildParams, context: QueryFunctionContext<QueryKey, [
|
|
143
180
|
unknown
|
|
144
|
-
] extends [TPageParam] ? never : TPageParam
|
|
145
|
-
select?: (data: TData) => TChildSelected;
|
|
181
|
+
] extends [TPageParam] ? never : TPageParam>, deps: TDeps) => AsyncIterable<TData>;
|
|
182
|
+
select?: (data: TData, deps: TDeps) => TChildSelected;
|
|
146
183
|
reduce?: (accumulator: TChildSelected | undefined, page: TData) => TChildSelected;
|
|
147
184
|
shouldFetchNextPage?: (combined: TChildSelected | undefined, crawlOptions: TCrawlOptions) => boolean;
|
|
148
185
|
getNextPageParam?: GetNextPageParamFunction<TPageParam, TData>;
|
|
149
186
|
getPreviousPageParam?: GetPreviousPageParamFunction<TPageParam, TData>;
|
|
150
187
|
initialPageParam?: TPageParam;
|
|
151
|
-
}): QueryFactory<TChildParams, TData, TError, TChildSelected, TPageParam, TCrawlOptions, boolean>;
|
|
188
|
+
}): QueryFactory<TChildParams, TData, TError, TChildSelected, TPageParam, TCrawlOptions, boolean, TDeps>;
|
|
152
189
|
/**
|
|
153
190
|
* Creates a child factory that inherits the query key and standard options from
|
|
154
191
|
* `parent` and introduces a new `queryFn`. The child's query key is appended to
|
|
@@ -156,10 +193,10 @@ declare function queryFactory<TChildParams extends TParentParams, TData = unknow
|
|
|
156
193
|
*
|
|
157
194
|
* Use this overload when the child fetches different data than the parent.
|
|
158
195
|
*/
|
|
159
|
-
declare function queryFactory<TChildParams extends TParentParams, TData = unknown, TError = Error, TChildSelected = TData, TParentParams = TChildParams, TPageParam = unknown, TCrawlOptions extends Record<string, unknown> = Record<string, unknown
|
|
196
|
+
declare function queryFactory<TChildParams extends TParentParams, TData = unknown, TError = Error, TChildSelected = TData, TParentParams = TChildParams, TPageParam = unknown, TCrawlOptions extends Record<string, unknown> = Record<string, unknown>, TDeps = void>(parent: QueryFactory<TParentParams, any, any, any, any, any, any, any>, config: Omit<QueryFactoryConfig<TChildParams, TData, TError, TChildSelected, TPageParam, TCrawlOptions, TDeps>, 'queryKey' | 'queryFn'> & {
|
|
160
197
|
queryKey?: QueryKey;
|
|
161
|
-
queryFn: NonNullable<QueryFactoryConfig<TChildParams, TData, TError, TChildSelected, TPageParam>['queryFn']>;
|
|
162
|
-
}): QueryFactory<TChildParams, TData, TError, TChildSelected, TPageParam, TCrawlOptions, boolean>;
|
|
198
|
+
queryFn: NonNullable<QueryFactoryConfig<TChildParams, TData, TError, TChildSelected, TPageParam, TCrawlOptions, TDeps>['queryFn']>;
|
|
199
|
+
}): QueryFactory<TChildParams, TData, TError, TChildSelected, TPageParam, TCrawlOptions, boolean, TDeps>;
|
|
163
200
|
/**
|
|
164
201
|
* Creates a child factory that reuses the parent's `queryFn` and pagination
|
|
165
202
|
* config. Useful for adding a `select` transform, narrowing params, or
|
|
@@ -167,49 +204,49 @@ declare function queryFactory<TChildParams extends TParentParams, TData = unknow
|
|
|
167
204
|
* without changing what data is fetched. Parent and child `select` functions
|
|
168
205
|
* are automatically composed: `child.select(parent.select(data))`.
|
|
169
206
|
*/
|
|
170
|
-
declare function queryFactory<TChildParams extends TParentParams, TData = unknown, TError = Error, TParentSelected = TData, TChildSelected = TParentSelected, TParentParams = TChildParams, TPageParam = unknown, TParentCrawlOptions extends Record<string, unknown> = Record<string, unknown>, TChildCrawlOptions extends Record<string, unknown> = TParentCrawlOptions, TParentHasReduce extends boolean = boolean>(parent: QueryFactory<TParentParams, TData, any, TParentSelected, TPageParam, TParentCrawlOptions, TParentHasReduce>, config: StandardQueryOptions<TError, TData> & {
|
|
207
|
+
declare function queryFactory<TChildParams extends TParentParams, TData = unknown, TError = Error, TParentSelected = TData, TChildSelected = TParentSelected, TParentParams = TChildParams, TPageParam = unknown, TParentCrawlOptions extends Record<string, unknown> = Record<string, unknown>, TChildCrawlOptions extends Record<string, unknown> = TParentCrawlOptions, TParentHasReduce extends boolean = boolean, TParentDeps = void>(parent: QueryFactory<TParentParams, TData, any, TParentSelected, TPageParam, TParentCrawlOptions, TParentHasReduce, TParentDeps>, config: StandardQueryOptions<TError, TData> & {
|
|
171
208
|
queryKey?: QueryKey;
|
|
172
209
|
queryFn?: never;
|
|
173
|
-
select?: (data: TParentSelected) => TChildSelected;
|
|
210
|
+
select?: (data: TParentSelected, deps: TParentDeps) => TChildSelected;
|
|
174
211
|
getNextPageParam?: GetNextPageParamFunction<TPageParam, TData>;
|
|
175
212
|
initialPageParam?: TPageParam;
|
|
176
213
|
getPreviousPageParam?: GetPreviousPageParamFunction<TPageParam, TData>;
|
|
177
214
|
reduce?: (accumulator: TChildSelected | undefined, page: TData) => TChildSelected;
|
|
178
215
|
shouldFetchNextPage?: (combined: TParentHasReduce extends true ? TChildSelected : TChildSelected | undefined, crawlOptions: TChildCrawlOptions) => boolean;
|
|
179
|
-
}): QueryFactory<TChildParams, TData, TError, TChildSelected, TPageParam, TChildCrawlOptions, TParentHasReduce>;
|
|
216
|
+
}): QueryFactory<TChildParams, TData, TError, TChildSelected, TPageParam, TChildCrawlOptions, TParentHasReduce, TParentDeps>;
|
|
180
217
|
/**
|
|
181
218
|
* Creates a standalone factory whose queryFn returns an AsyncIterable (e.g. an AWS SDK v3
|
|
182
219
|
* paginator). The library drives the crawl with `for await...of`; `getNextPageParam` and
|
|
183
220
|
* `initialPageParam` are not required for `useQuery` mode. When `reduce` is present,
|
|
184
221
|
* `shouldFetchNextPage` receives `TSelected` (never undefined).
|
|
185
222
|
*/
|
|
186
|
-
declare function queryFactory<TParams = void, TData = unknown, TError = Error, TSelected = TData, TPageParam = unknown, TCrawlOptions extends Record<string, unknown> = Record<string, unknown
|
|
223
|
+
declare function queryFactory<TParams = void, TData = unknown, TError = Error, TSelected = TData, TPageParam = unknown, TCrawlOptions extends Record<string, unknown> = Record<string, unknown>, TDeps = void>(config: StandardQueryOptions<TError, TData> & {
|
|
187
224
|
queryKey: QueryKey;
|
|
188
225
|
queryFn: (params: TParams, context: QueryFunctionContext<QueryKey, [
|
|
189
226
|
unknown
|
|
190
|
-
] extends [TPageParam] ? never : TPageParam
|
|
191
|
-
select?: (data: TData) => TSelected;
|
|
227
|
+
] extends [TPageParam] ? never : TPageParam>, deps: TDeps) => AsyncIterable<TData>;
|
|
228
|
+
select?: (data: TData, deps: TDeps) => TSelected;
|
|
192
229
|
getNextPageParam?: GetNextPageParamFunction<TPageParam, TData>;
|
|
193
230
|
initialPageParam?: TPageParam;
|
|
194
231
|
getPreviousPageParam?: GetPreviousPageParamFunction<TPageParam, TData>;
|
|
195
232
|
reduce: (accumulator: TSelected | undefined, page: TData) => TSelected;
|
|
196
233
|
shouldFetchNextPage?: (combined: TSelected, crawlOptions: TCrawlOptions) => boolean;
|
|
197
|
-
}): QueryFactory<TParams, TData, TError, TSelected, TPageParam, TCrawlOptions, true>;
|
|
234
|
+
}): QueryFactory<TParams, TData, TError, TSelected, TPageParam, TCrawlOptions, true, TDeps>;
|
|
198
235
|
/**
|
|
199
236
|
* Creates a standalone factory whose queryFn returns an AsyncIterable, without a `reduce`
|
|
200
237
|
* function. Result is `TData[]` (one element per yielded page).
|
|
201
238
|
*/
|
|
202
|
-
declare function queryFactory<TParams = void, TData = unknown, TError = Error, TSelected = TData, TPageParam = unknown, TCrawlOptions extends Record<string, unknown> = Record<string, unknown
|
|
239
|
+
declare function queryFactory<TParams = void, TData = unknown, TError = Error, TSelected = TData, TPageParam = unknown, TCrawlOptions extends Record<string, unknown> = Record<string, unknown>, TDeps = void>(config: StandardQueryOptions<TError, TData> & {
|
|
203
240
|
queryKey: QueryKey;
|
|
204
241
|
queryFn: (params: TParams, context: QueryFunctionContext<QueryKey, [
|
|
205
242
|
unknown
|
|
206
|
-
] extends [TPageParam] ? never : TPageParam
|
|
207
|
-
select?: (data: TData) => TSelected;
|
|
243
|
+
] extends [TPageParam] ? never : TPageParam>, deps: TDeps) => AsyncIterable<TData>;
|
|
244
|
+
select?: (data: TData, deps: TDeps) => TSelected;
|
|
208
245
|
getNextPageParam?: GetNextPageParamFunction<TPageParam, TData>;
|
|
209
246
|
initialPageParam?: TPageParam;
|
|
210
247
|
getPreviousPageParam?: GetPreviousPageParamFunction<TPageParam, TData>;
|
|
211
248
|
reduce?: never;
|
|
212
249
|
shouldFetchNextPage: (combined: TSelected | undefined, crawlOptions: TCrawlOptions) => boolean;
|
|
213
|
-
}): QueryFactory<TParams, TData, TError, TSelected, TPageParam, TCrawlOptions, false>;
|
|
250
|
+
}): QueryFactory<TParams, TData, TError, TSelected, TPageParam, TCrawlOptions, false, TDeps>;
|
|
214
251
|
|
|
215
|
-
export { type FactoryCrawlOptions, type FactoryParams, type QueryFactory, type QueryFactoryConfig, type ResolvedInfiniteOptions, type ResolvedQueryOptions, type StandardQueryOptions, queryFactory };
|
|
252
|
+
export { type FactoryCrawlOptions, type FactoryDeps, type FactoryParams, type PendingInjection, type QueryFactory, type QueryFactoryConfig, type ResolvedInfiniteOptions, type ResolvedQueryOptions, type StandardQueryOptions, type WithInjection, queryFactory };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { QueryKey, QueryObserverOptions, QueryFunctionContext, InfiniteData, GetNextPageParamFunction, GetPreviousPageParamFunction } from '@tanstack/react-query';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* All TanStack Query options that apply to both regular and infinite queries,
|
|
@@ -23,14 +23,18 @@ type StandardQueryOptions<TError = Error, TData = unknown> = Omit<QueryObserverO
|
|
|
23
23
|
* mirrors TanStack's own API and ensures `TPageParam` is inferred from the
|
|
24
24
|
* concrete initial value (so `ctx.pageParam` in `queryFn` is typed correctly).
|
|
25
25
|
*/
|
|
26
|
-
type QueryFactoryConfig<TParams = void, TData = unknown, TError = Error, TSelected = TData, TPageParam = unknown, TCrawlOptions extends Record<string, unknown> = Record<string, unknown
|
|
26
|
+
type QueryFactoryConfig<TParams = void, TData = unknown, TError = Error, TSelected = TData, TPageParam = unknown, TCrawlOptions extends Record<string, unknown> = Record<string, unknown>, TDeps = void> = StandardQueryOptions<TError, TData> & {
|
|
27
27
|
/** Namespace segments. Params are appended as the final element at call time,
|
|
28
28
|
* giving a full key of [...namespace, 'infinite'?, params, crawlOptions?]. */
|
|
29
29
|
queryKey: QueryKey;
|
|
30
|
+
/** The optional third argument is a bag of non-serializable runtime dependencies
|
|
31
|
+
* (an API client, a token, a translator…). It is supplied at the call site via
|
|
32
|
+
* `factory(params).inject(deps)` and is deliberately NEVER part of the queryKey.
|
|
33
|
+
* Declaring it makes `.inject()` required before the options can reach useQuery. */
|
|
30
34
|
queryFn?: (params: TParams, context: QueryFunctionContext<QueryKey, [
|
|
31
35
|
unknown
|
|
32
|
-
] extends [TPageParam] ? never : TPageParam
|
|
33
|
-
select?: (data: TData) => TSelected;
|
|
36
|
+
] extends [TPageParam] ? never : TPageParam>, deps: TDeps) => TData | Promise<TData>;
|
|
37
|
+
select?: (data: TData, deps: TDeps) => TSelected;
|
|
34
38
|
/** TanStack v5 generic order: GetNextPageParamFunction<TPageParam, TData> */
|
|
35
39
|
getNextPageParam?: GetNextPageParamFunction<TPageParam, TData>;
|
|
36
40
|
/** Drives TPageParam inference so ctx.pageParam in queryFn is typed as TPageParam.
|
|
@@ -82,6 +86,33 @@ type ResolvedInfiniteOptions<TData = unknown, TError = Error, TPageParam = unkno
|
|
|
82
86
|
/** Required so this type satisfies useInfiniteQuery, which requires initialPageParam. */
|
|
83
87
|
initialPageParam: TPageParam;
|
|
84
88
|
};
|
|
89
|
+
declare const INJECTION_REQUIRED: unique symbol;
|
|
90
|
+
/**
|
|
91
|
+
* What `factory(params)` / `factory.infinite(params)` return when the factory's
|
|
92
|
+
* `queryFn`/`select` declare a non-serializable dependency bag (the third `queryFn`
|
|
93
|
+
* argument, `TDeps`).
|
|
94
|
+
*
|
|
95
|
+
* It carries the real `queryKey` — so it can still be handed to
|
|
96
|
+
* `invalidateQueries` and other filter APIs without supplying deps — but its
|
|
97
|
+
* `queryFn` is branded with a type that is NOT assignable to TanStack's
|
|
98
|
+
* `QueryFunction`. That makes it a compile error to pass directly to
|
|
99
|
+
* `useQuery`/`useInfiniteQuery`: the only way to obtain usable options is to call
|
|
100
|
+
* `.inject(deps)`, which returns the real `TResolved`.
|
|
101
|
+
*
|
|
102
|
+
* `deps` is deliberately never part of the query key.
|
|
103
|
+
*/
|
|
104
|
+
interface PendingInjection<TDeps, TResolved> {
|
|
105
|
+
queryKey: QueryKey;
|
|
106
|
+
queryFn: {
|
|
107
|
+
readonly [INJECTION_REQUIRED]: 'Call .inject({ ...deps }) before passing this to useQuery/useInfiniteQuery';
|
|
108
|
+
};
|
|
109
|
+
inject(deps: TDeps): TResolved;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Resolves to `TResolved` when the factory declares no dependencies (`TDeps` is
|
|
113
|
+
* `void`), or to a `PendingInjection` that forces `.inject(deps)` when it does.
|
|
114
|
+
*/
|
|
115
|
+
type WithInjection<TDeps, TResolved> = [TDeps] extends [void] ? TResolved : PendingInjection<TDeps, TResolved>;
|
|
85
116
|
/**
|
|
86
117
|
* A callable factory produced by `queryFactory()`.
|
|
87
118
|
*
|
|
@@ -95,32 +126,38 @@ type ResolvedInfiniteOptions<TData = unknown, TError = Error, TPageParam = unkno
|
|
|
95
126
|
* `params` is always optional. Calling with no arguments produces just the
|
|
96
127
|
* namespace key, which is useful for broad cache invalidation:
|
|
97
128
|
* `queryClient.invalidateQueries(factory())`
|
|
129
|
+
*
|
|
130
|
+
* When `TDeps` is non-`void` (the `queryFn` declares a third argument), both calls
|
|
131
|
+
* return a `PendingInjection` and the caller must `.inject(deps)` before the
|
|
132
|
+
* options can reach `useQuery`/`useInfiniteQuery`.
|
|
98
133
|
*/
|
|
99
|
-
interface QueryFactory<TParams = void, TData = unknown, TError = Error, TSelected = TData, TPageParam = unknown, TCrawlOptions extends Record<string, unknown> = Record<string, unknown>, THasReduce extends boolean = boolean> {
|
|
100
|
-
(params?: TParams, crawlOptions?: TCrawlOptions): ResolvedQueryOptions<TData, TError, TSelected
|
|
101
|
-
infinite(params?: TParams, crawlOptions?: TCrawlOptions): ResolvedInfiniteOptions<TData, TError, TPageParam, InfiniteData<TSelected, TPageParam
|
|
134
|
+
interface QueryFactory<TParams = void, TData = unknown, TError = Error, TSelected = TData, TPageParam = unknown, TCrawlOptions extends Record<string, unknown> = Record<string, unknown>, THasReduce extends boolean = boolean, TDeps = void> {
|
|
135
|
+
(params?: TParams, crawlOptions?: TCrawlOptions): WithInjection<TDeps, ResolvedQueryOptions<TData, TError, TSelected>>;
|
|
136
|
+
infinite(params?: TParams, crawlOptions?: TCrawlOptions): WithInjection<TDeps, ResolvedInfiniteOptions<TData, TError, TPageParam, InfiniteData<TSelected, TPageParam>>>;
|
|
102
137
|
}
|
|
103
138
|
/** Extracts the params type from a factory — the first argument of a factory call. */
|
|
104
139
|
type FactoryParams<F> = F extends QueryFactory<infer TParams, any, any, any, any, any, any> ? TParams : never;
|
|
105
140
|
/** Extracts the crawl options type from a factory — the second argument of a factory call. */
|
|
106
141
|
type FactoryCrawlOptions<F> = F extends QueryFactory<any, any, any, any, any, infer TCrawlOptions, any> ? TCrawlOptions : never;
|
|
142
|
+
/** Extracts the injected-dependencies type from a factory — the argument to `.inject()`. */
|
|
143
|
+
type FactoryDeps<F> = F extends QueryFactory<any, any, any, any, any, any, any, infer TDeps> ? TDeps : never;
|
|
107
144
|
/**
|
|
108
145
|
* Creates a standalone query factory with pagination and reduce. When `reduce` is
|
|
109
146
|
* present, `shouldFetchNextPage` receives `TSelected` (never undefined) because
|
|
110
147
|
* reduce always runs before the crawl-stop check.
|
|
111
148
|
*/
|
|
112
|
-
declare function queryFactory<TParams = void, TData = unknown, TError = Error, TSelected = TData, TPageParam = unknown, TCrawlOptions extends Record<string, unknown> = Record<string, unknown
|
|
149
|
+
declare function queryFactory<TParams = void, TData = unknown, TError = Error, TSelected = TData, TPageParam = unknown, TCrawlOptions extends Record<string, unknown> = Record<string, unknown>, TDeps = void>(config: StandardQueryOptions<TError, TData> & {
|
|
113
150
|
queryKey: QueryKey;
|
|
114
151
|
queryFn?: (params: TParams, context: QueryFunctionContext<QueryKey, [
|
|
115
152
|
unknown
|
|
116
|
-
] extends [TPageParam] ? never : TPageParam
|
|
117
|
-
select?: (data: TData) => TSelected;
|
|
153
|
+
] extends [TPageParam] ? never : TPageParam>, deps: TDeps) => TData | Promise<TData>;
|
|
154
|
+
select?: (data: TData, deps: TDeps) => TSelected;
|
|
118
155
|
getNextPageParam?: GetNextPageParamFunction<TPageParam, TData>;
|
|
119
156
|
initialPageParam?: TPageParam;
|
|
120
157
|
getPreviousPageParam?: GetPreviousPageParamFunction<TPageParam, TData>;
|
|
121
158
|
reduce: (accumulator: TSelected | undefined, page: TData) => TSelected;
|
|
122
159
|
shouldFetchNextPage?: (combined: TSelected, crawlOptions: TCrawlOptions) => boolean;
|
|
123
|
-
}): QueryFactory<TParams, TData, TError, TSelected, TPageParam, TCrawlOptions, true>;
|
|
160
|
+
}): QueryFactory<TParams, TData, TError, TSelected, TPageParam, TCrawlOptions, true, TDeps>;
|
|
124
161
|
/**
|
|
125
162
|
* Creates a standalone query factory from a config object.
|
|
126
163
|
*
|
|
@@ -131,24 +168,24 @@ declare function queryFactory<TParams = void, TData = unknown, TError = Error, T
|
|
|
131
168
|
* });
|
|
132
169
|
* // useQuery(usersFactory({ page: 1 }))
|
|
133
170
|
*/
|
|
134
|
-
declare function queryFactory<TParams = void, TData = unknown, TError = Error, TSelected = TData, TPageParam = unknown, TCrawlOptions extends Record<string, unknown> = Record<string, unknown
|
|
171
|
+
declare function queryFactory<TParams = void, TData = unknown, TError = Error, TSelected = TData, TPageParam = unknown, TCrawlOptions extends Record<string, unknown> = Record<string, unknown>, TDeps = void>(config: QueryFactoryConfig<TParams, TData, TError, TSelected, TPageParam, TCrawlOptions, TDeps>): QueryFactory<TParams, TData, TError, TSelected, TPageParam, TCrawlOptions, false, TDeps>;
|
|
135
172
|
/**
|
|
136
173
|
* Creates a child factory whose queryFn returns an AsyncIterable (e.g. an AWS SDK v3
|
|
137
174
|
* paginator). Inherits the parent's key namespace. Use this overload when switching
|
|
138
175
|
* to a paginator-based fetch while keeping the same result shape and crawl options.
|
|
139
176
|
*/
|
|
140
|
-
declare function queryFactory<TChildParams extends TParentParams, TData = unknown, TError = Error, TParentSelected = TData, TChildSelected = TParentSelected, TParentParams = TChildParams, TPageParam = unknown, TCrawlOptions extends Record<string, unknown> = Record<string, unknown
|
|
177
|
+
declare function queryFactory<TChildParams extends TParentParams, TData = unknown, TError = Error, TParentSelected = TData, TChildSelected = TParentSelected, TParentParams = TChildParams, TPageParam = unknown, TCrawlOptions extends Record<string, unknown> = Record<string, unknown>, TDeps = void>(parent: QueryFactory<TParentParams, TData, any, TParentSelected, TPageParam, any, any, any>, config: StandardQueryOptions<TError, TData> & {
|
|
141
178
|
queryKey?: QueryKey;
|
|
142
179
|
queryFn: (params: TChildParams, context: QueryFunctionContext<QueryKey, [
|
|
143
180
|
unknown
|
|
144
|
-
] extends [TPageParam] ? never : TPageParam
|
|
145
|
-
select?: (data: TData) => TChildSelected;
|
|
181
|
+
] extends [TPageParam] ? never : TPageParam>, deps: TDeps) => AsyncIterable<TData>;
|
|
182
|
+
select?: (data: TData, deps: TDeps) => TChildSelected;
|
|
146
183
|
reduce?: (accumulator: TChildSelected | undefined, page: TData) => TChildSelected;
|
|
147
184
|
shouldFetchNextPage?: (combined: TChildSelected | undefined, crawlOptions: TCrawlOptions) => boolean;
|
|
148
185
|
getNextPageParam?: GetNextPageParamFunction<TPageParam, TData>;
|
|
149
186
|
getPreviousPageParam?: GetPreviousPageParamFunction<TPageParam, TData>;
|
|
150
187
|
initialPageParam?: TPageParam;
|
|
151
|
-
}): QueryFactory<TChildParams, TData, TError, TChildSelected, TPageParam, TCrawlOptions, boolean>;
|
|
188
|
+
}): QueryFactory<TChildParams, TData, TError, TChildSelected, TPageParam, TCrawlOptions, boolean, TDeps>;
|
|
152
189
|
/**
|
|
153
190
|
* Creates a child factory that inherits the query key and standard options from
|
|
154
191
|
* `parent` and introduces a new `queryFn`. The child's query key is appended to
|
|
@@ -156,10 +193,10 @@ declare function queryFactory<TChildParams extends TParentParams, TData = unknow
|
|
|
156
193
|
*
|
|
157
194
|
* Use this overload when the child fetches different data than the parent.
|
|
158
195
|
*/
|
|
159
|
-
declare function queryFactory<TChildParams extends TParentParams, TData = unknown, TError = Error, TChildSelected = TData, TParentParams = TChildParams, TPageParam = unknown, TCrawlOptions extends Record<string, unknown> = Record<string, unknown
|
|
196
|
+
declare function queryFactory<TChildParams extends TParentParams, TData = unknown, TError = Error, TChildSelected = TData, TParentParams = TChildParams, TPageParam = unknown, TCrawlOptions extends Record<string, unknown> = Record<string, unknown>, TDeps = void>(parent: QueryFactory<TParentParams, any, any, any, any, any, any, any>, config: Omit<QueryFactoryConfig<TChildParams, TData, TError, TChildSelected, TPageParam, TCrawlOptions, TDeps>, 'queryKey' | 'queryFn'> & {
|
|
160
197
|
queryKey?: QueryKey;
|
|
161
|
-
queryFn: NonNullable<QueryFactoryConfig<TChildParams, TData, TError, TChildSelected, TPageParam>['queryFn']>;
|
|
162
|
-
}): QueryFactory<TChildParams, TData, TError, TChildSelected, TPageParam, TCrawlOptions, boolean>;
|
|
198
|
+
queryFn: NonNullable<QueryFactoryConfig<TChildParams, TData, TError, TChildSelected, TPageParam, TCrawlOptions, TDeps>['queryFn']>;
|
|
199
|
+
}): QueryFactory<TChildParams, TData, TError, TChildSelected, TPageParam, TCrawlOptions, boolean, TDeps>;
|
|
163
200
|
/**
|
|
164
201
|
* Creates a child factory that reuses the parent's `queryFn` and pagination
|
|
165
202
|
* config. Useful for adding a `select` transform, narrowing params, or
|
|
@@ -167,49 +204,49 @@ declare function queryFactory<TChildParams extends TParentParams, TData = unknow
|
|
|
167
204
|
* without changing what data is fetched. Parent and child `select` functions
|
|
168
205
|
* are automatically composed: `child.select(parent.select(data))`.
|
|
169
206
|
*/
|
|
170
|
-
declare function queryFactory<TChildParams extends TParentParams, TData = unknown, TError = Error, TParentSelected = TData, TChildSelected = TParentSelected, TParentParams = TChildParams, TPageParam = unknown, TParentCrawlOptions extends Record<string, unknown> = Record<string, unknown>, TChildCrawlOptions extends Record<string, unknown> = TParentCrawlOptions, TParentHasReduce extends boolean = boolean>(parent: QueryFactory<TParentParams, TData, any, TParentSelected, TPageParam, TParentCrawlOptions, TParentHasReduce>, config: StandardQueryOptions<TError, TData> & {
|
|
207
|
+
declare function queryFactory<TChildParams extends TParentParams, TData = unknown, TError = Error, TParentSelected = TData, TChildSelected = TParentSelected, TParentParams = TChildParams, TPageParam = unknown, TParentCrawlOptions extends Record<string, unknown> = Record<string, unknown>, TChildCrawlOptions extends Record<string, unknown> = TParentCrawlOptions, TParentHasReduce extends boolean = boolean, TParentDeps = void>(parent: QueryFactory<TParentParams, TData, any, TParentSelected, TPageParam, TParentCrawlOptions, TParentHasReduce, TParentDeps>, config: StandardQueryOptions<TError, TData> & {
|
|
171
208
|
queryKey?: QueryKey;
|
|
172
209
|
queryFn?: never;
|
|
173
|
-
select?: (data: TParentSelected) => TChildSelected;
|
|
210
|
+
select?: (data: TParentSelected, deps: TParentDeps) => TChildSelected;
|
|
174
211
|
getNextPageParam?: GetNextPageParamFunction<TPageParam, TData>;
|
|
175
212
|
initialPageParam?: TPageParam;
|
|
176
213
|
getPreviousPageParam?: GetPreviousPageParamFunction<TPageParam, TData>;
|
|
177
214
|
reduce?: (accumulator: TChildSelected | undefined, page: TData) => TChildSelected;
|
|
178
215
|
shouldFetchNextPage?: (combined: TParentHasReduce extends true ? TChildSelected : TChildSelected | undefined, crawlOptions: TChildCrawlOptions) => boolean;
|
|
179
|
-
}): QueryFactory<TChildParams, TData, TError, TChildSelected, TPageParam, TChildCrawlOptions, TParentHasReduce>;
|
|
216
|
+
}): QueryFactory<TChildParams, TData, TError, TChildSelected, TPageParam, TChildCrawlOptions, TParentHasReduce, TParentDeps>;
|
|
180
217
|
/**
|
|
181
218
|
* Creates a standalone factory whose queryFn returns an AsyncIterable (e.g. an AWS SDK v3
|
|
182
219
|
* paginator). The library drives the crawl with `for await...of`; `getNextPageParam` and
|
|
183
220
|
* `initialPageParam` are not required for `useQuery` mode. When `reduce` is present,
|
|
184
221
|
* `shouldFetchNextPage` receives `TSelected` (never undefined).
|
|
185
222
|
*/
|
|
186
|
-
declare function queryFactory<TParams = void, TData = unknown, TError = Error, TSelected = TData, TPageParam = unknown, TCrawlOptions extends Record<string, unknown> = Record<string, unknown
|
|
223
|
+
declare function queryFactory<TParams = void, TData = unknown, TError = Error, TSelected = TData, TPageParam = unknown, TCrawlOptions extends Record<string, unknown> = Record<string, unknown>, TDeps = void>(config: StandardQueryOptions<TError, TData> & {
|
|
187
224
|
queryKey: QueryKey;
|
|
188
225
|
queryFn: (params: TParams, context: QueryFunctionContext<QueryKey, [
|
|
189
226
|
unknown
|
|
190
|
-
] extends [TPageParam] ? never : TPageParam
|
|
191
|
-
select?: (data: TData) => TSelected;
|
|
227
|
+
] extends [TPageParam] ? never : TPageParam>, deps: TDeps) => AsyncIterable<TData>;
|
|
228
|
+
select?: (data: TData, deps: TDeps) => TSelected;
|
|
192
229
|
getNextPageParam?: GetNextPageParamFunction<TPageParam, TData>;
|
|
193
230
|
initialPageParam?: TPageParam;
|
|
194
231
|
getPreviousPageParam?: GetPreviousPageParamFunction<TPageParam, TData>;
|
|
195
232
|
reduce: (accumulator: TSelected | undefined, page: TData) => TSelected;
|
|
196
233
|
shouldFetchNextPage?: (combined: TSelected, crawlOptions: TCrawlOptions) => boolean;
|
|
197
|
-
}): QueryFactory<TParams, TData, TError, TSelected, TPageParam, TCrawlOptions, true>;
|
|
234
|
+
}): QueryFactory<TParams, TData, TError, TSelected, TPageParam, TCrawlOptions, true, TDeps>;
|
|
198
235
|
/**
|
|
199
236
|
* Creates a standalone factory whose queryFn returns an AsyncIterable, without a `reduce`
|
|
200
237
|
* function. Result is `TData[]` (one element per yielded page).
|
|
201
238
|
*/
|
|
202
|
-
declare function queryFactory<TParams = void, TData = unknown, TError = Error, TSelected = TData, TPageParam = unknown, TCrawlOptions extends Record<string, unknown> = Record<string, unknown
|
|
239
|
+
declare function queryFactory<TParams = void, TData = unknown, TError = Error, TSelected = TData, TPageParam = unknown, TCrawlOptions extends Record<string, unknown> = Record<string, unknown>, TDeps = void>(config: StandardQueryOptions<TError, TData> & {
|
|
203
240
|
queryKey: QueryKey;
|
|
204
241
|
queryFn: (params: TParams, context: QueryFunctionContext<QueryKey, [
|
|
205
242
|
unknown
|
|
206
|
-
] extends [TPageParam] ? never : TPageParam
|
|
207
|
-
select?: (data: TData) => TSelected;
|
|
243
|
+
] extends [TPageParam] ? never : TPageParam>, deps: TDeps) => AsyncIterable<TData>;
|
|
244
|
+
select?: (data: TData, deps: TDeps) => TSelected;
|
|
208
245
|
getNextPageParam?: GetNextPageParamFunction<TPageParam, TData>;
|
|
209
246
|
initialPageParam?: TPageParam;
|
|
210
247
|
getPreviousPageParam?: GetPreviousPageParamFunction<TPageParam, TData>;
|
|
211
248
|
reduce?: never;
|
|
212
249
|
shouldFetchNextPage: (combined: TSelected | undefined, crawlOptions: TCrawlOptions) => boolean;
|
|
213
|
-
}): QueryFactory<TParams, TData, TError, TSelected, TPageParam, TCrawlOptions, false>;
|
|
250
|
+
}): QueryFactory<TParams, TData, TError, TSelected, TPageParam, TCrawlOptions, false, TDeps>;
|
|
214
251
|
|
|
215
|
-
export { type FactoryCrawlOptions, type FactoryParams, type QueryFactory, type QueryFactoryConfig, type ResolvedInfiniteOptions, type ResolvedQueryOptions, type StandardQueryOptions, queryFactory };
|
|
252
|
+
export { type FactoryCrawlOptions, type FactoryDeps, type FactoryParams, type PendingInjection, type QueryFactory, type QueryFactoryConfig, type ResolvedInfiniteOptions, type ResolvedQueryOptions, type StandardQueryOptions, type WithInjection, queryFactory };
|
package/dist/index.js
CHANGED
|
@@ -31,6 +31,9 @@ var noNextPage = () => void 0;
|
|
|
31
31
|
function isAsyncIterable(value) {
|
|
32
32
|
return value != null && typeof value[Symbol.asyncIterator] === "function";
|
|
33
33
|
}
|
|
34
|
+
function invokeQueryFn(queryFn, params, ctx, deps) {
|
|
35
|
+
return deps === void 0 ? queryFn(params, ctx) : queryFn(params, ctx, deps);
|
|
36
|
+
}
|
|
34
37
|
function resolveKey(namespace, params, crawlOptions) {
|
|
35
38
|
const withParams = params === void 0 ? namespace : [...namespace, params];
|
|
36
39
|
if (!crawlOptions) return withParams;
|
|
@@ -55,22 +58,22 @@ function buildChildKey(parentKey, ownSegments, params, crawlOptions, infinite) {
|
|
|
55
58
|
const withInfinite = infinite ? [...withOwn, "infinite"] : withOwn;
|
|
56
59
|
return defined ? [...withInfinite, defined] : withInfinite;
|
|
57
60
|
}
|
|
58
|
-
function wrapGetNextPageParam(getNextPageParam, shouldFetchNextPage, crawlOptions, select) {
|
|
61
|
+
function wrapGetNextPageParam(getNextPageParam, shouldFetchNextPage, crawlOptions, select, deps) {
|
|
59
62
|
return (lastPage, allPages, lastPageParam, allPageParams) => {
|
|
60
|
-
const combined = select ? select(lastPage) : lastPage;
|
|
63
|
+
const combined = select ? select(lastPage, deps) : lastPage;
|
|
61
64
|
if (!shouldFetchNextPage(combined, crawlOptions)) return void 0;
|
|
62
65
|
return getNextPageParam(lastPage, allPages, lastPageParam, allPageParams);
|
|
63
66
|
};
|
|
64
67
|
}
|
|
65
68
|
function buildCrawlingQueryFn(queryFn, getNextPageParam, initialPageParam, shouldFetchNextPage, reduce) {
|
|
66
|
-
return async (params, crawlOptions, context) => {
|
|
69
|
+
return async (params, crawlOptions, deps, context) => {
|
|
67
70
|
var _a, _b, _c;
|
|
68
71
|
if ((_a = context.signal) == null ? void 0 : _a.aborted) {
|
|
69
72
|
if (reduce) throw new DOMException("Aborted", "AbortError");
|
|
70
73
|
return [];
|
|
71
74
|
}
|
|
72
75
|
const ctx = { ...context, pageParam: initialPageParam };
|
|
73
|
-
const initialResult = queryFn
|
|
76
|
+
const initialResult = invokeQueryFn(queryFn, params, ctx, deps);
|
|
74
77
|
if (isAsyncIterable(initialResult)) {
|
|
75
78
|
const pages2 = [];
|
|
76
79
|
let acc2 = void 0;
|
|
@@ -102,7 +105,12 @@ function buildCrawlingQueryFn(queryFn, getNextPageParam, initialPageParam, shoul
|
|
|
102
105
|
if (nextParam == null) break;
|
|
103
106
|
currentParam = nextParam;
|
|
104
107
|
ctx.pageParam = currentParam;
|
|
105
|
-
page = await
|
|
108
|
+
page = await invokeQueryFn(
|
|
109
|
+
queryFn,
|
|
110
|
+
params,
|
|
111
|
+
ctx,
|
|
112
|
+
deps
|
|
113
|
+
);
|
|
106
114
|
}
|
|
107
115
|
if (reduce) {
|
|
108
116
|
if (acc === void 0) throw new DOMException("Aborted", "AbortError");
|
|
@@ -112,9 +120,9 @@ function buildCrawlingQueryFn(queryFn, getNextPageParam, initialPageParam, shoul
|
|
|
112
120
|
};
|
|
113
121
|
}
|
|
114
122
|
function buildAutoConsumeQueryFn(queryFn, reduce) {
|
|
115
|
-
return async (params, context) => {
|
|
123
|
+
return async (params, deps, context) => {
|
|
116
124
|
var _a;
|
|
117
|
-
const result = await queryFn
|
|
125
|
+
const result = await invokeQueryFn(queryFn, params, context, deps);
|
|
118
126
|
if (!isAsyncIterable(result)) return result;
|
|
119
127
|
const pages = [];
|
|
120
128
|
let acc = void 0;
|
|
@@ -127,12 +135,12 @@ function buildAutoConsumeQueryFn(queryFn, reduce) {
|
|
|
127
135
|
};
|
|
128
136
|
}
|
|
129
137
|
function buildInfiniteCrawlingQueryFn(queryFn, getNextPageParam, shouldFetchNextPage, reduce) {
|
|
130
|
-
return async (params, crawlOptions, context) => {
|
|
138
|
+
return async (params, crawlOptions, deps, context) => {
|
|
131
139
|
var _a, _b, _c;
|
|
132
140
|
if ((_a = context.signal) == null ? void 0 : _a.aborted)
|
|
133
141
|
throw new DOMException("Aborted", "AbortError");
|
|
134
142
|
const ctx = { ...context, pageParam: context.pageParam };
|
|
135
|
-
const initialResult = queryFn
|
|
143
|
+
const initialResult = invokeQueryFn(queryFn, params, ctx, deps);
|
|
136
144
|
if (isAsyncIterable(initialResult)) {
|
|
137
145
|
const pages2 = [];
|
|
138
146
|
const startParam = context.pageParam;
|
|
@@ -169,7 +177,12 @@ function buildInfiniteCrawlingQueryFn(queryFn, getNextPageParam, shouldFetchNext
|
|
|
169
177
|
if (!shouldFetchNextPage(acc, crawlOptions)) break;
|
|
170
178
|
currentParam = nextParam;
|
|
171
179
|
ctx.pageParam = currentParam;
|
|
172
|
-
page = await
|
|
180
|
+
page = await invokeQueryFn(
|
|
181
|
+
queryFn,
|
|
182
|
+
params,
|
|
183
|
+
ctx,
|
|
184
|
+
deps
|
|
185
|
+
);
|
|
173
186
|
}
|
|
174
187
|
if (acc === void 0) throw new DOMException("Aborted", "AbortError");
|
|
175
188
|
return { data: acc, nextPageParam: nextBatchParam };
|
|
@@ -206,56 +219,69 @@ function buildFactory(cfg) {
|
|
|
206
219
|
shouldFetchNextPage,
|
|
207
220
|
reduce
|
|
208
221
|
) : void 0;
|
|
209
|
-
const
|
|
210
|
-
...data,
|
|
211
|
-
pages: data.pages.map((e) => select ? select(e.data) : e.data)
|
|
212
|
-
}) : void 0;
|
|
213
|
-
const infiniteSelect = !infiniteCrawlingFn && select ? (data) => ({
|
|
214
|
-
...data,
|
|
215
|
-
pages: data.pages.map(select)
|
|
216
|
-
}) : void 0;
|
|
222
|
+
const bindSelect = (deps) => select === void 0 ? void 0 : deps === void 0 ? select : (data) => select(data, deps);
|
|
217
223
|
const factory = function(params, crawlOptions = {}) {
|
|
218
224
|
const queryKey = parentKey !== void 0 ? buildChildKey(parentKey, ownSegments, params, crawlOptions) : resolveKey(namespace, params, crawlOptions);
|
|
219
|
-
const
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
225
|
+
const make = (deps) => {
|
|
226
|
+
const resolvedQueryFn = crawlingFn ? (ctx) => crawlingFn(params, crawlOptions, deps, ctx) : autoConsumeFn ? (ctx) => autoConsumeFn(params, deps, ctx) : void 0;
|
|
227
|
+
const boundSelect = bindSelect(deps);
|
|
228
|
+
return {
|
|
229
|
+
...standardOptions,
|
|
230
|
+
queryKey,
|
|
231
|
+
...resolvedQueryFn !== void 0 && { queryFn: resolvedQueryFn },
|
|
232
|
+
...boundSelect !== void 0 && { select: boundSelect },
|
|
233
|
+
inject: (injected) => make(injected),
|
|
234
|
+
[FACTORY_CONFIG]: cfg
|
|
235
|
+
};
|
|
226
236
|
};
|
|
237
|
+
return make(void 0);
|
|
227
238
|
};
|
|
228
239
|
factory.infinite = function(params, crawlOptions = {}) {
|
|
229
240
|
const queryKey = parentKey !== void 0 ? buildChildKey(parentKey, ownSegments, params, crawlOptions, true) : resolveKey(infiniteNamespace, params, crawlOptions);
|
|
230
|
-
|
|
241
|
+
const make = (deps) => {
|
|
242
|
+
if (infiniteCrawlingFn) {
|
|
243
|
+
return {
|
|
244
|
+
...standardOptions,
|
|
245
|
+
queryKey,
|
|
246
|
+
queryFn: (ctx) => infiniteCrawlingFn(params, crawlOptions, deps, ctx),
|
|
247
|
+
getNextPageParam: getEnvelopeNextPageParam,
|
|
248
|
+
initialPageParam,
|
|
249
|
+
select: (data) => ({
|
|
250
|
+
...data,
|
|
251
|
+
pages: data.pages.map(
|
|
252
|
+
(e) => select ? select(e.data, deps) : e.data
|
|
253
|
+
)
|
|
254
|
+
}),
|
|
255
|
+
...getPreviousPageParam !== void 0 && { getPreviousPageParam },
|
|
256
|
+
inject: (injected) => make(injected),
|
|
257
|
+
[FACTORY_CONFIG]: cfg
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
const boundQueryFn = rawQueryFn ? (ctx) => invokeQueryFn(rawQueryFn, params, ctx, deps) : void 0;
|
|
261
|
+
const infiniteSelect = select ? (data) => ({
|
|
262
|
+
...data,
|
|
263
|
+
pages: data.pages.map((p) => select(p, deps))
|
|
264
|
+
}) : void 0;
|
|
265
|
+
const infiniteGetNextPageParam = getNextPageParam && shouldFetchNextPage ? wrapGetNextPageParam(
|
|
266
|
+
getNextPageParam,
|
|
267
|
+
shouldFetchNextPage,
|
|
268
|
+
crawlOptions,
|
|
269
|
+
select,
|
|
270
|
+
deps
|
|
271
|
+
) : getNextPageParam != null ? getNextPageParam : noNextPage;
|
|
231
272
|
return {
|
|
232
273
|
...standardOptions,
|
|
233
274
|
queryKey,
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
select: envelopeSelect,
|
|
275
|
+
...boundQueryFn !== void 0 && { queryFn: boundQueryFn },
|
|
276
|
+
...infiniteSelect !== void 0 && { select: infiniteSelect },
|
|
277
|
+
getNextPageParam: infiniteGetNextPageParam,
|
|
238
278
|
...getPreviousPageParam !== void 0 && { getPreviousPageParam },
|
|
279
|
+
...initialPageParam !== void 0 && { initialPageParam },
|
|
280
|
+
inject: (injected) => make(injected),
|
|
239
281
|
[FACTORY_CONFIG]: cfg
|
|
240
282
|
};
|
|
241
|
-
}
|
|
242
|
-
const boundQueryFn = rawQueryFn ? (ctx) => rawQueryFn(params, ctx) : void 0;
|
|
243
|
-
const infiniteGetNextPageParam = getNextPageParam && shouldFetchNextPage ? wrapGetNextPageParam(
|
|
244
|
-
getNextPageParam,
|
|
245
|
-
shouldFetchNextPage,
|
|
246
|
-
crawlOptions,
|
|
247
|
-
select
|
|
248
|
-
) : getNextPageParam != null ? getNextPageParam : noNextPage;
|
|
249
|
-
return {
|
|
250
|
-
...standardOptions,
|
|
251
|
-
queryKey,
|
|
252
|
-
...boundQueryFn !== void 0 && { queryFn: boundQueryFn },
|
|
253
|
-
...infiniteSelect !== void 0 && { select: infiniteSelect },
|
|
254
|
-
getNextPageParam: infiniteGetNextPageParam,
|
|
255
|
-
...getPreviousPageParam !== void 0 && { getPreviousPageParam },
|
|
256
|
-
...initialPageParam !== void 0 && { initialPageParam },
|
|
257
|
-
[FACTORY_CONFIG]: cfg
|
|
258
283
|
};
|
|
284
|
+
return make(void 0);
|
|
259
285
|
};
|
|
260
286
|
return factory;
|
|
261
287
|
}
|
|
@@ -281,7 +307,7 @@ function queryFactory(configOrParent, childConfig) {
|
|
|
281
307
|
} else if (childConfig.select && parentCfg.select) {
|
|
282
308
|
const p = parentCfg.select;
|
|
283
309
|
const c = childConfig.select;
|
|
284
|
-
resolvedSelect = (data) => c(p(data));
|
|
310
|
+
resolvedSelect = (data, deps) => c(p(data, deps), deps);
|
|
285
311
|
} else {
|
|
286
312
|
resolvedSelect = (_a = childConfig.select) != null ? _a : parentCfg.select;
|
|
287
313
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -5,6 +5,9 @@ var noNextPage = () => void 0;
|
|
|
5
5
|
function isAsyncIterable(value) {
|
|
6
6
|
return value != null && typeof value[Symbol.asyncIterator] === "function";
|
|
7
7
|
}
|
|
8
|
+
function invokeQueryFn(queryFn, params, ctx, deps) {
|
|
9
|
+
return deps === void 0 ? queryFn(params, ctx) : queryFn(params, ctx, deps);
|
|
10
|
+
}
|
|
8
11
|
function resolveKey(namespace, params, crawlOptions) {
|
|
9
12
|
const withParams = params === void 0 ? namespace : [...namespace, params];
|
|
10
13
|
if (!crawlOptions) return withParams;
|
|
@@ -29,22 +32,22 @@ function buildChildKey(parentKey, ownSegments, params, crawlOptions, infinite) {
|
|
|
29
32
|
const withInfinite = infinite ? [...withOwn, "infinite"] : withOwn;
|
|
30
33
|
return defined ? [...withInfinite, defined] : withInfinite;
|
|
31
34
|
}
|
|
32
|
-
function wrapGetNextPageParam(getNextPageParam, shouldFetchNextPage, crawlOptions, select) {
|
|
35
|
+
function wrapGetNextPageParam(getNextPageParam, shouldFetchNextPage, crawlOptions, select, deps) {
|
|
33
36
|
return (lastPage, allPages, lastPageParam, allPageParams) => {
|
|
34
|
-
const combined = select ? select(lastPage) : lastPage;
|
|
37
|
+
const combined = select ? select(lastPage, deps) : lastPage;
|
|
35
38
|
if (!shouldFetchNextPage(combined, crawlOptions)) return void 0;
|
|
36
39
|
return getNextPageParam(lastPage, allPages, lastPageParam, allPageParams);
|
|
37
40
|
};
|
|
38
41
|
}
|
|
39
42
|
function buildCrawlingQueryFn(queryFn, getNextPageParam, initialPageParam, shouldFetchNextPage, reduce) {
|
|
40
|
-
return async (params, crawlOptions, context) => {
|
|
43
|
+
return async (params, crawlOptions, deps, context) => {
|
|
41
44
|
var _a, _b, _c;
|
|
42
45
|
if ((_a = context.signal) == null ? void 0 : _a.aborted) {
|
|
43
46
|
if (reduce) throw new DOMException("Aborted", "AbortError");
|
|
44
47
|
return [];
|
|
45
48
|
}
|
|
46
49
|
const ctx = { ...context, pageParam: initialPageParam };
|
|
47
|
-
const initialResult = queryFn
|
|
50
|
+
const initialResult = invokeQueryFn(queryFn, params, ctx, deps);
|
|
48
51
|
if (isAsyncIterable(initialResult)) {
|
|
49
52
|
const pages2 = [];
|
|
50
53
|
let acc2 = void 0;
|
|
@@ -76,7 +79,12 @@ function buildCrawlingQueryFn(queryFn, getNextPageParam, initialPageParam, shoul
|
|
|
76
79
|
if (nextParam == null) break;
|
|
77
80
|
currentParam = nextParam;
|
|
78
81
|
ctx.pageParam = currentParam;
|
|
79
|
-
page = await
|
|
82
|
+
page = await invokeQueryFn(
|
|
83
|
+
queryFn,
|
|
84
|
+
params,
|
|
85
|
+
ctx,
|
|
86
|
+
deps
|
|
87
|
+
);
|
|
80
88
|
}
|
|
81
89
|
if (reduce) {
|
|
82
90
|
if (acc === void 0) throw new DOMException("Aborted", "AbortError");
|
|
@@ -86,9 +94,9 @@ function buildCrawlingQueryFn(queryFn, getNextPageParam, initialPageParam, shoul
|
|
|
86
94
|
};
|
|
87
95
|
}
|
|
88
96
|
function buildAutoConsumeQueryFn(queryFn, reduce) {
|
|
89
|
-
return async (params, context) => {
|
|
97
|
+
return async (params, deps, context) => {
|
|
90
98
|
var _a;
|
|
91
|
-
const result = await queryFn
|
|
99
|
+
const result = await invokeQueryFn(queryFn, params, context, deps);
|
|
92
100
|
if (!isAsyncIterable(result)) return result;
|
|
93
101
|
const pages = [];
|
|
94
102
|
let acc = void 0;
|
|
@@ -101,12 +109,12 @@ function buildAutoConsumeQueryFn(queryFn, reduce) {
|
|
|
101
109
|
};
|
|
102
110
|
}
|
|
103
111
|
function buildInfiniteCrawlingQueryFn(queryFn, getNextPageParam, shouldFetchNextPage, reduce) {
|
|
104
|
-
return async (params, crawlOptions, context) => {
|
|
112
|
+
return async (params, crawlOptions, deps, context) => {
|
|
105
113
|
var _a, _b, _c;
|
|
106
114
|
if ((_a = context.signal) == null ? void 0 : _a.aborted)
|
|
107
115
|
throw new DOMException("Aborted", "AbortError");
|
|
108
116
|
const ctx = { ...context, pageParam: context.pageParam };
|
|
109
|
-
const initialResult = queryFn
|
|
117
|
+
const initialResult = invokeQueryFn(queryFn, params, ctx, deps);
|
|
110
118
|
if (isAsyncIterable(initialResult)) {
|
|
111
119
|
const pages2 = [];
|
|
112
120
|
const startParam = context.pageParam;
|
|
@@ -143,7 +151,12 @@ function buildInfiniteCrawlingQueryFn(queryFn, getNextPageParam, shouldFetchNext
|
|
|
143
151
|
if (!shouldFetchNextPage(acc, crawlOptions)) break;
|
|
144
152
|
currentParam = nextParam;
|
|
145
153
|
ctx.pageParam = currentParam;
|
|
146
|
-
page = await
|
|
154
|
+
page = await invokeQueryFn(
|
|
155
|
+
queryFn,
|
|
156
|
+
params,
|
|
157
|
+
ctx,
|
|
158
|
+
deps
|
|
159
|
+
);
|
|
147
160
|
}
|
|
148
161
|
if (acc === void 0) throw new DOMException("Aborted", "AbortError");
|
|
149
162
|
return { data: acc, nextPageParam: nextBatchParam };
|
|
@@ -180,56 +193,69 @@ function buildFactory(cfg) {
|
|
|
180
193
|
shouldFetchNextPage,
|
|
181
194
|
reduce
|
|
182
195
|
) : void 0;
|
|
183
|
-
const
|
|
184
|
-
...data,
|
|
185
|
-
pages: data.pages.map((e) => select ? select(e.data) : e.data)
|
|
186
|
-
}) : void 0;
|
|
187
|
-
const infiniteSelect = !infiniteCrawlingFn && select ? (data) => ({
|
|
188
|
-
...data,
|
|
189
|
-
pages: data.pages.map(select)
|
|
190
|
-
}) : void 0;
|
|
196
|
+
const bindSelect = (deps) => select === void 0 ? void 0 : deps === void 0 ? select : (data) => select(data, deps);
|
|
191
197
|
const factory = function(params, crawlOptions = {}) {
|
|
192
198
|
const queryKey = parentKey !== void 0 ? buildChildKey(parentKey, ownSegments, params, crawlOptions) : resolveKey(namespace, params, crawlOptions);
|
|
193
|
-
const
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
199
|
+
const make = (deps) => {
|
|
200
|
+
const resolvedQueryFn = crawlingFn ? (ctx) => crawlingFn(params, crawlOptions, deps, ctx) : autoConsumeFn ? (ctx) => autoConsumeFn(params, deps, ctx) : void 0;
|
|
201
|
+
const boundSelect = bindSelect(deps);
|
|
202
|
+
return {
|
|
203
|
+
...standardOptions,
|
|
204
|
+
queryKey,
|
|
205
|
+
...resolvedQueryFn !== void 0 && { queryFn: resolvedQueryFn },
|
|
206
|
+
...boundSelect !== void 0 && { select: boundSelect },
|
|
207
|
+
inject: (injected) => make(injected),
|
|
208
|
+
[FACTORY_CONFIG]: cfg
|
|
209
|
+
};
|
|
200
210
|
};
|
|
211
|
+
return make(void 0);
|
|
201
212
|
};
|
|
202
213
|
factory.infinite = function(params, crawlOptions = {}) {
|
|
203
214
|
const queryKey = parentKey !== void 0 ? buildChildKey(parentKey, ownSegments, params, crawlOptions, true) : resolveKey(infiniteNamespace, params, crawlOptions);
|
|
204
|
-
|
|
215
|
+
const make = (deps) => {
|
|
216
|
+
if (infiniteCrawlingFn) {
|
|
217
|
+
return {
|
|
218
|
+
...standardOptions,
|
|
219
|
+
queryKey,
|
|
220
|
+
queryFn: (ctx) => infiniteCrawlingFn(params, crawlOptions, deps, ctx),
|
|
221
|
+
getNextPageParam: getEnvelopeNextPageParam,
|
|
222
|
+
initialPageParam,
|
|
223
|
+
select: (data) => ({
|
|
224
|
+
...data,
|
|
225
|
+
pages: data.pages.map(
|
|
226
|
+
(e) => select ? select(e.data, deps) : e.data
|
|
227
|
+
)
|
|
228
|
+
}),
|
|
229
|
+
...getPreviousPageParam !== void 0 && { getPreviousPageParam },
|
|
230
|
+
inject: (injected) => make(injected),
|
|
231
|
+
[FACTORY_CONFIG]: cfg
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
const boundQueryFn = rawQueryFn ? (ctx) => invokeQueryFn(rawQueryFn, params, ctx, deps) : void 0;
|
|
235
|
+
const infiniteSelect = select ? (data) => ({
|
|
236
|
+
...data,
|
|
237
|
+
pages: data.pages.map((p) => select(p, deps))
|
|
238
|
+
}) : void 0;
|
|
239
|
+
const infiniteGetNextPageParam = getNextPageParam && shouldFetchNextPage ? wrapGetNextPageParam(
|
|
240
|
+
getNextPageParam,
|
|
241
|
+
shouldFetchNextPage,
|
|
242
|
+
crawlOptions,
|
|
243
|
+
select,
|
|
244
|
+
deps
|
|
245
|
+
) : getNextPageParam != null ? getNextPageParam : noNextPage;
|
|
205
246
|
return {
|
|
206
247
|
...standardOptions,
|
|
207
248
|
queryKey,
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
select: envelopeSelect,
|
|
249
|
+
...boundQueryFn !== void 0 && { queryFn: boundQueryFn },
|
|
250
|
+
...infiniteSelect !== void 0 && { select: infiniteSelect },
|
|
251
|
+
getNextPageParam: infiniteGetNextPageParam,
|
|
212
252
|
...getPreviousPageParam !== void 0 && { getPreviousPageParam },
|
|
253
|
+
...initialPageParam !== void 0 && { initialPageParam },
|
|
254
|
+
inject: (injected) => make(injected),
|
|
213
255
|
[FACTORY_CONFIG]: cfg
|
|
214
256
|
};
|
|
215
|
-
}
|
|
216
|
-
const boundQueryFn = rawQueryFn ? (ctx) => rawQueryFn(params, ctx) : void 0;
|
|
217
|
-
const infiniteGetNextPageParam = getNextPageParam && shouldFetchNextPage ? wrapGetNextPageParam(
|
|
218
|
-
getNextPageParam,
|
|
219
|
-
shouldFetchNextPage,
|
|
220
|
-
crawlOptions,
|
|
221
|
-
select
|
|
222
|
-
) : getNextPageParam != null ? getNextPageParam : noNextPage;
|
|
223
|
-
return {
|
|
224
|
-
...standardOptions,
|
|
225
|
-
queryKey,
|
|
226
|
-
...boundQueryFn !== void 0 && { queryFn: boundQueryFn },
|
|
227
|
-
...infiniteSelect !== void 0 && { select: infiniteSelect },
|
|
228
|
-
getNextPageParam: infiniteGetNextPageParam,
|
|
229
|
-
...getPreviousPageParam !== void 0 && { getPreviousPageParam },
|
|
230
|
-
...initialPageParam !== void 0 && { initialPageParam },
|
|
231
|
-
[FACTORY_CONFIG]: cfg
|
|
232
257
|
};
|
|
258
|
+
return make(void 0);
|
|
233
259
|
};
|
|
234
260
|
return factory;
|
|
235
261
|
}
|
|
@@ -255,7 +281,7 @@ function queryFactory(configOrParent, childConfig) {
|
|
|
255
281
|
} else if (childConfig.select && parentCfg.select) {
|
|
256
282
|
const p = parentCfg.select;
|
|
257
283
|
const c = childConfig.select;
|
|
258
|
-
resolvedSelect = (data) => c(p(data));
|
|
284
|
+
resolvedSelect = (data, deps) => c(p(data, deps), deps);
|
|
259
285
|
} else {
|
|
260
286
|
resolvedSelect = (_a = childConfig.select) != null ? _a : parentCfg.select;
|
|
261
287
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@robohall/react-query-factory",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "A factory abstraction for TanStack Query (React Query) with composable keys, crawling support, and automatic infinite query generation",
|
|
5
5
|
"author": "Robert Hall",
|
|
6
6
|
"license": "MIT",
|