@zlink-systems/stream-wire 0.26.0 → 0.28.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.
@@ -1,4 +1,8 @@
1
1
  // packages/stream-wire/src/lz4-pickle.ts
2
+ var LZ4_MIN_MATCH_LENGTH = 4;
3
+ var LZ4_MATCH_OFFSET_BYTES = 2;
4
+ var LZ4_EXTENDED_LENGTH_NIBBLE = 15;
5
+ var LZ4_EXTENDED_LENGTH_BYTE = 255;
2
6
  var defaultMaxDecompressedPayloadSize = 64 * 1024;
3
7
  function lz4PickleUncompressed(payload) {
4
8
  if (payload.length === 0) {
@@ -74,15 +78,15 @@ function decodeLz4Block(source, resultLength) {
74
78
  if (sourceOffset >= source.length) {
75
79
  break;
76
80
  }
77
- if (source.length - sourceOffset < 2) {
81
+ if (source.length - sourceOffset < LZ4_MATCH_OFFSET_BYTES) {
78
82
  throw new Error("LZ4 match offset is incomplete.");
79
83
  }
80
84
  const matchOffset = source[sourceOffset] | source[sourceOffset + 1] << 8;
81
- sourceOffset += 2;
85
+ sourceOffset += LZ4_MATCH_OFFSET_BYTES;
82
86
  if (matchOffset === 0 || matchOffset > targetOffset) {
83
87
  throw new Error("LZ4 match offset is invalid.");
84
88
  }
85
- const matchLength = readLz4Length(source, token & 15, () => sourceOffset++) + 4;
89
+ const matchLength = readLz4Length(source, token & 15, () => sourceOffset++) + LZ4_MIN_MATCH_LENGTH;
86
90
  if (target.length - targetOffset < matchLength) {
87
91
  throw new Error("LZ4 match run exceeds output size.");
88
92
  }
@@ -98,7 +102,7 @@ function decodeLz4Block(source, resultLength) {
98
102
  }
99
103
  function readLz4Length(source, nibble, nextOffset) {
100
104
  let length = nibble;
101
- if (length !== 15) {
105
+ if (length !== LZ4_EXTENDED_LENGTH_NIBBLE) {
102
106
  return length;
103
107
  }
104
108
  for (; ; ) {
@@ -108,7 +112,7 @@ function readLz4Length(source, nibble, nextOffset) {
108
112
  }
109
113
  const value = source[offset];
110
114
  length += value;
111
- if (value !== 255) {
115
+ if (value !== LZ4_EXTENDED_LENGTH_BYTE) {
112
116
  return length;
113
117
  }
114
118
  }
@@ -122,68 +126,257 @@ var ZlinkStreamCodec = /* @__PURE__ */ ((ZlinkStreamCodec2) => {
122
126
  ZlinkStreamCodec2[ZlinkStreamCodec2["Protobuf"] = 3] = "Protobuf";
123
127
  return ZlinkStreamCodec2;
124
128
  })(ZlinkStreamCodec || {});
129
+ var ZlinkStreamMessageKind = /* @__PURE__ */ ((ZlinkStreamMessageKind2) => {
130
+ ZlinkStreamMessageKind2[ZlinkStreamMessageKind2["Send"] = 1] = "Send";
131
+ ZlinkStreamMessageKind2[ZlinkStreamMessageKind2["Request"] = 2] = "Request";
132
+ ZlinkStreamMessageKind2[ZlinkStreamMessageKind2["Response"] = 3] = "Response";
133
+ ZlinkStreamMessageKind2[ZlinkStreamMessageKind2["Error"] = 4] = "Error";
134
+ ZlinkStreamMessageKind2[ZlinkStreamMessageKind2["Control"] = 5] = "Control";
135
+ return ZlinkStreamMessageKind2;
136
+ })(ZlinkStreamMessageKind || {});
137
+ var ZlinkStreamHeaderFlags = /* @__PURE__ */ ((ZlinkStreamHeaderFlags2) => {
138
+ ZlinkStreamHeaderFlags2[ZlinkStreamHeaderFlags2["None"] = 0] = "None";
139
+ ZlinkStreamHeaderFlags2[ZlinkStreamHeaderFlags2["HasRequestSeq"] = 1] = "HasRequestSeq";
140
+ ZlinkStreamHeaderFlags2[ZlinkStreamHeaderFlags2["HasMetadata"] = 2] = "HasMetadata";
141
+ ZlinkStreamHeaderFlags2[ZlinkStreamHeaderFlags2["PayloadCompressed"] = 4] = "PayloadCompressed";
142
+ ZlinkStreamHeaderFlags2[ZlinkStreamHeaderFlags2["HasCorrelationId"] = 8] = "HasCorrelationId";
143
+ ZlinkStreamHeaderFlags2[ZlinkStreamHeaderFlags2["HasFlowId"] = 16] = "HasFlowId";
144
+ ZlinkStreamHeaderFlags2[ZlinkStreamHeaderFlags2["HasActorSlot"] = 32] = "HasActorSlot";
145
+ return ZlinkStreamHeaderFlags2;
146
+ })(ZlinkStreamHeaderFlags || {});
147
+ var ZlinkStreamCloseReasonCode = /* @__PURE__ */ ((ZlinkStreamCloseReasonCode2) => {
148
+ ZlinkStreamCloseReasonCode2[ZlinkStreamCloseReasonCode2["ClientClose"] = 1] = "ClientClose";
149
+ ZlinkStreamCloseReasonCode2[ZlinkStreamCloseReasonCode2["IdleTimeout"] = 2] = "IdleTimeout";
150
+ ZlinkStreamCloseReasonCode2[ZlinkStreamCloseReasonCode2["HeartbeatTimeout"] = 3] = "HeartbeatTimeout";
151
+ ZlinkStreamCloseReasonCode2[ZlinkStreamCloseReasonCode2["ServerDrain"] = 4] = "ServerDrain";
152
+ ZlinkStreamCloseReasonCode2[ZlinkStreamCloseReasonCode2["ProtocolError"] = 5] = "ProtocolError";
153
+ ZlinkStreamCloseReasonCode2[ZlinkStreamCloseReasonCode2["TransportError"] = 6] = "TransportError";
154
+ return ZlinkStreamCloseReasonCode2;
155
+ })(ZlinkStreamCloseReasonCode || {});
156
+ var unicodeWhiteSpaceOnly = /^\p{White_Space}*$/u;
157
+ var validMessageKinds = new Set(
158
+ Object.values(ZlinkStreamMessageKind).filter((value) => typeof value === "number")
159
+ );
160
+ var validCodecs = new Set(
161
+ Object.values(ZlinkStreamCodec).filter((value) => typeof value === "number")
162
+ );
163
+ function isStreamWireMessageKind(value) {
164
+ return validMessageKinds.has(value);
165
+ }
166
+ function isStreamWireCodec(value) {
167
+ return validCodecs.has(value);
168
+ }
169
+ var UTF8_TWO_BYTE_MIN = 128;
170
+ var UTF8_THREE_BYTE_MIN = 2048;
171
+ var UTF16_HIGH_SURROGATE_MIN = 55296;
172
+ var UTF16_HIGH_SURROGATE_MAX = 56319;
173
+ var UTF16_LOW_SURROGATE_MIN = 56320;
174
+ var UTF16_LOW_SURROGATE_MAX = 57343;
175
+ var UINT8_MAX = 255;
176
+ var UINT16_MAX = 65535;
177
+ var UINT16_BYTES = 2;
178
+ var UINT32_BYTES = 4;
179
+ var UINT64_BYTES = 8;
180
+ var UINT64_MAX = 0xffffffffffffffffn;
181
+ var UINT32_MAX = 4294967295;
182
+ var ZLINK_STREAM_FRAME_PREFIX_BYTES = UINT16_BYTES + UINT32_BYTES;
183
+ var ZLINK_STREAM_MAX_PACKET_NAME_BYTES = UINT8_MAX;
184
+ var ZLINK_STREAM_MAX_METADATA_BYTES = 1024;
185
+ var FLOW_ID_BYTES = 36;
186
+ var FLOW_FIELDS_BYTES = FLOW_ID_BYTES + 1;
187
+ var HEADER_MIN_BYTES = 5;
188
+ var HEADER_FLAG_MASK = 1 /* HasRequestSeq */ | 2 /* HasMetadata */ | 4 /* PayloadCompressed */ | 8 /* HasCorrelationId */ | 16 /* HasFlowId */ | 32 /* HasActorSlot */;
189
+ var CONTROL_PAYLOAD_VERSION = 1;
190
+ var ACTOR_SLOT_OFFSET = 1;
191
+ var ACTOR_ID_LENGTH_OFFSET = ACTOR_SLOT_OFFSET + UINT16_BYTES;
192
+ var ACTOR_BOUND_PREFIX_BYTES = ACTOR_ID_LENGTH_OFFSET + 1;
193
+ var ACTOR_UNBOUND_BYTES = ACTOR_SLOT_OFFSET + UINT16_BYTES;
194
+ var CLOSING_DIAGNOSTIC_LENGTH_OFFSET = 2;
195
+ var CLOSING_PREFIX_BYTES = CLOSING_DIAGNOSTIC_LENGTH_OFFSET + UINT16_BYTES;
196
+ var MAX_CLOSING_DIAGNOSTIC_BYTES = 512;
197
+ function encodeStreamWireActorBoundPayload(actorSlot, actorId) {
198
+ const actorIdBytes = utf8Encode(actorId);
199
+ if (actorIdBytes.length < 1 || actorIdBytes.length > UINT8_MAX) {
200
+ throw new Error("Actor id length is invalid for a STREAM binding control packet.");
201
+ }
202
+ const payload = new Uint8Array(ACTOR_BOUND_PREFIX_BYTES + actorIdBytes.length);
203
+ payload[0] = CONTROL_PAYLOAD_VERSION;
204
+ writeUInt16BE(payload, ACTOR_SLOT_OFFSET, actorSlot);
205
+ payload[ACTOR_ID_LENGTH_OFFSET] = actorIdBytes.length;
206
+ payload.set(actorIdBytes, ACTOR_BOUND_PREFIX_BYTES);
207
+ return payload;
208
+ }
209
+ function decodeStreamWireActorBoundPayload(payload) {
210
+ if (payload.length < ACTOR_BOUND_PREFIX_BYTES + 1 || payload[0] !== CONTROL_PAYLOAD_VERSION) {
211
+ throw new Error("Actor bound payload is invalid.");
212
+ }
213
+ const slot = readUInt16BE(payload, ACTOR_SLOT_OFFSET);
214
+ const idLength = payload[ACTOR_ID_LENGTH_OFFSET];
215
+ if (slot === 0 || idLength === 0 || payload.length !== ACTOR_BOUND_PREFIX_BYTES + idLength) {
216
+ throw new Error("Actor bound payload is invalid.");
217
+ }
218
+ try {
219
+ return { slot, actorId: decodeControlText(payload.subarray(ACTOR_BOUND_PREFIX_BYTES)) };
220
+ } catch (cause) {
221
+ throw new Error("Actor id is not valid UTF-8.", { cause });
222
+ }
223
+ }
224
+ function encodeStreamWireActorUnboundPayload(actorSlot) {
225
+ const payload = new Uint8Array(ACTOR_UNBOUND_BYTES);
226
+ payload[0] = CONTROL_PAYLOAD_VERSION;
227
+ writeUInt16BE(payload, ACTOR_SLOT_OFFSET, actorSlot);
228
+ return payload;
229
+ }
230
+ function decodeStreamWireActorUnboundPayload(payload) {
231
+ if (payload.length !== ACTOR_UNBOUND_BYTES || payload[0] !== CONTROL_PAYLOAD_VERSION) {
232
+ throw new Error("Actor unbound payload is invalid.");
233
+ }
234
+ return readUInt16BE(payload, ACTOR_SLOT_OFFSET);
235
+ }
236
+ function encodeStreamWireSessionClosingPayload(reasonCode, diagnostic = "") {
237
+ const bytes = utf8Encode(diagnostic);
238
+ if (bytes.length > MAX_CLOSING_DIAGNOSTIC_BYTES) {
239
+ throw new Error("Session-closing diagnostic is too large.");
240
+ }
241
+ const payload = new Uint8Array(CLOSING_PREFIX_BYTES + bytes.length);
242
+ payload[0] = CONTROL_PAYLOAD_VERSION;
243
+ payload[1] = reasonCode;
244
+ writeUInt16BE(payload, CLOSING_DIAGNOSTIC_LENGTH_OFFSET, bytes.length);
245
+ payload.set(bytes, CLOSING_PREFIX_BYTES);
246
+ return payload;
247
+ }
248
+ function decodeStreamWireSessionClosing(payload) {
249
+ if (payload.length < CLOSING_PREFIX_BYTES || payload[0] !== CONTROL_PAYLOAD_VERSION) {
250
+ throw new Error("Unsupported session-closing version.");
251
+ }
252
+ const closeReason = ZlinkStreamCloseReasonCode[payload[1]];
253
+ if (closeReason === void 0) throw new Error("Unknown session-closing reason.");
254
+ const length = readUInt16BE(payload, CLOSING_DIAGNOSTIC_LENGTH_OFFSET);
255
+ if (length > MAX_CLOSING_DIAGNOSTIC_BYTES || payload.length !== CLOSING_PREFIX_BYTES + length) {
256
+ throw new Error("Invalid session-closing diagnostic length.");
257
+ }
258
+ const diagnostic = length === 0 ? void 0 : decodeControlText(payload.subarray(CLOSING_PREFIX_BYTES));
259
+ return { closeReason, diagnostic };
260
+ }
261
+ function decodeControlText(value) {
262
+ return new TextDecoder("utf-8", { fatal: true }).decode(value);
263
+ }
264
+ function splitStreamWireFrames(chunk) {
265
+ if (chunk.length === 0) throw new Error("Stream frame prefix is incomplete.");
266
+ const frames = [];
267
+ let offset = 0;
268
+ while (offset < chunk.length) {
269
+ const remaining = chunk.length - offset;
270
+ if (remaining < ZLINK_STREAM_FRAME_PREFIX_BYTES) {
271
+ throw new Error("Stream frame prefix is incomplete.");
272
+ }
273
+ const headerLength = readUInt16BE(chunk, offset);
274
+ const payloadLength = readUInt32BE(chunk, offset + UINT16_BYTES);
275
+ const frameLength = ZLINK_STREAM_FRAME_PREFIX_BYTES + headerLength + payloadLength;
276
+ if (frameLength > remaining) throw new Error("Frame length does not match prefix.");
277
+ frames.push(chunk.subarray(offset, offset + frameLength));
278
+ offset += frameLength;
279
+ }
280
+ return frames;
281
+ }
282
+ var ZLINK_STREAM_RESERVED_PACKET_NAME_PREFIX = "$zlink.";
283
+ var ZlinkStreamControlPacket = Object.freeze({
284
+ HeartbeatPing: `${ZLINK_STREAM_RESERVED_PACKET_NAME_PREFIX}heartbeat.ping`,
285
+ HeartbeatPong: `${ZLINK_STREAM_RESERVED_PACKET_NAME_PREFIX}heartbeat.pong`,
286
+ ActorBound: `${ZLINK_STREAM_RESERVED_PACKET_NAME_PREFIX}actor.bound`,
287
+ ActorUnbound: `${ZLINK_STREAM_RESERVED_PACKET_NAME_PREFIX}actor.unbound`,
288
+ SessionClosing: "session-closing"
289
+ });
290
+ var ZlinkStreamContentType = Object.freeze({
291
+ Raw: "application/octet-stream",
292
+ Json: "application/json",
293
+ MessagePack: "application/x-msgpack",
294
+ Protobuf: "application/x-protobuf"
295
+ });
296
+ var contentTypesByCodec = /* @__PURE__ */ new Map([
297
+ [0 /* Raw */, ZlinkStreamContentType.Raw],
298
+ [1 /* Json */, ZlinkStreamContentType.Json],
299
+ [2 /* MessagePack */, ZlinkStreamContentType.MessagePack],
300
+ [3 /* Protobuf */, ZlinkStreamContentType.Protobuf]
301
+ ]);
302
+ var codecsByContentType = new Map(
303
+ Array.from(contentTypesByCodec, ([codec, contentType]) => [contentType, codec])
304
+ );
305
+ function streamCodecContentType(codec) {
306
+ const contentType = contentTypesByCodec.get(codec);
307
+ if (contentType === void 0) throw new TypeError(`Unsupported STREAM codec '${codec}'.`);
308
+ return contentType;
309
+ }
310
+ function streamCodecForContentType(contentType) {
311
+ const codec = codecsByContentType.get(contentType);
312
+ if (codec === void 0) throw new TypeError(`Unsupported STREAM content type '${contentType}'.`);
313
+ return codec;
314
+ }
125
315
  var defaultHeaderFlags = {
126
- hasRequestSeq: 1,
127
- hasMetadata: 2,
128
- hasCorrelationId: 8,
129
- hasFlowId: 16,
130
- hasActorSlot: 32
316
+ hasRequestSeq: 1 /* HasRequestSeq */,
317
+ hasMetadata: 2 /* HasMetadata */,
318
+ hasCorrelationId: 8 /* HasCorrelationId */,
319
+ hasFlowId: 16 /* HasFlowId */,
320
+ hasActorSlot: 32 /* HasActorSlot */
131
321
  };
132
322
  var ZLINK_STREAM_FORMAT_MARKER = 242;
133
- var ZLINK_STREAM_RESPONSE_KIND = 3;
134
- var ZLINK_STREAM_ERROR_KIND = 4;
135
323
  function encodeStreamWireFrame(header, payload) {
136
- if (header.length > 65535) {
324
+ if (header.length > UINT16_MAX) {
137
325
  throw new Error("Stream header is too large.");
138
326
  }
139
- if (payload.length > 4294967295) {
327
+ if (payload.length > UINT32_MAX) {
140
328
  throw new Error("Stream payload is too large.");
141
329
  }
142
- const frame = new Uint8Array(6 + header.length + payload.length);
330
+ const frame = new Uint8Array(ZLINK_STREAM_FRAME_PREFIX_BYTES + header.length + payload.length);
143
331
  writeUInt16BE(frame, 0, header.length);
144
- writeUInt32BE(frame, 2, payload.length);
145
- frame.set(header, 6);
146
- frame.set(payload, 6 + header.length);
332
+ writeUInt32BE(frame, UINT16_BYTES, payload.length);
333
+ frame.set(header, ZLINK_STREAM_FRAME_PREFIX_BYTES);
334
+ frame.set(payload, ZLINK_STREAM_FRAME_PREFIX_BYTES + header.length);
147
335
  return frame;
148
336
  }
149
337
  function decodeStreamWireFrame(frame) {
150
- if (frame.length < 6) {
338
+ if (frame.length < ZLINK_STREAM_FRAME_PREFIX_BYTES) {
151
339
  throw new Error("Stream frame prefix is incomplete.");
152
340
  }
153
341
  const headerLength = readUInt16BE(frame, 0);
154
- const payloadLength = readUInt32BE(frame, 2);
155
- if (frame.length !== 6 + headerLength + payloadLength) {
342
+ const payloadLength = readUInt32BE(frame, UINT16_BYTES);
343
+ if (frame.length !== ZLINK_STREAM_FRAME_PREFIX_BYTES + headerLength + payloadLength) {
156
344
  throw new Error("Stream frame length does not match prefix.");
157
345
  }
158
346
  return {
159
- header: frame.slice(6, 6 + headerLength),
160
- payload: frame.slice(6 + headerLength)
347
+ header: frame.slice(
348
+ ZLINK_STREAM_FRAME_PREFIX_BYTES,
349
+ ZLINK_STREAM_FRAME_PREFIX_BYTES + headerLength
350
+ ),
351
+ payload: frame.slice(ZLINK_STREAM_FRAME_PREFIX_BYTES + headerLength)
161
352
  };
162
353
  }
163
354
  function tryDecodeStreamWireFrame(frame) {
164
- if (frame.length < 6) {
355
+ if (frame.length < ZLINK_STREAM_FRAME_PREFIX_BYTES) {
165
356
  return void 0;
166
357
  }
167
358
  const headerLength = readUInt16BE(frame, 0);
168
- const payloadLength = readUInt32BE(frame, 2);
169
- if (frame.length !== 6 + headerLength + payloadLength) {
359
+ const payloadLength = readUInt32BE(frame, UINT16_BYTES);
360
+ if (frame.length !== ZLINK_STREAM_FRAME_PREFIX_BYTES + headerLength + payloadLength) {
170
361
  return void 0;
171
362
  }
172
363
  return {
173
- header: frame.slice(6, 6 + headerLength),
174
- payload: frame.slice(6 + headerLength)
364
+ header: frame.slice(
365
+ ZLINK_STREAM_FRAME_PREFIX_BYTES,
366
+ ZLINK_STREAM_FRAME_PREFIX_BYTES + headerLength
367
+ ),
368
+ payload: frame.slice(ZLINK_STREAM_FRAME_PREFIX_BYTES + headerLength)
175
369
  };
176
370
  }
177
371
  function encodeStreamWireHeader(header, flagOverrides) {
178
372
  const flags = flagOverrides ?? defaultHeaderFlags;
179
373
  const reply = isReplyKind(header.kind);
180
374
  const packetName = reply ? "" : header.name;
181
- if (!reply) validateStreamWirePacketName(packetName);
182
- const nameBytes = utf8Encode(packetName);
375
+ const nameBytes = reply ? new Uint8Array() : validateStreamWirePacketName(packetName);
183
376
  const hasRequestSeq = header.requestSeq !== void 0;
184
377
  const hasMetadata = header.metadata.size > 0;
185
378
  const correlationBytes = header.correlationId !== void 0 && header.correlationId.length > 0 ? utf8Encode(header.correlationId) : void 0;
186
- if (correlationBytes !== void 0 && correlationBytes.length > 255) {
379
+ if (correlationBytes !== void 0 && correlationBytes.length > UINT8_MAX) {
187
380
  throw new Error("Stream correlation id is too large.");
188
381
  }
189
382
  const hasCorrelation = correlationBytes !== void 0;
@@ -196,7 +389,7 @@ function encodeStreamWireHeader(header, flagOverrides) {
196
389
  if (header.flowOrigin !== void 0 && ![1, 2, 3, 4].includes(header.flowOrigin)) {
197
390
  throw new Error("Stream flow origin is invalid.");
198
391
  }
199
- if (header.actorSlot !== void 0 && (!Number.isInteger(header.actorSlot) || header.actorSlot < 1 || header.actorSlot > 65535)) {
392
+ if (header.actorSlot !== void 0 && (!Number.isInteger(header.actorSlot) || header.actorSlot < 1 || header.actorSlot > UINT16_MAX)) {
200
393
  throw new Error("Stream actor slot is invalid.");
201
394
  }
202
395
  let headerFlags = header.flags;
@@ -206,7 +399,7 @@ function encodeStreamWireHeader(header, flagOverrides) {
206
399
  headerFlags = hasFlow ? headerFlags | flags.hasFlowId : headerFlags & ~flags.hasFlowId;
207
400
  headerFlags = hasActorSlot ? headerFlags | flags.hasActorSlot : headerFlags & ~flags.hasActorSlot;
208
401
  const metadataBytes = hasMetadata ? encodeStreamWireMetadata(header.metadata) : new Uint8Array();
209
- const size = 4 + (hasRequestSeq ? 8 : 0) + 1 + nameBytes.length + (hasMetadata ? 2 + metadataBytes.length : 0) + (hasCorrelation ? 1 + correlationBytes.length : 0) + (hasFlow ? 37 : 0) + (hasActorSlot ? 2 : 0);
402
+ const size = 4 + (hasRequestSeq ? UINT64_BYTES : 0) + 1 + nameBytes.length + (hasMetadata ? UINT16_BYTES + metadataBytes.length : 0) + (hasCorrelation ? 1 + correlationBytes.length : 0) + (hasFlow ? FLOW_FIELDS_BYTES : 0) + (hasActorSlot ? UINT16_BYTES : 0);
210
403
  const buffer = new Uint8Array(size);
211
404
  let offset = 0;
212
405
  buffer[offset++] = ZLINK_STREAM_FORMAT_MARKER;
@@ -218,14 +411,14 @@ function encodeStreamWireHeader(header, flagOverrides) {
218
411
  throw new Error("Request sequence must not be zero.");
219
412
  }
220
413
  writeBigUInt64BE(buffer, offset, header.requestSeq);
221
- offset += 8;
414
+ offset += UINT64_BYTES;
222
415
  }
223
416
  buffer[offset++] = nameBytes.length;
224
417
  buffer.set(nameBytes, offset);
225
418
  offset += nameBytes.length;
226
419
  if (hasMetadata) {
227
420
  writeUInt16BE(buffer, offset, metadataBytes.length);
228
- offset += 2;
421
+ offset += UINT16_BYTES;
229
422
  buffer.set(metadataBytes, offset);
230
423
  offset += metadataBytes.length;
231
424
  }
@@ -236,7 +429,7 @@ function encodeStreamWireHeader(header, flagOverrides) {
236
429
  }
237
430
  if (hasFlow) {
238
431
  buffer.set(asciiEncode(header.flowId), offset);
239
- offset += 36;
432
+ offset += FLOW_ID_BYTES;
240
433
  buffer[offset++] = header.flowOrigin;
241
434
  }
242
435
  if (hasActorSlot) {
@@ -247,7 +440,7 @@ function encodeStreamWireHeader(header, flagOverrides) {
247
440
  function decodeStreamWireHeader(header, flagOverrides, includeFlow = true) {
248
441
  const flags = flagOverrides ?? defaultHeaderFlags;
249
442
  let offset = 0;
250
- if (header.length < 5) {
443
+ if (header.length < HEADER_MIN_BYTES) {
251
444
  throw new Error("Stream header is incomplete.");
252
445
  }
253
446
  if (header[offset++] !== ZLINK_STREAM_FORMAT_MARKER) {
@@ -261,29 +454,28 @@ function decodeStreamWireHeader(header, flagOverrides, includeFlow = true) {
261
454
  const hasCorrelation = (headerFlags & flags.hasCorrelationId) !== 0;
262
455
  const hasFlow = (headerFlags & flags.hasFlowId) !== 0;
263
456
  const hasActorSlot = (headerFlags & flags.hasActorSlot) !== 0;
264
- if ((headerFlags & ~63) !== 0) {
457
+ if ((headerFlags & ~HEADER_FLAG_MASK) !== 0) {
265
458
  throw new Error("Unknown mandatory stream header flag.");
266
459
  }
267
460
  let requestSeq;
268
461
  if (hasRequestSeq) {
269
- if (header.length - offset < 8) {
462
+ if (header.length - offset < UINT64_BYTES) {
270
463
  throw new Error("Stream request sequence is incomplete.");
271
464
  }
272
465
  requestSeq = readBigUInt64BE(header, offset);
273
466
  if (requestSeq === 0n) {
274
467
  throw new Error("Request sequence must not be zero.");
275
468
  }
276
- offset += 8;
469
+ offset += UINT64_BYTES;
277
470
  }
278
471
  if (header.length - offset < 1) {
279
472
  throw new Error("Stream packet name length is missing.");
280
473
  }
281
474
  const nameLength = header[offset++];
282
- if (!isReplyKind(kind) && nameLength === 0 || header.length - offset < nameLength) {
475
+ if ((isReplyKind(kind) ? nameLength !== 0 : nameLength === 0) || header.length - offset < nameLength) {
283
476
  throw new Error("Stream packet name is invalid.");
284
477
  }
285
- const decodedName = utf8Decode(header.subarray(offset, offset + nameLength));
286
- const name = isReplyKind(kind) ? "" : decodedName;
478
+ const name = utf8Decode(header.subarray(offset, offset + nameLength));
287
479
  offset += nameLength;
288
480
  const decodedMetadata = hasMetadata ? decodeStreamWireHeaderMetadata(header, offset) : { metadata: /* @__PURE__ */ new Map(), offset };
289
481
  offset = decodedMetadata.offset;
@@ -302,14 +494,14 @@ function decodeStreamWireHeader(header, flagOverrides, includeFlow = true) {
302
494
  let flowId;
303
495
  let flowOrigin;
304
496
  if (hasFlow) {
305
- if (header.length - offset < 37) {
497
+ if (header.length - offset < FLOW_FIELDS_BYTES) {
306
498
  throw new Error("Stream flow fields are incomplete.");
307
499
  }
308
500
  if (includeFlow) {
309
- flowId = asciiDecode(header.subarray(offset, offset + 36));
501
+ flowId = asciiDecode(header.subarray(offset, offset + FLOW_ID_BYTES));
310
502
  validateFlowId(flowId);
311
503
  }
312
- offset += 36;
504
+ offset += FLOW_ID_BYTES;
313
505
  const decodedFlowOrigin = header[offset++];
314
506
  if (includeFlow && ![1, 2, 3, 4].includes(decodedFlowOrigin)) {
315
507
  throw new Error("Stream flow origin is invalid.");
@@ -318,14 +510,14 @@ function decodeStreamWireHeader(header, flagOverrides, includeFlow = true) {
318
510
  }
319
511
  let actorSlot;
320
512
  if (hasActorSlot) {
321
- if (header.length - offset < 2) {
513
+ if (header.length - offset < UINT16_BYTES) {
322
514
  throw new Error("Stream actor slot is incomplete.");
323
515
  }
324
516
  actorSlot = readUInt16BE(header, offset);
325
517
  if (actorSlot === 0) {
326
518
  throw new Error("Stream actor slot must not be zero.");
327
519
  }
328
- offset += 2;
520
+ offset += UINT16_BYTES;
329
521
  }
330
522
  if (offset !== header.length) {
331
523
  throw new Error("Stream header has trailing bytes.");
@@ -355,32 +547,36 @@ function asciiDecode(value) {
355
547
  if (value.some((byte) => byte > 127)) throw new Error("Stream flow id must be ASCII.");
356
548
  return String.fromCharCode(...value);
357
549
  }
358
- function encodeStreamWireMetadata(metadata) {
359
- if (metadata.size > 255) {
550
+ function streamWireMetadataSize(metadata) {
551
+ if (metadata.size > UINT8_MAX) {
360
552
  throw new Error("Metadata entry count must not exceed 255.");
361
553
  }
362
554
  let size = 1;
363
- const encoded = [...metadata].map(([key, value]) => {
364
- const keyBytes = utf8Encode(key);
365
- const valueBytes = utf8Encode(value);
366
- if (keyBytes.length === 0 || keyBytes.length > 255) {
555
+ for (const [key, value] of metadata) {
556
+ const keySize = utf8Size(key);
557
+ const valueSize = utf8Size(value);
558
+ if (keySize === 0 || keySize > UINT8_MAX) {
367
559
  throw new Error("Metadata key length is invalid.");
368
560
  }
369
- if (valueBytes.length > 65535) {
561
+ if (valueSize > UINT16_MAX) {
370
562
  throw new Error("Metadata value is too large.");
371
563
  }
372
- size += 1 + keyBytes.length + 2 + valueBytes.length;
373
- return { keyBytes, valueBytes };
374
- });
375
- const buffer = new Uint8Array(size);
564
+ size += 1 + keySize + UINT16_BYTES + valueSize;
565
+ }
566
+ return size;
567
+ }
568
+ function encodeStreamWireMetadata(metadata) {
569
+ const buffer = new Uint8Array(streamWireMetadataSize(metadata));
376
570
  let offset = 0;
377
571
  buffer[offset++] = metadata.size;
378
- for (const { keyBytes, valueBytes } of encoded) {
572
+ for (const [key, value] of metadata) {
573
+ const keyBytes = utf8Encode(key);
574
+ const valueBytes = utf8Encode(value);
379
575
  buffer[offset++] = keyBytes.length;
380
576
  buffer.set(keyBytes, offset);
381
577
  offset += keyBytes.length;
382
578
  writeUInt16BE(buffer, offset, valueBytes.length);
383
- offset += 2;
579
+ offset += UINT16_BYTES;
384
580
  buffer.set(valueBytes, offset);
385
581
  offset += valueBytes.length;
386
582
  }
@@ -409,11 +605,11 @@ function utf8Decode(value) {
409
605
  return new TextDecoder().decode(value);
410
606
  }
411
607
  function decodeStreamWireHeaderMetadata(header, offset) {
412
- if (header.length - offset < 2) {
608
+ if (header.length - offset < UINT16_BYTES) {
413
609
  throw new Error("Stream metadata section is incomplete.");
414
610
  }
415
611
  const metadataLength = readUInt16BE(header, offset);
416
- offset += 2;
612
+ offset += UINT16_BYTES;
417
613
  if (header.length - offset < metadataLength) {
418
614
  throw new Error("Stream metadata payload is incomplete.");
419
615
  }
@@ -439,7 +635,7 @@ function decodeStreamWireMetadataAt(source, offset, end) {
439
635
  throw new Error("Stream metadata value length is missing.");
440
636
  }
441
637
  const valueLength = readUInt16BE(source, offset);
442
- offset += 2;
638
+ offset += UINT16_BYTES;
443
639
  if (end - offset < valueLength) {
444
640
  throw new Error("Stream metadata value is incomplete.");
445
641
  }
@@ -456,16 +652,17 @@ function decodeStreamWireMetadataAt(source, offset, end) {
456
652
  }
457
653
  function validateStreamWirePacketName(name) {
458
654
  const nameBytes = utf8Encode(name);
459
- if (name.trim().length === 0 || nameBytes.length > 255) {
655
+ if (unicodeWhiteSpaceOnly.test(name) || nameBytes.length > ZLINK_STREAM_MAX_PACKET_NAME_BYTES) {
460
656
  throw new Error("Stream packet name is invalid.");
461
657
  }
658
+ return nameBytes;
462
659
  }
463
660
  function isReplyKind(kind) {
464
- return kind === ZLINK_STREAM_RESPONSE_KIND || kind === ZLINK_STREAM_ERROR_KIND;
661
+ return kind === 3 /* Response */ || kind === 4 /* Error */;
465
662
  }
466
663
  function writeUInt16BE(buffer, offset, value) {
467
- buffer[offset] = value >>> 8 & 255;
468
- buffer[offset + 1] = value & 255;
664
+ buffer[offset] = value >>> 8 & UINT8_MAX;
665
+ buffer[offset + 1] = value & UINT8_MAX;
469
666
  }
470
667
  function readUInt16BE(buffer, offset) {
471
668
  return buffer[offset] << 8 | buffer[offset + 1];
@@ -474,10 +671,10 @@ function readUInt32BE(buffer, offset) {
474
671
  return buffer[offset] * 16777216 + (buffer[offset + 1] << 16 | buffer[offset + 2] << 8 | buffer[offset + 3]);
475
672
  }
476
673
  function writeUInt32BE(buffer, offset, value) {
477
- buffer[offset] = value >>> 24 & 255;
478
- buffer[offset + 1] = value >>> 16 & 255;
479
- buffer[offset + 2] = value >>> 8 & 255;
480
- buffer[offset + 3] = value & 255;
674
+ buffer[offset] = value >>> 24 & UINT8_MAX;
675
+ buffer[offset + 1] = value >>> 16 & UINT8_MAX;
676
+ buffer[offset + 2] = value >>> 8 & UINT8_MAX;
677
+ buffer[offset + 3] = value & UINT8_MAX;
481
678
  }
482
679
  function writeBigUInt64BE(buffer, offset, value) {
483
680
  for (let index = 7; index >= 0; index -= 1) {
@@ -492,19 +689,58 @@ function readBigUInt64BE(buffer, offset) {
492
689
  }
493
690
  return value;
494
691
  }
692
+ function utf8Size(value) {
693
+ let size = 0;
694
+ for (let index = 0; index < value.length; index += 1) {
695
+ const code = value.charCodeAt(index);
696
+ if (code < UTF8_TWO_BYTE_MIN) size += 1;
697
+ else if (code < UTF8_THREE_BYTE_MIN) size += 2;
698
+ else if (code >= UTF16_HIGH_SURROGATE_MIN && code <= UTF16_HIGH_SURROGATE_MAX && index + 1 < value.length && value.charCodeAt(index + 1) >= UTF16_LOW_SURROGATE_MIN && value.charCodeAt(index + 1) <= UTF16_LOW_SURROGATE_MAX) {
699
+ size += 4;
700
+ index += 1;
701
+ } else size += 3;
702
+ }
703
+ return size;
704
+ }
495
705
  export {
706
+ UINT32_MAX,
707
+ UINT64_BYTES,
708
+ UINT64_MAX,
496
709
  ZLINK_STREAM_FORMAT_MARKER,
710
+ ZLINK_STREAM_FRAME_PREFIX_BYTES,
711
+ ZLINK_STREAM_MAX_METADATA_BYTES,
712
+ ZLINK_STREAM_MAX_PACKET_NAME_BYTES,
713
+ ZLINK_STREAM_RESERVED_PACKET_NAME_PREFIX,
714
+ ZlinkStreamCloseReasonCode,
497
715
  ZlinkStreamCodec,
716
+ ZlinkStreamContentType,
717
+ ZlinkStreamControlPacket,
718
+ ZlinkStreamHeaderFlags,
719
+ ZlinkStreamMessageKind,
720
+ decodeStreamWireActorBoundPayload,
721
+ decodeStreamWireActorUnboundPayload,
498
722
  decodeStreamWireFrame,
499
723
  decodeStreamWireHeader,
500
724
  decodeStreamWireMetadata,
725
+ decodeStreamWireSessionClosing,
726
+ defaultMaxDecompressedPayloadSize,
727
+ encodeStreamWireActorBoundPayload,
728
+ encodeStreamWireActorUnboundPayload,
501
729
  encodeStreamWireFrame,
502
730
  encodeStreamWireHeader,
503
731
  encodeStreamWireMetadata,
732
+ encodeStreamWireSessionClosingPayload,
733
+ isStreamWireCodec,
734
+ isStreamWireMessageKind,
504
735
  lz4PickleUncompressed2 as lz4PickleUncompressed,
505
736
  lz4PickledLength2 as lz4PickledLength,
506
737
  lz4UnpicklePayload2 as lz4UnpicklePayload,
738
+ splitStreamWireFrames,
739
+ streamCodecContentType,
740
+ streamCodecForContentType,
741
+ streamWireMetadataSize,
507
742
  tryDecodeStreamWireFrame,
508
743
  utf8Decode,
509
- utf8Encode
744
+ utf8Encode,
745
+ validateStreamWirePacketName
510
746
  };