@stomp/stompjs 6.1.1 → 7.0.0-beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/bundles/stomp.umd.js +325 -308
  2. package/bundles/stomp.umd.min.js +1 -2
  3. package/esm6/augment-websocket.js +4 -3
  4. package/esm6/augment-websocket.js.map +1 -0
  5. package/esm6/byte.js.map +1 -0
  6. package/esm6/client.d.ts +29 -13
  7. package/esm6/client.js +75 -16
  8. package/esm6/client.js.map +1 -0
  9. package/esm6/compatibility/compat-client.d.ts +26 -20
  10. package/esm6/compatibility/compat-client.js.map +1 -0
  11. package/esm6/compatibility/heartbeat-info.d.ts +4 -2
  12. package/esm6/compatibility/heartbeat-info.js.map +1 -0
  13. package/esm6/compatibility/stomp.js.map +1 -0
  14. package/esm6/frame-impl.d.ts +2 -2
  15. package/esm6/frame-impl.js +2 -1
  16. package/esm6/frame-impl.js.map +1 -0
  17. package/esm6/i-frame.js +1 -0
  18. package/esm6/i-frame.js.map +1 -0
  19. package/esm6/i-message.js +1 -0
  20. package/esm6/i-message.js.map +1 -0
  21. package/esm6/i-transaction.js +1 -0
  22. package/esm6/i-transaction.js.map +1 -0
  23. package/esm6/index.js +3 -0
  24. package/esm6/index.js.map +1 -0
  25. package/esm6/parser.js +10 -2
  26. package/esm6/parser.js.map +1 -0
  27. package/esm6/stomp-config.js.map +1 -0
  28. package/esm6/stomp-handler.d.ts +5 -8
  29. package/esm6/stomp-handler.js +33 -15
  30. package/esm6/stomp-handler.js.map +1 -0
  31. package/esm6/stomp-headers.js.map +1 -0
  32. package/esm6/stomp-subscription.d.ts +1 -1
  33. package/esm6/stomp-subscription.js +1 -7
  34. package/esm6/stomp-subscription.js.map +1 -0
  35. package/esm6/types.d.ts +28 -2
  36. package/esm6/types.js.map +1 -0
  37. package/esm6/versions.js +2 -2
  38. package/esm6/versions.js.map +1 -0
  39. package/package.json +26 -24
  40. package/src/augment-websocket.ts +39 -0
  41. package/src/byte.ts +13 -0
  42. package/src/client.ts +858 -0
  43. package/src/compatibility/compat-client.ts +269 -0
  44. package/src/compatibility/heartbeat-info.ts +26 -0
  45. package/src/compatibility/stomp.ts +118 -0
  46. package/src/frame-impl.ts +254 -0
  47. package/src/i-frame.ts +41 -0
  48. package/src/i-message.ts +35 -0
  49. package/src/i-transaction.ts +23 -0
  50. package/src/index.ts +15 -0
  51. package/src/parser.ts +267 -0
  52. package/src/stomp-config.ts +152 -0
  53. package/src/stomp-handler.ts +555 -0
  54. package/src/stomp-headers.ts +12 -0
  55. package/src/stomp-subscription.ts +18 -0
  56. package/src/types.ts +183 -0
  57. package/src/versions.ts +50 -0
@@ -0,0 +1,269 @@
1
+ import { Client } from '../client';
2
+ import { StompHeaders } from '../stomp-headers';
3
+ import { frameCallbackType, messageCallbackType } from '../types';
4
+ import { HeartbeatInfo } from './heartbeat-info';
5
+
6
+ /**
7
+ * Available for backward compatibility, please shift to using {@link Client}.
8
+ *
9
+ * **Deprecated**
10
+ *
11
+ * Part of `@stomp/stompjs`.
12
+ *
13
+ * To upgrade, please follow the [Upgrade Guide](../additional-documentation/upgrading.html)
14
+ */
15
+ export class CompatClient extends Client {
16
+ /**
17
+ * It is no op now. No longer needed. Large packets work out of the box.
18
+ */
19
+ public maxWebSocketFrameSize: number = 16 * 1024;
20
+
21
+ /**
22
+ * Available for backward compatibility, please shift to using {@link Client}
23
+ * and [Client#webSocketFactory]{@link Client#webSocketFactory}.
24
+ *
25
+ * **Deprecated**
26
+ *
27
+ * @internal
28
+ */
29
+ constructor(webSocketFactory: () => any) {
30
+ super();
31
+ this.reconnect_delay = 0;
32
+ this.webSocketFactory = webSocketFactory;
33
+ // Default from previous version
34
+ this.debug = (...message: any[]) => {
35
+ console.log(...message);
36
+ };
37
+ }
38
+
39
+ private _parseConnect(...args: any[]): any {
40
+ let closeEventCallback;
41
+ let connectCallback;
42
+ let errorCallback;
43
+ let headers: StompHeaders = {};
44
+ if (args.length < 2) {
45
+ throw new Error('Connect requires at least 2 arguments');
46
+ }
47
+ if (typeof args[1] === 'function') {
48
+ [headers, connectCallback, errorCallback, closeEventCallback] = args;
49
+ } else {
50
+ switch (args.length) {
51
+ case 6:
52
+ [
53
+ headers.login,
54
+ headers.passcode,
55
+ connectCallback,
56
+ errorCallback,
57
+ closeEventCallback,
58
+ headers.host,
59
+ ] = args;
60
+ break;
61
+ default:
62
+ [
63
+ headers.login,
64
+ headers.passcode,
65
+ connectCallback,
66
+ errorCallback,
67
+ closeEventCallback,
68
+ ] = args;
69
+ }
70
+ }
71
+
72
+ return [headers, connectCallback, errorCallback, closeEventCallback];
73
+ }
74
+
75
+ /**
76
+ * Available for backward compatibility, please shift to using [Client#activate]{@link Client#activate}.
77
+ *
78
+ * **Deprecated**
79
+ *
80
+ * The `connect` method accepts different number of arguments and types. See the Overloads list. Use the
81
+ * version with headers to pass your broker specific options.
82
+ *
83
+ * overloads:
84
+ * - connect(headers, connectCallback)
85
+ * - connect(headers, connectCallback, errorCallback)
86
+ * - connect(login, passcode, connectCallback)
87
+ * - connect(login, passcode, connectCallback, errorCallback)
88
+ * - connect(login, passcode, connectCallback, errorCallback, closeEventCallback)
89
+ * - connect(login, passcode, connectCallback, errorCallback, closeEventCallback, host)
90
+ *
91
+ * params:
92
+ * - headers, see [Client#connectHeaders]{@link Client#connectHeaders}
93
+ * - connectCallback, see [Client#onConnect]{@link Client#onConnect}
94
+ * - errorCallback, see [Client#onStompError]{@link Client#onStompError}
95
+ * - closeEventCallback, see [Client#onWebSocketClose]{@link Client#onWebSocketClose}
96
+ * - login [String], see [Client#connectHeaders](../classes/Client.html#connectHeaders)
97
+ * - passcode [String], [Client#connectHeaders](../classes/Client.html#connectHeaders)
98
+ * - host [String], see [Client#connectHeaders](../classes/Client.html#connectHeaders)
99
+ *
100
+ * To upgrade, please follow the [Upgrade Guide](../additional-documentation/upgrading.html)
101
+ */
102
+ public connect(...args: any[]): void {
103
+ const out = this._parseConnect(...args);
104
+
105
+ if (out[0]) {
106
+ this.connectHeaders = out[0];
107
+ }
108
+ if (out[1]) {
109
+ this.onConnect = out[1];
110
+ }
111
+ if (out[2]) {
112
+ this.onStompError = out[2];
113
+ }
114
+ if (out[3]) {
115
+ this.onWebSocketClose = out[3];
116
+ }
117
+
118
+ super.activate();
119
+ }
120
+
121
+ /**
122
+ * Available for backward compatibility, please shift to using [Client#deactivate]{@link Client#deactivate}.
123
+ *
124
+ * **Deprecated**
125
+ *
126
+ * See:
127
+ * [Client#onDisconnect]{@link Client#onDisconnect}, and
128
+ * [Client#disconnectHeaders]{@link Client#disconnectHeaders}
129
+ *
130
+ * To upgrade, please follow the [Upgrade Guide](../additional-documentation/upgrading.html)
131
+ */
132
+ public disconnect(
133
+ disconnectCallback?: any,
134
+ headers: StompHeaders = {}
135
+ ): void {
136
+ if (disconnectCallback) {
137
+ this.onDisconnect = disconnectCallback;
138
+ }
139
+ this.disconnectHeaders = headers;
140
+
141
+ super.deactivate();
142
+ }
143
+
144
+ /**
145
+ * Available for backward compatibility, use [Client#publish]{@link Client#publish}.
146
+ *
147
+ * Send a message to a named destination. Refer to your STOMP broker documentation for types
148
+ * and naming of destinations. The headers will, typically, be available to the subscriber.
149
+ * However, there may be special purpose headers corresponding to your STOMP broker.
150
+ *
151
+ * **Deprecated**, use [Client#publish]{@link Client#publish}
152
+ *
153
+ * Note: Body must be String. You will need to covert the payload to string in case it is not string (e.g. JSON)
154
+ *
155
+ * ```javascript
156
+ * client.send("/queue/test", {priority: 9}, "Hello, STOMP");
157
+ *
158
+ * // If you want to send a message with a body, you must also pass the headers argument.
159
+ * client.send("/queue/test", {}, "Hello, STOMP");
160
+ * ```
161
+ *
162
+ * To upgrade, please follow the [Upgrade Guide](../additional-documentation/upgrading.html)
163
+ */
164
+ public send(
165
+ destination: string,
166
+ headers: { [key: string]: any } = {},
167
+ body: string = ''
168
+ ): void {
169
+ headers = (Object as any).assign({}, headers);
170
+
171
+ const skipContentLengthHeader = headers['content-length'] === false;
172
+ if (skipContentLengthHeader) {
173
+ delete headers['content-length'];
174
+ }
175
+ this.publish({
176
+ destination,
177
+ headers: headers as StompHeaders,
178
+ body,
179
+ skipContentLengthHeader,
180
+ });
181
+ }
182
+
183
+ /**
184
+ * Available for backward compatibility, renamed to [Client#reconnectDelay]{@link Client#reconnectDelay}.
185
+ *
186
+ * **Deprecated**
187
+ */
188
+ set reconnect_delay(value: number) {
189
+ this.reconnectDelay = value;
190
+ }
191
+
192
+ /**
193
+ * Available for backward compatibility, renamed to [Client#webSocket]{@link Client#webSocket}.
194
+ *
195
+ * **Deprecated**
196
+ */
197
+ get ws(): any {
198
+ return this.webSocket;
199
+ }
200
+
201
+ /**
202
+ * Available for backward compatibility, renamed to [Client#connectedVersion]{@link Client#connectedVersion}.
203
+ *
204
+ * **Deprecated**
205
+ */
206
+ get version() {
207
+ return this.connectedVersion;
208
+ }
209
+
210
+ /**
211
+ * Available for backward compatibility, renamed to [Client#onUnhandledMessage]{@link Client#onUnhandledMessage}.
212
+ *
213
+ * **Deprecated**
214
+ */
215
+ get onreceive(): messageCallbackType {
216
+ return this.onUnhandledMessage;
217
+ }
218
+
219
+ /**
220
+ * Available for backward compatibility, renamed to [Client#onUnhandledMessage]{@link Client#onUnhandledMessage}.
221
+ *
222
+ * **Deprecated**
223
+ */
224
+ set onreceive(value: messageCallbackType) {
225
+ this.onUnhandledMessage = value;
226
+ }
227
+
228
+ /**
229
+ * Available for backward compatibility, renamed to [Client#onUnhandledReceipt]{@link Client#onUnhandledReceipt}.
230
+ * Prefer using [Client#watchForReceipt]{@link Client#watchForReceipt}.
231
+ *
232
+ * **Deprecated**
233
+ */
234
+ get onreceipt(): frameCallbackType {
235
+ return this.onUnhandledReceipt;
236
+ }
237
+
238
+ /**
239
+ * Available for backward compatibility, renamed to [Client#onUnhandledReceipt]{@link Client#onUnhandledReceipt}.
240
+ *
241
+ * **Deprecated**
242
+ */
243
+ set onreceipt(value: frameCallbackType) {
244
+ this.onUnhandledReceipt = value;
245
+ }
246
+
247
+ private _heartbeatInfo: HeartbeatInfo = new HeartbeatInfo(this);
248
+
249
+ /**
250
+ * Available for backward compatibility, renamed to [Client#heartbeatIncoming]{@link Client#heartbeatIncoming}
251
+ * [Client#heartbeatOutgoing]{@link Client#heartbeatOutgoing}.
252
+ *
253
+ * **Deprecated**
254
+ */
255
+ get heartbeat() {
256
+ return this._heartbeatInfo;
257
+ }
258
+
259
+ /**
260
+ * Available for backward compatibility, renamed to [Client#heartbeatIncoming]{@link Client#heartbeatIncoming}
261
+ * [Client#heartbeatOutgoing]{@link Client#heartbeatOutgoing}.
262
+ *
263
+ * **Deprecated**
264
+ */
265
+ set heartbeat(value: { incoming: number; outgoing: number }) {
266
+ this.heartbeatIncoming = value.incoming;
267
+ this.heartbeatOutgoing = value.outgoing;
268
+ }
269
+ }
@@ -0,0 +1,26 @@
1
+ import { CompatClient } from './compat-client';
2
+
3
+ /**
4
+ * Part of `@stomp/stompjs`.
5
+ *
6
+ * @internal
7
+ */
8
+ export class HeartbeatInfo {
9
+ constructor(private client: CompatClient) {}
10
+
11
+ get outgoing(): number {
12
+ return this.client.heartbeatOutgoing;
13
+ }
14
+
15
+ set outgoing(value: number) {
16
+ this.client.heartbeatOutgoing = value;
17
+ }
18
+
19
+ get incoming(): number {
20
+ return this.client.heartbeatIncoming;
21
+ }
22
+
23
+ set incoming(value: number) {
24
+ this.client.heartbeatIncoming = value;
25
+ }
26
+ }
@@ -0,0 +1,118 @@
1
+ import { Versions } from '../versions';
2
+ import { CompatClient } from './compat-client';
3
+ import { IStompSocket } from '../types';
4
+
5
+ /**
6
+ * @internal
7
+ */
8
+ declare const WebSocket: {
9
+ prototype: IStompSocket;
10
+ new (url: string, protocols?: string | string[]): IStompSocket;
11
+ };
12
+
13
+ /**
14
+ * STOMP Class, acts like a factory to create {@link Client}.
15
+ *
16
+ * Part of `@stomp/stompjs`.
17
+ *
18
+ * **Deprecated**
19
+ *
20
+ * It will be removed in next major version. Please switch to {@link Client}.
21
+ */
22
+ export class Stomp {
23
+ /**
24
+ * In case you need to use a non standard class for WebSocket.
25
+ *
26
+ * For example when using within NodeJS environment:
27
+ *
28
+ * ```javascript
29
+ * StompJs = require('../../esm5/');
30
+ * Stomp = StompJs.Stomp;
31
+ * Stomp.WebSocketClass = require('websocket').w3cwebsocket;
32
+ * ```
33
+ *
34
+ * **Deprecated**
35
+ *
36
+ *
37
+ * It will be removed in next major version. Please switch to {@link Client}
38
+ * using [Client#webSocketFactory]{@link Client#webSocketFactory}.
39
+ */
40
+ // tslint:disable-next-line:variable-name
41
+ public static WebSocketClass: any = null;
42
+
43
+ /**
44
+ * This method creates a WebSocket client that is connected to
45
+ * the STOMP server located at the url.
46
+ *
47
+ * ```javascript
48
+ * var url = "ws://localhost:61614/stomp";
49
+ * var client = Stomp.client(url);
50
+ * ```
51
+ *
52
+ * **Deprecated**
53
+ *
54
+ * It will be removed in next major version. Please switch to {@link Client}
55
+ * using [Client#brokerURL]{@link Client#brokerURL}.
56
+ */
57
+ public static client(url: string, protocols?: string[]): CompatClient {
58
+ // This is a hack to allow another implementation than the standard
59
+ // HTML5 WebSocket class.
60
+ //
61
+ // It is possible to use another class by calling
62
+ //
63
+ // Stomp.WebSocketClass = MozWebSocket
64
+ //
65
+ // *prior* to call `Stomp.client()`.
66
+ //
67
+ // This hack is deprecated and `Stomp.over()` method should be used
68
+ // instead.
69
+
70
+ // See remarks on the function Stomp.over
71
+ if (protocols == null) {
72
+ protocols = Versions.default.protocolVersions();
73
+ }
74
+ const wsFn = () => {
75
+ const klass = Stomp.WebSocketClass || WebSocket;
76
+ return new klass(url, protocols);
77
+ };
78
+
79
+ return new CompatClient(wsFn);
80
+ }
81
+
82
+ /**
83
+ * This method is an alternative to [Stomp#client]{@link Stomp#client} to let the user
84
+ * specify the WebSocket to use (either a standard HTML5 WebSocket or
85
+ * a similar object).
86
+ *
87
+ * In order to support reconnection, the function Client._connect should be callable more than once.
88
+ * While reconnecting
89
+ * a new instance of underlying transport (TCP Socket, WebSocket or SockJS) will be needed. So, this function
90
+ * alternatively allows passing a function that should return a new instance of the underlying socket.
91
+ *
92
+ * ```javascript
93
+ * var client = Stomp.over(function(){
94
+ * return new WebSocket('ws://localhost:15674/ws')
95
+ * });
96
+ * ```
97
+ *
98
+ * **Deprecated**
99
+ *
100
+ * It will be removed in next major version. Please switch to {@link Client}
101
+ * using [Client#webSocketFactory]{@link Client#webSocketFactory}.
102
+ */
103
+ public static over(ws: any): CompatClient {
104
+ let wsFn: () => any;
105
+
106
+ if (typeof ws === 'function') {
107
+ wsFn = ws;
108
+ } else {
109
+ console.warn(
110
+ 'Stomp.over did not receive a factory, auto reconnect will not work. ' +
111
+ 'Please see https://stomp-js.github.io/api-docs/latest/classes/Stomp.html#over'
112
+ );
113
+ wsFn = () => ws;
114
+ }
115
+
116
+ return new CompatClient(wsFn);
117
+ }
118
+ }
@@ -0,0 +1,254 @@
1
+ import { BYTE } from './byte';
2
+ import { IFrame } from './i-frame';
3
+ import { StompHeaders } from './stomp-headers';
4
+ import { IRawFrameType } from './types';
5
+
6
+ /**
7
+ * Frame class represents a STOMP frame.
8
+ *
9
+ * @internal
10
+ */
11
+ export class FrameImpl implements IFrame {
12
+ /**
13
+ * STOMP Command
14
+ */
15
+ public command: string;
16
+
17
+ /**
18
+ * Headers, key value pairs.
19
+ */
20
+ public headers: StompHeaders;
21
+
22
+ /**
23
+ * Is this frame binary (based on whether body/binaryBody was passed when creating this frame).
24
+ */
25
+ public isBinaryBody: boolean;
26
+
27
+ /**
28
+ * body of the frame
29
+ */
30
+ get body(): string {
31
+ if (!this._body && this.isBinaryBody) {
32
+ this._body = new TextDecoder().decode(this._binaryBody);
33
+ }
34
+ return this._body || '';
35
+ }
36
+ private _body: string | undefined;
37
+
38
+ /**
39
+ * body as Uint8Array
40
+ */
41
+ get binaryBody(): Uint8Array {
42
+ if (!this._binaryBody && !this.isBinaryBody) {
43
+ this._binaryBody = new TextEncoder().encode(this._body);
44
+ }
45
+ // At this stage it will definitely have a valid value
46
+ return this._binaryBody as Uint8Array;
47
+ }
48
+ private _binaryBody: Uint8Array | undefined;
49
+
50
+ private escapeHeaderValues: boolean;
51
+ private skipContentLengthHeader: boolean;
52
+
53
+ /**
54
+ * Frame constructor. `command`, `headers` and `body` are available as properties.
55
+ *
56
+ * @internal
57
+ */
58
+ constructor(params: {
59
+ command: string;
60
+ headers?: StompHeaders;
61
+ body?: string;
62
+ binaryBody?: Uint8Array;
63
+ escapeHeaderValues?: boolean;
64
+ skipContentLengthHeader?: boolean;
65
+ }) {
66
+ const {
67
+ command,
68
+ headers,
69
+ body,
70
+ binaryBody,
71
+ escapeHeaderValues,
72
+ skipContentLengthHeader,
73
+ } = params;
74
+ this.command = command;
75
+ this.headers = (Object as any).assign({}, headers || {});
76
+
77
+ if (binaryBody) {
78
+ this._binaryBody = binaryBody;
79
+ this.isBinaryBody = true;
80
+ } else {
81
+ this._body = body || '';
82
+ this.isBinaryBody = false;
83
+ }
84
+ this.escapeHeaderValues = escapeHeaderValues || false;
85
+ this.skipContentLengthHeader = skipContentLengthHeader || false;
86
+ }
87
+
88
+ /**
89
+ * deserialize a STOMP Frame from raw data.
90
+ *
91
+ * @internal
92
+ */
93
+ public static fromRawFrame(
94
+ rawFrame: IRawFrameType,
95
+ escapeHeaderValues: boolean
96
+ ): FrameImpl {
97
+ const headers: StompHeaders = {};
98
+ const trim = (str: string): string => str.replace(/^\s+|\s+$/g, '');
99
+
100
+ // In case of repeated headers, as per standards, first value need to be used
101
+ for (const header of rawFrame.headers.reverse()) {
102
+ const idx = header.indexOf(':');
103
+
104
+ const key = trim(header[0]);
105
+ let value = trim(header[1]);
106
+
107
+ if (
108
+ escapeHeaderValues &&
109
+ rawFrame.command !== 'CONNECT' &&
110
+ rawFrame.command !== 'CONNECTED'
111
+ ) {
112
+ value = FrameImpl.hdrValueUnEscape(value);
113
+ }
114
+
115
+ headers[key] = value;
116
+ }
117
+
118
+ return new FrameImpl({
119
+ command: rawFrame.command as string,
120
+ headers,
121
+ binaryBody: rawFrame.binaryBody,
122
+ escapeHeaderValues,
123
+ });
124
+ }
125
+
126
+ /**
127
+ * @internal
128
+ */
129
+ public toString(): string {
130
+ return this.serializeCmdAndHeaders();
131
+ }
132
+
133
+ /**
134
+ * serialize this Frame in a format suitable to be passed to WebSocket.
135
+ * If the body is string the output will be string.
136
+ * If the body is binary (i.e. of type Unit8Array) it will be serialized to ArrayBuffer.
137
+ *
138
+ * @internal
139
+ */
140
+ public serialize(): string | ArrayBuffer {
141
+ const cmdAndHeaders = this.serializeCmdAndHeaders();
142
+
143
+ if (this.isBinaryBody) {
144
+ return FrameImpl.toUnit8Array(
145
+ cmdAndHeaders,
146
+ this._binaryBody as Uint8Array
147
+ ).buffer;
148
+ } else {
149
+ return cmdAndHeaders + this._body + BYTE.NULL;
150
+ }
151
+ }
152
+
153
+ private serializeCmdAndHeaders(): string {
154
+ const lines = [this.command];
155
+ if (this.skipContentLengthHeader) {
156
+ delete this.headers['content-length'];
157
+ }
158
+
159
+ for (const name of Object.keys(this.headers || {})) {
160
+ const value = this.headers[name];
161
+ if (
162
+ this.escapeHeaderValues &&
163
+ this.command !== 'CONNECT' &&
164
+ this.command !== 'CONNECTED'
165
+ ) {
166
+ lines.push(`${name}:${FrameImpl.hdrValueEscape(`${value}`)}`);
167
+ } else {
168
+ lines.push(`${name}:${value}`);
169
+ }
170
+ }
171
+ if (
172
+ this.isBinaryBody ||
173
+ (!this.isBodyEmpty() && !this.skipContentLengthHeader)
174
+ ) {
175
+ lines.push(`content-length:${this.bodyLength()}`);
176
+ }
177
+ return lines.join(BYTE.LF) + BYTE.LF + BYTE.LF;
178
+ }
179
+
180
+ private isBodyEmpty(): boolean {
181
+ return this.bodyLength() === 0;
182
+ }
183
+
184
+ private bodyLength(): number {
185
+ const binaryBody = this.binaryBody;
186
+ return binaryBody ? binaryBody.length : 0;
187
+ }
188
+
189
+ /**
190
+ * Compute the size of a UTF-8 string by counting its number of bytes
191
+ * (and not the number of characters composing the string)
192
+ */
193
+ private static sizeOfUTF8(s: string): number {
194
+ return s ? new TextEncoder().encode(s).length : 0;
195
+ }
196
+
197
+ private static toUnit8Array(
198
+ cmdAndHeaders: string,
199
+ binaryBody: Uint8Array
200
+ ): Uint8Array {
201
+ const uint8CmdAndHeaders = new TextEncoder().encode(cmdAndHeaders);
202
+ const nullTerminator = new Uint8Array([0]);
203
+ const uint8Frame = new Uint8Array(
204
+ uint8CmdAndHeaders.length + binaryBody.length + nullTerminator.length
205
+ );
206
+
207
+ uint8Frame.set(uint8CmdAndHeaders);
208
+ uint8Frame.set(binaryBody, uint8CmdAndHeaders.length);
209
+ uint8Frame.set(
210
+ nullTerminator,
211
+ uint8CmdAndHeaders.length + binaryBody.length
212
+ );
213
+
214
+ return uint8Frame;
215
+ }
216
+ /**
217
+ * Serialize a STOMP frame as per STOMP standards, suitable to be sent to the STOMP broker.
218
+ *
219
+ * @internal
220
+ */
221
+ public static marshall(params: {
222
+ command: string;
223
+ headers?: StompHeaders;
224
+ body?: string;
225
+ binaryBody?: Uint8Array;
226
+ escapeHeaderValues?: boolean;
227
+ skipContentLengthHeader?: boolean;
228
+ }) {
229
+ const frame = new FrameImpl(params);
230
+ return frame.serialize();
231
+ }
232
+
233
+ /**
234
+ * Escape header values
235
+ */
236
+ private static hdrValueEscape(str: string): string {
237
+ return str
238
+ .replace(/\\/g, '\\\\')
239
+ .replace(/\r/g, '\\r')
240
+ .replace(/\n/g, '\\n')
241
+ .replace(/:/g, '\\c');
242
+ }
243
+
244
+ /**
245
+ * UnEscape header values
246
+ */
247
+ private static hdrValueUnEscape(str: string): string {
248
+ return str
249
+ .replace(/\\r/g, '\r')
250
+ .replace(/\\n/g, '\n')
251
+ .replace(/\\c/g, ':')
252
+ .replace(/\\\\/g, '\\');
253
+ }
254
+ }
package/src/i-frame.ts ADDED
@@ -0,0 +1,41 @@
1
+ import { StompHeaders } from './stomp-headers';
2
+
3
+ /**
4
+ * It represents a STOMP frame. Many of the callbacks pass an IFrame received from
5
+ * the STOMP broker. For advanced usage you might need to access [headers]{@link IFrame#headers}.
6
+ *
7
+ * Part of `@stomp/stompjs`.
8
+ *
9
+ * {@link IMessage} is an extended IFrame.
10
+ */
11
+ export interface IFrame {
12
+ /**
13
+ * STOMP Command
14
+ */
15
+ command: string;
16
+
17
+ /**
18
+ * Headers, key value pairs.
19
+ */
20
+ headers: StompHeaders;
21
+
22
+ /**
23
+ * Is this frame binary (based on whether body/binaryBody was passed when creating this frame).
24
+ */
25
+ isBinaryBody: boolean;
26
+
27
+ /**
28
+ * body of the frame as string
29
+ */
30
+ readonly body: string;
31
+
32
+ /**
33
+ * body as Uint8Array
34
+ */
35
+ readonly binaryBody: Uint8Array;
36
+ }
37
+
38
+ /**
39
+ * Alias for {@link IFrame}
40
+ */
41
+ export type Frame = IFrame;