bun-dev-server 0.9.82 → 0.9.84

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,30 +124,6 @@ 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
- };
151
127
  }
152
128
  export interface BunServeConfig {
153
129
  port: number;
package/dist/index.js CHANGED
@@ -846,9 +846,188 @@ var require_picocolors = __commonJS((exports, module) => {
846
846
  module.exports.createColors = createColors;
847
847
  });
848
848
 
849
+ // node_modules/eventemitter3/index.js
850
+ var require_eventemitter3 = __commonJS((exports, module) => {
851
+ var has = Object.prototype.hasOwnProperty;
852
+ var prefix = "~";
853
+ function Events() {
854
+ }
855
+ if (Object.create) {
856
+ Events.prototype = Object.create(null);
857
+ if (!new Events().__proto__)
858
+ prefix = false;
859
+ }
860
+ function EE(fn, context, once) {
861
+ this.fn = fn;
862
+ this.context = context;
863
+ this.once = once || false;
864
+ }
865
+ function addListener(emitter, event, fn, context, once) {
866
+ if (typeof fn !== "function") {
867
+ throw new TypeError("The listener must be a function");
868
+ }
869
+ var listener = new EE(fn, context || emitter, once), evt = prefix ? prefix + event : event;
870
+ if (!emitter._events[evt])
871
+ emitter._events[evt] = listener, emitter._eventsCount++;
872
+ else if (!emitter._events[evt].fn)
873
+ emitter._events[evt].push(listener);
874
+ else
875
+ emitter._events[evt] = [emitter._events[evt], listener];
876
+ return emitter;
877
+ }
878
+ function clearEvent(emitter, evt) {
879
+ if (--emitter._eventsCount === 0)
880
+ emitter._events = new Events;
881
+ else
882
+ delete emitter._events[evt];
883
+ }
884
+ function EventEmitter() {
885
+ this._events = new Events;
886
+ this._eventsCount = 0;
887
+ }
888
+ EventEmitter.prototype.eventNames = function eventNames() {
889
+ var names = [], events, name;
890
+ if (this._eventsCount === 0)
891
+ return names;
892
+ for (name in events = this._events) {
893
+ if (has.call(events, name))
894
+ names.push(prefix ? name.slice(1) : name);
895
+ }
896
+ if (Object.getOwnPropertySymbols) {
897
+ return names.concat(Object.getOwnPropertySymbols(events));
898
+ }
899
+ return names;
900
+ };
901
+ EventEmitter.prototype.listeners = function listeners(event) {
902
+ var evt = prefix ? prefix + event : event, handlers = this._events[evt];
903
+ if (!handlers)
904
+ return [];
905
+ if (handlers.fn)
906
+ return [handlers.fn];
907
+ for (var i = 0, l = handlers.length, ee = new Array(l);i < l; i++) {
908
+ ee[i] = handlers[i].fn;
909
+ }
910
+ return ee;
911
+ };
912
+ EventEmitter.prototype.listenerCount = function listenerCount(event) {
913
+ var evt = prefix ? prefix + event : event, listeners = this._events[evt];
914
+ if (!listeners)
915
+ return 0;
916
+ if (listeners.fn)
917
+ return 1;
918
+ return listeners.length;
919
+ };
920
+ EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
921
+ var evt = prefix ? prefix + event : event;
922
+ if (!this._events[evt])
923
+ return false;
924
+ var listeners = this._events[evt], len = arguments.length, args, i;
925
+ if (listeners.fn) {
926
+ if (listeners.once)
927
+ this.removeListener(event, listeners.fn, undefined, true);
928
+ switch (len) {
929
+ case 1:
930
+ return listeners.fn.call(listeners.context), true;
931
+ case 2:
932
+ return listeners.fn.call(listeners.context, a1), true;
933
+ case 3:
934
+ return listeners.fn.call(listeners.context, a1, a2), true;
935
+ case 4:
936
+ return listeners.fn.call(listeners.context, a1, a2, a3), true;
937
+ case 5:
938
+ return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
939
+ case 6:
940
+ return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
941
+ }
942
+ for (i = 1, args = new Array(len - 1);i < len; i++) {
943
+ args[i - 1] = arguments[i];
944
+ }
945
+ listeners.fn.apply(listeners.context, args);
946
+ } else {
947
+ var length = listeners.length, j;
948
+ for (i = 0;i < length; i++) {
949
+ if (listeners[i].once)
950
+ this.removeListener(event, listeners[i].fn, undefined, true);
951
+ switch (len) {
952
+ case 1:
953
+ listeners[i].fn.call(listeners[i].context);
954
+ break;
955
+ case 2:
956
+ listeners[i].fn.call(listeners[i].context, a1);
957
+ break;
958
+ case 3:
959
+ listeners[i].fn.call(listeners[i].context, a1, a2);
960
+ break;
961
+ case 4:
962
+ listeners[i].fn.call(listeners[i].context, a1, a2, a3);
963
+ break;
964
+ default:
965
+ if (!args)
966
+ for (j = 1, args = new Array(len - 1);j < len; j++) {
967
+ args[j - 1] = arguments[j];
968
+ }
969
+ listeners[i].fn.apply(listeners[i].context, args);
970
+ }
971
+ }
972
+ }
973
+ return true;
974
+ };
975
+ EventEmitter.prototype.on = function on(event, fn, context) {
976
+ return addListener(this, event, fn, context, false);
977
+ };
978
+ EventEmitter.prototype.once = function once(event, fn, context) {
979
+ return addListener(this, event, fn, context, true);
980
+ };
981
+ EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {
982
+ var evt = prefix ? prefix + event : event;
983
+ if (!this._events[evt])
984
+ return this;
985
+ if (!fn) {
986
+ clearEvent(this, evt);
987
+ return this;
988
+ }
989
+ var listeners = this._events[evt];
990
+ if (listeners.fn) {
991
+ if (listeners.fn === fn && (!once || listeners.once) && (!context || listeners.context === context)) {
992
+ clearEvent(this, evt);
993
+ }
994
+ } else {
995
+ for (var i = 0, events = [], length = listeners.length;i < length; i++) {
996
+ if (listeners[i].fn !== fn || once && !listeners[i].once || context && listeners[i].context !== context) {
997
+ events.push(listeners[i]);
998
+ }
999
+ }
1000
+ if (events.length)
1001
+ this._events[evt] = events.length === 1 ? events[0] : events;
1002
+ else
1003
+ clearEvent(this, evt);
1004
+ }
1005
+ return this;
1006
+ };
1007
+ EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {
1008
+ var evt;
1009
+ if (event) {
1010
+ evt = prefix ? prefix + event : event;
1011
+ if (this._events[evt])
1012
+ clearEvent(this, evt);
1013
+ } else {
1014
+ this._events = new Events;
1015
+ this._eventsCount = 0;
1016
+ }
1017
+ return this;
1018
+ };
1019
+ EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
1020
+ EventEmitter.prototype.addListener = EventEmitter.prototype.on;
1021
+ EventEmitter.prefixed = prefix;
1022
+ EventEmitter.EventEmitter = EventEmitter;
1023
+ if (typeof module !== "undefined") {
1024
+ module.exports = EventEmitter;
1025
+ }
1026
+ });
1027
+
849
1028
  // src/server.ts
850
1029
  var import_ejs = __toESM(require_ejs(), 1);
851
- var {$: $2 } = globalThis.Bun;
1030
+ var {$: $2, build } = globalThis.Bun;
852
1031
 
853
1032
  // src/serveOutputTemplate.ejs
854
1033
  var serveOutputTemplate_default = `<!DOCTYPE html>\r
@@ -1064,57 +1243,402 @@ ${errOutput}`);
1064
1243
  return success;
1065
1244
  }
1066
1245
 
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) {
1246
+ // node_modules/eventemitter3/index.mjs
1247
+ var import__ = __toESM(require_eventemitter3(), 1);
1248
+
1249
+ // node_modules/p-timeout/index.js
1250
+ class TimeoutError extends Error {
1251
+ constructor(message) {
1252
+ super(message);
1253
+ this.name = "TimeoutError";
1254
+ }
1255
+ }
1256
+
1257
+ class AbortError extends Error {
1258
+ constructor(message) {
1259
+ super();
1260
+ this.name = "AbortError";
1261
+ this.message = message;
1262
+ }
1263
+ }
1264
+ var getDOMException = (errorMessage) => globalThis.DOMException === undefined ? new AbortError(errorMessage) : new DOMException(errorMessage);
1265
+ var getAbortedReason = (signal) => {
1266
+ const reason = signal.reason === undefined ? getDOMException("This operation was aborted.") : signal.reason;
1267
+ return reason instanceof Error ? reason : getDOMException(reason);
1268
+ };
1269
+ function pTimeout(promise, options) {
1270
+ const {
1271
+ milliseconds,
1272
+ fallback,
1273
+ message,
1274
+ customTimers = { setTimeout, clearTimeout }
1275
+ } = options;
1276
+ let timer;
1277
+ let abortHandler;
1278
+ const wrappedPromise = new Promise((resolve, reject) => {
1279
+ if (typeof milliseconds !== "number" || Math.sign(milliseconds) !== 1) {
1280
+ throw new TypeError(`Expected \`milliseconds\` to be a positive number, got \`${milliseconds}\``);
1281
+ }
1282
+ if (options.signal) {
1283
+ const { signal } = options;
1284
+ if (signal.aborted) {
1285
+ reject(getAbortedReason(signal));
1286
+ }
1287
+ abortHandler = () => {
1288
+ reject(getAbortedReason(signal));
1289
+ };
1290
+ signal.addEventListener("abort", abortHandler, { once: true });
1291
+ }
1292
+ if (milliseconds === Number.POSITIVE_INFINITY) {
1293
+ promise.then(resolve, reject);
1294
+ return;
1295
+ }
1296
+ const timeoutError = new TimeoutError;
1297
+ timer = customTimers.setTimeout.call(undefined, () => {
1298
+ if (fallback) {
1299
+ try {
1300
+ resolve(fallback());
1301
+ } catch (error) {
1302
+ reject(error);
1303
+ }
1304
+ return;
1305
+ }
1306
+ if (typeof promise.cancel === "function") {
1307
+ promise.cancel();
1308
+ }
1309
+ if (message === false) {
1310
+ resolve();
1311
+ } else if (message instanceof Error) {
1312
+ reject(message);
1313
+ } else {
1314
+ timeoutError.message = message ?? `Promise timed out after ${milliseconds} milliseconds`;
1315
+ reject(timeoutError);
1316
+ }
1317
+ }, milliseconds);
1318
+ (async () => {
1319
+ try {
1320
+ resolve(await promise);
1321
+ } catch (error) {
1322
+ reject(error);
1323
+ }
1324
+ })();
1325
+ });
1326
+ const cancelablePromise = wrappedPromise.finally(() => {
1327
+ cancelablePromise.clear();
1328
+ if (abortHandler && options.signal) {
1329
+ options.signal.removeEventListener("abort", abortHandler);
1330
+ }
1331
+ });
1332
+ cancelablePromise.clear = () => {
1333
+ customTimers.clearTimeout.call(undefined, timer);
1334
+ timer = undefined;
1335
+ };
1336
+ return cancelablePromise;
1337
+ }
1338
+
1339
+ // node_modules/p-queue/dist/lower-bound.js
1340
+ function lowerBound(array, value, comparator) {
1341
+ let first = 0;
1342
+ let count = array.length;
1343
+ while (count > 0) {
1344
+ const step = Math.trunc(count / 2);
1345
+ let it = first + step;
1346
+ if (comparator(array[it], value) <= 0) {
1347
+ first = ++it;
1348
+ count -= step + 1;
1349
+ } else {
1350
+ count = step;
1351
+ }
1352
+ }
1353
+ return first;
1354
+ }
1355
+
1356
+ // node_modules/p-queue/dist/priority-queue.js
1357
+ class PriorityQueue {
1358
+ #queue = [];
1359
+ enqueue(run, options) {
1360
+ options = {
1361
+ priority: 0,
1362
+ ...options
1363
+ };
1364
+ const element = {
1365
+ priority: options.priority,
1366
+ id: options.id,
1367
+ run
1368
+ };
1369
+ if (this.size === 0 || this.#queue[this.size - 1].priority >= options.priority) {
1370
+ this.#queue.push(element);
1090
1371
  return;
1091
1372
  }
1092
- function exec() {
1093
- lastExec = Date.now();
1094
- callback.apply(self, arguments_);
1373
+ const index = lowerBound(this.#queue, element, (a, b) => b.priority - a.priority);
1374
+ this.#queue.splice(index, 0, element);
1375
+ }
1376
+ setPriority(id, priority) {
1377
+ const index = this.#queue.findIndex((element) => element.id === id);
1378
+ if (index === -1) {
1379
+ throw new ReferenceError(`No promise function with the id "${id}" exists in the queue.`);
1095
1380
  }
1096
- function clear() {
1097
- timeoutID = undefined;
1381
+ const [item] = this.#queue.splice(index, 1);
1382
+ this.enqueue(item.run, { priority, id });
1383
+ }
1384
+ dequeue() {
1385
+ const item = this.#queue.shift();
1386
+ return item?.run;
1387
+ }
1388
+ filter(options) {
1389
+ return this.#queue.filter((element) => element.priority === options.priority).map((element) => element.run);
1390
+ }
1391
+ get size() {
1392
+ return this.#queue.length;
1393
+ }
1394
+ }
1395
+
1396
+ // node_modules/p-queue/dist/index.js
1397
+ class PQueue extends import__.default {
1398
+ #carryoverConcurrencyCount;
1399
+ #isIntervalIgnored;
1400
+ #intervalCount = 0;
1401
+ #intervalCap;
1402
+ #interval;
1403
+ #intervalEnd = 0;
1404
+ #intervalId;
1405
+ #timeoutId;
1406
+ #queue;
1407
+ #queueClass;
1408
+ #pending = 0;
1409
+ #concurrency;
1410
+ #isPaused;
1411
+ #throwOnTimeout;
1412
+ #idAssigner = 1n;
1413
+ timeout;
1414
+ constructor(options) {
1415
+ super();
1416
+ options = {
1417
+ carryoverConcurrencyCount: false,
1418
+ intervalCap: Number.POSITIVE_INFINITY,
1419
+ interval: 0,
1420
+ concurrency: Number.POSITIVE_INFINITY,
1421
+ autoStart: true,
1422
+ queueClass: PriorityQueue,
1423
+ ...options
1424
+ };
1425
+ if (!(typeof options.intervalCap === "number" && options.intervalCap >= 1)) {
1426
+ throw new TypeError(`Expected \`intervalCap\` to be a number from 1 and up, got \`${options.intervalCap?.toString() ?? ""}\` (${typeof options.intervalCap})`);
1098
1427
  }
1099
- if (!noLeading && debounceMode && !timeoutID) {
1100
- exec();
1428
+ if (options.interval === undefined || !(Number.isFinite(options.interval) && options.interval >= 0)) {
1429
+ throw new TypeError(`Expected \`interval\` to be a finite number >= 0, got \`${options.interval?.toString() ?? ""}\` (${typeof options.interval})`);
1101
1430
  }
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
- }
1431
+ this.#carryoverConcurrencyCount = options.carryoverConcurrencyCount;
1432
+ this.#isIntervalIgnored = options.intervalCap === Number.POSITIVE_INFINITY || options.interval === 0;
1433
+ this.#intervalCap = options.intervalCap;
1434
+ this.#interval = options.interval;
1435
+ this.#queue = new options.queueClass;
1436
+ this.#queueClass = options.queueClass;
1437
+ this.concurrency = options.concurrency;
1438
+ this.timeout = options.timeout;
1439
+ this.#throwOnTimeout = options.throwOnTimeout === true;
1440
+ this.#isPaused = options.autoStart === false;
1441
+ }
1442
+ get #doesIntervalAllowAnother() {
1443
+ return this.#isIntervalIgnored || this.#intervalCount < this.#intervalCap;
1444
+ }
1445
+ get #doesConcurrentAllowAnother() {
1446
+ return this.#pending < this.#concurrency;
1447
+ }
1448
+ #next() {
1449
+ this.#pending--;
1450
+ this.#tryToStartAnother();
1451
+ this.emit("next");
1452
+ }
1453
+ #onResumeInterval() {
1454
+ this.#onInterval();
1455
+ this.#initializeIntervalIfNeeded();
1456
+ this.#timeoutId = undefined;
1457
+ }
1458
+ get #isIntervalPaused() {
1459
+ const now = Date.now();
1460
+ if (this.#intervalId === undefined) {
1461
+ const delay = this.#intervalEnd - now;
1462
+ if (delay < 0) {
1463
+ this.#intervalCount = this.#carryoverConcurrencyCount ? this.#pending : 0;
1109
1464
  } else {
1110
- exec();
1465
+ if (this.#timeoutId === undefined) {
1466
+ this.#timeoutId = setTimeout(() => {
1467
+ this.#onResumeInterval();
1468
+ }, delay);
1469
+ }
1470
+ return true;
1471
+ }
1472
+ }
1473
+ return false;
1474
+ }
1475
+ #tryToStartAnother() {
1476
+ if (this.#queue.size === 0) {
1477
+ if (this.#intervalId) {
1478
+ clearInterval(this.#intervalId);
1111
1479
  }
1112
- } else if (noTrailing !== true) {
1113
- timeoutID = setTimeout(debounceMode ? clear : exec, debounceMode === undefined ? delay - elapsed : delay);
1480
+ this.#intervalId = undefined;
1481
+ this.emit("empty");
1482
+ if (this.#pending === 0) {
1483
+ this.emit("idle");
1484
+ }
1485
+ return false;
1486
+ }
1487
+ if (!this.#isPaused) {
1488
+ const canInitializeInterval = !this.#isIntervalPaused;
1489
+ if (this.#doesIntervalAllowAnother && this.#doesConcurrentAllowAnother) {
1490
+ const job = this.#queue.dequeue();
1491
+ if (!job) {
1492
+ return false;
1493
+ }
1494
+ this.emit("active");
1495
+ job();
1496
+ if (canInitializeInterval) {
1497
+ this.#initializeIntervalIfNeeded();
1498
+ }
1499
+ return true;
1500
+ }
1501
+ }
1502
+ return false;
1503
+ }
1504
+ #initializeIntervalIfNeeded() {
1505
+ if (this.#isIntervalIgnored || this.#intervalId !== undefined) {
1506
+ return;
1507
+ }
1508
+ this.#intervalId = setInterval(() => {
1509
+ this.#onInterval();
1510
+ }, this.#interval);
1511
+ this.#intervalEnd = Date.now() + this.#interval;
1512
+ }
1513
+ #onInterval() {
1514
+ if (this.#intervalCount === 0 && this.#pending === 0 && this.#intervalId) {
1515
+ clearInterval(this.#intervalId);
1516
+ this.#intervalId = undefined;
1517
+ }
1518
+ this.#intervalCount = this.#carryoverConcurrencyCount ? this.#pending : 0;
1519
+ this.#processQueue();
1520
+ }
1521
+ #processQueue() {
1522
+ while (this.#tryToStartAnother()) {
1523
+ }
1524
+ }
1525
+ get concurrency() {
1526
+ return this.#concurrency;
1527
+ }
1528
+ set concurrency(newConcurrency) {
1529
+ if (!(typeof newConcurrency === "number" && newConcurrency >= 1)) {
1530
+ throw new TypeError(`Expected \`concurrency\` to be a number from 1 and up, got \`${newConcurrency}\` (${typeof newConcurrency})`);
1531
+ }
1532
+ this.#concurrency = newConcurrency;
1533
+ this.#processQueue();
1534
+ }
1535
+ async#throwOnAbort(signal) {
1536
+ return new Promise((_resolve, reject) => {
1537
+ signal.addEventListener("abort", () => {
1538
+ reject(signal.reason);
1539
+ }, { once: true });
1540
+ });
1541
+ }
1542
+ setPriority(id, priority) {
1543
+ this.#queue.setPriority(id, priority);
1544
+ }
1545
+ async add(function_, options = {}) {
1546
+ options.id ??= (this.#idAssigner++).toString();
1547
+ options = {
1548
+ timeout: this.timeout,
1549
+ throwOnTimeout: this.#throwOnTimeout,
1550
+ ...options
1551
+ };
1552
+ return new Promise((resolve, reject) => {
1553
+ this.#queue.enqueue(async () => {
1554
+ this.#pending++;
1555
+ this.#intervalCount++;
1556
+ try {
1557
+ options.signal?.throwIfAborted();
1558
+ let operation = function_({ signal: options.signal });
1559
+ if (options.timeout) {
1560
+ operation = pTimeout(Promise.resolve(operation), { milliseconds: options.timeout });
1561
+ }
1562
+ if (options.signal) {
1563
+ operation = Promise.race([operation, this.#throwOnAbort(options.signal)]);
1564
+ }
1565
+ const result = await operation;
1566
+ resolve(result);
1567
+ this.emit("completed", result);
1568
+ } catch (error) {
1569
+ if (error instanceof TimeoutError && !options.throwOnTimeout) {
1570
+ resolve();
1571
+ return;
1572
+ }
1573
+ reject(error);
1574
+ this.emit("error", error);
1575
+ } finally {
1576
+ this.#next();
1577
+ }
1578
+ }, options);
1579
+ this.emit("add");
1580
+ this.#tryToStartAnother();
1581
+ });
1582
+ }
1583
+ async addAll(functions, options) {
1584
+ return Promise.all(functions.map(async (function_) => this.add(function_, options)));
1585
+ }
1586
+ start() {
1587
+ if (!this.#isPaused) {
1588
+ return this;
1589
+ }
1590
+ this.#isPaused = false;
1591
+ this.#processQueue();
1592
+ return this;
1593
+ }
1594
+ pause() {
1595
+ this.#isPaused = true;
1596
+ }
1597
+ clear() {
1598
+ this.#queue = new this.#queueClass;
1599
+ }
1600
+ async onEmpty() {
1601
+ if (this.#queue.size === 0) {
1602
+ return;
1114
1603
  }
1604
+ await this.#onEvent("empty");
1605
+ }
1606
+ async onSizeLessThan(limit) {
1607
+ if (this.#queue.size < limit) {
1608
+ return;
1609
+ }
1610
+ await this.#onEvent("next", () => this.#queue.size < limit);
1611
+ }
1612
+ async onIdle() {
1613
+ if (this.#pending === 0 && this.#queue.size === 0) {
1614
+ return;
1615
+ }
1616
+ await this.#onEvent("idle");
1617
+ }
1618
+ async#onEvent(event, filter) {
1619
+ return new Promise((resolve) => {
1620
+ const listener = () => {
1621
+ if (filter && !filter()) {
1622
+ return;
1623
+ }
1624
+ this.off(event, listener);
1625
+ resolve();
1626
+ };
1627
+ this.on(event, listener);
1628
+ });
1629
+ }
1630
+ get size() {
1631
+ return this.#queue.size;
1632
+ }
1633
+ sizeBy(options) {
1634
+ return this.#queue.filter(options).length;
1635
+ }
1636
+ get pending() {
1637
+ return this.#pending;
1638
+ }
1639
+ get isPaused() {
1640
+ return this.#isPaused;
1115
1641
  }
1116
- wrapper.cancel = cancel;
1117
- return wrapper;
1118
1642
  }
1119
1643
 
1120
1644
  // src/server.ts
@@ -1127,12 +1651,7 @@ async function startBunDevServer(serverConfig, importMeta) {
1127
1651
  createIndexHTML: true,
1128
1652
  tscConfigPath: resolve(importMeta.dir, "./tsconfig.json"),
1129
1653
  broadcastBuildOutputToConsole: true,
1130
- broadcastBuildOutputToClient: true,
1131
- throttleOptions: {
1132
- noLeading: false,
1133
- noTrailing: false,
1134
- debounceMode: undefined
1135
- }
1654
+ broadcastBuildOutputToClient: true
1136
1655
  };
1137
1656
  const finalConfig = { ...defaultConfig, ...serverConfig };
1138
1657
  if (serverConfig.tscConfigPath) {
@@ -1216,51 +1735,72 @@ async function startBunDevServer(serverConfig, importMeta) {
1216
1735
  sendPings: true
1217
1736
  }
1218
1737
  });
1219
- const debouncedbuildAndNotify = getThrottledBuildAndNotify(finalConfig);
1220
- debouncedbuildAndNotify(importMeta, finalConfig, destinationPath, buildCfg, bunServer, { filename: "Initial", eventType: "change" });
1738
+ const queue = getThrottledBuildAndNotify(finalConfig);
1739
+ await queue.add(async () => {
1740
+ await cleanBuildAndNotify(importMeta, finalConfig, destinationPath, buildCfg, bunServer, { filename: "Initial", eventType: "change" });
1741
+ });
1221
1742
  const watcher = watch(srcWatch, { recursive: true });
1222
1743
  for await (const event of watcher) {
1223
- debouncedbuildAndNotify(importMeta, finalConfig, destinationPath, buildCfg, bunServer, event);
1224
- }
1225
- }
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);
1230
- }
1231
- const buildEnv = {
1232
- importerMeta,
1233
- finalConfig,
1234
- destinationPath,
1235
- buildCfg,
1236
- bunServer,
1237
- event
1238
- };
1239
- finalConfig.beforeBuild?.(buildEnv);
1744
+ if (queue.pending > 0) {
1745
+ continue;
1746
+ }
1240
1747
  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 }));
1748
+ if (queue.size > 0) {
1749
+ queue.clear();
1259
1750
  }
1751
+ queue.add(async () => {
1752
+ await cleanBuildAndNotify(importMeta, finalConfig, destinationPath, buildCfg, bunServer, event);
1753
+ });
1260
1754
  } catch (e) {
1261
- console.error(e);
1755
+ console.error("Error while processing file change", e);
1262
1756
  }
1263
- }, serverConfig.throttleOptions);
1757
+ }
1758
+ }
1759
+ function getThrottledBuildAndNotify(serverConfig) {
1760
+ const anotherThrottle = new PQueue({
1761
+ concurrency: 1,
1762
+ intervalCap: 1,
1763
+ interval: serverConfig.watchDelay ?? 1000,
1764
+ carryoverConcurrencyCount: true
1765
+ });
1766
+ return anotherThrottle;
1767
+ }
1768
+ async function cleanBuildAndNotify(importerMeta, finalConfig, destinationPath, buildCfg, bunServer, event) {
1769
+ if (finalConfig.cleanServePath) {
1770
+ await cleanDirectory(destinationPath);
1771
+ }
1772
+ const buildEnv = {
1773
+ importerMeta,
1774
+ finalConfig,
1775
+ destinationPath,
1776
+ buildCfg,
1777
+ bunServer,
1778
+ event
1779
+ };
1780
+ finalConfig.beforeBuild?.(buildEnv);
1781
+ try {
1782
+ const output = await build(buildCfg);
1783
+ publishOutputLogs(bunServer, output, finalConfig, event);
1784
+ if (finalConfig.createIndexHTML) {
1785
+ publishIndexHTML(destinationPath, finalConfig.serveIndexHtmlEjs, output, event);
1786
+ }
1787
+ if (finalConfig.writeManifest) {
1788
+ writeManifest(output, destinationPath, finalConfig.manifestWithHash, finalConfig.manifestName);
1789
+ }
1790
+ finalConfig.afterBuild?.(output, buildEnv);
1791
+ if (finalConfig.reloadOnChange && !finalConfig.waitForTSCSuccessBeforeReload) {
1792
+ bunServer.publish("message", JSON.stringify({ type: "reload" }));
1793
+ }
1794
+ const tscSuccess = await performTSC(finalConfig, importerMeta);
1795
+ if (finalConfig.reloadOnChange && finalConfig.waitForTSCSuccessBeforeReload && !tscSuccess.error) {
1796
+ bunServer.publish("message", JSON.stringify({ type: "reload" }));
1797
+ }
1798
+ if (tscSuccess.error && finalConfig.broadcastTSCErrorToClient) {
1799
+ bunServer.publish("message", JSON.stringify({ type: "tscerror", message: tscSuccess.message }));
1800
+ }
1801
+ } catch (e) {
1802
+ console.error(e);
1803
+ }
1264
1804
  }
1265
1805
  function handleErrorResponse(req, err) {
1266
1806
  const msg = `Error while processing request ${req.url}`;
package/package.json CHANGED
@@ -24,7 +24,7 @@
24
24
  "exports": {
25
25
  ".": "./dist/index.js"
26
26
  },
27
- "version": "0.9.82",
27
+ "version": "0.9.84",
28
28
  "module": "index.ts",
29
29
  "type": "module",
30
30
  "license": "MIT",
@@ -32,16 +32,15 @@
32
32
  "build": "bun run ./build.ts"
33
33
  },
34
34
  "devDependencies": {
35
- "@types/bun": "^1.2.8",
36
- "@types/throttle-debounce": "^5.0.2",
37
- "throttle-debounce": "^5.0.2"
35
+ "@types/bun": "^1.2.8"
38
36
  },
39
37
  "peerDependencies": {
40
- "typescript": "^5.8.2"
38
+ "typescript": "^5.8.3"
41
39
  },
42
40
  "dependencies": {
43
41
  "@types/ejs": "^3.1.5",
44
42
  "ejs": "^3.1.10",
43
+ "p-queue": "^8.1.0",
45
44
  "picocolors": "^1.1.1"
46
45
  }
47
46
  }