bun-dev-server 0.3.0 → 0.4.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/bunClientHmr.d.ts +3 -0
- package/dist/bunHmrPlugin.d.ts +8 -0
- package/dist/bunManifest.d.ts +2 -0
- package/{bunServeConfig.ts → dist/bunServeConfig.d.ts} +26 -27
- package/dist/bunTSWatcher.d.ts +2 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1242 -0
- package/dist/server.d.ts +2 -0
- package/dist/tsChecker.d.ts +2 -0
- package/package.json +11 -3
- package/.vscode/launch.json +0 -36
- package/.vscode/settings.json +0 -15
- package/@types/fileTypes.d.ts +0 -5
- package/bunClientHmr.ts +0 -51
- package/bunHmrPlugin.ts +0 -38
- package/bunManifest.ts +0 -18
- package/bunTSWatcher.ts +0 -74
- package/index.ts +0 -247
- package/indexHTMLTemplate.ejs +0 -15
- package/serveOutputTemplate.ejs +0 -16
- package/test/README.md +0 -15
- package/test/bun.lockb +0 -0
- package/test/bunrun.ts +0 -18
- package/test/package.json +0 -16
- package/test/src/@types/filetypes.d.ts +0 -4
- package/test/src/app.ts +0 -10
- package/test/src/assets/something.svg +0 -6
- package/test/src/services/someservice.ts +0 -7
- package/test/src/something.ts +0 -3
- package/test/tsconfig.json +0 -28
- package/tsconfig.json +0 -28
package/dist/server.d.ts
ADDED
package/package.json
CHANGED
|
@@ -13,7 +13,13 @@
|
|
|
13
13
|
"reload",
|
|
14
14
|
"hot"
|
|
15
15
|
],
|
|
16
|
-
"
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"exports": {
|
|
20
|
+
".": "./dist/index.js"
|
|
21
|
+
},
|
|
22
|
+
"version": "0.4.0",
|
|
17
23
|
"module": "index.ts",
|
|
18
24
|
"type": "module",
|
|
19
25
|
"license": "MIT",
|
|
@@ -21,13 +27,15 @@
|
|
|
21
27
|
"serve": "bun --hot ./serve.ts"
|
|
22
28
|
},
|
|
23
29
|
"devDependencies": {
|
|
24
|
-
"@types/bun": "latest"
|
|
30
|
+
"@types/bun": "latest",
|
|
31
|
+
"bun": "^1.1.36"
|
|
25
32
|
},
|
|
26
33
|
"peerDependencies": {
|
|
27
34
|
"typescript": "^5.7.2"
|
|
28
35
|
},
|
|
29
36
|
"dependencies": {
|
|
37
|
+
"@types/ejs": "^3.1.5",
|
|
30
38
|
"ejs": "^3.1.10",
|
|
31
|
-
"
|
|
39
|
+
"picocolors": "^1.1.1"
|
|
32
40
|
}
|
|
33
41
|
}
|
package/.vscode/launch.json
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
// Use IntelliSense to learn about possible attributes.
|
|
3
|
-
// Hover to view descriptions of existing attributes.
|
|
4
|
-
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
|
5
|
-
"version": "0.2.0",
|
|
6
|
-
"configurations": [
|
|
7
|
-
{
|
|
8
|
-
"type": "bun",
|
|
9
|
-
"internalConsoleOptions": "neverOpen",
|
|
10
|
-
"request": "launch",
|
|
11
|
-
"name": "Debug File",
|
|
12
|
-
"program": "${file}",
|
|
13
|
-
"cwd": "${workspaceFolder}",
|
|
14
|
-
"stopOnEntry": false,
|
|
15
|
-
"watchMode": false
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
"type": "bun",
|
|
19
|
-
"internalConsoleOptions": "neverOpen",
|
|
20
|
-
"request": "launch",
|
|
21
|
-
"name": "Run File",
|
|
22
|
-
"program": "${file}",
|
|
23
|
-
"cwd": "${workspaceFolder}",
|
|
24
|
-
"noDebug": true,
|
|
25
|
-
"watchMode": false
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
"type": "bun",
|
|
29
|
-
"internalConsoleOptions": "neverOpen",
|
|
30
|
-
"request": "attach",
|
|
31
|
-
"name": "Attach Bun",
|
|
32
|
-
"url": "ws://localhost:6499/",
|
|
33
|
-
"stopOnEntry": false
|
|
34
|
-
}
|
|
35
|
-
]
|
|
36
|
-
}
|
package/.vscode/settings.json
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"[html]": {
|
|
3
|
-
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
|
4
|
-
},
|
|
5
|
-
"[typescript]": {
|
|
6
|
-
"editor.defaultFormatter": "vscode.typescript-language-features"
|
|
7
|
-
},
|
|
8
|
-
"editor.defaultFormatter": null,
|
|
9
|
-
"html.format.enable": true,
|
|
10
|
-
"js-beautify.break_chained_methods": true,
|
|
11
|
-
"js-beautify.indent_inner_html": true,
|
|
12
|
-
"js-beautify.brace_style": "expand",
|
|
13
|
-
"typescript.tsdk": "node_modules\\typescript\\lib"
|
|
14
|
-
|
|
15
|
-
}
|
package/@types/fileTypes.d.ts
DELETED
package/bunClientHmr.ts
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { type BunDevServerSocketConfig } from "./bunServeConfig";
|
|
2
|
-
|
|
3
|
-
function hotReload() {
|
|
4
|
-
if ((window as any).BUN_HMR_INITED) {
|
|
5
|
-
return;
|
|
6
|
-
}
|
|
7
|
-
(window as any).BUN_HMR_INITED = true;
|
|
8
|
-
const hmrSock = new WebSocket("[REPLACE_ENDPOINT]");
|
|
9
|
-
hmrSock.addEventListener("error", (err) => {
|
|
10
|
-
console.error("HMR ERROR", err);
|
|
11
|
-
})
|
|
12
|
-
hmrSock.addEventListener("message", (msg) => {
|
|
13
|
-
let parsed = msg.data;
|
|
14
|
-
try {
|
|
15
|
-
parsed = JSON.parse(msg.data);
|
|
16
|
-
} catch (e) { }
|
|
17
|
-
if (parsed?.type === "message") {
|
|
18
|
-
console.log(parsed.message);
|
|
19
|
-
return;
|
|
20
|
-
}
|
|
21
|
-
if (parsed?.type === "output") {
|
|
22
|
-
console.table(parsed.message);
|
|
23
|
-
return;
|
|
24
|
-
}
|
|
25
|
-
if (parsed?.type === "reload") {
|
|
26
|
-
window.location.reload();
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
if (parsed?.type === "error") {
|
|
30
|
-
console.error(parsed.message);
|
|
31
|
-
let newDiv = window.document.getElementById("bun-hmr-error")
|
|
32
|
-
const divExists = !!newDiv;
|
|
33
|
-
if (!newDiv) {
|
|
34
|
-
newDiv = window.document.createElement("div");
|
|
35
|
-
}
|
|
36
|
-
newDiv.id = "bun-hmr-error";
|
|
37
|
-
newDiv.innerText += parsed.message;
|
|
38
|
-
if (!divExists) {
|
|
39
|
-
|
|
40
|
-
window.document.body.appendChild(newDiv);
|
|
41
|
-
}
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export function bunHotReload(bunServerConfig: BunDevServerSocketConfig) {
|
|
48
|
-
const endPath = bunServerConfig.websocketPath.startsWith("/") ? bunServerConfig.websocketPath : `/${bunServerConfig.websocketPath}`;
|
|
49
|
-
const path = `${(bunServerConfig.tls ? "wss" : "ws")}://localhost:${bunServerConfig.port}${endPath}`;
|
|
50
|
-
return hotReload.toString().replace("[REPLACE_ENDPOINT]", path);
|
|
51
|
-
}
|
package/bunHmrPlugin.ts
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import type { BunPlugin, Loader } from "bun";
|
|
2
|
-
import { bunHotReload } from "./bunClientHmr";
|
|
3
|
-
import { readFile } from "fs/promises";
|
|
4
|
-
import { type BunDevServerSocketConfig } from "./bunServeConfig";
|
|
5
|
-
export function getBunHMRPlugin(config: BunDevServerSocketConfig) {
|
|
6
|
-
const bunHMRPlugin: BunPlugin = {
|
|
7
|
-
name: "hmr",
|
|
8
|
-
target: "browser",
|
|
9
|
-
setup(build) {
|
|
10
|
-
let hmrAdded = false;
|
|
11
|
-
build.onLoad({ filter: /\.m?tsx?/ }, async (args) => {
|
|
12
|
-
const contents = await readFile(args.path, { encoding: "utf-8" });
|
|
13
|
-
const isTSx = /\.m?tsx$/.test(args.path);
|
|
14
|
-
const isJSx = /\.m?jsx$/.test(args.path);
|
|
15
|
-
const isJS = /\.m?js$/.test(args.path);
|
|
16
|
-
const isTS = /\.m?ts$/.test(args.path);
|
|
17
|
-
const loader: Loader = isTSx ? "tsx" : isJSx ? "jsx" : isTS ? "ts" : isJS ? "js" : "text";
|
|
18
|
-
if (!hmrAdded) {
|
|
19
|
-
hmrAdded = true;
|
|
20
|
-
return { contents: `import "bun-hot-reload"\n` + contents, loader };
|
|
21
|
-
}
|
|
22
|
-
return { contents, loader };
|
|
23
|
-
});
|
|
24
|
-
build.onLoad({ filter: /./, namespace: "bun-hot-reload" }, async (args) => {
|
|
25
|
-
|
|
26
|
-
return { contents: `(${bunHotReload(config)})()\n`, loader: "ts" };
|
|
27
|
-
});
|
|
28
|
-
build.onResolve({ filter: /^bun-hot-reload$/ }, (args) => {
|
|
29
|
-
return { path: args.path, namespace: "bun-hot-reload" };
|
|
30
|
-
})
|
|
31
|
-
},
|
|
32
|
-
}
|
|
33
|
-
return bunHMRPlugin;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export function getBunHMRFooter(config: BunDevServerSocketConfig) {
|
|
37
|
-
return `(${bunHotReload(config)})()`;
|
|
38
|
-
}
|
package/bunManifest.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { type BuildOutput, write, pathToFileURL } from "bun";
|
|
2
|
-
export function writeManifest(output: BuildOutput, outdir: string, withHash = false, manifestName = "bunmanifest.txt") {
|
|
3
|
-
const entryPoints = output.outputs.filter(o => o.kind === "entry-point");
|
|
4
|
-
const epTable: string[] = [];
|
|
5
|
-
for (const ep of entryPoints) {
|
|
6
|
-
const basePathUrl = pathToFileURL(outdir);
|
|
7
|
-
const epUrl = pathToFileURL(ep.path);
|
|
8
|
-
const relativePath = epUrl.href.replace(`${basePathUrl.href}/`, "");
|
|
9
|
-
// const nameNoJs = relativePath.replace(".js", "");
|
|
10
|
-
const hashedImport = `${relativePath}${withHash ? `?${ep.hash}` : ``}`;
|
|
11
|
-
epTable.push(hashedImport);
|
|
12
|
-
}
|
|
13
|
-
const outObj = { js: epTable };
|
|
14
|
-
// for (const element of epTable) {
|
|
15
|
-
// Object.assign(outObj, { [element.name]: { js: [`${element.path}`] } });
|
|
16
|
-
// }
|
|
17
|
-
write(`${outdir}/${manifestName}`, JSON.stringify(outObj));
|
|
18
|
-
}
|
package/bunTSWatcher.ts
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import { $, type Server, type Subprocess, resolve } from "bun";
|
|
2
|
-
export async function startTSWatcher(server: Server, watchDir: URL) {
|
|
3
|
-
let dstcwd = process.cwd();
|
|
4
|
-
if (watchDir) {
|
|
5
|
-
dstcwd = process.platform === "win32" ? watchDir.pathname.substring(1) : watchDir.pathname;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
console.log("Starting TypeScript watcher in", dstcwd);
|
|
9
|
-
// var tscResolved = await resolve("tsc", import.meta.dir);
|
|
10
|
-
//const tsc = await $`bun run ${tscResolved} --noEmit --watch ${dstcwd}/*.ts`.quiet().arrayBuffer();
|
|
11
|
-
let tsc: Subprocess | undefined;
|
|
12
|
-
try {
|
|
13
|
-
tsc = Bun.spawn(["tsc", "--watch", "--project", `${process.cwd()}/tsconfig.json`], { stdout: "pipe", stderr: "pipe", cwd: dstcwd });
|
|
14
|
-
} catch (e) {
|
|
15
|
-
console.error("TSC not found have you installed it globally?");
|
|
16
|
-
return;
|
|
17
|
-
}
|
|
18
|
-
for await (const chunk of tsc.stdout as any) {
|
|
19
|
-
const strVal = new TextDecoder().decode(chunk);
|
|
20
|
-
const isError = /Found [1-9]\d* errors?\./.test(strVal);
|
|
21
|
-
const isNoError = /Found 0 errors?\./.test(strVal);
|
|
22
|
-
const isErrorLine = /error TS/.test(strVal);
|
|
23
|
-
let msgType = "message";
|
|
24
|
-
if (isError || isErrorLine) {
|
|
25
|
-
console.error(strVal);
|
|
26
|
-
msgType = "error";
|
|
27
|
-
}
|
|
28
|
-
else if (isNoError) {
|
|
29
|
-
console.log("\x1b[32m", strVal, "\x1b[0m");
|
|
30
|
-
}
|
|
31
|
-
else {
|
|
32
|
-
console.log(strVal);
|
|
33
|
-
}
|
|
34
|
-
server.publish("message", JSON.stringify({ type: msgType, message: strVal }));
|
|
35
|
-
if (isNoError) {
|
|
36
|
-
server.publish("message", JSON.stringify({ type: "reload", message: "" }));
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
// if (!Bun.stdout.readable.locked) {
|
|
40
|
-
// const tscErrorReader = Bun.stdout.readable.getReader();
|
|
41
|
-
|
|
42
|
-
// // tsc.stdout.pipeThrough(new TextDecoderStream());
|
|
43
|
-
// tscErrorReader.read().then(async function processResult(stdoutresult) {
|
|
44
|
-
// if (stdoutresult.value) {
|
|
45
|
-
// const strVal = Buffer.from(stdoutresult.value).toString();
|
|
46
|
-
// const isError = /Found [1-9]\d* errors?\./.test(strVal);
|
|
47
|
-
// const isNoError = /Found 0 errors?\./.test(strVal);
|
|
48
|
-
// const isErrorLine = /error TS/.test(strVal);
|
|
49
|
-
// let msgType = "message";
|
|
50
|
-
// if (isError || isErrorLine) {
|
|
51
|
-
// console.error(new Error(strVal));
|
|
52
|
-
// msgType = "error";
|
|
53
|
-
// //await Bun.write(Bun.stderr, stdoutresult.value);
|
|
54
|
-
// } else {
|
|
55
|
-
// console.log(strVal);
|
|
56
|
-
// }
|
|
57
|
-
// server.publish("message", JSON.stringify({ type: msgType, message: strVal }));
|
|
58
|
-
// if(isNoError) {
|
|
59
|
-
// server.publish("message", JSON.stringify({ type: "reload", message: "" }));
|
|
60
|
-
// }
|
|
61
|
-
// // const resVal = result.value;
|
|
62
|
-
// // const strVal = Buffer.from(result.value).toString();
|
|
63
|
-
// // await Bun.write(Bun.stdout, stdoutresult.value);
|
|
64
|
-
// // const result = strVal.indexOf("error") !== -1 ? new Error(strVal) : strVal;
|
|
65
|
-
// // console.log(Bun.inspect(result, {colors: true}));
|
|
66
|
-
// // Bun.stdout.writer().write();
|
|
67
|
-
// }
|
|
68
|
-
// if (stdoutresult.done) {
|
|
69
|
-
// return;
|
|
70
|
-
// }
|
|
71
|
-
// tscErrorReader.read().then(processResult);
|
|
72
|
-
// });
|
|
73
|
-
// }
|
|
74
|
-
}
|
package/index.ts
DELETED
|
@@ -1,247 +0,0 @@
|
|
|
1
|
-
/// <reference path="./@types/fileTypes.d.ts" />
|
|
2
|
-
import { render } from "ejs";
|
|
3
|
-
import Bun, { $, ShellError } from "bun";
|
|
4
|
-
import serveTemplate from "./serveOutputTemplate.ejs" with { type: "text" };
|
|
5
|
-
import indexTemplate from "./indexHTMLTemplate.ejs" with { type: "text" };
|
|
6
|
-
import { watch, readdir, exists, readFile } from "fs/promises";
|
|
7
|
-
import { type FileChangeInfo } from "fs/promises";
|
|
8
|
-
import { startTSWatcher } from "./bunTSWatcher";
|
|
9
|
-
import { getBunHMRFooter } from "./bunHmrPlugin";
|
|
10
|
-
import { type BunDevServerConfig } from "./bunServeConfig";
|
|
11
|
-
import { writeManifest } from "./bunManifest";
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
export async function startBunDevServer(serverConfig: BunDevServerConfig) {
|
|
16
|
-
const defaultConfig = {
|
|
17
|
-
port: 3000,
|
|
18
|
-
websocketPath: "/hmr-ws",
|
|
19
|
-
serveOutputEjs: serveTemplate,
|
|
20
|
-
serveOutputHtml: indexTemplate
|
|
21
|
-
}
|
|
22
|
-
const finalConfig = { ...defaultConfig, ...serverConfig };
|
|
23
|
-
const serveDestination = finalConfig.buildConfig.outdir ?? finalConfig.servePath ?? "dist";
|
|
24
|
-
const bunDestinationPath = Bun.pathToFileURL(serveDestination);
|
|
25
|
-
const dst = process.platform === "win32" ? bunDestinationPath.pathname.substring(1) : bunDestinationPath.pathname;
|
|
26
|
-
try {
|
|
27
|
-
await readdir(dst)
|
|
28
|
-
} catch (e) {
|
|
29
|
-
if ((e as ErrnoException).code === "ENOENT") {
|
|
30
|
-
console.log("Directory not found, creating it...");
|
|
31
|
-
await $`mkdir ${dst}`;
|
|
32
|
-
} else {
|
|
33
|
-
throw e;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
const buncfg = { port: finalConfig.port, tls: finalConfig.tls, websocketPath: finalConfig.websocketPath };
|
|
37
|
-
const buildCfg: Bun.BuildConfig = {
|
|
38
|
-
...serverConfig.buildConfig,
|
|
39
|
-
outdir: dst,
|
|
40
|
-
plugins: [...(serverConfig.buildConfig.plugins ?? [])],
|
|
41
|
-
footer: getBunHMRFooter(buncfg),
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if (serverConfig.cleanServePath) {
|
|
45
|
-
await cleanDirectory(dst);
|
|
46
|
-
}
|
|
47
|
-
console.log("Starting Bun Dev Server on port", finalConfig.port);
|
|
48
|
-
const bunServer = Bun.serve({
|
|
49
|
-
port: finalConfig.port,
|
|
50
|
-
development: true,
|
|
51
|
-
tls: finalConfig.tls,
|
|
52
|
-
async fetch(req, server) {
|
|
53
|
-
if (req.method === "OPTIONS") {
|
|
54
|
-
const response = new Response("", { status: 200 });
|
|
55
|
-
augumentHeaders(req, response);
|
|
56
|
-
return response;
|
|
57
|
-
}
|
|
58
|
-
if (req.url.toLowerCase().endsWith("/favicon.ico")) {
|
|
59
|
-
const response = new Response("", { status: 404 });
|
|
60
|
-
augumentHeaders(req, response);
|
|
61
|
-
return response;
|
|
62
|
-
}
|
|
63
|
-
if (req.url.toLowerCase().endsWith(finalConfig.websocketPath)) {
|
|
64
|
-
if (server.upgrade(req)) {
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
const url = new URL(req.url);
|
|
69
|
-
const requestPath = url.pathname;
|
|
70
|
-
const objThere = await exists(dst + requestPath);
|
|
71
|
-
let isDirectory = false;
|
|
72
|
-
if (objThere) {
|
|
73
|
-
try {
|
|
74
|
-
await readFile(dst + requestPath);
|
|
75
|
-
} catch (e) {
|
|
76
|
-
if ((e as ErrnoException).code === "EISDIR") {
|
|
77
|
-
isDirectory = true;
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
throw e;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
} else {
|
|
84
|
-
const response = new Response("", { status: 404 });
|
|
85
|
-
augumentHeaders(req, response);
|
|
86
|
-
return response;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
if (!isDirectory) {
|
|
90
|
-
try {
|
|
91
|
-
const fl = Bun.file(dst + requestPath);
|
|
92
|
-
const response = new Response(fl);
|
|
93
|
-
augumentHeaders(req, response);
|
|
94
|
-
return response;
|
|
95
|
-
}
|
|
96
|
-
catch (e) {
|
|
97
|
-
if ((e as ErrnoException).code === "ENOENT") {
|
|
98
|
-
const response = new Response("", { status: 404 });
|
|
99
|
-
augumentHeaders(req, response);
|
|
100
|
-
return response;
|
|
101
|
-
}
|
|
102
|
-
else {
|
|
103
|
-
throw e;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
try {
|
|
108
|
-
const allEntries = await readdir(dst + requestPath, {
|
|
109
|
-
withFileTypes: true,
|
|
110
|
-
});
|
|
111
|
-
const dirs = allEntries
|
|
112
|
-
.filter((entry) => entry.isDirectory())
|
|
113
|
-
.map((entry) => {
|
|
114
|
-
return {
|
|
115
|
-
requestPath: requestPath === "/" ? "" : requestPath,
|
|
116
|
-
name: entry.name,
|
|
117
|
-
};
|
|
118
|
-
});
|
|
119
|
-
const files = allEntries
|
|
120
|
-
.filter((entry) => entry.isFile())
|
|
121
|
-
.map((entry) => {
|
|
122
|
-
return {
|
|
123
|
-
requestPath: requestPath === "/" ? "" : requestPath,
|
|
124
|
-
name: entry.name,
|
|
125
|
-
};
|
|
126
|
-
});
|
|
127
|
-
const rnd = render(finalConfig.serveOutputEjs, { dirs, files });
|
|
128
|
-
const response = new Response(rnd, { headers: { "Content-Type": "text/html" } });
|
|
129
|
-
augumentHeaders(req, response);
|
|
130
|
-
return response;
|
|
131
|
-
} catch {
|
|
132
|
-
const response = new Response("Not Found", { status: 404 });
|
|
133
|
-
augumentHeaders(req, response);
|
|
134
|
-
return response;
|
|
135
|
-
}
|
|
136
|
-
},
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
websocket: {
|
|
140
|
-
open(ws) {
|
|
141
|
-
ws.subscribe("message");
|
|
142
|
-
},
|
|
143
|
-
message(ws, message) {
|
|
144
|
-
},
|
|
145
|
-
sendPings: true
|
|
146
|
-
}
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
const output = await Bun.build(buildCfg);
|
|
151
|
-
publishOutputLogs(output, { filename: "Initial", eventType: "change" });
|
|
152
|
-
publishIndexHTML(output, { filename: "Initial", eventType: "change" });
|
|
153
|
-
if (finalConfig.writeManifest) {
|
|
154
|
-
writeManifest(output, dst, finalConfig.manifestWithHash, finalConfig.manifestName);
|
|
155
|
-
}
|
|
156
|
-
// $`tsc --watch`.then((tsc) => {
|
|
157
|
-
// console.log("ASDASD");
|
|
158
|
-
// });
|
|
159
|
-
|
|
160
|
-
if (finalConfig.enableTypeScriptWatch) {
|
|
161
|
-
if (!finalConfig.watchDir) {
|
|
162
|
-
throw new Error("watchDir must be set to enable TypeScript watch");
|
|
163
|
-
}
|
|
164
|
-
const watchDir = Bun.pathToFileURL(finalConfig.watchDir);
|
|
165
|
-
startTSWatcher(bunServer, watchDir);
|
|
166
|
-
}
|
|
167
|
-
const watcher = watch("./src", { recursive: true });
|
|
168
|
-
for await (const event of watcher) {
|
|
169
|
-
if (finalConfig.cleanServePath) {
|
|
170
|
-
await cleanDirectory(dst);
|
|
171
|
-
}
|
|
172
|
-
const output = await Bun.build(buildCfg);
|
|
173
|
-
publishOutputLogs(output, event);
|
|
174
|
-
publishIndexHTML(output, event);
|
|
175
|
-
if (finalConfig.writeManifest) {
|
|
176
|
-
writeManifest(output, dst, finalConfig.manifestWithHash, finalConfig.manifestName);
|
|
177
|
-
}
|
|
178
|
-
if (finalConfig.reloadOnChange) {
|
|
179
|
-
bunServer.publish("message", JSON.stringify({ type: "reload" }));
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
function publishOutputLogs(output: Bun.BuildOutput, event: FileChangeInfo<string>) {
|
|
185
|
-
output.logs.forEach(console.log);
|
|
186
|
-
bunServer.publish("message", JSON.stringify({ type: "message", message: `[Bun HMR] ${event.filename} ${event.eventType}` }));
|
|
187
|
-
const outTable = output.outputs.filter(o => o.kind !== "sourcemap").map(o => {
|
|
188
|
-
const a = Bun.pathToFileURL(o.path);
|
|
189
|
-
const fileName = a.href.substring(a.href.lastIndexOf("/") + 1);
|
|
190
|
-
return {
|
|
191
|
-
name: fileName,
|
|
192
|
-
path: o.path,
|
|
193
|
-
size: convertBytes(o.size)
|
|
194
|
-
};
|
|
195
|
-
});
|
|
196
|
-
console.table(outTable);
|
|
197
|
-
bunServer.publish("message", JSON.stringify({ type: "output", message: outTable }));
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
function publishIndexHTML(output: Bun.BuildOutput, event: FileChangeInfo<string>) {
|
|
201
|
-
const eps = output.outputs.filter(o => o.kind === "entry-point");
|
|
202
|
-
const hashedImports: string[] = [];
|
|
203
|
-
for (const ep of eps) {
|
|
204
|
-
const basePathUrl = Bun.pathToFileURL(dst);
|
|
205
|
-
const epUrl = Bun.pathToFileURL(ep.path);
|
|
206
|
-
const hashedImport = `${epUrl.href.replace(basePathUrl.href, "")}?${ep.hash}`;
|
|
207
|
-
hashedImports.push(hashedImport);
|
|
208
|
-
}
|
|
209
|
-
Bun.write(dst + "/index.html", render(finalConfig.serveOutputHtml, { hashedImports }));
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
function augumentHeaders(request: Request, response: Response) {
|
|
215
|
-
response.headers.set("Access-Control-Allow-Origin", request.headers.get("origin") ?? "*");
|
|
216
|
-
response.headers.set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
|
|
217
|
-
response.headers.set("Access-Control-Allow-Credentials", "true");
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
async function cleanDirectory(dst: string) {
|
|
221
|
-
const { stderr, exitCode } = await $`rm -rf ${dst}/*`.nothrow();
|
|
222
|
-
if (exitCode !== 0) {
|
|
223
|
-
if (stderr.indexOf("no matches found") > -1) {
|
|
224
|
-
console.log("Directory is empty");
|
|
225
|
-
} else {
|
|
226
|
-
throw stderr;
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
function convertBytes(bytes: number) {
|
|
232
|
-
const sizes = ["Bytes", "KB", "MB", "GB", "TB"]
|
|
233
|
-
|
|
234
|
-
if (bytes == 0) {
|
|
235
|
-
return "n/a"
|
|
236
|
-
}
|
|
237
|
-
const floored = Math.floor(Math.log(bytes) / Math.log(1024));
|
|
238
|
-
// console.log(floored);
|
|
239
|
-
// console.log(parseInt(`${floored}`));
|
|
240
|
-
const i = floored;
|
|
241
|
-
|
|
242
|
-
if (i == 0) {
|
|
243
|
-
return bytes + " " + sizes[i]
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
return (bytes / Math.pow(1024, i)).toFixed(1) + " " + sizes[i]
|
|
247
|
-
}
|
package/indexHTMLTemplate.ejs
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
-
<title>Bun HTML File</title>
|
|
7
|
-
<% for (const hashedJs of hashedImports) { %>
|
|
8
|
-
<script type="module" src="<%= hashedJs %>"></script>
|
|
9
|
-
<% } %>
|
|
10
|
-
</head>
|
|
11
|
-
|
|
12
|
-
<body>
|
|
13
|
-
<div id="app"></div>
|
|
14
|
-
</body>
|
|
15
|
-
</html>
|
package/serveOutputTemplate.ejs
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
|
|
4
|
-
<head>
|
|
5
|
-
<meta charset="UTF-8" />
|
|
6
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
-
<title>Document</title>
|
|
8
|
-
</head>
|
|
9
|
-
|
|
10
|
-
<body>
|
|
11
|
-
<a href="../">..</a>
|
|
12
|
-
<% dirs.forEach(element => { %> <br /><a href=".<%= element.requestPath %>/<%= element.name %>"><%= element.name %></a> <% }) %>
|
|
13
|
-
<% files.forEach(element => { %> <br /><a href=".<%= element.requestPath %>/<%= element.name %>"><%= element.name %></a> <% }) %>
|
|
14
|
-
</body>
|
|
15
|
-
|
|
16
|
-
</html>
|
package/test/README.md
DELETED
package/test/bun.lockb
DELETED
|
Binary file
|
package/test/bunrun.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { startBunDevServer } from "../index";
|
|
2
|
-
|
|
3
|
-
startBunDevServer({
|
|
4
|
-
buildConfig: {
|
|
5
|
-
entrypoints: ["./src/app.ts"],
|
|
6
|
-
outdir: "dist",
|
|
7
|
-
splitting: true,
|
|
8
|
-
naming: {
|
|
9
|
-
asset: "assets/[name]-[hash].[ext]",
|
|
10
|
-
chunk: "chunks/[name]-[hash].[ext]",
|
|
11
|
-
},
|
|
12
|
-
sourcemap: "linked"
|
|
13
|
-
},
|
|
14
|
-
cleanServePath: true,
|
|
15
|
-
port: 4567,
|
|
16
|
-
enableTypeScriptWatch: true,
|
|
17
|
-
watchDir: "./src",
|
|
18
|
-
})
|
package/test/package.json
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "test",
|
|
3
|
-
"module": "app.ts",
|
|
4
|
-
"type": "module",
|
|
5
|
-
"devDependencies": {
|
|
6
|
-
"@types/bun": "^1.1.11"
|
|
7
|
-
},
|
|
8
|
-
"peerDependencies": {
|
|
9
|
-
"typescript": "^5.6.3"
|
|
10
|
-
},
|
|
11
|
-
"dependencies": {
|
|
12
|
-
"@pnp/queryable": "^4.6.0",
|
|
13
|
-
"@pnp/sp": "^4.6.0",
|
|
14
|
-
"bun": "^1.1.31"
|
|
15
|
-
}
|
|
16
|
-
}
|
package/test/src/app.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="-100 -100 200 200">
|
|
2
|
-
<polygon points="0,0 80,120 -80,120" fill="#234236" />
|
|
3
|
-
<polygon points="0,-40 60,60 -60,60" fill="#0C5C4C" />
|
|
4
|
-
<polygon points="0,-80 40,0 -40,0" fill="#38755B" />
|
|
5
|
-
<rect x="-20" y="120" width="40" height="30" fill="brown" />
|
|
6
|
-
</svg>
|
package/test/src/something.ts
DELETED