@zlink-systems/stream-connector 0.22.0 → 0.24.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 +504 -262
- package/dist/browser/index.mjs +504 -262
- package/package.json +2 -2
- package/dist/browser/Runtime/ZlinkFlowContext.d.ts +0 -15
- package/dist/browser/Runtime/ZlinkStreamDiagnosticsLevelCell.d.ts +0 -16
package/dist/browser/index.mjs
CHANGED
|
@@ -120,7 +120,8 @@ var defaultHeaderFlags = {
|
|
|
120
120
|
hasRequestSeq: 1,
|
|
121
121
|
hasMetadata: 2,
|
|
122
122
|
hasCorrelationId: 8,
|
|
123
|
-
hasFlowId: 16
|
|
123
|
+
hasFlowId: 16,
|
|
124
|
+
hasActorSlot: 32
|
|
124
125
|
};
|
|
125
126
|
var ZLINK_STREAM_FORMAT_MARKER = 242;
|
|
126
127
|
var ZLINK_STREAM_RESPONSE_KIND = 3;
|
|
@@ -167,6 +168,7 @@ function encodeStreamWireHeader(header, flagOverrides) {
|
|
|
167
168
|
}
|
|
168
169
|
const hasCorrelation = correlationBytes !== void 0;
|
|
169
170
|
const hasFlow = header.flowId !== void 0 || header.flowOrigin !== void 0;
|
|
171
|
+
const hasActorSlot = header.actorSlot !== void 0;
|
|
170
172
|
if (hasFlow && (header.flowId === void 0 || header.flowOrigin === void 0)) {
|
|
171
173
|
throw new Error("Stream flow id and origin must be provided together.");
|
|
172
174
|
}
|
|
@@ -174,13 +176,17 @@ function encodeStreamWireHeader(header, flagOverrides) {
|
|
|
174
176
|
if (header.flowOrigin !== void 0 && ![1, 2, 3, 4].includes(header.flowOrigin)) {
|
|
175
177
|
throw new Error("Stream flow origin is invalid.");
|
|
176
178
|
}
|
|
179
|
+
if (header.actorSlot !== void 0 && (!Number.isInteger(header.actorSlot) || header.actorSlot < 1 || header.actorSlot > 65535)) {
|
|
180
|
+
throw new Error("Stream actor slot is invalid.");
|
|
181
|
+
}
|
|
177
182
|
let headerFlags = header.flags;
|
|
178
183
|
headerFlags = hasRequestSeq ? headerFlags | flags.hasRequestSeq : headerFlags & ~flags.hasRequestSeq;
|
|
179
184
|
headerFlags = hasMetadata ? headerFlags | flags.hasMetadata : headerFlags & ~flags.hasMetadata;
|
|
180
185
|
headerFlags = hasCorrelation ? headerFlags | flags.hasCorrelationId : headerFlags & ~flags.hasCorrelationId;
|
|
181
186
|
headerFlags = hasFlow ? headerFlags | flags.hasFlowId : headerFlags & ~flags.hasFlowId;
|
|
187
|
+
headerFlags = hasActorSlot ? headerFlags | flags.hasActorSlot : headerFlags & ~flags.hasActorSlot;
|
|
182
188
|
const metadataBytes = hasMetadata ? encodeStreamWireMetadata(header.metadata) : new Uint8Array();
|
|
183
|
-
const size = 4 + (hasRequestSeq ? 8 : 0) + 1 + nameBytes.length + (hasMetadata ? 2 + metadataBytes.length : 0) + (hasCorrelation ? 1 + correlationBytes.length : 0) + (hasFlow ? 37 : 0);
|
|
189
|
+
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);
|
|
184
190
|
const buffer = new Uint8Array(size);
|
|
185
191
|
let offset = 0;
|
|
186
192
|
buffer[offset++] = ZLINK_STREAM_FORMAT_MARKER;
|
|
@@ -213,6 +219,9 @@ function encodeStreamWireHeader(header, flagOverrides) {
|
|
|
213
219
|
offset += 36;
|
|
214
220
|
buffer[offset++] = header.flowOrigin;
|
|
215
221
|
}
|
|
222
|
+
if (hasActorSlot) {
|
|
223
|
+
writeUInt16BE(buffer, offset, header.actorSlot);
|
|
224
|
+
}
|
|
216
225
|
return buffer;
|
|
217
226
|
}
|
|
218
227
|
function decodeStreamWireHeader(header, flagOverrides, includeFlow = true) {
|
|
@@ -231,7 +240,8 @@ function decodeStreamWireHeader(header, flagOverrides, includeFlow = true) {
|
|
|
231
240
|
const hasMetadata = (headerFlags & flags.hasMetadata) !== 0;
|
|
232
241
|
const hasCorrelation = (headerFlags & flags.hasCorrelationId) !== 0;
|
|
233
242
|
const hasFlow = (headerFlags & flags.hasFlowId) !== 0;
|
|
234
|
-
|
|
243
|
+
const hasActorSlot = (headerFlags & flags.hasActorSlot) !== 0;
|
|
244
|
+
if ((headerFlags & ~63) !== 0) {
|
|
235
245
|
throw new Error("Unknown mandatory stream header flag.");
|
|
236
246
|
}
|
|
237
247
|
let requestSeq;
|
|
@@ -286,6 +296,17 @@ function decodeStreamWireHeader(header, flagOverrides, includeFlow = true) {
|
|
|
286
296
|
}
|
|
287
297
|
flowOrigin = includeFlow ? decodedFlowOrigin : void 0;
|
|
288
298
|
}
|
|
299
|
+
let actorSlot;
|
|
300
|
+
if (hasActorSlot) {
|
|
301
|
+
if (header.length - offset < 2) {
|
|
302
|
+
throw new Error("Stream actor slot is incomplete.");
|
|
303
|
+
}
|
|
304
|
+
actorSlot = readUInt16BE(header, offset);
|
|
305
|
+
if (actorSlot === 0) {
|
|
306
|
+
throw new Error("Stream actor slot must not be zero.");
|
|
307
|
+
}
|
|
308
|
+
offset += 2;
|
|
309
|
+
}
|
|
289
310
|
if (offset !== header.length) {
|
|
290
311
|
throw new Error("Stream header has trailing bytes.");
|
|
291
312
|
}
|
|
@@ -298,7 +319,8 @@ function decodeStreamWireHeader(header, flagOverrides, includeFlow = true) {
|
|
|
298
319
|
metadata: decodedMetadata.metadata,
|
|
299
320
|
correlationId,
|
|
300
321
|
flowId,
|
|
301
|
-
flowOrigin
|
|
322
|
+
flowOrigin,
|
|
323
|
+
actorSlot
|
|
302
324
|
};
|
|
303
325
|
}
|
|
304
326
|
function validateFlowId(flowId) {
|
|
@@ -464,13 +486,6 @@ var ZlinkStreamDispatchMode = /* @__PURE__ */ ((ZlinkStreamDispatchMode2) => {
|
|
|
464
486
|
ZlinkStreamDispatchMode2["Immediate"] = "immediate";
|
|
465
487
|
return ZlinkStreamDispatchMode2;
|
|
466
488
|
})(ZlinkStreamDispatchMode || {});
|
|
467
|
-
var ZlinkStreamDiagnosticsLevel = /* @__PURE__ */ ((ZlinkStreamDiagnosticsLevel4) => {
|
|
468
|
-
ZlinkStreamDiagnosticsLevel4["Off"] = "off";
|
|
469
|
-
ZlinkStreamDiagnosticsLevel4["Errors"] = "errors";
|
|
470
|
-
ZlinkStreamDiagnosticsLevel4["Normal"] = "normal";
|
|
471
|
-
ZlinkStreamDiagnosticsLevel4["Detailed"] = "detailed";
|
|
472
|
-
return ZlinkStreamDiagnosticsLevel4;
|
|
473
|
-
})(ZlinkStreamDiagnosticsLevel || {});
|
|
474
489
|
var ZlinkStreamMessageKind = /* @__PURE__ */ ((ZlinkStreamMessageKind2) => {
|
|
475
490
|
ZlinkStreamMessageKind2[ZlinkStreamMessageKind2["Send"] = 1] = "Send";
|
|
476
491
|
ZlinkStreamMessageKind2[ZlinkStreamMessageKind2["Request"] = 2] = "Request";
|
|
@@ -486,6 +501,7 @@ var ZlinkStreamHeaderFlags = /* @__PURE__ */ ((ZlinkStreamHeaderFlags2) => {
|
|
|
486
501
|
ZlinkStreamHeaderFlags2[ZlinkStreamHeaderFlags2["PayloadCompressed"] = 4] = "PayloadCompressed";
|
|
487
502
|
ZlinkStreamHeaderFlags2[ZlinkStreamHeaderFlags2["HasCorrelationId"] = 8] = "HasCorrelationId";
|
|
488
503
|
ZlinkStreamHeaderFlags2[ZlinkStreamHeaderFlags2["HasFlowId"] = 16] = "HasFlowId";
|
|
504
|
+
ZlinkStreamHeaderFlags2[ZlinkStreamHeaderFlags2["HasActorSlot"] = 32] = "HasActorSlot";
|
|
489
505
|
return ZlinkStreamHeaderFlags2;
|
|
490
506
|
})(ZlinkStreamHeaderFlags || {});
|
|
491
507
|
var ZlinkStreamErrorCode = /* @__PURE__ */ ((ZlinkStreamErrorCode2) => {
|
|
@@ -734,15 +750,16 @@ function validateName(name, allowReserved = false) {
|
|
|
734
750
|
|
|
735
751
|
// packages/stream-connector/src/Runtime/Calls/ZlinkStreamCallBuilders.ts
|
|
736
752
|
var ZlinkStreamCallBuilderState = class {
|
|
753
|
+
constructor(name, actorSlot, validateActor) {
|
|
754
|
+
this.actorSlot = actorSlot;
|
|
755
|
+
this.validateActor = validateActor;
|
|
756
|
+
this.name = name;
|
|
757
|
+
}
|
|
737
758
|
executed = false;
|
|
738
759
|
name;
|
|
739
760
|
metadata = ZlinkStreamMetadataMap.empty;
|
|
740
761
|
timeoutMs;
|
|
741
762
|
compress = false;
|
|
742
|
-
flow;
|
|
743
|
-
constructor(name) {
|
|
744
|
-
this.name = name;
|
|
745
|
-
}
|
|
746
763
|
ensureNotExecuted() {
|
|
747
764
|
if (this.executed) {
|
|
748
765
|
throw connectorError(
|
|
@@ -751,6 +768,7 @@ var ZlinkStreamCallBuilderState = class {
|
|
|
751
768
|
);
|
|
752
769
|
}
|
|
753
770
|
this.executed = true;
|
|
771
|
+
this.validateActor?.();
|
|
754
772
|
}
|
|
755
773
|
resolveMessageName() {
|
|
756
774
|
if (this.name === void 0) {
|
|
@@ -763,10 +781,10 @@ var ZlinkStreamCallBuilderState = class {
|
|
|
763
781
|
}
|
|
764
782
|
};
|
|
765
783
|
var ZlinkStreamSendBuilder = class {
|
|
766
|
-
constructor(connector, name, payload) {
|
|
784
|
+
constructor(connector, name, payload, actorSlot, validateActor) {
|
|
767
785
|
this.connector = connector;
|
|
768
786
|
this.payload = payload;
|
|
769
|
-
this.state = new ZlinkStreamCallBuilderState(name);
|
|
787
|
+
this.state = new ZlinkStreamCallBuilderState(name, actorSlot, validateActor);
|
|
770
788
|
}
|
|
771
789
|
state;
|
|
772
790
|
packetName(name) {
|
|
@@ -782,10 +800,6 @@ var ZlinkStreamSendBuilder = class {
|
|
|
782
800
|
this.state.compress = true;
|
|
783
801
|
return this;
|
|
784
802
|
}
|
|
785
|
-
flowFrom(flow) {
|
|
786
|
-
this.state.flow = flow;
|
|
787
|
-
return this;
|
|
788
|
-
}
|
|
789
803
|
async submit(signal) {
|
|
790
804
|
throwIfAborted(signal);
|
|
791
805
|
this.state.ensureNotExecuted();
|
|
@@ -797,15 +811,16 @@ var ZlinkStreamSendBuilder = class {
|
|
|
797
811
|
this.state.compress,
|
|
798
812
|
void 0,
|
|
799
813
|
signal,
|
|
800
|
-
|
|
814
|
+
void 0,
|
|
815
|
+
this.state.actorSlot
|
|
801
816
|
);
|
|
802
817
|
}
|
|
803
818
|
};
|
|
804
819
|
var ZlinkStreamRequestBuilder = class {
|
|
805
|
-
constructor(connector, name, payload) {
|
|
820
|
+
constructor(connector, name, payload, actorSlot, validateActor) {
|
|
806
821
|
this.connector = connector;
|
|
807
822
|
this.payload = payload;
|
|
808
|
-
this.state = new ZlinkStreamCallBuilderState(name);
|
|
823
|
+
this.state = new ZlinkStreamCallBuilderState(name, actorSlot, validateActor);
|
|
809
824
|
}
|
|
810
825
|
state;
|
|
811
826
|
packetName(name) {
|
|
@@ -825,10 +840,6 @@ var ZlinkStreamRequestBuilder = class {
|
|
|
825
840
|
this.state.compress = true;
|
|
826
841
|
return this;
|
|
827
842
|
}
|
|
828
|
-
flowFrom(flow) {
|
|
829
|
-
this.state.flow = flow;
|
|
830
|
-
return this;
|
|
831
|
-
}
|
|
832
843
|
submit(signalOrCallback) {
|
|
833
844
|
this.state.ensureNotExecuted();
|
|
834
845
|
const operation = this.connector.requestEncoded(
|
|
@@ -838,7 +849,7 @@ var ZlinkStreamRequestBuilder = class {
|
|
|
838
849
|
this.state.compress,
|
|
839
850
|
this.state.timeoutMs ?? this.connector.options.requestTimeoutMs,
|
|
840
851
|
typeof signalOrCallback === "function" ? void 0 : signalOrCallback,
|
|
841
|
-
this.state.
|
|
852
|
+
this.state.actorSlot
|
|
842
853
|
);
|
|
843
854
|
if (typeof signalOrCallback === "function") {
|
|
844
855
|
operation.then(
|
|
@@ -860,7 +871,7 @@ var ZlinkStreamRequestBuilder = class {
|
|
|
860
871
|
this.state.compress,
|
|
861
872
|
this.state.timeoutMs ?? this.connector.options.requestTimeoutMs,
|
|
862
873
|
signal,
|
|
863
|
-
this.state.
|
|
874
|
+
this.state.actorSlot
|
|
864
875
|
);
|
|
865
876
|
}
|
|
866
877
|
};
|
|
@@ -1216,8 +1227,7 @@ var ZlinkStreamHeaderCodec = class {
|
|
|
1216
1227
|
name: header.name,
|
|
1217
1228
|
metadata: header.metadata.values,
|
|
1218
1229
|
correlationId: header.correlationId,
|
|
1219
|
-
|
|
1220
|
-
flowOrigin: encodeFlowOrigin(header.flowOrigin)
|
|
1230
|
+
actorSlot: header.actorSlot
|
|
1221
1231
|
});
|
|
1222
1232
|
} catch (cause) {
|
|
1223
1233
|
throw connectorError(
|
|
@@ -1227,15 +1237,10 @@ var ZlinkStreamHeaderCodec = class {
|
|
|
1227
1237
|
);
|
|
1228
1238
|
}
|
|
1229
1239
|
}
|
|
1230
|
-
|
|
1231
|
-
* `includeFlow=false` (diagnostics Off, spec 27 §4) skips reading and
|
|
1232
|
-
* validating the inbound flow fields while the structural length checks in
|
|
1233
|
-
* the wire decoder are preserved.
|
|
1234
|
-
*/
|
|
1235
|
-
static decode(header, includeFlow = true) {
|
|
1240
|
+
static decode(header) {
|
|
1236
1241
|
let decoded;
|
|
1237
1242
|
try {
|
|
1238
|
-
const wire = decodeStreamWireHeader(header, void 0,
|
|
1243
|
+
const wire = decodeStreamWireHeader(header, void 0, false);
|
|
1239
1244
|
const metadata = wire.metadata.size === 0 ? ZlinkStreamMetadataMap.empty : ZlinkStreamMetadataMap.from(wire.metadata);
|
|
1240
1245
|
decoded = {
|
|
1241
1246
|
kind: wire.kind,
|
|
@@ -1245,8 +1250,7 @@ var ZlinkStreamHeaderCodec = class {
|
|
|
1245
1250
|
name: wire.name,
|
|
1246
1251
|
metadata,
|
|
1247
1252
|
correlationId: wire.correlationId,
|
|
1248
|
-
|
|
1249
|
-
flowOrigin: decodeFlowOrigin(wire.flowOrigin)
|
|
1253
|
+
actorSlot: wire.actorSlot
|
|
1250
1254
|
};
|
|
1251
1255
|
} catch (cause) {
|
|
1252
1256
|
throw connectorError(
|
|
@@ -1269,7 +1273,7 @@ function isReplyKind2(kind) {
|
|
|
1269
1273
|
function streamWireErrorMessage2(cause) {
|
|
1270
1274
|
return cause instanceof Error ? cause.message : "Stream header is invalid.";
|
|
1271
1275
|
}
|
|
1272
|
-
function buildHeader(kind, name, codec, metadata, compress, requestSeq, correlationId,
|
|
1276
|
+
function buildHeader(kind, name, codec, metadata, compress, requestSeq, correlationId, actorSlot) {
|
|
1273
1277
|
let flags = 0 /* None */;
|
|
1274
1278
|
if (requestSeq !== void 0) {
|
|
1275
1279
|
flags |= 1 /* HasRequestSeq */;
|
|
@@ -1283,8 +1287,17 @@ function buildHeader(kind, name, codec, metadata, compress, requestSeq, correlat
|
|
|
1283
1287
|
if (correlationId !== void 0 && correlationId.length > 0) {
|
|
1284
1288
|
flags |= 8 /* HasCorrelationId */;
|
|
1285
1289
|
}
|
|
1286
|
-
if (
|
|
1287
|
-
return {
|
|
1290
|
+
if (actorSlot !== void 0) flags |= 32 /* HasActorSlot */;
|
|
1291
|
+
return {
|
|
1292
|
+
kind,
|
|
1293
|
+
codec,
|
|
1294
|
+
flags,
|
|
1295
|
+
requestSeq,
|
|
1296
|
+
name,
|
|
1297
|
+
metadata,
|
|
1298
|
+
correlationId,
|
|
1299
|
+
actorSlot
|
|
1300
|
+
};
|
|
1288
1301
|
}
|
|
1289
1302
|
function validateHeaderSemantics(header) {
|
|
1290
1303
|
validateEnum(header.kind, header.codec, header.flags);
|
|
@@ -1310,8 +1323,9 @@ function validateHeaderSemantics(header) {
|
|
|
1310
1323
|
}
|
|
1311
1324
|
if (header.kind === 5 /* Control */) {
|
|
1312
1325
|
const hasCorrelation = header.correlationId !== void 0 && header.correlationId.length > 0 || (header.flags & 8 /* HasCorrelationId */) !== 0;
|
|
1313
|
-
const hasFlow =
|
|
1314
|
-
|
|
1326
|
+
const hasFlow = (header.flags & 16 /* HasFlowId */) !== 0;
|
|
1327
|
+
const hasActorSlot = header.actorSlot !== void 0 || (header.flags & 32 /* HasActorSlot */) !== 0;
|
|
1328
|
+
if (header.flags !== 0 /* None */ || hasRequestSeq || hasMetadata || hasCorrelation || hasFlow || hasActorSlot || header.codec !== 0 /* Raw */) {
|
|
1315
1329
|
throw connectorError(
|
|
1316
1330
|
"frameDecodeFailed" /* FrameDecodeFailed */,
|
|
1317
1331
|
"Control packet must use raw codec and must not contain flags."
|
|
@@ -1326,17 +1340,11 @@ function validateEnum(kind, codec, flags) {
|
|
|
1326
1340
|
if (![0, 1, 2, 3].includes(codec)) {
|
|
1327
1341
|
throw connectorError("frameDecodeFailed" /* FrameDecodeFailed */, "Unknown stream codec.");
|
|
1328
1342
|
}
|
|
1329
|
-
const known = 1 /* HasRequestSeq */ | 2 /* HasMetadata */ | 4 /* PayloadCompressed */ | 8 /* HasCorrelationId */ | 16 /* HasFlowId */;
|
|
1343
|
+
const known = 1 /* HasRequestSeq */ | 2 /* HasMetadata */ | 4 /* PayloadCompressed */ | 8 /* HasCorrelationId */ | 16 /* HasFlowId */ | 32 /* HasActorSlot */;
|
|
1330
1344
|
if ((flags & ~known) !== 0) {
|
|
1331
1345
|
throw connectorError("frameDecodeFailed" /* FrameDecodeFailed */, "Unknown stream header flag.");
|
|
1332
1346
|
}
|
|
1333
1347
|
}
|
|
1334
|
-
function encodeFlowOrigin(origin) {
|
|
1335
|
-
return origin === void 0 ? void 0 : { Inbound: 1, Timer: 2, Application: 3, Lifecycle: 4 }[origin];
|
|
1336
|
-
}
|
|
1337
|
-
function decodeFlowOrigin(origin) {
|
|
1338
|
-
return origin === void 0 ? void 0 : { 1: "Inbound", 2: "Timer", 3: "Application", 4: "Lifecycle" }[origin];
|
|
1339
|
-
}
|
|
1340
1348
|
|
|
1341
1349
|
// packages/stream-connector/src/Runtime/Protocol/ZlinkStreamFrameProtocol.ts
|
|
1342
1350
|
var ZLINK_STREAM_HEARTBEAT_PING = "$zlink.heartbeat.ping";
|
|
@@ -1345,7 +1353,7 @@ var ZlinkStreamFrameProtocol = class {
|
|
|
1345
1353
|
constructor(options) {
|
|
1346
1354
|
this.options = options;
|
|
1347
1355
|
}
|
|
1348
|
-
encode(kind, name, payload, metadata, compress, requestSeq, correlationId,
|
|
1356
|
+
encode(kind, name, payload, metadata, compress, requestSeq, correlationId, actorSlot) {
|
|
1349
1357
|
const payloadBytes = compress ? compressPayload(payload.payload, this.options.compression, this.options.compressionCodec) : payload.payload;
|
|
1350
1358
|
const header = buildHeader(
|
|
1351
1359
|
kind,
|
|
@@ -1355,8 +1363,7 @@ var ZlinkStreamFrameProtocol = class {
|
|
|
1355
1363
|
compress,
|
|
1356
1364
|
requestSeq,
|
|
1357
1365
|
correlationId,
|
|
1358
|
-
|
|
1359
|
-
flowOrigin
|
|
1366
|
+
actorSlot
|
|
1360
1367
|
);
|
|
1361
1368
|
return this.encodeFrame(header, payloadBytes);
|
|
1362
1369
|
}
|
|
@@ -1372,21 +1379,16 @@ var ZlinkStreamFrameProtocol = class {
|
|
|
1372
1379
|
payload
|
|
1373
1380
|
);
|
|
1374
1381
|
}
|
|
1375
|
-
decode(frameBytes
|
|
1382
|
+
decode(frameBytes) {
|
|
1376
1383
|
const frame = ZlinkStreamFrameCodec.decode(frameBytes);
|
|
1377
1384
|
return {
|
|
1378
|
-
|
|
1379
|
-
// read nor validated (structural length checks are preserved).
|
|
1380
|
-
header: ZlinkStreamHeaderCodec.decode(frame.header, flowEnabled),
|
|
1385
|
+
header: ZlinkStreamHeaderCodec.decode(frame.header),
|
|
1381
1386
|
payload: frame.payload
|
|
1382
1387
|
};
|
|
1383
1388
|
}
|
|
1384
|
-
|
|
1385
|
-
return this.options.diagnosticsLevel !== "off" /* Off */;
|
|
1386
|
-
}
|
|
1387
|
-
decodeFrames(chunk, flowEnabled = this.flowEnabled()) {
|
|
1389
|
+
decodeFrames(chunk) {
|
|
1388
1390
|
return splitZlinkStreamFrames(chunk).map((frame) => {
|
|
1389
|
-
const decoded = this.decode(frame
|
|
1391
|
+
const decoded = this.decode(frame);
|
|
1390
1392
|
if (decoded.payload.length > this.options.maxReceivePayloadSize) {
|
|
1391
1393
|
throw connectorError(
|
|
1392
1394
|
"frameTooLarge" /* FrameTooLarge */,
|
|
@@ -1438,12 +1440,6 @@ function parseEndpoint(endpoint) {
|
|
|
1438
1440
|
}
|
|
1439
1441
|
|
|
1440
1442
|
// packages/stream-connector/src/Runtime/ZlinkStreamConnectorOptions.ts
|
|
1441
|
-
var validDiagnosticsLevels = /* @__PURE__ */ new Set([
|
|
1442
|
-
"off" /* Off */,
|
|
1443
|
-
"errors" /* Errors */,
|
|
1444
|
-
"normal" /* Normal */,
|
|
1445
|
-
"detailed" /* Detailed */
|
|
1446
|
-
]);
|
|
1447
1443
|
function normalizeOptions(options, defaultTransportFactory) {
|
|
1448
1444
|
const endpoint = options.endpoint;
|
|
1449
1445
|
if (endpoint.trim().length === 0) {
|
|
@@ -1463,7 +1459,6 @@ function normalizeOptions(options, defaultTransportFactory) {
|
|
|
1463
1459
|
validatePositive(options.maxReceivePayloadSize ?? 64 * 1024, "MaxReceivePayloadSize");
|
|
1464
1460
|
validateHeartbeat(options.heartbeat);
|
|
1465
1461
|
validateReconnect(options.reconnect);
|
|
1466
|
-
validateDiagnosticsLevel(options.diagnosticsLevel);
|
|
1467
1462
|
return {
|
|
1468
1463
|
endpoint,
|
|
1469
1464
|
transport: inferredTransport,
|
|
@@ -1489,10 +1484,7 @@ function normalizeOptions(options, defaultTransportFactory) {
|
|
|
1489
1484
|
compressionCodec: resolveCompressionCodec2(options),
|
|
1490
1485
|
nameResolver: options.nameResolver ?? defaultPacketNameResolver,
|
|
1491
1486
|
transportFactory: options.transportFactory ?? defaultTransportFactory,
|
|
1492
|
-
codec: options.codec
|
|
1493
|
-
// Spec 26 §4: the default diagnostics level is Errors, which preserves
|
|
1494
|
-
// the connector's established wire behavior.
|
|
1495
|
-
diagnosticsLevel: options.diagnosticsLevel ?? "errors" /* Errors */
|
|
1487
|
+
codec: options.codec
|
|
1496
1488
|
};
|
|
1497
1489
|
}
|
|
1498
1490
|
var defaultPacketNameResolver = {
|
|
@@ -1517,11 +1509,6 @@ function resolveCompressionCodec2(options) {
|
|
|
1517
1509
|
}
|
|
1518
1510
|
return options.compressionCodec;
|
|
1519
1511
|
}
|
|
1520
|
-
function validateDiagnosticsLevel(level) {
|
|
1521
|
-
if (level !== void 0 && !validDiagnosticsLevels.has(level)) {
|
|
1522
|
-
throw connectorError("configurationError" /* ConfigurationError */, "DiagnosticsLevel is invalid.");
|
|
1523
|
-
}
|
|
1524
|
-
}
|
|
1525
1512
|
function validatePositive(value, name) {
|
|
1526
1513
|
if (value <= 0) {
|
|
1527
1514
|
throw connectorError("validationFailed" /* ValidationFailed */, `${name} must be positive.`);
|
|
@@ -1565,25 +1552,6 @@ function validateReconnect(options) {
|
|
|
1565
1552
|
}
|
|
1566
1553
|
}
|
|
1567
1554
|
|
|
1568
|
-
// packages/stream-connector/src/Runtime/ZlinkStreamDiagnosticsLevelCell.ts
|
|
1569
|
-
var ZlinkStreamDiagnosticsLevelCell = class {
|
|
1570
|
-
current;
|
|
1571
|
-
constructor(initial) {
|
|
1572
|
-
this.current = initial;
|
|
1573
|
-
}
|
|
1574
|
-
get level() {
|
|
1575
|
-
return this.current;
|
|
1576
|
-
}
|
|
1577
|
-
set(level) {
|
|
1578
|
-
const candidate = level;
|
|
1579
|
-
if (candidate === void 0 || candidate === null) {
|
|
1580
|
-
throw connectorError("configurationError" /* ConfigurationError */, "DiagnosticsLevel is invalid.");
|
|
1581
|
-
}
|
|
1582
|
-
validateDiagnosticsLevel(level);
|
|
1583
|
-
this.current = level;
|
|
1584
|
-
}
|
|
1585
|
-
};
|
|
1586
|
-
|
|
1587
1555
|
// packages/stream-connector/src/Runtime/ZlinkStreamPendingRequests.ts
|
|
1588
1556
|
var ZlinkStreamPendingRequests = class {
|
|
1589
1557
|
nextRequestSeq = 1n;
|
|
@@ -1596,16 +1564,21 @@ var ZlinkStreamPendingRequests = class {
|
|
|
1596
1564
|
let timeout;
|
|
1597
1565
|
let resolvePending;
|
|
1598
1566
|
let rejectPending;
|
|
1599
|
-
const promise = new Promise(
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1567
|
+
const promise = new Promise(
|
|
1568
|
+
(resolve, reject) => {
|
|
1569
|
+
timeout = setTimeout(() => {
|
|
1570
|
+
this.active.delete(requestSeq);
|
|
1571
|
+
reject(
|
|
1572
|
+
connectorError(
|
|
1573
|
+
"requestTimeout" /* RequestTimeout */,
|
|
1574
|
+
`Request '${packetName}' timed out.`
|
|
1575
|
+
)
|
|
1576
|
+
);
|
|
1577
|
+
}, timeoutMs);
|
|
1578
|
+
resolvePending = resolve;
|
|
1579
|
+
rejectPending = (error) => reject(connectorError(error.code, error.message, error.cause));
|
|
1580
|
+
}
|
|
1581
|
+
);
|
|
1609
1582
|
this.active.set(requestSeq, {
|
|
1610
1583
|
packetName,
|
|
1611
1584
|
promise,
|
|
@@ -1629,15 +1602,14 @@ var ZlinkStreamPendingRequests = class {
|
|
|
1629
1602
|
});
|
|
1630
1603
|
return { requestSeq, promise };
|
|
1631
1604
|
}
|
|
1632
|
-
/* stream connector spec §5.2: a pending request is matched by request_seq alone.
|
|
1633
|
-
|
|
1634
|
-
resolve(requestSeq, value) {
|
|
1605
|
+
/* stream connector spec §5.2: a pending request is matched by request_seq alone. */
|
|
1606
|
+
resolve(requestSeq, value, metadata) {
|
|
1635
1607
|
const pending = this.active.get(requestSeq);
|
|
1636
1608
|
if (pending === void 0) {
|
|
1637
1609
|
return false;
|
|
1638
1610
|
}
|
|
1639
1611
|
this.active.delete(requestSeq);
|
|
1640
|
-
pending.resolve(value);
|
|
1612
|
+
pending.resolve({ name: pending.packetName, metadata, payload: value });
|
|
1641
1613
|
return true;
|
|
1642
1614
|
}
|
|
1643
1615
|
reject(requestSeq, error) {
|
|
@@ -1773,9 +1745,11 @@ var ZlinkStreamReceivedMessages = class {
|
|
|
1773
1745
|
*/
|
|
1774
1746
|
resetForNewConnection() {
|
|
1775
1747
|
this.receivedCounts.clear();
|
|
1748
|
+
const submittedCallbacks = this.queue.slice(this.queueHead).filter((item) => item?.kind === "callback");
|
|
1776
1749
|
this.queue.length = 0;
|
|
1750
|
+
this.queue.push(...submittedCallbacks);
|
|
1777
1751
|
this.queueHead = 0;
|
|
1778
|
-
this.queuedCount =
|
|
1752
|
+
this.queuedCount = submittedCallbacks.length;
|
|
1779
1753
|
}
|
|
1780
1754
|
/**
|
|
1781
1755
|
* Releases every registered wait surface because the connection it was
|
|
@@ -1791,7 +1765,7 @@ var ZlinkStreamReceivedMessages = class {
|
|
|
1791
1765
|
if (this.observers.size === 0) {
|
|
1792
1766
|
return;
|
|
1793
1767
|
}
|
|
1794
|
-
const abandoned =
|
|
1768
|
+
const abandoned = Array.from(this.observers.values()).flatMap((set) => Array.from(set));
|
|
1795
1769
|
this.observers.clear();
|
|
1796
1770
|
for (const registration of abandoned) {
|
|
1797
1771
|
registration.onConnectionEnded();
|
|
@@ -1799,12 +1773,19 @@ var ZlinkStreamReceivedMessages = class {
|
|
|
1799
1773
|
}
|
|
1800
1774
|
enqueue(message, signal) {
|
|
1801
1775
|
this.receivedCounts.set(message.name, (this.receivedCounts.get(message.name) ?? 0) + 1);
|
|
1802
|
-
for (const registration of
|
|
1776
|
+
for (const registration of Array.from(this.observers.get(message.name) ?? [])) {
|
|
1803
1777
|
if (registration.consume(message)) {
|
|
1804
1778
|
return;
|
|
1805
1779
|
}
|
|
1806
1780
|
}
|
|
1807
|
-
this.queue.push({ message, signal });
|
|
1781
|
+
this.queue.push({ kind: "message", message, signal });
|
|
1782
|
+
this.queuedCount += 1;
|
|
1783
|
+
if (this.deliverOnArrival) {
|
|
1784
|
+
this.scheduleDrain();
|
|
1785
|
+
}
|
|
1786
|
+
}
|
|
1787
|
+
enqueueCallback(callback) {
|
|
1788
|
+
this.queue.push({ kind: "callback", callback });
|
|
1808
1789
|
this.queuedCount += 1;
|
|
1809
1790
|
if (this.deliverOnArrival) {
|
|
1810
1791
|
this.scheduleDrain();
|
|
@@ -1831,7 +1812,7 @@ var ZlinkStreamReceivedMessages = class {
|
|
|
1831
1812
|
offerQueued(name, registration) {
|
|
1832
1813
|
for (let index = this.queueHead; index < this.queue.length; index += 1) {
|
|
1833
1814
|
const queued = this.queue[index];
|
|
1834
|
-
if (queued === void 0 || queued.message.name !== name) {
|
|
1815
|
+
if (queued === void 0 || queued.kind !== "message" || queued.message.name !== name) {
|
|
1835
1816
|
continue;
|
|
1836
1817
|
}
|
|
1837
1818
|
if (!registration.consume(queued.message)) {
|
|
@@ -1859,8 +1840,12 @@ var ZlinkStreamReceivedMessages = class {
|
|
|
1859
1840
|
const queued = this.queue[index];
|
|
1860
1841
|
if (queued === void 0) continue;
|
|
1861
1842
|
this.removeAt(index);
|
|
1843
|
+
if (queued.kind === "callback") {
|
|
1844
|
+
await queued.callback();
|
|
1845
|
+
continue;
|
|
1846
|
+
}
|
|
1862
1847
|
const { message, signal } = queued;
|
|
1863
|
-
const handlers =
|
|
1848
|
+
const handlers = Array.from(this.handlers.get(message.name));
|
|
1864
1849
|
for (const handler of handlers) {
|
|
1865
1850
|
try {
|
|
1866
1851
|
await handler(message, signal);
|
|
@@ -1889,7 +1874,7 @@ var ZlinkStreamReceivedMessages = class {
|
|
|
1889
1874
|
findDeliverableIndex() {
|
|
1890
1875
|
for (let index = this.queueHead; index < this.queue.length; index += 1) {
|
|
1891
1876
|
const queued = this.queue[index];
|
|
1892
|
-
if (queued !== void 0 && (this.handlers.get(queued.message.name)?.size ?? 0) > 0) {
|
|
1877
|
+
if (queued !== void 0 && (queued.kind === "callback" || (this.handlers.get(queued.message.name)?.size ?? 0) > 0)) {
|
|
1893
1878
|
return index;
|
|
1894
1879
|
}
|
|
1895
1880
|
}
|
|
@@ -1897,7 +1882,8 @@ var ZlinkStreamReceivedMessages = class {
|
|
|
1897
1882
|
}
|
|
1898
1883
|
hasQueuedMessage(name) {
|
|
1899
1884
|
for (let index = this.queueHead; index < this.queue.length; index += 1) {
|
|
1900
|
-
|
|
1885
|
+
const queued = this.queue[index];
|
|
1886
|
+
if (queued?.kind === "message" && queued.message.name === name) return true;
|
|
1901
1887
|
}
|
|
1902
1888
|
return false;
|
|
1903
1889
|
}
|
|
@@ -1921,14 +1907,12 @@ var ZlinkStreamReceivedMessages = class {
|
|
|
1921
1907
|
|
|
1922
1908
|
// packages/stream-connector/src/Runtime/ZlinkStreamFrameSender.ts
|
|
1923
1909
|
var ZlinkStreamFrameSender = class {
|
|
1924
|
-
constructor(protocol
|
|
1910
|
+
constructor(protocol) {
|
|
1925
1911
|
this.protocol = protocol;
|
|
1926
|
-
this.flowContext = flowContext;
|
|
1927
1912
|
}
|
|
1928
1913
|
pendingWrites = /* @__PURE__ */ new Set();
|
|
1929
|
-
async send(connection, kind, name, payload, metadata, compress, requestSeq, signal, correlationId,
|
|
1914
|
+
async send(connection, kind, name, payload, metadata, compress, requestSeq, signal, correlationId, actorSlot) {
|
|
1930
1915
|
throwIfAborted(signal);
|
|
1931
|
-
const flow = this.protocol.flowEnabled() ? this.flowContext.currentOrCreate(explicitFlow) : void 0;
|
|
1932
1916
|
await this.write(
|
|
1933
1917
|
connection,
|
|
1934
1918
|
this.protocol.encode(
|
|
@@ -1939,8 +1923,7 @@ var ZlinkStreamFrameSender = class {
|
|
|
1939
1923
|
compress,
|
|
1940
1924
|
requestSeq,
|
|
1941
1925
|
correlationId,
|
|
1942
|
-
|
|
1943
|
-
flow?.flowOrigin
|
|
1926
|
+
actorSlot
|
|
1944
1927
|
),
|
|
1945
1928
|
signal
|
|
1946
1929
|
);
|
|
@@ -1951,7 +1934,7 @@ var ZlinkStreamFrameSender = class {
|
|
|
1951
1934
|
async drain(signal) {
|
|
1952
1935
|
while (this.pendingWrites.size > 0) {
|
|
1953
1936
|
throwIfAborted(signal);
|
|
1954
|
-
await Promise.allSettled(
|
|
1937
|
+
await Promise.allSettled(Array.from(this.pendingWrites));
|
|
1955
1938
|
}
|
|
1956
1939
|
}
|
|
1957
1940
|
async write(connection, frame, signal) {
|
|
@@ -1987,15 +1970,185 @@ function decodeSessionClosing(payload) {
|
|
|
1987
1970
|
return { closeReason, diagnostic };
|
|
1988
1971
|
}
|
|
1989
1972
|
|
|
1973
|
+
// packages/stream-connector/src/Runtime/ZlinkStreamActors.ts
|
|
1974
|
+
var ACTOR_BOUND = "$zlink.actor.bound";
|
|
1975
|
+
var ACTOR_UNBOUND = "$zlink.actor.unbound";
|
|
1976
|
+
var zlinkStreamActorBinding = Symbol("zlink.stream.actorBinding");
|
|
1977
|
+
var DefaultZlinkStreamActor = class {
|
|
1978
|
+
constructor(connector, actorId, slot) {
|
|
1979
|
+
this.connector = connector;
|
|
1980
|
+
this.actorId = actorId;
|
|
1981
|
+
this.slot = slot;
|
|
1982
|
+
}
|
|
1983
|
+
bound = true;
|
|
1984
|
+
get isBound() {
|
|
1985
|
+
return this.bound;
|
|
1986
|
+
}
|
|
1987
|
+
send(payload, messageType) {
|
|
1988
|
+
this.ensureBound();
|
|
1989
|
+
return this.connector.sendForActor(this, payload, messageType);
|
|
1990
|
+
}
|
|
1991
|
+
request(payload, messageType) {
|
|
1992
|
+
this.ensureBound();
|
|
1993
|
+
return this.connector.requestForActor(this, payload, messageType);
|
|
1994
|
+
}
|
|
1995
|
+
on(nameOrType, handler, messageType) {
|
|
1996
|
+
return this.connector.onActorMessage(this, nameOrType, handler, messageType);
|
|
1997
|
+
}
|
|
1998
|
+
ensureBound() {
|
|
1999
|
+
if (!this.bound) {
|
|
2000
|
+
throw connectorError(
|
|
2001
|
+
"validationFailed" /* ValidationFailed */,
|
|
2002
|
+
`Actor '${this.actorId}' is no longer bound.`
|
|
2003
|
+
);
|
|
2004
|
+
}
|
|
2005
|
+
}
|
|
2006
|
+
close() {
|
|
2007
|
+
this.bound = false;
|
|
2008
|
+
}
|
|
2009
|
+
};
|
|
2010
|
+
var ZlinkStreamActors = class {
|
|
2011
|
+
constructor(connector, receivedMessages, events) {
|
|
2012
|
+
this.connector = connector;
|
|
2013
|
+
this.receivedMessages = receivedMessages;
|
|
2014
|
+
this.events = events;
|
|
2015
|
+
}
|
|
2016
|
+
bySlot = /* @__PURE__ */ new Map();
|
|
2017
|
+
byId = /* @__PURE__ */ new Map();
|
|
2018
|
+
issued = [];
|
|
2019
|
+
boundHandlers = /* @__PURE__ */ new Set();
|
|
2020
|
+
unboundHandlers = /* @__PURE__ */ new Set();
|
|
2021
|
+
get snapshot() {
|
|
2022
|
+
return Object.freeze(Array.from(this.bySlot.values()));
|
|
2023
|
+
}
|
|
2024
|
+
find(actorId) {
|
|
2025
|
+
return this.byId.get(actorId);
|
|
2026
|
+
}
|
|
2027
|
+
onBound(handler) {
|
|
2028
|
+
this.boundHandlers.add(handler);
|
|
2029
|
+
return subscription(() => this.boundHandlers.delete(handler));
|
|
2030
|
+
}
|
|
2031
|
+
onUnbound(handler) {
|
|
2032
|
+
this.unboundHandlers.add(handler);
|
|
2033
|
+
return subscription(() => this.unboundHandlers.delete(handler));
|
|
2034
|
+
}
|
|
2035
|
+
processControl(name, payload, signal) {
|
|
2036
|
+
if (name === ACTOR_BOUND) {
|
|
2037
|
+
this.bind(payload, signal);
|
|
2038
|
+
return true;
|
|
2039
|
+
}
|
|
2040
|
+
if (name === ACTOR_UNBOUND) {
|
|
2041
|
+
this.unbind(payload, signal);
|
|
2042
|
+
return true;
|
|
2043
|
+
}
|
|
2044
|
+
return false;
|
|
2045
|
+
}
|
|
2046
|
+
resolve(slot) {
|
|
2047
|
+
const actor = this.bySlot.get(slot);
|
|
2048
|
+
if (actor === void 0) {
|
|
2049
|
+
throw connectorError(
|
|
2050
|
+
"frameDecodeFailed" /* FrameDecodeFailed */,
|
|
2051
|
+
`Actor slot '${slot}' is not bound.`
|
|
2052
|
+
);
|
|
2053
|
+
}
|
|
2054
|
+
return actor;
|
|
2055
|
+
}
|
|
2056
|
+
closeAll(signal) {
|
|
2057
|
+
for (const actor of this.issued) {
|
|
2058
|
+
if (!actor.isBound) continue;
|
|
2059
|
+
this.bySlot.delete(actor.slot);
|
|
2060
|
+
this.byId.delete(actor.actorId);
|
|
2061
|
+
actor.close();
|
|
2062
|
+
this.queue(this.unboundHandlers, actor, signal);
|
|
2063
|
+
}
|
|
2064
|
+
this.issued.length = 0;
|
|
2065
|
+
}
|
|
2066
|
+
bind(payload, signal) {
|
|
2067
|
+
if (payload.length < 5 || payload[0] !== 1) {
|
|
2068
|
+
throw invalidControl("Actor bound payload is invalid.");
|
|
2069
|
+
}
|
|
2070
|
+
const slot = payload[1] << 8 | payload[2];
|
|
2071
|
+
const idLength = payload[3];
|
|
2072
|
+
if (slot === 0 || idLength === 0 || payload.length !== 4 + idLength) {
|
|
2073
|
+
throw invalidControl("Actor bound payload is invalid.");
|
|
2074
|
+
}
|
|
2075
|
+
let actorId;
|
|
2076
|
+
try {
|
|
2077
|
+
actorId = new TextDecoder("utf-8", { fatal: true }).decode(payload.subarray(4));
|
|
2078
|
+
} catch (cause) {
|
|
2079
|
+
throw connectorError(
|
|
2080
|
+
"frameDecodeFailed" /* FrameDecodeFailed */,
|
|
2081
|
+
"Actor id is not valid UTF-8.",
|
|
2082
|
+
cause
|
|
2083
|
+
);
|
|
2084
|
+
}
|
|
2085
|
+
if (actorId.length === 0 || this.bySlot.has(slot) || this.byId.has(actorId)) {
|
|
2086
|
+
throw invalidControl("Actor bound identity is already in use.");
|
|
2087
|
+
}
|
|
2088
|
+
const actor = new DefaultZlinkStreamActor(this.connector, actorId, slot);
|
|
2089
|
+
this.bySlot.set(slot, actor);
|
|
2090
|
+
this.byId.set(actorId, actor);
|
|
2091
|
+
this.issued.push(actor);
|
|
2092
|
+
this.queue(this.boundHandlers, actor, signal);
|
|
2093
|
+
}
|
|
2094
|
+
unbind(payload, signal) {
|
|
2095
|
+
if (payload.length !== 3 || payload[0] !== 1) {
|
|
2096
|
+
throw invalidControl("Actor unbound payload is invalid.");
|
|
2097
|
+
}
|
|
2098
|
+
const slot = payload[1] << 8 | payload[2];
|
|
2099
|
+
const actor = this.bySlot.get(slot);
|
|
2100
|
+
if (slot === 0 || actor === void 0) {
|
|
2101
|
+
throw invalidControl(`Actor slot '${slot}' is not bound.`);
|
|
2102
|
+
}
|
|
2103
|
+
this.bySlot.delete(slot);
|
|
2104
|
+
this.byId.delete(actor.actorId);
|
|
2105
|
+
actor.close();
|
|
2106
|
+
this.queue(this.unboundHandlers, actor, signal);
|
|
2107
|
+
}
|
|
2108
|
+
queue(handlers, actor, signal) {
|
|
2109
|
+
this.receivedMessages.enqueueCallback(() => {
|
|
2110
|
+
for (const handler of Array.from(handlers)) {
|
|
2111
|
+
this.invoke(handler, actor, signal);
|
|
2112
|
+
}
|
|
2113
|
+
});
|
|
2114
|
+
}
|
|
2115
|
+
invoke(handler, actor, signal) {
|
|
2116
|
+
try {
|
|
2117
|
+
Promise.resolve(handler(actor, signal)).catch((cause) => {
|
|
2118
|
+
void this.events.publishError(
|
|
2119
|
+
{
|
|
2120
|
+
code: "userCallbackFailed" /* UserCallbackFailed */,
|
|
2121
|
+
message: "Actor lifecycle handler failed.",
|
|
2122
|
+
cause
|
|
2123
|
+
},
|
|
2124
|
+
signal
|
|
2125
|
+
);
|
|
2126
|
+
});
|
|
2127
|
+
} catch (cause) {
|
|
2128
|
+
void this.events.publishError(
|
|
2129
|
+
{
|
|
2130
|
+
code: "userCallbackFailed" /* UserCallbackFailed */,
|
|
2131
|
+
message: "Actor lifecycle handler failed.",
|
|
2132
|
+
cause
|
|
2133
|
+
},
|
|
2134
|
+
signal
|
|
2135
|
+
);
|
|
2136
|
+
}
|
|
2137
|
+
}
|
|
2138
|
+
};
|
|
2139
|
+
function invalidControl(message) {
|
|
2140
|
+
return connectorError("frameDecodeFailed" /* FrameDecodeFailed */, message);
|
|
2141
|
+
}
|
|
2142
|
+
|
|
1990
2143
|
// packages/stream-connector/src/Runtime/ZlinkStreamReceiveDispatcher.ts
|
|
1991
2144
|
var ZlinkStreamReceiveDispatcher = class {
|
|
1992
|
-
constructor(protocol, pendingRequests, receivedMessages, frameSender, events,
|
|
2145
|
+
constructor(protocol, pendingRequests, receivedMessages, frameSender, events, actors, serverClosing) {
|
|
1993
2146
|
this.protocol = protocol;
|
|
1994
2147
|
this.pendingRequests = pendingRequests;
|
|
1995
2148
|
this.receivedMessages = receivedMessages;
|
|
1996
2149
|
this.frameSender = frameSender;
|
|
1997
2150
|
this.events = events;
|
|
1998
|
-
this.
|
|
2151
|
+
this.actors = actors;
|
|
1999
2152
|
this.serverClosing = serverClosing;
|
|
2000
2153
|
}
|
|
2001
2154
|
/**
|
|
@@ -2022,49 +2175,47 @@ var ZlinkStreamReceiveDispatcher = class {
|
|
|
2022
2175
|
if (frameBytes === void 0) {
|
|
2023
2176
|
return { available: false, inbound: false };
|
|
2024
2177
|
}
|
|
2025
|
-
const flowEnabled = this.protocol.flowEnabled();
|
|
2026
2178
|
let frames;
|
|
2027
2179
|
try {
|
|
2028
|
-
frames = this.protocol.decodeFrames(frameBytes
|
|
2180
|
+
frames = this.protocol.decodeFrames(frameBytes);
|
|
2029
2181
|
} catch (cause) {
|
|
2030
|
-
|
|
2031
|
-
toStreamError(cause, "frameDecodeFailed" /* FrameDecodeFailed */, "Frame decode failed."),
|
|
2032
|
-
signal
|
|
2033
|
-
);
|
|
2034
|
-
return { available: true, inbound: false };
|
|
2182
|
+
throw cause;
|
|
2035
2183
|
}
|
|
2036
2184
|
for (const frame of frames) {
|
|
2037
2185
|
if (isCurrent !== void 0 && !isCurrent()) {
|
|
2038
2186
|
break;
|
|
2039
2187
|
}
|
|
2040
2188
|
try {
|
|
2041
|
-
await this.dispatch(
|
|
2042
|
-
connection,
|
|
2043
|
-
frame.header,
|
|
2044
|
-
frame.payload,
|
|
2045
|
-
signal,
|
|
2046
|
-
flowEnabled,
|
|
2047
|
-
connectionForSend
|
|
2048
|
-
);
|
|
2189
|
+
await this.dispatch(connection, frame.header, frame.payload, signal, connectionForSend);
|
|
2049
2190
|
} catch (cause) {
|
|
2050
2191
|
if (frame.header.kind === 5 /* Control */ && frame.header.name === ZLINK_STREAM_HEARTBEAT_PING) {
|
|
2051
2192
|
throw cause;
|
|
2052
2193
|
}
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2194
|
+
const error = toStreamError(
|
|
2195
|
+
cause,
|
|
2196
|
+
"frameDecodeFailed" /* FrameDecodeFailed */,
|
|
2197
|
+
"Frame dispatch failed."
|
|
2056
2198
|
);
|
|
2199
|
+
if (error.code === "frameDecodeFailed" /* FrameDecodeFailed */) {
|
|
2200
|
+
throw cause;
|
|
2201
|
+
}
|
|
2202
|
+
await this.events.publishError(error, signal);
|
|
2057
2203
|
}
|
|
2058
2204
|
}
|
|
2059
2205
|
return { available: true, inbound: true };
|
|
2060
2206
|
}
|
|
2061
|
-
async dispatch(connection, header, payload, signal,
|
|
2207
|
+
async dispatch(connection, header, payload, signal, connectionForSend) {
|
|
2208
|
+
const actor = header.actorSlot === void 0 ? void 0 : this.actors.resolve(header.actorSlot);
|
|
2062
2209
|
if (header.kind === 3 /* Response */ && header.requestSeq !== void 0) {
|
|
2063
2210
|
try {
|
|
2064
|
-
if (!this.pendingRequests.resolve(
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2211
|
+
if (!this.pendingRequests.resolve(
|
|
2212
|
+
header.requestSeq,
|
|
2213
|
+
{
|
|
2214
|
+
codec: header.codec,
|
|
2215
|
+
payload: this.protocol.decodePayload(header, payload)
|
|
2216
|
+
},
|
|
2217
|
+
header.metadata
|
|
2218
|
+
)) {
|
|
2068
2219
|
await this.events.publishError(
|
|
2069
2220
|
{
|
|
2070
2221
|
code: "frameDecodeFailed" /* FrameDecodeFailed */,
|
|
@@ -2112,20 +2263,22 @@ var ZlinkStreamReceiveDispatcher = class {
|
|
|
2112
2263
|
return;
|
|
2113
2264
|
}
|
|
2114
2265
|
if (header.kind === 1 /* Send */) {
|
|
2115
|
-
const flow = flowEnabled ? this.flowContext.createInbound(header.flowId, header.flowOrigin) : void 0;
|
|
2116
2266
|
this.receivedMessages.enqueue(
|
|
2117
2267
|
{
|
|
2118
2268
|
name: header.name,
|
|
2119
2269
|
metadata: header.metadata,
|
|
2120
2270
|
payload: { codec: header.codec, payload: this.protocol.decodePayload(header, payload) },
|
|
2121
|
-
|
|
2122
|
-
|
|
2271
|
+
actorId: actor?.actorId,
|
|
2272
|
+
[zlinkStreamActorBinding]: actor
|
|
2123
2273
|
},
|
|
2124
2274
|
signal
|
|
2125
2275
|
);
|
|
2126
2276
|
}
|
|
2127
2277
|
}
|
|
2128
2278
|
async dispatchControl(connection, header, payload, signal, connectionForSend) {
|
|
2279
|
+
if (this.actors.processControl(header.name, payload, signal)) {
|
|
2280
|
+
return;
|
|
2281
|
+
}
|
|
2129
2282
|
if (header.name === ZLINK_SESSION_CLOSING) {
|
|
2130
2283
|
const closing = decodeSessionClosing(payload);
|
|
2131
2284
|
await this.serverClosing?.(closing.closeReason);
|
|
@@ -2184,12 +2337,13 @@ function randomizedDelay(baseDelayMs) {
|
|
|
2184
2337
|
return Math.round(baseDelayMs * (0.5 + Math.random() * 0.5));
|
|
2185
2338
|
}
|
|
2186
2339
|
var ZlinkStreamConnectorLifecycle = class {
|
|
2187
|
-
constructor(options, pendingRequests, frameSender, receiveDispatcher, receivedMessages, events) {
|
|
2340
|
+
constructor(options, pendingRequests, frameSender, receiveDispatcher, receivedMessages, actors, events) {
|
|
2188
2341
|
this.options = options;
|
|
2189
2342
|
this.pendingRequests = pendingRequests;
|
|
2190
2343
|
this.frameSender = frameSender;
|
|
2191
2344
|
this.receiveDispatcher = receiveDispatcher;
|
|
2192
2345
|
this.receivedMessages = receivedMessages;
|
|
2346
|
+
this.actors = actors;
|
|
2193
2347
|
this.events = events;
|
|
2194
2348
|
}
|
|
2195
2349
|
receiveLoopAbort;
|
|
@@ -2325,8 +2479,9 @@ var ZlinkStreamConnectorLifecycle = class {
|
|
|
2325
2479
|
message: "Connector closed."
|
|
2326
2480
|
});
|
|
2327
2481
|
this.receivedMessages.connectionEnded();
|
|
2328
|
-
|
|
2329
|
-
this.
|
|
2482
|
+
this.actors.closeAll(signal);
|
|
2483
|
+
this.queueState("closed" /* Closed */, void 0, signal);
|
|
2484
|
+
this.queueDisconnected(signal);
|
|
2330
2485
|
if (errors.length === 1) throw errors[0];
|
|
2331
2486
|
if (errors.length > 1) throw new AggregateError(errors, "Stream connector close failed.");
|
|
2332
2487
|
}
|
|
@@ -2555,6 +2710,7 @@ var ZlinkStreamConnectorLifecycle = class {
|
|
|
2555
2710
|
this.currentConnection = void 0;
|
|
2556
2711
|
this.pendingRequests.failAll(error);
|
|
2557
2712
|
this.receivedMessages.connectionEnded();
|
|
2713
|
+
this.actors.closeAll();
|
|
2558
2714
|
try {
|
|
2559
2715
|
await connection?.close();
|
|
2560
2716
|
} catch {
|
|
@@ -2570,11 +2726,8 @@ var ZlinkStreamConnectorLifecycle = class {
|
|
|
2570
2726
|
*/
|
|
2571
2727
|
async announceDisconnect(error) {
|
|
2572
2728
|
if (this.closeRequested) return;
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
if (announce) {
|
|
2576
|
-
void this.events.publishDisconnected().catch(() => void 0);
|
|
2577
|
-
}
|
|
2729
|
+
this.queueState("disconnected" /* Disconnected */, error);
|
|
2730
|
+
this.queueDisconnected();
|
|
2578
2731
|
if (this.shouldReconnect()) {
|
|
2579
2732
|
queueMicrotask(() => {
|
|
2580
2733
|
void this.connect().catch(() => void 0);
|
|
@@ -2622,16 +2775,35 @@ var ZlinkStreamConnectorLifecycle = class {
|
|
|
2622
2775
|
publishDisconnectedWithoutWaiting(signal) {
|
|
2623
2776
|
void this.publishDisconnectedOnce(signal).catch(() => void 0);
|
|
2624
2777
|
}
|
|
2778
|
+
queueDisconnected(signal) {
|
|
2779
|
+
if (!this.claimDisconnectedPublish()) return;
|
|
2780
|
+
this.receivedMessages.enqueueCallback(() => {
|
|
2781
|
+
void this.events.publishDisconnected(signal).catch(() => void 0);
|
|
2782
|
+
});
|
|
2783
|
+
}
|
|
2784
|
+
queueState(current, error, signal) {
|
|
2785
|
+
const change = this.transitionState(current, error);
|
|
2786
|
+
if (change === void 0) return;
|
|
2787
|
+
this.receivedMessages.enqueueCallback(() => {
|
|
2788
|
+
void this.publishStateChange(change, signal).catch(() => void 0);
|
|
2789
|
+
});
|
|
2790
|
+
}
|
|
2625
2791
|
async setState(current, error, signal) {
|
|
2792
|
+
const change = this.transitionState(current, error);
|
|
2793
|
+
if (change === void 0) return;
|
|
2794
|
+
await this.publishStateChange(change, signal);
|
|
2795
|
+
}
|
|
2796
|
+
transitionState(current, error) {
|
|
2626
2797
|
const previous = this.currentState;
|
|
2627
2798
|
this.currentState = current;
|
|
2628
2799
|
if (previous === current && error === void 0) {
|
|
2629
|
-
return;
|
|
2630
|
-
}
|
|
2631
|
-
await this.events.publishStateChanged({ previous, current, error }, signal);
|
|
2632
|
-
if (error !== void 0) {
|
|
2633
|
-
await this.events.publishError(error, signal);
|
|
2800
|
+
return void 0;
|
|
2634
2801
|
}
|
|
2802
|
+
return { previous, current, error };
|
|
2803
|
+
}
|
|
2804
|
+
async publishStateChange(change, signal) {
|
|
2805
|
+
await this.events.publishStateChanged(change, signal);
|
|
2806
|
+
if (change.error !== void 0) await this.events.publishError(change.error, signal);
|
|
2635
2807
|
}
|
|
2636
2808
|
};
|
|
2637
2809
|
|
|
@@ -2653,49 +2825,25 @@ var ZlinkStreamConnectorEvents = class {
|
|
|
2653
2825
|
return subscription(() => this.stateHandlers.delete(handler));
|
|
2654
2826
|
}
|
|
2655
2827
|
async publishError(error, signal) {
|
|
2656
|
-
await this.publish(
|
|
2828
|
+
await this.publish(
|
|
2829
|
+
Array.from(this.errorHandlers).map((handler) => () => handler(error, signal))
|
|
2830
|
+
);
|
|
2657
2831
|
}
|
|
2658
2832
|
async publishDisconnected(signal) {
|
|
2659
|
-
await this.publish(
|
|
2833
|
+
await this.publish(
|
|
2834
|
+
Array.from(this.disconnectedHandlers).map((handler) => () => handler(signal))
|
|
2835
|
+
);
|
|
2660
2836
|
}
|
|
2661
2837
|
async publishStateChanged(change, signal) {
|
|
2662
|
-
await this.publish(
|
|
2838
|
+
await this.publish(
|
|
2839
|
+
Array.from(this.stateHandlers).map((handler) => () => handler(change, signal))
|
|
2840
|
+
);
|
|
2663
2841
|
}
|
|
2664
2842
|
async publish(handlers) {
|
|
2665
2843
|
await Promise.allSettled(handlers.map(async (handler) => handler()));
|
|
2666
2844
|
}
|
|
2667
2845
|
};
|
|
2668
2846
|
|
|
2669
|
-
// packages/stream-connector/src/Runtime/ZlinkFlowContext.ts
|
|
2670
|
-
var BrowserZlinkFlowContext = class {
|
|
2671
|
-
currentOrCreate(explicit) {
|
|
2672
|
-
return explicit ?? { flowId: this.createUuidV7(), flowOrigin: "Application" };
|
|
2673
|
-
}
|
|
2674
|
-
createInbound(flowId, flowOrigin) {
|
|
2675
|
-
return { flowId: flowId ?? this.createUuidV7(), flowOrigin: flowOrigin ?? "Inbound" };
|
|
2676
|
-
}
|
|
2677
|
-
createUuidV7() {
|
|
2678
|
-
const crypto = globalThis.crypto;
|
|
2679
|
-
if (crypto === void 0) {
|
|
2680
|
-
throw connectorError(
|
|
2681
|
-
"configurationError" /* ConfigurationError */,
|
|
2682
|
-
"The browser entrypoint requires the platform Web Crypto API."
|
|
2683
|
-
);
|
|
2684
|
-
}
|
|
2685
|
-
return formatUuidV7(crypto.getRandomValues(new Uint8Array(16)));
|
|
2686
|
-
}
|
|
2687
|
-
};
|
|
2688
|
-
function formatUuidV7(bytes) {
|
|
2689
|
-
const timestamp = BigInt(Date.now());
|
|
2690
|
-
for (let index = 5; index >= 0; index -= 1) {
|
|
2691
|
-
bytes[index] = Number(timestamp >> BigInt((5 - index) * 8) & 0xffn);
|
|
2692
|
-
}
|
|
2693
|
-
bytes[6] = 112 | bytes[6] & 15;
|
|
2694
|
-
bytes[8] = 128 | bytes[8] & 63;
|
|
2695
|
-
const hex = [...bytes].map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
2696
|
-
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
2697
|
-
}
|
|
2698
|
-
|
|
2699
2847
|
// packages/stream-connector/src/Runtime/Transport/BrowserWebSocketConnection.ts
|
|
2700
2848
|
var BrowserStreamTransportFactory = class {
|
|
2701
2849
|
async connect(options, signal) {
|
|
@@ -2910,30 +3058,26 @@ var DefaultZlinkStreamConnector = class {
|
|
|
2910
3058
|
pendingRequests = new ZlinkStreamPendingRequests();
|
|
2911
3059
|
frameSender;
|
|
2912
3060
|
receiveDispatcher;
|
|
2913
|
-
|
|
3061
|
+
requestSendingHandlers = /* @__PURE__ */ new Set();
|
|
3062
|
+
replyReceivedHandlers = /* @__PURE__ */ new Set();
|
|
3063
|
+
boundActors;
|
|
2914
3064
|
options;
|
|
2915
3065
|
constructor(options) {
|
|
2916
|
-
const flowContext = new BrowserZlinkFlowContext();
|
|
2917
3066
|
this.options = normalizeOptions(options, new BrowserStreamTransportFactory());
|
|
2918
|
-
this.diagnosticsLevelCell = new ZlinkStreamDiagnosticsLevelCell(this.options.diagnosticsLevel);
|
|
2919
|
-
Object.defineProperty(this.options, "diagnosticsLevel", {
|
|
2920
|
-
enumerable: true,
|
|
2921
|
-
configurable: true,
|
|
2922
|
-
get: () => this.diagnosticsLevelCell.level
|
|
2923
|
-
});
|
|
2924
3067
|
const protocol = new ZlinkStreamFrameProtocol(this.options);
|
|
2925
|
-
this.frameSender = new ZlinkStreamFrameSender(protocol
|
|
3068
|
+
this.frameSender = new ZlinkStreamFrameSender(protocol);
|
|
2926
3069
|
this.receivedMessages = new ZlinkStreamReceivedMessages(
|
|
2927
3070
|
this.events,
|
|
2928
3071
|
this.options.dispatchMode === "immediate" /* Immediate */
|
|
2929
3072
|
);
|
|
3073
|
+
this.boundActors = new ZlinkStreamActors(this, this.receivedMessages, this.events);
|
|
2930
3074
|
this.receiveDispatcher = new ZlinkStreamReceiveDispatcher(
|
|
2931
3075
|
protocol,
|
|
2932
3076
|
this.pendingRequests,
|
|
2933
3077
|
this.receivedMessages,
|
|
2934
3078
|
this.frameSender,
|
|
2935
3079
|
this.events,
|
|
2936
|
-
|
|
3080
|
+
this.boundActors,
|
|
2937
3081
|
(reason) => this.lifecycle.serverClosing(reason)
|
|
2938
3082
|
);
|
|
2939
3083
|
this.lifecycle = new ZlinkStreamConnectorLifecycle(
|
|
@@ -2942,6 +3086,7 @@ var DefaultZlinkStreamConnector = class {
|
|
|
2942
3086
|
this.frameSender,
|
|
2943
3087
|
this.receiveDispatcher,
|
|
2944
3088
|
this.receivedMessages,
|
|
3089
|
+
this.boundActors,
|
|
2945
3090
|
this.events
|
|
2946
3091
|
);
|
|
2947
3092
|
}
|
|
@@ -2957,6 +3102,18 @@ var DefaultZlinkStreamConnector = class {
|
|
|
2957
3102
|
get pendingDispatchCount() {
|
|
2958
3103
|
return this.pendingRequests.count;
|
|
2959
3104
|
}
|
|
3105
|
+
get actors() {
|
|
3106
|
+
return this.boundActors.snapshot;
|
|
3107
|
+
}
|
|
3108
|
+
actor(actorId) {
|
|
3109
|
+
return this.boundActors.find(actorId);
|
|
3110
|
+
}
|
|
3111
|
+
onActorBound(handler) {
|
|
3112
|
+
return this.boundActors.onBound(handler);
|
|
3113
|
+
}
|
|
3114
|
+
onActorUnbound(handler) {
|
|
3115
|
+
return this.boundActors.onUnbound(handler);
|
|
3116
|
+
}
|
|
2960
3117
|
/**
|
|
2961
3118
|
* Spec stream-connector 32 §10: how many packets carrying `name` arrived on
|
|
2962
3119
|
* the current connection. Arrivals are what is counted, so a message a
|
|
@@ -2968,37 +3125,6 @@ var DefaultZlinkStreamConnector = class {
|
|
|
2968
3125
|
validateName(name);
|
|
2969
3126
|
return this.receivedMessages.receivedCount(name);
|
|
2970
3127
|
}
|
|
2971
|
-
/**
|
|
2972
|
-
* Current diagnostics level (spec 26 §4.1, spec stream-connector 32 §13).
|
|
2973
|
-
* Reflects the level set by the most recent {@link setDiagnosticsLevel}
|
|
2974
|
-
* call, or the construction-time option (default
|
|
2975
|
-
* {@link ZlinkStreamDiagnosticsLevel.Errors}) if it was never changed.
|
|
2976
|
-
*/
|
|
2977
|
-
get diagnosticsLevel() {
|
|
2978
|
-
return this.diagnosticsLevelCell.level;
|
|
2979
|
-
}
|
|
2980
|
-
/**
|
|
2981
|
-
* Changes the diagnostics level in place without recreating the connector
|
|
2982
|
-
* (spec 26 §4.1, spec stream-connector 32 §13). The change is an atomic
|
|
2983
|
-
* state update: it applies to processing points that read the level after
|
|
2984
|
-
* this call returns and is never applied retroactively to frames already
|
|
2985
|
-
* built. Rejects unknown values with {@link ZlinkStreamErrorCode.ConfigurationError}.
|
|
2986
|
-
* Spec stream-connector 32 §13: this surface changes the value without
|
|
2987
|
-
* waiting for anything; it is not a blocking call over the asynchronous pair,
|
|
2988
|
-
* which a receive callback would otherwise make wait for its own completion.
|
|
2989
|
-
*/
|
|
2990
|
-
setDiagnosticsLevel(level) {
|
|
2991
|
-
this.diagnosticsLevelCell.set(level);
|
|
2992
|
-
}
|
|
2993
|
-
/**
|
|
2994
|
-
* Asynchronous counterpart of {@link setDiagnosticsLevel} (spec
|
|
2995
|
-
* stream-connector 32 §13). It changes the same value; awaiting it is how a
|
|
2996
|
-
* caller observes the change, and it never replaces the synchronous surface.
|
|
2997
|
-
*/
|
|
2998
|
-
setDiagnosticsLevelAsync(level) {
|
|
2999
|
-
this.setDiagnosticsLevel(level);
|
|
3000
|
-
return Promise.resolve();
|
|
3001
|
-
}
|
|
3002
3128
|
onErrorReceived(handler) {
|
|
3003
3129
|
return this.events.onError(handler);
|
|
3004
3130
|
}
|
|
@@ -3008,6 +3134,14 @@ var DefaultZlinkStreamConnector = class {
|
|
|
3008
3134
|
onConnectionStateChanged(handler) {
|
|
3009
3135
|
return this.events.onStateChanged(handler);
|
|
3010
3136
|
}
|
|
3137
|
+
onRequestSending(handler) {
|
|
3138
|
+
this.requestSendingHandlers.add(handler);
|
|
3139
|
+
return subscription(() => this.requestSendingHandlers.delete(handler));
|
|
3140
|
+
}
|
|
3141
|
+
onReplyReceived(handler) {
|
|
3142
|
+
this.replyReceivedHandlers.add(handler);
|
|
3143
|
+
return subscription(() => this.replyReceivedHandlers.delete(handler));
|
|
3144
|
+
}
|
|
3011
3145
|
async connect(signal) {
|
|
3012
3146
|
await this.lifecycle.connect(signal);
|
|
3013
3147
|
}
|
|
@@ -3025,18 +3159,60 @@ var DefaultZlinkStreamConnector = class {
|
|
|
3025
3159
|
const encoded = this.encodePayload(payload, messageType);
|
|
3026
3160
|
return new ZlinkStreamRequestBuilder(this, this.resolveNameOrDefault(encoded), encoded);
|
|
3027
3161
|
}
|
|
3028
|
-
on(
|
|
3162
|
+
on(nameOrType, handler, messageType) {
|
|
3029
3163
|
const encodedHandler = (message, signal) => handler(
|
|
3030
3164
|
{
|
|
3031
3165
|
name: message.name,
|
|
3032
3166
|
metadata: message.metadata,
|
|
3033
|
-
payload: this.decodePayload(
|
|
3034
|
-
|
|
3035
|
-
|
|
3167
|
+
payload: this.decodePayload(
|
|
3168
|
+
message.payload,
|
|
3169
|
+
messageType ?? (typeof nameOrType === "function" ? nameOrType : void 0)
|
|
3170
|
+
),
|
|
3171
|
+
actorId: message.actorId
|
|
3036
3172
|
},
|
|
3037
3173
|
signal
|
|
3038
3174
|
);
|
|
3039
|
-
return this.receivedMessages.on(
|
|
3175
|
+
return this.receivedMessages.on(this.observedName(nameOrType), encodedHandler);
|
|
3176
|
+
}
|
|
3177
|
+
sendForActor(actor, payload, messageType) {
|
|
3178
|
+
const encoded = this.encodePayload(payload, messageType);
|
|
3179
|
+
return new ZlinkStreamSendBuilder(
|
|
3180
|
+
this,
|
|
3181
|
+
this.resolveNameOrDefault(encoded),
|
|
3182
|
+
encoded,
|
|
3183
|
+
actor.slot,
|
|
3184
|
+
() => actor.ensureBound()
|
|
3185
|
+
);
|
|
3186
|
+
}
|
|
3187
|
+
requestForActor(actor, payload, messageType) {
|
|
3188
|
+
const encoded = this.encodePayload(payload, messageType);
|
|
3189
|
+
return new ZlinkStreamRequestBuilder(
|
|
3190
|
+
this,
|
|
3191
|
+
this.resolveNameOrDefault(encoded),
|
|
3192
|
+
encoded,
|
|
3193
|
+
actor.slot,
|
|
3194
|
+
() => actor.ensureBound()
|
|
3195
|
+
);
|
|
3196
|
+
}
|
|
3197
|
+
onActorMessage(actor, nameOrType, handler, messageType) {
|
|
3198
|
+
const encodedHandler = (message, signal) => {
|
|
3199
|
+
if (message[zlinkStreamActorBinding] !== actor) {
|
|
3200
|
+
return;
|
|
3201
|
+
}
|
|
3202
|
+
return handler(
|
|
3203
|
+
{
|
|
3204
|
+
name: message.name,
|
|
3205
|
+
metadata: message.metadata,
|
|
3206
|
+
payload: this.decodePayload(
|
|
3207
|
+
message.payload,
|
|
3208
|
+
messageType ?? (typeof nameOrType === "function" ? nameOrType : void 0)
|
|
3209
|
+
),
|
|
3210
|
+
actorId: message.actorId
|
|
3211
|
+
},
|
|
3212
|
+
signal
|
|
3213
|
+
);
|
|
3214
|
+
};
|
|
3215
|
+
return this.receivedMessages.on(this.observedName(nameOrType), encodedHandler);
|
|
3040
3216
|
}
|
|
3041
3217
|
waitFor(nameOrType) {
|
|
3042
3218
|
return new ZlinkStreamWaitBuilder(this, this.observedName(nameOrType));
|
|
@@ -3119,8 +3295,7 @@ var DefaultZlinkStreamConnector = class {
|
|
|
3119
3295
|
name: message.name,
|
|
3120
3296
|
metadata: message.metadata,
|
|
3121
3297
|
payload: this.decodeWaitPayload(message.payload),
|
|
3122
|
-
|
|
3123
|
-
flowOrigin: message.flowOrigin
|
|
3298
|
+
actorId: message.actorId
|
|
3124
3299
|
};
|
|
3125
3300
|
if (!predicate(decoded)) {
|
|
3126
3301
|
return false;
|
|
@@ -3159,7 +3334,7 @@ var DefaultZlinkStreamConnector = class {
|
|
|
3159
3334
|
}
|
|
3160
3335
|
return payload;
|
|
3161
3336
|
}
|
|
3162
|
-
async sendEncoded(kind, name, payload, metadata, compress, requestSeq, signal,
|
|
3337
|
+
async sendEncoded(kind, name, payload, metadata, compress, requestSeq, signal, correlationId, actorSlot) {
|
|
3163
3338
|
await this.frameSender.send(
|
|
3164
3339
|
this.lifecycle.connectionForSend(),
|
|
3165
3340
|
kind,
|
|
@@ -3170,37 +3345,105 @@ var DefaultZlinkStreamConnector = class {
|
|
|
3170
3345
|
requestSeq,
|
|
3171
3346
|
signal,
|
|
3172
3347
|
correlationId,
|
|
3173
|
-
|
|
3348
|
+
actorSlot
|
|
3174
3349
|
);
|
|
3175
3350
|
}
|
|
3176
3351
|
/**
|
|
3177
3352
|
* Per-connector monotonic correlation id (hex). The client generates it on each request
|
|
3178
|
-
* and the server echoes it back on the reply
|
|
3353
|
+
* and the server echoes it back on the reply.
|
|
3179
3354
|
*/
|
|
3180
3355
|
nextCorrelationId() {
|
|
3181
3356
|
this.correlationCounter += 1n;
|
|
3182
3357
|
return this.correlationCounter.toString(16);
|
|
3183
3358
|
}
|
|
3184
|
-
async requestEncoded(name, payload, metadata, compress, timeoutMs, signal,
|
|
3185
|
-
const
|
|
3359
|
+
async requestEncoded(name, payload, metadata, compress, timeoutMs, signal, actorSlot) {
|
|
3360
|
+
const startedAt = Date.now();
|
|
3361
|
+
const actorId = actorSlot === void 0 ? void 0 : this.boundActors.resolve(actorSlot).actorId;
|
|
3362
|
+
let requestMetadata = metadata;
|
|
3363
|
+
const sendingContext = {
|
|
3364
|
+
requestPacketName: name,
|
|
3365
|
+
actorId,
|
|
3366
|
+
setMetadata(key, value) {
|
|
3367
|
+
requestMetadata = requestMetadata.with(key, value);
|
|
3368
|
+
}
|
|
3369
|
+
};
|
|
3370
|
+
let pending;
|
|
3186
3371
|
try {
|
|
3372
|
+
throwIfAborted(signal);
|
|
3373
|
+
for (const handler of Array.from(this.requestSendingHandlers)) {
|
|
3374
|
+
try {
|
|
3375
|
+
handler(sendingContext);
|
|
3376
|
+
} catch (cause) {
|
|
3377
|
+
queueMicrotask(() => {
|
|
3378
|
+
void this.events.publishError(
|
|
3379
|
+
toStreamError(
|
|
3380
|
+
cause,
|
|
3381
|
+
"userCallbackFailed" /* UserCallbackFailed */,
|
|
3382
|
+
"Request sending hook failed."
|
|
3383
|
+
),
|
|
3384
|
+
signal
|
|
3385
|
+
);
|
|
3386
|
+
});
|
|
3387
|
+
}
|
|
3388
|
+
}
|
|
3389
|
+
pending = this.pendingRequests.create(name, timeoutMs);
|
|
3187
3390
|
await this.sendEncoded(
|
|
3188
3391
|
2 /* Request */,
|
|
3189
3392
|
name,
|
|
3190
3393
|
payload,
|
|
3191
|
-
|
|
3394
|
+
requestMetadata,
|
|
3192
3395
|
compress,
|
|
3193
3396
|
pending.requestSeq,
|
|
3194
3397
|
signal,
|
|
3195
|
-
|
|
3196
|
-
|
|
3398
|
+
this.nextCorrelationId(),
|
|
3399
|
+
actorSlot
|
|
3400
|
+
);
|
|
3401
|
+
const reply = await pending.promise;
|
|
3402
|
+
this.publishReplyReceived(
|
|
3403
|
+
{
|
|
3404
|
+
requestPacketName: name,
|
|
3405
|
+
actorId,
|
|
3406
|
+
succeeded: true,
|
|
3407
|
+
reply: { ...reply, actorId },
|
|
3408
|
+
elapsed: Date.now() - startedAt
|
|
3409
|
+
},
|
|
3410
|
+
signal
|
|
3197
3411
|
);
|
|
3198
|
-
return
|
|
3412
|
+
return reply.payload;
|
|
3199
3413
|
} catch (error) {
|
|
3200
|
-
this.pendingRequests.cancel(pending.requestSeq);
|
|
3414
|
+
if (pending !== void 0) this.pendingRequests.cancel(pending.requestSeq);
|
|
3415
|
+
this.publishReplyReceived(
|
|
3416
|
+
{
|
|
3417
|
+
requestPacketName: name,
|
|
3418
|
+
actorId,
|
|
3419
|
+
succeeded: false,
|
|
3420
|
+
error: unwrapStreamError(error),
|
|
3421
|
+
elapsed: Date.now() - startedAt
|
|
3422
|
+
},
|
|
3423
|
+
signal
|
|
3424
|
+
);
|
|
3201
3425
|
throw error;
|
|
3202
3426
|
}
|
|
3203
3427
|
}
|
|
3428
|
+
publishReplyReceived(context, signal) {
|
|
3429
|
+
if (this.replyReceivedHandlers.size === 0) return;
|
|
3430
|
+
this.receivedMessages.enqueueCallback(async () => {
|
|
3431
|
+
for (const handler of Array.from(this.replyReceivedHandlers)) {
|
|
3432
|
+
try {
|
|
3433
|
+
await handler(context, signal);
|
|
3434
|
+
} catch (cause) {
|
|
3435
|
+
await this.events.publishError(
|
|
3436
|
+
toStreamError(
|
|
3437
|
+
cause,
|
|
3438
|
+
"userCallbackFailed" /* UserCallbackFailed */,
|
|
3439
|
+
"Reply received hook failed."
|
|
3440
|
+
),
|
|
3441
|
+
signal
|
|
3442
|
+
);
|
|
3443
|
+
}
|
|
3444
|
+
}
|
|
3445
|
+
});
|
|
3446
|
+
}
|
|
3204
3447
|
resolveNameOrDefault(payload) {
|
|
3205
3448
|
if (payload.messageType === void 0) {
|
|
3206
3449
|
return void 0;
|
|
@@ -3226,7 +3469,6 @@ export {
|
|
|
3226
3469
|
ZlinkStreamCodec,
|
|
3227
3470
|
ZlinkStreamCompression,
|
|
3228
3471
|
ZlinkStreamConnectionState,
|
|
3229
|
-
ZlinkStreamDiagnosticsLevel,
|
|
3230
3472
|
ZlinkStreamDispatchMode,
|
|
3231
3473
|
ZlinkStreamErrorCode,
|
|
3232
3474
|
ZlinkStreamException,
|