@hyperdrive.bot/paseo-client 0.2.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.
@@ -0,0 +1,120 @@
1
+ export function defaultWebSocketFactory(url, options) {
2
+ const globalWs = globalThis.WebSocket;
3
+ if (!globalWs) {
4
+ throw new Error("WebSocket is not available in this runtime");
5
+ }
6
+ return new globalWs(url, options?.protocols);
7
+ }
8
+ export function createWebSocketTransportFactory(factory) {
9
+ return ({ url, headers, protocols }) => {
10
+ const ws = factory(url, { headers, protocols });
11
+ if ("binaryType" in ws) {
12
+ try {
13
+ ws.binaryType = "arraybuffer";
14
+ }
15
+ catch {
16
+ // no-op
17
+ }
18
+ }
19
+ return {
20
+ send: (data) => {
21
+ if (typeof ws.readyState === "number" && ws.readyState !== 1) {
22
+ throw new Error(`WebSocket not open (readyState=${ws.readyState})`);
23
+ }
24
+ ws.send(data);
25
+ },
26
+ close: (code, reason) => {
27
+ // Node's `ws` may emit an `error` when a connecting socket is closed before the
28
+ // handshake completes. Keep a temporary no-op handler attached so cleanup during
29
+ // connect timeouts does not crash the CLI with an unhandled error event.
30
+ const suppressEarlyCloseError = bindTemporaryEarlyCloseErrorHandler(ws);
31
+ try {
32
+ ws.close(code, reason);
33
+ }
34
+ finally {
35
+ if (typeof ws.on !== "function" && typeof ws.addEventListener !== "function") {
36
+ suppressEarlyCloseError();
37
+ }
38
+ }
39
+ },
40
+ onOpen: (handler) => bindWsHandler(ws, "open", handler),
41
+ onClose: (handler) => bindWsHandler(ws, "close", handler),
42
+ onError: (handler) => bindWsHandler(ws, "error", handler),
43
+ onMessage: (handler) => bindWsHandler(ws, "message", handler),
44
+ };
45
+ };
46
+ }
47
+ function bindTemporaryEarlyCloseErrorHandler(ws) {
48
+ const noop = () => { };
49
+ if (typeof ws.addEventListener === "function") {
50
+ ws.addEventListener("error", noop);
51
+ const removeOnClose = bindWsHandler(ws, "close", () => {
52
+ removeOnClose();
53
+ if (typeof ws.removeEventListener === "function") {
54
+ ws.removeEventListener("error", noop);
55
+ }
56
+ });
57
+ return () => {
58
+ removeOnClose();
59
+ if (typeof ws.removeEventListener === "function") {
60
+ ws.removeEventListener("error", noop);
61
+ }
62
+ };
63
+ }
64
+ if (typeof ws.on === "function") {
65
+ ws.on("error", noop);
66
+ const removeOnClose = bindWsHandler(ws, "close", () => {
67
+ removeOnClose();
68
+ if (typeof ws.off === "function") {
69
+ ws.off("error", noop);
70
+ return;
71
+ }
72
+ if (typeof ws.removeListener === "function") {
73
+ ws.removeListener("error", noop);
74
+ }
75
+ });
76
+ return () => {
77
+ removeOnClose();
78
+ if (typeof ws.off === "function") {
79
+ ws.off("error", noop);
80
+ return;
81
+ }
82
+ if (typeof ws.removeListener === "function") {
83
+ ws.removeListener("error", noop);
84
+ }
85
+ };
86
+ }
87
+ return () => { };
88
+ }
89
+ export function bindWsHandler(ws, event, handler) {
90
+ if (typeof ws.addEventListener === "function") {
91
+ ws.addEventListener(event, handler);
92
+ return () => {
93
+ if (typeof ws.removeEventListener === "function") {
94
+ ws.removeEventListener(event, handler);
95
+ }
96
+ };
97
+ }
98
+ if (typeof ws.on === "function") {
99
+ ws.on(event, handler);
100
+ return () => {
101
+ if (typeof ws.off === "function") {
102
+ ws.off(event, handler);
103
+ return;
104
+ }
105
+ if (typeof ws.removeListener === "function") {
106
+ ws.removeListener(event, handler);
107
+ }
108
+ };
109
+ }
110
+ const prop = `on${event}`;
111
+ const wsRecord = ws;
112
+ const previous = wsRecord[prop];
113
+ wsRecord[prop] = handler;
114
+ return () => {
115
+ if (wsRecord[prop] === handler) {
116
+ wsRecord[prop] = previous ?? null;
117
+ }
118
+ };
119
+ }
120
+ //# sourceMappingURL=daemon-client-websocket-transport.js.map