@vercube/devkit 0.0.47 → 1.0.0-beta.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/dist/index.d.mts +5 -4
- package/dist/index.mjs +107 -55
- package/package.json +6 -6
package/dist/index.d.mts
CHANGED
|
@@ -64,9 +64,10 @@ declare namespace DevKitTypes {
|
|
|
64
64
|
//#endregion
|
|
65
65
|
//#region src/Common/App.d.ts
|
|
66
66
|
/**
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
* @
|
|
67
|
+
* Loads dev config, builds a `Hookable` app object, and runs plugin `hooks()` in the parent process.
|
|
68
|
+
*
|
|
69
|
+
* @param cfg - Partial config merged before load (typically sets `dev: true` via spread).
|
|
70
|
+
* @returns App handle with `hooks` and resolved `config`.
|
|
70
71
|
*/
|
|
71
72
|
declare function createVercube(cfg?: DeepPartial<ConfigTypes.Config>): Promise<DevKitTypes.App>;
|
|
72
73
|
//#endregion
|
|
@@ -97,4 +98,4 @@ declare function watch(app: DevKitTypes.App): Promise<void>;
|
|
|
97
98
|
*/
|
|
98
99
|
declare function createDevServer(app: DevKitTypes.App): DevKitTypes.DevServer;
|
|
99
100
|
//#endregion
|
|
100
|
-
export { build, createDevServer, createVercube, watch };
|
|
101
|
+
export { DevKitTypes, build, createDevServer, createVercube, watch };
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { builtinModules } from "node:module";
|
|
2
|
-
import { loadVercubeConfig } from "@vercube/core";
|
|
2
|
+
import { invokeVercubePluginDevHooks, loadVercubeConfig } from "@vercube/core";
|
|
3
3
|
import { createHooks } from "hookable";
|
|
4
4
|
import { join, resolve } from "node:path";
|
|
5
5
|
import consola, { consola as consola$1 } from "consola";
|
|
@@ -12,18 +12,27 @@ import { watch as watch$2 } from "chokidar";
|
|
|
12
12
|
import { fork } from "node:child_process";
|
|
13
13
|
//#region src/Common/App.ts
|
|
14
14
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* @
|
|
15
|
+
* Loads dev config, builds a `Hookable` app object, and runs plugin `hooks()` in the parent process.
|
|
16
|
+
*
|
|
17
|
+
* @param cfg - Partial config merged before load (typically sets `dev: true` via spread).
|
|
18
|
+
* @returns App handle with `hooks` and resolved `config`.
|
|
18
19
|
*/
|
|
19
20
|
async function createVercube(cfg) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
const hooks = createHooks();
|
|
22
|
+
const cwd = cfg?.build?.root ?? process.cwd();
|
|
23
|
+
const config = await loadVercubeConfig({
|
|
24
|
+
...cfg,
|
|
25
|
+
dev: true
|
|
26
|
+
}, { cwd });
|
|
27
|
+
const app = {
|
|
28
|
+
hooks,
|
|
29
|
+
config
|
|
26
30
|
};
|
|
31
|
+
await invokeVercubePluginDevHooks(config.plugins, {
|
|
32
|
+
hooks,
|
|
33
|
+
config
|
|
34
|
+
});
|
|
35
|
+
return app;
|
|
27
36
|
}
|
|
28
37
|
//#endregion
|
|
29
38
|
//#region src/Bundlers/Rolldown/Config.ts
|
|
@@ -105,6 +114,22 @@ async function build$1(ctx) {
|
|
|
105
114
|
});
|
|
106
115
|
}
|
|
107
116
|
//#endregion
|
|
117
|
+
//#region src/Common/reloadConfig.ts
|
|
118
|
+
/**
|
|
119
|
+
* Reloads config from disk into `app.config` and invokes each plugin's `hooks()` again with the new config.
|
|
120
|
+
*
|
|
121
|
+
* @param app - Devkit app instance returned by `createVercube` (mutates `app.config`).
|
|
122
|
+
* @returns Resolves when config load and all plugin `hooks` calls finish.
|
|
123
|
+
*/
|
|
124
|
+
async function reloadDevkitResolvedConfig(app) {
|
|
125
|
+
const next = await loadVercubeConfig({ dev: true }, { cwd: app.config.build?.root ?? process.cwd() });
|
|
126
|
+
app.config = next;
|
|
127
|
+
await invokeVercubePluginDevHooks(next.plugins, {
|
|
128
|
+
hooks: app.hooks,
|
|
129
|
+
config: next
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
//#endregion
|
|
108
133
|
//#region src/Bundlers/Rolldown/Watch.ts
|
|
109
134
|
/**
|
|
110
135
|
* Creates a watcher for rolldown
|
|
@@ -113,37 +138,49 @@ async function build$1(ctx) {
|
|
|
113
138
|
* @see https://github.com/nitrojs/nitro/blob/v2/src/core/build/dev.ts
|
|
114
139
|
*/
|
|
115
140
|
async function watch$3(app) {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
resolve$1(
|
|
122
|
-
resolve$1(app.config.build?.
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
141
|
+
let rolldownWatcher;
|
|
142
|
+
let extraWatcher;
|
|
143
|
+
const root = () => app.config.build?.root ?? process.cwd();
|
|
144
|
+
const filesToWatch = () => [
|
|
145
|
+
resolve$1(root(), (app.config?.c12?.dotenv)?.fileName?.[0] ?? ".env"),
|
|
146
|
+
resolve$1(root(), "vercube.config.ts"),
|
|
147
|
+
resolve$1(root(), app.config.build?.tsconfig ?? "tsconfig.json")
|
|
148
|
+
];
|
|
149
|
+
const startRolldown = async () => {
|
|
150
|
+
rolldownWatcher?.close();
|
|
151
|
+
const watcher = watch$1({
|
|
152
|
+
...await getRolldownConfig(app.config.build),
|
|
153
|
+
onwarn: () => {}
|
|
154
|
+
});
|
|
155
|
+
rolldownWatcher = watcher;
|
|
156
|
+
watcher.on("event", (event) => {
|
|
157
|
+
switch (event.code) {
|
|
158
|
+
case "START":
|
|
159
|
+
app.hooks.callHook("bundler-watch:init");
|
|
160
|
+
return;
|
|
161
|
+
case "BUNDLE_START":
|
|
162
|
+
app.hooks.callHook("bundler-watch:start");
|
|
163
|
+
return;
|
|
164
|
+
case "END":
|
|
165
|
+
app.hooks.callHook("bundler-watch:end");
|
|
166
|
+
return;
|
|
167
|
+
case "ERROR":
|
|
168
|
+
console.error(event.error);
|
|
169
|
+
app.hooks.callHook("bundler-watch:error", event.error);
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
};
|
|
173
|
+
const startChokidar = () => {
|
|
174
|
+
extraWatcher?.close();
|
|
175
|
+
extraWatcher = watch$2(filesToWatch(), { ignoreInitial: true });
|
|
176
|
+
extraWatcher.on("all", async () => {
|
|
177
|
+
await reloadDevkitResolvedConfig(app);
|
|
178
|
+
await app.hooks.callHook("bundler-watch:restart");
|
|
179
|
+
await startRolldown();
|
|
180
|
+
});
|
|
181
|
+
};
|
|
182
|
+
await startRolldown();
|
|
183
|
+
startChokidar();
|
|
147
184
|
}
|
|
148
185
|
//#endregion
|
|
149
186
|
//#region src/Utils/Utils.ts
|
|
@@ -203,9 +240,8 @@ async function watch(app) {
|
|
|
203
240
|
console.clear();
|
|
204
241
|
consola.info({
|
|
205
242
|
tag: "build",
|
|
206
|
-
message: "Configuration changed,
|
|
243
|
+
message: "Configuration changed, rebuilding..."
|
|
207
244
|
});
|
|
208
|
-
app.hooks.callHook("dev:reload");
|
|
209
245
|
});
|
|
210
246
|
app.hooks.hook("bundler-watch:error", (error) => {
|
|
211
247
|
console.log(error);
|
|
@@ -226,29 +262,47 @@ function createDevServer(app) {
|
|
|
226
262
|
let reloadPromise;
|
|
227
263
|
let currentFork;
|
|
228
264
|
/**
|
|
265
|
+
* Terminates a worker and resolves only once it has fully exited, so the
|
|
266
|
+
* resources it owns (the HTTP port and any message-queue consumers) are
|
|
267
|
+
* released before a replacement is spawned.
|
|
268
|
+
*
|
|
269
|
+
* A graceful SIGTERM may not stop a worker that holds long-lived handles -
|
|
270
|
+
* e.g. an open message-queue connection keeps the event loop alive - so fall
|
|
271
|
+
* back to SIGKILL after a short grace period.
|
|
272
|
+
* @param {ChildProcess} worker - The worker process to terminate.
|
|
273
|
+
* @returns {Promise<void>} A promise that resolves when the worker has exited.
|
|
274
|
+
*/
|
|
275
|
+
function killWorker(worker) {
|
|
276
|
+
if (worker.exitCode !== null || worker.signalCode !== null) return Promise.resolve();
|
|
277
|
+
return new Promise((resolve) => {
|
|
278
|
+
const killTimer = setTimeout(() => worker.kill("SIGKILL"), 1e3);
|
|
279
|
+
worker.once("exit", () => {
|
|
280
|
+
clearTimeout(killTimer);
|
|
281
|
+
resolve();
|
|
282
|
+
});
|
|
283
|
+
worker.kill("SIGTERM");
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
229
287
|
* Reloads the fork by killing the old one and creating a new one.
|
|
230
288
|
* @returns {Promise<void>} A promise that resolves when the fork is reloaded.
|
|
231
289
|
*/
|
|
232
290
|
async function _reload() {
|
|
233
291
|
const oldFork = currentFork;
|
|
234
292
|
currentFork = void 0;
|
|
235
|
-
if (oldFork) await
|
|
236
|
-
const killTimer = setTimeout(() => oldFork.kill("SIGKILL"), 1e3);
|
|
237
|
-
oldFork.once("exit", () => {
|
|
238
|
-
clearTimeout(killTimer);
|
|
239
|
-
resolve();
|
|
240
|
-
});
|
|
241
|
-
oldFork.kill("SIGTERM");
|
|
242
|
-
});
|
|
293
|
+
if (oldFork) await killWorker(oldFork);
|
|
243
294
|
currentFork = fork(forkEntry);
|
|
244
|
-
if (!currentFork) return;
|
|
245
295
|
}
|
|
246
296
|
/**
|
|
247
297
|
* Reloads the fork.
|
|
298
|
+
*
|
|
299
|
+
* Reloads are serialized: overlapping file-change events chain onto the
|
|
300
|
+
* previous reload instead of running concurrently, which would otherwise
|
|
301
|
+
* spawn a second worker while another is still shutting down.
|
|
248
302
|
* @returns {Promise<void>} A promise that resolves when the worker is reloaded.
|
|
249
303
|
*/
|
|
250
304
|
const reload = () => {
|
|
251
|
-
reloadPromise = _reload().then(() => {
|
|
305
|
+
reloadPromise = (reloadPromise ?? Promise.resolve()).then(() => _reload()).then(() => {
|
|
252
306
|
consola.success({
|
|
253
307
|
tag: "worker",
|
|
254
308
|
message: "Worker reloaded successfully"
|
|
@@ -259,8 +313,6 @@ function createDevServer(app) {
|
|
|
259
313
|
message: "Failed to reload worker",
|
|
260
314
|
error
|
|
261
315
|
});
|
|
262
|
-
}).finally(() => {
|
|
263
|
-
reloadPromise = void 0;
|
|
264
316
|
});
|
|
265
317
|
return reloadPromise;
|
|
266
318
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vercube/devkit",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "1.0.0-beta.1",
|
|
4
4
|
"description": "Devkit module for Vercube framework",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -22,19 +22,19 @@
|
|
|
22
22
|
"README.md"
|
|
23
23
|
],
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@oxc-project/runtime": "0.
|
|
25
|
+
"@oxc-project/runtime": "0.135.0",
|
|
26
26
|
"c12": "4.0.0-beta.5",
|
|
27
27
|
"chokidar": "5.0.0",
|
|
28
28
|
"consola": "3.4.2",
|
|
29
29
|
"defu": "6.1.7",
|
|
30
30
|
"dotenv": "17.4.2",
|
|
31
31
|
"hookable": "6.1.1",
|
|
32
|
-
"oxc-parser": "0.
|
|
33
|
-
"oxc-transform": "0.
|
|
32
|
+
"oxc-parser": "0.135.0",
|
|
33
|
+
"oxc-transform": "0.135.0",
|
|
34
34
|
"pathe": "2.0.3",
|
|
35
|
-
"rolldown": "1.
|
|
35
|
+
"rolldown": "1.1.1",
|
|
36
36
|
"unplugin-isolated-decl": "0.16.0",
|
|
37
|
-
"@vercube/core": "0.0.
|
|
37
|
+
"@vercube/core": "1.0.0-beta.1"
|
|
38
38
|
},
|
|
39
39
|
"publishConfig": {
|
|
40
40
|
"access": "public"
|