@ic-reactor/react 3.12.4 → 3.13.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.
Files changed (152) hide show
  1. package/README.md +410 -44
  2. package/dist/auth/auth-client-compat.d.ts +122 -0
  3. package/dist/auth/auth-client-compat.d.ts.map +1 -0
  4. package/dist/auth/auth-client-compat.js +162 -0
  5. package/dist/auth/auth-client-compat.js.map +1 -0
  6. package/dist/auth/authentication-manager.d.ts +287 -5
  7. package/dist/auth/authentication-manager.d.ts.map +1 -1
  8. package/dist/auth/authentication-manager.js +920 -150
  9. package/dist/auth/authentication-manager.js.map +1 -1
  10. package/dist/auth/createIdentityAttributeHooks.d.ts.map +1 -1
  11. package/dist/auth/createIdentityAttributeHooks.js +36 -20
  12. package/dist/auth/createIdentityAttributeHooks.js.map +1 -1
  13. package/dist/auth/identity-attributes-manager.d.ts +2 -1
  14. package/dist/auth/identity-attributes-manager.d.ts.map +1 -1
  15. package/dist/auth/identity-attributes-manager.js +90 -6
  16. package/dist/auth/identity-attributes-manager.js.map +1 -1
  17. package/dist/auth/identity-attributes.d.ts.map +1 -1
  18. package/dist/auth/identity-attributes.js +57 -0
  19. package/dist/auth/identity-attributes.js.map +1 -1
  20. package/dist/auth/local-ii-probe.d.ts +12 -1
  21. package/dist/auth/local-ii-probe.d.ts.map +1 -1
  22. package/dist/auth/local-ii-probe.js +22 -3
  23. package/dist/auth/local-ii-probe.js.map +1 -1
  24. package/dist/auth/types.d.ts +48 -5
  25. package/dist/auth/types.d.ts.map +1 -1
  26. package/dist/createActorHooks.d.ts +9 -20
  27. package/dist/createActorHooks.d.ts.map +1 -1
  28. package/dist/createActorHooks.js.map +1 -1
  29. package/dist/createInfiniteQuery.d.ts +51 -10
  30. package/dist/createInfiniteQuery.d.ts.map +1 -1
  31. package/dist/createInfiniteQuery.js +39 -15
  32. package/dist/createInfiniteQuery.js.map +1 -1
  33. package/dist/createMutation.d.ts +4 -1
  34. package/dist/createMutation.d.ts.map +1 -1
  35. package/dist/createMutation.js +121 -84
  36. package/dist/createMutation.js.map +1 -1
  37. package/dist/createQuery.d.ts +35 -2
  38. package/dist/createQuery.d.ts.map +1 -1
  39. package/dist/createQuery.js +104 -17
  40. package/dist/createQuery.js.map +1 -1
  41. package/dist/createReactorProvider.d.ts +158 -0
  42. package/dist/createReactorProvider.d.ts.map +1 -0
  43. package/dist/createReactorProvider.js +256 -0
  44. package/dist/createReactorProvider.js.map +1 -0
  45. package/dist/createSuspenseInfiniteQuery.d.ts +16 -9
  46. package/dist/createSuspenseInfiniteQuery.d.ts.map +1 -1
  47. package/dist/createSuspenseInfiniteQuery.js +59 -27
  48. package/dist/createSuspenseInfiniteQuery.js.map +1 -1
  49. package/dist/createSuspenseQuery.d.ts +23 -2
  50. package/dist/createSuspenseQuery.d.ts.map +1 -1
  51. package/dist/createSuspenseQuery.js +68 -21
  52. package/dist/createSuspenseQuery.js.map +1 -1
  53. package/dist/defineDisplayReactor.d.ts +43 -0
  54. package/dist/defineDisplayReactor.d.ts.map +1 -0
  55. package/dist/defineDisplayReactor.js +42 -0
  56. package/dist/defineDisplayReactor.js.map +1 -0
  57. package/dist/defineReactor.d.ts +46 -72
  58. package/dist/defineReactor.d.ts.map +1 -1
  59. package/dist/defineReactor.js +11 -176
  60. package/dist/defineReactor.js.map +1 -1
  61. package/dist/defineReactorShared.d.ts +84 -0
  62. package/dist/defineReactorShared.d.ts.map +1 -0
  63. package/dist/defineReactorShared.js +139 -0
  64. package/dist/defineReactorShared.js.map +1 -0
  65. package/dist/hooks/createAuthHooks.d.ts +9 -2
  66. package/dist/hooks/createAuthHooks.d.ts.map +1 -1
  67. package/dist/hooks/createAuthHooks.js +184 -24
  68. package/dist/hooks/createAuthHooks.js.map +1 -1
  69. package/dist/hooks/useActorInfiniteQuery.d.ts +36 -8
  70. package/dist/hooks/useActorInfiniteQuery.d.ts.map +1 -1
  71. package/dist/hooks/useActorInfiniteQuery.js +54 -21
  72. package/dist/hooks/useActorInfiniteQuery.js.map +1 -1
  73. package/dist/hooks/useActorMethod.d.ts +37 -4
  74. package/dist/hooks/useActorMethod.d.ts.map +1 -1
  75. package/dist/hooks/useActorMethod.js +201 -57
  76. package/dist/hooks/useActorMethod.js.map +1 -1
  77. package/dist/hooks/useActorMutation.d.ts +15 -12
  78. package/dist/hooks/useActorMutation.d.ts.map +1 -1
  79. package/dist/hooks/useActorMutation.js +14 -13
  80. package/dist/hooks/useActorMutation.js.map +1 -1
  81. package/dist/hooks/useActorQuery.d.ts +17 -4
  82. package/dist/hooks/useActorQuery.d.ts.map +1 -1
  83. package/dist/hooks/useActorQuery.js +30 -9
  84. package/dist/hooks/useActorQuery.js.map +1 -1
  85. package/dist/hooks/useActorSuspenseInfiniteQuery.d.ts +17 -5
  86. package/dist/hooks/useActorSuspenseInfiniteQuery.d.ts.map +1 -1
  87. package/dist/hooks/useActorSuspenseInfiniteQuery.js +37 -17
  88. package/dist/hooks/useActorSuspenseInfiniteQuery.js.map +1 -1
  89. package/dist/hooks/useActorSuspenseQuery.d.ts +2 -2
  90. package/dist/hooks/useActorSuspenseQuery.d.ts.map +1 -1
  91. package/dist/hooks/useActorSuspenseQuery.js +20 -9
  92. package/dist/hooks/useActorSuspenseQuery.js.map +1 -1
  93. package/dist/index.d.ts +4 -0
  94. package/dist/index.d.ts.map +1 -1
  95. package/dist/index.js +6 -0
  96. package/dist/index.js.map +1 -1
  97. package/dist/ownedAuthentication.d.ts +52 -0
  98. package/dist/ownedAuthentication.d.ts.map +1 -0
  99. package/dist/ownedAuthentication.js +49 -0
  100. package/dist/ownedAuthentication.js.map +1 -0
  101. package/dist/server.d.ts +21 -0
  102. package/dist/server.d.ts.map +1 -0
  103. package/dist/server.js +23 -0
  104. package/dist/server.js.map +1 -0
  105. package/dist/testing.d.ts +19 -0
  106. package/dist/testing.d.ts.map +1 -0
  107. package/dist/testing.js +19 -0
  108. package/dist/testing.js.map +1 -0
  109. package/dist/types.d.ts +428 -21
  110. package/dist/types.d.ts.map +1 -1
  111. package/dist/types.js +1 -1
  112. package/dist/utils.d.ts +159 -3
  113. package/dist/utils.d.ts.map +1 -1
  114. package/dist/utils.js +301 -1
  115. package/dist/utils.js.map +1 -1
  116. package/dist/validation.d.ts +12 -7
  117. package/dist/validation.d.ts.map +1 -1
  118. package/dist/validation.js +34 -15
  119. package/dist/validation.js.map +1 -1
  120. package/llms.txt +259 -33
  121. package/package.json +17 -5
  122. package/src/auth/auth-client-compat.ts +273 -0
  123. package/src/auth/authentication-manager.ts +918 -96
  124. package/src/auth/createIdentityAttributeHooks.ts +47 -21
  125. package/src/auth/identity-attributes-manager.ts +100 -5
  126. package/src/auth/identity-attributes.ts +75 -0
  127. package/src/auth/local-ii-probe.ts +29 -3
  128. package/src/auth/types.ts +49 -6
  129. package/src/createActorHooks.ts +50 -42
  130. package/src/createInfiniteQuery.ts +120 -28
  131. package/src/createMutation.ts +213 -132
  132. package/src/createQuery.ts +164 -32
  133. package/src/createReactorProvider.ts +365 -0
  134. package/src/createSuspenseInfiniteQuery.ts +93 -43
  135. package/src/createSuspenseQuery.ts +102 -32
  136. package/src/defineDisplayReactor.ts +62 -0
  137. package/src/defineReactor.ts +81 -263
  138. package/src/defineReactorShared.ts +268 -0
  139. package/src/hooks/createAuthHooks.ts +210 -28
  140. package/src/hooks/useActorInfiniteQuery.ts +156 -55
  141. package/src/hooks/useActorMethod.ts +295 -92
  142. package/src/hooks/useActorMutation.ts +42 -30
  143. package/src/hooks/useActorQuery.ts +43 -10
  144. package/src/hooks/useActorSuspenseInfiniteQuery.ts +110 -54
  145. package/src/hooks/useActorSuspenseQuery.ts +30 -15
  146. package/src/index.ts +8 -0
  147. package/src/ownedAuthentication.ts +81 -0
  148. package/src/server.ts +23 -0
  149. package/src/testing.ts +18 -0
  150. package/src/types.ts +492 -22
  151. package/src/utils.ts +387 -3
  152. package/src/validation.ts +43 -19
@@ -8,7 +8,7 @@
8
8
  * const postsQuery = createInfiniteQuery(reactor, {
9
9
  * functionName: "get_posts",
10
10
  * initialPageParam: 0,
11
- * getArgs: (cursor) => [{ cursor, limit: 10 }],
11
+ * getArgs: (cursor) => [{ cursor, limit: 10 }] as const,
12
12
  * getNextPageParam: (lastPage) => lastPage.nextCursor,
13
13
  * })
14
14
  *
@@ -42,13 +42,24 @@ import {
42
42
  QueryFunctionContext,
43
43
  FetchInfiniteQueryOptions,
44
44
  InfiniteQueryObserverOptions,
45
+ SkipToken,
45
46
  } from "@tanstack/react-query"
46
47
  import { CallConfig } from "@icp-sdk/core/agent"
47
- import { NoInfer } from "./types.js"
48
+ import type {
49
+ NoInfer,
50
+ QueryCacheControls,
51
+ QueryFactoryMethods,
52
+ } from "./types.js"
48
53
  import {
49
54
  buildChainedSelect,
55
+ callConfigForKey,
50
56
  mergeFactoryQueryKey,
51
57
  normalizeQueryData,
58
+ pickFetchOptions,
59
+ queryCacheControls,
60
+ retryOption,
61
+ useMountQueryClient,
62
+ withQueryFactoryMethods,
52
63
  } from "./utils.js"
53
64
 
54
65
  type InfiniteQueryFactoryFn<
@@ -57,7 +68,7 @@ type InfiniteQueryFactoryFn<
57
68
  Transform extends TransformKey,
58
69
  TPageParam,
59
70
  Selected,
60
- > = {
71
+ > = QueryFactoryMethods & {
61
72
  (
62
73
  getArgs: (pageParam: TPageParam) => ReactorArgs<Service, Method, Transform>
63
74
  ): InfiniteQueryResult<
@@ -91,7 +102,7 @@ export type InfiniteQueryError<
91
102
  // ============================================================================
92
103
 
93
104
  /**
94
- * Configuration for createActorInfiniteQuery.
105
+ * Configuration for createInfiniteQuery.
95
106
  * Extends InfiniteQueryObserverOptions to accept standard TanStack Query
96
107
  * infinite-query options at the create level (e.g. refetchInterval,
97
108
  * refetchOnMount, refetchOnWindowFocus, retry, gcTime, networkMode).
@@ -158,7 +169,56 @@ export interface InfiniteQueryConfig<
158
169
  }
159
170
 
160
171
  /**
161
- * Configuration for createActorInfiniteQueryFactory (without initialPageParam, getArgs determined at call time).
172
+ * Configuration for the non-suspense infinite query hook of
173
+ * `createActorHooks` and `defineReactor` (`useActorInfiniteQuery`): an
174
+ * {@link InfiniteQueryConfig} whose `getArgs` may also be TanStack Query's
175
+ * `skipToken`, for a list whose arguments are not known yet.
176
+ *
177
+ * A skipped list does not fetch. It has an entry of its own under its method
178
+ * and config `queryKey` (at the canister and agent `callConfig` names), which
179
+ * no call's key shares, so it shows no data until the arguments arrive. Once
180
+ * `getArgs` is a function, the list is keyed and fetched as usual. Its
181
+ * `refetch()` has nothing to run: TanStack Query answers it with a "Missing
182
+ * queryFn" error. `useActorSuspenseInfiniteQuery` does not take `skipToken`.
183
+ *
184
+ * @example
185
+ * ```typescript
186
+ * import { skipToken } from "@ic-reactor/react"
187
+ *
188
+ * const { data } = useActorInfiniteQuery({
189
+ * functionName: "get_transactions",
190
+ * getArgs: account
191
+ * ? (start: bigint) => [{ account, start, length: 20n }]
192
+ * : skipToken,
193
+ * initialPageParam: 0n,
194
+ * getNextPageParam: (lastPage) => lastPage.next[0],
195
+ * })
196
+ * ```
197
+ */
198
+ export interface SkippableInfiniteQueryConfig<
199
+ Service = BaseActor,
200
+ Method extends FunctionName<Service> = FunctionName<Service>,
201
+ Transform extends TransformKey = "candid",
202
+ TPageParam = unknown,
203
+ Selected = InfiniteData<
204
+ InfiniteQueryPageData<Service, Method, Transform>,
205
+ TPageParam
206
+ >,
207
+ > extends Omit<
208
+ InfiniteQueryConfig<Service, Method, Transform, TPageParam, Selected>,
209
+ "getArgs"
210
+ > {
211
+ /**
212
+ * Function to get args from page parameter, or `skipToken` while the args
213
+ * are not known: the list then waits without fetching.
214
+ */
215
+ getArgs:
216
+ | ((pageParam: TPageParam) => ReactorArgs<Service, Method, Transform>)
217
+ | SkipToken
218
+ }
219
+
220
+ /**
221
+ * Configuration for createInfiniteQueryFactory (without getArgs; provided at call time).
162
222
  */
163
223
  export type InfiniteQueryFactoryConfig<
164
224
  Service = BaseActor,
@@ -230,7 +290,11 @@ export interface UseInfiniteQueryWithSelect<
230
290
  // ============================================================================
231
291
 
232
292
  /**
233
- * Result from createActorInfiniteQuery
293
+ * Result from createInfiniteQuery
294
+ *
295
+ * `cancel()`, `reset()` and `optimisticUpdate()` act on the whole page set:
296
+ * `optimisticUpdate` gets and returns the raw `InfiniteData`, `{ pages,
297
+ * pageParams }`.
234
298
  *
235
299
  * @template TPageData - The raw page data type
236
300
  * @template TPageParam - The page parameter type
@@ -242,7 +306,7 @@ export interface InfiniteQueryResult<
242
306
  TPageParam,
243
307
  Selected = InfiniteData<TPageData, TPageParam>,
244
308
  TError = Error,
245
- > {
309
+ > extends QueryCacheControls<InfiniteData<TPageData, TPageParam>> {
246
310
  /** Fetch first page in loader (uses ensureQueryData for cache-first) */
247
311
  fetch: () => Promise<Selected>
248
312
 
@@ -342,7 +406,7 @@ const createInfiniteQueryImpl = <
342
406
  const result = await reactor.callMethod({
343
407
  functionName,
344
408
  args,
345
- callConfig,
409
+ callConfig: callConfigForKey(context.queryKey, callConfig),
346
410
  })
347
411
  return normalizeQueryData<ReactorReturnOk<Service, Method, Transform>>(
348
412
  result as ReactorReturnOk<Service, Method, Transform>
@@ -356,12 +420,20 @@ const createInfiniteQueryImpl = <
356
420
  TPageData,
357
421
  QueryKey,
358
422
  TPageParam
359
- > => ({
360
- queryKey: getQueryKey(),
361
- queryFn,
362
- initialPageParam,
363
- getNextPageParam,
364
- })
423
+ > => {
424
+ const queryKey = getQueryKey()
425
+ return {
426
+ // How the query function runs, shared with the hook; see
427
+ // pickFetchOptions. An update method's `retry` defaults as
428
+ // `Reactor.getQueryRetry` says.
429
+ ...pickFetchOptions(rest),
430
+ ...retryOption(rest.retry, reactor.getQueryRetry(functionName, queryKey)),
431
+ queryKey,
432
+ queryFn,
433
+ initialPageParam,
434
+ getNextPageParam,
435
+ }
436
+ }
365
437
 
366
438
  // Fetch function for loaders (cache-first, fetches first page)
367
439
  const fetch = async (): Promise<Selected> => {
@@ -373,9 +445,11 @@ const createInfiniteQueryImpl = <
373
445
  return select ? select(cachedData) : (cachedData as Selected)
374
446
  }
375
447
 
376
- // Fetch if not in cache
377
- const result = await reactor.queryClient.fetchInfiniteQuery(
378
- getInfiniteQueryOptions()
448
+ // Fetch if not in cache. A sign-in or sign-out while it is in flight
449
+ // cancels it; it then runs again for the new identity rather than
450
+ // rejecting with TanStack's CancelledError, as `reactor.fetchQuery` does.
451
+ const result = await reactor.clientManager.fetchAcrossIdentitySwitch(() =>
452
+ reactor.queryClient.fetchInfiniteQuery(getInfiniteQueryOptions())
379
453
  )
380
454
 
381
455
  // Result is already InfiniteData format
@@ -389,6 +463,8 @@ const createInfiniteQueryImpl = <
389
463
  Selected,
390
464
  TError
391
465
  > = (options: any): any => {
466
+ useMountQueryClient(reactor.queryClient)
467
+
392
468
  // Memoized and identity-preserving; see buildChainedSelect for why the
393
469
  // function identity matters to the observer's select-result cache.
394
470
  const chainedSelect = useMemo(
@@ -396,9 +472,11 @@ const createInfiniteQueryImpl = <
396
472
  [options?.select]
397
473
  )
398
474
 
475
+ const queryKey = getQueryKey()
476
+
399
477
  return useInfiniteQuery(
400
478
  {
401
- queryKey: getQueryKey(),
479
+ queryKey,
402
480
  queryFn,
403
481
  initialPageParam,
404
482
  getNextPageParam,
@@ -408,6 +486,12 @@ const createInfiniteQueryImpl = <
408
486
  ...rest,
409
487
  ...options,
410
488
  select: chainedSelect,
489
+ // The hook's `retry`, else the config's, else an update method's
490
+ // default; see `Reactor.getQueryRetry`.
491
+ ...retryOption(
492
+ options?.retry ?? rest.retry,
493
+ reactor.getQueryRetry(functionName, queryKey)
494
+ ),
411
495
  } as any,
412
496
  reactor.queryClient
413
497
  )
@@ -449,6 +533,7 @@ const createInfiniteQueryImpl = <
449
533
  invalidate,
450
534
  getQueryKey,
451
535
  getCacheData,
536
+ ...queryCacheControls<TInfiniteData>(reactor, getQueryKey),
452
537
  }
453
538
  }
454
539
 
@@ -508,10 +593,10 @@ export function createInfiniteQuery<
508
593
  *
509
594
  * @param reactor - The Reactor instance
510
595
  * @param config - Infinite query configuration (without getArgs)
511
- * @returns A function that accepts getArgs and returns an ActorInfiniteQueryResult
596
+ * @returns A function that accepts getArgs and returns an InfiniteQueryResult
512
597
  *
513
598
  * @example
514
- * const getPostsQuery = createActorInfiniteQueryFactory(reactor, {
599
+ * const getPostsQuery = createInfiniteQueryFactory(reactor, {
515
600
  * functionName: "get_posts",
516
601
  * initialPageParam: 0,
517
602
  * getKeyArgs: (args) => {
@@ -524,6 +609,9 @@ export function createInfiniteQuery<
524
609
  * // Create query with specific args builder
525
610
  * const userPostsQuery = getPostsQuery((cursor) => [{ userId, cursor, limit: 10 }])
526
611
  * const { data, fetchNextPage } = userPostsQuery.useInfiniteQuery()
612
+ *
613
+ * // Every list this factory made, whatever its args and pages
614
+ * await getPostsQuery.invalidate()
527
615
  */
528
616
 
529
617
  export function createInfiniteQueryFactory<
@@ -545,13 +633,7 @@ export function createInfiniteQueryFactory<
545
633
  Selected
546
634
  >
547
635
  ): InfiniteQueryFactoryFn<Service, Method, Transform, TPageParam, Selected> {
548
- const factory: InfiniteQueryFactoryFn<
549
- Service,
550
- Method,
551
- Transform,
552
- TPageParam,
553
- Selected
554
- > = (
636
+ const factory = (
555
637
  getArgs: (pageParam: TPageParam) => ReactorArgs<Service, Method, Transform>
556
638
  ) => {
557
639
  // `getKeyArgs` and the args-derived key segment are applied by the impl,
@@ -574,5 +656,15 @@ export function createInfiniteQueryFactory<
574
656
  })
575
657
  }
576
658
 
577
- return factory
659
+ // What every instance's key starts with: the method, the `callConfig`
660
+ // segments and the config `queryKey`. The args segment comes after them.
661
+ return withQueryFactoryMethods(factory, reactor, () =>
662
+ reactor.generateQueryKey(
663
+ {
664
+ functionName: config.functionName as Method,
665
+ queryKey: config.queryKey,
666
+ },
667
+ config.callConfig
668
+ )
669
+ )
578
670
  }