snapreq 0.0.1 → 0.0.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.
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Full-featured transport backed by Node's `http`/`https` modules. Supports
3
+ * Unix sockets, client TLS, keep-alive, request-body compression, response
4
+ * decompression and streaming. The `node:*` modules are loaded with a dynamic
5
+ * `import()` so this file never has to be bundled by web/Expo bundlers — the
6
+ * transport selector only imports it when running on Node.
7
+ */
8
+ export default class NodeTransport {
9
+ /** @returns {string} - Transport name. */
10
+ static get transportName(): string;
11
+ /** @returns {boolean} - Whether this transport can run in the current environment. */
12
+ static isAvailable(): boolean;
13
+ /**
14
+ * @param {object} [config] - Transport configuration.
15
+ * @param {string} [config.socketPath] - Unix domain socket path.
16
+ * @param {{ca?: string | Buffer, cert?: string | Buffer, key?: string | Buffer, rejectUnauthorized?: boolean}} [config.tls] - TLS material for HTTPS connections.
17
+ * @param {boolean} [config.keepAlive] - Reuse connections across requests. Defaults to true.
18
+ */
19
+ constructor({ socketPath, tls, keepAlive }?: {
20
+ socketPath?: string;
21
+ tls?: {
22
+ ca?: string | Buffer;
23
+ cert?: string | Buffer;
24
+ key?: string | Buffer;
25
+ rejectUnauthorized?: boolean;
26
+ };
27
+ keepAlive?: boolean;
28
+ });
29
+ socketPath: string;
30
+ tls: {
31
+ ca?: string | Buffer;
32
+ cert?: string | Buffer;
33
+ key?: string | Buffer;
34
+ rejectUnauthorized?: boolean;
35
+ };
36
+ keepAlive: boolean;
37
+ /** @type {{http: any, https: any, zlib: any, stream: any} | null} */
38
+ _modules: {
39
+ http: any;
40
+ https: any;
41
+ zlib: any;
42
+ stream: any;
43
+ } | null;
44
+ /** @type {any} */
45
+ _httpAgent: any;
46
+ /** @type {any} */
47
+ _httpsAgent: any;
48
+ /** @returns {import("../capabilities.js").TransportCapabilities} - Supported capabilities. */
49
+ get capabilities(): import("../capabilities.js").TransportCapabilities;
50
+ /** @returns {Promise<{http: any, https: any, zlib: any, stream: any}>} - Lazily-loaded Node modules. */
51
+ _load(): Promise<{
52
+ http: any;
53
+ https: any;
54
+ zlib: any;
55
+ stream: any;
56
+ }>;
57
+ /**
58
+ * @param {boolean} useTls - Whether the request uses TLS.
59
+ * @returns {any} - The keep-alive agent for the protocol.
60
+ */
61
+ _agent(useTls: boolean): any;
62
+ /**
63
+ * Performs a single request and resolves once the response headers arrive,
64
+ * exposing the (decoded) body as a stream so callers can buffer or stream it.
65
+ * @param {import("../snap-req.js").NormalizedRequest} request - Normalized request.
66
+ * @returns {Promise<SnapReqResponse>} - The response.
67
+ */
68
+ performRequest(request: import("../snap-req.js").NormalizedRequest): Promise<SnapReqResponse>;
69
+ /**
70
+ * @param {import("../snap-req.js").NormalizedRequest} request - Normalized request.
71
+ * @param {SnapReqHeaders} headers - Headers, mutated with Content-Length / Content-Encoding.
72
+ * @param {{zlib: any, stream: any}} modules - Node modules.
73
+ * @returns {{buffer: Buffer | null, stream: import("node:stream").Readable | null}} - Prepared body.
74
+ */
75
+ _prepareRequestBody(request: import("../snap-req.js").NormalizedRequest, headers: SnapReqHeaders, { zlib, stream }: {
76
+ zlib: any;
77
+ stream: any;
78
+ }): {
79
+ buffer: Buffer | null;
80
+ stream: import("node:stream").Readable | null;
81
+ };
82
+ /**
83
+ * @param {string} encoding - Compression encoding.
84
+ * @param {any} zlib - The zlib module.
85
+ * @returns {import("node:stream").Transform} - A compressor transform.
86
+ */
87
+ _requestCompressor(encoding: string, zlib: any): import("node:stream").Transform;
88
+ /**
89
+ * @param {import("node:http").IncomingMessage} response - The raw response.
90
+ * @param {any} zlib - The zlib module.
91
+ * @returns {import("node:stream").Readable} - The decoded response body stream.
92
+ */
93
+ _decodeResponseStream(response: import("node:http").IncomingMessage, zlib: any): import("node:stream").Readable;
94
+ /**
95
+ * @param {string} encoding - Content encoding.
96
+ * @param {any} zlib - The zlib module.
97
+ * @returns {import("node:stream").Transform} - A decompressor transform.
98
+ */
99
+ _responseDecoder(encoding: string, zlib: any): import("node:stream").Transform;
100
+ /**
101
+ * @param {import("node:http").IncomingMessage} response - The raw response.
102
+ * @returns {SnapReqHeaders} - The response headers.
103
+ */
104
+ _responseHeaders(response: import("node:http").IncomingMessage): SnapReqHeaders;
105
+ /**
106
+ * Destroys the keep-alive agents, closing all persistent connections.
107
+ * @returns {void}
108
+ */
109
+ close(): void;
110
+ }
111
+ import SnapReqResponse from "../response.js";
112
+ import SnapReqHeaders from "../headers.js";
@@ -0,0 +1,38 @@
1
+ /**
2
+ * @typedef {"auto" | "node" | "fetch" | "xhr"} TransportName
3
+ */
4
+ /**
5
+ * @typedef {object} Transport
6
+ * @property {import("../capabilities.js").TransportCapabilities} capabilities - Supported capabilities.
7
+ * @property {(request: import("../snap-req.js").NormalizedRequest) => Promise<import("../response.js").default>} performRequest - Perform a request.
8
+ * @property {() => void} [close] - Optional resource cleanup.
9
+ */
10
+ /**
11
+ * Detects the JavaScript runtime so `auto` can pick the right transport.
12
+ * @returns {"node" | "react-native" | "browser" | "unknown"} - Detected runtime.
13
+ */
14
+ export function detectRuntime(): "node" | "react-native" | "browser" | "unknown";
15
+ /**
16
+ * Resolves a transport for the requested preference. Returns the preference
17
+ * untouched when it is already a transport instance. The Node transport is
18
+ * imported dynamically so web/Expo bundlers never pull in `node:*` modules.
19
+ * @param {TransportName | Transport | undefined} preference - Requested transport.
20
+ * @param {object} nodeConfig - Configuration forwarded to the Node transport.
21
+ * @returns {Promise<Transport>} - The resolved transport.
22
+ */
23
+ export function selectTransport(preference: TransportName | Transport | undefined, nodeConfig: object): Promise<Transport>;
24
+ export type TransportName = "auto" | "node" | "fetch" | "xhr";
25
+ export type Transport = {
26
+ /**
27
+ * - Supported capabilities.
28
+ */
29
+ capabilities: import("../capabilities.js").TransportCapabilities;
30
+ /**
31
+ * - Perform a request.
32
+ */
33
+ performRequest: (request: import("../snap-req.js").NormalizedRequest) => Promise<import("../response.js").default>;
34
+ /**
35
+ * - Optional resource cleanup.
36
+ */
37
+ close?: () => void;
38
+ };
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Transport backed by `XMLHttpRequest`. A fallback for web environments that
3
+ * lack `fetch`. Buffers the whole response (no incremental streaming) and, like
4
+ * `fetch`, cannot do Unix sockets, client TLS or request-body compression.
5
+ */
6
+ export default class XhrTransport {
7
+ /** @returns {string} - Transport name. */
8
+ static get transportName(): string;
9
+ /** @returns {boolean} - Whether this transport can run in the current environment. */
10
+ static isAvailable(): boolean;
11
+ /** @returns {import("../capabilities.js").TransportCapabilities} - Supported capabilities. */
12
+ get capabilities(): import("../capabilities.js").TransportCapabilities;
13
+ /**
14
+ * @param {import("../snap-req.js").NormalizedRequest} request - Normalized request.
15
+ * @returns {Promise<SnapReqResponse>} - The response.
16
+ */
17
+ performRequest(request: import("../snap-req.js").NormalizedRequest): Promise<SnapReqResponse>;
18
+ /**
19
+ * @param {string} rawHeaders - Raw header block from `getAllResponseHeaders`.
20
+ * @returns {SnapReqHeaders} - The parsed response headers.
21
+ */
22
+ _parseHeaders(rawHeaders: string): SnapReqHeaders;
23
+ }
24
+ import SnapReqResponse from "../response.js";
25
+ import SnapReqHeaders from "../headers.js";
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Client-side handle for a channel subscription opened via
3
+ * `SnapReqWebSocketClient.subscribeChannel()`. Mirrors the server's
4
+ * subscription lifecycle — `subscribed` (resolves `ready`) / `onMessage` /
5
+ * `onClose`.
6
+ */
7
+ export default class SnapReqWebSocketChannel {
8
+ /**
9
+ * @param {object} args - Channel arguments.
10
+ * @param {import("./websocket-client.js").default} args.client - Owning client.
11
+ * @param {string} args.subscriptionId - Generated id unique within the session.
12
+ * @param {string} args.channelType - Name the server registered the channel under.
13
+ * @param {Record<string, any>} [args.params] - Opaque params forwarded to the server.
14
+ * @param {string} [args.lastEventId] - Resume replay from this event id.
15
+ * @param {(body: any) => void} [args.onMessage] - Fired on each `channel-message` from the server.
16
+ * @param {() => void} [args.onDisconnect] - Fired when the socket drops.
17
+ * @param {() => void} [args.onResume] - Fired when the session resumes after a drop.
18
+ * @param {(reason: string) => void} [args.onClose] - Fired exactly once when the subscription closes permanently.
19
+ */
20
+ constructor({ client, subscriptionId, channelType, params, lastEventId, onMessage, onDisconnect, onResume, onClose }: {
21
+ client: import("./websocket-client.js").default;
22
+ subscriptionId: string;
23
+ channelType: string;
24
+ params?: Record<string, any>;
25
+ lastEventId?: string;
26
+ onMessage?: (body: any) => void;
27
+ onDisconnect?: () => void;
28
+ onResume?: () => void;
29
+ onClose?: (reason: string) => void;
30
+ });
31
+ client: import("./websocket-client.js").default;
32
+ subscriptionId: string;
33
+ channelType: string;
34
+ params: Record<string, any>;
35
+ lastEventId: string;
36
+ _onMessage: (body: any) => void;
37
+ _onDisconnect: () => void;
38
+ _onResume: () => void;
39
+ _onClose: (reason: string) => void;
40
+ _ready: boolean;
41
+ _resumeReadyOnResume: boolean;
42
+ _subscribed: boolean;
43
+ _subscribeSent: boolean;
44
+ _closed: boolean;
45
+ /** @returns {Promise<void>} - Resolves once the subscription is acknowledged. */
46
+ _ensureReadyPromise(): Promise<void>;
47
+ /** @type {Promise<void>} */
48
+ _readyPromise: Promise<void>;
49
+ _resolveReady: (value: void | PromiseLike<void>) => void;
50
+ _rejectReady: (reason?: any) => void;
51
+ /** @returns {Promise<void>} - Resolves once the subscription is acknowledged. */
52
+ get ready(): Promise<void>;
53
+ /** @returns {void} */
54
+ _resolveReadyState(): void;
55
+ /** @returns {void} */
56
+ _markNotReady(): void;
57
+ /** @returns {void} */
58
+ _handleSubscribed(): void;
59
+ /** @returns {void} */
60
+ _markSubscribeSent(): void;
61
+ /** @returns {boolean} - Whether the subscription still needs to be sent. */
62
+ _needsSubscribe(): boolean;
63
+ /**
64
+ * @param {any} body - Message payload.
65
+ * @returns {void}
66
+ */
67
+ _handleMessage(body: any): void;
68
+ /** @returns {void} */
69
+ _handleDisconnected(): void;
70
+ /** @returns {void} */
71
+ _handleResumed(): void;
72
+ /**
73
+ * @param {string} reason - Why the subscription closed.
74
+ * @returns {void}
75
+ */
76
+ _handleClosed(reason: string): void;
77
+ /**
78
+ * @param {{timeoutMs?: number}} [params] - Options.
79
+ * @returns {Promise<void>} - Resolves once ready or rejects on timeout.
80
+ */
81
+ waitForReady({ timeoutMs }?: {
82
+ timeoutMs?: number;
83
+ }): Promise<void>;
84
+ /** @returns {void} */
85
+ close(): void;
86
+ /** @returns {boolean} - Whether the subscription is closed. */
87
+ isClosed(): boolean;
88
+ /** @returns {boolean} - Whether the subscription is acknowledged and ready. */
89
+ isReady(): boolean;
90
+ /** @returns {boolean} - Whether the subscription is active. */
91
+ isSubscribed(): boolean;
92
+ }
@@ -0,0 +1,364 @@
1
+ /**
2
+ * A small WebSocket client that mirrors simple HTTP-style calls and channel
3
+ * subscriptions over `globalThis.WebSocket`, so the same code runs on web, Expo
4
+ * / React Native and Node. Supports optional auto-reconnect with exponential
5
+ * backoff, session resumption and listener re-subscription.
6
+ *
7
+ * Response bodies are returned as raw parsed JSON; apps that need their own
8
+ * (de)serialization should apply it around `post`/`get` and the response
9
+ * `json()`.
10
+ */
11
+ export default class SnapReqWebSocketClient {
12
+ /**
13
+ * @param {object} args - Options object.
14
+ * @param {string} args.url - Full WebSocket URL, e.g. `ws://localhost:3006/websocket`.
15
+ * @param {boolean} [args.autoReconnect] - Enable auto-reconnect with exponential backoff.
16
+ * @param {boolean} [args.debug] - Whether to log debug output.
17
+ * @param {{getIsOnline?: () => boolean | Promise<boolean>, subscribe?: (callback: (isOnline: boolean) => void) => (() => void) | {remove: () => void}}} [args.networkMonitor] - Optional online-state adapter. When provided, auto-reconnect can wait for the network to report online before reconnecting, and open sockets are closed when the monitor reports offline.
18
+ * @param {number[]} [args.reconnectDelays] - Backoff delays in ms (default: [1000, 2000, 4000, 8000, 15000]).
19
+ * @param {{get: () => string | null | undefined | Promise<string | null | undefined>, set: (sessionId: string) => void | Promise<void>, clear: () => void | Promise<void>}} [args.sessionStore] - Optional sessionId persistence hook surviving reloads (localStorage, a cookie, SQLite, etc.).
20
+ * @param {(value: any) => any} [args.deserialize] - Optional transform applied to a response body inside `response.json()`. Lets an app re-hydrate its own wire format. Defaults to identity.
21
+ */
22
+ constructor({ autoReconnect, debug, deserialize, networkMonitor, reconnectDelays, sessionStore, url }?: {
23
+ url: string;
24
+ autoReconnect?: boolean;
25
+ debug?: boolean;
26
+ networkMonitor?: {
27
+ getIsOnline?: () => boolean | Promise<boolean>;
28
+ subscribe?: (callback: (isOnline: boolean) => void) => (() => void) | {
29
+ remove: () => void;
30
+ };
31
+ };
32
+ reconnectDelays?: number[];
33
+ sessionStore?: {
34
+ get: () => string | null | undefined | Promise<string | null | undefined>;
35
+ set: (sessionId: string) => void | Promise<void>;
36
+ clear: () => void | Promise<void>;
37
+ };
38
+ deserialize?: (value: any) => any;
39
+ });
40
+ /** @type {Map<string, {reject: (error: unknown) => void, resolve: (response: SnapReqWebSocketResponse) => void}>} */
41
+ pendingRequests: Map<string, {
42
+ reject: (error: unknown) => void;
43
+ resolve: (response: SnapReqWebSocketResponse) => void;
44
+ }>;
45
+ /** @type {Map<string, {reject: (error: unknown) => void, resolve: (value?: void) => void}>} */
46
+ pendingSubscriptions: Map<string, {
47
+ reject: (error: unknown) => void;
48
+ resolve: (value?: void) => void;
49
+ }>;
50
+ /** @type {Map<string, {callbacks: Set<(payload: any) => void>, channel: string, params: Record<string, any> | undefined, ready: Promise<void>}>} */
51
+ listeners: Map<string, {
52
+ callbacks: Set<(payload: any) => void>;
53
+ channel: string;
54
+ params: Record<string, any> | undefined;
55
+ ready: Promise<void>;
56
+ }>;
57
+ /** @type {(value: any) => any} */
58
+ _deserialize: (value: any) => any;
59
+ /** @type {boolean} */
60
+ autoReconnect: boolean;
61
+ debug: boolean;
62
+ /** @type {number | null} */
63
+ disconnectedSince: number | null;
64
+ /** @type {number} */
65
+ reconnectAttempt: number;
66
+ /** @type {number} */
67
+ connectionAttempts: number;
68
+ /** @type {number[]} */
69
+ reconnectDelays: number[];
70
+ /** @type {ReturnType<typeof setTimeout> | null} */
71
+ reconnectTimer: ReturnType<typeof setTimeout> | null;
72
+ url: string;
73
+ nextID: number;
74
+ /** @type {(() => void | Promise<void>) | null} */
75
+ onReconnect: (() => void | Promise<void>) | null;
76
+ /** @type {Record<string, any>} */
77
+ _metadata: Record<string, any>;
78
+ /** @type {Map<string, SnapReqWebSocketConnection>} */
79
+ _connections: Map<string, SnapReqWebSocketConnection>;
80
+ /** @type {Map<string, SnapReqWebSocketChannel>} */
81
+ _channelSubscriptions: Map<string, SnapReqWebSocketChannel>;
82
+ _nextConnectionIdSeq: number;
83
+ _nextSubscriptionIdSeq: number;
84
+ /** @type {string | null} - sessionId received from `session-established`; sent on reconnect for resumption. */
85
+ _sessionId: string | null;
86
+ /** @type {boolean} - true between a reconnect and the session-resumed / session-gone reply. */
87
+ _awaitingResume: boolean;
88
+ /** @type {boolean} - true once the current socket has an active session ready for app messages. */
89
+ _sessionReady: boolean;
90
+ /** @type {string | null} - provisional session id announced before a resume attempt finishes. */
91
+ _pendingSessionId: string | null;
92
+ /** @type {Promise<void> | null} */
93
+ _sessionReadyPromise: Promise<void> | null;
94
+ /** @type {(() => void) | null} */
95
+ _resolveSessionReady: (() => void) | null;
96
+ /** @type {unknown | null} */
97
+ _sessionReadyError: unknown | null;
98
+ /** @type {{get: () => string | null | undefined | Promise<string | null | undefined>, set: (sessionId: string) => void | Promise<void>, clear: () => void | Promise<void>} | undefined} */
99
+ _sessionStore: {
100
+ get: () => string | null | undefined | Promise<string | null | undefined>;
101
+ set: (sessionId: string) => void | Promise<void>;
102
+ clear: () => void | Promise<void>;
103
+ } | undefined;
104
+ /** @type {boolean} - true once the sessionStore has been consulted for a restored id. */
105
+ _sessionStoreRestored: boolean;
106
+ /** @type {{getIsOnline?: () => boolean | Promise<boolean>, subscribe?: (callback: (isOnline: boolean) => void) => (() => void) | {remove: () => void}} | undefined} */
107
+ _networkMonitor: {
108
+ getIsOnline?: () => boolean | Promise<boolean>;
109
+ subscribe?: (callback: (isOnline: boolean) => void) => (() => void) | {
110
+ remove: () => void;
111
+ };
112
+ } | undefined;
113
+ /** @type {null | (() => void) | {remove: () => void}} */
114
+ _networkMonitorSubscription: null | (() => void) | {
115
+ remove: () => void;
116
+ };
117
+ /** @type {boolean} */
118
+ _waitingForOnline: boolean;
119
+ /** @returns {boolean} - Whether the socket is open. */
120
+ isOpen(): boolean;
121
+ /** @returns {boolean} - Whether the session is ready for app messages. */
122
+ isSessionReady(): boolean;
123
+ /**
124
+ * Opens a 1:1 connection of the given type against the server. Requires the
125
+ * socket to already be connected (call `connect()` first).
126
+ * @param {string} connectionType - Name the server registered the class under.
127
+ * @param {{params?: Record<string, any>, onConnect?: () => void, onMessage?: (body: any) => void, onDisconnect?: () => void, onResume?: () => void, onClose?: (reason: string) => void}} [options] - Connection options.
128
+ * @returns {SnapReqWebSocketConnection} - The connection handle.
129
+ */
130
+ openConnection(connectionType: string, options?: {
131
+ params?: Record<string, any>;
132
+ onConnect?: () => void;
133
+ onMessage?: (body: any) => void;
134
+ onDisconnect?: () => void;
135
+ onResume?: () => void;
136
+ onClose?: (reason: string) => void;
137
+ }): SnapReqWebSocketConnection;
138
+ /**
139
+ * Drops a connection handle from the registry.
140
+ * @param {string} connectionId - The connection id.
141
+ * @returns {void}
142
+ */
143
+ _removeConnection(connectionId: string): void;
144
+ /**
145
+ * Subscribes to a named channel. If the socket is not yet open, the
146
+ * subscription is queued and sent once a connection is established.
147
+ * @param {string} channelType - Name the server registered the channel under.
148
+ * @param {{params?: Record<string, any>, lastEventId?: string, onMessage?: (body: any) => void, onDisconnect?: () => void, onResume?: () => void, onClose?: (reason: string) => void}} [options] - Subscription options.
149
+ * @returns {SnapReqWebSocketChannel} - The subscription handle.
150
+ */
151
+ subscribeChannel(channelType: string, options?: {
152
+ params?: Record<string, any>;
153
+ lastEventId?: string;
154
+ onMessage?: (body: any) => void;
155
+ onDisconnect?: () => void;
156
+ onResume?: () => void;
157
+ onClose?: (reason: string) => void;
158
+ }): SnapReqWebSocketChannel;
159
+ /**
160
+ * @param {string} subscriptionId - The subscription id.
161
+ * @returns {void}
162
+ */
163
+ _removeChannelSubscription(subscriptionId: string): void;
164
+ /**
165
+ * @param {SnapReqWebSocketChannel} subscription - The subscription to send.
166
+ * @returns {void}
167
+ */
168
+ _sendChannelSubscribe(subscription: SnapReqWebSocketChannel): void;
169
+ /** @returns {void} */
170
+ _sendPendingChannelSubscriptions(): void;
171
+ /** @returns {Promise<boolean>} - Whether the network reports online. */
172
+ _isOnline(): Promise<boolean>;
173
+ /** @returns {Promise<boolean>} - Whether reconnect should wait for online. */
174
+ _shouldWaitForOnline(): Promise<boolean>;
175
+ /** @returns {void} */
176
+ _ensureNetworkMonitorSubscription(): void;
177
+ /** @returns {void} */
178
+ _teardownNetworkMonitorSubscription(): void;
179
+ /**
180
+ * Sets a global metadata value that is sent to the server. When the socket is
181
+ * open, a metadata update message is sent immediately.
182
+ * @param {string} key - Metadata key.
183
+ * @param {any} value - Metadata value (null to clear).
184
+ * @returns {void}
185
+ */
186
+ setMetadata(key: string, value: any): void;
187
+ /** @returns {Record<string, any>} - Current metadata. */
188
+ getMetadata(): Record<string, any>;
189
+ /**
190
+ * Ensures a WebSocket connection is open. Auto-reconnect and online gating are
191
+ * enabled by default.
192
+ * @param {{autoReconnect?: boolean, waitForOnline?: boolean, resetReconnectState?: boolean}} [options] - Connect options.
193
+ * @returns {Promise<void>} - Resolves once connected and the session is ready.
194
+ */
195
+ connect({ autoReconnect, waitForOnline, resetReconnectState }?: {
196
+ autoReconnect?: boolean;
197
+ waitForOnline?: boolean;
198
+ resetReconnectState?: boolean;
199
+ }): Promise<void>;
200
+ connectPromise: Promise<any>;
201
+ socket: WebSocket;
202
+ /**
203
+ * Closes the WebSocket and clears pending state.
204
+ * @returns {Promise<void>} - Resolves once closed.
205
+ */
206
+ close(): Promise<void>;
207
+ /**
208
+ * Disables auto-reconnect and closes the WebSocket.
209
+ * @returns {Promise<void>} - Resolves once closed.
210
+ */
211
+ disconnectAndStopReconnect(): Promise<void>;
212
+ /**
213
+ * Closes the raw socket without disabling auto-reconnect. Used by tests to
214
+ * simulate an unexpected network drop.
215
+ * @returns {Promise<void>} - Resolves once the socket has closed.
216
+ */
217
+ dropConnection(): Promise<void>;
218
+ /**
219
+ * Performs a POST request over the WebSocket.
220
+ * @param {string} path - Path.
221
+ * @param {any} [body] - Request body.
222
+ * @param {{headers?: Record<string, string>}} [options] - Request options such as headers.
223
+ * @returns {Promise<SnapReqWebSocketResponse>} - The response.
224
+ */
225
+ post(path: string, body?: any, options?: {
226
+ headers?: Record<string, string>;
227
+ }): Promise<SnapReqWebSocketResponse>;
228
+ /**
229
+ * Performs a GET request over the WebSocket.
230
+ * @param {string} path - Path.
231
+ * @param {{headers?: Record<string, string>}} [options] - Request options such as headers.
232
+ * @returns {Promise<SnapReqWebSocketResponse>} - The response.
233
+ */
234
+ get(path: string, options?: {
235
+ headers?: Record<string, string>;
236
+ }): Promise<SnapReqWebSocketResponse>;
237
+ /**
238
+ * Subscribes to a channel for server-sent events.
239
+ * @param {string} channel - Channel name.
240
+ * @param {(payload: any) => void} callback - Callback function.
241
+ * @returns {() => void} - Unsubscribe function.
242
+ */
243
+ on(channel: string, callback: (payload: any) => void): () => void;
244
+ /**
245
+ * Returns a snapshot of the client's connection state.
246
+ * @returns {{disconnectedSince: number | null, isOpen: boolean, listenerCount: number}} - State snapshot.
247
+ */
248
+ state(): {
249
+ disconnectedSince: number | null;
250
+ isOpen: boolean;
251
+ listenerCount: number;
252
+ };
253
+ /**
254
+ * Subscribes to a channel for server-sent events with optional params.
255
+ * @param {string} channel - Channel name.
256
+ * @param {{lastEventId?: string, params?: Record<string, any>}} options - Subscription options.
257
+ * @param {(payload: any, message?: Record<string, any>) => void} callback - Callback function.
258
+ * @returns {(() => void) & {ready: Promise<void>}} - Unsubscribe function with readiness promise.
259
+ */
260
+ subscribe(channel: string, options: {
261
+ lastEventId?: string;
262
+ params?: Record<string, any>;
263
+ }, callback: (payload: any, message?: Record<string, any>) => void): (() => void) & {
264
+ ready: Promise<void>;
265
+ };
266
+ /**
267
+ * Subscribes to a channel and waits until the server acknowledges it.
268
+ * @param {string} channel - Channel name.
269
+ * @param {{lastEventId?: string, params?: Record<string, any>}} options - Subscription options.
270
+ * @param {(payload: any, message?: Record<string, any>) => void} callback - Callback function.
271
+ * @returns {Promise<(() => void) & {ready: Promise<void>}>} - Ready unsubscribe handle.
272
+ */
273
+ subscribeAndWait(channel: string, options: {
274
+ lastEventId?: string;
275
+ params?: Record<string, any>;
276
+ }, callback: (payload: any, message?: Record<string, any>) => void): Promise<(() => void) & {
277
+ ready: Promise<void>;
278
+ }>;
279
+ /**
280
+ * @param {string} method - HTTP method.
281
+ * @param {string} path - Path.
282
+ * @param {object} [options] - Options object.
283
+ * @param {any} [options.body] - Request body.
284
+ * @param {Record<string, string>} [options.headers] - Header list.
285
+ * @returns {Promise<SnapReqWebSocketResponse>} - The response.
286
+ */
287
+ request(method: string, path: string, { body, headers }?: {
288
+ body?: any;
289
+ headers?: Record<string, string>;
290
+ }): Promise<SnapReqWebSocketResponse>;
291
+ /**
292
+ * @param {MessageEvent<any>} event - Event payload.
293
+ * @returns {void}
294
+ */
295
+ onMessage: (event: MessageEvent<any>) => void;
296
+ /**
297
+ * @param {string} channel - Channel name.
298
+ * @param {Record<string, any> | undefined} params - Subscription params.
299
+ * @returns {string} - Stable subscription key.
300
+ */
301
+ _subscriptionKey(channel: string, params: Record<string, any> | undefined): string;
302
+ /**
303
+ * Rejects all pending requests when the socket closes. Schedules reconnect if
304
+ * enabled.
305
+ * @returns {void}
306
+ */
307
+ onClose: () => void;
308
+ /**
309
+ * @param {Record<string, any>} payload - Payload data.
310
+ * @returns {void}
311
+ */
312
+ _sendMessage(payload: Record<string, any>): void;
313
+ /** @returns {void} */
314
+ _cancelPendingReconnect(): void;
315
+ /** @returns {void} */
316
+ _scheduleReconnect(): void;
317
+ /** @returns {Promise<void>} */
318
+ _attemptReconnect(): Promise<void>;
319
+ /**
320
+ * Re-sends subscribe messages for all active listeners after reconnection.
321
+ * @returns {void}
322
+ */
323
+ _resubscribeActiveListeners(): void;
324
+ /**
325
+ * @param {...any} args - Log arguments.
326
+ * @returns {void}
327
+ */
328
+ _debug(...args: any[]): void;
329
+ /**
330
+ * @param {string} sessionId - Id to persist through the configured sessionStore.
331
+ * @returns {void}
332
+ */
333
+ _persistSessionId(sessionId: string): void;
334
+ /** @returns {void} */
335
+ _clearPersistedSessionId(): void;
336
+ /** @returns {Promise<void>} - Resolves once the session is ready. */
337
+ _waitForSessionReady(): Promise<void>;
338
+ /** @returns {void} */
339
+ _markSessionReady(): void;
340
+ /**
341
+ * @param {unknown} [error] - Reason for the reset.
342
+ * @returns {void}
343
+ */
344
+ _resetSessionReadyState(error?: unknown): void;
345
+ }
346
+ /** A response to a request made over the WebSocket transport. */
347
+ export class SnapReqWebSocketResponse {
348
+ /**
349
+ * @param {object} message - The response message.
350
+ * @param {(value: any) => any} [deserialize] - Transform applied to the parsed body in `json()`. Defaults to identity.
351
+ */
352
+ constructor(message: object, deserialize?: (value: any) => any);
353
+ body: any;
354
+ headers: Record<string, any>;
355
+ id: string | number;
356
+ statusCode: number;
357
+ statusMessage: string;
358
+ type: string;
359
+ _deserialize: (value: any) => any;
360
+ /** @returns {any} - The parsed (and optionally deserialized) JSON body. */
361
+ json(): any;
362
+ }
363
+ import SnapReqWebSocketConnection from "./websocket-connection.js";
364
+ import SnapReqWebSocketChannel from "./websocket-channel.js";