@ic-reactor/vite-plugin 0.4.1 → 0.5.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 +32 -114
- package/dist/index.cjs +65 -87
- package/dist/index.d.cts +18 -36
- package/dist/index.d.ts +18 -36
- package/dist/index.js +65 -89
- package/package.json +2 -2
- package/src/env.ts +80 -0
- package/src/index.test.ts +21 -98
- package/src/index.ts +93 -184
package/dist/index.js
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
|
-
import fs from "fs";
|
|
3
2
|
import path from "path";
|
|
4
|
-
import { execFileSync } from "child_process";
|
|
5
3
|
import {
|
|
6
|
-
|
|
7
|
-
generateReactorFile,
|
|
8
|
-
generateClientFile
|
|
4
|
+
runCanisterPipeline
|
|
9
5
|
} from "@ic-reactor/codegen";
|
|
6
|
+
|
|
7
|
+
// src/env.ts
|
|
8
|
+
import { execFileSync } from "child_process";
|
|
10
9
|
function getIcEnvironmentInfo(canisterNames) {
|
|
11
10
|
const environment = process.env.ICP_ENVIRONMENT || "local";
|
|
12
11
|
try {
|
|
13
12
|
const networkStatus = JSON.parse(
|
|
14
13
|
execFileSync("icp", ["network", "status", "-e", environment, "--json"], {
|
|
15
|
-
encoding: "utf-8"
|
|
14
|
+
encoding: "utf-8",
|
|
15
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
16
|
+
// suppress stderr
|
|
16
17
|
})
|
|
17
18
|
);
|
|
18
19
|
const rootKey = networkStatus.root_key;
|
|
@@ -23,35 +24,48 @@ function getIcEnvironmentInfo(canisterNames) {
|
|
|
23
24
|
const canisterId = execFileSync(
|
|
24
25
|
"icp",
|
|
25
26
|
["canister", "status", name, "-e", environment, "-i"],
|
|
26
|
-
{
|
|
27
|
-
encoding: "utf-8"
|
|
28
|
-
}
|
|
27
|
+
{ encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"] }
|
|
29
28
|
).trim();
|
|
30
|
-
|
|
29
|
+
if (canisterId) {
|
|
30
|
+
canisterIds[name] = canisterId;
|
|
31
|
+
}
|
|
31
32
|
} catch {
|
|
32
33
|
}
|
|
33
34
|
}
|
|
34
35
|
return { environment, rootKey, proxyTarget, canisterIds };
|
|
35
|
-
} catch {
|
|
36
|
+
} catch (error) {
|
|
36
37
|
return null;
|
|
37
38
|
}
|
|
38
39
|
}
|
|
39
40
|
function buildIcEnvCookie(canisterIds, rootKey) {
|
|
40
|
-
const
|
|
41
|
+
const parts = [`ic_root_key=${rootKey}`];
|
|
41
42
|
for (const [name, id] of Object.entries(canisterIds)) {
|
|
42
|
-
|
|
43
|
+
parts.push(`PUBLIC_CANISTER_ID:${name}=${id}`);
|
|
43
44
|
}
|
|
44
|
-
return encodeURIComponent(
|
|
45
|
+
return encodeURIComponent(parts.join("&"));
|
|
45
46
|
}
|
|
47
|
+
|
|
48
|
+
// src/index.ts
|
|
46
49
|
function icReactorPlugin(options) {
|
|
47
|
-
const
|
|
50
|
+
const {
|
|
51
|
+
canisters,
|
|
52
|
+
outDir = "src/declarations",
|
|
53
|
+
clientManagerPath = "../../clients",
|
|
54
|
+
injectEnvironment = true
|
|
55
|
+
} = options;
|
|
56
|
+
const globalConfig = {
|
|
57
|
+
outDir,
|
|
58
|
+
clientManagerPath
|
|
59
|
+
};
|
|
48
60
|
return {
|
|
49
61
|
name: "ic-reactor-plugin",
|
|
50
|
-
|
|
51
|
-
|
|
62
|
+
enforce: "pre",
|
|
63
|
+
// Run before other plugins
|
|
64
|
+
config(config, { command }) {
|
|
65
|
+
if (command !== "serve" || !injectEnvironment) {
|
|
52
66
|
return {};
|
|
53
67
|
}
|
|
54
|
-
const canisterNames =
|
|
68
|
+
const canisterNames = canisters.map((c) => c.name).filter((n) => !!n);
|
|
55
69
|
if (!canisterNames.includes("internet_identity")) {
|
|
56
70
|
canisterNames.push("internet_identity");
|
|
57
71
|
}
|
|
@@ -84,91 +98,53 @@ function icReactorPlugin(options) {
|
|
|
84
98
|
};
|
|
85
99
|
},
|
|
86
100
|
async buildStart() {
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
101
|
+
const projectRoot = process.cwd();
|
|
102
|
+
console.log(
|
|
103
|
+
`[ic-reactor] Generating hooks for ${canisters.length} canisters...`
|
|
90
104
|
);
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
for (const canister of options.canisters) {
|
|
100
|
-
let didFile = canister.didFile;
|
|
101
|
-
const outDir = canister.outDir ?? path.join(baseOutDir, canister.name);
|
|
102
|
-
if (!didFile) {
|
|
103
|
-
const environment = process.env.ICP_ENVIRONMENT || "local";
|
|
104
|
-
console.log(
|
|
105
|
-
`[ic-reactor] didFile not specified for "${canister.name}". Attempting to download from canister...`
|
|
106
|
-
);
|
|
107
|
-
try {
|
|
108
|
-
const candidContent = execFileSync(
|
|
109
|
-
"icp",
|
|
110
|
-
[
|
|
111
|
-
"canister",
|
|
112
|
-
"metadata",
|
|
113
|
-
canister.name,
|
|
114
|
-
"candid:service",
|
|
115
|
-
"-e",
|
|
116
|
-
environment
|
|
117
|
-
],
|
|
118
|
-
{ encoding: "utf-8" }
|
|
119
|
-
).trim();
|
|
120
|
-
const declarationsDir = path.join(outDir, "declarations");
|
|
121
|
-
if (!fs.existsSync(declarationsDir)) {
|
|
122
|
-
fs.mkdirSync(declarationsDir, { recursive: true });
|
|
123
|
-
}
|
|
124
|
-
didFile = path.join(declarationsDir, `${canister.name}.did`);
|
|
125
|
-
fs.writeFileSync(didFile, candidContent);
|
|
126
|
-
console.log(
|
|
127
|
-
`[ic-reactor] Candid downloaded and saved to ${didFile}`
|
|
128
|
-
);
|
|
129
|
-
} catch (error) {
|
|
105
|
+
for (const canisterConfig of canisters) {
|
|
106
|
+
try {
|
|
107
|
+
const result = await runCanisterPipeline({
|
|
108
|
+
canisterConfig,
|
|
109
|
+
projectRoot,
|
|
110
|
+
globalConfig
|
|
111
|
+
});
|
|
112
|
+
if (!result.success) {
|
|
130
113
|
console.error(
|
|
131
|
-
`[ic-reactor] Failed to
|
|
114
|
+
`[ic-reactor] Failed to generate ${canisterConfig.name}: ${result.error}`
|
|
132
115
|
);
|
|
133
|
-
|
|
116
|
+
} else {
|
|
134
117
|
}
|
|
135
|
-
}
|
|
136
|
-
console.log(
|
|
137
|
-
`[ic-reactor] Generating hooks for ${canister.name} from ${didFile}`
|
|
138
|
-
);
|
|
139
|
-
const result = await generateDeclarations({
|
|
140
|
-
didFile,
|
|
141
|
-
outDir,
|
|
142
|
-
canisterName: canister.name
|
|
143
|
-
});
|
|
144
|
-
if (!result.success) {
|
|
118
|
+
} catch (err) {
|
|
145
119
|
console.error(
|
|
146
|
-
`[ic-reactor]
|
|
120
|
+
`[ic-reactor] Error generating ${canisterConfig.name}:`,
|
|
121
|
+
err
|
|
147
122
|
);
|
|
148
|
-
continue;
|
|
149
123
|
}
|
|
150
|
-
const reactorContent = generateReactorFile({
|
|
151
|
-
canisterName: canister.name,
|
|
152
|
-
didFile,
|
|
153
|
-
clientManagerPath: canister.clientManagerPath ?? options.clientManagerPath
|
|
154
|
-
});
|
|
155
|
-
const reactorPath = path.join(outDir, "index.ts");
|
|
156
|
-
fs.mkdirSync(outDir, { recursive: true });
|
|
157
|
-
fs.writeFileSync(reactorPath, reactorContent);
|
|
158
|
-
console.log(`[ic-reactor] Reactor hooks generated at ${reactorPath}`);
|
|
159
124
|
}
|
|
160
125
|
},
|
|
161
126
|
handleHotUpdate({ file, server }) {
|
|
162
127
|
if (file.endsWith(".did")) {
|
|
163
|
-
const
|
|
164
|
-
|
|
165
|
-
return
|
|
128
|
+
const affectedCanister = canisters.find((c) => {
|
|
129
|
+
const configPath = path.resolve(process.cwd(), c.didFile);
|
|
130
|
+
return configPath === file;
|
|
166
131
|
});
|
|
167
|
-
if (
|
|
132
|
+
if (affectedCanister) {
|
|
168
133
|
console.log(
|
|
169
|
-
`[ic-reactor]
|
|
134
|
+
`[ic-reactor] .did file changed: ${affectedCanister.name}. Regenerating...`
|
|
170
135
|
);
|
|
171
|
-
|
|
136
|
+
const projectRoot = process.cwd();
|
|
137
|
+
runCanisterPipeline({
|
|
138
|
+
canisterConfig: affectedCanister,
|
|
139
|
+
projectRoot,
|
|
140
|
+
globalConfig
|
|
141
|
+
}).then((result) => {
|
|
142
|
+
if (result.success) {
|
|
143
|
+
server.ws.send({ type: "full-reload" });
|
|
144
|
+
} else {
|
|
145
|
+
console.error(`[ic-reactor] Regeneration failed: ${result.error}`);
|
|
146
|
+
}
|
|
147
|
+
});
|
|
172
148
|
}
|
|
173
149
|
}
|
|
174
150
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ic-reactor/vite-plugin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.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,7 +37,7 @@
|
|
|
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.5.0"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
43
|
"vite": "^5.0.0 || ^6.0.0 || ^7.0.0"
|
package/src/env.ts
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Environment Injection Utilities
|
|
3
|
+
*
|
|
4
|
+
* Handles detecting the local IC environment (via `dfx` or `icp` CLI)
|
|
5
|
+
* and building the `ic_env` cookie for the browser.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { execFileSync } from "child_process"
|
|
9
|
+
|
|
10
|
+
export interface IcEnvironment {
|
|
11
|
+
environment: string
|
|
12
|
+
rootKey: string
|
|
13
|
+
proxyTarget: string
|
|
14
|
+
canisterIds: Record<string, string>
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Detect the IC environment using the `icp` or `dfx` CLI.
|
|
19
|
+
*/
|
|
20
|
+
export function getIcEnvironmentInfo(
|
|
21
|
+
canisterNames: string[]
|
|
22
|
+
): IcEnvironment | null {
|
|
23
|
+
const environment = process.env.ICP_ENVIRONMENT || "local"
|
|
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
|
+
try {
|
|
29
|
+
const networkStatus = JSON.parse(
|
|
30
|
+
execFileSync("icp", ["network", "status", "-e", environment, "--json"], {
|
|
31
|
+
encoding: "utf-8",
|
|
32
|
+
stdio: ["ignore", "pipe", "ignore"], // suppress stderr
|
|
33
|
+
})
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
const rootKey = networkStatus.root_key
|
|
37
|
+
// Default to localhost:4943 if port strictly needed, but `icp` gives us the port
|
|
38
|
+
const proxyTarget = `http://127.0.0.1:${networkStatus.port}`
|
|
39
|
+
|
|
40
|
+
const canisterIds: Record<string, string> = {}
|
|
41
|
+
|
|
42
|
+
for (const name of canisterNames) {
|
|
43
|
+
try {
|
|
44
|
+
const canisterId = execFileSync(
|
|
45
|
+
"icp",
|
|
46
|
+
["canister", "status", name, "-e", environment, "-i"],
|
|
47
|
+
{ encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"] }
|
|
48
|
+
).trim()
|
|
49
|
+
|
|
50
|
+
if (canisterId) {
|
|
51
|
+
canisterIds[name] = canisterId
|
|
52
|
+
}
|
|
53
|
+
} catch {
|
|
54
|
+
// Canister might not exist or be deployed yet
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return { environment, rootKey, proxyTarget, canisterIds }
|
|
59
|
+
} catch (error) {
|
|
60
|
+
// CLI not found or failed
|
|
61
|
+
return null
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Build the `ic_env` cookie string.
|
|
67
|
+
* Format: `ic_root_key=<key>&PUBLIC_CANISTER_ID:<name>=<id>&...`
|
|
68
|
+
*/
|
|
69
|
+
export function buildIcEnvCookie(
|
|
70
|
+
canisterIds: Record<string, string>,
|
|
71
|
+
rootKey: string
|
|
72
|
+
): string {
|
|
73
|
+
const parts = [`ic_root_key=${rootKey}`]
|
|
74
|
+
|
|
75
|
+
for (const [name, id] of Object.entries(canisterIds)) {
|
|
76
|
+
parts.push(`PUBLIC_CANISTER_ID:${name}=${id}`)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return encodeURIComponent(parts.join("&"))
|
|
80
|
+
}
|
package/src/index.test.ts
CHANGED
|
@@ -3,17 +3,11 @@ import { icReactorPlugin, type IcReactorPluginOptions } from "./index"
|
|
|
3
3
|
import fs from "fs"
|
|
4
4
|
import path from "path"
|
|
5
5
|
import { execFileSync } from "child_process"
|
|
6
|
-
import {
|
|
7
|
-
generateDeclarations,
|
|
8
|
-
generateReactorFile,
|
|
9
|
-
generateClientFile,
|
|
10
|
-
} from "@ic-reactor/codegen"
|
|
6
|
+
import { runCanisterPipeline } from "@ic-reactor/codegen"
|
|
11
7
|
|
|
12
8
|
// Mock internal dependencies
|
|
13
9
|
vi.mock("@ic-reactor/codegen", () => ({
|
|
14
|
-
|
|
15
|
-
generateReactorFile: vi.fn(),
|
|
16
|
-
generateClientFile: vi.fn(),
|
|
10
|
+
runCanisterPipeline: vi.fn(),
|
|
17
11
|
}))
|
|
18
12
|
|
|
19
13
|
// Mock child_process
|
|
@@ -54,16 +48,16 @@ describe("icReactorPlugin", () => {
|
|
|
54
48
|
use: vi.fn(),
|
|
55
49
|
},
|
|
56
50
|
restart: vi.fn(),
|
|
51
|
+
ws: {
|
|
52
|
+
send: vi.fn(),
|
|
53
|
+
},
|
|
57
54
|
}
|
|
58
55
|
|
|
59
56
|
beforeEach(() => {
|
|
60
57
|
vi.resetAllMocks()
|
|
61
|
-
;(
|
|
58
|
+
;(runCanisterPipeline as any).mockResolvedValue({
|
|
62
59
|
success: true,
|
|
63
|
-
declarationsDir: "/mock/declarations",
|
|
64
60
|
})
|
|
65
|
-
;(generateReactorFile as any).mockReturnValue("export const reactor = {}")
|
|
66
|
-
;(generateClientFile as any).mockReturnValue("export const client = {}")
|
|
67
61
|
})
|
|
68
62
|
|
|
69
63
|
it("should return correct plugin structure", () => {
|
|
@@ -72,8 +66,6 @@ describe("icReactorPlugin", () => {
|
|
|
72
66
|
expect(plugin.buildStart).toBeDefined()
|
|
73
67
|
expect(plugin.handleHotUpdate).toBeDefined()
|
|
74
68
|
expect((plugin as any).config).toBeDefined()
|
|
75
|
-
// configureServer is no longer used for middleware
|
|
76
|
-
expect(plugin.configureServer).toBeUndefined()
|
|
77
69
|
})
|
|
78
70
|
|
|
79
71
|
describe("config", () => {
|
|
@@ -136,82 +128,13 @@ describe("icReactorPlugin", () => {
|
|
|
136
128
|
const plugin = icReactorPlugin(mockOptions)
|
|
137
129
|
await (plugin.buildStart as any)()
|
|
138
130
|
|
|
139
|
-
expect(
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
canisterName: "test_canister",
|
|
147
|
-
didFile: "src/declarations/test.did",
|
|
148
|
-
clientManagerPath: undefined,
|
|
149
|
-
})
|
|
150
|
-
|
|
151
|
-
expect(fs.writeFileSync).toHaveBeenCalledWith(
|
|
152
|
-
path.join("src/declarations/test_canister", "index.ts"),
|
|
153
|
-
"export const reactor = {}"
|
|
154
|
-
)
|
|
155
|
-
})
|
|
156
|
-
|
|
157
|
-
it("should download candid if not specified", async () => {
|
|
158
|
-
const optionsWithMissingDid: IcReactorPluginOptions = {
|
|
159
|
-
canisters: [
|
|
160
|
-
{
|
|
161
|
-
name: "missing_did",
|
|
162
|
-
outDir: "src/declarations/missing_did",
|
|
163
|
-
},
|
|
164
|
-
],
|
|
165
|
-
outDir: "src/declarations",
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
;(execFileSync as any).mockImplementation(
|
|
169
|
-
(command: string, args: string[]) => {
|
|
170
|
-
if (command === "icp" && args.includes("metadata")) {
|
|
171
|
-
return "service : { greet: (text) -> (text) query }"
|
|
172
|
-
}
|
|
173
|
-
return ""
|
|
174
|
-
}
|
|
175
|
-
)
|
|
176
|
-
|
|
177
|
-
const plugin = icReactorPlugin(optionsWithMissingDid)
|
|
178
|
-
await (plugin.buildStart as any)()
|
|
179
|
-
|
|
180
|
-
expect(execFileSync).toHaveBeenCalledWith(
|
|
181
|
-
"icp",
|
|
182
|
-
expect.arrayContaining([
|
|
183
|
-
"canister",
|
|
184
|
-
"metadata",
|
|
185
|
-
"missing_did",
|
|
186
|
-
"candid:service",
|
|
187
|
-
]),
|
|
188
|
-
expect.any(Object)
|
|
189
|
-
)
|
|
190
|
-
|
|
191
|
-
expect(fs.writeFileSync).toHaveBeenCalledWith(
|
|
192
|
-
path.join(
|
|
193
|
-
"src/declarations/missing_did/declarations",
|
|
194
|
-
"missing_did.did"
|
|
195
|
-
),
|
|
196
|
-
"service : { greet: (text) -> (text) query }"
|
|
197
|
-
)
|
|
198
|
-
|
|
199
|
-
expect(generateDeclarations).toHaveBeenCalledWith({
|
|
200
|
-
didFile: path.join(
|
|
201
|
-
"src/declarations/missing_did/declarations",
|
|
202
|
-
"missing_did.did"
|
|
203
|
-
),
|
|
204
|
-
outDir: "src/declarations/missing_did",
|
|
205
|
-
canisterName: "missing_did",
|
|
206
|
-
})
|
|
207
|
-
|
|
208
|
-
expect(generateReactorFile).toHaveBeenCalledWith({
|
|
209
|
-
canisterName: "missing_did",
|
|
210
|
-
didFile: path.join(
|
|
211
|
-
"src/declarations/missing_did/declarations",
|
|
212
|
-
"missing_did.did"
|
|
213
|
-
),
|
|
214
|
-
clientManagerPath: undefined,
|
|
131
|
+
expect(runCanisterPipeline).toHaveBeenCalledWith({
|
|
132
|
+
canisterConfig: mockOptions.canisters[0],
|
|
133
|
+
projectRoot: expect.any(String),
|
|
134
|
+
globalConfig: {
|
|
135
|
+
outDir: "src/declarations",
|
|
136
|
+
clientManagerPath: "../../clients",
|
|
137
|
+
},
|
|
215
138
|
})
|
|
216
139
|
})
|
|
217
140
|
|
|
@@ -220,7 +143,7 @@ describe("icReactorPlugin", () => {
|
|
|
220
143
|
.spyOn(console, "error")
|
|
221
144
|
.mockImplementation(() => {})
|
|
222
145
|
|
|
223
|
-
;(
|
|
146
|
+
;(runCanisterPipeline as any).mockResolvedValue({
|
|
224
147
|
success: false,
|
|
225
148
|
error: "Failed to generate",
|
|
226
149
|
})
|
|
@@ -229,16 +152,15 @@ describe("icReactorPlugin", () => {
|
|
|
229
152
|
await (plugin.buildStart as any)()
|
|
230
153
|
|
|
231
154
|
expect(consoleErrorSpy).toHaveBeenCalledWith(
|
|
232
|
-
expect.stringContaining("Failed to generate
|
|
155
|
+
expect.stringContaining("Failed to generate test_canister")
|
|
233
156
|
)
|
|
234
|
-
expect(generateReactorFile).not.toHaveBeenCalled()
|
|
235
157
|
|
|
236
158
|
consoleErrorSpy.mockRestore()
|
|
237
159
|
})
|
|
238
160
|
})
|
|
239
161
|
|
|
240
162
|
describe("handleHotUpdate", () => {
|
|
241
|
-
it("should restart server when .did file changes", () => {
|
|
163
|
+
it("should restart server when .did file changes", async () => {
|
|
242
164
|
const plugin = icReactorPlugin(mockOptions)
|
|
243
165
|
const ctx = {
|
|
244
166
|
file: "/absolute/path/to/src/declarations/test.did",
|
|
@@ -248,14 +170,15 @@ describe("icReactorPlugin", () => {
|
|
|
248
170
|
// Mock path.resolve to match the test case
|
|
249
171
|
const originalResolve = path.resolve
|
|
250
172
|
vi.spyOn(path, "resolve").mockImplementation((...args) => {
|
|
251
|
-
if (args.some((a) => a.includes("test.did"))) {
|
|
173
|
+
if (args.some((a) => a && a.includes("test.did"))) {
|
|
252
174
|
return "/absolute/path/to/src/declarations/test.did"
|
|
253
175
|
}
|
|
254
176
|
return originalResolve(...args)
|
|
255
177
|
})
|
|
256
|
-
;(plugin.handleHotUpdate as any)(ctx)
|
|
257
178
|
|
|
258
|
-
|
|
179
|
+
await (plugin.handleHotUpdate as any)(ctx)
|
|
180
|
+
|
|
181
|
+
expect(mockServer.ws.send).toHaveBeenCalledWith({ type: "full-reload" })
|
|
259
182
|
})
|
|
260
183
|
|
|
261
184
|
it("should ignore other files", () => {
|
|
@@ -267,7 +190,7 @@ describe("icReactorPlugin", () => {
|
|
|
267
190
|
|
|
268
191
|
;(plugin.handleHotUpdate as any)(ctx)
|
|
269
192
|
|
|
270
|
-
expect(mockServer.
|
|
193
|
+
expect(mockServer.ws.send).not.toHaveBeenCalled()
|
|
271
194
|
})
|
|
272
195
|
})
|
|
273
196
|
})
|