@ic-reactor/react 2.0.1 → 3.0.0-beta.2

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 (155) hide show
  1. package/README.md +283 -87
  2. package/dist/createActorHooks.d.ts +39 -0
  3. package/dist/createActorHooks.d.ts.map +1 -0
  4. package/dist/createActorHooks.js +30 -0
  5. package/dist/createActorHooks.js.map +1 -0
  6. package/dist/createAuthHooks.d.ts +37 -0
  7. package/dist/createAuthHooks.d.ts.map +1 -0
  8. package/dist/createAuthHooks.js +94 -0
  9. package/dist/createAuthHooks.js.map +1 -0
  10. package/dist/createInfiniteQuery.d.ts +129 -0
  11. package/dist/createInfiniteQuery.d.ts.map +1 -0
  12. package/dist/createInfiniteQuery.js +160 -0
  13. package/dist/createInfiniteQuery.js.map +1 -0
  14. package/dist/createMutation.d.ts +19 -0
  15. package/dist/createMutation.d.ts.map +1 -0
  16. package/dist/createMutation.js +98 -0
  17. package/dist/createMutation.js.map +1 -0
  18. package/dist/createQuery.d.ts +20 -0
  19. package/dist/createQuery.d.ts.map +1 -0
  20. package/dist/createQuery.js +111 -0
  21. package/dist/createQuery.js.map +1 -0
  22. package/dist/createSuspenseInfiniteQuery.d.ts +122 -0
  23. package/dist/createSuspenseInfiniteQuery.d.ts.map +1 -0
  24. package/dist/createSuspenseInfiniteQuery.js +160 -0
  25. package/dist/createSuspenseInfiniteQuery.js.map +1 -0
  26. package/dist/createSuspenseQuery.d.ts +25 -0
  27. package/dist/createSuspenseQuery.d.ts.map +1 -0
  28. package/dist/createSuspenseQuery.js +116 -0
  29. package/dist/createSuspenseQuery.js.map +1 -0
  30. package/dist/hooks/index.d.ts +6 -2
  31. package/dist/hooks/index.d.ts.map +1 -0
  32. package/dist/hooks/index.js +6 -18
  33. package/dist/hooks/index.js.map +1 -0
  34. package/dist/hooks/useActorInfiniteQuery.d.ts +37 -0
  35. package/dist/hooks/useActorInfiniteQuery.d.ts.map +1 -0
  36. package/dist/hooks/useActorInfiniteQuery.js +33 -0
  37. package/dist/hooks/useActorInfiniteQuery.js.map +1 -0
  38. package/dist/hooks/useActorMutation.d.ts +23 -0
  39. package/dist/hooks/useActorMutation.d.ts.map +1 -0
  40. package/dist/hooks/useActorMutation.js +39 -0
  41. package/dist/hooks/useActorMutation.js.map +1 -0
  42. package/dist/hooks/useActorQuery.d.ts +32 -0
  43. package/dist/hooks/useActorQuery.d.ts.map +1 -0
  44. package/dist/hooks/useActorQuery.js +35 -0
  45. package/dist/hooks/useActorQuery.js.map +1 -0
  46. package/dist/hooks/useActorSuspenseInfiniteQuery.d.ts +36 -0
  47. package/dist/hooks/useActorSuspenseInfiniteQuery.d.ts.map +1 -0
  48. package/dist/hooks/useActorSuspenseInfiniteQuery.js +33 -0
  49. package/dist/hooks/useActorSuspenseInfiniteQuery.js.map +1 -0
  50. package/dist/hooks/useActorSuspenseQuery.d.ts +32 -0
  51. package/dist/hooks/useActorSuspenseQuery.d.ts.map +1 -0
  52. package/dist/hooks/useActorSuspenseQuery.js +36 -0
  53. package/dist/hooks/useActorSuspenseQuery.js.map +1 -0
  54. package/dist/index.d.ts +11 -8
  55. package/dist/index.d.ts.map +1 -0
  56. package/dist/index.js +17 -49
  57. package/dist/index.js.map +1 -0
  58. package/dist/types.d.ts +232 -13
  59. package/dist/types.d.ts.map +1 -0
  60. package/dist/types.js +5 -22
  61. package/dist/types.js.map +1 -0
  62. package/dist/validation.d.ts +131 -0
  63. package/dist/validation.d.ts.map +1 -0
  64. package/dist/validation.js +125 -0
  65. package/dist/validation.js.map +1 -0
  66. package/package.json +70 -35
  67. package/LICENSE.md +0 -8
  68. package/dist/context/actor/create.d.ts +0 -63
  69. package/dist/context/actor/create.js +0 -119
  70. package/dist/context/actor/hooks/useActorInterface.d.ts +0 -4
  71. package/dist/context/actor/hooks/useActorInterface.js +0 -10
  72. package/dist/context/actor/hooks/useActorState.d.ts +0 -21
  73. package/dist/context/actor/hooks/useActorState.js +0 -25
  74. package/dist/context/actor/hooks/useActorStore.d.ts +0 -32
  75. package/dist/context/actor/hooks/useActorStore.js +0 -36
  76. package/dist/context/actor/hooks/useInitializeActor.d.ts +0 -6
  77. package/dist/context/actor/hooks/useInitializeActor.js +0 -10
  78. package/dist/context/actor/hooks/useMethod.d.ts +0 -29
  79. package/dist/context/actor/hooks/useMethod.js +0 -34
  80. package/dist/context/actor/hooks/useMethodAttributes.d.ts +0 -7
  81. package/dist/context/actor/hooks/useMethodAttributes.js +0 -11
  82. package/dist/context/actor/hooks/useMethodNames.d.ts +0 -7
  83. package/dist/context/actor/hooks/useMethodNames.js +0 -11
  84. package/dist/context/actor/hooks/useQueryCall.d.ts +0 -28
  85. package/dist/context/actor/hooks/useQueryCall.js +0 -33
  86. package/dist/context/actor/hooks/useUpdateCall.d.ts +0 -29
  87. package/dist/context/actor/hooks/useUpdateCall.js +0 -34
  88. package/dist/context/actor/hooks/useVisitMethod.d.ts +0 -8
  89. package/dist/context/actor/hooks/useVisitMethod.js +0 -13
  90. package/dist/context/actor/hooks/useVisitService.d.ts +0 -8
  91. package/dist/context/actor/hooks/useVisitService.js +0 -13
  92. package/dist/context/actor/index.d.ts +0 -16
  93. package/dist/context/actor/index.js +0 -33
  94. package/dist/context/actor/provider.d.ts +0 -71
  95. package/dist/context/actor/provider.js +0 -75
  96. package/dist/context/actor/types.d.ts +0 -35
  97. package/dist/context/actor/types.js +0 -2
  98. package/dist/context/adapter/create.d.ts +0 -2
  99. package/dist/context/adapter/create.js +0 -102
  100. package/dist/context/adapter/hooks/useCandidAdapter.d.ts +0 -23
  101. package/dist/context/adapter/hooks/useCandidAdapter.js +0 -27
  102. package/dist/context/adapter/hooks/useCandidEvaluation.d.ts +0 -5
  103. package/dist/context/adapter/hooks/useCandidEvaluation.js +0 -9
  104. package/dist/context/adapter/index.d.ts +0 -6
  105. package/dist/context/adapter/index.js +0 -24
  106. package/dist/context/adapter/provider.d.ts +0 -23
  107. package/dist/context/adapter/provider.js +0 -27
  108. package/dist/context/adapter/types.d.ts +0 -52
  109. package/dist/context/adapter/types.js +0 -2
  110. package/dist/context/agent/create.d.ts +0 -74
  111. package/dist/context/agent/create.js +0 -104
  112. package/dist/context/agent/hooks/useAgent.d.ts +0 -14
  113. package/dist/context/agent/hooks/useAgent.js +0 -18
  114. package/dist/context/agent/hooks/useAgentManager.d.ts +0 -14
  115. package/dist/context/agent/hooks/useAgentManager.js +0 -18
  116. package/dist/context/agent/hooks/useAgentState.d.ts +0 -21
  117. package/dist/context/agent/hooks/useAgentState.js +0 -25
  118. package/dist/context/agent/hooks/useAuth.d.ts +0 -57
  119. package/dist/context/agent/hooks/useAuth.js +0 -61
  120. package/dist/context/agent/hooks/useAuthState.d.ts +0 -19
  121. package/dist/context/agent/hooks/useAuthState.js +0 -23
  122. package/dist/context/agent/hooks/useUserPrincipal.d.ts +0 -17
  123. package/dist/context/agent/hooks/useUserPrincipal.js +0 -21
  124. package/dist/context/agent/index.d.ts +0 -12
  125. package/dist/context/agent/index.js +0 -29
  126. package/dist/context/agent/provider.d.ts +0 -28
  127. package/dist/context/agent/provider.js +0 -32
  128. package/dist/context/agent/types.d.ts +0 -17
  129. package/dist/context/agent/types.js +0 -2
  130. package/dist/core.d.ts +0 -1
  131. package/dist/core.js +0 -9
  132. package/dist/createReactor.d.ts +0 -49
  133. package/dist/createReactor.js +0 -69
  134. package/dist/helpers/actorHooks.d.ts +0 -18
  135. package/dist/helpers/actorHooks.js +0 -283
  136. package/dist/helpers/agentHooks.d.ts +0 -3
  137. package/dist/helpers/agentHooks.js +0 -22
  138. package/dist/helpers/authHooks.d.ts +0 -2
  139. package/dist/helpers/authHooks.js +0 -120
  140. package/dist/helpers/extractActorContext.d.ts +0 -4
  141. package/dist/helpers/extractActorContext.js +0 -44
  142. package/dist/helpers/extractAgentContext.d.ts +0 -28
  143. package/dist/helpers/extractAgentContext.js +0 -59
  144. package/dist/helpers/index.d.ts +0 -5
  145. package/dist/helpers/index.js +0 -21
  146. package/dist/helpers/types.d.ts +0 -222
  147. package/dist/helpers/types.js +0 -2
  148. package/dist/hooks/types.d.ts +0 -22
  149. package/dist/hooks/types.js +0 -2
  150. package/dist/hooks/useActor.d.ts +0 -67
  151. package/dist/hooks/useActor.js +0 -197
  152. package/dist/hooks/useActorManager.d.ts +0 -68
  153. package/dist/hooks/useActorManager.js +0 -75
  154. package/dist/utils.d.ts +0 -1
  155. package/dist/utils.js +0 -17
package/README.md CHANGED
@@ -1,121 +1,317 @@
1
- `@ic-reactor/react` is a comprehensive React library designed to streamline interactions with the Internet Computer (IC) blockchain. It provides React hooks and utilities for efficient state management, authentication, and interaction with IC actors.
1
+ # @ic-reactor/react
2
+
3
+ <div align="center">
4
+ <strong>The Ultimate React Hooks for the Internet Computer.</strong>
5
+ <br><br>
6
+
7
+ [![npm version](https://img.shields.io/npm/v/@ic-reactor/react.svg)](https://www.npmjs.com/package/@ic-reactor/react)
8
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
9
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-blue.svg)](https://www.typescriptlang.org/)
10
+ </div>
11
+
12
+ ---
13
+
14
+ Connect your React application to the Internet Computer Blockchain with full [TanStack Query](https://tanstack.com/query) integration for caching, suspense, and infinite queries.
2
15
 
3
16
  ## Features
4
17
 
5
- - **React Hooks Integration**: Custom hooks for managing blockchain actor states and authentication within React applications.
6
- - **Type-Safe Actor Interactions**: Type-safe interaction with IC actors using the provided actor declaration file.
7
- - **Efficient State Management**: Utilize the power of Zustand for global state management in React components.
8
- - **Asynchronous Data Handling**: Easy handling of asynchronous operations related to IC actors.
9
- - **Authentication Support**: Integrated hooks for managing authentication with the IC blockchain.
10
- - **Auto-Refresh and Query Capabilities**: Support for auto-refreshing data and querying IC actors.
18
+ - ⚛️ **TanStack Query Integration** Full power of React Query (caching, refetching, suspense, infinite queries)
19
+ - **End-to-End Type Safety** Automatic type inference from your Candid files
20
+ - **Auto Transformations** `DisplayReactor` converts BigInt to string, Principal to text, and more
21
+ - 📦 **Result Unwrapping** Automatic `Ok`/`Err` handling from Candid Result types
22
+ - 🔐 **Authentication** Easy-to-use hooks with Internet Identity integration
23
+ - 🏗️ **Multi-Actor Support** Manage multiple canisters with shared authentication
11
24
 
12
25
  ## Installation
13
26
 
14
- Install the package using npm:
15
-
16
27
  ```bash
17
- npm install @ic-reactor/react
18
- ```
28
+ # With npm
29
+ npm install @ic-reactor/react @tanstack/react-query @icp-sdk/core
19
30
 
20
- or using yarn:
31
+ # With pnpm
32
+ pnpm add @ic-reactor/react @tanstack/react-query @icp-sdk/core
21
33
 
22
- ```bash
23
- yarn add @ic-reactor/react
34
+ # Optional: For Internet Identity authentication
35
+ npm install @icp-sdk/auth
24
36
  ```
25
37
 
26
- ## Usage
38
+ ## Quick Start
27
39
 
28
- Here's a simple example to get you started:
40
+ ### 1. Setup ClientManager and Reactor
29
41
 
30
- First, create an actor declaration file:
42
+ ```typescript
43
+ // src/reactor.ts
44
+ import { ClientManager, Reactor } from "@ic-reactor/react"
45
+ import { QueryClient } from "@tanstack/react-query"
46
+ import { idlFactory, type _SERVICE } from "./declarations/my_canister"
31
47
 
32
- ```ts
33
- // actor.ts
34
- import { canisterId, idlFactory, actor } from "declaration/actor"
35
- import { createReactor } from "@ic-reactor/react"
48
+ // Create query client for caching
49
+ export const queryClient = new QueryClient()
36
50
 
37
- type Actor = typeof actor
51
+ // Create client manager (handles identity and agent)
52
+ export const clientManager = new ClientManager({
53
+ queryClient,
54
+ withProcessEnv: true, // Reads DFX_NETWORK from environment
55
+ })
38
56
 
39
- export const { useActorStore, useAuth, useQueryCall } = createReactor<Actor>({
40
- canisterId,
57
+ // Create reactor for your canister
58
+ export const backend = new Reactor<_SERVICE>({
59
+ clientManager,
41
60
  idlFactory,
42
- host: "https://localhost:4943",
61
+ canisterId: "rrkah-fqaaa-aaaaa-aaaaq-cai",
43
62
  })
44
63
  ```
45
64
 
46
- Then, use the `useQueryCall` hook to call your canister method:
47
-
48
- ```jsx
49
- // Balance.tsx
50
- import { useQueryCall } from "./actor"
51
-
52
- const Balance = ({ principal }) => {
53
- const { call, data, loading, error } = useQueryCall({
54
- functionName: "get_balance",
55
- args: [principal],
56
- refetchInterval: 1000,
57
- refetchOnMount: true,
58
- onLoading: () => console.log("Loading..."),
59
- onSuccess: (data) => console.log("Success!", data),
60
- onError: (error) => console.log("Error!", error),
61
- })
65
+ ### 2. Create Hooks
66
+
67
+ ```typescript
68
+ // src/hooks.ts
69
+ import { createActorHooks, createAuthHooks } from "@ic-reactor/react"
70
+ import { backend, clientManager } from "./reactor"
71
+
72
+ // Create actor hooks for queries and mutations
73
+ export const { useActorQuery, useActorMutation, useActorSuspenseQuery } =
74
+ createActorHooks(backend)
75
+
76
+ // Create auth hooks for login/logout
77
+ export const { useAuth, useUserPrincipal } = createAuthHooks(clientManager)
78
+ ```
79
+
80
+ ### 3. Setup Provider (not required) and Use in Components
81
+
82
+ ```tsx
83
+ // src/App.tsx
84
+ import { QueryClientProvider } from "@tanstack/react-query"
85
+ import { queryClient } from "./reactor"
86
+ import { useAuth, useActorQuery, useActorMutation } from "./hooks"
62
87
 
88
+ function App() {
63
89
  return (
64
- <div>
65
- <button onClick={call} disabled={loading}>
66
- {loading ? "Loading..." : "Refresh"}
67
- </button>
68
- {loading && <p>Loading...</p>}
69
- {data && <p>Balance: {data}</p>}
70
- {error && <p>Error: {error}</p>}
71
- </div>
90
+ <QueryClientProvider client={queryClient}>
91
+ <AuthButton />
92
+ <Greeting />
93
+ </QueryClientProvider>
72
94
  )
73
95
  }
74
96
 
75
- export default Balance
97
+ function AuthButton() {
98
+ const { login, logout, isAuthenticated, principal } = useAuth()
99
+
100
+ return isAuthenticated ? (
101
+ <button onClick={() => logout()}>
102
+ Logout {principal?.toText().slice(0, 8)}...
103
+ </button>
104
+ ) : (
105
+ <button onClick={() => login()}>Login with Internet Identity</button>
106
+ )
107
+ }
108
+
109
+ function Greeting() {
110
+ // Query: Fetch data (auto-cached!)
111
+ const { data, isPending, error } = useActorQuery({
112
+ functionName: "greet",
113
+ args: ["World"],
114
+ })
115
+
116
+ if (isPending) return <div>Loading...</div>
117
+ if (error) return <div>Error: {error.message}</div>
118
+
119
+ return <h1>{data}</h1>
120
+ }
76
121
  ```
77
122
 
78
- ## Authentication
123
+ ## Core Concepts
79
124
 
80
- `@ic-reactor/react` provides a custom hook for managing authentication with the IC blockchain. To use it, first create an authentication declaration file:
125
+ ### Reactor vs DisplayReactor
81
126
 
82
- ```jsx
83
- // Login.tsx
84
- import { useAuth } from "./actor"
127
+ | Feature | `Reactor` | `DisplayReactor` |
128
+ | ------------- | ---------------- | --------------------------- |
129
+ | Types | Raw Candid types | Display-friendly types |
130
+ | BigInt | `bigint` | `string` |
131
+ | Principal | `Principal` | `string` |
132
+ | Vec nat8 | `Uint8Array` | <= 96 bytes: `string` (hex) |
133
+ | Result | Unwrapped | Unwrapped |
134
+ | Form-friendly | No | Yes |
85
135
 
86
- const Login = () => {
87
- const {
88
- login,
89
- logout,
90
- loginLoading,
91
- loginError,
92
- identity,
93
- authenticating,
94
- authenticated,
95
- } = useAuth()
136
+ ```typescript
137
+ import { DisplayReactor } from "@ic-reactor/react"
96
138
 
97
- return (
98
- <div>
99
- <h2>Login:</h2>
100
- <div>
101
- {loginLoading && <div>Loading...</div>}
102
- {loginError ? <div>{JSON.stringify(loginError)}</div> : null}
103
- {identity && <div>{identity.getPrincipal().toText()}</div>}
104
- </div>
105
- {authenticated ? (
106
- <div>
107
- <button onClick={logout}>Logout</button>
108
- </div>
109
- ) : (
110
- <div>
111
- <button onClick={login} disabled={authenticating}>
112
- Login
113
- </button>
114
- </div>
115
- )}
116
- </div>
117
- )
139
+ // DisplayReactor for form-friendly UI work
140
+ const backend = new DisplayReactor<_SERVICE>({
141
+ clientManager,
142
+ idlFactory,
143
+ canisterId: "rrkah-fqaaa-aaaaa-aaaaq-cai",
144
+ })
145
+
146
+ // Now hooks return strings instead of bigint/Principal
147
+ const { data } = useActorQuery({
148
+ functionName: "icrc1_balance_of",
149
+ args: [{ owner: "aaaaa-aa", subaccount: [] }], // strings!
150
+ })
151
+ // data is "100000000" instead of 100000000n
152
+ ```
153
+
154
+ ## Hooks Reference
155
+
156
+ ### Actor Hooks (from `createActorHooks`)
157
+
158
+ | Hook | Description |
159
+ | ------------------------------- | ---------------------------------------------- |
160
+ | `useActorQuery` | Standard queries with loading states |
161
+ | `useActorSuspenseQuery` | Suspense-enabled queries (data always defined) |
162
+ | `useActorInfiniteQuery` | Paginated/infinite scroll queries |
163
+ | `useActorSuspenseInfiniteQuery` | Suspense infinite queries |
164
+ | `useActorMutation` | State-changing operations |
165
+
166
+ ### Auth Hooks (from `createAuthHooks`)
167
+
168
+ | Hook | Description |
169
+ | ------------------ | ----------------------------------- |
170
+ | `useAuth` | Login, logout, authentication state |
171
+ | `useAgentState` | Agent initialization state |
172
+ | `useUserPrincipal` | Current user's Principal |
173
+
174
+ ## Query Examples
175
+
176
+ ### Standard Query
177
+
178
+ ```tsx
179
+ const { data, isPending, error } = useActorQuery({
180
+ functionName: "get_user",
181
+ args: ["user-123"],
182
+ staleTime: 5 * 60 * 1000, // 5 minutes
183
+ })
184
+ ```
185
+
186
+ ### Suspense Query
187
+
188
+ ```tsx
189
+ // Parent must have <Suspense> boundary
190
+ function UserProfile() {
191
+ // data is never undefined with suspense!
192
+ const { data } = useActorSuspenseQuery({
193
+ functionName: "get_user",
194
+ args: ["user-123"],
195
+ })
196
+
197
+ return <div>{data.name}</div>
118
198
  }
199
+ ```
200
+
201
+ ### Infinite Query
202
+
203
+ ```tsx
204
+ const { data, fetchNextPage, hasNextPage } = useActorInfiniteQuery({
205
+ functionName: "get_posts",
206
+ initialPageParam: 0,
207
+ getNextPageParam: (lastPage, pages) => pages.length * 10,
208
+ args: (pageParam) => [{ offset: pageParam, limit: 10 }],
209
+ })
210
+ ```
211
+
212
+ ## Mutation Examples
213
+
214
+ ### Basic Mutation
215
+
216
+ ```tsx
217
+ const { mutate, isPending, error } = useActorMutation({
218
+ functionName: "update_profile",
219
+ onSuccess: (result) => {
220
+ console.log("Profile updated!", result)
221
+ },
222
+ })
223
+
224
+ // Call the mutation
225
+ mutate([{ name: "Alice", bio: "Hello IC!" }])
226
+ ```
227
+
228
+ ## Query Factories
229
+
230
+ Create reusable query configurations with factory functions:
231
+
232
+ ```typescript
233
+ import {
234
+ createQuery,
235
+ createSuspenseQuery,
236
+ createMutation,
237
+ } from "@ic-reactor/react"
238
+
239
+ // Static query (no args at call time)
240
+ export const tokenNameQuery = createSuspenseQuery(backend, {
241
+ functionName: "icrc1_name",
242
+ })
243
+
244
+ // In component:
245
+ const { data } = tokenNameQuery.useSuspenseQuery()
246
+ ```
247
+
248
+ ### Factory with Dynamic Args
249
+
250
+ ```typescript
251
+ import { createSuspenseQueryFactory } from "@ic-reactor/react"
252
+
253
+ // Factory for balance queries
254
+ export const getBalance = createSuspenseQueryFactory(backend, {
255
+ functionName: "icrc1_balance_of",
256
+ select: (balance) => `${balance} tokens`,
257
+ })
119
258
 
120
- export default Login
259
+ // In component - pass args at call time
260
+ const { data } = getBalance.useSuspenseQuery({
261
+ args: [{ owner: userPrincipal, subaccount: [] }],
262
+ })
121
263
  ```
264
+
265
+ ## Advanced: Direct Reactor Usage
266
+
267
+ Access reactor methods directly for manual cache management:
268
+
269
+ ```typescript
270
+ // Fetch and cache
271
+ await backend.fetchQuery({
272
+ functionName: "get_user",
273
+ args: ["user-123"],
274
+ })
275
+
276
+ // Get cached data (no fetch)
277
+ const cached = backend.getQueryData({
278
+ functionName: "get_user",
279
+ args: ["user-123"],
280
+ })
281
+
282
+ // Invalidate cache to trigger refetch
283
+ backend.invalidateQueries({
284
+ functionName: "get_user",
285
+ })
286
+
287
+ // Direct call without caching
288
+ const result = await backend.callMethod({
289
+ functionName: "update_user",
290
+ args: [{ name: "Alice" }],
291
+ })
292
+ ```
293
+
294
+ ## Re-exports
295
+
296
+ `@ic-reactor/react` re-exports everything from `@ic-reactor/core`, so you typically only need one import:
297
+
298
+ ```typescript
299
+ // Everything from one package
300
+ import {
301
+ ClientManager,
302
+ Reactor,
303
+ DisplayReactor,
304
+ createActorHooks,
305
+ createAuthHooks,
306
+ createQuery,
307
+ CanisterError,
308
+ } from "@ic-reactor/react"
309
+ ```
310
+
311
+ ## Documentation
312
+
313
+ For comprehensive guides and API reference, visit the [documentation site](https://b3pay.github.io/ic-reactor/v3).
314
+
315
+ ## License
316
+
317
+ MIT © [Behrad Deylami](https://github.com/b3hr4d)
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Actor Hooks Factory - Creates a full set of React hooks for a reactor instance.
3
+ *
4
+ * This is the primary entry point for using the library in React applications.
5
+ * It generates type-safe hooks for:
6
+ * - Queries (useActorQuery)
7
+ * - Suspense Queries (useActorSuspenseQuery)
8
+ * - Infinite Queries (useActorInfiniteQuery)
9
+ * - Suspense Infinite Queries (useActorSuspenseInfiniteQuery)
10
+ * - Mutations (useActorMutation)
11
+ *
12
+ * @example
13
+ * const { useActorQuery, useActorMutation } = createActorHooks(reactor)
14
+ *
15
+ * // In component
16
+ * const { data } = useActorQuery({ functionName: 'get_user' })
17
+ * const { mutate } = useActorMutation({ functionName: 'update_user' })
18
+ */
19
+ import { Reactor, DisplayReactor, ReactorReturnErr, ReactorReturnOk, BaseActor, FunctionName, TransformKey } from "@ic-reactor/core";
20
+ import { UseQueryResult, UseSuspenseQueryResult, UseInfiniteQueryResult, UseSuspenseInfiniteQueryResult, UseMutationResult, InfiniteData } from "@tanstack/react-query";
21
+ import { InfiniteQueryConfig } from "./createInfiniteQuery";
22
+ import { SuspenseInfiniteQueryConfig } from "./createSuspenseInfiniteQuery";
23
+ import { QueryConfig, SuspenseQueryConfig, MutationConfig } from "./types";
24
+ export type ActorHooks<A, T extends TransformKey> = {
25
+ useActorQuery: {
26
+ <M extends FunctionName<A>>(config: QueryConfig<A, M, T, ReactorReturnOk<A, M, T>>): UseQueryResult<ReactorReturnOk<A, M, T>, ReactorReturnErr<A, M, T>>;
27
+ <M extends FunctionName<A>, TData>(config: QueryConfig<A, M, T, TData>): UseQueryResult<TData, ReactorReturnErr<A, M, T>>;
28
+ };
29
+ useActorSuspenseQuery: {
30
+ <M extends FunctionName<A>>(config: SuspenseQueryConfig<A, M, T, ReactorReturnOk<A, M, T>>): UseSuspenseQueryResult<ReactorReturnOk<A, M, T>, ReactorReturnErr<A, M, T>>;
31
+ <M extends FunctionName<A>, TData>(config: SuspenseQueryConfig<A, M, T, TData>): UseSuspenseQueryResult<TData, ReactorReturnErr<A, M, T>>;
32
+ };
33
+ useActorInfiniteQuery: <M extends FunctionName<A>, TPageParam = unknown>(config: InfiniteQueryConfig<A, M, T, TPageParam>) => UseInfiniteQueryResult<InfiniteData<ReactorReturnOk<A, M, T>, TPageParam>, ReactorReturnErr<A, M, T>>;
34
+ useActorSuspenseInfiniteQuery: <M extends FunctionName<A>, TPageParam = unknown>(config: SuspenseInfiniteQueryConfig<A, M, T, TPageParam>) => UseSuspenseInfiniteQueryResult<InfiniteData<ReactorReturnOk<A, M, T>, TPageParam>, ReactorReturnErr<A, M, T>>;
35
+ useActorMutation: <M extends FunctionName<A>>(config: MutationConfig<A, M, T>) => UseMutationResult<ReactorReturnOk<A, M, T>, ReactorReturnErr<A, M, T>>;
36
+ };
37
+ export declare function createActorHooks<A>(reactor: DisplayReactor<A>): ActorHooks<A, "display">;
38
+ export declare function createActorHooks<A = BaseActor, T extends TransformKey = "candid">(reactor: Reactor<A, T>): ActorHooks<A, T>;
39
+ //# sourceMappingURL=createActorHooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createActorHooks.d.ts","sourceRoot":"","sources":["../src/createActorHooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EACL,OAAO,EACP,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,SAAS,EACT,YAAY,EACZ,YAAY,EACb,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,cAAc,EACd,sBAAsB,EACtB,sBAAsB,EACtB,8BAA8B,EAC9B,iBAAiB,EACjB,YAAY,EACb,MAAM,uBAAuB,CAAA;AAG9B,OAAO,EAAuB,mBAAmB,EAAE,MAAM,uBAAuB,CAAA;AAChF,OAAO,EAEL,2BAA2B,EAC5B,MAAM,+BAA+B,CAAA;AAEtC,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAE1E,MAAM,MAAM,UAAU,CAAC,CAAC,EAAE,CAAC,SAAS,YAAY,IAAI;IAClD,aAAa,EAAE;QACb,CAAC,CAAC,SAAS,YAAY,CAAC,CAAC,CAAC,EACxB,MAAM,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GACrD,cAAc,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACtE,CAAC,CAAC,SAAS,YAAY,CAAC,CAAC,CAAC,EAAE,KAAK,EAC/B,MAAM,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,GAClC,cAAc,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;KACpD,CAAA;IAED,qBAAqB,EAAE;QACrB,CAAC,CAAC,SAAS,YAAY,CAAC,CAAC,CAAC,EACxB,MAAM,EAAE,mBAAmB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAC7D,sBAAsB,CACvB,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EACxB,gBAAgB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAC1B,CAAA;QACD,CAAC,CAAC,SAAS,YAAY,CAAC,CAAC,CAAC,EAAE,KAAK,EAC/B,MAAM,EAAE,mBAAmB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,GAC1C,sBAAsB,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;KAC5D,CAAA;IAED,qBAAqB,EAAE,CAAC,CAAC,SAAS,YAAY,CAAC,CAAC,CAAC,EAAE,UAAU,GAAG,OAAO,EACrE,MAAM,EAAE,mBAAmB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,UAAU,CAAC,KAC7C,sBAAsB,CACzB,YAAY,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,CAAC,EAClD,gBAAgB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAC1B,CAAA;IAED,6BAA6B,EAAE,CAC7B,CAAC,SAAS,YAAY,CAAC,CAAC,CAAC,EACzB,UAAU,GAAG,OAAO,EAEpB,MAAM,EAAE,2BAA2B,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,UAAU,CAAC,KACrD,8BAA8B,CACjC,YAAY,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,CAAC,EAClD,gBAAgB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAC1B,CAAA;IAED,gBAAgB,EAAE,CAAC,CAAC,SAAS,YAAY,CAAC,CAAC,CAAC,EAC1C,MAAM,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAC5B,iBAAiB,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;CAC5E,CAAA;AAED,wBAAgB,gBAAgB,CAAC,CAAC,EAChC,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,GACzB,UAAU,CAAC,CAAC,EAAE,SAAS,CAAC,CAAA;AAE3B,wBAAgB,gBAAgB,CAC9B,CAAC,GAAG,SAAS,EACb,CAAC,SAAS,YAAY,GAAG,QAAQ,EACjC,OAAO,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA"}
@@ -0,0 +1,30 @@
1
+ import { createQuery } from "./createQuery";
2
+ import { createSuspenseQuery } from "./createSuspenseQuery";
3
+ import { createInfiniteQuery } from "./createInfiniteQuery";
4
+ import { createSuspenseInfiniteQuery, } from "./createSuspenseInfiniteQuery";
5
+ import { createMutation } from "./createMutation";
6
+ export function createActorHooks(reactor) {
7
+ return {
8
+ useActorQuery: ((config) => {
9
+ const { select, ...options } = config;
10
+ return createQuery(reactor, config).useQuery(options);
11
+ }),
12
+ useActorSuspenseQuery: ((config) => {
13
+ const { select, ...options } = config;
14
+ return createSuspenseQuery(reactor, config).useSuspenseQuery(options);
15
+ }),
16
+ useActorInfiniteQuery: ((config) => {
17
+ const { select, ...options } = config;
18
+ return createInfiniteQuery(reactor, config).useInfiniteQuery(options);
19
+ }),
20
+ useActorSuspenseInfiniteQuery: ((config) => {
21
+ const { select, ...options } = config;
22
+ return createSuspenseInfiniteQuery(reactor, config).useSuspenseInfiniteQuery(options);
23
+ }),
24
+ useActorMutation: ((config) => {
25
+ const { onSuccess, refetchQueries, ...options } = config;
26
+ return createMutation(reactor, config).useMutation(options);
27
+ }),
28
+ };
29
+ }
30
+ //# sourceMappingURL=createActorHooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createActorHooks.js","sourceRoot":"","sources":["../src/createActorHooks.ts"],"names":[],"mappings":"AAmCA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAA;AAC3D,OAAO,EAAE,mBAAmB,EAAuB,MAAM,uBAAuB,CAAA;AAChF,OAAO,EACL,2BAA2B,GAE5B,MAAM,+BAA+B,CAAA;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAwDjD,MAAM,UAAU,gBAAgB,CAC9B,OAAsB;IAEtB,OAAO;QACL,aAAa,EAAE,CAAC,CAAC,MAAW,EAAE,EAAE;YAC9B,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE,GAAG,MAAM,CAAA;YACrC,OAAO,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;QACvD,CAAC,CAAsC;QAEvC,qBAAqB,EAAE,CAAC,CAAC,MAAW,EAAE,EAAE;YACtC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE,GAAG,MAAM,CAAA;YACrC,OAAO,mBAAmB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAA;QACvE,CAAC,CAA8C;QAE/C,qBAAqB,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE;YACjC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE,GAAG,MAAM,CAAA;YACrC,OAAO,mBAAmB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAA;QACvE,CAAC,CAA8C;QAE/C,6BAA6B,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE;YACzC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE,GAAG,MAAM,CAAA;YACrC,OAAO,2BAA2B,CAChC,OAAO,EACP,MAAM,CACP,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAA;QACrC,CAAC,CAAsD;QAEvD,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE;YAC5B,MAAM,EAAE,SAAS,EAAE,cAAc,EAAE,GAAG,OAAO,EAAE,GAAG,MAAM,CAAA;YACxD,OAAO,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,CAAA;QAC7D,CAAC,CAAyC;KAC3C,CAAA;AACH,CAAC"}
@@ -0,0 +1,37 @@
1
+ import { ClientManager, AgentState } from "@ic-reactor/core";
2
+ import { Principal } from "@icp-sdk/core/principal";
3
+ import { Identity } from "@icp-sdk/core/agent";
4
+ import { AuthClientLoginOptions } from "@icp-sdk/auth/client";
5
+ export interface UseAuthReturn {
6
+ authenticate: () => Promise<Identity | undefined>;
7
+ login: (options?: AuthClientLoginOptions) => Promise<void>;
8
+ logout: (options?: {
9
+ returnTo?: string;
10
+ }) => Promise<void>;
11
+ isAuthenticated: boolean;
12
+ isAuthenticating: boolean;
13
+ principal: Principal | null;
14
+ identity: Identity | null;
15
+ error: Error | undefined;
16
+ }
17
+ export interface CreateAuthHooksReturn {
18
+ useAgentState: () => AgentState;
19
+ useUserPrincipal: () => Principal | null;
20
+ useAuth: () => UseAuthReturn;
21
+ }
22
+ /**
23
+ * Create authentication hooks for managing user sessions with Internet Identity.
24
+ *
25
+ * @example
26
+ * const { useAuth, useUserPrincipal, useAgentState } = createAuthHooks(clientManager)
27
+ *
28
+ * function App() {
29
+ * const { login, logout, principal, isAuthenticated } = useAuth()
30
+ *
31
+ * return isAuthenticated
32
+ * ? <button onClick={logout}>Logout {principal?.toText()}</button>
33
+ * : <button onClick={login}>Login with II</button>
34
+ * }
35
+ */
36
+ export declare const createAuthHooks: (clientManager: ClientManager) => CreateAuthHooksReturn;
37
+ //# sourceMappingURL=createAuthHooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createAuthHooks.d.ts","sourceRoot":"","sources":["../src/createAuthHooks.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAa,MAAM,kBAAkB,CAAA;AACvE,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAC9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAA;AAE7D,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAAA;IACjD,KAAK,EAAE,CAAC,OAAO,CAAC,EAAE,sBAAsB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1D,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1D,eAAe,EAAE,OAAO,CAAA;IACxB,gBAAgB,EAAE,OAAO,CAAA;IACzB,SAAS,EAAE,SAAS,GAAG,IAAI,CAAA;IAC3B,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAA;IACzB,KAAK,EAAE,KAAK,GAAG,SAAS,CAAA;CACzB;AAED,MAAM,WAAW,qBAAqB;IACpC,aAAa,EAAE,MAAM,UAAU,CAAA;IAC/B,gBAAgB,EAAE,MAAM,SAAS,GAAG,IAAI,CAAA;IACxC,OAAO,EAAE,MAAM,aAAa,CAAA;CAC7B;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,eAAe,GAC1B,eAAe,aAAa,KAC3B,qBAiGF,CAAA"}
@@ -0,0 +1,94 @@
1
+ import { useSyncExternalStore, useEffect, useRef, useMemo } from "react";
2
+ /**
3
+ * Create authentication hooks for managing user sessions with Internet Identity.
4
+ *
5
+ * @example
6
+ * const { useAuth, useUserPrincipal, useAgentState } = createAuthHooks(clientManager)
7
+ *
8
+ * function App() {
9
+ * const { login, logout, principal, isAuthenticated } = useAuth()
10
+ *
11
+ * return isAuthenticated
12
+ * ? <button onClick={logout}>Logout {principal?.toText()}</button>
13
+ * : <button onClick={login}>Login with II</button>
14
+ * }
15
+ */
16
+ export const createAuthHooks = (clientManager) => {
17
+ /**
18
+ * Subscribe to agent state changes.
19
+ * Returns the current agent state (agent, isInitialized, etc.)
20
+ */
21
+ const useAgentState = () => useSyncExternalStore((callback) => clientManager.subscribeAgentState(callback), () => clientManager.agentState,
22
+ // Server snapshot - provide initial state for SSR
23
+ () => clientManager.agentState);
24
+ /**
25
+ * Subscribe to authentication state changes.
26
+ * Returns auth state (isAuthenticated, isAuthenticating, identity, error)
27
+ */
28
+ const useAuthState = () => useSyncExternalStore((callback) => clientManager.subscribeAuthState(callback), () => clientManager.authState,
29
+ // Server snapshot - provide initial state for SSR
30
+ () => clientManager.authState);
31
+ /**
32
+ * Main authentication hook that provides login/logout methods and auth state.
33
+ * Automatically initializes the session on first use, restoring any previous session.
34
+ *
35
+ * @example
36
+ * function AuthButton() {
37
+ * const { login, logout, isAuthenticated, isAuthenticating } = useAuth()
38
+ *
39
+ * if (isAuthenticated) {
40
+ * return <button onClick={logout}>Logout</button>
41
+ * }
42
+ * return (
43
+ * <button onClick={login} disabled={isAuthenticating}>
44
+ * {isAuthenticating ? "Connecting..." : "Login"}
45
+ * </button>
46
+ * )
47
+ * }
48
+ */
49
+ const useAuth = () => {
50
+ const { login, logout, authenticate } = clientManager;
51
+ const { isAuthenticated, isAuthenticating, identity, error } = useAuthState();
52
+ // Track if we've already initialized to avoid duplicate calls
53
+ const initializedRef = useRef(false);
54
+ // Auto-initialize on first mount to restore previous session
55
+ useEffect(() => {
56
+ if (!initializedRef.current) {
57
+ initializedRef.current = true;
58
+ clientManager.initialize();
59
+ }
60
+ }, []);
61
+ const principal = useMemo(() => (identity ? identity.getPrincipal() : null), [identity]);
62
+ return {
63
+ authenticate,
64
+ login,
65
+ logout,
66
+ isAuthenticated,
67
+ isAuthenticating,
68
+ principal,
69
+ identity,
70
+ error,
71
+ };
72
+ };
73
+ /**
74
+ * Get the current user's Principal.
75
+ * Returns null if not authenticated.
76
+ *
77
+ * @example
78
+ * function UserInfo() {
79
+ * const principal = useUserPrincipal()
80
+ * if (!principal) return null
81
+ * return <span>Logged in as: {principal.toText()}</span>
82
+ * }
83
+ */
84
+ const useUserPrincipal = () => {
85
+ const { identity } = useAuthState();
86
+ return identity ? identity.getPrincipal() : null;
87
+ };
88
+ return {
89
+ useAuth,
90
+ useAgentState,
91
+ useUserPrincipal,
92
+ };
93
+ };
94
+ //# sourceMappingURL=createAuthHooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createAuthHooks.js","sourceRoot":"","sources":["../src/createAuthHooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAuBxE;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,aAA4B,EACL,EAAE;IACzB;;;OAGG;IACH,MAAM,aAAa,GAAG,GAAe,EAAE,CACrC,oBAAoB,CAClB,CAAC,QAAQ,EAAE,EAAE,CAAC,aAAa,CAAC,mBAAmB,CAAC,QAAQ,CAAC,EACzD,GAAG,EAAE,CAAC,aAAa,CAAC,UAAU;IAC9B,kDAAkD;IAClD,GAAG,EAAE,CAAC,aAAa,CAAC,UAAU,CAC/B,CAAA;IAEH;;;OAGG;IACH,MAAM,YAAY,GAAG,GAAc,EAAE,CACnC,oBAAoB,CAClB,CAAC,QAAQ,EAAE,EAAE,CAAC,aAAa,CAAC,kBAAkB,CAAC,QAAQ,CAAC,EACxD,GAAG,EAAE,CAAC,aAAa,CAAC,SAAS;IAC7B,kDAAkD;IAClD,GAAG,EAAE,CAAC,aAAa,CAAC,SAAS,CAC9B,CAAA;IAEH;;;;;;;;;;;;;;;;;OAiBG;IACH,MAAM,OAAO,GAAG,GAAkB,EAAE;QAClC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,aAAa,CAAA;QACrD,MAAM,EAAE,eAAe,EAAE,gBAAgB,EAAE,QAAQ,EAAE,KAAK,EAAE,GAC1D,YAAY,EAAE,CAAA;QAEhB,8DAA8D;QAC9D,MAAM,cAAc,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;QAEpC,6DAA6D;QAC7D,SAAS,CAAC,GAAG,EAAE;YACb,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC;gBAC5B,cAAc,CAAC,OAAO,GAAG,IAAI,CAAA;gBAC7B,aAAa,CAAC,UAAU,EAAE,CAAA;YAC5B,CAAC;QACH,CAAC,EAAE,EAAE,CAAC,CAAA;QAEN,MAAM,SAAS,GAAG,OAAO,CACvB,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EACjD,CAAC,QAAQ,CAAC,CACX,CAAA;QAED,OAAO;YACL,YAAY;YACZ,KAAK;YACL,MAAM;YACN,eAAe;YACf,gBAAgB;YAChB,SAAS;YACT,QAAQ;YACR,KAAK;SACN,CAAA;IACH,CAAC,CAAA;IAED;;;;;;;;;;OAUG;IACH,MAAM,gBAAgB,GAAG,GAAqB,EAAE;QAC9C,MAAM,EAAE,QAAQ,EAAE,GAAG,YAAY,EAAE,CAAA;QACnC,OAAO,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;IAClD,CAAC,CAAA;IAED,OAAO;QACL,OAAO;QACP,aAAa;QACb,gBAAgB;KACjB,CAAA;AACH,CAAC,CAAA"}