@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,304 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Suspense Query Factory - Generic wrapper for React Suspense-based canister data
|
|
3
|
-
*
|
|
4
|
-
* Creates unified fetch/hook/invalidate functions for any canister method.
|
|
5
|
-
* Works with any Reactor instance.
|
|
6
|
-
*
|
|
7
|
-
* Uses `useSuspenseQuery` which:
|
|
8
|
-
* - Requires wrapping in <Suspense> boundary
|
|
9
|
-
* - Data is always defined (no undefined checks)
|
|
10
|
-
* - Does NOT support `enabled` option
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* const userQuery = createSuspenseQuery(todoManager, {
|
|
14
|
-
* functionName: "get_user",
|
|
15
|
-
* select: (result) => result.user,
|
|
16
|
-
* })
|
|
17
|
-
*
|
|
18
|
-
* // In component (wrap in Suspense)
|
|
19
|
-
* const { data: user } = userQuery.useSuspenseQuery() // data is never undefined!
|
|
20
|
-
*/
|
|
21
|
-
|
|
22
|
-
import type {
|
|
23
|
-
Reactor,
|
|
24
|
-
FunctionName,
|
|
25
|
-
ReactorArgs,
|
|
26
|
-
TransformKey,
|
|
27
|
-
} from "@ic-reactor/core"
|
|
28
|
-
import { useMemo } from "react"
|
|
29
|
-
import { useSuspenseQuery } from "@tanstack/react-query"
|
|
30
|
-
import type {
|
|
31
|
-
QueryFnData,
|
|
32
|
-
QueryError,
|
|
33
|
-
SuspenseQueryConfig,
|
|
34
|
-
UseSuspenseQueryWithSelect,
|
|
35
|
-
SuspenseQueryResult,
|
|
36
|
-
SuspenseQueryFactoryConfig,
|
|
37
|
-
QueryFactoryFn,
|
|
38
|
-
NoInfer,
|
|
39
|
-
} from "./types.js"
|
|
40
|
-
import {
|
|
41
|
-
buildChainedSelect,
|
|
42
|
-
createBoundedCache,
|
|
43
|
-
mountWhileSuspended,
|
|
44
|
-
pickFetchOptions,
|
|
45
|
-
queryCacheControls,
|
|
46
|
-
retryOption,
|
|
47
|
-
useMountQueryClient,
|
|
48
|
-
withQueryFactoryMethods,
|
|
49
|
-
} from "./utils.js"
|
|
50
|
-
|
|
51
|
-
// ============================================================================
|
|
52
|
-
// Internal Implementation
|
|
53
|
-
// ============================================================================
|
|
54
|
-
|
|
55
|
-
const createSuspenseQueryImpl = <
|
|
56
|
-
Service,
|
|
57
|
-
Method extends FunctionName<Service> = FunctionName<Service>,
|
|
58
|
-
Transform extends TransformKey = "candid",
|
|
59
|
-
Selected = QueryFnData<Service, Method, Transform>,
|
|
60
|
-
>(
|
|
61
|
-
reactor: Reactor<Service, Transform>,
|
|
62
|
-
config: SuspenseQueryConfig<Service, Method, Transform, Selected>
|
|
63
|
-
): SuspenseQueryResult<
|
|
64
|
-
QueryFnData<Service, Method, Transform>,
|
|
65
|
-
Selected,
|
|
66
|
-
QueryError<Service, Method, Transform>
|
|
67
|
-
> => {
|
|
68
|
-
type TData = QueryFnData<Service, Method, Transform>
|
|
69
|
-
type TError = QueryError<Service, Method, Transform>
|
|
70
|
-
|
|
71
|
-
const {
|
|
72
|
-
functionName,
|
|
73
|
-
args,
|
|
74
|
-
callConfig,
|
|
75
|
-
staleTime = 5 * 60 * 1000,
|
|
76
|
-
select,
|
|
77
|
-
queryKey: customQueryKey,
|
|
78
|
-
...rest
|
|
79
|
-
} = config
|
|
80
|
-
|
|
81
|
-
// `callConfig` goes wherever the hooks send it: to the call and into the
|
|
82
|
-
// key, so a query of another canister or agent has an entry of its own.
|
|
83
|
-
const params = { functionName, args, queryKey: customQueryKey, callConfig }
|
|
84
|
-
|
|
85
|
-
const getQueryKey = () => reactor.generateQueryKey(params, callConfig)
|
|
86
|
-
|
|
87
|
-
const applySelect = (raw: TData): Selected =>
|
|
88
|
-
select ? select(raw) : (raw as unknown as Selected)
|
|
89
|
-
|
|
90
|
-
// How the query function runs, shared with the hook; see pickFetchOptions.
|
|
91
|
-
const fetchOptions = pickFetchOptions(rest)
|
|
92
|
-
|
|
93
|
-
/** Cache-first fetch for use in loaders / route preloading. */
|
|
94
|
-
const fetch = async (): Promise<Selected> => {
|
|
95
|
-
// Through the reactor rather than straight to the QueryClient: overriding
|
|
96
|
-
// `fetchQuery` in a Reactor subclass is a documented way to add logic to
|
|
97
|
-
// every factory fetch.
|
|
98
|
-
const result = await reactor.fetchQuery(params, fetchOptions)
|
|
99
|
-
return applySelect(result)
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/** Fire-and-forget prefetch — warms the cache without blocking. */
|
|
103
|
-
const prefetch = (): Promise<void> => {
|
|
104
|
-
const baseOptions = reactor.getQueryOptions(params)
|
|
105
|
-
// Runs again when a sign-in or sign-out cancels it, and never rejects;
|
|
106
|
-
// see `prefetch` in createQuery.
|
|
107
|
-
return reactor.clientManager
|
|
108
|
-
.fetchAcrossIdentitySwitch(() =>
|
|
109
|
-
reactor.queryClient.prefetchQuery({
|
|
110
|
-
...fetchOptions,
|
|
111
|
-
// An update method's default `retry`; see `Reactor.getQueryRetry`.
|
|
112
|
-
...retryOption(fetchOptions.retry, baseOptions.retry),
|
|
113
|
-
queryKey: baseOptions.queryKey,
|
|
114
|
-
queryFn: baseOptions.queryFn,
|
|
115
|
-
staleTime,
|
|
116
|
-
})
|
|
117
|
-
)
|
|
118
|
-
.catch(() => undefined)
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
const useSuspenseQueryHook: UseSuspenseQueryWithSelect<
|
|
122
|
-
TData,
|
|
123
|
-
Selected,
|
|
124
|
-
TError
|
|
125
|
-
> = (options: any): any => {
|
|
126
|
-
useMountQueryClient(reactor.queryClient)
|
|
127
|
-
const baseOptions = reactor.getQueryOptions(params)
|
|
128
|
-
// Memoized so the observer's select-result cache can hit; see
|
|
129
|
-
// buildChainedSelect. `select` comes from the factory config and is stable.
|
|
130
|
-
const chainedSelect = useMemo(
|
|
131
|
-
() => buildChainedSelect(select, options?.select),
|
|
132
|
-
[options?.select]
|
|
133
|
-
)
|
|
134
|
-
try {
|
|
135
|
-
return useSuspenseQuery(
|
|
136
|
-
{
|
|
137
|
-
queryKey: baseOptions.queryKey,
|
|
138
|
-
staleTime,
|
|
139
|
-
...rest,
|
|
140
|
-
...options,
|
|
141
|
-
queryFn: baseOptions.queryFn,
|
|
142
|
-
select: chainedSelect,
|
|
143
|
-
// The hook's `retry`, else the config's, else an update method's
|
|
144
|
-
// default; see `Reactor.getQueryRetry`.
|
|
145
|
-
...retryOption(options?.retry ?? rest.retry, baseOptions.retry),
|
|
146
|
-
},
|
|
147
|
-
reactor.queryClient
|
|
148
|
-
)
|
|
149
|
-
} catch (thrown) {
|
|
150
|
-
mountWhileSuspended(reactor.queryClient, thrown)
|
|
151
|
-
throw thrown
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
const invalidate = async (): Promise<void> => {
|
|
156
|
-
await reactor.queryClient.invalidateQueries({ queryKey: getQueryKey() })
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
const getCacheData: SuspenseQueryResult<
|
|
160
|
-
TData,
|
|
161
|
-
Selected,
|
|
162
|
-
TError
|
|
163
|
-
>["getCacheData"] = (selectFn?: (data: Selected) => unknown): any => {
|
|
164
|
-
const raw = reactor.getQueryData(params, callConfig)
|
|
165
|
-
if (raw === undefined) return undefined
|
|
166
|
-
const selected = applySelect(raw)
|
|
167
|
-
return selectFn ? selectFn(selected) : selected
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
const setData: SuspenseQueryResult<TData, Selected, TError>["setData"] = (
|
|
171
|
-
updater
|
|
172
|
-
) => {
|
|
173
|
-
return reactor.queryClient.setQueryData(getQueryKey(), updater as any) as
|
|
174
|
-
TData | undefined
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
return {
|
|
178
|
-
fetch,
|
|
179
|
-
prefetch,
|
|
180
|
-
useSuspenseQuery: useSuspenseQueryHook,
|
|
181
|
-
invalidate,
|
|
182
|
-
getQueryKey,
|
|
183
|
-
getCacheData,
|
|
184
|
-
setData,
|
|
185
|
-
...queryCacheControls<TData>(reactor, getQueryKey),
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
// ============================================================================
|
|
190
|
-
// Public Factory Function
|
|
191
|
-
// ============================================================================
|
|
192
|
-
|
|
193
|
-
export function createSuspenseQuery<
|
|
194
|
-
Service,
|
|
195
|
-
Transform extends TransformKey,
|
|
196
|
-
Method extends FunctionName<Service> = FunctionName<Service>,
|
|
197
|
-
Selected = QueryFnData<Service, Method, Transform>,
|
|
198
|
-
>(
|
|
199
|
-
reactor: Reactor<Service, Transform>,
|
|
200
|
-
config: SuspenseQueryConfig<NoInfer<Service>, Method, Transform, Selected>
|
|
201
|
-
): SuspenseQueryResult<
|
|
202
|
-
QueryFnData<Service, Method, Transform>,
|
|
203
|
-
Selected,
|
|
204
|
-
QueryError<Service, Method, Transform>
|
|
205
|
-
> {
|
|
206
|
-
return createSuspenseQueryImpl(
|
|
207
|
-
reactor,
|
|
208
|
-
config as SuspenseQueryConfig<Service, Method, Transform, Selected>
|
|
209
|
-
)
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
// ============================================================================
|
|
213
|
-
// Convenience: Create suspense query with dynamic args
|
|
214
|
-
// ============================================================================
|
|
215
|
-
|
|
216
|
-
/**
|
|
217
|
-
* Create a suspense query factory: a function that takes the method's args
|
|
218
|
-
* and returns the suspense query object for them, the same object for the
|
|
219
|
-
* same args.
|
|
220
|
-
*
|
|
221
|
-
* The function also has `getQueryKey()`, the key prefix every query it
|
|
222
|
-
* returns shares, and `invalidate()`, which invalidates all of them whatever
|
|
223
|
-
* their args. Pass the function itself to a mutation's `invalidateQueries` to
|
|
224
|
-
* refresh every instance after the mutation.
|
|
225
|
-
*
|
|
226
|
-
* @example
|
|
227
|
-
* const getBalance = createSuspenseQueryFactory(ledger, {
|
|
228
|
-
* functionName: "icrc1_balance_of",
|
|
229
|
-
* })
|
|
230
|
-
*
|
|
231
|
-
* // In a component under <Suspense>
|
|
232
|
-
* const { data } = getBalance([{ owner, subaccount: [] }]).useSuspenseQuery()
|
|
233
|
-
*
|
|
234
|
-
* // Refetch every account's balance
|
|
235
|
-
* await getBalance.invalidate()
|
|
236
|
-
*/
|
|
237
|
-
export function createSuspenseQueryFactory<
|
|
238
|
-
Service,
|
|
239
|
-
Transform extends TransformKey,
|
|
240
|
-
Method extends FunctionName<Service> = FunctionName<Service>,
|
|
241
|
-
Selected = QueryFnData<Service, Method, Transform>,
|
|
242
|
-
>(
|
|
243
|
-
reactor: Reactor<Service, Transform>,
|
|
244
|
-
config: SuspenseQueryFactoryConfig<
|
|
245
|
-
NoInfer<Service>,
|
|
246
|
-
Method,
|
|
247
|
-
Transform,
|
|
248
|
-
Selected
|
|
249
|
-
>
|
|
250
|
-
): QueryFactoryFn<
|
|
251
|
-
ReactorArgs<Service, Method, Transform>,
|
|
252
|
-
SuspenseQueryResult<
|
|
253
|
-
QueryFnData<Service, Method, Transform>,
|
|
254
|
-
Selected,
|
|
255
|
-
QueryError<Service, Method, Transform>
|
|
256
|
-
>
|
|
257
|
-
> {
|
|
258
|
-
const cache =
|
|
259
|
-
createBoundedCache<
|
|
260
|
-
SuspenseQueryResult<
|
|
261
|
-
QueryFnData<Service, Method, Transform>,
|
|
262
|
-
Selected,
|
|
263
|
-
QueryError<Service, Method, Transform>
|
|
264
|
-
>
|
|
265
|
-
>()
|
|
266
|
-
|
|
267
|
-
const factory = (args: ReactorArgs<Service, Method, Transform>) => {
|
|
268
|
-
const key = reactor.generateQueryKey(
|
|
269
|
-
{ functionName: config.functionName as Method, args },
|
|
270
|
-
config.callConfig
|
|
271
|
-
)
|
|
272
|
-
const cacheKey = JSON.stringify(key)
|
|
273
|
-
|
|
274
|
-
const existing = cache.get(cacheKey)
|
|
275
|
-
if (existing) return existing
|
|
276
|
-
|
|
277
|
-
const result = createSuspenseQueryImpl<
|
|
278
|
-
Service,
|
|
279
|
-
Method,
|
|
280
|
-
Transform,
|
|
281
|
-
Selected
|
|
282
|
-
>(reactor, {
|
|
283
|
-
...(config as SuspenseQueryFactoryConfig<
|
|
284
|
-
Service,
|
|
285
|
-
Method,
|
|
286
|
-
Transform,
|
|
287
|
-
Selected
|
|
288
|
-
>),
|
|
289
|
-
args,
|
|
290
|
-
})
|
|
291
|
-
cache.set(cacheKey, result)
|
|
292
|
-
return result
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
// The method's own prefix, at the canister and agent the config's
|
|
296
|
-
// `callConfig` names. A config `queryKey` follows the args segment in every
|
|
297
|
-
// instance's key, so it cannot narrow the prefix.
|
|
298
|
-
return withQueryFactoryMethods(factory, reactor, () =>
|
|
299
|
-
reactor.generateQueryKey(
|
|
300
|
-
{ functionName: config.functionName as Method },
|
|
301
|
-
config.callConfig
|
|
302
|
-
)
|
|
303
|
-
)
|
|
304
|
-
}
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import { DisplayReactor } from "@ic-reactor/core"
|
|
2
|
-
import type { BaseActor, DisplayReactorParameters } from "@ic-reactor/core"
|
|
3
|
-
import { defineReactorWith } from "./defineReactorShared.js"
|
|
4
|
-
import type {
|
|
5
|
-
DefineReactorSharedParameters,
|
|
6
|
-
DefineReactorResult,
|
|
7
|
-
} from "./defineReactorShared.js"
|
|
8
|
-
|
|
9
|
-
/** Options for {@link defineDisplayReactor}: `defineReactor`'s, plus validators. */
|
|
10
|
-
export interface DefineDisplayReactorOptions<
|
|
11
|
-
Service,
|
|
12
|
-
> extends DefineReactorSharedParameters {
|
|
13
|
-
/** Optional initial argument validators (receive display types). */
|
|
14
|
-
validators?: DisplayReactorParameters<Service>["validators"]
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* One-call bootstrap for a {@link DisplayReactor} and its React hooks: the
|
|
19
|
-
* display counterpart of `defineReactor`, taking the same options.
|
|
20
|
-
*
|
|
21
|
-
* A DisplayReactor takes and returns UI-friendly values — text for
|
|
22
|
-
* `Principal`, `nat`, `int` and 64-bit integers, hex for blobs — which suits
|
|
23
|
-
* forms and components. Its codecs are built on zod, so this adds zod to the
|
|
24
|
-
* bundle. `defineReactor`, which builds a plain `Reactor` with raw Candid
|
|
25
|
-
* values, does not need zod, but until its deprecated `display` flag is removed
|
|
26
|
-
* at the next major it bundles zod anyway; `createActorHooks(new Reactor(...))`
|
|
27
|
-
* is the setup without it.
|
|
28
|
-
*
|
|
29
|
-
* Replaces `defineReactor({ display: true })`, which is deprecated.
|
|
30
|
-
*
|
|
31
|
-
* @example
|
|
32
|
-
* ```typescript
|
|
33
|
-
* import { defineDisplayReactor } from "@ic-reactor/react"
|
|
34
|
-
* import { idlFactory, type _SERVICE } from "./declarations/backend"
|
|
35
|
-
*
|
|
36
|
-
* export const { reactor, useActorQuery, useActorMutation, useAuth } =
|
|
37
|
-
* defineDisplayReactor<_SERVICE>({
|
|
38
|
-
* name: "backend",
|
|
39
|
-
* idlFactory,
|
|
40
|
-
* canisterId: "rrkah-fqaaa-aaaaa-aaaaq-cai",
|
|
41
|
-
* })
|
|
42
|
-
*
|
|
43
|
-
* function Balance() {
|
|
44
|
-
* // `nat` arrives as text, ready to render.
|
|
45
|
-
* const { data } = useActorQuery({ functionName: "get_balance" })
|
|
46
|
-
* return <span>{data}</span>
|
|
47
|
-
* }
|
|
48
|
-
* ```
|
|
49
|
-
*/
|
|
50
|
-
export function defineDisplayReactor<Service = BaseActor>(
|
|
51
|
-
params: DefineDisplayReactorOptions<Service>
|
|
52
|
-
): DefineReactorResult<Service, "display", DisplayReactor<Service>> {
|
|
53
|
-
return defineReactorWith<Service, "display", DisplayReactor<Service>>(
|
|
54
|
-
"defineDisplayReactor",
|
|
55
|
-
params,
|
|
56
|
-
(config) =>
|
|
57
|
-
new DisplayReactor<Service>({
|
|
58
|
-
...config,
|
|
59
|
-
validators: params.validators,
|
|
60
|
-
})
|
|
61
|
-
)
|
|
62
|
-
}
|
package/src/defineReactor.ts
DELETED
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
// DisplayReactor is only for the deprecated `display: true` path. It is what
|
|
2
|
-
// puts DisplayReactor and zod in every bundle that uses defineReactor; drop it
|
|
3
|
-
// with that path.
|
|
4
|
-
import { DisplayReactor, Reactor } from "@ic-reactor/core"
|
|
5
|
-
import type { BaseActor } from "@ic-reactor/core"
|
|
6
|
-
import { defineReactorWith } from "./defineReactorShared.js"
|
|
7
|
-
import type {
|
|
8
|
-
DefineReactorSharedParameters,
|
|
9
|
-
DefineReactorResult,
|
|
10
|
-
} from "./defineReactorShared.js"
|
|
11
|
-
import type { DefineDisplayReactorOptions } from "./defineDisplayReactor.js"
|
|
12
|
-
|
|
13
|
-
export type {
|
|
14
|
-
DefineReactorSharedParameters,
|
|
15
|
-
DefineReactorResult,
|
|
16
|
-
} from "./defineReactorShared.js"
|
|
17
|
-
|
|
18
|
-
/** Parameters for a standard (raw Candid types) reactor. */
|
|
19
|
-
export interface DefineReactorParameters extends DefineReactorSharedParameters {
|
|
20
|
-
display?: false
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Parameters for `defineReactor({ display: true })`.
|
|
25
|
-
*
|
|
26
|
-
* @deprecated Call `defineDisplayReactor` with the same options, without
|
|
27
|
-
* `display`: see {@link DefineDisplayReactorOptions}.
|
|
28
|
-
*/
|
|
29
|
-
export interface DefineDisplayReactorParameters<
|
|
30
|
-
Service,
|
|
31
|
-
> extends DefineDisplayReactorOptions<Service> {
|
|
32
|
-
/**
|
|
33
|
-
* @deprecated Use `defineDisplayReactor(...)` instead of
|
|
34
|
-
* `defineReactor({ display: true, ... })`. The flag keeps working until the
|
|
35
|
-
* next major, but it makes every bundle that calls `defineReactor` carry
|
|
36
|
-
* `DisplayReactor` and zod, even when it never sets the flag.
|
|
37
|
-
*/
|
|
38
|
-
display: true
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* The `display: true` form: builds a DisplayReactor and its hooks.
|
|
43
|
-
*
|
|
44
|
-
* @deprecated `defineReactor({ display: true })` is deprecated: pass the same
|
|
45
|
-
* options, without `display`, to `defineDisplayReactor(...)`. Only this form
|
|
46
|
-
* is; `defineReactor` without `display` builds a plain `Reactor` and is not
|
|
47
|
-
* deprecated. The flag keeps working until the next major, but it makes every
|
|
48
|
-
* bundle that calls `defineReactor` carry `DisplayReactor` and zod, even when
|
|
49
|
-
* it never sets the flag.
|
|
50
|
-
*/
|
|
51
|
-
export function defineReactor<Service = BaseActor>(
|
|
52
|
-
params: DefineDisplayReactorParameters<Service>
|
|
53
|
-
): DefineReactorResult<Service, "display", DisplayReactor<Service>>
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* One-call bootstrap for a canister reactor + its React hooks.
|
|
57
|
-
*
|
|
58
|
-
* Collapses the four manual steps (QueryClient → ClientManager → Reactor →
|
|
59
|
-
* createActorHooks) into a single call. It builds a `Reactor`, which takes and
|
|
60
|
-
* returns raw Candid values; `defineDisplayReactor` takes the same options and
|
|
61
|
-
* builds a `DisplayReactor` for UI-friendly ones.
|
|
62
|
-
* Use this when one-call bootstrap is enough. If you need reusable
|
|
63
|
-
* method-specific operations outside React, compose with query/mutation
|
|
64
|
-
* factories after setup.
|
|
65
|
-
*
|
|
66
|
-
* @example
|
|
67
|
-
* ```typescript
|
|
68
|
-
* import { defineReactor } from "@ic-reactor/react"
|
|
69
|
-
* import { idlFactory, type _SERVICE } from "./declarations/backend"
|
|
70
|
-
*
|
|
71
|
-
* const { reactor, useActorQuery, useActorMutation } = defineReactor<_SERVICE>({
|
|
72
|
-
* name: "backend",
|
|
73
|
-
* idlFactory,
|
|
74
|
-
* canisterId: "rrkah-fqaaa-aaaaa-aaaaq-cai",
|
|
75
|
-
* })
|
|
76
|
-
*
|
|
77
|
-
* function Profile() {
|
|
78
|
-
* const { data } = useActorQuery({ functionName: "get_profile" })
|
|
79
|
-
* return <div>{data?.name}</div>
|
|
80
|
-
* }
|
|
81
|
-
* ```
|
|
82
|
-
*
|
|
83
|
-
* @example Reuse an existing ClientManager (multiple canisters share one agent)
|
|
84
|
-
* ```typescript
|
|
85
|
-
* const ledger = defineReactor<_LEDGER>({
|
|
86
|
-
* name: "ledger",
|
|
87
|
-
* idlFactory: ledgerIdl,
|
|
88
|
-
* canisterId: "ryjl3-tyaaa-aaaaa-aaaba-cai",
|
|
89
|
-
* })
|
|
90
|
-
* const index = defineReactor<_INDEX>({
|
|
91
|
-
* name: "index",
|
|
92
|
-
* idlFactory: indexIdl,
|
|
93
|
-
* canisterId: "qhbym-qaaaa-aaaaa-aaafq-cai",
|
|
94
|
-
* clientManager: ledger.clientManager,
|
|
95
|
-
* authentication: ledger.authentication, // one Internet Identity session
|
|
96
|
-
* })
|
|
97
|
-
* ```
|
|
98
|
-
*
|
|
99
|
-
* @example Internet Identity is wired up out of the box
|
|
100
|
-
* ```typescript
|
|
101
|
-
* const { useAuth, useIdentityAttributes } = defineReactor<_SERVICE>({
|
|
102
|
-
* name: "backend",
|
|
103
|
-
* idlFactory,
|
|
104
|
-
* canisterId: "rrkah-fqaaa-aaaaa-aaaaq-cai",
|
|
105
|
-
* // Needed when the app is served from more than one origin.
|
|
106
|
-
* auth: { derivationOrigin: "https://app.example.com" },
|
|
107
|
-
* })
|
|
108
|
-
*
|
|
109
|
-
* function LoginButton() {
|
|
110
|
-
* const { login, logout, isAuthenticated, principal } = useAuth()
|
|
111
|
-
* return isAuthenticated
|
|
112
|
-
* ? <button onClick={() => logout()}>{principal?.toText()}</button>
|
|
113
|
-
* : <button onClick={() => login()}>Sign in</button>
|
|
114
|
-
* }
|
|
115
|
-
* ```
|
|
116
|
-
*/
|
|
117
|
-
export function defineReactor<Service = BaseActor>(
|
|
118
|
-
params: DefineReactorParameters
|
|
119
|
-
): DefineReactorResult<Service, "candid", Reactor<Service, "candid">>
|
|
120
|
-
|
|
121
|
-
export function defineReactor<Service = BaseActor>(
|
|
122
|
-
params: DefineReactorParameters | DefineDisplayReactorParameters<Service>
|
|
123
|
-
):
|
|
124
|
-
| DefineReactorResult<Service, "display", DisplayReactor<Service>>
|
|
125
|
-
| DefineReactorResult<Service, "candid", Reactor<Service, "candid">> {
|
|
126
|
-
if (params.display) {
|
|
127
|
-
// What defineDisplayReactor builds, but under this function's name, so an
|
|
128
|
-
// error names the call the app actually made.
|
|
129
|
-
const { validators } = params
|
|
130
|
-
return defineReactorWith<Service, "display", DisplayReactor<Service>>(
|
|
131
|
-
"defineReactor",
|
|
132
|
-
params,
|
|
133
|
-
(config) => new DisplayReactor<Service>({ ...config, validators })
|
|
134
|
-
)
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
return defineReactorWith<Service, "candid", Reactor<Service, "candid">>(
|
|
138
|
-
"defineReactor",
|
|
139
|
-
params,
|
|
140
|
-
(config) => new Reactor<Service>(config)
|
|
141
|
-
)
|
|
142
|
-
}
|