@ic-reactor/react 3.12.5 → 4.0.0-beta.1

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.
Files changed (139) hide show
  1. package/README.md +236 -423
  2. package/dist/index.d.ts +259 -12
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +470 -17
  5. package/dist/index.js.map +1 -1
  6. package/llms.txt +82 -54
  7. package/package.json +12 -28
  8. package/src/index.tsx +611 -0
  9. package/dist/auth/authentication-manager.d.ts +0 -123
  10. package/dist/auth/authentication-manager.d.ts.map +0 -1
  11. package/dist/auth/authentication-manager.js +0 -767
  12. package/dist/auth/authentication-manager.js.map +0 -1
  13. package/dist/auth/constants.d.ts +0 -24
  14. package/dist/auth/constants.d.ts.map +0 -1
  15. package/dist/auth/constants.js +0 -24
  16. package/dist/auth/constants.js.map +0 -1
  17. package/dist/auth/createIdentityAttributeHooks.d.ts +0 -14
  18. package/dist/auth/createIdentityAttributeHooks.d.ts.map +0 -1
  19. package/dist/auth/createIdentityAttributeHooks.js +0 -106
  20. package/dist/auth/createIdentityAttributeHooks.js.map +0 -1
  21. package/dist/auth/identity-attributes-manager.d.ts +0 -26
  22. package/dist/auth/identity-attributes-manager.d.ts.map +0 -1
  23. package/dist/auth/identity-attributes-manager.js +0 -107
  24. package/dist/auth/identity-attributes-manager.js.map +0 -1
  25. package/dist/auth/identity-attributes.d.ts +0 -19
  26. package/dist/auth/identity-attributes.d.ts.map +0 -1
  27. package/dist/auth/identity-attributes.js +0 -170
  28. package/dist/auth/identity-attributes.js.map +0 -1
  29. package/dist/auth/index.d.ts +0 -8
  30. package/dist/auth/index.d.ts.map +0 -1
  31. package/dist/auth/index.js +0 -8
  32. package/dist/auth/index.js.map +0 -1
  33. package/dist/auth/local-ii-probe.d.ts +0 -46
  34. package/dist/auth/local-ii-probe.d.ts.map +0 -1
  35. package/dist/auth/local-ii-probe.js +0 -102
  36. package/dist/auth/local-ii-probe.js.map +0 -1
  37. package/dist/auth/types.d.ts +0 -179
  38. package/dist/auth/types.d.ts.map +0 -1
  39. package/dist/auth/types.js +0 -2
  40. package/dist/auth/types.js.map +0 -1
  41. package/dist/createActorHooks.d.ts +0 -52
  42. package/dist/createActorHooks.d.ts.map +0 -1
  43. package/dist/createActorHooks.js +0 -17
  44. package/dist/createActorHooks.js.map +0 -1
  45. package/dist/createInfiniteQuery.d.ts +0 -144
  46. package/dist/createInfiniteQuery.d.ts.map +0 -1
  47. package/dist/createInfiniteQuery.js +0 -174
  48. package/dist/createInfiniteQuery.js.map +0 -1
  49. package/dist/createMutation.d.ts +0 -30
  50. package/dist/createMutation.d.ts.map +0 -1
  51. package/dist/createMutation.js +0 -192
  52. package/dist/createMutation.js.map +0 -1
  53. package/dist/createQuery.d.ts +0 -30
  54. package/dist/createQuery.d.ts.map +0 -1
  55. package/dist/createQuery.js +0 -117
  56. package/dist/createQuery.js.map +0 -1
  57. package/dist/createSuspenseInfiniteQuery.d.ts +0 -147
  58. package/dist/createSuspenseInfiniteQuery.d.ts.map +0 -1
  59. package/dist/createSuspenseInfiniteQuery.js +0 -177
  60. package/dist/createSuspenseInfiniteQuery.js.map +0 -1
  61. package/dist/createSuspenseQuery.d.ts +0 -25
  62. package/dist/createSuspenseQuery.d.ts.map +0 -1
  63. package/dist/createSuspenseQuery.js +0 -111
  64. package/dist/createSuspenseQuery.js.map +0 -1
  65. package/dist/defineReactor.d.ts +0 -125
  66. package/dist/defineReactor.d.ts.map +0 -1
  67. package/dist/defineReactor.js +0 -180
  68. package/dist/defineReactor.js.map +0 -1
  69. package/dist/hooks/createAuthHooks.d.ts +0 -43
  70. package/dist/hooks/createAuthHooks.d.ts.map +0 -1
  71. package/dist/hooks/createAuthHooks.js +0 -131
  72. package/dist/hooks/createAuthHooks.js.map +0 -1
  73. package/dist/hooks/index.d.ts +0 -21
  74. package/dist/hooks/index.d.ts.map +0 -1
  75. package/dist/hooks/index.js +0 -24
  76. package/dist/hooks/index.js.map +0 -1
  77. package/dist/hooks/useActorInfiniteQuery.d.ts +0 -39
  78. package/dist/hooks/useActorInfiniteQuery.d.ts.map +0 -1
  79. package/dist/hooks/useActorInfiniteQuery.js +0 -56
  80. package/dist/hooks/useActorInfiniteQuery.js.map +0 -1
  81. package/dist/hooks/useActorMethod.d.ts +0 -115
  82. package/dist/hooks/useActorMethod.d.ts.map +0 -1
  83. package/dist/hooks/useActorMethod.js +0 -250
  84. package/dist/hooks/useActorMethod.js.map +0 -1
  85. package/dist/hooks/useActorMutation.d.ts +0 -48
  86. package/dist/hooks/useActorMutation.d.ts.map +0 -1
  87. package/dist/hooks/useActorMutation.js +0 -69
  88. package/dist/hooks/useActorMutation.js.map +0 -1
  89. package/dist/hooks/useActorQuery.d.ts +0 -32
  90. package/dist/hooks/useActorQuery.d.ts.map +0 -1
  91. package/dist/hooks/useActorQuery.js +0 -46
  92. package/dist/hooks/useActorQuery.js.map +0 -1
  93. package/dist/hooks/useActorSuspenseInfiniteQuery.d.ts +0 -39
  94. package/dist/hooks/useActorSuspenseInfiniteQuery.d.ts.map +0 -1
  95. package/dist/hooks/useActorSuspenseInfiniteQuery.js +0 -56
  96. package/dist/hooks/useActorSuspenseInfiniteQuery.js.map +0 -1
  97. package/dist/hooks/useActorSuspenseQuery.d.ts +0 -32
  98. package/dist/hooks/useActorSuspenseQuery.d.ts.map +0 -1
  99. package/dist/hooks/useActorSuspenseQuery.js +0 -47
  100. package/dist/hooks/useActorSuspenseQuery.js.map +0 -1
  101. package/dist/types.d.ts +0 -270
  102. package/dist/types.d.ts.map +0 -1
  103. package/dist/types.js +0 -5
  104. package/dist/types.js.map +0 -1
  105. package/dist/utils.d.ts +0 -51
  106. package/dist/utils.d.ts.map +0 -1
  107. package/dist/utils.js +0 -105
  108. package/dist/utils.js.map +0 -1
  109. package/dist/validation.d.ts +0 -131
  110. package/dist/validation.d.ts.map +0 -1
  111. package/dist/validation.js +0 -125
  112. package/dist/validation.js.map +0 -1
  113. package/src/auth/authentication-manager.ts +0 -860
  114. package/src/auth/constants.ts +0 -32
  115. package/src/auth/createIdentityAttributeHooks.ts +0 -143
  116. package/src/auth/identity-attributes-manager.ts +0 -131
  117. package/src/auth/identity-attributes.ts +0 -270
  118. package/src/auth/index.ts +0 -7
  119. package/src/auth/local-ii-probe.ts +0 -147
  120. package/src/auth/types.ts +0 -200
  121. package/src/createActorHooks.ts +0 -220
  122. package/src/createInfiniteQuery.ts +0 -578
  123. package/src/createMutation.ts +0 -341
  124. package/src/createQuery.ts +0 -237
  125. package/src/createSuspenseInfiniteQuery.ts +0 -601
  126. package/src/createSuspenseQuery.ts +0 -234
  127. package/src/defineReactor.ts +0 -324
  128. package/src/hooks/createAuthHooks.ts +0 -189
  129. package/src/hooks/index.ts +0 -103
  130. package/src/hooks/useActorInfiniteQuery.ts +0 -205
  131. package/src/hooks/useActorMethod.ts +0 -507
  132. package/src/hooks/useActorMutation.ts +0 -205
  133. package/src/hooks/useActorQuery.ts +0 -124
  134. package/src/hooks/useActorSuspenseInfiniteQuery.ts +0 -205
  135. package/src/hooks/useActorSuspenseQuery.ts +0 -132
  136. package/src/index.ts +0 -23
  137. package/src/types.ts +0 -499
  138. package/src/utils.ts +0 -121
  139. package/src/validation.ts +0 -202
@@ -1,601 +0,0 @@
1
- /**
2
- * Suspense Infinite Query Factory - Generic wrapper for React Query suspense-based paginated canister data
3
- *
4
- * Creates unified fetch/hook/invalidate functions for any paginated canister method.
5
- * Works with any Reactor instance.
6
- *
7
- * Uses `useSuspenseInfiniteQuery` which:
8
- * - Requires wrapping in <Suspense> boundary
9
- * - Data is always defined (no undefined checks)
10
- * - Does NOT support `enabled` or `placeholderData` options
11
- *
12
- * @example
13
- * const postsQuery = createSuspenseInfiniteQuery(reactor, {
14
- * functionName: "get_posts",
15
- * initialPageParam: 0,
16
- * getArgs: (cursor) => [{ cursor, limit: 10 }],
17
- * getNextPageParam: (lastPage) => lastPage.nextCursor,
18
- * })
19
- *
20
- * // In component (wrap in Suspense)
21
- * const { data, fetchNextPage, hasNextPage } = postsQuery.useSuspenseInfiniteQuery()
22
- *
23
- * // Flatten all pages
24
- * const allPosts = data.pages.flatMap(page => page.posts)
25
- */
26
-
27
- import { useMemo } from "react"
28
- import type {
29
- Reactor,
30
- FunctionName,
31
- ReactorArgs,
32
- BaseActor,
33
- TransformKey,
34
- ReactorReturnOk,
35
- ReactorQueryData,
36
- ReactorReturnErr,
37
- } from "@ic-reactor/core"
38
- import {
39
- QueryKey,
40
- useSuspenseInfiniteQuery,
41
- InfiniteData,
42
- UseSuspenseInfiniteQueryResult,
43
- UseSuspenseInfiniteQueryOptions,
44
- QueryFunctionContext,
45
- FetchInfiniteQueryOptions,
46
- InfiniteQueryObserverOptions,
47
- } from "@tanstack/react-query"
48
- import { CallConfig } from "@icp-sdk/core/agent"
49
- import { NoInfer } from "./types.js"
50
- import {
51
- buildChainedSelect,
52
- mergeFactoryQueryKey,
53
- normalizeQueryData,
54
- } from "./utils.js"
55
-
56
- type SuspenseInfiniteFactoryCallOptions = {
57
- queryKey?: QueryKey
58
- }
59
-
60
- type SuspenseInfiniteQueryFactoryFn<
61
- Service,
62
- Method extends FunctionName<Service>,
63
- Transform extends TransformKey,
64
- TPageParam,
65
- Selected,
66
- > = {
67
- (
68
- getArgs: (pageParam: TPageParam) => ReactorArgs<Service, Method, Transform>
69
- ): SuspenseInfiniteQueryResult<
70
- SuspenseInfiniteQueryPageData<Service, Method, Transform>,
71
- TPageParam,
72
- Selected,
73
- SuspenseInfiniteQueryError<Service, Method, Transform>
74
- >
75
- (
76
- getArgs: (pageParam: TPageParam) => ReactorArgs<Service, Method, Transform>,
77
- options?: SuspenseInfiniteFactoryCallOptions
78
- ): SuspenseInfiniteQueryResult<
79
- SuspenseInfiniteQueryPageData<Service, Method, Transform>,
80
- TPageParam,
81
- Selected,
82
- SuspenseInfiniteQueryError<Service, Method, Transform>
83
- >
84
- }
85
-
86
- // ============================================================================
87
- // Type Definitions
88
- // ============================================================================
89
-
90
- /** The raw page data type returned by the query function */
91
- export type SuspenseInfiniteQueryPageData<
92
- Service = BaseActor,
93
- Method extends FunctionName<Service> = FunctionName<Service>,
94
- Transform extends TransformKey = "candid",
95
- > = ReactorQueryData<ReactorReturnOk<Service, Method, Transform>>
96
-
97
- /** The error type for infinite queries */
98
- export type SuspenseInfiniteQueryError<
99
- Service = BaseActor,
100
- Method extends FunctionName<Service> = FunctionName<Service>,
101
- Transform extends TransformKey = "candid",
102
- > = ReactorReturnErr<Service, Method, Transform>
103
-
104
- // ============================================================================
105
- // Configuration Types
106
- // ============================================================================
107
-
108
- /**
109
- * Configuration for createActorSuspenseInfiniteQuery.
110
- * Extends InfiniteQueryObserverOptions to accept all React Query options at the create level.
111
- *
112
- * @template Service - The actor interface type
113
- * @template Method - The method name on the actor
114
- * @template Transform - The transformation key (identity, display, etc.)
115
- * @template TPageParam - The type of the page parameter
116
- * @template Selected - The type returned after select transformation
117
- */
118
- export interface SuspenseInfiniteQueryConfig<
119
- Service = BaseActor,
120
- Method extends FunctionName<Service> = FunctionName<Service>,
121
- Transform extends TransformKey = "candid",
122
- TPageParam = unknown,
123
- Selected = InfiniteData<
124
- SuspenseInfiniteQueryPageData<Service, Method, Transform>,
125
- TPageParam
126
- >,
127
- > extends Omit<
128
- InfiniteQueryObserverOptions<
129
- SuspenseInfiniteQueryPageData<Service, Method, Transform>,
130
- SuspenseInfiniteQueryError<Service, Method, Transform>,
131
- Selected,
132
- QueryKey,
133
- TPageParam
134
- >,
135
- "queryKey" | "queryFn"
136
- > {
137
- /** The method to call on the canister */
138
- functionName: Method
139
- /** Call configuration for the actor method */
140
- callConfig?: CallConfig
141
- /** Custom query key (optional, auto-generated if not provided) */
142
- queryKey?: QueryKey
143
- /** Function to get args from page parameter */
144
- getArgs: (pageParam: TPageParam) => ReactorArgs<Service, Method, Transform>
145
- /**
146
- * Narrows what the cache key derives from the call arguments.
147
- *
148
- * By default the key is scoped by `getArgs(initialPageParam)`, so two
149
- * infinite queries on the same method with different arguments stay in
150
- * separate cache entries. Supply this when those args embed the cursor and
151
- * only part of them identifies the query.
152
- */
153
- getKeyArgs?: (args: ReactorArgs<Service, Method, Transform>) => unknown
154
- }
155
-
156
- /**
157
- * Configuration for createActorSuspenseInfiniteQueryFactory (without getArgs; provided at call time).
158
- */
159
- export type SuspenseInfiniteQueryFactoryConfig<
160
- Service = BaseActor,
161
- Method extends FunctionName<Service> = FunctionName<Service>,
162
- Transform extends TransformKey = "candid",
163
- TPageParam = unknown,
164
- Selected = InfiniteData<
165
- SuspenseInfiniteQueryPageData<Service, Method, Transform>,
166
- TPageParam
167
- >,
168
- > = Omit<
169
- // `getArgs` is supplied per factory call. `getKeyArgs` is inherited from
170
- // SuspenseInfiniteQueryConfig, which now applies it for every infinite query.
171
- SuspenseInfiniteQueryConfig<Service, Method, Transform, TPageParam, Selected>,
172
- "getArgs"
173
- >
174
-
175
- // ============================================================================
176
- // Hook Interface
177
- // ============================================================================
178
-
179
- /**
180
- * useSuspenseInfiniteQuery hook with chained select support.
181
- */
182
- export interface UseSuspenseInfiniteQueryWithSelect<
183
- TPageData,
184
- TPageParam,
185
- Selected = InfiniteData<TPageData, TPageParam>,
186
- TError = Error,
187
- > {
188
- // Overload 1: Without select - returns Selected
189
- (
190
- options?: Omit<
191
- UseSuspenseInfiniteQueryOptions<
192
- TPageData,
193
- TError,
194
- Selected,
195
- QueryKey,
196
- TPageParam
197
- >,
198
- | "select"
199
- | "queryKey"
200
- | "queryFn"
201
- | "initialPageParam"
202
- | "getNextPageParam"
203
- | "getPreviousPageParam"
204
- >
205
- ): UseSuspenseInfiniteQueryResult<Selected, TError>
206
-
207
- // Overload 2: With select - chains on top and returns TFinal
208
- <TFinal = Selected>(
209
- options: Omit<
210
- UseSuspenseInfiniteQueryOptions<
211
- TPageData,
212
- TError,
213
- TFinal,
214
- QueryKey,
215
- TPageParam
216
- >,
217
- | "queryKey"
218
- | "queryFn"
219
- | "select"
220
- | "initialPageParam"
221
- | "getNextPageParam"
222
- | "getPreviousPageParam"
223
- > & {
224
- select: (data: Selected) => TFinal
225
- }
226
- ): UseSuspenseInfiniteQueryResult<TFinal, TError>
227
- }
228
-
229
- // ============================================================================
230
- // Result Interface
231
- // ============================================================================
232
-
233
- /**
234
- * Result from createActorSuspenseInfiniteQuery
235
- *
236
- * @template TPageData - The raw page data type
237
- * @template TPageParam - The page parameter type
238
- * @template Selected - The type after select transformation
239
- * @template TError - The error type
240
- */
241
- export interface SuspenseInfiniteQueryResult<
242
- TPageData,
243
- TPageParam,
244
- Selected = InfiniteData<TPageData, TPageParam>,
245
- TError = Error,
246
- > {
247
- /** Fetch first page in loader (uses ensureInfiniteQueryData for cache-first) */
248
- fetch: () => Promise<Selected>
249
-
250
- /** React hook for components - supports pagination */
251
- useSuspenseInfiniteQuery: UseSuspenseInfiniteQueryWithSelect<
252
- TPageData,
253
- TPageParam,
254
- Selected,
255
- TError
256
- >
257
-
258
- /** Invalidate the cache (refetches if query is active) */
259
- invalidate: () => Promise<void>
260
-
261
- /** Get query key (for advanced React Query usage) */
262
- getQueryKey: () => QueryKey
263
-
264
- /**
265
- * Read data directly from cache without fetching.
266
- * Returns undefined if data is not in cache.
267
- */
268
- getCacheData: {
269
- (): Selected | undefined
270
- <TFinal>(select: (data: Selected) => TFinal): TFinal | undefined
271
- }
272
- }
273
-
274
- // ============================================================================
275
- // Internal Implementation
276
- // ============================================================================
277
-
278
- const createSuspenseInfiniteQueryImpl = <
279
- Service,
280
- Method extends FunctionName<Service> = FunctionName<Service>,
281
- Transform extends TransformKey = "candid",
282
- TPageParam = unknown,
283
- Selected = InfiniteData<
284
- SuspenseInfiniteQueryPageData<Service, Method, Transform>,
285
- TPageParam
286
- >,
287
- >(
288
- reactor: Reactor<Service, Transform>,
289
- config: SuspenseInfiniteQueryConfig<
290
- Service,
291
- Method,
292
- Transform,
293
- TPageParam,
294
- Selected
295
- >
296
- ): SuspenseInfiniteQueryResult<
297
- SuspenseInfiniteQueryPageData<Service, Method, Transform>,
298
- TPageParam,
299
- Selected,
300
- SuspenseInfiniteQueryError<Service, Method, Transform>
301
- > => {
302
- type TPageData = SuspenseInfiniteQueryPageData<Service, Method, Transform>
303
- type TError = SuspenseInfiniteQueryError<Service, Method, Transform>
304
- type TInfiniteData = InfiniteData<TPageData, TPageParam>
305
-
306
- const {
307
- functionName,
308
- callConfig,
309
- queryKey: customQueryKey,
310
- initialPageParam,
311
- getArgs,
312
- getKeyArgs,
313
- getNextPageParam,
314
- getPreviousPageParam,
315
- maxPages,
316
- staleTime = 5 * 60 * 1000,
317
- select,
318
- ...rest
319
- } = config
320
-
321
- // Fold the call arguments into the key — see the matching comment in
322
- // createInfiniteQuery. Without them every infinite query on a method shares
323
- // one cache entry, because the arguments live in a `getArgs` closure rather
324
- // than in the config.
325
- const getQueryKey = (): QueryKey => {
326
- const initialArgs = getArgs(initialPageParam)
327
- const keyArgs = getKeyArgs?.(initialArgs) ?? initialArgs
328
-
329
- return reactor.generateQueryKey(
330
- {
331
- functionName,
332
- queryKey: mergeFactoryQueryKey(customQueryKey, undefined, keyArgs),
333
- },
334
- callConfig
335
- )
336
- }
337
-
338
- // Query function - accepts QueryFunctionContext
339
- const queryFn = async (
340
- context: QueryFunctionContext<QueryKey, TPageParam>
341
- ): Promise<TPageData> => {
342
- // pageParam is typed as unknown in QueryFunctionContext, but we know its type
343
- const pageParam = context.pageParam as TPageParam
344
- const args = getArgs(pageParam)
345
- const result = await reactor.callMethod({
346
- functionName,
347
- args,
348
- callConfig,
349
- })
350
- return normalizeQueryData<ReactorReturnOk<Service, Method, Transform>>(
351
- result as ReactorReturnOk<Service, Method, Transform>
352
- )
353
- }
354
-
355
- // Get infinite query options for fetchInfiniteQuery
356
- const getInfiniteQueryOptions = (): FetchInfiniteQueryOptions<
357
- TPageData,
358
- TError,
359
- TPageData,
360
- QueryKey,
361
- TPageParam
362
- > => ({
363
- queryKey: getQueryKey(),
364
- queryFn,
365
- initialPageParam,
366
- getNextPageParam,
367
- staleTime,
368
- })
369
-
370
- // Fetch function for loaders (cache-first, fetches first page)
371
- const fetch = async (): Promise<Selected> => {
372
- // Use ensureInfiniteQueryData to get cached data or fetch if stale
373
- const result = await reactor.queryClient.ensureInfiniteQueryData(
374
- getInfiniteQueryOptions()
375
- )
376
-
377
- // Result is already InfiniteData format
378
- return select ? select(result) : (result as unknown as Selected)
379
- }
380
-
381
- // Implementation
382
- const useSuspenseInfiniteQueryHook: UseSuspenseInfiniteQueryWithSelect<
383
- TPageData,
384
- TPageParam,
385
- Selected,
386
- TError
387
- > = (options: any): any => {
388
- // Memoized and identity-preserving; see buildChainedSelect for why the
389
- // function identity matters to the observer's select-result cache.
390
- const chainedSelect = useMemo(
391
- () => buildChainedSelect(select as never, options?.select),
392
- [options?.select]
393
- )
394
-
395
- return useSuspenseInfiniteQuery(
396
- {
397
- queryKey: getQueryKey(),
398
- queryFn,
399
- initialPageParam,
400
- getNextPageParam,
401
- getPreviousPageParam,
402
- maxPages,
403
- staleTime,
404
- ...rest,
405
- ...options,
406
- select: chainedSelect,
407
- },
408
- reactor.queryClient
409
- )
410
- }
411
-
412
- // Invalidate function
413
- const invalidate = async (): Promise<void> => {
414
- const queryKey = getQueryKey()
415
- await reactor.queryClient.invalidateQueries({ queryKey })
416
- }
417
-
418
- // Get data from cache without fetching
419
- const getCacheData = (selectFn?: (data: Selected) => any) => {
420
- const queryKey = getQueryKey()
421
- const cachedRawData = reactor.queryClient.getQueryData(
422
- queryKey
423
- ) as TInfiniteData
424
-
425
- if (cachedRawData === undefined) {
426
- return undefined
427
- }
428
-
429
- // Apply config.select to raw cache data
430
- const selectedData = (
431
- select ? select(cachedRawData) : cachedRawData
432
- ) as Selected
433
-
434
- // Apply optional select parameter
435
- if (selectFn) {
436
- return selectFn(selectedData)
437
- }
438
-
439
- return selectedData
440
- }
441
-
442
- return {
443
- fetch,
444
- useSuspenseInfiniteQuery: useSuspenseInfiniteQueryHook,
445
- invalidate,
446
- getQueryKey,
447
- getCacheData,
448
- }
449
- }
450
-
451
- // ============================================================================
452
- // Factory Function
453
- // ============================================================================
454
-
455
- export function createSuspenseInfiniteQuery<
456
- Service,
457
- Transform extends TransformKey,
458
- Method extends FunctionName<Service> = FunctionName<Service>,
459
- TPageParam = unknown,
460
- Selected = InfiniteData<
461
- SuspenseInfiniteQueryPageData<Service, Method, Transform>,
462
- TPageParam
463
- >,
464
- >(
465
- reactor: Reactor<Service, Transform>,
466
- config: SuspenseInfiniteQueryConfig<
467
- NoInfer<Service>,
468
- Method,
469
- Transform,
470
- TPageParam,
471
- Selected
472
- >
473
- ): SuspenseInfiniteQueryResult<
474
- SuspenseInfiniteQueryPageData<Service, Method, Transform>,
475
- TPageParam,
476
- Selected,
477
- SuspenseInfiniteQueryError<Service, Method, Transform>
478
- > {
479
- return createSuspenseInfiniteQueryImpl(
480
- reactor,
481
- config as SuspenseInfiniteQueryConfig<
482
- Service,
483
- Method,
484
- Transform,
485
- TPageParam,
486
- Selected
487
- >
488
- )
489
- }
490
-
491
- // ============================================================================
492
- // Factory with Dynamic Args
493
- // ============================================================================
494
-
495
- /**
496
- * Create a suspense infinite query factory that accepts getArgs at call time.
497
- * Useful when pagination logic varies by context.
498
- *
499
- * @template Service - The actor interface type
500
- * @template Method - The method name on the actor
501
- * @template Transform - The transformation key (identity, display, etc.)
502
- * @template TPageParam - The page parameter type
503
- * @template Selected - The type returned after select transformation
504
- *
505
- * @param reactor - The Reactor instance
506
- * @param config - Suspense infinite query configuration (without getArgs)
507
- * @returns A function that accepts getArgs and returns an SuspenseActorInfiniteQueryResult
508
- *
509
- * @example
510
- * const getPostsQuery = createActorSuspenseInfiniteQueryFactory(reactor, {
511
- * functionName: "get_posts",
512
- * initialPageParam: 0,
513
- * getKeyArgs: (args) => {
514
- * const [{ userId }] = args
515
- * return [{ userId }]
516
- * },
517
- * getNextPageParam: (lastPage) => lastPage.nextCursor,
518
- * })
519
- *
520
- * // Create query with specific args builder
521
- * const userPostsQuery = getPostsQuery((cursor) => [{ userId, cursor, limit: 10 }])
522
- * const { data, fetchNextPage } = userPostsQuery.useSuspenseInfiniteQuery()
523
- *
524
- * // Optional: append a manual query-key suffix in addition to auto key args
525
- * const scopedPostsQuery = getPostsQuery(
526
- * (cursor) => [{ userId, cursor, limit: 10 }],
527
- * { queryKey: ["v2"] }
528
- * )
529
- */
530
-
531
- export function createSuspenseInfiniteQueryFactory<
532
- Service,
533
- Transform extends TransformKey,
534
- Method extends FunctionName<Service> = FunctionName<Service>,
535
- TPageParam = unknown,
536
- Selected = InfiniteData<
537
- SuspenseInfiniteQueryPageData<Service, Method, Transform>,
538
- TPageParam
539
- >,
540
- >(
541
- reactor: Reactor<Service, Transform>,
542
- config: SuspenseInfiniteQueryFactoryConfig<
543
- NoInfer<Service>,
544
- Method,
545
- Transform,
546
- TPageParam,
547
- Selected
548
- >
549
- ): SuspenseInfiniteQueryFactoryFn<
550
- Service,
551
- Method,
552
- Transform,
553
- TPageParam,
554
- Selected
555
- > {
556
- const factory: SuspenseInfiniteQueryFactoryFn<
557
- Service,
558
- Method,
559
- Transform,
560
- TPageParam,
561
- Selected
562
- > = (
563
- getArgs: (pageParam: TPageParam) => ReactorArgs<Service, Method, Transform>,
564
- options?: SuspenseInfiniteFactoryCallOptions
565
- ) => {
566
- // Only the caller-supplied segments are merged here; the args-derived
567
- // segment is added by the impl, which does it for every infinite query.
568
- // Applying it in both places would append the args twice.
569
- const queryKey = mergeFactoryQueryKey(
570
- config.queryKey,
571
- options?.queryKey,
572
- undefined
573
- )
574
-
575
- return createSuspenseInfiniteQueryImpl<
576
- Service,
577
- Method,
578
- Transform,
579
- TPageParam,
580
- Selected
581
- >(reactor, {
582
- ...(config as SuspenseInfiniteQueryFactoryConfig<
583
- Service,
584
- Method,
585
- Transform,
586
- TPageParam,
587
- Selected
588
- >),
589
- queryKey,
590
- getArgs,
591
- } as SuspenseInfiniteQueryConfig<
592
- Service,
593
- Method,
594
- Transform,
595
- TPageParam,
596
- Selected
597
- >)
598
- }
599
-
600
- return factory
601
- }