@zlink-systems/stream-connector 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.
- package/dist/browser/Contracts/ZlinkStreamConnectorOptions.d.ts +1 -0
- package/dist/browser/Contracts/ZlinkStreamEnums.d.ts +3 -17
- package/dist/browser/Contracts/index.d.ts +1 -1
- package/dist/browser/Runtime/Protocol/ZlinkSessionClosing.d.ts +2 -7
- package/dist/browser/Runtime/Protocol/ZlinkStreamFrameProtocol.d.ts +3 -4
- package/dist/browser/Runtime/Protocol/ZlinkStreamMetadataCodec.d.ts +1 -3
- package/dist/browser/Runtime/Transport/BrowserWebSocketConnection.d.ts +1 -2
- package/dist/browser/Runtime/ZlinkStreamActors.d.ts +2 -3
- package/dist/browser/Runtime/ZlinkStreamConnector.d.ts +3 -3
- package/dist/browser/Runtime/ZlinkStreamConnectorLifecycle.d.ts +4 -6
- package/dist/browser/Runtime/ZlinkStreamConnectorOptions.d.ts +1 -0
- package/dist/browser/Runtime/ZlinkStreamReceivedMessages.d.ts +2 -1
- package/dist/browser/Runtime/ZlinkStreamSupport.d.ts +8 -7
- package/dist/browser/index.global.js +583 -507
- package/dist/browser/index.mjs +582 -503
- package/package.json +2 -2
|
@@ -43,6 +43,10 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
43
43
|
});
|
|
44
44
|
|
|
45
45
|
// packages/stream-wire/src/lz4-pickle.ts
|
|
46
|
+
var LZ4_MIN_MATCH_LENGTH = 4;
|
|
47
|
+
var LZ4_MATCH_OFFSET_BYTES = 2;
|
|
48
|
+
var LZ4_EXTENDED_LENGTH_NIBBLE = 15;
|
|
49
|
+
var LZ4_EXTENDED_LENGTH_BYTE = 255;
|
|
46
50
|
var defaultMaxDecompressedPayloadSize = 64 * 1024;
|
|
47
51
|
function lz4PickleUncompressed(payload) {
|
|
48
52
|
if (payload.length === 0) {
|
|
@@ -118,15 +122,15 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
118
122
|
if (sourceOffset >= source.length) {
|
|
119
123
|
break;
|
|
120
124
|
}
|
|
121
|
-
if (source.length - sourceOffset <
|
|
125
|
+
if (source.length - sourceOffset < LZ4_MATCH_OFFSET_BYTES) {
|
|
122
126
|
throw new Error("LZ4 match offset is incomplete.");
|
|
123
127
|
}
|
|
124
128
|
const matchOffset = source[sourceOffset] | source[sourceOffset + 1] << 8;
|
|
125
|
-
sourceOffset +=
|
|
129
|
+
sourceOffset += LZ4_MATCH_OFFSET_BYTES;
|
|
126
130
|
if (matchOffset === 0 || matchOffset > targetOffset) {
|
|
127
131
|
throw new Error("LZ4 match offset is invalid.");
|
|
128
132
|
}
|
|
129
|
-
const matchLength = readLz4Length(source, token & 15, () => sourceOffset++) +
|
|
133
|
+
const matchLength = readLz4Length(source, token & 15, () => sourceOffset++) + LZ4_MIN_MATCH_LENGTH;
|
|
130
134
|
if (target.length - targetOffset < matchLength) {
|
|
131
135
|
throw new Error("LZ4 match run exceeds output size.");
|
|
132
136
|
}
|
|
@@ -142,7 +146,7 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
142
146
|
}
|
|
143
147
|
function readLz4Length(source, nibble, nextOffset) {
|
|
144
148
|
let length = nibble;
|
|
145
|
-
if (length !==
|
|
149
|
+
if (length !== LZ4_EXTENDED_LENGTH_NIBBLE) {
|
|
146
150
|
return length;
|
|
147
151
|
}
|
|
148
152
|
for (; ; ) {
|
|
@@ -152,7 +156,7 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
152
156
|
}
|
|
153
157
|
const value = source[offset];
|
|
154
158
|
length += value;
|
|
155
|
-
if (value !==
|
|
159
|
+
if (value !== LZ4_EXTENDED_LENGTH_BYTE) {
|
|
156
160
|
return length;
|
|
157
161
|
}
|
|
158
162
|
}
|
|
@@ -166,54 +170,200 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
166
170
|
ZlinkStreamCodec2[ZlinkStreamCodec2["Protobuf"] = 3] = "Protobuf";
|
|
167
171
|
return ZlinkStreamCodec2;
|
|
168
172
|
})(ZlinkStreamCodec || {});
|
|
173
|
+
var ZlinkStreamMessageKind = /* @__PURE__ */ ((ZlinkStreamMessageKind2) => {
|
|
174
|
+
ZlinkStreamMessageKind2[ZlinkStreamMessageKind2["Send"] = 1] = "Send";
|
|
175
|
+
ZlinkStreamMessageKind2[ZlinkStreamMessageKind2["Request"] = 2] = "Request";
|
|
176
|
+
ZlinkStreamMessageKind2[ZlinkStreamMessageKind2["Response"] = 3] = "Response";
|
|
177
|
+
ZlinkStreamMessageKind2[ZlinkStreamMessageKind2["Error"] = 4] = "Error";
|
|
178
|
+
ZlinkStreamMessageKind2[ZlinkStreamMessageKind2["Control"] = 5] = "Control";
|
|
179
|
+
return ZlinkStreamMessageKind2;
|
|
180
|
+
})(ZlinkStreamMessageKind || {});
|
|
181
|
+
var ZlinkStreamHeaderFlags = /* @__PURE__ */ ((ZlinkStreamHeaderFlags2) => {
|
|
182
|
+
ZlinkStreamHeaderFlags2[ZlinkStreamHeaderFlags2["None"] = 0] = "None";
|
|
183
|
+
ZlinkStreamHeaderFlags2[ZlinkStreamHeaderFlags2["HasRequestSeq"] = 1] = "HasRequestSeq";
|
|
184
|
+
ZlinkStreamHeaderFlags2[ZlinkStreamHeaderFlags2["HasMetadata"] = 2] = "HasMetadata";
|
|
185
|
+
ZlinkStreamHeaderFlags2[ZlinkStreamHeaderFlags2["PayloadCompressed"] = 4] = "PayloadCompressed";
|
|
186
|
+
ZlinkStreamHeaderFlags2[ZlinkStreamHeaderFlags2["HasCorrelationId"] = 8] = "HasCorrelationId";
|
|
187
|
+
ZlinkStreamHeaderFlags2[ZlinkStreamHeaderFlags2["HasFlowId"] = 16] = "HasFlowId";
|
|
188
|
+
ZlinkStreamHeaderFlags2[ZlinkStreamHeaderFlags2["HasActorSlot"] = 32] = "HasActorSlot";
|
|
189
|
+
return ZlinkStreamHeaderFlags2;
|
|
190
|
+
})(ZlinkStreamHeaderFlags || {});
|
|
191
|
+
var ZlinkStreamCloseReasonCode = /* @__PURE__ */ ((ZlinkStreamCloseReasonCode2) => {
|
|
192
|
+
ZlinkStreamCloseReasonCode2[ZlinkStreamCloseReasonCode2["ClientClose"] = 1] = "ClientClose";
|
|
193
|
+
ZlinkStreamCloseReasonCode2[ZlinkStreamCloseReasonCode2["IdleTimeout"] = 2] = "IdleTimeout";
|
|
194
|
+
ZlinkStreamCloseReasonCode2[ZlinkStreamCloseReasonCode2["HeartbeatTimeout"] = 3] = "HeartbeatTimeout";
|
|
195
|
+
ZlinkStreamCloseReasonCode2[ZlinkStreamCloseReasonCode2["ServerDrain"] = 4] = "ServerDrain";
|
|
196
|
+
ZlinkStreamCloseReasonCode2[ZlinkStreamCloseReasonCode2["ProtocolError"] = 5] = "ProtocolError";
|
|
197
|
+
ZlinkStreamCloseReasonCode2[ZlinkStreamCloseReasonCode2["TransportError"] = 6] = "TransportError";
|
|
198
|
+
return ZlinkStreamCloseReasonCode2;
|
|
199
|
+
})(ZlinkStreamCloseReasonCode || {});
|
|
200
|
+
var unicodeWhiteSpaceOnly = /^\p{White_Space}*$/u;
|
|
201
|
+
var validMessageKinds = new Set(
|
|
202
|
+
Object.values(ZlinkStreamMessageKind).filter((value) => typeof value === "number")
|
|
203
|
+
);
|
|
204
|
+
var validCodecs = new Set(
|
|
205
|
+
Object.values(ZlinkStreamCodec).filter((value) => typeof value === "number")
|
|
206
|
+
);
|
|
207
|
+
function isStreamWireMessageKind(value) {
|
|
208
|
+
return validMessageKinds.has(value);
|
|
209
|
+
}
|
|
210
|
+
function isStreamWireCodec(value) {
|
|
211
|
+
return validCodecs.has(value);
|
|
212
|
+
}
|
|
213
|
+
var UTF8_TWO_BYTE_MIN = 128;
|
|
214
|
+
var UTF8_THREE_BYTE_MIN = 2048;
|
|
215
|
+
var UTF16_HIGH_SURROGATE_MIN = 55296;
|
|
216
|
+
var UTF16_HIGH_SURROGATE_MAX = 56319;
|
|
217
|
+
var UTF16_LOW_SURROGATE_MIN = 56320;
|
|
218
|
+
var UTF16_LOW_SURROGATE_MAX = 57343;
|
|
219
|
+
var UINT8_MAX = 255;
|
|
220
|
+
var UINT16_MAX = 65535;
|
|
221
|
+
var UINT16_BYTES = 2;
|
|
222
|
+
var UINT32_BYTES = 4;
|
|
223
|
+
var UINT64_BYTES = 8;
|
|
224
|
+
var UINT64_MAX = 0xffffffffffffffffn;
|
|
225
|
+
var UINT32_MAX = 4294967295;
|
|
226
|
+
var ZLINK_STREAM_FRAME_PREFIX_BYTES = UINT16_BYTES + UINT32_BYTES;
|
|
227
|
+
var ZLINK_STREAM_MAX_PACKET_NAME_BYTES = UINT8_MAX;
|
|
228
|
+
var ZLINK_STREAM_MAX_METADATA_BYTES = 1024;
|
|
229
|
+
var FLOW_ID_BYTES = 36;
|
|
230
|
+
var FLOW_FIELDS_BYTES = FLOW_ID_BYTES + 1;
|
|
231
|
+
var HEADER_MIN_BYTES = 5;
|
|
232
|
+
var HEADER_FLAG_MASK = 1 /* HasRequestSeq */ | 2 /* HasMetadata */ | 4 /* PayloadCompressed */ | 8 /* HasCorrelationId */ | 16 /* HasFlowId */ | 32 /* HasActorSlot */;
|
|
233
|
+
var CONTROL_PAYLOAD_VERSION = 1;
|
|
234
|
+
var ACTOR_SLOT_OFFSET = 1;
|
|
235
|
+
var ACTOR_ID_LENGTH_OFFSET = ACTOR_SLOT_OFFSET + UINT16_BYTES;
|
|
236
|
+
var ACTOR_BOUND_PREFIX_BYTES = ACTOR_ID_LENGTH_OFFSET + 1;
|
|
237
|
+
var ACTOR_UNBOUND_BYTES = ACTOR_SLOT_OFFSET + UINT16_BYTES;
|
|
238
|
+
var CLOSING_DIAGNOSTIC_LENGTH_OFFSET = 2;
|
|
239
|
+
var CLOSING_PREFIX_BYTES = CLOSING_DIAGNOSTIC_LENGTH_OFFSET + UINT16_BYTES;
|
|
240
|
+
var MAX_CLOSING_DIAGNOSTIC_BYTES = 512;
|
|
241
|
+
function decodeStreamWireActorBoundPayload(payload) {
|
|
242
|
+
if (payload.length < ACTOR_BOUND_PREFIX_BYTES + 1 || payload[0] !== CONTROL_PAYLOAD_VERSION) {
|
|
243
|
+
throw new Error("Actor bound payload is invalid.");
|
|
244
|
+
}
|
|
245
|
+
const slot = readUInt16BE(payload, ACTOR_SLOT_OFFSET);
|
|
246
|
+
const idLength = payload[ACTOR_ID_LENGTH_OFFSET];
|
|
247
|
+
if (slot === 0 || idLength === 0 || payload.length !== ACTOR_BOUND_PREFIX_BYTES + idLength) {
|
|
248
|
+
throw new Error("Actor bound payload is invalid.");
|
|
249
|
+
}
|
|
250
|
+
try {
|
|
251
|
+
return { slot, actorId: decodeControlText(payload.subarray(ACTOR_BOUND_PREFIX_BYTES)) };
|
|
252
|
+
} catch (cause) {
|
|
253
|
+
throw new Error("Actor id is not valid UTF-8.", { cause });
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
function decodeStreamWireActorUnboundPayload(payload) {
|
|
257
|
+
if (payload.length !== ACTOR_UNBOUND_BYTES || payload[0] !== CONTROL_PAYLOAD_VERSION) {
|
|
258
|
+
throw new Error("Actor unbound payload is invalid.");
|
|
259
|
+
}
|
|
260
|
+
return readUInt16BE(payload, ACTOR_SLOT_OFFSET);
|
|
261
|
+
}
|
|
262
|
+
function decodeStreamWireSessionClosing(payload) {
|
|
263
|
+
if (payload.length < CLOSING_PREFIX_BYTES || payload[0] !== CONTROL_PAYLOAD_VERSION) {
|
|
264
|
+
throw new Error("Unsupported session-closing version.");
|
|
265
|
+
}
|
|
266
|
+
const closeReason = ZlinkStreamCloseReasonCode[payload[1]];
|
|
267
|
+
if (closeReason === void 0) throw new Error("Unknown session-closing reason.");
|
|
268
|
+
const length = readUInt16BE(payload, CLOSING_DIAGNOSTIC_LENGTH_OFFSET);
|
|
269
|
+
if (length > MAX_CLOSING_DIAGNOSTIC_BYTES || payload.length !== CLOSING_PREFIX_BYTES + length) {
|
|
270
|
+
throw new Error("Invalid session-closing diagnostic length.");
|
|
271
|
+
}
|
|
272
|
+
const diagnostic = length === 0 ? void 0 : decodeControlText(payload.subarray(CLOSING_PREFIX_BYTES));
|
|
273
|
+
return { closeReason, diagnostic };
|
|
274
|
+
}
|
|
275
|
+
function decodeControlText(value) {
|
|
276
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(value);
|
|
277
|
+
}
|
|
278
|
+
function splitStreamWireFrames(chunk) {
|
|
279
|
+
if (chunk.length === 0) throw new Error("Stream frame prefix is incomplete.");
|
|
280
|
+
const frames = [];
|
|
281
|
+
let offset = 0;
|
|
282
|
+
while (offset < chunk.length) {
|
|
283
|
+
const remaining = chunk.length - offset;
|
|
284
|
+
if (remaining < ZLINK_STREAM_FRAME_PREFIX_BYTES) {
|
|
285
|
+
throw new Error("Stream frame prefix is incomplete.");
|
|
286
|
+
}
|
|
287
|
+
const headerLength = readUInt16BE(chunk, offset);
|
|
288
|
+
const payloadLength = readUInt32BE(chunk, offset + UINT16_BYTES);
|
|
289
|
+
const frameLength = ZLINK_STREAM_FRAME_PREFIX_BYTES + headerLength + payloadLength;
|
|
290
|
+
if (frameLength > remaining) throw new Error("Frame length does not match prefix.");
|
|
291
|
+
frames.push(chunk.subarray(offset, offset + frameLength));
|
|
292
|
+
offset += frameLength;
|
|
293
|
+
}
|
|
294
|
+
return frames;
|
|
295
|
+
}
|
|
296
|
+
var ZLINK_STREAM_RESERVED_PACKET_NAME_PREFIX = "$zlink.";
|
|
297
|
+
var ZlinkStreamControlPacket = Object.freeze({
|
|
298
|
+
HeartbeatPing: `${ZLINK_STREAM_RESERVED_PACKET_NAME_PREFIX}heartbeat.ping`,
|
|
299
|
+
HeartbeatPong: `${ZLINK_STREAM_RESERVED_PACKET_NAME_PREFIX}heartbeat.pong`,
|
|
300
|
+
ActorBound: `${ZLINK_STREAM_RESERVED_PACKET_NAME_PREFIX}actor.bound`,
|
|
301
|
+
ActorUnbound: `${ZLINK_STREAM_RESERVED_PACKET_NAME_PREFIX}actor.unbound`,
|
|
302
|
+
SessionClosing: "session-closing"
|
|
303
|
+
});
|
|
304
|
+
var ZlinkStreamContentType = Object.freeze({
|
|
305
|
+
Raw: "application/octet-stream",
|
|
306
|
+
Json: "application/json",
|
|
307
|
+
MessagePack: "application/x-msgpack",
|
|
308
|
+
Protobuf: "application/x-protobuf"
|
|
309
|
+
});
|
|
310
|
+
var contentTypesByCodec = /* @__PURE__ */ new Map([
|
|
311
|
+
[0 /* Raw */, ZlinkStreamContentType.Raw],
|
|
312
|
+
[1 /* Json */, ZlinkStreamContentType.Json],
|
|
313
|
+
[2 /* MessagePack */, ZlinkStreamContentType.MessagePack],
|
|
314
|
+
[3 /* Protobuf */, ZlinkStreamContentType.Protobuf]
|
|
315
|
+
]);
|
|
316
|
+
var codecsByContentType = new Map(
|
|
317
|
+
Array.from(contentTypesByCodec, ([codec, contentType]) => [contentType, codec])
|
|
318
|
+
);
|
|
169
319
|
var defaultHeaderFlags = {
|
|
170
|
-
hasRequestSeq: 1
|
|
171
|
-
hasMetadata: 2
|
|
172
|
-
hasCorrelationId: 8
|
|
173
|
-
hasFlowId: 16
|
|
174
|
-
hasActorSlot: 32
|
|
320
|
+
hasRequestSeq: 1 /* HasRequestSeq */,
|
|
321
|
+
hasMetadata: 2 /* HasMetadata */,
|
|
322
|
+
hasCorrelationId: 8 /* HasCorrelationId */,
|
|
323
|
+
hasFlowId: 16 /* HasFlowId */,
|
|
324
|
+
hasActorSlot: 32 /* HasActorSlot */
|
|
175
325
|
};
|
|
176
326
|
var ZLINK_STREAM_FORMAT_MARKER = 242;
|
|
177
|
-
var ZLINK_STREAM_RESPONSE_KIND = 3;
|
|
178
|
-
var ZLINK_STREAM_ERROR_KIND = 4;
|
|
179
327
|
function encodeStreamWireFrame(header, payload) {
|
|
180
|
-
if (header.length >
|
|
328
|
+
if (header.length > UINT16_MAX) {
|
|
181
329
|
throw new Error("Stream header is too large.");
|
|
182
330
|
}
|
|
183
|
-
if (payload.length >
|
|
331
|
+
if (payload.length > UINT32_MAX) {
|
|
184
332
|
throw new Error("Stream payload is too large.");
|
|
185
333
|
}
|
|
186
|
-
const frame = new Uint8Array(
|
|
334
|
+
const frame = new Uint8Array(ZLINK_STREAM_FRAME_PREFIX_BYTES + header.length + payload.length);
|
|
187
335
|
writeUInt16BE(frame, 0, header.length);
|
|
188
|
-
writeUInt32BE(frame,
|
|
189
|
-
frame.set(header,
|
|
190
|
-
frame.set(payload,
|
|
336
|
+
writeUInt32BE(frame, UINT16_BYTES, payload.length);
|
|
337
|
+
frame.set(header, ZLINK_STREAM_FRAME_PREFIX_BYTES);
|
|
338
|
+
frame.set(payload, ZLINK_STREAM_FRAME_PREFIX_BYTES + header.length);
|
|
191
339
|
return frame;
|
|
192
340
|
}
|
|
193
341
|
function decodeStreamWireFrame(frame) {
|
|
194
|
-
if (frame.length <
|
|
342
|
+
if (frame.length < ZLINK_STREAM_FRAME_PREFIX_BYTES) {
|
|
195
343
|
throw new Error("Stream frame prefix is incomplete.");
|
|
196
344
|
}
|
|
197
345
|
const headerLength = readUInt16BE(frame, 0);
|
|
198
|
-
const payloadLength = readUInt32BE(frame,
|
|
199
|
-
if (frame.length !==
|
|
346
|
+
const payloadLength = readUInt32BE(frame, UINT16_BYTES);
|
|
347
|
+
if (frame.length !== ZLINK_STREAM_FRAME_PREFIX_BYTES + headerLength + payloadLength) {
|
|
200
348
|
throw new Error("Stream frame length does not match prefix.");
|
|
201
349
|
}
|
|
202
350
|
return {
|
|
203
|
-
header: frame.slice(
|
|
204
|
-
|
|
351
|
+
header: frame.slice(
|
|
352
|
+
ZLINK_STREAM_FRAME_PREFIX_BYTES,
|
|
353
|
+
ZLINK_STREAM_FRAME_PREFIX_BYTES + headerLength
|
|
354
|
+
),
|
|
355
|
+
payload: frame.slice(ZLINK_STREAM_FRAME_PREFIX_BYTES + headerLength)
|
|
205
356
|
};
|
|
206
357
|
}
|
|
207
358
|
function encodeStreamWireHeader(header, flagOverrides) {
|
|
208
359
|
const flags = flagOverrides != null ? flagOverrides : defaultHeaderFlags;
|
|
209
360
|
const reply = isReplyKind(header.kind);
|
|
210
361
|
const packetName = reply ? "" : header.name;
|
|
211
|
-
|
|
212
|
-
const nameBytes = utf8Encode(packetName);
|
|
362
|
+
const nameBytes = reply ? new Uint8Array() : validateStreamWirePacketName(packetName);
|
|
213
363
|
const hasRequestSeq = header.requestSeq !== void 0;
|
|
214
364
|
const hasMetadata = header.metadata.size > 0;
|
|
215
365
|
const correlationBytes = header.correlationId !== void 0 && header.correlationId.length > 0 ? utf8Encode(header.correlationId) : void 0;
|
|
216
|
-
if (correlationBytes !== void 0 && correlationBytes.length >
|
|
366
|
+
if (correlationBytes !== void 0 && correlationBytes.length > UINT8_MAX) {
|
|
217
367
|
throw new Error("Stream correlation id is too large.");
|
|
218
368
|
}
|
|
219
369
|
const hasCorrelation = correlationBytes !== void 0;
|
|
@@ -226,7 +376,7 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
226
376
|
if (header.flowOrigin !== void 0 && ![1, 2, 3, 4].includes(header.flowOrigin)) {
|
|
227
377
|
throw new Error("Stream flow origin is invalid.");
|
|
228
378
|
}
|
|
229
|
-
if (header.actorSlot !== void 0 && (!Number.isInteger(header.actorSlot) || header.actorSlot < 1 || header.actorSlot >
|
|
379
|
+
if (header.actorSlot !== void 0 && (!Number.isInteger(header.actorSlot) || header.actorSlot < 1 || header.actorSlot > UINT16_MAX)) {
|
|
230
380
|
throw new Error("Stream actor slot is invalid.");
|
|
231
381
|
}
|
|
232
382
|
let headerFlags = header.flags;
|
|
@@ -236,7 +386,7 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
236
386
|
headerFlags = hasFlow ? headerFlags | flags.hasFlowId : headerFlags & ~flags.hasFlowId;
|
|
237
387
|
headerFlags = hasActorSlot ? headerFlags | flags.hasActorSlot : headerFlags & ~flags.hasActorSlot;
|
|
238
388
|
const metadataBytes = hasMetadata ? encodeStreamWireMetadata(header.metadata) : new Uint8Array();
|
|
239
|
-
const size = 4 + (hasRequestSeq ?
|
|
389
|
+
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);
|
|
240
390
|
const buffer = new Uint8Array(size);
|
|
241
391
|
let offset = 0;
|
|
242
392
|
buffer[offset++] = ZLINK_STREAM_FORMAT_MARKER;
|
|
@@ -248,14 +398,14 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
248
398
|
throw new Error("Request sequence must not be zero.");
|
|
249
399
|
}
|
|
250
400
|
writeBigUInt64BE(buffer, offset, header.requestSeq);
|
|
251
|
-
offset +=
|
|
401
|
+
offset += UINT64_BYTES;
|
|
252
402
|
}
|
|
253
403
|
buffer[offset++] = nameBytes.length;
|
|
254
404
|
buffer.set(nameBytes, offset);
|
|
255
405
|
offset += nameBytes.length;
|
|
256
406
|
if (hasMetadata) {
|
|
257
407
|
writeUInt16BE(buffer, offset, metadataBytes.length);
|
|
258
|
-
offset +=
|
|
408
|
+
offset += UINT16_BYTES;
|
|
259
409
|
buffer.set(metadataBytes, offset);
|
|
260
410
|
offset += metadataBytes.length;
|
|
261
411
|
}
|
|
@@ -266,7 +416,7 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
266
416
|
}
|
|
267
417
|
if (hasFlow) {
|
|
268
418
|
buffer.set(asciiEncode(header.flowId), offset);
|
|
269
|
-
offset +=
|
|
419
|
+
offset += FLOW_ID_BYTES;
|
|
270
420
|
buffer[offset++] = header.flowOrigin;
|
|
271
421
|
}
|
|
272
422
|
if (hasActorSlot) {
|
|
@@ -277,7 +427,7 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
277
427
|
function decodeStreamWireHeader(header, flagOverrides, includeFlow = true) {
|
|
278
428
|
const flags = flagOverrides != null ? flagOverrides : defaultHeaderFlags;
|
|
279
429
|
let offset = 0;
|
|
280
|
-
if (header.length <
|
|
430
|
+
if (header.length < HEADER_MIN_BYTES) {
|
|
281
431
|
throw new Error("Stream header is incomplete.");
|
|
282
432
|
}
|
|
283
433
|
if (header[offset++] !== ZLINK_STREAM_FORMAT_MARKER) {
|
|
@@ -291,29 +441,28 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
291
441
|
const hasCorrelation = (headerFlags & flags.hasCorrelationId) !== 0;
|
|
292
442
|
const hasFlow = (headerFlags & flags.hasFlowId) !== 0;
|
|
293
443
|
const hasActorSlot = (headerFlags & flags.hasActorSlot) !== 0;
|
|
294
|
-
if ((headerFlags & ~
|
|
444
|
+
if ((headerFlags & ~HEADER_FLAG_MASK) !== 0) {
|
|
295
445
|
throw new Error("Unknown mandatory stream header flag.");
|
|
296
446
|
}
|
|
297
447
|
let requestSeq;
|
|
298
448
|
if (hasRequestSeq) {
|
|
299
|
-
if (header.length - offset <
|
|
449
|
+
if (header.length - offset < UINT64_BYTES) {
|
|
300
450
|
throw new Error("Stream request sequence is incomplete.");
|
|
301
451
|
}
|
|
302
452
|
requestSeq = readBigUInt64BE(header, offset);
|
|
303
453
|
if (requestSeq === 0n) {
|
|
304
454
|
throw new Error("Request sequence must not be zero.");
|
|
305
455
|
}
|
|
306
|
-
offset +=
|
|
456
|
+
offset += UINT64_BYTES;
|
|
307
457
|
}
|
|
308
458
|
if (header.length - offset < 1) {
|
|
309
459
|
throw new Error("Stream packet name length is missing.");
|
|
310
460
|
}
|
|
311
461
|
const nameLength = header[offset++];
|
|
312
|
-
if (
|
|
462
|
+
if ((isReplyKind(kind) ? nameLength !== 0 : nameLength === 0) || header.length - offset < nameLength) {
|
|
313
463
|
throw new Error("Stream packet name is invalid.");
|
|
314
464
|
}
|
|
315
|
-
const
|
|
316
|
-
const name = isReplyKind(kind) ? "" : decodedName;
|
|
465
|
+
const name = utf8Decode(header.subarray(offset, offset + nameLength));
|
|
317
466
|
offset += nameLength;
|
|
318
467
|
const decodedMetadata = hasMetadata ? decodeStreamWireHeaderMetadata(header, offset) : { metadata: /* @__PURE__ */ new Map(), offset };
|
|
319
468
|
offset = decodedMetadata.offset;
|
|
@@ -332,14 +481,14 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
332
481
|
let flowId;
|
|
333
482
|
let flowOrigin;
|
|
334
483
|
if (hasFlow) {
|
|
335
|
-
if (header.length - offset <
|
|
484
|
+
if (header.length - offset < FLOW_FIELDS_BYTES) {
|
|
336
485
|
throw new Error("Stream flow fields are incomplete.");
|
|
337
486
|
}
|
|
338
487
|
if (includeFlow) {
|
|
339
|
-
flowId = asciiDecode(header.subarray(offset, offset +
|
|
488
|
+
flowId = asciiDecode(header.subarray(offset, offset + FLOW_ID_BYTES));
|
|
340
489
|
validateFlowId(flowId);
|
|
341
490
|
}
|
|
342
|
-
offset +=
|
|
491
|
+
offset += FLOW_ID_BYTES;
|
|
343
492
|
const decodedFlowOrigin = header[offset++];
|
|
344
493
|
if (includeFlow && ![1, 2, 3, 4].includes(decodedFlowOrigin)) {
|
|
345
494
|
throw new Error("Stream flow origin is invalid.");
|
|
@@ -348,14 +497,14 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
348
497
|
}
|
|
349
498
|
let actorSlot;
|
|
350
499
|
if (hasActorSlot) {
|
|
351
|
-
if (header.length - offset <
|
|
500
|
+
if (header.length - offset < UINT16_BYTES) {
|
|
352
501
|
throw new Error("Stream actor slot is incomplete.");
|
|
353
502
|
}
|
|
354
503
|
actorSlot = readUInt16BE(header, offset);
|
|
355
504
|
if (actorSlot === 0) {
|
|
356
505
|
throw new Error("Stream actor slot must not be zero.");
|
|
357
506
|
}
|
|
358
|
-
offset +=
|
|
507
|
+
offset += UINT16_BYTES;
|
|
359
508
|
}
|
|
360
509
|
if (offset !== header.length) {
|
|
361
510
|
throw new Error("Stream header has trailing bytes.");
|
|
@@ -385,44 +534,41 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
385
534
|
if (value.some((byte) => byte > 127)) throw new Error("Stream flow id must be ASCII.");
|
|
386
535
|
return String.fromCharCode(...value);
|
|
387
536
|
}
|
|
388
|
-
function
|
|
389
|
-
if (metadata.size >
|
|
537
|
+
function streamWireMetadataSize(metadata) {
|
|
538
|
+
if (metadata.size > UINT8_MAX) {
|
|
390
539
|
throw new Error("Metadata entry count must not exceed 255.");
|
|
391
540
|
}
|
|
392
541
|
let size = 1;
|
|
393
|
-
const
|
|
394
|
-
const
|
|
395
|
-
const
|
|
396
|
-
if (
|
|
542
|
+
for (const [key, value] of metadata) {
|
|
543
|
+
const keySize = utf8Size(key);
|
|
544
|
+
const valueSize = utf8Size(value);
|
|
545
|
+
if (keySize === 0 || keySize > UINT8_MAX) {
|
|
397
546
|
throw new Error("Metadata key length is invalid.");
|
|
398
547
|
}
|
|
399
|
-
if (
|
|
548
|
+
if (valueSize > UINT16_MAX) {
|
|
400
549
|
throw new Error("Metadata value is too large.");
|
|
401
550
|
}
|
|
402
|
-
size += 1 +
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
551
|
+
size += 1 + keySize + UINT16_BYTES + valueSize;
|
|
552
|
+
}
|
|
553
|
+
return size;
|
|
554
|
+
}
|
|
555
|
+
function encodeStreamWireMetadata(metadata) {
|
|
556
|
+
const buffer = new Uint8Array(streamWireMetadataSize(metadata));
|
|
406
557
|
let offset = 0;
|
|
407
558
|
buffer[offset++] = metadata.size;
|
|
408
|
-
for (const
|
|
559
|
+
for (const [key, value] of metadata) {
|
|
560
|
+
const keyBytes = utf8Encode(key);
|
|
561
|
+
const valueBytes = utf8Encode(value);
|
|
409
562
|
buffer[offset++] = keyBytes.length;
|
|
410
563
|
buffer.set(keyBytes, offset);
|
|
411
564
|
offset += keyBytes.length;
|
|
412
565
|
writeUInt16BE(buffer, offset, valueBytes.length);
|
|
413
|
-
offset +=
|
|
566
|
+
offset += UINT16_BYTES;
|
|
414
567
|
buffer.set(valueBytes, offset);
|
|
415
568
|
offset += valueBytes.length;
|
|
416
569
|
}
|
|
417
570
|
return buffer;
|
|
418
571
|
}
|
|
419
|
-
function decodeStreamWireMetadata(metadata) {
|
|
420
|
-
const decoded = decodeStreamWireMetadataAt(metadata, 0, metadata.length);
|
|
421
|
-
if (decoded.offset !== metadata.length) {
|
|
422
|
-
throw new Error("Stream metadata payload has trailing bytes.");
|
|
423
|
-
}
|
|
424
|
-
return decoded.metadata;
|
|
425
|
-
}
|
|
426
572
|
function lz4PickleUncompressed2(payload) {
|
|
427
573
|
return lz4PickleUncompressed(payload);
|
|
428
574
|
}
|
|
@@ -439,11 +585,11 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
439
585
|
return new TextDecoder().decode(value);
|
|
440
586
|
}
|
|
441
587
|
function decodeStreamWireHeaderMetadata(header, offset) {
|
|
442
|
-
if (header.length - offset <
|
|
588
|
+
if (header.length - offset < UINT16_BYTES) {
|
|
443
589
|
throw new Error("Stream metadata section is incomplete.");
|
|
444
590
|
}
|
|
445
591
|
const metadataLength = readUInt16BE(header, offset);
|
|
446
|
-
offset +=
|
|
592
|
+
offset += UINT16_BYTES;
|
|
447
593
|
if (header.length - offset < metadataLength) {
|
|
448
594
|
throw new Error("Stream metadata payload is incomplete.");
|
|
449
595
|
}
|
|
@@ -469,7 +615,7 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
469
615
|
throw new Error("Stream metadata value length is missing.");
|
|
470
616
|
}
|
|
471
617
|
const valueLength = readUInt16BE(source, offset);
|
|
472
|
-
offset +=
|
|
618
|
+
offset += UINT16_BYTES;
|
|
473
619
|
if (end - offset < valueLength) {
|
|
474
620
|
throw new Error("Stream metadata value is incomplete.");
|
|
475
621
|
}
|
|
@@ -486,16 +632,17 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
486
632
|
}
|
|
487
633
|
function validateStreamWirePacketName(name) {
|
|
488
634
|
const nameBytes = utf8Encode(name);
|
|
489
|
-
if (
|
|
635
|
+
if (unicodeWhiteSpaceOnly.test(name) || nameBytes.length > ZLINK_STREAM_MAX_PACKET_NAME_BYTES) {
|
|
490
636
|
throw new Error("Stream packet name is invalid.");
|
|
491
637
|
}
|
|
638
|
+
return nameBytes;
|
|
492
639
|
}
|
|
493
640
|
function isReplyKind(kind) {
|
|
494
|
-
return kind ===
|
|
641
|
+
return kind === 3 /* Response */ || kind === 4 /* Error */;
|
|
495
642
|
}
|
|
496
643
|
function writeUInt16BE(buffer, offset, value) {
|
|
497
|
-
buffer[offset] = value >>> 8 &
|
|
498
|
-
buffer[offset + 1] = value &
|
|
644
|
+
buffer[offset] = value >>> 8 & UINT8_MAX;
|
|
645
|
+
buffer[offset + 1] = value & UINT8_MAX;
|
|
499
646
|
}
|
|
500
647
|
function readUInt16BE(buffer, offset) {
|
|
501
648
|
return buffer[offset] << 8 | buffer[offset + 1];
|
|
@@ -504,10 +651,10 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
504
651
|
return buffer[offset] * 16777216 + (buffer[offset + 1] << 16 | buffer[offset + 2] << 8 | buffer[offset + 3]);
|
|
505
652
|
}
|
|
506
653
|
function writeUInt32BE(buffer, offset, value) {
|
|
507
|
-
buffer[offset] = value >>> 24 &
|
|
508
|
-
buffer[offset + 1] = value >>> 16 &
|
|
509
|
-
buffer[offset + 2] = value >>> 8 &
|
|
510
|
-
buffer[offset + 3] = value &
|
|
654
|
+
buffer[offset] = value >>> 24 & UINT8_MAX;
|
|
655
|
+
buffer[offset + 1] = value >>> 16 & UINT8_MAX;
|
|
656
|
+
buffer[offset + 2] = value >>> 8 & UINT8_MAX;
|
|
657
|
+
buffer[offset + 3] = value & UINT8_MAX;
|
|
511
658
|
}
|
|
512
659
|
function writeBigUInt64BE(buffer, offset, value) {
|
|
513
660
|
for (let index = 7; index >= 0; index -= 1) {
|
|
@@ -522,6 +669,19 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
522
669
|
}
|
|
523
670
|
return value;
|
|
524
671
|
}
|
|
672
|
+
function utf8Size(value) {
|
|
673
|
+
let size = 0;
|
|
674
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
675
|
+
const code = value.charCodeAt(index);
|
|
676
|
+
if (code < UTF8_TWO_BYTE_MIN) size += 1;
|
|
677
|
+
else if (code < UTF8_THREE_BYTE_MIN) size += 2;
|
|
678
|
+
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) {
|
|
679
|
+
size += 4;
|
|
680
|
+
index += 1;
|
|
681
|
+
} else size += 3;
|
|
682
|
+
}
|
|
683
|
+
return size;
|
|
684
|
+
}
|
|
525
685
|
|
|
526
686
|
// packages/stream-connector/src/Contracts/ZlinkStreamEnums.ts
|
|
527
687
|
var ZlinkStreamTransport = /* @__PURE__ */ ((ZlinkStreamTransport2) => {
|
|
@@ -539,24 +699,6 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
539
699
|
ZlinkStreamDispatchMode2["Immediate"] = "immediate";
|
|
540
700
|
return ZlinkStreamDispatchMode2;
|
|
541
701
|
})(ZlinkStreamDispatchMode || {});
|
|
542
|
-
var ZlinkStreamMessageKind = /* @__PURE__ */ ((ZlinkStreamMessageKind2) => {
|
|
543
|
-
ZlinkStreamMessageKind2[ZlinkStreamMessageKind2["Send"] = 1] = "Send";
|
|
544
|
-
ZlinkStreamMessageKind2[ZlinkStreamMessageKind2["Request"] = 2] = "Request";
|
|
545
|
-
ZlinkStreamMessageKind2[ZlinkStreamMessageKind2["Response"] = 3] = "Response";
|
|
546
|
-
ZlinkStreamMessageKind2[ZlinkStreamMessageKind2["Error"] = 4] = "Error";
|
|
547
|
-
ZlinkStreamMessageKind2[ZlinkStreamMessageKind2["Control"] = 5] = "Control";
|
|
548
|
-
return ZlinkStreamMessageKind2;
|
|
549
|
-
})(ZlinkStreamMessageKind || {});
|
|
550
|
-
var ZlinkStreamHeaderFlags = /* @__PURE__ */ ((ZlinkStreamHeaderFlags2) => {
|
|
551
|
-
ZlinkStreamHeaderFlags2[ZlinkStreamHeaderFlags2["None"] = 0] = "None";
|
|
552
|
-
ZlinkStreamHeaderFlags2[ZlinkStreamHeaderFlags2["HasRequestSeq"] = 1] = "HasRequestSeq";
|
|
553
|
-
ZlinkStreamHeaderFlags2[ZlinkStreamHeaderFlags2["HasMetadata"] = 2] = "HasMetadata";
|
|
554
|
-
ZlinkStreamHeaderFlags2[ZlinkStreamHeaderFlags2["PayloadCompressed"] = 4] = "PayloadCompressed";
|
|
555
|
-
ZlinkStreamHeaderFlags2[ZlinkStreamHeaderFlags2["HasCorrelationId"] = 8] = "HasCorrelationId";
|
|
556
|
-
ZlinkStreamHeaderFlags2[ZlinkStreamHeaderFlags2["HasFlowId"] = 16] = "HasFlowId";
|
|
557
|
-
ZlinkStreamHeaderFlags2[ZlinkStreamHeaderFlags2["HasActorSlot"] = 32] = "HasActorSlot";
|
|
558
|
-
return ZlinkStreamHeaderFlags2;
|
|
559
|
-
})(ZlinkStreamHeaderFlags || {});
|
|
560
702
|
var ZlinkStreamErrorCode = /* @__PURE__ */ ((ZlinkStreamErrorCode2) => {
|
|
561
703
|
ZlinkStreamErrorCode2["Disconnected"] = "disconnected";
|
|
562
704
|
ZlinkStreamErrorCode2["ConfigurationError"] = "configurationError";
|
|
@@ -568,6 +710,7 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
568
710
|
ZlinkStreamErrorCode2["SendFailed"] = "sendFailed";
|
|
569
711
|
ZlinkStreamErrorCode2["CompressionFailed"] = "compressionFailed";
|
|
570
712
|
ZlinkStreamErrorCode2["DecompressionFailed"] = "decompressionFailed";
|
|
713
|
+
ZlinkStreamErrorCode2["TlsValidationFailed"] = "tlsValidationFailed";
|
|
571
714
|
ZlinkStreamErrorCode2["UserCallbackFailed"] = "userCallbackFailed";
|
|
572
715
|
ZlinkStreamErrorCode2["RemoteError"] = "remoteError";
|
|
573
716
|
return ZlinkStreamErrorCode2;
|
|
@@ -582,6 +725,15 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
582
725
|
return ZlinkStreamConnectionState3;
|
|
583
726
|
})(ZlinkStreamConnectionState || {});
|
|
584
727
|
|
|
728
|
+
// packages/stream-connector/src/Contracts/ZlinkStreamModels.ts
|
|
729
|
+
var ZlinkStreamException = class extends Error {
|
|
730
|
+
constructor(error) {
|
|
731
|
+
super(error.message);
|
|
732
|
+
this.error = error;
|
|
733
|
+
this.name = "ZlinkStreamException";
|
|
734
|
+
}
|
|
735
|
+
};
|
|
736
|
+
|
|
585
737
|
// packages/stream-connector/src/Contracts/ZlinkStreamMetadata.ts
|
|
586
738
|
var _ZlinkStreamMetadataMap = class _ZlinkStreamMetadataMap {
|
|
587
739
|
constructor(values) {
|
|
@@ -615,25 +767,13 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
615
767
|
var ZlinkStreamMetadataMap = _ZlinkStreamMetadataMap;
|
|
616
768
|
function validateMetadataKey(key) {
|
|
617
769
|
if (key.length === 0) {
|
|
618
|
-
throw new
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
if (code < 32 || code > 126 || key[index] === "=") {
|
|
623
|
-
throw new Error('Metadata key must contain printable ASCII characters except "=".');
|
|
624
|
-
}
|
|
770
|
+
throw new ZlinkStreamException({
|
|
771
|
+
code: "validationFailed" /* ValidationFailed */,
|
|
772
|
+
message: "Metadata key must not be empty."
|
|
773
|
+
});
|
|
625
774
|
}
|
|
626
775
|
}
|
|
627
776
|
|
|
628
|
-
// packages/stream-connector/src/Contracts/ZlinkStreamModels.ts
|
|
629
|
-
var ZlinkStreamException = class extends Error {
|
|
630
|
-
constructor(error) {
|
|
631
|
-
super(error.message);
|
|
632
|
-
this.error = error;
|
|
633
|
-
this.name = "ZlinkStreamException";
|
|
634
|
-
}
|
|
635
|
-
};
|
|
636
|
-
|
|
637
777
|
// packages/stream-connector/src/Contracts/ZlinkStreamJsonCodec.ts
|
|
638
778
|
var zlinkStreamJsonCodecName = "json";
|
|
639
779
|
var codecOptions = {};
|
|
@@ -686,6 +826,10 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
686
826
|
}
|
|
687
827
|
|
|
688
828
|
// packages/stream-connector/src/Runtime/ZlinkStreamSupport.ts
|
|
829
|
+
var BACKING_ARRAY_COMPACTION_MIN_HEAD = 1024;
|
|
830
|
+
function shouldCompactBackingArray(head, length) {
|
|
831
|
+
return head >= BACKING_ARRAY_COMPACTION_MIN_HEAD && head * 2 >= length;
|
|
832
|
+
}
|
|
689
833
|
function connectorError(code, message, cause) {
|
|
690
834
|
return new ZlinkStreamException({ code, message, cause });
|
|
691
835
|
}
|
|
@@ -699,15 +843,21 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
699
843
|
if (error instanceof ZlinkStreamException) {
|
|
700
844
|
return error.error;
|
|
701
845
|
}
|
|
702
|
-
|
|
703
|
-
code: "remoteError" /* RemoteError */,
|
|
704
|
-
message: error instanceof Error ? error.message : String(error),
|
|
705
|
-
cause: error
|
|
706
|
-
};
|
|
846
|
+
throw error;
|
|
707
847
|
}
|
|
708
848
|
function subscription(dispose) {
|
|
709
849
|
return { dispose };
|
|
710
850
|
}
|
|
851
|
+
function* currentRegistrations(registrations, snapshot = Array.from(registrations)) {
|
|
852
|
+
for (const registration of snapshot) {
|
|
853
|
+
if (registrations.has(registration)) yield registration;
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
function registerHandler(handlers, handler) {
|
|
857
|
+
const registration = { handler };
|
|
858
|
+
handlers.add(registration);
|
|
859
|
+
return subscription(() => handlers.delete(registration));
|
|
860
|
+
}
|
|
711
861
|
function throwIfAborted(signal) {
|
|
712
862
|
if ((signal == null ? void 0 : signal.aborted) === true) {
|
|
713
863
|
throw connectorError("disconnected" /* Disconnected */, "Operation canceled.");
|
|
@@ -727,9 +877,6 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
727
877
|
signal == null ? void 0 : signal.addEventListener("abort", onAbort, { once: true });
|
|
728
878
|
});
|
|
729
879
|
}
|
|
730
|
-
function utf8Encode2(value) {
|
|
731
|
-
return new TextEncoder().encode(value);
|
|
732
|
-
}
|
|
733
880
|
function utf8Decode2(value) {
|
|
734
881
|
return new TextDecoder().decode(value);
|
|
735
882
|
}
|
|
@@ -748,59 +895,48 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
748
895
|
}
|
|
749
896
|
},
|
|
750
897
|
async expectFailure(action, errorKind) {
|
|
751
|
-
let failure;
|
|
752
898
|
try {
|
|
753
899
|
await action();
|
|
754
|
-
} catch (
|
|
755
|
-
failure
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
failure
|
|
766
|
-
);
|
|
900
|
+
} catch (failure) {
|
|
901
|
+
if (!(failure instanceof ZlinkStreamException)) throw failure;
|
|
902
|
+
const streamError = failure.error;
|
|
903
|
+
if (errorKind !== void 0 && streamError.code !== errorKind) {
|
|
904
|
+
throw connectorError(
|
|
905
|
+
"validationFailed" /* ValidationFailed */,
|
|
906
|
+
`Expected failure kind '${errorKind}', got '${streamError.code}'.`,
|
|
907
|
+
failure
|
|
908
|
+
);
|
|
909
|
+
}
|
|
910
|
+
return streamError;
|
|
767
911
|
}
|
|
768
|
-
|
|
912
|
+
throw connectorError("validationFailed" /* ValidationFailed */, "Expected action to fail.");
|
|
769
913
|
},
|
|
770
914
|
async expectTimeout(action) {
|
|
771
|
-
let failure;
|
|
772
915
|
try {
|
|
773
916
|
await action();
|
|
774
|
-
} catch (
|
|
775
|
-
failure
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
}
|
|
780
|
-
const code = unwrapStreamError(failure).code;
|
|
781
|
-
if (code !== "requestTimeout" /* RequestTimeout */ && code !== "connectTimeout" /* ConnectTimeout */) {
|
|
782
|
-
throw failure;
|
|
917
|
+
} catch (failure) {
|
|
918
|
+
if (!(failure instanceof ZlinkStreamException) || failure.error.code !== "requestTimeout" /* RequestTimeout */ && failure.error.code !== "connectTimeout" /* ConnectTimeout */) {
|
|
919
|
+
throw failure;
|
|
920
|
+
}
|
|
921
|
+
return;
|
|
783
922
|
}
|
|
923
|
+
throw connectorError("validationFailed" /* ValidationFailed */, "Expected action to time out.");
|
|
784
924
|
}
|
|
785
925
|
};
|
|
786
926
|
|
|
787
927
|
// packages/stream-connector/src/Runtime/Protocol/ZlinkStreamPacketNameValidator.ts
|
|
788
928
|
function validateName(name, allowReserved = false) {
|
|
789
|
-
|
|
790
|
-
|
|
929
|
+
try {
|
|
930
|
+
validateStreamWirePacketName(name);
|
|
931
|
+
} catch (cause) {
|
|
932
|
+
throw connectorError("validationFailed" /* ValidationFailed */, "Message name is invalid.", cause);
|
|
791
933
|
}
|
|
792
|
-
if (!allowReserved && name.startsWith(
|
|
934
|
+
if (!allowReserved && name.startsWith(ZLINK_STREAM_RESERVED_PACKET_NAME_PREFIX)) {
|
|
793
935
|
throw connectorError(
|
|
794
936
|
"validationFailed" /* ValidationFailed */,
|
|
795
937
|
"Message name uses a reserved zlink prefix."
|
|
796
938
|
);
|
|
797
939
|
}
|
|
798
|
-
if (utf8Encode2(name).length > 255) {
|
|
799
|
-
throw connectorError(
|
|
800
|
-
"validationFailed" /* ValidationFailed */,
|
|
801
|
-
"Message name must not exceed 255 UTF-8 bytes."
|
|
802
|
-
);
|
|
803
|
-
}
|
|
804
940
|
}
|
|
805
941
|
|
|
806
942
|
// packages/stream-connector/src/Runtime/Calls/ZlinkStreamCallBuilders.ts
|
|
@@ -1181,9 +1317,165 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1181
1317
|
return compressionCodec != null ? compressionCodec : zlinkStreamLz4CompressionCodec;
|
|
1182
1318
|
}
|
|
1183
1319
|
|
|
1320
|
+
// packages/stream-connector/src/Contracts/ZlinkStreamConnectorOptions.ts
|
|
1321
|
+
var ZLINK_STREAM_DEFAULT_PAYLOAD_BYTES = 64 * 1024;
|
|
1322
|
+
|
|
1323
|
+
// packages/stream-connector/src/Runtime/Transport/ZlinkStreamEndpoint.ts
|
|
1324
|
+
function inferTransport(endpoint) {
|
|
1325
|
+
const url = parseEndpoint(endpoint);
|
|
1326
|
+
switch (url.protocol) {
|
|
1327
|
+
case "ws:":
|
|
1328
|
+
return "webSocket" /* WebSocket */;
|
|
1329
|
+
case "wss:":
|
|
1330
|
+
return "webSocketSecure" /* WebSocketSecure */;
|
|
1331
|
+
default:
|
|
1332
|
+
throw connectorError(
|
|
1333
|
+
"configurationError" /* ConfigurationError */,
|
|
1334
|
+
"The TypeScript Stream Connector supports only ws:// and wss:// endpoints."
|
|
1335
|
+
);
|
|
1336
|
+
}
|
|
1337
|
+
}
|
|
1338
|
+
function parseEndpoint(endpoint) {
|
|
1339
|
+
try {
|
|
1340
|
+
return new URL(endpoint);
|
|
1341
|
+
} catch (cause) {
|
|
1342
|
+
throw connectorError("configurationError" /* ConfigurationError */, "Endpoint is invalid.", cause);
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1345
|
+
|
|
1346
|
+
// packages/stream-connector/src/Runtime/ZlinkStreamConnectorOptions.ts
|
|
1347
|
+
function normalizeOptions(options, defaultTransportFactory) {
|
|
1348
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z;
|
|
1349
|
+
const endpoint = options.endpoint;
|
|
1350
|
+
if (endpoint.trim().length === 0) {
|
|
1351
|
+
throw connectorError("configurationError" /* ConfigurationError */, "Endpoint must not be empty.");
|
|
1352
|
+
}
|
|
1353
|
+
const inferredTransport = inferTransport(endpoint);
|
|
1354
|
+
if (options.transport !== void 0 && options.transport !== inferredTransport) {
|
|
1355
|
+
throw connectorError(
|
|
1356
|
+
"configurationError" /* ConfigurationError */,
|
|
1357
|
+
"Configured transport conflicts with endpoint scheme."
|
|
1358
|
+
);
|
|
1359
|
+
}
|
|
1360
|
+
const normalized = {
|
|
1361
|
+
endpoint,
|
|
1362
|
+
transport: inferredTransport,
|
|
1363
|
+
connectTimeoutMs: (_a = options.connectTimeoutMs) != null ? _a : 5e3,
|
|
1364
|
+
requestTimeoutMs: (_b = options.requestTimeoutMs) != null ? _b : 3e4,
|
|
1365
|
+
waitTimeoutMs: (_c = options.waitTimeoutMs) != null ? _c : 5e3,
|
|
1366
|
+
heartbeat: {
|
|
1367
|
+
enabled: (_e = (_d = options.heartbeat) == null ? void 0 : _d.enabled) != null ? _e : true,
|
|
1368
|
+
intervalMs: (_g = (_f = options.heartbeat) == null ? void 0 : _f.intervalMs) != null ? _g : 1e3,
|
|
1369
|
+
timeoutMs: (_i = (_h = options.heartbeat) == null ? void 0 : _h.timeoutMs) != null ? _i : 5e3
|
|
1370
|
+
},
|
|
1371
|
+
reconnect: {
|
|
1372
|
+
enabled: (_k = (_j = options.reconnect) == null ? void 0 : _j.enabled) != null ? _k : true,
|
|
1373
|
+
initialDelayMs: (_m = (_l = options.reconnect) == null ? void 0 : _l.initialDelayMs) != null ? _m : 250,
|
|
1374
|
+
maxDelayMs: (_o = (_n = options.reconnect) == null ? void 0 : _n.maxDelayMs) != null ? _o : 5e3,
|
|
1375
|
+
backoffFactor: (_q = (_p = options.reconnect) == null ? void 0 : _p.backoffFactor) != null ? _q : 2,
|
|
1376
|
+
maxAttempts: ((_r = options.reconnect) == null ? void 0 : _r.maxAttempts) === void 0 ? 3 : options.reconnect.maxAttempts
|
|
1377
|
+
},
|
|
1378
|
+
maxSendPayloadSize: (_s = options.maxSendPayloadSize) != null ? _s : ZLINK_STREAM_DEFAULT_PAYLOAD_BYTES,
|
|
1379
|
+
maxReceivePayloadSize: (_t = options.maxReceivePayloadSize) != null ? _t : ZLINK_STREAM_DEFAULT_PAYLOAD_BYTES,
|
|
1380
|
+
dispatchMode: (_u = options.dispatchMode) != null ? _u : "manual" /* Manual */,
|
|
1381
|
+
compression: (_v = options.compression) != null ? _v : "lz4" /* Lz4 */,
|
|
1382
|
+
compressionCodec: options.compressionCodec,
|
|
1383
|
+
nameResolver: (_w = options.nameResolver) != null ? _w : defaultPacketNameResolver,
|
|
1384
|
+
transportFactory: (_x = options.transportFactory) != null ? _x : defaultTransportFactory,
|
|
1385
|
+
codec: options.codec
|
|
1386
|
+
};
|
|
1387
|
+
validatePositive(normalized.connectTimeoutMs, "ConnectTimeout");
|
|
1388
|
+
validatePositive(normalized.requestTimeoutMs, "RequestTimeout");
|
|
1389
|
+
validatePositive(normalized.waitTimeoutMs, "WaitTimeout");
|
|
1390
|
+
validatePositive(normalized.maxSendPayloadSize, "MaxSendPayloadSize");
|
|
1391
|
+
validatePositive(normalized.maxReceivePayloadSize, "MaxReceivePayloadSize");
|
|
1392
|
+
validateHeartbeat(normalized.heartbeat);
|
|
1393
|
+
validateReconnect(normalized.reconnect);
|
|
1394
|
+
if (((_y = options.heartbeat) == null ? void 0 : _y.enabled) !== void 0 && typeof options.heartbeat.enabled !== "boolean") {
|
|
1395
|
+
throw connectorError(
|
|
1396
|
+
"validationFailed" /* ValidationFailed */,
|
|
1397
|
+
"Heartbeat enabled must be boolean."
|
|
1398
|
+
);
|
|
1399
|
+
}
|
|
1400
|
+
if (((_z = options.reconnect) == null ? void 0 : _z.enabled) !== void 0 && typeof options.reconnect.enabled !== "boolean") {
|
|
1401
|
+
throw connectorError(
|
|
1402
|
+
"validationFailed" /* ValidationFailed */,
|
|
1403
|
+
"Reconnect enabled must be boolean."
|
|
1404
|
+
);
|
|
1405
|
+
}
|
|
1406
|
+
if (options.compressionCodec !== void 0 && !hasMethods(options.compressionCodec, "compress", "decompress")) {
|
|
1407
|
+
throw connectorError("validationFailed" /* ValidationFailed */, "Compression codec is invalid.");
|
|
1408
|
+
}
|
|
1409
|
+
if (options.codec !== void 0 && !hasMethods(options.codec, "encode", "decode")) {
|
|
1410
|
+
throw connectorError("validationFailed" /* ValidationFailed */, "Payload codec is invalid.");
|
|
1411
|
+
}
|
|
1412
|
+
if (options.nameResolver !== void 0 && !hasMethods(options.nameResolver, "resolve")) {
|
|
1413
|
+
throw connectorError("validationFailed" /* ValidationFailed */, "Packet name resolver is invalid.");
|
|
1414
|
+
}
|
|
1415
|
+
if (options.transportFactory !== void 0 && !hasMethods(options.transportFactory, "connect")) {
|
|
1416
|
+
throw connectorError("validationFailed" /* ValidationFailed */, "Transport factory is invalid.");
|
|
1417
|
+
}
|
|
1418
|
+
if (!Object.values(ZlinkStreamDispatchMode).includes(normalized.dispatchMode)) {
|
|
1419
|
+
throw connectorError("validationFailed" /* ValidationFailed */, "DispatchMode is invalid.");
|
|
1420
|
+
}
|
|
1421
|
+
if (!Object.values(ZlinkStreamCompression).includes(normalized.compression)) {
|
|
1422
|
+
throw connectorError("validationFailed" /* ValidationFailed */, "Compression is invalid.");
|
|
1423
|
+
}
|
|
1424
|
+
validateCompressionCodec(normalized);
|
|
1425
|
+
return normalized;
|
|
1426
|
+
}
|
|
1427
|
+
var defaultPacketNameResolver = {
|
|
1428
|
+
resolve(payloadType) {
|
|
1429
|
+
const declared = payloadType.packetName;
|
|
1430
|
+
if (typeof declared === "string" && declared.length > 0) {
|
|
1431
|
+
return declared;
|
|
1432
|
+
}
|
|
1433
|
+
return payloadType.name;
|
|
1434
|
+
}
|
|
1435
|
+
};
|
|
1436
|
+
function validateCompressionCodec(options) {
|
|
1437
|
+
const compression = options.compression;
|
|
1438
|
+
if (compression === "none" /* None */) {
|
|
1439
|
+
if (options.compressionCodec !== void 0) {
|
|
1440
|
+
throw connectorError(
|
|
1441
|
+
"configurationError" /* ConfigurationError */,
|
|
1442
|
+
"compressionCodec cannot be set when compression is none."
|
|
1443
|
+
);
|
|
1444
|
+
}
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1447
|
+
function validatePositive(value, name) {
|
|
1448
|
+
if (!Number.isFinite(value) || value <= 0) {
|
|
1449
|
+
throw connectorError("validationFailed" /* ValidationFailed */, `${name} must be positive.`);
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1452
|
+
function hasMethods(value, ...names) {
|
|
1453
|
+
if (value === null || typeof value !== "object") return false;
|
|
1454
|
+
const candidate = value;
|
|
1455
|
+
return names.every((name) => typeof candidate[name] === "function");
|
|
1456
|
+
}
|
|
1457
|
+
function validateHeartbeat(options) {
|
|
1458
|
+
const intervalMs = options.intervalMs;
|
|
1459
|
+
const timeoutMs = options.timeoutMs;
|
|
1460
|
+
validatePositive(intervalMs, "Heartbeat interval");
|
|
1461
|
+
validatePositive(timeoutMs, "Heartbeat timeout");
|
|
1462
|
+
}
|
|
1463
|
+
function validateReconnect(options) {
|
|
1464
|
+
validatePositive(options.initialDelayMs, "Reconnect InitialDelay");
|
|
1465
|
+
validatePositive(options.maxDelayMs, "Reconnect MaxDelay");
|
|
1466
|
+
validatePositive(options.backoffFactor, "Reconnect BackoffFactor");
|
|
1467
|
+
const maxAttempts = options.maxAttempts;
|
|
1468
|
+
if (maxAttempts !== null && !(Number.isFinite(maxAttempts) && maxAttempts > 0)) {
|
|
1469
|
+
throw connectorError(
|
|
1470
|
+
"validationFailed" /* ValidationFailed */,
|
|
1471
|
+
"Reconnect MaxAttempts must be null or positive."
|
|
1472
|
+
);
|
|
1473
|
+
}
|
|
1474
|
+
}
|
|
1475
|
+
|
|
1184
1476
|
// packages/stream-connector/src/Runtime/Protocol/ZlinkStreamFrameCodec.ts
|
|
1185
1477
|
var ZlinkStreamFrameCodec = class {
|
|
1186
|
-
static encode(header, payload, maxPayloadSize =
|
|
1478
|
+
static encode(header, payload, maxPayloadSize = ZLINK_STREAM_DEFAULT_PAYLOAD_BYTES) {
|
|
1187
1479
|
validatePayload(payload.length, maxPayloadSize);
|
|
1188
1480
|
try {
|
|
1189
1481
|
return encodeStreamWireFrame(header, payload);
|
|
@@ -1204,35 +1496,14 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1204
1496
|
}
|
|
1205
1497
|
};
|
|
1206
1498
|
function splitZlinkStreamFrames(chunk) {
|
|
1207
|
-
|
|
1499
|
+
try {
|
|
1500
|
+
return splitStreamWireFrames(chunk);
|
|
1501
|
+
} catch (cause) {
|
|
1208
1502
|
throw connectorError(
|
|
1209
1503
|
"frameDecodeFailed" /* FrameDecodeFailed */,
|
|
1210
|
-
"
|
|
1504
|
+
cause instanceof Error ? cause.message : "Frame length does not match prefix."
|
|
1211
1505
|
);
|
|
1212
1506
|
}
|
|
1213
|
-
const frames = [];
|
|
1214
|
-
let offset = 0;
|
|
1215
|
-
while (offset < chunk.length) {
|
|
1216
|
-
const remaining = chunk.length - offset;
|
|
1217
|
-
if (remaining < 6) {
|
|
1218
|
-
throw connectorError(
|
|
1219
|
-
"frameDecodeFailed" /* FrameDecodeFailed */,
|
|
1220
|
-
"Stream frame prefix is incomplete."
|
|
1221
|
-
);
|
|
1222
|
-
}
|
|
1223
|
-
const headerLength = chunk[offset] << 8 | chunk[offset + 1];
|
|
1224
|
-
const payloadLength = chunk[offset + 2] * 16777216 + (chunk[offset + 3] << 16) + (chunk[offset + 4] << 8) + chunk[offset + 5];
|
|
1225
|
-
const frameLength = 6 + headerLength + payloadLength;
|
|
1226
|
-
if (frameLength > remaining) {
|
|
1227
|
-
throw connectorError(
|
|
1228
|
-
"frameDecodeFailed" /* FrameDecodeFailed */,
|
|
1229
|
-
"Frame length does not match prefix."
|
|
1230
|
-
);
|
|
1231
|
-
}
|
|
1232
|
-
frames.push(chunk.subarray(offset, offset + frameLength));
|
|
1233
|
-
offset += frameLength;
|
|
1234
|
-
}
|
|
1235
|
-
return frames;
|
|
1236
1507
|
}
|
|
1237
1508
|
function validatePayload(payloadLength, maxPayloadSize) {
|
|
1238
1509
|
if (payloadLength > maxPayloadSize) {
|
|
@@ -1244,59 +1515,34 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1244
1515
|
}
|
|
1245
1516
|
|
|
1246
1517
|
// packages/stream-connector/src/Runtime/Protocol/ZlinkStreamMetadataCodec.ts
|
|
1247
|
-
var ZLINK_STREAM_MAX_METADATA_BYTES = 1024;
|
|
1248
1518
|
var ZlinkStreamMetadataCodec = class {
|
|
1249
1519
|
static size(metadata) {
|
|
1520
|
+
let size;
|
|
1250
1521
|
try {
|
|
1251
|
-
|
|
1252
|
-
if (size > ZLINK_STREAM_MAX_METADATA_BYTES) {
|
|
1253
|
-
throw connectorError(
|
|
1254
|
-
"validationFailed" /* ValidationFailed */,
|
|
1255
|
-
`Metadata must not exceed ${ZLINK_STREAM_MAX_METADATA_BYTES} bytes.`
|
|
1256
|
-
);
|
|
1257
|
-
}
|
|
1258
|
-
return size;
|
|
1522
|
+
size = metadata.count === 0 ? 0 : streamWireMetadataSize(metadata.values);
|
|
1259
1523
|
} catch (cause) {
|
|
1260
1524
|
throw connectorError(
|
|
1261
1525
|
"validationFailed" /* ValidationFailed */,
|
|
1262
|
-
|
|
1526
|
+
cause instanceof Error ? cause.message : "Metadata is invalid.",
|
|
1263
1527
|
cause
|
|
1264
1528
|
);
|
|
1265
1529
|
}
|
|
1266
|
-
|
|
1267
|
-
static write(metadata, destination) {
|
|
1268
|
-
try {
|
|
1269
|
-
destination.set(encodeStreamWireMetadata(metadata.values));
|
|
1270
|
-
} catch (cause) {
|
|
1530
|
+
if (size > ZLINK_STREAM_MAX_METADATA_BYTES) {
|
|
1271
1531
|
throw connectorError(
|
|
1272
1532
|
"validationFailed" /* ValidationFailed */,
|
|
1273
|
-
|
|
1274
|
-
cause
|
|
1275
|
-
);
|
|
1276
|
-
}
|
|
1277
|
-
}
|
|
1278
|
-
static decode(metadata) {
|
|
1279
|
-
try {
|
|
1280
|
-
const values = decodeStreamWireMetadata(metadata);
|
|
1281
|
-
return values.size === 0 ? ZlinkStreamMetadataMap.empty : ZlinkStreamMetadataMap.from(values);
|
|
1282
|
-
} catch (cause) {
|
|
1283
|
-
throw connectorError(
|
|
1284
|
-
"frameDecodeFailed" /* FrameDecodeFailed */,
|
|
1285
|
-
streamWireErrorMessage(cause),
|
|
1286
|
-
cause
|
|
1533
|
+
`Metadata must not exceed ${ZLINK_STREAM_MAX_METADATA_BYTES} bytes.`
|
|
1287
1534
|
);
|
|
1288
1535
|
}
|
|
1536
|
+
return size;
|
|
1289
1537
|
}
|
|
1290
1538
|
};
|
|
1291
|
-
function streamWireErrorMessage(cause) {
|
|
1292
|
-
return cause instanceof Error ? cause.message : "Metadata is invalid.";
|
|
1293
|
-
}
|
|
1294
1539
|
|
|
1295
1540
|
// packages/stream-connector/src/Runtime/Protocol/ZlinkStreamHeaderCodec.ts
|
|
1296
1541
|
var ZlinkStreamHeaderCodec = class {
|
|
1297
1542
|
static encode(header) {
|
|
1298
1543
|
const reply = isReplyKind2(header.kind);
|
|
1299
1544
|
if (!reply) validateName(header.name, header.kind === 5 /* Control */);
|
|
1545
|
+
validateEncodeFlags(header.flags);
|
|
1300
1546
|
validateHeaderSemantics(header);
|
|
1301
1547
|
ZlinkStreamMetadataCodec.size(header.metadata);
|
|
1302
1548
|
try {
|
|
@@ -1313,7 +1559,7 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1313
1559
|
} catch (cause) {
|
|
1314
1560
|
throw connectorError(
|
|
1315
1561
|
"validationFailed" /* ValidationFailed */,
|
|
1316
|
-
|
|
1562
|
+
streamWireErrorMessage(cause),
|
|
1317
1563
|
cause
|
|
1318
1564
|
);
|
|
1319
1565
|
}
|
|
@@ -1333,25 +1579,24 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1333
1579
|
correlationId: wire.correlationId,
|
|
1334
1580
|
actorSlot: wire.actorSlot
|
|
1335
1581
|
};
|
|
1582
|
+
if (!isReplyKind2(decoded.kind)) {
|
|
1583
|
+
validateName(decoded.name, decoded.kind === 5 /* Control */);
|
|
1584
|
+
}
|
|
1585
|
+
validateHeaderSemantics(decoded);
|
|
1336
1586
|
} catch (cause) {
|
|
1337
1587
|
throw connectorError(
|
|
1338
1588
|
"frameDecodeFailed" /* FrameDecodeFailed */,
|
|
1339
|
-
|
|
1589
|
+
streamWireErrorMessage(cause),
|
|
1340
1590
|
cause
|
|
1341
1591
|
);
|
|
1342
1592
|
}
|
|
1343
|
-
validateEnum(decoded.kind, decoded.codec, decoded.flags);
|
|
1344
|
-
if (!isReplyKind2(decoded.kind)) {
|
|
1345
|
-
validateName(decoded.name, decoded.kind === 5 /* Control */);
|
|
1346
|
-
}
|
|
1347
|
-
validateHeaderSemantics(decoded);
|
|
1348
1593
|
return decoded;
|
|
1349
1594
|
}
|
|
1350
1595
|
};
|
|
1351
1596
|
function isReplyKind2(kind) {
|
|
1352
1597
|
return kind === 3 /* Response */ || kind === 4 /* Error */;
|
|
1353
1598
|
}
|
|
1354
|
-
function
|
|
1599
|
+
function streamWireErrorMessage(cause) {
|
|
1355
1600
|
return cause instanceof Error ? cause.message : "Stream header is invalid.";
|
|
1356
1601
|
}
|
|
1357
1602
|
function buildHeader(kind, name, codec, metadata, compress, requestSeq, correlationId, actorSlot) {
|
|
@@ -1381,7 +1626,7 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1381
1626
|
};
|
|
1382
1627
|
}
|
|
1383
1628
|
function validateHeaderSemantics(header) {
|
|
1384
|
-
validateEnum(header.kind, header.codec
|
|
1629
|
+
validateEnum(header.kind, header.codec);
|
|
1385
1630
|
const hasRequestSeq = header.requestSeq !== void 0 || (header.flags & 1 /* HasRequestSeq */) !== 0;
|
|
1386
1631
|
const hasMetadata = header.metadata.count > 0 || (header.flags & 2 /* HasMetadata */) !== 0;
|
|
1387
1632
|
if (header.kind === 1 /* Send */ && hasRequestSeq) {
|
|
@@ -1414,13 +1659,15 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1414
1659
|
}
|
|
1415
1660
|
}
|
|
1416
1661
|
}
|
|
1417
|
-
function validateEnum(kind, codec
|
|
1418
|
-
if (!
|
|
1662
|
+
function validateEnum(kind, codec) {
|
|
1663
|
+
if (!isStreamWireMessageKind(kind)) {
|
|
1419
1664
|
throw connectorError("frameDecodeFailed" /* FrameDecodeFailed */, "Unknown stream message kind.");
|
|
1420
1665
|
}
|
|
1421
|
-
if (!
|
|
1666
|
+
if (!isStreamWireCodec(codec)) {
|
|
1422
1667
|
throw connectorError("frameDecodeFailed" /* FrameDecodeFailed */, "Unknown stream codec.");
|
|
1423
1668
|
}
|
|
1669
|
+
}
|
|
1670
|
+
function validateEncodeFlags(flags) {
|
|
1424
1671
|
const known = 1 /* HasRequestSeq */ | 2 /* HasMetadata */ | 4 /* PayloadCompressed */ | 8 /* HasCorrelationId */ | 16 /* HasFlowId */ | 32 /* HasActorSlot */;
|
|
1425
1672
|
if ((flags & ~known) !== 0) {
|
|
1426
1673
|
throw connectorError("frameDecodeFailed" /* FrameDecodeFailed */, "Unknown stream header flag.");
|
|
@@ -1428,8 +1675,8 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1428
1675
|
}
|
|
1429
1676
|
|
|
1430
1677
|
// packages/stream-connector/src/Runtime/Protocol/ZlinkStreamFrameProtocol.ts
|
|
1431
|
-
var ZLINK_STREAM_HEARTBEAT_PING =
|
|
1432
|
-
var ZLINK_STREAM_HEARTBEAT_PONG =
|
|
1678
|
+
var ZLINK_STREAM_HEARTBEAT_PING = ZlinkStreamControlPacket.HeartbeatPing;
|
|
1679
|
+
var ZLINK_STREAM_HEARTBEAT_PONG = ZlinkStreamControlPacket.HeartbeatPong;
|
|
1433
1680
|
var ZlinkStreamFrameProtocol = class {
|
|
1434
1681
|
constructor(options) {
|
|
1435
1682
|
this.options = options;
|
|
@@ -1497,166 +1744,6 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1497
1744
|
}
|
|
1498
1745
|
};
|
|
1499
1746
|
|
|
1500
|
-
// packages/stream-connector/src/Runtime/Transport/ZlinkStreamEndpoint.ts
|
|
1501
|
-
function inferTransport(endpoint) {
|
|
1502
|
-
const url = parseEndpoint(endpoint);
|
|
1503
|
-
switch (url.protocol) {
|
|
1504
|
-
case "ws:":
|
|
1505
|
-
return "webSocket" /* WebSocket */;
|
|
1506
|
-
case "wss:":
|
|
1507
|
-
return "webSocketSecure" /* WebSocketSecure */;
|
|
1508
|
-
default:
|
|
1509
|
-
throw connectorError(
|
|
1510
|
-
"configurationError" /* ConfigurationError */,
|
|
1511
|
-
"The TypeScript Stream Connector supports only ws:// and wss:// endpoints."
|
|
1512
|
-
);
|
|
1513
|
-
}
|
|
1514
|
-
}
|
|
1515
|
-
function parseEndpoint(endpoint) {
|
|
1516
|
-
try {
|
|
1517
|
-
return new URL(endpoint);
|
|
1518
|
-
} catch (cause) {
|
|
1519
|
-
throw connectorError("configurationError" /* ConfigurationError */, "Endpoint is invalid.", cause);
|
|
1520
|
-
}
|
|
1521
|
-
}
|
|
1522
|
-
|
|
1523
|
-
// packages/stream-connector/src/Runtime/ZlinkStreamConnectorOptions.ts
|
|
1524
|
-
function normalizeOptions(options, defaultTransportFactory) {
|
|
1525
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G;
|
|
1526
|
-
const endpoint = options.endpoint;
|
|
1527
|
-
if (endpoint.trim().length === 0) {
|
|
1528
|
-
throw connectorError("configurationError" /* ConfigurationError */, "Endpoint must not be empty.");
|
|
1529
|
-
}
|
|
1530
|
-
const inferredTransport = inferTransport(endpoint);
|
|
1531
|
-
if (options.transport !== void 0 && options.transport !== inferredTransport) {
|
|
1532
|
-
throw connectorError(
|
|
1533
|
-
"configurationError" /* ConfigurationError */,
|
|
1534
|
-
"Configured transport conflicts with endpoint scheme."
|
|
1535
|
-
);
|
|
1536
|
-
}
|
|
1537
|
-
validatePositive((_a = options.connectTimeoutMs) != null ? _a : 5e3, "ConnectTimeout");
|
|
1538
|
-
validatePositive((_b = options.requestTimeoutMs) != null ? _b : 3e4, "RequestTimeout");
|
|
1539
|
-
validatePositive((_c = options.waitTimeoutMs) != null ? _c : 5e3, "WaitTimeout");
|
|
1540
|
-
validatePositive((_d = options.maxSendPayloadSize) != null ? _d : 64 * 1024, "MaxSendPayloadSize");
|
|
1541
|
-
validatePositive((_e = options.maxReceivePayloadSize) != null ? _e : 64 * 1024, "MaxReceivePayloadSize");
|
|
1542
|
-
validateHeartbeat(options.heartbeat);
|
|
1543
|
-
validateReconnect(options.reconnect);
|
|
1544
|
-
if (((_f = options.heartbeat) == null ? void 0 : _f.enabled) !== void 0 && typeof options.heartbeat.enabled !== "boolean") {
|
|
1545
|
-
throw connectorError(
|
|
1546
|
-
"validationFailed" /* ValidationFailed */,
|
|
1547
|
-
"Heartbeat enabled must be boolean."
|
|
1548
|
-
);
|
|
1549
|
-
}
|
|
1550
|
-
if (((_g = options.reconnect) == null ? void 0 : _g.enabled) !== void 0 && typeof options.reconnect.enabled !== "boolean") {
|
|
1551
|
-
throw connectorError(
|
|
1552
|
-
"validationFailed" /* ValidationFailed */,
|
|
1553
|
-
"Reconnect enabled must be boolean."
|
|
1554
|
-
);
|
|
1555
|
-
}
|
|
1556
|
-
if (options.compressionCodec !== void 0 && !hasMethods(options.compressionCodec, "compress", "decompress")) {
|
|
1557
|
-
throw connectorError("validationFailed" /* ValidationFailed */, "Compression codec is invalid.");
|
|
1558
|
-
}
|
|
1559
|
-
if (options.codec !== void 0 && !hasMethods(options.codec, "encode", "decode")) {
|
|
1560
|
-
throw connectorError("validationFailed" /* ValidationFailed */, "Payload codec is invalid.");
|
|
1561
|
-
}
|
|
1562
|
-
if (options.nameResolver !== void 0 && !hasMethods(options.nameResolver, "resolve")) {
|
|
1563
|
-
throw connectorError("validationFailed" /* ValidationFailed */, "Packet name resolver is invalid.");
|
|
1564
|
-
}
|
|
1565
|
-
if (options.transportFactory !== void 0 && !hasMethods(options.transportFactory, "connect")) {
|
|
1566
|
-
throw connectorError("validationFailed" /* ValidationFailed */, "Transport factory is invalid.");
|
|
1567
|
-
}
|
|
1568
|
-
if (!Object.values(ZlinkStreamDispatchMode).includes(
|
|
1569
|
-
(_h = options.dispatchMode) != null ? _h : "manual" /* Manual */
|
|
1570
|
-
)) {
|
|
1571
|
-
throw connectorError("validationFailed" /* ValidationFailed */, "DispatchMode is invalid.");
|
|
1572
|
-
}
|
|
1573
|
-
if (!Object.values(ZlinkStreamCompression).includes(
|
|
1574
|
-
(_i = options.compression) != null ? _i : "lz4" /* Lz4 */
|
|
1575
|
-
)) {
|
|
1576
|
-
throw connectorError("validationFailed" /* ValidationFailed */, "Compression is invalid.");
|
|
1577
|
-
}
|
|
1578
|
-
return {
|
|
1579
|
-
endpoint,
|
|
1580
|
-
transport: inferredTransport,
|
|
1581
|
-
connectTimeoutMs: (_j = options.connectTimeoutMs) != null ? _j : 5e3,
|
|
1582
|
-
requestTimeoutMs: (_k = options.requestTimeoutMs) != null ? _k : 3e4,
|
|
1583
|
-
waitTimeoutMs: (_l = options.waitTimeoutMs) != null ? _l : 5e3,
|
|
1584
|
-
heartbeat: {
|
|
1585
|
-
enabled: (_n = (_m = options.heartbeat) == null ? void 0 : _m.enabled) != null ? _n : true,
|
|
1586
|
-
intervalMs: (_p = (_o = options.heartbeat) == null ? void 0 : _o.intervalMs) != null ? _p : 1e3,
|
|
1587
|
-
timeoutMs: (_r = (_q = options.heartbeat) == null ? void 0 : _q.timeoutMs) != null ? _r : 5e3
|
|
1588
|
-
},
|
|
1589
|
-
reconnect: {
|
|
1590
|
-
enabled: (_t = (_s = options.reconnect) == null ? void 0 : _s.enabled) != null ? _t : true,
|
|
1591
|
-
initialDelayMs: (_v = (_u = options.reconnect) == null ? void 0 : _u.initialDelayMs) != null ? _v : 250,
|
|
1592
|
-
maxDelayMs: (_x = (_w = options.reconnect) == null ? void 0 : _w.maxDelayMs) != null ? _x : 5e3,
|
|
1593
|
-
backoffFactor: (_z = (_y = options.reconnect) == null ? void 0 : _y.backoffFactor) != null ? _z : 2,
|
|
1594
|
-
maxAttempts: ((_A = options.reconnect) == null ? void 0 : _A.maxAttempts) === void 0 ? 3 : options.reconnect.maxAttempts
|
|
1595
|
-
},
|
|
1596
|
-
maxSendPayloadSize: (_B = options.maxSendPayloadSize) != null ? _B : 64 * 1024,
|
|
1597
|
-
maxReceivePayloadSize: (_C = options.maxReceivePayloadSize) != null ? _C : 64 * 1024,
|
|
1598
|
-
dispatchMode: (_D = options.dispatchMode) != null ? _D : "manual" /* Manual */,
|
|
1599
|
-
compression: (_E = options.compression) != null ? _E : "lz4" /* Lz4 */,
|
|
1600
|
-
compressionCodec: resolveCompressionCodec2(options),
|
|
1601
|
-
nameResolver: (_F = options.nameResolver) != null ? _F : defaultPacketNameResolver,
|
|
1602
|
-
transportFactory: (_G = options.transportFactory) != null ? _G : defaultTransportFactory,
|
|
1603
|
-
codec: options.codec
|
|
1604
|
-
};
|
|
1605
|
-
}
|
|
1606
|
-
var defaultPacketNameResolver = {
|
|
1607
|
-
resolve(payloadType) {
|
|
1608
|
-
const declared = payloadType.packetName;
|
|
1609
|
-
if (typeof declared === "string" && declared.length > 0) {
|
|
1610
|
-
return declared;
|
|
1611
|
-
}
|
|
1612
|
-
return payloadType.name;
|
|
1613
|
-
}
|
|
1614
|
-
};
|
|
1615
|
-
function resolveCompressionCodec2(options) {
|
|
1616
|
-
var _a;
|
|
1617
|
-
const compression = (_a = options.compression) != null ? _a : "lz4" /* Lz4 */;
|
|
1618
|
-
if (compression === "none" /* None */) {
|
|
1619
|
-
if (options.compressionCodec !== void 0) {
|
|
1620
|
-
throw connectorError(
|
|
1621
|
-
"configurationError" /* ConfigurationError */,
|
|
1622
|
-
"compressionCodec cannot be set when compression is none."
|
|
1623
|
-
);
|
|
1624
|
-
}
|
|
1625
|
-
return void 0;
|
|
1626
|
-
}
|
|
1627
|
-
return options.compressionCodec;
|
|
1628
|
-
}
|
|
1629
|
-
function validatePositive(value, name) {
|
|
1630
|
-
if (!Number.isFinite(value) || value <= 0) {
|
|
1631
|
-
throw connectorError("validationFailed" /* ValidationFailed */, `${name} must be positive.`);
|
|
1632
|
-
}
|
|
1633
|
-
}
|
|
1634
|
-
function hasMethods(value, ...names) {
|
|
1635
|
-
if (value === null || typeof value !== "object") return false;
|
|
1636
|
-
const candidate = value;
|
|
1637
|
-
return names.every((name) => typeof candidate[name] === "function");
|
|
1638
|
-
}
|
|
1639
|
-
function validateHeartbeat(options) {
|
|
1640
|
-
var _a, _b;
|
|
1641
|
-
const intervalMs = (_a = options == null ? void 0 : options.intervalMs) != null ? _a : 1e3;
|
|
1642
|
-
const timeoutMs = (_b = options == null ? void 0 : options.timeoutMs) != null ? _b : 5e3;
|
|
1643
|
-
validatePositive(intervalMs, "Heartbeat interval");
|
|
1644
|
-
validatePositive(timeoutMs, "Heartbeat timeout");
|
|
1645
|
-
}
|
|
1646
|
-
function validateReconnect(options) {
|
|
1647
|
-
var _a, _b, _c;
|
|
1648
|
-
validatePositive((_a = options == null ? void 0 : options.initialDelayMs) != null ? _a : 250, "Reconnect InitialDelay");
|
|
1649
|
-
validatePositive((_b = options == null ? void 0 : options.maxDelayMs) != null ? _b : 5e3, "Reconnect MaxDelay");
|
|
1650
|
-
validatePositive((_c = options == null ? void 0 : options.backoffFactor) != null ? _c : 2, "Reconnect BackoffFactor");
|
|
1651
|
-
const maxAttempts = (options == null ? void 0 : options.maxAttempts) === void 0 ? 3 : options.maxAttempts;
|
|
1652
|
-
if (maxAttempts !== null && !(Number.isFinite(maxAttempts) && maxAttempts > 0)) {
|
|
1653
|
-
throw connectorError(
|
|
1654
|
-
"validationFailed" /* ValidationFailed */,
|
|
1655
|
-
"Reconnect MaxAttempts must be null or positive."
|
|
1656
|
-
);
|
|
1657
|
-
}
|
|
1658
|
-
}
|
|
1659
|
-
|
|
1660
1747
|
// packages/stream-connector/src/Runtime/ZlinkStreamPendingRequests.ts
|
|
1661
1748
|
var ZlinkStreamPendingRequests = class {
|
|
1662
1749
|
constructor() {
|
|
@@ -1664,7 +1751,7 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1664
1751
|
__publicField(this, "active", /* @__PURE__ */ new Map());
|
|
1665
1752
|
}
|
|
1666
1753
|
create(packetName, timeoutMs) {
|
|
1667
|
-
if (this.nextRequestSeq >
|
|
1754
|
+
if (this.nextRequestSeq > UINT64_MAX) {
|
|
1668
1755
|
throw connectorError("sendFailed" /* SendFailed */, "Request sequence is exhausted.");
|
|
1669
1756
|
}
|
|
1670
1757
|
const requestSeq = this.nextRequestSeq++;
|
|
@@ -1748,8 +1835,8 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1748
1835
|
};
|
|
1749
1836
|
|
|
1750
1837
|
// packages/stream-connector/src/Runtime/ZlinkStreamActors.ts
|
|
1751
|
-
var ACTOR_BOUND =
|
|
1752
|
-
var ACTOR_UNBOUND =
|
|
1838
|
+
var ACTOR_BOUND = ZlinkStreamControlPacket.ActorBound;
|
|
1839
|
+
var ACTOR_UNBOUND = ZlinkStreamControlPacket.ActorUnbound;
|
|
1753
1840
|
var zlinkStreamActorBinding = Symbol("zlink.stream.actorBinding");
|
|
1754
1841
|
var DefaultZlinkStreamActor = class {
|
|
1755
1842
|
constructor(connector, actorId, slot) {
|
|
@@ -1791,7 +1878,6 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1791
1878
|
this.events = events;
|
|
1792
1879
|
__publicField(this, "bySlot", /* @__PURE__ */ new Map());
|
|
1793
1880
|
__publicField(this, "byId", /* @__PURE__ */ new Map());
|
|
1794
|
-
__publicField(this, "issued", []);
|
|
1795
1881
|
__publicField(this, "boundHandlers", /* @__PURE__ */ new Set());
|
|
1796
1882
|
__publicField(this, "unboundHandlers", /* @__PURE__ */ new Set());
|
|
1797
1883
|
}
|
|
@@ -1802,12 +1888,10 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1802
1888
|
return this.byId.get(actorId);
|
|
1803
1889
|
}
|
|
1804
1890
|
onBound(handler) {
|
|
1805
|
-
this.boundHandlers
|
|
1806
|
-
return subscription(() => this.boundHandlers.delete(handler));
|
|
1891
|
+
return registerHandler(this.boundHandlers, handler);
|
|
1807
1892
|
}
|
|
1808
1893
|
onUnbound(handler) {
|
|
1809
|
-
this.unboundHandlers
|
|
1810
|
-
return subscription(() => this.unboundHandlers.delete(handler));
|
|
1894
|
+
return registerHandler(this.unboundHandlers, handler);
|
|
1811
1895
|
}
|
|
1812
1896
|
processControl(name, payload, signal) {
|
|
1813
1897
|
if (name === ACTOR_BOUND) {
|
|
@@ -1831,48 +1915,43 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1831
1915
|
return actor;
|
|
1832
1916
|
}
|
|
1833
1917
|
closeAll(signal) {
|
|
1834
|
-
for (const actor of this.
|
|
1835
|
-
if (!actor.isBound) continue;
|
|
1918
|
+
for (const actor of this.bySlot.values()) {
|
|
1836
1919
|
this.bySlot.delete(actor.slot);
|
|
1837
1920
|
this.byId.delete(actor.actorId);
|
|
1838
1921
|
actor.close();
|
|
1839
1922
|
this.queue(this.unboundHandlers, actor, signal);
|
|
1840
1923
|
}
|
|
1841
|
-
this.issued.length = 0;
|
|
1842
1924
|
}
|
|
1843
1925
|
bind(payload, signal) {
|
|
1844
|
-
|
|
1845
|
-
throw invalidControl("Actor bound payload is invalid.");
|
|
1846
|
-
}
|
|
1847
|
-
const slot = payload[1] << 8 | payload[2];
|
|
1848
|
-
const idLength = payload[3];
|
|
1849
|
-
if (slot === 0 || idLength === 0 || payload.length !== 4 + idLength) {
|
|
1850
|
-
throw invalidControl("Actor bound payload is invalid.");
|
|
1851
|
-
}
|
|
1852
|
-
let actorId;
|
|
1926
|
+
let binding;
|
|
1853
1927
|
try {
|
|
1854
|
-
|
|
1928
|
+
binding = decodeStreamWireActorBoundPayload(payload);
|
|
1855
1929
|
} catch (cause) {
|
|
1856
1930
|
throw connectorError(
|
|
1857
1931
|
"frameDecodeFailed" /* FrameDecodeFailed */,
|
|
1858
|
-
"Actor
|
|
1859
|
-
cause
|
|
1932
|
+
cause instanceof Error ? cause.message : "Actor bound payload is invalid.",
|
|
1933
|
+
cause instanceof Error ? cause.cause : void 0
|
|
1860
1934
|
);
|
|
1861
1935
|
}
|
|
1936
|
+
const { slot, actorId } = binding;
|
|
1862
1937
|
if (actorId.length === 0 || this.bySlot.has(slot) || this.byId.has(actorId)) {
|
|
1863
1938
|
throw invalidControl("Actor bound identity is already in use.");
|
|
1864
1939
|
}
|
|
1865
1940
|
const actor = new DefaultZlinkStreamActor(this.connector, actorId, slot);
|
|
1866
1941
|
this.bySlot.set(slot, actor);
|
|
1867
1942
|
this.byId.set(actorId, actor);
|
|
1868
|
-
this.issued.push(actor);
|
|
1869
1943
|
this.queue(this.boundHandlers, actor, signal);
|
|
1870
1944
|
}
|
|
1871
1945
|
unbind(payload, signal) {
|
|
1872
|
-
|
|
1873
|
-
|
|
1946
|
+
let slot;
|
|
1947
|
+
try {
|
|
1948
|
+
slot = decodeStreamWireActorUnboundPayload(payload);
|
|
1949
|
+
} catch (cause) {
|
|
1950
|
+
throw connectorError(
|
|
1951
|
+
"frameDecodeFailed" /* FrameDecodeFailed */,
|
|
1952
|
+
cause instanceof Error ? cause.message : "Actor unbound payload is invalid."
|
|
1953
|
+
);
|
|
1874
1954
|
}
|
|
1875
|
-
const slot = payload[1] << 8 | payload[2];
|
|
1876
1955
|
const actor = this.bySlot.get(slot);
|
|
1877
1956
|
if (slot === 0 || actor === void 0) {
|
|
1878
1957
|
throw invalidControl(`Actor slot '${slot}' is not bound.`);
|
|
@@ -1885,7 +1964,7 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1885
1964
|
queue(handlers, actor, signal) {
|
|
1886
1965
|
this.receivedMessages.enqueueCallback(
|
|
1887
1966
|
() => {
|
|
1888
|
-
for (const handler of
|
|
1967
|
+
for (const { handler } of currentRegistrations(handlers)) {
|
|
1889
1968
|
this.events.runUserCallback(
|
|
1890
1969
|
() => handler(actor, signal),
|
|
1891
1970
|
"Actor lifecycle handler failed.",
|
|
@@ -1903,7 +1982,7 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1903
1982
|
|
|
1904
1983
|
// packages/stream-connector/src/Runtime/ZlinkStreamReceivedMessages.ts
|
|
1905
1984
|
function receives(registration, message) {
|
|
1906
|
-
return registration.actor === void 0 || registration.actor === message[zlinkStreamActorBinding];
|
|
1985
|
+
return registration.actor === void 0 || registration.actor.isBound && registration.actor === message[zlinkStreamActorBinding];
|
|
1907
1986
|
}
|
|
1908
1987
|
var ZlinkStreamReceivedMessages = class {
|
|
1909
1988
|
/**
|
|
@@ -2112,7 +2191,8 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
2112
2191
|
}
|
|
2113
2192
|
const { message, signal } = queued;
|
|
2114
2193
|
const handlers = this.receiversOf(message);
|
|
2115
|
-
for (const handler of handlers) {
|
|
2194
|
+
for (const handler of currentRegistrations(this.handlers.get(message.name), handlers)) {
|
|
2195
|
+
if (!receives(handler, message)) continue;
|
|
2116
2196
|
this.events.runUserCallback(
|
|
2117
2197
|
() => handler.handle(message, signal),
|
|
2118
2198
|
"Typed message handler failed.",
|
|
@@ -2227,8 +2307,14 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
2227
2307
|
this.deliverable.length = 0;
|
|
2228
2308
|
return;
|
|
2229
2309
|
}
|
|
2230
|
-
|
|
2231
|
-
|
|
2310
|
+
const removed = this.queue.length - this.queuedCount;
|
|
2311
|
+
if (shouldCompactBackingArray(removed, this.queue.length)) {
|
|
2312
|
+
let destination = 0;
|
|
2313
|
+
for (let source = this.queueHead; source < this.queue.length; source += 1) {
|
|
2314
|
+
const queued = this.queue[source];
|
|
2315
|
+
if (queued !== void 0) this.queue[destination++] = queued;
|
|
2316
|
+
}
|
|
2317
|
+
this.queue.length = destination;
|
|
2232
2318
|
this.queueHead = 0;
|
|
2233
2319
|
this.deliverable.length = 0;
|
|
2234
2320
|
for (let index = 0; index < this.queue.length; index += 1) {
|
|
@@ -2259,7 +2345,7 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
2259
2345
|
this.advance();
|
|
2260
2346
|
}
|
|
2261
2347
|
cancel(operation, error) {
|
|
2262
|
-
if (this.queue.
|
|
2348
|
+
if (this.queue.delete(operation) || this.active === operation) operation.fail(error);
|
|
2263
2349
|
}
|
|
2264
2350
|
/**
|
|
2265
2351
|
* Spec stream-connector 32 §7: when the connection ends, frames that have not
|
|
@@ -2267,7 +2353,8 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
2267
2353
|
* waited for. The operations of both fail with `error`.
|
|
2268
2354
|
*/
|
|
2269
2355
|
failAll(error) {
|
|
2270
|
-
const operations =
|
|
2356
|
+
const operations = Array.from(this.queue);
|
|
2357
|
+
if (this.active !== void 0) operations.unshift(this.active);
|
|
2271
2358
|
this.queue.clear();
|
|
2272
2359
|
this.active = void 0;
|
|
2273
2360
|
for (const operation of operations) operation.fail(error);
|
|
@@ -2406,26 +2493,7 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
2406
2493
|
};
|
|
2407
2494
|
|
|
2408
2495
|
// packages/stream-connector/src/Runtime/Protocol/ZlinkSessionClosing.ts
|
|
2409
|
-
var ZLINK_SESSION_CLOSING =
|
|
2410
|
-
var reasons = {
|
|
2411
|
-
1: "ClientClose",
|
|
2412
|
-
2: "IdleTimeout",
|
|
2413
|
-
3: "HeartbeatTimeout",
|
|
2414
|
-
4: "ServerDrain",
|
|
2415
|
-
5: "ProtocolError",
|
|
2416
|
-
6: "TransportError"
|
|
2417
|
-
};
|
|
2418
|
-
function decodeSessionClosing(payload) {
|
|
2419
|
-
if (payload.length < 4 || payload[0] !== 1)
|
|
2420
|
-
throw new Error("Unsupported session-closing version.");
|
|
2421
|
-
const closeReason = reasons[payload[1]];
|
|
2422
|
-
if (closeReason === void 0) throw new Error("Unknown session-closing reason.");
|
|
2423
|
-
const length = payload[2] << 8 | payload[3];
|
|
2424
|
-
if (length > 512 || payload.length !== 4 + length)
|
|
2425
|
-
throw new Error("Invalid session-closing diagnostic length.");
|
|
2426
|
-
const diagnostic = length === 0 ? void 0 : new TextDecoder("utf-8", { fatal: true }).decode(payload.subarray(4));
|
|
2427
|
-
return { closeReason, diagnostic };
|
|
2428
|
-
}
|
|
2496
|
+
var ZLINK_SESSION_CLOSING = ZlinkStreamControlPacket.SessionClosing;
|
|
2429
2497
|
|
|
2430
2498
|
// packages/stream-connector/src/Runtime/ZlinkStreamReceiveDispatcher.ts
|
|
2431
2499
|
function closeReasonFor(error) {
|
|
@@ -2551,27 +2619,21 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
2551
2619
|
}
|
|
2552
2620
|
return;
|
|
2553
2621
|
}
|
|
2554
|
-
if (header.kind === 4 /* Error */
|
|
2622
|
+
if (header.kind === 4 /* Error */) {
|
|
2623
|
+
let error;
|
|
2555
2624
|
try {
|
|
2556
|
-
|
|
2557
|
-
if (!this.pendingRequests.reject(header.requestSeq, remoteError)) {
|
|
2558
|
-
this.events.publishError(remoteError, signal);
|
|
2559
|
-
}
|
|
2625
|
+
error = decodeRemoteError(this.decodePayload(header, payload));
|
|
2560
2626
|
} catch (cause) {
|
|
2561
2627
|
if (cause instanceof ZlinkStreamConnectionEnd) throw cause;
|
|
2562
|
-
|
|
2628
|
+
error = toStreamError(
|
|
2563
2629
|
cause,
|
|
2564
2630
|
"frameDecodeFailed" /* FrameDecodeFailed */,
|
|
2565
2631
|
"Remote error payload is invalid."
|
|
2566
2632
|
);
|
|
2567
|
-
if (!this.pendingRequests.reject(header.requestSeq, decodeError)) {
|
|
2568
|
-
this.events.publishError(decodeError, signal);
|
|
2569
|
-
}
|
|
2570
2633
|
}
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
this.events.publishError(decodeRemoteError(this.decodePayload(header, payload)), signal);
|
|
2634
|
+
if (header.requestSeq === void 0 || !this.pendingRequests.reject(header.requestSeq, error)) {
|
|
2635
|
+
this.events.publishError(error, signal);
|
|
2636
|
+
}
|
|
2575
2637
|
return;
|
|
2576
2638
|
}
|
|
2577
2639
|
if (header.kind === 5 /* Control */) {
|
|
@@ -2597,7 +2659,7 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
2597
2659
|
return;
|
|
2598
2660
|
}
|
|
2599
2661
|
if (header.name === ZLINK_SESSION_CLOSING) {
|
|
2600
|
-
const closing =
|
|
2662
|
+
const closing = decodeStreamWireSessionClosing(payload);
|
|
2601
2663
|
await ((_a = this.serverClosing) == null ? void 0 : _a.call(this, closing.closeReason));
|
|
2602
2664
|
return;
|
|
2603
2665
|
}
|
|
@@ -2638,8 +2700,11 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
2638
2700
|
}
|
|
2639
2701
|
|
|
2640
2702
|
// packages/stream-connector/src/Runtime/ZlinkStreamConnectorLifecycle.ts
|
|
2703
|
+
var RECONNECT_JITTER_FLOOR = 0.5;
|
|
2641
2704
|
function randomizedDelay(baseDelayMs) {
|
|
2642
|
-
return Math.round(
|
|
2705
|
+
return Math.round(
|
|
2706
|
+
baseDelayMs * (RECONNECT_JITTER_FLOOR + Math.random() * (1 - RECONNECT_JITTER_FLOOR))
|
|
2707
|
+
);
|
|
2643
2708
|
}
|
|
2644
2709
|
var ZlinkStreamConnectorLifecycle = class {
|
|
2645
2710
|
constructor(options, pendingRequests, frameSender, receiveDispatcher, receivedMessages, actors, events) {
|
|
@@ -2667,7 +2732,6 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
2667
2732
|
__publicField(this, "closeRequested", false);
|
|
2668
2733
|
__publicField(this, "disconnectedPublished", false);
|
|
2669
2734
|
__publicField(this, "closeReasonValue");
|
|
2670
|
-
__publicField(this, "lateConnectCleanupError");
|
|
2671
2735
|
}
|
|
2672
2736
|
get isConnected() {
|
|
2673
2737
|
return this.currentState === "connected" /* Connected */;
|
|
@@ -2711,12 +2775,7 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
2711
2775
|
try {
|
|
2712
2776
|
const connection = await this.connectWithReconnect(attempts.signal);
|
|
2713
2777
|
if (this.closeRequested) {
|
|
2714
|
-
|
|
2715
|
-
await connection.close(signal);
|
|
2716
|
-
} catch (error) {
|
|
2717
|
-
this.lateConnectCleanupError = error;
|
|
2718
|
-
throw error;
|
|
2719
|
-
}
|
|
2778
|
+
await this.closeTransport(connection, void 0, signal);
|
|
2720
2779
|
throw connectorError(
|
|
2721
2780
|
"disconnected" /* Disconnected */,
|
|
2722
2781
|
"Connector closed while connecting."
|
|
@@ -2796,23 +2855,10 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
2796
2855
|
(_a = this.connectAbort) == null ? void 0 : _a.abort();
|
|
2797
2856
|
await ((_b = this.connectTask) == null ? void 0 : _b.catch(() => void 0));
|
|
2798
2857
|
await ((_c = this.disconnectTask) == null ? void 0 : _c.catch(() => void 0));
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
}
|
|
2804
|
-
try {
|
|
2805
|
-
await this.tearDownConnection(
|
|
2806
|
-
{ code: "disconnected" /* Disconnected */, message: "Connector closed." },
|
|
2807
|
-
signal
|
|
2808
|
-
);
|
|
2809
|
-
} catch (error) {
|
|
2810
|
-
errors.push(error);
|
|
2811
|
-
}
|
|
2812
|
-
this.setState("closed" /* Closed */, void 0, signal);
|
|
2813
|
-
this.publishDisconnected(signal);
|
|
2814
|
-
if (errors.length === 1) throw errors[0];
|
|
2815
|
-
if (errors.length > 1) throw new AggregateError(errors, "Stream connector close failed.");
|
|
2858
|
+
await this.tearDownConnection(
|
|
2859
|
+
{ code: "disconnected" /* Disconnected */, message: "Connector closed." },
|
|
2860
|
+
signal
|
|
2861
|
+
);
|
|
2816
2862
|
}
|
|
2817
2863
|
/**
|
|
2818
2864
|
* Spec stream-connector 32 §7: `dispatch` runs the callbacks the receive loop
|
|
@@ -3021,19 +3067,26 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
3021
3067
|
if (this.disconnectTask !== void 0) {
|
|
3022
3068
|
return await this.disconnectTask;
|
|
3023
3069
|
}
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3070
|
+
let resolve;
|
|
3071
|
+
let reject;
|
|
3072
|
+
const pending = new Promise((complete, fail) => {
|
|
3073
|
+
resolve = complete;
|
|
3074
|
+
reject = fail;
|
|
3027
3075
|
});
|
|
3028
|
-
|
|
3029
|
-
|
|
3076
|
+
const task = pending.finally(() => {
|
|
3077
|
+
if (this.disconnectTask === task) this.disconnectTask = void 0;
|
|
3078
|
+
});
|
|
3079
|
+
this.disconnectTask = task;
|
|
3080
|
+
void this.tearDownConnection(error).then(resolve, reject);
|
|
3081
|
+
await task;
|
|
3082
|
+
this.announceDisconnect();
|
|
3030
3083
|
}
|
|
3031
3084
|
isCurrentConnection(connection, generation) {
|
|
3032
3085
|
return !this.closeRequested && this.currentConnection === connection && this.connectionGeneration === generation;
|
|
3033
3086
|
}
|
|
3034
3087
|
/**
|
|
3035
3088
|
* Ends the current connection, for close and for transport loss alike. No
|
|
3036
|
-
* application callback runs
|
|
3089
|
+
* application callback runs before terminal operations settle. Spec stream-connector 32 §7 and §9:
|
|
3037
3090
|
* every operation the ending connection fails (the frames it has not
|
|
3038
3091
|
* written, the one it is writing and the pending requests) fails with
|
|
3039
3092
|
* `Disconnected`, whatever ended it; the cause stays in the close reason.
|
|
@@ -3054,7 +3107,31 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
3054
3107
|
this.pendingRequests.failAll(disconnected);
|
|
3055
3108
|
this.receivedMessages.connectionEnded();
|
|
3056
3109
|
this.actors.closeAll(signal);
|
|
3057
|
-
await (connection
|
|
3110
|
+
await this.closeTransport(connection, error, signal);
|
|
3111
|
+
}
|
|
3112
|
+
async closeTransport(connection, error, signal) {
|
|
3113
|
+
try {
|
|
3114
|
+
try {
|
|
3115
|
+
await (connection == null ? void 0 : connection.close(signal));
|
|
3116
|
+
} finally {
|
|
3117
|
+
this.setState(
|
|
3118
|
+
this.closeRequested ? "closed" /* Closed */ : "disconnected" /* Disconnected */,
|
|
3119
|
+
this.closeRequested ? void 0 : error,
|
|
3120
|
+
signal
|
|
3121
|
+
);
|
|
3122
|
+
}
|
|
3123
|
+
} catch (cause) {
|
|
3124
|
+
this.events.publishError(
|
|
3125
|
+
{
|
|
3126
|
+
code: "disconnected" /* Disconnected */,
|
|
3127
|
+
message: `Transport close failed: ${cause instanceof Error ? cause.message : String(cause)}`,
|
|
3128
|
+
cause
|
|
3129
|
+
},
|
|
3130
|
+
signal
|
|
3131
|
+
);
|
|
3132
|
+
} finally {
|
|
3133
|
+
this.publishDisconnected(signal);
|
|
3134
|
+
}
|
|
3058
3135
|
}
|
|
3059
3136
|
/**
|
|
3060
3137
|
* Runs once the teardown promise has settled, so a handler reached from here
|
|
@@ -3064,10 +3141,7 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
3064
3141
|
* handler that is slow — or whose promise never settles at all — must not
|
|
3065
3142
|
* cost the connector the attempt.
|
|
3066
3143
|
*/
|
|
3067
|
-
|
|
3068
|
-
if (this.closeRequested) return;
|
|
3069
|
-
this.setState("disconnected" /* Disconnected */, error);
|
|
3070
|
-
this.publishDisconnected();
|
|
3144
|
+
announceDisconnect() {
|
|
3071
3145
|
if (this.shouldReconnect()) {
|
|
3072
3146
|
queueMicrotask(() => {
|
|
3073
3147
|
void this.connect().catch(() => void 0);
|
|
@@ -3111,16 +3185,13 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
3111
3185
|
__publicField(this, "stateHandlers", /* @__PURE__ */ new Set());
|
|
3112
3186
|
}
|
|
3113
3187
|
onError(handler) {
|
|
3114
|
-
this.errorHandlers
|
|
3115
|
-
return subscription(() => this.errorHandlers.delete(handler));
|
|
3188
|
+
return registerHandler(this.errorHandlers, handler);
|
|
3116
3189
|
}
|
|
3117
3190
|
onDisconnected(handler) {
|
|
3118
|
-
this.disconnectedHandlers
|
|
3119
|
-
return subscription(() => this.disconnectedHandlers.delete(handler));
|
|
3191
|
+
return registerHandler(this.disconnectedHandlers, handler);
|
|
3120
3192
|
}
|
|
3121
3193
|
onStateChanged(handler) {
|
|
3122
|
-
this.stateHandlers
|
|
3123
|
-
return subscription(() => this.stateHandlers.delete(handler));
|
|
3194
|
+
return registerHandler(this.stateHandlers, handler);
|
|
3124
3195
|
}
|
|
3125
3196
|
publishError(error, signal) {
|
|
3126
3197
|
this.publish(this.errorHandlers, (handler) => handler(error, signal), signal);
|
|
@@ -3148,13 +3219,13 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
3148
3219
|
publish(handlers, invoke, signal) {
|
|
3149
3220
|
this.enqueueCallback(
|
|
3150
3221
|
() => {
|
|
3151
|
-
for (const handler of
|
|
3222
|
+
for (const handler of currentRegistrations(handlers)) {
|
|
3152
3223
|
const report = (cause) => this.reportFailure(
|
|
3153
3224
|
cause,
|
|
3154
3225
|
signal,
|
|
3155
3226
|
handlers === this.errorHandlers ? handler : void 0
|
|
3156
3227
|
);
|
|
3157
|
-
this.invoke(() => invoke(handler), report);
|
|
3228
|
+
this.invoke(() => invoke(handler.handler), report);
|
|
3158
3229
|
}
|
|
3159
3230
|
},
|
|
3160
3231
|
() => handlers.size
|
|
@@ -3177,15 +3248,22 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
3177
3248
|
(candidate) => !attempted.has(candidate)
|
|
3178
3249
|
);
|
|
3179
3250
|
if (remaining.length === 0) return;
|
|
3180
|
-
const nextAttempted =
|
|
3251
|
+
const nextAttempted = new Set(attempted);
|
|
3252
|
+
for (const handler of remaining) nextAttempted.add(handler);
|
|
3181
3253
|
this.enqueueCallback(
|
|
3182
3254
|
() => {
|
|
3183
|
-
for (const handler of remaining) {
|
|
3255
|
+
for (const handler of currentRegistrations(this.errorHandlers, remaining)) {
|
|
3184
3256
|
const report = (cause) => this.reportToRemaining({ ...error, cause }, signal, nextAttempted);
|
|
3185
|
-
|
|
3257
|
+
const callback = handler.handler;
|
|
3258
|
+
this.invoke(() => callback(error, signal), report);
|
|
3186
3259
|
}
|
|
3187
3260
|
},
|
|
3188
|
-
() =>
|
|
3261
|
+
() => {
|
|
3262
|
+
let count = 0;
|
|
3263
|
+
const registrations = currentRegistrations(this.errorHandlers, remaining);
|
|
3264
|
+
while (registrations.next().done !== true) count += 1;
|
|
3265
|
+
return count;
|
|
3266
|
+
}
|
|
3189
3267
|
);
|
|
3190
3268
|
}
|
|
3191
3269
|
invoke(run, report) {
|
|
@@ -3333,7 +3411,7 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
3333
3411
|
const message = this.messages[this.messageHead];
|
|
3334
3412
|
this.messages[this.messageHead] = void 0;
|
|
3335
3413
|
this.messageHead += 1;
|
|
3336
|
-
if (this.messageHead
|
|
3414
|
+
if (shouldCompactBackingArray(this.messageHead, this.messages.length)) {
|
|
3337
3415
|
this.messages.splice(0, this.messageHead);
|
|
3338
3416
|
this.messageHead = 0;
|
|
3339
3417
|
}
|
|
@@ -3348,8 +3426,8 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
3348
3426
|
connectTimeoutMs
|
|
3349
3427
|
);
|
|
3350
3428
|
const onOpen = () => finish();
|
|
3351
|
-
const onClose = () => finish(connectorError("
|
|
3352
|
-
const onError = () => finish(connectorError("
|
|
3429
|
+
const onClose = () => finish(connectorError("disconnected" /* Disconnected */, "Connect closed before opening."));
|
|
3430
|
+
const onError = () => finish(connectorError("disconnected" /* Disconnected */, "Connect failed."));
|
|
3353
3431
|
const onAbort = () => finish(connectorError("disconnected" /* Disconnected */, "Connect canceled."));
|
|
3354
3432
|
const finish = (error) => {
|
|
3355
3433
|
clearTimeout(timeout);
|
|
@@ -3471,12 +3549,10 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
3471
3549
|
return this.events.onStateChanged(handler);
|
|
3472
3550
|
}
|
|
3473
3551
|
onRequestSending(handler) {
|
|
3474
|
-
this.requestSendingHandlers
|
|
3475
|
-
return subscription(() => this.requestSendingHandlers.delete(handler));
|
|
3552
|
+
return registerHandler(this.requestSendingHandlers, handler);
|
|
3476
3553
|
}
|
|
3477
3554
|
onReplyReceived(handler) {
|
|
3478
|
-
this.replyReceivedHandlers
|
|
3479
|
-
return subscription(() => this.replyReceivedHandlers.delete(handler));
|
|
3555
|
+
return registerHandler(this.replyReceivedHandlers, handler);
|
|
3480
3556
|
}
|
|
3481
3557
|
async connect(signal) {
|
|
3482
3558
|
await this.lifecycle.connect(signal);
|
|
@@ -3713,7 +3789,7 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
3713
3789
|
let stopCancellation;
|
|
3714
3790
|
try {
|
|
3715
3791
|
throwIfAborted(signal);
|
|
3716
|
-
for (const handler of
|
|
3792
|
+
for (const { handler } of currentRegistrations(this.requestSendingHandlers)) {
|
|
3717
3793
|
try {
|
|
3718
3794
|
handler(sendingContext);
|
|
3719
3795
|
} catch (cause) {
|
|
@@ -3785,7 +3861,7 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
3785
3861
|
if (this.replyReceivedHandlers.size === 0) return;
|
|
3786
3862
|
this.receivedMessages.enqueueCallback(
|
|
3787
3863
|
() => {
|
|
3788
|
-
for (const handler of
|
|
3864
|
+
for (const { handler } of currentRegistrations(this.replyReceivedHandlers)) {
|
|
3789
3865
|
this.events.runUserCallback(
|
|
3790
3866
|
() => handler(context, signal),
|
|
3791
3867
|
"Reply received hook failed.",
|