crossws 0.3.4 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/README.md +7 -7
  2. package/adapters/bun.d.ts +2 -2
  3. package/adapters/cloudflare.d.ts +2 -2
  4. package/adapters/deno.d.ts +2 -2
  5. package/adapters/node.d.ts +2 -2
  6. package/adapters/sse.d.ts +2 -2
  7. package/adapters/uws.d.ts +2 -2
  8. package/dist/adapters/bun.d.mts +9 -6
  9. package/dist/adapters/bun.mjs +23 -13
  10. package/dist/adapters/cloudflare.d.mts +41 -7
  11. package/dist/adapters/cloudflare.mjs +172 -14
  12. package/dist/adapters/deno.d.mts +4 -3
  13. package/dist/adapters/deno.mjs +18 -9
  14. package/dist/adapters/node.d.mts +8 -7
  15. package/dist/adapters/node.mjs +39 -33
  16. package/dist/adapters/sse.d.mts +4 -3
  17. package/dist/adapters/sse.mjs +9 -8
  18. package/dist/adapters/uws.d.mts +15 -11
  19. package/dist/adapters/uws.mjs +25 -27
  20. package/dist/index.d.mts +35 -21
  21. package/dist/index.mjs +1 -1
  22. package/dist/server/bun.d.mts +24 -0
  23. package/dist/server/bun.mjs +37 -0
  24. package/dist/server/cloudflare.d.mts +24 -0
  25. package/dist/server/cloudflare.mjs +36 -0
  26. package/dist/server/default.d.mts +24 -0
  27. package/dist/server/default.mjs +32 -0
  28. package/dist/server/deno.d.mts +24 -0
  29. package/dist/server/deno.mjs +30 -0
  30. package/dist/server/node.d.mts +24 -0
  31. package/dist/server/node.mjs +43 -0
  32. package/dist/shared/crossws.95-eYp2D.d.mts +23 -0
  33. package/dist/shared/crossws.B31KJMcF.mjs +83 -0
  34. package/dist/shared/{crossws.ChIJSJVK.d.mts → crossws.BQXMA5bH.d.mts} +1 -1
  35. package/dist/shared/{crossws.D9ehKjSh.mjs → crossws.CPlNx7g8.mjs} +44 -25
  36. package/dist/shared/{crossws.DelSCW9g.mjs → crossws.CipVM6lf.mjs} +197 -7
  37. package/dist/shared/{crossws.BS81iGZK.mjs → crossws.WpyOHUXc.mjs} +21 -16
  38. package/dist/websocket/node.mjs +1 -1
  39. package/dist/websocket/sse.d.mts +3 -2
  40. package/dist/websocket/sse.mjs +1 -1
  41. package/package.json +61 -64
  42. package/server/bun.d.ts +2 -0
  43. package/server/deno.d.ts +2 -0
  44. package/server/node.d.ts +2 -0
  45. package/server.d.ts +2 -0
  46. package/websocket/sse.d.ts +2 -0
  47. package/websocket.d.ts +2 -2
  48. package/dist/adapters/bun.d.ts +0 -38
  49. package/dist/adapters/cloudflare-durable.d.mts +0 -41
  50. package/dist/adapters/cloudflare-durable.d.ts +0 -41
  51. package/dist/adapters/cloudflare-durable.mjs +0 -141
  52. package/dist/adapters/cloudflare.d.ts +0 -12
  53. package/dist/adapters/deno.d.ts +0 -18
  54. package/dist/adapters/node.d.ts +0 -298
  55. package/dist/adapters/sse.d.ts +0 -12
  56. package/dist/adapters/uws.d.ts +0 -58
  57. package/dist/index.d.ts +0 -156
  58. package/dist/shared/crossws.ChIJSJVK.d.ts +0 -297
  59. package/dist/websocket/native.d.ts +0 -3
  60. package/dist/websocket/node.d.ts +0 -3
  61. package/dist/websocket/sse.d.ts +0 -41
package/README.md CHANGED
@@ -9,13 +9,13 @@
9
9
 
10
10
  Elegant, typed, and simple toolkit to implement cross-platform WebSocket servers.
11
11
 
12
- 👉 [📖 documentation](https://crossws.unjs.io)
12
+ 👉 [📖 documentation](https://crossws.h3.dev)
13
13
 
14
14
  ## Features
15
15
 
16
- 🧩 Seamlessly integrates with [Bun](https://crossws.unjs.io/adapters/bun), [Cloudflare Workers](https://crossws.unjs.io/adapters/cloudflare), [Deno](https://crossws.unjs.io/adapters/deno) and [Node.js](https://crossws.unjs.io/adapters/node) and any compatible web framework.
16
+ 🧩 Seamlessly integrates with [Bun](https://crossws.h3.dev/adapters/bun), [Cloudflare Workers](https://crossws.h3.dev/adapters/cloudflare), [Deno](https://crossws.h3.dev/adapters/deno) and [Node.js](https://crossws.h3.dev/adapters/node) and any compatible web framework.
17
17
 
18
- ✅ Prebundled with [ws](https://github.com/websockets/ws) for Node.js support with alternative/much faster [uWebSockets](https://crossws.unjs.io/adapters/node#uwebsockets) adapter.
18
+ ✅ Prebundled with [ws](https://github.com/websockets/ws) for Node.js support with alternative/much faster [uWebSockets](https://crossws.h3.dev/adapters/node#uwebsockets) adapter.
19
19
 
20
20
  📦 Extremely lightweight and tree-shakable conditional ESM exports.
21
21
 
@@ -44,11 +44,11 @@ Elegant, typed, and simple toolkit to implement cross-platform WebSocket servers
44
44
 
45
45
  <!-- automd:contributors license=MIT author="pi0" -->
46
46
 
47
- Published under the [MIT](https://github.com/unjs/crossws/blob/main/LICENSE) license.
48
- Made by [@pi0](https://github.com/pi0) and [community](https://github.com/unjs/crossws/graphs/contributors) 💛
47
+ Published under the [MIT](https://github.com/h3js/crossws/blob/main/LICENSE) license.
48
+ Made by [@pi0](https://github.com/pi0) and [community](https://github.com/h3js/crossws/graphs/contributors) 💛
49
49
  <br><br>
50
- <a href="https://github.com/unjs/crossws/graphs/contributors">
51
- <img src="https://contrib.rocks/image?repo=unjs/crossws" />
50
+ <a href="https://github.com/h3js/crossws/graphs/contributors">
51
+ <img src="https://contrib.rocks/image?repo=h3js/crossws" />
52
52
  </a>
53
53
 
54
54
  <!-- /automd -->
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";
@@ -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";
@@ -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";
@@ -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";
@@ -1,6 +1,6 @@
1
- import { WebSocketHandler, Server, ServerWebSocket } from 'bun';
2
- import { AdapterInstance, AdapterOptions, Peer, Adapter } from '../index.mjs';
3
- import '../shared/crossws.ChIJSJVK.mjs';
1
+ import { WebSocketHandler, ServerWebSocket, Server } from 'bun';
2
+ import { Adapter, AdapterInstance, Peer, PeerContext, AdapterOptions } from '../index.mjs';
3
+ import '../shared/crossws.BQXMA5bH.mjs';
4
4
 
5
5
  interface BunAdapter extends AdapterInstance {
6
6
  websocket: WebSocketHandler<ContextData>;
@@ -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: Peer["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(): Peer["context"];
27
+ get context(): PeerContext;
26
28
  send(data: unknown, options?: {
27
29
  compress?: boolean;
28
30
  }): number;
@@ -35,4 +37,5 @@ declare class BunPeer extends Peer<{
35
37
  terminate(): void;
36
38
  }
37
39
 
38
- export { type BunAdapter, type BunOptions, bunAdapter as default };
40
+ export { bunAdapter as default };
41
+ export type { BunAdapter, BunOptions };
@@ -1,14 +1,18 @@
1
- import { M as Message, P as Peer, t as toBufferLike } from '../shared/crossws.BS81iGZK.mjs';
2
- import { a as adapterUtils, A as AdapterHookable } from '../shared/crossws.D9ehKjSh.mjs';
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 peers = /* @__PURE__ */ new Set();
11
+ const globalPeers = /* @__PURE__ */ new Map();
8
12
  return {
9
- ...adapterUtils(peers),
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?.peer) {
54
+ if (ws.data.peer) {
47
55
  return ws.data.peer;
48
56
  }
49
- const peer = new BunPeer({ ws, request: ws.data.request, peers });
50
- ws.data = {
51
- ...ws.data,
52
- peer
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,12 +1,46 @@
1
- import { AdapterInstance, AdapterOptions, Adapter } from '../index.mjs';
2
1
  import * as CF from '@cloudflare/workers-types';
3
- import '../shared/crossws.ChIJSJVK.mjs';
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
- interface CloudflareAdapter extends AdapterInstance {
6
- handleUpgrade(req: CF.Request, env: unknown, context: CF.ExecutionContext): Promise<CF.Response>;
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
- export { type CloudflareAdapter, type CloudflareOptions, cloudflareAdapter as default };
45
+ export { cloudflareAdapter as default };
46
+ export type { CloudflareDurableAdapter, CloudflareOptions };
@@ -1,31 +1,54 @@
1
- import { M as Message, P as Peer, t as toBufferLike } from '../shared/crossws.BS81iGZK.mjs';
2
- import { a as adapterUtils, A as AdapterHookable } from '../shared/crossws.D9ehKjSh.mjs';
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 = (options = {}) => {
7
- const hooks = new AdapterHookable(options);
8
- const peers = /* @__PURE__ */ new Set();
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
- ...adapterUtils(peers),
11
- handleUpgrade: async (request, env, cfCtx) => {
12
- const { upgradeHeaders, endResponse, context } = await hooks.upgrade(
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 CloudflarePeer({
43
+ const peer = new CloudflareFallbackPeer({
22
44
  ws: client,
23
45
  peers,
24
46
  wsServer: server,
25
47
  request,
26
- cfEnv: env,
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 CloudflarePeer extends Peer {
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 };
@@ -1,5 +1,5 @@
1
- import { AdapterInstance, AdapterOptions, Adapter } from '../index.mjs';
2
- import '../shared/crossws.ChIJSJVK.mjs';
1
+ import { Adapter, AdapterInstance, AdapterOptions } from '../index.mjs';
2
+ import '../shared/crossws.BQXMA5bH.mjs';
3
3
 
4
4
  interface DenoAdapter extends AdapterInstance {
5
5
  handleUpgrade(req: Request, info: ServeHandlerInfo): Promise<Response>;
@@ -15,4 +15,5 @@ type ServeHandlerInfo = {
15
15
  };
16
16
  declare const denoAdapter: Adapter<DenoAdapter, DenoOptions>;
17
17
 
18
- export { type DenoAdapter, type DenoOptions, denoAdapter as default };
18
+ export { denoAdapter as default };
19
+ export type { DenoAdapter, DenoOptions };
@@ -1,28 +1,37 @@
1
- import { M as Message, P as Peer, t as toBufferLike } from '../shared/crossws.BS81iGZK.mjs';
2
- import { a as adapterUtils, A as AdapterHookable } from '../shared/crossws.D9ehKjSh.mjs';
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 peers = /* @__PURE__ */ new Set();
12
+ const globalPeers = /* @__PURE__ */ new Map();
9
13
  return {
10
- ...adapterUtils(peers),
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 https://github.com/denoland/deno/pull/22242
18
- headers: upgradeHeaders
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", () => {
@@ -1,12 +1,12 @@
1
- import { AdapterInstance, AdapterOptions, Adapter } from '../index.mjs';
2
- import { IncomingMessage, Server as Server$1, ClientRequestArgs, ClientRequest, OutgoingHttpHeaders, Agent } from 'node:http';
3
- import { Duplex, DuplexOptions } from 'node:stream';
1
+ import { Adapter, AdapterInstance, AdapterOptions } from '../index.mjs';
2
+ import { Agent, ClientRequestArgs, IncomingMessage, ClientRequest, Server as Server$1, OutgoingHttpHeaders } from 'node:http';
3
+ import { DuplexOptions, Duplex } from 'node:stream';
4
4
  import { EventEmitter } from 'events';
5
5
  import { Server as Server$2 } 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
- import '../shared/crossws.ChIJSJVK.mjs';
9
+ import '../shared/crossws.BQXMA5bH.mjs';
10
10
 
11
11
  type BufferLike = string | Buffer | DataView | number | ArrayBufferView | Uint8Array | ArrayBuffer | SharedArrayBuffer | readonly any[] | readonly number[] | {
12
12
  valueOf(): ArrayBuffer;
@@ -286,8 +286,8 @@ 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): void;
290
- closeAll: (code?: number, data?: string | Buffer) => void;
289
+ handleUpgrade(req: IncomingMessage, socket: Duplex, head: Buffer, webRequest?: Request): Promise<void>;
290
+ closeAll: (code?: number, data?: string | Buffer, force?: boolean) => void;
291
291
  }
292
292
  interface NodeOptions extends AdapterOptions {
293
293
  wss?: WebSocketServer;
@@ -295,4 +295,5 @@ interface NodeOptions extends AdapterOptions {
295
295
  }
296
296
  declare const nodeAdapter: Adapter<NodeAdapter, NodeOptions>;
297
297
 
298
- export { type NodeAdapter, type NodeOptions, nodeAdapter as default };
298
+ export { nodeAdapter as default };
299
+ export type { NodeAdapter, NodeOptions };