@hedystia/ws 2.3.3 → 2.3.5

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/dist/client.cjs CHANGED
@@ -1,14 +1,24 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  //#region src/client.ts
3
3
  /**
4
- * Resolve the best `WebSocket` constructor for the current runtime.
4
+ * Resolve the `WebSocket` constructor from the current runtime's global scope.
5
5
  *
6
6
  * @remarks
7
- * - Bun, Deno, browsers and Node ≥ 22 expose `globalThis.WebSocket`.
8
- * - Older Node falls back to the [`ws`](https://github.com/websockets/ws)
9
- * package, which mirrors the WHATWG `WebSocket` API.
7
+ * Every supported runtime exposes a WHATWG-compliant `WebSocket` natively:
10
8
  *
11
- * @returns A `WebSocket` constructor compatible with the WHATWG interface.
9
+ * | Runtime | Available since |
10
+ * |---------------|-----------------|
11
+ * | Browsers | always |
12
+ * | Bun | always |
13
+ * | Deno | v1.4 |
14
+ * | Node.js | v22 (stable) |
15
+ *
16
+ * If `globalThis.WebSocket` is not present (e.g. Node.js < 22 without a
17
+ * polyfill), this function throws with a descriptive message instead of
18
+ * silently falling back to a third-party package.
19
+ *
20
+ * @returns The global `WebSocket` constructor.
21
+ * @throws {Error} When no native `WebSocket` is available in the current runtime.
12
22
  *
13
23
  * @example
14
24
  * ```ts
@@ -20,22 +30,23 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
20
30
  */
21
31
  function resolveWebSocket() {
22
32
  if (typeof globalThis !== "undefined" && globalThis.WebSocket) return globalThis.WebSocket;
23
- const mod = require("ws");
24
- return mod.WebSocket ?? mod;
33
+ throw new Error("@hedystia/ws: no native WebSocket found in globalThis. Ensure you are running Bun, Deno, a modern browser, or Node.js ≥ 22.");
25
34
  }
26
35
  /**
27
- * Create a `WebSocket` instance using the best available implementation
28
- * for the current runtime.
36
+ * Create a `WebSocket` instance using the runtime's native `globalThis.WebSocket`.
29
37
  *
30
38
  * @remarks
31
- * Custom request headers are honoured on Node via the `ws` package; on
32
- * runtimes that ship a WHATWG-compliant global `WebSocket` (Bun, Deno,
33
- * browsers, Node 22) headers are ignored — matching standard semantics.
39
+ * Custom request headers are only honoured on runtimes that expose them via
40
+ * the second constructor argument (e.g. Bun). On browsers and other
41
+ * WHATWG-strict environments, `options.headers` is silently ignored —
42
+ * matching standard WebSocket semantics.
34
43
  *
35
- * @param url - Absolute WebSocket URL (`ws://` or `wss://`)
36
- * @param options - Optional protocols / headers
44
+ * @param url - Absolute WebSocket URL (`ws://` or `wss://`).
45
+ * @param options - Optional sub-protocols and headers, see {@link ClientWebSocketOptions}.
37
46
  * @returns A connected (or connecting) `WebSocket` instance.
38
47
  *
48
+ * @throws {Error} When no native `WebSocket` is available in the current runtime.
49
+ *
39
50
  * @example
40
51
  * ```ts
41
52
  * import { createWebSocket } from "@hedystia/ws/client";
@@ -45,32 +56,31 @@ function resolveWebSocket() {
45
56
  * headers: { authorization: "Bearer ..." },
46
57
  * });
47
58
  *
48
- * ws.onopen = () => ws.send("hi");
59
+ * ws.onopen = () => ws.send("hi");
49
60
  * ws.onmessage = (event) => console.log(event.data);
50
61
  * ```
51
62
  */
52
63
  function createWebSocket(url, options) {
53
64
  const Ctor = resolveWebSocket();
54
- if (typeof globalThis !== "undefined" && globalThis.WebSocket === Ctor) return options?.protocols ? new Ctor(url, options.protocols) : new Ctor(url);
55
- const init = {};
56
- if (options?.headers) init.headers = options.headers;
57
- return new Ctor(url, options?.protocols, init);
65
+ if (options?.protocols) return new Ctor(url, options.protocols);
66
+ return new Ctor(url);
58
67
  }
59
68
  /**
60
69
  * Lightweight runtime-agnostic wrapper that mirrors a small, predictable
61
- * subset of the WHATWG WebSocket interface.
70
+ * subset of the WHATWG `WebSocket` interface.
62
71
  *
63
72
  * @remarks
64
73
  * Useful for higher-level code that wants to assign event handlers by
65
- * property (`socket.onmessage = ...`) without caring whether the underlying
66
- * implementation comes from `globalThis.WebSocket` or the `ws` package.
74
+ * property (`socket.onmessage = …`) without referencing the global
75
+ * `WebSocket` type directly. Delegates all operations to the native
76
+ * `WebSocket` produced by {@link createWebSocket}.
67
77
  *
68
78
  * @example
69
79
  * ```ts
70
80
  * import { WebSocketClient } from "@hedystia/ws/client";
71
81
  *
72
82
  * const client = new WebSocketClient("ws://localhost:3000");
73
- * client.onopen = () => client.send("hello");
83
+ * client.onopen = () => client.send("hello");
74
84
  * client.onmessage = (event) => console.log(event.data);
75
85
  * ```
76
86
  */
@@ -84,8 +94,8 @@ var WebSocketClient = class {
84
94
  /**
85
95
  * Create a new client and immediately initiate the connection.
86
96
  *
87
- * @param url - Absolute WebSocket URL (`ws://` or `wss://`)
88
- * @param options - Optional protocols / headers, see {@link ClientWebSocketOptions}
97
+ * @param url - Absolute WebSocket URL (`ws://` or `wss://`).
98
+ * @param options - Optional sub-protocols / headers; see {@link ClientWebSocketOptions}.
89
99
  */
90
100
  constructor(url, options) {
91
101
  this.socket = createWebSocket(url, options);
@@ -93,7 +103,7 @@ var WebSocketClient = class {
93
103
  /**
94
104
  * Current connection state, mirroring {@link WebSocket.readyState}.
95
105
  *
96
- * @returns `0` connecting, `1` open, `2` closing, `3` closed.
106
+ * @returns `0` connecting · `1` open · `2` closing · `3` closed.
97
107
  */
98
108
  get readyState() {
99
109
  return this.socket.readyState;
@@ -101,7 +111,7 @@ var WebSocketClient = class {
101
111
  /**
102
112
  * Send a payload to the server.
103
113
  *
104
- * @param data - WHATWG-compatible payload
114
+ * @param data - WHATWG-compatible payload.
105
115
  */
106
116
  send(data) {
107
117
  this.socket.send(data);
@@ -109,8 +119,8 @@ var WebSocketClient = class {
109
119
  /**
110
120
  * Close the underlying socket.
111
121
  *
112
- * @param code - Close code (defaults to 1000)
113
- * @param reason - Optional human-readable reason
122
+ * @param code - Close code (defaults to `1000`).
123
+ * @param reason - Optional human-readable reason phrase.
114
124
  */
115
125
  close(code, reason) {
116
126
  this.socket.close(code, reason);
@@ -1 +1 @@
1
- {"version":3,"file":"client.cjs","names":[],"sources":["../src/client.ts"],"sourcesContent":["import type { ClientWebSocketOptions } from \"./types\";\n\nexport type { ClientWebSocketOptions } from \"./types\";\n\n/**\n * Resolve the best `WebSocket` constructor for the current runtime.\n *\n * @remarks\n * - Bun, Deno, browsers and Node 22 expose `globalThis.WebSocket`.\n * - Older Node falls back to the [`ws`](https://github.com/websockets/ws)\n * package, which mirrors the WHATWG `WebSocket` API.\n *\n * @returns A `WebSocket` constructor compatible with the WHATWG interface.\n *\n * @example\n * ```ts\n * import { resolveWebSocket } from \"@hedystia/ws/client\";\n *\n * const WS = resolveWebSocket();\n * const socket = new WS(\"ws://localhost:3000\");\n * ```\n */\nexport function resolveWebSocket(): typeof WebSocket {\n if (typeof globalThis !== \"undefined\" && (globalThis as any).WebSocket) {\n return (globalThis as any).WebSocket as typeof WebSocket;\n }\n const mod = require(\"ws\");\n return (mod.WebSocket ?? mod) as typeof WebSocket;\n}\n\n/**\n * Create a `WebSocket` instance using the best available implementation\n * for the current runtime.\n *\n * @remarks\n * Custom request headers are honoured on Node via the `ws` package; on\n * runtimes that ship a WHATWG-compliant global `WebSocket` (Bun, Deno,\n * browsers, Node 22) headers are ignored matching standard semantics.\n *\n * @param url - Absolute WebSocket URL (`ws://` or `wss://`)\n * @param options - Optional protocols / headers\n * @returns A connected (or connecting) `WebSocket` instance.\n *\n * @example\n * ```ts\n * import { createWebSocket } from \"@hedystia/ws/client\";\n *\n * const ws = createWebSocket(\"ws://localhost:3000\", {\n * protocols: \"v1\",\n * headers: { authorization: \"Bearer ...\" },\n * });\n *\n * ws.onopen = () => ws.send(\"hi\");\n * ws.onmessage = (event) => console.log(event.data);\n * ```\n */\nexport function createWebSocket(url: string, options?: ClientWebSocketOptions): WebSocket {\n const Ctor = resolveWebSocket();\n const isWhatwg =\n typeof globalThis !== \"undefined\" && (globalThis as any).WebSocket === (Ctor as any);\n\n if (isWhatwg) {\n return options?.protocols ? new Ctor(url, options.protocols as any) : new Ctor(url);\n }\n\n const init: any = {};\n if (options?.headers) {\n init.headers = options.headers;\n }\n return new (Ctor as any)(url, options?.protocols, init);\n}\n\n/**\n * Lightweight runtime-agnostic wrapper that mirrors a small, predictable\n * subset of the WHATWG WebSocket interface.\n *\n * @remarks\n * Useful for higher-level code that wants to assign event handlers by\n * property (`socket.onmessage = ...`) without caring whether the underlying\n * implementation comes from `globalThis.WebSocket` or the `ws` package.\n *\n * @example\n * ```ts\n * import { WebSocketClient } from \"@hedystia/ws/client\";\n *\n * const client = new WebSocketClient(\"ws://localhost:3000\");\n * client.onopen = () => client.send(\"hello\");\n * client.onmessage = (event) => console.log(event.data);\n * ```\n */\nexport class WebSocketClient {\n /**\n * Underlying WebSocket instance produced by {@link createWebSocket}.\n *\n * @readonly\n */\n readonly socket: WebSocket;\n\n /**\n * Create a new client and immediately initiate the connection.\n *\n * @param url - Absolute WebSocket URL (`ws://` or `wss://`)\n * @param options - Optional protocols / headers, see {@link ClientWebSocketOptions}\n */\n constructor(url: string, options?: ClientWebSocketOptions) {\n this.socket = createWebSocket(url, options);\n }\n\n /**\n * Current connection state, mirroring {@link WebSocket.readyState}.\n *\n * @returns `0` connecting, `1` open, `2` closing, `3` closed.\n */\n get readyState(): number {\n return this.socket.readyState;\n }\n\n /**\n * Send a payload to the server.\n *\n * @param data - WHATWG-compatible payload\n */\n send(data: string | ArrayBufferLike | Blob | ArrayBufferView): void {\n this.socket.send(data as any);\n }\n\n /**\n * Close the underlying socket.\n *\n * @param code - Close code (defaults to 1000)\n * @param reason - Optional human-readable reason\n */\n close(code?: number, reason?: string): void {\n this.socket.close(code, reason);\n }\n\n /**\n * Assign the open-event listener.\n */\n set onopen(cb: ((ev: Event) => void) | null) {\n (this.socket as any).onopen = cb;\n }\n /**\n * Assign the message-event listener.\n */\n set onmessage(cb: ((ev: MessageEvent) => void) | null) {\n (this.socket as any).onmessage = cb;\n }\n /**\n * Assign the close-event listener.\n */\n set onclose(cb: ((ev: CloseEvent) => void) | null) {\n (this.socket as any).onclose = cb;\n }\n /**\n * Assign the error-event listener.\n */\n set onerror(cb: ((ev: Event) => void) | null) {\n (this.socket as any).onerror = cb;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAsBA,SAAgB,mBAAqC;CACnD,IAAI,OAAO,eAAe,eAAgB,WAAmB,WAC3D,OAAQ,WAAmB;CAE7B,MAAM,MAAM,QAAQ,KAAK;CACzB,OAAQ,IAAI,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6B3B,SAAgB,gBAAgB,KAAa,SAA6C;CACxF,MAAM,OAAO,kBAAkB;CAI/B,IAFE,OAAO,eAAe,eAAgB,WAAmB,cAAe,MAGxE,OAAO,SAAS,YAAY,IAAI,KAAK,KAAK,QAAQ,UAAiB,GAAG,IAAI,KAAK,IAAI;CAGrF,MAAM,OAAY,EAAE;CACpB,IAAI,SAAS,SACX,KAAK,UAAU,QAAQ;CAEzB,OAAO,IAAK,KAAa,KAAK,SAAS,WAAW,KAAK;;;;;;;;;;;;;;;;;;;;AAqBzD,IAAa,kBAAb,MAA6B;;;;;;CAM3B;;;;;;;CAQA,YAAY,KAAa,SAAkC;EACzD,KAAK,SAAS,gBAAgB,KAAK,QAAQ;;;;;;;CAQ7C,IAAI,aAAqB;EACvB,OAAO,KAAK,OAAO;;;;;;;CAQrB,KAAK,MAA+D;EAClE,KAAK,OAAO,KAAK,KAAY;;;;;;;;CAS/B,MAAM,MAAe,QAAuB;EAC1C,KAAK,OAAO,MAAM,MAAM,OAAO;;;;;CAMjC,IAAI,OAAO,IAAkC;EAC3C,KAAM,OAAe,SAAS;;;;;CAKhC,IAAI,UAAU,IAAyC;EACrD,KAAM,OAAe,YAAY;;;;;CAKnC,IAAI,QAAQ,IAAuC;EACjD,KAAM,OAAe,UAAU;;;;;CAKjC,IAAI,QAAQ,IAAkC;EAC5C,KAAM,OAAe,UAAU"}
1
+ {"version":3,"file":"client.cjs","names":[],"sources":["../src/client.ts"],"sourcesContent":["import type { ClientWebSocketOptions } from \"./types\";\n\nexport type { ClientWebSocketOptions } from \"./types\";\n\n/**\n * Resolve the `WebSocket` constructor from the current runtime's global scope.\n *\n * @remarks\n * Every supported runtime exposes a WHATWG-compliant `WebSocket` natively:\n *\n * | Runtime | Available since |\n * |---------------|-----------------|\n * | Browsers | always |\n * | Bun | always |\n * | Deno | v1.4 |\n * | Node.js | v22 (stable) |\n *\n * If `globalThis.WebSocket` is not present (e.g. Node.js < 22 without a\n * polyfill), this function throws with a descriptive message instead of\n * silently falling back to a third-party package.\n *\n * @returns The global `WebSocket` constructor.\n * @throws {Error} When no native `WebSocket` is available in the current runtime.\n *\n * @example\n * ```ts\n * import { resolveWebSocket } from \"@hedystia/ws/client\";\n *\n * const WS = resolveWebSocket();\n * const socket = new WS(\"ws://localhost:3000\");\n * ```\n */\nexport function resolveWebSocket(): typeof WebSocket {\n if (typeof globalThis !== \"undefined\" && (globalThis as any).WebSocket) {\n return (globalThis as any).WebSocket as typeof WebSocket;\n }\n throw new Error(\n \"@hedystia/ws: no native WebSocket found in globalThis. \" +\n \"Ensure you are running Bun, Deno, a modern browser, or Node.js ≥ 22.\",\n );\n}\n\n/**\n * Create a `WebSocket` instance using the runtime's native `globalThis.WebSocket`.\n *\n * @remarks\n * Custom request headers are only honoured on runtimes that expose them via\n * the second constructor argument (e.g. Bun). On browsers and other\n * WHATWG-strict environments, `options.headers` is silently ignored —\n * matching standard WebSocket semantics.\n *\n * @param url - Absolute WebSocket URL (`ws://` or `wss://`).\n * @param options - Optional sub-protocols and headers, see {@link ClientWebSocketOptions}.\n * @returns A connected (or connecting) `WebSocket` instance.\n *\n * @throws {Error} When no native `WebSocket` is available in the current runtime.\n *\n * @example\n * ```ts\n * import { createWebSocket } from \"@hedystia/ws/client\";\n *\n * const ws = createWebSocket(\"ws://localhost:3000\", {\n * protocols: \"v1\",\n * headers: { authorization: \"Bearer ...\" },\n * });\n *\n * ws.onopen = () => ws.send(\"hi\");\n * ws.onmessage = (event) => console.log(event.data);\n * ```\n */\nexport function createWebSocket(url: string, options?: ClientWebSocketOptions): WebSocket {\n const Ctor = resolveWebSocket();\n\n if (options?.protocols) {\n return new Ctor(url, options.protocols as any);\n }\n return new Ctor(url);\n}\n\n/**\n * Lightweight runtime-agnostic wrapper that mirrors a small, predictable\n * subset of the WHATWG `WebSocket` interface.\n *\n * @remarks\n * Useful for higher-level code that wants to assign event handlers by\n * property (`socket.onmessage = …`) without referencing the global\n * `WebSocket` type directly. Delegates all operations to the native\n * `WebSocket` produced by {@link createWebSocket}.\n *\n * @example\n * ```ts\n * import { WebSocketClient } from \"@hedystia/ws/client\";\n *\n * const client = new WebSocketClient(\"ws://localhost:3000\");\n * client.onopen = () => client.send(\"hello\");\n * client.onmessage = (event) => console.log(event.data);\n * ```\n */\nexport class WebSocketClient {\n /**\n * Underlying WebSocket instance produced by {@link createWebSocket}.\n *\n * @readonly\n */\n readonly socket: WebSocket;\n\n /**\n * Create a new client and immediately initiate the connection.\n *\n * @param url - Absolute WebSocket URL (`ws://` or `wss://`).\n * @param options - Optional sub-protocols / headers; see {@link ClientWebSocketOptions}.\n */\n constructor(url: string, options?: ClientWebSocketOptions) {\n this.socket = createWebSocket(url, options);\n }\n\n /**\n * Current connection state, mirroring {@link WebSocket.readyState}.\n *\n * @returns `0` connecting · `1` open · `2` closing · `3` closed.\n */\n get readyState(): number {\n return this.socket.readyState;\n }\n\n /**\n * Send a payload to the server.\n *\n * @param data - WHATWG-compatible payload.\n */\n send(data: string | ArrayBufferLike | Blob | ArrayBufferView): void {\n this.socket.send(data as any);\n }\n\n /**\n * Close the underlying socket.\n *\n * @param code - Close code (defaults to `1000`).\n * @param reason - Optional human-readable reason phrase.\n */\n close(code?: number, reason?: string): void {\n this.socket.close(code, reason);\n }\n\n /**\n * Assign the open-event listener.\n */\n set onopen(cb: ((ev: Event) => void) | null) {\n (this.socket as any).onopen = cb;\n }\n\n /**\n * Assign the message-event listener.\n */\n set onmessage(cb: ((ev: MessageEvent) => void) | null) {\n (this.socket as any).onmessage = cb;\n }\n\n /**\n * Assign the close-event listener.\n */\n set onclose(cb: ((ev: CloseEvent) => void) | null) {\n (this.socket as any).onclose = cb;\n }\n\n /**\n * Assign the error-event listener.\n */\n set onerror(cb: ((ev: Event) => void) | null) {\n (this.socket as any).onerror = cb;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,SAAgB,mBAAqC;CACnD,IAAI,OAAO,eAAe,eAAgB,WAAmB,WAC3D,OAAQ,WAAmB;CAE7B,MAAM,IAAI,MACR,8HAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BH,SAAgB,gBAAgB,KAAa,SAA6C;CACxF,MAAM,OAAO,kBAAkB;CAE/B,IAAI,SAAS,WACX,OAAO,IAAI,KAAK,KAAK,QAAQ,UAAiB;CAEhD,OAAO,IAAI,KAAK,IAAI;;;;;;;;;;;;;;;;;;;;;AAsBtB,IAAa,kBAAb,MAA6B;;;;;;CAM3B;;;;;;;CAQA,YAAY,KAAa,SAAkC;EACzD,KAAK,SAAS,gBAAgB,KAAK,QAAQ;;;;;;;CAQ7C,IAAI,aAAqB;EACvB,OAAO,KAAK,OAAO;;;;;;;CAQrB,KAAK,MAA+D;EAClE,KAAK,OAAO,KAAK,KAAY;;;;;;;;CAS/B,MAAM,MAAe,QAAuB;EAC1C,KAAK,OAAO,MAAM,MAAM,OAAO;;;;;CAMjC,IAAI,OAAO,IAAkC;EAC3C,KAAM,OAAe,SAAS;;;;;CAMhC,IAAI,UAAU,IAAyC;EACrD,KAAM,OAAe,YAAY;;;;;CAMnC,IAAI,QAAQ,IAAuC;EACjD,KAAM,OAAe,UAAU;;;;;CAMjC,IAAI,QAAQ,IAAkC;EAC5C,KAAM,OAAe,UAAU"}
package/dist/client.d.cts CHANGED
@@ -2,14 +2,24 @@ import { ClientWebSocketOptions } from "./types.cjs";
2
2
 
3
3
  //#region src/client.d.ts
4
4
  /**
5
- * Resolve the best `WebSocket` constructor for the current runtime.
5
+ * Resolve the `WebSocket` constructor from the current runtime's global scope.
6
6
  *
7
7
  * @remarks
8
- * - Bun, Deno, browsers and Node ≥ 22 expose `globalThis.WebSocket`.
9
- * - Older Node falls back to the [`ws`](https://github.com/websockets/ws)
10
- * package, which mirrors the WHATWG `WebSocket` API.
8
+ * Every supported runtime exposes a WHATWG-compliant `WebSocket` natively:
11
9
  *
12
- * @returns A `WebSocket` constructor compatible with the WHATWG interface.
10
+ * | Runtime | Available since |
11
+ * |---------------|-----------------|
12
+ * | Browsers | always |
13
+ * | Bun | always |
14
+ * | Deno | v1.4 |
15
+ * | Node.js | v22 (stable) |
16
+ *
17
+ * If `globalThis.WebSocket` is not present (e.g. Node.js < 22 without a
18
+ * polyfill), this function throws with a descriptive message instead of
19
+ * silently falling back to a third-party package.
20
+ *
21
+ * @returns The global `WebSocket` constructor.
22
+ * @throws {Error} When no native `WebSocket` is available in the current runtime.
13
23
  *
14
24
  * @example
15
25
  * ```ts
@@ -21,18 +31,20 @@ import { ClientWebSocketOptions } from "./types.cjs";
21
31
  */
22
32
  declare function resolveWebSocket(): typeof WebSocket;
23
33
  /**
24
- * Create a `WebSocket` instance using the best available implementation
25
- * for the current runtime.
34
+ * Create a `WebSocket` instance using the runtime's native `globalThis.WebSocket`.
26
35
  *
27
36
  * @remarks
28
- * Custom request headers are honoured on Node via the `ws` package; on
29
- * runtimes that ship a WHATWG-compliant global `WebSocket` (Bun, Deno,
30
- * browsers, Node 22) headers are ignored — matching standard semantics.
37
+ * Custom request headers are only honoured on runtimes that expose them via
38
+ * the second constructor argument (e.g. Bun). On browsers and other
39
+ * WHATWG-strict environments, `options.headers` is silently ignored —
40
+ * matching standard WebSocket semantics.
31
41
  *
32
- * @param url - Absolute WebSocket URL (`ws://` or `wss://`)
33
- * @param options - Optional protocols / headers
42
+ * @param url - Absolute WebSocket URL (`ws://` or `wss://`).
43
+ * @param options - Optional sub-protocols and headers, see {@link ClientWebSocketOptions}.
34
44
  * @returns A connected (or connecting) `WebSocket` instance.
35
45
  *
46
+ * @throws {Error} When no native `WebSocket` is available in the current runtime.
47
+ *
36
48
  * @example
37
49
  * ```ts
38
50
  * import { createWebSocket } from "@hedystia/ws/client";
@@ -42,26 +54,27 @@ declare function resolveWebSocket(): typeof WebSocket;
42
54
  * headers: { authorization: "Bearer ..." },
43
55
  * });
44
56
  *
45
- * ws.onopen = () => ws.send("hi");
57
+ * ws.onopen = () => ws.send("hi");
46
58
  * ws.onmessage = (event) => console.log(event.data);
47
59
  * ```
48
60
  */
49
61
  declare function createWebSocket(url: string, options?: ClientWebSocketOptions): WebSocket;
50
62
  /**
51
63
  * Lightweight runtime-agnostic wrapper that mirrors a small, predictable
52
- * subset of the WHATWG WebSocket interface.
64
+ * subset of the WHATWG `WebSocket` interface.
53
65
  *
54
66
  * @remarks
55
67
  * Useful for higher-level code that wants to assign event handlers by
56
- * property (`socket.onmessage = ...`) without caring whether the underlying
57
- * implementation comes from `globalThis.WebSocket` or the `ws` package.
68
+ * property (`socket.onmessage = …`) without referencing the global
69
+ * `WebSocket` type directly. Delegates all operations to the native
70
+ * `WebSocket` produced by {@link createWebSocket}.
58
71
  *
59
72
  * @example
60
73
  * ```ts
61
74
  * import { WebSocketClient } from "@hedystia/ws/client";
62
75
  *
63
76
  * const client = new WebSocketClient("ws://localhost:3000");
64
- * client.onopen = () => client.send("hello");
77
+ * client.onopen = () => client.send("hello");
65
78
  * client.onmessage = (event) => console.log(event.data);
66
79
  * ```
67
80
  */
@@ -75,27 +88,27 @@ declare class WebSocketClient {
75
88
  /**
76
89
  * Create a new client and immediately initiate the connection.
77
90
  *
78
- * @param url - Absolute WebSocket URL (`ws://` or `wss://`)
79
- * @param options - Optional protocols / headers, see {@link ClientWebSocketOptions}
91
+ * @param url - Absolute WebSocket URL (`ws://` or `wss://`).
92
+ * @param options - Optional sub-protocols / headers; see {@link ClientWebSocketOptions}.
80
93
  */
81
94
  constructor(url: string, options?: ClientWebSocketOptions);
82
95
  /**
83
96
  * Current connection state, mirroring {@link WebSocket.readyState}.
84
97
  *
85
- * @returns `0` connecting, `1` open, `2` closing, `3` closed.
98
+ * @returns `0` connecting · `1` open · `2` closing · `3` closed.
86
99
  */
87
100
  get readyState(): number;
88
101
  /**
89
102
  * Send a payload to the server.
90
103
  *
91
- * @param data - WHATWG-compatible payload
104
+ * @param data - WHATWG-compatible payload.
92
105
  */
93
106
  send(data: string | ArrayBufferLike | Blob | ArrayBufferView): void;
94
107
  /**
95
108
  * Close the underlying socket.
96
109
  *
97
- * @param code - Close code (defaults to 1000)
98
- * @param reason - Optional human-readable reason
110
+ * @param code - Close code (defaults to `1000`).
111
+ * @param reason - Optional human-readable reason phrase.
99
112
  */
100
113
  close(code?: number, reason?: string): void;
101
114
  /**
package/dist/client.d.mts CHANGED
@@ -2,14 +2,24 @@ import { ClientWebSocketOptions } from "./types.mjs";
2
2
 
3
3
  //#region src/client.d.ts
4
4
  /**
5
- * Resolve the best `WebSocket` constructor for the current runtime.
5
+ * Resolve the `WebSocket` constructor from the current runtime's global scope.
6
6
  *
7
7
  * @remarks
8
- * - Bun, Deno, browsers and Node ≥ 22 expose `globalThis.WebSocket`.
9
- * - Older Node falls back to the [`ws`](https://github.com/websockets/ws)
10
- * package, which mirrors the WHATWG `WebSocket` API.
8
+ * Every supported runtime exposes a WHATWG-compliant `WebSocket` natively:
11
9
  *
12
- * @returns A `WebSocket` constructor compatible with the WHATWG interface.
10
+ * | Runtime | Available since |
11
+ * |---------------|-----------------|
12
+ * | Browsers | always |
13
+ * | Bun | always |
14
+ * | Deno | v1.4 |
15
+ * | Node.js | v22 (stable) |
16
+ *
17
+ * If `globalThis.WebSocket` is not present (e.g. Node.js < 22 without a
18
+ * polyfill), this function throws with a descriptive message instead of
19
+ * silently falling back to a third-party package.
20
+ *
21
+ * @returns The global `WebSocket` constructor.
22
+ * @throws {Error} When no native `WebSocket` is available in the current runtime.
13
23
  *
14
24
  * @example
15
25
  * ```ts
@@ -21,18 +31,20 @@ import { ClientWebSocketOptions } from "./types.mjs";
21
31
  */
22
32
  declare function resolveWebSocket(): typeof WebSocket;
23
33
  /**
24
- * Create a `WebSocket` instance using the best available implementation
25
- * for the current runtime.
34
+ * Create a `WebSocket` instance using the runtime's native `globalThis.WebSocket`.
26
35
  *
27
36
  * @remarks
28
- * Custom request headers are honoured on Node via the `ws` package; on
29
- * runtimes that ship a WHATWG-compliant global `WebSocket` (Bun, Deno,
30
- * browsers, Node 22) headers are ignored — matching standard semantics.
37
+ * Custom request headers are only honoured on runtimes that expose them via
38
+ * the second constructor argument (e.g. Bun). On browsers and other
39
+ * WHATWG-strict environments, `options.headers` is silently ignored —
40
+ * matching standard WebSocket semantics.
31
41
  *
32
- * @param url - Absolute WebSocket URL (`ws://` or `wss://`)
33
- * @param options - Optional protocols / headers
42
+ * @param url - Absolute WebSocket URL (`ws://` or `wss://`).
43
+ * @param options - Optional sub-protocols and headers, see {@link ClientWebSocketOptions}.
34
44
  * @returns A connected (or connecting) `WebSocket` instance.
35
45
  *
46
+ * @throws {Error} When no native `WebSocket` is available in the current runtime.
47
+ *
36
48
  * @example
37
49
  * ```ts
38
50
  * import { createWebSocket } from "@hedystia/ws/client";
@@ -42,26 +54,27 @@ declare function resolveWebSocket(): typeof WebSocket;
42
54
  * headers: { authorization: "Bearer ..." },
43
55
  * });
44
56
  *
45
- * ws.onopen = () => ws.send("hi");
57
+ * ws.onopen = () => ws.send("hi");
46
58
  * ws.onmessage = (event) => console.log(event.data);
47
59
  * ```
48
60
  */
49
61
  declare function createWebSocket(url: string, options?: ClientWebSocketOptions): WebSocket;
50
62
  /**
51
63
  * Lightweight runtime-agnostic wrapper that mirrors a small, predictable
52
- * subset of the WHATWG WebSocket interface.
64
+ * subset of the WHATWG `WebSocket` interface.
53
65
  *
54
66
  * @remarks
55
67
  * Useful for higher-level code that wants to assign event handlers by
56
- * property (`socket.onmessage = ...`) without caring whether the underlying
57
- * implementation comes from `globalThis.WebSocket` or the `ws` package.
68
+ * property (`socket.onmessage = …`) without referencing the global
69
+ * `WebSocket` type directly. Delegates all operations to the native
70
+ * `WebSocket` produced by {@link createWebSocket}.
58
71
  *
59
72
  * @example
60
73
  * ```ts
61
74
  * import { WebSocketClient } from "@hedystia/ws/client";
62
75
  *
63
76
  * const client = new WebSocketClient("ws://localhost:3000");
64
- * client.onopen = () => client.send("hello");
77
+ * client.onopen = () => client.send("hello");
65
78
  * client.onmessage = (event) => console.log(event.data);
66
79
  * ```
67
80
  */
@@ -75,27 +88,27 @@ declare class WebSocketClient {
75
88
  /**
76
89
  * Create a new client and immediately initiate the connection.
77
90
  *
78
- * @param url - Absolute WebSocket URL (`ws://` or `wss://`)
79
- * @param options - Optional protocols / headers, see {@link ClientWebSocketOptions}
91
+ * @param url - Absolute WebSocket URL (`ws://` or `wss://`).
92
+ * @param options - Optional sub-protocols / headers; see {@link ClientWebSocketOptions}.
80
93
  */
81
94
  constructor(url: string, options?: ClientWebSocketOptions);
82
95
  /**
83
96
  * Current connection state, mirroring {@link WebSocket.readyState}.
84
97
  *
85
- * @returns `0` connecting, `1` open, `2` closing, `3` closed.
98
+ * @returns `0` connecting · `1` open · `2` closing · `3` closed.
86
99
  */
87
100
  get readyState(): number;
88
101
  /**
89
102
  * Send a payload to the server.
90
103
  *
91
- * @param data - WHATWG-compatible payload
104
+ * @param data - WHATWG-compatible payload.
92
105
  */
93
106
  send(data: string | ArrayBufferLike | Blob | ArrayBufferView): void;
94
107
  /**
95
108
  * Close the underlying socket.
96
109
  *
97
- * @param code - Close code (defaults to 1000)
98
- * @param reason - Optional human-readable reason
110
+ * @param code - Close code (defaults to `1000`).
111
+ * @param reason - Optional human-readable reason phrase.
99
112
  */
100
113
  close(code?: number, reason?: string): void;
101
114
  /**
package/dist/client.mjs CHANGED
@@ -1,14 +1,23 @@
1
- import { __require } from "./_virtual/_rolldown/runtime.mjs";
2
1
  //#region src/client.ts
3
2
  /**
4
- * Resolve the best `WebSocket` constructor for the current runtime.
3
+ * Resolve the `WebSocket` constructor from the current runtime's global scope.
5
4
  *
6
5
  * @remarks
7
- * - Bun, Deno, browsers and Node ≥ 22 expose `globalThis.WebSocket`.
8
- * - Older Node falls back to the [`ws`](https://github.com/websockets/ws)
9
- * package, which mirrors the WHATWG `WebSocket` API.
6
+ * Every supported runtime exposes a WHATWG-compliant `WebSocket` natively:
10
7
  *
11
- * @returns A `WebSocket` constructor compatible with the WHATWG interface.
8
+ * | Runtime | Available since |
9
+ * |---------------|-----------------|
10
+ * | Browsers | always |
11
+ * | Bun | always |
12
+ * | Deno | v1.4 |
13
+ * | Node.js | v22 (stable) |
14
+ *
15
+ * If `globalThis.WebSocket` is not present (e.g. Node.js < 22 without a
16
+ * polyfill), this function throws with a descriptive message instead of
17
+ * silently falling back to a third-party package.
18
+ *
19
+ * @returns The global `WebSocket` constructor.
20
+ * @throws {Error} When no native `WebSocket` is available in the current runtime.
12
21
  *
13
22
  * @example
14
23
  * ```ts
@@ -20,22 +29,23 @@ import { __require } from "./_virtual/_rolldown/runtime.mjs";
20
29
  */
21
30
  function resolveWebSocket() {
22
31
  if (typeof globalThis !== "undefined" && globalThis.WebSocket) return globalThis.WebSocket;
23
- const mod = __require("ws");
24
- return mod.WebSocket ?? mod;
32
+ throw new Error("@hedystia/ws: no native WebSocket found in globalThis. Ensure you are running Bun, Deno, a modern browser, or Node.js ≥ 22.");
25
33
  }
26
34
  /**
27
- * Create a `WebSocket` instance using the best available implementation
28
- * for the current runtime.
35
+ * Create a `WebSocket` instance using the runtime's native `globalThis.WebSocket`.
29
36
  *
30
37
  * @remarks
31
- * Custom request headers are honoured on Node via the `ws` package; on
32
- * runtimes that ship a WHATWG-compliant global `WebSocket` (Bun, Deno,
33
- * browsers, Node 22) headers are ignored — matching standard semantics.
38
+ * Custom request headers are only honoured on runtimes that expose them via
39
+ * the second constructor argument (e.g. Bun). On browsers and other
40
+ * WHATWG-strict environments, `options.headers` is silently ignored —
41
+ * matching standard WebSocket semantics.
34
42
  *
35
- * @param url - Absolute WebSocket URL (`ws://` or `wss://`)
36
- * @param options - Optional protocols / headers
43
+ * @param url - Absolute WebSocket URL (`ws://` or `wss://`).
44
+ * @param options - Optional sub-protocols and headers, see {@link ClientWebSocketOptions}.
37
45
  * @returns A connected (or connecting) `WebSocket` instance.
38
46
  *
47
+ * @throws {Error} When no native `WebSocket` is available in the current runtime.
48
+ *
39
49
  * @example
40
50
  * ```ts
41
51
  * import { createWebSocket } from "@hedystia/ws/client";
@@ -45,32 +55,31 @@ function resolveWebSocket() {
45
55
  * headers: { authorization: "Bearer ..." },
46
56
  * });
47
57
  *
48
- * ws.onopen = () => ws.send("hi");
58
+ * ws.onopen = () => ws.send("hi");
49
59
  * ws.onmessage = (event) => console.log(event.data);
50
60
  * ```
51
61
  */
52
62
  function createWebSocket(url, options) {
53
63
  const Ctor = resolveWebSocket();
54
- if (typeof globalThis !== "undefined" && globalThis.WebSocket === Ctor) return options?.protocols ? new Ctor(url, options.protocols) : new Ctor(url);
55
- const init = {};
56
- if (options?.headers) init.headers = options.headers;
57
- return new Ctor(url, options?.protocols, init);
64
+ if (options?.protocols) return new Ctor(url, options.protocols);
65
+ return new Ctor(url);
58
66
  }
59
67
  /**
60
68
  * Lightweight runtime-agnostic wrapper that mirrors a small, predictable
61
- * subset of the WHATWG WebSocket interface.
69
+ * subset of the WHATWG `WebSocket` interface.
62
70
  *
63
71
  * @remarks
64
72
  * Useful for higher-level code that wants to assign event handlers by
65
- * property (`socket.onmessage = ...`) without caring whether the underlying
66
- * implementation comes from `globalThis.WebSocket` or the `ws` package.
73
+ * property (`socket.onmessage = …`) without referencing the global
74
+ * `WebSocket` type directly. Delegates all operations to the native
75
+ * `WebSocket` produced by {@link createWebSocket}.
67
76
  *
68
77
  * @example
69
78
  * ```ts
70
79
  * import { WebSocketClient } from "@hedystia/ws/client";
71
80
  *
72
81
  * const client = new WebSocketClient("ws://localhost:3000");
73
- * client.onopen = () => client.send("hello");
82
+ * client.onopen = () => client.send("hello");
74
83
  * client.onmessage = (event) => console.log(event.data);
75
84
  * ```
76
85
  */
@@ -84,8 +93,8 @@ var WebSocketClient = class {
84
93
  /**
85
94
  * Create a new client and immediately initiate the connection.
86
95
  *
87
- * @param url - Absolute WebSocket URL (`ws://` or `wss://`)
88
- * @param options - Optional protocols / headers, see {@link ClientWebSocketOptions}
96
+ * @param url - Absolute WebSocket URL (`ws://` or `wss://`).
97
+ * @param options - Optional sub-protocols / headers; see {@link ClientWebSocketOptions}.
89
98
  */
90
99
  constructor(url, options) {
91
100
  this.socket = createWebSocket(url, options);
@@ -93,7 +102,7 @@ var WebSocketClient = class {
93
102
  /**
94
103
  * Current connection state, mirroring {@link WebSocket.readyState}.
95
104
  *
96
- * @returns `0` connecting, `1` open, `2` closing, `3` closed.
105
+ * @returns `0` connecting · `1` open · `2` closing · `3` closed.
97
106
  */
98
107
  get readyState() {
99
108
  return this.socket.readyState;
@@ -101,7 +110,7 @@ var WebSocketClient = class {
101
110
  /**
102
111
  * Send a payload to the server.
103
112
  *
104
- * @param data - WHATWG-compatible payload
113
+ * @param data - WHATWG-compatible payload.
105
114
  */
106
115
  send(data) {
107
116
  this.socket.send(data);
@@ -109,8 +118,8 @@ var WebSocketClient = class {
109
118
  /**
110
119
  * Close the underlying socket.
111
120
  *
112
- * @param code - Close code (defaults to 1000)
113
- * @param reason - Optional human-readable reason
121
+ * @param code - Close code (defaults to `1000`).
122
+ * @param reason - Optional human-readable reason phrase.
114
123
  */
115
124
  close(code, reason) {
116
125
  this.socket.close(code, reason);
@@ -1 +1 @@
1
- {"version":3,"file":"client.mjs","names":[],"sources":["../src/client.ts"],"sourcesContent":["import type { ClientWebSocketOptions } from \"./types\";\n\nexport type { ClientWebSocketOptions } from \"./types\";\n\n/**\n * Resolve the best `WebSocket` constructor for the current runtime.\n *\n * @remarks\n * - Bun, Deno, browsers and Node 22 expose `globalThis.WebSocket`.\n * - Older Node falls back to the [`ws`](https://github.com/websockets/ws)\n * package, which mirrors the WHATWG `WebSocket` API.\n *\n * @returns A `WebSocket` constructor compatible with the WHATWG interface.\n *\n * @example\n * ```ts\n * import { resolveWebSocket } from \"@hedystia/ws/client\";\n *\n * const WS = resolveWebSocket();\n * const socket = new WS(\"ws://localhost:3000\");\n * ```\n */\nexport function resolveWebSocket(): typeof WebSocket {\n if (typeof globalThis !== \"undefined\" && (globalThis as any).WebSocket) {\n return (globalThis as any).WebSocket as typeof WebSocket;\n }\n const mod = require(\"ws\");\n return (mod.WebSocket ?? mod) as typeof WebSocket;\n}\n\n/**\n * Create a `WebSocket` instance using the best available implementation\n * for the current runtime.\n *\n * @remarks\n * Custom request headers are honoured on Node via the `ws` package; on\n * runtimes that ship a WHATWG-compliant global `WebSocket` (Bun, Deno,\n * browsers, Node 22) headers are ignored matching standard semantics.\n *\n * @param url - Absolute WebSocket URL (`ws://` or `wss://`)\n * @param options - Optional protocols / headers\n * @returns A connected (or connecting) `WebSocket` instance.\n *\n * @example\n * ```ts\n * import { createWebSocket } from \"@hedystia/ws/client\";\n *\n * const ws = createWebSocket(\"ws://localhost:3000\", {\n * protocols: \"v1\",\n * headers: { authorization: \"Bearer ...\" },\n * });\n *\n * ws.onopen = () => ws.send(\"hi\");\n * ws.onmessage = (event) => console.log(event.data);\n * ```\n */\nexport function createWebSocket(url: string, options?: ClientWebSocketOptions): WebSocket {\n const Ctor = resolveWebSocket();\n const isWhatwg =\n typeof globalThis !== \"undefined\" && (globalThis as any).WebSocket === (Ctor as any);\n\n if (isWhatwg) {\n return options?.protocols ? new Ctor(url, options.protocols as any) : new Ctor(url);\n }\n\n const init: any = {};\n if (options?.headers) {\n init.headers = options.headers;\n }\n return new (Ctor as any)(url, options?.protocols, init);\n}\n\n/**\n * Lightweight runtime-agnostic wrapper that mirrors a small, predictable\n * subset of the WHATWG WebSocket interface.\n *\n * @remarks\n * Useful for higher-level code that wants to assign event handlers by\n * property (`socket.onmessage = ...`) without caring whether the underlying\n * implementation comes from `globalThis.WebSocket` or the `ws` package.\n *\n * @example\n * ```ts\n * import { WebSocketClient } from \"@hedystia/ws/client\";\n *\n * const client = new WebSocketClient(\"ws://localhost:3000\");\n * client.onopen = () => client.send(\"hello\");\n * client.onmessage = (event) => console.log(event.data);\n * ```\n */\nexport class WebSocketClient {\n /**\n * Underlying WebSocket instance produced by {@link createWebSocket}.\n *\n * @readonly\n */\n readonly socket: WebSocket;\n\n /**\n * Create a new client and immediately initiate the connection.\n *\n * @param url - Absolute WebSocket URL (`ws://` or `wss://`)\n * @param options - Optional protocols / headers, see {@link ClientWebSocketOptions}\n */\n constructor(url: string, options?: ClientWebSocketOptions) {\n this.socket = createWebSocket(url, options);\n }\n\n /**\n * Current connection state, mirroring {@link WebSocket.readyState}.\n *\n * @returns `0` connecting, `1` open, `2` closing, `3` closed.\n */\n get readyState(): number {\n return this.socket.readyState;\n }\n\n /**\n * Send a payload to the server.\n *\n * @param data - WHATWG-compatible payload\n */\n send(data: string | ArrayBufferLike | Blob | ArrayBufferView): void {\n this.socket.send(data as any);\n }\n\n /**\n * Close the underlying socket.\n *\n * @param code - Close code (defaults to 1000)\n * @param reason - Optional human-readable reason\n */\n close(code?: number, reason?: string): void {\n this.socket.close(code, reason);\n }\n\n /**\n * Assign the open-event listener.\n */\n set onopen(cb: ((ev: Event) => void) | null) {\n (this.socket as any).onopen = cb;\n }\n /**\n * Assign the message-event listener.\n */\n set onmessage(cb: ((ev: MessageEvent) => void) | null) {\n (this.socket as any).onmessage = cb;\n }\n /**\n * Assign the close-event listener.\n */\n set onclose(cb: ((ev: CloseEvent) => void) | null) {\n (this.socket as any).onclose = cb;\n }\n /**\n * Assign the error-event listener.\n */\n set onerror(cb: ((ev: Event) => void) | null) {\n (this.socket as any).onerror = cb;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAsBA,SAAgB,mBAAqC;CACnD,IAAI,OAAO,eAAe,eAAgB,WAAmB,WAC3D,OAAQ,WAAmB;CAE7B,MAAM,MAAA,UAAc,KAAK;CACzB,OAAQ,IAAI,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6B3B,SAAgB,gBAAgB,KAAa,SAA6C;CACxF,MAAM,OAAO,kBAAkB;CAI/B,IAFE,OAAO,eAAe,eAAgB,WAAmB,cAAe,MAGxE,OAAO,SAAS,YAAY,IAAI,KAAK,KAAK,QAAQ,UAAiB,GAAG,IAAI,KAAK,IAAI;CAGrF,MAAM,OAAY,EAAE;CACpB,IAAI,SAAS,SACX,KAAK,UAAU,QAAQ;CAEzB,OAAO,IAAK,KAAa,KAAK,SAAS,WAAW,KAAK;;;;;;;;;;;;;;;;;;;;AAqBzD,IAAa,kBAAb,MAA6B;;;;;;CAM3B;;;;;;;CAQA,YAAY,KAAa,SAAkC;EACzD,KAAK,SAAS,gBAAgB,KAAK,QAAQ;;;;;;;CAQ7C,IAAI,aAAqB;EACvB,OAAO,KAAK,OAAO;;;;;;;CAQrB,KAAK,MAA+D;EAClE,KAAK,OAAO,KAAK,KAAY;;;;;;;;CAS/B,MAAM,MAAe,QAAuB;EAC1C,KAAK,OAAO,MAAM,MAAM,OAAO;;;;;CAMjC,IAAI,OAAO,IAAkC;EAC3C,KAAM,OAAe,SAAS;;;;;CAKhC,IAAI,UAAU,IAAyC;EACrD,KAAM,OAAe,YAAY;;;;;CAKnC,IAAI,QAAQ,IAAuC;EACjD,KAAM,OAAe,UAAU;;;;;CAKjC,IAAI,QAAQ,IAAkC;EAC5C,KAAM,OAAe,UAAU"}
1
+ {"version":3,"file":"client.mjs","names":[],"sources":["../src/client.ts"],"sourcesContent":["import type { ClientWebSocketOptions } from \"./types\";\n\nexport type { ClientWebSocketOptions } from \"./types\";\n\n/**\n * Resolve the `WebSocket` constructor from the current runtime's global scope.\n *\n * @remarks\n * Every supported runtime exposes a WHATWG-compliant `WebSocket` natively:\n *\n * | Runtime | Available since |\n * |---------------|-----------------|\n * | Browsers | always |\n * | Bun | always |\n * | Deno | v1.4 |\n * | Node.js | v22 (stable) |\n *\n * If `globalThis.WebSocket` is not present (e.g. Node.js < 22 without a\n * polyfill), this function throws with a descriptive message instead of\n * silently falling back to a third-party package.\n *\n * @returns The global `WebSocket` constructor.\n * @throws {Error} When no native `WebSocket` is available in the current runtime.\n *\n * @example\n * ```ts\n * import { resolveWebSocket } from \"@hedystia/ws/client\";\n *\n * const WS = resolveWebSocket();\n * const socket = new WS(\"ws://localhost:3000\");\n * ```\n */\nexport function resolveWebSocket(): typeof WebSocket {\n if (typeof globalThis !== \"undefined\" && (globalThis as any).WebSocket) {\n return (globalThis as any).WebSocket as typeof WebSocket;\n }\n throw new Error(\n \"@hedystia/ws: no native WebSocket found in globalThis. \" +\n \"Ensure you are running Bun, Deno, a modern browser, or Node.js ≥ 22.\",\n );\n}\n\n/**\n * Create a `WebSocket` instance using the runtime's native `globalThis.WebSocket`.\n *\n * @remarks\n * Custom request headers are only honoured on runtimes that expose them via\n * the second constructor argument (e.g. Bun). On browsers and other\n * WHATWG-strict environments, `options.headers` is silently ignored —\n * matching standard WebSocket semantics.\n *\n * @param url - Absolute WebSocket URL (`ws://` or `wss://`).\n * @param options - Optional sub-protocols and headers, see {@link ClientWebSocketOptions}.\n * @returns A connected (or connecting) `WebSocket` instance.\n *\n * @throws {Error} When no native `WebSocket` is available in the current runtime.\n *\n * @example\n * ```ts\n * import { createWebSocket } from \"@hedystia/ws/client\";\n *\n * const ws = createWebSocket(\"ws://localhost:3000\", {\n * protocols: \"v1\",\n * headers: { authorization: \"Bearer ...\" },\n * });\n *\n * ws.onopen = () => ws.send(\"hi\");\n * ws.onmessage = (event) => console.log(event.data);\n * ```\n */\nexport function createWebSocket(url: string, options?: ClientWebSocketOptions): WebSocket {\n const Ctor = resolveWebSocket();\n\n if (options?.protocols) {\n return new Ctor(url, options.protocols as any);\n }\n return new Ctor(url);\n}\n\n/**\n * Lightweight runtime-agnostic wrapper that mirrors a small, predictable\n * subset of the WHATWG `WebSocket` interface.\n *\n * @remarks\n * Useful for higher-level code that wants to assign event handlers by\n * property (`socket.onmessage = …`) without referencing the global\n * `WebSocket` type directly. Delegates all operations to the native\n * `WebSocket` produced by {@link createWebSocket}.\n *\n * @example\n * ```ts\n * import { WebSocketClient } from \"@hedystia/ws/client\";\n *\n * const client = new WebSocketClient(\"ws://localhost:3000\");\n * client.onopen = () => client.send(\"hello\");\n * client.onmessage = (event) => console.log(event.data);\n * ```\n */\nexport class WebSocketClient {\n /**\n * Underlying WebSocket instance produced by {@link createWebSocket}.\n *\n * @readonly\n */\n readonly socket: WebSocket;\n\n /**\n * Create a new client and immediately initiate the connection.\n *\n * @param url - Absolute WebSocket URL (`ws://` or `wss://`).\n * @param options - Optional sub-protocols / headers; see {@link ClientWebSocketOptions}.\n */\n constructor(url: string, options?: ClientWebSocketOptions) {\n this.socket = createWebSocket(url, options);\n }\n\n /**\n * Current connection state, mirroring {@link WebSocket.readyState}.\n *\n * @returns `0` connecting · `1` open · `2` closing · `3` closed.\n */\n get readyState(): number {\n return this.socket.readyState;\n }\n\n /**\n * Send a payload to the server.\n *\n * @param data - WHATWG-compatible payload.\n */\n send(data: string | ArrayBufferLike | Blob | ArrayBufferView): void {\n this.socket.send(data as any);\n }\n\n /**\n * Close the underlying socket.\n *\n * @param code - Close code (defaults to `1000`).\n * @param reason - Optional human-readable reason phrase.\n */\n close(code?: number, reason?: string): void {\n this.socket.close(code, reason);\n }\n\n /**\n * Assign the open-event listener.\n */\n set onopen(cb: ((ev: Event) => void) | null) {\n (this.socket as any).onopen = cb;\n }\n\n /**\n * Assign the message-event listener.\n */\n set onmessage(cb: ((ev: MessageEvent) => void) | null) {\n (this.socket as any).onmessage = cb;\n }\n\n /**\n * Assign the close-event listener.\n */\n set onclose(cb: ((ev: CloseEvent) => void) | null) {\n (this.socket as any).onclose = cb;\n }\n\n /**\n * Assign the error-event listener.\n */\n set onerror(cb: ((ev: Event) => void) | null) {\n (this.socket as any).onerror = cb;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,SAAgB,mBAAqC;CACnD,IAAI,OAAO,eAAe,eAAgB,WAAmB,WAC3D,OAAQ,WAAmB;CAE7B,MAAM,IAAI,MACR,8HAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BH,SAAgB,gBAAgB,KAAa,SAA6C;CACxF,MAAM,OAAO,kBAAkB;CAE/B,IAAI,SAAS,WACX,OAAO,IAAI,KAAK,KAAK,QAAQ,UAAiB;CAEhD,OAAO,IAAI,KAAK,IAAI;;;;;;;;;;;;;;;;;;;;;AAsBtB,IAAa,kBAAb,MAA6B;;;;;;CAM3B;;;;;;;CAQA,YAAY,KAAa,SAAkC;EACzD,KAAK,SAAS,gBAAgB,KAAK,QAAQ;;;;;;;CAQ7C,IAAI,aAAqB;EACvB,OAAO,KAAK,OAAO;;;;;;;CAQrB,KAAK,MAA+D;EAClE,KAAK,OAAO,KAAK,KAAY;;;;;;;;CAS/B,MAAM,MAAe,QAAuB;EAC1C,KAAK,OAAO,MAAM,MAAM,OAAO;;;;;CAMjC,IAAI,OAAO,IAAkC;EAC3C,KAAM,OAAe,SAAS;;;;;CAMhC,IAAI,UAAU,IAAyC;EACrD,KAAM,OAAe,YAAY;;;;;CAMnC,IAAI,QAAQ,IAAuC;EACjD,KAAM,OAAe,UAAU;;;;;CAMjC,IAAI,QAAQ,IAAkC;EAC5C,KAAM,OAAe,UAAU"}
package/dist/index.cjs CHANGED
@@ -18,5 +18,6 @@ exports.isBun = require_runtime.isBun;
18
18
  exports.isDeno = require_runtime.isDeno;
19
19
  exports.isNode = require_runtime.isNode;
20
20
  exports.resolveWebSocket = require_client.resolveWebSocket;
21
+ exports.serve = require_server.serve;
21
22
 
22
23
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["WebSocketServer"],"sources":["../src/index.ts"],"sourcesContent":["export type { ClientWebSocketOptions } from \"./client\";\nexport { createWebSocket, resolveWebSocket, WebSocketClient } from \"./client\";\nexport type { Runtime } from \"./runtime\";\nexport { detectRuntime, isBrowser, isBun, isDeno, isNode } from \"./runtime\";\nexport type {\n ServerWebSocket,\n UpgradeOptions,\n UpgradeRequest,\n WebSocketHandlers,\n WebSocketServerOptions,\n WSData,\n WSMessage,\n} from \"./server\";\n\nimport { WebSocketServer } from \"./server\";\n\nexport { WebSocketServer };\n\nexport default WebSocketServer;\n"],"mappings":";;;;;;;;AAkBA,IAAA,cAAeA,eAAAA"}
1
+ {"version":3,"file":"index.cjs","names":["WebSocketServer"],"sources":["../src/index.ts"],"sourcesContent":["export type { ClientWebSocketOptions } from \"./client\";\nexport { createWebSocket, resolveWebSocket, WebSocketClient } from \"./client\";\nexport type { Runtime } from \"./runtime\";\nexport { detectRuntime, isBrowser, isBun, isDeno, isNode } from \"./runtime\";\nexport type {\n ServeInfo,\n ServerWebSocket,\n UpgradeOptions,\n UpgradeRequest,\n WebSocketHandlers,\n WebSocketServerOptions,\n WSData,\n WSMessage,\n} from \"./server\";\n\nimport { serve, WebSocketServer } from \"./server\";\n\nexport { serve, WebSocketServer };\n\nexport default WebSocketServer;\n"],"mappings":";;;;;;;;AAmBA,IAAA,cAAeA,eAAAA"}
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { ClientWebSocketOptions, ServerWebSocket, UpgradeOptions, UpgradeRequest, WSData, WSMessage, WebSocketHandlers, WebSocketServerOptions } from "./types.cjs";
2
2
  import { WebSocketClient, createWebSocket, resolveWebSocket } from "./client.cjs";
3
3
  import { Runtime, detectRuntime, isBrowser, isBun, isDeno, isNode } from "./runtime.cjs";
4
- import { WebSocketServer } from "./server.cjs";
5
- export { type ClientWebSocketOptions, type Runtime, type ServerWebSocket, type UpgradeOptions, type UpgradeRequest, type WSData, type WSMessage, WebSocketClient, type WebSocketHandlers, WebSocketServer, WebSocketServer as default, type WebSocketServerOptions, createWebSocket, detectRuntime, isBrowser, isBun, isDeno, isNode, resolveWebSocket };
4
+ import { ServeInfo, WebSocketServer, serve } from "./server.cjs";
5
+ export { type ClientWebSocketOptions, type Runtime, type ServeInfo, type ServerWebSocket, type UpgradeOptions, type UpgradeRequest, type WSData, type WSMessage, WebSocketClient, type WebSocketHandlers, WebSocketServer, WebSocketServer as default, type WebSocketServerOptions, createWebSocket, detectRuntime, isBrowser, isBun, isDeno, isNode, resolveWebSocket, serve };