@hla4ts/session 0.1.0 → 0.1.1

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/messages.ts CHANGED
@@ -1,329 +1,329 @@
1
- /**
2
- * Session Message Encoding/Decoding
3
- *
4
- * Handles encoding and decoding of Federate Protocol session control messages.
5
- * These are the messages used for session management (not HLA calls/callbacks).
6
- */
7
-
8
- import {
9
- encodeMessage,
10
- MessageType,
11
- FEDERATE_PROTOCOL_VERSION,
12
- NO_SESSION_ID,
13
- type MessageHeader,
14
- } from "@hla4ts/transport";
15
- import {
16
- INITIAL_SEQUENCE_NUMBER,
17
- NO_SEQUENCE_NUMBER as SEQ_NO_SEQUENCE_NUMBER,
18
- } from "./sequence-number.ts";
19
-
20
- // Size of a 32-bit integer in bytes
21
- const INT32_SIZE = 4;
22
-
23
- /**
24
- * Create a CTRL_NEW_SESSION message to initiate a new session.
25
- *
26
- * Payload format:
27
- * - protocolVersion (4 bytes, big-endian)
28
- *
29
- * @returns Encoded message ready to send
30
- */
31
- export function createNewSessionMessage(): Uint8Array {
32
- const payload = new Uint8Array(INT32_SIZE);
33
- const view = new DataView(payload.buffer);
34
- view.setUint32(0, FEDERATE_PROTOCOL_VERSION, false); // big-endian
35
-
36
- return encodeMessage(
37
- INITIAL_SEQUENCE_NUMBER,
38
- NO_SESSION_ID,
39
- SEQ_NO_SEQUENCE_NUMBER,
40
- MessageType.CTRL_NEW_SESSION,
41
- payload
42
- );
43
- }
44
-
45
- /**
46
- * Decode a CTRL_NEW_SESSION_STATUS response.
47
- *
48
- * Payload format:
49
- * - reason (4 bytes, big-endian) - 0 = success
50
- *
51
- * @param payload - The message payload
52
- * @returns Status code (0 = success)
53
- */
54
- export function decodeNewSessionStatus(payload: Uint8Array): number {
55
- if (payload.length < INT32_SIZE) {
56
- throw new Error(
57
- `NewSessionStatus payload too small: ${payload.length} bytes`
58
- );
59
- }
60
- const view = new DataView(payload.buffer, payload.byteOffset);
61
- return view.getUint32(0, false); // big-endian
62
- }
63
-
64
- /**
65
- * Create a CTRL_RESUME_REQUEST message to resume a dropped session.
66
- *
67
- * Payload format:
68
- * - lastReceivedSequenceNumber (4 bytes, big-endian)
69
- * - oldestAvailableSequenceNumber (4 bytes, big-endian)
70
- *
71
- * @param sessionId - The session ID to resume
72
- * @param lastReceivedSequenceNumber - Last sequence number received from RTI
73
- * @param oldestAvailableSequenceNumber - Oldest message still available for retransmission
74
- * @returns Encoded message ready to send
75
- */
76
- export function createResumeRequestMessage(
77
- sessionId: bigint,
78
- lastReceivedSequenceNumber: number,
79
- oldestAvailableSequenceNumber: number
80
- ): Uint8Array {
81
- const payload = new Uint8Array(INT32_SIZE * 2);
82
- const view = new DataView(payload.buffer);
83
- view.setUint32(0, lastReceivedSequenceNumber, false);
84
- view.setUint32(4, oldestAvailableSequenceNumber, false);
85
-
86
- return encodeMessage(
87
- SEQ_NO_SEQUENCE_NUMBER,
88
- sessionId,
89
- lastReceivedSequenceNumber,
90
- MessageType.CTRL_RESUME_REQUEST,
91
- payload
92
- );
93
- }
94
-
95
- /**
96
- * Decoded resume status response
97
- */
98
- export interface ResumeStatusResult {
99
- /** Status code (0 = success) */
100
- status: number;
101
- /** Last sequence number the server received from us */
102
- lastReceivedFederateSequenceNumber: number;
103
- }
104
-
105
- /**
106
- * Resume status codes
107
- */
108
- export const ResumeStatusCode = {
109
- /** Resume successful */
110
- OK_TO_RESUME: 0,
111
- /** Session not found (expired or invalid) */
112
- SESSION_NOT_FOUND: 1,
113
- /** Resume not allowed */
114
- NOT_ALLOWED: 2,
115
- } as const;
116
-
117
- /**
118
- * Decode a CTRL_RESUME_STATUS response.
119
- *
120
- * Payload format:
121
- * - status (4 bytes, big-endian)
122
- * - lastReceivedFederateSequenceNumber (4 bytes, big-endian)
123
- *
124
- * @param payload - The message payload
125
- * @returns Decoded resume status
126
- */
127
- export function decodeResumeStatus(payload: Uint8Array): ResumeStatusResult {
128
- if (payload.length < INT32_SIZE * 2) {
129
- throw new Error(`ResumeStatus payload too small: ${payload.length} bytes`);
130
- }
131
- const view = new DataView(payload.buffer, payload.byteOffset);
132
- return {
133
- status: view.getUint32(0, false),
134
- lastReceivedFederateSequenceNumber: view.getUint32(4, false),
135
- };
136
- }
137
-
138
- /**
139
- * Create a CTRL_HEARTBEAT message.
140
- *
141
- * No payload - the header contains all necessary information.
142
- *
143
- * @param sequenceNumber - Sequence number for this heartbeat
144
- * @param sessionId - Current session ID
145
- * @param lastReceivedSequenceNumber - Last sequence number received from RTI
146
- * @returns Encoded message ready to send
147
- */
148
- export function createHeartbeatMessage(
149
- sequenceNumber: number,
150
- sessionId: bigint,
151
- lastReceivedSequenceNumber: number
152
- ): Uint8Array {
153
- return encodeMessage(
154
- sequenceNumber,
155
- sessionId,
156
- lastReceivedSequenceNumber,
157
- MessageType.CTRL_HEARTBEAT
158
- );
159
- }
160
-
161
- /**
162
- * Decode a CTRL_HEARTBEAT_RESPONSE.
163
- *
164
- * Payload format:
165
- * - responseToSequenceNumber (4 bytes, big-endian)
166
- *
167
- * @param payload - The message payload
168
- * @returns The sequence number this is a response to
169
- */
170
- export function decodeHeartbeatResponse(payload: Uint8Array): number {
171
- if (payload.length < INT32_SIZE) {
172
- throw new Error(
173
- `HeartbeatResponse payload too small: ${payload.length} bytes`
174
- );
175
- }
176
- const view = new DataView(payload.buffer, payload.byteOffset);
177
- return view.getUint32(0, false);
178
- }
179
-
180
- /**
181
- * Create a CTRL_TERMINATE_SESSION message.
182
- *
183
- * No payload.
184
- *
185
- * @param sequenceNumber - Sequence number for this message
186
- * @param sessionId - Current session ID
187
- * @param lastReceivedSequenceNumber - Last sequence number received from RTI
188
- * @returns Encoded message ready to send
189
- */
190
- export function createTerminateSessionMessage(
191
- sequenceNumber: number,
192
- sessionId: bigint,
193
- lastReceivedSequenceNumber: number
194
- ): Uint8Array {
195
- return encodeMessage(
196
- sequenceNumber,
197
- sessionId,
198
- lastReceivedSequenceNumber,
199
- MessageType.CTRL_TERMINATE_SESSION
200
- );
201
- }
202
-
203
- /**
204
- * Create an HLA_CALL_REQUEST message.
205
- *
206
- * Payload format:
207
- * - hlaServiceCallWithParams (variable, protobuf-encoded CallRequest)
208
- *
209
- * @param sequenceNumber - Sequence number for this message
210
- * @param sessionId - Current session ID
211
- * @param lastReceivedSequenceNumber - Last sequence number received from RTI
212
- * @param hlaCallPayload - Protobuf-encoded HLA call request
213
- * @returns Encoded message ready to send
214
- */
215
- export function createHlaCallRequestMessage(
216
- sequenceNumber: number,
217
- sessionId: bigint,
218
- lastReceivedSequenceNumber: number,
219
- hlaCallPayload: Uint8Array
220
- ): Uint8Array {
221
- return encodeMessage(
222
- sequenceNumber,
223
- sessionId,
224
- lastReceivedSequenceNumber,
225
- MessageType.HLA_CALL_REQUEST,
226
- hlaCallPayload
227
- );
228
- }
229
-
230
- /**
231
- * Decoded HLA call response
232
- */
233
- export interface HlaCallResponseResult {
234
- /** Sequence number this is a response to */
235
- responseToSequenceNumber: number;
236
- /** The HLA response payload (protobuf-encoded CallResponse) */
237
- hlaServiceReturnValueOrException: Uint8Array;
238
- }
239
-
240
- /**
241
- * Decode an HLA_CALL_RESPONSE message.
242
- *
243
- * Payload format:
244
- * - responseToSequenceNumber (4 bytes, big-endian)
245
- * - hlaServiceReturnValueOrException (remaining bytes)
246
- *
247
- * @param payload - The message payload
248
- * @returns Decoded HLA call response
249
- */
250
- export function decodeHlaCallResponse(payload: Uint8Array): HlaCallResponseResult {
251
- if (payload.length < INT32_SIZE) {
252
- throw new Error(
253
- `HlaCallResponse payload too small: ${payload.length} bytes`
254
- );
255
- }
256
- const view = new DataView(payload.buffer, payload.byteOffset);
257
- const responseToSequenceNumber = view.getUint32(0, false);
258
-
259
- return {
260
- responseToSequenceNumber,
261
- hlaServiceReturnValueOrException: payload.slice(INT32_SIZE),
262
- };
263
- }
264
-
265
- /**
266
- * Decoded HLA callback request
267
- */
268
- export interface HlaCallbackRequestResult {
269
- /** The HLA callback payload (protobuf-encoded CallbackRequest) */
270
- hlaServiceCallbackWithParams: Uint8Array;
271
- }
272
-
273
- /**
274
- * Decode an HLA_CALLBACK_REQUEST message.
275
- *
276
- * Payload format:
277
- * - hlaServiceCallbackWithParams (all bytes, protobuf-encoded CallbackRequest)
278
- *
279
- * @param payload - The message payload
280
- * @returns Decoded HLA callback request
281
- */
282
- export function decodeHlaCallbackRequest(payload: Uint8Array): HlaCallbackRequestResult {
283
- return {
284
- hlaServiceCallbackWithParams: payload,
285
- };
286
- }
287
-
288
- /**
289
- * Create an HLA_CALLBACK_RESPONSE message.
290
- *
291
- * Payload format:
292
- * - responseToSequenceNumber (4 bytes, big-endian)
293
- * - hlaCallbackResponse (remaining bytes, protobuf-encoded CallbackResponse)
294
- *
295
- * @param sequenceNumber - Sequence number for this message
296
- * @param sessionId - Current session ID
297
- * @param lastReceivedSequenceNumber - Last sequence number received from RTI
298
- * @param responseToSequenceNumber - Sequence number of the callback request
299
- * @param hlaCallbackResponse - Protobuf-encoded callback response
300
- * @returns Encoded message ready to send
301
- */
302
- export function createHlaCallbackResponseMessage(
303
- sequenceNumber: number,
304
- sessionId: bigint,
305
- lastReceivedSequenceNumber: number,
306
- responseToSequenceNumber: number,
307
- hlaCallbackResponse: Uint8Array
308
- ): Uint8Array {
309
- const payloadSize = INT32_SIZE + hlaCallbackResponse.length;
310
- const payload = new Uint8Array(payloadSize);
311
- const view = new DataView(payload.buffer);
312
- view.setUint32(0, responseToSequenceNumber, false);
313
- payload.set(hlaCallbackResponse, INT32_SIZE);
314
-
315
- return encodeMessage(
316
- sequenceNumber,
317
- sessionId,
318
- lastReceivedSequenceNumber,
319
- MessageType.HLA_CALLBACK_RESPONSE,
320
- payload
321
- );
322
- }
323
-
324
- /**
325
- * Get a human-readable description of a message header
326
- */
327
- export function describeHeader(header: MessageHeader): string {
328
- return `[seq=${header.sequenceNumber}, session=${header.sessionId}, lastRecv=${header.lastReceivedSequenceNumber}, type=${MessageType[header.messageType] ?? header.messageType}]`;
329
- }
1
+ /**
2
+ * Session Message Encoding/Decoding
3
+ *
4
+ * Handles encoding and decoding of Federate Protocol session control messages.
5
+ * These are the messages used for session management (not HLA calls/callbacks).
6
+ */
7
+
8
+ import {
9
+ encodeMessage,
10
+ MessageType,
11
+ FEDERATE_PROTOCOL_VERSION,
12
+ NO_SESSION_ID,
13
+ type MessageHeader,
14
+ } from "@hla4ts/transport";
15
+ import {
16
+ INITIAL_SEQUENCE_NUMBER,
17
+ NO_SEQUENCE_NUMBER as SEQ_NO_SEQUENCE_NUMBER,
18
+ } from "./sequence-number.ts";
19
+
20
+ // Size of a 32-bit integer in bytes
21
+ const INT32_SIZE = 4;
22
+
23
+ /**
24
+ * Create a CTRL_NEW_SESSION message to initiate a new session.
25
+ *
26
+ * Payload format:
27
+ * - protocolVersion (4 bytes, big-endian)
28
+ *
29
+ * @returns Encoded message ready to send
30
+ */
31
+ export function createNewSessionMessage(): Uint8Array {
32
+ const payload = new Uint8Array(INT32_SIZE);
33
+ const view = new DataView(payload.buffer);
34
+ view.setUint32(0, FEDERATE_PROTOCOL_VERSION, false); // big-endian
35
+
36
+ return encodeMessage(
37
+ INITIAL_SEQUENCE_NUMBER,
38
+ NO_SESSION_ID,
39
+ SEQ_NO_SEQUENCE_NUMBER,
40
+ MessageType.CTRL_NEW_SESSION,
41
+ payload
42
+ );
43
+ }
44
+
45
+ /**
46
+ * Decode a CTRL_NEW_SESSION_STATUS response.
47
+ *
48
+ * Payload format:
49
+ * - reason (4 bytes, big-endian) - 0 = success
50
+ *
51
+ * @param payload - The message payload
52
+ * @returns Status code (0 = success)
53
+ */
54
+ export function decodeNewSessionStatus(payload: Uint8Array): number {
55
+ if (payload.length < INT32_SIZE) {
56
+ throw new Error(
57
+ `NewSessionStatus payload too small: ${payload.length} bytes`
58
+ );
59
+ }
60
+ const view = new DataView(payload.buffer, payload.byteOffset);
61
+ return view.getUint32(0, false); // big-endian
62
+ }
63
+
64
+ /**
65
+ * Create a CTRL_RESUME_REQUEST message to resume a dropped session.
66
+ *
67
+ * Payload format:
68
+ * - lastReceivedSequenceNumber (4 bytes, big-endian)
69
+ * - oldestAvailableSequenceNumber (4 bytes, big-endian)
70
+ *
71
+ * @param sessionId - The session ID to resume
72
+ * @param lastReceivedSequenceNumber - Last sequence number received from RTI
73
+ * @param oldestAvailableSequenceNumber - Oldest message still available for retransmission
74
+ * @returns Encoded message ready to send
75
+ */
76
+ export function createResumeRequestMessage(
77
+ sessionId: bigint,
78
+ lastReceivedSequenceNumber: number,
79
+ oldestAvailableSequenceNumber: number
80
+ ): Uint8Array {
81
+ const payload = new Uint8Array(INT32_SIZE * 2);
82
+ const view = new DataView(payload.buffer);
83
+ view.setUint32(0, lastReceivedSequenceNumber, false);
84
+ view.setUint32(4, oldestAvailableSequenceNumber, false);
85
+
86
+ return encodeMessage(
87
+ SEQ_NO_SEQUENCE_NUMBER,
88
+ sessionId,
89
+ lastReceivedSequenceNumber,
90
+ MessageType.CTRL_RESUME_REQUEST,
91
+ payload
92
+ );
93
+ }
94
+
95
+ /**
96
+ * Decoded resume status response
97
+ */
98
+ export interface ResumeStatusResult {
99
+ /** Status code (0 = success) */
100
+ status: number;
101
+ /** Last sequence number the server received from us */
102
+ lastReceivedFederateSequenceNumber: number;
103
+ }
104
+
105
+ /**
106
+ * Resume status codes
107
+ */
108
+ export const ResumeStatusCode = {
109
+ /** Resume successful */
110
+ OK_TO_RESUME: 0,
111
+ /** Session not found (expired or invalid) */
112
+ SESSION_NOT_FOUND: 1,
113
+ /** Resume not allowed */
114
+ NOT_ALLOWED: 2,
115
+ } as const;
116
+
117
+ /**
118
+ * Decode a CTRL_RESUME_STATUS response.
119
+ *
120
+ * Payload format:
121
+ * - status (4 bytes, big-endian)
122
+ * - lastReceivedFederateSequenceNumber (4 bytes, big-endian)
123
+ *
124
+ * @param payload - The message payload
125
+ * @returns Decoded resume status
126
+ */
127
+ export function decodeResumeStatus(payload: Uint8Array): ResumeStatusResult {
128
+ if (payload.length < INT32_SIZE * 2) {
129
+ throw new Error(`ResumeStatus payload too small: ${payload.length} bytes`);
130
+ }
131
+ const view = new DataView(payload.buffer, payload.byteOffset);
132
+ return {
133
+ status: view.getUint32(0, false),
134
+ lastReceivedFederateSequenceNumber: view.getUint32(4, false),
135
+ };
136
+ }
137
+
138
+ /**
139
+ * Create a CTRL_HEARTBEAT message.
140
+ *
141
+ * No payload - the header contains all necessary information.
142
+ *
143
+ * @param sequenceNumber - Sequence number for this heartbeat
144
+ * @param sessionId - Current session ID
145
+ * @param lastReceivedSequenceNumber - Last sequence number received from RTI
146
+ * @returns Encoded message ready to send
147
+ */
148
+ export function createHeartbeatMessage(
149
+ sequenceNumber: number,
150
+ sessionId: bigint,
151
+ lastReceivedSequenceNumber: number
152
+ ): Uint8Array {
153
+ return encodeMessage(
154
+ sequenceNumber,
155
+ sessionId,
156
+ lastReceivedSequenceNumber,
157
+ MessageType.CTRL_HEARTBEAT
158
+ );
159
+ }
160
+
161
+ /**
162
+ * Decode a CTRL_HEARTBEAT_RESPONSE.
163
+ *
164
+ * Payload format:
165
+ * - responseToSequenceNumber (4 bytes, big-endian)
166
+ *
167
+ * @param payload - The message payload
168
+ * @returns The sequence number this is a response to
169
+ */
170
+ export function decodeHeartbeatResponse(payload: Uint8Array): number {
171
+ if (payload.length < INT32_SIZE) {
172
+ throw new Error(
173
+ `HeartbeatResponse payload too small: ${payload.length} bytes`
174
+ );
175
+ }
176
+ const view = new DataView(payload.buffer, payload.byteOffset);
177
+ return view.getUint32(0, false);
178
+ }
179
+
180
+ /**
181
+ * Create a CTRL_TERMINATE_SESSION message.
182
+ *
183
+ * No payload.
184
+ *
185
+ * @param sequenceNumber - Sequence number for this message
186
+ * @param sessionId - Current session ID
187
+ * @param lastReceivedSequenceNumber - Last sequence number received from RTI
188
+ * @returns Encoded message ready to send
189
+ */
190
+ export function createTerminateSessionMessage(
191
+ sequenceNumber: number,
192
+ sessionId: bigint,
193
+ lastReceivedSequenceNumber: number
194
+ ): Uint8Array {
195
+ return encodeMessage(
196
+ sequenceNumber,
197
+ sessionId,
198
+ lastReceivedSequenceNumber,
199
+ MessageType.CTRL_TERMINATE_SESSION
200
+ );
201
+ }
202
+
203
+ /**
204
+ * Create an HLA_CALL_REQUEST message.
205
+ *
206
+ * Payload format:
207
+ * - hlaServiceCallWithParams (variable, protobuf-encoded CallRequest)
208
+ *
209
+ * @param sequenceNumber - Sequence number for this message
210
+ * @param sessionId - Current session ID
211
+ * @param lastReceivedSequenceNumber - Last sequence number received from RTI
212
+ * @param hlaCallPayload - Protobuf-encoded HLA call request
213
+ * @returns Encoded message ready to send
214
+ */
215
+ export function createHlaCallRequestMessage(
216
+ sequenceNumber: number,
217
+ sessionId: bigint,
218
+ lastReceivedSequenceNumber: number,
219
+ hlaCallPayload: Uint8Array
220
+ ): Uint8Array {
221
+ return encodeMessage(
222
+ sequenceNumber,
223
+ sessionId,
224
+ lastReceivedSequenceNumber,
225
+ MessageType.HLA_CALL_REQUEST,
226
+ hlaCallPayload
227
+ );
228
+ }
229
+
230
+ /**
231
+ * Decoded HLA call response
232
+ */
233
+ export interface HlaCallResponseResult {
234
+ /** Sequence number this is a response to */
235
+ responseToSequenceNumber: number;
236
+ /** The HLA response payload (protobuf-encoded CallResponse) */
237
+ hlaServiceReturnValueOrException: Uint8Array;
238
+ }
239
+
240
+ /**
241
+ * Decode an HLA_CALL_RESPONSE message.
242
+ *
243
+ * Payload format:
244
+ * - responseToSequenceNumber (4 bytes, big-endian)
245
+ * - hlaServiceReturnValueOrException (remaining bytes)
246
+ *
247
+ * @param payload - The message payload
248
+ * @returns Decoded HLA call response
249
+ */
250
+ export function decodeHlaCallResponse(payload: Uint8Array): HlaCallResponseResult {
251
+ if (payload.length < INT32_SIZE) {
252
+ throw new Error(
253
+ `HlaCallResponse payload too small: ${payload.length} bytes`
254
+ );
255
+ }
256
+ const view = new DataView(payload.buffer, payload.byteOffset);
257
+ const responseToSequenceNumber = view.getUint32(0, false);
258
+
259
+ return {
260
+ responseToSequenceNumber,
261
+ hlaServiceReturnValueOrException: payload.slice(INT32_SIZE),
262
+ };
263
+ }
264
+
265
+ /**
266
+ * Decoded HLA callback request
267
+ */
268
+ export interface HlaCallbackRequestResult {
269
+ /** The HLA callback payload (protobuf-encoded CallbackRequest) */
270
+ hlaServiceCallbackWithParams: Uint8Array;
271
+ }
272
+
273
+ /**
274
+ * Decode an HLA_CALLBACK_REQUEST message.
275
+ *
276
+ * Payload format:
277
+ * - hlaServiceCallbackWithParams (all bytes, protobuf-encoded CallbackRequest)
278
+ *
279
+ * @param payload - The message payload
280
+ * @returns Decoded HLA callback request
281
+ */
282
+ export function decodeHlaCallbackRequest(payload: Uint8Array): HlaCallbackRequestResult {
283
+ return {
284
+ hlaServiceCallbackWithParams: payload,
285
+ };
286
+ }
287
+
288
+ /**
289
+ * Create an HLA_CALLBACK_RESPONSE message.
290
+ *
291
+ * Payload format:
292
+ * - responseToSequenceNumber (4 bytes, big-endian)
293
+ * - hlaCallbackResponse (remaining bytes, protobuf-encoded CallbackResponse)
294
+ *
295
+ * @param sequenceNumber - Sequence number for this message
296
+ * @param sessionId - Current session ID
297
+ * @param lastReceivedSequenceNumber - Last sequence number received from RTI
298
+ * @param responseToSequenceNumber - Sequence number of the callback request
299
+ * @param hlaCallbackResponse - Protobuf-encoded callback response
300
+ * @returns Encoded message ready to send
301
+ */
302
+ export function createHlaCallbackResponseMessage(
303
+ sequenceNumber: number,
304
+ sessionId: bigint,
305
+ lastReceivedSequenceNumber: number,
306
+ responseToSequenceNumber: number,
307
+ hlaCallbackResponse: Uint8Array
308
+ ): Uint8Array {
309
+ const payloadSize = INT32_SIZE + hlaCallbackResponse.length;
310
+ const payload = new Uint8Array(payloadSize);
311
+ const view = new DataView(payload.buffer);
312
+ view.setUint32(0, responseToSequenceNumber, false);
313
+ payload.set(hlaCallbackResponse, INT32_SIZE);
314
+
315
+ return encodeMessage(
316
+ sequenceNumber,
317
+ sessionId,
318
+ lastReceivedSequenceNumber,
319
+ MessageType.HLA_CALLBACK_RESPONSE,
320
+ payload
321
+ );
322
+ }
323
+
324
+ /**
325
+ * Get a human-readable description of a message header
326
+ */
327
+ export function describeHeader(header: MessageHeader): string {
328
+ return `[seq=${header.sequenceNumber}, session=${header.sessionId}, lastRecv=${header.lastReceivedSequenceNumber}, type=${MessageType[header.messageType] ?? header.messageType}]`;
329
+ }