@ic-reactor/vite-plugin 0.5.0 → 0.6.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 +60 -2
- package/dist/index.cjs +10 -5
- package/dist/index.d.cts +8 -4
- package/dist/index.d.ts +8 -4
- package/dist/index.js +9 -4
- package/package.json +3 -4
- package/src/index.test.ts +39 -11
- package/src/index.ts +19 -5
package/README.md
CHANGED
|
@@ -38,12 +38,12 @@ pnpm add @ic-reactor/react @tanstack/react-query @icp-sdk/core
|
|
|
38
38
|
// vite.config.ts
|
|
39
39
|
import { defineConfig } from "vite"
|
|
40
40
|
import react from "@vitejs/plugin-react"
|
|
41
|
-
import {
|
|
41
|
+
import { icReactor } from "@ic-reactor/vite-plugin"
|
|
42
42
|
|
|
43
43
|
export default defineConfig({
|
|
44
44
|
plugins: [
|
|
45
45
|
react(),
|
|
46
|
-
|
|
46
|
+
icReactor({
|
|
47
47
|
canisters: [
|
|
48
48
|
{
|
|
49
49
|
name: "backend",
|
|
@@ -87,6 +87,56 @@ function MyComponent() {
|
|
|
87
87
|
}
|
|
88
88
|
```
|
|
89
89
|
|
|
90
|
+
### Reactor Mode (raw vs display)
|
|
91
|
+
|
|
92
|
+
By default, generated hooks use `DisplayReactor` (backward compatible). You can switch the default globally, and override specific canisters that need raw Candid shapes.
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
icReactor({
|
|
96
|
+
canisters: [
|
|
97
|
+
{ name: "backend", didFile: "./backend/backend.did" },
|
|
98
|
+
{ name: "workflow_engine", didFile: "./workflow/workflow_engine.did" },
|
|
99
|
+
],
|
|
100
|
+
reactor: {
|
|
101
|
+
defaultMode: "display",
|
|
102
|
+
canisters: {
|
|
103
|
+
workflow_engine: "raw",
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
})
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Generated canister folders now contain:
|
|
110
|
+
|
|
111
|
+
- `index.generated.ts` (overwritten on regenerate)
|
|
112
|
+
- `index.ts` (created once if missing, never overwritten)
|
|
113
|
+
|
|
114
|
+
The generated implementation exports both factories so apps can opt in explicitly without editing generated files:
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
// display-default canister (generated)
|
|
118
|
+
export function createBackendRawReactor() {
|
|
119
|
+
/* ... */
|
|
120
|
+
}
|
|
121
|
+
export function createBackendDisplayReactor() {
|
|
122
|
+
/* ... */
|
|
123
|
+
}
|
|
124
|
+
export const backendReactor = createBackendDisplayReactor()
|
|
125
|
+
export const BackendReactorMode = "display" as const
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
// raw-default canister (generated)
|
|
130
|
+
export function createWorkflowEngineRawReactor() {
|
|
131
|
+
/* ... */
|
|
132
|
+
}
|
|
133
|
+
export function createWorkflowEngineDisplayReactor() {
|
|
134
|
+
/* ... */
|
|
135
|
+
}
|
|
136
|
+
export const workflowEngineReactor = createWorkflowEngineRawReactor()
|
|
137
|
+
export const WorkflowEngineReactorMode = "raw" as const
|
|
138
|
+
```
|
|
139
|
+
|
|
90
140
|
## Configuration
|
|
91
141
|
|
|
92
142
|
### Plugin Options
|
|
@@ -97,6 +147,7 @@ function MyComponent() {
|
|
|
97
147
|
| `outDir` | `string` | Base output directory for generated files. | `"src/declarations"` |
|
|
98
148
|
| `clientManagerPath` | `string` | Path to client manager import. | `"../../clients"` |
|
|
99
149
|
| `injectEnvironment` | `boolean` | Inject `ic_env` cookie for local development. | `true` |
|
|
150
|
+
| `reactor` | `ReactorConfig` | Default/per-canister raw vs display reactor mode. | display default |
|
|
100
151
|
|
|
101
152
|
### Canister Config
|
|
102
153
|
|
|
@@ -108,6 +159,13 @@ function MyComponent() {
|
|
|
108
159
|
| `clientManagerPath` | `string` | Override client manager path. | No |
|
|
109
160
|
| `canisterId` | `string` | Optional fixed canister ID. | No |
|
|
110
161
|
|
|
162
|
+
### ReactorConfig
|
|
163
|
+
|
|
164
|
+
| Option | Type | Description | Required |
|
|
165
|
+
| :------------ | :----------------------------------- | :--------------------------------------- | :------- |
|
|
166
|
+
| `defaultMode` | `"raw" \| "display"` | Global default mode for generated hooks. | No |
|
|
167
|
+
| `canisters` | `Record<string, "raw" \| "display">` | Per-canister overrides keyed by name. | No |
|
|
168
|
+
|
|
111
169
|
## Local Development (Environment Injection)
|
|
112
170
|
|
|
113
171
|
When running `vite dev`, the plugin automatically handles local canister environment connection:
|
package/dist/index.cjs
CHANGED
|
@@ -30,7 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
-
|
|
33
|
+
icReactor: () => icReactor
|
|
34
34
|
});
|
|
35
35
|
module.exports = __toCommonJS(index_exports);
|
|
36
36
|
var import_node_path = __toESM(require("path"), 1);
|
|
@@ -78,18 +78,22 @@ function buildIcEnvCookie(canisterIds, rootKey) {
|
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
// src/index.ts
|
|
81
|
-
function
|
|
81
|
+
function icReactor(options) {
|
|
82
82
|
const {
|
|
83
83
|
canisters,
|
|
84
84
|
outDir = "src/declarations",
|
|
85
85
|
clientManagerPath = "../../clients",
|
|
86
|
-
injectEnvironment = true
|
|
86
|
+
injectEnvironment = true,
|
|
87
|
+
reactor
|
|
87
88
|
} = options;
|
|
88
89
|
const globalConfig = {
|
|
89
90
|
outDir,
|
|
90
91
|
clientManagerPath
|
|
91
92
|
};
|
|
92
|
-
|
|
93
|
+
if (reactor != null) {
|
|
94
|
+
globalConfig.reactor = reactor;
|
|
95
|
+
}
|
|
96
|
+
const plugin = {
|
|
93
97
|
name: "ic-reactor-plugin",
|
|
94
98
|
enforce: "pre",
|
|
95
99
|
// Run before other plugins
|
|
@@ -181,8 +185,9 @@ function icReactorPlugin(options) {
|
|
|
181
185
|
}
|
|
182
186
|
}
|
|
183
187
|
};
|
|
188
|
+
return plugin;
|
|
184
189
|
}
|
|
185
190
|
// Annotate the CommonJS export names for ESM import in node:
|
|
186
191
|
0 && (module.exports = {
|
|
187
|
-
|
|
192
|
+
icReactor
|
|
188
193
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { CanisterConfig } from '@ic-reactor/codegen';
|
|
1
|
+
import { CanisterConfig, ReactorGenerationConfig } from '@ic-reactor/codegen';
|
|
3
2
|
|
|
4
3
|
/**
|
|
5
4
|
* @ic-reactor/vite-plugin
|
|
@@ -31,7 +30,12 @@ interface IcReactorPluginOptions {
|
|
|
31
30
|
* Default: true
|
|
32
31
|
*/
|
|
33
32
|
injectEnvironment?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Reactor generation behavior.
|
|
35
|
+
* Controls whether generated default hooks use raw (Reactor) or display (DisplayReactor).
|
|
36
|
+
*/
|
|
37
|
+
reactor?: ReactorGenerationConfig;
|
|
34
38
|
}
|
|
35
|
-
declare function
|
|
39
|
+
declare function icReactor(options: IcReactorPluginOptions): any;
|
|
36
40
|
|
|
37
|
-
export { type IcReactorPluginOptions,
|
|
41
|
+
export { type IcReactorPluginOptions, icReactor };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { CanisterConfig } from '@ic-reactor/codegen';
|
|
1
|
+
import { CanisterConfig, ReactorGenerationConfig } from '@ic-reactor/codegen';
|
|
3
2
|
|
|
4
3
|
/**
|
|
5
4
|
* @ic-reactor/vite-plugin
|
|
@@ -31,7 +30,12 @@ interface IcReactorPluginOptions {
|
|
|
31
30
|
* Default: true
|
|
32
31
|
*/
|
|
33
32
|
injectEnvironment?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Reactor generation behavior.
|
|
35
|
+
* Controls whether generated default hooks use raw (Reactor) or display (DisplayReactor).
|
|
36
|
+
*/
|
|
37
|
+
reactor?: ReactorGenerationConfig;
|
|
34
38
|
}
|
|
35
|
-
declare function
|
|
39
|
+
declare function icReactor(options: IcReactorPluginOptions): any;
|
|
36
40
|
|
|
37
|
-
export { type IcReactorPluginOptions,
|
|
41
|
+
export { type IcReactorPluginOptions, icReactor };
|
package/dist/index.js
CHANGED
|
@@ -46,18 +46,22 @@ function buildIcEnvCookie(canisterIds, rootKey) {
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
// src/index.ts
|
|
49
|
-
function
|
|
49
|
+
function icReactor(options) {
|
|
50
50
|
const {
|
|
51
51
|
canisters,
|
|
52
52
|
outDir = "src/declarations",
|
|
53
53
|
clientManagerPath = "../../clients",
|
|
54
|
-
injectEnvironment = true
|
|
54
|
+
injectEnvironment = true,
|
|
55
|
+
reactor
|
|
55
56
|
} = options;
|
|
56
57
|
const globalConfig = {
|
|
57
58
|
outDir,
|
|
58
59
|
clientManagerPath
|
|
59
60
|
};
|
|
60
|
-
|
|
61
|
+
if (reactor != null) {
|
|
62
|
+
globalConfig.reactor = reactor;
|
|
63
|
+
}
|
|
64
|
+
const plugin = {
|
|
61
65
|
name: "ic-reactor-plugin",
|
|
62
66
|
enforce: "pre",
|
|
63
67
|
// Run before other plugins
|
|
@@ -149,7 +153,8 @@ function icReactorPlugin(options) {
|
|
|
149
153
|
}
|
|
150
154
|
}
|
|
151
155
|
};
|
|
156
|
+
return plugin;
|
|
152
157
|
}
|
|
153
158
|
export {
|
|
154
|
-
|
|
159
|
+
icReactor
|
|
155
160
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ic-reactor/vite-plugin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.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,16 @@
|
|
|
37
37
|
"url": "https://github.com/B3Pay/ic-reactor/issues"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@ic-reactor/codegen": "0.
|
|
40
|
+
"@ic-reactor/codegen": "0.6.0"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
|
-
"vite": "^5.0.0 || ^6.0.0 || ^7.0.0"
|
|
43
|
+
"vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@icp-sdk/bindgen": "^0.2.1",
|
|
47
47
|
"@types/node": "^25.2.3",
|
|
48
48
|
"tsup": "^8.5.1",
|
|
49
49
|
"typescript": "^5.9.3",
|
|
50
|
-
"vite": "^7.3.1",
|
|
51
50
|
"vitest": "^4.0.18"
|
|
52
51
|
},
|
|
53
52
|
"scripts": {
|
package/src/index.test.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { describe, it, expect, vi, beforeEach } from "vitest"
|
|
2
|
-
import {
|
|
3
|
-
import fs from "fs"
|
|
2
|
+
import { icReactor, type IcReactorPluginOptions } from "./index"
|
|
4
3
|
import path from "path"
|
|
5
4
|
import { execFileSync } from "child_process"
|
|
6
5
|
import { runCanisterPipeline } from "@ic-reactor/codegen"
|
|
@@ -25,7 +24,7 @@ vi.mock("fs", () => ({
|
|
|
25
24
|
},
|
|
26
25
|
}))
|
|
27
26
|
|
|
28
|
-
describe("
|
|
27
|
+
describe("icReactor", () => {
|
|
29
28
|
const mockOptions: IcReactorPluginOptions = {
|
|
30
29
|
canisters: [
|
|
31
30
|
{
|
|
@@ -61,7 +60,7 @@ describe("icReactorPlugin", () => {
|
|
|
61
60
|
})
|
|
62
61
|
|
|
63
62
|
it("should return correct plugin structure", () => {
|
|
64
|
-
const plugin =
|
|
63
|
+
const plugin = icReactor(mockOptions)
|
|
65
64
|
expect(plugin.name).toBe("ic-reactor-plugin")
|
|
66
65
|
expect(plugin.buildStart).toBeDefined()
|
|
67
66
|
expect(plugin.handleHotUpdate).toBeDefined()
|
|
@@ -90,7 +89,7 @@ describe("icReactorPlugin", () => {
|
|
|
90
89
|
}
|
|
91
90
|
)
|
|
92
91
|
|
|
93
|
-
const plugin =
|
|
92
|
+
const plugin = icReactor(mockOptions)
|
|
94
93
|
const config = (plugin as any).config({}, { command: "serve" })
|
|
95
94
|
|
|
96
95
|
expect(config.server.headers["Set-Cookie"]).toContain("ic_env=")
|
|
@@ -108,7 +107,7 @@ describe("icReactorPlugin", () => {
|
|
|
108
107
|
throw new Error("Command not found")
|
|
109
108
|
})
|
|
110
109
|
|
|
111
|
-
const plugin =
|
|
110
|
+
const plugin = icReactor(mockOptions)
|
|
112
111
|
const config = (plugin as any).config({}, { command: "serve" })
|
|
113
112
|
|
|
114
113
|
expect(config.server.headers).toBeUndefined()
|
|
@@ -116,7 +115,7 @@ describe("icReactorPlugin", () => {
|
|
|
116
115
|
})
|
|
117
116
|
|
|
118
117
|
it("should return empty config for build command", () => {
|
|
119
|
-
const plugin =
|
|
118
|
+
const plugin = icReactor(mockOptions)
|
|
120
119
|
const config = (plugin as any).config({}, { command: "build" })
|
|
121
120
|
|
|
122
121
|
expect(config).toEqual({})
|
|
@@ -125,7 +124,7 @@ describe("icReactorPlugin", () => {
|
|
|
125
124
|
|
|
126
125
|
describe("buildStart", () => {
|
|
127
126
|
it("should generate declarations and reactor file", async () => {
|
|
128
|
-
const plugin =
|
|
127
|
+
const plugin = icReactor(mockOptions)
|
|
129
128
|
await (plugin.buildStart as any)()
|
|
130
129
|
|
|
131
130
|
expect(runCanisterPipeline).toHaveBeenCalledWith({
|
|
@@ -148,7 +147,7 @@ describe("icReactorPlugin", () => {
|
|
|
148
147
|
error: "Failed to generate",
|
|
149
148
|
})
|
|
150
149
|
|
|
151
|
-
const plugin =
|
|
150
|
+
const plugin = icReactor(mockOptions)
|
|
152
151
|
await (plugin.buildStart as any)()
|
|
153
152
|
|
|
154
153
|
expect(consoleErrorSpy).toHaveBeenCalledWith(
|
|
@@ -157,11 +156,40 @@ describe("icReactorPlugin", () => {
|
|
|
157
156
|
|
|
158
157
|
consoleErrorSpy.mockRestore()
|
|
159
158
|
})
|
|
159
|
+
|
|
160
|
+
it("should pass reactor mode config to codegen", async () => {
|
|
161
|
+
const plugin = icReactor({
|
|
162
|
+
...mockOptions,
|
|
163
|
+
reactor: {
|
|
164
|
+
defaultMode: "display",
|
|
165
|
+
canisters: {
|
|
166
|
+
test_canister: "raw",
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
})
|
|
170
|
+
|
|
171
|
+
await (plugin.buildStart as any)()
|
|
172
|
+
|
|
173
|
+
expect(runCanisterPipeline).toHaveBeenCalledWith({
|
|
174
|
+
canisterConfig: mockOptions.canisters[0],
|
|
175
|
+
projectRoot: expect.any(String),
|
|
176
|
+
globalConfig: {
|
|
177
|
+
outDir: "src/declarations",
|
|
178
|
+
clientManagerPath: "../../clients",
|
|
179
|
+
reactor: {
|
|
180
|
+
defaultMode: "display",
|
|
181
|
+
canisters: {
|
|
182
|
+
test_canister: "raw",
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
})
|
|
187
|
+
})
|
|
160
188
|
})
|
|
161
189
|
|
|
162
190
|
describe("handleHotUpdate", () => {
|
|
163
191
|
it("should restart server when .did file changes", async () => {
|
|
164
|
-
const plugin =
|
|
192
|
+
const plugin = icReactor(mockOptions)
|
|
165
193
|
const ctx = {
|
|
166
194
|
file: "/absolute/path/to/src/declarations/test.did",
|
|
167
195
|
server: mockServer,
|
|
@@ -182,7 +210,7 @@ describe("icReactorPlugin", () => {
|
|
|
182
210
|
})
|
|
183
211
|
|
|
184
212
|
it("should ignore other files", () => {
|
|
185
|
-
const plugin =
|
|
213
|
+
const plugin = icReactor(mockOptions)
|
|
186
214
|
const ctx = {
|
|
187
215
|
file: "/some/other/file.ts",
|
|
188
216
|
server: mockServer,
|
package/src/index.ts
CHANGED
|
@@ -7,13 +7,13 @@
|
|
|
7
7
|
* 3. Hot-reloads when .did files change
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import type { Plugin
|
|
11
|
-
import fs from "node:fs"
|
|
10
|
+
import type { Plugin } from "vite"
|
|
12
11
|
import path from "node:path"
|
|
13
12
|
import {
|
|
14
13
|
runCanisterPipeline,
|
|
15
14
|
type CanisterConfig,
|
|
16
15
|
type CodegenConfig,
|
|
16
|
+
type ReactorGenerationConfig,
|
|
17
17
|
} from "@ic-reactor/codegen"
|
|
18
18
|
import { getIcEnvironmentInfo, buildIcEnvCookie } from "./env.js"
|
|
19
19
|
|
|
@@ -38,23 +38,35 @@ export interface IcReactorPluginOptions {
|
|
|
38
38
|
* Default: true
|
|
39
39
|
*/
|
|
40
40
|
injectEnvironment?: boolean
|
|
41
|
+
/**
|
|
42
|
+
* Reactor generation behavior.
|
|
43
|
+
* Controls whether generated default hooks use raw (Reactor) or display (DisplayReactor).
|
|
44
|
+
*/
|
|
45
|
+
reactor?: ReactorGenerationConfig
|
|
41
46
|
}
|
|
42
47
|
|
|
43
|
-
export function
|
|
48
|
+
export function icReactor(options: IcReactorPluginOptions): any {
|
|
44
49
|
const {
|
|
45
50
|
canisters,
|
|
46
51
|
outDir = "src/declarations",
|
|
47
52
|
clientManagerPath = "../../clients",
|
|
48
53
|
injectEnvironment = true,
|
|
54
|
+
reactor,
|
|
49
55
|
} = options
|
|
50
56
|
|
|
51
57
|
// Construct a partial CodegenConfig to pass to the pipeline
|
|
52
|
-
const globalConfig: Pick<
|
|
58
|
+
const globalConfig: Pick<
|
|
59
|
+
CodegenConfig,
|
|
60
|
+
"outDir" | "clientManagerPath" | "reactor"
|
|
61
|
+
> = {
|
|
53
62
|
outDir,
|
|
54
63
|
clientManagerPath,
|
|
55
64
|
}
|
|
65
|
+
if (reactor != null) {
|
|
66
|
+
globalConfig.reactor = reactor
|
|
67
|
+
}
|
|
56
68
|
|
|
57
|
-
|
|
69
|
+
const plugin: Plugin = {
|
|
58
70
|
name: "ic-reactor-plugin",
|
|
59
71
|
enforce: "pre", // Run before other plugins
|
|
60
72
|
|
|
@@ -176,4 +188,6 @@ export function icReactorPlugin(options: IcReactorPluginOptions): Plugin {
|
|
|
176
188
|
}
|
|
177
189
|
},
|
|
178
190
|
}
|
|
191
|
+
|
|
192
|
+
return plugin
|
|
179
193
|
}
|