crossws 0.4.4 → 0.4.6
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/adapters/bunny.d.ts +2 -0
- package/adapters/vercel.d.ts +2 -0
- package/dist/THIRD-PARTY-LICENSES.md +33 -0
- package/dist/_chunks/_request.mjs +1 -4
- package/dist/_chunks/_types.d.mts +9 -10
- package/dist/_chunks/adapter.d.mts +7 -15
- package/dist/_chunks/adapter.mjs +6 -7
- package/dist/_chunks/bun.d.mts +2 -5
- package/dist/_chunks/bunny.d.mts +22 -0
- package/dist/_chunks/cloudflare.d.mts +3 -6
- package/dist/_chunks/deno.d.mts +2 -5
- package/dist/_chunks/error.mjs +1 -4
- package/dist/_chunks/libs/ws.mjs +96 -1171
- package/dist/_chunks/node.d.mts +36 -7
- package/dist/_chunks/node.mjs +129 -0
- package/dist/_chunks/peer.mjs +2 -60
- package/dist/_chunks/rolldown-runtime.mjs +8 -16
- package/dist/_chunks/sse.d.mts +2 -5
- package/dist/_chunks/web.d.mts +1 -3
- package/dist/adapters/bun.d.mts +1 -1
- package/dist/adapters/bun.mjs +3 -8
- package/dist/adapters/bunny.d.mts +2 -0
- package/dist/adapters/bunny.mjs +68 -0
- package/dist/adapters/cloudflare.d.mts +1 -1
- package/dist/adapters/cloudflare.mjs +11 -15
- package/dist/adapters/deno.d.mts +1 -1
- package/dist/adapters/deno.mjs +4 -9
- package/dist/adapters/node.d.mts +2 -2
- package/dist/adapters/node.mjs +2 -125
- package/dist/adapters/sse.d.mts +1 -1
- package/dist/adapters/sse.mjs +3 -8
- package/dist/adapters/uws.d.mts +2 -7
- package/dist/adapters/uws.mjs +6 -10
- package/dist/adapters/vercel.d.mts +25 -0
- package/dist/adapters/vercel.mjs +48 -0
- package/dist/index.d.mts +97 -2
- package/dist/index.mjs +178 -3
- package/dist/server/bun.d.mts +1 -7
- package/dist/server/bun.mjs +3 -7
- package/dist/server/bunny.d.mts +5 -0
- package/dist/server/bunny.mjs +23 -0
- package/dist/server/cloudflare.d.mts +1 -7
- package/dist/server/cloudflare.mjs +3 -7
- package/dist/server/default.d.mts +1 -7
- package/dist/server/default.mjs +3 -7
- package/dist/server/deno.d.mts +1 -7
- package/dist/server/deno.mjs +3 -7
- package/dist/server/node.d.mts +1 -7
- package/dist/server/node.mjs +3 -9
- package/dist/websocket/native.d.mts +0 -2
- package/dist/websocket/native.mjs +1 -5
- package/dist/websocket/node.d.mts +0 -2
- package/dist/websocket/node.mjs +2 -8
- package/dist/websocket/sse.d.mts +1 -4
- package/dist/websocket/sse.mjs +1 -4
- package/package.json +45 -42
- package/server/bunny.d.ts +2 -0
package/dist/_chunks/node.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Adapter, AdapterInstance, AdapterOptions, Hooks } from "./adapter.mjs";
|
|
2
2
|
import { EventEmitter } from "events";
|
|
3
3
|
import { Agent, ClientRequest, ClientRequestArgs, IncomingMessage, OutgoingHttpHeaders, Server } from "node:http";
|
|
4
4
|
import { Duplex, DuplexOptions } from "node:stream";
|
|
@@ -6,8 +6,6 @@ import { Server as Server$1 } from "node:https";
|
|
|
6
6
|
import { SecureContextOptions } from "node:tls";
|
|
7
7
|
import { URL } from "node:url";
|
|
8
8
|
import { ZlibOptions } from "node:zlib";
|
|
9
|
-
|
|
10
|
-
//#region types/ws.d.ts
|
|
11
9
|
type BufferLike = string | Buffer | DataView | number | ArrayBufferView | Uint8Array | ArrayBuffer | SharedArrayBuffer | readonly any[] | readonly number[] | {
|
|
12
10
|
valueOf(): ArrayBuffer;
|
|
13
11
|
} | {
|
|
@@ -284,8 +282,40 @@ declare class Server$2<T extends typeof WebSocket = typeof WebSocket, U extends
|
|
|
284
282
|
}
|
|
285
283
|
type WebSocketServer = Server$2;
|
|
286
284
|
declare function createWebSocketStream(websocket: WebSocket, options?: DuplexOptions): Duplex;
|
|
287
|
-
|
|
288
|
-
|
|
285
|
+
/**
|
|
286
|
+
* A Node.js `(req, socket, head)` upgrade handler.
|
|
287
|
+
*/
|
|
288
|
+
type NodeUpgradeHandler = (req: IncomingMessage, socket: Duplex, head: Buffer) => void | Promise<void>;
|
|
289
|
+
/**
|
|
290
|
+
* Wrap a Node.js `(req, socket, head)` upgrade handler as a {@link Hooks}
|
|
291
|
+
* object that can be mounted via `crossws/server/node`.
|
|
292
|
+
*
|
|
293
|
+
* The wrapped handler takes ownership of the socket; crossws's other
|
|
294
|
+
* lifecycle hooks (`open`/`message`/`close`/`error`) are **not** invoked
|
|
295
|
+
* for connections routed through it.
|
|
296
|
+
*
|
|
297
|
+
* @example
|
|
298
|
+
* ```ts
|
|
299
|
+
* import { WebSocketServer } from "ws";
|
|
300
|
+
* import { fromNodeUpgradeHandler } from "crossws/adapters/node";
|
|
301
|
+
* import { serve } from "crossws/server/node";
|
|
302
|
+
*
|
|
303
|
+
* const wss = new WebSocketServer({ noServer: true });
|
|
304
|
+
* wss.on("connection", (ws) => {
|
|
305
|
+
* ws.on("message", (data) => ws.send(data));
|
|
306
|
+
* });
|
|
307
|
+
*
|
|
308
|
+
* serve({
|
|
309
|
+
* websocket: fromNodeUpgradeHandler((req, socket, head) => {
|
|
310
|
+
* wss.handleUpgrade(req, socket, head, (ws) => {
|
|
311
|
+
* wss.emit("connection", ws, req);
|
|
312
|
+
* });
|
|
313
|
+
* }),
|
|
314
|
+
* fetch: () => new Response("ok"),
|
|
315
|
+
* });
|
|
316
|
+
* ```
|
|
317
|
+
*/
|
|
318
|
+
declare function fromNodeUpgradeHandler(handler: NodeUpgradeHandler): Partial<Hooks>;
|
|
289
319
|
interface NodeAdapter extends AdapterInstance {
|
|
290
320
|
handleUpgrade(req: IncomingMessage, socket: Duplex, head: Buffer, webRequest?: Request): Promise<void>;
|
|
291
321
|
closeAll: (code?: number, data?: string | Buffer, force?: boolean) => void;
|
|
@@ -295,5 +325,4 @@ interface NodeOptions extends AdapterOptions {
|
|
|
295
325
|
serverOptions?: ServerOptions;
|
|
296
326
|
}
|
|
297
327
|
declare const nodeAdapter: Adapter<NodeAdapter, NodeOptions>;
|
|
298
|
-
|
|
299
|
-
export { NodeOptions as n, nodeAdapter as r, NodeAdapter as t };
|
|
328
|
+
export { NodeAdapter, NodeOptions, NodeUpgradeHandler, fromNodeUpgradeHandler, nodeAdapter };
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { AdapterHookable, adapterUtils, getPeers } from "./adapter.mjs";
|
|
2
|
+
import { import_websocket_server } from "./libs/ws.mjs";
|
|
3
|
+
import { Message, Peer, toBufferLike } from "./peer.mjs";
|
|
4
|
+
import { WSError } from "./error.mjs";
|
|
5
|
+
import { StubRequest } from "./_request.mjs";
|
|
6
|
+
function fromNodeUpgradeHandler(handler) {
|
|
7
|
+
return { async upgrade(request) {
|
|
8
|
+
const node = request.runtime?.node;
|
|
9
|
+
if (!node?.upgrade) throw new Error("[crossws] `fromNodeUpgradeHandler` must be mounted via `crossws/server/node`.");
|
|
10
|
+
await handler(node.req, node.upgrade.socket, node.upgrade.head);
|
|
11
|
+
return { handled: true };
|
|
12
|
+
} };
|
|
13
|
+
}
|
|
14
|
+
const nodeAdapter = (options = {}) => {
|
|
15
|
+
if ("Deno" in globalThis || "Bun" in globalThis) throw new Error("[crossws] Using Node.js adapter in an incompatible environment.");
|
|
16
|
+
const hooks = new AdapterHookable(options);
|
|
17
|
+
const globalPeers = /* @__PURE__ */ new Map();
|
|
18
|
+
const wss = options.wss || new import_websocket_server.default({
|
|
19
|
+
noServer: true,
|
|
20
|
+
handleProtocols: () => false,
|
|
21
|
+
...options.serverOptions
|
|
22
|
+
});
|
|
23
|
+
wss.on("connection", (ws, nodeReq) => {
|
|
24
|
+
const request = new NodeReqProxy(nodeReq);
|
|
25
|
+
const peers = getPeers(globalPeers, nodeReq._namespace);
|
|
26
|
+
const peer = new NodePeer({
|
|
27
|
+
ws,
|
|
28
|
+
request,
|
|
29
|
+
peers,
|
|
30
|
+
nodeReq,
|
|
31
|
+
namespace: nodeReq._namespace
|
|
32
|
+
});
|
|
33
|
+
peers.add(peer);
|
|
34
|
+
hooks.callHook("open", peer);
|
|
35
|
+
ws.on("message", (data, isBinary) => {
|
|
36
|
+
if (Array.isArray(data)) data = Buffer.concat(data);
|
|
37
|
+
if (!isBinary && Buffer.isBuffer(data)) data = data.toString("utf8");
|
|
38
|
+
hooks.callHook("message", peer, new Message(data, peer));
|
|
39
|
+
});
|
|
40
|
+
ws.on("error", (error) => {
|
|
41
|
+
peers.delete(peer);
|
|
42
|
+
hooks.callHook("error", peer, new WSError(error));
|
|
43
|
+
});
|
|
44
|
+
ws.on("close", (code, reason) => {
|
|
45
|
+
peers.delete(peer);
|
|
46
|
+
hooks.callHook("close", peer, {
|
|
47
|
+
code,
|
|
48
|
+
reason: reason?.toString()
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
wss.on("headers", (outgoingHeaders, req) => {
|
|
53
|
+
const upgradeHeaders = req._upgradeHeaders;
|
|
54
|
+
if (upgradeHeaders) for (const [key, value] of new Headers(upgradeHeaders)) outgoingHeaders.push(`${key}: ${value}`);
|
|
55
|
+
});
|
|
56
|
+
return {
|
|
57
|
+
...adapterUtils(globalPeers),
|
|
58
|
+
handleUpgrade: async (nodeReq, socket, head, webRequest) => {
|
|
59
|
+
const request = webRequest || new NodeReqProxy(nodeReq);
|
|
60
|
+
const { upgradeHeaders, endResponse, handled, context, namespace } = await hooks.upgrade(request);
|
|
61
|
+
if (endResponse) return sendResponse(socket, endResponse);
|
|
62
|
+
if (handled) return;
|
|
63
|
+
nodeReq._request = request;
|
|
64
|
+
nodeReq._upgradeHeaders = upgradeHeaders;
|
|
65
|
+
nodeReq._context = context;
|
|
66
|
+
nodeReq._namespace = namespace;
|
|
67
|
+
wss.handleUpgrade(nodeReq, socket, head, (ws) => {
|
|
68
|
+
wss.emit("connection", ws, nodeReq);
|
|
69
|
+
});
|
|
70
|
+
},
|
|
71
|
+
closeAll: (code, data, force) => {
|
|
72
|
+
for (const client of wss.clients) if (force) client.terminate();
|
|
73
|
+
else client.close(code, data);
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
var NodePeer = class extends Peer {
|
|
78
|
+
get remoteAddress() {
|
|
79
|
+
return this._internal.nodeReq.socket?.remoteAddress;
|
|
80
|
+
}
|
|
81
|
+
get context() {
|
|
82
|
+
return this._internal.nodeReq._context;
|
|
83
|
+
}
|
|
84
|
+
send(data, options) {
|
|
85
|
+
const dataBuff = toBufferLike(data);
|
|
86
|
+
const isBinary = typeof dataBuff !== "string";
|
|
87
|
+
this._internal.ws.send(dataBuff, {
|
|
88
|
+
compress: options?.compress,
|
|
89
|
+
binary: isBinary,
|
|
90
|
+
...options
|
|
91
|
+
});
|
|
92
|
+
return 0;
|
|
93
|
+
}
|
|
94
|
+
publish(topic, data, options) {
|
|
95
|
+
const dataBuff = toBufferLike(data);
|
|
96
|
+
const isBinary = typeof data !== "string";
|
|
97
|
+
const sendOptions = {
|
|
98
|
+
compress: options?.compress,
|
|
99
|
+
binary: isBinary,
|
|
100
|
+
...options
|
|
101
|
+
};
|
|
102
|
+
for (const peer of this._internal.peers) if (peer !== this && peer._topics.has(topic)) peer._internal.ws.send(dataBuff, sendOptions);
|
|
103
|
+
}
|
|
104
|
+
close(code, data) {
|
|
105
|
+
this._internal.ws.close(code, data);
|
|
106
|
+
}
|
|
107
|
+
terminate() {
|
|
108
|
+
this._internal.ws.terminate();
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
var NodeReqProxy = class extends StubRequest {
|
|
112
|
+
constructor(req) {
|
|
113
|
+
const host = req.headers["host"] || "localhost";
|
|
114
|
+
const url = `${req.socket?.encrypted ?? req.headers["x-forwarded-proto"] === "https" ? "https" : "http"}://${host}${req.url}`;
|
|
115
|
+
super(url, { headers: req.headers });
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
async function sendResponse(socket, res) {
|
|
119
|
+
const head = [`HTTP/1.1 ${res.status || 200} ${res.statusText || ""}`, ...[...res.headers.entries()].map(([key, value]) => `${key}: ${value}`)];
|
|
120
|
+
socket.write(head.join("\r\n") + "\r\n\r\n");
|
|
121
|
+
if (res.body) for await (const chunk of res.body) socket.write(chunk);
|
|
122
|
+
return new Promise((resolve) => {
|
|
123
|
+
socket.end(() => {
|
|
124
|
+
socket.destroy();
|
|
125
|
+
resolve();
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
export { fromNodeUpgradeHandler, nodeAdapter };
|
package/dist/_chunks/peer.mjs
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
const kNodeInspect = /* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom");
|
|
1
|
+
const kNodeInspect = /*#__PURE__*/ Symbol.for("nodejs.util.inspect.custom");
|
|
3
2
|
function toBufferLike(val) {
|
|
4
3
|
if (val === void 0 || val === null) return "";
|
|
5
4
|
const type = typeof val;
|
|
@@ -24,15 +23,9 @@ function isPlainObject(value) {
|
|
|
24
23
|
if (Symbol.toStringTag in value) return Object.prototype.toString.call(value) === "[object Module]";
|
|
25
24
|
return true;
|
|
26
25
|
}
|
|
27
|
-
|
|
28
|
-
//#endregion
|
|
29
|
-
//#region src/message.ts
|
|
30
26
|
var Message = class {
|
|
31
|
-
/** Access to the original [message event](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/message_event) if available. */
|
|
32
27
|
event;
|
|
33
|
-
/** Access to the Peer that emitted the message. */
|
|
34
28
|
peer;
|
|
35
|
-
/** Raw message data (can be of any type). */
|
|
36
29
|
rawData;
|
|
37
30
|
#id;
|
|
38
31
|
#uint8Array;
|
|
@@ -45,18 +38,10 @@ var Message = class {
|
|
|
45
38
|
this.peer = peer;
|
|
46
39
|
this.event = event;
|
|
47
40
|
}
|
|
48
|
-
/**
|
|
49
|
-
* Unique random [uuid v4](https://developer.mozilla.org/en-US/docs/Glossary/UUID) identifier for the message.
|
|
50
|
-
*/
|
|
51
41
|
get id() {
|
|
52
42
|
if (!this.#id) this.#id = crypto.randomUUID();
|
|
53
43
|
return this.#id;
|
|
54
44
|
}
|
|
55
|
-
/**
|
|
56
|
-
* Get data as [Uint8Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) value.
|
|
57
|
-
*
|
|
58
|
-
* If raw data is in any other format or string, it will be automatically converted and encoded.
|
|
59
|
-
*/
|
|
60
45
|
uint8Array() {
|
|
61
46
|
const _uint8Array = this.#uint8Array;
|
|
62
47
|
if (_uint8Array) return _uint8Array;
|
|
@@ -75,11 +60,6 @@ var Message = class {
|
|
|
75
60
|
if (rawData instanceof DataView) return this.#uint8Array = new Uint8Array(rawData.buffer, rawData.byteOffset, rawData.byteLength);
|
|
76
61
|
throw new TypeError(`Unsupported message type: ${Object.prototype.toString.call(rawData)}`);
|
|
77
62
|
}
|
|
78
|
-
/**
|
|
79
|
-
* Get data as [ArrayBuffer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer) or [SharedArrayBuffer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer) value.
|
|
80
|
-
*
|
|
81
|
-
* If raw data is in any other format or string, it will be automatically converted and encoded.
|
|
82
|
-
*/
|
|
83
63
|
arrayBuffer() {
|
|
84
64
|
const _arrayBuffer = this.#arrayBuffer;
|
|
85
65
|
if (_arrayBuffer) return _arrayBuffer;
|
|
@@ -87,10 +67,6 @@ var Message = class {
|
|
|
87
67
|
if (rawData instanceof ArrayBuffer || rawData instanceof SharedArrayBuffer) return this.#arrayBuffer = rawData;
|
|
88
68
|
return this.#arrayBuffer = this.uint8Array().buffer;
|
|
89
69
|
}
|
|
90
|
-
/**
|
|
91
|
-
* Get data as [Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob) value.
|
|
92
|
-
*
|
|
93
|
-
* If raw data is in any other format or string, it will be automatically converted and encoded. */
|
|
94
70
|
blob() {
|
|
95
71
|
const _blob = this.#blob;
|
|
96
72
|
if (_blob) return _blob;
|
|
@@ -98,11 +74,6 @@ var Message = class {
|
|
|
98
74
|
if (rawData instanceof Blob) return this.#blob = rawData;
|
|
99
75
|
return this.#blob = new Blob([this.uint8Array()]);
|
|
100
76
|
}
|
|
101
|
-
/**
|
|
102
|
-
* Get stringified text version of the message.
|
|
103
|
-
*
|
|
104
|
-
* If raw data is in any other format, it will be automatically converted and decoded.
|
|
105
|
-
*/
|
|
106
77
|
text() {
|
|
107
78
|
const _text = this.#text;
|
|
108
79
|
if (_text) return _text;
|
|
@@ -110,17 +81,11 @@ var Message = class {
|
|
|
110
81
|
if (typeof rawData === "string") return this.#text = rawData;
|
|
111
82
|
return this.#text = new TextDecoder().decode(this.uint8Array());
|
|
112
83
|
}
|
|
113
|
-
/**
|
|
114
|
-
* Get parsed version of the message text with [`JSON.parse()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse).
|
|
115
|
-
*/
|
|
116
84
|
json() {
|
|
117
85
|
const _json = this.#json;
|
|
118
86
|
if (_json) return _json;
|
|
119
87
|
return this.#json = JSON.parse(this.text());
|
|
120
88
|
}
|
|
121
|
-
/**
|
|
122
|
-
* Message data (value varies based on `peer.websocket.binaryType`).
|
|
123
|
-
*/
|
|
124
89
|
get data() {
|
|
125
90
|
switch (this.peer?.websocket?.binaryType) {
|
|
126
91
|
case "arraybuffer": return this.arrayBuffer();
|
|
@@ -145,9 +110,6 @@ var Message = class {
|
|
|
145
110
|
} };
|
|
146
111
|
}
|
|
147
112
|
};
|
|
148
|
-
|
|
149
|
-
//#endregion
|
|
150
|
-
//#region src/peer.ts
|
|
151
113
|
var Peer = class {
|
|
152
114
|
_internal;
|
|
153
115
|
_topics;
|
|
@@ -163,27 +125,14 @@ var Peer = class {
|
|
|
163
125
|
get namespace() {
|
|
164
126
|
return this._internal.namespace;
|
|
165
127
|
}
|
|
166
|
-
/**
|
|
167
|
-
* Unique random [uuid v4](https://developer.mozilla.org/en-US/docs/Glossary/UUID) identifier for the peer.
|
|
168
|
-
*/
|
|
169
128
|
get id() {
|
|
170
129
|
if (!this._id) this._id = crypto.randomUUID();
|
|
171
130
|
return this._id;
|
|
172
131
|
}
|
|
173
|
-
/** IP address of the peer */
|
|
174
132
|
get remoteAddress() {}
|
|
175
|
-
/** upgrade request */
|
|
176
133
|
get request() {
|
|
177
134
|
return this._internal.request;
|
|
178
135
|
}
|
|
179
|
-
/**
|
|
180
|
-
* Get the [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) instance.
|
|
181
|
-
*
|
|
182
|
-
* **Note:** crossws adds polyfill for the following properties if native values are not available:
|
|
183
|
-
* - `protocol`: Extracted from the `sec-websocket-protocol` header.
|
|
184
|
-
* - `extensions`: Extracted from the `sec-websocket-extensions` header.
|
|
185
|
-
* - `url`: Extracted from the request URL (http -> ws).
|
|
186
|
-
* */
|
|
187
136
|
get websocket() {
|
|
188
137
|
if (!this.#ws) {
|
|
189
138
|
const _ws = this._internal.ws;
|
|
@@ -192,23 +141,18 @@ var Peer = class {
|
|
|
192
141
|
}
|
|
193
142
|
return this.#ws;
|
|
194
143
|
}
|
|
195
|
-
/** All connected peers to the server */
|
|
196
144
|
get peers() {
|
|
197
145
|
return this._internal.peers || /* @__PURE__ */ new Set();
|
|
198
146
|
}
|
|
199
|
-
/** All topics, this peer has been subscribed to. */
|
|
200
147
|
get topics() {
|
|
201
148
|
return this._topics;
|
|
202
149
|
}
|
|
203
|
-
/** Abruptly close the connection */
|
|
204
150
|
terminate() {
|
|
205
151
|
this.close();
|
|
206
152
|
}
|
|
207
|
-
/** Subscribe to a topic */
|
|
208
153
|
subscribe(topic) {
|
|
209
154
|
this._topics.add(topic);
|
|
210
155
|
}
|
|
211
|
-
/** Unsubscribe from a topic */
|
|
212
156
|
unsubscribe(topic) {
|
|
213
157
|
this._topics.delete(topic);
|
|
214
158
|
}
|
|
@@ -239,6 +183,4 @@ function createWsProxy(ws, request) {
|
|
|
239
183
|
return value;
|
|
240
184
|
} });
|
|
241
185
|
}
|
|
242
|
-
|
|
243
|
-
//#endregion
|
|
244
|
-
export { toString as i, Message as n, toBufferLike as r, Peer as t };
|
|
186
|
+
export { Message, Peer, toBufferLike, toString };
|
|
@@ -1,24 +1,18 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
|
-
|
|
3
|
-
//#region rolldown:runtime
|
|
4
2
|
var __create = Object.create;
|
|
5
3
|
var __defProp = Object.defineProperty;
|
|
6
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
7
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
8
6
|
var __getProtoOf = Object.getPrototypeOf;
|
|
9
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
10
|
-
var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
8
|
+
var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
|
|
11
9
|
var __copyProps = (to, from, except, desc) => {
|
|
12
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
}
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
11
|
+
key = keys[i];
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
13
|
+
get: ((k) => from[k]).bind(null, key),
|
|
14
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
15
|
+
});
|
|
22
16
|
}
|
|
23
17
|
return to;
|
|
24
18
|
};
|
|
@@ -27,6 +21,4 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
27
21
|
enumerable: true
|
|
28
22
|
}) : target, mod));
|
|
29
23
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
30
|
-
|
|
31
|
-
//#endregion
|
|
32
|
-
export { __require as n, __toESM as r, __commonJSMin as t };
|
|
24
|
+
export { __commonJSMin, __require, __toESM };
|
package/dist/_chunks/sse.d.mts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
//#region src/adapters/sse.d.ts
|
|
1
|
+
import { Adapter, AdapterInstance, AdapterOptions } from "./adapter.mjs";
|
|
4
2
|
interface SSEAdapter extends AdapterInstance {
|
|
5
3
|
fetch(req: Request): Promise<Response>;
|
|
6
4
|
}
|
|
@@ -8,5 +6,4 @@ interface SSEOptions extends AdapterOptions {
|
|
|
8
6
|
bidir?: boolean;
|
|
9
7
|
}
|
|
10
8
|
declare const sseAdapter: Adapter<SSEAdapter, SSEOptions>;
|
|
11
|
-
|
|
12
|
-
export { SSEOptions as n, sseAdapter as r, SSEAdapter as t };
|
|
9
|
+
export { SSEAdapter, SSEOptions, sseAdapter };
|
package/dist/_chunks/web.d.mts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
//#region types/web.d.ts
|
|
2
1
|
/**
|
|
3
2
|
* A CloseEvent is sent to clients using WebSockets when the connection is closed. This is delivered to the listener indicated by the WebSocket object's onclose attribute.
|
|
4
3
|
*
|
|
@@ -294,5 +293,4 @@ interface WebSocket extends EventTarget {
|
|
|
294
293
|
removeEventListener<K extends keyof WebSocketEventMap>(type: K, listener: (this: WebSocket, ev: WebSocketEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
|
|
295
294
|
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
|
296
295
|
}
|
|
297
|
-
|
|
298
|
-
export { WebSocket as a, MessageEvent as i, Event as n, EventTarget as r, CloseEvent as t };
|
|
296
|
+
export { CloseEvent, Event, EventTarget, MessageEvent, WebSocket };
|
package/dist/adapters/bun.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BunAdapter, BunOptions, bunAdapter } from "../_chunks/bun.mjs";
|
|
2
2
|
export { BunAdapter, BunOptions, bunAdapter as default };
|
package/dist/adapters/bun.mjs
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
//#region src/adapters/bun.ts
|
|
1
|
+
import { AdapterHookable, adapterUtils, getPeers } from "../_chunks/adapter.mjs";
|
|
2
|
+
import { Message, Peer, toBufferLike } from "../_chunks/peer.mjs";
|
|
5
3
|
const bunAdapter = (options = {}) => {
|
|
6
4
|
if (typeof Bun === "undefined") throw new Error("[crossws] Using Bun adapter in an incompatible environment.");
|
|
7
5
|
const hooks = new AdapterHookable(options);
|
|
@@ -44,7 +42,6 @@ const bunAdapter = (options = {}) => {
|
|
|
44
42
|
}
|
|
45
43
|
};
|
|
46
44
|
};
|
|
47
|
-
var bun_default = bunAdapter;
|
|
48
45
|
function getPeer(ws, peers) {
|
|
49
46
|
if (ws.data.peer) return ws.data.peer;
|
|
50
47
|
const peer = new BunPeer({
|
|
@@ -84,6 +81,4 @@ var BunPeer = class extends Peer {
|
|
|
84
81
|
this._internal.ws.terminate();
|
|
85
82
|
}
|
|
86
83
|
};
|
|
87
|
-
|
|
88
|
-
//#endregion
|
|
89
|
-
export { bun_default as default };
|
|
84
|
+
export { bunAdapter as default };
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { AdapterHookable, adapterUtils, getPeers } from "../_chunks/adapter.mjs";
|
|
2
|
+
import { Message, Peer, toBufferLike } from "../_chunks/peer.mjs";
|
|
3
|
+
import { WSError } from "../_chunks/error.mjs";
|
|
4
|
+
const bunnyAdapter = (options = {}) => {
|
|
5
|
+
const hooks = new AdapterHookable(options);
|
|
6
|
+
const globalPeers = /* @__PURE__ */ new Map();
|
|
7
|
+
return {
|
|
8
|
+
...adapterUtils(globalPeers),
|
|
9
|
+
handleUpgrade: async (request) => {
|
|
10
|
+
if (!request.upgradeWebSocket || typeof request.upgradeWebSocket !== "function") throw new Error("[crossws] Bunny adapter requires the request to have an upgradeWebSocket method.");
|
|
11
|
+
const { endResponse, context, namespace, upgradeHeaders } = await hooks.upgrade(request);
|
|
12
|
+
if (endResponse) return endResponse;
|
|
13
|
+
const negotiatedProtocol = (upgradeHeaders instanceof Headers ? upgradeHeaders : new Headers(upgradeHeaders)).get("sec-websocket-protocol") ?? options.protocol;
|
|
14
|
+
const upgradeOptions = {};
|
|
15
|
+
if (negotiatedProtocol) upgradeOptions.protocol = negotiatedProtocol;
|
|
16
|
+
if (options.idleTimeout !== void 0) upgradeOptions.idleTimeout = options.idleTimeout;
|
|
17
|
+
const { response, socket } = request.upgradeWebSocket(Object.keys(upgradeOptions).length > 0 ? upgradeOptions : void 0);
|
|
18
|
+
const remoteAddress = request.headers.get("x-real-ip") || void 0;
|
|
19
|
+
const peers = getPeers(globalPeers, namespace);
|
|
20
|
+
const peer = new BunnyPeer({
|
|
21
|
+
ws: socket,
|
|
22
|
+
request,
|
|
23
|
+
namespace,
|
|
24
|
+
remoteAddress,
|
|
25
|
+
peers,
|
|
26
|
+
context
|
|
27
|
+
});
|
|
28
|
+
peers.add(peer);
|
|
29
|
+
socket.addEventListener("open", () => {
|
|
30
|
+
hooks.callHook("open", peer);
|
|
31
|
+
});
|
|
32
|
+
socket.addEventListener("message", (event) => {
|
|
33
|
+
hooks.callHook("message", peer, new Message(event.data, peer, event));
|
|
34
|
+
});
|
|
35
|
+
socket.addEventListener("close", (event) => {
|
|
36
|
+
peers.delete(peer);
|
|
37
|
+
hooks.callHook("close", peer, {
|
|
38
|
+
code: event.code,
|
|
39
|
+
reason: event.reason
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
socket.addEventListener("error", (error) => {
|
|
43
|
+
peers.delete(peer);
|
|
44
|
+
hooks.callHook("error", peer, new WSError(error));
|
|
45
|
+
});
|
|
46
|
+
return response;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
var BunnyPeer = class extends Peer {
|
|
51
|
+
get remoteAddress() {
|
|
52
|
+
return this._internal.remoteAddress;
|
|
53
|
+
}
|
|
54
|
+
send(data) {
|
|
55
|
+
return this._internal.ws.send(toBufferLike(data));
|
|
56
|
+
}
|
|
57
|
+
publish(topic, data) {
|
|
58
|
+
const dataBuff = toBufferLike(data);
|
|
59
|
+
for (const peer of this._internal.peers) if (peer !== this && peer._topics.has(topic)) peer._internal.ws.send(dataBuff);
|
|
60
|
+
}
|
|
61
|
+
close(code, reason) {
|
|
62
|
+
this._internal.ws.close(code, reason);
|
|
63
|
+
}
|
|
64
|
+
terminate() {
|
|
65
|
+
this._internal.ws.close();
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
export { bunnyAdapter as default };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CloudflareDurableAdapter, CloudflareOptions, cloudflareAdapter } from "../_chunks/cloudflare.mjs";
|
|
2
2
|
export { CloudflareDurableAdapter, CloudflareOptions, cloudflareAdapter as default };
|
|
@@ -1,16 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { env
|
|
6
|
-
|
|
7
|
-
//#region src/adapters/cloudflare.ts
|
|
1
|
+
import { AdapterHookable, adapterUtils, getPeers } from "../_chunks/adapter.mjs";
|
|
2
|
+
import { Message, Peer, toBufferLike } from "../_chunks/peer.mjs";
|
|
3
|
+
import { WSError } from "../_chunks/error.mjs";
|
|
4
|
+
import { StubRequest } from "../_chunks/_request.mjs";
|
|
5
|
+
import { env } from "cloudflare:workers";
|
|
8
6
|
const cloudflareAdapter = (opts = {}) => {
|
|
9
7
|
const hooks = new AdapterHookable(opts);
|
|
10
8
|
const globalPeers = /* @__PURE__ */ new Map();
|
|
11
|
-
const resolveDurableStub = opts.resolveDurableStub || ((_req, env, _context) => {
|
|
9
|
+
const resolveDurableStub = opts.resolveDurableStub || ((_req, env$1, _context) => {
|
|
12
10
|
const bindingName = opts.bindingName || "$DurableObject";
|
|
13
|
-
const binding = (env || env
|
|
11
|
+
const binding = (env$1 || env)[bindingName];
|
|
14
12
|
if (binding) {
|
|
15
13
|
const instanceId = binding.idFromName(opts.instanceName || "crossws");
|
|
16
14
|
return binding.get(instanceId);
|
|
@@ -59,7 +57,7 @@ const cloudflareAdapter = (opts = {}) => {
|
|
|
59
57
|
headers: upgradeHeaders
|
|
60
58
|
});
|
|
61
59
|
},
|
|
62
|
-
handleDurableInit: async (
|
|
60
|
+
handleDurableInit: async (_obj, _state, _env) => {},
|
|
63
61
|
handleDurableUpgrade: async (obj, request) => {
|
|
64
62
|
const { upgradeHeaders, endResponse, namespace } = await hooks.upgrade(request);
|
|
65
63
|
if (endResponse) return endResponse;
|
|
@@ -95,7 +93,7 @@ const cloudflareAdapter = (opts = {}) => {
|
|
|
95
93
|
return durablePublish(topic, data, opts);
|
|
96
94
|
},
|
|
97
95
|
publish: async (topic, data, opts) => {
|
|
98
|
-
const stub = await resolveDurableStub(void 0, env
|
|
96
|
+
const stub = await resolveDurableStub(void 0, env, void 0);
|
|
99
97
|
if (!stub) throw new Error("[crossws] Durable Object binding cannot be resolved.");
|
|
100
98
|
try {
|
|
101
99
|
return await stub.webSocketPublish(topic, data, opts);
|
|
@@ -106,7 +104,6 @@ const cloudflareAdapter = (opts = {}) => {
|
|
|
106
104
|
}
|
|
107
105
|
};
|
|
108
106
|
};
|
|
109
|
-
var cloudflare_default = cloudflareAdapter;
|
|
110
107
|
var CloudflareDurablePeer = class CloudflareDurablePeer extends Peer {
|
|
111
108
|
get peers() {
|
|
112
109
|
return new Set(this.#getwebsockets().map((ws) => CloudflareDurablePeer._restore(this._internal.durable, ws)));
|
|
@@ -149,6 +146,7 @@ var CloudflareDurablePeer = class CloudflareDurablePeer extends Peer {
|
|
|
149
146
|
if (state.i) peer._id = state.i;
|
|
150
147
|
if (request?.url) state.u = request.url;
|
|
151
148
|
state.i = peer.id;
|
|
149
|
+
state.n = peer.namespace;
|
|
152
150
|
setAttachedState(ws, state);
|
|
153
151
|
return peer;
|
|
154
152
|
}
|
|
@@ -176,6 +174,4 @@ function setAttachedState(ws, state) {
|
|
|
176
174
|
ws._crosswsState = state;
|
|
177
175
|
ws.serializeAttachment(state);
|
|
178
176
|
}
|
|
179
|
-
|
|
180
|
-
//#endregion
|
|
181
|
-
export { cloudflare_default as default };
|
|
177
|
+
export { cloudflareAdapter as default };
|
package/dist/adapters/deno.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DenoAdapter, DenoOptions, denoAdapter } from "../_chunks/deno.mjs";
|
|
2
2
|
export { DenoAdapter, DenoOptions, denoAdapter as default };
|
package/dist/adapters/deno.mjs
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
//#region src/adapters/deno.ts
|
|
1
|
+
import { AdapterHookable, adapterUtils, getPeers } from "../_chunks/adapter.mjs";
|
|
2
|
+
import { Message, Peer, toBufferLike } from "../_chunks/peer.mjs";
|
|
3
|
+
import { WSError } from "../_chunks/error.mjs";
|
|
6
4
|
const denoAdapter = (options = {}) => {
|
|
7
5
|
if (typeof Deno === "undefined") throw new Error("[crossws] Using Deno adapter in an incompatible environment.");
|
|
8
6
|
const hooks = new AdapterHookable(options);
|
|
@@ -45,7 +43,6 @@ const denoAdapter = (options = {}) => {
|
|
|
45
43
|
}
|
|
46
44
|
};
|
|
47
45
|
};
|
|
48
|
-
var deno_default = denoAdapter;
|
|
49
46
|
var DenoPeer = class extends Peer {
|
|
50
47
|
get remoteAddress() {
|
|
51
48
|
return this._internal.denoInfo.remoteAddr?.hostname;
|
|
@@ -64,6 +61,4 @@ var DenoPeer = class extends Peer {
|
|
|
64
61
|
this._internal.ws.terminate();
|
|
65
62
|
}
|
|
66
63
|
};
|
|
67
|
-
|
|
68
|
-
//#endregion
|
|
69
|
-
export { deno_default as default };
|
|
64
|
+
export { denoAdapter as default };
|
package/dist/adapters/node.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { NodeAdapter, NodeOptions, nodeAdapter as default };
|
|
1
|
+
import { NodeAdapter, NodeOptions, NodeUpgradeHandler, fromNodeUpgradeHandler, nodeAdapter } from "../_chunks/node.mjs";
|
|
2
|
+
export { NodeAdapter, NodeOptions, type NodeUpgradeHandler, nodeAdapter as default, fromNodeUpgradeHandler };
|