@moqtap/codec 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-YBSEOSSP.js → chunk-A27S7HW7.js} +5 -1
- package/dist/{chunk-5WFXFLL4.cjs → chunk-FUFTMAQD.cjs} +96 -63
- package/dist/{chunk-2NARXGVA.cjs → chunk-FWISIR26.cjs} +5 -1
- package/dist/{chunk-23YG7F46.js → chunk-IXHOBNXA.js} +117 -17
- package/dist/{chunk-3BSZ55L3.cjs → chunk-NLYTRGXA.cjs} +153 -19
- package/dist/{chunk-GDRGWFEK.cjs → chunk-NPWHHWXT.cjs} +249 -37
- package/dist/{chunk-IQPDRQVC.js → chunk-U2B3B42P.js} +62 -29
- package/dist/{chunk-WNTXF3DE.cjs → chunk-YBZD3DU5.cjs} +127 -27
- package/dist/{chunk-DC4L6ZIT.js → chunk-YTXLWKOR.js} +153 -19
- package/dist/{chunk-YPXLV5YK.js → chunk-Z66WDWHI.js} +249 -37
- package/dist/{codec-qPzfmLNu.d.ts → codec-B2mc2g3i.d.ts} +5 -5
- package/dist/{codec-CTvFtQQI.d.cts → codec-Bvr7rFtj.d.cts} +5 -5
- package/dist/draft14-session.cjs +2 -2
- package/dist/draft14-session.d.cts +4 -4
- package/dist/draft14-session.d.ts +4 -4
- package/dist/draft14-session.js +1 -1
- package/dist/draft14.cjs +4 -4
- package/dist/draft14.d.cts +15 -15
- package/dist/draft14.d.ts +15 -15
- package/dist/draft14.js +3 -3
- package/dist/draft7-session.cjs +2 -2
- package/dist/draft7-session.d.cts +3 -3
- package/dist/draft7-session.d.ts +3 -3
- package/dist/draft7-session.js +1 -1
- package/dist/draft7.cjs +5 -5
- package/dist/draft7.d.cts +10 -10
- package/dist/draft7.d.ts +10 -10
- package/dist/draft7.js +2 -2
- package/dist/index.cjs +6 -6
- package/dist/index.d.cts +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/index.js +3 -3
- package/dist/{session-types-B9NIf7_F.d.ts → session-types-DFjMk4HH.d.ts} +20 -20
- package/dist/{session-types-CCo-oA-d.d.cts → session-types-DW1RSZX_.d.cts} +20 -20
- package/dist/session.cjs +4 -4
- package/dist/session.d.cts +3 -3
- package/dist/session.d.ts +3 -3
- package/dist/session.js +2 -2
- package/dist/{types-CIk5W10V.d.ts → types-BTFeKYCb.d.cts} +37 -37
- package/dist/{types-CIk5W10V.d.cts → types-BTFeKYCb.d.ts} +37 -37
- package/dist/{types-ClXELFGN.d.cts → types-DPYE49t0.d.cts} +36 -36
- package/dist/{types-ClXELFGN.d.ts → types-DPYE49t0.d.ts} +36 -36
- package/package.json +7 -7
- package/src/core/buffer-reader.ts +16 -9
- package/src/core/buffer-writer.ts +2 -2
- package/src/core/errors.ts +1 -1
- package/src/core/session-types.ts +28 -41
- package/src/core/types.ts +70 -70
- package/src/drafts/draft07/announce-fsm.ts +1 -1
- package/src/drafts/draft07/codec.ts +195 -86
- package/src/drafts/draft07/index.ts +43 -44
- package/src/drafts/draft07/messages.ts +1 -1
- package/src/drafts/draft07/parameters.ts +2 -2
- package/src/drafts/draft07/rules.ts +68 -37
- package/src/drafts/draft07/session-fsm.ts +330 -117
- package/src/drafts/draft07/session.ts +10 -10
- package/src/drafts/draft07/subscription-fsm.ts +1 -1
- package/src/drafts/draft07/varint.ts +4 -4
- package/src/drafts/draft14/codec.ts +339 -189
- package/src/drafts/draft14/index.ts +103 -108
- package/src/drafts/draft14/messages.ts +61 -61
- package/src/drafts/draft14/rules.ts +77 -34
- package/src/drafts/draft14/session-fsm.ts +458 -146
- package/src/drafts/draft14/session.ts +13 -13
- package/src/drafts/draft14/types.ts +68 -68
- package/src/index.ts +66 -31
- package/src/session.ts +20 -20
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
var
|
|
5
|
+
var _chunkFWISIR26cjs = require('./chunk-FWISIR26.cjs');
|
|
6
6
|
|
|
7
7
|
// src/drafts/draft07/messages.ts
|
|
8
8
|
var MESSAGE_TYPE_IDS = {
|
|
@@ -49,17 +49,17 @@ for (const [name, id] of Object.entries(MESSAGE_TYPE_IDS)) {
|
|
|
49
49
|
|
|
50
50
|
// src/drafts/draft07/varint.ts
|
|
51
51
|
function encodeVarInt(value) {
|
|
52
|
-
const writer = new (0,
|
|
52
|
+
const writer = new (0, _chunkFWISIR26cjs.BufferWriter)(8);
|
|
53
53
|
writer.writeVarInt(value);
|
|
54
54
|
return writer.finish();
|
|
55
55
|
}
|
|
56
56
|
function decodeVarInt(bytes, offset = 0) {
|
|
57
57
|
try {
|
|
58
|
-
const reader = new (0,
|
|
58
|
+
const reader = new (0, _chunkFWISIR26cjs.BufferReader)(bytes, offset);
|
|
59
59
|
const value = reader.readVarInt();
|
|
60
60
|
return { ok: true, value, bytesRead: reader.offset - offset };
|
|
61
61
|
} catch (e) {
|
|
62
|
-
if (e instanceof
|
|
62
|
+
if (e instanceof _chunkFWISIR26cjs.DecodeError) {
|
|
63
63
|
return { ok: false, error: e };
|
|
64
64
|
}
|
|
65
65
|
throw e;
|
|
@@ -97,7 +97,11 @@ function readGroupOrder(reader) {
|
|
|
97
97
|
const wire = reader.readUint8();
|
|
98
98
|
const value = WIRE_TO_GROUP_ORDER.get(wire);
|
|
99
99
|
if (value === void 0) {
|
|
100
|
-
throw new (0,
|
|
100
|
+
throw new (0, _chunkFWISIR26cjs.DecodeError)(
|
|
101
|
+
"CONSTRAINT_VIOLATION",
|
|
102
|
+
`Invalid group order value: ${wire}`,
|
|
103
|
+
reader.offset - 1
|
|
104
|
+
);
|
|
101
105
|
}
|
|
102
106
|
return value;
|
|
103
107
|
}
|
|
@@ -341,7 +345,11 @@ var dataStreamEncoders = {
|
|
|
341
345
|
function decodeClientSetup(reader) {
|
|
342
346
|
const numVersions = reader.readVarInt();
|
|
343
347
|
if (numVersions === 0n) {
|
|
344
|
-
throw new (0,
|
|
348
|
+
throw new (0, _chunkFWISIR26cjs.DecodeError)(
|
|
349
|
+
"CONSTRAINT_VIOLATION",
|
|
350
|
+
"supported_versions must not be empty",
|
|
351
|
+
reader.offset
|
|
352
|
+
);
|
|
345
353
|
}
|
|
346
354
|
const supportedVersions = [];
|
|
347
355
|
for (let i = 0n; i < numVersions; i++) {
|
|
@@ -365,7 +373,11 @@ function decodeSubscribe(reader) {
|
|
|
365
373
|
const filterTypeWire = reader.readVarInt();
|
|
366
374
|
const filterType = WIRE_TO_FILTER_TYPE.get(filterTypeWire);
|
|
367
375
|
if (filterType === void 0) {
|
|
368
|
-
throw new (0,
|
|
376
|
+
throw new (0, _chunkFWISIR26cjs.DecodeError)(
|
|
377
|
+
"CONSTRAINT_VIOLATION",
|
|
378
|
+
`Invalid filter type: ${filterTypeWire}`,
|
|
379
|
+
reader.offset
|
|
380
|
+
);
|
|
369
381
|
}
|
|
370
382
|
const base = {
|
|
371
383
|
type: "subscribe",
|
|
@@ -405,10 +417,26 @@ function decodeSubscribeOk(reader) {
|
|
|
405
417
|
const largestGroupId = reader.readVarInt();
|
|
406
418
|
const largestObjectId = reader.readVarInt();
|
|
407
419
|
const parameters2 = reader.readParameters();
|
|
408
|
-
return {
|
|
420
|
+
return {
|
|
421
|
+
type: "subscribe_ok",
|
|
422
|
+
subscribeId,
|
|
423
|
+
expires,
|
|
424
|
+
groupOrder,
|
|
425
|
+
contentExists,
|
|
426
|
+
largestGroupId,
|
|
427
|
+
largestObjectId,
|
|
428
|
+
parameters: parameters2
|
|
429
|
+
};
|
|
409
430
|
}
|
|
410
431
|
const parameters = reader.readParameters();
|
|
411
|
-
return {
|
|
432
|
+
return {
|
|
433
|
+
type: "subscribe_ok",
|
|
434
|
+
subscribeId,
|
|
435
|
+
expires,
|
|
436
|
+
groupOrder,
|
|
437
|
+
contentExists,
|
|
438
|
+
parameters
|
|
439
|
+
};
|
|
412
440
|
}
|
|
413
441
|
function decodeSubscribeError(reader) {
|
|
414
442
|
const subscribeId = reader.readVarInt();
|
|
@@ -426,7 +454,15 @@ function decodeSubscribeDone(reader) {
|
|
|
426
454
|
if (contentExists) {
|
|
427
455
|
const finalGroupId = reader.readVarInt();
|
|
428
456
|
const finalObjectId = reader.readVarInt();
|
|
429
|
-
return {
|
|
457
|
+
return {
|
|
458
|
+
type: "subscribe_done",
|
|
459
|
+
subscribeId,
|
|
460
|
+
statusCode,
|
|
461
|
+
reasonPhrase,
|
|
462
|
+
contentExists,
|
|
463
|
+
finalGroupId,
|
|
464
|
+
finalObjectId
|
|
465
|
+
};
|
|
430
466
|
}
|
|
431
467
|
return { type: "subscribe_done", subscribeId, statusCode, reasonPhrase, contentExists };
|
|
432
468
|
}
|
|
@@ -438,7 +474,16 @@ function decodeSubscribeUpdate(reader) {
|
|
|
438
474
|
const endObject = reader.readVarInt();
|
|
439
475
|
const subscriberPriority = reader.readUint8();
|
|
440
476
|
const parameters = reader.readParameters();
|
|
441
|
-
return {
|
|
477
|
+
return {
|
|
478
|
+
type: "subscribe_update",
|
|
479
|
+
subscribeId,
|
|
480
|
+
startGroup,
|
|
481
|
+
startObject,
|
|
482
|
+
endGroup,
|
|
483
|
+
endObject,
|
|
484
|
+
subscriberPriority,
|
|
485
|
+
parameters
|
|
486
|
+
};
|
|
442
487
|
}
|
|
443
488
|
function decodeUnsubscribe(reader) {
|
|
444
489
|
const subscribeId = reader.readVarInt();
|
|
@@ -520,7 +565,19 @@ function decodeFetch(reader) {
|
|
|
520
565
|
const endGroup = reader.readVarInt();
|
|
521
566
|
const endObject = reader.readVarInt();
|
|
522
567
|
const parameters = reader.readParameters();
|
|
523
|
-
return {
|
|
568
|
+
return {
|
|
569
|
+
type: "fetch",
|
|
570
|
+
subscribeId,
|
|
571
|
+
trackNamespace,
|
|
572
|
+
trackName,
|
|
573
|
+
subscriberPriority,
|
|
574
|
+
groupOrder,
|
|
575
|
+
startGroup,
|
|
576
|
+
startObject,
|
|
577
|
+
endGroup,
|
|
578
|
+
endObject,
|
|
579
|
+
parameters
|
|
580
|
+
};
|
|
524
581
|
}
|
|
525
582
|
function decodeFetchOk(reader) {
|
|
526
583
|
const subscribeId = reader.readVarInt();
|
|
@@ -530,7 +587,15 @@ function decodeFetchOk(reader) {
|
|
|
530
587
|
const largestGroupId = reader.readVarInt();
|
|
531
588
|
const largestObjectId = reader.readVarInt();
|
|
532
589
|
const parameters = reader.readParameters();
|
|
533
|
-
return {
|
|
590
|
+
return {
|
|
591
|
+
type: "fetch_ok",
|
|
592
|
+
subscribeId,
|
|
593
|
+
groupOrder,
|
|
594
|
+
endOfTrack,
|
|
595
|
+
largestGroupId,
|
|
596
|
+
largestObjectId,
|
|
597
|
+
parameters
|
|
598
|
+
};
|
|
534
599
|
}
|
|
535
600
|
function decodeFetchError(reader) {
|
|
536
601
|
const subscribeId = reader.readVarInt();
|
|
@@ -550,7 +615,15 @@ function decodeObjectStream(reader) {
|
|
|
550
615
|
const publisherPriority = reader.readUint8();
|
|
551
616
|
const objectStatusRaw = Number(reader.readVarInt());
|
|
552
617
|
const payload = reader.readBytes(reader.remaining);
|
|
553
|
-
const base = {
|
|
618
|
+
const base = {
|
|
619
|
+
type: "object_stream",
|
|
620
|
+
subscribeId,
|
|
621
|
+
trackAlias,
|
|
622
|
+
groupId,
|
|
623
|
+
objectId,
|
|
624
|
+
publisherPriority,
|
|
625
|
+
payload
|
|
626
|
+
};
|
|
554
627
|
if (objectStatusRaw !== 0) {
|
|
555
628
|
return { ...base, objectStatus: objectStatusRaw };
|
|
556
629
|
}
|
|
@@ -564,7 +637,15 @@ function decodeObjectDatagram(reader) {
|
|
|
564
637
|
const publisherPriority = reader.readUint8();
|
|
565
638
|
const objectStatusRaw = Number(reader.readVarInt());
|
|
566
639
|
const payload = reader.readBytes(reader.remaining);
|
|
567
|
-
const base = {
|
|
640
|
+
const base = {
|
|
641
|
+
type: "object_datagram",
|
|
642
|
+
subscribeId,
|
|
643
|
+
trackAlias,
|
|
644
|
+
groupId,
|
|
645
|
+
objectId,
|
|
646
|
+
publisherPriority,
|
|
647
|
+
payload
|
|
648
|
+
};
|
|
568
649
|
if (objectStatusRaw !== 0) {
|
|
569
650
|
return { ...base, objectStatus: objectStatusRaw };
|
|
570
651
|
}
|
|
@@ -589,7 +670,14 @@ function decodeStreamHeaderSubgroup(reader) {
|
|
|
589
670
|
const groupId = reader.readVarInt();
|
|
590
671
|
const subgroupId = reader.readVarInt();
|
|
591
672
|
const publisherPriority = reader.readUint8();
|
|
592
|
-
return {
|
|
673
|
+
return {
|
|
674
|
+
type: "stream_header_subgroup",
|
|
675
|
+
subscribeId,
|
|
676
|
+
trackAlias,
|
|
677
|
+
groupId,
|
|
678
|
+
subgroupId,
|
|
679
|
+
publisherPriority
|
|
680
|
+
};
|
|
593
681
|
}
|
|
594
682
|
var controlDecoders = /* @__PURE__ */ new Map([
|
|
595
683
|
[MESSAGE_TYPE_IDS.client_setup, decodeClientSetup],
|
|
@@ -655,7 +743,7 @@ var MESSAGE_TYPE_TO_WIRE = {
|
|
|
655
743
|
function encodeMessageImpl(message) {
|
|
656
744
|
const dataEncoder = dataStreamEncoders[message.type];
|
|
657
745
|
if (dataEncoder) {
|
|
658
|
-
const writer = new (0,
|
|
746
|
+
const writer = new (0, _chunkFWISIR26cjs.BufferWriter)();
|
|
659
747
|
dataEncoder(message, writer);
|
|
660
748
|
return writer.finish();
|
|
661
749
|
}
|
|
@@ -663,10 +751,10 @@ function encodeMessageImpl(message) {
|
|
|
663
751
|
if (!controlEncoder) {
|
|
664
752
|
throw new Error(`Unknown message type: ${message.type}`);
|
|
665
753
|
}
|
|
666
|
-
const payloadWriter = new (0,
|
|
754
|
+
const payloadWriter = new (0, _chunkFWISIR26cjs.BufferWriter)();
|
|
667
755
|
controlEncoder(message, payloadWriter);
|
|
668
756
|
const payload = payloadWriter.finish();
|
|
669
|
-
const frameWriter = new (0,
|
|
757
|
+
const frameWriter = new (0, _chunkFWISIR26cjs.BufferWriter)();
|
|
670
758
|
frameWriter.writeVarInt(MESSAGE_TYPE_TO_WIRE[message.type]);
|
|
671
759
|
frameWriter.writeVarInt(payload.byteLength);
|
|
672
760
|
frameWriter.writeBytes(payload);
|
|
@@ -674,25 +762,33 @@ function encodeMessageImpl(message) {
|
|
|
674
762
|
}
|
|
675
763
|
function decodeMessageImpl(bytes) {
|
|
676
764
|
try {
|
|
677
|
-
const reader = new (0,
|
|
765
|
+
const reader = new (0, _chunkFWISIR26cjs.BufferReader)(bytes, 0);
|
|
678
766
|
const typeId = reader.readVarInt();
|
|
679
767
|
if (DATA_STREAM_TYPE_IDS.has(typeId)) {
|
|
680
768
|
const decoder2 = dataStreamDecoders.get(typeId);
|
|
681
769
|
if (!decoder2) {
|
|
682
770
|
return {
|
|
683
771
|
ok: false,
|
|
684
|
-
error: new (0,
|
|
772
|
+
error: new (0, _chunkFWISIR26cjs.DecodeError)(
|
|
773
|
+
"UNKNOWN_MESSAGE_TYPE",
|
|
774
|
+
`Unknown data stream type ID: 0x${typeId.toString(16)}`,
|
|
775
|
+
0
|
|
776
|
+
)
|
|
685
777
|
};
|
|
686
778
|
}
|
|
687
779
|
const message2 = decoder2(reader);
|
|
688
780
|
return { ok: true, value: message2, bytesRead: reader.offset };
|
|
689
781
|
}
|
|
690
782
|
const payloadLength = Number(reader.readVarInt());
|
|
691
|
-
const
|
|
783
|
+
const _headerBytes = reader.offset;
|
|
692
784
|
if (reader.remaining < payloadLength) {
|
|
693
785
|
return {
|
|
694
786
|
ok: false,
|
|
695
|
-
error: new (0,
|
|
787
|
+
error: new (0, _chunkFWISIR26cjs.DecodeError)(
|
|
788
|
+
"UNEXPECTED_END",
|
|
789
|
+
`Not enough bytes for payload: need ${payloadLength}, have ${reader.remaining}`,
|
|
790
|
+
reader.offset
|
|
791
|
+
)
|
|
696
792
|
};
|
|
697
793
|
}
|
|
698
794
|
const payloadBytes = reader.readBytes(payloadLength);
|
|
@@ -701,14 +797,18 @@ function decodeMessageImpl(bytes) {
|
|
|
701
797
|
if (!decoder) {
|
|
702
798
|
return {
|
|
703
799
|
ok: false,
|
|
704
|
-
error: new (0,
|
|
800
|
+
error: new (0, _chunkFWISIR26cjs.DecodeError)(
|
|
801
|
+
"UNKNOWN_MESSAGE_TYPE",
|
|
802
|
+
`Unknown message type ID: 0x${typeId.toString(16)}`,
|
|
803
|
+
0
|
|
804
|
+
)
|
|
705
805
|
};
|
|
706
806
|
}
|
|
707
|
-
const payloadReader = new (0,
|
|
807
|
+
const payloadReader = new (0, _chunkFWISIR26cjs.BufferReader)(payloadBytes, 0);
|
|
708
808
|
const message = decoder(payloadReader);
|
|
709
809
|
return { ok: true, value: message, bytesRead: totalBytesRead };
|
|
710
810
|
} catch (e) {
|
|
711
|
-
if (e instanceof
|
|
811
|
+
if (e instanceof _chunkFWISIR26cjs.DecodeError) {
|
|
712
812
|
return { ok: false, error: e };
|
|
713
813
|
}
|
|
714
814
|
throw e;
|
|
@@ -738,7 +838,7 @@ function createStreamDecoderImpl() {
|
|
|
738
838
|
flush(controller) {
|
|
739
839
|
if (buffer.length > 0) {
|
|
740
840
|
controller.error(
|
|
741
|
-
new (0,
|
|
841
|
+
new (0, _chunkFWISIR26cjs.DecodeError)("UNEXPECTED_END", "Stream ended with incomplete message data", 0)
|
|
742
842
|
);
|
|
743
843
|
}
|
|
744
844
|
}
|
|
@@ -39,10 +39,20 @@ var SessionFSM = class {
|
|
|
39
39
|
checkRole(message, direction) {
|
|
40
40
|
const senderRole = direction === "outbound" ? this._role : this._role === "client" ? "server" : "client";
|
|
41
41
|
if (CLIENT_ONLY_MESSAGES.has(message.type) && senderRole !== "client") {
|
|
42
|
-
return violation(
|
|
42
|
+
return violation(
|
|
43
|
+
"ROLE_VIOLATION",
|
|
44
|
+
`${message.type} can only be sent by client`,
|
|
45
|
+
this._phase,
|
|
46
|
+
message.type
|
|
47
|
+
);
|
|
43
48
|
}
|
|
44
49
|
if (SERVER_ONLY_MESSAGES.has(message.type) && senderRole !== "server") {
|
|
45
|
-
return violation(
|
|
50
|
+
return violation(
|
|
51
|
+
"ROLE_VIOLATION",
|
|
52
|
+
`${message.type} can only be sent by server`,
|
|
53
|
+
this._phase,
|
|
54
|
+
message.type
|
|
55
|
+
);
|
|
46
56
|
}
|
|
47
57
|
return null;
|
|
48
58
|
}
|
|
@@ -116,27 +126,67 @@ var SessionFSM = class {
|
|
|
116
126
|
}
|
|
117
127
|
handleClientSetup(_message, direction) {
|
|
118
128
|
if (this._phase !== "idle") {
|
|
119
|
-
return {
|
|
129
|
+
return {
|
|
130
|
+
ok: false,
|
|
131
|
+
violation: violation(
|
|
132
|
+
"SETUP_VIOLATION",
|
|
133
|
+
"CLIENT_SETUP already sent/received",
|
|
134
|
+
this._phase,
|
|
135
|
+
"client_setup"
|
|
136
|
+
)
|
|
137
|
+
};
|
|
120
138
|
}
|
|
121
139
|
if (direction === "outbound" && this._role !== "client") {
|
|
122
|
-
return {
|
|
140
|
+
return {
|
|
141
|
+
ok: false,
|
|
142
|
+
violation: violation(
|
|
143
|
+
"ROLE_VIOLATION",
|
|
144
|
+
"Only client can send CLIENT_SETUP",
|
|
145
|
+
this._phase,
|
|
146
|
+
"client_setup"
|
|
147
|
+
)
|
|
148
|
+
};
|
|
123
149
|
}
|
|
124
150
|
this._phase = "setup";
|
|
125
151
|
return { ok: true, phase: this._phase, sideEffects: [] };
|
|
126
152
|
}
|
|
127
153
|
handleServerSetup(_message, direction) {
|
|
128
154
|
if (this._phase !== "setup") {
|
|
129
|
-
return {
|
|
155
|
+
return {
|
|
156
|
+
ok: false,
|
|
157
|
+
violation: violation(
|
|
158
|
+
"SETUP_VIOLATION",
|
|
159
|
+
"SERVER_SETUP before CLIENT_SETUP",
|
|
160
|
+
this._phase,
|
|
161
|
+
"server_setup"
|
|
162
|
+
)
|
|
163
|
+
};
|
|
130
164
|
}
|
|
131
165
|
if (direction === "outbound" && this._role !== "server") {
|
|
132
|
-
return {
|
|
166
|
+
return {
|
|
167
|
+
ok: false,
|
|
168
|
+
violation: violation(
|
|
169
|
+
"ROLE_VIOLATION",
|
|
170
|
+
"Only server can send SERVER_SETUP",
|
|
171
|
+
this._phase,
|
|
172
|
+
"server_setup"
|
|
173
|
+
)
|
|
174
|
+
};
|
|
133
175
|
}
|
|
134
176
|
this._phase = "ready";
|
|
135
177
|
return { ok: true, phase: this._phase, sideEffects: [{ type: "session-ready" }] };
|
|
136
178
|
}
|
|
137
179
|
handleGoAway(message, _direction, sideEffects) {
|
|
138
180
|
if (this._phase !== "ready" && this._phase !== "draining") {
|
|
139
|
-
return {
|
|
181
|
+
return {
|
|
182
|
+
ok: false,
|
|
183
|
+
violation: violation(
|
|
184
|
+
"UNEXPECTED_MESSAGE",
|
|
185
|
+
`GOAWAY not valid in phase ${this._phase}`,
|
|
186
|
+
this._phase,
|
|
187
|
+
"goaway"
|
|
188
|
+
)
|
|
189
|
+
};
|
|
140
190
|
}
|
|
141
191
|
this._phase = "draining";
|
|
142
192
|
const goaway = message;
|
|
@@ -159,7 +209,15 @@ var SessionFSM = class {
|
|
|
159
209
|
if (err) return { ok: false, violation: err };
|
|
160
210
|
const sub = message;
|
|
161
211
|
if (this._subscriptions.has(sub.subscribeId)) {
|
|
162
|
-
return {
|
|
212
|
+
return {
|
|
213
|
+
ok: false,
|
|
214
|
+
violation: violation(
|
|
215
|
+
"DUPLICATE_SUBSCRIBE_ID",
|
|
216
|
+
`Subscribe ID ${sub.subscribeId} already exists`,
|
|
217
|
+
this._phase,
|
|
218
|
+
message.type
|
|
219
|
+
)
|
|
220
|
+
};
|
|
163
221
|
}
|
|
164
222
|
this._subscriptions.set(sub.subscribeId, {
|
|
165
223
|
subscribeId: sub.subscribeId,
|
|
@@ -175,10 +233,26 @@ var SessionFSM = class {
|
|
|
175
233
|
const ok = message;
|
|
176
234
|
const existing = this._subscriptions.get(ok.subscribeId);
|
|
177
235
|
if (!existing) {
|
|
178
|
-
return {
|
|
236
|
+
return {
|
|
237
|
+
ok: false,
|
|
238
|
+
violation: violation(
|
|
239
|
+
"UNKNOWN_SUBSCRIBE_ID",
|
|
240
|
+
`No subscription with ID ${ok.subscribeId}`,
|
|
241
|
+
this._phase,
|
|
242
|
+
message.type
|
|
243
|
+
)
|
|
244
|
+
};
|
|
179
245
|
}
|
|
180
246
|
if (existing.phase !== "pending") {
|
|
181
|
-
return {
|
|
247
|
+
return {
|
|
248
|
+
ok: false,
|
|
249
|
+
violation: violation(
|
|
250
|
+
"STATE_VIOLATION",
|
|
251
|
+
`Subscription ${ok.subscribeId} is ${existing.phase}, not pending`,
|
|
252
|
+
this._phase,
|
|
253
|
+
message.type
|
|
254
|
+
)
|
|
255
|
+
};
|
|
182
256
|
}
|
|
183
257
|
this._subscriptions.set(ok.subscribeId, { ...existing, phase: "active" });
|
|
184
258
|
sideEffects.push({ type: "subscription-activated", subscribeId: ok.subscribeId });
|
|
@@ -190,13 +264,33 @@ var SessionFSM = class {
|
|
|
190
264
|
const subErr = message;
|
|
191
265
|
const existing = this._subscriptions.get(subErr.subscribeId);
|
|
192
266
|
if (!existing) {
|
|
193
|
-
return {
|
|
267
|
+
return {
|
|
268
|
+
ok: false,
|
|
269
|
+
violation: violation(
|
|
270
|
+
"UNKNOWN_SUBSCRIBE_ID",
|
|
271
|
+
`No subscription with ID ${subErr.subscribeId}`,
|
|
272
|
+
this._phase,
|
|
273
|
+
message.type
|
|
274
|
+
)
|
|
275
|
+
};
|
|
194
276
|
}
|
|
195
277
|
if (existing.phase !== "pending") {
|
|
196
|
-
return {
|
|
278
|
+
return {
|
|
279
|
+
ok: false,
|
|
280
|
+
violation: violation(
|
|
281
|
+
"STATE_VIOLATION",
|
|
282
|
+
`Subscription ${subErr.subscribeId} is ${existing.phase}, not pending`,
|
|
283
|
+
this._phase,
|
|
284
|
+
message.type
|
|
285
|
+
)
|
|
286
|
+
};
|
|
197
287
|
}
|
|
198
288
|
this._subscriptions.set(subErr.subscribeId, { ...existing, phase: "error" });
|
|
199
|
-
sideEffects.push({
|
|
289
|
+
sideEffects.push({
|
|
290
|
+
type: "subscription-ended",
|
|
291
|
+
subscribeId: subErr.subscribeId,
|
|
292
|
+
reason: subErr.reasonPhrase
|
|
293
|
+
});
|
|
200
294
|
return { ok: true, phase: this._phase, sideEffects };
|
|
201
295
|
}
|
|
202
296
|
handleSubscribeDone(message, _direction, sideEffects) {
|
|
@@ -205,10 +299,22 @@ var SessionFSM = class {
|
|
|
205
299
|
const done = message;
|
|
206
300
|
const existing = this._subscriptions.get(done.subscribeId);
|
|
207
301
|
if (!existing) {
|
|
208
|
-
return {
|
|
302
|
+
return {
|
|
303
|
+
ok: false,
|
|
304
|
+
violation: violation(
|
|
305
|
+
"UNKNOWN_SUBSCRIBE_ID",
|
|
306
|
+
`No subscription with ID ${done.subscribeId}`,
|
|
307
|
+
this._phase,
|
|
308
|
+
message.type
|
|
309
|
+
)
|
|
310
|
+
};
|
|
209
311
|
}
|
|
210
312
|
this._subscriptions.set(done.subscribeId, { ...existing, phase: "done" });
|
|
211
|
-
sideEffects.push({
|
|
313
|
+
sideEffects.push({
|
|
314
|
+
type: "subscription-ended",
|
|
315
|
+
subscribeId: done.subscribeId,
|
|
316
|
+
reason: done.reasonPhrase
|
|
317
|
+
});
|
|
212
318
|
return { ok: true, phase: this._phase, sideEffects };
|
|
213
319
|
}
|
|
214
320
|
handleUnsubscribe(message, _direction, sideEffects) {
|
|
@@ -217,10 +323,22 @@ var SessionFSM = class {
|
|
|
217
323
|
const unsub = message;
|
|
218
324
|
const existing = this._subscriptions.get(unsub.subscribeId);
|
|
219
325
|
if (!existing) {
|
|
220
|
-
return {
|
|
326
|
+
return {
|
|
327
|
+
ok: false,
|
|
328
|
+
violation: violation(
|
|
329
|
+
"UNKNOWN_SUBSCRIBE_ID",
|
|
330
|
+
`No subscription with ID ${unsub.subscribeId}`,
|
|
331
|
+
this._phase,
|
|
332
|
+
message.type
|
|
333
|
+
)
|
|
334
|
+
};
|
|
221
335
|
}
|
|
222
336
|
this._subscriptions.set(unsub.subscribeId, { ...existing, phase: "done" });
|
|
223
|
-
sideEffects.push({
|
|
337
|
+
sideEffects.push({
|
|
338
|
+
type: "subscription-ended",
|
|
339
|
+
subscribeId: unsub.subscribeId,
|
|
340
|
+
reason: "unsubscribed"
|
|
341
|
+
});
|
|
224
342
|
return { ok: true, phase: this._phase, sideEffects };
|
|
225
343
|
}
|
|
226
344
|
// Announce handlers
|
|
@@ -242,7 +360,15 @@ var SessionFSM = class {
|
|
|
242
360
|
const key = this.namespaceKey(ok.trackNamespace);
|
|
243
361
|
const existing = this._announces.get(key);
|
|
244
362
|
if (!existing) {
|
|
245
|
-
return {
|
|
363
|
+
return {
|
|
364
|
+
ok: false,
|
|
365
|
+
violation: violation(
|
|
366
|
+
"UNEXPECTED_MESSAGE",
|
|
367
|
+
`No announce for namespace ${key}`,
|
|
368
|
+
this._phase,
|
|
369
|
+
message.type
|
|
370
|
+
)
|
|
371
|
+
};
|
|
246
372
|
}
|
|
247
373
|
this._announces.set(key, { ...existing, phase: "active" });
|
|
248
374
|
sideEffects.push({ type: "announce-activated", namespace: ok.trackNamespace });
|
|
@@ -255,7 +381,15 @@ var SessionFSM = class {
|
|
|
255
381
|
const key = this.namespaceKey(annErr.trackNamespace);
|
|
256
382
|
const existing = this._announces.get(key);
|
|
257
383
|
if (!existing) {
|
|
258
|
-
return {
|
|
384
|
+
return {
|
|
385
|
+
ok: false,
|
|
386
|
+
violation: violation(
|
|
387
|
+
"UNEXPECTED_MESSAGE",
|
|
388
|
+
`No announce for namespace ${key}`,
|
|
389
|
+
this._phase,
|
|
390
|
+
message.type
|
|
391
|
+
)
|
|
392
|
+
};
|
|
259
393
|
}
|
|
260
394
|
this._announces.set(key, { ...existing, phase: "error" });
|
|
261
395
|
sideEffects.push({ type: "announce-ended", namespace: annErr.trackNamespace });
|