@ic-reactor/vite-plugin 0.7.0 → 0.7.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 +9 -27
- package/dist/index.cjs +13 -7
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +12 -6
- package/package.json +2 -2
- package/src/index.test.ts +21 -35
- package/src/index.ts +14 -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 { icReactorPlugin } from "@ic-reactor/vite-plugin"
|
|
42
42
|
|
|
43
43
|
export default defineConfig({
|
|
44
44
|
plugins: [
|
|
45
45
|
react(),
|
|
46
|
-
|
|
46
|
+
icReactorPlugin({
|
|
47
47
|
canisters: [
|
|
48
48
|
{
|
|
49
49
|
name: "backend",
|
|
@@ -87,23 +87,6 @@ function MyComponent() {
|
|
|
87
87
|
}
|
|
88
88
|
```
|
|
89
89
|
|
|
90
|
-
### Reactor Mode (per canister)
|
|
91
|
-
|
|
92
|
-
By default, generated hooks use `DisplayReactor` (backward compatible). Set `mode` on a canister to choose the generated reactor class (`Reactor`, `DisplayReactor`, `CandidReactor`, `CandidDisplayReactor`, or `MetadataDisplayReactor`).
|
|
93
|
-
|
|
94
|
-
```ts
|
|
95
|
-
icReactor({
|
|
96
|
-
canisters: [
|
|
97
|
-
{ name: "backend", didFile: "./backend/backend.did" },
|
|
98
|
-
{
|
|
99
|
-
name: "workflow_engine",
|
|
100
|
-
mode: "Reactor",
|
|
101
|
-
didFile: "./workflow/workflow_engine.did",
|
|
102
|
-
},
|
|
103
|
-
],
|
|
104
|
-
})
|
|
105
|
-
```
|
|
106
|
-
|
|
107
90
|
## Configuration
|
|
108
91
|
|
|
109
92
|
### Plugin Options
|
|
@@ -117,14 +100,13 @@ icReactor({
|
|
|
117
100
|
|
|
118
101
|
### Canister Config
|
|
119
102
|
|
|
120
|
-
| Option | Type
|
|
121
|
-
| :------------------ |
|
|
122
|
-
| `name` | `string`
|
|
123
|
-
| `didFile` | `string`
|
|
124
|
-
| `outDir` | `string`
|
|
125
|
-
| `clientManagerPath` | `string`
|
|
126
|
-
| `
|
|
127
|
-
| `canisterId` | `string` | Optional fixed canister ID. | No |
|
|
103
|
+
| Option | Type | Description | Required |
|
|
104
|
+
| :------------------ | :------- | :---------------------------------------------- | :------- |
|
|
105
|
+
| `name` | `string` | Name of the canister (used for variable names). | Yes |
|
|
106
|
+
| `didFile` | `string` | Path to the `.did` file. | Yes |
|
|
107
|
+
| `outDir` | `string` | Override output directory for this canister. | No |
|
|
108
|
+
| `clientManagerPath` | `string` | Override client manager path. | No |
|
|
109
|
+
| `canisterId` | `string` | Optional fixed canister ID. | No |
|
|
128
110
|
|
|
129
111
|
## Local Development (Environment Injection)
|
|
130
112
|
|
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
|
+
icReactorPlugin: () => icReactorPlugin
|
|
34
34
|
});
|
|
35
35
|
module.exports = __toCommonJS(index_exports);
|
|
36
36
|
var import_node_path = __toESM(require("path"), 1);
|
|
@@ -78,7 +78,7 @@ function buildIcEnvCookie(canisterIds, rootKey) {
|
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
// src/index.ts
|
|
81
|
-
function
|
|
81
|
+
function icReactorPlugin(options) {
|
|
82
82
|
const {
|
|
83
83
|
canisters,
|
|
84
84
|
outDir = "src/declarations",
|
|
@@ -89,6 +89,10 @@ function icReactor(options) {
|
|
|
89
89
|
outDir,
|
|
90
90
|
clientManagerPath
|
|
91
91
|
};
|
|
92
|
+
const projectRoot = process.cwd();
|
|
93
|
+
const resolveDidPath = (didFile) => import_node_path.default.normalize(
|
|
94
|
+
import_node_path.default.isAbsolute(didFile) ? didFile : import_node_path.default.resolve(projectRoot, didFile)
|
|
95
|
+
);
|
|
92
96
|
const plugin = {
|
|
93
97
|
name: "ic-reactor-plugin",
|
|
94
98
|
enforce: "pre",
|
|
@@ -129,8 +133,11 @@ function icReactor(options) {
|
|
|
129
133
|
}
|
|
130
134
|
};
|
|
131
135
|
},
|
|
136
|
+
configureServer(server) {
|
|
137
|
+
const didFiles = canisters.map((c) => resolveDidPath(c.didFile));
|
|
138
|
+
server.watcher.add(didFiles);
|
|
139
|
+
},
|
|
132
140
|
async buildStart() {
|
|
133
|
-
const projectRoot = process.cwd();
|
|
134
141
|
console.log(
|
|
135
142
|
`[ic-reactor] Generating hooks for ${canisters.length} canisters...`
|
|
136
143
|
);
|
|
@@ -158,14 +165,13 @@ function icReactor(options) {
|
|
|
158
165
|
handleHotUpdate({ file, server }) {
|
|
159
166
|
if (file.endsWith(".did")) {
|
|
160
167
|
const affectedCanister = canisters.find((c) => {
|
|
161
|
-
const configPath =
|
|
162
|
-
return configPath === file;
|
|
168
|
+
const configPath = resolveDidPath(c.didFile);
|
|
169
|
+
return configPath === import_node_path.default.normalize(file);
|
|
163
170
|
});
|
|
164
171
|
if (affectedCanister) {
|
|
165
172
|
console.log(
|
|
166
173
|
`[ic-reactor] .did file changed: ${affectedCanister.name}. Regenerating...`
|
|
167
174
|
);
|
|
168
|
-
const projectRoot = process.cwd();
|
|
169
175
|
(0, import_codegen.runCanisterPipeline)({
|
|
170
176
|
canisterConfig: affectedCanister,
|
|
171
177
|
projectRoot,
|
|
@@ -185,5 +191,5 @@ function icReactor(options) {
|
|
|
185
191
|
}
|
|
186
192
|
// Annotate the CommonJS export names for ESM import in node:
|
|
187
193
|
0 && (module.exports = {
|
|
188
|
-
|
|
194
|
+
icReactorPlugin
|
|
189
195
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -31,6 +31,6 @@ interface IcReactorPluginOptions {
|
|
|
31
31
|
*/
|
|
32
32
|
injectEnvironment?: boolean;
|
|
33
33
|
}
|
|
34
|
-
declare function
|
|
34
|
+
declare function icReactorPlugin(options: IcReactorPluginOptions): any;
|
|
35
35
|
|
|
36
|
-
export { type IcReactorPluginOptions,
|
|
36
|
+
export { type IcReactorPluginOptions, icReactorPlugin };
|
package/dist/index.d.ts
CHANGED
|
@@ -31,6 +31,6 @@ interface IcReactorPluginOptions {
|
|
|
31
31
|
*/
|
|
32
32
|
injectEnvironment?: boolean;
|
|
33
33
|
}
|
|
34
|
-
declare function
|
|
34
|
+
declare function icReactorPlugin(options: IcReactorPluginOptions): any;
|
|
35
35
|
|
|
36
|
-
export { type IcReactorPluginOptions,
|
|
36
|
+
export { type IcReactorPluginOptions, icReactorPlugin };
|
package/dist/index.js
CHANGED
|
@@ -46,7 +46,7 @@ function buildIcEnvCookie(canisterIds, rootKey) {
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
// src/index.ts
|
|
49
|
-
function
|
|
49
|
+
function icReactorPlugin(options) {
|
|
50
50
|
const {
|
|
51
51
|
canisters,
|
|
52
52
|
outDir = "src/declarations",
|
|
@@ -57,6 +57,10 @@ function icReactor(options) {
|
|
|
57
57
|
outDir,
|
|
58
58
|
clientManagerPath
|
|
59
59
|
};
|
|
60
|
+
const projectRoot = process.cwd();
|
|
61
|
+
const resolveDidPath = (didFile) => path.normalize(
|
|
62
|
+
path.isAbsolute(didFile) ? didFile : path.resolve(projectRoot, didFile)
|
|
63
|
+
);
|
|
60
64
|
const plugin = {
|
|
61
65
|
name: "ic-reactor-plugin",
|
|
62
66
|
enforce: "pre",
|
|
@@ -97,8 +101,11 @@ function icReactor(options) {
|
|
|
97
101
|
}
|
|
98
102
|
};
|
|
99
103
|
},
|
|
104
|
+
configureServer(server) {
|
|
105
|
+
const didFiles = canisters.map((c) => resolveDidPath(c.didFile));
|
|
106
|
+
server.watcher.add(didFiles);
|
|
107
|
+
},
|
|
100
108
|
async buildStart() {
|
|
101
|
-
const projectRoot = process.cwd();
|
|
102
109
|
console.log(
|
|
103
110
|
`[ic-reactor] Generating hooks for ${canisters.length} canisters...`
|
|
104
111
|
);
|
|
@@ -126,14 +133,13 @@ function icReactor(options) {
|
|
|
126
133
|
handleHotUpdate({ file, server }) {
|
|
127
134
|
if (file.endsWith(".did")) {
|
|
128
135
|
const affectedCanister = canisters.find((c) => {
|
|
129
|
-
const configPath =
|
|
130
|
-
return configPath === file;
|
|
136
|
+
const configPath = resolveDidPath(c.didFile);
|
|
137
|
+
return configPath === path.normalize(file);
|
|
131
138
|
});
|
|
132
139
|
if (affectedCanister) {
|
|
133
140
|
console.log(
|
|
134
141
|
`[ic-reactor] .did file changed: ${affectedCanister.name}. Regenerating...`
|
|
135
142
|
);
|
|
136
|
-
const projectRoot = process.cwd();
|
|
137
143
|
runCanisterPipeline({
|
|
138
144
|
canisterConfig: affectedCanister,
|
|
139
145
|
projectRoot,
|
|
@@ -152,5 +158,5 @@ function icReactor(options) {
|
|
|
152
158
|
return plugin;
|
|
153
159
|
}
|
|
154
160
|
export {
|
|
155
|
-
|
|
161
|
+
icReactorPlugin
|
|
156
162
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ic-reactor/vite-plugin",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.1",
|
|
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,7 +37,7 @@
|
|
|
37
37
|
"url": "https://github.com/B3Pay/ic-reactor/issues"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@ic-reactor/codegen": "0.7.
|
|
40
|
+
"@ic-reactor/codegen": "0.7.1"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
43
|
"vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
|
package/src/index.test.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, it, expect, vi, beforeEach } from "vitest"
|
|
2
|
-
import {
|
|
2
|
+
import { icReactorPlugin, type IcReactorPluginOptions } from "./index"
|
|
3
3
|
import path from "path"
|
|
4
4
|
import { execFileSync } from "child_process"
|
|
5
5
|
import { runCanisterPipeline } from "@ic-reactor/codegen"
|
|
@@ -24,7 +24,7 @@ vi.mock("fs", () => ({
|
|
|
24
24
|
},
|
|
25
25
|
}))
|
|
26
26
|
|
|
27
|
-
describe("
|
|
27
|
+
describe("icReactorPlugin", () => {
|
|
28
28
|
const mockOptions: IcReactorPluginOptions = {
|
|
29
29
|
canisters: [
|
|
30
30
|
{
|
|
@@ -50,6 +50,9 @@ describe("icReactor", () => {
|
|
|
50
50
|
ws: {
|
|
51
51
|
send: vi.fn(),
|
|
52
52
|
},
|
|
53
|
+
watcher: {
|
|
54
|
+
add: vi.fn(),
|
|
55
|
+
},
|
|
53
56
|
}
|
|
54
57
|
|
|
55
58
|
beforeEach(() => {
|
|
@@ -60,7 +63,7 @@ describe("icReactor", () => {
|
|
|
60
63
|
})
|
|
61
64
|
|
|
62
65
|
it("should return correct plugin structure", () => {
|
|
63
|
-
const plugin =
|
|
66
|
+
const plugin = icReactorPlugin(mockOptions)
|
|
64
67
|
expect(plugin.name).toBe("ic-reactor-plugin")
|
|
65
68
|
expect(plugin.buildStart).toBeDefined()
|
|
66
69
|
expect(plugin.handleHotUpdate).toBeDefined()
|
|
@@ -89,7 +92,7 @@ describe("icReactor", () => {
|
|
|
89
92
|
}
|
|
90
93
|
)
|
|
91
94
|
|
|
92
|
-
const plugin =
|
|
95
|
+
const plugin = icReactorPlugin(mockOptions)
|
|
93
96
|
const config = (plugin as any).config({}, { command: "serve" })
|
|
94
97
|
|
|
95
98
|
expect(config.server.headers["Set-Cookie"]).toContain("ic_env=")
|
|
@@ -107,7 +110,7 @@ describe("icReactor", () => {
|
|
|
107
110
|
throw new Error("Command not found")
|
|
108
111
|
})
|
|
109
112
|
|
|
110
|
-
const plugin =
|
|
113
|
+
const plugin = icReactorPlugin(mockOptions)
|
|
111
114
|
const config = (plugin as any).config({}, { command: "serve" })
|
|
112
115
|
|
|
113
116
|
expect(config.server.headers).toBeUndefined()
|
|
@@ -115,7 +118,7 @@ describe("icReactor", () => {
|
|
|
115
118
|
})
|
|
116
119
|
|
|
117
120
|
it("should return empty config for build command", () => {
|
|
118
|
-
const plugin =
|
|
121
|
+
const plugin = icReactorPlugin(mockOptions)
|
|
119
122
|
const config = (plugin as any).config({}, { command: "build" })
|
|
120
123
|
|
|
121
124
|
expect(config).toEqual({})
|
|
@@ -124,7 +127,7 @@ describe("icReactor", () => {
|
|
|
124
127
|
|
|
125
128
|
describe("buildStart", () => {
|
|
126
129
|
it("should generate declarations and reactor file", async () => {
|
|
127
|
-
const plugin =
|
|
130
|
+
const plugin = icReactorPlugin(mockOptions)
|
|
128
131
|
await (plugin.buildStart as any)()
|
|
129
132
|
|
|
130
133
|
expect(runCanisterPipeline).toHaveBeenCalledWith({
|
|
@@ -147,7 +150,7 @@ describe("icReactor", () => {
|
|
|
147
150
|
error: "Failed to generate",
|
|
148
151
|
})
|
|
149
152
|
|
|
150
|
-
const plugin =
|
|
153
|
+
const plugin = icReactorPlugin(mockOptions)
|
|
151
154
|
await (plugin.buildStart as any)()
|
|
152
155
|
|
|
153
156
|
expect(consoleErrorSpy).toHaveBeenCalledWith(
|
|
@@ -156,37 +159,20 @@ describe("icReactor", () => {
|
|
|
156
159
|
|
|
157
160
|
consoleErrorSpy.mockRestore()
|
|
158
161
|
})
|
|
162
|
+
})
|
|
159
163
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
...mockOptions.canisters[0],
|
|
165
|
-
mode: "Reactor",
|
|
166
|
-
},
|
|
167
|
-
],
|
|
168
|
-
outDir: mockOptions.outDir,
|
|
169
|
-
})
|
|
170
|
-
|
|
171
|
-
await (plugin.buildStart as any)()
|
|
164
|
+
describe("handleHotUpdate", () => {
|
|
165
|
+
it("should register configured .did files with the watcher", () => {
|
|
166
|
+
const plugin = icReactorPlugin(mockOptions)
|
|
167
|
+
;(plugin.configureServer as any)(mockServer)
|
|
172
168
|
|
|
173
|
-
expect(
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
mode: "Reactor",
|
|
177
|
-
},
|
|
178
|
-
projectRoot: expect.any(String),
|
|
179
|
-
globalConfig: {
|
|
180
|
-
outDir: "src/declarations",
|
|
181
|
-
clientManagerPath: "../../clients",
|
|
182
|
-
},
|
|
183
|
-
})
|
|
169
|
+
expect(mockServer.watcher.add).toHaveBeenCalledWith([
|
|
170
|
+
expect.stringContaining("src/declarations/test.did"),
|
|
171
|
+
])
|
|
184
172
|
})
|
|
185
|
-
})
|
|
186
173
|
|
|
187
|
-
describe("handleHotUpdate", () => {
|
|
188
174
|
it("should restart server when .did file changes", async () => {
|
|
189
|
-
const plugin =
|
|
175
|
+
const plugin = icReactorPlugin(mockOptions)
|
|
190
176
|
const ctx = {
|
|
191
177
|
file: "/absolute/path/to/src/declarations/test.did",
|
|
192
178
|
server: mockServer,
|
|
@@ -207,7 +193,7 @@ describe("icReactor", () => {
|
|
|
207
193
|
})
|
|
208
194
|
|
|
209
195
|
it("should ignore other files", () => {
|
|
210
|
-
const plugin =
|
|
196
|
+
const plugin = icReactorPlugin(mockOptions)
|
|
211
197
|
const ctx = {
|
|
212
198
|
file: "/some/other/file.ts",
|
|
213
199
|
server: mockServer,
|
package/src/index.ts
CHANGED
|
@@ -39,7 +39,7 @@ export interface IcReactorPluginOptions {
|
|
|
39
39
|
injectEnvironment?: boolean
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
export function
|
|
42
|
+
export function icReactorPlugin(options: IcReactorPluginOptions): any {
|
|
43
43
|
const {
|
|
44
44
|
canisters,
|
|
45
45
|
outDir = "src/declarations",
|
|
@@ -52,6 +52,11 @@ export function icReactor(options: IcReactorPluginOptions): any {
|
|
|
52
52
|
outDir,
|
|
53
53
|
clientManagerPath,
|
|
54
54
|
}
|
|
55
|
+
const projectRoot = process.cwd()
|
|
56
|
+
const resolveDidPath = (didFile: string) =>
|
|
57
|
+
path.normalize(
|
|
58
|
+
path.isAbsolute(didFile) ? didFile : path.resolve(projectRoot, didFile)
|
|
59
|
+
)
|
|
55
60
|
|
|
56
61
|
const plugin: Plugin = {
|
|
57
62
|
name: "ic-reactor-plugin",
|
|
@@ -105,10 +110,15 @@ export function icReactor(options: IcReactorPluginOptions): any {
|
|
|
105
110
|
}
|
|
106
111
|
},
|
|
107
112
|
|
|
113
|
+
configureServer(server) {
|
|
114
|
+
// Explicitly watch configured DID files so HMR works even when they are not in the module graph.
|
|
115
|
+
const didFiles = canisters.map((c) => resolveDidPath(c.didFile))
|
|
116
|
+
server.watcher.add(didFiles)
|
|
117
|
+
},
|
|
118
|
+
|
|
108
119
|
async buildStart() {
|
|
109
120
|
// ── Code Generation ──────────────────────────────────────────────────
|
|
110
121
|
|
|
111
|
-
const projectRoot = process.cwd()
|
|
112
122
|
console.log(
|
|
113
123
|
`[ic-reactor] Generating hooks for ${canisters.length} canisters...`
|
|
114
124
|
)
|
|
@@ -148,8 +158,8 @@ export function icReactor(options: IcReactorPluginOptions): any {
|
|
|
148
158
|
const affectedCanister = canisters.find((c) => {
|
|
149
159
|
// Check if changed file matches configured didFile
|
|
150
160
|
// Cast is safe because didFile is required in CanisterConfig
|
|
151
|
-
const configPath =
|
|
152
|
-
return configPath === file
|
|
161
|
+
const configPath = resolveDidPath(c.didFile)
|
|
162
|
+
return configPath === path.normalize(file)
|
|
153
163
|
})
|
|
154
164
|
|
|
155
165
|
if (affectedCanister) {
|
|
@@ -158,7 +168,6 @@ export function icReactor(options: IcReactorPluginOptions): any {
|
|
|
158
168
|
)
|
|
159
169
|
|
|
160
170
|
// Re-run pipeline for this canister
|
|
161
|
-
const projectRoot = process.cwd()
|
|
162
171
|
runCanisterPipeline({
|
|
163
172
|
canisterConfig: affectedCanister,
|
|
164
173
|
projectRoot,
|