@ic-reactor/react 3.6.0 → 3.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/README.md +28 -8
  2. package/dist/auth/authentication-manager.d.ts +66 -0
  3. package/dist/auth/authentication-manager.d.ts.map +1 -0
  4. package/dist/auth/authentication-manager.js +458 -0
  5. package/dist/auth/authentication-manager.js.map +1 -0
  6. package/dist/auth/constants.d.ts +18 -0
  7. package/dist/auth/constants.d.ts.map +1 -0
  8. package/dist/auth/constants.js +18 -0
  9. package/dist/auth/constants.js.map +1 -0
  10. package/dist/auth/createIdentityAttributeHooks.d.ts +14 -0
  11. package/dist/auth/createIdentityAttributeHooks.d.ts.map +1 -0
  12. package/dist/auth/createIdentityAttributeHooks.js +54 -0
  13. package/dist/auth/createIdentityAttributeHooks.js.map +1 -0
  14. package/dist/auth/identity-attributes-manager.d.ts +19 -0
  15. package/dist/auth/identity-attributes-manager.d.ts.map +1 -0
  16. package/dist/auth/identity-attributes-manager.js +94 -0
  17. package/dist/auth/identity-attributes-manager.js.map +1 -0
  18. package/dist/auth/identity-attributes.d.ts +19 -0
  19. package/dist/auth/identity-attributes.d.ts.map +1 -0
  20. package/dist/auth/identity-attributes.js +170 -0
  21. package/dist/auth/identity-attributes.js.map +1 -0
  22. package/dist/auth/index.d.ts +8 -0
  23. package/dist/auth/index.d.ts.map +1 -0
  24. package/dist/auth/index.js +8 -0
  25. package/dist/auth/index.js.map +1 -0
  26. package/dist/auth/types.d.ts +75 -0
  27. package/dist/auth/types.d.ts.map +1 -0
  28. package/dist/auth/types.js +2 -0
  29. package/dist/auth/types.js.map +1 -0
  30. package/dist/createActorHooks.d.ts +12 -12
  31. package/dist/createActorHooks.d.ts.map +1 -1
  32. package/dist/createActorHooks.js.map +1 -1
  33. package/dist/createInfiniteQuery.d.ts +32 -32
  34. package/dist/createInfiniteQuery.d.ts.map +1 -1
  35. package/dist/createInfiniteQuery.js +6 -6
  36. package/dist/createInfiniteQuery.js.map +1 -1
  37. package/dist/createMutation.d.ts +12 -1
  38. package/dist/createMutation.d.ts.map +1 -1
  39. package/dist/createMutation.js +11 -0
  40. package/dist/createMutation.js.map +1 -1
  41. package/dist/createQuery.d.ts +12 -2
  42. package/dist/createQuery.d.ts.map +1 -1
  43. package/dist/createQuery.js +15 -5
  44. package/dist/createQuery.js.map +1 -1
  45. package/dist/createSuspenseInfiniteQuery.d.ts +31 -31
  46. package/dist/createSuspenseInfiniteQuery.d.ts.map +1 -1
  47. package/dist/createSuspenseInfiniteQuery.js +6 -6
  48. package/dist/createSuspenseInfiniteQuery.js.map +1 -1
  49. package/dist/createSuspenseQuery.d.ts +2 -2
  50. package/dist/createSuspenseQuery.d.ts.map +1 -1
  51. package/dist/createSuspenseQuery.js.map +1 -1
  52. package/dist/defineReactor.d.ts +74 -0
  53. package/dist/defineReactor.d.ts.map +1 -0
  54. package/dist/defineReactor.js +75 -0
  55. package/dist/defineReactor.js.map +1 -0
  56. package/dist/{createAuthHooks.d.ts → hooks/createAuthHooks.d.ts} +6 -13
  57. package/dist/hooks/createAuthHooks.d.ts.map +1 -0
  58. package/dist/{createAuthHooks.js → hooks/createAuthHooks.js} +12 -57
  59. package/dist/hooks/createAuthHooks.js.map +1 -0
  60. package/dist/hooks/index.d.ts +2 -0
  61. package/dist/hooks/index.d.ts.map +1 -1
  62. package/dist/hooks/index.js +2 -0
  63. package/dist/hooks/index.js.map +1 -1
  64. package/dist/hooks/useActorInfiniteQuery.d.ts +9 -9
  65. package/dist/hooks/useActorInfiniteQuery.d.ts.map +1 -1
  66. package/dist/hooks/useActorInfiniteQuery.js +3 -1
  67. package/dist/hooks/useActorInfiniteQuery.js.map +1 -1
  68. package/dist/hooks/useActorMethod.d.ts +17 -17
  69. package/dist/hooks/useActorMethod.d.ts.map +1 -1
  70. package/dist/hooks/useActorMethod.js.map +1 -1
  71. package/dist/hooks/useActorMutation.d.ts +18 -7
  72. package/dist/hooks/useActorMutation.d.ts.map +1 -1
  73. package/dist/hooks/useActorMutation.js +11 -0
  74. package/dist/hooks/useActorMutation.js.map +1 -1
  75. package/dist/hooks/useActorQuery.d.ts +8 -8
  76. package/dist/hooks/useActorQuery.d.ts.map +1 -1
  77. package/dist/hooks/useActorQuery.js.map +1 -1
  78. package/dist/hooks/useActorSuspenseInfiniteQuery.d.ts +9 -9
  79. package/dist/hooks/useActorSuspenseInfiniteQuery.d.ts.map +1 -1
  80. package/dist/hooks/useActorSuspenseInfiniteQuery.js +3 -1
  81. package/dist/hooks/useActorSuspenseInfiniteQuery.js.map +1 -1
  82. package/dist/hooks/useActorSuspenseQuery.d.ts +8 -8
  83. package/dist/hooks/useActorSuspenseQuery.d.ts.map +1 -1
  84. package/dist/hooks/useActorSuspenseQuery.js.map +1 -1
  85. package/dist/index.d.ts +2 -1
  86. package/dist/index.d.ts.map +1 -1
  87. package/dist/index.js +2 -1
  88. package/dist/index.js.map +1 -1
  89. package/dist/types.d.ts +24 -24
  90. package/dist/types.d.ts.map +1 -1
  91. package/dist/utils.d.ts +3 -0
  92. package/dist/utils.d.ts.map +1 -1
  93. package/dist/utils.js +10 -2
  94. package/dist/utils.js.map +1 -1
  95. package/llms.txt +48 -0
  96. package/package.json +27 -21
  97. package/src/auth/authentication-manager.ts +519 -0
  98. package/src/auth/constants.ts +25 -0
  99. package/src/auth/createIdentityAttributeHooks.ts +83 -0
  100. package/src/auth/identity-attributes-manager.ts +127 -0
  101. package/src/auth/identity-attributes.ts +270 -0
  102. package/src/auth/index.ts +7 -0
  103. package/src/auth/types.ts +88 -0
  104. package/src/createActorHooks.ts +81 -49
  105. package/src/createInfiniteQuery.ts +153 -97
  106. package/src/createMutation.ts +34 -18
  107. package/src/createQuery.ts +92 -48
  108. package/src/createSuspenseInfiniteQuery.ts +165 -114
  109. package/src/createSuspenseQuery.ts +67 -41
  110. package/src/defineReactor.test.ts +70 -0
  111. package/src/defineReactor.ts +150 -0
  112. package/src/{createAuthHooks.ts → hooks/createAuthHooks.ts} +17 -98
  113. package/src/hooks/index.ts +4 -0
  114. package/src/hooks/useActorInfiniteQuery.ts +44 -30
  115. package/src/hooks/useActorMethod.ts +62 -53
  116. package/src/hooks/useActorMutation.ts +47 -30
  117. package/src/hooks/useActorQuery.ts +36 -32
  118. package/src/hooks/useActorSuspenseInfiniteQuery.ts +56 -30
  119. package/src/hooks/useActorSuspenseQuery.ts +42 -32
  120. package/src/index.ts +3 -1
  121. package/src/types.ts +76 -71
  122. package/src/utils.test.ts +14 -0
  123. package/src/utils.ts +15 -2
  124. package/dist/createAuthHooks.d.ts.map +0 -1
  125. package/dist/createAuthHooks.js.map +0 -1
@@ -29,6 +29,7 @@ import type {
29
29
  BaseActor,
30
30
  TransformKey,
31
31
  ReactorReturnOk,
32
+ ReactorQueryData,
32
33
  ReactorReturnErr,
33
34
  } from "@ic-reactor/core"
34
35
  import {
@@ -43,22 +44,22 @@ import {
43
44
  } from "@tanstack/react-query"
44
45
  import { CallConfig } from "@icp-sdk/core/agent"
45
46
  import { NoInfer } from "./types"
46
- import { mergeFactoryQueryKey } from "./utils"
47
+ import { mergeFactoryQueryKey, normalizeQueryData } from "./utils"
47
48
 
48
49
  type InfiniteQueryFactoryFn<
49
- A,
50
- M extends FunctionName<A>,
51
- T extends TransformKey,
50
+ Service,
51
+ Method extends FunctionName<Service>,
52
+ Transform extends TransformKey,
52
53
  TPageParam,
53
- TSelected,
54
+ Selected,
54
55
  > = {
55
56
  (
56
- getArgs: (pageParam: TPageParam) => ReactorArgs<A, M, T>
57
+ getArgs: (pageParam: TPageParam) => ReactorArgs<Service, Method, Transform>
57
58
  ): InfiniteQueryResult<
58
- InfiniteQueryPageData<A, M, T>,
59
+ InfiniteQueryPageData<Service, Method, Transform>,
59
60
  TPageParam,
60
- TSelected,
61
- InfiniteQueryError<A, M, T>
61
+ Selected,
62
+ InfiniteQueryError<Service, Method, Transform>
62
63
  >
63
64
  }
64
65
 
@@ -68,17 +69,17 @@ type InfiniteQueryFactoryFn<
68
69
 
69
70
  /** The raw page data type returned by the query function */
70
71
  export type InfiniteQueryPageData<
71
- A = BaseActor,
72
- M extends FunctionName<A> = FunctionName<A>,
73
- T extends TransformKey = "candid",
74
- > = ReactorReturnOk<A, M, T>
72
+ Service = BaseActor,
73
+ Method extends FunctionName<Service> = FunctionName<Service>,
74
+ Transform extends TransformKey = "candid",
75
+ > = ReactorQueryData<ReactorReturnOk<Service, Method, Transform>>
75
76
 
76
77
  /** The error type for infinite queries */
77
78
  export type InfiniteQueryError<
78
- A = BaseActor,
79
- M extends FunctionName<A> = FunctionName<A>,
80
- T extends TransformKey = "candid",
81
- > = ReactorReturnErr<A, M, T>
79
+ Service = BaseActor,
80
+ Method extends FunctionName<Service> = FunctionName<Service>,
81
+ Transform extends TransformKey = "candid",
82
+ > = ReactorReturnErr<Service, Method, Transform>
82
83
 
83
84
  // ============================================================================
84
85
  // Configuration Types
@@ -90,30 +91,33 @@ export type InfiniteQueryError<
90
91
  * infinite-query options at the create level (e.g. refetchInterval,
91
92
  * refetchOnMount, refetchOnWindowFocus, retry, gcTime, networkMode).
92
93
  *
93
- * @template A - The actor interface type
94
- * @template M - The method name on the actor
95
- * @template T - The transformation key (identity, display, etc.)
94
+ * @template Service - The actor interface type
95
+ * @template Method - The method name on the actor
96
+ * @template Transform - The transformation key (identity, display, etc.)
96
97
  * @template TPageParam - The type of the page parameter
97
- * @template TSelected - The type returned after select transformation
98
+ * @template Selected - The type returned after select transformation
98
99
  */
99
100
  export interface InfiniteQueryConfig<
100
- A = BaseActor,
101
- M extends FunctionName<A> = FunctionName<A>,
102
- T extends TransformKey = "candid",
101
+ Service = BaseActor,
102
+ Method extends FunctionName<Service> = FunctionName<Service>,
103
+ Transform extends TransformKey = "candid",
103
104
  TPageParam = unknown,
104
- TSelected = InfiniteData<InfiniteQueryPageData<A, M, T>, TPageParam>,
105
+ Selected = InfiniteData<
106
+ InfiniteQueryPageData<Service, Method, Transform>,
107
+ TPageParam
108
+ >,
105
109
  > extends Omit<
106
110
  InfiniteQueryObserverOptions<
107
- InfiniteQueryPageData<A, M, T>,
108
- InfiniteQueryError<A, M, T>,
109
- TSelected,
111
+ InfiniteQueryPageData<Service, Method, Transform>,
112
+ InfiniteQueryError<Service, Method, Transform>,
113
+ Selected,
110
114
  QueryKey,
111
115
  TPageParam
112
116
  >,
113
117
  "queryKey" | "queryFn"
114
118
  > {
115
119
  /** The method to call on the canister */
116
- functionName: M
120
+ functionName: Method
117
121
  /** Call configuration for the actor method */
118
122
  callConfig?: CallConfig
119
123
  /** Custom query key (optional, auto-generated if not provided) */
@@ -121,18 +125,18 @@ export interface InfiniteQueryConfig<
121
125
  /** Initial page parameter */
122
126
  initialPageParam: TPageParam
123
127
  /** Function to get args from page parameter */
124
- getArgs: (pageParam: TPageParam) => ReactorArgs<A, M, T>
128
+ getArgs: (pageParam: TPageParam) => ReactorArgs<Service, Method, Transform>
125
129
  /** Function to determine next page parameter */
126
130
  getNextPageParam: (
127
- lastPage: InfiniteQueryPageData<A, M, T>,
128
- allPages: InfiniteQueryPageData<A, M, T>[],
131
+ lastPage: InfiniteQueryPageData<Service, Method, Transform>,
132
+ allPages: InfiniteQueryPageData<Service, Method, Transform>[],
129
133
  lastPageParam: TPageParam,
130
134
  allPageParams: TPageParam[]
131
135
  ) => TPageParam | undefined | null
132
136
  /** Function to determine previous page parameter (for bi-directional) */
133
137
  getPreviousPageParam?: (
134
- firstPage: InfiniteQueryPageData<A, M, T>,
135
- allPages: InfiniteQueryPageData<A, M, T>[],
138
+ firstPage: InfiniteQueryPageData<Service, Method, Transform>,
139
+ allPages: InfiniteQueryPageData<Service, Method, Transform>[],
136
140
  firstPageParam: TPageParam,
137
141
  allPageParams: TPageParam[]
138
142
  ) => TPageParam | undefined | null
@@ -142,19 +146,25 @@ export interface InfiniteQueryConfig<
142
146
  * Configuration for createActorInfiniteQueryFactory (without initialPageParam, getArgs determined at call time).
143
147
  */
144
148
  export type InfiniteQueryFactoryConfig<
145
- A = BaseActor,
146
- M extends FunctionName<A> = FunctionName<A>,
147
- T extends TransformKey = "candid",
149
+ Service = BaseActor,
150
+ Method extends FunctionName<Service> = FunctionName<Service>,
151
+ Transform extends TransformKey = "candid",
148
152
  TPageParam = unknown,
149
- TSelected = InfiniteData<InfiniteQueryPageData<A, M, T>, TPageParam>,
150
- > = Omit<InfiniteQueryConfig<A, M, T, TPageParam, TSelected>, "getArgs"> & {
153
+ Selected = InfiniteData<
154
+ InfiniteQueryPageData<Service, Method, Transform>,
155
+ TPageParam
156
+ >,
157
+ > = Omit<
158
+ InfiniteQueryConfig<Service, Method, Transform, TPageParam, Selected>,
159
+ "getArgs"
160
+ > & {
151
161
  /**
152
162
  * Optional key-args derivation for factory calls.
153
163
  * Receives the resolved args from `getArgs(initialPageParam)` and should return
154
164
  * a stable serializable representation of the logical query identity
155
165
  * (typically excluding pagination/cursor fields).
156
166
  */
157
- getKeyArgs?: (args: ReactorArgs<A, M, T>) => unknown
167
+ getKeyArgs?: (args: ReactorArgs<Service, Method, Transform>) => unknown
158
168
  }
159
169
 
160
170
  // ============================================================================
@@ -167,16 +177,16 @@ export type InfiniteQueryFactoryConfig<
167
177
  export interface UseInfiniteQueryWithSelect<
168
178
  TPageData,
169
179
  TPageParam,
170
- TSelected = InfiniteData<TPageData, TPageParam>,
180
+ Selected = InfiniteData<TPageData, TPageParam>,
171
181
  TError = Error,
172
182
  > {
173
- // Overload 1: Without select - returns TSelected
183
+ // Overload 1: Without select - returns Selected
174
184
  (
175
185
  options?: Omit<
176
186
  UseInfiniteQueryOptions<
177
187
  TPageData,
178
188
  TError,
179
- TSelected,
189
+ Selected,
180
190
  QueryKey,
181
191
  TPageParam
182
192
  >,
@@ -187,10 +197,10 @@ export interface UseInfiniteQueryWithSelect<
187
197
  | "getNextPageParam"
188
198
  | "getPreviousPageParam"
189
199
  >
190
- ): UseInfiniteQueryResult<TSelected, TError>
200
+ ): UseInfiniteQueryResult<Selected, TError>
191
201
 
192
202
  // Overload 2: With select - chains on top and returns TFinal
193
- <TFinal = TSelected>(
203
+ <TFinal = Selected>(
194
204
  options: Omit<
195
205
  UseInfiniteQueryOptions<TPageData, TError, TFinal, QueryKey, TPageParam>,
196
206
  | "queryKey"
@@ -200,7 +210,7 @@ export interface UseInfiniteQueryWithSelect<
200
210
  | "getNextPageParam"
201
211
  | "getPreviousPageParam"
202
212
  > & {
203
- select: (data: TSelected) => TFinal
213
+ select: (data: Selected) => TFinal
204
214
  }
205
215
  ): UseInfiniteQueryResult<TFinal, TError>
206
216
  }
@@ -214,23 +224,23 @@ export interface UseInfiniteQueryWithSelect<
214
224
  *
215
225
  * @template TPageData - The raw page data type
216
226
  * @template TPageParam - The page parameter type
217
- * @template TSelected - The type after select transformation
227
+ * @template Selected - The type after select transformation
218
228
  * @template TError - The error type
219
229
  */
220
230
  export interface InfiniteQueryResult<
221
231
  TPageData,
222
232
  TPageParam,
223
- TSelected = InfiniteData<TPageData, TPageParam>,
233
+ Selected = InfiniteData<TPageData, TPageParam>,
224
234
  TError = Error,
225
235
  > {
226
236
  /** Fetch first page in loader (uses ensureQueryData for cache-first) */
227
- fetch: () => Promise<TSelected>
237
+ fetch: () => Promise<Selected>
228
238
 
229
239
  /** React hook for components - supports pagination */
230
240
  useInfiniteQuery: UseInfiniteQueryWithSelect<
231
241
  TPageData,
232
242
  TPageParam,
233
- TSelected,
243
+ Selected,
234
244
  TError
235
245
  >
236
246
 
@@ -245,8 +255,8 @@ export interface InfiniteQueryResult<
245
255
  * Returns undefined if data is not in cache.
246
256
  */
247
257
  getCacheData: {
248
- (): TSelected | undefined
249
- <TFinal>(select: (data: TSelected) => TFinal): TFinal | undefined
258
+ (): Selected | undefined
259
+ <TFinal>(select: (data: Selected) => TFinal): TFinal | undefined
250
260
  }
251
261
  }
252
262
 
@@ -255,22 +265,25 @@ export interface InfiniteQueryResult<
255
265
  // ============================================================================
256
266
 
257
267
  const createInfiniteQueryImpl = <
258
- A,
259
- M extends FunctionName<A> = FunctionName<A>,
260
- T extends TransformKey = "candid",
268
+ Service,
269
+ Method extends FunctionName<Service> = FunctionName<Service>,
270
+ Transform extends TransformKey = "candid",
261
271
  TPageParam = unknown,
262
- TSelected = InfiniteData<InfiniteQueryPageData<A, M, T>, TPageParam>,
272
+ Selected = InfiniteData<
273
+ InfiniteQueryPageData<Service, Method, Transform>,
274
+ TPageParam
275
+ >,
263
276
  >(
264
- reactor: Reactor<A, T>,
265
- config: InfiniteQueryConfig<A, M, T, TPageParam, TSelected>
277
+ reactor: Reactor<Service, Transform>,
278
+ config: InfiniteQueryConfig<Service, Method, Transform, TPageParam, Selected>
266
279
  ): InfiniteQueryResult<
267
- InfiniteQueryPageData<A, M, T>,
280
+ InfiniteQueryPageData<Service, Method, Transform>,
268
281
  TPageParam,
269
- TSelected,
270
- InfiniteQueryError<A, M, T>
282
+ Selected,
283
+ InfiniteQueryError<Service, Method, Transform>
271
284
  > => {
272
- type TPageData = InfiniteQueryPageData<A, M, T>
273
- type TError = InfiniteQueryError<A, M, T>
285
+ type TPageData = InfiniteQueryPageData<Service, Method, Transform>
286
+ type TError = InfiniteQueryError<Service, Method, Transform>
274
287
  type TInfiniteData = InfiniteData<TPageData, TPageParam>
275
288
 
276
289
  const {
@@ -310,7 +323,9 @@ const createInfiniteQueryImpl = <
310
323
  args,
311
324
  callConfig,
312
325
  })
313
- return result
326
+ return normalizeQueryData<ReactorReturnOk<Service, Method, Transform>>(
327
+ result as ReactorReturnOk<Service, Method, Transform>
328
+ )
314
329
  }
315
330
 
316
331
  // Get infinite query options for fetchInfiniteQuery
@@ -328,14 +343,13 @@ const createInfiniteQueryImpl = <
328
343
  })
329
344
 
330
345
  // Fetch function for loaders (cache-first, fetches first page)
331
- const fetch = async (): Promise<TSelected> => {
346
+ const fetch = async (): Promise<Selected> => {
332
347
  // Check cache first
333
348
  const cachedData = reactor.queryClient.getQueryData(getQueryKey()) as
334
- | TInfiniteData
335
- | undefined
349
+ TInfiniteData | undefined
336
350
 
337
351
  if (cachedData !== undefined) {
338
- return select ? select(cachedData) : (cachedData as TSelected)
352
+ return select ? select(cachedData) : (cachedData as Selected)
339
353
  }
340
354
 
341
355
  // Fetch if not in cache
@@ -344,14 +358,14 @@ const createInfiniteQueryImpl = <
344
358
  )
345
359
 
346
360
  // Result is already InfiniteData format
347
- return select ? select(result) : (result as unknown as TSelected)
361
+ return select ? select(result) : (result as unknown as Selected)
348
362
  }
349
363
 
350
364
  // Implementation
351
365
  const useInfiniteQueryHook: UseInfiniteQueryWithSelect<
352
366
  TPageData,
353
367
  TPageParam,
354
- TSelected,
368
+ Selected,
355
369
  TError
356
370
  > = (options: any): any => {
357
371
  // Chain the selects: raw -> config.select -> options.select
@@ -387,7 +401,7 @@ const createInfiniteQueryImpl = <
387
401
  }
388
402
 
389
403
  // Get data from cache without fetching
390
- const getCacheData: any = (selectFn?: (data: TSelected) => any) => {
404
+ const getCacheData: any = (selectFn?: (data: Selected) => any) => {
391
405
  const queryKey = getQueryKey()
392
406
  const cachedRawData = reactor.queryClient.getQueryData(
393
407
  queryKey
@@ -400,7 +414,7 @@ const createInfiniteQueryImpl = <
400
414
  // Apply config.select to raw cache data
401
415
  const selectedData = (
402
416
  select ? select(cachedRawData) : cachedRawData
403
- ) as TSelected
417
+ ) as Selected
404
418
 
405
419
  // Apply optional select parameter
406
420
  if (selectFn) {
@@ -424,23 +438,38 @@ const createInfiniteQueryImpl = <
424
438
  // ============================================================================
425
439
 
426
440
  export function createInfiniteQuery<
427
- A,
428
- T extends TransformKey,
429
- M extends FunctionName<A> = FunctionName<A>,
441
+ Service,
442
+ Transform extends TransformKey,
443
+ Method extends FunctionName<Service> = FunctionName<Service>,
430
444
  TPageParam = unknown,
431
- TSelected = InfiniteData<InfiniteQueryPageData<A, M, T>, TPageParam>,
445
+ Selected = InfiniteData<
446
+ InfiniteQueryPageData<Service, Method, Transform>,
447
+ TPageParam
448
+ >,
432
449
  >(
433
- reactor: Reactor<A, T>,
434
- config: InfiniteQueryConfig<NoInfer<A>, M, T, TPageParam, TSelected>
450
+ reactor: Reactor<Service, Transform>,
451
+ config: InfiniteQueryConfig<
452
+ NoInfer<Service>,
453
+ Method,
454
+ Transform,
455
+ TPageParam,
456
+ Selected
457
+ >
435
458
  ): InfiniteQueryResult<
436
- InfiniteQueryPageData<A, M, T>,
459
+ InfiniteQueryPageData<Service, Method, Transform>,
437
460
  TPageParam,
438
- TSelected,
439
- InfiniteQueryError<A, M, T>
461
+ Selected,
462
+ InfiniteQueryError<Service, Method, Transform>
440
463
  > {
441
464
  return createInfiniteQueryImpl(
442
465
  reactor,
443
- config as InfiniteQueryConfig<A, M, T, TPageParam, TSelected>
466
+ config as InfiniteQueryConfig<
467
+ Service,
468
+ Method,
469
+ Transform,
470
+ TPageParam,
471
+ Selected
472
+ >
444
473
  )
445
474
  }
446
475
 
@@ -452,11 +481,11 @@ export function createInfiniteQuery<
452
481
  * Create an infinite query factory that accepts getArgs at call time.
453
482
  * Useful when pagination logic varies by context.
454
483
  *
455
- * @template A - The actor interface type
456
- * @template M - The method name on the actor
457
- * @template T - The transformation key (identity, display, etc.)
484
+ * @template Service - The actor interface type
485
+ * @template Method - The method name on the actor
486
+ * @template Transform - The transformation key (identity, display, etc.)
458
487
  * @template TPageParam - The page parameter type
459
- * @template TSelected - The type returned after select transformation
488
+ * @template Selected - The type returned after select transformation
460
489
  *
461
490
  * @param reactor - The Reactor instance
462
491
  * @param config - Infinite query configuration (without getArgs)
@@ -479,25 +508,52 @@ export function createInfiniteQuery<
479
508
  */
480
509
 
481
510
  export function createInfiniteQueryFactory<
482
- A,
483
- T extends TransformKey,
484
- M extends FunctionName<A> = FunctionName<A>,
511
+ Service,
512
+ Transform extends TransformKey,
513
+ Method extends FunctionName<Service> = FunctionName<Service>,
485
514
  TPageParam = unknown,
486
- TSelected = InfiniteData<InfiniteQueryPageData<A, M, T>, TPageParam>,
515
+ Selected = InfiniteData<
516
+ InfiniteQueryPageData<Service, Method, Transform>,
517
+ TPageParam
518
+ >,
487
519
  >(
488
- reactor: Reactor<A, T>,
489
- config: InfiniteQueryFactoryConfig<NoInfer<A>, M, T, TPageParam, TSelected>
490
- ): InfiniteQueryFactoryFn<A, M, T, TPageParam, TSelected> {
491
- const factory: InfiniteQueryFactoryFn<A, M, T, TPageParam, TSelected> = (
492
- getArgs: (pageParam: TPageParam) => ReactorArgs<A, M, T>
520
+ reactor: Reactor<Service, Transform>,
521
+ config: InfiniteQueryFactoryConfig<
522
+ NoInfer<Service>,
523
+ Method,
524
+ Transform,
525
+ TPageParam,
526
+ Selected
527
+ >
528
+ ): InfiniteQueryFactoryFn<Service, Method, Transform, TPageParam, Selected> {
529
+ const factory: InfiniteQueryFactoryFn<
530
+ Service,
531
+ Method,
532
+ Transform,
533
+ TPageParam,
534
+ Selected
535
+ > = (
536
+ getArgs: (pageParam: TPageParam) => ReactorArgs<Service, Method, Transform>
493
537
  ) => {
494
538
  const initialArgs = getArgs(config.initialPageParam)
495
539
  const keyArgs = config.getKeyArgs?.(initialArgs) ?? initialArgs
496
540
  const queryKey = mergeFactoryQueryKey(config.queryKey, undefined, keyArgs)
497
541
 
498
- return createInfiniteQueryImpl<A, M, T, TPageParam, TSelected>(reactor, {
542
+ return createInfiniteQueryImpl<
543
+ Service,
544
+ Method,
545
+ Transform,
546
+ TPageParam,
547
+ Selected
548
+ >(reactor, {
499
549
  ...(({ getKeyArgs: _getKeyArgs, ...rest }) => rest)(
500
- config as InfiniteQueryFactoryConfig<A, M, T, TPageParam, TSelected>
550
+ config as InfiniteQueryFactoryConfig<
551
+ Service,
552
+ Method,
553
+ Transform,
554
+ TPageParam,
555
+ Selected
556
+ >
501
557
  ),
502
558
  queryKey,
503
559
  getArgs,
@@ -3,6 +3,8 @@
3
3
  *
4
4
  * Creates unified mutation hooks for any canister method.
5
5
  * Works with any Reactor instance.
6
+ * Use this when one mutation should support both React hooks and imperative
7
+ * execution outside React.
6
8
  *
7
9
  * @example
8
10
  * const transferMutation = createMutation(reactor, {
@@ -12,6 +14,15 @@
12
14
  *
13
15
  * // In component
14
16
  * const { mutate, isPending } = transferMutation.useMutation()
17
+ *
18
+ * @example
19
+ * const transferMutation = createMutation(reactor, {
20
+ * functionName: "transfer",
21
+ * onCanisterError: (err) => console.error(err.code),
22
+ * })
23
+ *
24
+ * // Outside React (loader/service/script)
25
+ * await transferMutation.execute([{ to: "aaaaa-aa", amount: "1000" }])
15
26
  */
16
27
 
17
28
  import { useMutation } from "@tanstack/react-query"
@@ -51,13 +62,13 @@ async function invalidateAll(
51
62
  // ============================================================================
52
63
 
53
64
  const createMutationImpl = <
54
- A,
55
- M extends FunctionName<A> = FunctionName<A>,
56
- T extends TransformKey = "candid",
65
+ Service,
66
+ Method extends FunctionName<Service> = FunctionName<Service>,
67
+ Transform extends TransformKey = "candid",
57
68
  >(
58
- reactor: Reactor<A, T>,
59
- config: MutationConfig<A, M, T>
60
- ): MutationResult<A, M, T> => {
69
+ reactor: Reactor<Service, Transform>,
70
+ config: MutationConfig<Service, Method, Transform>
71
+ ): MutationResult<Service, Method, Transform> => {
61
72
  const {
62
73
  functionName,
63
74
  callConfig,
@@ -74,8 +85,8 @@ const createMutationImpl = <
74
85
  * and there is no double-invalidation.
75
86
  */
76
87
  const callFn = (
77
- args: ReactorArgs<A, M, T>
78
- ): Promise<ReactorReturnOk<A, M, T>> =>
88
+ args: ReactorArgs<Service, Method, Transform>
89
+ ): Promise<ReactorReturnOk<Service, Method, Transform>> =>
79
90
  reactor.callMethod({ functionName, args, callConfig })
80
91
 
81
92
  /**
@@ -84,8 +95,8 @@ const createMutationImpl = <
84
95
  * Use this in route loaders, scripts, or server-side code.
85
96
  */
86
97
  const execute = async (
87
- args: ReactorArgs<A, M, T>
88
- ): Promise<ReactorReturnOk<A, M, T>> => {
98
+ args: ReactorArgs<Service, Method, Transform>
99
+ ): Promise<ReactorReturnOk<Service, Method, Transform>> => {
89
100
  const result = await callFn(args)
90
101
  if (factoryInvalidateQueries) {
91
102
  await invalidateAll(reactor.queryClient, factoryInvalidateQueries)
@@ -94,7 +105,9 @@ const createMutationImpl = <
94
105
  }
95
106
 
96
107
  // Hook implementation
97
- const useMutationHook = (options?: MutationHookOptions<A, M, T>) => {
108
+ const useMutationHook = (
109
+ options?: MutationHookOptions<Service, Method, Transform>
110
+ ) => {
98
111
  const baseOptions = reactor.getQueryOptions({ functionName })
99
112
  const {
100
113
  invalidateQueries: hookInvalidateQueries,
@@ -145,12 +158,15 @@ const createMutationImpl = <
145
158
  // ============================================================================
146
159
 
147
160
  export function createMutation<
148
- A,
149
- T extends TransformKey,
150
- M extends FunctionName<A> = FunctionName<A>,
161
+ Service,
162
+ Transform extends TransformKey,
163
+ Method extends FunctionName<Service> = FunctionName<Service>,
151
164
  >(
152
- reactor: Reactor<A, T>,
153
- config: MutationConfig<NoInfer<A>, M, T>
154
- ): MutationResult<A, M, T> {
155
- return createMutationImpl(reactor, config as MutationConfig<A, M, T>)
165
+ reactor: Reactor<Service, Transform>,
166
+ config: MutationConfig<NoInfer<Service>, Method, Transform>
167
+ ): MutationResult<Service, Method, Transform> {
168
+ return createMutationImpl(
169
+ reactor,
170
+ config as MutationConfig<Service, Method, Transform>
171
+ )
156
172
  }