crossws 0.3.5 → 0.4.1
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/bun.d.ts +2 -2
- package/adapters/cloudflare.d.ts +2 -2
- package/adapters/deno.d.ts +2 -2
- package/adapters/node.d.ts +2 -2
- package/adapters/sse.d.ts +2 -2
- package/adapters/uws.d.ts +2 -2
- package/dist/adapters/bun.d.mts +5 -3
- package/dist/adapters/bun.mjs +23 -13
- package/dist/adapters/cloudflare.d.mts +40 -7
- package/dist/adapters/cloudflare.mjs +172 -14
- package/dist/adapters/deno.mjs +18 -9
- package/dist/adapters/node.d.mts +1 -1
- package/dist/adapters/node.mjs +28 -29
- package/dist/adapters/sse.mjs +8 -7
- package/dist/adapters/uws.d.mts +12 -9
- package/dist/adapters/uws.mjs +25 -27
- package/dist/index.d.mts +33 -20
- package/dist/index.mjs +1 -1
- package/dist/server/bun.d.mts +24 -0
- package/dist/server/bun.mjs +37 -0
- package/dist/server/cloudflare.d.mts +24 -0
- package/dist/server/cloudflare.mjs +36 -0
- package/dist/server/default.d.mts +24 -0
- package/dist/server/default.mjs +32 -0
- package/dist/server/deno.d.mts +24 -0
- package/dist/server/deno.mjs +30 -0
- package/dist/server/node.d.mts +24 -0
- package/dist/server/node.mjs +49 -0
- package/dist/shared/crossws.95-eYp2D.d.mts +23 -0
- package/dist/shared/crossws.B31KJMcF.mjs +83 -0
- package/dist/shared/{crossws.D9ehKjSh.mjs → crossws.CPlNx7g8.mjs} +44 -25
- package/dist/shared/{crossws.DfCzGthR.mjs → crossws.WpyOHUXc.mjs} +18 -13
- package/package.json +42 -53
- package/server/bun.d.ts +2 -0
- package/server/deno.d.ts +2 -0
- package/server/node.d.ts +2 -0
- package/server.d.ts +2 -0
- package/websocket/sse.d.ts +2 -0
- package/websocket.d.ts +2 -2
- package/dist/adapters/bun.d.ts +0 -39
- package/dist/adapters/cloudflare-durable.d.mts +0 -42
- package/dist/adapters/cloudflare-durable.d.ts +0 -42
- package/dist/adapters/cloudflare-durable.mjs +0 -141
- package/dist/adapters/cloudflare.d.ts +0 -13
- package/dist/adapters/deno.d.ts +0 -19
- package/dist/adapters/node.d.ts +0 -299
- package/dist/adapters/sse.d.ts +0 -13
- package/dist/adapters/uws.d.ts +0 -59
- package/dist/index.d.ts +0 -157
- package/dist/shared/crossws.BQXMA5bH.d.ts +0 -297
- package/dist/websocket/native.d.ts +0 -3
- package/dist/websocket/node.d.ts +0 -3
- package/dist/websocket/sse.d.ts +0 -42
package/adapters/bun.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from "../dist/adapters/bun";
|
|
2
|
-
export { default } from "../dist/adapters/bun";
|
|
1
|
+
export * from "../dist/adapters/bun.mjs";
|
|
2
|
+
export { default } from "../dist/adapters/bun.mjs";
|
package/adapters/cloudflare.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from "../dist/adapters/cloudflare";
|
|
2
|
-
export { default } from "../dist/adapters/cloudflare";
|
|
1
|
+
export * from "../dist/adapters/cloudflare.mjs";
|
|
2
|
+
export { default } from "../dist/adapters/cloudflare.mjs";
|
package/adapters/deno.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from "../dist/adapters/deno";
|
|
2
|
-
export { default } from "../dist/adapters/deno";
|
|
1
|
+
export * from "../dist/adapters/deno.mjs";
|
|
2
|
+
export { default } from "../dist/adapters/deno.mjs";
|
package/adapters/node.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from "../dist/adapters/node";
|
|
2
|
-
export { default } from "../dist/adapters/node";
|
|
1
|
+
export * from "../dist/adapters/node.mjs";
|
|
2
|
+
export { default } from "../dist/adapters/node.mjs";
|
package/adapters/sse.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from "../dist/adapters/sse";
|
|
2
|
-
export { default } from "../dist/adapters/sse";
|
|
1
|
+
export * from "../dist/adapters/sse.mjs";
|
|
2
|
+
export { default } from "../dist/adapters/sse.mjs";
|
package/adapters/uws.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from "../dist/adapters/uws";
|
|
2
|
-
export { default } from "../dist/adapters/uws";
|
|
1
|
+
export * from "../dist/adapters/uws.mjs";
|
|
2
|
+
export { default } from "../dist/adapters/uws.mjs";
|
package/dist/adapters/bun.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { WebSocketHandler, ServerWebSocket, Server } from 'bun';
|
|
2
|
-
import { Adapter, AdapterInstance, Peer, AdapterOptions } from '../index.mjs';
|
|
2
|
+
import { Adapter, AdapterInstance, Peer, PeerContext, AdapterOptions } from '../index.mjs';
|
|
3
3
|
import '../shared/crossws.BQXMA5bH.mjs';
|
|
4
4
|
|
|
5
5
|
interface BunAdapter extends AdapterInstance {
|
|
@@ -10,19 +10,21 @@ interface BunOptions extends AdapterOptions {
|
|
|
10
10
|
}
|
|
11
11
|
type ContextData = {
|
|
12
12
|
peer?: BunPeer;
|
|
13
|
+
namespace: string;
|
|
13
14
|
request: Request;
|
|
14
15
|
server?: Server;
|
|
15
|
-
context:
|
|
16
|
+
context: PeerContext;
|
|
16
17
|
};
|
|
17
18
|
declare const bunAdapter: Adapter<BunAdapter, BunOptions>;
|
|
18
19
|
|
|
19
20
|
declare class BunPeer extends Peer<{
|
|
20
21
|
ws: ServerWebSocket<ContextData>;
|
|
22
|
+
namespace: string;
|
|
21
23
|
request: Request;
|
|
22
24
|
peers: Set<BunPeer>;
|
|
23
25
|
}> {
|
|
24
26
|
get remoteAddress(): string;
|
|
25
|
-
get context():
|
|
27
|
+
get context(): PeerContext;
|
|
26
28
|
send(data: unknown, options?: {
|
|
27
29
|
compress?: boolean;
|
|
28
30
|
}): number;
|
package/dist/adapters/bun.mjs
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
|
-
import { M as Message, P as Peer, t as toBufferLike } from '../shared/crossws.
|
|
2
|
-
import { a as adapterUtils, A as AdapterHookable } from '../shared/crossws.
|
|
3
|
-
import 'uncrypto';
|
|
1
|
+
import { M as Message, P as Peer, t as toBufferLike } from '../shared/crossws.WpyOHUXc.mjs';
|
|
2
|
+
import { a as adapterUtils, g as getPeers, A as AdapterHookable } from '../shared/crossws.CPlNx7g8.mjs';
|
|
4
3
|
|
|
5
4
|
const bunAdapter = (options = {}) => {
|
|
5
|
+
if (typeof Bun === "undefined") {
|
|
6
|
+
throw new Error(
|
|
7
|
+
"[crossws] Using Bun adapter in an incompatible environment."
|
|
8
|
+
);
|
|
9
|
+
}
|
|
6
10
|
const hooks = new AdapterHookable(options);
|
|
7
|
-
const
|
|
11
|
+
const globalPeers = /* @__PURE__ */ new Map();
|
|
8
12
|
return {
|
|
9
|
-
...adapterUtils(
|
|
13
|
+
...adapterUtils(globalPeers),
|
|
10
14
|
async handleUpgrade(request, server) {
|
|
11
|
-
const { upgradeHeaders, endResponse, context } = await hooks.upgrade(request);
|
|
15
|
+
const { upgradeHeaders, endResponse, context, namespace } = await hooks.upgrade(request);
|
|
12
16
|
if (endResponse) {
|
|
13
17
|
return endResponse;
|
|
14
18
|
}
|
|
@@ -16,7 +20,8 @@ const bunAdapter = (options = {}) => {
|
|
|
16
20
|
data: {
|
|
17
21
|
server,
|
|
18
22
|
request,
|
|
19
|
-
context
|
|
23
|
+
context,
|
|
24
|
+
namespace
|
|
20
25
|
},
|
|
21
26
|
headers: upgradeHeaders
|
|
22
27
|
});
|
|
@@ -26,15 +31,18 @@ const bunAdapter = (options = {}) => {
|
|
|
26
31
|
},
|
|
27
32
|
websocket: {
|
|
28
33
|
message: (ws, message) => {
|
|
34
|
+
const peers = getPeers(globalPeers, ws.data.namespace);
|
|
29
35
|
const peer = getPeer(ws, peers);
|
|
30
36
|
hooks.callHook("message", peer, new Message(message, peer));
|
|
31
37
|
},
|
|
32
38
|
open: (ws) => {
|
|
39
|
+
const peers = getPeers(globalPeers, ws.data.namespace);
|
|
33
40
|
const peer = getPeer(ws, peers);
|
|
34
41
|
peers.add(peer);
|
|
35
42
|
hooks.callHook("open", peer);
|
|
36
43
|
},
|
|
37
44
|
close: (ws, code, reason) => {
|
|
45
|
+
const peers = getPeers(globalPeers, ws.data.namespace);
|
|
38
46
|
const peer = getPeer(ws, peers);
|
|
39
47
|
peers.delete(peer);
|
|
40
48
|
hooks.callHook("close", peer, { code, reason });
|
|
@@ -43,14 +51,16 @@ const bunAdapter = (options = {}) => {
|
|
|
43
51
|
};
|
|
44
52
|
};
|
|
45
53
|
function getPeer(ws, peers) {
|
|
46
|
-
if (ws.data
|
|
54
|
+
if (ws.data.peer) {
|
|
47
55
|
return ws.data.peer;
|
|
48
56
|
}
|
|
49
|
-
const peer = new BunPeer({
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
57
|
+
const peer = new BunPeer({
|
|
58
|
+
ws,
|
|
59
|
+
request: ws.data.request,
|
|
60
|
+
peers,
|
|
61
|
+
namespace: ws.data.namespace
|
|
62
|
+
});
|
|
63
|
+
ws.data.peer = peer;
|
|
54
64
|
return peer;
|
|
55
65
|
}
|
|
56
66
|
class BunPeer extends Peer {
|
|
@@ -1,13 +1,46 @@
|
|
|
1
|
-
import { Adapter, AdapterInstance, AdapterOptions } from '../index.mjs';
|
|
2
1
|
import * as CF from '@cloudflare/workers-types';
|
|
3
|
-
import '
|
|
2
|
+
import { DurableObject } from 'cloudflare:workers';
|
|
3
|
+
import { Adapter, AdapterInstance, AdapterOptions } from '../index.mjs';
|
|
4
|
+
import { W as WebSocket$1 } from '../shared/crossws.BQXMA5bH.mjs';
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
}
|
|
6
|
+
type WSDurableObjectStub = CF.DurableObjectStub & {
|
|
7
|
+
webSocketPublish?: (topic: string, data: unknown, opts: any) => Promise<void>;
|
|
8
|
+
};
|
|
9
|
+
type ResolveDurableStub = (req: CF.Request | undefined, env: unknown, context: CF.ExecutionContext | undefined) => WSDurableObjectStub | undefined | Promise<WSDurableObjectStub | undefined>;
|
|
8
10
|
interface CloudflareOptions extends AdapterOptions {
|
|
11
|
+
/**
|
|
12
|
+
* Durable Object binding name from environment.
|
|
13
|
+
*
|
|
14
|
+
* **Note:** This option will be ignored if `resolveDurableStub` is provided.
|
|
15
|
+
*
|
|
16
|
+
* @default "$DurableObject"
|
|
17
|
+
*/
|
|
18
|
+
bindingName?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Durable Object instance name.
|
|
21
|
+
*
|
|
22
|
+
* **Note:** This option will be ignored if `resolveDurableStub` is provided.
|
|
23
|
+
*
|
|
24
|
+
* @default "crossws"
|
|
25
|
+
*/
|
|
26
|
+
instanceName?: string;
|
|
27
|
+
/**
|
|
28
|
+
* Custom function that resolves Durable Object binding to handle the WebSocket upgrade.
|
|
29
|
+
*
|
|
30
|
+
* **Note:** This option will override `bindingName` and `instanceName`.
|
|
31
|
+
*/
|
|
32
|
+
resolveDurableStub?: ResolveDurableStub;
|
|
33
|
+
}
|
|
34
|
+
declare const cloudflareAdapter: Adapter<CloudflareDurableAdapter, CloudflareOptions>;
|
|
35
|
+
|
|
36
|
+
interface CloudflareDurableAdapter extends AdapterInstance {
|
|
37
|
+
handleUpgrade(req: Request | CF.Request, env: unknown, context: CF.ExecutionContext): Promise<Response>;
|
|
38
|
+
handleDurableInit(obj: DurableObject, state: DurableObjectState, env: unknown): void;
|
|
39
|
+
handleDurableUpgrade(obj: DurableObject, req: Request | CF.Request): Promise<Response>;
|
|
40
|
+
handleDurableMessage(obj: DurableObject, ws: WebSocket | CF.WebSocket | WebSocket$1, message: ArrayBuffer | string): Promise<void>;
|
|
41
|
+
handleDurablePublish: (obj: DurableObject, topic: string, data: unknown, opts: any) => Promise<void>;
|
|
42
|
+
handleDurableClose(obj: DurableObject, ws: WebSocket | CF.WebSocket | WebSocket$1, code: number, reason: string, wasClean: boolean): Promise<void>;
|
|
9
43
|
}
|
|
10
|
-
declare const cloudflareAdapter: Adapter<CloudflareAdapter, CloudflareOptions>;
|
|
11
44
|
|
|
12
45
|
export { cloudflareAdapter as default };
|
|
13
|
-
export type {
|
|
46
|
+
export type { CloudflareDurableAdapter, CloudflareOptions };
|
|
@@ -1,31 +1,54 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { env } from 'cloudflare:workers';
|
|
2
|
+
import { M as Message, P as Peer, t as toBufferLike } from '../shared/crossws.WpyOHUXc.mjs';
|
|
3
|
+
import { a as adapterUtils, g as getPeers, A as AdapterHookable } from '../shared/crossws.CPlNx7g8.mjs';
|
|
4
|
+
import { S as StubRequest } from '../shared/crossws.B31KJMcF.mjs';
|
|
3
5
|
import { W as WSError } from '../shared/crossws.By9qWDAI.mjs';
|
|
4
|
-
import 'uncrypto';
|
|
5
6
|
|
|
6
|
-
const cloudflareAdapter = (
|
|
7
|
-
const hooks = new AdapterHookable(
|
|
8
|
-
const
|
|
7
|
+
const cloudflareAdapter = (opts = {}) => {
|
|
8
|
+
const hooks = new AdapterHookable(opts);
|
|
9
|
+
const globalPeers = /* @__PURE__ */ new Map();
|
|
10
|
+
const resolveDurableStub = opts.resolveDurableStub || ((_req, env$1, _context) => {
|
|
11
|
+
const bindingName = opts.bindingName || "$DurableObject";
|
|
12
|
+
const binding = (env$1 || env)[bindingName];
|
|
13
|
+
if (binding) {
|
|
14
|
+
const instanceId = binding.idFromName(opts.instanceName || "crossws");
|
|
15
|
+
return binding.get(instanceId);
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
const { publish: durablePublish, ...utils } = adapterUtils(globalPeers);
|
|
9
19
|
return {
|
|
10
|
-
...
|
|
11
|
-
handleUpgrade: async (request,
|
|
12
|
-
const
|
|
13
|
-
request
|
|
20
|
+
...utils,
|
|
21
|
+
handleUpgrade: async (request, cfEnv, cfCtx) => {
|
|
22
|
+
const stub = await resolveDurableStub(
|
|
23
|
+
request,
|
|
24
|
+
cfEnv,
|
|
25
|
+
cfCtx
|
|
14
26
|
);
|
|
27
|
+
if (stub) {
|
|
28
|
+
return stub.fetch(
|
|
29
|
+
request
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
const { upgradeHeaders, endResponse, context, namespace } = await hooks.upgrade(request);
|
|
15
33
|
if (endResponse) {
|
|
16
34
|
return endResponse;
|
|
17
35
|
}
|
|
36
|
+
const peers = getPeers(
|
|
37
|
+
globalPeers,
|
|
38
|
+
namespace
|
|
39
|
+
);
|
|
18
40
|
const pair = new WebSocketPair();
|
|
19
41
|
const client = pair[0];
|
|
20
42
|
const server = pair[1];
|
|
21
|
-
const peer = new
|
|
43
|
+
const peer = new CloudflareFallbackPeer({
|
|
22
44
|
ws: client,
|
|
23
45
|
peers,
|
|
24
46
|
wsServer: server,
|
|
25
47
|
request,
|
|
26
|
-
cfEnv
|
|
48
|
+
cfEnv,
|
|
27
49
|
cfCtx,
|
|
28
|
-
context
|
|
50
|
+
context,
|
|
51
|
+
namespace
|
|
29
52
|
});
|
|
30
53
|
peers.add(peer);
|
|
31
54
|
server.accept();
|
|
@@ -50,19 +73,154 @@ const cloudflareAdapter = (options = {}) => {
|
|
|
50
73
|
webSocket: client,
|
|
51
74
|
headers: upgradeHeaders
|
|
52
75
|
});
|
|
76
|
+
},
|
|
77
|
+
handleDurableInit: async (obj, state, env) => {
|
|
78
|
+
},
|
|
79
|
+
handleDurableUpgrade: async (obj, request) => {
|
|
80
|
+
const { upgradeHeaders, endResponse, namespace } = await hooks.upgrade(
|
|
81
|
+
request
|
|
82
|
+
);
|
|
83
|
+
if (endResponse) {
|
|
84
|
+
return endResponse;
|
|
85
|
+
}
|
|
86
|
+
const peers = getPeers(globalPeers, namespace);
|
|
87
|
+
const pair = new WebSocketPair();
|
|
88
|
+
const client = pair[0];
|
|
89
|
+
const server = pair[1];
|
|
90
|
+
const peer = CloudflareDurablePeer._restore(
|
|
91
|
+
obj,
|
|
92
|
+
server,
|
|
93
|
+
request,
|
|
94
|
+
namespace
|
|
95
|
+
);
|
|
96
|
+
peers.add(peer);
|
|
97
|
+
obj.ctx.acceptWebSocket(server);
|
|
98
|
+
await hooks.callHook("open", peer);
|
|
99
|
+
return new Response(null, {
|
|
100
|
+
status: 101,
|
|
101
|
+
webSocket: client,
|
|
102
|
+
headers: upgradeHeaders
|
|
103
|
+
});
|
|
104
|
+
},
|
|
105
|
+
handleDurableMessage: async (obj, ws, message) => {
|
|
106
|
+
const peer = CloudflareDurablePeer._restore(obj, ws);
|
|
107
|
+
await hooks.callHook("message", peer, new Message(message, peer));
|
|
108
|
+
},
|
|
109
|
+
handleDurableClose: async (obj, ws, code, reason, wasClean) => {
|
|
110
|
+
const peer = CloudflareDurablePeer._restore(obj, ws);
|
|
111
|
+
const peers = getPeers(globalPeers, peer.namespace);
|
|
112
|
+
peers.delete(peer);
|
|
113
|
+
const details = { code, reason, wasClean };
|
|
114
|
+
await hooks.callHook("close", peer, details);
|
|
115
|
+
},
|
|
116
|
+
handleDurablePublish: async (_obj, topic, data, opts2) => {
|
|
117
|
+
return durablePublish(topic, data, opts2);
|
|
118
|
+
},
|
|
119
|
+
publish: async (topic, data, opts2) => {
|
|
120
|
+
const stub = await resolveDurableStub(void 0, env, void 0);
|
|
121
|
+
if (!stub) {
|
|
122
|
+
throw new Error("[crossws] Durable Object binding cannot be resolved.");
|
|
123
|
+
}
|
|
124
|
+
try {
|
|
125
|
+
return await stub.webSocketPublish(topic, data, opts2);
|
|
126
|
+
} catch (error) {
|
|
127
|
+
console.error(error);
|
|
128
|
+
throw error;
|
|
129
|
+
}
|
|
53
130
|
}
|
|
54
131
|
};
|
|
55
132
|
};
|
|
56
|
-
class
|
|
133
|
+
class CloudflareDurablePeer extends Peer {
|
|
134
|
+
get peers() {
|
|
135
|
+
return new Set(
|
|
136
|
+
this.#getwebsockets().map(
|
|
137
|
+
(ws) => CloudflareDurablePeer._restore(this._internal.durable, ws)
|
|
138
|
+
)
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
#getwebsockets() {
|
|
142
|
+
return this._internal.durable.ctx.getWebSockets();
|
|
143
|
+
}
|
|
144
|
+
send(data) {
|
|
145
|
+
return this._internal.ws.send(toBufferLike(data));
|
|
146
|
+
}
|
|
147
|
+
subscribe(topic) {
|
|
148
|
+
super.subscribe(topic);
|
|
149
|
+
const state = getAttachedState(this._internal.ws);
|
|
150
|
+
if (!state.t) {
|
|
151
|
+
state.t = /* @__PURE__ */ new Set();
|
|
152
|
+
}
|
|
153
|
+
state.t.add(topic);
|
|
154
|
+
setAttachedState(this._internal.ws, state);
|
|
155
|
+
}
|
|
156
|
+
publish(topic, data) {
|
|
157
|
+
const websockets = this.#getwebsockets();
|
|
158
|
+
if (websockets.length < 2) {
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
const dataBuff = toBufferLike(data);
|
|
162
|
+
for (const ws of websockets) {
|
|
163
|
+
if (ws === this._internal.ws) {
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
const state = getAttachedState(ws);
|
|
167
|
+
if (state.t?.has(topic)) {
|
|
168
|
+
ws.send(dataBuff);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
close(code, reason) {
|
|
173
|
+
this._internal.ws.close(code, reason);
|
|
174
|
+
}
|
|
175
|
+
static _restore(durable, ws, request, namespace) {
|
|
176
|
+
let peer = ws._crosswsPeer;
|
|
177
|
+
if (peer) {
|
|
178
|
+
return peer;
|
|
179
|
+
}
|
|
180
|
+
const state = ws.deserializeAttachment() || {};
|
|
181
|
+
peer = ws._crosswsPeer = new CloudflareDurablePeer({
|
|
182
|
+
ws,
|
|
183
|
+
request: request || new StubRequest(state.u || ""),
|
|
184
|
+
namespace: namespace || state.n || "",
|
|
185
|
+
durable
|
|
186
|
+
});
|
|
187
|
+
if (state.i) {
|
|
188
|
+
peer._id = state.i;
|
|
189
|
+
}
|
|
190
|
+
if (request?.url) {
|
|
191
|
+
state.u = request.url;
|
|
192
|
+
}
|
|
193
|
+
state.i = peer.id;
|
|
194
|
+
setAttachedState(ws, state);
|
|
195
|
+
return peer;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
class CloudflareFallbackPeer extends Peer {
|
|
57
199
|
send(data) {
|
|
58
200
|
this._internal.wsServer.send(toBufferLike(data));
|
|
59
201
|
return 0;
|
|
60
202
|
}
|
|
61
203
|
publish(_topic, _message) {
|
|
204
|
+
console.warn(
|
|
205
|
+
"[crossws] [cloudflare] pub/sub support requires Durable Objects."
|
|
206
|
+
);
|
|
62
207
|
}
|
|
63
208
|
close(code, reason) {
|
|
64
209
|
this._internal.ws.close(code, reason);
|
|
65
210
|
}
|
|
66
211
|
}
|
|
212
|
+
function getAttachedState(ws) {
|
|
213
|
+
let state = ws._crosswsState;
|
|
214
|
+
if (state) {
|
|
215
|
+
return state;
|
|
216
|
+
}
|
|
217
|
+
state = ws.deserializeAttachment() || {};
|
|
218
|
+
ws._crosswsState = state;
|
|
219
|
+
return state;
|
|
220
|
+
}
|
|
221
|
+
function setAttachedState(ws, state) {
|
|
222
|
+
ws._crosswsState = state;
|
|
223
|
+
ws.serializeAttachment(state);
|
|
224
|
+
}
|
|
67
225
|
|
|
68
226
|
export { cloudflareAdapter as default };
|
package/dist/adapters/deno.mjs
CHANGED
|
@@ -1,28 +1,37 @@
|
|
|
1
|
-
import { M as Message, P as Peer, t as toBufferLike } from '../shared/crossws.
|
|
2
|
-
import { a as adapterUtils, A as AdapterHookable } from '../shared/crossws.
|
|
1
|
+
import { M as Message, P as Peer, t as toBufferLike } from '../shared/crossws.WpyOHUXc.mjs';
|
|
2
|
+
import { a as adapterUtils, A as AdapterHookable, g as getPeers } from '../shared/crossws.CPlNx7g8.mjs';
|
|
3
3
|
import { W as WSError } from '../shared/crossws.By9qWDAI.mjs';
|
|
4
|
-
import 'uncrypto';
|
|
5
4
|
|
|
6
5
|
const denoAdapter = (options = {}) => {
|
|
6
|
+
if (typeof Deno === "undefined") {
|
|
7
|
+
throw new Error(
|
|
8
|
+
"[crossws] Using Deno adapter in an incompatible environment."
|
|
9
|
+
);
|
|
10
|
+
}
|
|
7
11
|
const hooks = new AdapterHookable(options);
|
|
8
|
-
const
|
|
12
|
+
const globalPeers = /* @__PURE__ */ new Map();
|
|
9
13
|
return {
|
|
10
|
-
...adapterUtils(
|
|
14
|
+
...adapterUtils(globalPeers),
|
|
11
15
|
handleUpgrade: async (request, info) => {
|
|
12
|
-
const { upgradeHeaders, endResponse, context } = await hooks.upgrade(request);
|
|
16
|
+
const { upgradeHeaders, endResponse, context, namespace } = await hooks.upgrade(request);
|
|
13
17
|
if (endResponse) {
|
|
14
18
|
return endResponse;
|
|
15
19
|
}
|
|
20
|
+
const headers = upgradeHeaders instanceof Headers ? upgradeHeaders : new Headers(upgradeHeaders);
|
|
16
21
|
const upgrade = Deno.upgradeWebSocket(request, {
|
|
17
|
-
// @ts-expect-error
|
|
18
|
-
|
|
22
|
+
// @ts-expect-error Setting headers is currently not supported in Deno
|
|
23
|
+
// https://github.com/denoland/deno/issues/19277
|
|
24
|
+
headers,
|
|
25
|
+
protocol: headers.get("sec-websocket-protocol") ?? ""
|
|
19
26
|
});
|
|
27
|
+
const peers = getPeers(globalPeers, namespace);
|
|
20
28
|
const peer = new DenoPeer({
|
|
21
29
|
ws: upgrade.socket,
|
|
22
30
|
request,
|
|
23
31
|
peers,
|
|
24
32
|
denoInfo: info,
|
|
25
|
-
context
|
|
33
|
+
context,
|
|
34
|
+
namespace
|
|
26
35
|
});
|
|
27
36
|
peers.add(peer);
|
|
28
37
|
upgrade.socket.addEventListener("open", () => {
|
package/dist/adapters/node.d.mts
CHANGED
|
@@ -286,7 +286,7 @@ type WebSocketServer = Server;
|
|
|
286
286
|
declare function createWebSocketStream(websocket: WebSocket, options?: DuplexOptions): Duplex;
|
|
287
287
|
|
|
288
288
|
interface NodeAdapter extends AdapterInstance {
|
|
289
|
-
handleUpgrade(req: IncomingMessage, socket: Duplex, head: Buffer): Promise<void>;
|
|
289
|
+
handleUpgrade(req: IncomingMessage, socket: Duplex, head: Buffer, webRequest?: Request): Promise<void>;
|
|
290
290
|
closeAll: (code?: number, data?: string | Buffer, force?: boolean) => void;
|
|
291
291
|
}
|
|
292
292
|
interface NodeOptions extends AdapterOptions {
|
package/dist/adapters/node.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { M as Message, P as Peer, t as toBufferLike } from '../shared/crossws.
|
|
2
|
-
import { A as AdapterHookable, a as adapterUtils } from '../shared/crossws.
|
|
1
|
+
import { M as Message, P as Peer, t as toBufferLike } from '../shared/crossws.WpyOHUXc.mjs';
|
|
2
|
+
import { g as getPeers, A as AdapterHookable, a as adapterUtils } from '../shared/crossws.CPlNx7g8.mjs';
|
|
3
3
|
import { W as WSError } from '../shared/crossws.By9qWDAI.mjs';
|
|
4
4
|
import { _ as _WebSocketServer } from '../shared/crossws.CipVM6lf.mjs';
|
|
5
|
-
import '
|
|
5
|
+
import { S as StubRequest } from '../shared/crossws.B31KJMcF.mjs';
|
|
6
6
|
import 'stream';
|
|
7
7
|
import 'events';
|
|
8
8
|
import 'http';
|
|
@@ -15,15 +15,28 @@ import 'tls';
|
|
|
15
15
|
import 'url';
|
|
16
16
|
|
|
17
17
|
const nodeAdapter = (options = {}) => {
|
|
18
|
+
if ("Deno" in globalThis || "Bun" in globalThis) {
|
|
19
|
+
throw new Error(
|
|
20
|
+
"[crossws] Using Node.js adapter in an incompatible environment."
|
|
21
|
+
);
|
|
22
|
+
}
|
|
18
23
|
const hooks = new AdapterHookable(options);
|
|
19
|
-
const
|
|
24
|
+
const globalPeers = /* @__PURE__ */ new Map();
|
|
20
25
|
const wss = options.wss || new _WebSocketServer({
|
|
21
26
|
noServer: true,
|
|
27
|
+
handleProtocols: () => false,
|
|
22
28
|
...options.serverOptions
|
|
23
29
|
});
|
|
24
30
|
wss.on("connection", (ws, nodeReq) => {
|
|
25
31
|
const request = new NodeReqProxy(nodeReq);
|
|
26
|
-
const
|
|
32
|
+
const peers = getPeers(globalPeers, nodeReq._namespace);
|
|
33
|
+
const peer = new NodePeer({
|
|
34
|
+
ws,
|
|
35
|
+
request,
|
|
36
|
+
peers,
|
|
37
|
+
nodeReq,
|
|
38
|
+
namespace: nodeReq._namespace
|
|
39
|
+
});
|
|
27
40
|
peers.add(peer);
|
|
28
41
|
hooks.callHook("open", peer);
|
|
29
42
|
ws.on("message", (data) => {
|
|
@@ -53,16 +66,17 @@ const nodeAdapter = (options = {}) => {
|
|
|
53
66
|
}
|
|
54
67
|
});
|
|
55
68
|
return {
|
|
56
|
-
...adapterUtils(
|
|
57
|
-
handleUpgrade: async (nodeReq, socket, head) => {
|
|
58
|
-
const request = new NodeReqProxy(nodeReq);
|
|
59
|
-
const { upgradeHeaders, endResponse, context } = await hooks.upgrade(request);
|
|
69
|
+
...adapterUtils(globalPeers),
|
|
70
|
+
handleUpgrade: async (nodeReq, socket, head, webRequest) => {
|
|
71
|
+
const request = webRequest || new NodeReqProxy(nodeReq);
|
|
72
|
+
const { upgradeHeaders, endResponse, context, namespace } = await hooks.upgrade(request);
|
|
60
73
|
if (endResponse) {
|
|
61
74
|
return sendResponse(socket, endResponse);
|
|
62
75
|
}
|
|
63
76
|
nodeReq._request = request;
|
|
64
77
|
nodeReq._upgradeHeaders = upgradeHeaders;
|
|
65
78
|
nodeReq._context = context;
|
|
79
|
+
nodeReq._namespace = namespace;
|
|
66
80
|
wss.handleUpgrade(nodeReq, socket, head, (ws) => {
|
|
67
81
|
wss.emit("connection", ws, nodeReq);
|
|
68
82
|
});
|
|
@@ -116,27 +130,12 @@ class NodePeer extends Peer {
|
|
|
116
130
|
this._internal.ws.terminate();
|
|
117
131
|
}
|
|
118
132
|
}
|
|
119
|
-
class NodeReqProxy {
|
|
120
|
-
_req;
|
|
121
|
-
_headers;
|
|
122
|
-
_url;
|
|
133
|
+
class NodeReqProxy extends StubRequest {
|
|
123
134
|
constructor(req) {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
const req = this._req;
|
|
129
|
-
const host = req.headers["host"] || "localhost";
|
|
130
|
-
const isSecure = req.socket?.encrypted ?? req.headers["x-forwarded-proto"] === "https";
|
|
131
|
-
this._url = `${isSecure ? "https" : "http"}://${host}${req.url}`;
|
|
132
|
-
}
|
|
133
|
-
return this._url;
|
|
134
|
-
}
|
|
135
|
-
get headers() {
|
|
136
|
-
if (!this._headers) {
|
|
137
|
-
this._headers = new Headers(this._req.headers);
|
|
138
|
-
}
|
|
139
|
-
return this._headers;
|
|
135
|
+
const host = req.headers["host"] || "localhost";
|
|
136
|
+
const isSecure = req.socket?.encrypted ?? req.headers["x-forwarded-proto"] === "https";
|
|
137
|
+
const url = `${isSecure ? "https" : "http"}://${host}${req.url}`;
|
|
138
|
+
super(url, { headers: req.headers });
|
|
140
139
|
}
|
|
141
140
|
}
|
|
142
141
|
async function sendResponse(socket, res) {
|
package/dist/adapters/sse.mjs
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
import { M as Message, P as Peer, a as toString } from '../shared/crossws.
|
|
2
|
-
import { a as adapterUtils, A as AdapterHookable } from '../shared/crossws.
|
|
3
|
-
import 'uncrypto';
|
|
1
|
+
import { M as Message, P as Peer, a as toString } from '../shared/crossws.WpyOHUXc.mjs';
|
|
2
|
+
import { a as adapterUtils, A as AdapterHookable, g as getPeers } from '../shared/crossws.CPlNx7g8.mjs';
|
|
4
3
|
|
|
5
4
|
const sseAdapter = (opts = {}) => {
|
|
6
5
|
const hooks = new AdapterHookable(opts);
|
|
7
|
-
const
|
|
6
|
+
const globalPeers = /* @__PURE__ */ new Map();
|
|
8
7
|
const peersMap = opts.bidir ? /* @__PURE__ */ new Map() : void 0;
|
|
9
8
|
return {
|
|
10
|
-
...adapterUtils(
|
|
9
|
+
...adapterUtils(globalPeers),
|
|
11
10
|
fetch: async (request) => {
|
|
12
|
-
const { upgradeHeaders, endResponse, context } = await hooks.upgrade(request);
|
|
11
|
+
const { upgradeHeaders, endResponse, context, namespace } = await hooks.upgrade(request);
|
|
13
12
|
if (endResponse) {
|
|
14
13
|
return endResponse;
|
|
15
14
|
}
|
|
@@ -32,13 +31,15 @@ const sseAdapter = (opts = {}) => {
|
|
|
32
31
|
return new Response(null, {});
|
|
33
32
|
} else {
|
|
34
33
|
const ws = new SSEWebSocketStub();
|
|
34
|
+
const peers = getPeers(globalPeers, namespace);
|
|
35
35
|
peer = new SSEPeer({
|
|
36
36
|
peers,
|
|
37
37
|
peersMap,
|
|
38
38
|
request,
|
|
39
39
|
hooks,
|
|
40
40
|
ws,
|
|
41
|
-
context
|
|
41
|
+
context,
|
|
42
|
+
namespace
|
|
42
43
|
});
|
|
43
44
|
peers.add(peer);
|
|
44
45
|
if (opts.bidir) {
|
package/dist/adapters/uws.d.mts
CHANGED
|
@@ -1,14 +1,20 @@
|
|
|
1
|
-
import { Adapter, AdapterInstance, Peer, AdapterOptions } from '../index.mjs';
|
|
1
|
+
import { Adapter, AdapterInstance, Peer, PeerContext, AdapterOptions } from '../index.mjs';
|
|
2
2
|
import { W as WebSocket } from '../shared/crossws.BQXMA5bH.mjs';
|
|
3
3
|
import uws from 'uWebSockets.js';
|
|
4
4
|
|
|
5
|
+
declare const StubRequest: {
|
|
6
|
+
new (url: string, init?: RequestInit): Request;
|
|
7
|
+
};
|
|
8
|
+
|
|
5
9
|
type UserData = {
|
|
6
10
|
peer?: UWSPeer;
|
|
7
11
|
req: uws.HttpRequest;
|
|
8
12
|
res: uws.HttpResponse;
|
|
13
|
+
webReq: UWSReqProxy;
|
|
9
14
|
protocol: string;
|
|
10
15
|
extensions: string;
|
|
11
|
-
context:
|
|
16
|
+
context: PeerContext;
|
|
17
|
+
namespace: string;
|
|
12
18
|
};
|
|
13
19
|
type WebSocketHandler = uws.WebSocketBehavior<UserData>;
|
|
14
20
|
interface UWSAdapter extends AdapterInstance {
|
|
@@ -22,12 +28,13 @@ declare const uwsAdapter: Adapter<UWSAdapter, UWSOptions>;
|
|
|
22
28
|
declare class UWSPeer extends Peer<{
|
|
23
29
|
peers: Set<UWSPeer>;
|
|
24
30
|
request: UWSReqProxy;
|
|
31
|
+
namespace: string;
|
|
25
32
|
uws: uws.WebSocket<UserData>;
|
|
26
33
|
ws: UwsWebSocketProxy;
|
|
27
34
|
uwsData: UserData;
|
|
28
35
|
}> {
|
|
29
36
|
get remoteAddress(): string | undefined;
|
|
30
|
-
get context():
|
|
37
|
+
get context(): PeerContext;
|
|
31
38
|
send(data: unknown, options?: {
|
|
32
39
|
compress?: boolean;
|
|
33
40
|
}): number;
|
|
@@ -39,12 +46,8 @@ declare class UWSPeer extends Peer<{
|
|
|
39
46
|
close(code?: number, reason?: uws.RecognizedString): void;
|
|
40
47
|
terminate(): void;
|
|
41
48
|
}
|
|
42
|
-
declare class UWSReqProxy {
|
|
43
|
-
|
|
44
|
-
private _rawHeaders;
|
|
45
|
-
url: string;
|
|
46
|
-
constructor(_req: uws.HttpRequest);
|
|
47
|
-
get headers(): Headers;
|
|
49
|
+
declare class UWSReqProxy extends StubRequest {
|
|
50
|
+
constructor(req: uws.HttpRequest);
|
|
48
51
|
}
|
|
49
52
|
declare class UwsWebSocketProxy implements Partial<WebSocket> {
|
|
50
53
|
private _uws;
|