crossws 0.4.2 → 0.4.4

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 (52) hide show
  1. package/dist/_chunks/_request.mjs +83 -0
  2. package/dist/_chunks/_types.d.mts +24 -0
  3. package/dist/_chunks/adapter.d.mts +174 -0
  4. package/dist/_chunks/adapter.mjs +93 -0
  5. package/dist/_chunks/bun.d.mts +38 -0
  6. package/dist/_chunks/cloudflare.d.mts +45 -0
  7. package/dist/_chunks/deno.d.mts +17 -0
  8. package/dist/_chunks/error.mjs +10 -0
  9. package/dist/_chunks/libs/ws.mjs +3531 -0
  10. package/dist/_chunks/node.d.mts +299 -0
  11. package/dist/_chunks/peer.mjs +244 -0
  12. package/dist/_chunks/rolldown-runtime.mjs +32 -0
  13. package/dist/_chunks/sse.d.mts +12 -0
  14. package/dist/_chunks/web.d.mts +298 -0
  15. package/dist/adapters/bun.d.mts +2 -41
  16. package/dist/adapters/bun.mjs +83 -93
  17. package/dist/adapters/cloudflare.d.mts +2 -46
  18. package/dist/adapters/cloudflare.mjs +173 -219
  19. package/dist/adapters/deno.d.mts +2 -19
  20. package/dist/adapters/deno.mjs +65 -74
  21. package/dist/adapters/node.d.mts +2 -299
  22. package/dist/adapters/node.mjs +119 -156
  23. package/dist/adapters/sse.d.mts +2 -13
  24. package/dist/adapters/sse.mjs +98 -118
  25. package/dist/adapters/uws.d.mts +44 -44
  26. package/dist/adapters/uws.mjs +152 -175
  27. package/dist/index.d.mts +2 -170
  28. package/dist/index.mjs +3 -1
  29. package/dist/server/bun.d.mts +8 -21
  30. package/dist/server/bun.mjs +24 -31
  31. package/dist/server/cloudflare.d.mts +8 -21
  32. package/dist/server/cloudflare.mjs +21 -30
  33. package/dist/server/default.d.mts +8 -21
  34. package/dist/server/default.mjs +22 -26
  35. package/dist/server/deno.d.mts +8 -21
  36. package/dist/server/deno.mjs +21 -24
  37. package/dist/server/node.d.mts +8 -21
  38. package/dist/server/node.mjs +32 -43
  39. package/dist/websocket/native.d.mts +3 -2
  40. package/dist/websocket/native.mjs +4 -1
  41. package/dist/websocket/node.d.mts +3 -2
  42. package/dist/websocket/node.mjs +7 -13
  43. package/dist/websocket/sse.d.mts +34 -34
  44. package/dist/websocket/sse.mjs +112 -121
  45. package/package.json +14 -13
  46. package/dist/shared/crossws.B31KJMcF.mjs +0 -83
  47. package/dist/shared/crossws.BQXMA5bH.d.mts +0 -297
  48. package/dist/shared/crossws.By9qWDAI.mjs +0 -8
  49. package/dist/shared/crossws.C5pESzqN.mjs +0 -4993
  50. package/dist/shared/crossws.CP-89VBK.d.mts +0 -23
  51. package/dist/shared/crossws.CPlNx7g8.mjs +0 -105
  52. package/dist/shared/crossws.WpyOHUXc.mjs +0 -330
@@ -0,0 +1,83 @@
1
+ //#region src/_request.ts
2
+ const StubRequest = /* @__PURE__ */ (() => {
3
+ class StubRequest {
4
+ url;
5
+ _abortController;
6
+ _headers;
7
+ _init;
8
+ constructor(url, init = {}) {
9
+ this.url = url;
10
+ this._init = init;
11
+ }
12
+ get headers() {
13
+ if (!this._headers) this._headers = new Headers(this._init?.headers);
14
+ return this._headers;
15
+ }
16
+ clone() {
17
+ return new StubRequest(this.url, this._init);
18
+ }
19
+ get method() {
20
+ return "GET";
21
+ }
22
+ get signal() {
23
+ if (!this._abortController) this._abortController = new AbortController();
24
+ return this._abortController.signal;
25
+ }
26
+ get cache() {
27
+ return "default";
28
+ }
29
+ get credentials() {
30
+ return "same-origin";
31
+ }
32
+ get destination() {
33
+ return "";
34
+ }
35
+ get integrity() {
36
+ return "";
37
+ }
38
+ get keepalive() {
39
+ return false;
40
+ }
41
+ get redirect() {
42
+ return "follow";
43
+ }
44
+ get mode() {
45
+ return "cors";
46
+ }
47
+ get referrer() {
48
+ return "about:client";
49
+ }
50
+ get referrerPolicy() {
51
+ return "";
52
+ }
53
+ get body() {
54
+ return null;
55
+ }
56
+ get bodyUsed() {
57
+ return false;
58
+ }
59
+ arrayBuffer() {
60
+ return Promise.resolve(/* @__PURE__ */ new ArrayBuffer(0));
61
+ }
62
+ blob() {
63
+ return Promise.resolve(new Blob());
64
+ }
65
+ bytes() {
66
+ return Promise.resolve(new Uint8Array());
67
+ }
68
+ formData() {
69
+ return Promise.resolve(new FormData());
70
+ }
71
+ json() {
72
+ return Promise.resolve(JSON.parse(""));
73
+ }
74
+ text() {
75
+ return Promise.resolve("");
76
+ }
77
+ }
78
+ Object.setPrototypeOf(StubRequest.prototype, globalThis.Request.prototype);
79
+ return StubRequest;
80
+ })();
81
+
82
+ //#endregion
83
+ export { StubRequest as t };
@@ -0,0 +1,24 @@
1
+ import { a as Hooks } from "./adapter.mjs";
2
+ import { n as BunOptions } from "./bun.mjs";
3
+ import { n as CloudflareOptions } from "./cloudflare.mjs";
4
+ import { n as DenoOptions } from "./deno.mjs";
5
+ import { n as NodeOptions } from "./node.mjs";
6
+ import { n as SSEOptions } from "./sse.mjs";
7
+ import { Server, ServerOptions, ServerPlugin, ServerRequest } from "srvx";
8
+
9
+ //#region src/server/_types.d.ts
10
+ type WSOptions = Partial<Hooks> & {
11
+ resolve?: (req: ServerRequest) => Partial<Hooks> | Promise<Partial<Hooks>>;
12
+ options?: {
13
+ bun?: BunOptions;
14
+ deno?: DenoOptions;
15
+ node?: NodeOptions;
16
+ sse?: SSEOptions;
17
+ cloudflare?: CloudflareOptions;
18
+ };
19
+ };
20
+ type ServerWithWSOptions = ServerOptions & {
21
+ websocket?: WSOptions;
22
+ };
23
+ //#endregion
24
+ export { WSOptions as n, ServerWithWSOptions as t };
@@ -0,0 +1,174 @@
1
+ import { a as WebSocket } from "./web.mjs";
2
+
3
+ //#region src/error.d.ts
4
+ declare class WSError extends Error {
5
+ constructor(...args: any[]);
6
+ }
7
+ //#endregion
8
+ //#region src/utils.d.ts
9
+ declare const kNodeInspect: unique symbol;
10
+ //#endregion
11
+ //#region src/peer.d.ts
12
+ interface PeerContext extends Record<string, unknown> {}
13
+ interface AdapterInternal {
14
+ ws: unknown;
15
+ request: Request;
16
+ namespace: string;
17
+ peers?: Set<Peer>;
18
+ context?: PeerContext;
19
+ }
20
+ declare abstract class Peer<Internal extends AdapterInternal = AdapterInternal> {
21
+ #private;
22
+ protected _internal: Internal;
23
+ protected _topics: Set<string>;
24
+ protected _id?: string;
25
+ constructor(internal: Internal);
26
+ get context(): PeerContext;
27
+ get namespace(): string;
28
+ /**
29
+ * Unique random [uuid v4](https://developer.mozilla.org/en-US/docs/Glossary/UUID) identifier for the peer.
30
+ */
31
+ get id(): string;
32
+ /** IP address of the peer */
33
+ get remoteAddress(): string | undefined;
34
+ /** upgrade request */
35
+ get request(): Request;
36
+ /**
37
+ * Get the [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) instance.
38
+ *
39
+ * **Note:** crossws adds polyfill for the following properties if native values are not available:
40
+ * - `protocol`: Extracted from the `sec-websocket-protocol` header.
41
+ * - `extensions`: Extracted from the `sec-websocket-extensions` header.
42
+ * - `url`: Extracted from the request URL (http -> ws).
43
+ * */
44
+ get websocket(): Partial<WebSocket>;
45
+ /** All connected peers to the server */
46
+ get peers(): Set<Peer>;
47
+ /** All topics, this peer has been subscribed to. */
48
+ get topics(): Set<string>;
49
+ abstract close(code?: number, reason?: string): void;
50
+ /** Abruptly close the connection */
51
+ terminate(): void;
52
+ /** Subscribe to a topic */
53
+ subscribe(topic: string): void;
54
+ /** Unsubscribe from a topic */
55
+ unsubscribe(topic: string): void;
56
+ /** Send a message to the peer. */
57
+ abstract send(data: unknown, options?: {
58
+ compress?: boolean;
59
+ }): number | void | undefined;
60
+ /** Send message to subscribes of topic */
61
+ abstract publish(topic: string, data: unknown, options?: {
62
+ compress?: boolean;
63
+ }): void;
64
+ toString(): string;
65
+ [Symbol.toPrimitive](): string;
66
+ [Symbol.toStringTag](): "WebSocket";
67
+ [kNodeInspect](): unknown;
68
+ }
69
+ //#endregion
70
+ //#region src/message.d.ts
71
+ declare class Message implements Partial<MessageEvent> {
72
+ #private;
73
+ /** Access to the original [message event](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/message_event) if available. */
74
+ readonly event?: MessageEvent;
75
+ /** Access to the Peer that emitted the message. */
76
+ readonly peer?: Peer;
77
+ /** Raw message data (can be of any type). */
78
+ readonly rawData: unknown;
79
+ constructor(rawData: unknown, peer: Peer, event?: MessageEvent);
80
+ /**
81
+ * Unique random [uuid v4](https://developer.mozilla.org/en-US/docs/Glossary/UUID) identifier for the message.
82
+ */
83
+ get id(): string;
84
+ /**
85
+ * Get data as [Uint8Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) value.
86
+ *
87
+ * If raw data is in any other format or string, it will be automatically converted and encoded.
88
+ */
89
+ uint8Array(): Uint8Array;
90
+ /**
91
+ * 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.
92
+ *
93
+ * If raw data is in any other format or string, it will be automatically converted and encoded.
94
+ */
95
+ arrayBuffer(): ArrayBuffer | SharedArrayBuffer;
96
+ /**
97
+ * Get data as [Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob) value.
98
+ *
99
+ * If raw data is in any other format or string, it will be automatically converted and encoded. */
100
+ blob(): Blob;
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
+ text(): string;
107
+ /**
108
+ * Get parsed version of the message text with [`JSON.parse()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse).
109
+ */
110
+ json<T = unknown>(): T;
111
+ /**
112
+ * Message data (value varies based on `peer.websocket.binaryType`).
113
+ */
114
+ get data(): unknown;
115
+ toString(): string;
116
+ [Symbol.toPrimitive](): string;
117
+ [kNodeInspect](): unknown;
118
+ }
119
+ //#endregion
120
+ //#region src/hooks.d.ts
121
+ declare function defineHooks<T extends Partial<Hooks> = Partial<Hooks>>(hooks: T): T;
122
+ type ResolveHooks = (request: Request & {
123
+ readonly context?: PeerContext;
124
+ }) => Partial<Hooks> | Promise<Partial<Hooks>>;
125
+ type MaybePromise<T> = T | Promise<T>;
126
+ interface Hooks {
127
+ /**
128
+ * Upgrading a request to a WebSocket connection.
129
+ *
130
+ * - You can throw a Response to abort the upgrade.
131
+ * - You can return { headers } to modify the response.
132
+ * - You can return { namespace } to change the pub/sub namespace.
133
+ * - You can return { context } to provide a custom peer context.
134
+ *
135
+ * @param request
136
+ * @throws {Response}
137
+ */
138
+ upgrade: (request: Request & {
139
+ readonly context?: Record<string, unknown>;
140
+ }) => MaybePromise<{
141
+ headers?: HeadersInit;
142
+ namespace?: string;
143
+ context?: PeerContext;
144
+ } | Response | void>;
145
+ /** A message is received */
146
+ message: (peer: Peer, message: Message) => MaybePromise<void>;
147
+ /** A socket is opened */
148
+ open: (peer: Peer) => MaybePromise<void>;
149
+ /** A socket is closed */
150
+ close: (peer: Peer, details: {
151
+ code?: number;
152
+ reason?: string;
153
+ }) => MaybePromise<void>;
154
+ /** An error occurs */
155
+ error: (peer: Peer, error: WSError) => MaybePromise<void>;
156
+ }
157
+ //#endregion
158
+ //#region src/adapter.d.ts
159
+ interface AdapterInstance {
160
+ readonly peers: Map<string, Set<Peer>>;
161
+ readonly publish: (topic: string, data: unknown, options?: {
162
+ compress?: boolean;
163
+ namespace?: string;
164
+ }) => void;
165
+ }
166
+ interface AdapterOptions {
167
+ resolve?: ResolveHooks;
168
+ getNamespace?: (request: Request) => string;
169
+ hooks?: Partial<Hooks>;
170
+ }
171
+ type Adapter<AdapterT extends AdapterInstance = AdapterInstance, Options extends AdapterOptions = AdapterOptions> = (options?: Options) => AdapterT;
172
+ declare function defineWebSocketAdapter<AdapterT extends AdapterInstance = AdapterInstance, Options extends AdapterOptions = AdapterOptions>(factory: Adapter<AdapterT, Options>): Adapter<AdapterT, Options>;
173
+ //#endregion
174
+ export { Hooks as a, Message as c, PeerContext as d, WSError as f, defineWebSocketAdapter as i, AdapterInternal as l, AdapterInstance as n, ResolveHooks as o, AdapterOptions as r, defineHooks as s, Adapter as t, Peer as u };
@@ -0,0 +1,93 @@
1
+ //#region src/hooks.ts
2
+ var AdapterHookable = class {
3
+ options;
4
+ constructor(options) {
5
+ this.options = options || {};
6
+ }
7
+ callHook(name, arg1, arg2) {
8
+ const globalHook = this.options.hooks?.[name];
9
+ const globalPromise = globalHook?.(arg1, arg2);
10
+ const request = arg1.request || arg1;
11
+ const resolveHooksPromise = this.options.resolve?.(request);
12
+ if (!resolveHooksPromise) return globalPromise;
13
+ const resolvePromise = resolveHooksPromise instanceof Promise ? resolveHooksPromise.then((hooks) => hooks?.[name]) : resolveHooksPromise?.[name];
14
+ return Promise.all([globalPromise, resolvePromise]).then(([globalRes, hook]) => {
15
+ const hookResPromise = hook?.(arg1, arg2);
16
+ return hookResPromise instanceof Promise ? hookResPromise.then((hookRes) => hookRes || globalRes) : hookResPromise || globalRes;
17
+ });
18
+ }
19
+ async upgrade(request) {
20
+ let namespace = this.options.getNamespace?.(request) ?? new URL(request.url).pathname;
21
+ const context = request.context || {};
22
+ try {
23
+ const res = await this.callHook("upgrade", request);
24
+ if (!res) return {
25
+ context,
26
+ namespace
27
+ };
28
+ if (res.namespace) namespace = res.namespace;
29
+ if (res.context) Object.assign(context, res.context);
30
+ if (res instanceof Response) return {
31
+ context,
32
+ namespace,
33
+ endResponse: res
34
+ };
35
+ if (res.headers) return {
36
+ context,
37
+ namespace,
38
+ upgradeHeaders: res.headers
39
+ };
40
+ } catch (error) {
41
+ const errResponse = error.response || error;
42
+ if (errResponse instanceof Response) return {
43
+ context,
44
+ namespace,
45
+ endResponse: errResponse
46
+ };
47
+ throw error;
48
+ }
49
+ return {
50
+ context,
51
+ namespace
52
+ };
53
+ }
54
+ };
55
+ function defineHooks(hooks) {
56
+ return hooks;
57
+ }
58
+
59
+ //#endregion
60
+ //#region src/adapter.ts
61
+ function adapterUtils(globalPeers) {
62
+ return {
63
+ peers: globalPeers,
64
+ publish(topic, message, options) {
65
+ for (const peers of options?.namespace ? [globalPeers.get(options.namespace) || []] : globalPeers.values()) {
66
+ let firstPeerWithTopic;
67
+ for (const peer of peers) if (peer.topics.has(topic)) {
68
+ firstPeerWithTopic = peer;
69
+ break;
70
+ }
71
+ if (firstPeerWithTopic) {
72
+ firstPeerWithTopic.send(message, options);
73
+ firstPeerWithTopic.publish(topic, message, options);
74
+ }
75
+ }
76
+ }
77
+ };
78
+ }
79
+ function getPeers(globalPeers, namespace) {
80
+ if (!namespace) throw new Error("Websocket publish namespace missing.");
81
+ let peers = globalPeers.get(namespace);
82
+ if (!peers) {
83
+ peers = /* @__PURE__ */ new Set();
84
+ globalPeers.set(namespace, peers);
85
+ }
86
+ return peers;
87
+ }
88
+ function defineWebSocketAdapter(factory) {
89
+ return factory;
90
+ }
91
+
92
+ //#endregion
93
+ export { defineHooks as a, AdapterHookable as i, defineWebSocketAdapter as n, getPeers as r, adapterUtils as t };
@@ -0,0 +1,38 @@
1
+ import { d as PeerContext, n as AdapterInstance, r as AdapterOptions, t as Adapter, u as Peer } from "./adapter.mjs";
2
+ import { Server, ServerWebSocket, WebSocketHandler } from "bun";
3
+
4
+ //#region src/adapters/bun.d.ts
5
+ interface BunAdapter extends AdapterInstance {
6
+ websocket: WebSocketHandler<ContextData>;
7
+ handleUpgrade(req: Request, server: Server<ContextData>): Promise<Response | undefined>;
8
+ }
9
+ interface BunOptions extends AdapterOptions {}
10
+ type ContextData = {
11
+ peer?: BunPeer;
12
+ namespace: string;
13
+ request: Request;
14
+ server?: Server<ContextData>;
15
+ context: PeerContext;
16
+ };
17
+ declare const bunAdapter: Adapter<BunAdapter, BunOptions>;
18
+ declare class BunPeer extends Peer<{
19
+ ws: ServerWebSocket<ContextData>;
20
+ namespace: string;
21
+ request: Request;
22
+ peers: Set<BunPeer>;
23
+ }> {
24
+ get remoteAddress(): string;
25
+ get context(): PeerContext;
26
+ send(data: unknown, options?: {
27
+ compress?: boolean;
28
+ }): number;
29
+ publish(topic: string, data: unknown, options?: {
30
+ compress?: boolean;
31
+ }): number;
32
+ subscribe(topic: string): void;
33
+ unsubscribe(topic: string): void;
34
+ close(code?: number, reason?: string): void;
35
+ terminate(): void;
36
+ }
37
+ //#endregion
38
+ export { BunOptions as n, bunAdapter as r, BunAdapter as t };
@@ -0,0 +1,45 @@
1
+ import { n as AdapterInstance, r as AdapterOptions, t as Adapter } from "./adapter.mjs";
2
+ import { a as WebSocket$1 } from "./web.mjs";
3
+ import { DurableObject } from "cloudflare:workers";
4
+ import * as CF from "@cloudflare/workers-types";
5
+
6
+ //#region src/adapters/cloudflare.d.ts
7
+ type WSDurableObjectStub = CF.DurableObjectStub & {
8
+ webSocketPublish?: (topic: string, data: unknown, opts: any) => Promise<void>;
9
+ };
10
+ type ResolveDurableStub = (req: CF.Request | undefined, env: unknown, context: CF.ExecutionContext | undefined) => WSDurableObjectStub | undefined | Promise<WSDurableObjectStub | undefined>;
11
+ interface CloudflareOptions extends AdapterOptions {
12
+ /**
13
+ * Durable Object binding name from environment.
14
+ *
15
+ * **Note:** This option will be ignored if `resolveDurableStub` is provided.
16
+ *
17
+ * @default "$DurableObject"
18
+ */
19
+ bindingName?: string;
20
+ /**
21
+ * Durable Object instance name.
22
+ *
23
+ * **Note:** This option will be ignored if `resolveDurableStub` is provided.
24
+ *
25
+ * @default "crossws"
26
+ */
27
+ instanceName?: string;
28
+ /**
29
+ * Custom function that resolves Durable Object binding to handle the WebSocket upgrade.
30
+ *
31
+ * **Note:** This option will override `bindingName` and `instanceName`.
32
+ */
33
+ resolveDurableStub?: ResolveDurableStub;
34
+ }
35
+ declare const cloudflareAdapter: Adapter<CloudflareDurableAdapter, CloudflareOptions>;
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>;
43
+ }
44
+ //#endregion
45
+ export { CloudflareOptions as n, cloudflareAdapter as r, CloudflareDurableAdapter as t };
@@ -0,0 +1,17 @@
1
+ import { n as AdapterInstance, r as AdapterOptions, t as Adapter } from "./adapter.mjs";
2
+
3
+ //#region src/adapters/deno.d.ts
4
+ interface DenoAdapter extends AdapterInstance {
5
+ handleUpgrade(req: Request, info: ServeHandlerInfo): Promise<Response>;
6
+ }
7
+ interface DenoOptions extends AdapterOptions {}
8
+ type ServeHandlerInfo = {
9
+ remoteAddr?: {
10
+ transport: string;
11
+ hostname: string;
12
+ port: number;
13
+ };
14
+ };
15
+ declare const denoAdapter: Adapter<DenoAdapter, DenoOptions>;
16
+ //#endregion
17
+ export { DenoOptions as n, denoAdapter as r, DenoAdapter as t };
@@ -0,0 +1,10 @@
1
+ //#region src/error.ts
2
+ var WSError = class extends Error {
3
+ constructor(...args) {
4
+ super(...args);
5
+ this.name = "WSError";
6
+ }
7
+ };
8
+
9
+ //#endregion
10
+ export { WSError as t };