@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 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 | Notes |
462
- | ----------------------------------- | ------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
463
- | `queryKey` | `QueryKey` | Namespace segments. Params are appended at call time. |
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. Composed automatically on child factories. |
466
- | `getNextPageParam` | `GetNextPageParamFunction<TPageParam, TData>` | Exact TanStack API. Required (with `shouldFetchNextPage`) to activate cursor-based crawling. Required (with `initialPageParam`) for `.infinite()`. |
467
- | `initialPageParam` | `TPageParam` | Exact TanStack API. Drives `TPageParam` inference. Required for `.infinite()` to work at runtime. |
468
- | `getPreviousPageParam` | `GetPreviousPageParamFunction<TPageParam, TData>` | Exact TanStack API. Passed through on `.infinite()`. |
469
- | `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. |
470
- | `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[]`). |
471
- | + all `StandardQueryOptions` fields | | `staleTime`, `gcTime`, `retry`, `enabled`, `refetchOnWindowFocus`, `placeholderData`, `initialData`, `meta`, etc. Function-form callbacks are supported wherever TanStack accepts them. |
472
-
473
- ### `QueryFactory<TParams, TData, TError, TSelected, TPageParam, TCrawlOptions>`
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 { QueryObserverOptions, QueryKey, QueryFunctionContext, InfiniteData, GetNextPageParamFunction, GetPreviousPageParamFunction } from '@tanstack/react-query';
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>> = StandardQueryOptions<TError, TData> & {
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>) => TData | Promise<TData>;
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>>(config: StandardQueryOptions<TError, TData> & {
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>) => TData | Promise<TData>;
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>>(config: QueryFactoryConfig<TParams, TData, TError, TSelected, TPageParam, TCrawlOptions>): QueryFactory<TParams, TData, TError, TSelected, TPageParam, TCrawlOptions, false>;
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>>(parent: QueryFactory<TParentParams, TData, any, TParentSelected, TPageParam, any, any>, config: StandardQueryOptions<TError, TData> & {
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>) => AsyncIterable<TData>;
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>>(parent: QueryFactory<TParentParams, any, any, any, any, any, any>, config: Omit<QueryFactoryConfig<TChildParams, TData, TError, TChildSelected, TPageParam, TCrawlOptions>, 'queryKey' | 'queryFn'> & {
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>>(config: StandardQueryOptions<TError, TData> & {
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>) => AsyncIterable<TData>;
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>>(config: StandardQueryOptions<TError, TData> & {
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>) => AsyncIterable<TData>;
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 { QueryObserverOptions, QueryKey, QueryFunctionContext, InfiniteData, GetNextPageParamFunction, GetPreviousPageParamFunction } from '@tanstack/react-query';
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>> = StandardQueryOptions<TError, TData> & {
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>) => TData | Promise<TData>;
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>>(config: StandardQueryOptions<TError, TData> & {
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>) => TData | Promise<TData>;
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>>(config: QueryFactoryConfig<TParams, TData, TError, TSelected, TPageParam, TCrawlOptions>): QueryFactory<TParams, TData, TError, TSelected, TPageParam, TCrawlOptions, false>;
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>>(parent: QueryFactory<TParentParams, TData, any, TParentSelected, TPageParam, any, any>, config: StandardQueryOptions<TError, TData> & {
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>) => AsyncIterable<TData>;
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>>(parent: QueryFactory<TParentParams, any, any, any, any, any, any>, config: Omit<QueryFactoryConfig<TChildParams, TData, TError, TChildSelected, TPageParam, TCrawlOptions>, 'queryKey' | 'queryFn'> & {
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>>(config: StandardQueryOptions<TError, TData> & {
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>) => AsyncIterable<TData>;
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>>(config: StandardQueryOptions<TError, TData> & {
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>) => AsyncIterable<TData>;
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(params, ctx);
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 queryFn(params, ctx);
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(params, context);
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(params, ctx);
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 queryFn(params, ctx);
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 envelopeSelect = infiniteCrawlingFn ? (data) => ({
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 resolvedQueryFn = crawlingFn ? (ctx) => crawlingFn(params, crawlOptions, ctx) : autoConsumeFn ? (ctx) => autoConsumeFn(params, ctx) : void 0;
220
- return {
221
- ...standardOptions,
222
- queryKey,
223
- ...resolvedQueryFn !== void 0 && { queryFn: resolvedQueryFn },
224
- ...select !== void 0 && { select },
225
- [FACTORY_CONFIG]: cfg
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
- if (infiniteCrawlingFn) {
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
- queryFn: (ctx) => infiniteCrawlingFn(params, crawlOptions, ctx),
235
- getNextPageParam: getEnvelopeNextPageParam,
236
- initialPageParam,
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(params, ctx);
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 queryFn(params, ctx);
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(params, context);
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(params, ctx);
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 queryFn(params, ctx);
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 envelopeSelect = infiniteCrawlingFn ? (data) => ({
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 resolvedQueryFn = crawlingFn ? (ctx) => crawlingFn(params, crawlOptions, ctx) : autoConsumeFn ? (ctx) => autoConsumeFn(params, ctx) : void 0;
194
- return {
195
- ...standardOptions,
196
- queryKey,
197
- ...resolvedQueryFn !== void 0 && { queryFn: resolvedQueryFn },
198
- ...select !== void 0 && { select },
199
- [FACTORY_CONFIG]: cfg
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
- if (infiniteCrawlingFn) {
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
- queryFn: (ctx) => infiniteCrawlingFn(params, crawlOptions, ctx),
209
- getNextPageParam: getEnvelopeNextPageParam,
210
- initialPageParam,
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": "2.2.1",
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",