@krisanalfa/bunest-adapter 0.1.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -16,11 +16,49 @@ var __legacyMetadataTS = (k, v) => {
16
16
 
17
17
  // lib/bun.adapter.ts
18
18
  import {
19
- Logger
19
+ Logger as Logger2
20
20
  } from "@nestjs/common";
21
21
  var {randomUUIDv7 } = globalThis.Bun;
22
22
  import { AbstractHttpAdapter } from "@nestjs/core";
23
23
 
24
+ // lib/bun.preflight-http-server.ts
25
+ class BunPreflightHttpServer {
26
+ serverInstance;
27
+ constructor(serverInstance) {
28
+ this.serverInstance = serverInstance;
29
+ }
30
+ on(event, callback) {}
31
+ once() {}
32
+ removeListener() {}
33
+ async stop(force) {
34
+ await this.serverInstance.stop(force);
35
+ }
36
+ address() {
37
+ return this.serverInstance.address();
38
+ }
39
+ setWsOptions(options) {
40
+ this.serverInstance.setWsOptions(options);
41
+ }
42
+ registerWsOpenHandler(handler) {
43
+ this.serverInstance.registerWsOpenHandler(handler);
44
+ }
45
+ registerWsMessageHandler(handler) {
46
+ this.serverInstance.registerWsMessageHandler(handler);
47
+ }
48
+ registerWsCloseHandler(handler) {
49
+ this.serverInstance.registerWsCloseHandler(handler);
50
+ }
51
+ getBunServer() {
52
+ return this.serverInstance.getBunServer();
53
+ }
54
+ async close() {
55
+ await this.serverInstance.close();
56
+ }
57
+ }
58
+
59
+ // lib/bun.server-instance.ts
60
+ import { Logger } from "@nestjs/common";
61
+
24
62
  // lib/bun.body-parser.middleware.ts
25
63
  var GET_CODE = 71;
26
64
  var HEAD_CODE = 72;
@@ -179,6 +217,7 @@ class BunCorsMiddleware {
179
217
  }
180
218
 
181
219
  // lib/bun.middleware-engine.ts
220
+ var {peek } = globalThis.Bun;
182
221
  var EMPTY_HANDLERS = new Array(0);
183
222
  var noop = () => {};
184
223
 
@@ -258,6 +297,17 @@ class BunMiddlewareEngine {
258
297
  const keyPathLen = keyPath.length;
259
298
  return path === keyPath || pathLen > keyPathLen && path.charCodeAt(keyPathLen) === 47 && path.startsWith(keyPath);
260
299
  }
300
+ async executeHandler(handler, req, res, next) {
301
+ if (!handler)
302
+ return;
303
+ const result = handler(req, res, next);
304
+ if (result instanceof Promise) {
305
+ const peeked = peek(result);
306
+ if (peeked !== result)
307
+ return;
308
+ await result;
309
+ }
310
+ }
261
311
  async run(options) {
262
312
  try {
263
313
  const middlewares = this.getMiddlewareChain(options.method, options.path);
@@ -333,25 +383,18 @@ class BunMiddlewareEngine {
333
383
  if (err)
334
384
  throw err;
335
385
  if (index < chainLength) {
336
- const handler = chain[index++];
337
- const result = handler(req, res, next);
338
- if (result instanceof Promise)
339
- await result;
386
+ await this.executeHandler(chain[index++], req, res, next);
340
387
  return;
341
388
  }
342
389
  if (index === chainLength) {
343
390
  index++;
344
391
  if (!res.isEnded()) {
345
- const result = requestHandler(req, res, next);
346
- if (result instanceof Promise)
347
- await result;
392
+ await this.executeHandler(requestHandler, req, res, next);
348
393
  }
349
394
  return;
350
395
  }
351
- if (index > chainLength && !res.isEnded()) {
352
- const result = this.notFoundHandler?.(req, res, noop);
353
- if (result instanceof Promise)
354
- await result;
396
+ if (!res.isEnded()) {
397
+ await this.executeHandler(this.notFoundHandler ?? undefined, req, res, () => Promise.resolve());
355
398
  }
356
399
  };
357
400
  await next();
@@ -359,8 +402,11 @@ class BunMiddlewareEngine {
359
402
  async handleError(error, req, res) {
360
403
  if (this.errorHandler !== null) {
361
404
  const result = this.errorHandler(error, req, res, noop);
362
- if (result instanceof Promise)
363
- await result;
405
+ if (result instanceof Promise) {
406
+ const peeked = peek(result);
407
+ if (peeked === result)
408
+ await result;
409
+ }
364
410
  return res;
365
411
  }
366
412
  throw error;
@@ -397,7 +443,10 @@ class BunRequest {
397
443
  }
398
444
  get socket() {
399
445
  return {
400
- encrypted: this._parsedUrl.protocol === "https:"
446
+ encrypted: this._parsedUrl.protocol === "https:",
447
+ setKeepAlive: () => {},
448
+ setNoDelay: () => {},
449
+ setTimeout: () => {}
401
450
  };
402
451
  }
403
452
  get url() {
@@ -492,6 +541,18 @@ class BunRequest {
492
541
  cloned._settings = this._settings;
493
542
  return cloned;
494
543
  }
544
+ on(event, listener) {
545
+ return this;
546
+ }
547
+ once(event, listener) {
548
+ return this;
549
+ }
550
+ off(event, listener) {
551
+ return this;
552
+ }
553
+ emit(event, ...args) {
554
+ return true;
555
+ }
495
556
  }
496
557
 
497
558
  // lib/bun.response.ts
@@ -504,11 +565,14 @@ class BunResponse {
504
565
  response;
505
566
  cookieMap = new CookieMap;
506
567
  static textDecoder = new TextDecoder;
568
+ writable = true;
507
569
  headers = null;
508
570
  statusCode = 200;
509
571
  ended = false;
510
572
  cookieHeaders = null;
511
573
  chunks = [];
574
+ streamWriter = null;
575
+ textEncoder = new TextEncoder;
512
576
  constructor() {
513
577
  this.response = new Promise((r) => {
514
578
  this.resolve = r;
@@ -542,6 +606,16 @@ class BunResponse {
542
606
  if (this.ended)
543
607
  return;
544
608
  this.ended = true;
609
+ if (this.streamWriter) {
610
+ try {
611
+ if (body) {
612
+ const bytes = typeof body === "string" ? this.textEncoder.encode(body) : body instanceof Uint8Array ? body : this.textEncoder.encode(JSON.stringify(body));
613
+ this.streamWriter.write(bytes);
614
+ }
615
+ this.streamWriter.close();
616
+ } catch {}
617
+ return;
618
+ }
545
619
  this.applyCookieHeaders();
546
620
  if (this.chunks.length > 0) {
547
621
  const finalBody = this.combineChunks(body);
@@ -551,14 +625,19 @@ class BunResponse {
551
625
  this.sendResponse(body);
552
626
  }
553
627
  applyCookieHeaders() {
628
+ if (this.cookieMap.size === 0)
629
+ return;
554
630
  this.cookieHeaders ??= this.cookieMap.toSetCookieHeaders();
555
- if (this.cookieHeaders.length > 0) {
556
- this.setHeader("set-cookie", this.cookieHeaders.join(`
631
+ this.setHeader("set-cookie", this.cookieHeaders.join(`
557
632
  `));
558
- }
559
633
  }
560
634
  sendResponse(body) {
561
635
  if (body !== null && typeof body === "object") {
636
+ const ctor = body.constructor;
637
+ if (ctor === Object || ctor === Array) {
638
+ this.resolve(this.buildJsonResponse(body));
639
+ return;
640
+ }
562
641
  if (body instanceof Uint8Array || body instanceof Blob) {
563
642
  this.resolve(this.createResponse(body));
564
643
  return;
@@ -642,10 +721,30 @@ class BunResponse {
642
721
  once(event, listener) {
643
722
  return this;
644
723
  }
724
+ emit(event, ...args) {
725
+ return true;
726
+ }
727
+ get writableEnded() {
728
+ return this.ended;
729
+ }
645
730
  write(chunk) {
646
731
  if (this.ended) {
647
732
  return false;
648
733
  }
734
+ const contentType = this.headers?.get("content-type") ?? "";
735
+ const isStreamingResponse = contentType.includes("text/event-stream") || contentType.includes("application/octet-stream");
736
+ if (isStreamingResponse && !this.streamWriter) {
737
+ this.initializeStreamingMode();
738
+ }
739
+ if (this.streamWriter) {
740
+ try {
741
+ const bytes = typeof chunk === "string" ? this.textEncoder.encode(chunk) : chunk instanceof Uint8Array ? chunk : chunk instanceof Buffer ? new Uint8Array(chunk) : this.textEncoder.encode(JSON.stringify(chunk));
742
+ this.streamWriter.write(bytes);
743
+ return true;
744
+ } catch {
745
+ return false;
746
+ }
747
+ }
649
748
  if (typeof chunk === "string") {
650
749
  this.chunks.push(chunk);
651
750
  return true;
@@ -668,6 +767,12 @@ class BunResponse {
668
767
  }
669
768
  return true;
670
769
  }
770
+ initializeStreamingMode() {
771
+ const { readable, writable } = new TransformStream;
772
+ this.streamWriter = writable.getWriter();
773
+ this.applyCookieHeaders();
774
+ this.resolve(this.createResponse(readable));
775
+ }
671
776
  getHeader(name) {
672
777
  return this.headers?.get(name.toLowerCase()) ?? null;
673
778
  }
@@ -711,9 +816,7 @@ class BunResponse {
711
816
  if (headers === null || headers.size === 0) {
712
817
  return Response.json(body, { status: this.statusCode });
713
818
  }
714
- if (!headers.has("content-type")) {
715
- headers.set("content-type", JSON_CONTENT_TYPE);
716
- }
819
+ headers.set("content-type", JSON_CONTENT_TYPE);
717
820
  return Response.json(body, {
718
821
  status: this.statusCode,
719
822
  headers: Object.fromEntries(headers)
@@ -733,13 +836,9 @@ class BunResponse {
733
836
 
734
837
  // lib/bun.version-filter.middleware.ts
735
838
  import { VERSION_NEUTRAL, VersioningType } from "@nestjs/common";
736
- async function executeHandler(handler, req, res, next) {
737
- const result = handler(req, res, next);
738
- return result instanceof Promise ? await result : result;
739
- }
740
- function callNext(next) {
741
- return next();
742
- }
839
+ var CUSTOM_VERSIONING_PHASE_KEY = "_cvp";
840
+ var CUSTOM_VERSIONING_CANDIDATES_KEY = "_cvc";
841
+ var CUSTOM_VERSIONING_BEST_CANDIDATE_KEY = "_cvb";
743
842
 
744
843
  class BunVersionFilterMiddleware {
745
844
  static createFilter(handler, version, versioningOptions) {
@@ -767,24 +866,26 @@ class BunVersionFilterMiddleware {
767
866
  static computeAcceptsNeutral(version) {
768
867
  return version === VERSION_NEUTRAL || Array.isArray(version) && version.includes(VERSION_NEUTRAL);
769
868
  }
770
- static getHeader(req, name) {
771
- return req.headers.get(name) ?? undefined;
772
- }
773
869
  static createCustomVersionFilter(handler, version, options) {
774
870
  const isVersionArray = Array.isArray(version);
775
871
  const versionSet = isVersionArray ? new Set(version) : null;
776
872
  const singleVersion = isVersionArray ? null : version;
777
- return async (req, res, next) => {
873
+ return (req, res, next) => {
778
874
  const extracted = options.extractor(req);
779
- const reqMeta = req;
780
- reqMeta._customVersioningPhase ??= "discovery";
781
- reqMeta._customVersioningCandidates ??= new Map;
782
- const isDiscovery = reqMeta._customVersioningPhase === "discovery";
783
- const extractedIsArray = Array.isArray(extracted);
784
- const extractedVersions = extractedIsArray ? extracted : [extracted];
875
+ let phase = req.get(CUSTOM_VERSIONING_PHASE_KEY);
876
+ if (phase === undefined) {
877
+ phase = 0;
878
+ req.set(CUSTOM_VERSIONING_PHASE_KEY, phase);
879
+ }
880
+ let candidates = req.get(CUSTOM_VERSIONING_CANDIDATES_KEY);
881
+ if (!candidates) {
882
+ candidates = new Map;
883
+ req.set(CUSTOM_VERSIONING_CANDIDATES_KEY, candidates);
884
+ }
885
+ const extractedVersions = Array.isArray(extracted) ? extracted : [extracted];
785
886
  let match;
786
887
  let matchIndex = -1;
787
- for (let i = 0;i < extractedVersions.length; i++) {
888
+ for (let i = 0, len = extractedVersions.length;i < len; i++) {
788
889
  const extractedVersion = extractedVersions[i];
789
890
  if (versionSet ? versionSet.has(extractedVersion) : extractedVersion === singleVersion) {
790
891
  match = extractedVersion;
@@ -793,44 +894,44 @@ class BunVersionFilterMiddleware {
793
894
  }
794
895
  }
795
896
  if (match) {
796
- if (isDiscovery) {
797
- reqMeta._customVersioningCandidates.set(match, {
798
- priority: matchIndex,
799
- execute: () => handler(req, res, next)
800
- });
801
- return callNext(next);
897
+ if (phase === 0) {
898
+ candidates.set(match, matchIndex);
899
+ next();
900
+ return;
802
901
  }
803
- if (reqMeta._customVersioningBestCandidate === match) {
804
- return executeHandler(handler, req, res, next);
902
+ if (req.get(CUSTOM_VERSIONING_BEST_CANDIDATE_KEY) === match) {
903
+ return handler(req, res, next);
805
904
  }
806
905
  }
807
- return callNext(next);
906
+ next();
808
907
  };
809
908
  }
810
909
  static createMediaTypeVersionFilter(handler, version, options) {
811
910
  const acceptsNeutral = this.computeAcceptsNeutral(version);
812
911
  const versionMatches = this.createVersionMatcher(version);
813
- const keyLength = options.key.length;
814
- return async (req, res, next) => {
815
- const acceptHeader = this.getHeader(req, "accept");
912
+ const key = options.key;
913
+ const keyLength = key.length;
914
+ return (req, res, next) => {
915
+ const acceptHeader = req.headers.get("accept");
816
916
  if (acceptHeader) {
817
917
  const semiIndex = acceptHeader.indexOf(";");
818
918
  if (semiIndex !== -1) {
819
919
  const versionPart = acceptHeader.substring(semiIndex + 1).trim();
820
- const keyIndex = versionPart.indexOf(options.key);
920
+ const keyIndex = versionPart.indexOf(key);
821
921
  if (keyIndex !== -1) {
822
922
  const headerVersion = versionPart.substring(keyIndex + keyLength);
823
923
  if (versionMatches(headerVersion)) {
824
- return executeHandler(handler, req, res, next);
924
+ return handler(req, res, next);
825
925
  }
826
- return callNext(next);
926
+ next();
927
+ return;
827
928
  }
828
929
  }
829
930
  }
830
931
  if (acceptsNeutral) {
831
- return executeHandler(handler, req, res, next);
932
+ return handler(req, res, next);
832
933
  }
833
- return callNext(next);
934
+ next();
834
935
  };
835
936
  }
836
937
  static createHeaderVersionFilter(handler, version, options) {
@@ -840,21 +941,25 @@ class BunVersionFilterMiddleware {
840
941
  const hasNeutralDefault = defaultVersion === VERSION_NEUTRAL;
841
942
  const resolvedDefault = this.resolveDefaultVersion(version, defaultVersion);
842
943
  const headerName = options.header;
843
- return async (req, res, next) => {
844
- let headerVersion = this.getHeader(req, headerName)?.trim();
845
- if (headerVersion === "")
846
- headerVersion = undefined;
944
+ return (req, res, next) => {
945
+ let headerVersion = req.headers.get(headerName) ?? undefined;
946
+ if (headerVersion) {
947
+ headerVersion = headerVersion.trim();
948
+ if (headerVersion === "")
949
+ headerVersion = undefined;
950
+ }
847
951
  headerVersion ??= resolvedDefault;
848
952
  if (!headerVersion) {
849
953
  if ((hasNeutralDefault || !defaultVersion) && acceptsNeutral) {
850
- return executeHandler(handler, req, res, next);
954
+ return handler(req, res, next);
851
955
  }
852
- return callNext(next);
956
+ next();
957
+ return;
853
958
  }
854
959
  if (versionMatches(headerVersion)) {
855
- return executeHandler(handler, req, res, next);
960
+ return handler(req, res, next);
856
961
  }
857
- return callNext(next);
962
+ next();
858
963
  };
859
964
  }
860
965
  static resolveDefaultVersion(handlerVersion, defaultVersion) {
@@ -871,12 +976,15 @@ class BunVersionFilterMiddleware {
871
976
  return;
872
977
  }
873
978
  static selectBestCustomVersionCandidate(req) {
874
- const { _customVersioningPhase: phase, _customVersioningCandidates: candidates } = req;
875
- if (phase !== "discovery" || !candidates?.size)
979
+ const phase = req.get(CUSTOM_VERSIONING_PHASE_KEY);
980
+ if (phase !== 0)
981
+ return null;
982
+ const candidates = req.get(CUSTOM_VERSIONING_CANDIDATES_KEY);
983
+ if (!candidates?.size)
876
984
  return null;
877
985
  let bestVersion = null;
878
986
  let bestPriority = Infinity;
879
- for (const [version, { priority }] of candidates) {
987
+ for (const [version, priority] of candidates) {
880
988
  if (priority < bestPriority) {
881
989
  bestPriority = priority;
882
990
  bestVersion = version;
@@ -885,17 +993,19 @@ class BunVersionFilterMiddleware {
885
993
  return bestVersion;
886
994
  }
887
995
  static setCustomVersioningExecutionPhase(req, bestVersion) {
888
- const reqMeta = req;
889
- reqMeta._customVersioningPhase = "execution";
890
- reqMeta._customVersioningBestCandidate = bestVersion;
996
+ req.set(CUSTOM_VERSIONING_PHASE_KEY, 1);
997
+ req.set(CUSTOM_VERSIONING_BEST_CANDIDATE_KEY, bestVersion);
891
998
  }
892
999
  static hasCustomVersioningCandidates(req) {
893
- const { _customVersioningPhase: phase, _customVersioningCandidates: candidates } = req;
894
- return phase === "discovery" && !!candidates?.size;
1000
+ const phase = req.get(CUSTOM_VERSIONING_PHASE_KEY);
1001
+ if (phase !== 0)
1002
+ return false;
1003
+ const candidates = req.get(CUSTOM_VERSIONING_CANDIDATES_KEY);
1004
+ return !!candidates?.size;
895
1005
  }
896
1006
  }
897
1007
 
898
- // lib/bun.adapter.ts
1008
+ // lib/bun.server-instance.ts
899
1009
  var REQUEST_METHOD_STRINGS = [
900
1010
  "GET",
901
1011
  "POST",
@@ -915,9 +1025,9 @@ var REQUEST_METHOD_STRINGS = [
915
1025
  "UNLOCK"
916
1026
  ];
917
1027
 
918
- class BunAdapter extends AbstractHttpAdapter {
1028
+ class BunServerInstance {
919
1029
  bunServeOptions;
920
- logger = new Logger("BunAdapter", { timestamp: true });
1030
+ logger = new Logger("BunServerInstance", { timestamp: true });
921
1031
  middlewareEngine = new BunMiddlewareEngine;
922
1032
  useVersioning = false;
923
1033
  routes = Object.create(null);
@@ -926,175 +1036,176 @@ class BunAdapter extends AbstractHttpAdapter {
926
1036
  res.setStatus(404);
927
1037
  res.end({ message: "Not Found" });
928
1038
  };
929
- constructor(bunServeOptions = {
930
- development: false,
931
- id: randomUUIDv7()
932
- }) {
933
- super();
1039
+ wsHandlers = {
1040
+ onOpen: undefined,
1041
+ onMessage: undefined,
1042
+ onClose: undefined
1043
+ };
1044
+ wsMiddlewareEngine = new BunMiddlewareEngine;
1045
+ wsOptions = {};
1046
+ useWs = false;
1047
+ useWsCors = false;
1048
+ httpServer = null;
1049
+ constructor(bunServeOptions) {
934
1050
  this.bunServeOptions = bunServeOptions;
935
- this.setInstance({
936
- use: (maybePath, maybeHandler) => {
937
- if (typeof maybePath === "string") {
938
- let path = maybePath;
939
- const handler = maybeHandler;
940
- if (!handler) {
941
- throw new Error("Handler must be provided when path is a string.");
942
- }
943
- if (path.includes("/*")) {
944
- path = path.substring(0, path.indexOf("/*"));
945
- }
946
- this.logger.log(`Registering middleware for path: ${path}`);
947
- this.middlewareEngine.useRoute("ALL", path, handler);
948
- } else {
949
- const handler = maybePath;
950
- this.middlewareEngine.useGlobal(handler);
951
- }
1051
+ }
1052
+ use(maybePath, maybeHandler) {
1053
+ if (typeof maybePath === "string") {
1054
+ let path = maybePath;
1055
+ const handler = maybeHandler;
1056
+ if (!handler) {
1057
+ throw new Error("Handler must be provided when path is a string.");
952
1058
  }
953
- });
1059
+ if (path.includes("/*")) {
1060
+ path = path.substring(0, path.indexOf("/*"));
1061
+ }
1062
+ this.logger.log(`Registering middleware for path: ${path}`);
1063
+ this.middlewareEngine.useRoute("ALL", path, handler);
1064
+ } else {
1065
+ const handler = maybePath;
1066
+ this.middlewareEngine.useGlobal(handler);
1067
+ }
954
1068
  }
955
- use(middleware) {
956
- this.middlewareEngine.useGlobal(middleware);
1069
+ createHttpMethodHandler(httpMethod) {
1070
+ return (pathOrHandler, maybeHandler) => {
1071
+ const { path, handler } = this.parseRouteHandler(pathOrHandler, maybeHandler);
1072
+ this.delegateRouteHandler(httpMethod, path, handler);
1073
+ };
957
1074
  }
958
1075
  get(pathOrHandler, maybeHandler) {
959
- const { path, handler } = this.parseRouteHandler(pathOrHandler, maybeHandler);
960
- this.delegateRouteHandler("GET", path, handler);
1076
+ this.createHttpMethodHandler("GET")(pathOrHandler, maybeHandler);
961
1077
  }
962
1078
  post(pathOrHandler, maybeHandler) {
963
- const { path, handler } = this.parseRouteHandler(pathOrHandler, maybeHandler);
964
- this.delegateRouteHandler("POST", path, handler);
1079
+ this.createHttpMethodHandler("POST")(pathOrHandler, maybeHandler);
965
1080
  }
966
1081
  put(pathOrHandler, maybeHandler) {
967
- const { path, handler } = this.parseRouteHandler(pathOrHandler, maybeHandler);
968
- this.delegateRouteHandler("PUT", path, handler);
1082
+ this.createHttpMethodHandler("PUT")(pathOrHandler, maybeHandler);
969
1083
  }
970
1084
  patch(pathOrHandler, maybeHandler) {
971
- const { path, handler } = this.parseRouteHandler(pathOrHandler, maybeHandler);
972
- this.delegateRouteHandler("PATCH", path, handler);
1085
+ this.createHttpMethodHandler("PATCH")(pathOrHandler, maybeHandler);
973
1086
  }
974
1087
  delete(pathOrHandler, maybeHandler) {
975
- const { path, handler } = this.parseRouteHandler(pathOrHandler, maybeHandler);
976
- this.delegateRouteHandler("DELETE", path, handler);
1088
+ this.createHttpMethodHandler("DELETE")(pathOrHandler, maybeHandler);
977
1089
  }
978
1090
  head(pathOrHandler, maybeHandler) {
979
- const { path, handler } = this.parseRouteHandler(pathOrHandler, maybeHandler);
980
- this.delegateRouteHandler("HEAD", path, handler);
1091
+ this.createHttpMethodHandler("HEAD")(pathOrHandler, maybeHandler);
981
1092
  }
982
1093
  options(pathOrHandler, maybeHandler) {
983
- const { path, handler } = this.parseRouteHandler(pathOrHandler, maybeHandler);
984
- this.delegateRouteHandler("OPTIONS", path, handler);
1094
+ this.createHttpMethodHandler("OPTIONS")(pathOrHandler, maybeHandler);
1095
+ }
1096
+ createUnsupportedMethod() {
1097
+ return (pathOrHandler, maybeHandler) => {
1098
+ throw new Error("Not supported.");
1099
+ };
985
1100
  }
986
1101
  all(pathOrHandler, maybeHandler) {
987
- throw new Error("Not supported.");
1102
+ this.createUnsupportedMethod()(pathOrHandler, maybeHandler);
988
1103
  }
989
1104
  propfind(pathOrHandler, maybeHandler) {
990
- throw new Error("Not supported.");
1105
+ this.createUnsupportedMethod()(pathOrHandler, maybeHandler);
991
1106
  }
992
1107
  proppatch(pathOrHandler, maybeHandler) {
993
- throw new Error("Not supported.");
1108
+ this.createUnsupportedMethod()(pathOrHandler, maybeHandler);
994
1109
  }
995
1110
  mkcol(pathOrHandler, maybeHandler) {
996
- throw new Error("Not supported.");
1111
+ this.createUnsupportedMethod()(pathOrHandler, maybeHandler);
997
1112
  }
998
1113
  copy(pathOrHandler, maybeHandler) {
999
- throw new Error("Not supported.");
1114
+ this.createUnsupportedMethod()(pathOrHandler, maybeHandler);
1000
1115
  }
1001
1116
  move(pathOrHandler, maybeHandler) {
1002
- throw new Error("Not supported.");
1117
+ this.createUnsupportedMethod()(pathOrHandler, maybeHandler);
1003
1118
  }
1004
1119
  lock(pathOrHandler, maybeHandler) {
1005
- throw new Error("Not supported.");
1120
+ this.createUnsupportedMethod()(pathOrHandler, maybeHandler);
1006
1121
  }
1007
1122
  unlock(pathOrHandler, maybeHandler) {
1008
- throw new Error("Not supported.");
1123
+ this.createUnsupportedMethod()(pathOrHandler, maybeHandler);
1009
1124
  }
1010
1125
  search(pathOrHandler, maybeHandler) {
1011
- throw new Error("Not supported.");
1012
- }
1013
- useStaticAssets(...args) {
1014
- throw new Error("Not supported.");
1015
- }
1016
- setViewEngine(engine) {
1017
- throw new Error("Not supported.");
1126
+ this.createUnsupportedMethod()(pathOrHandler, maybeHandler);
1018
1127
  }
1019
- render(response, view, options) {
1020
- throw new Error("Not supported.");
1021
- }
1022
- async close() {
1023
- await this.httpServer.stop();
1128
+ listen(port, hostnameOrCallback, maybeCallback) {
1129
+ const hostname = typeof hostnameOrCallback === "string" ? hostnameOrCallback : this.bunServeOptions.hostname ?? "127.0.0.1";
1130
+ const callback = typeof hostnameOrCallback === "function" ? hostnameOrCallback : maybeCallback;
1131
+ const middlewareEngine = this.middlewareEngine;
1132
+ const notFoundHandler = this.notFoundHandler;
1133
+ const wsHandlers = this.wsHandlers;
1134
+ const bunServeOptions = this.bunServeOptions;
1135
+ this.setupWebSocketIfNeeded(wsHandlers, bunServeOptions);
1136
+ const fetch = async (request, server) => {
1137
+ const bunRequest = new BunRequest(request);
1138
+ if (await this.upgradeWebSocket(request, bunRequest, server)) {
1139
+ return;
1140
+ }
1141
+ const routeHandler = middlewareEngine.findRouteHandler(bunRequest.method, bunRequest.pathname) ?? notFoundHandler;
1142
+ const bunResponse = await middlewareEngine.run({
1143
+ req: bunRequest,
1144
+ res: new BunResponse,
1145
+ method: bunRequest.method,
1146
+ path: bunRequest.pathname,
1147
+ requestHandler: routeHandler
1148
+ });
1149
+ return bunResponse.res();
1150
+ };
1151
+ this.httpServer = this.createServer(port, hostname, bunServeOptions, fetch);
1152
+ callback?.();
1153
+ return this.httpServer;
1024
1154
  }
1025
- initHttpServer(options) {
1026
- this.setHttpServer({
1027
- once: () => {},
1028
- address: () => ({ address: "0.0.0.0", port: 0 }),
1029
- removeListener: () => {},
1030
- stop: () => {}
1031
- });
1032
- if (options.httpsOptions) {
1033
- this.bunServeOptions.tls = {
1034
- key: options.httpsOptions.key,
1035
- cert: options.httpsOptions.cert,
1036
- passphrase: options.httpsOptions.passphrase,
1037
- ca: options.httpsOptions.ca,
1038
- ciphers: options.httpsOptions.ciphers,
1039
- secureOptions: options.httpsOptions.secureOptions,
1040
- rejectUnauthorized: options.httpsOptions.rejectUnauthorized,
1041
- requestCert: options.httpsOptions.requestCert
1155
+ async stop(force) {
1156
+ const server = this.httpServer;
1157
+ if (!server) {
1158
+ return;
1159
+ }
1160
+ await server.stop(force);
1161
+ }
1162
+ address() {
1163
+ const server = this.httpServer;
1164
+ if (!server) {
1165
+ const hostname = this.bunServeOptions.hostname;
1166
+ const port = this.bunServeOptions.port;
1167
+ return {
1168
+ address: typeof hostname === "string" ? hostname : "127.0.0.1",
1169
+ port: typeof port === "number" ? port : 3000
1042
1170
  };
1043
1171
  }
1172
+ return {
1173
+ address: server.hostname ?? "127.0.0.1",
1174
+ port: server.port ?? 3000
1175
+ };
1044
1176
  }
1045
- getRequestHostname(request) {
1046
- return request.hostname;
1177
+ setWsOptions(options) {
1178
+ this.wsOptions = options;
1047
1179
  }
1048
- getRequestMethod(request) {
1049
- return request.method;
1180
+ registerWsOpenHandler(handler) {
1181
+ this.wsHandlers.onOpen = handler;
1050
1182
  }
1051
- getRequestUrl(request) {
1052
- return request.pathname;
1183
+ registerWsMessageHandler(handler) {
1184
+ this.wsHandlers.onMessage = handler;
1053
1185
  }
1054
- status(response, statusCode) {
1055
- response.setStatus(statusCode);
1186
+ registerWsCloseHandler(handler) {
1187
+ this.wsHandlers.onClose = handler;
1056
1188
  }
1057
- reply(response, body, statusCode) {
1058
- if (statusCode) {
1059
- response.setStatus(statusCode);
1060
- }
1061
- response.end(body);
1189
+ getBunServer() {
1190
+ return this.httpServer;
1062
1191
  }
1063
- end(response, message) {
1064
- response.end(message);
1192
+ async close() {
1193
+ await this.stop(true);
1065
1194
  }
1066
- redirect(response, statusCode, url) {
1067
- response.redirect(url, statusCode);
1195
+ getMiddlewareEngine() {
1196
+ return this.middlewareEngine;
1068
1197
  }
1069
- setErrorHandler(handler, prefix) {
1070
- this.middlewareEngine.useErrorHandler(handler);
1071
- }
1072
- setNotFoundHandler(handler, prefix) {
1198
+ setNotFoundHandler(handler) {
1073
1199
  this.notFoundHandler = handler;
1074
- this.middlewareEngine.useNotFoundHandler(handler);
1075
1200
  }
1076
- isHeadersSent(response) {
1077
- return response.isEnded();
1078
- }
1079
- getHeader(response, name) {
1080
- return response.getHeader(name);
1081
- }
1082
- setHeader(response, name, value) {
1083
- response.setHeader(name, value);
1084
- }
1085
- appendHeader(response, name, value) {
1086
- response.appendHeader(name, value);
1201
+ setUseVersioning(value) {
1202
+ this.useVersioning = value;
1087
1203
  }
1088
1204
  registerParserMiddleware(prefix, rawBody) {
1089
1205
  this.logger.log(`Registering Body Parser Middleware with prefix: ${prefix || "/"} and rawBody: ${rawBody ? "true" : "false"}`);
1090
1206
  const bodyParser = new BunBodyParserMiddleware({ prefix, rawBody });
1091
1207
  this.middlewareEngine.useGlobal(bodyParser.run.bind(bodyParser));
1092
1208
  }
1093
- enableCors(options, prefix) {
1094
- this.logger.log(`Enabling CORS Middleware with prefix: ${prefix ?? "/"}`);
1095
- const corsMiddleware = new BunCorsMiddleware({ corsOptions: options, prefix });
1096
- this.middlewareEngine.useGlobal(corsMiddleware.run.bind(corsMiddleware));
1097
- }
1098
1209
  createMiddlewareFactory(requestMethod) {
1099
1210
  return (path, callback) => {
1100
1211
  const methodName = this.mapRequestMethodToString(requestMethod);
@@ -1106,73 +1217,121 @@ class BunAdapter extends AbstractHttpAdapter {
1106
1217
  this.middlewareEngine.useRoute(methodName, normalizedPath, callback);
1107
1218
  };
1108
1219
  }
1109
- getType() {
1110
- return "bun";
1220
+ enableCors(corsOptions, prefix) {
1221
+ this.logger.log(`Enabling CORS Middleware with prefix: ${prefix ?? "/"}`);
1222
+ const corsMiddleware = new BunCorsMiddleware({ corsOptions, prefix });
1223
+ this.middlewareEngine.useGlobal(corsMiddleware.run.bind(corsMiddleware));
1111
1224
  }
1112
- applyVersionFilter(handler, version, versioningOptions) {
1113
- this.logger.log(`Applying Version Filter Middleware for version: ${JSON.stringify(version)}`);
1114
- this.useVersioning = true;
1115
- return BunVersionFilterMiddleware.createFilter(handler, version, versioningOptions);
1225
+ static isNumericPort(value) {
1226
+ return typeof value === "number" || !isNaN(Number(value));
1116
1227
  }
1117
- listen(port, hostnameOrCallback, maybeCallback) {
1118
- const hostname = typeof hostnameOrCallback === "string" ? hostnameOrCallback : "localhost";
1119
- const callback = typeof hostnameOrCallback === "function" ? hostnameOrCallback : maybeCallback;
1120
- const middlewareEngine = this.middlewareEngine;
1121
- const notFoundHandler = this.notFoundHandler;
1122
- const fetch = async (request) => {
1123
- const bunRequest = new BunRequest(request);
1124
- const bunResponse = new BunResponse;
1125
- const routeHandler = middlewareEngine.findRouteHandler(bunRequest.method, bunRequest.pathname) ?? notFoundHandler;
1126
- await middlewareEngine.run({
1127
- req: bunRequest,
1128
- res: bunResponse,
1129
- method: bunRequest.method,
1130
- path: bunRequest.pathname,
1131
- requestHandler: routeHandler
1132
- });
1133
- return bunResponse.res();
1134
- };
1135
- const omit = (obj, ...keys) => {
1136
- const result = { ...obj };
1137
- for (const key of keys) {
1138
- Reflect.deleteProperty(result, key);
1228
+ static omitKeys(obj, ...keys) {
1229
+ const result = { ...obj };
1230
+ for (const key of keys) {
1231
+ Reflect.deleteProperty(result, key);
1232
+ }
1233
+ return result;
1234
+ }
1235
+ isWebSocketUpgradeRequest(request) {
1236
+ const upgradeHeader = request.headers.get("upgrade");
1237
+ const connectionHeader = request.headers.get("connection");
1238
+ return !!(upgradeHeader?.toLowerCase() === "websocket" && connectionHeader?.toLowerCase().includes("upgrade"));
1239
+ }
1240
+ async provideCorsHeaders(bunRequest) {
1241
+ const bunResponse = new BunResponse;
1242
+ await this.wsMiddlewareEngine.run({
1243
+ req: bunRequest,
1244
+ res: bunResponse,
1245
+ method: bunRequest.method,
1246
+ path: bunRequest.pathname,
1247
+ requestHandler: (req, res) => {
1248
+ res.end();
1249
+ }
1250
+ });
1251
+ const response = await bunResponse.res();
1252
+ return response.headers;
1253
+ }
1254
+ async upgradeWebSocket(request, bunRequest, server) {
1255
+ if (!this.useWs || !this.isWebSocketUpgradeRequest(request)) {
1256
+ return false;
1257
+ }
1258
+ const headers = this.useWsCors ? await this.provideCorsHeaders(bunRequest) : undefined;
1259
+ return server.upgrade(request, {
1260
+ headers,
1261
+ data: await this.wsOptions.clientDataFactory?.(bunRequest) ?? {}
1262
+ });
1263
+ }
1264
+ setupWebSocketIfNeeded(wsHandlers, bunServeOptions) {
1265
+ const useWs = !!wsHandlers.onOpen && !!wsHandlers.onMessage && !!wsHandlers.onClose;
1266
+ if (!useWs)
1267
+ return;
1268
+ this.useWs = true;
1269
+ const getServer = () => this.getBunServer();
1270
+ const onMessage = wsHandlers.onMessage;
1271
+ const onOpen = wsHandlers.onOpen;
1272
+ const onClose = wsHandlers.onClose;
1273
+ bunServeOptions.websocket = {
1274
+ ...this.wsOptions,
1275
+ message: (ws, message) => {
1276
+ ws.data.onMessageInternal?.(message);
1277
+ onMessage?.(ws, message, getServer());
1278
+ },
1279
+ open: (ws) => {
1280
+ onOpen?.(ws);
1281
+ },
1282
+ close: (ws, code, reason) => {
1283
+ ws.data.onCloseInternal?.();
1284
+ ws.data.onDisconnect?.(ws);
1285
+ onClose?.(ws, code, reason);
1139
1286
  }
1140
- return result;
1141
1287
  };
1142
- const server = typeof port === "number" || !isNaN(Number(port)) ? Bun.serve({
1143
- ...this.bunServeOptions,
1288
+ const useWsCors = typeof this.wsOptions.cors !== "undefined";
1289
+ if (!useWsCors)
1290
+ return;
1291
+ this.useWsCors = true;
1292
+ const corsMiddleware = new BunCorsMiddleware({
1293
+ corsOptions: this.wsOptions.cors === true ? undefined : this.wsOptions.cors
1294
+ });
1295
+ this.wsMiddlewareEngine.useGlobal(corsMiddleware.run.bind(corsMiddleware));
1296
+ }
1297
+ createServer(port, hostname, bunServeOptions, fetch) {
1298
+ return BunServerInstance.isNumericPort(port) ? Bun.serve({
1299
+ ...bunServeOptions,
1144
1300
  hostname,
1145
1301
  port,
1146
1302
  routes: this.routes,
1147
1303
  fetch
1148
1304
  }) : Bun.serve({
1149
- ...omit(this.bunServeOptions, "idleTimeout"),
1305
+ ...BunServerInstance.omitKeys(bunServeOptions, "idleTimeout", "port", "hostname"),
1150
1306
  unix: port,
1151
1307
  routes: this.routes,
1152
1308
  fetch
1153
1309
  });
1154
- if (typeof port === "string" && isNaN(Number(port))) {
1155
- this.logger.log(`Bun server listening on unix socket: ${port}`);
1156
- }
1157
- callback?.();
1158
- Object.defineProperty(server, "address", {
1159
- configurable: true,
1160
- enumerable: true,
1161
- get: () => ({ address: server.hostname, port: server.port })
1162
- });
1163
- this.setHttpServer(server);
1164
1310
  }
1165
1311
  delegateRouteHandler(method, path, handler) {
1312
+ this.ensureRouteExists(path);
1313
+ const requestHandler = this.prepareRequestHandler(method, path, handler);
1314
+ this.routes[path][method] = this.createRouteFetchHandler(path, method, requestHandler);
1315
+ }
1316
+ ensureRouteExists(path) {
1166
1317
  if (!(path in this.routes)) {
1167
1318
  this.routes[path] = Object.create(null);
1168
1319
  }
1169
- const requestHandler = !this.useVersioning ? handler : this.createChainedHandlerForVersioningResolution(this.createVersioningHandlers(method, path, handler), this.notFoundHandler);
1170
- this.routes[path][method] = async (request) => {
1320
+ }
1321
+ prepareRequestHandler(method, path, handler) {
1322
+ if (!this.useVersioning)
1323
+ return handler;
1324
+ return this.createChainedHandlerForVersioningResolution(this.createVersioningHandlers(method, path, handler), this.notFoundHandler);
1325
+ }
1326
+ createRouteFetchHandler(path, method, requestHandler) {
1327
+ return async (request, server) => {
1171
1328
  const bunRequest = new BunRequest(request);
1172
- const bunResponse = new BunResponse;
1173
- await this.middlewareEngine.run({
1329
+ if (path === "/" && await this.upgradeWebSocket(request, bunRequest, server)) {
1330
+ return;
1331
+ }
1332
+ const bunResponse = await this.middlewareEngine.run({
1174
1333
  req: bunRequest,
1175
- res: bunResponse,
1334
+ res: new BunResponse,
1176
1335
  method,
1177
1336
  path,
1178
1337
  requestHandler
@@ -1228,6 +1387,114 @@ class BunAdapter extends AbstractHttpAdapter {
1228
1387
  return { path, handler };
1229
1388
  }
1230
1389
  }
1390
+
1391
+ // lib/bun.adapter.ts
1392
+ class BunAdapter extends AbstractHttpAdapter {
1393
+ bunServeOptions;
1394
+ logger = new Logger2("BunAdapter", { timestamp: true });
1395
+ constructor(bunServeOptions = {
1396
+ development: false,
1397
+ id: randomUUIDv7()
1398
+ }) {
1399
+ super(new BunServerInstance(bunServeOptions));
1400
+ this.bunServeOptions = bunServeOptions;
1401
+ }
1402
+ useStaticAssets(...args) {
1403
+ throw new Error("Not supported.");
1404
+ }
1405
+ setViewEngine(engine) {
1406
+ throw new Error("Not supported.");
1407
+ }
1408
+ render(response, view, options) {
1409
+ throw new Error("Not supported.");
1410
+ }
1411
+ async close() {
1412
+ await this.instance.close();
1413
+ }
1414
+ initHttpServer(options) {
1415
+ this.configureTls(options);
1416
+ const preflightServer = new BunPreflightHttpServer(this.instance);
1417
+ this.setHttpServer(preflightServer);
1418
+ return preflightServer;
1419
+ }
1420
+ getRequestHostname(request) {
1421
+ return request.hostname;
1422
+ }
1423
+ getRequestMethod(request) {
1424
+ return request.method;
1425
+ }
1426
+ getRequestUrl(request) {
1427
+ return request.pathname;
1428
+ }
1429
+ status(response, statusCode) {
1430
+ response.setStatus(statusCode);
1431
+ }
1432
+ reply(response, body, statusCode) {
1433
+ if (statusCode) {
1434
+ response.setStatus(statusCode);
1435
+ }
1436
+ response.end(body);
1437
+ }
1438
+ end(response, message) {
1439
+ response.end(message);
1440
+ }
1441
+ redirect(response, statusCode, url) {
1442
+ response.redirect(url, statusCode);
1443
+ }
1444
+ setErrorHandler(handler, prefix) {
1445
+ this.instance.getMiddlewareEngine().useErrorHandler(handler);
1446
+ }
1447
+ setNotFoundHandler(handler, prefix) {
1448
+ this.instance.setNotFoundHandler(handler);
1449
+ this.instance.getMiddlewareEngine().useNotFoundHandler(handler);
1450
+ }
1451
+ isHeadersSent(response) {
1452
+ return response.isEnded();
1453
+ }
1454
+ getHeader(response, name) {
1455
+ return response.getHeader(name);
1456
+ }
1457
+ setHeader(response, name, value) {
1458
+ response.setHeader(name, value);
1459
+ }
1460
+ appendHeader(response, name, value) {
1461
+ response.appendHeader(name, value);
1462
+ }
1463
+ registerParserMiddleware(prefix, rawBody) {
1464
+ this.instance.registerParserMiddleware(prefix, rawBody);
1465
+ }
1466
+ enableCors(options, prefix) {
1467
+ this.instance.enableCors(options, prefix);
1468
+ }
1469
+ createMiddlewareFactory(requestMethod) {
1470
+ return this.instance.createMiddlewareFactory(requestMethod);
1471
+ }
1472
+ getType() {
1473
+ return "bun";
1474
+ }
1475
+ applyVersionFilter(handler, version, versioningOptions) {
1476
+ this.logger.log(`Applying Version Filter Middleware for version: ${JSON.stringify(version)}`);
1477
+ this.instance.setUseVersioning(true);
1478
+ return BunVersionFilterMiddleware.createFilter(handler, version, versioningOptions);
1479
+ }
1480
+ listen(port, hostnameOrCallback, maybeCallback) {
1481
+ this.setHttpServer(this.instance.listen(port, hostnameOrCallback, maybeCallback));
1482
+ }
1483
+ configureTls(options) {
1484
+ if (options.httpsOptions) {
1485
+ this.bunServeOptions.tls = {
1486
+ key: options.httpsOptions.key,
1487
+ cert: options.httpsOptions.cert,
1488
+ passphrase: options.httpsOptions.passphrase,
1489
+ ca: options.httpsOptions.ca,
1490
+ ciphers: options.httpsOptions.ciphers,
1491
+ secureOptions: options.httpsOptions.secureOptions,
1492
+ rejectUnauthorized: options.httpsOptions.rejectUnauthorized,
1493
+ requestCert: options.httpsOptions.requestCert
1494
+ };
1495
+ }
1496
+ }
1497
+ }
1231
1498
  // lib/bun.file.interceptor.ts
1232
1499
  import { Injectable } from "@nestjs/common";
1233
1500
  import { basename, join } from "path";
@@ -1263,12 +1530,160 @@ BunFileInterceptor = __legacyDecorateClassTS([
1263
1530
  typeof HttpAdapterHost === "undefined" ? Object : HttpAdapterHost
1264
1531
  ])
1265
1532
  ], BunFileInterceptor);
1533
+ // lib/bun.ws-adapter.ts
1534
+ import {
1535
+ AbstractWsAdapter
1536
+ } from "@nestjs/websockets";
1537
+ import { EMPTY, Subject, mergeMap } from "rxjs";
1538
+ import { Logger as Logger3 } from "@nestjs/common";
1539
+ import { isNil } from "@nestjs/common/utils/shared.utils.js";
1540
+ var WS_READY_STATE_OPEN = 1;
1541
+ var defaultMessageParser = (data) => {
1542
+ if (typeof data === "string") {
1543
+ return JSON.parse(data);
1544
+ }
1545
+ if (data instanceof ArrayBuffer) {
1546
+ return JSON.parse(new TextDecoder().decode(data));
1547
+ }
1548
+ if (Buffer.isBuffer(data)) {
1549
+ return JSON.parse(data.toString("utf8"));
1550
+ }
1551
+ return JSON.parse(Buffer.concat(data).toString("utf8"));
1552
+ };
1553
+
1554
+ class BunWsAdapter extends AbstractWsAdapter {
1555
+ logger = new Logger3(BunWsAdapter.name);
1556
+ nestApp;
1557
+ messageParser = defaultMessageParser;
1558
+ onOpenHandler;
1559
+ globalHandlersInitialized = false;
1560
+ constructor(appOrHttpServer) {
1561
+ super(appOrHttpServer);
1562
+ if (!appOrHttpServer || !("getHttpAdapter" in appOrHttpServer)) {
1563
+ throw new Error("BunWsAdapter requires a NestApplication instance in the constructor.");
1564
+ }
1565
+ this.nestApp = appOrHttpServer;
1566
+ }
1567
+ create(_port, options) {
1568
+ if (options?.messageParser) {
1569
+ this.messageParser = options.messageParser;
1570
+ }
1571
+ const server = this.nestApp.getHttpAdapter().getHttpServer();
1572
+ const wsOptions = this.extractWsOptions(options);
1573
+ server.setWsOptions(wsOptions);
1574
+ this.initializeGlobalHandlers(server);
1575
+ return server;
1576
+ }
1577
+ extractWsOptions(options) {
1578
+ if (!options) {
1579
+ return {};
1580
+ }
1581
+ const wsOptions = { ...options };
1582
+ delete wsOptions.messageParser;
1583
+ return wsOptions;
1584
+ }
1585
+ async close(server) {
1586
+ await server.close();
1587
+ }
1588
+ bindClientConnect(server, callback) {
1589
+ this.onOpenHandler = callback;
1590
+ }
1591
+ bindClientDisconnect(client, callback) {
1592
+ const existingHandler = client.data.onDisconnect;
1593
+ client.data.onDisconnect = (ws) => {
1594
+ existingHandler?.(ws);
1595
+ callback(client);
1596
+ };
1597
+ }
1598
+ bindMessageHandlers(client, handlers, transform) {
1599
+ const handlerMap = this.buildHandlerMap(handlers);
1600
+ const message$ = new Subject;
1601
+ let isActive = true;
1602
+ const existingOnMessage = client.data.onMessageInternal;
1603
+ client.data.onMessageInternal = (data) => {
1604
+ existingOnMessage?.(data);
1605
+ if (isActive) {
1606
+ message$.next(data);
1607
+ }
1608
+ };
1609
+ const subscription = message$.pipe(mergeMap((data) => this.processMessage(data, handlerMap, transform))).subscribe({
1610
+ next: (response) => {
1611
+ this.sendResponse(client, response, isActive);
1612
+ },
1613
+ error: (err) => {
1614
+ this.logger.error("Message processing error", err instanceof Error ? err.stack : err);
1615
+ }
1616
+ });
1617
+ const existingOnClose = client.data.onCloseInternal;
1618
+ client.data.onCloseInternal = () => {
1619
+ existingOnClose?.();
1620
+ isActive = false;
1621
+ this.cleanupClient(message$, subscription);
1622
+ };
1623
+ }
1624
+ initializeGlobalHandlers(server) {
1625
+ if (this.globalHandlersInitialized) {
1626
+ return;
1627
+ }
1628
+ this.globalHandlersInitialized = true;
1629
+ server.registerWsOpenHandler((ws) => {
1630
+ this.onOpenHandler?.(ws);
1631
+ });
1632
+ server.registerWsMessageHandler(() => {});
1633
+ server.registerWsCloseHandler(() => {});
1634
+ }
1635
+ buildHandlerMap(handlers) {
1636
+ const map = new Map;
1637
+ for (const handler of handlers) {
1638
+ map.set(handler.message, handler);
1639
+ }
1640
+ return map;
1641
+ }
1642
+ processMessage(data, handlerMap, transform) {
1643
+ try {
1644
+ const parsed = this.messageParser(data);
1645
+ if (typeof parsed.event !== "string") {
1646
+ return EMPTY;
1647
+ }
1648
+ const handler = handlerMap.get(parsed.event);
1649
+ if (!handler) {
1650
+ return EMPTY;
1651
+ }
1652
+ const result = handler.callback(parsed.data, parsed.event);
1653
+ return transform(result).pipe(mergeMap((value) => isNil(value) ? EMPTY : [value]));
1654
+ } catch (error) {
1655
+ this.logger.warn("Failed to parse WebSocket message", error instanceof Error ? error.message : String(error));
1656
+ return EMPTY;
1657
+ }
1658
+ }
1659
+ sendResponse(client, response, isActive) {
1660
+ if (!isActive || client.readyState !== WS_READY_STATE_OPEN) {
1661
+ return;
1662
+ }
1663
+ if (response instanceof ArrayBuffer) {
1664
+ client.send(response);
1665
+ return;
1666
+ }
1667
+ if (ArrayBuffer.isView(response)) {
1668
+ client.send(response.buffer);
1669
+ return;
1670
+ }
1671
+ client.send(JSON.stringify(response));
1672
+ }
1673
+ cleanupClient(message$, subscription) {
1674
+ message$.complete();
1675
+ subscription.unsubscribe();
1676
+ }
1677
+ }
1266
1678
  export {
1679
+ BunWsAdapter,
1680
+ BunServerInstance,
1267
1681
  BunResponse,
1268
1682
  BunRequest,
1683
+ BunPreflightHttpServer,
1269
1684
  BunFileInterceptor,
1270
1685
  BunAdapter
1271
1686
  };
1272
1687
 
1273
- //# debugId=43ACC6E0AFE16AD764756E2164756E21
1688
+ //# debugId=813882D1C572F1EC64756E2164756E21
1274
1689
  //# sourceMappingURL=index.js.map