bun-dev-server 1.0.0 → 1.0.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/assets/file.svg +4 -0
- package/dist/assets/folder.svg +4 -0
- package/dist/assets/index.ejs +18 -0
- package/dist/assets/output.ejs +74 -0
- package/dist/assets/parent.svg +4 -0
- package/dist/assets/serveOutputStyles.css +166 -0
- package/dist/buildManager.d.ts +20 -0
- package/dist/bunClientHmr.d.ts +1 -0
- package/dist/configManager.d.ts +18 -0
- package/dist/fileWatcher.d.ts +12 -0
- package/dist/httpHandler.d.ts +17 -0
- package/dist/index.js +600 -479
- package/dist/staticAssets.d.ts +18 -0
- package/dist/utils/cors.d.ts +10 -0
- package/dist/utils/filesystem.d.ts +17 -0
- package/package.json +5 -2
package/dist/index.js
CHANGED
|
@@ -17,6 +17,76 @@ var __toESM = (mod, isNodeMode, target) => {
|
|
|
17
17
|
};
|
|
18
18
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
19
19
|
|
|
20
|
+
// node_modules/picocolors/picocolors.js
|
|
21
|
+
var require_picocolors = __commonJS((exports, module) => {
|
|
22
|
+
var p = process || {};
|
|
23
|
+
var argv = p.argv || [];
|
|
24
|
+
var env = p.env || {};
|
|
25
|
+
var isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
|
|
26
|
+
var formatter = (open, close, replace = open) => (input) => {
|
|
27
|
+
let string = "" + input, index = string.indexOf(close, open.length);
|
|
28
|
+
return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
|
|
29
|
+
};
|
|
30
|
+
var replaceClose = (string, close, replace, index) => {
|
|
31
|
+
let result = "", cursor = 0;
|
|
32
|
+
do {
|
|
33
|
+
result += string.substring(cursor, index) + replace;
|
|
34
|
+
cursor = index + close.length;
|
|
35
|
+
index = string.indexOf(close, cursor);
|
|
36
|
+
} while (~index);
|
|
37
|
+
return result + string.substring(cursor);
|
|
38
|
+
};
|
|
39
|
+
var createColors = (enabled = isColorSupported) => {
|
|
40
|
+
let f = enabled ? formatter : () => String;
|
|
41
|
+
return {
|
|
42
|
+
isColorSupported: enabled,
|
|
43
|
+
reset: f("\x1B[0m", "\x1B[0m"),
|
|
44
|
+
bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
|
|
45
|
+
dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
|
|
46
|
+
italic: f("\x1B[3m", "\x1B[23m"),
|
|
47
|
+
underline: f("\x1B[4m", "\x1B[24m"),
|
|
48
|
+
inverse: f("\x1B[7m", "\x1B[27m"),
|
|
49
|
+
hidden: f("\x1B[8m", "\x1B[28m"),
|
|
50
|
+
strikethrough: f("\x1B[9m", "\x1B[29m"),
|
|
51
|
+
black: f("\x1B[30m", "\x1B[39m"),
|
|
52
|
+
red: f("\x1B[31m", "\x1B[39m"),
|
|
53
|
+
green: f("\x1B[32m", "\x1B[39m"),
|
|
54
|
+
yellow: f("\x1B[33m", "\x1B[39m"),
|
|
55
|
+
blue: f("\x1B[34m", "\x1B[39m"),
|
|
56
|
+
magenta: f("\x1B[35m", "\x1B[39m"),
|
|
57
|
+
cyan: f("\x1B[36m", "\x1B[39m"),
|
|
58
|
+
white: f("\x1B[37m", "\x1B[39m"),
|
|
59
|
+
gray: f("\x1B[90m", "\x1B[39m"),
|
|
60
|
+
bgBlack: f("\x1B[40m", "\x1B[49m"),
|
|
61
|
+
bgRed: f("\x1B[41m", "\x1B[49m"),
|
|
62
|
+
bgGreen: f("\x1B[42m", "\x1B[49m"),
|
|
63
|
+
bgYellow: f("\x1B[43m", "\x1B[49m"),
|
|
64
|
+
bgBlue: f("\x1B[44m", "\x1B[49m"),
|
|
65
|
+
bgMagenta: f("\x1B[45m", "\x1B[49m"),
|
|
66
|
+
bgCyan: f("\x1B[46m", "\x1B[49m"),
|
|
67
|
+
bgWhite: f("\x1B[47m", "\x1B[49m"),
|
|
68
|
+
blackBright: f("\x1B[90m", "\x1B[39m"),
|
|
69
|
+
redBright: f("\x1B[91m", "\x1B[39m"),
|
|
70
|
+
greenBright: f("\x1B[92m", "\x1B[39m"),
|
|
71
|
+
yellowBright: f("\x1B[93m", "\x1B[39m"),
|
|
72
|
+
blueBright: f("\x1B[94m", "\x1B[39m"),
|
|
73
|
+
magentaBright: f("\x1B[95m", "\x1B[39m"),
|
|
74
|
+
cyanBright: f("\x1B[96m", "\x1B[39m"),
|
|
75
|
+
whiteBright: f("\x1B[97m", "\x1B[39m"),
|
|
76
|
+
bgBlackBright: f("\x1B[100m", "\x1B[49m"),
|
|
77
|
+
bgRedBright: f("\x1B[101m", "\x1B[49m"),
|
|
78
|
+
bgGreenBright: f("\x1B[102m", "\x1B[49m"),
|
|
79
|
+
bgYellowBright: f("\x1B[103m", "\x1B[49m"),
|
|
80
|
+
bgBlueBright: f("\x1B[104m", "\x1B[49m"),
|
|
81
|
+
bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
|
|
82
|
+
bgCyanBright: f("\x1B[106m", "\x1B[49m"),
|
|
83
|
+
bgWhiteBright: f("\x1B[107m", "\x1B[49m")
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
module.exports = createColors();
|
|
87
|
+
module.exports.createColors = createColors;
|
|
88
|
+
});
|
|
89
|
+
|
|
20
90
|
// node_modules/ejs/lib/utils.js
|
|
21
91
|
var require_utils = __commonJS((exports) => {
|
|
22
92
|
var regExpChars = /[|\\{}()[\]^$+*?.]/g;
|
|
@@ -776,76 +846,6 @@ var require_ejs = __commonJS((exports) => {
|
|
|
776
846
|
}
|
|
777
847
|
});
|
|
778
848
|
|
|
779
|
-
// node_modules/picocolors/picocolors.js
|
|
780
|
-
var require_picocolors = __commonJS((exports, module) => {
|
|
781
|
-
var p = process || {};
|
|
782
|
-
var argv = p.argv || [];
|
|
783
|
-
var env = p.env || {};
|
|
784
|
-
var isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
|
|
785
|
-
var formatter = (open, close, replace = open) => (input) => {
|
|
786
|
-
let string = "" + input, index = string.indexOf(close, open.length);
|
|
787
|
-
return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
|
|
788
|
-
};
|
|
789
|
-
var replaceClose = (string, close, replace, index) => {
|
|
790
|
-
let result = "", cursor = 0;
|
|
791
|
-
do {
|
|
792
|
-
result += string.substring(cursor, index) + replace;
|
|
793
|
-
cursor = index + close.length;
|
|
794
|
-
index = string.indexOf(close, cursor);
|
|
795
|
-
} while (~index);
|
|
796
|
-
return result + string.substring(cursor);
|
|
797
|
-
};
|
|
798
|
-
var createColors = (enabled = isColorSupported) => {
|
|
799
|
-
let f = enabled ? formatter : () => String;
|
|
800
|
-
return {
|
|
801
|
-
isColorSupported: enabled,
|
|
802
|
-
reset: f("\x1B[0m", "\x1B[0m"),
|
|
803
|
-
bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
|
|
804
|
-
dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
|
|
805
|
-
italic: f("\x1B[3m", "\x1B[23m"),
|
|
806
|
-
underline: f("\x1B[4m", "\x1B[24m"),
|
|
807
|
-
inverse: f("\x1B[7m", "\x1B[27m"),
|
|
808
|
-
hidden: f("\x1B[8m", "\x1B[28m"),
|
|
809
|
-
strikethrough: f("\x1B[9m", "\x1B[29m"),
|
|
810
|
-
black: f("\x1B[30m", "\x1B[39m"),
|
|
811
|
-
red: f("\x1B[31m", "\x1B[39m"),
|
|
812
|
-
green: f("\x1B[32m", "\x1B[39m"),
|
|
813
|
-
yellow: f("\x1B[33m", "\x1B[39m"),
|
|
814
|
-
blue: f("\x1B[34m", "\x1B[39m"),
|
|
815
|
-
magenta: f("\x1B[35m", "\x1B[39m"),
|
|
816
|
-
cyan: f("\x1B[36m", "\x1B[39m"),
|
|
817
|
-
white: f("\x1B[37m", "\x1B[39m"),
|
|
818
|
-
gray: f("\x1B[90m", "\x1B[39m"),
|
|
819
|
-
bgBlack: f("\x1B[40m", "\x1B[49m"),
|
|
820
|
-
bgRed: f("\x1B[41m", "\x1B[49m"),
|
|
821
|
-
bgGreen: f("\x1B[42m", "\x1B[49m"),
|
|
822
|
-
bgYellow: f("\x1B[43m", "\x1B[49m"),
|
|
823
|
-
bgBlue: f("\x1B[44m", "\x1B[49m"),
|
|
824
|
-
bgMagenta: f("\x1B[45m", "\x1B[49m"),
|
|
825
|
-
bgCyan: f("\x1B[46m", "\x1B[49m"),
|
|
826
|
-
bgWhite: f("\x1B[47m", "\x1B[49m"),
|
|
827
|
-
blackBright: f("\x1B[90m", "\x1B[39m"),
|
|
828
|
-
redBright: f("\x1B[91m", "\x1B[39m"),
|
|
829
|
-
greenBright: f("\x1B[92m", "\x1B[39m"),
|
|
830
|
-
yellowBright: f("\x1B[93m", "\x1B[39m"),
|
|
831
|
-
blueBright: f("\x1B[94m", "\x1B[39m"),
|
|
832
|
-
magentaBright: f("\x1B[95m", "\x1B[39m"),
|
|
833
|
-
cyanBright: f("\x1B[96m", "\x1B[39m"),
|
|
834
|
-
whiteBright: f("\x1B[97m", "\x1B[39m"),
|
|
835
|
-
bgBlackBright: f("\x1B[100m", "\x1B[49m"),
|
|
836
|
-
bgRedBright: f("\x1B[101m", "\x1B[49m"),
|
|
837
|
-
bgGreenBright: f("\x1B[102m", "\x1B[49m"),
|
|
838
|
-
bgYellowBright: f("\x1B[103m", "\x1B[49m"),
|
|
839
|
-
bgBlueBright: f("\x1B[104m", "\x1B[49m"),
|
|
840
|
-
bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
|
|
841
|
-
bgCyanBright: f("\x1B[106m", "\x1B[49m"),
|
|
842
|
-
bgWhiteBright: f("\x1B[107m", "\x1B[49m")
|
|
843
|
-
};
|
|
844
|
-
};
|
|
845
|
-
module.exports = createColors();
|
|
846
|
-
module.exports.createColors = createColors;
|
|
847
|
-
});
|
|
848
|
-
|
|
849
849
|
// node_modules/eventemitter3/index.js
|
|
850
850
|
var require_eventemitter3 = __commonJS((exports, module) => {
|
|
851
851
|
var has = Object.prototype.hasOwnProperty;
|
|
@@ -1026,223 +1026,174 @@ var require_eventemitter3 = __commonJS((exports, module) => {
|
|
|
1026
1026
|
});
|
|
1027
1027
|
|
|
1028
1028
|
// src/server.ts
|
|
1029
|
-
var
|
|
1030
|
-
var {$: $2, build } = globalThis.Bun;
|
|
1031
|
-
|
|
1032
|
-
// src/serveOutputTemplate.ejs
|
|
1033
|
-
var serveOutputTemplate_default = `<!DOCTYPE html>\r
|
|
1034
|
-
<html lang="en">\r
|
|
1035
|
-
\r
|
|
1036
|
-
<head>\r
|
|
1037
|
-
<meta charset="UTF-8" />\r
|
|
1038
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />\r
|
|
1039
|
-
<title>Document</title>\r
|
|
1040
|
-
</head>\r
|
|
1041
|
-
\r
|
|
1042
|
-
<body>\r
|
|
1043
|
-
<a href="../">..</a>\r
|
|
1044
|
-
<% dirs.forEach(element => { %> <br /><a href=".<%= element.requestPath %>/<%= element.name %>"><%= element.name %></a> <% }) %>\r
|
|
1045
|
-
<% files.forEach(element => { %> <br /><a href=".<%= element.requestPath %>/<%= element.name %>"><%= element.name %></a> <% }) %>\r
|
|
1046
|
-
</body>\r
|
|
1047
|
-
\r
|
|
1048
|
-
</html>`;
|
|
1029
|
+
var import_picocolors3 = __toESM(require_picocolors(), 1);
|
|
1049
1030
|
|
|
1050
|
-
// src/
|
|
1051
|
-
var
|
|
1052
|
-
|
|
1053
|
-
<head>\r
|
|
1054
|
-
<meta charset="UTF-8" />\r
|
|
1055
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />\r
|
|
1056
|
-
<title>Bun HTML File</title>\r
|
|
1057
|
-
<% for (const hashedJs of hashedImports) { %>\r
|
|
1058
|
-
<script type="module" src="<%= hashedJs %>"></script>\r
|
|
1059
|
-
<% } %>\r
|
|
1060
|
-
</head>\r
|
|
1061
|
-
\r
|
|
1062
|
-
<body>\r
|
|
1063
|
-
<div id="app"></div>\r
|
|
1064
|
-
</body>\r
|
|
1065
|
-
</html>\r
|
|
1066
|
-
`;
|
|
1031
|
+
// src/httpHandler.ts
|
|
1032
|
+
var import_ejs = __toESM(require_ejs(), 1);
|
|
1033
|
+
import { readFile, readdir } from "fs/promises";
|
|
1067
1034
|
|
|
1068
|
-
// src/
|
|
1069
|
-
|
|
1070
|
-
|
|
1035
|
+
// src/utils/cors.ts
|
|
1036
|
+
function withCORSHeaders(response, request) {
|
|
1037
|
+
response.headers.set("Access-Control-Allow-Origin", request?.headers.get("origin") ?? "*");
|
|
1038
|
+
response.headers.set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH, OPTIONS");
|
|
1039
|
+
response.headers.set("Access-Control-Allow-Credentials", "true");
|
|
1040
|
+
response.headers.set("Cache-Control", "no-store, no-cache, must-revalidate");
|
|
1041
|
+
return response;
|
|
1042
|
+
}
|
|
1071
1043
|
|
|
1072
|
-
// src/
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1044
|
+
// src/utils/filesystem.ts
|
|
1045
|
+
var {$ } = globalThis.Bun;
|
|
1046
|
+
import { access, constants } from "fs/promises";
|
|
1047
|
+
async function cleanDirectory(dst) {
|
|
1048
|
+
const { stderr, exitCode } = await $`rm -rf ${dst}/*`.nothrow();
|
|
1049
|
+
if (exitCode !== 0) {
|
|
1050
|
+
if (stderr.indexOf("no matches found") > -1) {
|
|
1051
|
+
console.log("Directory is empty");
|
|
1052
|
+
} else {
|
|
1053
|
+
console.warn("Unable to clean directory", stderr.toString("utf8"));
|
|
1054
|
+
}
|
|
1076
1055
|
}
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
if (
|
|
1081
|
-
|
|
1056
|
+
}
|
|
1057
|
+
function convertBytes(bytes) {
|
|
1058
|
+
const sizes = ["Bytes", "KB", "MB", "GB", "TB"];
|
|
1059
|
+
if (bytes == 0) {
|
|
1060
|
+
return "n/a";
|
|
1082
1061
|
}
|
|
1083
|
-
|
|
1084
|
-
|
|
1062
|
+
const floored = Math.floor(Math.log(bytes) / Math.log(1024));
|
|
1063
|
+
const i = floored;
|
|
1064
|
+
if (i == 0) {
|
|
1065
|
+
return bytes + " " + sizes[i];
|
|
1085
1066
|
}
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1067
|
+
return (bytes / Math.pow(1024, i)).toFixed(1) + " " + sizes[i];
|
|
1068
|
+
}
|
|
1069
|
+
async function checkObjectExists(fsPath) {
|
|
1070
|
+
try {
|
|
1071
|
+
await access(fsPath, constants.R_OK);
|
|
1072
|
+
return true;
|
|
1073
|
+
} catch (e) {
|
|
1074
|
+
if (e?.code === "ENOENT") {
|
|
1075
|
+
return false;
|
|
1076
|
+
}
|
|
1077
|
+
const msg = `Error while accessing path ${fsPath}`;
|
|
1078
|
+
console.error(msg, e);
|
|
1079
|
+
return false;
|
|
1091
1080
|
}
|
|
1092
|
-
|
|
1093
|
-
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
// src/httpHandler.ts
|
|
1084
|
+
function handleErrorResponse(req, err) {
|
|
1085
|
+
const msg = `Error while processing request ${req.url}`;
|
|
1086
|
+
console.error(msg, err);
|
|
1087
|
+
return withCORSHeaders(new Response(msg, { status: 500 }), req);
|
|
1088
|
+
}
|
|
1089
|
+
async function handlePathRequest(requestPath, req, finalConfig, destinationPath) {
|
|
1090
|
+
let fsPath = destinationPath + requestPath;
|
|
1091
|
+
const objThere = await checkObjectExists(fsPath);
|
|
1092
|
+
let isDirectory = false;
|
|
1093
|
+
if (objThere) {
|
|
1094
1094
|
try {
|
|
1095
|
-
|
|
1095
|
+
await readFile(fsPath);
|
|
1096
1096
|
} catch (e) {
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
}
|
|
1102
|
-
if (parsed?.type === "output") {
|
|
1103
|
-
console.table(devServer, parsed.message);
|
|
1104
|
-
return;
|
|
1105
|
-
}
|
|
1106
|
-
if (parsed?.type === "reload") {
|
|
1107
|
-
window.location.reload();
|
|
1108
|
-
return;
|
|
1109
|
-
}
|
|
1110
|
-
if (parsed?.type === "tscerror") {
|
|
1111
|
-
console.error(parsed.message);
|
|
1112
|
-
return;
|
|
1113
|
-
}
|
|
1114
|
-
if (parsed?.type === "error") {
|
|
1115
|
-
console.error(parsed.message);
|
|
1116
|
-
let newDiv = window.document.getElementById("bun-hmr-error");
|
|
1117
|
-
const divExists = !!newDiv;
|
|
1118
|
-
if (!newDiv) {
|
|
1119
|
-
newDiv = window.document.createElement("div");
|
|
1120
|
-
}
|
|
1121
|
-
newDiv.id = "bun-hmr-error";
|
|
1122
|
-
newDiv.innerText += parsed.message;
|
|
1123
|
-
if (!divExists) {
|
|
1124
|
-
window.document.body.appendChild(newDiv);
|
|
1097
|
+
if (e.code === "EISDIR") {
|
|
1098
|
+
isDirectory = true;
|
|
1099
|
+
} else {
|
|
1100
|
+
throw e;
|
|
1125
1101
|
}
|
|
1126
|
-
return;
|
|
1127
1102
|
}
|
|
1103
|
+
} else {
|
|
1104
|
+
if (requestPath.toLowerCase() !== "/index.html") {
|
|
1105
|
+
finalConfig.logRequests && console.log(`${404} ${req.url}`);
|
|
1106
|
+
return withCORSHeaders(new Response("", { status: 404 }), req);
|
|
1107
|
+
}
|
|
1108
|
+
requestPath = "/";
|
|
1109
|
+
isDirectory = true;
|
|
1110
|
+
fsPath = destinationPath + requestPath;
|
|
1128
1111
|
}
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
foundServer.socket?.removeEventListener("error", errorHandler);
|
|
1132
|
-
foundServer.socket?.removeEventListener("message", messageHandler);
|
|
1133
|
-
foundServer.socket?.removeEventListener("open", messageHandler);
|
|
1134
|
-
foundServer.socket?.removeEventListener("close", closeHandler);
|
|
1135
|
-
foundServer.socket = null;
|
|
1136
|
-
setTimeout(function() {
|
|
1137
|
-
console.log(devServer, "Attempting to reconnect...");
|
|
1138
|
-
hotReload();
|
|
1139
|
-
}, 5000);
|
|
1140
|
-
}
|
|
1141
|
-
function openHandler(ev) {
|
|
1142
|
-
console.log(devServer, "Connected to Bun Dev Server");
|
|
1112
|
+
if (!isDirectory) {
|
|
1113
|
+
return handleFileRequest(fsPath, req, finalConfig);
|
|
1143
1114
|
}
|
|
1144
|
-
|
|
1145
|
-
foundServer.socket.addEventListener("message", messageHandler);
|
|
1146
|
-
foundServer.socket.addEventListener("close", closeHandler);
|
|
1147
|
-
foundServer.socket.addEventListener("open", openHandler);
|
|
1115
|
+
return handleDirectoryRequest(fsPath, requestPath, req, finalConfig);
|
|
1148
1116
|
}
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
const bunHMRPlugin = {
|
|
1161
|
-
name: "hmr",
|
|
1162
|
-
target: "browser",
|
|
1163
|
-
setup(build) {
|
|
1164
|
-
const entryPoints = [];
|
|
1165
|
-
const addedEnryPoints = new Set;
|
|
1166
|
-
build.config.entrypoints.forEach((entry) => {
|
|
1167
|
-
let entryPath = entry.replace(/^\.*/, "");
|
|
1168
|
-
if (process.platform === "win32") {
|
|
1169
|
-
entryPath = entryPath.replace(/\//g, "\\");
|
|
1170
|
-
}
|
|
1171
|
-
entryPoints.push(entryPath);
|
|
1172
|
-
});
|
|
1173
|
-
build.onLoad({ filter: /\.m?tsx?/ }, async (args) => {
|
|
1174
|
-
const contents = await readFile(args.path, { encoding: "utf-8" });
|
|
1175
|
-
const isTSx = /\.m?tsx$/.test(args.path);
|
|
1176
|
-
const isJSx = /\.m?jsx$/.test(args.path);
|
|
1177
|
-
const isJS = /\.m?js$/.test(args.path);
|
|
1178
|
-
const isTS = /\.m?ts$/.test(args.path);
|
|
1179
|
-
const loader = isTSx ? "tsx" : isJSx ? "jsx" : isTS ? "ts" : isJS ? "js" : "text";
|
|
1180
|
-
const isEntry = entryPoints.some((entry) => args.path.endsWith(entry));
|
|
1181
|
-
if (!addedEnryPoints.has(args.path) && isEntry) {
|
|
1182
|
-
addedEnryPoints.add(args.path);
|
|
1183
|
-
return { contents: `import "bun-hot-reload"
|
|
1184
|
-
` + contents, loader };
|
|
1185
|
-
}
|
|
1186
|
-
return { contents, loader };
|
|
1187
|
-
});
|
|
1188
|
-
build.onLoad({ filter: /./, namespace: "bun-hot-reload" }, async (args) => {
|
|
1189
|
-
return { contents: `(${bunHotReload(config)})()
|
|
1190
|
-
`, loader: "ts" };
|
|
1191
|
-
});
|
|
1192
|
-
build.onResolve({ filter: /^bun-hot-reload$/ }, (args) => {
|
|
1193
|
-
return { path: args.path, namespace: "bun-hot-reload" };
|
|
1194
|
-
});
|
|
1117
|
+
async function handleFileRequest(fsPath, req, finalConfig) {
|
|
1118
|
+
try {
|
|
1119
|
+
const fl = Bun.file(fsPath);
|
|
1120
|
+
finalConfig.logRequests && console.log(`${200} ${req.url}`);
|
|
1121
|
+
return withCORSHeaders(new Response(fl), req);
|
|
1122
|
+
} catch (e) {
|
|
1123
|
+
if (e?.code === "ENOENT") {
|
|
1124
|
+
finalConfig.logRequests && console.log(`${404} ${req.url}`);
|
|
1125
|
+
return withCORSHeaders(new Response("", { status: 404 }), req);
|
|
1126
|
+
} else {
|
|
1127
|
+
return handleErrorResponse(req, e);
|
|
1195
1128
|
}
|
|
1196
|
-
};
|
|
1197
|
-
return bunHMRPlugin;
|
|
1198
|
-
}
|
|
1199
|
-
function getBunHMRFooter(config) {
|
|
1200
|
-
return `;(${bunHotReload(config)})();`;
|
|
1201
|
-
}
|
|
1202
|
-
|
|
1203
|
-
// src/bunManifest.ts
|
|
1204
|
-
var {write, pathToFileURL } = globalThis.Bun;
|
|
1205
|
-
function writeManifest(output, outdir, withHash = false, manifestName = "bun_server_manifest.json") {
|
|
1206
|
-
const entryPoints = output.outputs.filter((o) => o.kind === "entry-point");
|
|
1207
|
-
const epTable = [];
|
|
1208
|
-
for (const ep of entryPoints) {
|
|
1209
|
-
const basePathUrl = pathToFileURL(outdir);
|
|
1210
|
-
const epUrl = pathToFileURL(ep.path);
|
|
1211
|
-
const relativePath = epUrl.href.replace(`${basePathUrl.href}/`, "");
|
|
1212
|
-
const hashedImport = `${relativePath}${withHash ? `?${ep.hash}` : ``}`;
|
|
1213
|
-
epTable.push(hashedImport);
|
|
1214
1129
|
}
|
|
1215
|
-
const outObj = { js: epTable };
|
|
1216
|
-
write(`${outdir}/${manifestName}`, JSON.stringify(outObj));
|
|
1217
1130
|
}
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
message: ""
|
|
1225
|
-
};
|
|
1226
|
-
async function performTSC(finalConfig, importMeta) {
|
|
1227
|
-
if (finalConfig.enableTSC) {
|
|
1228
|
-
console.log("Performing TSC check");
|
|
1229
|
-
const tsc = await $`tsc --noEmit --noErrorTruncation -p ${finalConfig.tscConfigPath}`.cwd(importMeta.dir).quiet().nothrow();
|
|
1230
|
-
if (tsc.exitCode === 0) {
|
|
1231
|
-
console.log(import_picocolors.default.bgGreen("\u2714 [SUCCESS]"), "TSC check passed");
|
|
1232
|
-
return success;
|
|
1233
|
-
} else {
|
|
1234
|
-
const errOutput = tsc.stdout.toString();
|
|
1235
|
-
console.log(import_picocolors.default.bgRed("\u2718 [ERROR]"), `\r
|
|
1236
|
-
${errOutput}`);
|
|
1131
|
+
async function handleDirectoryRequest(fsPath, requestPath, req, finalConfig) {
|
|
1132
|
+
try {
|
|
1133
|
+
const allEntries = await readdir(fsPath, {
|
|
1134
|
+
withFileTypes: true
|
|
1135
|
+
});
|
|
1136
|
+
const dirs = allEntries.filter((entry) => entry.isDirectory()).map((entry) => {
|
|
1237
1137
|
return {
|
|
1238
|
-
|
|
1239
|
-
|
|
1138
|
+
requestPath: requestPath === "/" ? "" : requestPath,
|
|
1139
|
+
name: entry.name
|
|
1240
1140
|
};
|
|
1241
|
-
}
|
|
1141
|
+
});
|
|
1142
|
+
const files = allEntries.filter((entry) => entry.isFile()).map((entry) => {
|
|
1143
|
+
return {
|
|
1144
|
+
requestPath: requestPath === "/" ? "" : requestPath,
|
|
1145
|
+
name: entry.name
|
|
1146
|
+
};
|
|
1147
|
+
});
|
|
1148
|
+
const templatePath = requestPath === "/" ? "" : requestPath;
|
|
1149
|
+
const rnd = import_ejs.render(finalConfig.serveOutputEjs, {
|
|
1150
|
+
dirs,
|
|
1151
|
+
files,
|
|
1152
|
+
requestPath: templatePath
|
|
1153
|
+
});
|
|
1154
|
+
finalConfig.logRequests && console.log(`${200} ${req.url}`);
|
|
1155
|
+
return withCORSHeaders(new Response(rnd, { headers: { "Content-Type": "text/html" } }), req);
|
|
1156
|
+
} catch (err) {
|
|
1157
|
+
return handleErrorResponse(req, err);
|
|
1242
1158
|
}
|
|
1243
|
-
return success;
|
|
1244
1159
|
}
|
|
1245
1160
|
|
|
1161
|
+
// src/staticAssets.ts
|
|
1162
|
+
import { resolve } from "path";
|
|
1163
|
+
|
|
1164
|
+
// src/static/serveOutputStyles.css
|
|
1165
|
+
var serveOutputStyles_default = "./assets/serveOutputStyles.css";
|
|
1166
|
+
|
|
1167
|
+
// src/static/file.svg
|
|
1168
|
+
var file_default = "./assets/file.svg";
|
|
1169
|
+
|
|
1170
|
+
// src/static/folder.svg
|
|
1171
|
+
var folder_default = "./assets/folder.svg";
|
|
1172
|
+
|
|
1173
|
+
// src/static/parent.svg
|
|
1174
|
+
var parent_default = "./assets/parent.svg";
|
|
1175
|
+
|
|
1176
|
+
// src/staticAssets.ts
|
|
1177
|
+
var staticAssets = {
|
|
1178
|
+
listingStyle: Bun.file(resolve(import.meta.dir, serveOutputStyles_default)),
|
|
1179
|
+
fileSvg: Bun.file(resolve(import.meta.dir, file_default)),
|
|
1180
|
+
folderSvg: Bun.file(resolve(import.meta.dir, folder_default)),
|
|
1181
|
+
parentSvg: Bun.file(resolve(import.meta.dir, parent_default))
|
|
1182
|
+
};
|
|
1183
|
+
var staticAssetRoutes = {
|
|
1184
|
+
"/__bun_dev_server__/serveOutputStyles.css": staticAssets.listingStyle,
|
|
1185
|
+
"/__bun_dev_server__/file.svg": staticAssets.fileSvg,
|
|
1186
|
+
"/__bun_dev_server__/folder.svg": staticAssets.folderSvg,
|
|
1187
|
+
"/__bun_dev_server__/parent.svg": staticAssets.parentSvg
|
|
1188
|
+
};
|
|
1189
|
+
|
|
1190
|
+
// src/fileWatcher.ts
|
|
1191
|
+
import { watch } from "fs/promises";
|
|
1192
|
+
|
|
1193
|
+
// src/buildManager.ts
|
|
1194
|
+
var import_ejs2 = __toESM(require_ejs(), 1);
|
|
1195
|
+
var {build } = globalThis.Bun;
|
|
1196
|
+
|
|
1246
1197
|
// node_modules/eventemitter3/index.mjs
|
|
1247
1198
|
var import__ = __toESM(require_eventemitter3(), 1);
|
|
1248
1199
|
|
|
@@ -1265,7 +1216,7 @@ function pTimeout(promise, options) {
|
|
|
1265
1216
|
} = options;
|
|
1266
1217
|
let timer;
|
|
1267
1218
|
let abortHandler;
|
|
1268
|
-
const wrappedPromise = new Promise((
|
|
1219
|
+
const wrappedPromise = new Promise((resolve2, reject) => {
|
|
1269
1220
|
if (typeof milliseconds !== "number" || Math.sign(milliseconds) !== 1) {
|
|
1270
1221
|
throw new TypeError(`Expected \`milliseconds\` to be a positive number, got \`${milliseconds}\``);
|
|
1271
1222
|
}
|
|
@@ -1279,7 +1230,7 @@ function pTimeout(promise, options) {
|
|
|
1279
1230
|
};
|
|
1280
1231
|
signal.addEventListener("abort", abortHandler, { once: true });
|
|
1281
1232
|
}
|
|
1282
|
-
promise.then(
|
|
1233
|
+
promise.then(resolve2, reject);
|
|
1283
1234
|
if (milliseconds === Number.POSITIVE_INFINITY) {
|
|
1284
1235
|
return;
|
|
1285
1236
|
}
|
|
@@ -1287,7 +1238,7 @@ function pTimeout(promise, options) {
|
|
|
1287
1238
|
timer = customTimers.setTimeout.call(undefined, () => {
|
|
1288
1239
|
if (fallback) {
|
|
1289
1240
|
try {
|
|
1290
|
-
|
|
1241
|
+
resolve2(fallback());
|
|
1291
1242
|
} catch (error) {
|
|
1292
1243
|
reject(error);
|
|
1293
1244
|
}
|
|
@@ -1297,7 +1248,7 @@ function pTimeout(promise, options) {
|
|
|
1297
1248
|
promise.cancel();
|
|
1298
1249
|
}
|
|
1299
1250
|
if (message === false) {
|
|
1300
|
-
|
|
1251
|
+
resolve2();
|
|
1301
1252
|
} else if (message instanceof Error) {
|
|
1302
1253
|
reject(message);
|
|
1303
1254
|
} else {
|
|
@@ -1564,7 +1515,7 @@ class PQueue extends import__.default {
|
|
|
1564
1515
|
timeout: this.timeout,
|
|
1565
1516
|
...options
|
|
1566
1517
|
};
|
|
1567
|
-
return new Promise((
|
|
1518
|
+
return new Promise((resolve2, reject) => {
|
|
1568
1519
|
const taskSymbol = Symbol(`task-${options.id}`);
|
|
1569
1520
|
this.#queue.enqueue(async () => {
|
|
1570
1521
|
this.#pending++;
|
|
@@ -1595,7 +1546,7 @@ class PQueue extends import__.default {
|
|
|
1595
1546
|
operation = Promise.race([operation, this.#throwOnAbort(options.signal)]);
|
|
1596
1547
|
}
|
|
1597
1548
|
const result = await operation;
|
|
1598
|
-
|
|
1549
|
+
resolve2(result);
|
|
1599
1550
|
this.emit("completed", result);
|
|
1600
1551
|
} catch (error) {
|
|
1601
1552
|
reject(error);
|
|
@@ -1675,13 +1626,13 @@ class PQueue extends import__.default {
|
|
|
1675
1626
|
});
|
|
1676
1627
|
}
|
|
1677
1628
|
async#onEvent(event, filter) {
|
|
1678
|
-
return new Promise((
|
|
1629
|
+
return new Promise((resolve2) => {
|
|
1679
1630
|
const listener = () => {
|
|
1680
1631
|
if (filter && !filter()) {
|
|
1681
1632
|
return;
|
|
1682
1633
|
}
|
|
1683
1634
|
this.off(event, listener);
|
|
1684
|
-
|
|
1635
|
+
resolve2();
|
|
1685
1636
|
};
|
|
1686
1637
|
this.on(event, listener);
|
|
1687
1638
|
});
|
|
@@ -1740,134 +1691,62 @@ class PQueue extends import__.default {
|
|
|
1740
1691
|
}
|
|
1741
1692
|
}
|
|
1742
1693
|
|
|
1743
|
-
// src/
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
throw new Error("watchDir must be set");
|
|
1761
|
-
}
|
|
1762
|
-
const servePart = finalConfig.buildConfig.outdir ?? finalConfig.servePath ?? "./dist";
|
|
1763
|
-
const serveDestination = resolve(importMeta.dir, servePart);
|
|
1764
|
-
const watchDestination = resolve(importMeta.dir, finalConfig.watchDir);
|
|
1765
|
-
const allEntries = serverConfig.buildConfig.entrypoints.splice(0, serverConfig.buildConfig.entrypoints.length);
|
|
1766
|
-
const resolvedEntries = allEntries.map((e) => resolve(importMeta.dir, e));
|
|
1767
|
-
serverConfig.buildConfig.entrypoints = resolvedEntries;
|
|
1768
|
-
const destinationPath = serveDestination;
|
|
1769
|
-
const srcWatch = watchDestination;
|
|
1770
|
-
try {
|
|
1771
|
-
await readdir(destinationPath);
|
|
1772
|
-
} catch (e) {
|
|
1773
|
-
if (e.code === "ENOENT") {
|
|
1774
|
-
console.log("Directory not found, creating it...");
|
|
1775
|
-
try {
|
|
1776
|
-
await $2`mkdir ${destinationPath}`;
|
|
1777
|
-
} catch (e2) {
|
|
1778
|
-
console.error("Unable to create directory", e2);
|
|
1779
|
-
}
|
|
1694
|
+
// src/buildManager.ts
|
|
1695
|
+
var import_picocolors2 = __toESM(require_picocolors(), 1);
|
|
1696
|
+
|
|
1697
|
+
// src/tsChecker.ts
|
|
1698
|
+
var import_picocolors = __toESM(require_picocolors(), 1);
|
|
1699
|
+
var {$: $2 } = globalThis.Bun;
|
|
1700
|
+
var success = {
|
|
1701
|
+
error: false,
|
|
1702
|
+
message: ""
|
|
1703
|
+
};
|
|
1704
|
+
async function performTSC(finalConfig, importMeta) {
|
|
1705
|
+
if (finalConfig.enableTSC) {
|
|
1706
|
+
console.log("Performing TSC check");
|
|
1707
|
+
const tsc = await $2`tsc --noEmit --noErrorTruncation -p ${finalConfig.tscConfigPath}`.cwd(importMeta.dir).quiet().nothrow();
|
|
1708
|
+
if (tsc.exitCode === 0) {
|
|
1709
|
+
console.log(import_picocolors.default.bgGreen("\u2714 [SUCCESS]"), "TSC check passed");
|
|
1710
|
+
return success;
|
|
1780
1711
|
} else {
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
};
|
|
1789
|
-
if (finalConfig.hotReload === "footer") {
|
|
1790
|
-
if (!buildCfg.footer) {
|
|
1791
|
-
buildCfg.footer = "";
|
|
1792
|
-
}
|
|
1793
|
-
buildCfg.footer += getBunHMRFooter(buncfg);
|
|
1794
|
-
}
|
|
1795
|
-
if (finalConfig.hotReload === "plugin") {
|
|
1796
|
-
if (!buildCfg.plugins) {
|
|
1797
|
-
buildCfg.plugins = [];
|
|
1712
|
+
const errOutput = tsc.stdout.toString();
|
|
1713
|
+
console.log(import_picocolors.default.bgRed("\u2718 [ERROR]"), `\r
|
|
1714
|
+
${errOutput}`);
|
|
1715
|
+
return {
|
|
1716
|
+
error: true,
|
|
1717
|
+
message: errOutput
|
|
1718
|
+
};
|
|
1798
1719
|
}
|
|
1799
|
-
buildCfg.plugins.push(bunHotReloadPlugin(buncfg));
|
|
1800
|
-
}
|
|
1801
|
-
if (serverConfig.cleanServePath) {
|
|
1802
|
-
await cleanDirectory(destinationPath);
|
|
1803
1720
|
}
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
if (req.url.toLowerCase().endsWith(finalConfig.websocketPath)) {
|
|
1819
|
-
finalConfig.logRequests && console.log(`${req.url} Socket Upgrade`);
|
|
1820
|
-
if (server.upgrade(req)) {
|
|
1821
|
-
return withCORSHeaders(new Response("", { status: 200 }), req);
|
|
1822
|
-
}
|
|
1823
|
-
}
|
|
1824
|
-
const url = new URL(req.url);
|
|
1825
|
-
let requestPath = url.pathname;
|
|
1826
|
-
return handlePathRequest(requestPath, req, finalConfig, destinationPath);
|
|
1827
|
-
},
|
|
1828
|
-
websocket: {
|
|
1829
|
-
open(ws) {
|
|
1830
|
-
ws.subscribe("message");
|
|
1831
|
-
},
|
|
1832
|
-
message(ws, message) {
|
|
1833
|
-
},
|
|
1834
|
-
sendPings: true
|
|
1835
|
-
}
|
|
1836
|
-
});
|
|
1837
|
-
const queue = getThrottledBuildAndNotify(finalConfig);
|
|
1838
|
-
await queue.add(async () => {
|
|
1839
|
-
await cleanBuildAndNotify(importMeta, finalConfig, destinationPath, buildCfg, bunServer, { filename: "Initial", eventType: "change" });
|
|
1840
|
-
});
|
|
1841
|
-
const watcher = watch(srcWatch, { recursive: true });
|
|
1842
|
-
for await (const event of watcher) {
|
|
1843
|
-
if (queue.pending > 0) {
|
|
1844
|
-
continue;
|
|
1845
|
-
}
|
|
1846
|
-
try {
|
|
1847
|
-
if (queue.size > 0) {
|
|
1848
|
-
queue.clear();
|
|
1849
|
-
}
|
|
1850
|
-
queue.add(async () => {
|
|
1851
|
-
await cleanBuildAndNotify(importMeta, finalConfig, destinationPath, buildCfg, bunServer, event);
|
|
1852
|
-
});
|
|
1853
|
-
} catch (e) {
|
|
1854
|
-
console.error("Error while processing file change", e);
|
|
1855
|
-
}
|
|
1721
|
+
return success;
|
|
1722
|
+
}
|
|
1723
|
+
|
|
1724
|
+
// src/bunManifest.ts
|
|
1725
|
+
var {write, pathToFileURL } = globalThis.Bun;
|
|
1726
|
+
function writeManifest(output, outdir, withHash = false, manifestName = "bun_server_manifest.json") {
|
|
1727
|
+
const entryPoints = output.outputs.filter((o) => o.kind === "entry-point");
|
|
1728
|
+
const epTable = [];
|
|
1729
|
+
for (const ep of entryPoints) {
|
|
1730
|
+
const basePathUrl = pathToFileURL(outdir);
|
|
1731
|
+
const epUrl = pathToFileURL(ep.path);
|
|
1732
|
+
const relativePath = epUrl.href.replace(`${basePathUrl.href}/`, "");
|
|
1733
|
+
const hashedImport = `${relativePath}${withHash ? `?${ep.hash}` : ``}`;
|
|
1734
|
+
epTable.push(hashedImport);
|
|
1856
1735
|
}
|
|
1736
|
+
const outObj = { js: epTable };
|
|
1737
|
+
write(`${outdir}/${manifestName}`, JSON.stringify(outObj));
|
|
1857
1738
|
}
|
|
1858
|
-
|
|
1859
|
-
|
|
1739
|
+
|
|
1740
|
+
// src/buildManager.ts
|
|
1741
|
+
function getThrottledBuildQueue(serverConfig) {
|
|
1742
|
+
return new PQueue({
|
|
1860
1743
|
concurrency: 1,
|
|
1861
1744
|
intervalCap: 1,
|
|
1862
1745
|
interval: serverConfig.watchDelay ?? 1000,
|
|
1863
1746
|
carryoverConcurrencyCount: true
|
|
1864
1747
|
});
|
|
1865
|
-
return anotherThrottle;
|
|
1866
1748
|
}
|
|
1867
1749
|
async function cleanBuildAndNotify(importerMeta, finalConfig, destinationPath, buildCfg, bunServer, event) {
|
|
1868
|
-
if (finalConfig.cleanServePath) {
|
|
1869
|
-
await cleanDirectory(destinationPath);
|
|
1870
|
-
}
|
|
1871
1750
|
const buildEnv = {
|
|
1872
1751
|
importerMeta,
|
|
1873
1752
|
finalConfig,
|
|
@@ -1878,6 +1757,12 @@ async function cleanBuildAndNotify(importerMeta, finalConfig, destinationPath, b
|
|
|
1878
1757
|
};
|
|
1879
1758
|
await finalConfig.beforeBuild?.(buildEnv);
|
|
1880
1759
|
try {
|
|
1760
|
+
if (buildCfg.outdir) {
|
|
1761
|
+
const outdirExists = await checkObjectExists(buildCfg.outdir);
|
|
1762
|
+
if (!outdirExists) {
|
|
1763
|
+
return;
|
|
1764
|
+
}
|
|
1765
|
+
}
|
|
1881
1766
|
const output = await build(buildCfg);
|
|
1882
1767
|
publishOutputLogs(bunServer, output, finalConfig, event);
|
|
1883
1768
|
if (finalConfig.createIndexHTML) {
|
|
@@ -1898,17 +1783,19 @@ async function cleanBuildAndNotify(importerMeta, finalConfig, destinationPath, b
|
|
|
1898
1783
|
bunServer.publish("message", JSON.stringify({ type: "tscerror", message: tscSuccess.message }));
|
|
1899
1784
|
}
|
|
1900
1785
|
} catch (e) {
|
|
1786
|
+
const errorMessage = e instanceof Error ? e.message : String(e);
|
|
1787
|
+
if (errorMessage.includes("test-file-watcher") || errorMessage.includes("test-build") || errorMessage.includes("test-watch-dir")) {
|
|
1788
|
+
return;
|
|
1789
|
+
}
|
|
1901
1790
|
console.error(e);
|
|
1902
1791
|
}
|
|
1903
1792
|
}
|
|
1904
|
-
function handleErrorResponse(req, err) {
|
|
1905
|
-
const msg = `Error while processing request ${req.url}`;
|
|
1906
|
-
console.error(msg, err);
|
|
1907
|
-
return withCORSHeaders(new Response(msg, { status: 500 }), req);
|
|
1908
|
-
}
|
|
1909
1793
|
function publishOutputLogs(bunServer, output, config, event) {
|
|
1910
1794
|
output.logs.forEach(console.log);
|
|
1911
|
-
bunServer.publish("message", JSON.stringify({
|
|
1795
|
+
bunServer.publish("message", JSON.stringify({
|
|
1796
|
+
type: "message",
|
|
1797
|
+
message: `[Bun HMR] ${event.filename} ${event.eventType}`
|
|
1798
|
+
}));
|
|
1912
1799
|
const outTable = output.outputs.filter((o) => o.kind !== "sourcemap").map((o) => {
|
|
1913
1800
|
const a = Bun.pathToFileURL(o.path);
|
|
1914
1801
|
const distPath = Bun.pathToFileURL(config.buildConfig.outdir ?? "./dist");
|
|
@@ -1923,7 +1810,7 @@ function publishOutputLogs(bunServer, output, config, event) {
|
|
|
1923
1810
|
};
|
|
1924
1811
|
});
|
|
1925
1812
|
if (config.broadcastBuildOutputToConsole) {
|
|
1926
|
-
|
|
1813
|
+
printPrettyBuildOutput(outTable);
|
|
1927
1814
|
}
|
|
1928
1815
|
if (config.broadcastBuildOutputToClient) {
|
|
1929
1816
|
bunServer.publish("message", JSON.stringify({ type: "output", message: outTable }));
|
|
@@ -1932,114 +1819,348 @@ function publishOutputLogs(bunServer, output, config, event) {
|
|
|
1932
1819
|
function publishIndexHTML(destinationPath, template, output, _event) {
|
|
1933
1820
|
const eps = output.outputs.filter((o) => o.kind === "entry-point");
|
|
1934
1821
|
const hashedImports = [];
|
|
1822
|
+
const cssFiles = [];
|
|
1823
|
+
const basePathUrl = Bun.pathToFileURL(destinationPath);
|
|
1935
1824
|
for (const ep of eps) {
|
|
1936
|
-
const basePathUrl = Bun.pathToFileURL(destinationPath);
|
|
1937
1825
|
const epUrl = Bun.pathToFileURL(ep.path);
|
|
1938
1826
|
const hashedImport = `${epUrl.href.replace(basePathUrl.href, "")}?${ep.hash}`;
|
|
1939
1827
|
hashedImports.push(hashedImport);
|
|
1940
1828
|
}
|
|
1941
|
-
|
|
1829
|
+
const cssOutputs = output.outputs.filter((o) => o.path.endsWith(".css"));
|
|
1830
|
+
for (const cssFile of cssOutputs) {
|
|
1831
|
+
const cssUrl = Bun.pathToFileURL(cssFile.path);
|
|
1832
|
+
const hashedCss = `${cssUrl.href.replace(basePathUrl.href, "")}?${cssFile.hash}`;
|
|
1833
|
+
cssFiles.push(hashedCss);
|
|
1834
|
+
}
|
|
1835
|
+
Bun.write(destinationPath + "/index.html", import_ejs2.render(template, { hashedImports, cssFiles }));
|
|
1942
1836
|
}
|
|
1943
|
-
function
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1837
|
+
function printPrettyBuildOutput(outTable) {
|
|
1838
|
+
if (outTable.length === 0)
|
|
1839
|
+
return;
|
|
1840
|
+
const totalFiles = outTable.length;
|
|
1841
|
+
const fileWord = totalFiles === 1 ? "file" : "files";
|
|
1842
|
+
console.log(`
|
|
1843
|
+
` + import_picocolors2.default.bold(import_picocolors2.default.cyan(`\uD83D\uDCE6 Build Output (${totalFiles} ${fileWord})`)));
|
|
1844
|
+
outTable.forEach((row) => {
|
|
1845
|
+
const checkmark = import_picocolors2.default.green(" \u2713");
|
|
1846
|
+
const filePath = import_picocolors2.default.white(row.path);
|
|
1847
|
+
const size = import_picocolors2.default.dim(`(${row.size})`);
|
|
1848
|
+
console.log(`${checkmark} ${filePath} ${size}`);
|
|
1849
|
+
});
|
|
1850
|
+
console.log("");
|
|
1949
1851
|
}
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1852
|
+
|
|
1853
|
+
// src/fileWatcher.ts
|
|
1854
|
+
async function startFileWatcher(srcWatch, importMeta, finalConfig, destinationPath, buildCfg, bunServer) {
|
|
1855
|
+
const queue = getThrottledBuildQueue(finalConfig);
|
|
1856
|
+
await queue.add(async () => {
|
|
1857
|
+
await cleanBuildAndNotify(importMeta, finalConfig, destinationPath, buildCfg, bunServer, { filename: "Initial", eventType: "change" });
|
|
1858
|
+
});
|
|
1859
|
+
const watcher = watch(srcWatch, { recursive: true });
|
|
1860
|
+
try {
|
|
1861
|
+
for await (const event of watcher) {
|
|
1862
|
+
if (queue.pending > 0) {
|
|
1863
|
+
continue;
|
|
1864
|
+
}
|
|
1865
|
+
try {
|
|
1866
|
+
if (queue.size > 0) {
|
|
1867
|
+
queue.clear();
|
|
1868
|
+
}
|
|
1869
|
+
queue.add(async () => {
|
|
1870
|
+
await cleanBuildAndNotify(importMeta, finalConfig, destinationPath, buildCfg, bunServer, event);
|
|
1871
|
+
});
|
|
1872
|
+
} catch (e) {
|
|
1873
|
+
console.error("Error while processing file change", e);
|
|
1874
|
+
}
|
|
1875
|
+
}
|
|
1876
|
+
} catch (e) {
|
|
1877
|
+
if (e?.code !== "EPERM") {
|
|
1878
|
+
console.error("Error in file watcher", e);
|
|
1957
1879
|
}
|
|
1958
1880
|
}
|
|
1959
1881
|
}
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1882
|
+
|
|
1883
|
+
// src/configManager.ts
|
|
1884
|
+
var {$: $3 } = globalThis.Bun;
|
|
1885
|
+
import { readdir as readdir2 } from "fs/promises";
|
|
1886
|
+
import { resolve as resolve2 } from "path";
|
|
1887
|
+
|
|
1888
|
+
// src/templates/output.ejs
|
|
1889
|
+
var output_default = "./assets/output.ejs";
|
|
1890
|
+
|
|
1891
|
+
// src/templates/index.ejs
|
|
1892
|
+
var templates_default = "./assets/index.ejs";
|
|
1893
|
+
|
|
1894
|
+
// src/bunClientHmr.ts
|
|
1895
|
+
function hotReload() {
|
|
1896
|
+
if (!window.BUN_DEV_SERVER) {
|
|
1897
|
+
window.BUN_DEV_SERVER = [];
|
|
1964
1898
|
}
|
|
1965
|
-
const
|
|
1966
|
-
const
|
|
1967
|
-
|
|
1968
|
-
|
|
1899
|
+
const devServer = "[Bun Dev Server]";
|
|
1900
|
+
const connectAddress = "[REPLACE_ENDPOINT]";
|
|
1901
|
+
let foundServer = window.BUN_DEV_SERVER.find((server) => server.url === connectAddress);
|
|
1902
|
+
if (!foundServer) {
|
|
1903
|
+
foundServer = { url: connectAddress, socket: null };
|
|
1969
1904
|
}
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1905
|
+
if (foundServer.socket) {
|
|
1906
|
+
return;
|
|
1907
|
+
}
|
|
1908
|
+
console.log(devServer, "Connecting to Bun Dev Server at", connectAddress);
|
|
1909
|
+
foundServer.socket = new WebSocket(connectAddress);
|
|
1910
|
+
window.BUN_DEV_SERVER.push(foundServer);
|
|
1911
|
+
function errorHandler(err) {
|
|
1912
|
+
console.error(devServer, "ERROR", err);
|
|
1913
|
+
}
|
|
1914
|
+
function messageHandler(msg) {
|
|
1915
|
+
let parsed = msg.data;
|
|
1977
1916
|
try {
|
|
1978
|
-
|
|
1917
|
+
parsed = JSON.parse(msg.data);
|
|
1979
1918
|
} catch (e) {
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1919
|
+
}
|
|
1920
|
+
if (parsed?.type === "message") {
|
|
1921
|
+
console.log(devServer, parsed.message);
|
|
1922
|
+
return;
|
|
1923
|
+
}
|
|
1924
|
+
if (parsed?.type === "output") {
|
|
1925
|
+
console.table(devServer, parsed.message);
|
|
1926
|
+
return;
|
|
1927
|
+
}
|
|
1928
|
+
if (parsed?.type === "reload") {
|
|
1929
|
+
window.location.reload();
|
|
1930
|
+
return;
|
|
1931
|
+
}
|
|
1932
|
+
if (parsed?.type === "tscerror") {
|
|
1933
|
+
console.error(parsed.message);
|
|
1934
|
+
return;
|
|
1935
|
+
}
|
|
1936
|
+
if (parsed?.type === "error") {
|
|
1937
|
+
console.error(parsed.message);
|
|
1938
|
+
let newDiv = window.document.getElementById("bun-hmr-error");
|
|
1939
|
+
const divExists = !!newDiv;
|
|
1940
|
+
if (!newDiv) {
|
|
1941
|
+
newDiv = window.document.createElement("div");
|
|
1942
|
+
}
|
|
1943
|
+
newDiv.id = "bun-hmr-error";
|
|
1944
|
+
newDiv.innerText += parsed.message;
|
|
1945
|
+
if (!divExists) {
|
|
1946
|
+
window.document.body.appendChild(newDiv);
|
|
1984
1947
|
}
|
|
1948
|
+
return;
|
|
1985
1949
|
}
|
|
1986
|
-
}
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1950
|
+
}
|
|
1951
|
+
function closeHandler(ev) {
|
|
1952
|
+
console.warn(devServer, "Connection closed. Will retry in 5 seconds...");
|
|
1953
|
+
foundServer.socket?.removeEventListener("error", errorHandler);
|
|
1954
|
+
foundServer.socket?.removeEventListener("message", messageHandler);
|
|
1955
|
+
foundServer.socket?.removeEventListener("open", messageHandler);
|
|
1956
|
+
foundServer.socket?.removeEventListener("close", closeHandler);
|
|
1957
|
+
foundServer.socket = null;
|
|
1958
|
+
setTimeout(function() {
|
|
1959
|
+
console.log(devServer, "Attempting to reconnect...");
|
|
1960
|
+
hotReload();
|
|
1961
|
+
}, 5000);
|
|
1962
|
+
}
|
|
1963
|
+
function openHandler(ev) {
|
|
1964
|
+
console.log(devServer, "Connected to Bun Dev Server");
|
|
1965
|
+
}
|
|
1966
|
+
foundServer.socket.addEventListener("error", errorHandler);
|
|
1967
|
+
foundServer.socket.addEventListener("message", messageHandler);
|
|
1968
|
+
foundServer.socket.addEventListener("close", closeHandler);
|
|
1969
|
+
foundServer.socket.addEventListener("open", openHandler);
|
|
1970
|
+
}
|
|
1971
|
+
var DEFAULT_HMR_PATH = "/hmr-ws";
|
|
1972
|
+
function bunHotReload(bunServerConfig) {
|
|
1973
|
+
const socketPath = bunServerConfig.websocketPath || DEFAULT_HMR_PATH;
|
|
1974
|
+
const endPath = socketPath.startsWith("/") ? socketPath : `/${socketPath}`;
|
|
1975
|
+
const path = `${bunServerConfig.secure ? "wss" : "ws"}://localhost:${bunServerConfig.port}${endPath}`;
|
|
1976
|
+
return hotReload.toString().replace("[REPLACE_ENDPOINT]", path);
|
|
1977
|
+
}
|
|
1978
|
+
|
|
1979
|
+
// src/bunHmrPlugin.ts
|
|
1980
|
+
import { readFile as readFile2 } from "fs/promises";
|
|
1981
|
+
function bunHotReloadPlugin(config) {
|
|
1982
|
+
const bunHMRPlugin = {
|
|
1983
|
+
name: "hmr",
|
|
1984
|
+
target: "browser",
|
|
1985
|
+
setup(build2) {
|
|
1986
|
+
const entryPoints = [];
|
|
1987
|
+
const addedEnryPoints = new Set;
|
|
1988
|
+
build2.config.entrypoints.forEach((entry) => {
|
|
1989
|
+
let entryPath = entry.replace(/^\.*/, "");
|
|
1990
|
+
if (process.platform === "win32") {
|
|
1991
|
+
entryPath = entryPath.replace(/\//g, "\\");
|
|
1992
|
+
}
|
|
1993
|
+
entryPoints.push(entryPath);
|
|
1994
|
+
});
|
|
1995
|
+
build2.onLoad({ filter: /\.m?(t|j)sx?/ }, async (args) => {
|
|
1996
|
+
const contents = await readFile2(args.path, { encoding: "utf-8" });
|
|
1997
|
+
const isTSx = /\.m?tsx$/.test(args.path);
|
|
1998
|
+
const isJSx = /\.m?jsx$/.test(args.path);
|
|
1999
|
+
const isJS = /\.m?js$/.test(args.path);
|
|
2000
|
+
const isTS = /\.m?ts$/.test(args.path);
|
|
2001
|
+
const loader = isTSx ? "tsx" : isJSx ? "jsx" : isTS ? "ts" : isJS ? "js" : "text";
|
|
2002
|
+
const isEntry = entryPoints.some((entry) => args.path.endsWith(entry));
|
|
2003
|
+
if (!addedEnryPoints.has(args.path) && isEntry) {
|
|
2004
|
+
addedEnryPoints.add(args.path);
|
|
2005
|
+
return { contents: `import "bun-hot-reload"
|
|
2006
|
+
` + contents, loader };
|
|
2007
|
+
}
|
|
2008
|
+
return { contents, loader };
|
|
2009
|
+
});
|
|
2010
|
+
build2.onLoad({ filter: /./, namespace: "bun-hot-reload" }, async (args) => {
|
|
2011
|
+
return { contents: `(${bunHotReload(config)})()
|
|
2012
|
+
`, loader: "ts" };
|
|
2013
|
+
});
|
|
2014
|
+
build2.onResolve({ filter: /^bun-hot-reload$/ }, (args) => {
|
|
2015
|
+
return { path: args.path, namespace: "bun-hot-reload" };
|
|
2016
|
+
});
|
|
1990
2017
|
}
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
2018
|
+
};
|
|
2019
|
+
return bunHMRPlugin;
|
|
2020
|
+
}
|
|
2021
|
+
function getBunHMRFooter(config) {
|
|
2022
|
+
return `;(${bunHotReload(config)})();`;
|
|
2023
|
+
}
|
|
2024
|
+
|
|
2025
|
+
// src/configManager.ts
|
|
2026
|
+
var serveTemplate = await Bun.file(Bun.fileURLToPath(import.meta.resolve(output_default))).text();
|
|
2027
|
+
var indexTemplate = await Bun.file(Bun.fileURLToPath(import.meta.resolve(templates_default))).text();
|
|
2028
|
+
async function prepareConfiguration(serverConfig, importMeta) {
|
|
2029
|
+
const defaultConfig = {
|
|
2030
|
+
port: 3000,
|
|
2031
|
+
websocketPath: DEFAULT_HMR_PATH,
|
|
2032
|
+
serveOutputEjs: serveTemplate,
|
|
2033
|
+
serveIndexHtmlEjs: indexTemplate,
|
|
2034
|
+
createIndexHTML: true,
|
|
2035
|
+
tscConfigPath: resolve2(importMeta.dir, "./tsconfig.json"),
|
|
2036
|
+
broadcastBuildOutputToConsole: true,
|
|
2037
|
+
broadcastBuildOutputToClient: true
|
|
2038
|
+
};
|
|
2039
|
+
const finalConfig = { ...defaultConfig, ...serverConfig };
|
|
2040
|
+
if (serverConfig.tscConfigPath) {
|
|
2041
|
+
finalConfig.tscConfigPath = resolve2(importMeta.dir, serverConfig.tscConfigPath);
|
|
1994
2042
|
}
|
|
1995
|
-
if (!
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2043
|
+
if (!finalConfig.watchDir) {
|
|
2044
|
+
throw new Error("watchDir must be set");
|
|
2045
|
+
}
|
|
2046
|
+
const servePart = finalConfig.buildConfig.outdir ?? finalConfig.servePath ?? "./dist";
|
|
2047
|
+
const serveDestination = resolve2(importMeta.dir, servePart);
|
|
2048
|
+
const watchDestination = resolve2(importMeta.dir, finalConfig.watchDir);
|
|
2049
|
+
const allEntries = serverConfig.buildConfig.entrypoints.splice(0, serverConfig.buildConfig.entrypoints.length);
|
|
2050
|
+
const resolvedEntries = allEntries.map((e) => resolve2(importMeta.dir, e));
|
|
2051
|
+
serverConfig.buildConfig.entrypoints = resolvedEntries;
|
|
2052
|
+
const destinationPath = serveDestination;
|
|
2053
|
+
const srcWatch = watchDestination;
|
|
2054
|
+
await ensureDestinationDirectory(destinationPath);
|
|
2055
|
+
const buncfg = {
|
|
2056
|
+
port: finalConfig.port,
|
|
2057
|
+
tls: finalConfig.tls,
|
|
2058
|
+
websocketPath: finalConfig.websocketPath,
|
|
2059
|
+
secure: finalConfig.tls !== undefined
|
|
2060
|
+
};
|
|
2061
|
+
const buildCfg = {
|
|
2062
|
+
...serverConfig.buildConfig,
|
|
2063
|
+
outdir: destinationPath
|
|
2064
|
+
};
|
|
2065
|
+
if (finalConfig.hotReload === "footer") {
|
|
2066
|
+
if (!buildCfg.footer) {
|
|
2067
|
+
buildCfg.footer = "";
|
|
2007
2068
|
}
|
|
2069
|
+
buildCfg.footer += getBunHMRFooter(buncfg);
|
|
2008
2070
|
}
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
}
|
|
2013
|
-
|
|
2014
|
-
return {
|
|
2015
|
-
requestPath: requestPath === "/" ? "" : requestPath,
|
|
2016
|
-
name: entry.name
|
|
2017
|
-
};
|
|
2018
|
-
});
|
|
2019
|
-
const files = allEntries.filter((entry) => entry.isFile()).map((entry) => {
|
|
2020
|
-
return {
|
|
2021
|
-
requestPath: requestPath === "/" ? "" : requestPath,
|
|
2022
|
-
name: entry.name
|
|
2023
|
-
};
|
|
2024
|
-
});
|
|
2025
|
-
const rnd = import_ejs.render(finalConfig.serveOutputEjs, { dirs, files });
|
|
2026
|
-
finalConfig.logRequests && console.log(`${200} ${req.url}`);
|
|
2027
|
-
return withCORSHeaders(new Response(rnd, { headers: { "Content-Type": "text/html" } }), req);
|
|
2028
|
-
} catch (err) {
|
|
2029
|
-
return handleErrorResponse(req, err);
|
|
2071
|
+
if (finalConfig.hotReload === "plugin") {
|
|
2072
|
+
if (!buildCfg.plugins) {
|
|
2073
|
+
buildCfg.plugins = [];
|
|
2074
|
+
}
|
|
2075
|
+
buildCfg.plugins.push(bunHotReloadPlugin(buncfg));
|
|
2030
2076
|
}
|
|
2077
|
+
const userBeforeBuild = finalConfig.beforeBuild;
|
|
2078
|
+
finalConfig.beforeBuild = async (env) => {
|
|
2079
|
+
if (serverConfig.cleanServePath) {
|
|
2080
|
+
await cleanDirectory(env.destinationPath);
|
|
2081
|
+
}
|
|
2082
|
+
await userBeforeBuild?.(env);
|
|
2083
|
+
};
|
|
2084
|
+
return {
|
|
2085
|
+
finalConfig,
|
|
2086
|
+
destinationPath,
|
|
2087
|
+
srcWatch,
|
|
2088
|
+
buildCfg
|
|
2089
|
+
};
|
|
2031
2090
|
}
|
|
2032
|
-
async function
|
|
2091
|
+
async function ensureDestinationDirectory(destinationPath) {
|
|
2033
2092
|
try {
|
|
2034
|
-
await
|
|
2035
|
-
return true;
|
|
2093
|
+
await readdir2(destinationPath);
|
|
2036
2094
|
} catch (e) {
|
|
2037
|
-
if (e
|
|
2038
|
-
|
|
2095
|
+
if (e.code === "ENOENT") {
|
|
2096
|
+
console.log("Directory not found, creating it...");
|
|
2097
|
+
try {
|
|
2098
|
+
await $3`mkdir ${destinationPath}`;
|
|
2099
|
+
} catch (e2) {
|
|
2100
|
+
console.error("Unable to create directory", e2);
|
|
2101
|
+
}
|
|
2102
|
+
} else {
|
|
2103
|
+
throw e;
|
|
2039
2104
|
}
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2105
|
+
}
|
|
2106
|
+
}
|
|
2107
|
+
|
|
2108
|
+
// src/server.ts
|
|
2109
|
+
async function startBunDevServer(serverConfig, importMeta) {
|
|
2110
|
+
const { finalConfig, destinationPath, srcWatch, buildCfg } = await prepareConfiguration(serverConfig, importMeta);
|
|
2111
|
+
const protocol = finalConfig.tls ? "https" : "http";
|
|
2112
|
+
const serverUrl = `${protocol}://localhost:${finalConfig.port}`;
|
|
2113
|
+
const isTestMode = process.env.BUN_TEST === "true" || typeof Bun !== "undefined" && Bun.main.includes("test");
|
|
2114
|
+
if (!isTestMode) {
|
|
2115
|
+
console.log(import_picocolors3.default.bold(import_picocolors3.default.green("\uD83D\uDE80 Server running at")) + " " + import_picocolors3.default.cyan(import_picocolors3.default.underline(serverUrl)));
|
|
2116
|
+
}
|
|
2117
|
+
let bunServer;
|
|
2118
|
+
try {
|
|
2119
|
+
bunServer = Bun.serve({
|
|
2120
|
+
port: finalConfig.port,
|
|
2121
|
+
development: {
|
|
2122
|
+
console: true,
|
|
2123
|
+
hmr: true,
|
|
2124
|
+
chromeDevToolsAutomaticWorkspaceFolders: true
|
|
2125
|
+
},
|
|
2126
|
+
tls: finalConfig.tls,
|
|
2127
|
+
routes: {
|
|
2128
|
+
"/favicon.ico": withCORSHeaders(new Response("", { status: 404 })),
|
|
2129
|
+
...finalConfig.routes,
|
|
2130
|
+
...staticAssetRoutes
|
|
2131
|
+
},
|
|
2132
|
+
async fetch(req, server) {
|
|
2133
|
+
if (req.method === "OPTIONS") {
|
|
2134
|
+
finalConfig.logRequests && console.log(`${200} ${req.url} OPTIONS`);
|
|
2135
|
+
return withCORSHeaders(new Response("", { status: 200 }), req);
|
|
2136
|
+
}
|
|
2137
|
+
if (req.url.toLowerCase().endsWith(finalConfig.websocketPath)) {
|
|
2138
|
+
finalConfig.logRequests && console.log(`${req.url} Socket Upgrade`);
|
|
2139
|
+
if (server.upgrade(req)) {
|
|
2140
|
+
return withCORSHeaders(new Response("", { status: 200 }), req);
|
|
2141
|
+
}
|
|
2142
|
+
}
|
|
2143
|
+
const url = new URL(req.url);
|
|
2144
|
+
let requestPath = url.pathname;
|
|
2145
|
+
return handlePathRequest(requestPath, req, finalConfig, destinationPath);
|
|
2146
|
+
},
|
|
2147
|
+
websocket: {
|
|
2148
|
+
open(ws) {
|
|
2149
|
+
ws.subscribe("message");
|
|
2150
|
+
},
|
|
2151
|
+
message(ws, message) {
|
|
2152
|
+
},
|
|
2153
|
+
sendPings: true
|
|
2154
|
+
}
|
|
2155
|
+
});
|
|
2156
|
+
} catch (error) {
|
|
2157
|
+
if (isTestMode) {
|
|
2158
|
+
return;
|
|
2159
|
+
}
|
|
2160
|
+
throw error;
|
|
2161
|
+
}
|
|
2162
|
+
if (bunServer) {
|
|
2163
|
+
await startFileWatcher(srcWatch, importMeta, finalConfig, destinationPath, buildCfg, bunServer);
|
|
2043
2164
|
}
|
|
2044
2165
|
}
|
|
2045
2166
|
export {
|