vantris 0.2.0 → 0.3.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/dist/chunk-LRSN7SF4.js +1117 -0
- package/dist/chunk-LRSN7SF4.js.map +1 -0
- package/dist/cli/index.js +1 -1
- package/dist/index.d.ts +152 -2
- package/dist/index.js +1 -1
- package/package.json +20 -2
- package/dist/chunk-OFLPPG2U.js +0 -600
- package/dist/chunk-OFLPPG2U.js.map +0 -1
package/dist/chunk-OFLPPG2U.js
DELETED
|
@@ -1,600 +0,0 @@
|
|
|
1
|
-
import { pathToFileURL } from 'url';
|
|
2
|
-
import { readFile, stat, mkdir } from 'fs/promises';
|
|
3
|
-
import { relative, isAbsolute, resolve, join, sep, extname } from 'path';
|
|
4
|
-
import { createServer } from 'http';
|
|
5
|
-
import { H3, toNodeHandler, getRequestURL } from 'h3';
|
|
6
|
-
import { WebSocketServer, WebSocket } from 'ws';
|
|
7
|
-
import { transform } from 'esbuild';
|
|
8
|
-
import { watch } from 'chokidar';
|
|
9
|
-
|
|
10
|
-
// src/shared/constants.ts
|
|
11
|
-
var APP_NAME = "vantris";
|
|
12
|
-
var VERSION = "0.2.0";
|
|
13
|
-
var HTML_ENTRY_FILENAME = "index.html";
|
|
14
|
-
var DEFAULTS = {
|
|
15
|
-
root: ".",
|
|
16
|
-
rootDir: "./src",
|
|
17
|
-
publicDir: "./public",
|
|
18
|
-
outDir: "./dist"
|
|
19
|
-
};
|
|
20
|
-
var DEV_DEFAULTS = {
|
|
21
|
-
port: 3e3,
|
|
22
|
-
host: "localhost"
|
|
23
|
-
};
|
|
24
|
-
var RELOAD_MESSAGE = "reload";
|
|
25
|
-
var CONFIG_FILENAMES = [
|
|
26
|
-
"vantris.config.ts",
|
|
27
|
-
"vantris.config.js",
|
|
28
|
-
"vantris.config.mjs"
|
|
29
|
-
];
|
|
30
|
-
|
|
31
|
-
// src/shared/errors.ts
|
|
32
|
-
var VantrisError = class extends Error {
|
|
33
|
-
name = "VantrisError";
|
|
34
|
-
constructor(message, options) {
|
|
35
|
-
super(message, options);
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
var ConfigError = class extends VantrisError {
|
|
39
|
-
name = "ConfigError";
|
|
40
|
-
};
|
|
41
|
-
var HtmlEntryError = class extends VantrisError {
|
|
42
|
-
name = "HtmlEntryError";
|
|
43
|
-
};
|
|
44
|
-
var NotImplementedError = class extends VantrisError {
|
|
45
|
-
name = "NotImplementedError";
|
|
46
|
-
};
|
|
47
|
-
function isVantrisError(error) {
|
|
48
|
-
return error instanceof VantrisError;
|
|
49
|
-
}
|
|
50
|
-
async function isFile(path) {
|
|
51
|
-
try {
|
|
52
|
-
return (await stat(path)).isFile();
|
|
53
|
-
} catch {
|
|
54
|
-
return false;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
function readTextFile(path) {
|
|
58
|
-
return readFile(path, "utf8");
|
|
59
|
-
}
|
|
60
|
-
async function ensureDir(path) {
|
|
61
|
-
await mkdir(path, { recursive: true });
|
|
62
|
-
}
|
|
63
|
-
function resolveFrom(base, target) {
|
|
64
|
-
return isAbsolute(target) ? target : resolve(base, target);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// src/config/load.ts
|
|
68
|
-
async function loadConfig(options) {
|
|
69
|
-
const { cwd, logger } = options;
|
|
70
|
-
const file = options.configFile ? resolveFrom(cwd, options.configFile) : await findConfigFile(cwd);
|
|
71
|
-
if (!file) {
|
|
72
|
-
logger.debug("No config file found; using defaults.");
|
|
73
|
-
return { config: {}, file: null };
|
|
74
|
-
}
|
|
75
|
-
logger.debug(`Loading config from ${file}`);
|
|
76
|
-
const config = await importConfig(file);
|
|
77
|
-
return { config, file };
|
|
78
|
-
}
|
|
79
|
-
async function findConfigFile(cwd) {
|
|
80
|
-
for (const name of CONFIG_FILENAMES) {
|
|
81
|
-
const candidate = resolveFrom(cwd, name);
|
|
82
|
-
if (await isFile(candidate)) return candidate;
|
|
83
|
-
}
|
|
84
|
-
return null;
|
|
85
|
-
}
|
|
86
|
-
async function importConfig(file) {
|
|
87
|
-
let mod;
|
|
88
|
-
try {
|
|
89
|
-
const url = `${pathToFileURL(file).href}?t=${Date.now()}`;
|
|
90
|
-
mod = await import(url);
|
|
91
|
-
} catch (cause) {
|
|
92
|
-
throw new ConfigError(`Failed to load config file: ${file}`, { cause });
|
|
93
|
-
}
|
|
94
|
-
const exported = mod.default;
|
|
95
|
-
if (exported === void 0) {
|
|
96
|
-
throw new ConfigError(
|
|
97
|
-
`Config file "${file}" has no default export. Export your config with \`export default defineConfig({ ... })\`.`
|
|
98
|
-
);
|
|
99
|
-
}
|
|
100
|
-
return normalise(exported, file);
|
|
101
|
-
}
|
|
102
|
-
async function normalise(input, file) {
|
|
103
|
-
const value = typeof input === "function" ? await input() : input;
|
|
104
|
-
if (value === null || typeof value !== "object") {
|
|
105
|
-
throw new ConfigError(
|
|
106
|
-
`Config file "${file}" must export an object (or a function returning one).`
|
|
107
|
-
);
|
|
108
|
-
}
|
|
109
|
-
return value;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// src/config/resolve.ts
|
|
113
|
-
function resolveConfig(raw, cwd, configFile = null) {
|
|
114
|
-
const root = resolveFrom(cwd, raw.root ?? DEFAULTS.root);
|
|
115
|
-
const paths = {
|
|
116
|
-
root,
|
|
117
|
-
rootDir: resolveFrom(root, raw.rootDir ?? DEFAULTS.rootDir),
|
|
118
|
-
publicDir: resolveFrom(root, raw.publicDir ?? DEFAULTS.publicDir),
|
|
119
|
-
outDir: resolveFrom(root, raw.outDir ?? DEFAULTS.outDir)
|
|
120
|
-
};
|
|
121
|
-
const dev2 = {
|
|
122
|
-
port: raw.dev?.port ?? DEV_DEFAULTS.port,
|
|
123
|
-
host: raw.dev?.host ?? DEV_DEFAULTS.host
|
|
124
|
-
};
|
|
125
|
-
return { raw, paths, dev: dev2, configFile };
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// src/html/parse.ts
|
|
129
|
-
var SCRIPT_TAG = /<script\b[^>]*>/gi;
|
|
130
|
-
var TYPE_MODULE = /\btype\s*=\s*["']module["']/i;
|
|
131
|
-
var SRC_ATTR = /\bsrc\s*=\s*["']([^"']+)["']/i;
|
|
132
|
-
function parseHtml(file, html) {
|
|
133
|
-
const scripts = [];
|
|
134
|
-
for (const [tag] of html.matchAll(SCRIPT_TAG)) {
|
|
135
|
-
if (!TYPE_MODULE.test(tag)) continue;
|
|
136
|
-
const src = SRC_ATTR.exec(tag)?.[1];
|
|
137
|
-
if (src) scripts.push({ src });
|
|
138
|
-
}
|
|
139
|
-
return { file, html, scripts };
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// src/html/detect.ts
|
|
143
|
-
async function detectHtmlEntry(root) {
|
|
144
|
-
const file = resolveFrom(root, HTML_ENTRY_FILENAME);
|
|
145
|
-
if (!await isFile(file)) return null;
|
|
146
|
-
const html = await readTextFile(file);
|
|
147
|
-
return parseHtml(file, html);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// src/html/client.ts
|
|
151
|
-
var DEV_CLIENT_SCRIPT = `<script type="module">
|
|
152
|
-
// Injected by Vantris dev server \u2014 live reload (full page).
|
|
153
|
-
const connect = () => {
|
|
154
|
-
const ws = new WebSocket("ws://" + location.host);
|
|
155
|
-
ws.addEventListener("message", () => location.reload());
|
|
156
|
-
// Reconnect if the dev server restarts.
|
|
157
|
-
ws.addEventListener("close", () => setTimeout(connect, 1000));
|
|
158
|
-
};
|
|
159
|
-
connect();
|
|
160
|
-
</script>`;
|
|
161
|
-
function injectDevClient(html) {
|
|
162
|
-
if (html.includes("</head>")) {
|
|
163
|
-
return html.replace("</head>", `${DEV_CLIENT_SCRIPT}
|
|
164
|
-
</head>`);
|
|
165
|
-
}
|
|
166
|
-
if (html.includes("</body>")) {
|
|
167
|
-
return html.replace("</body>", `${DEV_CLIENT_SCRIPT}
|
|
168
|
-
</body>`);
|
|
169
|
-
}
|
|
170
|
-
return `${html}
|
|
171
|
-
${DEV_CLIENT_SCRIPT}`;
|
|
172
|
-
}
|
|
173
|
-
function createReloadSocket(options) {
|
|
174
|
-
const { server, logger } = options;
|
|
175
|
-
const wss = new WebSocketServer({ server });
|
|
176
|
-
const clients = /* @__PURE__ */ new Set();
|
|
177
|
-
wss.on("connection", (socket) => {
|
|
178
|
-
clients.add(socket);
|
|
179
|
-
socket.on("close", () => clients.delete(socket));
|
|
180
|
-
socket.on("error", () => clients.delete(socket));
|
|
181
|
-
});
|
|
182
|
-
wss.on("error", (error) => {
|
|
183
|
-
logger.error(`websocket error: ${error.message}`);
|
|
184
|
-
});
|
|
185
|
-
return {
|
|
186
|
-
broadcastReload() {
|
|
187
|
-
for (const socket of clients) {
|
|
188
|
-
if (socket.readyState === WebSocket.OPEN) {
|
|
189
|
-
socket.send(RELOAD_MESSAGE);
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
},
|
|
193
|
-
get clientCount() {
|
|
194
|
-
return clients.size;
|
|
195
|
-
},
|
|
196
|
-
close() {
|
|
197
|
-
return new Promise((resolveClose) => {
|
|
198
|
-
for (const socket of clients) socket.terminate();
|
|
199
|
-
clients.clear();
|
|
200
|
-
wss.close(() => resolveClose());
|
|
201
|
-
});
|
|
202
|
-
}
|
|
203
|
-
};
|
|
204
|
-
}
|
|
205
|
-
var MIME_TYPES = {
|
|
206
|
-
".html": "text/html; charset=utf-8",
|
|
207
|
-
".js": "text/javascript; charset=utf-8",
|
|
208
|
-
".mjs": "text/javascript; charset=utf-8",
|
|
209
|
-
".css": "text/css; charset=utf-8",
|
|
210
|
-
".json": "application/json; charset=utf-8",
|
|
211
|
-
".svg": "image/svg+xml",
|
|
212
|
-
".png": "image/png",
|
|
213
|
-
".jpg": "image/jpeg",
|
|
214
|
-
".jpeg": "image/jpeg",
|
|
215
|
-
".gif": "image/gif",
|
|
216
|
-
".webp": "image/webp",
|
|
217
|
-
".ico": "image/x-icon",
|
|
218
|
-
".woff": "font/woff",
|
|
219
|
-
".woff2": "font/woff2",
|
|
220
|
-
".txt": "text/plain; charset=utf-8",
|
|
221
|
-
".map": "application/json; charset=utf-8"
|
|
222
|
-
};
|
|
223
|
-
var JAVASCRIPT = "text/javascript; charset=utf-8";
|
|
224
|
-
function contentTypeFor(file, transpiled = false) {
|
|
225
|
-
if (transpiled) return JAVASCRIPT;
|
|
226
|
-
return MIME_TYPES[extname(file).toLowerCase()] ?? "application/octet-stream";
|
|
227
|
-
}
|
|
228
|
-
var TRANSPILE_EXTENSIONS = /* @__PURE__ */ new Set([".ts", ".tsx", ".mts", ".cts", ".jsx"]);
|
|
229
|
-
function shouldTranspile(file) {
|
|
230
|
-
return TRANSPILE_EXTENSIONS.has(extname(file).toLowerCase());
|
|
231
|
-
}
|
|
232
|
-
function loaderFor(file) {
|
|
233
|
-
switch (extname(file).toLowerCase()) {
|
|
234
|
-
case ".tsx":
|
|
235
|
-
return "tsx";
|
|
236
|
-
case ".jsx":
|
|
237
|
-
return "jsx";
|
|
238
|
-
default:
|
|
239
|
-
return "ts";
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
async function transpile(code, file) {
|
|
243
|
-
const result = await transform(code, {
|
|
244
|
-
loader: loaderFor(file),
|
|
245
|
-
format: "esm",
|
|
246
|
-
target: "es2022",
|
|
247
|
-
sourcemap: "inline",
|
|
248
|
-
sourcefile: file
|
|
249
|
-
});
|
|
250
|
-
return result.code;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
// src/server/static.ts
|
|
254
|
-
var RESOLVE_EXTENSIONS = [".ts", ".tsx", ".mts", ".js", ".mjs", ".jsx"];
|
|
255
|
-
function createStaticLoader(options) {
|
|
256
|
-
const root = resolve(options.root);
|
|
257
|
-
const rootDir = resolve(options.rootDir);
|
|
258
|
-
const publicDir = resolve(options.publicDir);
|
|
259
|
-
return async function loadAsset(pathname) {
|
|
260
|
-
const relative3 = decodeURIComponent(pathname).replace(/^\/+/, "");
|
|
261
|
-
if (!relative3) return null;
|
|
262
|
-
const source = await resolveConfined(root, rootDir, relative3);
|
|
263
|
-
if (source) return readAsset(source);
|
|
264
|
-
const asset = await resolveConfined(publicDir, publicDir, relative3);
|
|
265
|
-
if (asset) return readAsset(asset);
|
|
266
|
-
return null;
|
|
267
|
-
};
|
|
268
|
-
}
|
|
269
|
-
async function resolveConfined(base, confine, relative3) {
|
|
270
|
-
const target = resolve(join(base, relative3));
|
|
271
|
-
if (target !== confine && !target.startsWith(confine + sep)) {
|
|
272
|
-
return null;
|
|
273
|
-
}
|
|
274
|
-
if (await isFile(target)) return target;
|
|
275
|
-
if (!extname(target)) {
|
|
276
|
-
for (const ext of RESOLVE_EXTENSIONS) {
|
|
277
|
-
const candidate = `${target}${ext}`;
|
|
278
|
-
if (await isFile(candidate)) return candidate;
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
return null;
|
|
282
|
-
}
|
|
283
|
-
async function readAsset(file) {
|
|
284
|
-
const ext = extname(file).toLowerCase();
|
|
285
|
-
const isHtml = ext === ".html";
|
|
286
|
-
if (shouldTranspile(file)) {
|
|
287
|
-
const source = await readFile(file, "utf8");
|
|
288
|
-
return {
|
|
289
|
-
body: await transpile(source, file),
|
|
290
|
-
contentType: contentTypeFor(file, true),
|
|
291
|
-
isHtml: false
|
|
292
|
-
};
|
|
293
|
-
}
|
|
294
|
-
if (isHtml) {
|
|
295
|
-
return {
|
|
296
|
-
body: await readFile(file, "utf8"),
|
|
297
|
-
contentType: contentTypeFor(file),
|
|
298
|
-
isHtml: true
|
|
299
|
-
};
|
|
300
|
-
}
|
|
301
|
-
return {
|
|
302
|
-
body: await readFile(file),
|
|
303
|
-
contentType: contentTypeFor(file),
|
|
304
|
-
isHtml: false
|
|
305
|
-
};
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
// src/server/index.ts
|
|
309
|
-
var HTML_HEADERS = {
|
|
310
|
-
"content-type": "text/html; charset=utf-8",
|
|
311
|
-
"cache-control": "no-cache"
|
|
312
|
-
};
|
|
313
|
-
async function startDevServer(options) {
|
|
314
|
-
const { ctx, entry } = options;
|
|
315
|
-
const { paths, dev: dev2 } = ctx.config;
|
|
316
|
-
const loadAsset = createStaticLoader({
|
|
317
|
-
root: paths.root,
|
|
318
|
-
rootDir: paths.rootDir,
|
|
319
|
-
publicDir: paths.publicDir
|
|
320
|
-
});
|
|
321
|
-
const entryFile = entry?.file ?? null;
|
|
322
|
-
const app = new H3();
|
|
323
|
-
const handler = async (event) => {
|
|
324
|
-
const { pathname } = getRequestURL(event);
|
|
325
|
-
const asset = await loadAsset(pathname);
|
|
326
|
-
if (asset) {
|
|
327
|
-
if (asset.isHtml) {
|
|
328
|
-
return new Response(injectDevClient(asset.body), {
|
|
329
|
-
headers: HTML_HEADERS
|
|
330
|
-
});
|
|
331
|
-
}
|
|
332
|
-
return new Response(asset.body, {
|
|
333
|
-
headers: { "content-type": asset.contentType, "cache-control": "no-cache" }
|
|
334
|
-
});
|
|
335
|
-
}
|
|
336
|
-
if (entryFile) {
|
|
337
|
-
const html = await readFile(entryFile, "utf8");
|
|
338
|
-
return new Response(injectDevClient(html), { headers: HTML_HEADERS });
|
|
339
|
-
}
|
|
340
|
-
return new Response(`404 Not Found: ${pathname}`, {
|
|
341
|
-
status: 404,
|
|
342
|
-
headers: { "content-type": "text/plain; charset=utf-8" }
|
|
343
|
-
});
|
|
344
|
-
};
|
|
345
|
-
app.all("/", handler);
|
|
346
|
-
app.all("/**", handler);
|
|
347
|
-
const server = createServer(toNodeHandler(app));
|
|
348
|
-
const reload = createReloadSocket({ server, logger: ctx.logger });
|
|
349
|
-
await listen(server, dev2.port, dev2.host);
|
|
350
|
-
const url = `http://${dev2.host}:${dev2.port}/`;
|
|
351
|
-
return {
|
|
352
|
-
url,
|
|
353
|
-
host: dev2.host,
|
|
354
|
-
port: dev2.port,
|
|
355
|
-
broadcastReload: () => reload.broadcastReload(),
|
|
356
|
-
async close() {
|
|
357
|
-
await reload.close();
|
|
358
|
-
await new Promise((resolveClose, reject) => {
|
|
359
|
-
server.close((err) => err ? reject(err) : resolveClose());
|
|
360
|
-
});
|
|
361
|
-
}
|
|
362
|
-
};
|
|
363
|
-
}
|
|
364
|
-
function listen(server, port, host) {
|
|
365
|
-
return new Promise((resolveListen, reject) => {
|
|
366
|
-
const onError = (err) => {
|
|
367
|
-
server.removeListener("error", onError);
|
|
368
|
-
reject(
|
|
369
|
-
err.code === "EADDRINUSE" ? new Error(`Port ${port} is already in use.`) : err
|
|
370
|
-
);
|
|
371
|
-
};
|
|
372
|
-
server.once("error", onError);
|
|
373
|
-
server.listen(port, host, () => {
|
|
374
|
-
server.removeListener("error", onError);
|
|
375
|
-
resolveListen();
|
|
376
|
-
});
|
|
377
|
-
});
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
// src/shared/logger.ts
|
|
381
|
-
var prefix = `[${APP_NAME}]`;
|
|
382
|
-
function createLogger(options = {}) {
|
|
383
|
-
const { verbose = false, sink = console } = options;
|
|
384
|
-
return {
|
|
385
|
-
info(message) {
|
|
386
|
-
sink.log(`${prefix} ${message}`);
|
|
387
|
-
},
|
|
388
|
-
warn(message) {
|
|
389
|
-
sink.warn(`${prefix} ${message}`);
|
|
390
|
-
},
|
|
391
|
-
error(message) {
|
|
392
|
-
sink.error(`${prefix} ${message}`);
|
|
393
|
-
},
|
|
394
|
-
debug(message) {
|
|
395
|
-
if (verbose) sink.log(`${prefix} ${message}`);
|
|
396
|
-
}
|
|
397
|
-
};
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
// src/shared/context.ts
|
|
401
|
-
async function createContext(options) {
|
|
402
|
-
const { cwd, logger } = options;
|
|
403
|
-
const loaded = await loadConfig({
|
|
404
|
-
cwd,
|
|
405
|
-
logger,
|
|
406
|
-
...options.configFile !== void 0 ? { configFile: options.configFile } : {}
|
|
407
|
-
});
|
|
408
|
-
const config = resolveConfig(loaded.config, cwd, loaded.file);
|
|
409
|
-
return { cwd, config, logger };
|
|
410
|
-
}
|
|
411
|
-
function createWatcher(options) {
|
|
412
|
-
const { dir, logger, onChange } = options;
|
|
413
|
-
const watcher = watch(dir, {
|
|
414
|
-
ignoreInitial: true,
|
|
415
|
-
persistent: true,
|
|
416
|
-
ignored: (path) => path.includes("node_modules") || /(^|[/\\])\.[^/\\]/.test(path)
|
|
417
|
-
});
|
|
418
|
-
const emit = (kind) => (file) => {
|
|
419
|
-
logger.debug(`watch ${kind}: ${file}`);
|
|
420
|
-
onChange({ kind, file });
|
|
421
|
-
};
|
|
422
|
-
watcher.on("add", emit("add")).on("change", emit("change")).on("unlink", emit("unlink")).on(
|
|
423
|
-
"error",
|
|
424
|
-
(error) => logger.error(`watcher error: ${error.message}`)
|
|
425
|
-
);
|
|
426
|
-
return {
|
|
427
|
-
close: () => watcher.close()
|
|
428
|
-
};
|
|
429
|
-
}
|
|
430
|
-
function rel(ctx, target) {
|
|
431
|
-
return relative(ctx.config.paths.root, target) || ".";
|
|
432
|
-
}
|
|
433
|
-
async function inspectProject(ctx) {
|
|
434
|
-
const { paths, configFile } = ctx.config;
|
|
435
|
-
ctx.logger.info(
|
|
436
|
-
`config: ${configFile ? rel(ctx, configFile) : "defaults (no config file)"}`
|
|
437
|
-
);
|
|
438
|
-
ctx.logger.info(`rootDir: ${rel(ctx, paths.rootDir)}`);
|
|
439
|
-
ctx.logger.info(`publicDir: ${rel(ctx, paths.publicDir)}`);
|
|
440
|
-
ctx.logger.info(`outDir: ${rel(ctx, paths.outDir)}`);
|
|
441
|
-
const entry = await detectHtmlEntry(paths.root);
|
|
442
|
-
if (entry) {
|
|
443
|
-
ctx.logger.info(`html entry: ${rel(ctx, entry.file)}`);
|
|
444
|
-
} else {
|
|
445
|
-
ctx.logger.warn(
|
|
446
|
-
"no index.html found at the project root; nothing to serve yet."
|
|
447
|
-
);
|
|
448
|
-
}
|
|
449
|
-
return entry;
|
|
450
|
-
}
|
|
451
|
-
async function prepareDirectories(ctx, dirs) {
|
|
452
|
-
for (const dir of dirs) {
|
|
453
|
-
await ensureDir(dir);
|
|
454
|
-
ctx.logger.debug(`prepared directory: ${dir}`);
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
// src/commands/dev.ts
|
|
459
|
-
var RELOAD_DEBOUNCE_MS = 50;
|
|
460
|
-
var dev = {
|
|
461
|
-
name: "dev",
|
|
462
|
-
description: "Start the development server",
|
|
463
|
-
async run(ctx) {
|
|
464
|
-
const { root, rootDir, publicDir } = ctx.config.paths;
|
|
465
|
-
await prepareDirectories(ctx, [rootDir, publicDir]);
|
|
466
|
-
const entry = await inspectProject(ctx);
|
|
467
|
-
const server = await startDevServer({ ctx, entry });
|
|
468
|
-
ctx.logger.info(`ready \u2014 dev server running at ${server.url}`);
|
|
469
|
-
let timer;
|
|
470
|
-
const watcher = createWatcher({
|
|
471
|
-
dir: rootDir,
|
|
472
|
-
logger: ctx.logger,
|
|
473
|
-
onChange: ({ kind, file }) => {
|
|
474
|
-
ctx.logger.info(`${kind}: ${relative(root, file)} \u2014 reloading`);
|
|
475
|
-
if (timer) clearTimeout(timer);
|
|
476
|
-
timer = setTimeout(() => server.broadcastReload(), RELOAD_DEBOUNCE_MS);
|
|
477
|
-
}
|
|
478
|
-
});
|
|
479
|
-
await waitForShutdown();
|
|
480
|
-
ctx.logger.info("shutting down\u2026");
|
|
481
|
-
if (timer) clearTimeout(timer);
|
|
482
|
-
await watcher.close();
|
|
483
|
-
await server.close();
|
|
484
|
-
}
|
|
485
|
-
};
|
|
486
|
-
function waitForShutdown() {
|
|
487
|
-
return new Promise((resolve3) => {
|
|
488
|
-
const onSignal = () => {
|
|
489
|
-
process.removeListener("SIGINT", onSignal);
|
|
490
|
-
process.removeListener("SIGTERM", onSignal);
|
|
491
|
-
resolve3();
|
|
492
|
-
};
|
|
493
|
-
process.once("SIGINT", onSignal);
|
|
494
|
-
process.once("SIGTERM", onSignal);
|
|
495
|
-
});
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
// src/build/index.ts
|
|
499
|
-
async function runBuild(options) {
|
|
500
|
-
const { ctx } = options;
|
|
501
|
-
ctx.logger.info(
|
|
502
|
-
"build is not implemented in v0.1.0 (planned: Rolldown + esbuild)."
|
|
503
|
-
);
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
// src/commands/build.ts
|
|
507
|
-
var build = {
|
|
508
|
-
name: "build",
|
|
509
|
-
description: "Build the project for production",
|
|
510
|
-
async run(ctx) {
|
|
511
|
-
const { rootDir, publicDir, outDir } = ctx.config.paths;
|
|
512
|
-
await prepareDirectories(ctx, [rootDir, publicDir, outDir]);
|
|
513
|
-
await inspectProject(ctx);
|
|
514
|
-
await runBuild({ ctx});
|
|
515
|
-
}
|
|
516
|
-
};
|
|
517
|
-
|
|
518
|
-
// src/preview/index.ts
|
|
519
|
-
async function runPreview(options) {
|
|
520
|
-
const { ctx } = options;
|
|
521
|
-
ctx.logger.info(
|
|
522
|
-
"preview is not implemented in v0.1.0 (planned: static server over outDir)."
|
|
523
|
-
);
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
// src/commands/preview.ts
|
|
527
|
-
var preview = {
|
|
528
|
-
name: "preview",
|
|
529
|
-
description: "Locally preview a production build",
|
|
530
|
-
async run(ctx) {
|
|
531
|
-
await prepareDirectories(ctx, [ctx.config.paths.outDir]);
|
|
532
|
-
await inspectProject(ctx);
|
|
533
|
-
await runPreview({ ctx });
|
|
534
|
-
}
|
|
535
|
-
};
|
|
536
|
-
|
|
537
|
-
// src/commands/index.ts
|
|
538
|
-
var commands = {
|
|
539
|
-
[dev.name]: dev,
|
|
540
|
-
[build.name]: build,
|
|
541
|
-
[preview.name]: preview
|
|
542
|
-
};
|
|
543
|
-
|
|
544
|
-
// src/cli/help.ts
|
|
545
|
-
function helpText() {
|
|
546
|
-
const lines = [
|
|
547
|
-
`${APP_NAME} v${VERSION} \u2014 a modern bundler for JavaScript/TypeScript`,
|
|
548
|
-
"",
|
|
549
|
-
"Usage:",
|
|
550
|
-
` ${APP_NAME} <command> [options]`,
|
|
551
|
-
"",
|
|
552
|
-
"Commands:"
|
|
553
|
-
];
|
|
554
|
-
const width = Math.max(...Object.keys(commands).map((n) => n.length));
|
|
555
|
-
for (const command of Object.values(commands)) {
|
|
556
|
-
lines.push(` ${command.name.padEnd(width)} ${command.description}`);
|
|
557
|
-
}
|
|
558
|
-
lines.push(
|
|
559
|
-
"",
|
|
560
|
-
"Options:",
|
|
561
|
-
" -h, --help Show this help",
|
|
562
|
-
" -v, --version Show the version number"
|
|
563
|
-
);
|
|
564
|
-
return lines.join("\n");
|
|
565
|
-
}
|
|
566
|
-
function versionText() {
|
|
567
|
-
return `${APP_NAME} v${VERSION}`;
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
// src/cli/run.ts
|
|
571
|
-
async function run(argv, options = {}) {
|
|
572
|
-
const verbose = argv.includes("--verbose") || argv.includes("--debug");
|
|
573
|
-
const logger = options.logger ?? createLogger({ verbose });
|
|
574
|
-
const cwd = options.cwd ?? process.cwd();
|
|
575
|
-
const [first, ...rest] = argv.filter((arg) => !isGlobalFlag(arg));
|
|
576
|
-
if (!first || first === "--help" || first === "-h" || first === "help") {
|
|
577
|
-
logger.info(helpText());
|
|
578
|
-
return 0 /* Ok */;
|
|
579
|
-
}
|
|
580
|
-
if (first === "--version" || first === "-v") {
|
|
581
|
-
logger.info(versionText());
|
|
582
|
-
return 0 /* Ok */;
|
|
583
|
-
}
|
|
584
|
-
const command = commands[first];
|
|
585
|
-
if (!command) {
|
|
586
|
-
logger.error(`Unknown command: "${first}"`);
|
|
587
|
-
logger.info(helpText());
|
|
588
|
-
return 1 /* Error */;
|
|
589
|
-
}
|
|
590
|
-
const ctx = await createContext({ cwd, logger });
|
|
591
|
-
await command.run(ctx, rest);
|
|
592
|
-
return 0 /* Ok */;
|
|
593
|
-
}
|
|
594
|
-
function isGlobalFlag(arg) {
|
|
595
|
-
return arg === "--verbose" || arg === "--debug";
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
export { ConfigError, DEV_CLIENT_SCRIPT, HtmlEntryError, NotImplementedError, VERSION, VantrisError, commands, createContext, createLogger, createWatcher, detectHtmlEntry, injectDevClient, isVantrisError, loadConfig, parseHtml, resolveConfig, run, startDevServer };
|
|
599
|
-
//# sourceMappingURL=chunk-OFLPPG2U.js.map
|
|
600
|
-
//# sourceMappingURL=chunk-OFLPPG2U.js.map
|