crossws 0.1.0 → 0.1.2

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.
Files changed (44) hide show
  1. package/README.md +34 -257
  2. package/adapters/bun.d.ts +1 -0
  3. package/adapters/cloudflare.d.ts +1 -0
  4. package/adapters/deno.d.ts +1 -0
  5. package/adapters/node.d.ts +1 -0
  6. package/adapters/uws.d.ts +2 -0
  7. package/dist/adapters/bun.cjs +52 -29
  8. package/dist/adapters/bun.d.cts +10 -6
  9. package/dist/adapters/bun.d.mts +10 -6
  10. package/dist/adapters/bun.d.ts +10 -6
  11. package/dist/adapters/bun.mjs +52 -29
  12. package/dist/adapters/cloudflare.cjs +26 -16
  13. package/dist/adapters/cloudflare.d.cts +3 -3
  14. package/dist/adapters/cloudflare.d.mts +3 -3
  15. package/dist/adapters/cloudflare.d.ts +3 -3
  16. package/dist/adapters/cloudflare.mjs +26 -16
  17. package/dist/adapters/deno.cjs +32 -17
  18. package/dist/adapters/deno.d.cts +7 -3
  19. package/dist/adapters/deno.d.mts +7 -3
  20. package/dist/adapters/deno.d.ts +7 -3
  21. package/dist/adapters/deno.mjs +31 -16
  22. package/dist/adapters/node.cjs +48 -22
  23. package/dist/adapters/node.d.cts +2 -2
  24. package/dist/adapters/node.d.mts +2 -2
  25. package/dist/adapters/node.d.ts +2 -2
  26. package/dist/adapters/node.mjs +47 -21
  27. package/dist/adapters/uws.cjs +146 -0
  28. package/dist/adapters/uws.d.cts +19 -0
  29. package/dist/adapters/uws.d.mts +19 -0
  30. package/dist/adapters/uws.d.ts +19 -0
  31. package/dist/adapters/uws.mjs +144 -0
  32. package/dist/index.cjs +6 -4
  33. package/dist/index.d.cts +65 -17
  34. package/dist/index.d.mts +65 -17
  35. package/dist/index.d.ts +65 -17
  36. package/dist/index.mjs +2 -1
  37. package/dist/shared/crossws.6009d265.cjs +156 -0
  38. package/dist/shared/crossws.6f7f02b3.mjs +8 -0
  39. package/dist/shared/crossws.a6b0a7cc.mjs +150 -0
  40. package/dist/shared/crossws.deae10fd.cjs +10 -0
  41. package/package.json +29 -7
  42. package/websocket.d.ts +1 -0
  43. package/dist/shared/crossws.21e14e0d.cjs +0 -59
  44. package/dist/shared/crossws.9536f626.mjs +0 -54
@@ -3,7 +3,8 @@ import { v as validationExports, g as getDefaultExportFromCjs, e as extension$1,
3
3
  import require$$0 from 'events';
4
4
  import require$$2 from 'http';
5
5
  import require$$1 from 'crypto';
6
- import { d as defineWebSocketAdapter, a as WebSocketMessage, W as WebSocketError, b as WebSocketPeerBase } from '../shared/crossws.9536f626.mjs';
6
+ import { d as defineWebSocketAdapter, c as createCrossWS, W as WSMessage, a as WSPeer, t as toBufferLike } from '../shared/crossws.a6b0a7cc.mjs';
7
+ import { W as WebSocketError } from '../shared/crossws.6f7f02b3.mjs';
7
8
  import 'https';
8
9
  import 'net';
9
10
  import 'tls';
@@ -612,53 +613,68 @@ function abortHandshakeOrEmitwsClientError(server, req, socket, code, message) {
612
613
  const _WebSocketServer = /*@__PURE__*/getDefaultExportFromCjs(websocketServer);
613
614
 
614
615
  const node = defineWebSocketAdapter(
615
- (hooks, opts = {}) => {
616
- const wss = opts.wss || new _WebSocketServer({
616
+ (hooks, options = {}) => {
617
+ const crossws = createCrossWS(hooks, options);
618
+ const wss = options.wss || new _WebSocketServer({
617
619
  noServer: true,
618
- ...opts.serverOptions
620
+ ...options.serverOptions
619
621
  });
620
622
  wss.on("connection", (ws, req) => {
621
- const peer = new NodeWebSocketPeer({ node: { ws, req, server: wss } });
622
- hooks.open?.(peer);
623
+ const peer = new NodeWSPeer({ node: { ws, req, server: wss } });
624
+ crossws.open(peer);
623
625
  ws.on("message", (data, isBinary) => {
624
- hooks["node:message"]?.(peer, data, isBinary);
626
+ crossws.$("node:message", peer, data, isBinary);
625
627
  if (Array.isArray(data)) {
626
628
  data = Buffer.concat(data);
627
629
  }
628
- hooks.message?.(peer, new WebSocketMessage(data, isBinary));
630
+ crossws.message(peer, new WSMessage(data, isBinary));
629
631
  });
630
632
  ws.on("error", (error) => {
631
- hooks["node:error"]?.(peer, error);
632
- hooks.error?.(peer, new WebSocketError(error));
633
+ crossws.$("node:error", peer, error);
634
+ crossws.error(peer, new WebSocketError(error));
633
635
  });
634
636
  ws.on("close", (code, reason) => {
635
- hooks["node:close"]?.(peer, code, reason);
636
- hooks.close?.(peer, {
637
+ crossws.$("node:close", peer, code, reason);
638
+ crossws.close(peer, {
637
639
  code,
638
640
  reason: reason?.toString()
639
641
  });
640
642
  });
641
643
  ws.on("open", () => {
642
- hooks["node:open"]?.(peer);
644
+ crossws.$("node:open", peer);
643
645
  });
644
646
  ws.on("ping", (data) => {
645
- hooks["node:ping"]?.(peer, data);
647
+ crossws.$("node:ping", peer, data);
646
648
  });
647
649
  ws.on("pong", (data) => {
648
- hooks["node:pong"]?.(peer, data);
650
+ crossws.$("node:pong", peer, data);
649
651
  });
650
652
  ws.on(
651
653
  "unexpected-response",
652
654
  (req2, res) => {
653
- hooks["node:unexpected-response"]?.(peer, req2, res);
655
+ crossws.$("node:unexpected-response", peer, req2, res);
654
656
  }
655
657
  );
656
658
  ws.on("upgrade", (req2) => {
657
- hooks["node:upgrade"]?.(peer, req2);
659
+ crossws.$("node:upgrade", peer, req2);
658
660
  });
659
661
  });
662
+ wss.on("headers", function(outgoingHeaders, req) {
663
+ const upgradeHeaders = req._upgradeHeaders;
664
+ if (upgradeHeaders) {
665
+ const _headers = new Headers(upgradeHeaders);
666
+ for (const [key, value] of _headers) {
667
+ outgoingHeaders.push(`${key}: ${value}`);
668
+ }
669
+ }
670
+ });
660
671
  return {
661
- handleUpgrade: (req, socket, head) => {
672
+ handleUpgrade: async (req, socket, head) => {
673
+ const { headers } = await crossws.upgrade({
674
+ url: req.url || "",
675
+ headers: req.headers
676
+ });
677
+ req._upgradeHeaders = headers;
662
678
  wss.handleUpgrade(req, socket, head, (ws) => {
663
679
  wss.emit("connection", ws, req);
664
680
  });
@@ -666,7 +682,7 @@ const node = defineWebSocketAdapter(
666
682
  };
667
683
  }
668
684
  );
669
- class NodeWebSocketPeer extends WebSocketPeerBase {
685
+ class NodeWSPeer extends WSPeer {
670
686
  get id() {
671
687
  const socket = this.ctx.node.req.socket;
672
688
  if (!socket) {
@@ -675,11 +691,21 @@ class NodeWebSocketPeer extends WebSocketPeerBase {
675
691
  const addr = socket.remoteFamily === "IPv6" ? `[${socket.remoteAddress}]` : socket.remoteAddress;
676
692
  return `${addr}:${socket.remotePort}`;
677
693
  }
694
+ get url() {
695
+ return this.ctx.node.req.url || "/";
696
+ }
697
+ get headers() {
698
+ return this.ctx.node.req.headers;
699
+ }
678
700
  get readyState() {
679
701
  return this.ctx.node.ws.readyState;
680
702
  }
681
- send(message, compress) {
682
- this.ctx.node.ws.send(message, { compress });
703
+ send(message, options) {
704
+ this.ctx.node.ws.send(toBufferLike(message), {
705
+ compress: options?.compress,
706
+ binary: options?.binary,
707
+ ...options
708
+ });
683
709
  return 0;
684
710
  }
685
711
  }
@@ -0,0 +1,146 @@
1
+ 'use strict';
2
+
3
+ const peer = require('../shared/crossws.6009d265.cjs');
4
+
5
+ var __defProp = Object.defineProperty;
6
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7
+ var __publicField = (obj, key, value) => {
8
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
9
+ return value;
10
+ };
11
+ const uws = peer.defineWebSocketAdapter(
12
+ (hooks, options = {}) => {
13
+ const crossws = peer.createCrossWS(hooks, options);
14
+ const getWSPeer = (ws) => {
15
+ const userData = ws.getUserData();
16
+ if (userData._peer) {
17
+ return userData._peer;
18
+ }
19
+ const peer = new UWSWSPeer({ uws: { ws, userData } });
20
+ userData._peer = peer;
21
+ return peer;
22
+ };
23
+ const websocket = {
24
+ ...options.uws,
25
+ close(ws, code, message) {
26
+ const peer = getWSPeer(ws);
27
+ crossws.$("uws:close", peer, ws, code, message);
28
+ crossws.close(peer, { code, reason: message?.toString() });
29
+ },
30
+ drain(ws) {
31
+ const peer = getWSPeer(ws);
32
+ crossws.$("uws:drain", peer, ws);
33
+ },
34
+ message(ws, message, isBinary) {
35
+ const peer$1 = getWSPeer(ws);
36
+ crossws.$("uws:message", peer$1, ws, message, isBinary);
37
+ const msg = new peer.WSMessage(message, isBinary);
38
+ crossws.message(peer$1, msg);
39
+ },
40
+ open(ws) {
41
+ const peer = getWSPeer(ws);
42
+ crossws.$("uws:open", peer, ws);
43
+ crossws.open(peer);
44
+ },
45
+ ping(ws, message) {
46
+ const peer = getWSPeer(ws);
47
+ crossws.$("uws:ping", peer, ws, message);
48
+ },
49
+ pong(ws, message) {
50
+ const peer = getWSPeer(ws);
51
+ crossws.$("uws:pong", peer, ws, message);
52
+ },
53
+ subscription(ws, topic, newCount, oldCount) {
54
+ const peer = getWSPeer(ws);
55
+ crossws.$("uws:subscription", peer, ws, topic, newCount, oldCount);
56
+ },
57
+ async upgrade(res, req, context) {
58
+ let aborted = false;
59
+ res.onAborted(() => {
60
+ aborted = true;
61
+ });
62
+ const { headers } = await crossws.upgrade({
63
+ get url() {
64
+ return req.getUrl();
65
+ },
66
+ get headers() {
67
+ return _getHeaders(req);
68
+ }
69
+ });
70
+ res.writeStatus("101 Switching Protocols");
71
+ for (const [key, value] of new Headers(headers)) {
72
+ res.writeHeader(key, value);
73
+ }
74
+ if (aborted) {
75
+ return;
76
+ }
77
+ res.cork(() => {
78
+ res.upgrade(
79
+ {
80
+ req,
81
+ res,
82
+ context
83
+ },
84
+ req.getHeader("sec-websocket-key"),
85
+ req.getHeader("sec-websocket-protocol"),
86
+ req.getHeader("sec-websocket-extensions"),
87
+ context
88
+ );
89
+ });
90
+ }
91
+ };
92
+ return {
93
+ websocket
94
+ };
95
+ }
96
+ );
97
+ class UWSWSPeer extends peer.WSPeer {
98
+ constructor() {
99
+ super(...arguments);
100
+ __publicField(this, "_headers");
101
+ __publicField(this, "_decoder", new TextDecoder());
102
+ }
103
+ get id() {
104
+ try {
105
+ const addr = this._decoder.decode(
106
+ this.ctx.uws.ws?.getRemoteAddressAsText()
107
+ );
108
+ return addr.replace(/(0000:)+/, "");
109
+ } catch {
110
+ }
111
+ }
112
+ // TODO
113
+ // get readyState() {}
114
+ get url() {
115
+ return this.ctx.uws.userData.req.getUrl();
116
+ }
117
+ get headers() {
118
+ if (!this._headers) {
119
+ this._headers = _getHeaders(this.ctx.uws.userData.req);
120
+ }
121
+ return this._headers;
122
+ }
123
+ send(message, options) {
124
+ return this.ctx.uws.ws.send(
125
+ peer.toBufferLike(message),
126
+ options?.binary,
127
+ options?.compress
128
+ );
129
+ }
130
+ subscribe(topic) {
131
+ this.ctx.uws.ws.subscribe(topic);
132
+ }
133
+ publish(topic, message, options) {
134
+ this.ctx.uws.ws.publish(topic, message, options?.binary, options?.compress);
135
+ return 0;
136
+ }
137
+ }
138
+ function _getHeaders(req) {
139
+ const headers = [];
140
+ req.forEach((key, value) => {
141
+ headers.push([key, value]);
142
+ });
143
+ return headers;
144
+ }
145
+
146
+ module.exports = uws;
@@ -0,0 +1,19 @@
1
+ import { CrossWSOptions, WebSocketAdapter } from '../index.cjs';
2
+ import { WebSocketBehavior, HttpRequest, HttpResponse } from 'uWebSockets.js';
3
+
4
+ type UserData = {
5
+ _peer?: any;
6
+ req: HttpRequest;
7
+ res: HttpResponse;
8
+ context: any;
9
+ };
10
+ type WebSocketHandler = WebSocketBehavior<UserData>;
11
+ interface AdapterOptions extends CrossWSOptions {
12
+ uws?: Exclude<WebSocketBehavior<any>, "close" | "drain" | "message" | "open" | "ping" | "pong" | "subscription" | "upgrade">;
13
+ }
14
+ interface Adapter {
15
+ websocket: WebSocketHandler;
16
+ }
17
+ declare const _default: WebSocketAdapter<Adapter, AdapterOptions>;
18
+
19
+ export { type Adapter, type AdapterOptions, _default as default };
@@ -0,0 +1,19 @@
1
+ import { CrossWSOptions, WebSocketAdapter } from '../index.mjs';
2
+ import { WebSocketBehavior, HttpRequest, HttpResponse } from 'uWebSockets.js';
3
+
4
+ type UserData = {
5
+ _peer?: any;
6
+ req: HttpRequest;
7
+ res: HttpResponse;
8
+ context: any;
9
+ };
10
+ type WebSocketHandler = WebSocketBehavior<UserData>;
11
+ interface AdapterOptions extends CrossWSOptions {
12
+ uws?: Exclude<WebSocketBehavior<any>, "close" | "drain" | "message" | "open" | "ping" | "pong" | "subscription" | "upgrade">;
13
+ }
14
+ interface Adapter {
15
+ websocket: WebSocketHandler;
16
+ }
17
+ declare const _default: WebSocketAdapter<Adapter, AdapterOptions>;
18
+
19
+ export { type Adapter, type AdapterOptions, _default as default };
@@ -0,0 +1,19 @@
1
+ import { CrossWSOptions, WebSocketAdapter } from '../index.js';
2
+ import { WebSocketBehavior, HttpRequest, HttpResponse } from 'uWebSockets.js';
3
+
4
+ type UserData = {
5
+ _peer?: any;
6
+ req: HttpRequest;
7
+ res: HttpResponse;
8
+ context: any;
9
+ };
10
+ type WebSocketHandler = WebSocketBehavior<UserData>;
11
+ interface AdapterOptions extends CrossWSOptions {
12
+ uws?: Exclude<WebSocketBehavior<any>, "close" | "drain" | "message" | "open" | "ping" | "pong" | "subscription" | "upgrade">;
13
+ }
14
+ interface Adapter {
15
+ websocket: WebSocketHandler;
16
+ }
17
+ declare const _default: WebSocketAdapter<Adapter, AdapterOptions>;
18
+
19
+ export { type Adapter, type AdapterOptions, _default as default };
@@ -0,0 +1,144 @@
1
+ import { d as defineWebSocketAdapter, c as createCrossWS, W as WSMessage, a as WSPeer, t as toBufferLike } from '../shared/crossws.a6b0a7cc.mjs';
2
+
3
+ var __defProp = Object.defineProperty;
4
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
5
+ var __publicField = (obj, key, value) => {
6
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
7
+ return value;
8
+ };
9
+ const uws = defineWebSocketAdapter(
10
+ (hooks, options = {}) => {
11
+ const crossws = createCrossWS(hooks, options);
12
+ const getWSPeer = (ws) => {
13
+ const userData = ws.getUserData();
14
+ if (userData._peer) {
15
+ return userData._peer;
16
+ }
17
+ const peer = new UWSWSPeer({ uws: { ws, userData } });
18
+ userData._peer = peer;
19
+ return peer;
20
+ };
21
+ const websocket = {
22
+ ...options.uws,
23
+ close(ws, code, message) {
24
+ const peer = getWSPeer(ws);
25
+ crossws.$("uws:close", peer, ws, code, message);
26
+ crossws.close(peer, { code, reason: message?.toString() });
27
+ },
28
+ drain(ws) {
29
+ const peer = getWSPeer(ws);
30
+ crossws.$("uws:drain", peer, ws);
31
+ },
32
+ message(ws, message, isBinary) {
33
+ const peer = getWSPeer(ws);
34
+ crossws.$("uws:message", peer, ws, message, isBinary);
35
+ const msg = new WSMessage(message, isBinary);
36
+ crossws.message(peer, msg);
37
+ },
38
+ open(ws) {
39
+ const peer = getWSPeer(ws);
40
+ crossws.$("uws:open", peer, ws);
41
+ crossws.open(peer);
42
+ },
43
+ ping(ws, message) {
44
+ const peer = getWSPeer(ws);
45
+ crossws.$("uws:ping", peer, ws, message);
46
+ },
47
+ pong(ws, message) {
48
+ const peer = getWSPeer(ws);
49
+ crossws.$("uws:pong", peer, ws, message);
50
+ },
51
+ subscription(ws, topic, newCount, oldCount) {
52
+ const peer = getWSPeer(ws);
53
+ crossws.$("uws:subscription", peer, ws, topic, newCount, oldCount);
54
+ },
55
+ async upgrade(res, req, context) {
56
+ let aborted = false;
57
+ res.onAborted(() => {
58
+ aborted = true;
59
+ });
60
+ const { headers } = await crossws.upgrade({
61
+ get url() {
62
+ return req.getUrl();
63
+ },
64
+ get headers() {
65
+ return _getHeaders(req);
66
+ }
67
+ });
68
+ res.writeStatus("101 Switching Protocols");
69
+ for (const [key, value] of new Headers(headers)) {
70
+ res.writeHeader(key, value);
71
+ }
72
+ if (aborted) {
73
+ return;
74
+ }
75
+ res.cork(() => {
76
+ res.upgrade(
77
+ {
78
+ req,
79
+ res,
80
+ context
81
+ },
82
+ req.getHeader("sec-websocket-key"),
83
+ req.getHeader("sec-websocket-protocol"),
84
+ req.getHeader("sec-websocket-extensions"),
85
+ context
86
+ );
87
+ });
88
+ }
89
+ };
90
+ return {
91
+ websocket
92
+ };
93
+ }
94
+ );
95
+ class UWSWSPeer extends WSPeer {
96
+ constructor() {
97
+ super(...arguments);
98
+ __publicField(this, "_headers");
99
+ __publicField(this, "_decoder", new TextDecoder());
100
+ }
101
+ get id() {
102
+ try {
103
+ const addr = this._decoder.decode(
104
+ this.ctx.uws.ws?.getRemoteAddressAsText()
105
+ );
106
+ return addr.replace(/(0000:)+/, "");
107
+ } catch {
108
+ }
109
+ }
110
+ // TODO
111
+ // get readyState() {}
112
+ get url() {
113
+ return this.ctx.uws.userData.req.getUrl();
114
+ }
115
+ get headers() {
116
+ if (!this._headers) {
117
+ this._headers = _getHeaders(this.ctx.uws.userData.req);
118
+ }
119
+ return this._headers;
120
+ }
121
+ send(message, options) {
122
+ return this.ctx.uws.ws.send(
123
+ toBufferLike(message),
124
+ options?.binary,
125
+ options?.compress
126
+ );
127
+ }
128
+ subscribe(topic) {
129
+ this.ctx.uws.ws.subscribe(topic);
130
+ }
131
+ publish(topic, message, options) {
132
+ this.ctx.uws.ws.publish(topic, message, options?.binary, options?.compress);
133
+ return 0;
134
+ }
135
+ }
136
+ function _getHeaders(req) {
137
+ const headers = [];
138
+ req.forEach((key, value) => {
139
+ headers.push([key, value]);
140
+ });
141
+ return headers;
142
+ }
143
+
144
+ export { uws as default };
package/dist/index.cjs CHANGED
@@ -1,13 +1,15 @@
1
1
  'use strict';
2
2
 
3
- const peer = require('./shared/crossws.21e14e0d.cjs');
3
+ const peer = require('./shared/crossws.6009d265.cjs');
4
+ const error = require('./shared/crossws.deae10fd.cjs');
4
5
 
5
6
  function defineWebSocketHooks(hooks) {
6
7
  return hooks;
7
8
  }
8
9
 
9
- exports.WebSocketError = peer.WebSocketError;
10
- exports.WebSocketMessage = peer.WebSocketMessage;
11
- exports.WebSocketPeerBase = peer.WebSocketPeerBase;
10
+ exports.WSMessage = peer.WSMessage;
11
+ exports.WSPeer = peer.WSPeer;
12
+ exports.createCrossWS = peer.createCrossWS;
12
13
  exports.defineWebSocketAdapter = peer.defineWebSocketAdapter;
14
+ exports.WebSocketError = error.WebSocketError;
13
15
  exports.defineWebSocketHooks = defineWebSocketHooks;
package/dist/index.d.cts CHANGED
@@ -2,40 +2,65 @@ declare class WebSocketError extends Error {
2
2
  constructor(...args: any[]);
3
3
  }
4
4
 
5
- declare class WebSocketMessage {
6
- readonly rawData: string | ArrayBuffer | Uint8Array;
5
+ declare class WSMessage {
6
+ readonly rawData: any;
7
7
  readonly isBinary?: boolean | undefined;
8
- constructor(rawData: string | ArrayBuffer | Uint8Array, isBinary?: boolean | undefined);
8
+ constructor(rawData: any, isBinary?: boolean | undefined);
9
9
  text(): string;
10
10
  toString(): string;
11
11
  }
12
12
 
13
13
  type ReadyState = 0 | 1 | 2 | 3;
14
- interface WebSocketContext {
14
+ interface WSRequest {
15
+ readonly url: string;
16
+ readonly headers: HeadersInit;
15
17
  }
16
- declare abstract class WebSocketPeerBase<T extends WebSocketContext = WebSocketContext> {
17
- ctx: T;
18
- constructor(ctx: T);
18
+ declare abstract class WSPeer<AdapterContext = any> implements WSRequest {
19
+ ctx: AdapterContext;
20
+ _subscriptions: Set<string>;
21
+ constructor(ctx: AdapterContext);
19
22
  get id(): string | undefined;
23
+ get url(): string;
24
+ get headers(): HeadersInit;
20
25
  get readyState(): ReadyState | -1;
21
- abstract send(message: string | ArrayBuffer | Uint8Array, compress?: boolean): number;
26
+ abstract send(message: any, options?: {
27
+ compress?: boolean;
28
+ }): number;
29
+ publish(topic: string, message: any, options?: {
30
+ compress?: boolean;
31
+ }): void;
32
+ subscribe(topic: string): void;
33
+ unsubscribe(topic: string): void;
22
34
  toString(): string;
23
35
  }
24
36
 
25
- type WSHook<ArgsT extends Array<any> = []> = (peer: WebSocketPeerBase, ...args: ArgsT) => void | Promise<void>;
26
- declare function defineWebSocketHooks(hooks: Partial<WebSocketHooks>): Partial<WebSocketHooks>;
37
+ type MaybePromise<T> = T | Promise<T>;
38
+ type _UserHooks = WebSocketHooks & AdapterHooks;
39
+ type UserHooks = Partial<_UserHooks>;
40
+ declare function defineWebSocketHooks<T extends UserHooks = UserHooks>(hooks: T): T;
41
+ type UserHookName = Exclude<keyof _UserHooks, "$">;
42
+ type CatchAllHandler = <Name extends UserHookName>(name: Name, ...args: Parameters<_UserHooks[Name]>) => MaybePromise<void>;
27
43
  interface WebSocketHooks {
44
+ /** Catch-all handler */
45
+ $: CatchAllHandler;
46
+ /** Upgrading */
47
+ upgrade: (req: WSRequest) => MaybePromise<void | {
48
+ headers?: HeadersInit;
49
+ }>;
28
50
  /** A message is received */
29
- message: WSHook<[WebSocketMessage]>;
51
+ message: (peer: WSPeer, message: WSMessage) => MaybePromise<void>;
30
52
  /** A socket is opened */
31
- open: WSHook<[]>;
53
+ open: (peer: WSPeer) => MaybePromise<void>;
32
54
  /** A socket is closed */
33
- close: WSHook<[{
55
+ close: (peer: WSPeer, details: {
34
56
  code?: number;
35
57
  reason?: string;
36
- }]>;
58
+ }) => MaybePromise<void>;
37
59
  /** An error occurs */
38
- error: WSHook<[WebSocketError]>;
60
+ error: (peer: WSPeer, error: WebSocketError) => MaybePromise<void>;
61
+ }
62
+ type WSHook<ArgsT extends Array<any> = []> = (peer: WSPeer, ...args: ArgsT) => MaybePromise<void>;
63
+ interface AdapterHooks {
39
64
  "bun:message": WSHook<[ws: any, message: any]>;
40
65
  "bun:open": WSHook<[ws: any]>;
41
66
  "bun:close": WSHook<[ws: any]>;
@@ -59,9 +84,32 @@ interface WebSocketHooks {
59
84
  "node:pong": WSHook<[data: Buffer]>;
60
85
  "node:unexpected-response": WSHook<[req: any, res: any]>;
61
86
  "node:upgrade": WSHook<[req: any]>;
87
+ "uws:open": WSHook<[ws: any]>;
88
+ "uws:message": WSHook<[ws: any, message: any, isBinary: boolean]>;
89
+ "uws:close": WSHook<[ws: any, code: number, message: any]>;
90
+ "uws:ping": WSHook<[ws: any, message: any]>;
91
+ "uws:pong": WSHook<[ws: any, message: any]>;
92
+ "uws:drain": WSHook<[ws: any]>;
93
+ "uws:upgrade": WSHook<[res: any, req: any, context: any]>;
94
+ "uws:subscription": WSHook<[
95
+ ws: any,
96
+ topic: any,
97
+ newCount: number,
98
+ oldCount: number
99
+ ]>;
62
100
  }
63
101
 
64
- type WebSocketAdapter<RT = any, OT = any> = (hooks: Partial<WebSocketHooks>, opts: OT) => RT;
102
+ type WebSocketAdapter<RT = any, OT = any> = (hooks: Partial<WebSocketHooks & AdapterHooks>, opts: OT) => RT;
65
103
  declare function defineWebSocketAdapter<RT, OT>(factory: WebSocketAdapter<RT, OT>): WebSocketAdapter<RT, OT>;
66
104
 
67
- export { type WebSocketAdapter, type WebSocketContext, WebSocketError, type WebSocketHooks, WebSocketMessage, WebSocketPeerBase, defineWebSocketAdapter, defineWebSocketHooks };
105
+ interface CrossWS extends WebSocketHooks {
106
+ upgrade: (req: WSRequest) => Promise<{
107
+ headers: HeadersInit;
108
+ }>;
109
+ }
110
+ interface CrossWSOptions {
111
+ resolve?: (info: WSRequest | WSPeer) => UserHooks | Promise<UserHooks>;
112
+ }
113
+ declare function createCrossWS(hooks: UserHooks, options: CrossWSOptions): CrossWS;
114
+
115
+ export { type AdapterHooks, type CrossWS, type CrossWSOptions, type UserHooks, WSMessage, WSPeer, type WSRequest, type WebSocketAdapter, WebSocketError, type WebSocketHooks, type _UserHooks, createCrossWS, defineWebSocketAdapter, defineWebSocketHooks };