bun-dev-server 0.9.8 → 0.9.82

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.
@@ -124,6 +124,30 @@ export interface BunDevServerConfig extends Partial<BunServeConfig> {
124
124
  * @param env Supplied environment for the build
125
125
  */
126
126
  afterBuild?: (output: BuildOutput, env: BuildEnv) => void;
127
+ /**
128
+ * throttle-debounce library options used internally to limit build execution.
129
+ */
130
+ throttleOptions?: {
131
+ /**
132
+ * Optional, defaults to `false`.
133
+ * If noTrailing is `true`, callback will only execute every delay milliseconds while the throttled-function is being called.
134
+ * If noTrailing is `false` or unspecified, callback will be executed one final time after the last throttled-function call.
135
+ * (After the throttled-function has not been called for delay milliseconds, the internal counter is reset)
136
+ */
137
+ noLeading?: boolean;
138
+ /**
139
+ * Optional, defaults to `false`.
140
+ * If noLeading is `false`, the first throttled-function call will execute callback immediately.
141
+ * If noLeading is `true`, the first the callback execution will be skipped.
142
+ * It should be noted that callback will never executed if both noLeading = `true` and noTrailing = `true`.
143
+ */
144
+ noTrailing?: boolean;
145
+ /**
146
+ * If debounceMode is `true` (at begin), schedule clear to execute after delay ms.
147
+ * If debounceMode is `false` (at end), schedule callback to execute after delay ms.
148
+ */
149
+ debounceMode?: boolean;
150
+ };
127
151
  }
128
152
  export interface BunServeConfig {
129
153
  port: number;
package/dist/index.js CHANGED
@@ -846,84 +846,6 @@ 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
-
927
849
  // src/server.ts
928
850
  var import_ejs = __toESM(require_ejs(), 1);
929
851
  var {$: $2 } = globalThis.Bun;
@@ -1142,9 +1064,60 @@ ${errOutput}`);
1142
1064
  return success;
1143
1065
  }
1144
1066
 
1067
+ // node_modules/throttle-debounce/esm/index.js
1068
+ function throttle(delay, callback, options) {
1069
+ var _ref = options || {}, _ref$noTrailing = _ref.noTrailing, noTrailing = _ref$noTrailing === undefined ? false : _ref$noTrailing, _ref$noLeading = _ref.noLeading, noLeading = _ref$noLeading === undefined ? false : _ref$noLeading, _ref$debounceMode = _ref.debounceMode, debounceMode = _ref$debounceMode === undefined ? undefined : _ref$debounceMode;
1070
+ var timeoutID;
1071
+ var cancelled = false;
1072
+ var lastExec = 0;
1073
+ function clearExistingTimeout() {
1074
+ if (timeoutID) {
1075
+ clearTimeout(timeoutID);
1076
+ }
1077
+ }
1078
+ function cancel(options2) {
1079
+ var _ref2 = options2 || {}, _ref2$upcomingOnly = _ref2.upcomingOnly, upcomingOnly = _ref2$upcomingOnly === undefined ? false : _ref2$upcomingOnly;
1080
+ clearExistingTimeout();
1081
+ cancelled = !upcomingOnly;
1082
+ }
1083
+ function wrapper() {
1084
+ for (var _len = arguments.length, arguments_ = new Array(_len), _key = 0;_key < _len; _key++) {
1085
+ arguments_[_key] = arguments[_key];
1086
+ }
1087
+ var self = this;
1088
+ var elapsed = Date.now() - lastExec;
1089
+ if (cancelled) {
1090
+ return;
1091
+ }
1092
+ function exec() {
1093
+ lastExec = Date.now();
1094
+ callback.apply(self, arguments_);
1095
+ }
1096
+ function clear() {
1097
+ timeoutID = undefined;
1098
+ }
1099
+ if (!noLeading && debounceMode && !timeoutID) {
1100
+ exec();
1101
+ }
1102
+ clearExistingTimeout();
1103
+ if (debounceMode === undefined && elapsed > delay) {
1104
+ if (noLeading) {
1105
+ lastExec = Date.now();
1106
+ if (!noTrailing) {
1107
+ timeoutID = setTimeout(debounceMode ? clear : exec, delay);
1108
+ }
1109
+ } else {
1110
+ exec();
1111
+ }
1112
+ } else if (noTrailing !== true) {
1113
+ timeoutID = setTimeout(debounceMode ? clear : exec, debounceMode === undefined ? delay - elapsed : delay);
1114
+ }
1115
+ }
1116
+ wrapper.cancel = cancel;
1117
+ return wrapper;
1118
+ }
1119
+
1145
1120
  // src/server.ts
1146
- var import_debounce = __toESM(require_debounce(), 1);
1147
- var watchDelay = 1000;
1148
1121
  async function startBunDevServer(serverConfig, importMeta) {
1149
1122
  const defaultConfig = {
1150
1123
  port: 3000,
@@ -1154,12 +1127,14 @@ async function startBunDevServer(serverConfig, importMeta) {
1154
1127
  createIndexHTML: true,
1155
1128
  tscConfigPath: resolve(importMeta.dir, "./tsconfig.json"),
1156
1129
  broadcastBuildOutputToConsole: true,
1157
- broadcastBuildOutputToClient: true
1130
+ broadcastBuildOutputToClient: true,
1131
+ throttleOptions: {
1132
+ noLeading: false,
1133
+ noTrailing: false,
1134
+ debounceMode: undefined
1135
+ }
1158
1136
  };
1159
1137
  const finalConfig = { ...defaultConfig, ...serverConfig };
1160
- if (finalConfig.watchDelay) {
1161
- watchDelay = finalConfig.watchDelay;
1162
- }
1163
1138
  if (serverConfig.tscConfigPath) {
1164
1139
  finalConfig.tscConfigPath = resolve(importMeta.dir, serverConfig.tscConfigPath);
1165
1140
  }
@@ -1241,49 +1216,52 @@ async function startBunDevServer(serverConfig, importMeta) {
1241
1216
  sendPings: true
1242
1217
  }
1243
1218
  });
1219
+ const debouncedbuildAndNotify = getThrottledBuildAndNotify(finalConfig);
1244
1220
  debouncedbuildAndNotify(importMeta, finalConfig, destinationPath, buildCfg, bunServer, { filename: "Initial", eventType: "change" });
1245
1221
  const watcher = watch(srcWatch, { recursive: true });
1246
1222
  for await (const event of watcher) {
1247
1223
  debouncedbuildAndNotify(importMeta, finalConfig, destinationPath, buildCfg, bunServer, event);
1248
1224
  }
1249
1225
  }
1250
- var debouncedbuildAndNotify = import_debounce.default(async (importerMeta, finalConfig, destinationPath, buildCfg, bunServer, event) => {
1251
- if (finalConfig.cleanServePath) {
1252
- await cleanDirectory(destinationPath);
1253
- }
1254
- const buildEnv = {
1255
- importerMeta,
1256
- finalConfig,
1257
- destinationPath,
1258
- buildCfg,
1259
- bunServer,
1260
- event
1261
- };
1262
- finalConfig.beforeBuild?.(buildEnv);
1263
- try {
1264
- const output = await Bun.build(buildCfg);
1265
- publishOutputLogs(bunServer, output, finalConfig, event);
1266
- if (finalConfig.createIndexHTML) {
1267
- publishIndexHTML(destinationPath, finalConfig.serveIndexHtmlEjs, output, event);
1226
+ function getThrottledBuildAndNotify(serverConfig) {
1227
+ return throttle(serverConfig.watchDelay ?? 1000, async (importerMeta, finalConfig, destinationPath, buildCfg, bunServer, event) => {
1228
+ if (finalConfig.cleanServePath) {
1229
+ await cleanDirectory(destinationPath);
1268
1230
  }
1269
- if (finalConfig.writeManifest) {
1270
- writeManifest(output, destinationPath, finalConfig.manifestWithHash, finalConfig.manifestName);
1271
- }
1272
- finalConfig.afterBuild?.(output, buildEnv);
1273
- if (finalConfig.reloadOnChange && !finalConfig.waitForTSCSuccessBeforeReload) {
1274
- bunServer.publish("message", JSON.stringify({ type: "reload" }));
1275
- }
1276
- const tscSuccess = await performTSC(finalConfig, importerMeta);
1277
- if (finalConfig.reloadOnChange && finalConfig.waitForTSCSuccessBeforeReload && !tscSuccess.error) {
1278
- bunServer.publish("message", JSON.stringify({ type: "reload" }));
1279
- }
1280
- if (tscSuccess.error && finalConfig.broadcastTSCErrorToClient) {
1281
- bunServer.publish("message", JSON.stringify({ type: "tscerror", message: tscSuccess.message }));
1231
+ const buildEnv = {
1232
+ importerMeta,
1233
+ finalConfig,
1234
+ destinationPath,
1235
+ buildCfg,
1236
+ bunServer,
1237
+ event
1238
+ };
1239
+ finalConfig.beforeBuild?.(buildEnv);
1240
+ try {
1241
+ const output = await Bun.build(buildCfg);
1242
+ publishOutputLogs(bunServer, output, finalConfig, event);
1243
+ if (finalConfig.createIndexHTML) {
1244
+ publishIndexHTML(destinationPath, finalConfig.serveIndexHtmlEjs, output, event);
1245
+ }
1246
+ if (finalConfig.writeManifest) {
1247
+ writeManifest(output, destinationPath, finalConfig.manifestWithHash, finalConfig.manifestName);
1248
+ }
1249
+ finalConfig.afterBuild?.(output, buildEnv);
1250
+ if (finalConfig.reloadOnChange && !finalConfig.waitForTSCSuccessBeforeReload) {
1251
+ bunServer.publish("message", JSON.stringify({ type: "reload" }));
1252
+ }
1253
+ const tscSuccess = await performTSC(finalConfig, importerMeta);
1254
+ if (finalConfig.reloadOnChange && finalConfig.waitForTSCSuccessBeforeReload && !tscSuccess.error) {
1255
+ bunServer.publish("message", JSON.stringify({ type: "reload" }));
1256
+ }
1257
+ if (tscSuccess.error && finalConfig.broadcastTSCErrorToClient) {
1258
+ bunServer.publish("message", JSON.stringify({ type: "tscerror", message: tscSuccess.message }));
1259
+ }
1260
+ } catch (e) {
1261
+ console.error(e);
1282
1262
  }
1283
- } catch (e) {
1284
- console.error(e);
1285
- }
1286
- }, watchDelay, { immediate: true });
1263
+ }, serverConfig.throttleOptions);
1264
+ }
1287
1265
  function handleErrorResponse(req, err) {
1288
1266
  const msg = `Error while processing request ${req.url}`;
1289
1267
  console.error(msg, err);
@@ -1294,10 +1272,14 @@ function publishOutputLogs(bunServer, output, config, event) {
1294
1272
  bunServer.publish("message", JSON.stringify({ type: "message", message: `[Bun HMR] ${event.filename} ${event.eventType}` }));
1295
1273
  const outTable = output.outputs.filter((o) => o.kind !== "sourcemap").map((o) => {
1296
1274
  const a = Bun.pathToFileURL(o.path);
1275
+ const distPath = Bun.pathToFileURL(config.buildConfig.outdir ?? "./dist");
1276
+ const distPathHref = distPath.href;
1277
+ const lastDistIdx = distPathHref.lastIndexOf("/") + 1;
1297
1278
  const fileName = a.href.substring(a.href.lastIndexOf("/") + 1);
1279
+ const fileWithPath = a.href.substring(lastDistIdx);
1298
1280
  return {
1299
1281
  name: fileName,
1300
- path: o.path,
1282
+ path: fileWithPath,
1301
1283
  size: convertBytes(o.size)
1302
1284
  };
1303
1285
  });
package/package.json CHANGED
@@ -24,7 +24,7 @@
24
24
  "exports": {
25
25
  ".": "./dist/index.js"
26
26
  },
27
- "version": "0.9.8",
27
+ "version": "0.9.82",
28
28
  "module": "index.ts",
29
29
  "type": "module",
30
30
  "license": "MIT",
@@ -32,14 +32,15 @@
32
32
  "build": "bun run ./build.ts"
33
33
  },
34
34
  "devDependencies": {
35
- "@types/bun": "^1.2.7"
35
+ "@types/bun": "^1.2.8",
36
+ "@types/throttle-debounce": "^5.0.2",
37
+ "throttle-debounce": "^5.0.2"
36
38
  },
37
39
  "peerDependencies": {
38
40
  "typescript": "^5.8.2"
39
41
  },
40
42
  "dependencies": {
41
43
  "@types/ejs": "^3.1.5",
42
- "debounce": "^2.2.0",
43
44
  "ejs": "^3.1.10",
44
45
  "picocolors": "^1.1.1"
45
46
  }