@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,189 +0,0 @@
1
- import { useSyncExternalStore, useEffect, useRef, useMemo } from "react"
2
- import type { AuthenticationManager } from "../auth/authentication-manager.js"
3
- import type { AuthState, AuthenticationSignInOptions } from "../auth/types.js"
4
- import type { AgentState } from "@ic-reactor/core"
5
- import type { Principal } from "@icp-sdk/core/principal"
6
- import type { Identity } from "@icp-sdk/core/agent"
7
-
8
- export interface UseAuthReturn {
9
- authenticate: () => Promise<Identity | undefined>
10
- login: (options?: AuthenticationSignInOptions) => Promise<void>
11
- logout: (options?: { returnTo?: string }) => Promise<void>
12
- isAuthenticated: boolean
13
- isAuthenticating: boolean
14
- /**
15
- * The signed-in user's principal, or `null` while signed out. A signed-out
16
- * session still holds an anonymous `identity`, and its principal is not
17
- * returned here.
18
- */
19
- principal: Principal | null
20
- identity: Identity | null
21
- error: Error | undefined
22
- }
23
-
24
- export interface CreateAuthHooksReturn {
25
- useAgentState: () => AgentState
26
- useUserPrincipal: () => Principal | null
27
- useAuth: () => UseAuthReturn
28
- }
29
-
30
- /**
31
- * The principal both hooks return.
32
- *
33
- * `authenticate()` and `logout()` leave the client's anonymous identity in
34
- * `authState.identity` with `isAuthenticated: false`, so deriving the principal
35
- * from the identity alone reported `2vxsx-fae` for a signed-out user, and
36
- * `principal ? <SignedIn /> : <SignedOut />` rendered the signed-in branch.
37
- * Memoized on the identity, because `getPrincipal()` may build a new object on
38
- * each call and the result is often a hook dependency.
39
- */
40
- function usePrincipal(
41
- isAuthenticated: boolean,
42
- identity: Identity | null
43
- ): Principal | null {
44
- return useMemo(
45
- () => (isAuthenticated && identity ? identity.getPrincipal() : null),
46
- [isAuthenticated, identity]
47
- )
48
- }
49
-
50
- /**
51
- * Create authentication hooks for managing user sessions with Internet Identity.
52
- *
53
- * @example
54
- * const { useAuth, useUserPrincipal, useAgentState } = createAuthHooks(authentication)
55
- *
56
- * function App() {
57
- * const { login, logout, principal, isAuthenticated } = useAuth()
58
- *
59
- * return isAuthenticated
60
- * ? <button onClick={() => logout()}>Logout {principal?.toText()}</button>
61
- * : <button onClick={() => login()}>Login with II</button>
62
- * }
63
- */
64
- export const createAuthHooks = (
65
- authentication: AuthenticationManager
66
- ): CreateAuthHooksReturn => {
67
- // Passing a ClientManager here is the natural mistake — it is what
68
- // `AuthenticationManager` is built from, and the two are adjacent in every
69
- // setup snippet. TypeScript rejects it, but a JS caller got no error until
70
- // render, where it surfaced as "Cannot destructure property 'isAuthenticated'
71
- // of 'useAuthState(...)' as it is undefined" — which names neither the cause
72
- // nor this function.
73
- if (
74
- !authentication ||
75
- typeof authentication.subscribeAuthState !== "function"
76
- ) {
77
- throw new TypeError(
78
- "[ic-reactor] createAuthHooks() expects an AuthenticationManager, not a " +
79
- "ClientManager. Build one first: " +
80
- "`new AuthenticationManager({ clientManager })`, or take it from " +
81
- "`defineReactor(...).authentication`."
82
- )
83
- }
84
-
85
- const { clientManager } = authentication
86
- /**
87
- * Subscribe to agent state changes.
88
- * Returns the current agent state (agent, isInitialized, etc.)
89
- */
90
- const useAgentState = (): AgentState =>
91
- useSyncExternalStore(
92
- (callback) => clientManager.subscribeAgentState(callback),
93
- () => clientManager.agentState,
94
- // Server snapshot - provide initial state for SSR
95
- () => clientManager.agentState
96
- )
97
-
98
- /**
99
- * Subscribe to authentication state changes.
100
- * Returns auth state (isAuthenticated, isAuthenticating, identity, error)
101
- */
102
- const useAuthState = (): AuthState =>
103
- useSyncExternalStore(
104
- (callback) => authentication.subscribeAuthState(callback),
105
- () => authentication.authState,
106
- // Server snapshot - provide initial state for SSR
107
- () => authentication.authState
108
- )
109
-
110
- /**
111
- * Main authentication hook that provides login/logout methods and auth state.
112
- * Automatically initializes the session on first use, restoring any previous session.
113
- *
114
- * @example
115
- * function AuthButton() {
116
- * const { login, logout, isAuthenticated, isAuthenticating } = useAuth()
117
- *
118
- * if (isAuthenticated) {
119
- * return <button onClick={() => logout()}>Logout</button>
120
- * }
121
- * return (
122
- * <button onClick={() => login()} disabled={isAuthenticating}>
123
- * {isAuthenticating ? "Connecting..." : "Login"}
124
- * </button>
125
- * )
126
- * }
127
- */
128
- const useAuth = (): UseAuthReturn => {
129
- const { login, logout, authenticate } = authentication
130
- const { isAuthenticated, isAuthenticating, identity, error } =
131
- useAuthState()
132
-
133
- // Track if we've already initialized to avoid duplicate calls
134
- const initializedRef = useRef(false)
135
-
136
- // Auto-initialize on first mount to restore previous session.
137
- // `prepareClient` also warms up the AuthClient so a later `login()` can
138
- // open the identity provider window inside the click handler.
139
- useEffect(() => {
140
- if (!initializedRef.current) {
141
- initializedRef.current = true
142
- authentication
143
- .prepareClient()
144
- .catch(() => undefined)
145
- .then(() => clientManager.initialize())
146
- .then(() => authentication.authenticate())
147
- // Failures are already reflected in authState/agentState; without
148
- // this the rejection escapes as an unhandled promise rejection.
149
- .catch(() => undefined)
150
- }
151
- }, [])
152
-
153
- const principal = usePrincipal(isAuthenticated, identity)
154
-
155
- return {
156
- authenticate,
157
- login,
158
- logout,
159
- isAuthenticated,
160
- isAuthenticating,
161
- principal,
162
- identity,
163
- error,
164
- }
165
- }
166
-
167
- /**
168
- * Get the current user's Principal.
169
- * Returns null if not authenticated, including while the signed-out session
170
- * holds the anonymous identity.
171
- *
172
- * @example
173
- * function UserInfo() {
174
- * const principal = useUserPrincipal()
175
- * if (!principal) return null
176
- * return <span>Logged in as: {principal.toText()}</span>
177
- * }
178
- */
179
- const useUserPrincipal = (): Principal | null => {
180
- const { isAuthenticated, identity } = useAuthState()
181
- return usePrincipal(isAuthenticated, identity)
182
- }
183
-
184
- return {
185
- useAuth,
186
- useAgentState,
187
- useUserPrincipal,
188
- }
189
- }
@@ -1,103 +0,0 @@
1
- // ============================================================================
2
- // Hooks
3
- //
4
- // These are the RAW hooks: they take the reactor as a property. They are
5
- // therefore exported as `useReactor*` only — the `useActor*` names belong to
6
- // the bound hooks `createActorHooks` returns, which take no reactor. Aliasing
7
- // the raw implementations under the bound names would hand a caller following
8
- // the documented `useActorQuery({ functionName })` shape an undefined reactor.
9
- // ============================================================================
10
-
11
- // useActorQuery / useReactorQuery
12
- export { useActorQuery as useReactorQuery } from "./useActorQuery.js"
13
-
14
- // useActorMutation / useReactorMutation
15
- export { useActorMutation as useReactorMutation } from "./useActorMutation.js"
16
-
17
- // useActorSuspenseQuery / useReactorSuspenseQuery
18
- export { useActorSuspenseQuery as useReactorSuspenseQuery } from "./useActorSuspenseQuery.js"
19
-
20
- // useActorInfiniteQuery / useReactorInfiniteQuery
21
- export { useActorInfiniteQuery as useReactorInfiniteQuery } from "./useActorInfiniteQuery.js"
22
-
23
- // useActorSuspenseInfiniteQuery / useReactorSuspenseInfiniteQuery
24
- export { useActorSuspenseInfiniteQuery as useReactorSuspenseInfiniteQuery } from "./useActorSuspenseInfiniteQuery.js"
25
-
26
- // useActorMethod / useReactorMethod
27
- export {
28
- useActorMethod,
29
- useActorMethod as useReactorMethod,
30
- createActorMethodHooks,
31
- } from "./useActorMethod.js"
32
-
33
- // createAuthHooks
34
- export { createAuthHooks } from "./createAuthHooks.js"
35
- export type { CreateAuthHooksReturn, UseAuthReturn } from "./createAuthHooks.js"
36
-
37
- // ============================================================================
38
- // Types - UseReactor* (with reactor parameter)
39
- // ============================================================================
40
-
41
- export type {
42
- UseActorQueryParameters as UseReactorQueryParameters,
43
- UseActorQueryResult as UseReactorQueryResult,
44
- } from "./useActorQuery.js"
45
-
46
- export type {
47
- UseActorMutationParameters as UseReactorMutationParameters,
48
- UseActorMutationResult as UseReactorMutationResult,
49
- } from "./useActorMutation.js"
50
-
51
- export type {
52
- UseActorSuspenseQueryParameters as UseReactorSuspenseQueryParameters,
53
- UseActorSuspenseQueryResult as UseReactorSuspenseQueryResult,
54
- } from "./useActorSuspenseQuery.js"
55
-
56
- export type {
57
- UseActorInfiniteQueryParameters as UseReactorInfiniteQueryParameters,
58
- UseActorInfiniteQueryResult as UseReactorInfiniteQueryResult,
59
- } from "./useActorInfiniteQuery.js"
60
-
61
- export type {
62
- UseActorSuspenseInfiniteQueryParameters as UseReactorSuspenseInfiniteQueryParameters,
63
- UseActorSuspenseInfiniteQueryResult as UseReactorSuspenseInfiniteQueryResult,
64
- } from "./useActorSuspenseInfiniteQuery.js"
65
-
66
- export type {
67
- UseActorMethodParameters as UseReactorMethodParameters,
68
- UseActorMethodResult as UseReactorMethodResult,
69
- } from "./useActorMethod.js"
70
-
71
- // ============================================================================
72
- // Types - UseActor* (without reactor parameter, for use with createActorHooks)
73
- // ============================================================================
74
-
75
- export type {
76
- UseActorQueryConfig as UseActorQueryParameters,
77
- UseActorQueryResult,
78
- } from "./useActorQuery.js"
79
-
80
- export type {
81
- UseActorMutationConfig as UseActorMutationParameters,
82
- UseActorMutationResult,
83
- } from "./useActorMutation.js"
84
-
85
- export type {
86
- UseActorSuspenseQueryConfig as UseActorSuspenseQueryParameters,
87
- UseActorSuspenseQueryResult,
88
- } from "./useActorSuspenseQuery.js"
89
-
90
- export type {
91
- UseActorInfiniteQueryConfig as UseActorInfiniteQueryParameters,
92
- UseActorInfiniteQueryResult,
93
- } from "./useActorInfiniteQuery.js"
94
-
95
- export type {
96
- UseActorSuspenseInfiniteQueryConfig as UseActorSuspenseInfiniteQueryParameters,
97
- UseActorSuspenseInfiniteQueryResult,
98
- } from "./useActorSuspenseInfiniteQuery.js"
99
-
100
- export type {
101
- UseActorMethodConfig as UseActorMethodParameters,
102
- UseActorMethodResult,
103
- } from "./useActorMethod.js"
@@ -1,205 +0,0 @@
1
- import { useMemo, useCallback } from "react"
2
- import {
3
- QueryKey,
4
- useInfiniteQuery,
5
- UseInfiniteQueryResult,
6
- UseInfiniteQueryOptions,
7
- InfiniteData,
8
- } from "@tanstack/react-query"
9
- import {
10
- FunctionName,
11
- Reactor,
12
- TransformKey,
13
- ReactorArgs,
14
- ReactorReturnOk,
15
- ReactorQueryData,
16
- ReactorReturnErr,
17
- } from "@ic-reactor/core"
18
- import { CallConfig } from "@icp-sdk/core/agent"
19
- import { mergeFactoryQueryKey, normalizeQueryData } from "../utils.js"
20
-
21
- /**
22
- * Parameters for useActorInfiniteQuery hook.
23
- * Extends react-query's UseInfiniteQueryOptions with custom reactor params.
24
- */
25
- export interface UseActorInfiniteQueryParameters<
26
- Service,
27
- Method extends FunctionName<Service>,
28
- Transform extends TransformKey = "candid",
29
- TPageParam = unknown,
30
- Selected = InfiniteData<
31
- ReactorQueryData<ReactorReturnOk<Service, Method, Transform>>,
32
- TPageParam
33
- >,
34
- > extends Omit<
35
- UseInfiniteQueryOptions<
36
- ReactorQueryData<ReactorReturnOk<Service, Method, Transform>>,
37
- ReactorReturnErr<Service, Method, Transform>,
38
- Selected,
39
- QueryKey,
40
- TPageParam
41
- >,
42
- "queryKey" | "queryFn" | "getNextPageParam" | "initialPageParam"
43
- > {
44
- /** The reactor instance to use for method calls */
45
- reactor: Reactor<Service, Transform>
46
- /** The method name to call on the canister */
47
- functionName: Method
48
- /** Function to get args from page parameter */
49
- getArgs: (pageParam: TPageParam) => ReactorArgs<Service, Method, Transform>
50
- /** Agent call configuration (effectiveCanisterId, etc.) */
51
- callConfig?: CallConfig
52
- /** Custom query key (auto-generated if not provided) */
53
- queryKey?: QueryKey
54
- /** Initial page parameter */
55
- initialPageParam: TPageParam
56
- /** Function to determine next page parameter */
57
- getNextPageParam: (
58
- lastPage: ReactorQueryData<ReactorReturnOk<Service, Method, Transform>>,
59
- allPages: ReactorQueryData<ReactorReturnOk<Service, Method, Transform>>[],
60
- lastPageParam: TPageParam,
61
- allPageParams: TPageParam[]
62
- ) => TPageParam | undefined | null
63
- }
64
-
65
- export type UseActorInfiniteQueryConfig<
66
- Service,
67
- Method extends FunctionName<Service>,
68
- Transform extends TransformKey = "candid",
69
- TPageParam = unknown,
70
- Selected = InfiniteData<
71
- ReactorQueryData<ReactorReturnOk<Service, Method, Transform>>,
72
- TPageParam
73
- >,
74
- > = Omit<
75
- UseActorInfiniteQueryParameters<
76
- Service,
77
- Method,
78
- Transform,
79
- TPageParam,
80
- Selected
81
- >,
82
- "reactor"
83
- >
84
-
85
- export type UseActorInfiniteQueryResult<
86
- Service,
87
- Method extends FunctionName<Service>,
88
- Transform extends TransformKey = "candid",
89
- TPageParam = unknown,
90
- Selected = InfiniteData<
91
- ReactorQueryData<ReactorReturnOk<Service, Method, Transform>>,
92
- TPageParam
93
- >,
94
- > = UseInfiniteQueryResult<
95
- Selected,
96
- ReactorReturnErr<Service, Method, Transform>
97
- >
98
-
99
- /**
100
- * Hook for executing infinite/paginated query calls on a canister.
101
- *
102
- * @example
103
- * const { data, fetchNextPage, hasNextPage } = useActorInfiniteQuery({
104
- * reactor,
105
- * functionName: "getItems",
106
- * getArgs: (pageParam) => [{ offset: pageParam, limit: 10 }],
107
- * initialPageParam: 0,
108
- * getNextPageParam: (lastPage) => lastPage.nextOffset,
109
- * })
110
- */
111
- export const useActorInfiniteQuery = <
112
- Service,
113
- Method extends FunctionName<Service>,
114
- Transform extends TransformKey = "candid",
115
- TPageParam = unknown,
116
- Selected = InfiniteData<
117
- ReactorQueryData<ReactorReturnOk<Service, Method, Transform>>,
118
- TPageParam
119
- >,
120
- >({
121
- reactor,
122
- functionName,
123
- getArgs,
124
- callConfig,
125
- queryKey,
126
- ...options
127
- }: UseActorInfiniteQueryParameters<
128
- Service,
129
- Method,
130
- Transform,
131
- TPageParam,
132
- Selected
133
- >): UseActorInfiniteQueryResult<
134
- Service,
135
- Method,
136
- Transform,
137
- TPageParam,
138
- Selected
139
- > => {
140
- // Always pass queryKey through generateQueryKey so it is merged with the
141
- // reactor/function identity. Using the custom key verbatim would cause cache
142
- // collisions if two different actors or methods share the same key string.
143
- const baseQueryKey = useMemo(
144
- () =>
145
- reactor.generateQueryKey(
146
- {
147
- functionName,
148
- // Fold the call arguments into the key. They live in the `getArgs`
149
- // closure rather than in the config, so without this two hooks on the
150
- // same method with different arguments share one cache entry and
151
- // serve each other's pages.
152
- queryKey: mergeFactoryQueryKey(
153
- queryKey,
154
- undefined,
155
- getArgs(options.initialPageParam)
156
- ),
157
- },
158
- callConfig
159
- ),
160
- [
161
- queryKey,
162
- reactor,
163
- // `canisterId` is mutable reactor state that `setCanisterId` can change,
164
- // while `reactor` itself stays the same object — so it has to be a
165
- // dependency in its own right or the key stays pinned to the old canister
166
- // while the queryFn already calls the new one.
167
- reactor.canisterId?.toString(),
168
- functionName,
169
- callConfig,
170
- getArgs,
171
- options.initialPageParam,
172
- ]
173
- )
174
-
175
- // Memoize queryFn to prevent recreation on every render
176
- const queryFn = useCallback(
177
- async ({ pageParam }: { pageParam: TPageParam }) => {
178
- const args = getArgs(pageParam)
179
- const result = await reactor.callMethod({
180
- functionName,
181
- args,
182
- callConfig,
183
- })
184
- return normalizeQueryData<ReactorReturnOk<Service, Method, Transform>>(
185
- result as ReactorReturnOk<Service, Method, Transform>
186
- )
187
- },
188
- [reactor, functionName, getArgs, callConfig]
189
- )
190
-
191
- return useInfiniteQuery(
192
- {
193
- queryKey: baseQueryKey,
194
- queryFn,
195
- ...options,
196
- } as any,
197
- reactor.queryClient
198
- ) as UseActorInfiniteQueryResult<
199
- Service,
200
- Method,
201
- Transform,
202
- TPageParam,
203
- Selected
204
- >
205
- }