crossws 0.2.4 → 0.3.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/README.md +8 -9
- package/adapters/cloudflare-durable.d.ts +2 -0
- package/adapters/sse.d.ts +2 -0
- package/dist/adapters/bun.d.mts +25 -6
- package/dist/adapters/bun.d.ts +25 -6
- package/dist/adapters/bun.mjs +54 -62
- package/dist/adapters/cloudflare-durable.d.mts +20 -0
- package/dist/adapters/cloudflare-durable.d.ts +20 -0
- package/dist/adapters/cloudflare-durable.mjs +132 -0
- package/dist/adapters/cloudflare.d.mts +5 -5
- package/dist/adapters/cloudflare.d.ts +5 -5
- package/dist/adapters/cloudflare.mjs +56 -49
- package/dist/adapters/deno.d.mts +10 -3
- package/dist/adapters/deno.d.ts +10 -3
- package/dist/adapters/deno.mjs +54 -45
- package/dist/adapters/node.d.mts +4 -2
- package/dist/adapters/node.d.ts +4 -2
- package/dist/adapters/node.mjs +106 -82
- package/dist/adapters/sse.d.mts +12 -0
- package/dist/adapters/sse.d.ts +12 -0
- package/dist/adapters/sse.mjs +120 -0
- package/dist/adapters/uws.d.mts +45 -9
- package/dist/adapters/uws.d.ts +45 -9
- package/dist/adapters/uws.mjs +148 -124
- package/dist/index.d.mts +136 -4
- package/dist/index.d.ts +136 -4
- package/dist/index.mjs +1 -10
- package/dist/shared/crossws.B4sHId41.mjs +42 -0
- package/dist/shared/crossws.By9qWDAI.mjs +8 -0
- package/dist/shared/crossws.ChIJSJVK.d.mts +297 -0
- package/dist/shared/crossws.ChIJSJVK.d.ts +297 -0
- package/dist/shared/crossws.DTY7a69w.mjs +315 -0
- package/dist/shared/{crossws.a5db571c.mjs → crossws.YgHWLi0G.mjs} +284 -115
- package/dist/websocket/{index.d.mts → native.d.mts} +1 -1
- package/dist/websocket/{node.d.cts → native.d.ts} +1 -1
- package/dist/websocket/native.mjs +3 -0
- package/dist/websocket/node.d.mts +1 -1
- package/dist/websocket/node.d.ts +1 -1
- package/dist/websocket/node.mjs +1 -1
- package/dist/websocket/sse.d.mts +41 -0
- package/dist/websocket/sse.d.ts +41 -0
- package/dist/websocket/sse.mjs +127 -0
- package/package.json +78 -75
- package/dist/adapters/bun.cjs +0 -95
- package/dist/adapters/bun.d.cts +0 -17
- package/dist/adapters/cloudflare.cjs +0 -65
- package/dist/adapters/cloudflare.d.cts +0 -12
- package/dist/adapters/deno.cjs +0 -63
- package/dist/adapters/deno.d.cts +0 -15
- package/dist/adapters/node.cjs +0 -739
- package/dist/adapters/node.d.cts +0 -298
- package/dist/adapters/uws.cjs +0 -153
- package/dist/adapters/uws.d.cts +0 -19
- package/dist/index.cjs +0 -17
- package/dist/index.d.cts +0 -6
- package/dist/shared/crossws.2ed26345.cjs +0 -3931
- package/dist/shared/crossws.36b9e66f.cjs +0 -156
- package/dist/shared/crossws.381454fe.d.cts +0 -115
- package/dist/shared/crossws.381454fe.d.mts +0 -115
- package/dist/shared/crossws.381454fe.d.ts +0 -115
- package/dist/shared/crossws.77e89680.mjs +0 -149
- package/dist/websocket/index.cjs +0 -5
- package/dist/websocket/index.d.cts +0 -10
- package/dist/websocket/index.d.ts +0 -10
- package/dist/websocket/index.mjs +0 -3
- package/dist/websocket/node.cjs +0 -17
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
import { randomUUID } from 'uncrypto';
|
|
2
|
+
|
|
3
|
+
function toBufferLike(val) {
|
|
4
|
+
if (val === void 0 || val === null) {
|
|
5
|
+
return "";
|
|
6
|
+
}
|
|
7
|
+
const type = typeof val;
|
|
8
|
+
if (type === "string") {
|
|
9
|
+
return val;
|
|
10
|
+
}
|
|
11
|
+
if (type === "number" || type === "boolean" || type === "bigint") {
|
|
12
|
+
return val.toString();
|
|
13
|
+
}
|
|
14
|
+
if (type === "function" || type === "symbol") {
|
|
15
|
+
return "{}";
|
|
16
|
+
}
|
|
17
|
+
if (val instanceof Uint8Array || val instanceof ArrayBuffer) {
|
|
18
|
+
return val;
|
|
19
|
+
}
|
|
20
|
+
if (isPlainObject(val)) {
|
|
21
|
+
return JSON.stringify(val);
|
|
22
|
+
}
|
|
23
|
+
return val;
|
|
24
|
+
}
|
|
25
|
+
function toString(val) {
|
|
26
|
+
if (typeof val === "string") {
|
|
27
|
+
return val;
|
|
28
|
+
}
|
|
29
|
+
const data = toBufferLike(val);
|
|
30
|
+
if (typeof data === "string") {
|
|
31
|
+
return data;
|
|
32
|
+
}
|
|
33
|
+
const base64 = btoa(String.fromCharCode(...new Uint8Array(data)));
|
|
34
|
+
return `data:application/octet-stream;base64,${base64}`;
|
|
35
|
+
}
|
|
36
|
+
function isPlainObject(value) {
|
|
37
|
+
if (value === null || typeof value !== "object") {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
const prototype = Object.getPrototypeOf(value);
|
|
41
|
+
if (prototype !== null && prototype !== Object.prototype && Object.getPrototypeOf(prototype) !== null) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
if (Symbol.iterator in value) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
if (Symbol.toStringTag in value) {
|
|
48
|
+
return Object.prototype.toString.call(value) === "[object Module]";
|
|
49
|
+
}
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
class Message {
|
|
54
|
+
/** Access to the original [message event](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/message_event) if available. */
|
|
55
|
+
event;
|
|
56
|
+
/** Access to the Peer that emitted the message. */
|
|
57
|
+
peer;
|
|
58
|
+
/** Raw message data (can be of any type). */
|
|
59
|
+
rawData;
|
|
60
|
+
#id;
|
|
61
|
+
#uint8Array;
|
|
62
|
+
#arrayBuffer;
|
|
63
|
+
#blob;
|
|
64
|
+
#text;
|
|
65
|
+
#json;
|
|
66
|
+
constructor(rawData, peer, event) {
|
|
67
|
+
this.rawData = rawData || "";
|
|
68
|
+
this.peer = peer;
|
|
69
|
+
this.event = event;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Unique random [uuid v4](https://developer.mozilla.org/en-US/docs/Glossary/UUID) identifier for the message.
|
|
73
|
+
*/
|
|
74
|
+
get id() {
|
|
75
|
+
if (!this.#id) {
|
|
76
|
+
this.#id = randomUUID();
|
|
77
|
+
}
|
|
78
|
+
return this.#id;
|
|
79
|
+
}
|
|
80
|
+
// --- data views ---
|
|
81
|
+
/**
|
|
82
|
+
* Get data as [Uint8Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) value.
|
|
83
|
+
*
|
|
84
|
+
* If raw data is in any other format or string, it will be automatically converted and encoded.
|
|
85
|
+
*/
|
|
86
|
+
uint8Array() {
|
|
87
|
+
const _uint8Array = this.#uint8Array;
|
|
88
|
+
if (_uint8Array) {
|
|
89
|
+
return _uint8Array;
|
|
90
|
+
}
|
|
91
|
+
const rawData = this.rawData;
|
|
92
|
+
if (rawData instanceof Uint8Array) {
|
|
93
|
+
return this.#uint8Array = rawData;
|
|
94
|
+
}
|
|
95
|
+
if (rawData instanceof ArrayBuffer || rawData instanceof SharedArrayBuffer) {
|
|
96
|
+
this.#arrayBuffer = rawData;
|
|
97
|
+
return this.#uint8Array = new Uint8Array(rawData);
|
|
98
|
+
}
|
|
99
|
+
if (typeof rawData === "string") {
|
|
100
|
+
this.#text = rawData;
|
|
101
|
+
return this.#uint8Array = new TextEncoder().encode(this.#text);
|
|
102
|
+
}
|
|
103
|
+
if (Symbol.iterator in rawData) {
|
|
104
|
+
return this.#uint8Array = new Uint8Array(rawData);
|
|
105
|
+
}
|
|
106
|
+
if (typeof rawData?.length === "number") {
|
|
107
|
+
return this.#uint8Array = new Uint8Array(rawData);
|
|
108
|
+
}
|
|
109
|
+
if (rawData instanceof DataView) {
|
|
110
|
+
return this.#uint8Array = new Uint8Array(
|
|
111
|
+
rawData.buffer,
|
|
112
|
+
rawData.byteOffset,
|
|
113
|
+
rawData.byteLength
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
throw new TypeError(
|
|
117
|
+
`Unsupported message type: ${Object.prototype.toString.call(rawData)}`
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* 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.
|
|
122
|
+
*
|
|
123
|
+
* If raw data is in any other format or string, it will be automatically converted and encoded.
|
|
124
|
+
*/
|
|
125
|
+
arrayBuffer() {
|
|
126
|
+
const _arrayBuffer = this.#arrayBuffer;
|
|
127
|
+
if (_arrayBuffer) {
|
|
128
|
+
return _arrayBuffer;
|
|
129
|
+
}
|
|
130
|
+
const rawData = this.rawData;
|
|
131
|
+
if (rawData instanceof ArrayBuffer || rawData instanceof SharedArrayBuffer) {
|
|
132
|
+
return this.#arrayBuffer = rawData;
|
|
133
|
+
}
|
|
134
|
+
return this.#arrayBuffer = this.uint8Array().buffer;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Get data as [Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob) value.
|
|
138
|
+
*
|
|
139
|
+
* If raw data is in any other format or string, it will be automatically converted and encoded. */
|
|
140
|
+
blob() {
|
|
141
|
+
const _blob = this.#blob;
|
|
142
|
+
if (_blob) {
|
|
143
|
+
return _blob;
|
|
144
|
+
}
|
|
145
|
+
const rawData = this.rawData;
|
|
146
|
+
if (rawData instanceof Blob) {
|
|
147
|
+
return this.#blob = rawData;
|
|
148
|
+
}
|
|
149
|
+
return this.#blob = new Blob([this.uint8Array()]);
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Get stringified text version of the message.
|
|
153
|
+
*
|
|
154
|
+
* If raw data is in any other format, it will be automatically converted and decoded.
|
|
155
|
+
*/
|
|
156
|
+
text() {
|
|
157
|
+
const _text = this.#text;
|
|
158
|
+
if (_text) {
|
|
159
|
+
return _text;
|
|
160
|
+
}
|
|
161
|
+
const rawData = this.rawData;
|
|
162
|
+
if (typeof rawData === "string") {
|
|
163
|
+
return this.#text = rawData;
|
|
164
|
+
}
|
|
165
|
+
return this.#text = new TextDecoder().decode(this.uint8Array());
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Get parsed version of the message text with [`JSON.parse()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse).
|
|
169
|
+
*/
|
|
170
|
+
json() {
|
|
171
|
+
const _json = this.#json;
|
|
172
|
+
if (_json) {
|
|
173
|
+
return _json;
|
|
174
|
+
}
|
|
175
|
+
return this.#json = JSON.parse(this.text());
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Message data (value varies based on `peer.websocket.binaryType`).
|
|
179
|
+
*/
|
|
180
|
+
get data() {
|
|
181
|
+
switch (this.peer?.websocket?.binaryType) {
|
|
182
|
+
case "arraybuffer": {
|
|
183
|
+
return this.arrayBuffer();
|
|
184
|
+
}
|
|
185
|
+
case "blob": {
|
|
186
|
+
return this.blob();
|
|
187
|
+
}
|
|
188
|
+
case "nodebuffer": {
|
|
189
|
+
return globalThis.Buffer ? Buffer.from(this.uint8Array()) : this.uint8Array();
|
|
190
|
+
}
|
|
191
|
+
case "uint8array": {
|
|
192
|
+
return this.uint8Array();
|
|
193
|
+
}
|
|
194
|
+
case "text": {
|
|
195
|
+
return this.text();
|
|
196
|
+
}
|
|
197
|
+
default: {
|
|
198
|
+
return this.rawData;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
// --- inspect ---
|
|
203
|
+
toString() {
|
|
204
|
+
return this.text();
|
|
205
|
+
}
|
|
206
|
+
[Symbol.toPrimitive]() {
|
|
207
|
+
return this.text();
|
|
208
|
+
}
|
|
209
|
+
[Symbol.for("nodejs.util.inspect.custom")]() {
|
|
210
|
+
return { data: this.rawData };
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
class Peer {
|
|
215
|
+
_internal;
|
|
216
|
+
_topics;
|
|
217
|
+
_id;
|
|
218
|
+
#ws;
|
|
219
|
+
constructor(internal) {
|
|
220
|
+
this._topics = /* @__PURE__ */ new Set();
|
|
221
|
+
this._internal = internal;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Unique random [uuid v4](https://developer.mozilla.org/en-US/docs/Glossary/UUID) identifier for the peer.
|
|
225
|
+
*/
|
|
226
|
+
get id() {
|
|
227
|
+
if (!this._id) {
|
|
228
|
+
this._id = randomUUID();
|
|
229
|
+
}
|
|
230
|
+
return this._id;
|
|
231
|
+
}
|
|
232
|
+
/** IP address of the peer */
|
|
233
|
+
get remoteAddress() {
|
|
234
|
+
return void 0;
|
|
235
|
+
}
|
|
236
|
+
/** upgrade request */
|
|
237
|
+
get request() {
|
|
238
|
+
return this._internal.request;
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Get the [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) instance.
|
|
242
|
+
*
|
|
243
|
+
* **Note:** crossws adds polyfill for the following properties if native values are not available:
|
|
244
|
+
* - `protocol`: Extracted from the `sec-websocket-protocol` header.
|
|
245
|
+
* - `extensions`: Extracted from the `sec-websocket-extensions` header.
|
|
246
|
+
* - `url`: Extracted from the request URL (http -> ws).
|
|
247
|
+
* */
|
|
248
|
+
get websocket() {
|
|
249
|
+
if (!this.#ws) {
|
|
250
|
+
const _ws = this._internal.ws;
|
|
251
|
+
const _request = this._internal.request;
|
|
252
|
+
this.#ws = _request ? createWsProxy(_ws, _request) : _ws;
|
|
253
|
+
}
|
|
254
|
+
return this.#ws;
|
|
255
|
+
}
|
|
256
|
+
/** All connected peers to the server */
|
|
257
|
+
get peers() {
|
|
258
|
+
return this._internal.peers || /* @__PURE__ */ new Set();
|
|
259
|
+
}
|
|
260
|
+
/** Abruptly close the connection */
|
|
261
|
+
terminate() {
|
|
262
|
+
this.close();
|
|
263
|
+
}
|
|
264
|
+
/** Subscribe to a topic */
|
|
265
|
+
subscribe(topic) {
|
|
266
|
+
this._topics.add(topic);
|
|
267
|
+
}
|
|
268
|
+
/** Unsubscribe from a topic */
|
|
269
|
+
unsubscribe(topic) {
|
|
270
|
+
this._topics.delete(topic);
|
|
271
|
+
}
|
|
272
|
+
// --- inspect ---
|
|
273
|
+
toString() {
|
|
274
|
+
return this.id;
|
|
275
|
+
}
|
|
276
|
+
[Symbol.toPrimitive]() {
|
|
277
|
+
return this.id;
|
|
278
|
+
}
|
|
279
|
+
[Symbol.toStringTag]() {
|
|
280
|
+
return "WebSocket";
|
|
281
|
+
}
|
|
282
|
+
[Symbol.for("nodejs.util.inspect.custom")]() {
|
|
283
|
+
return Object.fromEntries(
|
|
284
|
+
[
|
|
285
|
+
["id", this.id],
|
|
286
|
+
["remoteAddress", this.remoteAddress],
|
|
287
|
+
["peers", this.peers],
|
|
288
|
+
["webSocket", this.websocket]
|
|
289
|
+
].filter((p) => p[1])
|
|
290
|
+
);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
function createWsProxy(ws, request) {
|
|
294
|
+
return new Proxy(ws, {
|
|
295
|
+
get: (target, prop) => {
|
|
296
|
+
const value = Reflect.get(target, prop);
|
|
297
|
+
if (!value) {
|
|
298
|
+
switch (prop) {
|
|
299
|
+
case "protocol": {
|
|
300
|
+
return request?.headers?.get("sec-websocket-protocol") || "";
|
|
301
|
+
}
|
|
302
|
+
case "extensions": {
|
|
303
|
+
return request?.headers?.get("sec-websocket-extensions") || "";
|
|
304
|
+
}
|
|
305
|
+
case "url": {
|
|
306
|
+
return request?.url?.replace(/^http/, "ws") || void 0;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
return value;
|
|
311
|
+
}
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
export { Message as M, Peer as P, toString as a, toBufferLike as t };
|