@zlink-systems/stream-connector 0.21.0 → 0.23.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/Calls/ZlinkStreamCalls.d.ts +1 -3
- package/dist/browser/Contracts/IZlinkStreamConnector.d.ts +10 -24
- package/dist/browser/Contracts/ZlinkStreamActor.d.ts +10 -0
- package/dist/browser/Contracts/ZlinkStreamConnectorOptions.d.ts +1 -11
- package/dist/browser/Contracts/ZlinkStreamEnums.d.ts +2 -16
- package/dist/browser/Contracts/ZlinkStreamModels.d.ts +16 -14
- package/dist/browser/Contracts/index.d.ts +4 -3
- package/dist/browser/Runtime/Calls/ZlinkStreamCallBuilders.d.ts +5 -7
- package/dist/browser/Runtime/Protocol/ZlinkStreamFrameProtocol.d.ts +3 -5
- package/dist/browser/Runtime/Protocol/ZlinkStreamHeaderCodec.d.ts +2 -7
- package/dist/browser/Runtime/ZlinkStreamActors.d.ts +45 -0
- package/dist/browser/Runtime/ZlinkStreamConnector.d.ts +19 -30
- package/dist/browser/Runtime/ZlinkStreamConnectorLifecycle.d.ts +7 -1
- package/dist/browser/Runtime/ZlinkStreamConnectorOptions.d.ts +1 -2
- package/dist/browser/Runtime/ZlinkStreamFrameSender.d.ts +3 -5
- package/dist/browser/Runtime/ZlinkStreamPendingRequests.d.ts +3 -3
- package/dist/browser/Runtime/ZlinkStreamReceiveDispatcher.d.ts +3 -3
- package/dist/browser/Runtime/ZlinkStreamReceivedMessages.d.ts +1 -0
- package/dist/browser/index.global.js +811 -357
- package/dist/browser/index.mjs +808 -354
- package/package.json +2 -2
- package/dist/browser/Runtime/ZlinkFlowContext.d.ts +0 -15
- package/dist/browser/Runtime/ZlinkStreamDiagnosticsLevelCell.d.ts +0 -16
|
@@ -26,7 +26,6 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
26
26
|
ZlinkStreamCodec: () => ZlinkStreamCodec,
|
|
27
27
|
ZlinkStreamCompression: () => ZlinkStreamCompression,
|
|
28
28
|
ZlinkStreamConnectionState: () => ZlinkStreamConnectionState,
|
|
29
|
-
ZlinkStreamDiagnosticsLevel: () => ZlinkStreamDiagnosticsLevel,
|
|
30
29
|
ZlinkStreamDispatchMode: () => ZlinkStreamDispatchMode,
|
|
31
30
|
ZlinkStreamErrorCode: () => ZlinkStreamErrorCode,
|
|
32
31
|
ZlinkStreamException: () => ZlinkStreamException,
|
|
@@ -165,7 +164,8 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
165
164
|
hasRequestSeq: 1,
|
|
166
165
|
hasMetadata: 2,
|
|
167
166
|
hasCorrelationId: 8,
|
|
168
|
-
hasFlowId: 16
|
|
167
|
+
hasFlowId: 16,
|
|
168
|
+
hasActorSlot: 32
|
|
169
169
|
};
|
|
170
170
|
var ZLINK_STREAM_FORMAT_MARKER = 242;
|
|
171
171
|
var ZLINK_STREAM_RESPONSE_KIND = 3;
|
|
@@ -212,6 +212,7 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
212
212
|
}
|
|
213
213
|
const hasCorrelation = correlationBytes !== void 0;
|
|
214
214
|
const hasFlow = header.flowId !== void 0 || header.flowOrigin !== void 0;
|
|
215
|
+
const hasActorSlot = header.actorSlot !== void 0;
|
|
215
216
|
if (hasFlow && (header.flowId === void 0 || header.flowOrigin === void 0)) {
|
|
216
217
|
throw new Error("Stream flow id and origin must be provided together.");
|
|
217
218
|
}
|
|
@@ -219,13 +220,17 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
219
220
|
if (header.flowOrigin !== void 0 && ![1, 2, 3, 4].includes(header.flowOrigin)) {
|
|
220
221
|
throw new Error("Stream flow origin is invalid.");
|
|
221
222
|
}
|
|
223
|
+
if (header.actorSlot !== void 0 && (!Number.isInteger(header.actorSlot) || header.actorSlot < 1 || header.actorSlot > 65535)) {
|
|
224
|
+
throw new Error("Stream actor slot is invalid.");
|
|
225
|
+
}
|
|
222
226
|
let headerFlags = header.flags;
|
|
223
227
|
headerFlags = hasRequestSeq ? headerFlags | flags.hasRequestSeq : headerFlags & ~flags.hasRequestSeq;
|
|
224
228
|
headerFlags = hasMetadata ? headerFlags | flags.hasMetadata : headerFlags & ~flags.hasMetadata;
|
|
225
229
|
headerFlags = hasCorrelation ? headerFlags | flags.hasCorrelationId : headerFlags & ~flags.hasCorrelationId;
|
|
226
230
|
headerFlags = hasFlow ? headerFlags | flags.hasFlowId : headerFlags & ~flags.hasFlowId;
|
|
231
|
+
headerFlags = hasActorSlot ? headerFlags | flags.hasActorSlot : headerFlags & ~flags.hasActorSlot;
|
|
227
232
|
const metadataBytes = hasMetadata ? encodeStreamWireMetadata(header.metadata) : new Uint8Array();
|
|
228
|
-
const size = 4 + (hasRequestSeq ? 8 : 0) + 1 + nameBytes.length + (hasMetadata ? 2 + metadataBytes.length : 0) + (hasCorrelation ? 1 + correlationBytes.length : 0) + (hasFlow ? 37 : 0);
|
|
233
|
+
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);
|
|
229
234
|
const buffer = new Uint8Array(size);
|
|
230
235
|
let offset = 0;
|
|
231
236
|
buffer[offset++] = ZLINK_STREAM_FORMAT_MARKER;
|
|
@@ -258,6 +263,9 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
258
263
|
offset += 36;
|
|
259
264
|
buffer[offset++] = header.flowOrigin;
|
|
260
265
|
}
|
|
266
|
+
if (hasActorSlot) {
|
|
267
|
+
writeUInt16BE(buffer, offset, header.actorSlot);
|
|
268
|
+
}
|
|
261
269
|
return buffer;
|
|
262
270
|
}
|
|
263
271
|
function decodeStreamWireHeader(header, flagOverrides, includeFlow = true) {
|
|
@@ -276,7 +284,8 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
276
284
|
const hasMetadata = (headerFlags & flags.hasMetadata) !== 0;
|
|
277
285
|
const hasCorrelation = (headerFlags & flags.hasCorrelationId) !== 0;
|
|
278
286
|
const hasFlow = (headerFlags & flags.hasFlowId) !== 0;
|
|
279
|
-
|
|
287
|
+
const hasActorSlot = (headerFlags & flags.hasActorSlot) !== 0;
|
|
288
|
+
if ((headerFlags & ~63) !== 0) {
|
|
280
289
|
throw new Error("Unknown mandatory stream header flag.");
|
|
281
290
|
}
|
|
282
291
|
let requestSeq;
|
|
@@ -331,6 +340,17 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
331
340
|
}
|
|
332
341
|
flowOrigin = includeFlow ? decodedFlowOrigin : void 0;
|
|
333
342
|
}
|
|
343
|
+
let actorSlot;
|
|
344
|
+
if (hasActorSlot) {
|
|
345
|
+
if (header.length - offset < 2) {
|
|
346
|
+
throw new Error("Stream actor slot is incomplete.");
|
|
347
|
+
}
|
|
348
|
+
actorSlot = readUInt16BE(header, offset);
|
|
349
|
+
if (actorSlot === 0) {
|
|
350
|
+
throw new Error("Stream actor slot must not be zero.");
|
|
351
|
+
}
|
|
352
|
+
offset += 2;
|
|
353
|
+
}
|
|
334
354
|
if (offset !== header.length) {
|
|
335
355
|
throw new Error("Stream header has trailing bytes.");
|
|
336
356
|
}
|
|
@@ -343,7 +363,8 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
343
363
|
metadata: decodedMetadata.metadata,
|
|
344
364
|
correlationId,
|
|
345
365
|
flowId,
|
|
346
|
-
flowOrigin
|
|
366
|
+
flowOrigin,
|
|
367
|
+
actorSlot
|
|
347
368
|
};
|
|
348
369
|
}
|
|
349
370
|
function validateFlowId(flowId) {
|
|
@@ -509,13 +530,6 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
509
530
|
ZlinkStreamDispatchMode2["Immediate"] = "immediate";
|
|
510
531
|
return ZlinkStreamDispatchMode2;
|
|
511
532
|
})(ZlinkStreamDispatchMode || {});
|
|
512
|
-
var ZlinkStreamDiagnosticsLevel = /* @__PURE__ */ ((ZlinkStreamDiagnosticsLevel4) => {
|
|
513
|
-
ZlinkStreamDiagnosticsLevel4["Off"] = "off";
|
|
514
|
-
ZlinkStreamDiagnosticsLevel4["Errors"] = "errors";
|
|
515
|
-
ZlinkStreamDiagnosticsLevel4["Normal"] = "normal";
|
|
516
|
-
ZlinkStreamDiagnosticsLevel4["Detailed"] = "detailed";
|
|
517
|
-
return ZlinkStreamDiagnosticsLevel4;
|
|
518
|
-
})(ZlinkStreamDiagnosticsLevel || {});
|
|
519
533
|
var ZlinkStreamMessageKind = /* @__PURE__ */ ((ZlinkStreamMessageKind2) => {
|
|
520
534
|
ZlinkStreamMessageKind2[ZlinkStreamMessageKind2["Send"] = 1] = "Send";
|
|
521
535
|
ZlinkStreamMessageKind2[ZlinkStreamMessageKind2["Request"] = 2] = "Request";
|
|
@@ -531,6 +545,7 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
531
545
|
ZlinkStreamHeaderFlags2[ZlinkStreamHeaderFlags2["PayloadCompressed"] = 4] = "PayloadCompressed";
|
|
532
546
|
ZlinkStreamHeaderFlags2[ZlinkStreamHeaderFlags2["HasCorrelationId"] = 8] = "HasCorrelationId";
|
|
533
547
|
ZlinkStreamHeaderFlags2[ZlinkStreamHeaderFlags2["HasFlowId"] = 16] = "HasFlowId";
|
|
548
|
+
ZlinkStreamHeaderFlags2[ZlinkStreamHeaderFlags2["HasActorSlot"] = 32] = "HasActorSlot";
|
|
534
549
|
return ZlinkStreamHeaderFlags2;
|
|
535
550
|
})(ZlinkStreamHeaderFlags || {});
|
|
536
551
|
var ZlinkStreamErrorCode = /* @__PURE__ */ ((ZlinkStreamErrorCode2) => {
|
|
@@ -675,7 +690,11 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
675
690
|
if (error instanceof ZlinkStreamException) {
|
|
676
691
|
return error.error;
|
|
677
692
|
}
|
|
678
|
-
return {
|
|
693
|
+
return {
|
|
694
|
+
code: "remoteError" /* RemoteError */,
|
|
695
|
+
message: error instanceof Error ? error.message : String(error),
|
|
696
|
+
cause: error
|
|
697
|
+
};
|
|
679
698
|
}
|
|
680
699
|
function subscription(dispose) {
|
|
681
700
|
return { dispose };
|
|
@@ -710,7 +729,10 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
710
729
|
var zlinkStreamAssert = {
|
|
711
730
|
ensure(condition, message) {
|
|
712
731
|
if (typeof message !== "string" || message.trim().length === 0) {
|
|
713
|
-
throw connectorError(
|
|
732
|
+
throw connectorError(
|
|
733
|
+
"validationFailed" /* ValidationFailed */,
|
|
734
|
+
"zlinkStreamAssert.ensure requires a non-empty diagnostic message."
|
|
735
|
+
);
|
|
714
736
|
}
|
|
715
737
|
if (!condition) {
|
|
716
738
|
throw connectorError("validationFailed" /* ValidationFailed */, message);
|
|
@@ -759,43 +781,58 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
759
781
|
throw connectorError("validationFailed" /* ValidationFailed */, "Message name must not be empty.");
|
|
760
782
|
}
|
|
761
783
|
if (!allowReserved && name.startsWith("$zlink.")) {
|
|
762
|
-
throw connectorError(
|
|
784
|
+
throw connectorError(
|
|
785
|
+
"validationFailed" /* ValidationFailed */,
|
|
786
|
+
"Message name uses a reserved zlink prefix."
|
|
787
|
+
);
|
|
763
788
|
}
|
|
764
789
|
if (utf8Encode2(name).length > 255) {
|
|
765
|
-
throw connectorError(
|
|
790
|
+
throw connectorError(
|
|
791
|
+
"validationFailed" /* ValidationFailed */,
|
|
792
|
+
"Message name must not exceed 255 UTF-8 bytes."
|
|
793
|
+
);
|
|
766
794
|
}
|
|
767
795
|
}
|
|
768
796
|
|
|
769
797
|
// packages/stream-connector/src/Runtime/Calls/ZlinkStreamCallBuilders.ts
|
|
770
798
|
var ZlinkStreamCallBuilderState = class {
|
|
771
|
-
constructor(name) {
|
|
799
|
+
constructor(name, actorSlot, validateActor) {
|
|
800
|
+
this.actorSlot = actorSlot;
|
|
801
|
+
this.validateActor = validateActor;
|
|
772
802
|
__publicField(this, "executed", false);
|
|
773
803
|
__publicField(this, "name");
|
|
774
804
|
__publicField(this, "metadata", ZlinkStreamMetadataMap.empty);
|
|
775
805
|
__publicField(this, "timeoutMs");
|
|
776
806
|
__publicField(this, "compress", false);
|
|
777
|
-
__publicField(this, "flow");
|
|
778
807
|
this.name = name;
|
|
779
808
|
}
|
|
780
809
|
ensureNotExecuted() {
|
|
810
|
+
var _a;
|
|
781
811
|
if (this.executed) {
|
|
782
|
-
throw connectorError(
|
|
812
|
+
throw connectorError(
|
|
813
|
+
"validationFailed" /* ValidationFailed */,
|
|
814
|
+
"Builder instances can be executed only once."
|
|
815
|
+
);
|
|
783
816
|
}
|
|
784
817
|
this.executed = true;
|
|
818
|
+
(_a = this.validateActor) == null ? void 0 : _a.call(this);
|
|
785
819
|
}
|
|
786
820
|
resolveMessageName() {
|
|
787
821
|
if (this.name === void 0) {
|
|
788
|
-
throw connectorError(
|
|
822
|
+
throw connectorError(
|
|
823
|
+
"validationFailed" /* ValidationFailed */,
|
|
824
|
+
"Message name is required when the encoded stream payload has no message type."
|
|
825
|
+
);
|
|
789
826
|
}
|
|
790
827
|
return this.name;
|
|
791
828
|
}
|
|
792
829
|
};
|
|
793
830
|
var ZlinkStreamSendBuilder = class {
|
|
794
|
-
constructor(connector, name, payload) {
|
|
831
|
+
constructor(connector, name, payload, actorSlot, validateActor) {
|
|
795
832
|
this.connector = connector;
|
|
796
833
|
this.payload = payload;
|
|
797
834
|
__publicField(this, "state");
|
|
798
|
-
this.state = new ZlinkStreamCallBuilderState(name);
|
|
835
|
+
this.state = new ZlinkStreamCallBuilderState(name, actorSlot, validateActor);
|
|
799
836
|
}
|
|
800
837
|
packetName(name) {
|
|
801
838
|
validateName(name);
|
|
@@ -810,10 +847,6 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
810
847
|
this.state.compress = true;
|
|
811
848
|
return this;
|
|
812
849
|
}
|
|
813
|
-
flowFrom(flow) {
|
|
814
|
-
this.state.flow = flow;
|
|
815
|
-
return this;
|
|
816
|
-
}
|
|
817
850
|
async submit(signal) {
|
|
818
851
|
throwIfAborted(signal);
|
|
819
852
|
this.state.ensureNotExecuted();
|
|
@@ -825,16 +858,17 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
825
858
|
this.state.compress,
|
|
826
859
|
void 0,
|
|
827
860
|
signal,
|
|
828
|
-
|
|
861
|
+
void 0,
|
|
862
|
+
this.state.actorSlot
|
|
829
863
|
);
|
|
830
864
|
}
|
|
831
865
|
};
|
|
832
866
|
var ZlinkStreamRequestBuilder = class {
|
|
833
|
-
constructor(connector, name, payload) {
|
|
867
|
+
constructor(connector, name, payload, actorSlot, validateActor) {
|
|
834
868
|
this.connector = connector;
|
|
835
869
|
this.payload = payload;
|
|
836
870
|
__publicField(this, "state");
|
|
837
|
-
this.state = new ZlinkStreamCallBuilderState(name);
|
|
871
|
+
this.state = new ZlinkStreamCallBuilderState(name, actorSlot, validateActor);
|
|
838
872
|
}
|
|
839
873
|
packetName(name) {
|
|
840
874
|
validateName(name);
|
|
@@ -853,10 +887,6 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
853
887
|
this.state.compress = true;
|
|
854
888
|
return this;
|
|
855
889
|
}
|
|
856
|
-
flowFrom(flow) {
|
|
857
|
-
this.state.flow = flow;
|
|
858
|
-
return this;
|
|
859
|
-
}
|
|
860
890
|
submit(signalOrCallback) {
|
|
861
891
|
var _a;
|
|
862
892
|
this.state.ensureNotExecuted();
|
|
@@ -867,7 +897,7 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
867
897
|
this.state.compress,
|
|
868
898
|
(_a = this.state.timeoutMs) != null ? _a : this.connector.options.requestTimeoutMs,
|
|
869
899
|
typeof signalOrCallback === "function" ? void 0 : signalOrCallback,
|
|
870
|
-
this.state.
|
|
900
|
+
this.state.actorSlot
|
|
871
901
|
);
|
|
872
902
|
if (typeof signalOrCallback === "function") {
|
|
873
903
|
operation.then(
|
|
@@ -876,10 +906,12 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
876
906
|
);
|
|
877
907
|
return;
|
|
878
908
|
}
|
|
879
|
-
return operation.then(
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
909
|
+
return operation.then(
|
|
910
|
+
(value) => {
|
|
911
|
+
var _a2;
|
|
912
|
+
return ((_a2 = this.connector.options.codec) != null ? _a2 : zlinkStreamJsonCodec).decode(value);
|
|
913
|
+
}
|
|
914
|
+
);
|
|
883
915
|
}
|
|
884
916
|
submitEncoded(signal) {
|
|
885
917
|
var _a;
|
|
@@ -891,7 +923,7 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
891
923
|
this.state.compress,
|
|
892
924
|
(_a = this.state.timeoutMs) != null ? _a : this.connector.options.requestTimeoutMs,
|
|
893
925
|
signal,
|
|
894
|
-
this.state.
|
|
926
|
+
this.state.actorSlot
|
|
895
927
|
);
|
|
896
928
|
}
|
|
897
929
|
};
|
|
@@ -917,7 +949,12 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
917
949
|
var _a;
|
|
918
950
|
this.markExecuted();
|
|
919
951
|
const timeoutMs = (_a = this.timeoutMs) != null ? _a : this.connector.options.waitTimeoutMs;
|
|
920
|
-
const message = await this.connector.waitForMessage(
|
|
952
|
+
const message = await this.connector.waitForMessage(
|
|
953
|
+
this.name,
|
|
954
|
+
timeoutMs,
|
|
955
|
+
this.predicate,
|
|
956
|
+
signal
|
|
957
|
+
);
|
|
921
958
|
if (message === void 0) {
|
|
922
959
|
throw connectorError(
|
|
923
960
|
"validationFailed" /* ValidationFailed */,
|
|
@@ -928,7 +965,10 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
928
965
|
}
|
|
929
966
|
ensureConfigurable() {
|
|
930
967
|
if (this.executed) {
|
|
931
|
-
throw connectorError(
|
|
968
|
+
throw connectorError(
|
|
969
|
+
"validationFailed" /* ValidationFailed */,
|
|
970
|
+
"Builder instances can be executed only once."
|
|
971
|
+
);
|
|
932
972
|
}
|
|
933
973
|
}
|
|
934
974
|
markExecuted() {
|
|
@@ -954,9 +994,17 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
954
994
|
async run(signal) {
|
|
955
995
|
this.markExecuted();
|
|
956
996
|
if (this.windowMs === void 0) {
|
|
957
|
-
throw connectorError(
|
|
997
|
+
throw connectorError(
|
|
998
|
+
"validationFailed" /* ValidationFailed */,
|
|
999
|
+
"expectNone requires within(windowMs)."
|
|
1000
|
+
);
|
|
958
1001
|
}
|
|
959
|
-
const message = await this.connector.waitForMessage(
|
|
1002
|
+
const message = await this.connector.waitForMessage(
|
|
1003
|
+
this.name,
|
|
1004
|
+
this.windowMs,
|
|
1005
|
+
() => true,
|
|
1006
|
+
signal
|
|
1007
|
+
);
|
|
960
1008
|
if (message === void 0) {
|
|
961
1009
|
return;
|
|
962
1010
|
}
|
|
@@ -967,7 +1015,10 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
967
1015
|
}
|
|
968
1016
|
ensureConfigurable() {
|
|
969
1017
|
if (this.executed) {
|
|
970
|
-
throw connectorError(
|
|
1018
|
+
throw connectorError(
|
|
1019
|
+
"validationFailed" /* ValidationFailed */,
|
|
1020
|
+
"Builder instances can be executed only once."
|
|
1021
|
+
);
|
|
971
1022
|
}
|
|
972
1023
|
}
|
|
973
1024
|
markExecuted() {
|
|
@@ -1001,7 +1052,10 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1001
1052
|
var _a;
|
|
1002
1053
|
this.markExecuted();
|
|
1003
1054
|
if (this.predicates.length === 0) {
|
|
1004
|
-
throw connectorError(
|
|
1055
|
+
throw connectorError(
|
|
1056
|
+
"validationFailed" /* ValidationFailed */,
|
|
1057
|
+
"waitForSequence requires at least one expectation."
|
|
1058
|
+
);
|
|
1005
1059
|
}
|
|
1006
1060
|
const timeoutMs = (_a = this.timeoutMs) != null ? _a : this.connector.options.waitTimeoutMs;
|
|
1007
1061
|
const deadline = Date.now() + timeoutMs;
|
|
@@ -1033,7 +1087,10 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1033
1087
|
}
|
|
1034
1088
|
ensureConfigurable() {
|
|
1035
1089
|
if (this.executed) {
|
|
1036
|
-
throw connectorError(
|
|
1090
|
+
throw connectorError(
|
|
1091
|
+
"validationFailed" /* ValidationFailed */,
|
|
1092
|
+
"Builder instances can be executed only once."
|
|
1093
|
+
);
|
|
1037
1094
|
}
|
|
1038
1095
|
}
|
|
1039
1096
|
markExecuted() {
|
|
@@ -1043,7 +1100,10 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1043
1100
|
};
|
|
1044
1101
|
function validateTimeout(timeoutMs) {
|
|
1045
1102
|
if (!Number.isFinite(timeoutMs) || timeoutMs < 0) {
|
|
1046
|
-
throw connectorError(
|
|
1103
|
+
throw connectorError(
|
|
1104
|
+
"validationFailed" /* ValidationFailed */,
|
|
1105
|
+
"Timeout must be a non-negative finite number."
|
|
1106
|
+
);
|
|
1047
1107
|
}
|
|
1048
1108
|
}
|
|
1049
1109
|
|
|
@@ -1059,7 +1119,10 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1059
1119
|
function compressPayload(payload, compression, compressionCodec) {
|
|
1060
1120
|
const codec = resolveCompressionCodec(compression, compressionCodec);
|
|
1061
1121
|
if (codec === void 0) {
|
|
1062
|
-
throw connectorError(
|
|
1122
|
+
throw connectorError(
|
|
1123
|
+
"compressionFailed" /* CompressionFailed */,
|
|
1124
|
+
"Compression codec is not configured."
|
|
1125
|
+
);
|
|
1063
1126
|
}
|
|
1064
1127
|
return codec.compress(payload);
|
|
1065
1128
|
}
|
|
@@ -1069,7 +1132,10 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1069
1132
|
}
|
|
1070
1133
|
const codec = resolveCompressionCodec(compression, compressionCodec);
|
|
1071
1134
|
if (codec === void 0) {
|
|
1072
|
-
throw connectorError(
|
|
1135
|
+
throw connectorError(
|
|
1136
|
+
"decompressionFailed" /* DecompressionFailed */,
|
|
1137
|
+
"Compression codec is not configured."
|
|
1138
|
+
);
|
|
1073
1139
|
}
|
|
1074
1140
|
try {
|
|
1075
1141
|
const decompressed = codec.decompress(payload, maxDecompressedSize);
|
|
@@ -1102,26 +1168,39 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1102
1168
|
try {
|
|
1103
1169
|
return decodeStreamWireFrame(frame);
|
|
1104
1170
|
} catch (cause) {
|
|
1105
|
-
throw connectorError(
|
|
1171
|
+
throw connectorError(
|
|
1172
|
+
"frameDecodeFailed" /* FrameDecodeFailed */,
|
|
1173
|
+
"Frame length does not match prefix.",
|
|
1174
|
+
cause
|
|
1175
|
+
);
|
|
1106
1176
|
}
|
|
1107
1177
|
}
|
|
1108
1178
|
};
|
|
1109
1179
|
function splitZlinkStreamFrames(chunk) {
|
|
1110
1180
|
if (chunk.length === 0) {
|
|
1111
|
-
throw connectorError(
|
|
1181
|
+
throw connectorError(
|
|
1182
|
+
"frameDecodeFailed" /* FrameDecodeFailed */,
|
|
1183
|
+
"Stream frame prefix is incomplete."
|
|
1184
|
+
);
|
|
1112
1185
|
}
|
|
1113
1186
|
const frames = [];
|
|
1114
1187
|
let offset = 0;
|
|
1115
1188
|
while (offset < chunk.length) {
|
|
1116
1189
|
const remaining = chunk.length - offset;
|
|
1117
1190
|
if (remaining < 6) {
|
|
1118
|
-
throw connectorError(
|
|
1191
|
+
throw connectorError(
|
|
1192
|
+
"frameDecodeFailed" /* FrameDecodeFailed */,
|
|
1193
|
+
"Stream frame prefix is incomplete."
|
|
1194
|
+
);
|
|
1119
1195
|
}
|
|
1120
1196
|
const headerLength = chunk[offset] << 8 | chunk[offset + 1];
|
|
1121
1197
|
const payloadLength = chunk[offset + 2] * 16777216 + (chunk[offset + 3] << 16) + (chunk[offset + 4] << 8) + chunk[offset + 5];
|
|
1122
1198
|
const frameLength = 6 + headerLength + payloadLength;
|
|
1123
1199
|
if (frameLength > remaining) {
|
|
1124
|
-
throw connectorError(
|
|
1200
|
+
throw connectorError(
|
|
1201
|
+
"frameDecodeFailed" /* FrameDecodeFailed */,
|
|
1202
|
+
"Frame length does not match prefix."
|
|
1203
|
+
);
|
|
1125
1204
|
}
|
|
1126
1205
|
frames.push(chunk.subarray(offset, offset + frameLength));
|
|
1127
1206
|
offset += frameLength;
|
|
@@ -1130,7 +1209,10 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1130
1209
|
}
|
|
1131
1210
|
function validatePayload(payloadLength, maxPayloadSize) {
|
|
1132
1211
|
if (payloadLength > maxPayloadSize) {
|
|
1133
|
-
throw connectorError(
|
|
1212
|
+
throw connectorError(
|
|
1213
|
+
"validationFailed" /* ValidationFailed */,
|
|
1214
|
+
"Payload exceeds MaxSendPayloadSize."
|
|
1215
|
+
);
|
|
1134
1216
|
}
|
|
1135
1217
|
}
|
|
1136
1218
|
|
|
@@ -1148,14 +1230,22 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1148
1230
|
}
|
|
1149
1231
|
return size;
|
|
1150
1232
|
} catch (cause) {
|
|
1151
|
-
throw connectorError(
|
|
1233
|
+
throw connectorError(
|
|
1234
|
+
"validationFailed" /* ValidationFailed */,
|
|
1235
|
+
streamWireErrorMessage(cause),
|
|
1236
|
+
cause
|
|
1237
|
+
);
|
|
1152
1238
|
}
|
|
1153
1239
|
}
|
|
1154
1240
|
static write(metadata, destination) {
|
|
1155
1241
|
try {
|
|
1156
1242
|
destination.set(encodeStreamWireMetadata(metadata.values));
|
|
1157
1243
|
} catch (cause) {
|
|
1158
|
-
throw connectorError(
|
|
1244
|
+
throw connectorError(
|
|
1245
|
+
"validationFailed" /* ValidationFailed */,
|
|
1246
|
+
streamWireErrorMessage(cause),
|
|
1247
|
+
cause
|
|
1248
|
+
);
|
|
1159
1249
|
}
|
|
1160
1250
|
}
|
|
1161
1251
|
static decode(metadata) {
|
|
@@ -1163,7 +1253,11 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1163
1253
|
const values = decodeStreamWireMetadata(metadata);
|
|
1164
1254
|
return values.size === 0 ? ZlinkStreamMetadataMap.empty : ZlinkStreamMetadataMap.from(values);
|
|
1165
1255
|
} catch (cause) {
|
|
1166
|
-
throw connectorError(
|
|
1256
|
+
throw connectorError(
|
|
1257
|
+
"frameDecodeFailed" /* FrameDecodeFailed */,
|
|
1258
|
+
streamWireErrorMessage(cause),
|
|
1259
|
+
cause
|
|
1260
|
+
);
|
|
1167
1261
|
}
|
|
1168
1262
|
}
|
|
1169
1263
|
};
|
|
@@ -1187,22 +1281,20 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1187
1281
|
name: header.name,
|
|
1188
1282
|
metadata: header.metadata.values,
|
|
1189
1283
|
correlationId: header.correlationId,
|
|
1190
|
-
|
|
1191
|
-
flowOrigin: encodeFlowOrigin(header.flowOrigin)
|
|
1284
|
+
actorSlot: header.actorSlot
|
|
1192
1285
|
});
|
|
1193
1286
|
} catch (cause) {
|
|
1194
|
-
throw connectorError(
|
|
1287
|
+
throw connectorError(
|
|
1288
|
+
"validationFailed" /* ValidationFailed */,
|
|
1289
|
+
streamWireErrorMessage2(cause),
|
|
1290
|
+
cause
|
|
1291
|
+
);
|
|
1195
1292
|
}
|
|
1196
1293
|
}
|
|
1197
|
-
|
|
1198
|
-
* `includeFlow=false` (diagnostics Off, spec 27 §4) skips reading and
|
|
1199
|
-
* validating the inbound flow fields while the structural length checks in
|
|
1200
|
-
* the wire decoder are preserved.
|
|
1201
|
-
*/
|
|
1202
|
-
static decode(header, includeFlow = true) {
|
|
1294
|
+
static decode(header) {
|
|
1203
1295
|
let decoded;
|
|
1204
1296
|
try {
|
|
1205
|
-
const wire = decodeStreamWireHeader(header, void 0,
|
|
1297
|
+
const wire = decodeStreamWireHeader(header, void 0, false);
|
|
1206
1298
|
const metadata = wire.metadata.size === 0 ? ZlinkStreamMetadataMap.empty : ZlinkStreamMetadataMap.from(wire.metadata);
|
|
1207
1299
|
decoded = {
|
|
1208
1300
|
kind: wire.kind,
|
|
@@ -1212,11 +1304,14 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1212
1304
|
name: wire.name,
|
|
1213
1305
|
metadata,
|
|
1214
1306
|
correlationId: wire.correlationId,
|
|
1215
|
-
|
|
1216
|
-
flowOrigin: decodeFlowOrigin(wire.flowOrigin)
|
|
1307
|
+
actorSlot: wire.actorSlot
|
|
1217
1308
|
};
|
|
1218
1309
|
} catch (cause) {
|
|
1219
|
-
throw connectorError(
|
|
1310
|
+
throw connectorError(
|
|
1311
|
+
"frameDecodeFailed" /* FrameDecodeFailed */,
|
|
1312
|
+
streamWireErrorMessage2(cause),
|
|
1313
|
+
cause
|
|
1314
|
+
);
|
|
1220
1315
|
}
|
|
1221
1316
|
validateEnum(decoded.kind, decoded.codec, decoded.flags);
|
|
1222
1317
|
if (!isReplyKind2(decoded.kind)) {
|
|
@@ -1232,7 +1327,7 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1232
1327
|
function streamWireErrorMessage2(cause) {
|
|
1233
1328
|
return cause instanceof Error ? cause.message : "Stream header is invalid.";
|
|
1234
1329
|
}
|
|
1235
|
-
function buildHeader(kind, name, codec, metadata, compress, requestSeq, correlationId,
|
|
1330
|
+
function buildHeader(kind, name, codec, metadata, compress, requestSeq, correlationId, actorSlot) {
|
|
1236
1331
|
let flags = 0 /* None */;
|
|
1237
1332
|
if (requestSeq !== void 0) {
|
|
1238
1333
|
flags |= 1 /* HasRequestSeq */;
|
|
@@ -1246,27 +1341,49 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1246
1341
|
if (correlationId !== void 0 && correlationId.length > 0) {
|
|
1247
1342
|
flags |= 8 /* HasCorrelationId */;
|
|
1248
1343
|
}
|
|
1249
|
-
if (
|
|
1250
|
-
return {
|
|
1344
|
+
if (actorSlot !== void 0) flags |= 32 /* HasActorSlot */;
|
|
1345
|
+
return {
|
|
1346
|
+
kind,
|
|
1347
|
+
codec,
|
|
1348
|
+
flags,
|
|
1349
|
+
requestSeq,
|
|
1350
|
+
name,
|
|
1351
|
+
metadata,
|
|
1352
|
+
correlationId,
|
|
1353
|
+
actorSlot
|
|
1354
|
+
};
|
|
1251
1355
|
}
|
|
1252
1356
|
function validateHeaderSemantics(header) {
|
|
1253
1357
|
validateEnum(header.kind, header.codec, header.flags);
|
|
1254
1358
|
const hasRequestSeq = header.requestSeq !== void 0 || (header.flags & 1 /* HasRequestSeq */) !== 0;
|
|
1255
1359
|
const hasMetadata = header.metadata.count > 0 || (header.flags & 2 /* HasMetadata */) !== 0;
|
|
1256
1360
|
if (header.kind === 1 /* Send */ && hasRequestSeq) {
|
|
1257
|
-
throw connectorError(
|
|
1361
|
+
throw connectorError(
|
|
1362
|
+
"frameDecodeFailed" /* FrameDecodeFailed */,
|
|
1363
|
+
"Send packet must not contain a request sequence."
|
|
1364
|
+
);
|
|
1258
1365
|
}
|
|
1259
1366
|
if ((header.kind === 2 /* Request */ || header.kind === 3 /* Response */) && !hasRequestSeq) {
|
|
1260
|
-
throw connectorError(
|
|
1367
|
+
throw connectorError(
|
|
1368
|
+
"frameDecodeFailed" /* FrameDecodeFailed */,
|
|
1369
|
+
"Request and response packets must contain a request sequence."
|
|
1370
|
+
);
|
|
1261
1371
|
}
|
|
1262
1372
|
if (header.kind === 4 /* Error */ && header.codec !== 1 /* Json */) {
|
|
1263
|
-
throw connectorError(
|
|
1373
|
+
throw connectorError(
|
|
1374
|
+
"frameDecodeFailed" /* FrameDecodeFailed */,
|
|
1375
|
+
"Error packet must use the JSON codec."
|
|
1376
|
+
);
|
|
1264
1377
|
}
|
|
1265
1378
|
if (header.kind === 5 /* Control */) {
|
|
1266
1379
|
const hasCorrelation = header.correlationId !== void 0 && header.correlationId.length > 0 || (header.flags & 8 /* HasCorrelationId */) !== 0;
|
|
1267
|
-
const hasFlow =
|
|
1268
|
-
|
|
1269
|
-
|
|
1380
|
+
const hasFlow = (header.flags & 16 /* HasFlowId */) !== 0;
|
|
1381
|
+
const hasActorSlot = header.actorSlot !== void 0 || (header.flags & 32 /* HasActorSlot */) !== 0;
|
|
1382
|
+
if (header.flags !== 0 /* None */ || hasRequestSeq || hasMetadata || hasCorrelation || hasFlow || hasActorSlot || header.codec !== 0 /* Raw */) {
|
|
1383
|
+
throw connectorError(
|
|
1384
|
+
"frameDecodeFailed" /* FrameDecodeFailed */,
|
|
1385
|
+
"Control packet must use raw codec and must not contain flags."
|
|
1386
|
+
);
|
|
1270
1387
|
}
|
|
1271
1388
|
}
|
|
1272
1389
|
}
|
|
@@ -1277,17 +1394,11 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1277
1394
|
if (![0, 1, 2, 3].includes(codec)) {
|
|
1278
1395
|
throw connectorError("frameDecodeFailed" /* FrameDecodeFailed */, "Unknown stream codec.");
|
|
1279
1396
|
}
|
|
1280
|
-
const known = 1 /* HasRequestSeq */ | 2 /* HasMetadata */ | 4 /* PayloadCompressed */ | 8 /* HasCorrelationId */ | 16 /* HasFlowId */;
|
|
1397
|
+
const known = 1 /* HasRequestSeq */ | 2 /* HasMetadata */ | 4 /* PayloadCompressed */ | 8 /* HasCorrelationId */ | 16 /* HasFlowId */ | 32 /* HasActorSlot */;
|
|
1281
1398
|
if ((flags & ~known) !== 0) {
|
|
1282
1399
|
throw connectorError("frameDecodeFailed" /* FrameDecodeFailed */, "Unknown stream header flag.");
|
|
1283
1400
|
}
|
|
1284
1401
|
}
|
|
1285
|
-
function encodeFlowOrigin(origin) {
|
|
1286
|
-
return origin === void 0 ? void 0 : { Inbound: 1, Timer: 2, Application: 3, Lifecycle: 4 }[origin];
|
|
1287
|
-
}
|
|
1288
|
-
function decodeFlowOrigin(origin) {
|
|
1289
|
-
return origin === void 0 ? void 0 : { 1: "Inbound", 2: "Timer", 3: "Application", 4: "Lifecycle" }[origin];
|
|
1290
|
-
}
|
|
1291
1402
|
|
|
1292
1403
|
// packages/stream-connector/src/Runtime/Protocol/ZlinkStreamFrameProtocol.ts
|
|
1293
1404
|
var ZLINK_STREAM_HEARTBEAT_PING = "$zlink.heartbeat.ping";
|
|
@@ -1296,37 +1407,47 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1296
1407
|
constructor(options) {
|
|
1297
1408
|
this.options = options;
|
|
1298
1409
|
}
|
|
1299
|
-
encode(kind, name, payload, metadata, compress, requestSeq, correlationId,
|
|
1410
|
+
encode(kind, name, payload, metadata, compress, requestSeq, correlationId, actorSlot) {
|
|
1300
1411
|
const payloadBytes = compress ? compressPayload(payload.payload, this.options.compression, this.options.compressionCodec) : payload.payload;
|
|
1301
|
-
const header = buildHeader(
|
|
1412
|
+
const header = buildHeader(
|
|
1413
|
+
kind,
|
|
1414
|
+
name,
|
|
1415
|
+
payload.codec,
|
|
1416
|
+
metadata,
|
|
1417
|
+
compress,
|
|
1418
|
+
requestSeq,
|
|
1419
|
+
correlationId,
|
|
1420
|
+
actorSlot
|
|
1421
|
+
);
|
|
1302
1422
|
return this.encodeFrame(header, payloadBytes);
|
|
1303
1423
|
}
|
|
1304
1424
|
encodeControl(name, payload = new Uint8Array()) {
|
|
1305
|
-
return this.encodeFrame(
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1425
|
+
return this.encodeFrame(
|
|
1426
|
+
{
|
|
1427
|
+
kind: 5 /* Control */,
|
|
1428
|
+
codec: 0 /* Raw */,
|
|
1429
|
+
flags: 0 /* None */,
|
|
1430
|
+
name,
|
|
1431
|
+
metadata: ZlinkStreamMetadataMap.empty
|
|
1432
|
+
},
|
|
1433
|
+
payload
|
|
1434
|
+
);
|
|
1312
1435
|
}
|
|
1313
|
-
decode(frameBytes
|
|
1436
|
+
decode(frameBytes) {
|
|
1314
1437
|
const frame = ZlinkStreamFrameCodec.decode(frameBytes);
|
|
1315
1438
|
return {
|
|
1316
|
-
|
|
1317
|
-
// read nor validated (structural length checks are preserved).
|
|
1318
|
-
header: ZlinkStreamHeaderCodec.decode(frame.header, flowEnabled),
|
|
1439
|
+
header: ZlinkStreamHeaderCodec.decode(frame.header),
|
|
1319
1440
|
payload: frame.payload
|
|
1320
1441
|
};
|
|
1321
1442
|
}
|
|
1322
|
-
|
|
1323
|
-
return this.options.diagnosticsLevel !== "off" /* Off */;
|
|
1324
|
-
}
|
|
1325
|
-
decodeFrames(chunk, flowEnabled = this.flowEnabled()) {
|
|
1443
|
+
decodeFrames(chunk) {
|
|
1326
1444
|
return splitZlinkStreamFrames(chunk).map((frame) => {
|
|
1327
|
-
const decoded = this.decode(frame
|
|
1445
|
+
const decoded = this.decode(frame);
|
|
1328
1446
|
if (decoded.payload.length > this.options.maxReceivePayloadSize) {
|
|
1329
|
-
throw connectorError(
|
|
1447
|
+
throw connectorError(
|
|
1448
|
+
"frameTooLarge" /* FrameTooLarge */,
|
|
1449
|
+
"Payload exceeds MaxReceivePayloadSize."
|
|
1450
|
+
);
|
|
1330
1451
|
}
|
|
1331
1452
|
return decoded;
|
|
1332
1453
|
});
|
|
@@ -1373,21 +1494,18 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1373
1494
|
}
|
|
1374
1495
|
|
|
1375
1496
|
// packages/stream-connector/src/Runtime/ZlinkStreamConnectorOptions.ts
|
|
1376
|
-
var validDiagnosticsLevels = /* @__PURE__ */ new Set([
|
|
1377
|
-
"off" /* Off */,
|
|
1378
|
-
"errors" /* Errors */,
|
|
1379
|
-
"normal" /* Normal */,
|
|
1380
|
-
"detailed" /* Detailed */
|
|
1381
|
-
]);
|
|
1382
1497
|
function normalizeOptions(options, defaultTransportFactory) {
|
|
1383
|
-
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
|
|
1498
|
+
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;
|
|
1384
1499
|
const endpoint = options.endpoint;
|
|
1385
1500
|
if (endpoint.trim().length === 0) {
|
|
1386
1501
|
throw connectorError("configurationError" /* ConfigurationError */, "Endpoint must not be empty.");
|
|
1387
1502
|
}
|
|
1388
1503
|
const inferredTransport = inferTransport(endpoint);
|
|
1389
1504
|
if (options.transport !== void 0 && options.transport !== inferredTransport) {
|
|
1390
|
-
throw connectorError(
|
|
1505
|
+
throw connectorError(
|
|
1506
|
+
"configurationError" /* ConfigurationError */,
|
|
1507
|
+
"Configured transport conflicts with endpoint scheme."
|
|
1508
|
+
);
|
|
1391
1509
|
}
|
|
1392
1510
|
validatePositive((_a = options.connectTimeoutMs) != null ? _a : 5e3, "ConnectTimeout");
|
|
1393
1511
|
validatePositive((_b = options.requestTimeoutMs) != null ? _b : 3e4, "RequestTimeout");
|
|
@@ -1396,7 +1514,6 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1396
1514
|
validatePositive((_e = options.maxReceivePayloadSize) != null ? _e : 64 * 1024, "MaxReceivePayloadSize");
|
|
1397
1515
|
validateHeartbeat(options.heartbeat);
|
|
1398
1516
|
validateReconnect(options.reconnect);
|
|
1399
|
-
validateDiagnosticsLevel(options.diagnosticsLevel);
|
|
1400
1517
|
return {
|
|
1401
1518
|
endpoint,
|
|
1402
1519
|
transport: inferredTransport,
|
|
@@ -1422,10 +1539,7 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1422
1539
|
compressionCodec: resolveCompressionCodec2(options),
|
|
1423
1540
|
nameResolver: (_B = options.nameResolver) != null ? _B : defaultPacketNameResolver,
|
|
1424
1541
|
transportFactory: (_C = options.transportFactory) != null ? _C : defaultTransportFactory,
|
|
1425
|
-
codec: options.codec
|
|
1426
|
-
// Spec 26 §4: the default diagnostics level is Errors, which preserves
|
|
1427
|
-
// the connector's established wire behavior.
|
|
1428
|
-
diagnosticsLevel: (_D = options.diagnosticsLevel) != null ? _D : "errors" /* Errors */
|
|
1542
|
+
codec: options.codec
|
|
1429
1543
|
};
|
|
1430
1544
|
}
|
|
1431
1545
|
var defaultPacketNameResolver = {
|
|
@@ -1442,17 +1556,15 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1442
1556
|
const compression = (_a = options.compression) != null ? _a : "lz4" /* Lz4 */;
|
|
1443
1557
|
if (compression === "none" /* None */) {
|
|
1444
1558
|
if (options.compressionCodec !== void 0) {
|
|
1445
|
-
throw connectorError(
|
|
1559
|
+
throw connectorError(
|
|
1560
|
+
"configurationError" /* ConfigurationError */,
|
|
1561
|
+
"compressionCodec cannot be set when compression is none."
|
|
1562
|
+
);
|
|
1446
1563
|
}
|
|
1447
1564
|
return void 0;
|
|
1448
1565
|
}
|
|
1449
1566
|
return options.compressionCodec;
|
|
1450
1567
|
}
|
|
1451
|
-
function validateDiagnosticsLevel(level) {
|
|
1452
|
-
if (level !== void 0 && !validDiagnosticsLevels.has(level)) {
|
|
1453
|
-
throw connectorError("configurationError" /* ConfigurationError */, "DiagnosticsLevel is invalid.");
|
|
1454
|
-
}
|
|
1455
|
-
}
|
|
1456
1568
|
function validatePositive(value, name) {
|
|
1457
1569
|
if (value <= 0) {
|
|
1458
1570
|
throw connectorError("validationFailed" /* ValidationFailed */, `${name} must be positive.`);
|
|
@@ -1469,7 +1581,10 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1469
1581
|
validatePositive(intervalMs, "Heartbeat interval");
|
|
1470
1582
|
validatePositive(timeoutMs, "Heartbeat timeout");
|
|
1471
1583
|
if (timeoutMs <= intervalMs) {
|
|
1472
|
-
throw connectorError(
|
|
1584
|
+
throw connectorError(
|
|
1585
|
+
"validationFailed" /* ValidationFailed */,
|
|
1586
|
+
"Heartbeat timeout must be greater than the heartbeat interval."
|
|
1587
|
+
);
|
|
1473
1588
|
}
|
|
1474
1589
|
}
|
|
1475
1590
|
function validateReconnect(options) {
|
|
@@ -1481,33 +1596,20 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1481
1596
|
validatePositive((_b = options == null ? void 0 : options.initialDelayMs) != null ? _b : 250, "Reconnect InitialDelay");
|
|
1482
1597
|
validatePositive((_c = options == null ? void 0 : options.maxDelayMs) != null ? _c : 5e3, "Reconnect MaxDelay");
|
|
1483
1598
|
if (((_d = options == null ? void 0 : options.backoffFactor) != null ? _d : 2) < 1) {
|
|
1484
|
-
throw connectorError(
|
|
1599
|
+
throw connectorError(
|
|
1600
|
+
"validationFailed" /* ValidationFailed */,
|
|
1601
|
+
"Reconnect BackoffFactor must be at least 1.0."
|
|
1602
|
+
);
|
|
1485
1603
|
}
|
|
1486
1604
|
const maxAttempts = (options == null ? void 0 : options.maxAttempts) === void 0 ? 3 : options.maxAttempts;
|
|
1487
1605
|
if (maxAttempts !== null && !(Number.isFinite(maxAttempts) && maxAttempts > 0)) {
|
|
1488
|
-
throw connectorError(
|
|
1606
|
+
throw connectorError(
|
|
1607
|
+
"validationFailed" /* ValidationFailed */,
|
|
1608
|
+
"Reconnect MaxAttempts must be null or positive."
|
|
1609
|
+
);
|
|
1489
1610
|
}
|
|
1490
1611
|
}
|
|
1491
1612
|
|
|
1492
|
-
// packages/stream-connector/src/Runtime/ZlinkStreamDiagnosticsLevelCell.ts
|
|
1493
|
-
var ZlinkStreamDiagnosticsLevelCell = class {
|
|
1494
|
-
constructor(initial) {
|
|
1495
|
-
__publicField(this, "current");
|
|
1496
|
-
this.current = initial;
|
|
1497
|
-
}
|
|
1498
|
-
get level() {
|
|
1499
|
-
return this.current;
|
|
1500
|
-
}
|
|
1501
|
-
set(level) {
|
|
1502
|
-
const candidate = level;
|
|
1503
|
-
if (candidate === void 0 || candidate === null) {
|
|
1504
|
-
throw connectorError("configurationError" /* ConfigurationError */, "DiagnosticsLevel is invalid.");
|
|
1505
|
-
}
|
|
1506
|
-
validateDiagnosticsLevel(level);
|
|
1507
|
-
this.current = level;
|
|
1508
|
-
}
|
|
1509
|
-
};
|
|
1510
|
-
|
|
1511
1613
|
// packages/stream-connector/src/Runtime/ZlinkStreamPendingRequests.ts
|
|
1512
1614
|
var ZlinkStreamPendingRequests = class {
|
|
1513
1615
|
constructor() {
|
|
@@ -1522,14 +1624,21 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1522
1624
|
let timeout;
|
|
1523
1625
|
let resolvePending;
|
|
1524
1626
|
let rejectPending;
|
|
1525
|
-
const promise = new Promise(
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1627
|
+
const promise = new Promise(
|
|
1628
|
+
(resolve, reject) => {
|
|
1629
|
+
timeout = setTimeout(() => {
|
|
1630
|
+
this.active.delete(requestSeq);
|
|
1631
|
+
reject(
|
|
1632
|
+
connectorError(
|
|
1633
|
+
"requestTimeout" /* RequestTimeout */,
|
|
1634
|
+
`Request '${packetName}' timed out.`
|
|
1635
|
+
)
|
|
1636
|
+
);
|
|
1637
|
+
}, timeoutMs);
|
|
1638
|
+
resolvePending = resolve;
|
|
1639
|
+
rejectPending = (error) => reject(connectorError(error.code, error.message, error.cause));
|
|
1640
|
+
}
|
|
1641
|
+
);
|
|
1533
1642
|
this.active.set(requestSeq, {
|
|
1534
1643
|
packetName,
|
|
1535
1644
|
promise,
|
|
@@ -1553,15 +1662,14 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1553
1662
|
});
|
|
1554
1663
|
return { requestSeq, promise };
|
|
1555
1664
|
}
|
|
1556
|
-
/* stream connector spec §5.2: a pending request is matched by request_seq alone.
|
|
1557
|
-
|
|
1558
|
-
resolve(requestSeq, value) {
|
|
1665
|
+
/* stream connector spec §5.2: a pending request is matched by request_seq alone. */
|
|
1666
|
+
resolve(requestSeq, value, metadata) {
|
|
1559
1667
|
const pending = this.active.get(requestSeq);
|
|
1560
1668
|
if (pending === void 0) {
|
|
1561
1669
|
return false;
|
|
1562
1670
|
}
|
|
1563
1671
|
this.active.delete(requestSeq);
|
|
1564
|
-
pending.resolve(value);
|
|
1672
|
+
pending.resolve({ name: pending.packetName, metadata, payload: value });
|
|
1565
1673
|
return true;
|
|
1566
1674
|
}
|
|
1567
1675
|
reject(requestSeq, error) {
|
|
@@ -1699,9 +1807,11 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1699
1807
|
*/
|
|
1700
1808
|
resetForNewConnection() {
|
|
1701
1809
|
this.receivedCounts.clear();
|
|
1810
|
+
const submittedCallbacks = this.queue.slice(this.queueHead).filter((item) => (item == null ? void 0 : item.kind) === "callback");
|
|
1702
1811
|
this.queue.length = 0;
|
|
1812
|
+
this.queue.push(...submittedCallbacks);
|
|
1703
1813
|
this.queueHead = 0;
|
|
1704
|
-
this.queuedCount =
|
|
1814
|
+
this.queuedCount = submittedCallbacks.length;
|
|
1705
1815
|
}
|
|
1706
1816
|
/**
|
|
1707
1817
|
* Releases every registered wait surface because the connection it was
|
|
@@ -1731,7 +1841,14 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1731
1841
|
return;
|
|
1732
1842
|
}
|
|
1733
1843
|
}
|
|
1734
|
-
this.queue.push({ message, signal });
|
|
1844
|
+
this.queue.push({ kind: "message", message, signal });
|
|
1845
|
+
this.queuedCount += 1;
|
|
1846
|
+
if (this.deliverOnArrival) {
|
|
1847
|
+
this.scheduleDrain();
|
|
1848
|
+
}
|
|
1849
|
+
}
|
|
1850
|
+
enqueueCallback(callback) {
|
|
1851
|
+
this.queue.push({ kind: "callback", callback });
|
|
1735
1852
|
this.queuedCount += 1;
|
|
1736
1853
|
if (this.deliverOnArrival) {
|
|
1737
1854
|
this.scheduleDrain();
|
|
@@ -1758,7 +1875,7 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1758
1875
|
offerQueued(name, registration) {
|
|
1759
1876
|
for (let index = this.queueHead; index < this.queue.length; index += 1) {
|
|
1760
1877
|
const queued = this.queue[index];
|
|
1761
|
-
if (queued === void 0 || queued.message.name !== name) {
|
|
1878
|
+
if (queued === void 0 || queued.kind !== "message" || queued.message.name !== name) {
|
|
1762
1879
|
continue;
|
|
1763
1880
|
}
|
|
1764
1881
|
if (!registration.consume(queued.message)) {
|
|
@@ -1786,17 +1903,24 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1786
1903
|
const queued = this.queue[index];
|
|
1787
1904
|
if (queued === void 0) continue;
|
|
1788
1905
|
this.removeAt(index);
|
|
1906
|
+
if (queued.kind === "callback") {
|
|
1907
|
+
await queued.callback();
|
|
1908
|
+
continue;
|
|
1909
|
+
}
|
|
1789
1910
|
const { message, signal } = queued;
|
|
1790
1911
|
const handlers = [...this.handlers.get(message.name)];
|
|
1791
1912
|
for (const handler of handlers) {
|
|
1792
1913
|
try {
|
|
1793
1914
|
await handler(message, signal);
|
|
1794
1915
|
} catch (cause) {
|
|
1795
|
-
await this.events.publishError(
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1916
|
+
await this.events.publishError(
|
|
1917
|
+
{
|
|
1918
|
+
code: "userCallbackFailed" /* UserCallbackFailed */,
|
|
1919
|
+
message: "Typed message handler failed.",
|
|
1920
|
+
cause
|
|
1921
|
+
},
|
|
1922
|
+
signal
|
|
1923
|
+
);
|
|
1800
1924
|
}
|
|
1801
1925
|
}
|
|
1802
1926
|
}
|
|
@@ -1814,16 +1938,16 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1814
1938
|
var _a, _b;
|
|
1815
1939
|
for (let index = this.queueHead; index < this.queue.length; index += 1) {
|
|
1816
1940
|
const queued = this.queue[index];
|
|
1817
|
-
if (queued !== void 0 && ((_b = (_a = this.handlers.get(queued.message.name)) == null ? void 0 : _a.size) != null ? _b : 0) > 0) {
|
|
1941
|
+
if (queued !== void 0 && (queued.kind === "callback" || ((_b = (_a = this.handlers.get(queued.message.name)) == null ? void 0 : _a.size) != null ? _b : 0) > 0)) {
|
|
1818
1942
|
return index;
|
|
1819
1943
|
}
|
|
1820
1944
|
}
|
|
1821
1945
|
return -1;
|
|
1822
1946
|
}
|
|
1823
1947
|
hasQueuedMessage(name) {
|
|
1824
|
-
var _a;
|
|
1825
1948
|
for (let index = this.queueHead; index < this.queue.length; index += 1) {
|
|
1826
|
-
|
|
1949
|
+
const queued = this.queue[index];
|
|
1950
|
+
if ((queued == null ? void 0 : queued.kind) === "message" && queued.message.name === name) return true;
|
|
1827
1951
|
}
|
|
1828
1952
|
return false;
|
|
1829
1953
|
}
|
|
@@ -1847,17 +1971,24 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1847
1971
|
|
|
1848
1972
|
// packages/stream-connector/src/Runtime/ZlinkStreamFrameSender.ts
|
|
1849
1973
|
var ZlinkStreamFrameSender = class {
|
|
1850
|
-
constructor(protocol
|
|
1974
|
+
constructor(protocol) {
|
|
1851
1975
|
this.protocol = protocol;
|
|
1852
|
-
this.flowContext = flowContext;
|
|
1853
1976
|
__publicField(this, "pendingWrites", /* @__PURE__ */ new Set());
|
|
1854
1977
|
}
|
|
1855
|
-
async send(connection, kind, name, payload, metadata, compress, requestSeq, signal, correlationId,
|
|
1978
|
+
async send(connection, kind, name, payload, metadata, compress, requestSeq, signal, correlationId, actorSlot) {
|
|
1856
1979
|
throwIfAborted(signal);
|
|
1857
|
-
const flow = this.protocol.flowEnabled() ? this.flowContext.currentOrCreate(explicitFlow) : void 0;
|
|
1858
1980
|
await this.write(
|
|
1859
1981
|
connection,
|
|
1860
|
-
this.protocol.encode(
|
|
1982
|
+
this.protocol.encode(
|
|
1983
|
+
kind,
|
|
1984
|
+
name,
|
|
1985
|
+
payload,
|
|
1986
|
+
metadata,
|
|
1987
|
+
compress,
|
|
1988
|
+
requestSeq,
|
|
1989
|
+
correlationId,
|
|
1990
|
+
actorSlot
|
|
1991
|
+
),
|
|
1861
1992
|
signal
|
|
1862
1993
|
);
|
|
1863
1994
|
}
|
|
@@ -1892,24 +2023,196 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1892
2023
|
6: "TransportError"
|
|
1893
2024
|
};
|
|
1894
2025
|
function decodeSessionClosing(payload) {
|
|
1895
|
-
if (payload.length < 4 || payload[0] !== 1)
|
|
2026
|
+
if (payload.length < 4 || payload[0] !== 1)
|
|
2027
|
+
throw new Error("Unsupported session-closing version.");
|
|
1896
2028
|
const closeReason = reasons[payload[1]];
|
|
1897
2029
|
if (closeReason === void 0) throw new Error("Unknown session-closing reason.");
|
|
1898
2030
|
const length = payload[2] << 8 | payload[3];
|
|
1899
|
-
if (length > 512 || payload.length !== 4 + length)
|
|
2031
|
+
if (length > 512 || payload.length !== 4 + length)
|
|
2032
|
+
throw new Error("Invalid session-closing diagnostic length.");
|
|
1900
2033
|
const diagnostic = length === 0 ? void 0 : new TextDecoder("utf-8", { fatal: true }).decode(payload.subarray(4));
|
|
1901
2034
|
return { closeReason, diagnostic };
|
|
1902
2035
|
}
|
|
1903
2036
|
|
|
2037
|
+
// packages/stream-connector/src/Runtime/ZlinkStreamActors.ts
|
|
2038
|
+
var ACTOR_BOUND = "$zlink.actor.bound";
|
|
2039
|
+
var ACTOR_UNBOUND = "$zlink.actor.unbound";
|
|
2040
|
+
var zlinkStreamActorBinding = Symbol("zlink.stream.actorBinding");
|
|
2041
|
+
var DefaultZlinkStreamActor = class {
|
|
2042
|
+
constructor(connector, actorId, slot) {
|
|
2043
|
+
this.connector = connector;
|
|
2044
|
+
this.actorId = actorId;
|
|
2045
|
+
this.slot = slot;
|
|
2046
|
+
__publicField(this, "bound", true);
|
|
2047
|
+
}
|
|
2048
|
+
get isBound() {
|
|
2049
|
+
return this.bound;
|
|
2050
|
+
}
|
|
2051
|
+
send(payload, messageType) {
|
|
2052
|
+
this.ensureBound();
|
|
2053
|
+
return this.connector.sendForActor(this, payload, messageType);
|
|
2054
|
+
}
|
|
2055
|
+
request(payload, messageType) {
|
|
2056
|
+
this.ensureBound();
|
|
2057
|
+
return this.connector.requestForActor(this, payload, messageType);
|
|
2058
|
+
}
|
|
2059
|
+
on(nameOrType, handler, messageType) {
|
|
2060
|
+
return this.connector.onActorMessage(this, nameOrType, handler, messageType);
|
|
2061
|
+
}
|
|
2062
|
+
ensureBound() {
|
|
2063
|
+
if (!this.bound) {
|
|
2064
|
+
throw connectorError(
|
|
2065
|
+
"validationFailed" /* ValidationFailed */,
|
|
2066
|
+
`Actor '${this.actorId}' is no longer bound.`
|
|
2067
|
+
);
|
|
2068
|
+
}
|
|
2069
|
+
}
|
|
2070
|
+
close() {
|
|
2071
|
+
this.bound = false;
|
|
2072
|
+
}
|
|
2073
|
+
};
|
|
2074
|
+
var ZlinkStreamActors = class {
|
|
2075
|
+
constructor(connector, receivedMessages, events) {
|
|
2076
|
+
this.connector = connector;
|
|
2077
|
+
this.receivedMessages = receivedMessages;
|
|
2078
|
+
this.events = events;
|
|
2079
|
+
__publicField(this, "bySlot", /* @__PURE__ */ new Map());
|
|
2080
|
+
__publicField(this, "byId", /* @__PURE__ */ new Map());
|
|
2081
|
+
__publicField(this, "issued", []);
|
|
2082
|
+
__publicField(this, "boundHandlers", /* @__PURE__ */ new Set());
|
|
2083
|
+
__publicField(this, "unboundHandlers", /* @__PURE__ */ new Set());
|
|
2084
|
+
}
|
|
2085
|
+
get snapshot() {
|
|
2086
|
+
return Object.freeze([...this.bySlot.values()]);
|
|
2087
|
+
}
|
|
2088
|
+
find(actorId) {
|
|
2089
|
+
return this.byId.get(actorId);
|
|
2090
|
+
}
|
|
2091
|
+
onBound(handler) {
|
|
2092
|
+
this.boundHandlers.add(handler);
|
|
2093
|
+
return subscription(() => this.boundHandlers.delete(handler));
|
|
2094
|
+
}
|
|
2095
|
+
onUnbound(handler) {
|
|
2096
|
+
this.unboundHandlers.add(handler);
|
|
2097
|
+
return subscription(() => this.unboundHandlers.delete(handler));
|
|
2098
|
+
}
|
|
2099
|
+
processControl(name, payload, signal) {
|
|
2100
|
+
if (name === ACTOR_BOUND) {
|
|
2101
|
+
this.bind(payload, signal);
|
|
2102
|
+
return true;
|
|
2103
|
+
}
|
|
2104
|
+
if (name === ACTOR_UNBOUND) {
|
|
2105
|
+
this.unbind(payload, signal);
|
|
2106
|
+
return true;
|
|
2107
|
+
}
|
|
2108
|
+
return false;
|
|
2109
|
+
}
|
|
2110
|
+
resolve(slot) {
|
|
2111
|
+
const actor = this.bySlot.get(slot);
|
|
2112
|
+
if (actor === void 0) {
|
|
2113
|
+
throw connectorError(
|
|
2114
|
+
"frameDecodeFailed" /* FrameDecodeFailed */,
|
|
2115
|
+
`Actor slot '${slot}' is not bound.`
|
|
2116
|
+
);
|
|
2117
|
+
}
|
|
2118
|
+
return actor;
|
|
2119
|
+
}
|
|
2120
|
+
closeAll(signal) {
|
|
2121
|
+
for (const actor of this.issued) {
|
|
2122
|
+
if (!actor.isBound) continue;
|
|
2123
|
+
this.bySlot.delete(actor.slot);
|
|
2124
|
+
this.byId.delete(actor.actorId);
|
|
2125
|
+
actor.close();
|
|
2126
|
+
this.queue(this.unboundHandlers, actor, signal);
|
|
2127
|
+
}
|
|
2128
|
+
this.issued.length = 0;
|
|
2129
|
+
}
|
|
2130
|
+
bind(payload, signal) {
|
|
2131
|
+
if (payload.length < 5 || payload[0] !== 1) {
|
|
2132
|
+
throw invalidControl("Actor bound payload is invalid.");
|
|
2133
|
+
}
|
|
2134
|
+
const slot = payload[1] << 8 | payload[2];
|
|
2135
|
+
const idLength = payload[3];
|
|
2136
|
+
if (slot === 0 || idLength === 0 || payload.length !== 4 + idLength) {
|
|
2137
|
+
throw invalidControl("Actor bound payload is invalid.");
|
|
2138
|
+
}
|
|
2139
|
+
let actorId;
|
|
2140
|
+
try {
|
|
2141
|
+
actorId = new TextDecoder("utf-8", { fatal: true }).decode(payload.subarray(4));
|
|
2142
|
+
} catch (cause) {
|
|
2143
|
+
throw connectorError(
|
|
2144
|
+
"frameDecodeFailed" /* FrameDecodeFailed */,
|
|
2145
|
+
"Actor id is not valid UTF-8.",
|
|
2146
|
+
cause
|
|
2147
|
+
);
|
|
2148
|
+
}
|
|
2149
|
+
if (actorId.length === 0 || this.bySlot.has(slot) || this.byId.has(actorId)) {
|
|
2150
|
+
throw invalidControl("Actor bound identity is already in use.");
|
|
2151
|
+
}
|
|
2152
|
+
const actor = new DefaultZlinkStreamActor(this.connector, actorId, slot);
|
|
2153
|
+
this.bySlot.set(slot, actor);
|
|
2154
|
+
this.byId.set(actorId, actor);
|
|
2155
|
+
this.issued.push(actor);
|
|
2156
|
+
this.queue(this.boundHandlers, actor, signal);
|
|
2157
|
+
}
|
|
2158
|
+
unbind(payload, signal) {
|
|
2159
|
+
if (payload.length !== 3 || payload[0] !== 1) {
|
|
2160
|
+
throw invalidControl("Actor unbound payload is invalid.");
|
|
2161
|
+
}
|
|
2162
|
+
const slot = payload[1] << 8 | payload[2];
|
|
2163
|
+
const actor = this.bySlot.get(slot);
|
|
2164
|
+
if (slot === 0 || actor === void 0) {
|
|
2165
|
+
throw invalidControl(`Actor slot '${slot}' is not bound.`);
|
|
2166
|
+
}
|
|
2167
|
+
this.bySlot.delete(slot);
|
|
2168
|
+
this.byId.delete(actor.actorId);
|
|
2169
|
+
actor.close();
|
|
2170
|
+
this.queue(this.unboundHandlers, actor, signal);
|
|
2171
|
+
}
|
|
2172
|
+
queue(handlers, actor, signal) {
|
|
2173
|
+
this.receivedMessages.enqueueCallback(() => {
|
|
2174
|
+
for (const handler of [...handlers]) {
|
|
2175
|
+
this.invoke(handler, actor, signal);
|
|
2176
|
+
}
|
|
2177
|
+
});
|
|
2178
|
+
}
|
|
2179
|
+
invoke(handler, actor, signal) {
|
|
2180
|
+
try {
|
|
2181
|
+
Promise.resolve(handler(actor, signal)).catch((cause) => {
|
|
2182
|
+
void this.events.publishError(
|
|
2183
|
+
{
|
|
2184
|
+
code: "userCallbackFailed" /* UserCallbackFailed */,
|
|
2185
|
+
message: "Actor lifecycle handler failed.",
|
|
2186
|
+
cause
|
|
2187
|
+
},
|
|
2188
|
+
signal
|
|
2189
|
+
);
|
|
2190
|
+
});
|
|
2191
|
+
} catch (cause) {
|
|
2192
|
+
void this.events.publishError(
|
|
2193
|
+
{
|
|
2194
|
+
code: "userCallbackFailed" /* UserCallbackFailed */,
|
|
2195
|
+
message: "Actor lifecycle handler failed.",
|
|
2196
|
+
cause
|
|
2197
|
+
},
|
|
2198
|
+
signal
|
|
2199
|
+
);
|
|
2200
|
+
}
|
|
2201
|
+
}
|
|
2202
|
+
};
|
|
2203
|
+
function invalidControl(message) {
|
|
2204
|
+
return connectorError("frameDecodeFailed" /* FrameDecodeFailed */, message);
|
|
2205
|
+
}
|
|
2206
|
+
|
|
1904
2207
|
// packages/stream-connector/src/Runtime/ZlinkStreamReceiveDispatcher.ts
|
|
1905
2208
|
var ZlinkStreamReceiveDispatcher = class {
|
|
1906
|
-
constructor(protocol, pendingRequests, receivedMessages, frameSender, events,
|
|
2209
|
+
constructor(protocol, pendingRequests, receivedMessages, frameSender, events, actors, serverClosing) {
|
|
1907
2210
|
this.protocol = protocol;
|
|
1908
2211
|
this.pendingRequests = pendingRequests;
|
|
1909
2212
|
this.receivedMessages = receivedMessages;
|
|
1910
2213
|
this.frameSender = frameSender;
|
|
1911
2214
|
this.events = events;
|
|
1912
|
-
this.
|
|
2215
|
+
this.actors = actors;
|
|
1913
2216
|
this.serverClosing = serverClosing;
|
|
1914
2217
|
}
|
|
1915
2218
|
/**
|
|
@@ -1936,46 +2239,54 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1936
2239
|
if (frameBytes === void 0) {
|
|
1937
2240
|
return { available: false, inbound: false };
|
|
1938
2241
|
}
|
|
1939
|
-
const flowEnabled = this.protocol.flowEnabled();
|
|
1940
2242
|
let frames;
|
|
1941
2243
|
try {
|
|
1942
|
-
frames = this.protocol.decodeFrames(frameBytes
|
|
2244
|
+
frames = this.protocol.decodeFrames(frameBytes);
|
|
1943
2245
|
} catch (cause) {
|
|
1944
|
-
|
|
1945
|
-
toStreamError(cause, "frameDecodeFailed" /* FrameDecodeFailed */, "Frame decode failed."),
|
|
1946
|
-
signal
|
|
1947
|
-
);
|
|
1948
|
-
return { available: true, inbound: false };
|
|
2246
|
+
throw cause;
|
|
1949
2247
|
}
|
|
1950
2248
|
for (const frame of frames) {
|
|
1951
2249
|
if (isCurrent !== void 0 && !isCurrent()) {
|
|
1952
2250
|
break;
|
|
1953
2251
|
}
|
|
1954
2252
|
try {
|
|
1955
|
-
await this.dispatch(connection, frame.header, frame.payload, signal,
|
|
2253
|
+
await this.dispatch(connection, frame.header, frame.payload, signal, connectionForSend);
|
|
1956
2254
|
} catch (cause) {
|
|
1957
2255
|
if (frame.header.kind === 5 /* Control */ && frame.header.name === ZLINK_STREAM_HEARTBEAT_PING) {
|
|
1958
2256
|
throw cause;
|
|
1959
2257
|
}
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
2258
|
+
const error = toStreamError(
|
|
2259
|
+
cause,
|
|
2260
|
+
"frameDecodeFailed" /* FrameDecodeFailed */,
|
|
2261
|
+
"Frame dispatch failed."
|
|
1963
2262
|
);
|
|
2263
|
+
if (error.code === "frameDecodeFailed" /* FrameDecodeFailed */) {
|
|
2264
|
+
throw cause;
|
|
2265
|
+
}
|
|
2266
|
+
await this.events.publishError(error, signal);
|
|
1964
2267
|
}
|
|
1965
2268
|
}
|
|
1966
2269
|
return { available: true, inbound: true };
|
|
1967
2270
|
}
|
|
1968
|
-
async dispatch(connection, header, payload, signal,
|
|
2271
|
+
async dispatch(connection, header, payload, signal, connectionForSend) {
|
|
2272
|
+
const actor = header.actorSlot === void 0 ? void 0 : this.actors.resolve(header.actorSlot);
|
|
1969
2273
|
if (header.kind === 3 /* Response */ && header.requestSeq !== void 0) {
|
|
1970
2274
|
try {
|
|
1971
|
-
if (!this.pendingRequests.resolve(
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
2275
|
+
if (!this.pendingRequests.resolve(
|
|
2276
|
+
header.requestSeq,
|
|
2277
|
+
{
|
|
2278
|
+
codec: header.codec,
|
|
2279
|
+
payload: this.protocol.decodePayload(header, payload)
|
|
2280
|
+
},
|
|
2281
|
+
header.metadata
|
|
2282
|
+
)) {
|
|
2283
|
+
await this.events.publishError(
|
|
2284
|
+
{
|
|
2285
|
+
code: "frameDecodeFailed" /* FrameDecodeFailed */,
|
|
2286
|
+
message: `Response request sequence '${header.requestSeq}' has no pending request.`
|
|
2287
|
+
},
|
|
2288
|
+
signal
|
|
2289
|
+
);
|
|
1979
2290
|
}
|
|
1980
2291
|
} catch (cause) {
|
|
1981
2292
|
const decodeError = toStreamError(
|
|
@@ -1983,10 +2294,7 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
1983
2294
|
"decompressionFailed" /* DecompressionFailed */,
|
|
1984
2295
|
"Decompression failed."
|
|
1985
2296
|
);
|
|
1986
|
-
if (!this.pendingRequests.reject(
|
|
1987
|
-
header.requestSeq,
|
|
1988
|
-
decodeError
|
|
1989
|
-
)) {
|
|
2297
|
+
if (!this.pendingRequests.reject(header.requestSeq, decodeError)) {
|
|
1990
2298
|
await this.events.publishError(decodeError, signal);
|
|
1991
2299
|
}
|
|
1992
2300
|
}
|
|
@@ -2004,10 +2312,7 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
2004
2312
|
"frameDecodeFailed" /* FrameDecodeFailed */,
|
|
2005
2313
|
"Remote error payload is invalid."
|
|
2006
2314
|
);
|
|
2007
|
-
if (!this.pendingRequests.reject(
|
|
2008
|
-
header.requestSeq,
|
|
2009
|
-
decodeError
|
|
2010
|
-
)) {
|
|
2315
|
+
if (!this.pendingRequests.reject(header.requestSeq, decodeError)) {
|
|
2011
2316
|
await this.events.publishError(decodeError, signal);
|
|
2012
2317
|
}
|
|
2013
2318
|
}
|
|
@@ -2022,25 +2327,33 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
2022
2327
|
return;
|
|
2023
2328
|
}
|
|
2024
2329
|
if (header.kind === 1 /* Send */) {
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2330
|
+
this.receivedMessages.enqueue(
|
|
2331
|
+
{
|
|
2332
|
+
name: header.name,
|
|
2333
|
+
metadata: header.metadata,
|
|
2334
|
+
payload: { codec: header.codec, payload: this.protocol.decodePayload(header, payload) },
|
|
2335
|
+
actorId: actor == null ? void 0 : actor.actorId,
|
|
2336
|
+
[zlinkStreamActorBinding]: actor
|
|
2337
|
+
},
|
|
2338
|
+
signal
|
|
2339
|
+
);
|
|
2033
2340
|
}
|
|
2034
2341
|
}
|
|
2035
2342
|
async dispatchControl(connection, header, payload, signal, connectionForSend) {
|
|
2036
2343
|
var _a, _b;
|
|
2344
|
+
if (this.actors.processControl(header.name, payload, signal)) {
|
|
2345
|
+
return;
|
|
2346
|
+
}
|
|
2037
2347
|
if (header.name === ZLINK_SESSION_CLOSING) {
|
|
2038
2348
|
const closing = decodeSessionClosing(payload);
|
|
2039
2349
|
await ((_a = this.serverClosing) == null ? void 0 : _a.call(this, closing.closeReason));
|
|
2040
2350
|
return;
|
|
2041
2351
|
}
|
|
2042
2352
|
if (payload.length !== 0) {
|
|
2043
|
-
throw connectorError(
|
|
2353
|
+
throw connectorError(
|
|
2354
|
+
"frameDecodeFailed" /* FrameDecodeFailed */,
|
|
2355
|
+
"Control packet payload must be empty."
|
|
2356
|
+
);
|
|
2044
2357
|
}
|
|
2045
2358
|
if (header.name === ZLINK_STREAM_HEARTBEAT_PING) {
|
|
2046
2359
|
try {
|
|
@@ -2068,7 +2381,11 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
2068
2381
|
try {
|
|
2069
2382
|
decoded = JSON.parse(utf8Decode2(decodedPayload));
|
|
2070
2383
|
} catch (cause) {
|
|
2071
|
-
throw connectorError(
|
|
2384
|
+
throw connectorError(
|
|
2385
|
+
"frameDecodeFailed" /* FrameDecodeFailed */,
|
|
2386
|
+
"Remote error payload must be a JSON object.",
|
|
2387
|
+
cause
|
|
2388
|
+
);
|
|
2072
2389
|
}
|
|
2073
2390
|
if (decoded === null || typeof decoded !== "object" || Array.isArray(decoded) || typeof decoded.code !== "string" || typeof decoded.message !== "string") {
|
|
2074
2391
|
throw connectorError(
|
|
@@ -2085,12 +2402,13 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
2085
2402
|
return Math.round(baseDelayMs * (0.5 + Math.random() * 0.5));
|
|
2086
2403
|
}
|
|
2087
2404
|
var ZlinkStreamConnectorLifecycle = class {
|
|
2088
|
-
constructor(options, pendingRequests, frameSender, receiveDispatcher, receivedMessages, events) {
|
|
2405
|
+
constructor(options, pendingRequests, frameSender, receiveDispatcher, receivedMessages, actors, events) {
|
|
2089
2406
|
this.options = options;
|
|
2090
2407
|
this.pendingRequests = pendingRequests;
|
|
2091
2408
|
this.frameSender = frameSender;
|
|
2092
2409
|
this.receiveDispatcher = receiveDispatcher;
|
|
2093
2410
|
this.receivedMessages = receivedMessages;
|
|
2411
|
+
this.actors = actors;
|
|
2094
2412
|
this.events = events;
|
|
2095
2413
|
__publicField(this, "receiveLoopAbort");
|
|
2096
2414
|
__publicField(this, "receiveLoopSleeping", false);
|
|
@@ -2149,7 +2467,10 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
2149
2467
|
this.lateConnectCleanupError = error;
|
|
2150
2468
|
throw error;
|
|
2151
2469
|
}
|
|
2152
|
-
throw connectorError(
|
|
2470
|
+
throw connectorError(
|
|
2471
|
+
"disconnected" /* Disconnected */,
|
|
2472
|
+
"Connector closed while connecting."
|
|
2473
|
+
);
|
|
2153
2474
|
}
|
|
2154
2475
|
this.currentConnection = connection;
|
|
2155
2476
|
this.connectionGeneration += 1;
|
|
@@ -2188,8 +2509,15 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
2188
2509
|
}
|
|
2189
2510
|
async serverClosing(reason) {
|
|
2190
2511
|
this.closeReasonValue = reason;
|
|
2191
|
-
const error = {
|
|
2192
|
-
|
|
2512
|
+
const error = {
|
|
2513
|
+
code: "disconnected" /* Disconnected */,
|
|
2514
|
+
message: `Server closed the session: ${reason}.`
|
|
2515
|
+
};
|
|
2516
|
+
await this.disconnectForTransportFailure(
|
|
2517
|
+
error,
|
|
2518
|
+
this.currentConnection,
|
|
2519
|
+
this.connectionGeneration
|
|
2520
|
+
);
|
|
2193
2521
|
}
|
|
2194
2522
|
async closeOnce(signal) {
|
|
2195
2523
|
var _a, _b;
|
|
@@ -2214,10 +2542,14 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
2214
2542
|
} catch (error) {
|
|
2215
2543
|
errors.push(error);
|
|
2216
2544
|
}
|
|
2217
|
-
this.pendingRequests.failAll({
|
|
2545
|
+
this.pendingRequests.failAll({
|
|
2546
|
+
code: "disconnected" /* Disconnected */,
|
|
2547
|
+
message: "Connector closed."
|
|
2548
|
+
});
|
|
2218
2549
|
this.receivedMessages.connectionEnded();
|
|
2219
|
-
|
|
2220
|
-
this.
|
|
2550
|
+
this.actors.closeAll(signal);
|
|
2551
|
+
this.queueState("closed" /* Closed */, void 0, signal);
|
|
2552
|
+
this.queueDisconnected(signal);
|
|
2221
2553
|
if (errors.length === 1) throw errors[0];
|
|
2222
2554
|
if (errors.length > 1) throw new AggregateError(errors, "Stream connector close failed.");
|
|
2223
2555
|
}
|
|
@@ -2341,7 +2673,11 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
2341
2673
|
}
|
|
2342
2674
|
} catch (cause) {
|
|
2343
2675
|
if (signal.aborted) return;
|
|
2344
|
-
const error = toStreamError(
|
|
2676
|
+
const error = toStreamError(
|
|
2677
|
+
cause,
|
|
2678
|
+
"frameDecodeFailed" /* FrameDecodeFailed */,
|
|
2679
|
+
"Receive loop failed."
|
|
2680
|
+
);
|
|
2345
2681
|
await this.disconnectForTransportFailure(error, connection, generation);
|
|
2346
2682
|
} finally {
|
|
2347
2683
|
this.receiveLoopSleeping = false;
|
|
@@ -2401,7 +2737,11 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
2401
2737
|
if (Date.now() - this.lastInboundAt > this.options.heartbeat.timeoutMs) {
|
|
2402
2738
|
this.closeReasonValue = "HeartbeatTimeout";
|
|
2403
2739
|
const error = { code: "disconnected" /* Disconnected */, message: "Heartbeat timed out." };
|
|
2404
|
-
await this.disconnectForTransportFailure(
|
|
2740
|
+
await this.disconnectForTransportFailure(
|
|
2741
|
+
error,
|
|
2742
|
+
this.currentConnection,
|
|
2743
|
+
this.connectionGeneration
|
|
2744
|
+
);
|
|
2405
2745
|
return;
|
|
2406
2746
|
}
|
|
2407
2747
|
const connection = this.currentConnection;
|
|
@@ -2442,6 +2782,7 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
2442
2782
|
this.currentConnection = void 0;
|
|
2443
2783
|
this.pendingRequests.failAll(error);
|
|
2444
2784
|
this.receivedMessages.connectionEnded();
|
|
2785
|
+
this.actors.closeAll();
|
|
2445
2786
|
try {
|
|
2446
2787
|
await (connection == null ? void 0 : connection.close());
|
|
2447
2788
|
} catch {
|
|
@@ -2457,11 +2798,8 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
2457
2798
|
*/
|
|
2458
2799
|
async announceDisconnect(error) {
|
|
2459
2800
|
if (this.closeRequested) return;
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
if (announce) {
|
|
2463
|
-
void this.events.publishDisconnected().catch(() => void 0);
|
|
2464
|
-
}
|
|
2801
|
+
this.queueState("disconnected" /* Disconnected */, error);
|
|
2802
|
+
this.queueDisconnected();
|
|
2465
2803
|
if (this.shouldReconnect()) {
|
|
2466
2804
|
queueMicrotask(() => {
|
|
2467
2805
|
void this.connect().catch(() => void 0);
|
|
@@ -2509,16 +2847,35 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
2509
2847
|
publishDisconnectedWithoutWaiting(signal) {
|
|
2510
2848
|
void this.publishDisconnectedOnce(signal).catch(() => void 0);
|
|
2511
2849
|
}
|
|
2850
|
+
queueDisconnected(signal) {
|
|
2851
|
+
if (!this.claimDisconnectedPublish()) return;
|
|
2852
|
+
this.receivedMessages.enqueueCallback(() => {
|
|
2853
|
+
void this.events.publishDisconnected(signal).catch(() => void 0);
|
|
2854
|
+
});
|
|
2855
|
+
}
|
|
2856
|
+
queueState(current, error, signal) {
|
|
2857
|
+
const change = this.transitionState(current, error);
|
|
2858
|
+
if (change === void 0) return;
|
|
2859
|
+
this.receivedMessages.enqueueCallback(() => {
|
|
2860
|
+
void this.publishStateChange(change, signal).catch(() => void 0);
|
|
2861
|
+
});
|
|
2862
|
+
}
|
|
2512
2863
|
async setState(current, error, signal) {
|
|
2864
|
+
const change = this.transitionState(current, error);
|
|
2865
|
+
if (change === void 0) return;
|
|
2866
|
+
await this.publishStateChange(change, signal);
|
|
2867
|
+
}
|
|
2868
|
+
transitionState(current, error) {
|
|
2513
2869
|
const previous = this.currentState;
|
|
2514
2870
|
this.currentState = current;
|
|
2515
2871
|
if (previous === current && error === void 0) {
|
|
2516
|
-
return;
|
|
2517
|
-
}
|
|
2518
|
-
await this.events.publishStateChanged({ previous, current, error }, signal);
|
|
2519
|
-
if (error !== void 0) {
|
|
2520
|
-
await this.events.publishError(error, signal);
|
|
2872
|
+
return void 0;
|
|
2521
2873
|
}
|
|
2874
|
+
return { previous, current, error };
|
|
2875
|
+
}
|
|
2876
|
+
async publishStateChange(change, signal) {
|
|
2877
|
+
await this.events.publishStateChanged(change, signal);
|
|
2878
|
+
if (change.error !== void 0) await this.events.publishError(change.error, signal);
|
|
2522
2879
|
}
|
|
2523
2880
|
};
|
|
2524
2881
|
|
|
@@ -2555,36 +2912,6 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
2555
2912
|
}
|
|
2556
2913
|
};
|
|
2557
2914
|
|
|
2558
|
-
// packages/stream-connector/src/Runtime/ZlinkFlowContext.ts
|
|
2559
|
-
var BrowserZlinkFlowContext = class {
|
|
2560
|
-
currentOrCreate(explicit) {
|
|
2561
|
-
return explicit != null ? explicit : { flowId: this.createUuidV7(), flowOrigin: "Application" };
|
|
2562
|
-
}
|
|
2563
|
-
createInbound(flowId, flowOrigin) {
|
|
2564
|
-
return { flowId: flowId != null ? flowId : this.createUuidV7(), flowOrigin: flowOrigin != null ? flowOrigin : "Inbound" };
|
|
2565
|
-
}
|
|
2566
|
-
createUuidV7() {
|
|
2567
|
-
const crypto = globalThis.crypto;
|
|
2568
|
-
if (crypto === void 0) {
|
|
2569
|
-
throw connectorError(
|
|
2570
|
-
"configurationError" /* ConfigurationError */,
|
|
2571
|
-
"The browser entrypoint requires the platform Web Crypto API."
|
|
2572
|
-
);
|
|
2573
|
-
}
|
|
2574
|
-
return formatUuidV7(crypto.getRandomValues(new Uint8Array(16)));
|
|
2575
|
-
}
|
|
2576
|
-
};
|
|
2577
|
-
function formatUuidV7(bytes) {
|
|
2578
|
-
const timestamp = BigInt(Date.now());
|
|
2579
|
-
for (let index = 5; index >= 0; index -= 1) {
|
|
2580
|
-
bytes[index] = Number(timestamp >> BigInt((5 - index) * 8) & 0xffn);
|
|
2581
|
-
}
|
|
2582
|
-
bytes[6] = 112 | bytes[6] & 15;
|
|
2583
|
-
bytes[8] = 128 | bytes[8] & 63;
|
|
2584
|
-
const hex = [...bytes].map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
2585
|
-
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
2586
|
-
}
|
|
2587
|
-
|
|
2588
2915
|
// packages/stream-connector/src/Runtime/Transport/BrowserWebSocketConnection.ts
|
|
2589
2916
|
var BrowserStreamTransportFactory = class {
|
|
2590
2917
|
async connect(options, signal) {
|
|
@@ -2615,7 +2942,11 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
2615
2942
|
const message = toUint8Array(event.data);
|
|
2616
2943
|
this.messages.push(message);
|
|
2617
2944
|
} catch (cause) {
|
|
2618
|
-
this.error = cause instanceof Error ? cause : connectorError(
|
|
2945
|
+
this.error = cause instanceof Error ? cause : connectorError(
|
|
2946
|
+
"frameDecodeFailed" /* FrameDecodeFailed */,
|
|
2947
|
+
"WebSocket message decode failed.",
|
|
2948
|
+
cause
|
|
2949
|
+
);
|
|
2619
2950
|
this.closed = true;
|
|
2620
2951
|
this.socket.close();
|
|
2621
2952
|
}
|
|
@@ -2623,13 +2954,19 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
2623
2954
|
});
|
|
2624
2955
|
__publicField(this, "onClose", () => {
|
|
2625
2956
|
if (!this.closed) {
|
|
2626
|
-
this.error = connectorError(
|
|
2957
|
+
this.error = connectorError(
|
|
2958
|
+
"disconnected" /* Disconnected */,
|
|
2959
|
+
"Remote stream closed the WebSocket connection."
|
|
2960
|
+
);
|
|
2627
2961
|
}
|
|
2628
2962
|
this.closed = true;
|
|
2629
2963
|
this.wakeReader();
|
|
2630
2964
|
});
|
|
2631
2965
|
__publicField(this, "onError", () => {
|
|
2632
|
-
this.error = connectorError(
|
|
2966
|
+
this.error = connectorError(
|
|
2967
|
+
"disconnected" /* Disconnected */,
|
|
2968
|
+
"Remote stream closed after a WebSocket error."
|
|
2969
|
+
);
|
|
2633
2970
|
this.closed = true;
|
|
2634
2971
|
this.wakeReader();
|
|
2635
2972
|
});
|
|
@@ -2679,7 +3016,10 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
2679
3016
|
}
|
|
2680
3017
|
waitForMessage(signal) {
|
|
2681
3018
|
if (this.readWaiter !== void 0) {
|
|
2682
|
-
throw connectorError(
|
|
3019
|
+
throw connectorError(
|
|
3020
|
+
"validationFailed" /* ValidationFailed */,
|
|
3021
|
+
"Only one pending stream read is supported."
|
|
3022
|
+
);
|
|
2683
3023
|
}
|
|
2684
3024
|
return new Promise((resolve, reject) => {
|
|
2685
3025
|
const onAbort = () => {
|
|
@@ -2736,9 +3076,10 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
2736
3076
|
async function waitForOpen(socket, connectTimeoutMs, signal) {
|
|
2737
3077
|
throwIfAborted(signal);
|
|
2738
3078
|
await new Promise((resolve, reject) => {
|
|
2739
|
-
const timeout = setTimeout(
|
|
2740
|
-
connectorError("connectTimeout" /* ConnectTimeout */, "Connect timed out.")
|
|
2741
|
-
|
|
3079
|
+
const timeout = setTimeout(
|
|
3080
|
+
() => finish(connectorError("connectTimeout" /* ConnectTimeout */, "Connect timed out.")),
|
|
3081
|
+
connectTimeoutMs
|
|
3082
|
+
);
|
|
2742
3083
|
const onOpen = () => finish();
|
|
2743
3084
|
const onClose = () => finish(connectorError("connectTimeout" /* ConnectTimeout */, "Connect closed before opening."));
|
|
2744
3085
|
const onError = () => finish(connectorError("connectTimeout" /* ConnectTimeout */, "Connect failed."));
|
|
@@ -2769,7 +3110,10 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
2769
3110
|
if (ArrayBuffer.isView(data)) {
|
|
2770
3111
|
return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
2771
3112
|
}
|
|
2772
|
-
throw connectorError(
|
|
3113
|
+
throw connectorError(
|
|
3114
|
+
"frameDecodeFailed" /* FrameDecodeFailed */,
|
|
3115
|
+
"WebSocket text messages are not supported."
|
|
3116
|
+
);
|
|
2773
3117
|
}
|
|
2774
3118
|
|
|
2775
3119
|
// packages/stream-connector/src/Runtime/ZlinkStreamConnector.ts
|
|
@@ -2782,29 +3126,25 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
2782
3126
|
__publicField(this, "pendingRequests", new ZlinkStreamPendingRequests());
|
|
2783
3127
|
__publicField(this, "frameSender");
|
|
2784
3128
|
__publicField(this, "receiveDispatcher");
|
|
2785
|
-
__publicField(this, "
|
|
3129
|
+
__publicField(this, "requestSendingHandlers", /* @__PURE__ */ new Set());
|
|
3130
|
+
__publicField(this, "replyReceivedHandlers", /* @__PURE__ */ new Set());
|
|
3131
|
+
__publicField(this, "boundActors");
|
|
2786
3132
|
__publicField(this, "options");
|
|
2787
|
-
const flowContext = new BrowserZlinkFlowContext();
|
|
2788
3133
|
this.options = normalizeOptions(options, new BrowserStreamTransportFactory());
|
|
2789
|
-
this.diagnosticsLevelCell = new ZlinkStreamDiagnosticsLevelCell(this.options.diagnosticsLevel);
|
|
2790
|
-
Object.defineProperty(this.options, "diagnosticsLevel", {
|
|
2791
|
-
enumerable: true,
|
|
2792
|
-
configurable: true,
|
|
2793
|
-
get: () => this.diagnosticsLevelCell.level
|
|
2794
|
-
});
|
|
2795
3134
|
const protocol = new ZlinkStreamFrameProtocol(this.options);
|
|
2796
|
-
this.frameSender = new ZlinkStreamFrameSender(protocol
|
|
3135
|
+
this.frameSender = new ZlinkStreamFrameSender(protocol);
|
|
2797
3136
|
this.receivedMessages = new ZlinkStreamReceivedMessages(
|
|
2798
3137
|
this.events,
|
|
2799
3138
|
this.options.dispatchMode === "immediate" /* Immediate */
|
|
2800
3139
|
);
|
|
3140
|
+
this.boundActors = new ZlinkStreamActors(this, this.receivedMessages, this.events);
|
|
2801
3141
|
this.receiveDispatcher = new ZlinkStreamReceiveDispatcher(
|
|
2802
3142
|
protocol,
|
|
2803
3143
|
this.pendingRequests,
|
|
2804
3144
|
this.receivedMessages,
|
|
2805
3145
|
this.frameSender,
|
|
2806
3146
|
this.events,
|
|
2807
|
-
|
|
3147
|
+
this.boundActors,
|
|
2808
3148
|
(reason) => this.lifecycle.serverClosing(reason)
|
|
2809
3149
|
);
|
|
2810
3150
|
this.lifecycle = new ZlinkStreamConnectorLifecycle(
|
|
@@ -2813,6 +3153,7 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
2813
3153
|
this.frameSender,
|
|
2814
3154
|
this.receiveDispatcher,
|
|
2815
3155
|
this.receivedMessages,
|
|
3156
|
+
this.boundActors,
|
|
2816
3157
|
this.events
|
|
2817
3158
|
);
|
|
2818
3159
|
}
|
|
@@ -2828,6 +3169,18 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
2828
3169
|
get pendingDispatchCount() {
|
|
2829
3170
|
return this.pendingRequests.count;
|
|
2830
3171
|
}
|
|
3172
|
+
get actors() {
|
|
3173
|
+
return this.boundActors.snapshot;
|
|
3174
|
+
}
|
|
3175
|
+
actor(actorId) {
|
|
3176
|
+
return this.boundActors.find(actorId);
|
|
3177
|
+
}
|
|
3178
|
+
onActorBound(handler) {
|
|
3179
|
+
return this.boundActors.onBound(handler);
|
|
3180
|
+
}
|
|
3181
|
+
onActorUnbound(handler) {
|
|
3182
|
+
return this.boundActors.onUnbound(handler);
|
|
3183
|
+
}
|
|
2831
3184
|
/**
|
|
2832
3185
|
* Spec stream-connector 32 §10: how many packets carrying `name` arrived on
|
|
2833
3186
|
* the current connection. Arrivals are what is counted, so a message a
|
|
@@ -2839,37 +3192,6 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
2839
3192
|
validateName(name);
|
|
2840
3193
|
return this.receivedMessages.receivedCount(name);
|
|
2841
3194
|
}
|
|
2842
|
-
/**
|
|
2843
|
-
* Current diagnostics level (spec 26 §4.1, spec stream-connector 32 §13).
|
|
2844
|
-
* Reflects the level set by the most recent {@link setDiagnosticsLevel}
|
|
2845
|
-
* call, or the construction-time option (default
|
|
2846
|
-
* {@link ZlinkStreamDiagnosticsLevel.Errors}) if it was never changed.
|
|
2847
|
-
*/
|
|
2848
|
-
get diagnosticsLevel() {
|
|
2849
|
-
return this.diagnosticsLevelCell.level;
|
|
2850
|
-
}
|
|
2851
|
-
/**
|
|
2852
|
-
* Changes the diagnostics level in place without recreating the connector
|
|
2853
|
-
* (spec 26 §4.1, spec stream-connector 32 §13). The change is an atomic
|
|
2854
|
-
* state update: it applies to processing points that read the level after
|
|
2855
|
-
* this call returns and is never applied retroactively to frames already
|
|
2856
|
-
* built. Rejects unknown values with {@link ZlinkStreamErrorCode.ConfigurationError}.
|
|
2857
|
-
* Spec stream-connector 32 §13: this surface changes the value without
|
|
2858
|
-
* waiting for anything; it is not a blocking call over the asynchronous pair,
|
|
2859
|
-
* which a receive callback would otherwise make wait for its own completion.
|
|
2860
|
-
*/
|
|
2861
|
-
setDiagnosticsLevel(level) {
|
|
2862
|
-
this.diagnosticsLevelCell.set(level);
|
|
2863
|
-
}
|
|
2864
|
-
/**
|
|
2865
|
-
* Asynchronous counterpart of {@link setDiagnosticsLevel} (spec
|
|
2866
|
-
* stream-connector 32 §13). It changes the same value; awaiting it is how a
|
|
2867
|
-
* caller observes the change, and it never replaces the synchronous surface.
|
|
2868
|
-
*/
|
|
2869
|
-
setDiagnosticsLevelAsync(level) {
|
|
2870
|
-
this.setDiagnosticsLevel(level);
|
|
2871
|
-
return Promise.resolve();
|
|
2872
|
-
}
|
|
2873
3195
|
onErrorReceived(handler) {
|
|
2874
3196
|
return this.events.onError(handler);
|
|
2875
3197
|
}
|
|
@@ -2879,6 +3201,14 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
2879
3201
|
onConnectionStateChanged(handler) {
|
|
2880
3202
|
return this.events.onStateChanged(handler);
|
|
2881
3203
|
}
|
|
3204
|
+
onRequestSending(handler) {
|
|
3205
|
+
this.requestSendingHandlers.add(handler);
|
|
3206
|
+
return subscription(() => this.requestSendingHandlers.delete(handler));
|
|
3207
|
+
}
|
|
3208
|
+
onReplyReceived(handler) {
|
|
3209
|
+
this.replyReceivedHandlers.add(handler);
|
|
3210
|
+
return subscription(() => this.replyReceivedHandlers.delete(handler));
|
|
3211
|
+
}
|
|
2882
3212
|
async connect(signal) {
|
|
2883
3213
|
await this.lifecycle.connect(signal);
|
|
2884
3214
|
}
|
|
@@ -2896,15 +3226,60 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
2896
3226
|
const encoded = this.encodePayload(payload, messageType);
|
|
2897
3227
|
return new ZlinkStreamRequestBuilder(this, this.resolveNameOrDefault(encoded), encoded);
|
|
2898
3228
|
}
|
|
2899
|
-
on(
|
|
2900
|
-
const encodedHandler = (message, signal) => handler(
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
3229
|
+
on(nameOrType, handler, messageType) {
|
|
3230
|
+
const encodedHandler = (message, signal) => handler(
|
|
3231
|
+
{
|
|
3232
|
+
name: message.name,
|
|
3233
|
+
metadata: message.metadata,
|
|
3234
|
+
payload: this.decodePayload(
|
|
3235
|
+
message.payload,
|
|
3236
|
+
messageType != null ? messageType : typeof nameOrType === "function" ? nameOrType : void 0
|
|
3237
|
+
),
|
|
3238
|
+
actorId: message.actorId
|
|
3239
|
+
},
|
|
3240
|
+
signal
|
|
3241
|
+
);
|
|
3242
|
+
return this.receivedMessages.on(this.observedName(nameOrType), encodedHandler);
|
|
3243
|
+
}
|
|
3244
|
+
sendForActor(actor, payload, messageType) {
|
|
3245
|
+
const encoded = this.encodePayload(payload, messageType);
|
|
3246
|
+
return new ZlinkStreamSendBuilder(
|
|
3247
|
+
this,
|
|
3248
|
+
this.resolveNameOrDefault(encoded),
|
|
3249
|
+
encoded,
|
|
3250
|
+
actor.slot,
|
|
3251
|
+
() => actor.ensureBound()
|
|
3252
|
+
);
|
|
3253
|
+
}
|
|
3254
|
+
requestForActor(actor, payload, messageType) {
|
|
3255
|
+
const encoded = this.encodePayload(payload, messageType);
|
|
3256
|
+
return new ZlinkStreamRequestBuilder(
|
|
3257
|
+
this,
|
|
3258
|
+
this.resolveNameOrDefault(encoded),
|
|
3259
|
+
encoded,
|
|
3260
|
+
actor.slot,
|
|
3261
|
+
() => actor.ensureBound()
|
|
3262
|
+
);
|
|
3263
|
+
}
|
|
3264
|
+
onActorMessage(actor, nameOrType, handler, messageType) {
|
|
3265
|
+
const encodedHandler = (message, signal) => {
|
|
3266
|
+
if (message[zlinkStreamActorBinding] !== actor) {
|
|
3267
|
+
return;
|
|
3268
|
+
}
|
|
3269
|
+
return handler(
|
|
3270
|
+
{
|
|
3271
|
+
name: message.name,
|
|
3272
|
+
metadata: message.metadata,
|
|
3273
|
+
payload: this.decodePayload(
|
|
3274
|
+
message.payload,
|
|
3275
|
+
messageType != null ? messageType : typeof nameOrType === "function" ? nameOrType : void 0
|
|
3276
|
+
),
|
|
3277
|
+
actorId: message.actorId
|
|
3278
|
+
},
|
|
3279
|
+
signal
|
|
3280
|
+
);
|
|
3281
|
+
};
|
|
3282
|
+
return this.receivedMessages.on(this.observedName(nameOrType), encodedHandler);
|
|
2908
3283
|
}
|
|
2909
3284
|
waitFor(nameOrType) {
|
|
2910
3285
|
return new ZlinkStreamWaitBuilder(this, this.observedName(nameOrType));
|
|
@@ -2924,7 +3299,10 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
2924
3299
|
observedName(nameOrType) {
|
|
2925
3300
|
const name = typeof nameOrType === "function" ? this.options.nameResolver.resolve(nameOrType) : nameOrType;
|
|
2926
3301
|
if (typeof name !== "string") {
|
|
2927
|
-
throw connectorError(
|
|
3302
|
+
throw connectorError(
|
|
3303
|
+
"validationFailed" /* ValidationFailed */,
|
|
3304
|
+
"Packet name must be a string or a payload constructor."
|
|
3305
|
+
);
|
|
2928
3306
|
}
|
|
2929
3307
|
validateName(name);
|
|
2930
3308
|
return name;
|
|
@@ -2944,7 +3322,10 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
2944
3322
|
waitForMessage(name, timeoutMs, predicate, signal) {
|
|
2945
3323
|
validateName(name);
|
|
2946
3324
|
if (!Number.isFinite(timeoutMs) || timeoutMs < 0) {
|
|
2947
|
-
throw connectorError(
|
|
3325
|
+
throw connectorError(
|
|
3326
|
+
"validationFailed" /* ValidationFailed */,
|
|
3327
|
+
"Timeout must be a non-negative finite number."
|
|
3328
|
+
);
|
|
2948
3329
|
}
|
|
2949
3330
|
throwIfAborted(signal);
|
|
2950
3331
|
return new Promise((resolve, reject) => {
|
|
@@ -2970,30 +3351,35 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
2970
3351
|
};
|
|
2971
3352
|
timer = setTimeout(() => finish(), timeoutMs);
|
|
2972
3353
|
signal == null ? void 0 : signal.addEventListener("abort", onAbort, { once: true });
|
|
2973
|
-
disposable = this.receivedMessages.observe(
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
try {
|
|
2978
|
-
const decoded = {
|
|
2979
|
-
name: message.name,
|
|
2980
|
-
metadata: message.metadata,
|
|
2981
|
-
payload: this.decodeWaitPayload(message.payload),
|
|
2982
|
-
flowId: message.flowId,
|
|
2983
|
-
flowOrigin: message.flowOrigin
|
|
2984
|
-
};
|
|
2985
|
-
if (!predicate(decoded)) {
|
|
3354
|
+
disposable = this.receivedMessages.observe(
|
|
3355
|
+
name,
|
|
3356
|
+
(message) => {
|
|
3357
|
+
if (done) {
|
|
2986
3358
|
return false;
|
|
2987
3359
|
}
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
3360
|
+
try {
|
|
3361
|
+
const decoded = {
|
|
3362
|
+
name: message.name,
|
|
3363
|
+
metadata: message.metadata,
|
|
3364
|
+
payload: this.decodeWaitPayload(message.payload),
|
|
3365
|
+
actorId: message.actorId
|
|
3366
|
+
};
|
|
3367
|
+
if (!predicate(decoded)) {
|
|
3368
|
+
return false;
|
|
3369
|
+
}
|
|
3370
|
+
finish(void 0, decoded);
|
|
3371
|
+
} catch (cause) {
|
|
3372
|
+
finish(cause);
|
|
3373
|
+
}
|
|
3374
|
+
return true;
|
|
3375
|
+
},
|
|
3376
|
+
() => finish(
|
|
3377
|
+
connectorError(
|
|
3378
|
+
"disconnected" /* Disconnected */,
|
|
3379
|
+
`The connection this wait for '${name}' observed has ended.`
|
|
3380
|
+
)
|
|
3381
|
+
)
|
|
3382
|
+
);
|
|
2997
3383
|
});
|
|
2998
3384
|
}
|
|
2999
3385
|
encodePayload(payload, messageType) {
|
|
@@ -3018,7 +3404,7 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
3018
3404
|
}
|
|
3019
3405
|
return payload;
|
|
3020
3406
|
}
|
|
3021
|
-
async sendEncoded(kind, name, payload, metadata, compress, requestSeq, signal,
|
|
3407
|
+
async sendEncoded(kind, name, payload, metadata, compress, requestSeq, signal, correlationId, actorSlot) {
|
|
3022
3408
|
await this.frameSender.send(
|
|
3023
3409
|
this.lifecycle.connectionForSend(),
|
|
3024
3410
|
kind,
|
|
@@ -3029,37 +3415,105 @@ var ZlinkStreamConnectorBundle = (() => {
|
|
|
3029
3415
|
requestSeq,
|
|
3030
3416
|
signal,
|
|
3031
3417
|
correlationId,
|
|
3032
|
-
|
|
3418
|
+
actorSlot
|
|
3033
3419
|
);
|
|
3034
3420
|
}
|
|
3035
3421
|
/**
|
|
3036
3422
|
* Per-connector monotonic correlation id (hex). The client generates it on each request
|
|
3037
|
-
* and the server echoes it back on the reply
|
|
3423
|
+
* and the server echoes it back on the reply.
|
|
3038
3424
|
*/
|
|
3039
3425
|
nextCorrelationId() {
|
|
3040
3426
|
this.correlationCounter += 1n;
|
|
3041
3427
|
return this.correlationCounter.toString(16);
|
|
3042
3428
|
}
|
|
3043
|
-
async requestEncoded(name, payload, metadata, compress, timeoutMs, signal,
|
|
3044
|
-
const
|
|
3429
|
+
async requestEncoded(name, payload, metadata, compress, timeoutMs, signal, actorSlot) {
|
|
3430
|
+
const startedAt = Date.now();
|
|
3431
|
+
const actorId = actorSlot === void 0 ? void 0 : this.boundActors.resolve(actorSlot).actorId;
|
|
3432
|
+
let requestMetadata = metadata;
|
|
3433
|
+
const sendingContext = {
|
|
3434
|
+
requestPacketName: name,
|
|
3435
|
+
actorId,
|
|
3436
|
+
setMetadata(key, value) {
|
|
3437
|
+
requestMetadata = requestMetadata.with(key, value);
|
|
3438
|
+
}
|
|
3439
|
+
};
|
|
3440
|
+
let pending;
|
|
3045
3441
|
try {
|
|
3442
|
+
throwIfAborted(signal);
|
|
3443
|
+
for (const handler of [...this.requestSendingHandlers]) {
|
|
3444
|
+
try {
|
|
3445
|
+
handler(sendingContext);
|
|
3446
|
+
} catch (cause) {
|
|
3447
|
+
queueMicrotask(() => {
|
|
3448
|
+
void this.events.publishError(
|
|
3449
|
+
toStreamError(
|
|
3450
|
+
cause,
|
|
3451
|
+
"userCallbackFailed" /* UserCallbackFailed */,
|
|
3452
|
+
"Request sending hook failed."
|
|
3453
|
+
),
|
|
3454
|
+
signal
|
|
3455
|
+
);
|
|
3456
|
+
});
|
|
3457
|
+
}
|
|
3458
|
+
}
|
|
3459
|
+
pending = this.pendingRequests.create(name, timeoutMs);
|
|
3046
3460
|
await this.sendEncoded(
|
|
3047
3461
|
2 /* Request */,
|
|
3048
3462
|
name,
|
|
3049
3463
|
payload,
|
|
3050
|
-
|
|
3464
|
+
requestMetadata,
|
|
3051
3465
|
compress,
|
|
3052
3466
|
pending.requestSeq,
|
|
3053
3467
|
signal,
|
|
3054
|
-
|
|
3055
|
-
|
|
3468
|
+
this.nextCorrelationId(),
|
|
3469
|
+
actorSlot
|
|
3056
3470
|
);
|
|
3057
|
-
|
|
3471
|
+
const reply = await pending.promise;
|
|
3472
|
+
this.publishReplyReceived(
|
|
3473
|
+
{
|
|
3474
|
+
requestPacketName: name,
|
|
3475
|
+
actorId,
|
|
3476
|
+
succeeded: true,
|
|
3477
|
+
reply: { ...reply, actorId },
|
|
3478
|
+
elapsed: Date.now() - startedAt
|
|
3479
|
+
},
|
|
3480
|
+
signal
|
|
3481
|
+
);
|
|
3482
|
+
return reply.payload;
|
|
3058
3483
|
} catch (error) {
|
|
3059
|
-
this.pendingRequests.cancel(pending.requestSeq);
|
|
3484
|
+
if (pending !== void 0) this.pendingRequests.cancel(pending.requestSeq);
|
|
3485
|
+
this.publishReplyReceived(
|
|
3486
|
+
{
|
|
3487
|
+
requestPacketName: name,
|
|
3488
|
+
actorId,
|
|
3489
|
+
succeeded: false,
|
|
3490
|
+
error: unwrapStreamError(error),
|
|
3491
|
+
elapsed: Date.now() - startedAt
|
|
3492
|
+
},
|
|
3493
|
+
signal
|
|
3494
|
+
);
|
|
3060
3495
|
throw error;
|
|
3061
3496
|
}
|
|
3062
3497
|
}
|
|
3498
|
+
publishReplyReceived(context, signal) {
|
|
3499
|
+
if (this.replyReceivedHandlers.size === 0) return;
|
|
3500
|
+
this.receivedMessages.enqueueCallback(async () => {
|
|
3501
|
+
for (const handler of [...this.replyReceivedHandlers]) {
|
|
3502
|
+
try {
|
|
3503
|
+
await handler(context, signal);
|
|
3504
|
+
} catch (cause) {
|
|
3505
|
+
await this.events.publishError(
|
|
3506
|
+
toStreamError(
|
|
3507
|
+
cause,
|
|
3508
|
+
"userCallbackFailed" /* UserCallbackFailed */,
|
|
3509
|
+
"Reply received hook failed."
|
|
3510
|
+
),
|
|
3511
|
+
signal
|
|
3512
|
+
);
|
|
3513
|
+
}
|
|
3514
|
+
}
|
|
3515
|
+
});
|
|
3516
|
+
}
|
|
3063
3517
|
resolveNameOrDefault(payload) {
|
|
3064
3518
|
if (payload.messageType === void 0) {
|
|
3065
3519
|
return void 0;
|