@ic-reactor/vite-plugin 0.8.0 → 0.10.0

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
@@ -31,7 +31,7 @@ export default defineConfig({
31
31
 
32
32
  ```ts
33
33
  // src/clients.ts
34
- import { ClientManager } from "@ic-reactor/react"
34
+ import { ClientManager } from "@ic-reactor/core"
35
35
  import { QueryClient } from "@tanstack/react-query"
36
36
 
37
37
  export const queryClient = new QueryClient()
@@ -43,6 +43,9 @@ export const clientManager = new ClientManager({
43
43
 
44
44
  The plugin generates files under `src/declarations/<canister>/` by default.
45
45
 
46
+ If you want non-React output, set `target: "core"` and install the matching
47
+ runtime package instead of `@ic-reactor/react`.
48
+
46
49
  ## Options
47
50
 
48
51
  ```ts
@@ -56,6 +59,7 @@ icReactor({
56
59
  ],
57
60
  outDir: "src/declarations",
58
61
  clientManagerPath: "../../clients",
62
+ target: "react",
59
63
  injectEnvironment: true,
60
64
  })
61
65
  ```
@@ -66,6 +70,7 @@ icReactor({
66
70
  - `didFile`
67
71
  - `outDir`
68
72
  - `clientManagerPath`
73
+ - `target`
69
74
  - `mode`
70
75
  - `canisterId`
71
76
 
@@ -77,11 +82,16 @@ Supported `mode` values:
77
82
  - `CandidDisplayReactor`
78
83
  - `MetadataDisplayReactor`
79
84
 
85
+ Supported `target` values:
86
+
87
+ - `react` (default): generates the reactor plus bound React hooks
88
+ - `core`: generates only the typed reactor exports with no React dependency
89
+
80
90
  ## Local Development Behavior
81
91
 
82
92
  When `injectEnvironment` is enabled during `vite dev`, the plugin:
83
93
 
84
- 1. asks `icp-cli` for the local network status
94
+ 1. asks `icp` for the local network status
85
95
  2. resolves configured canister IDs
86
96
  3. sets the `ic_env` cookie
87
97
  4. proxies `/api` to the local replica
package/dist/index.cjs CHANGED
@@ -83,11 +83,13 @@ function icReactor(options) {
83
83
  canisters,
84
84
  outDir = "src/declarations",
85
85
  clientManagerPath = "../../clients",
86
+ target = "react",
86
87
  injectEnvironment = true
87
88
  } = options;
88
89
  const globalConfig = {
89
90
  outDir,
90
- clientManagerPath
91
+ clientManagerPath,
92
+ target
91
93
  };
92
94
  const projectRoot = process.cwd();
93
95
  const resolveDidPath = (didFile) => import_node_path.default.normalize(
@@ -100,7 +102,7 @@ function icReactor(options) {
100
102
  name: "ic-reactor-plugin",
101
103
  enforce: "pre",
102
104
  // Run before other plugins
103
- config(config, { command }) {
105
+ config(_config, { command }) {
104
106
  if (command !== "serve" || !injectEnvironment) {
105
107
  return {};
106
108
  }
@@ -148,28 +150,29 @@ function icReactor(options) {
148
150
  },
149
151
  async buildStart() {
150
152
  console.log(
151
- `[ic-reactor] Generating hooks for ${canisters.length} canisters...`
153
+ `[ic-reactor] Generating canister bindings for ${canisters.length} canisters...`
152
154
  );
153
- for (const canisterConfig of canisters) {
154
- try {
155
- const result = await (0, import_codegen.runCanisterPipeline)({
156
- canisterConfig,
157
- projectRoot,
158
- globalConfig
159
- });
160
- if (!result.success) {
155
+ await Promise.allSettled(
156
+ canisters.map(async (canisterConfig) => {
157
+ try {
158
+ const result = await (0, import_codegen.runCanisterPipeline)({
159
+ canisterConfig,
160
+ projectRoot,
161
+ globalConfig
162
+ });
163
+ if (!result.success) {
164
+ console.error(
165
+ `[ic-reactor] Failed to generate ${canisterConfig.name}: ${result.error}`
166
+ );
167
+ }
168
+ } catch (err) {
161
169
  console.error(
162
- `[ic-reactor] Failed to generate ${canisterConfig.name}: ${result.error}`
170
+ `[ic-reactor] Error generating ${canisterConfig.name}:`,
171
+ err
163
172
  );
164
- } else {
165
173
  }
166
- } catch (err) {
167
- console.error(
168
- `[ic-reactor] Error generating ${canisterConfig.name}:`,
169
- err
170
- );
171
- }
172
- }
174
+ })
175
+ );
173
176
  },
174
177
  handleHotUpdate({ file, server }) {
175
178
  if (file.endsWith(".did")) {
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { CanisterConfig } from '@ic-reactor/codegen';
1
+ import { CanisterConfig, CodegenTarget } from '@ic-reactor/codegen';
2
2
 
3
3
  /**
4
4
  * @ic-reactor/vite-plugin
@@ -25,6 +25,11 @@ interface IcReactorPluginOptions {
25
25
  * Default: "../../clients"
26
26
  */
27
27
  clientManagerPath?: string;
28
+ /**
29
+ * Default generated runtime target.
30
+ * Default: "react"
31
+ */
32
+ target?: CodegenTarget;
28
33
  /**
29
34
  * Automatically inject `ic_env` cookie for local development?
30
35
  * Default: true
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { CanisterConfig } from '@ic-reactor/codegen';
1
+ import { CanisterConfig, CodegenTarget } from '@ic-reactor/codegen';
2
2
 
3
3
  /**
4
4
  * @ic-reactor/vite-plugin
@@ -25,6 +25,11 @@ interface IcReactorPluginOptions {
25
25
  * Default: "../../clients"
26
26
  */
27
27
  clientManagerPath?: string;
28
+ /**
29
+ * Default generated runtime target.
30
+ * Default: "react"
31
+ */
32
+ target?: CodegenTarget;
28
33
  /**
29
34
  * Automatically inject `ic_env` cookie for local development?
30
35
  * Default: true
package/dist/index.js CHANGED
@@ -51,11 +51,13 @@ function icReactor(options) {
51
51
  canisters,
52
52
  outDir = "src/declarations",
53
53
  clientManagerPath = "../../clients",
54
+ target = "react",
54
55
  injectEnvironment = true
55
56
  } = options;
56
57
  const globalConfig = {
57
58
  outDir,
58
- clientManagerPath
59
+ clientManagerPath,
60
+ target
59
61
  };
60
62
  const projectRoot = process.cwd();
61
63
  const resolveDidPath = (didFile) => path.normalize(
@@ -68,7 +70,7 @@ function icReactor(options) {
68
70
  name: "ic-reactor-plugin",
69
71
  enforce: "pre",
70
72
  // Run before other plugins
71
- config(config, { command }) {
73
+ config(_config, { command }) {
72
74
  if (command !== "serve" || !injectEnvironment) {
73
75
  return {};
74
76
  }
@@ -116,28 +118,29 @@ function icReactor(options) {
116
118
  },
117
119
  async buildStart() {
118
120
  console.log(
119
- `[ic-reactor] Generating hooks for ${canisters.length} canisters...`
121
+ `[ic-reactor] Generating canister bindings for ${canisters.length} canisters...`
120
122
  );
121
- for (const canisterConfig of canisters) {
122
- try {
123
- const result = await runCanisterPipeline({
124
- canisterConfig,
125
- projectRoot,
126
- globalConfig
127
- });
128
- if (!result.success) {
123
+ await Promise.allSettled(
124
+ canisters.map(async (canisterConfig) => {
125
+ try {
126
+ const result = await runCanisterPipeline({
127
+ canisterConfig,
128
+ projectRoot,
129
+ globalConfig
130
+ });
131
+ if (!result.success) {
132
+ console.error(
133
+ `[ic-reactor] Failed to generate ${canisterConfig.name}: ${result.error}`
134
+ );
135
+ }
136
+ } catch (err) {
129
137
  console.error(
130
- `[ic-reactor] Failed to generate ${canisterConfig.name}: ${result.error}`
138
+ `[ic-reactor] Error generating ${canisterConfig.name}:`,
139
+ err
131
140
  );
132
- } else {
133
141
  }
134
- } catch (err) {
135
- console.error(
136
- `[ic-reactor] Error generating ${canisterConfig.name}:`,
137
- err
138
- );
139
- }
140
- }
142
+ })
143
+ );
141
144
  },
142
145
  handleHotUpdate({ file, server }) {
143
146
  if (file.endsWith(".did")) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ic-reactor/vite-plugin",
3
- "version": "0.8.0",
3
+ "version": "0.10.0",
4
4
  "description": "Vite plugin for zero-config IC reactor generation from Candid files",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -37,17 +37,17 @@
37
37
  "url": "https://github.com/B3Pay/ic-reactor/issues"
38
38
  },
39
39
  "dependencies": {
40
- "@ic-reactor/codegen": "0.8.0"
40
+ "@ic-reactor/codegen": "0.10.0"
41
41
  },
42
42
  "peerDependencies": {
43
43
  "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
44
44
  },
45
45
  "devDependencies": {
46
- "@icp-sdk/bindgen": "^0.2.2",
47
- "@types/node": "^25.3.5",
46
+ "@icp-sdk/bindgen": "^0.3.0",
47
+ "@types/node": "^25.5.2",
48
48
  "tsup": "^8.5.1",
49
49
  "typescript": "^5.9.3",
50
- "vitest": "^4.0.18"
50
+ "vitest": "^4.1.2"
51
51
  },
52
52
  "scripts": {
53
53
  "build": "tsup src/index.ts --format esm,cjs --dts --tsconfig tsconfig.json",
package/src/env.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Environment Injection Utilities
3
3
  *
4
- * Handles detecting the local IC environment (via `dfx` or `icp` CLI)
4
+ * Handles detecting the local IC environment via the `icp` CLI
5
5
  * and building the `ic_env` cookie for the browser.
6
6
  */
7
7
 
@@ -15,16 +15,13 @@ export interface IcEnvironment {
15
15
  }
16
16
 
17
17
  /**
18
- * Detect the IC environment using the `icp` or `dfx` CLI.
18
+ * Detect the IC environment using the `icp` CLI.
19
19
  */
20
20
  export function getIcEnvironmentInfo(
21
21
  canisterNames: string[]
22
22
  ): IcEnvironment | null {
23
23
  const environment = process.env.ICP_ENVIRONMENT || "local"
24
24
 
25
- // We try `icp` first, but could fallback to `dfx` logic if needed.
26
- // For now, assuming `icp` CLI is available based on previous code.
27
-
28
25
  try {
29
26
  const networkStatus = JSON.parse(
30
27
  execFileSync("icp", ["network", "status", "-e", environment, "--json"], {
package/src/index.test.ts CHANGED
@@ -78,7 +78,7 @@ describe("icReactor", () => {
78
78
  describe("config", () => {
79
79
  it("should set up API proxy and headers when icp-cli is available", () => {
80
80
  ;(execFileSync as any).mockImplementation(
81
- (command: string, args: string[], options: any) => {
81
+ (command: string, args: string[], _options: any) => {
82
82
  if (
83
83
  command === "icp" &&
84
84
  args.includes("network") &&
@@ -112,7 +112,7 @@ describe("icReactor", () => {
112
112
 
113
113
  it("should prefer configured canisterId over CLI-discovered env values", () => {
114
114
  ;(execFileSync as any).mockImplementation(
115
- (command: string, args: string[], options: any) => {
115
+ (command: string, args: string[], _options: any) => {
116
116
  if (
117
117
  command === "icp" &&
118
118
  args.includes("network") &&
@@ -181,6 +181,7 @@ describe("icReactor", () => {
181
181
  globalConfig: {
182
182
  outDir: "src/declarations",
183
183
  clientManagerPath: "../../clients",
184
+ target: "react",
184
185
  },
185
186
  })
186
187
  })
@@ -227,6 +228,26 @@ describe("icReactor", () => {
227
228
  globalConfig: {
228
229
  outDir: "src/declarations",
229
230
  clientManagerPath: "../../clients",
231
+ target: "react",
232
+ },
233
+ })
234
+ })
235
+
236
+ it("should pass the configured runtime target to codegen", async () => {
237
+ const plugin = createVitePlugin({
238
+ ...mockOptions,
239
+ target: "core",
240
+ })
241
+
242
+ await (plugin.buildStart as any)()
243
+
244
+ expect(runCanisterPipeline).toHaveBeenCalledWith({
245
+ canisterConfig: mockOptions.canisters[0],
246
+ projectRoot: expect.any(String),
247
+ globalConfig: {
248
+ outDir: "src/declarations",
249
+ clientManagerPath: "../../clients",
250
+ target: "core",
230
251
  },
231
252
  })
232
253
  })
package/src/index.ts CHANGED
@@ -13,6 +13,7 @@ import {
13
13
  runCanisterPipeline,
14
14
  type CanisterConfig,
15
15
  type CodegenConfig,
16
+ type CodegenTarget,
16
17
  } from "@ic-reactor/codegen"
17
18
  import { getIcEnvironmentInfo, buildIcEnvCookie } from "./env.js"
18
19
 
@@ -32,6 +33,11 @@ export interface IcReactorPluginOptions {
32
33
  * Default: "../../clients"
33
34
  */
34
35
  clientManagerPath?: string
36
+ /**
37
+ * Default generated runtime target.
38
+ * Default: "react"
39
+ */
40
+ target?: CodegenTarget
35
41
  /**
36
42
  * Automatically inject `ic_env` cookie for local development?
37
43
  * Default: true
@@ -44,13 +50,18 @@ export function icReactor(options: IcReactorPluginOptions): any {
44
50
  canisters,
45
51
  outDir = "src/declarations",
46
52
  clientManagerPath = "../../clients",
53
+ target = "react",
47
54
  injectEnvironment = true,
48
55
  } = options
49
56
 
50
57
  // Construct a partial CodegenConfig to pass to the pipeline
51
- const globalConfig: Pick<CodegenConfig, "outDir" | "clientManagerPath"> = {
58
+ const globalConfig: Pick<
59
+ CodegenConfig,
60
+ "outDir" | "clientManagerPath" | "target"
61
+ > = {
52
62
  outDir,
53
63
  clientManagerPath,
64
+ target,
54
65
  }
55
66
  const projectRoot = process.cwd()
56
67
  const resolveDidPath = (didFile: string) =>
@@ -67,7 +78,7 @@ export function icReactor(options: IcReactorPluginOptions): any {
67
78
  name: "ic-reactor-plugin",
68
79
  enforce: "pre", // Run before other plugins
69
80
 
70
- config(config, { command }) {
81
+ config(_config, { command }) {
71
82
  if (command !== "serve" || !injectEnvironment) {
72
83
  return {}
73
84
  }
@@ -131,36 +142,35 @@ export function icReactor(options: IcReactorPluginOptions): any {
131
142
  // ── Code Generation ──────────────────────────────────────────────────
132
143
 
133
144
  console.log(
134
- `[ic-reactor] Generating hooks for ${canisters.length} canisters...`
145
+ `[ic-reactor] Generating canister bindings for ${canisters.length} canisters...`
135
146
  )
136
147
 
137
- for (const canisterConfig of canisters) {
138
- try {
139
- // If .did file is missing, we might want to attempt pulling it?
140
- // For now, pipeline fails if missing. The old plugin logic to "download"
141
- // is omitted for simplicity unless requested, to keep "codegen" pure.
142
-
143
- const result = await runCanisterPipeline({
144
- canisterConfig,
145
- projectRoot,
146
- globalConfig,
147
- })
148
-
149
- if (!result.success) {
148
+ await Promise.allSettled(
149
+ canisters.map(async (canisterConfig) => {
150
+ try {
151
+ // If .did file is missing, we might want to attempt pulling it?
152
+ // For now, pipeline fails if missing. The old plugin logic to "download"
153
+ // is omitted for simplicity unless requested, to keep "codegen" pure.
154
+
155
+ const result = await runCanisterPipeline({
156
+ canisterConfig,
157
+ projectRoot,
158
+ globalConfig,
159
+ })
160
+
161
+ if (!result.success) {
162
+ console.error(
163
+ `[ic-reactor] Failed to generate ${canisterConfig.name}: ${result.error}`
164
+ )
165
+ }
166
+ } catch (err) {
150
167
  console.error(
151
- `[ic-reactor] Failed to generate ${canisterConfig.name}: ${result.error}`
168
+ `[ic-reactor] Error generating ${canisterConfig.name}:`,
169
+ err
152
170
  )
153
- } else {
154
- // Optional: log success
155
- // console.log(`[ic-reactor] Generated ${canisterConfig.name} hooks`)
156
171
  }
157
- } catch (err) {
158
- console.error(
159
- `[ic-reactor] Error generating ${canisterConfig.name}:`,
160
- err
161
- )
162
- }
163
- }
172
+ })
173
+ )
164
174
  },
165
175
 
166
176
  handleHotUpdate({ file, server }) {