mono-jsx-dom 0.1.3 → 0.1.5
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/bin/build.mjs +12 -9
- package/bin/cli +1 -1
- package/bin/dev.mjs +47 -11
- package/bin/init.mjs +132 -47
- package/package.json +1 -1
- package/server/node-fetch-server.mjs +8 -4
package/bin/build.mjs
CHANGED
|
@@ -60,11 +60,11 @@ async function run() {
|
|
|
60
60
|
const flags = parseFlags();
|
|
61
61
|
const start = performance.now();
|
|
62
62
|
const runtime = flags.node ?? "fetch-server";
|
|
63
|
-
await build({ runtime });
|
|
63
|
+
await build({ serverType: runtime });
|
|
64
64
|
console.log("\x1B[32m\u2728 Build completed.\x1B[0m", "\x1B[90m(%d ms)\x1B[0m", performance.now() - start);
|
|
65
65
|
}
|
|
66
66
|
async function build(options) {
|
|
67
|
-
const workDir = join(cwd(), options?.
|
|
67
|
+
const workDir = join(cwd(), options?.appName ?? ".");
|
|
68
68
|
const outdir = join(workDir, options?.outdir ?? "dist");
|
|
69
69
|
if (!await exists(join(workDir, "index.html"))) {
|
|
70
70
|
console.error("index.html not found");
|
|
@@ -159,7 +159,9 @@ async function build(options) {
|
|
|
159
159
|
for (const file of outputFiles) {
|
|
160
160
|
const contentType = file.path.endsWith(".js") ? "application/javascript" : "text/css";
|
|
161
161
|
const filename = relative(outdir, file.path);
|
|
162
|
-
|
|
162
|
+
if (filename !== tw?.entryCSS) {
|
|
163
|
+
vfs[filename] = await createVFile(indexHTML, filename, file.text, contentType);
|
|
164
|
+
}
|
|
163
165
|
}
|
|
164
166
|
if (tw) {
|
|
165
167
|
const css = await tw.build();
|
|
@@ -173,10 +175,10 @@ async function build(options) {
|
|
|
173
175
|
'import buildJSON$ from "./build.json" with { type: "json" };',
|
|
174
176
|
"server$.setVFS(new Map(Object.entries(buildJSON$)));"
|
|
175
177
|
].join("");
|
|
176
|
-
await buildServerJS(workDir, outdir, options?.
|
|
178
|
+
await buildServerJS(workDir, outdir, options?.serverType, extraJS);
|
|
177
179
|
await dispose();
|
|
178
180
|
}
|
|
179
|
-
async function buildServerJS(workDir, outdir,
|
|
181
|
+
async function buildServerJS(workDir, outdir, serverType = "fetch-server", extraJS, watch) {
|
|
180
182
|
const stdin2 = {
|
|
181
183
|
sourcefile: join(workDir, "server.js"),
|
|
182
184
|
contents: 'import server from "mono-jsx-dom/server;export default server;',
|
|
@@ -185,7 +187,7 @@ async function buildServerJS(workDir, outdir, runtime = "fetch-server", extraJS,
|
|
|
185
187
|
for (const loader of ["ts", "tsx", "js", "jsx"]) {
|
|
186
188
|
const sourcefile = join(workDir, "server." + loader);
|
|
187
189
|
if (await exists(sourcefile)) {
|
|
188
|
-
if (
|
|
190
|
+
if (serverType === "node") {
|
|
189
191
|
stdin2.sourcefile = join(workDir, "server-node.mjs");
|
|
190
192
|
stdin2.resolveDir = workDir;
|
|
191
193
|
stdin2.contents = [
|
|
@@ -235,6 +237,7 @@ async function buildServerJS(workDir, outdir, runtime = "fetch-server", extraJS,
|
|
|
235
237
|
} else {
|
|
236
238
|
await ctx.rebuild();
|
|
237
239
|
await ctx.dispose();
|
|
240
|
+
await esbuild.stop();
|
|
238
241
|
}
|
|
239
242
|
}
|
|
240
243
|
function initTailwindBuilder(workDir, entryCSS) {
|
|
@@ -297,7 +300,7 @@ async function paseIndexHtml(workDir) {
|
|
|
297
300
|
}
|
|
298
301
|
const relativePath = relative(workDir, join(workDir, href));
|
|
299
302
|
entryPoints[relativePath] = relativePath;
|
|
300
|
-
return `<link${attrs}
|
|
303
|
+
return `<link${attrs}href="/${relativePath}">`;
|
|
301
304
|
});
|
|
302
305
|
content = content.replace(/<script(\s[^>]*?)src="([^"]+\.(ts|tsx|js|jsx|mjs))"\s*>/g, (tag, attrs, src) => {
|
|
303
306
|
if (isUrl(src)) {
|
|
@@ -306,7 +309,7 @@ async function paseIndexHtml(workDir) {
|
|
|
306
309
|
const relativePath = relative(workDir, join(workDir, src));
|
|
307
310
|
const resolvedPath = relativePath.slice(0, relativePath.lastIndexOf(".")) + ".js";
|
|
308
311
|
entryPoints[relativePath] = resolvedPath;
|
|
309
|
-
return `<script${attrs}
|
|
312
|
+
return `<script${attrs}src="/${resolvedPath}">`;
|
|
310
313
|
});
|
|
311
314
|
return { content, entryPoints };
|
|
312
315
|
}
|
|
@@ -318,7 +321,7 @@ async function createVFile(indexHTML, filename, content, contentType) {
|
|
|
318
321
|
if (ext !== ".css" && ext !== ".js") {
|
|
319
322
|
filename = filename.slice(0, -ext.length) + ".js";
|
|
320
323
|
}
|
|
321
|
-
indexHTML.content = indexHTML.content.replace('"/' + filename + '"', '"/' + filename + "?hash=" +
|
|
324
|
+
indexHTML.content = indexHTML.content.replace('"/' + filename + '"', '"/' + filename + "?hash=" + contentHash.slice(0, 8) + '"');
|
|
322
325
|
}
|
|
323
326
|
return {
|
|
324
327
|
content,
|
package/bin/cli
CHANGED
package/bin/dev.mjs
CHANGED
|
@@ -50,9 +50,9 @@ async function exists(filename) {
|
|
|
50
50
|
// bin/dev.ts
|
|
51
51
|
import { build } from "./build.mjs";
|
|
52
52
|
async function dev(options) {
|
|
53
|
-
const
|
|
54
|
-
const
|
|
55
|
-
const workDir = join(cwd(), options?.
|
|
53
|
+
const runtime = "Deno" in globalThis ? "deno" : "Bun" in globalThis ? "bun" : "node";
|
|
54
|
+
const ac = options?.ac ?? new AbortController();
|
|
55
|
+
const workDir = join(cwd(), options?.appName ?? ".");
|
|
56
56
|
const outdir = join(workDir, options?.outdir ?? "dist");
|
|
57
57
|
const port = options?.port ?? 3e3;
|
|
58
58
|
const devServerPort = 8798;
|
|
@@ -77,8 +77,11 @@ async function dev(options) {
|
|
|
77
77
|
});
|
|
78
78
|
await serve({
|
|
79
79
|
port: devServerPort,
|
|
80
|
+
hostname: "localhost",
|
|
80
81
|
idleTimeout: 32,
|
|
81
82
|
// 32 seconds
|
|
83
|
+
onListen: (_localAddress) => {
|
|
84
|
+
},
|
|
82
85
|
fetch: async (req) => {
|
|
83
86
|
const { pathname } = new URL(req.url);
|
|
84
87
|
if (pathname === "/__dev_vfs.json") {
|
|
@@ -162,30 +165,49 @@ async function dev(options) {
|
|
|
162
165
|
}
|
|
163
166
|
});
|
|
164
167
|
const serverScript = await resolveModule(join(workDir, "server"), [".ts", ".mjs", ".js"]) ?? join(workDir, "node_modules/mono-jsx-dom/server/index.mjs");
|
|
168
|
+
const args = ["--watch", serverScript];
|
|
169
|
+
if (runtime === "node") {
|
|
170
|
+
args.push("--port", port.toString());
|
|
171
|
+
} else {
|
|
172
|
+
args.unshift("--port", port.toString());
|
|
173
|
+
}
|
|
174
|
+
if (runtime === "deno") {
|
|
175
|
+
args.unshift("serve", "-A");
|
|
176
|
+
}
|
|
165
177
|
const serverProcess = spawn(
|
|
166
|
-
|
|
167
|
-
|
|
178
|
+
runtime,
|
|
179
|
+
args,
|
|
168
180
|
{
|
|
169
181
|
cwd: workDir,
|
|
170
182
|
env: { ...env, DEV_SERVER: devServerUrl },
|
|
171
183
|
stdio: "inherit"
|
|
172
184
|
}
|
|
173
185
|
);
|
|
174
|
-
|
|
186
|
+
const onClose = () => ac.abort();
|
|
187
|
+
serverProcess.on("close", onClose);
|
|
188
|
+
ac.signal.addEventListener("abort", () => {
|
|
189
|
+
serverProcess.off("close", onClose);
|
|
190
|
+
serverProcess.kill();
|
|
191
|
+
});
|
|
175
192
|
};
|
|
176
193
|
const onError = (error) => {
|
|
177
194
|
console.error(error);
|
|
178
195
|
ac.abort();
|
|
179
196
|
};
|
|
180
|
-
if (
|
|
197
|
+
if (runtime === "node") {
|
|
181
198
|
const [major, minor] = versions.node.split(".").map(Number);
|
|
182
199
|
if (major < 22 || major === 22 && minor < 18) {
|
|
183
200
|
console.error("Node.js version 22.18.0 or higher is required to use the dev command.");
|
|
184
201
|
exit2(1);
|
|
185
202
|
}
|
|
186
203
|
}
|
|
204
|
+
process.on("SIGINT", () => {
|
|
205
|
+
console.log("\x1B[90mShutting down dev server...\x1B[0m");
|
|
206
|
+
ac.abort();
|
|
207
|
+
exit2(0);
|
|
208
|
+
});
|
|
187
209
|
await build({
|
|
188
|
-
|
|
210
|
+
appName: options?.appName,
|
|
189
211
|
outdir: options?.outdir,
|
|
190
212
|
dev: {
|
|
191
213
|
signal: ac.signal,
|
|
@@ -194,9 +216,23 @@ async function dev(options) {
|
|
|
194
216
|
}).catch(onError);
|
|
195
217
|
}
|
|
196
218
|
async function serve(options) {
|
|
197
|
-
const
|
|
198
|
-
|
|
199
|
-
|
|
219
|
+
const denoServe = globalThis.Deno?.serve;
|
|
220
|
+
const bunServe = globalThis.Bun?.serve;
|
|
221
|
+
if (denoServe) {
|
|
222
|
+
const { fetch, port, signal, hostname, onListen } = options;
|
|
223
|
+
denoServe(
|
|
224
|
+
{
|
|
225
|
+
port,
|
|
226
|
+
signal,
|
|
227
|
+
hostname,
|
|
228
|
+
onListen: onListen ?? ((localAddress) => {
|
|
229
|
+
console.log(`Server is running on http://${hostname ?? "localhost"}:${localAddress.port}`);
|
|
230
|
+
})
|
|
231
|
+
},
|
|
232
|
+
fetch
|
|
233
|
+
);
|
|
234
|
+
} else if (bunServe) {
|
|
235
|
+
const server = bunServe(options);
|
|
200
236
|
options.signal?.addEventListener("abort", () => server.stop());
|
|
201
237
|
} else {
|
|
202
238
|
await import("../server/node-fetch-server.mjs").then((m) => m.serve(options));
|
package/bin/init.mjs
CHANGED
|
@@ -9,11 +9,74 @@ import { argv, exit, stdin, stdout } from "node:process";
|
|
|
9
9
|
import { access, mkdir } from "node:fs/promises";
|
|
10
10
|
import { createInterface } from "node:readline/promises";
|
|
11
11
|
async function input(prompt, placeholder = "") {
|
|
12
|
+
const hint = `\x1B[34m?\x1B[0m ${prompt}:`;
|
|
13
|
+
if (stdin.isTTY && stdout.isTTY) {
|
|
14
|
+
let text = "";
|
|
15
|
+
const render = () => {
|
|
16
|
+
stdout.write(`\r\x1B[2K${hint} `);
|
|
17
|
+
if (text) {
|
|
18
|
+
stdout.write(text);
|
|
19
|
+
} else if (placeholder) {
|
|
20
|
+
stdout.write(`\x1B[90m${placeholder}\x1B[0m`);
|
|
21
|
+
stdout.write(`\x1B[${placeholder.length}D`);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
render();
|
|
25
|
+
const wasRaw = stdin.isRaw;
|
|
26
|
+
stdin.setRawMode(true);
|
|
27
|
+
stdin.resume();
|
|
28
|
+
try {
|
|
29
|
+
text = await new Promise((resolve) => {
|
|
30
|
+
const decoder = new TextDecoder("utf8");
|
|
31
|
+
const onData = (buf) => {
|
|
32
|
+
const chars = typeof buf === "string" ? buf : decoder.decode(buf);
|
|
33
|
+
switch (chars) {
|
|
34
|
+
case "":
|
|
35
|
+
stdout.write("\x1B[999C\n\x1B[90mcancelled\x1B[0m\n");
|
|
36
|
+
exit(130);
|
|
37
|
+
return;
|
|
38
|
+
case "\r":
|
|
39
|
+
case "\n":
|
|
40
|
+
stdin.off("data", onData);
|
|
41
|
+
resolve(text.trim() || placeholder);
|
|
42
|
+
return;
|
|
43
|
+
case "\x7F":
|
|
44
|
+
case "\b":
|
|
45
|
+
text = text.slice(0, -1);
|
|
46
|
+
render();
|
|
47
|
+
return;
|
|
48
|
+
case "":
|
|
49
|
+
text = "";
|
|
50
|
+
render();
|
|
51
|
+
return;
|
|
52
|
+
case " ":
|
|
53
|
+
if (!text && placeholder) {
|
|
54
|
+
text = placeholder;
|
|
55
|
+
render();
|
|
56
|
+
}
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
if (chars.startsWith("\x1B")) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
text += chars;
|
|
63
|
+
render();
|
|
64
|
+
};
|
|
65
|
+
stdin.on("data", onData);
|
|
66
|
+
});
|
|
67
|
+
stdout.write(`\r\x1B[2K${hint} \x1B[32m${text}\x1B[0m
|
|
68
|
+
`);
|
|
69
|
+
return text;
|
|
70
|
+
} finally {
|
|
71
|
+
stdin.setRawMode(wasRaw ?? false);
|
|
72
|
+
stdin.pause();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
12
75
|
const rl = createInterface({ input: stdin, output: stdout });
|
|
13
76
|
try {
|
|
14
|
-
const line = await rl.question(
|
|
77
|
+
const line = await rl.question(hint + (placeholder ? " \x1B[90m" + placeholder + "\x1B[0m" : ""));
|
|
15
78
|
if (stdout.isTTY) {
|
|
16
|
-
stdout.write(`\x1B[1A\r\x1B[34m?\x1B[0m ${prompt}
|
|
79
|
+
stdout.write(`\x1B[1A\r\x1B[34m?\x1B[0m ${prompt} \x1B[32m${line.trim()}\x1B[0m\x1B[K
|
|
17
80
|
`);
|
|
18
81
|
}
|
|
19
82
|
return line.trim() || placeholder;
|
|
@@ -27,12 +90,14 @@ async function confirm(prompt) {
|
|
|
27
90
|
stdout.write(hint);
|
|
28
91
|
const wasRaw = stdin.isRaw;
|
|
29
92
|
stdin.setRawMode(true);
|
|
93
|
+
stdin.resume();
|
|
30
94
|
try {
|
|
31
95
|
const yes = await new Promise((resolve) => {
|
|
32
96
|
stdin.once("data", (buf) => {
|
|
33
97
|
const c = typeof buf === "string" ? buf.charCodeAt(0) : buf[0];
|
|
34
98
|
switch (c) {
|
|
35
99
|
case 3:
|
|
100
|
+
stdout.write("\x1B[999C\n\x1B[90mcancelled\x1B[0m\n");
|
|
36
101
|
exit(130);
|
|
37
102
|
break;
|
|
38
103
|
case 89:
|
|
@@ -54,6 +119,7 @@ async function confirm(prompt) {
|
|
|
54
119
|
return yes;
|
|
55
120
|
} finally {
|
|
56
121
|
stdin.setRawMode(wasRaw ?? false);
|
|
122
|
+
stdin.pause();
|
|
57
123
|
}
|
|
58
124
|
}
|
|
59
125
|
const rl = createInterface({ input: stdin, output: stdout });
|
|
@@ -101,8 +167,8 @@ var template = {
|
|
|
101
167
|
version: "0.0.0",
|
|
102
168
|
private: true,
|
|
103
169
|
scripts: {
|
|
104
|
-
dev: (bun ? "bun --bun" : "") + "
|
|
105
|
-
build: (bun ? "bun --bun" : "") + "
|
|
170
|
+
dev: (bun ? "bun --bun " : "") + "mono-jsx-dom dev",
|
|
171
|
+
build: (bun ? "bun --bun " : "") + "mono-jsx-dom build",
|
|
106
172
|
start: bun ? "bun --bun mono-jsx-dom build && bun dist/server.mjs" : "mono-jsx-dom build --node && node dist/server.mjs"
|
|
107
173
|
}
|
|
108
174
|
},
|
|
@@ -158,18 +224,41 @@ export default {
|
|
|
158
224
|
`
|
|
159
225
|
};
|
|
160
226
|
async function run() {
|
|
161
|
-
const appName = argv2[3] ?? await input("Enter the name of the app
|
|
162
|
-
|
|
163
|
-
}
|
|
164
|
-
async function init(appName) {
|
|
165
|
-
const appDir = join(cwd(), appName);
|
|
166
|
-
if (await exists(appDir) && !await confirm(`Directory ${appName} already exists. Overwrite?`)) {
|
|
227
|
+
const appName = argv2[3] ?? await input("Enter the name of the app", "mono-app");
|
|
228
|
+
const dir = join(cwd(), appName);
|
|
229
|
+
if (await exists(dir) && !await confirm(`Directory ${appName} already exists. Overwrite?`)) {
|
|
167
230
|
return;
|
|
168
231
|
}
|
|
232
|
+
const tailwindCSS = await confirm("Use TailwindCSS for styling?");
|
|
233
|
+
const wrangler = await confirm("Add Cloudflare Workers integration?");
|
|
234
|
+
const npmCmd = bun ? "bun" : "npm";
|
|
235
|
+
await init({
|
|
236
|
+
dir,
|
|
237
|
+
appName,
|
|
238
|
+
tailwindCSS,
|
|
239
|
+
wrangler,
|
|
240
|
+
onInstall: () => {
|
|
241
|
+
console.log("\x1B[90mInstalling dependencies...\x1B[0m");
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
console.log("");
|
|
245
|
+
console.log("\u2728 \x1B[32mSetup completed.\x1B[0m");
|
|
246
|
+
console.log("You can now start or build the app with the following commands:");
|
|
247
|
+
console.log("");
|
|
248
|
+
console.log(`cd ${appName}`);
|
|
249
|
+
console.log(`${npmCmd} dev${bun ? " " : ""} \x1B[90m# start the app in development mode.\x1B[0m`);
|
|
250
|
+
if (wrangler) {
|
|
251
|
+
console.log(`${npmCmd}${bun ? " run" : ""} deploy \x1B[90m# deploy the app to Cloudflare Workers.\x1B[0m`);
|
|
252
|
+
} else {
|
|
253
|
+
console.log(`${npmCmd}${bun ? " run" : ""} build \x1B[90m# build the app for production.\x1B[0m`);
|
|
254
|
+
console.log(`${npmCmd} start${bun ? " " : ""} \x1B[90m# build and start the app in production mode.\x1B[0m`);
|
|
255
|
+
}
|
|
256
|
+
console.log("");
|
|
257
|
+
}
|
|
258
|
+
async function init(options) {
|
|
259
|
+
const { dir, appName, tailwindCSS, wrangler } = options;
|
|
169
260
|
const scaffold = { ...template };
|
|
170
|
-
|
|
171
|
-
const withWrangler = await confirm("Add Cloudflare Workers integration?");
|
|
172
|
-
if (withWrangler) {
|
|
261
|
+
if (wrangler) {
|
|
173
262
|
scaffold["wrangler.jsonc"] = JSON.stringify(
|
|
174
263
|
{
|
|
175
264
|
$schema: "./node_modules/wrangler/config-schema.json",
|
|
@@ -188,17 +277,17 @@ async function init(appName) {
|
|
|
188
277
|
2
|
|
189
278
|
);
|
|
190
279
|
}
|
|
191
|
-
if (!
|
|
280
|
+
if (!tailwindCSS) {
|
|
192
281
|
scaffold["app/style.css"] = "/* app styles */\n";
|
|
193
282
|
}
|
|
194
|
-
await ensureDir(
|
|
283
|
+
await ensureDir(dir);
|
|
195
284
|
await Promise.all(
|
|
196
285
|
Object.entries(scaffold).map(async ([filename, content]) => {
|
|
197
|
-
const filepath = join(
|
|
286
|
+
const filepath = join(dir, filename);
|
|
198
287
|
if (filename === "package.json") {
|
|
199
288
|
const pkg = JSON.parse(content);
|
|
200
289
|
pkg.name = appName;
|
|
201
|
-
if (
|
|
290
|
+
if (wrangler) {
|
|
202
291
|
pkg.scripts.dev = "wrangler dev";
|
|
203
292
|
pkg.scripts.deploy = "wrangler deploy";
|
|
204
293
|
delete pkg.scripts.build;
|
|
@@ -214,7 +303,7 @@ async function init(appName) {
|
|
|
214
303
|
);
|
|
215
304
|
let tsConfig = /* @__PURE__ */ Object.create(null);
|
|
216
305
|
try {
|
|
217
|
-
const data = await readFile(join(
|
|
306
|
+
const data = await readFile(join(dir, "tsconfig.json"), "utf8");
|
|
218
307
|
tsConfig = JSON.parse(data);
|
|
219
308
|
} catch {
|
|
220
309
|
}
|
|
@@ -226,44 +315,40 @@ async function init(appName) {
|
|
|
226
315
|
compilerOptions.noEmit ??= true;
|
|
227
316
|
compilerOptions.jsx = "react-jsx";
|
|
228
317
|
compilerOptions.jsxImportSource = "mono-jsx-dom";
|
|
229
|
-
await writeFile(join(
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
console.log("");
|
|
234
|
-
console.log("\u2728 \x1B[32mSetup completed.\x1B[0m");
|
|
235
|
-
console.log("You can now start or build the app with the following commands:");
|
|
236
|
-
console.log("");
|
|
237
|
-
console.log(`cd ${appName}`);
|
|
238
|
-
console.log(`${cmd} dev${isBun ? " " : ""} \x1B[90m# start the app in development mode.\x1B[0m`);
|
|
239
|
-
if (withWrangler) {
|
|
240
|
-
console.log(`${cmd}${isBun ? " run" : ""} deploy \x1B[90m# deploy the app to Cloudflare Workers.\x1B[0m`);
|
|
241
|
-
} else {
|
|
242
|
-
console.log(`${cmd}${isBun ? " run" : ""} build \x1B[90m# build the app for production.\x1B[0m`);
|
|
243
|
-
console.log(`${cmd} start${isBun ? " " : ""} \x1B[90m# build and start the app in production mode.\x1B[0m`);
|
|
244
|
-
}
|
|
245
|
-
console.log("");
|
|
318
|
+
await writeFile(join(dir, "tsconfig.json"), JSON.stringify(tsConfig, null, 2));
|
|
319
|
+
const depsOptions = { tailwindCSS, wrangler };
|
|
320
|
+
options.onInstall?.(depsOptions);
|
|
321
|
+
installDependencies(dir, depsOptions);
|
|
246
322
|
}
|
|
247
|
-
function
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
}
|
|
252
|
-
spawnSync(cmd, ["add", "mono-jsx-dom"], { cwd: cwd2 });
|
|
323
|
+
function installDependencies(cwd2, options) {
|
|
324
|
+
const { tailwindCSS, wrangler, extraDependencies, extraDevDependencies } = options;
|
|
325
|
+
const npmCmd = bun ? "bun" : "npm";
|
|
326
|
+
const deps = ["mono-jsx-dom"];
|
|
253
327
|
const devDeps = ["esbuild"];
|
|
254
|
-
if (
|
|
328
|
+
if (tailwindCSS) {
|
|
255
329
|
devDeps.push("tailwindcss", "oxide-wasm");
|
|
256
330
|
}
|
|
257
|
-
if (
|
|
331
|
+
if (wrangler) {
|
|
258
332
|
devDeps.push("wrangler");
|
|
259
333
|
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
334
|
+
if (extraDependencies) {
|
|
335
|
+
deps.push(...extraDependencies);
|
|
336
|
+
}
|
|
337
|
+
if (extraDevDependencies) {
|
|
338
|
+
devDeps.push(...extraDevDependencies);
|
|
339
|
+
}
|
|
340
|
+
spawnSync(npmCmd, ["add", ...deps], { cwd: cwd2 });
|
|
341
|
+
spawnSync(npmCmd, ["add", "-D", ...devDeps], { cwd: cwd2 });
|
|
342
|
+
if (wrangler) {
|
|
343
|
+
if (npmCmd === "bun") {
|
|
344
|
+
spawnSync(npmCmd, ["--bun", "wrangler", "types"], { cwd: cwd2 });
|
|
345
|
+
} else {
|
|
346
|
+
spawnSync(npmCmd, ["wrangler", "types"], { cwd: cwd2 });
|
|
347
|
+
}
|
|
263
348
|
}
|
|
264
|
-
return cmd;
|
|
265
349
|
}
|
|
266
350
|
export {
|
|
267
351
|
init,
|
|
352
|
+
installDependencies,
|
|
268
353
|
run
|
|
269
354
|
};
|
package/package.json
CHANGED
|
@@ -115,12 +115,16 @@ async function sendResponse(res, response) {
|
|
|
115
115
|
res.end();
|
|
116
116
|
}
|
|
117
117
|
function serve(options) {
|
|
118
|
-
const port =
|
|
119
|
-
const server = createServer(createRequestListener(
|
|
118
|
+
const { port = getDefaultPort(), hostname, signal, fetch, onListen } = options;
|
|
119
|
+
const server = createServer(createRequestListener(fetch, options));
|
|
120
120
|
server.listen(port, options?.hostname, () => {
|
|
121
|
-
|
|
121
|
+
if (onListen) {
|
|
122
|
+
onListen({ port });
|
|
123
|
+
} else {
|
|
124
|
+
console.log(`Server is running on http://${hostname ?? "localhost"}:${port}`);
|
|
125
|
+
}
|
|
122
126
|
});
|
|
123
|
-
|
|
127
|
+
signal?.addEventListener("abort", () => {
|
|
124
128
|
server.close();
|
|
125
129
|
});
|
|
126
130
|
return new Promise((resolve, reject) => {
|