@stomp/stompjs 7.1.1 → 7.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/client.ts CHANGED
@@ -7,6 +7,7 @@ import {
7
7
  ActivationState,
8
8
  closeEventCallbackType,
9
9
  debugFnType,
10
+ emptyCallbackType,
10
11
  frameCallbackType,
11
12
  IPublishParams,
12
13
  IStompSocket,
@@ -30,181 +31,297 @@ declare const WebSocket: {
30
31
  * STOMP Client Class.
31
32
  *
32
33
  * Part of `@stomp/stompjs`.
34
+ *
35
+ * This class provides a robust implementation for connecting to and interacting with a
36
+ * STOMP-compliant messaging broker over WebSocket. It supports STOMP versions 1.2, 1.1, and 1.0.
37
+ *
38
+ * Features:
39
+ * - Handles automatic reconnections.
40
+ * - Supports heartbeat mechanisms to detect and report communication failures.
41
+ * - Allows customization of connection and WebSocket behaviors through configurations.
42
+ * - Compatible with both browser environments and Node.js with polyfill support for WebSocket.
33
43
  */
34
44
  export class Client {
35
45
  /**
36
46
  * The URL for the STOMP broker to connect to.
37
- * Typically like `"ws://broker.329broker.com:15674/ws"` or `"wss://broker.329broker.com:15674/ws"`.
38
- *
39
- * Only one of this or [Client#webSocketFactory]{@link Client#webSocketFactory} need to be set.
40
- * If both are set, [Client#webSocketFactory]{@link Client#webSocketFactory} will be used.
41
- *
42
- * If your environment does not support WebSockets natively, please refer to
43
- * [Polyfills]{@link https://stomp-js.github.io/guide/stompjs/rx-stomp/ng2-stompjs/pollyfils-for-stompjs-v5.html}.
47
+ * Example: `"ws://broker.domain.com:15674/ws"` or `"wss://broker.domain.com:15674/ws"`.
48
+ *
49
+ * Use this property to define the broker's WebSocket endpoint.
50
+ * Note:
51
+ * - Only one of `brokerURL` or [Client#webSocketFactory]{@link Client#webSocketFactory} needs to be set.
52
+ * - If both are provided, [Client#webSocketFactory]{@link Client#webSocketFactory} takes precedence.
53
+ * - When targeting environments without native WebSocket support, refer to
54
+ * [Polyfills]{@link https://stomp-js.github.io/guide/stompjs/rx-stomp/ng2-stompjs/pollyfils-for-stompjs-v5.html}.
44
55
  */
45
56
  public brokerURL: string | undefined;
46
57
 
47
58
  /**
48
- * STOMP versions to attempt during STOMP handshake. By default, versions `1.2`, `1.1`, and `1.0` are attempted.
59
+ * STOMP protocol versions to use during the handshake. By default, the client will attempt
60
+ * versions `1.2`, `1.1`, and `1.0` in descending order of preference.
49
61
  *
50
62
  * Example:
51
63
  * ```javascript
52
- * // Try only versions 1.1 and 1.0
53
- * client.stompVersions = new Versions(['1.1', '1.0'])
64
+ * // Configure the client to only use versions 1.1 and 1.0
65
+ * client.stompVersions = new Versions(['1.1', '1.0']);
54
66
  * ```
55
67
  */
56
68
  public stompVersions = Versions.default;
57
69
 
58
70
  /**
59
- * This function should return a WebSocket or a similar (e.g. SockJS) object.
60
- * If your environment does not support WebSockets natively, please refer to
61
- * [Polyfills]{@link https://stomp-js.github.io/guide/stompjs/rx-stomp/ng2-stompjs/pollyfils-for-stompjs-v5.html}.
62
- * If your STOMP Broker supports WebSockets, prefer setting [Client#brokerURL]{@link Client#brokerURL}.
71
+ * A function that returns a WebSocket or a similar object (e.g., SockJS) to establish connections.
63
72
  *
64
- * If both this and [Client#brokerURL]{@link Client#brokerURL} are set, this will be used.
73
+ * This is an alternative to [Client#brokerURL]{@link Client#brokerURL}.
74
+ * Using this allows finer control over WebSocket creation, especially for custom wrappers
75
+ * or when working in non-standard environments.
65
76
  *
66
77
  * Example:
67
78
  * ```javascript
68
- * // use a WebSocket
69
- * client.webSocketFactory= function () {
70
- * return new WebSocket("wss://broker.329broker.com:15674/ws");
71
- * };
72
- *
73
- * // Typical usage with SockJS
74
- * client.webSocketFactory= function () {
75
- * return new SockJS("http://broker.329broker.com/stomp");
76
- * };
79
+ * client.webSocketFactory = function () {
80
+ * return new WebSocket("ws://my-custom-websocket-endpoint");
81
+ * };
82
+ *
83
+ * // Typical usage with SockJS
84
+ * client.webSocketFactory= function () {
85
+ * return new SockJS("http://broker.329broker.com/stomp");
86
+ * };
77
87
  * ```
88
+ *
89
+ * Note:
90
+ * - If both [Client#brokerURL]{@link Client#brokerURL} and this property are set, the factory will be used.
91
+ * - Refer to [Polyfills Guide]{@link https://stomp-js.github.io/guide/stompjs/rx-stomp/ng2-stompjs/pollyfils-for-stompjs-v5.html}
92
+ * when running in environments without native WebSocket support.
78
93
  */
79
94
  public webSocketFactory: (() => IStompSocket) | undefined;
80
95
 
81
96
  /**
82
- * Will retry if Stomp connection is not established in specified milliseconds.
83
- * Default 0, which switches off automatic reconnection.
97
+ * Timeout for establishing STOMP connection, in milliseconds.
98
+ *
99
+ * If the connection is not established within this period, the attempt will fail.
100
+ * The default is `0`, meaning no timeout is set for connection attempts.
101
+ *
102
+ * Example:
103
+ * ```javascript
104
+ * client.connectionTimeout = 5000; // Fail connection if not established in 5 seconds
105
+ * ```
84
106
  */
85
107
  public connectionTimeout: number = 0;
86
108
 
87
- // As per https://stackoverflow.com/questions/45802988/typescript-use-correct-version-of-settimeout-node-vs-window/56239226#56239226
88
- private _connectionWatcher: ReturnType<typeof setTimeout> | undefined; // Timer
109
+ // Internal timer for handling connection timeout, if set.
110
+ // See https://stackoverflow.com/questions/45802988/typescript-use-correct-version-of-settimeout-node-vs-window/56239226#56239226
111
+ private _connectionWatcher: ReturnType<typeof setTimeout> | undefined;
89
112
 
90
113
  /**
91
- * automatically reconnect with delay in milliseconds, set to 0 to disable.
114
+ * Delay (in milliseconds) between reconnection attempts if the connection drops.
115
+ *
116
+ * Set to `0` to disable automatic reconnections. The default value is `5000` ms (5 seconds).
117
+ *
118
+ * Example:
119
+ * ```javascript
120
+ * client.reconnectDelay = 3000; // Attempt reconnection every 3 seconds
121
+ * client.reconnectDelay = 0; // Disable automatic reconnection
122
+ * ```
92
123
  */
93
124
  public reconnectDelay: number = 5000;
94
125
 
95
126
  /**
96
- * tracking the time to the next reconnection. Initialized to [Client#reconnectDelay]{@link Client#reconnectDelay}'s value and it may
97
- * change depending on the [Client#reconnectTimeMode]{@link Client#reconnectTimeMode} setting
127
+ * The next reconnection delay, used internally.
128
+ * Initialized to the value of [Client#reconnectDelay]{@link Client#reconnectDelay}, and it may
129
+ * dynamically change based on [Client#reconnectTimeMode]{@link Client#reconnectTimeMode}.
98
130
  */
99
131
  private _nextReconnectDelay: number = 0;
100
132
 
101
133
  /**
102
- * Maximum time to wait between reconnects, in milliseconds. Defaults to 15 minutes.
103
- * Only relevant when [Client#reconnectTimeMode]{@link Client#reconnectTimeMode} not LINEAR (e.g., EXPONENTIAL).
104
- * Set to 0 for no limit on wait time.
134
+ * Maximum delay (in milliseconds) between reconnection attempts when using exponential backoff.
135
+ *
136
+ * Default is 15 minutes (`15 * 60 * 1000` milliseconds). If `0`, there will be no upper limit.
137
+ *
138
+ * Example:
139
+ * ```javascript
140
+ * client.maxReconnectDelay = 10000; // Maximum wait time is 10 seconds
141
+ * ```
105
142
  */
106
- public maxReconnectDelay: number = 15 * 60 * 1000; // 15 minutes in ms
143
+ public maxReconnectDelay: number = 15 * 60 * 1000;
107
144
 
108
145
  /**
109
- * Reconnection wait time mode, either linear (default) or exponential.
110
- * Note: See [Client#maxReconnectDelay]{@link Client#maxReconnectDelay} for setting the maximum delay when exponential
111
- *
146
+ * Mode for determining the time interval between reconnection attempts.
147
+ *
148
+ * Available modes:
149
+ * - `ReconnectionTimeMode.LINEAR` (default): Fixed delays between reconnection attempts.
150
+ * - `ReconnectionTimeMode.EXPONENTIAL`: Delay doubles after each attempt, capped by [maxReconnectDelay]{@link Client#maxReconnectDelay}.
151
+ *
152
+ * Example:
112
153
  * ```javascript
113
- * client.configure({
114
- * reconnectTimeMode: ReconnectionTimeMode.EXPONENTIAL,
115
- * reconnectDelay: 200, // It will wait 200, 400, 800 ms...
116
- * maxReconnectDelay: 10000, // Optional, when provided, it will not wait more that these ms
117
- * })
154
+ * client.reconnectTimeMode = ReconnectionTimeMode.EXPONENTIAL;
155
+ * client.reconnectDelay = 200; // Initial delay of 200 ms, doubles with each attempt
156
+ * client.maxReconnectDelay = 2 * 60 * 1000; // Cap delay at 10 minutes
118
157
  * ```
119
158
  */
120
159
  public reconnectTimeMode: ReconnectionTimeMode = ReconnectionTimeMode.LINEAR;
121
160
 
122
161
  /**
123
- * Incoming heartbeat interval in milliseconds. Set to 0 to disable.
162
+ * Interval (in milliseconds) for receiving heartbeat signals from the server.
163
+ *
164
+ * Specifies the expected frequency of heartbeats sent by the server. Set to `0` to disable.
165
+ *
166
+ * Example:
167
+ * ```javascript
168
+ * client.heartbeatIncoming = 10000; // Expect a heartbeat every 10 seconds
169
+ * ```
124
170
  */
125
171
  public heartbeatIncoming: number = 10000;
126
172
 
127
173
  /**
128
- * Outgoing heartbeat interval in milliseconds. Set to 0 to disable.
174
+ * Multiplier for adjusting tolerance when processing heartbeat signals.
175
+ *
176
+ * Tolerance level is calculated using the multiplier:
177
+ * `tolerance = heartbeatIncoming * heartbeatToleranceMultiplier`.
178
+ * This helps account for delays in network communication or variations in timings.
179
+ *
180
+ * Default value is `2`.
181
+ *
182
+ * Example:
183
+ * ```javascript
184
+ * client.heartbeatToleranceMultiplier = 2.5; // Tolerates longer delays
185
+ * ```
186
+ */
187
+ public heartbeatToleranceMultiplier: number = 2;
188
+
189
+ /**
190
+ * Interval (in milliseconds) for sending heartbeat signals to the server.
191
+ *
192
+ * Specifies how frequently heartbeats should be sent to the server. Set to `0` to disable.
193
+ *
194
+ * Example:
195
+ * ```javascript
196
+ * client.heartbeatOutgoing = 5000; // Send a heartbeat every 5 seconds
197
+ * ```
129
198
  */
130
199
  public heartbeatOutgoing: number = 10000;
131
200
 
132
201
  /**
133
- * Outgoing heartbeat strategy.
134
- * See https://github.com/stomp-js/stompjs/pull/579
135
- *
136
- * Can be worker or interval strategy, but will always use `interval`
137
- * if web workers are unavailable, for example, in a non-browser environment.
138
- *
139
- * Using Web Workers may work better on long-running pages
140
- * and mobile apps, as the browser may suspend Timers in the main page.
141
- * Try the `Worker` mode if you discover disconnects when the browser tab is in the background.
142
- *
143
- * When used in a JS environment, use 'worker' or 'interval' as valid values.
144
- *
145
- * Defaults to `interval` strategy.
202
+ * Strategy for sending outgoing heartbeats.
203
+ *
204
+ * Options:
205
+ * - `TickerStrategy.Worker`: Uses Web Workers for sending heartbeats (recommended for long-running or background sessions).
206
+ * - `TickerStrategy.Interval`: Uses standard JavaScript `setInterval` (default).
207
+ *
208
+ * Note:
209
+ * - If Web Workers are unavailable (e.g., in Node.js), the `Interval` strategy is used automatically.
210
+ * - Web Workers are preferable in browsers for reducing disconnects when tabs are in the background.
211
+ *
212
+ * Example:
213
+ * ```javascript
214
+ * client.heartbeatStrategy = TickerStrategy.Worker;
215
+ * ```
146
216
  */
147
217
  public heartbeatStrategy: TickerStrategy = TickerStrategy.Interval;
148
218
 
149
219
  /**
150
- * This switches on a non-standard behavior while sending WebSocket packets.
151
- * It splits larger (text) packets into chunks of [maxWebSocketChunkSize]{@link Client#maxWebSocketChunkSize}.
152
- * Only Java Spring brokers seem to support this mode.
220
+ * Enables splitting of large text WebSocket frames into smaller chunks.
153
221
  *
154
- * WebSockets, by itself, split large (text) packets,
155
- * so it is not needed with a truly compliant STOMP/WebSocket broker.
156
- * Setting it for such a broker will cause large messages to fail.
222
+ * This setting is enabled for brokers that support only chunked messages (e.g., Java Spring-based brokers).
223
+ * Default is `false`.
157
224
  *
158
- * `false` by default.
225
+ * Warning:
226
+ * - Should not be used with WebSocket-compliant brokers, as chunking may cause large message failures.
227
+ * - Binary WebSocket frames are never split.
159
228
  *
160
- * Binary frames are never split.
229
+ * Example:
230
+ * ```javascript
231
+ * client.splitLargeFrames = true;
232
+ * client.maxWebSocketChunkSize = 4096; // Allow chunks of 4 KB
233
+ * ```
161
234
  */
162
235
  public splitLargeFrames: boolean = false;
163
236
 
164
237
  /**
165
- * See [splitLargeFrames]{@link Client#splitLargeFrames}.
166
- * This has no effect if [splitLargeFrames]{@link Client#splitLargeFrames} is `false`.
238
+ * Maximum size (in bytes) for individual WebSocket chunks if [splitLargeFrames]{@link Client#splitLargeFrames} is enabled.
239
+ *
240
+ * Default is 8 KB (`8 * 1024` bytes). This value has no effect if [splitLargeFrames]{@link Client#splitLargeFrames} is `false`.
167
241
  */
168
242
  public maxWebSocketChunkSize: number = 8 * 1024;
169
243
 
170
244
  /**
171
- * Usually the
172
- * [type of WebSocket frame]{@link https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/send#Parameters}
173
- * is automatically decided by type of the payload.
174
- * Default is `false`, which should work with all compliant brokers.
245
+ * Forces all WebSocket frames to use binary transport, irrespective of payload type.
175
246
  *
176
- * Set this flag to force binary frames.
247
+ * Default behavior determines frame type based on payload (e.g., binary data for ArrayBuffers).
248
+ *
249
+ * Example:
250
+ * ```javascript
251
+ * client.forceBinaryWSFrames = true;
252
+ * ```
177
253
  */
178
254
  public forceBinaryWSFrames: boolean = false;
179
255
 
180
256
  /**
181
- * A bug in ReactNative chops a string on occurrence of a NULL.
182
- * See issue [https://github.com/stomp-js/stompjs/issues/89]{@link https://github.com/stomp-js/stompjs/issues/89}.
183
- * This makes incoming WebSocket messages invalid STOMP packets.
184
- * Setting this flag attempts to reverse the damage by appending a NULL.
185
- * If the broker splits a large message into multiple WebSocket messages,
186
- * this flag will cause data loss and abnormal termination of connection.
257
+ * Workaround for a React Native WebSocket bug, where messages containing `NULL` are chopped.
187
258
  *
188
- * This is not an ideal solution, but a stop gap until the underlying issue is fixed at ReactNative library.
259
+ * Enabling this appends a `NULL` character to incoming frames to ensure they remain valid STOMP packets.
260
+ *
261
+ * Warning:
262
+ * - For brokers that split large messages, this may cause data loss or connection termination.
263
+ *
264
+ * Example:
265
+ * ```javascript
266
+ * client.appendMissingNULLonIncoming = true;
267
+ * ```
189
268
  */
190
269
  public appendMissingNULLonIncoming: boolean = false;
191
270
 
192
271
  /**
193
- * Underlying WebSocket instance, READONLY.
272
+ * Provides access to the underlying WebSocket instance.
273
+ * This property is **read-only**.
274
+ *
275
+ * Example:
276
+ * ```javascript
277
+ * const webSocket = client.webSocket;
278
+ * if (webSocket) {
279
+ * console.log('WebSocket is connected:', webSocket.readyState === WebSocket.OPEN);
280
+ * }
281
+ * ```
282
+ *
283
+ * **Caution:**
284
+ * Directly interacting with the WebSocket instance (e.g., sending or receiving frames)
285
+ * can interfere with the proper functioning of this library. Such actions may cause
286
+ * unexpected behavior, disconnections, or invalid state in the library's internal mechanisms.
287
+ *
288
+ * Instead, use the library's provided methods to manage STOMP communication.
289
+ *
290
+ * @returns The WebSocket instance used by the STOMP handler, or `undefined` if not connected.
194
291
  */
195
292
  get webSocket(): IStompSocket | undefined {
196
293
  return this._stompHandler?._webSocket;
197
294
  }
198
295
 
199
296
  /**
200
- * Connection headers, important keys - `login`, `passcode`, `host`.
201
- * Though STOMP 1.2 standard marks these keys to be present, check your broker documentation for
202
- * details specific to your broker.
297
+ * Connection headers to be sent during the connection handshake.
298
+ *
299
+ * Keys like `login`, `passcode`, and `host` are commonly expected for most brokers.
300
+ * Although STOMP 1.2 specifies these keys as mandatory, consult your broker's documentation
301
+ * for additional requirements or alternative header usage.
302
+ *
303
+ * Example:
304
+ * ```javascript
305
+ * client.connectHeaders = {
306
+ * login: 'my-username',
307
+ * passcode: 'my-password',
308
+ * host: 'my-vhost'
309
+ * };
310
+ * ```
203
311
  */
204
312
  public connectHeaders: StompHeaders;
205
313
 
206
314
  /**
207
- * Disconnection headers.
315
+ * Allows customization of the disconnection headers.
316
+ *
317
+ * Any changes made during an active session will also be applied immediately.
318
+ *
319
+ * Example:
320
+ * ```javascript
321
+ * client.disconnectHeaders = {
322
+ * receipt: 'custom-receipt-id'
323
+ * };
324
+ * ```
208
325
  */
209
326
  get disconnectHeaders(): StompHeaders {
210
327
  return this._disconnectHeaders;
@@ -219,139 +336,272 @@ export class Client {
219
336
  private _disconnectHeaders: StompHeaders;
220
337
 
221
338
  /**
222
- * This function will be called for any unhandled messages.
223
- * It is useful for receiving messages sent to RabbitMQ temporary queues.
339
+ * Callback invoked for any unhandled messages received from the broker.
224
340
  *
225
- * It can also get invoked with stray messages while the server is processing
226
- * a request to [Client#unsubscribe]{@link Client#unsubscribe}
227
- * from an endpoint.
341
+ * This is particularly useful for handling messages sent to RabbitMQ temporary queues
342
+ * or other queues where no explicit subscription exists. It can also be triggered
343
+ * by stray messages received while a subscription is being unsubscribed.
228
344
  *
229
- * The actual {@link IMessage} will be passed as parameter to the callback.
345
+ * Usage:
346
+ * ```javascript
347
+ * client.onUnhandledMessage = (message) => {
348
+ * console.log('Unhandled message:', message);
349
+ * };
350
+ * ```
351
+ *
352
+ * @param message The actual {@link IMessage} received.
230
353
  */
231
354
  public onUnhandledMessage: messageCallbackType;
232
355
 
233
356
  /**
234
- * STOMP brokers can be requested to notify when an operation is actually completed.
235
- * Prefer using [Client#watchForReceipt]{@link Client#watchForReceipt}. See
236
- * [Client#watchForReceipt]{@link Client#watchForReceipt} for examples.
357
+ * Callback invoked when the broker sends a receipt indicating the completion
358
+ * of an operation. Receipts are typically requested using the
359
+ * [Client#watchForReceipt]{@link Client#watchForReceipt} function.
237
360
  *
238
- * The actual {@link IFrame} will be passed as parameter to the callback.
361
+ * Usage Example:
362
+ * See [Client#watchForReceipt]{@link Client#watchForReceipt}.
363
+ *
364
+ * @param frame The actual {@link IFrame} received from the broker.
239
365
  */
240
366
  public onUnhandledReceipt: frameCallbackType;
241
367
 
242
368
  /**
243
- * Will be invoked if {@link IFrame} of an unknown type is received from the STOMP broker.
369
+ * Callback invoked when a frame of an unknown or unexpected type is received
370
+ * from the broker.
371
+ *
372
+ * This is intended as a fallback for handling unexpected or unsupported frames
373
+ * sent by the broker.
374
+ *
375
+ * Usage:
376
+ * ```javascript
377
+ * client.onUnhandledFrame = (frame) => {
378
+ * console.warn('Unhandled frame received:', frame);
379
+ * };
380
+ * ```
244
381
  *
245
- * The actual {@link IFrame} will be passed as parameter to the callback.
382
+ * @param frame The actual {@link IFrame} received from the broker.
246
383
  */
247
384
  public onUnhandledFrame: frameCallbackType;
248
385
 
249
386
  /**
250
- * `true` if there is an active connection to STOMP Broker
387
+ * Callback invoked when a heartbeat message is received from the STOMP broker.
388
+ *
389
+ * Heartbeats ensure that the connection remains active and responsive. This callback
390
+ * is executed on every received heartbeat. It is useful for monitoring connection health
391
+ * or logging heartbeat activity.
392
+ *
393
+ * **Note**: The library handles heartbeats internally to maintain and verify connection status.
394
+ * Implementing this callback is optional and primarily for custom monitoring or debugging.
395
+ *
396
+ * Usage:
397
+ * ```javascript
398
+ * client.onHeartbeatReceived = () => {
399
+ * console.log('Heartbeat received');
400
+ * };
401
+ * ```
402
+ */
403
+ public onHeartbeatReceived: emptyCallbackType;
404
+
405
+ /**
406
+ * Callback invoked when no heartbeat is received from the broker within
407
+ * the acceptable interval, indicating a potential communication issue or connection failure.
408
+ *
409
+ * This callback is triggered when the heartbeat interval defined by `heartbeatIncoming`
410
+ * elapses without a received heartbeat.
411
+ *
412
+ * **Note**: The library handles this condition internally and takes appropriate
413
+ * actions, such as marking the connection as failed. This callback is available
414
+ * for implementing custom recovery strategies or additional notifications.
415
+ *
416
+ * Usage:
417
+ * ```javascript
418
+ * client.onHeartbeatLost = () => {
419
+ * console.error('Lost connection to the broker');
420
+ * };
421
+ * ```
422
+ */
423
+ public onHeartbeatLost: emptyCallbackType;
424
+
425
+ /**
426
+ * Indicates whether there is an active connection to the STOMP broker.
427
+ *
428
+ * Usage:
429
+ * ```javascript
430
+ * if (client.connected) {
431
+ * console.log('Client is connected to the broker.');
432
+ * } else {
433
+ * console.log('No connection to the broker.');
434
+ * }
435
+ * ```
436
+ *
437
+ * @returns `true` if the client is currently connected, `false` otherwise.
251
438
  */
252
439
  get connected(): boolean {
253
440
  return !!this._stompHandler && this._stompHandler.connected;
254
441
  }
255
442
 
256
443
  /**
257
- * Callback, invoked on before a connection to the STOMP broker.
444
+ * Callback executed before initiating a connection to the STOMP broker.
445
+ *
446
+ * This callback allows users to modify connection options dynamically,
447
+ * such as updating credentials or connection parameters, before the connection is made.
258
448
  *
259
- * You can change options on the client, which will impact the immediate connecting.
260
- * It is valid to call [Client#decativate]{@link Client#deactivate} in this callback.
449
+ * As of version 5.1, this callback supports `async/await`, enabling seamless integration
450
+ * with asynchronous operations, such as fetching tokens or credentials.
261
451
  *
262
- * As of version 5.1, this callback can be
263
- * [async](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)
264
- * (i.e., it can return a
265
- * [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)).
266
- * In that case, connect will be called only after the Promise is resolved.
267
- * This can be used to reliably fetch credentials, access token etc. from some other service
268
- * in an asynchronous way.
452
+ * Example:
453
+ * ```javascript
454
+ * client.beforeConnect = async () => {
455
+ * const token = await fetchToken();
456
+ * client.connectHeaders = { Authorization: `Bearer ${token}` };
457
+ * };
458
+ * ```
269
459
  */
270
460
  public beforeConnect: (client: Client) => void | Promise<void>;
271
461
 
272
462
  /**
273
- * Callback, invoked on every successful connection to the STOMP broker.
463
+ * Callback executed upon every successful connection to the STOMP broker.
464
+ *
465
+ * This callback is invoked after the connection is established and the CONNECTED frame
466
+ * is received from the broker. It provides access to the broker's response frame,
467
+ * allowing users to parse its headers or other data.
274
468
  *
275
- * The actual {@link IFrame} will be passed as parameter to the callback.
276
- * Sometimes clients will like to use headers from this frame.
469
+ * Example:
470
+ * ```javascript
471
+ * client.onConnect = (frame) => {
472
+ * console.log('Connected to broker, session ID:', frame.headers['session']);
473
+ * };
474
+ * ```
277
475
  */
278
476
  public onConnect: frameCallbackType;
279
477
 
280
478
  /**
281
- * Callback, invoked on every successful disconnection from the STOMP broker. It will not be invoked if
282
- * the STOMP broker disconnected due to an error.
479
+ * Callback executed upon successful disconnection from the STOMP broker.
283
480
  *
284
- * The actual Receipt {@link IFrame} acknowledging the DISCONNECT will be passed as parameter to the callback.
481
+ * The callback is invoked when the DISCONNECT receipt is received from the broker.
482
+ * Note that due to the design of the STOMP protocol or communication interrupts, the
483
+ * DISCONNECT receipt may not always be received. For handling such cases, use
484
+ * [Client#onWebSocketClose]{@link Client#onWebSocketClose}.
285
485
  *
286
- * The way STOMP protocol is designed, the connection may close/terminate without the client
287
- * receiving the Receipt {@link IFrame} acknowledging the DISCONNECT.
288
- * You might find [Client#onWebSocketClose]{@link Client#onWebSocketClose} more appropriate to watch
289
- * STOMP broker disconnects.
486
+ * Example:
487
+ * ```javascript
488
+ * client.onDisconnect = (frame) => {
489
+ * console.log('Disconnected successfully');
490
+ * };
491
+ * ```
290
492
  */
291
493
  public onDisconnect: frameCallbackType;
292
494
 
293
495
  /**
294
- * Callback, invoked on an ERROR frame received from the STOMP Broker.
295
- * A compliant STOMP Broker will close the connection after this type of frame.
296
- * Please check broker specific documentation for exact behavior.
496
+ * Callback executed when an ERROR frame is received from the STOMP broker.
497
+ *
498
+ * Receiving an ERROR frame typically indicates a problem with the subscription,
499
+ * message format, or protocol violation. The broker will usually close the connection
500
+ * after sending an ERROR frame.
297
501
  *
298
- * The actual {@link IFrame} will be passed as parameter to the callback.
502
+ * Example:
503
+ * ```javascript
504
+ * client.onStompError = (frame) => {
505
+ * console.error('Broker reported an error:', frame.body);
506
+ * };
507
+ * ```
299
508
  */
300
509
  public onStompError: frameCallbackType;
301
510
 
302
511
  /**
303
- * Callback, invoked when underlying WebSocket is closed.
512
+ * Callback executed when the underlying WebSocket is closed.
513
+ *
514
+ * This can occur due to various reasons, such as network interruptions or broker shutdown.
515
+ * The callback provides the WebSocket [CloseEvent]{@link https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent},
516
+ * which contains details about the closure.
304
517
  *
305
- * Actual [CloseEvent]{@link https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent}
306
- * is passed as parameter to the callback.
518
+ * Example:
519
+ * ```javascript
520
+ * client.onWebSocketClose = (event) => {
521
+ * console.log('WebSocket closed. Code:', event.code);
522
+ * };
523
+ * ```
307
524
  */
308
525
  public onWebSocketClose: closeEventCallbackType;
309
526
 
310
527
  /**
311
- * Callback, invoked when underlying WebSocket raises an error.
528
+ * Callback executed when the underlying WebSocket raises an error.
312
529
  *
313
- * Actual [Event]{@link https://developer.mozilla.org/en-US/docs/Web/API/Event}
314
- * is passed as parameter to the callback.
530
+ * This callback provides an [Event]{@link https://developer.mozilla.org/en-US/docs/Web/API/Event}
531
+ * representing the error raised by the WebSocket.
532
+ *
533
+ * Example:
534
+ * ```javascript
535
+ * client.onWebSocketError = (event) => {
536
+ * console.error('WebSocket error:', event);
537
+ * };
538
+ * ```
315
539
  */
316
540
  public onWebSocketError: wsErrorCallbackType;
317
541
 
318
542
  /**
319
- * Set it to log the actual raw communication with the broker.
320
- * When unset, it logs headers of the parsed frames.
543
+ * Enable or disable logging of the raw communication with the broker.
321
544
  *
322
- * Changes effect from the next broker reconnect.
545
+ * When enabled, it logs the raw frames exchanged with the broker. If disabled,
546
+ * only the headers of the parsed frames will be logged.
323
547
  *
324
- * **Caution: this assumes that frames only have valid UTF8 strings.**
548
+ * **Caution**: Raw communication frames must contain valid UTF-8 strings,
549
+ * as any non-compliant data can cause errors in the logging process.
550
+ *
551
+ * Changes to this setting will take effect during the next broker reconnect.
552
+ *
553
+ * Example:
554
+ * ```javascript
555
+ * client.logRawCommunication = true; // Enable logging raw communication
556
+ * ```
325
557
  */
326
558
  public logRawCommunication: boolean;
327
559
 
328
560
  /**
329
- * By default, debug messages are discarded. To log to `console` following can be used:
561
+ * Set a custom debug function to capture debug messages.
330
562
  *
563
+ * By default, debug messages are discarded. To log messages to the console, you can use:
331
564
  * ```javascript
332
- * client.debug = function(str) {
333
- * console.log(str);
334
- * };
565
+ * client.debug = (str) => {
566
+ * console.log(str);
567
+ * };
335
568
  * ```
336
569
  *
337
- * Currently this method does not support levels of log. Be aware that the
338
- * output can be quite verbose
339
- * and may contain sensitive information (like passwords, tokens etc.).
570
+ * **Note**: This method does not support configurable log levels, and the output can be
571
+ * verbose. Be cautious as debug messages may contain sensitive information, such as
572
+ * credentials or tokens.
340
573
  */
341
574
  public debug: debugFnType;
342
575
 
343
576
  /**
344
- * Browsers do not immediately close WebSockets when `.close` is issued.
345
- * This may cause reconnection to take a significantly long time in case
346
- * of some types of failures.
347
- * In case of incoming heartbeat failure, this experimental flag instructs
348
- * the library to discard the socket immediately
349
- * (even before it is actually closed).
577
+ * Instruct the library to immediately terminate the socket on communication failures, even
578
+ * before the WebSocket is completely closed.
579
+ *
580
+ * This is particularly useful in browser environments where WebSocket closure may get delayed,
581
+ * causing prolonged reconnection intervals under certain failure conditions.
582
+ *
583
+ *
584
+ * Example:
585
+ * ```javascript
586
+ * client.discardWebsocketOnCommFailure = true; // Enable aggressive closing of WebSocket
587
+ * ```
588
+ *
589
+ * Default value: `false`.
350
590
  */
351
591
  public discardWebsocketOnCommFailure: boolean = false;
352
592
 
353
593
  /**
354
- * version of STOMP protocol negotiated with the server, READONLY
594
+ * The version of the STOMP protocol negotiated with the server during connection.
595
+ *
596
+ * This is a **read-only** property and reflects the negotiated protocol version after
597
+ * a successful connection.
598
+ *
599
+ * Example:
600
+ * ```javascript
601
+ * console.log('Connected STOMP version:', client.connectedVersion);
602
+ * ```
603
+ *
604
+ * @returns The negotiated STOMP protocol version or `undefined` if not connected.
355
605
  */
356
606
  get connectedVersion(): string | undefined {
357
607
  return this._stompHandler ? this._stompHandler.connectedVersion : undefined;
@@ -360,16 +610,38 @@ export class Client {
360
610
  private _stompHandler: StompHandler | undefined;
361
611
 
362
612
  /**
363
- * if the client is active (connected or going to reconnect)
613
+ * Indicates whether the client is currently active.
614
+ *
615
+ * A client is considered active if it is connected or actively attempting to reconnect.
616
+ *
617
+ * Example:
618
+ * ```javascript
619
+ * if (client.active) {
620
+ * console.log('The client is active.');
621
+ * } else {
622
+ * console.log('The client is inactive.');
623
+ * }
624
+ * ```
625
+ *
626
+ * @returns `true` if the client is active, otherwise `false`.
364
627
  */
365
628
  get active(): boolean {
366
629
  return this.state === ActivationState.ACTIVE;
367
630
  }
368
631
 
369
632
  /**
370
- * It will be called on state change.
633
+ * Callback invoked whenever the client's state changes.
634
+ *
635
+ * This callback can be used to monitor transitions between various states, such as `ACTIVE`,
636
+ * `INACTIVE`, or `DEACTIVATING`. Note that in some scenarios, the client may transition
637
+ * directly from `ACTIVE` to `INACTIVE` without entering the `DEACTIVATING` state.
371
638
  *
372
- * When deactivating, it may go from ACTIVE to INACTIVE without entering DEACTIVATING.
639
+ * Example:
640
+ * ```javascript
641
+ * client.onChangeState = (state) => {
642
+ * console.log(`Client state changed to: ${state}`);
643
+ * };
644
+ * ```
373
645
  */
374
646
  public onChangeState: (state: ActivationState) => void;
375
647
 
@@ -379,17 +651,35 @@ export class Client {
379
651
  }
380
652
 
381
653
  /**
382
- * Activation state.
654
+ * Current activation state of the client.
655
+ *
656
+ * Possible states:
657
+ * - `ActivationState.ACTIVE`: Client is connected or actively attempting to connect.
658
+ * - `ActivationState.INACTIVE`: Client is disconnected and not attempting to reconnect.
659
+ * - `ActivationState.DEACTIVATING`: Client is in the process of disconnecting.
383
660
  *
384
- * It will usually be ACTIVE or INACTIVE.
385
- * When deactivating, it may go from ACTIVE to INACTIVE without entering DEACTIVATING.
661
+ * Note: The client may transition directly from `ACTIVE` to `INACTIVE` without entering
662
+ * the `DEACTIVATING` state.
386
663
  */
387
664
  public state: ActivationState = ActivationState.INACTIVE;
388
665
 
389
666
  private _reconnector: any;
390
667
 
391
668
  /**
392
- * Create an instance.
669
+ * Constructs a new STOMP client instance.
670
+ *
671
+ * The constructor initializes default values and sets up no-op callbacks for all events.
672
+ * Configuration can be passed during construction, or updated later using `configure`.
673
+ *
674
+ * Example:
675
+ * ```javascript
676
+ * const client = new Client({
677
+ * brokerURL: 'wss://broker.example.com',
678
+ * reconnectDelay: 5000
679
+ * });
680
+ * ```
681
+ *
682
+ * @param conf Optional configuration object to initialize the client with.
393
683
  */
394
684
  constructor(conf: StompConfig = {}) {
395
685
  // No op callbacks
@@ -401,6 +691,8 @@ export class Client {
401
691
  this.onUnhandledMessage = noOp;
402
692
  this.onUnhandledReceipt = noOp;
403
693
  this.onUnhandledFrame = noOp;
694
+ this.onHeartbeatReceived = noOp;
695
+ this.onHeartbeatLost = noOp;
404
696
  this.onStompError = noOp;
405
697
  this.onWebSocketClose = noOp;
406
698
  this.onWebSocketError = noOp;
@@ -416,8 +708,24 @@ export class Client {
416
708
  }
417
709
 
418
710
  /**
419
- * Update configuration.
711
+ * Updates the client's configuration.
712
+ *
713
+ * All properties in the provided configuration object will override the current settings.
714
+ *
715
+ * Additionally, a warning is logged if `maxReconnectDelay` is configured to a
716
+ * value lower than `reconnectDelay`, and `maxReconnectDelay` is adjusted to match `reconnectDelay`.
717
+ *
718
+ * Example:
719
+ * ```javascript
720
+ * client.configure({
721
+ * reconnectDelay: 3000,
722
+ * maxReconnectDelay: 10000
723
+ * });
724
+ * ```
725
+ *
726
+ * @param conf Configuration object containing the new settings.
420
727
  */
728
+
421
729
  public configure(conf: StompConfig): void {
422
730
  // bulk assign all properties to this
423
731
  (Object as any).assign(this, conf);
@@ -435,12 +743,20 @@ export class Client {
435
743
  }
436
744
 
437
745
  /**
438
- * Initiate the connection with the broker.
439
- * If the connection breaks, as per [Client#reconnectDelay]{@link Client#reconnectDelay},
440
- * it will keep trying to reconnect. If the [Client#reconnectTimeMode]{@link Client#reconnectTimeMode}
441
- * is set to EXPONENTIAL it will increase the wait time exponentially
746
+ * Activates the client, initiating a connection to the STOMP broker.
747
+ *
748
+ * On activation, the client attempts to connect and sets its state to `ACTIVE`. If the connection
749
+ * is lost, it will automatically retry based on `reconnectDelay` or `maxReconnectDelay`. If
750
+ * `reconnectTimeMode` is set to `EXPONENTIAL`, the reconnect delay increases exponentially.
751
+ *
752
+ * To stop reconnection attempts and disconnect, call [Client#deactivate]{@link Client#deactivate}.
753
+ *
754
+ * Example:
755
+ * ```javascript
756
+ * client.activate(); // Connect to the broker
757
+ * ```
442
758
  *
443
- * Call [Client#deactivate]{@link Client#deactivate} to disconnect and stop reconnection attempts.
759
+ * If the client is currently `DEACTIVATING`, connection is delayed until the deactivation process completes.
444
760
  */
445
761
  public activate(): void {
446
762
  const _activate = () => {
@@ -513,6 +829,7 @@ export class Client {
513
829
  connectHeaders: this.connectHeaders,
514
830
  disconnectHeaders: this._disconnectHeaders,
515
831
  heartbeatIncoming: this.heartbeatIncoming,
832
+ heartbeatGracePeriods: this.heartbeatToleranceMultiplier,
516
833
  heartbeatOutgoing: this.heartbeatOutgoing,
517
834
  heartbeatStrategy: this.heartbeatStrategy,
518
835
  splitLargeFrames: this.splitLargeFrames,
@@ -572,6 +889,12 @@ export class Client {
572
889
  onUnhandledFrame: frame => {
573
890
  this.onUnhandledFrame(frame);
574
891
  },
892
+ onHeartbeatReceived: () => {
893
+ this.onHeartbeatReceived();
894
+ },
895
+ onHeartbeatLost: () => {
896
+ this.onHeartbeatLost();
897
+ },
575
898
  });
576
899
 
577
900
  this._stompHandler.start();
@@ -619,27 +942,36 @@ export class Client {
619
942
  }
620
943
 
621
944
  /**
622
- * Disconnect if connected and stop auto reconnect loop.
623
- * Appropriate callbacks will be invoked if there is an underlying STOMP connection.
945
+ * Disconnects the client and stops the automatic reconnection loop.
624
946
  *
625
- * This call is async. It will resolve immediately if there is no underlying active websocket,
626
- * otherwise, it will resolve after the underlying websocket is properly disposed of.
947
+ * If there is an active STOMP connection at the time of invocation, the appropriate callbacks
948
+ * will be triggered during the shutdown sequence. Once deactivated, the client will enter the
949
+ * `INACTIVE` state, and no further reconnection attempts will be made.
627
950
  *
628
- * It is not an error to invoke this method more than once.
629
- * Each of those would resolve on completion of deactivation.
951
+ * **Behavior**:
952
+ * - If there is no active WebSocket connection, this method resolves immediately.
953
+ * - If there is an active connection, the method waits for the underlying WebSocket
954
+ * to properly close before resolving.
955
+ * - Multiple calls to this method are safe. Each invocation resolves upon completion.
956
+ * - To reactivate, call [Client#activate]{@link Client#activate}.
630
957
  *
631
- * To reactivate, you can call [Client#activate]{@link Client#activate}.
958
+ * **Experimental Option:**
959
+ * - By specifying the `force: true` option, the WebSocket connection is discarded immediately,
960
+ * bypassing both the STOMP and WebSocket shutdown sequences.
961
+ * - **Caution:** Using `force: true` may leave the WebSocket in an inconsistent state,
962
+ * and brokers may not immediately detect the termination.
632
963
  *
633
- * Experimental: pass `force: true` to immediately discard the underlying connection.
634
- * This mode will skip both the STOMP and the Websocket shutdown sequences.
635
- * In some cases, browsers take a long time in the Websocket shutdown
636
- * if the underlying connection had gone stale.
637
- * Using this mode can speed up.
638
- * When this mode is used, the actual Websocket may linger for a while
639
- * and the broker may not realize that the connection is no longer in use.
964
+ * Example:
965
+ * ```javascript
966
+ * // Graceful disconnect
967
+ * await client.deactivate();
640
968
  *
641
- * It is possible to invoke this method initially without the `force` option
642
- * and subsequently, say after a wait, with the `force` option.
969
+ * // Forced disconnect to speed up shutdown when the connection is stale
970
+ * await client.deactivate({ force: true });
971
+ * ```
972
+ *
973
+ * @param options Configuration options for deactivation. Use `force: true` for immediate shutdown.
974
+ * @returns A Promise that resolves when the deactivation process completes.
643
975
  */
644
976
  public async deactivate(options: { force?: boolean } = {}): Promise<void> {
645
977
  const force: boolean = options.force || false;
@@ -692,10 +1024,18 @@ export class Client {
692
1024
  }
693
1025
 
694
1026
  /**
695
- * Force disconnect if there is an active connection by directly closing the underlying WebSocket.
696
- * This is different from a normal disconnect where a DISCONNECT sequence is carried out with the broker.
697
- * After forcing disconnect, automatic reconnect will be attempted.
698
- * To stop further reconnects call [Client#deactivate]{@link Client#deactivate} as well.
1027
+ * Forces a disconnect by directly closing the WebSocket.
1028
+ *
1029
+ * Unlike a normal disconnect, this does not send a DISCONNECT sequence to the broker but
1030
+ * instead closes the WebSocket connection directly. After forcing a disconnect, the client
1031
+ * will automatically attempt to reconnect based on its `reconnectDelay` configuration.
1032
+ *
1033
+ * **Note:** To prevent further reconnect attempts, call [Client#deactivate]{@link Client#deactivate}.
1034
+ *
1035
+ * Example:
1036
+ * ```javascript
1037
+ * client.forceDisconnect();
1038
+ * ```
699
1039
  */
700
1040
  public forceDisconnect() {
701
1041
  if (this._stompHandler) {
@@ -711,39 +1051,38 @@ export class Client {
711
1051
  }
712
1052
 
713
1053
  /**
714
- * Send a message to a named destination. Refer to your STOMP broker documentation for types
715
- * and naming of destinations.
716
- *
717
- * STOMP protocol specifies and suggests some headers and also allows broker-specific headers.
718
- *
719
- * `body` must be String.
720
- * You will need to covert the payload to string in case it is not string (e.g. JSON).
1054
+ * Sends a message to the specified destination on the STOMP broker.
721
1055
  *
722
- * To send a binary message body, use `binaryBody` parameter. It should be a
723
- * [Uint8Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array).
724
- * Sometimes brokers may not support binary frames out of the box.
725
- * Please check your broker documentation.
1056
+ * The `body` must be a `string`. For non-string payloads (e.g., JSON), encode it as a string before sending.
1057
+ * If sending binary data, use the `binaryBody` parameter as a [Uint8Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array).
726
1058
  *
727
- * `content-length` header is automatically added to the STOMP Frame sent to the broker.
728
- * Set `skipContentLengthHeader` to indicate that `content-length` header should not be added.
729
- * For binary messages, `content-length` header is always added.
1059
+ * **Content-Length Behavior**:
1060
+ * - For non-binary messages, the `content-length` header is added by default.
1061
+ * - The `content-length` header can be skipped for text frames by setting `skipContentLengthHeader: true` in the parameters.
1062
+ * - For binary messages, the `content-length` header is always included.
730
1063
  *
731
- * Caution: The broker will, most likely, report an error and disconnect
732
- * if the message body has NULL octet(s) and `content-length` header is missing.
1064
+ * **Notes**:
1065
+ * - Ensure that brokers support binary frames before using `binaryBody`.
1066
+ * - Sending messages with NULL octets and missing `content-length` headers can cause brokers to disconnect and throw errors.
733
1067
  *
1068
+ * Example:
734
1069
  * ```javascript
735
- * client.publish({destination: "/queue/test", headers: {priority: 9}, body: "Hello, STOMP"});
736
- *
737
- * // Only destination is mandatory parameter
738
- * client.publish({destination: "/queue/test", body: "Hello, STOMP"});
739
- *
740
- * // Skip content-length header in the frame to the broker
741
- * client.publish({"/queue/test", body: "Hello, STOMP", skipContentLengthHeader: true});
742
- *
743
- * var binaryData = generateBinaryData(); // This need to be of type Uint8Array
744
- * // setting content-type header is not mandatory, however a good practice
745
- * client.publish({destination: '/topic/special', binaryBody: binaryData,
746
- * headers: {'content-type': 'application/octet-stream'}});
1070
+ * // Basic text message
1071
+ * client.publish({ destination: "/queue/test", body: "Hello, STOMP" });
1072
+ *
1073
+ * // Text message with additional headers
1074
+ * client.publish({ destination: "/queue/test", headers: { priority: 9 }, body: "Hello, STOMP" });
1075
+ *
1076
+ * // Skip content-length header
1077
+ * client.publish({ destination: "/queue/test", body: "Hello, STOMP", skipContentLengthHeader: true });
1078
+ *
1079
+ * // Binary message
1080
+ * const binaryData = new Uint8Array([1, 2, 3, 4]);
1081
+ * client.publish({
1082
+ * destination: '/topic/special',
1083
+ * binaryBody: binaryData,
1084
+ * headers: { 'content-type': 'application/octet-stream' }
1085
+ * });
747
1086
  * ```
748
1087
  */
749
1088
  public publish(params: IPublishParams) {
@@ -759,39 +1098,27 @@ export class Client {
759
1098
  }
760
1099
 
761
1100
  /**
762
- * STOMP brokers may carry out operation asynchronously and allow requesting for acknowledgement.
763
- * To request an acknowledgement, a `receipt` header needs to be sent with the actual request.
764
- * The value (say receipt-id) for this header needs to be unique for each use.
765
- * Typically, a sequence, a UUID, a random number or a combination may be used.
766
- *
767
- * A complaint broker will send a RECEIPT frame when an operation has actually been completed.
768
- * The operation needs to be matched based on the value of the receipt-id.
1101
+ * Monitors for a receipt acknowledgment from the broker for specific operations.
769
1102
  *
770
- * This method allows watching for a receipt and invoking the callback
771
- * when the corresponding receipt has been received.
1103
+ * Add a `receipt` header to the operation (like subscribe or publish), and use this method with
1104
+ * the same receipt ID to detect when the broker has acknowledged the operation's completion.
772
1105
  *
773
- * The actual {@link IFrame} will be passed as parameter to the callback.
1106
+ * The callback is invoked with the corresponding {@link IFrame} when the receipt is received.
774
1107
  *
775
1108
  * Example:
776
1109
  * ```javascript
777
- * // Subscribing with acknowledgement
778
- * let receiptId = randomText();
779
- *
780
- * client.watchForReceipt(receiptId, function() {
781
- * // Will be called after server acknowledges
782
- * });
1110
+ * const receiptId = "unique-receipt-id";
783
1111
  *
784
- * client.subscribe(TEST.destination, onMessage, {receipt: receiptId});
1112
+ * client.watchForReceipt(receiptId, (frame) => {
1113
+ * console.log("Operation acknowledged by the broker:", frame);
1114
+ * });
785
1115
  *
786
- *
787
- * // Publishing with acknowledgement
788
- * receiptId = randomText();
789
- *
790
- * client.watchForReceipt(receiptId, function() {
791
- * // Will be called after server acknowledges
792
- * });
793
- * client.publish({destination: TEST.destination, headers: {receipt: receiptId}, body: msg});
1116
+ * // Attach the receipt header to an operation
1117
+ * client.publish({ destination: "/queue/test", headers: { receipt: receiptId }, body: "Hello" });
794
1118
  * ```
1119
+ *
1120
+ * @param receiptId Unique identifier for the receipt.
1121
+ * @param callback Callback function invoked on receiving the RECEIPT frame.
795
1122
  */
796
1123
  public watchForReceipt(receiptId: string, callback: frameCallbackType): void {
797
1124
  this._checkConnection();
@@ -800,28 +1127,33 @@ export class Client {
800
1127
  }
801
1128
 
802
1129
  /**
803
- * Subscribe to a STOMP Broker location. The callback will be invoked for each
804
- * received message with the {@link IMessage} as argument.
1130
+ * Subscribes to a destination on the STOMP broker.
1131
+ *
1132
+ * The callback is triggered for each message received from the subscribed destination. The message
1133
+ * is passed as an {@link IMessage} instance.
805
1134
  *
806
- * Note: The library will generate a unique ID if there is none provided in the headers.
807
- * To use your own ID, pass it using the `headers` argument.
1135
+ * **Subscription ID**:
1136
+ * - If no `id` is provided in `headers`, the library generates a unique subscription ID automatically.
1137
+ * - Provide an explicit `id` in `headers` if you wish to manage the subscription ID manually.
808
1138
  *
1139
+ * Example:
809
1140
  * ```javascript
810
- * callback = function(message) {
811
- * // called when the client receives a STOMP message from the server
812
- * if (message.body) {
813
- * alert("got message with body " + message.body)
814
- * } else {
815
- * alert("got empty message");
816
- * }
817
- * });
1141
+ * const callback = (message) => {
1142
+ * console.log("Received message:", message.body);
1143
+ * };
818
1144
  *
819
- * var subscription = client.subscribe("/queue/test", callback);
1145
+ * // Auto-generated subscription ID
1146
+ * const subscription = client.subscribe("/queue/test", callback);
820
1147
  *
821
- * // Explicit subscription id
822
- * var mySubId = 'my-subscription-id-001';
823
- * var subscription = client.subscribe(destination, callback, { id: mySubId });
1148
+ * // Explicit subscription ID
1149
+ * const mySubId = "my-subscription-id";
1150
+ * const subscription = client.subscribe("/queue/test", callback, { id: mySubId });
824
1151
  * ```
1152
+ *
1153
+ * @param destination Destination to subscribe to.
1154
+ * @param callback Function invoked for each received message.
1155
+ * @param headers Optional headers for subscription, such as `id`.
1156
+ * @returns A {@link StompSubscription} which can be used to manage the subscription.
825
1157
  */
826
1158
  public subscribe(
827
1159
  destination: string,
@@ -834,16 +1166,24 @@ export class Client {
834
1166
  }
835
1167
 
836
1168
  /**
837
- * It is preferable to unsubscribe from a subscription by calling
838
- * `unsubscribe()` directly on {@link StompSubscription} returned by `client.subscribe()`:
1169
+ * Unsubscribes from a subscription on the STOMP broker.
839
1170
  *
1171
+ * Prefer using the `unsubscribe` method directly on the {@link StompSubscription} returned from `subscribe` for cleaner management:
840
1172
  * ```javascript
841
- * var subscription = client.subscribe(destination, onmessage);
842
- * // ...
843
- * subscription.unsubscribe();
1173
+ * const subscription = client.subscribe("/queue/test", callback);
1174
+ * // Unsubscribe using the subscription object
1175
+ * subscription.unsubscribe();
844
1176
  * ```
845
1177
  *
846
- * See: https://stomp.github.com/stomp-specification-1.2.html#UNSUBSCRIBE UNSUBSCRIBE Frame
1178
+ * This method can also be used directly with the subscription ID.
1179
+ *
1180
+ * Example:
1181
+ * ```javascript
1182
+ * client.unsubscribe("my-subscription-id");
1183
+ * ```
1184
+ *
1185
+ * @param id Subscription ID to unsubscribe.
1186
+ * @param headers Optional headers to pass for the UNSUBSCRIBE frame.
847
1187
  */
848
1188
  public unsubscribe(id: string, headers: StompHeaders = {}): void {
849
1189
  this._checkConnection();
@@ -852,10 +1192,21 @@ export class Client {
852
1192
  }
853
1193
 
854
1194
  /**
855
- * Start a transaction, the returned {@link ITransaction} has methods - [commit]{@link ITransaction#commit}
856
- * and [abort]{@link ITransaction#abort}.
1195
+ * Starts a new transaction. The returned {@link ITransaction} object provides
1196
+ * methods for [commit]{@link ITransaction#commit} and [abort]{@link ITransaction#abort}.
1197
+ *
1198
+ * If `transactionId` is not provided, the library generates a unique ID internally.
1199
+ *
1200
+ * Example:
1201
+ * ```javascript
1202
+ * const tx = client.begin(); // Auto-generated ID
1203
+ *
1204
+ * // Or explicitly specify a transaction ID
1205
+ * const tx = client.begin("my-transaction-id");
1206
+ * ```
857
1207
  *
858
- * `transactionId` is optional, if not passed the library will generate it internally.
1208
+ * @param transactionId Optional transaction ID.
1209
+ * @returns An instance of {@link ITransaction}.
859
1210
  */
860
1211
  public begin(transactionId?: string): ITransaction {
861
1212
  this._checkConnection();
@@ -864,16 +1215,19 @@ export class Client {
864
1215
  }
865
1216
 
866
1217
  /**
867
- * Commit a transaction.
868
- *
869
- * It is preferable to commit a transaction by calling [commit]{@link ITransaction#commit} directly on
870
- * {@link ITransaction} returned by [client.begin]{@link Client#begin}.
871
- *
1218
+ * Commits a transaction.
1219
+ *
1220
+ * It is strongly recommended to call [commit]{@link ITransaction#commit} on
1221
+ * the transaction object returned by [client#begin]{@link Client#begin}.
1222
+ *
1223
+ * Example:
872
1224
  * ```javascript
873
- * var tx = client.begin(txId);
874
- * //...
875
- * tx.commit();
1225
+ * const tx = client.begin();
1226
+ * // Perform operations under this transaction
1227
+ * tx.commit();
876
1228
  * ```
1229
+ *
1230
+ * @param transactionId The ID of the transaction to commit.
877
1231
  */
878
1232
  public commit(transactionId: string): void {
879
1233
  this._checkConnection();
@@ -882,15 +1236,19 @@ export class Client {
882
1236
  }
883
1237
 
884
1238
  /**
885
- * Abort a transaction.
886
- * It is preferable to abort a transaction by calling [abort]{@link ITransaction#abort} directly on
887
- * {@link ITransaction} returned by [client.begin]{@link Client#begin}.
888
- *
1239
+ * Aborts a transaction.
1240
+ *
1241
+ * It is strongly recommended to call [abort]{@link ITransaction#abort} directly
1242
+ * on the transaction object returned by [client#begin]{@link Client#begin}.
1243
+ *
1244
+ * Example:
889
1245
  * ```javascript
890
- * var tx = client.begin(txId);
891
- * //...
892
- * tx.abort();
1246
+ * const tx = client.begin();
1247
+ * // Perform operations under this transaction
1248
+ * tx.abort(); // Abort the transaction
893
1249
  * ```
1250
+ *
1251
+ * @param transactionId The ID of the transaction to abort.
894
1252
  */
895
1253
  public abort(transactionId: string): void {
896
1254
  this._checkConnection();
@@ -899,17 +1257,23 @@ export class Client {
899
1257
  }
900
1258
 
901
1259
  /**
902
- * ACK a message. It is preferable to acknowledge a message by calling [ack]{@link IMessage#ack} directly
903
- * on the {@link IMessage} handled by a subscription callback:
904
- *
1260
+ * Acknowledges receipt of a message. Typically, this should be done by calling
1261
+ * [ack]{@link IMessage#ack} directly on the {@link IMessage} instance passed
1262
+ * to the subscription callback.
1263
+ *
1264
+ * Example:
905
1265
  * ```javascript
906
- * var callback = function (message) {
907
- * // process the message
908
- * // acknowledge it
909
- * message.ack();
910
- * };
911
- * client.subscribe(destination, callback, {'ack': 'client'});
1266
+ * const callback = (message) => {
1267
+ * // Process the message
1268
+ * message.ack(); // Acknowledge the message
1269
+ * };
1270
+ *
1271
+ * client.subscribe("/queue/example", callback, { ack: "client" });
912
1272
  * ```
1273
+ *
1274
+ * @param messageId The ID of the message to acknowledge.
1275
+ * @param subscriptionId The ID of the subscription.
1276
+ * @param headers Optional headers for the acknowledgment frame.
913
1277
  */
914
1278
  public ack(
915
1279
  messageId: string,
@@ -922,17 +1286,25 @@ export class Client {
922
1286
  }
923
1287
 
924
1288
  /**
925
- * NACK a message. It is preferable to acknowledge a message by calling [nack]{@link IMessage#nack} directly
926
- * on the {@link IMessage} handled by a subscription callback:
927
- *
1289
+ * Rejects a message (negative acknowledgment). Like acknowledgments, this should
1290
+ * typically be done by calling [nack]{@link IMessage#nack} directly on the {@link IMessage}
1291
+ * instance passed to the subscription callback.
1292
+ *
1293
+ * Example:
928
1294
  * ```javascript
929
- * var callback = function (message) {
930
- * // process the message
931
- * // an error occurs, nack it
932
- * message.nack();
933
- * };
934
- * client.subscribe(destination, callback, {'ack': 'client'});
1295
+ * const callback = (message) => {
1296
+ * // Process the message
1297
+ * if (isError(message)) {
1298
+ * message.nack(); // Reject the message
1299
+ * }
1300
+ * };
1301
+ *
1302
+ * client.subscribe("/queue/example", callback, { ack: "client" });
935
1303
  * ```
1304
+ *
1305
+ * @param messageId The ID of the message to negatively acknowledge.
1306
+ * @param subscriptionId The ID of the subscription.
1307
+ * @param headers Optional headers for the NACK frame.
936
1308
  */
937
1309
  public nack(
938
1310
  messageId: string,