bun-dev-server 0.4.0 → 0.6.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.
@@ -1,13 +1,20 @@
1
1
  import { type BuildConfig, type TLSOptions } from "bun";
2
- export interface BunDevServerConfig extends Partial<BunDevServerSocketConfig> {
2
+ export interface BunDevServerConfig extends Partial<BunServeConfig> {
3
3
  port: number;
4
4
  buildConfig: BuildConfig;
5
5
  watchDir: string;
6
+ /**
7
+ * The delay in milliseconds to wait before starting a new build once a file has changed.
8
+ * Used in debounce function, in case many changes happen in file system at once
9
+ * @default 1000
10
+ */
11
+ watchDelay?: number;
6
12
  enableTSC?: boolean;
7
13
  writeManifest?: boolean;
8
14
  manifestName?: string;
9
15
  manifestWithHash?: boolean;
10
16
  hotReload?: "plugin" | "footer";
17
+ logRequests?: boolean;
11
18
  reloadOnChange?: boolean;
12
19
  /**
13
20
  * The path to the directory to serve files from.
@@ -19,8 +26,9 @@ export interface BunDevServerConfig extends Partial<BunDevServerSocketConfig> {
19
26
  serveOutputEjs?: string;
20
27
  serveOutputHtml?: string;
21
28
  }
22
- export interface BunDevServerSocketConfig {
29
+ export interface BunServeConfig {
23
30
  port: number;
24
31
  tls?: TLSOptions;
25
32
  websocketPath?: string;
33
+ static?: Record<`/${string}`, Response>;
26
34
  }
package/dist/index.js CHANGED
@@ -846,6 +846,84 @@ var require_picocolors = __commonJS((exports, module) => {
846
846
  module.exports.createColors = createColors;
847
847
  });
848
848
 
849
+ // node_modules/debounce/index.js
850
+ var require_debounce = __commonJS((exports, module) => {
851
+ function debounce(function_, wait = 100, options = {}) {
852
+ if (typeof function_ !== "function") {
853
+ throw new TypeError(`Expected the first parameter to be a function, got \`${typeof function_}\`.`);
854
+ }
855
+ if (wait < 0) {
856
+ throw new RangeError("`wait` must not be negative.");
857
+ }
858
+ const { immediate } = typeof options === "boolean" ? { immediate: options } : options;
859
+ let storedContext;
860
+ let storedArguments;
861
+ let timeoutId;
862
+ let timestamp;
863
+ let result;
864
+ function run() {
865
+ const callContext = storedContext;
866
+ const callArguments = storedArguments;
867
+ storedContext = undefined;
868
+ storedArguments = undefined;
869
+ result = function_.apply(callContext, callArguments);
870
+ return result;
871
+ }
872
+ function later() {
873
+ const last = Date.now() - timestamp;
874
+ if (last < wait && last >= 0) {
875
+ timeoutId = setTimeout(later, wait - last);
876
+ } else {
877
+ timeoutId = undefined;
878
+ if (!immediate) {
879
+ result = run();
880
+ }
881
+ }
882
+ }
883
+ const debounced = function(...arguments_) {
884
+ if (storedContext && this !== storedContext && Object.getPrototypeOf(this) === Object.getPrototypeOf(storedContext)) {
885
+ throw new Error("Debounced method called with different contexts of the same prototype.");
886
+ }
887
+ storedContext = this;
888
+ storedArguments = arguments_;
889
+ timestamp = Date.now();
890
+ const callNow = immediate && !timeoutId;
891
+ if (!timeoutId) {
892
+ timeoutId = setTimeout(later, wait);
893
+ }
894
+ if (callNow) {
895
+ result = run();
896
+ }
897
+ return result;
898
+ };
899
+ Object.defineProperty(debounced, "isPending", {
900
+ get() {
901
+ return timeoutId !== undefined;
902
+ }
903
+ });
904
+ debounced.clear = () => {
905
+ if (!timeoutId) {
906
+ return;
907
+ }
908
+ clearTimeout(timeoutId);
909
+ timeoutId = undefined;
910
+ };
911
+ debounced.flush = () => {
912
+ if (!timeoutId) {
913
+ return;
914
+ }
915
+ debounced.trigger();
916
+ };
917
+ debounced.trigger = () => {
918
+ result = run();
919
+ debounced.clear();
920
+ };
921
+ return debounced;
922
+ }
923
+ exports.debounce = debounce;
924
+ module.exports = debounce;
925
+ });
926
+
849
927
  // src/server.ts
850
928
  var import_ejs = __toESM(require_ejs(), 1);
851
929
  var Bun = globalThis.Bun;
@@ -888,30 +966,40 @@ var indexHTMLTemplate_default = `<!DOCTYPE html>\r
888
966
  `;
889
967
 
890
968
  // src/server.ts
891
- import { watch, readdir, exists, readFile as readFile2 } from "fs/promises";
969
+ import { watch, readdir, access, readFile as readFile2, constants } from "fs/promises";
892
970
 
893
971
  // src/bunClientHmr.ts
894
972
  function hotReload() {
895
- if (window.BUN_HMR_INITED) {
973
+ if (!window.BUN_DEV_SERVER) {
974
+ window.BUN_DEV_SERVER = [];
975
+ }
976
+ const devServer = "[Bun Dev Server]";
977
+ const connectAddress = "[REPLACE_ENDPOINT]";
978
+ let foundServer = window.BUN_DEV_SERVER.find((server) => server.url === connectAddress);
979
+ if (!foundServer) {
980
+ foundServer = { url: connectAddress, socket: null };
981
+ }
982
+ if (foundServer.socket) {
896
983
  return;
897
984
  }
898
- window.BUN_HMR_INITED = true;
899
- const hmrSock = new WebSocket("[REPLACE_ENDPOINT]");
900
- hmrSock.addEventListener("error", (err) => {
901
- console.error("HMR ERROR", err);
902
- });
903
- hmrSock.addEventListener("message", (msg) => {
985
+ console.log(devServer, "Connecting to Bun Dev Server at", connectAddress);
986
+ foundServer.socket = new WebSocket(connectAddress);
987
+ window.BUN_DEV_SERVER.push(foundServer);
988
+ function errorHandler(err) {
989
+ console.error(devServer, "ERROR", err);
990
+ }
991
+ function messageHandler(msg) {
904
992
  let parsed = msg.data;
905
993
  try {
906
994
  parsed = JSON.parse(msg.data);
907
995
  } catch (e) {
908
996
  }
909
997
  if (parsed?.type === "message") {
910
- console.log(parsed.message);
998
+ console.log(devServer, parsed.message);
911
999
  return;
912
1000
  }
913
1001
  if (parsed?.type === "output") {
914
- console.table(parsed.message);
1002
+ console.table(devServer, parsed.message);
915
1003
  return;
916
1004
  }
917
1005
  if (parsed?.type === "reload") {
@@ -932,7 +1020,26 @@ function hotReload() {
932
1020
  }
933
1021
  return;
934
1022
  }
935
- });
1023
+ }
1024
+ function closeHandler(ev) {
1025
+ console.warn(devServer, "Connection closed. Will retry in 5 seconds...");
1026
+ foundServer.socket?.removeEventListener("error", errorHandler);
1027
+ foundServer.socket?.removeEventListener("message", messageHandler);
1028
+ foundServer.socket?.removeEventListener("open", messageHandler);
1029
+ foundServer.socket?.removeEventListener("close", closeHandler);
1030
+ foundServer.socket = null;
1031
+ setTimeout(function() {
1032
+ console.log(devServer, "Attempting to reconnect...");
1033
+ hotReload();
1034
+ }, 5000);
1035
+ }
1036
+ function openHandler(ev) {
1037
+ console.log(devServer, "Connected to Bun Dev Server");
1038
+ }
1039
+ foundServer.socket.addEventListener("error", errorHandler);
1040
+ foundServer.socket.addEventListener("message", messageHandler);
1041
+ foundServer.socket.addEventListener("close", closeHandler);
1042
+ foundServer.socket.addEventListener("open", openHandler);
936
1043
  }
937
1044
  var DEFAULT_HMR_PATH = "/hmr-ws";
938
1045
  function bunHotReload(bunServerConfig) {
@@ -1013,14 +1120,19 @@ async function performTSC(finalConfig) {
1013
1120
  const tsc = await $`tsc`.nothrow().quiet();
1014
1121
  if (tsc.exitCode === 0) {
1015
1122
  console.log(import_picocolors.default.bgGreen("\u2714 [SUCCESS]"), "TSC check passed");
1123
+ return true;
1016
1124
  } else {
1017
1125
  console.log(import_picocolors.default.bgRed("\u2718 [ERROR]"), `\r
1018
1126
  ${tsc.stdout.toString()}`);
1127
+ return false;
1019
1128
  }
1020
1129
  }
1130
+ return true;
1021
1131
  }
1022
1132
 
1023
1133
  // src/server.ts
1134
+ var import_debounce = __toESM(require_debounce(), 1);
1135
+ var watchDelay = 1000;
1024
1136
  async function startBunDevServer(serverConfig) {
1025
1137
  const defaultConfig = {
1026
1138
  port: 3000,
@@ -1029,20 +1141,23 @@ async function startBunDevServer(serverConfig) {
1029
1141
  serveOutputHtml: indexHTMLTemplate_default
1030
1142
  };
1031
1143
  const finalConfig = { ...defaultConfig, ...serverConfig };
1144
+ if (finalConfig.watchDelay) {
1145
+ watchDelay = finalConfig.watchDelay;
1146
+ }
1032
1147
  if (!finalConfig.watchDir) {
1033
1148
  throw new Error("watchDir must be set");
1034
1149
  }
1035
1150
  const serveDestination = finalConfig.buildConfig.outdir ?? finalConfig.servePath ?? "dist";
1036
1151
  const bunDestinationPath = Bun.pathToFileURL(serveDestination);
1037
1152
  const bunWatchDirPath = Bun.pathToFileURL(finalConfig.watchDir);
1038
- const dst = process.platform === "win32" ? bunDestinationPath.pathname.substring(1) : bunDestinationPath.pathname;
1153
+ const destinationPath = process.platform === "win32" ? bunDestinationPath.pathname.substring(1) : bunDestinationPath.pathname;
1039
1154
  const srcWatch = process.platform === "win32" ? bunWatchDirPath.pathname.substring(1) : bunWatchDirPath.pathname;
1040
1155
  try {
1041
- await readdir(dst);
1156
+ await readdir(destinationPath);
1042
1157
  } catch (e) {
1043
1158
  if (e.code === "ENOENT") {
1044
1159
  console.log("Directory not found, creating it...");
1045
- await $2`mkdir ${dst}`;
1160
+ await $2`mkdir ${destinationPath}`;
1046
1161
  } else {
1047
1162
  throw e;
1048
1163
  }
@@ -1050,7 +1165,7 @@ async function startBunDevServer(serverConfig) {
1050
1165
  const buncfg = { port: finalConfig.port, tls: finalConfig.tls, websocketPath: finalConfig.websocketPath };
1051
1166
  const buildCfg = {
1052
1167
  ...serverConfig.buildConfig,
1053
- outdir: dst
1168
+ outdir: destinationPath
1054
1169
  };
1055
1170
  if (finalConfig.hotReload === "footer") {
1056
1171
  if (!buildCfg.footer) {
@@ -1065,89 +1180,34 @@ async function startBunDevServer(serverConfig) {
1065
1180
  buildCfg.plugins.push(bunHotReloadPlugin(buncfg));
1066
1181
  }
1067
1182
  if (serverConfig.cleanServePath) {
1068
- await cleanDirectory(dst);
1183
+ await cleanDirectory(destinationPath);
1069
1184
  }
1070
1185
  console.log("Starting Bun Dev Server on port", finalConfig.port);
1071
1186
  const bunServer = Bun.serve({
1072
1187
  port: finalConfig.port,
1073
1188
  development: true,
1074
1189
  tls: finalConfig.tls,
1190
+ static: {
1191
+ "/favicon.ico": withCORSHeaders(new Response("", { status: 404 })),
1192
+ ...finalConfig.static
1193
+ },
1075
1194
  async fetch(req, server) {
1076
1195
  if (req.method === "OPTIONS") {
1077
- const response = new Response("", { status: 200 });
1078
- augumentHeaders(req, response);
1079
- return response;
1080
- }
1081
- if (req.url.toLowerCase().endsWith("/favicon.ico")) {
1082
- const response = new Response("", { status: 404 });
1083
- augumentHeaders(req, response);
1084
- return response;
1196
+ finalConfig.logRequests && console.log(`${200} ${req.url} OPTIONS`);
1197
+ return withCORSHeaders(new Response("", { status: 200 }), req);
1085
1198
  }
1086
1199
  if (req.url.toLowerCase().endsWith(finalConfig.websocketPath)) {
1200
+ finalConfig.logRequests && console.log(`${req.url} Socket Upgrade`);
1087
1201
  if (server.upgrade(req)) {
1088
1202
  return;
1089
1203
  }
1090
1204
  }
1091
1205
  const url = new URL(req.url);
1092
- const requestPath = url.pathname;
1093
- const objThere = await exists(dst + requestPath);
1094
- let isDirectory = false;
1095
- if (objThere) {
1096
- try {
1097
- await readFile2(dst + requestPath);
1098
- } catch (e) {
1099
- if (e.code === "EISDIR") {
1100
- isDirectory = true;
1101
- } else {
1102
- throw e;
1103
- }
1104
- }
1105
- } else {
1106
- const response = new Response("", { status: 404 });
1107
- augumentHeaders(req, response);
1108
- return response;
1109
- }
1110
- if (!isDirectory) {
1111
- try {
1112
- const fl = Bun.file(dst + requestPath);
1113
- const response = new Response(fl);
1114
- augumentHeaders(req, response);
1115
- return response;
1116
- } catch (e) {
1117
- if (e.code === "ENOENT") {
1118
- const response = new Response("", { status: 404 });
1119
- augumentHeaders(req, response);
1120
- return response;
1121
- } else {
1122
- throw e;
1123
- }
1124
- }
1125
- }
1126
- try {
1127
- const allEntries = await readdir(dst + requestPath, {
1128
- withFileTypes: true
1129
- });
1130
- const dirs = allEntries.filter((entry) => entry.isDirectory()).map((entry) => {
1131
- return {
1132
- requestPath: requestPath === "/" ? "" : requestPath,
1133
- name: entry.name
1134
- };
1135
- });
1136
- const files = allEntries.filter((entry) => entry.isFile()).map((entry) => {
1137
- return {
1138
- requestPath: requestPath === "/" ? "" : requestPath,
1139
- name: entry.name
1140
- };
1141
- });
1142
- const rnd = import_ejs.render(finalConfig.serveOutputEjs, { dirs, files });
1143
- const response = new Response(rnd, { headers: { "Content-Type": "text/html" } });
1144
- augumentHeaders(req, response);
1145
- return response;
1146
- } catch {
1147
- const response = new Response("Not Found", { status: 404 });
1148
- augumentHeaders(req, response);
1149
- return response;
1206
+ let requestPath = url.pathname;
1207
+ if (requestPath.toLowerCase() === "/index.html") {
1208
+ requestPath = "/";
1150
1209
  }
1210
+ return handlePathRequest(requestPath, req, finalConfig, destinationPath);
1151
1211
  },
1152
1212
  websocket: {
1153
1213
  open(ws) {
@@ -1158,60 +1218,63 @@ async function startBunDevServer(serverConfig) {
1158
1218
  sendPings: true
1159
1219
  }
1160
1220
  });
1161
- const output = await Bun.build(buildCfg);
1162
- publishOutputLogs(output, { filename: "Initial", eventType: "change" });
1163
- publishIndexHTML(output, { filename: "Initial", eventType: "change" });
1164
- if (finalConfig.writeManifest) {
1165
- writeManifest(output, dst, finalConfig.manifestWithHash, finalConfig.manifestName);
1166
- }
1167
- await performTSC(finalConfig);
1221
+ debouncedbuildAndNotify(finalConfig, destinationPath, buildCfg, bunServer, { filename: "Initial", eventType: "change" });
1168
1222
  const watcher = watch(srcWatch, { recursive: true });
1169
1223
  for await (const event of watcher) {
1170
- if (finalConfig.cleanServePath) {
1171
- await cleanDirectory(dst);
1172
- }
1173
- const output2 = await Bun.build(buildCfg);
1174
- publishOutputLogs(output2, event);
1175
- publishIndexHTML(output2, event);
1176
- if (finalConfig.writeManifest) {
1177
- writeManifest(output2, dst, finalConfig.manifestWithHash, finalConfig.manifestName);
1178
- }
1179
- await performTSC(finalConfig);
1180
- if (finalConfig.reloadOnChange) {
1181
- bunServer.publish("message", JSON.stringify({ type: "reload" }));
1182
- }
1224
+ debouncedbuildAndNotify(finalConfig, destinationPath, buildCfg, bunServer, event);
1183
1225
  }
1184
- function publishOutputLogs(output2, event) {
1185
- output2.logs.forEach(console.log);
1186
- bunServer.publish("message", JSON.stringify({ type: "message", message: `[Bun HMR] ${event.filename} ${event.eventType}` }));
1187
- const outTable = output2.outputs.filter((o) => o.kind !== "sourcemap").map((o) => {
1188
- const a = Bun.pathToFileURL(o.path);
1189
- const fileName = a.href.substring(a.href.lastIndexOf("/") + 1);
1190
- return {
1191
- name: fileName,
1192
- path: o.path,
1193
- size: convertBytes(o.size)
1194
- };
1195
- });
1196
- console.table(outTable);
1197
- bunServer.publish("message", JSON.stringify({ type: "output", message: outTable }));
1226
+ }
1227
+ var debouncedbuildAndNotify = import_debounce.default(async (finalConfig, destinationPath, buildCfg, bunServer, event) => {
1228
+ if (finalConfig.cleanServePath) {
1229
+ await cleanDirectory(destinationPath);
1198
1230
  }
1199
- function publishIndexHTML(output2, event) {
1200
- const eps = output2.outputs.filter((o) => o.kind === "entry-point");
1201
- const hashedImports = [];
1202
- for (const ep of eps) {
1203
- const basePathUrl = Bun.pathToFileURL(dst);
1204
- const epUrl = Bun.pathToFileURL(ep.path);
1205
- const hashedImport = `${epUrl.href.replace(basePathUrl.href, "")}?${ep.hash}`;
1206
- hashedImports.push(hashedImport);
1207
- }
1208
- Bun.write(dst + "/index.html", import_ejs.render(finalConfig.serveOutputHtml, { hashedImports }));
1231
+ const output = await Bun.build(buildCfg);
1232
+ publishOutputLogs(bunServer, output, event);
1233
+ publishIndexHTML(destinationPath, finalConfig.serveOutputHtml, output, event);
1234
+ if (finalConfig.writeManifest) {
1235
+ writeManifest(output, destinationPath, finalConfig.manifestWithHash, finalConfig.manifestName);
1209
1236
  }
1237
+ const tscSuccess = await performTSC(finalConfig);
1238
+ if (finalConfig.reloadOnChange && tscSuccess) {
1239
+ bunServer.publish("message", JSON.stringify({ type: "reload" }));
1240
+ }
1241
+ }, watchDelay, { immediate: true });
1242
+ function handleErrorResponse(req, err) {
1243
+ const msg = `Error while processing request ${req.url}`;
1244
+ console.error(msg, err);
1245
+ return withCORSHeaders(new Response(msg, { status: 500 }), req);
1246
+ }
1247
+ function publishOutputLogs(bunServer, output, event) {
1248
+ output.logs.forEach(console.log);
1249
+ bunServer.publish("message", JSON.stringify({ type: "message", message: `[Bun HMR] ${event.filename} ${event.eventType}` }));
1250
+ const outTable = output.outputs.filter((o) => o.kind !== "sourcemap").map((o) => {
1251
+ const a = Bun.pathToFileURL(o.path);
1252
+ const fileName = a.href.substring(a.href.lastIndexOf("/") + 1);
1253
+ return {
1254
+ name: fileName,
1255
+ path: o.path,
1256
+ size: convertBytes(o.size)
1257
+ };
1258
+ });
1259
+ console.table(outTable);
1260
+ bunServer.publish("message", JSON.stringify({ type: "output", message: outTable }));
1261
+ }
1262
+ function publishIndexHTML(destinationPath, template, output, _event) {
1263
+ const eps = output.outputs.filter((o) => o.kind === "entry-point");
1264
+ const hashedImports = [];
1265
+ for (const ep of eps) {
1266
+ const basePathUrl = Bun.pathToFileURL(destinationPath);
1267
+ const epUrl = Bun.pathToFileURL(ep.path);
1268
+ const hashedImport = `${epUrl.href.replace(basePathUrl.href, "")}?${ep.hash}`;
1269
+ hashedImports.push(hashedImport);
1270
+ }
1271
+ Bun.write(destinationPath + "/index.html", import_ejs.render(template, { hashedImports }));
1210
1272
  }
1211
- function augumentHeaders(request, response) {
1212
- response.headers.set("Access-Control-Allow-Origin", request.headers.get("origin") ?? "*");
1213
- response.headers.set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
1273
+ function withCORSHeaders(response, request) {
1274
+ response.headers.set("Access-Control-Allow-Origin", request?.headers.get("origin") ?? "*");
1275
+ response.headers.set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH, OPTIONS");
1214
1276
  response.headers.set("Access-Control-Allow-Credentials", "true");
1277
+ return response;
1215
1278
  }
1216
1279
  async function cleanDirectory(dst) {
1217
1280
  const { stderr, exitCode } = await $2`rm -rf ${dst}/*`.nothrow();
@@ -1235,6 +1298,74 @@ function convertBytes(bytes) {
1235
1298
  }
1236
1299
  return (bytes / Math.pow(1024, i)).toFixed(1) + " " + sizes[i];
1237
1300
  }
1301
+ async function handlePathRequest(requestPath, req, finalConfig, destinationPath) {
1302
+ const fsPath = destinationPath + requestPath;
1303
+ const objThere = await checkObjectExists(fsPath, req);
1304
+ let isDirectory = false;
1305
+ if (objThere) {
1306
+ try {
1307
+ await readFile2(fsPath);
1308
+ } catch (e) {
1309
+ if (e.code === "EISDIR") {
1310
+ isDirectory = true;
1311
+ } else {
1312
+ throw e;
1313
+ }
1314
+ }
1315
+ } else {
1316
+ finalConfig.logRequests && console.log(`${404} ${req.url}`);
1317
+ return withCORSHeaders(new Response("", { status: 404 }), req);
1318
+ }
1319
+ if (!isDirectory) {
1320
+ try {
1321
+ const fl = Bun.file(fsPath);
1322
+ finalConfig.logRequests && console.log(`${200} ${req.url}`);
1323
+ return withCORSHeaders(new Response(fl), req);
1324
+ } catch (e) {
1325
+ if (e?.code === "ENOENT") {
1326
+ finalConfig.logRequests && console.log(`${404} ${req.url}`);
1327
+ return withCORSHeaders(new Response("", { status: 404 }), req);
1328
+ } else {
1329
+ return handleErrorResponse(req, e);
1330
+ }
1331
+ }
1332
+ }
1333
+ try {
1334
+ const allEntries = await readdir(fsPath, {
1335
+ withFileTypes: true
1336
+ });
1337
+ const dirs = allEntries.filter((entry) => entry.isDirectory()).map((entry) => {
1338
+ return {
1339
+ requestPath: requestPath === "/" ? "" : requestPath,
1340
+ name: entry.name
1341
+ };
1342
+ });
1343
+ const files = allEntries.filter((entry) => entry.isFile()).map((entry) => {
1344
+ return {
1345
+ requestPath: requestPath === "/" ? "" : requestPath,
1346
+ name: entry.name
1347
+ };
1348
+ });
1349
+ const rnd = import_ejs.render(finalConfig.serveOutputEjs, { dirs, files });
1350
+ finalConfig.logRequests && console.log(`${200} ${req.url}`);
1351
+ return withCORSHeaders(new Response(rnd, { headers: { "Content-Type": "text/html" } }), req);
1352
+ } catch (err) {
1353
+ return handleErrorResponse(req, err);
1354
+ }
1355
+ }
1356
+ async function checkObjectExists(fsPath, req) {
1357
+ try {
1358
+ await access(fsPath, constants.R_OK);
1359
+ return true;
1360
+ } catch (e) {
1361
+ if (e?.code === "ENOENT") {
1362
+ return false;
1363
+ }
1364
+ const msg = `Error while accessing path ${fsPath}`;
1365
+ console.error(msg, e);
1366
+ return false;
1367
+ }
1368
+ }
1238
1369
  export {
1239
1370
  startBunDevServer,
1240
1371
  getBunHMRFooter,
@@ -1,2 +1,2 @@
1
1
  import type { BunDevServerConfig } from "./bunServeConfig";
2
- export declare function performTSC(finalConfig: BunDevServerConfig): Promise<void>;
2
+ export declare function performTSC(finalConfig: BunDevServerConfig): Promise<boolean>;
package/package.json CHANGED
@@ -9,6 +9,8 @@
9
9
  "keywords": [
10
10
  "bun",
11
11
  "devserver",
12
+ "dev",
13
+ "server",
12
14
  "hmr",
13
15
  "reload",
14
16
  "hot"
@@ -19,22 +21,22 @@
19
21
  "exports": {
20
22
  ".": "./dist/index.js"
21
23
  },
22
- "version": "0.4.0",
24
+ "version": "0.6.0",
23
25
  "module": "index.ts",
24
26
  "type": "module",
25
27
  "license": "MIT",
26
28
  "scripts": {
27
- "serve": "bun --hot ./serve.ts"
29
+ "build": "bun run ./build.ts"
28
30
  },
29
31
  "devDependencies": {
30
- "@types/bun": "latest",
31
- "bun": "^1.1.36"
32
+ "@types/bun": "latest"
32
33
  },
33
34
  "peerDependencies": {
34
- "typescript": "^5.7.2"
35
+ "typescript": "^5.7.3"
35
36
  },
36
37
  "dependencies": {
37
38
  "@types/ejs": "^3.1.5",
39
+ "debounce": "^2.2.0",
38
40
  "ejs": "^3.1.10",
39
41
  "picocolors": "^1.1.1"
40
42
  }