@ic-reactor/react 3.13.0 → 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.
- package/README.md +234 -787
- package/dist/index.d.ts +259 -16
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +470 -23
- package/dist/index.js.map +1 -1
- package/llms.txt +80 -278
- package/package.json +11 -39
- package/src/index.tsx +611 -0
- package/dist/auth/auth-client-compat.d.ts +0 -122
- package/dist/auth/auth-client-compat.d.ts.map +0 -1
- package/dist/auth/auth-client-compat.js +0 -162
- package/dist/auth/auth-client-compat.js.map +0 -1
- package/dist/auth/authentication-manager.d.ts +0 -405
- package/dist/auth/authentication-manager.d.ts.map +0 -1
- package/dist/auth/authentication-manager.js +0 -1537
- package/dist/auth/authentication-manager.js.map +0 -1
- package/dist/auth/constants.d.ts +0 -24
- package/dist/auth/constants.d.ts.map +0 -1
- package/dist/auth/constants.js +0 -24
- package/dist/auth/constants.js.map +0 -1
- package/dist/auth/createIdentityAttributeHooks.d.ts +0 -14
- package/dist/auth/createIdentityAttributeHooks.d.ts.map +0 -1
- package/dist/auth/createIdentityAttributeHooks.js +0 -122
- package/dist/auth/createIdentityAttributeHooks.js.map +0 -1
- package/dist/auth/identity-attributes-manager.d.ts +0 -27
- package/dist/auth/identity-attributes-manager.d.ts.map +0 -1
- package/dist/auth/identity-attributes-manager.js +0 -191
- package/dist/auth/identity-attributes-manager.js.map +0 -1
- package/dist/auth/identity-attributes.d.ts +0 -19
- package/dist/auth/identity-attributes.d.ts.map +0 -1
- package/dist/auth/identity-attributes.js +0 -227
- package/dist/auth/identity-attributes.js.map +0 -1
- package/dist/auth/index.d.ts +0 -8
- package/dist/auth/index.d.ts.map +0 -1
- package/dist/auth/index.js +0 -8
- package/dist/auth/index.js.map +0 -1
- package/dist/auth/local-ii-probe.d.ts +0 -57
- package/dist/auth/local-ii-probe.d.ts.map +0 -1
- package/dist/auth/local-ii-probe.js +0 -121
- package/dist/auth/local-ii-probe.js.map +0 -1
- package/dist/auth/types.d.ts +0 -222
- package/dist/auth/types.d.ts.map +0 -1
- package/dist/auth/types.js +0 -2
- package/dist/auth/types.js.map +0 -1
- package/dist/createActorHooks.d.ts +0 -41
- package/dist/createActorHooks.d.ts.map +0 -1
- package/dist/createActorHooks.js +0 -17
- package/dist/createActorHooks.js.map +0 -1
- package/dist/createInfiniteQuery.d.ts +0 -185
- package/dist/createInfiniteQuery.d.ts.map +0 -1
- package/dist/createInfiniteQuery.js +0 -198
- package/dist/createInfiniteQuery.js.map +0 -1
- package/dist/createMutation.d.ts +0 -33
- package/dist/createMutation.d.ts.map +0 -1
- package/dist/createMutation.js +0 -199
- package/dist/createMutation.js.map +0 -1
- package/dist/createQuery.d.ts +0 -63
- package/dist/createQuery.d.ts.map +0 -1
- package/dist/createQuery.js +0 -204
- package/dist/createQuery.js.map +0 -1
- package/dist/createReactorProvider.d.ts +0 -158
- package/dist/createReactorProvider.d.ts.map +0 -1
- package/dist/createReactorProvider.js +0 -256
- package/dist/createReactorProvider.js.map +0 -1
- package/dist/createSuspenseInfiniteQuery.d.ts +0 -154
- package/dist/createSuspenseInfiniteQuery.d.ts.map +0 -1
- package/dist/createSuspenseInfiniteQuery.js +0 -209
- package/dist/createSuspenseInfiniteQuery.js.map +0 -1
- package/dist/createSuspenseQuery.d.ts +0 -46
- package/dist/createSuspenseQuery.d.ts.map +0 -1
- package/dist/createSuspenseQuery.js +0 -158
- package/dist/createSuspenseQuery.js.map +0 -1
- package/dist/defineDisplayReactor.d.ts +0 -43
- package/dist/defineDisplayReactor.d.ts.map +0 -1
- package/dist/defineDisplayReactor.js +0 -42
- package/dist/defineDisplayReactor.js.map +0 -1
- package/dist/defineReactor.d.ts +0 -99
- package/dist/defineReactor.d.ts.map +0 -1
- package/dist/defineReactor.js +0 -15
- package/dist/defineReactor.js.map +0 -1
- package/dist/defineReactorShared.d.ts +0 -84
- package/dist/defineReactorShared.d.ts.map +0 -1
- package/dist/defineReactorShared.js +0 -139
- package/dist/defineReactorShared.js.map +0 -1
- package/dist/hooks/createAuthHooks.d.ts +0 -50
- package/dist/hooks/createAuthHooks.d.ts.map +0 -1
- package/dist/hooks/createAuthHooks.js +0 -291
- package/dist/hooks/createAuthHooks.js.map +0 -1
- package/dist/hooks/index.d.ts +0 -21
- package/dist/hooks/index.d.ts.map +0 -1
- package/dist/hooks/index.js +0 -24
- package/dist/hooks/index.js.map +0 -1
- package/dist/hooks/useActorInfiniteQuery.d.ts +0 -67
- package/dist/hooks/useActorInfiniteQuery.d.ts.map +0 -1
- package/dist/hooks/useActorInfiniteQuery.js +0 -89
- package/dist/hooks/useActorInfiniteQuery.js.map +0 -1
- package/dist/hooks/useActorMethod.d.ts +0 -148
- package/dist/hooks/useActorMethod.d.ts.map +0 -1
- package/dist/hooks/useActorMethod.js +0 -394
- package/dist/hooks/useActorMethod.js.map +0 -1
- package/dist/hooks/useActorMutation.d.ts +0 -51
- package/dist/hooks/useActorMutation.d.ts.map +0 -1
- package/dist/hooks/useActorMutation.js +0 -70
- package/dist/hooks/useActorMutation.js.map +0 -1
- package/dist/hooks/useActorQuery.d.ts +0 -45
- package/dist/hooks/useActorQuery.d.ts.map +0 -1
- package/dist/hooks/useActorQuery.js +0 -67
- package/dist/hooks/useActorQuery.js.map +0 -1
- package/dist/hooks/useActorSuspenseInfiniteQuery.d.ts +0 -51
- package/dist/hooks/useActorSuspenseInfiniteQuery.d.ts.map +0 -1
- package/dist/hooks/useActorSuspenseInfiniteQuery.js +0 -76
- package/dist/hooks/useActorSuspenseInfiniteQuery.js.map +0 -1
- package/dist/hooks/useActorSuspenseQuery.d.ts +0 -32
- package/dist/hooks/useActorSuspenseQuery.d.ts.map +0 -1
- package/dist/hooks/useActorSuspenseQuery.js +0 -58
- package/dist/hooks/useActorSuspenseQuery.js.map +0 -1
- package/dist/ownedAuthentication.d.ts +0 -52
- package/dist/ownedAuthentication.d.ts.map +0 -1
- package/dist/ownedAuthentication.js +0 -49
- package/dist/ownedAuthentication.js.map +0 -1
- package/dist/server.d.ts +0 -21
- package/dist/server.d.ts.map +0 -1
- package/dist/server.js +0 -23
- package/dist/server.js.map +0 -1
- package/dist/testing.d.ts +0 -19
- package/dist/testing.d.ts.map +0 -1
- package/dist/testing.js +0 -19
- package/dist/testing.js.map +0 -1
- package/dist/types.d.ts +0 -671
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -5
- package/dist/types.js.map +0 -1
- package/dist/utils.d.ts +0 -207
- package/dist/utils.d.ts.map +0 -1
- package/dist/utils.js +0 -405
- package/dist/utils.js.map +0 -1
- package/dist/validation.d.ts +0 -136
- package/dist/validation.d.ts.map +0 -1
- package/dist/validation.js +0 -144
- package/dist/validation.js.map +0 -1
- package/src/auth/auth-client-compat.ts +0 -273
- package/src/auth/authentication-manager.ts +0 -1682
- package/src/auth/constants.ts +0 -32
- package/src/auth/createIdentityAttributeHooks.ts +0 -169
- package/src/auth/identity-attributes-manager.ts +0 -226
- package/src/auth/identity-attributes.ts +0 -345
- package/src/auth/index.ts +0 -7
- package/src/auth/local-ii-probe.ts +0 -173
- package/src/auth/types.ts +0 -243
- package/src/createActorHooks.ts +0 -208
- package/src/createInfiniteQuery.ts +0 -670
- package/src/createMutation.ts +0 -324
- package/src/createQuery.ts +0 -369
- package/src/createReactorProvider.ts +0 -365
- package/src/createSuspenseInfiniteQuery.ts +0 -651
- package/src/createSuspenseQuery.ts +0 -304
- package/src/defineDisplayReactor.ts +0 -62
- package/src/defineReactor.ts +0 -142
- package/src/defineReactorShared.ts +0 -268
- package/src/hooks/createAuthHooks.ts +0 -371
- package/src/hooks/index.ts +0 -103
- package/src/hooks/useActorInfiniteQuery.ts +0 -278
- package/src/hooks/useActorMethod.ts +0 -710
- package/src/hooks/useActorMutation.ts +0 -205
- package/src/hooks/useActorQuery.ts +0 -157
- package/src/hooks/useActorSuspenseInfiniteQuery.ts +0 -248
- package/src/hooks/useActorSuspenseQuery.ts +0 -147
- package/src/index.ts +0 -31
- package/src/ownedAuthentication.ts +0 -81
- package/src/server.ts +0 -23
- package/src/testing.ts +0 -18
- package/src/types.ts +0 -948
- package/src/utils.ts +0 -505
- package/src/validation.ts +0 -226
|
@@ -1,205 +0,0 @@
|
|
|
1
|
-
import { useCallback } from "react"
|
|
2
|
-
import {
|
|
3
|
-
useMutation,
|
|
4
|
-
UseMutationOptions,
|
|
5
|
-
UseMutationResult,
|
|
6
|
-
} from "@tanstack/react-query"
|
|
7
|
-
import {
|
|
8
|
-
Reactor,
|
|
9
|
-
ReactorArgs,
|
|
10
|
-
ReactorReturnOk,
|
|
11
|
-
FunctionName,
|
|
12
|
-
TransformKey,
|
|
13
|
-
ReactorReturnErr,
|
|
14
|
-
isCanisterError,
|
|
15
|
-
CanisterError,
|
|
16
|
-
ErrResult,
|
|
17
|
-
ActorMethodReturnType,
|
|
18
|
-
TransformReturnRegistry,
|
|
19
|
-
} from "@ic-reactor/core"
|
|
20
|
-
import { CallConfig } from "@icp-sdk/core/agent"
|
|
21
|
-
import { invalidateTargets, useMountQueryClient } from "../utils.js"
|
|
22
|
-
import type { InvalidationTarget } from "../types.js"
|
|
23
|
-
|
|
24
|
-
export interface UseActorMutationParameters<
|
|
25
|
-
Service,
|
|
26
|
-
Method extends FunctionName<Service>,
|
|
27
|
-
Transform extends TransformKey = "candid",
|
|
28
|
-
TOnMutateResult = unknown,
|
|
29
|
-
> extends Omit<
|
|
30
|
-
UseMutationOptions<
|
|
31
|
-
ReactorReturnOk<Service, Method, Transform>,
|
|
32
|
-
ReactorReturnErr<Service, Method, Transform>,
|
|
33
|
-
ReactorArgs<Service, Method, Transform>,
|
|
34
|
-
TOnMutateResult
|
|
35
|
-
>,
|
|
36
|
-
"mutationFn"
|
|
37
|
-
> {
|
|
38
|
-
reactor: Reactor<Service, Transform>
|
|
39
|
-
functionName: Method
|
|
40
|
-
callConfig?: CallConfig
|
|
41
|
-
/**
|
|
42
|
-
* Queries to invalidate upon successful mutation, awaited before
|
|
43
|
-
* `onSuccess` runs.
|
|
44
|
-
*
|
|
45
|
-
* Each entry is a query key, a query object or query factory, or a
|
|
46
|
-
* `{ functionName, args? }` method of `reactor`; see
|
|
47
|
-
* {@link InvalidationTarget}. `undefined` entries are skipped, so
|
|
48
|
-
* `[maybeQuery]` is safe when the optional query object is absent.
|
|
49
|
-
*/
|
|
50
|
-
invalidateQueries?: InvalidationTarget<Service, Transform>[]
|
|
51
|
-
/**
|
|
52
|
-
* Callback for canister-level business logic errors.
|
|
53
|
-
* Called when the canister returns a Result { Err: E } variant.
|
|
54
|
-
* Separate from `onError`, which fires for all errors including network failures.
|
|
55
|
-
*/
|
|
56
|
-
onCanisterError?: (
|
|
57
|
-
error: CanisterError<
|
|
58
|
-
TransformReturnRegistry<
|
|
59
|
-
ErrResult<ActorMethodReturnType<Service[Method]>>,
|
|
60
|
-
Service
|
|
61
|
-
>[Transform]
|
|
62
|
-
>,
|
|
63
|
-
variables: ReactorArgs<Service, Method, Transform>
|
|
64
|
-
) => void
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export type UseActorMutationConfig<
|
|
68
|
-
Service,
|
|
69
|
-
Method extends FunctionName<Service>,
|
|
70
|
-
Transform extends TransformKey = "candid",
|
|
71
|
-
TOnMutateResult = unknown,
|
|
72
|
-
> = Omit<
|
|
73
|
-
UseActorMutationParameters<Service, Method, Transform, TOnMutateResult>,
|
|
74
|
-
"reactor"
|
|
75
|
-
>
|
|
76
|
-
|
|
77
|
-
export type UseActorMutationResult<
|
|
78
|
-
Service,
|
|
79
|
-
Method extends FunctionName<Service>,
|
|
80
|
-
Transform extends TransformKey = "candid",
|
|
81
|
-
TOnMutateResult = unknown,
|
|
82
|
-
> = UseMutationResult<
|
|
83
|
-
ReactorReturnOk<Service, Method, Transform>,
|
|
84
|
-
ReactorReturnErr<Service, Method, Transform>,
|
|
85
|
-
ReactorArgs<Service, Method, Transform>,
|
|
86
|
-
TOnMutateResult
|
|
87
|
-
>
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Hook for executing mutation calls on a canister.
|
|
91
|
-
* Use this for component-level mutation flows.
|
|
92
|
-
* For non-React usage, prefer `createMutation(...).execute(args)`.
|
|
93
|
-
*
|
|
94
|
-
* @example
|
|
95
|
-
* const { mutate, isPending } = useReactorMutation({
|
|
96
|
-
* reactor,
|
|
97
|
-
* functionName: "transfer",
|
|
98
|
-
* onSuccess: () => console.log("Success!"),
|
|
99
|
-
* onCanisterError: (err) => console.error("Canister Err:", err.code),
|
|
100
|
-
* })
|
|
101
|
-
*
|
|
102
|
-
* @example
|
|
103
|
-
* const transferMutation = createMutation(reactor, {
|
|
104
|
-
* functionName: "transfer",
|
|
105
|
-
* onCanisterError: (err) => console.error(err.code),
|
|
106
|
-
* })
|
|
107
|
-
*
|
|
108
|
-
* // Non-React execution path
|
|
109
|
-
* await transferMutation.execute([{ to: "aaaaa-aa", amount: "100" }])
|
|
110
|
-
*/
|
|
111
|
-
export const useActorMutation = <
|
|
112
|
-
Service,
|
|
113
|
-
Method extends FunctionName<Service>,
|
|
114
|
-
Transform extends TransformKey = "candid",
|
|
115
|
-
TOnMutateResult = unknown,
|
|
116
|
-
>({
|
|
117
|
-
reactor,
|
|
118
|
-
functionName,
|
|
119
|
-
invalidateQueries,
|
|
120
|
-
onSuccess,
|
|
121
|
-
onError,
|
|
122
|
-
onCanisterError,
|
|
123
|
-
callConfig,
|
|
124
|
-
...options
|
|
125
|
-
}: UseActorMutationParameters<
|
|
126
|
-
Service,
|
|
127
|
-
Method,
|
|
128
|
-
Transform,
|
|
129
|
-
TOnMutateResult
|
|
130
|
-
>): UseActorMutationResult<Service, Method, Transform, TOnMutateResult> => {
|
|
131
|
-
useMountQueryClient(reactor.queryClient)
|
|
132
|
-
|
|
133
|
-
const mutationFn = useCallback(
|
|
134
|
-
async (args: ReactorArgs<Service, Method, Transform>) =>
|
|
135
|
-
reactor.callMethod({ functionName, callConfig, args }),
|
|
136
|
-
[reactor, functionName, callConfig]
|
|
137
|
-
)
|
|
138
|
-
|
|
139
|
-
const handleSuccess = useCallback(
|
|
140
|
-
async (
|
|
141
|
-
...params: Parameters<
|
|
142
|
-
NonNullable<
|
|
143
|
-
UseMutationOptions<
|
|
144
|
-
ReactorReturnOk<Service, Method, Transform>,
|
|
145
|
-
ReactorReturnErr<Service, Method, Transform>,
|
|
146
|
-
ReactorArgs<Service, Method, Transform>,
|
|
147
|
-
TOnMutateResult
|
|
148
|
-
>["onSuccess"]
|
|
149
|
-
>
|
|
150
|
-
>
|
|
151
|
-
) => {
|
|
152
|
-
// Undefined entries are skipped: React Query reads
|
|
153
|
-
// `{ queryKey: undefined }` as "match everything", and the natural
|
|
154
|
-
// `[maybeQuery]` idiom produces one whenever the query is absent.
|
|
155
|
-
await invalidateTargets(reactor, invalidateQueries, callConfig)
|
|
156
|
-
await onSuccess?.(...params)
|
|
157
|
-
},
|
|
158
|
-
[reactor, invalidateQueries, onSuccess, callConfig]
|
|
159
|
-
)
|
|
160
|
-
|
|
161
|
-
const handleError = useCallback(
|
|
162
|
-
async (
|
|
163
|
-
error: ReactorReturnErr<Service, Method, Transform>,
|
|
164
|
-
variables: ReactorArgs<Service, Method, Transform>,
|
|
165
|
-
context: unknown,
|
|
166
|
-
mutation: unknown
|
|
167
|
-
) => {
|
|
168
|
-
if (isCanisterError(error)) {
|
|
169
|
-
onCanisterError?.(error as any, variables)
|
|
170
|
-
}
|
|
171
|
-
// Awaited like `onSuccess` above. TanStack Query waits for the promise
|
|
172
|
-
// `onError` returns before it runs `onSettled` and settles the mutation,
|
|
173
|
-
// and it can only wait for a promise this wrapper passes back.
|
|
174
|
-
await onError?.(error, variables, context as any, mutation as any)
|
|
175
|
-
},
|
|
176
|
-
[onCanisterError, onError]
|
|
177
|
-
)
|
|
178
|
-
|
|
179
|
-
// Not memoized. The deps could only ever list the values destructured above,
|
|
180
|
-
// never the `options` rest bucket, so everything passed straight through —
|
|
181
|
-
// `onMutate`, `onSettled`, `retry`, `meta`, `gcTime` — was frozen at the first
|
|
182
|
-
// render: `useMutation` calls `observer.setOptions` from an effect keyed on
|
|
183
|
-
// the options identity, so a later render's closures never reached it. A
|
|
184
|
-
// component passing only `onSettled` would report the recipient selected at
|
|
185
|
-
// mount rather than at submit.
|
|
186
|
-
//
|
|
187
|
-
// `createMutation`'s own hook builds its options inline for the same reason.
|
|
188
|
-
// A fresh object per render costs nothing here: `setOptions` diffs the values
|
|
189
|
-
// rather than the reference.
|
|
190
|
-
return useMutation(
|
|
191
|
-
{
|
|
192
|
-
// Keyed like `createMutation`'s hook and `useActorMethod`'s mutations,
|
|
193
|
-
// so `useIsMutating({ mutationKey })`, `useMutationState` and defaults
|
|
194
|
-
// registered with `setMutationDefaults` can find this one too. An
|
|
195
|
-
// explicit `mutationKey` in the options still wins.
|
|
196
|
-
mutationKey: reactor.getQueryOptions({ functionName, callConfig })
|
|
197
|
-
.queryKey,
|
|
198
|
-
...options,
|
|
199
|
-
mutationFn,
|
|
200
|
-
onSuccess: handleSuccess,
|
|
201
|
-
onError: handleError,
|
|
202
|
-
},
|
|
203
|
-
reactor.queryClient
|
|
204
|
-
)
|
|
205
|
-
}
|
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
import { useMemo } from "react"
|
|
2
|
-
import {
|
|
3
|
-
QueryKey,
|
|
4
|
-
useQuery,
|
|
5
|
-
skipToken,
|
|
6
|
-
QueryObserverOptions,
|
|
7
|
-
UseQueryResult,
|
|
8
|
-
type SkipToken,
|
|
9
|
-
} from "@tanstack/react-query"
|
|
10
|
-
import {
|
|
11
|
-
FunctionName,
|
|
12
|
-
Reactor,
|
|
13
|
-
TransformKey,
|
|
14
|
-
ReactorArgs,
|
|
15
|
-
ReactorReturnOk,
|
|
16
|
-
ReactorQueryData,
|
|
17
|
-
ReactorReturnErr,
|
|
18
|
-
} from "@ic-reactor/core"
|
|
19
|
-
import { CallConfig } from "@icp-sdk/core/agent"
|
|
20
|
-
import { retryOption, skippedQueryKey, useMountQueryClient } from "../utils.js"
|
|
21
|
-
|
|
22
|
-
export interface UseActorQueryParameters<
|
|
23
|
-
Service,
|
|
24
|
-
Method extends FunctionName<Service>,
|
|
25
|
-
Transform extends TransformKey = "candid",
|
|
26
|
-
Selected = ReactorQueryData<ReactorReturnOk<Service, Method, Transform>>,
|
|
27
|
-
> extends Omit<
|
|
28
|
-
QueryObserverOptions<
|
|
29
|
-
ReactorQueryData<ReactorReturnOk<Service, Method, Transform>>,
|
|
30
|
-
ReactorReturnErr<Service, Method, Transform>,
|
|
31
|
-
Selected,
|
|
32
|
-
ReactorQueryData<ReactorReturnOk<Service, Method, Transform>>,
|
|
33
|
-
QueryKey
|
|
34
|
-
>,
|
|
35
|
-
"queryKey" | "queryFn"
|
|
36
|
-
> {
|
|
37
|
-
reactor: Reactor<Service, Transform>
|
|
38
|
-
functionName: Method
|
|
39
|
-
/**
|
|
40
|
-
* The method's arguments, or TanStack Query's `skipToken` while they are
|
|
41
|
-
* not known: the query then waits without fetching, in an entry of its own
|
|
42
|
-
* under its method's key, which no call's key shares, so it shows no data
|
|
43
|
-
* until the arguments arrive.
|
|
44
|
-
*/
|
|
45
|
-
args?: ReactorArgs<Service, Method, Transform> | SkipToken
|
|
46
|
-
callConfig?: CallConfig
|
|
47
|
-
queryKey?: QueryKey
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export type UseActorQueryConfig<
|
|
51
|
-
Service,
|
|
52
|
-
Method extends FunctionName<Service>,
|
|
53
|
-
Transform extends TransformKey = "candid",
|
|
54
|
-
Selected = ReactorQueryData<ReactorReturnOk<Service, Method, Transform>>,
|
|
55
|
-
> = Omit<
|
|
56
|
-
UseActorQueryParameters<Service, Method, Transform, Selected>,
|
|
57
|
-
"reactor"
|
|
58
|
-
>
|
|
59
|
-
|
|
60
|
-
export type UseActorQueryResult<
|
|
61
|
-
Service,
|
|
62
|
-
Method extends FunctionName<Service>,
|
|
63
|
-
Transform extends TransformKey = "candid",
|
|
64
|
-
Selected = ReactorQueryData<ReactorReturnOk<Service, Method, Transform>>,
|
|
65
|
-
> = UseQueryResult<Selected, ReactorReturnErr<Service, Method, Transform>>
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Hook for executing query calls on a canister.
|
|
69
|
-
*
|
|
70
|
-
* @example
|
|
71
|
-
* const { data, isLoading } = useReactorQuery({
|
|
72
|
-
* reactor,
|
|
73
|
-
* functionName: "getUser",
|
|
74
|
-
* args: ["user-123"],
|
|
75
|
-
* })
|
|
76
|
-
*
|
|
77
|
-
* // With select transformation
|
|
78
|
-
* const { data } = useReactorQuery({
|
|
79
|
-
* reactor,
|
|
80
|
-
* functionName: "getUser",
|
|
81
|
-
* args: ["user-123"],
|
|
82
|
-
* select: (user) => user.name,
|
|
83
|
-
* })
|
|
84
|
-
*
|
|
85
|
-
* // Wait for the args: no fetch until userId is known
|
|
86
|
-
* const { data } = useReactorQuery({
|
|
87
|
-
* reactor,
|
|
88
|
-
* functionName: "getUser",
|
|
89
|
-
* args: userId ? [userId] : skipToken,
|
|
90
|
-
* })
|
|
91
|
-
*/
|
|
92
|
-
export const useActorQuery = <
|
|
93
|
-
Service,
|
|
94
|
-
Method extends FunctionName<Service>,
|
|
95
|
-
Transform extends TransformKey = "candid",
|
|
96
|
-
Selected = ReactorQueryData<ReactorReturnOk<Service, Method, Transform>>,
|
|
97
|
-
>({
|
|
98
|
-
reactor,
|
|
99
|
-
functionName,
|
|
100
|
-
args,
|
|
101
|
-
callConfig,
|
|
102
|
-
queryKey: defaultQueryKey,
|
|
103
|
-
...options
|
|
104
|
-
}: UseActorQueryParameters<
|
|
105
|
-
Service,
|
|
106
|
-
Method,
|
|
107
|
-
Transform,
|
|
108
|
-
Selected
|
|
109
|
-
>): UseActorQueryResult<Service, Method, Transform, Selected> => {
|
|
110
|
-
useMountQueryClient(reactor.queryClient)
|
|
111
|
-
|
|
112
|
-
// Memoize query options to prevent unnecessary re-computations
|
|
113
|
-
// For an update method, the options also carry its default `retry`; see
|
|
114
|
-
// `Reactor.getQueryRetry`.
|
|
115
|
-
const { queryKey, queryFn, retry } = useMemo(
|
|
116
|
-
() =>
|
|
117
|
-
args === skipToken
|
|
118
|
-
? // Waiting for its args: an entry of its own under the method's key,
|
|
119
|
-
// with nothing to run until then; see skippedQueryKey.
|
|
120
|
-
{
|
|
121
|
-
queryKey: skippedQueryKey(
|
|
122
|
-
reactor.generateQueryKey({ functionName }, callConfig),
|
|
123
|
-
"query"
|
|
124
|
-
),
|
|
125
|
-
// Kept as the unique symbol, which an object literal widens.
|
|
126
|
-
queryFn: skipToken as SkipToken,
|
|
127
|
-
retry: undefined,
|
|
128
|
-
}
|
|
129
|
-
: reactor.getQueryOptions<Method>({
|
|
130
|
-
callConfig,
|
|
131
|
-
functionName,
|
|
132
|
-
args,
|
|
133
|
-
queryKey: defaultQueryKey,
|
|
134
|
-
}),
|
|
135
|
-
// `canisterId` is mutable reactor state that `setCanisterId` can change,
|
|
136
|
-
// while `reactor` itself stays the same object — so it has to be a
|
|
137
|
-
// dependency in its own right or the key stays pinned to the old canister.
|
|
138
|
-
[
|
|
139
|
-
reactor,
|
|
140
|
-
reactor.canisterId?.toString(),
|
|
141
|
-
callConfig,
|
|
142
|
-
functionName,
|
|
143
|
-
args,
|
|
144
|
-
defaultQueryKey,
|
|
145
|
-
]
|
|
146
|
-
)
|
|
147
|
-
|
|
148
|
-
return useQuery(
|
|
149
|
-
{
|
|
150
|
-
queryFn,
|
|
151
|
-
...options,
|
|
152
|
-
queryKey,
|
|
153
|
-
...retryOption(options.retry, retry),
|
|
154
|
-
},
|
|
155
|
-
reactor.queryClient
|
|
156
|
-
)
|
|
157
|
-
}
|
|
@@ -1,248 +0,0 @@
|
|
|
1
|
-
import { useMemo, useCallback } from "react"
|
|
2
|
-
import {
|
|
3
|
-
QueryKey,
|
|
4
|
-
useSuspenseInfiniteQuery,
|
|
5
|
-
UseSuspenseInfiniteQueryResult,
|
|
6
|
-
UseSuspenseInfiniteQueryOptions,
|
|
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 {
|
|
20
|
-
callConfigForKey,
|
|
21
|
-
mergeFactoryQueryKey,
|
|
22
|
-
mountWhileSuspended,
|
|
23
|
-
normalizeQueryData,
|
|
24
|
-
retryOption,
|
|
25
|
-
useMountQueryClient,
|
|
26
|
-
} from "../utils.js"
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Parameters for useActorSuspenseInfiniteQuery hook.
|
|
30
|
-
* Extends react-query's UseSuspenseInfiniteQueryOptions with custom reactor params.
|
|
31
|
-
*/
|
|
32
|
-
export interface UseActorSuspenseInfiniteQueryParameters<
|
|
33
|
-
Service,
|
|
34
|
-
Method extends FunctionName<Service>,
|
|
35
|
-
Transform extends TransformKey = "candid",
|
|
36
|
-
TPageParam = unknown,
|
|
37
|
-
Selected = InfiniteData<
|
|
38
|
-
ReactorQueryData<ReactorReturnOk<Service, Method, Transform>>,
|
|
39
|
-
TPageParam
|
|
40
|
-
>,
|
|
41
|
-
> extends Omit<
|
|
42
|
-
UseSuspenseInfiniteQueryOptions<
|
|
43
|
-
ReactorQueryData<ReactorReturnOk<Service, Method, Transform>>,
|
|
44
|
-
ReactorReturnErr<Service, Method, Transform>,
|
|
45
|
-
Selected,
|
|
46
|
-
QueryKey,
|
|
47
|
-
TPageParam
|
|
48
|
-
>,
|
|
49
|
-
"queryKey" | "queryFn" | "getNextPageParam" | "initialPageParam"
|
|
50
|
-
> {
|
|
51
|
-
/** The reactor instance to use for method calls */
|
|
52
|
-
reactor: Reactor<Service, Transform>
|
|
53
|
-
/** The method name to call on the canister */
|
|
54
|
-
functionName: Method
|
|
55
|
-
/** Function to get args from page parameter */
|
|
56
|
-
getArgs: (pageParam: TPageParam) => ReactorArgs<Service, Method, Transform>
|
|
57
|
-
/**
|
|
58
|
-
* Narrows what the cache key derives from the call arguments.
|
|
59
|
-
*
|
|
60
|
-
* By default the key is scoped by `getArgs(initialPageParam)`, so two
|
|
61
|
-
* infinite queries on the same method with different arguments stay in
|
|
62
|
-
* separate cache entries. Supply this when those args embed the cursor and
|
|
63
|
-
* only part of them identifies the query — return the stable, serializable
|
|
64
|
-
* portion (typically everything except the pagination field). It is required
|
|
65
|
-
* when `initialPageParam` changes between renders, as `Date.now()` does:
|
|
66
|
-
* without it every render keys a new query.
|
|
67
|
-
*/
|
|
68
|
-
getKeyArgs?: (args: ReactorArgs<Service, Method, Transform>) => unknown
|
|
69
|
-
/** Agent call configuration (effectiveCanisterId, etc.) */
|
|
70
|
-
callConfig?: CallConfig
|
|
71
|
-
/** Custom query key (auto-generated if not provided) */
|
|
72
|
-
queryKey?: QueryKey
|
|
73
|
-
/** Initial page parameter */
|
|
74
|
-
initialPageParam: TPageParam
|
|
75
|
-
/** Function to determine next page parameter */
|
|
76
|
-
getNextPageParam: (
|
|
77
|
-
lastPage: ReactorQueryData<ReactorReturnOk<Service, Method, Transform>>,
|
|
78
|
-
allPages: ReactorQueryData<ReactorReturnOk<Service, Method, Transform>>[],
|
|
79
|
-
lastPageParam: TPageParam,
|
|
80
|
-
allPageParams: TPageParam[]
|
|
81
|
-
) => TPageParam | undefined | null
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
export type UseActorSuspenseInfiniteQueryConfig<
|
|
85
|
-
Service,
|
|
86
|
-
Method extends FunctionName<Service>,
|
|
87
|
-
Transform extends TransformKey = "candid",
|
|
88
|
-
TPageParam = unknown,
|
|
89
|
-
Selected = InfiniteData<
|
|
90
|
-
ReactorQueryData<ReactorReturnOk<Service, Method, Transform>>,
|
|
91
|
-
TPageParam
|
|
92
|
-
>,
|
|
93
|
-
> = Omit<
|
|
94
|
-
UseActorSuspenseInfiniteQueryParameters<
|
|
95
|
-
Service,
|
|
96
|
-
Method,
|
|
97
|
-
Transform,
|
|
98
|
-
TPageParam,
|
|
99
|
-
Selected
|
|
100
|
-
>,
|
|
101
|
-
"reactor"
|
|
102
|
-
>
|
|
103
|
-
|
|
104
|
-
export type UseActorSuspenseInfiniteQueryResult<
|
|
105
|
-
Service,
|
|
106
|
-
Method extends FunctionName<Service>,
|
|
107
|
-
Transform extends TransformKey = "candid",
|
|
108
|
-
TPageParam = unknown,
|
|
109
|
-
Selected = InfiniteData<
|
|
110
|
-
ReactorQueryData<ReactorReturnOk<Service, Method, Transform>>,
|
|
111
|
-
TPageParam
|
|
112
|
-
>,
|
|
113
|
-
> = UseSuspenseInfiniteQueryResult<
|
|
114
|
-
Selected,
|
|
115
|
-
ReactorReturnErr<Service, Method, Transform>
|
|
116
|
-
>
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Hook for executing suspense-enabled infinite/paginated query calls on a canister.
|
|
120
|
-
*
|
|
121
|
-
* @example
|
|
122
|
-
* const { data, fetchNextPage, hasNextPage } = useReactorSuspenseInfiniteQuery({
|
|
123
|
-
* reactor,
|
|
124
|
-
* functionName: "getItems",
|
|
125
|
-
* getArgs: (pageParam) => [{ offset: pageParam, limit: 10 }] as const,
|
|
126
|
-
* initialPageParam: 0,
|
|
127
|
-
* getNextPageParam: (lastPage) => lastPage.nextOffset,
|
|
128
|
-
* })
|
|
129
|
-
*/
|
|
130
|
-
export const useActorSuspenseInfiniteQuery = <
|
|
131
|
-
Service,
|
|
132
|
-
Method extends FunctionName<Service>,
|
|
133
|
-
Transform extends TransformKey = "candid",
|
|
134
|
-
TPageParam = unknown,
|
|
135
|
-
Selected = InfiniteData<
|
|
136
|
-
ReactorQueryData<ReactorReturnOk<Service, Method, Transform>>,
|
|
137
|
-
TPageParam
|
|
138
|
-
>,
|
|
139
|
-
>({
|
|
140
|
-
reactor,
|
|
141
|
-
functionName,
|
|
142
|
-
getArgs,
|
|
143
|
-
getKeyArgs,
|
|
144
|
-
callConfig,
|
|
145
|
-
queryKey,
|
|
146
|
-
...options
|
|
147
|
-
}: UseActorSuspenseInfiniteQueryParameters<
|
|
148
|
-
Service,
|
|
149
|
-
Method,
|
|
150
|
-
Transform,
|
|
151
|
-
TPageParam,
|
|
152
|
-
Selected
|
|
153
|
-
>): UseActorSuspenseInfiniteQueryResult<
|
|
154
|
-
Service,
|
|
155
|
-
Method,
|
|
156
|
-
Transform,
|
|
157
|
-
TPageParam,
|
|
158
|
-
Selected
|
|
159
|
-
> => {
|
|
160
|
-
useMountQueryClient(reactor.queryClient)
|
|
161
|
-
|
|
162
|
-
// Always pass queryKey through generateQueryKey so it is merged with the
|
|
163
|
-
// reactor/function identity. Using the custom key verbatim would cause cache
|
|
164
|
-
// collisions if two different actors or methods share the same key string.
|
|
165
|
-
const baseQueryKey = useMemo(() => {
|
|
166
|
-
// Fold the call arguments into the key. They live in the `getArgs`
|
|
167
|
-
// closure rather than in the config, so without this two hooks on the
|
|
168
|
-
// same method with different arguments share one cache entry and serve
|
|
169
|
-
// each other's pages. `getKeyArgs` narrows them exactly as it does for the
|
|
170
|
-
// factories, which the bound hook's config type always accepted: it used
|
|
171
|
-
// to be ignored here, so the cursor stayed in the key, and an
|
|
172
|
-
// `initialPageParam` that changes every render (`Date.now()`) keyed a new
|
|
173
|
-
// query on every render — an endless loop of first-page fetches.
|
|
174
|
-
const initialArgs = getArgs(options.initialPageParam)
|
|
175
|
-
const keyArgs = getKeyArgs?.(initialArgs) ?? initialArgs
|
|
176
|
-
|
|
177
|
-
return reactor.generateQueryKey(
|
|
178
|
-
{
|
|
179
|
-
functionName,
|
|
180
|
-
queryKey: mergeFactoryQueryKey(queryKey, undefined, keyArgs),
|
|
181
|
-
},
|
|
182
|
-
callConfig
|
|
183
|
-
)
|
|
184
|
-
}, [
|
|
185
|
-
queryKey,
|
|
186
|
-
reactor,
|
|
187
|
-
// `canisterId` is mutable reactor state that `setCanisterId` can change,
|
|
188
|
-
// while `reactor` itself stays the same object — so it has to be a
|
|
189
|
-
// dependency in its own right or the key stays pinned to the old canister
|
|
190
|
-
// while the queryFn already calls the new one.
|
|
191
|
-
reactor.canisterId?.toString(),
|
|
192
|
-
functionName,
|
|
193
|
-
callConfig,
|
|
194
|
-
getArgs,
|
|
195
|
-
getKeyArgs,
|
|
196
|
-
options.initialPageParam,
|
|
197
|
-
])
|
|
198
|
-
|
|
199
|
-
// Memoize queryFn to prevent recreation on every render
|
|
200
|
-
const queryFn = useCallback(
|
|
201
|
-
async ({
|
|
202
|
-
pageParam,
|
|
203
|
-
queryKey: fetchedKey,
|
|
204
|
-
}: {
|
|
205
|
-
pageParam: TPageParam
|
|
206
|
-
queryKey: QueryKey
|
|
207
|
-
}) => {
|
|
208
|
-
const args = getArgs(pageParam)
|
|
209
|
-
const result = await reactor.callMethod({
|
|
210
|
-
functionName,
|
|
211
|
-
args,
|
|
212
|
-
callConfig: callConfigForKey(fetchedKey, callConfig),
|
|
213
|
-
})
|
|
214
|
-
return normalizeQueryData<ReactorReturnOk<Service, Method, Transform>>(
|
|
215
|
-
result as ReactorReturnOk<Service, Method, Transform>
|
|
216
|
-
)
|
|
217
|
-
},
|
|
218
|
-
[reactor, functionName, getArgs, callConfig]
|
|
219
|
-
)
|
|
220
|
-
|
|
221
|
-
// The method's default `retry`: for an update method, only failures that
|
|
222
|
-
// prove the canister never ran the call; see `Reactor.getQueryRetry`.
|
|
223
|
-
const defaultRetry = useMemo(
|
|
224
|
-
() => reactor.getQueryRetry(functionName, baseQueryKey),
|
|
225
|
-
[reactor, functionName, baseQueryKey]
|
|
226
|
-
)
|
|
227
|
-
|
|
228
|
-
try {
|
|
229
|
-
return useSuspenseInfiniteQuery(
|
|
230
|
-
{
|
|
231
|
-
queryKey: baseQueryKey,
|
|
232
|
-
queryFn,
|
|
233
|
-
...options,
|
|
234
|
-
...retryOption(options.retry, defaultRetry),
|
|
235
|
-
} as any,
|
|
236
|
-
reactor.queryClient
|
|
237
|
-
) as UseActorSuspenseInfiniteQueryResult<
|
|
238
|
-
Service,
|
|
239
|
-
Method,
|
|
240
|
-
Transform,
|
|
241
|
-
TPageParam,
|
|
242
|
-
Selected
|
|
243
|
-
>
|
|
244
|
-
} catch (thrown) {
|
|
245
|
-
mountWhileSuspended(reactor.queryClient, thrown)
|
|
246
|
-
throw thrown
|
|
247
|
-
}
|
|
248
|
-
}
|