@ic-reactor/cli 0.2.0 → 0.3.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 CHANGED
@@ -1,23 +1,12 @@
1
1
  # @ic-reactor/cli
2
2
 
3
- > 🔧 Generate shadcn-style React hooks for ICP canisters
3
+ > 🔧 Command-line tool for generating IC reactor hooks and declarations.
4
4
 
5
- The `@ic-reactor/cli` generates **customizable, user-owned** React hooks for interacting with Internet Computer canisters. Unlike build-time code generation, you get full control over the generated code.
6
-
7
- ## Philosophy
8
-
9
- Like [shadcn/ui](https://ui.shadcn.com/), this CLI generates code **into your project** rather than hiding it in `node_modules`. This means:
10
-
11
- - ✅ **Full control** - Customize hooks to your needs
12
- - ✅ **No magic** - See exactly what's happening
13
- - ✅ **Version controlled** - Hooks are part of your codebase
14
- - ✅ **Framework agnostic** - Works with any React setup
5
+ The `@ic-reactor/cli` helps you generate TypeScript declarations and React hooks from your Candid files. It provides a simple way to keep your frontend types and interactions in sync with your backend canisters.
15
6
 
16
7
  ## Installation
17
8
 
18
9
  ```bash
19
- npm install -D @ic-reactor/cli
20
- # or
21
10
  pnpm add -D @ic-reactor/cli
22
11
  ```
23
12
 
@@ -29,38 +18,47 @@ pnpm add -D @ic-reactor/cli
29
18
  npx @ic-reactor/cli init
30
19
  ```
31
20
 
32
- This creates:
21
+ This creates an `ic-reactor.json` configuration file in your project root.
33
22
 
34
- - `reactor.config.json` - Configuration file
35
- - `src/lib/client.ts` - Client manager (optional)
36
- - `src/canisters/` - Output directory for hooks
23
+ ### 2. Configure your canisters
37
24
 
38
- ### 2. Add hooks for a canister
25
+ Update `ic-reactor.json` with the paths to your Candid files:
26
+
27
+ ```json
28
+ {
29
+ "outDir": "./src/canisters",
30
+ "canisters": {
31
+ "backend": {
32
+ "didFile": "src/declarations/backend.did"
33
+ }
34
+ }
35
+ }
36
+ ```
37
+
38
+ ### 3. Sync hooks and declarations
39
39
 
40
40
  ```bash
41
- npx @ic-reactor/cli add
41
+ npx @ic-reactor/cli sync
42
42
  ```
43
43
 
44
- Interactive prompts will guide you through:
44
+ This command will:
45
45
 
46
- 1. Selecting a canister
47
- 2. Choosing methods to generate hooks for
48
- 3. Selecting hook types (Query, Suspense Query, Infinite Query, Mutation)
46
+ 1. Regenerate TypeScript declarations for your canisters.
47
+ 2. Create an `index.ts` file for each canister with fully typed hooks.
49
48
 
50
- ### 3. Use the hooks
49
+ ### 4. Use the generated hooks
50
+
51
+ Import the hooks directly from the generated output folder:
51
52
 
52
53
  ```tsx
53
- import { useGetMessageQuery, getMessageQuery } from "./canisters/backend/hooks"
54
+ import { useActorQuery } from "./canisters/backend"
54
55
 
55
56
  function MyComponent() {
56
- // Use the React hook
57
- const { data, isLoading } = useGetMessageQuery()
58
-
59
- // Or fetch directly (for loaders, etc.)
60
- await getMessageQuery.fetch()
57
+ const { data, isPending } = useActorQuery({
58
+ functionName: "get_message",
59
+ })
61
60
 
62
- // Invalidate cache
63
- await getMessageQuery.invalidate()
61
+ return <p>{isPending ? "Loading..." : data}</p>
64
62
  }
65
63
  ```
66
64
 
@@ -68,7 +66,7 @@ function MyComponent() {
68
66
 
69
67
  ### `init`
70
68
 
71
- Initialize ic-reactor in your project.
69
+ Initialize the configuration file (`ic-reactor.json`).
72
70
 
73
71
  ```bash
74
72
  npx @ic-reactor/cli init [options]
@@ -78,189 +76,49 @@ Options:
78
76
  -o, --out-dir <path> Output directory for generated hooks
79
77
  ```
80
78
 
81
- ### `add`
82
-
83
- Add hooks for canister methods (from local .did file).
84
-
85
- ```bash
86
- npx @ic-reactor/cli add [options]
87
-
88
- Options:
89
- -c, --canister <name> Canister to add hooks for
90
- -m, --methods <methods...> Specific methods to generate
91
- -a, --all Add hooks for all methods
92
- ```
93
-
94
- ### `fetch`
79
+ ### `sync`
95
80
 
96
- **Fetch Candid from a live canister** and generate hooks. No local .did file needed!
81
+ Regenerate hooks and declarations based on your configuration and DID files.
97
82
 
98
83
  ```bash
99
- npx @ic-reactor/cli fetch [options]
84
+ npx @ic-reactor/cli sync [options]
100
85
 
101
86
  Options:
102
- -i, --canister-id <id> Canister ID to fetch from
103
- -n, --network <network> Network: 'ic' or 'local' (default: ic)
104
- --name <name> Name for the canister in generated code
105
- -m, --methods <methods...> Specific methods to generate
106
- -a, --all Add hooks for all methods
107
- ```
108
-
109
- **Example:**
110
-
111
- ```bash
112
- # Fetch from IC mainnet
113
- npx @ic-reactor/cli fetch -i ryjl3-tyaaa-aaaaa-aaaba-cai
114
-
115
- # Fetch from local replica
116
- npx @ic-reactor/cli fetch -i bkyz2-fmaaa-aaaaa-qaaaq-cai -n local
87
+ -c, --canister <name> Sync only a specific canister
117
88
  ```
118
89
 
119
90
  ### `list`
120
91
 
121
- List available methods from a canister.
92
+ List all available methods from a canister's Candid definition.
122
93
 
123
94
  ```bash
124
- npx @ic-reactor/cli list [options]
125
-
126
- Options:
127
- -c, --canister <name> Canister to list methods from
128
- ```
129
-
130
- ### `sync`
131
-
132
- Regenerate hooks after DID file changes.
133
-
134
- ```bash
135
- npx @ic-reactor/cli sync [options]
136
-
137
- Options:
138
- -c, --canister <name> Canister to sync (default: all)
95
+ npx @ic-reactor/cli list -c <canister_name>
139
96
  ```
140
97
 
141
98
  ## Configuration
142
99
 
143
- ### reactor.config.json
144
-
145
- ```json
146
- {
147
- "$schema": "https://raw.githubusercontent.com/B3Pay/ic-reactor/main/packages/cli/schema.json",
148
- "outDir": "src/canisters",
149
- "canisters": {
150
- "backend": {
151
- "didFile": "./backend.did",
152
- "clientManagerPath": "../../lib/client",
153
- "useDisplayReactor": true
154
- }
155
- },
156
- "generatedHooks": {
157
- "backend": ["get_message", "set_message"]
158
- }
159
- }
160
- ```
161
-
162
- ### Configuration Options
163
-
164
- | Option | Description |
165
- | ------------------------------------ | ----------------------------------------- |
166
- | `outDir` | Directory where hooks are generated |
167
- | `canisters` | Canister configurations |
168
- | `canisters.<name>.didFile` | Path to the `.did` file |
169
- | `canisters.<name>.clientManagerPath` | Import path to client manager |
170
- | `canisters.<name>.useDisplayReactor` | Use DisplayReactor for type transforms |
171
- | `generatedHooks` | Tracks which methods have hooks generated |
172
-
173
- ## Generated File Structure
174
-
175
- ```
176
- src/canisters/
177
- ├── backend/
178
- │ ├── reactor.ts # Shared reactor instance
179
- │ └── hooks/
180
- │ ├── index.ts # Barrel exports
181
- │ ├── getMessageQuery.ts # Query hook
182
- │ ├── setMessageMutation.ts # Mutation hook
183
- │ └── getPostsInfiniteQuery.ts # Infinite query
184
- ```
185
-
186
- ## Hook Types
187
-
188
- ### Query (methods without side effects)
189
-
190
- ```typescript
191
- // For methods WITH arguments - factory pattern
192
- export const getUserQuery = createQueryFactory(reactor, {
193
- functionName: "get_user",
194
- })
195
-
196
- // Usage
197
- const query = getUserQuery([userId])
198
- const { data } = query.useQuery()
199
-
200
- // For methods WITHOUT arguments - static instance
201
- export const getConfigQuery = createQuery(reactor, {
202
- functionName: "get_config",
203
- })
204
-
205
- // Usage
206
- const { data } = getConfigQuery.useQuery()
207
- await getConfigQuery.fetch()
208
- ```
209
-
210
- ### Mutation (methods with side effects)
211
-
212
- ```typescript
213
- export const setMessageMutation = createMutation(reactor, {
214
- functionName: "set_message",
215
- invalidateQueries: [getMessageQuery.getQueryKey()],
216
- })
100
+ The `ic-reactor.json` file supports the following options:
217
101
 
218
- // Usage
219
- const { mutate, isPending } = setMessageMutation.useMutation()
220
- mutate(["Hello, ICP!"])
221
- ```
222
-
223
- ### Infinite Query (paginated data)
224
-
225
- ```typescript
226
- export const getPostsInfiniteQuery = createInfiniteQuery(reactor, {
227
- functionName: "get_posts",
228
- initialPageParam: 0,
229
- getArgs: (cursor) => [{ cursor, limit: 10 }],
230
- getNextPageParam: (lastPage) => lastPage.nextCursor ?? undefined,
231
- })
232
-
233
- // Usage
234
- const { data, fetchNextPage, hasNextPage } =
235
- getPostsInfiniteQuery.useInfiniteQuery()
236
- const allPosts = data?.pages.flatMap((page) => page.items) ?? []
237
- ```
102
+ | Option | Type | Description |
103
+ | :------------------ | :------------------------------- | :----------------------------------------- |
104
+ | `outDir` | `string` | Base output directory for generated files. |
105
+ | `canisters` | `Record<string, CanisterConfig>` | Map of canister names to configurations. |
106
+ | `clientManagerPath` | `string` | Path to a custom `ClientManager` instance. |
238
107
 
239
- ## Customization
108
+ ### Canister Config
240
109
 
241
- Since the code is generated into your project, you can:
242
-
243
- 1. **Modify hook options** - Change staleTime, select transforms, etc.
244
- 2. **Add custom logic** - Error handling, optimistic updates
245
- 3. **Combine hooks** - Create composite hooks
246
- 4. **Type overrides** - Adjust TypeScript types
247
-
248
- Example customization:
249
-
250
- ```typescript
251
- // getMessageQuery.ts (generated, then customized)
252
- export const getMessageQuery = createQuery(reactor, {
253
- functionName: "get_message",
254
- staleTime: 30 * 1000, // Custom: 30 seconds
255
- select: (data) => data.message.toUpperCase(), // Custom transform
256
- })
257
- ```
110
+ | Option | Type | Description |
111
+ | :------------------ | :-------- | :-------------------------------------------------- |
112
+ | `didFile` | `string` | Path to the `.did` file. |
113
+ | `outDir` | `string` | Override output directory for this canister. |
114
+ | `useDisplayReactor` | `boolean` | Use `DisplayReactor` instead of standard `Reactor`. |
115
+ | `clientManagerPath` | `string` | Override client manager path. |
258
116
 
259
117
  ## Requirements
260
118
 
261
119
  - Node.js 18+
262
120
  - @ic-reactor/react 3.x
263
- - React 18+
121
+ - TypeScript 5.0+
264
122
 
265
123
  ## License
266
124