@moqtap/codec 0.1.0 → 0.2.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/README.md +99 -95
- package/dist/chunk-4RIXXEII.js +1275 -0
- package/dist/chunk-4XYGE53S.cjs +698 -0
- package/dist/chunk-4YJANAXU.cjs +1109 -0
- package/dist/chunk-6AEHWULA.cjs +641 -0
- package/dist/chunk-7DUBLRXC.js +680 -0
- package/dist/{chunk-WNTXF3DE.cjs → chunk-7IVGHMKJ.cjs} +164 -62
- package/dist/{chunk-YBSEOSSP.js → chunk-A27S7HW7.js} +5 -1
- package/dist/chunk-BISI45MN.cjs +680 -0
- package/dist/{chunk-3BSZ55L3.cjs → chunk-BPNL5YFQ.cjs} +158 -24
- package/dist/chunk-CXDHOMHG.js +1097 -0
- package/dist/chunk-DUBCL3WF.cjs +749 -0
- package/dist/chunk-DWK5ZQZ4.js +642 -0
- package/dist/chunk-E6E3NQYU.js +680 -0
- package/dist/chunk-EFM5T7OM.js +698 -0
- package/dist/chunk-ENURAVHI.cjs +680 -0
- package/dist/{chunk-5WFXFLL4.cjs → chunk-FUFTMAQD.cjs} +96 -63
- package/dist/{chunk-2NARXGVA.cjs → chunk-FWISIR26.cjs} +5 -1
- package/dist/{chunk-YPXLV5YK.js → chunk-FXZ2MYKJ.js} +376 -38
- package/dist/chunk-G26SJ6XS.cjs +1341 -0
- package/dist/chunk-G7GI7LJA.js +737 -0
- package/dist/chunk-GXEW4COZ.cjs +737 -0
- package/dist/chunk-HSVYF6XX.cjs +1361 -0
- package/dist/chunk-IBVM4DMJ.cjs +1097 -0
- package/dist/chunk-IV2H5CFI.cjs +1275 -0
- package/dist/chunk-IV2HRJVT.js +1198 -0
- package/dist/chunk-JSQM2MG3.js +680 -0
- package/dist/chunk-K4OLITS2.cjs +1055 -0
- package/dist/{chunk-UOBWHJA5.js → chunk-KFTCU2P6.js} +2 -3
- package/dist/chunk-LH4NTURO.js +1361 -0
- package/dist/{chunk-DC4L6ZIT.js → chunk-MFAP7R6L.js} +154 -20
- package/dist/chunk-NGVE2RZT.js +1097 -0
- package/dist/chunk-NUX5BHWO.js +1341 -0
- package/dist/chunk-PJRA2TQ5.js +1055 -0
- package/dist/chunk-RVJAGE4S.cjs +1198 -0
- package/dist/{chunk-QYG6KGOV.cjs → chunk-RWQ43Z4F.cjs} +2 -3
- package/dist/chunk-RZHAPEXO.js +749 -0
- package/dist/chunk-ST24APEO.js +1109 -0
- package/dist/chunk-SYHW3FLI.cjs +642 -0
- package/dist/chunk-TLYNOOQP.cjs +432 -0
- package/dist/{chunk-23YG7F46.js → chunk-TMNGRIPL.js} +153 -51
- package/dist/{chunk-IQPDRQVC.js → chunk-U2B3B42P.js} +62 -29
- package/dist/chunk-UNS34PTA.cjs +680 -0
- package/dist/chunk-UR6JKS56.js +432 -0
- package/dist/{chunk-GDRGWFEK.cjs → chunk-UYXTY6ZQ.cjs} +376 -38
- package/dist/chunk-XUUCOLWU.cjs +1097 -0
- package/dist/chunk-YG5KJESI.js +641 -0
- package/dist/chunk-ZBKE2QRQ.js +1401 -0
- package/dist/chunk-ZSPO2GF2.cjs +1401 -0
- package/dist/codec-95k8CAu5.d.cts +35 -0
- package/dist/codec-AFuOxfsO.d.ts +60 -0
- package/dist/codec-B-UJ5Iow.d.cts +75 -0
- package/dist/codec-BC5jfvMb.d.ts +35 -0
- package/dist/codec-BECYPfY8.d.ts +35 -0
- package/dist/codec-BsPU1vNC.d.ts +39 -0
- package/dist/codec-BvpuF-6u.d.cts +39 -0
- package/dist/codec-C8jZI5Cx.d.cts +39 -0
- package/dist/codec-CAevkgf5.d.cts +33 -0
- package/dist/codec-CSUqCrRs.d.ts +39 -0
- package/dist/codec-C_HMXNK_.d.ts +33 -0
- package/dist/{codec-CTvFtQQI.d.cts → codec-CpuvYTSV.d.cts} +5 -5
- package/dist/codec-D0x8-SCw.d.cts +35 -0
- package/dist/codec-D7ARhpG1.d.ts +75 -0
- package/dist/codec-DNAUGshO.d.cts +60 -0
- package/dist/codec-DPx_QNn0.d.ts +31 -0
- package/dist/{codec-qPzfmLNu.d.ts → codec-DRhCx_hw.d.ts} +5 -5
- package/dist/codec-Db7YPe3l.d.ts +31 -0
- package/dist/codec-axkJpb7D.d.cts +31 -0
- package/dist/codec-ujAbFaep.d.cts +31 -0
- package/dist/draft10-session.cjs +6 -0
- package/dist/draft10-session.d.cts +8 -0
- package/dist/draft10-session.d.ts +8 -0
- package/dist/draft10-session.js +6 -0
- package/dist/draft10.cjs +115 -0
- package/dist/draft10.d.cts +95 -0
- package/dist/draft10.d.ts +95 -0
- package/dist/draft10.js +115 -0
- package/dist/draft11-session.cjs +6 -0
- package/dist/draft11-session.d.cts +8 -0
- package/dist/draft11-session.d.ts +8 -0
- package/dist/draft11-session.js +6 -0
- package/dist/draft11.cjs +109 -0
- package/dist/draft11.d.cts +99 -0
- package/dist/draft11.d.ts +99 -0
- package/dist/draft11.js +109 -0
- package/dist/draft12-session.cjs +6 -0
- package/dist/draft12-session.d.cts +8 -0
- package/dist/draft12-session.d.ts +8 -0
- package/dist/draft12-session.js +6 -0
- package/dist/draft12.cjs +117 -0
- package/dist/draft12.d.cts +106 -0
- package/dist/draft12.d.ts +106 -0
- package/dist/draft12.js +117 -0
- package/dist/draft13-session.cjs +6 -0
- package/dist/draft13-session.d.cts +8 -0
- package/dist/draft13-session.d.ts +8 -0
- package/dist/draft13-session.js +6 -0
- package/dist/draft13.cjs +119 -0
- package/dist/draft13.d.cts +108 -0
- package/dist/draft13.d.ts +108 -0
- package/dist/draft13.js +119 -0
- 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 +27 -15
- package/dist/draft14.d.ts +27 -15
- package/dist/draft14.js +3 -3
- package/dist/draft15-session.cjs +6 -0
- package/dist/draft15-session.d.cts +8 -0
- package/dist/draft15-session.d.ts +8 -0
- package/dist/draft15-session.js +6 -0
- package/dist/draft15.cjs +111 -0
- package/dist/draft15.d.cts +93 -0
- package/dist/draft15.d.ts +93 -0
- package/dist/draft15.js +111 -0
- package/dist/draft16-session.cjs +6 -0
- package/dist/draft16-session.d.cts +8 -0
- package/dist/draft16-session.d.ts +8 -0
- package/dist/draft16-session.js +6 -0
- package/dist/draft16.cjs +113 -0
- package/dist/draft16.d.cts +94 -0
- package/dist/draft16.d.ts +94 -0
- package/dist/draft16.js +113 -0
- package/dist/draft17-session.cjs +8 -0
- package/dist/draft17-session.d.cts +51 -0
- package/dist/draft17-session.d.ts +51 -0
- package/dist/draft17-session.js +8 -0
- package/dist/draft17.cjs +99 -0
- package/dist/draft17.d.cts +40 -0
- package/dist/draft17.d.ts +40 -0
- package/dist/draft17.js +99 -0
- package/dist/draft7-session.cjs +3 -3
- package/dist/draft7-session.d.cts +3 -3
- package/dist/draft7-session.d.ts +3 -3
- package/dist/draft7-session.js +2 -2
- package/dist/draft7.cjs +6 -6
- package/dist/draft7.d.cts +10 -10
- package/dist/draft7.d.ts +10 -10
- package/dist/draft7.js +3 -3
- package/dist/draft8-session.cjs +6 -0
- package/dist/draft8-session.d.cts +8 -0
- package/dist/draft8-session.d.ts +8 -0
- package/dist/draft8-session.js +6 -0
- package/dist/draft8.cjs +115 -0
- package/dist/draft8.d.cts +95 -0
- package/dist/draft8.d.ts +95 -0
- package/dist/draft8.js +115 -0
- package/dist/draft9-session.cjs +6 -0
- package/dist/draft9-session.d.cts +8 -0
- package/dist/draft9-session.d.ts +8 -0
- package/dist/draft9-session.js +6 -0
- package/dist/draft9.cjs +115 -0
- package/dist/draft9.d.cts +95 -0
- package/dist/draft9.d.ts +95 -0
- package/dist/draft9.js +115 -0
- package/dist/index.cjs +79 -7
- package/dist/index.d.cts +71 -8
- package/dist/index.d.ts +71 -8
- package/dist/index.js +77 -5
- package/dist/{session-types-B9NIf7_F.d.ts → session-types-CJIFbTPd.d.ts} +20 -20
- package/dist/{session-types-CCo-oA-d.d.cts → session-types-Cbq8IGCP.d.cts} +20 -20
- package/dist/session.cjs +5 -5
- package/dist/session.d.cts +3 -3
- package/dist/session.d.ts +3 -3
- package/dist/session.js +5 -5
- package/dist/types-4VxSL2Ho.d.cts +261 -0
- package/dist/types-4VxSL2Ho.d.ts +261 -0
- package/dist/types-B2afJZM-.d.cts +236 -0
- package/dist/types-B2afJZM-.d.ts +236 -0
- 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-Bg6QYNVt.d.cts +290 -0
- package/dist/types-Bg6QYNVt.d.ts +290 -0
- package/dist/types-C_1HrqBl.d.cts +306 -0
- package/dist/types-C_1HrqBl.d.ts +306 -0
- package/dist/types-Cw4WE9dh.d.cts +261 -0
- package/dist/types-Cw4WE9dh.d.ts +261 -0
- package/dist/types-D5gNQiDj.d.cts +261 -0
- package/dist/types-D5gNQiDj.d.ts +261 -0
- package/dist/types-DqCDFqgB.d.cts +230 -0
- package/dist/types-DqCDFqgB.d.ts +230 -0
- package/dist/types-ERexTpT8.d.cts +217 -0
- package/dist/types-ERexTpT8.d.ts +217 -0
- package/dist/{types-ClXELFGN.d.cts → types-QNXoxC9Y.d.cts} +36 -41
- package/dist/{types-ClXELFGN.d.ts → types-QNXoxC9Y.d.ts} +36 -41
- package/dist/types-r-CasCf1.d.cts +262 -0
- package/dist/types-r-CasCf1.d.ts +262 -0
- package/package.json +116 -8
- 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 +92 -75
- package/src/drafts/draft07/announce-fsm.ts +1 -1
- package/src/drafts/draft07/codec.ts +235 -118
- 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 +67 -38
- 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/draft08/codec.ts +1254 -0
- package/src/drafts/draft08/index.ts +125 -0
- package/src/drafts/draft08/messages.ts +72 -0
- package/src/drafts/draft08/rules.ts +91 -0
- package/src/drafts/draft08/session-fsm.ts +718 -0
- package/src/drafts/draft08/session.ts +26 -0
- package/src/drafts/draft08/types.ts +377 -0
- package/src/drafts/draft09/codec.ts +1235 -0
- package/src/drafts/draft09/index.ts +125 -0
- package/src/drafts/draft09/messages.ts +72 -0
- package/src/drafts/draft09/rules.ts +91 -0
- package/src/drafts/draft09/session-fsm.ts +718 -0
- package/src/drafts/draft09/session.ts +26 -0
- package/src/drafts/draft09/types.ts +376 -0
- package/src/drafts/draft10/codec.ts +1235 -0
- package/src/drafts/draft10/index.ts +125 -0
- package/src/drafts/draft10/messages.ts +72 -0
- package/src/drafts/draft10/rules.ts +91 -0
- package/src/drafts/draft10/session-fsm.ts +718 -0
- package/src/drafts/draft10/session.ts +26 -0
- package/src/drafts/draft10/types.ts +376 -0
- package/src/drafts/draft11/codec.ts +1198 -0
- package/src/drafts/draft11/index.ts +123 -0
- package/src/drafts/draft11/messages.ts +71 -0
- package/src/drafts/draft11/rules.ts +100 -0
- package/src/drafts/draft11/session-fsm.ts +758 -0
- package/src/drafts/draft11/session.ts +26 -0
- package/src/drafts/draft11/types.ts +375 -0
- package/src/drafts/draft12/codec.ts +1354 -0
- package/src/drafts/draft12/index.ts +130 -0
- package/src/drafts/draft12/messages.ts +84 -0
- package/src/drafts/draft12/rules.ts +106 -0
- package/src/drafts/draft12/session-fsm.ts +805 -0
- package/src/drafts/draft12/session.ts +26 -0
- package/src/drafts/draft12/types.ts +414 -0
- package/src/drafts/draft13/codec.ts +1438 -0
- package/src/drafts/draft13/index.ts +132 -0
- package/src/drafts/draft13/messages.ts +86 -0
- package/src/drafts/draft13/rules.ts +108 -0
- package/src/drafts/draft13/session-fsm.ts +819 -0
- package/src/drafts/draft13/session.ts +26 -0
- package/src/drafts/draft13/types.ts +433 -0
- 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 +640 -147
- package/src/drafts/draft14/session.ts +13 -13
- package/src/drafts/draft14/types.ts +68 -68
- package/src/drafts/draft15/codec.ts +1661 -0
- package/src/drafts/draft15/index.ts +121 -0
- package/src/drafts/draft15/messages.ts +64 -0
- package/src/drafts/draft15/rules.ts +95 -0
- package/src/drafts/draft15/session-fsm.ts +687 -0
- package/src/drafts/draft15/session.ts +26 -0
- package/src/drafts/draft15/types.ts +336 -0
- package/src/drafts/draft16/codec.ts +1623 -0
- package/src/drafts/draft16/index.ts +123 -0
- package/src/drafts/draft16/messages.ts +67 -0
- package/src/drafts/draft16/rules.ts +96 -0
- package/src/drafts/draft16/session-fsm.ts +682 -0
- package/src/drafts/draft16/session.ts +26 -0
- package/src/drafts/draft16/types.ts +354 -0
- package/src/drafts/draft17/codec.ts +1621 -0
- package/src/drafts/draft17/index.ts +105 -0
- package/src/drafts/draft17/messages.ts +53 -0
- package/src/drafts/draft17/rules.ts +85 -0
- package/src/drafts/draft17/session-fsm.ts +437 -0
- package/src/drafts/draft17/session.ts +15 -0
- package/src/drafts/draft17/types.ts +310 -0
- package/src/index.ts +283 -33
- package/src/session.ts +20 -20
|
@@ -1,33 +1,51 @@
|
|
|
1
|
-
import type { MoqtMessage, MoqtMessageType } from '../../core/types.js';
|
|
2
1
|
import type {
|
|
3
|
-
|
|
4
|
-
TransitionResult,
|
|
5
|
-
ValidationResult,
|
|
2
|
+
AnnounceState,
|
|
6
3
|
ProtocolViolation,
|
|
4
|
+
SessionPhase,
|
|
7
5
|
SideEffect,
|
|
8
6
|
SubscriptionState,
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
7
|
+
TransitionResult,
|
|
8
|
+
ValidationResult,
|
|
9
|
+
} from "../../core/session-types.js";
|
|
10
|
+
import type { MoqtMessage, MoqtMessageType } from "../../core/types.js";
|
|
11
|
+
import {
|
|
12
|
+
CLIENT_ONLY_MESSAGES,
|
|
13
|
+
getLegalIncoming,
|
|
14
|
+
getLegalOutgoing,
|
|
15
|
+
SERVER_ONLY_MESSAGES,
|
|
16
|
+
} from "./rules.js";
|
|
17
|
+
|
|
18
|
+
function violation(
|
|
19
|
+
code: ProtocolViolation["code"],
|
|
20
|
+
message: string,
|
|
21
|
+
currentPhase: SessionPhase,
|
|
22
|
+
offendingMessage: MoqtMessageType,
|
|
23
|
+
): ProtocolViolation {
|
|
14
24
|
return { code, message, currentPhase, offendingMessage };
|
|
15
25
|
}
|
|
16
26
|
|
|
17
27
|
export class SessionFSM {
|
|
18
|
-
private _phase: SessionPhase =
|
|
19
|
-
private _role:
|
|
28
|
+
private _phase: SessionPhase = "idle";
|
|
29
|
+
private _role: "client" | "server";
|
|
20
30
|
private _subscriptions = new Map<bigint, SubscriptionState>();
|
|
21
31
|
private _announces = new Map<string, AnnounceState>();
|
|
22
32
|
|
|
23
|
-
constructor(role:
|
|
33
|
+
constructor(role: "client" | "server") {
|
|
24
34
|
this._role = role;
|
|
25
35
|
}
|
|
26
36
|
|
|
27
|
-
get phase(): SessionPhase {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
get
|
|
37
|
+
get phase(): SessionPhase {
|
|
38
|
+
return this._phase;
|
|
39
|
+
}
|
|
40
|
+
get role(): "client" | "server" {
|
|
41
|
+
return this._role;
|
|
42
|
+
}
|
|
43
|
+
get subscriptions(): ReadonlyMap<bigint, SubscriptionState> {
|
|
44
|
+
return this._subscriptions;
|
|
45
|
+
}
|
|
46
|
+
get announces(): ReadonlyMap<string, AnnounceState> {
|
|
47
|
+
return this._announces;
|
|
48
|
+
}
|
|
31
49
|
|
|
32
50
|
get legalOutgoing(): ReadonlySet<MoqtMessageType> {
|
|
33
51
|
return getLegalOutgoing(this._phase, this._role);
|
|
@@ -38,27 +56,43 @@ export class SessionFSM {
|
|
|
38
56
|
}
|
|
39
57
|
|
|
40
58
|
// Validate role constraints
|
|
41
|
-
private checkRole(
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
59
|
+
private checkRole(
|
|
60
|
+
message: MoqtMessage,
|
|
61
|
+
direction: "inbound" | "outbound",
|
|
62
|
+
): ProtocolViolation | null {
|
|
63
|
+
const senderRole =
|
|
64
|
+
direction === "outbound" ? this._role : this._role === "client" ? "server" : "client";
|
|
65
|
+
|
|
66
|
+
if (CLIENT_ONLY_MESSAGES.has(message.type) && senderRole !== "client") {
|
|
67
|
+
return violation(
|
|
68
|
+
"ROLE_VIOLATION",
|
|
69
|
+
`${message.type} can only be sent by client`,
|
|
70
|
+
this._phase,
|
|
71
|
+
message.type,
|
|
72
|
+
);
|
|
46
73
|
}
|
|
47
|
-
if (SERVER_ONLY_MESSAGES.has(message.type) && senderRole !==
|
|
48
|
-
return violation(
|
|
74
|
+
if (SERVER_ONLY_MESSAGES.has(message.type) && senderRole !== "server") {
|
|
75
|
+
return violation(
|
|
76
|
+
"ROLE_VIOLATION",
|
|
77
|
+
`${message.type} can only be sent by server`,
|
|
78
|
+
this._phase,
|
|
79
|
+
message.type,
|
|
80
|
+
);
|
|
49
81
|
}
|
|
50
82
|
return null;
|
|
51
83
|
}
|
|
52
84
|
|
|
53
85
|
validateOutgoing(message: MoqtMessage): ValidationResult {
|
|
54
|
-
const roleViolation = this.checkRole(message,
|
|
86
|
+
const roleViolation = this.checkRole(message, "outbound");
|
|
55
87
|
if (roleViolation) return { ok: false, violation: roleViolation };
|
|
56
88
|
|
|
57
89
|
if (!this.legalOutgoing.has(message.type)) {
|
|
58
90
|
return {
|
|
59
91
|
ok: false,
|
|
60
92
|
violation: violation(
|
|
61
|
-
this._phase ===
|
|
93
|
+
this._phase === "idle" || this._phase === "setup"
|
|
94
|
+
? "MESSAGE_BEFORE_SETUP"
|
|
95
|
+
: "UNEXPECTED_MESSAGE",
|
|
62
96
|
`Cannot send ${message.type} in phase ${this._phase}`,
|
|
63
97
|
this._phase,
|
|
64
98
|
message.type,
|
|
@@ -69,59 +103,62 @@ export class SessionFSM {
|
|
|
69
103
|
}
|
|
70
104
|
|
|
71
105
|
receive(message: MoqtMessage): TransitionResult {
|
|
72
|
-
const roleViolation = this.checkRole(message,
|
|
106
|
+
const roleViolation = this.checkRole(message, "inbound");
|
|
73
107
|
if (roleViolation) return { ok: false, violation: roleViolation };
|
|
74
108
|
|
|
75
|
-
return this.applyTransition(message,
|
|
109
|
+
return this.applyTransition(message, "inbound");
|
|
76
110
|
}
|
|
77
111
|
|
|
78
112
|
send(message: MoqtMessage): TransitionResult {
|
|
79
|
-
const roleViolation = this.checkRole(message,
|
|
113
|
+
const roleViolation = this.checkRole(message, "outbound");
|
|
80
114
|
if (roleViolation) return { ok: false, violation: roleViolation };
|
|
81
115
|
|
|
82
|
-
return this.applyTransition(message,
|
|
116
|
+
return this.applyTransition(message, "outbound");
|
|
83
117
|
}
|
|
84
118
|
|
|
85
|
-
private applyTransition(
|
|
119
|
+
private applyTransition(
|
|
120
|
+
message: MoqtMessage,
|
|
121
|
+
direction: "inbound" | "outbound",
|
|
122
|
+
): TransitionResult {
|
|
86
123
|
const sideEffects: SideEffect[] = [];
|
|
87
124
|
|
|
88
125
|
switch (message.type) {
|
|
89
|
-
case
|
|
126
|
+
case "client_setup":
|
|
90
127
|
return this.handleClientSetup(message, direction);
|
|
91
|
-
case
|
|
128
|
+
case "server_setup":
|
|
92
129
|
return this.handleServerSetup(message, direction);
|
|
93
|
-
case
|
|
130
|
+
case "goaway":
|
|
94
131
|
return this.handleGoAway(message, direction, sideEffects);
|
|
95
132
|
|
|
96
133
|
// Subscription lifecycle
|
|
97
|
-
case
|
|
134
|
+
case "subscribe":
|
|
98
135
|
return this.handleSubscribe(message, direction, sideEffects);
|
|
99
|
-
case
|
|
136
|
+
case "subscribe_ok":
|
|
100
137
|
return this.handleSubscribeOk(message, direction, sideEffects);
|
|
101
|
-
case
|
|
138
|
+
case "subscribe_error":
|
|
102
139
|
return this.handleSubscribeError(message, direction, sideEffects);
|
|
103
|
-
case
|
|
140
|
+
case "subscribe_done":
|
|
104
141
|
return this.handleSubscribeDone(message, direction, sideEffects);
|
|
105
|
-
case
|
|
142
|
+
case "unsubscribe":
|
|
106
143
|
return this.handleUnsubscribe(message, direction, sideEffects);
|
|
107
144
|
|
|
108
145
|
// Announce lifecycle
|
|
109
|
-
case
|
|
146
|
+
case "announce":
|
|
110
147
|
return this.handleAnnounce(message, direction, sideEffects);
|
|
111
|
-
case
|
|
148
|
+
case "announce_ok":
|
|
112
149
|
return this.handleAnnounceOk(message, direction, sideEffects);
|
|
113
|
-
case
|
|
150
|
+
case "announce_error":
|
|
114
151
|
return this.handleAnnounceError(message, direction, sideEffects);
|
|
115
|
-
case
|
|
152
|
+
case "announce_cancel":
|
|
116
153
|
return this.handleAnnounceCancel(message, direction, sideEffects);
|
|
117
|
-
case
|
|
154
|
+
case "unannounce":
|
|
118
155
|
return this.handleUnannounce(message, direction, sideEffects);
|
|
119
156
|
|
|
120
157
|
// Fetch lifecycle
|
|
121
|
-
case
|
|
122
|
-
case
|
|
123
|
-
case
|
|
124
|
-
case
|
|
158
|
+
case "fetch":
|
|
159
|
+
case "fetch_ok":
|
|
160
|
+
case "fetch_error":
|
|
161
|
+
case "fetch_cancel":
|
|
125
162
|
return this.handleReadyPhaseMessage(message);
|
|
126
163
|
|
|
127
164
|
// Other ready-phase messages
|
|
@@ -130,46 +167,98 @@ export class SessionFSM {
|
|
|
130
167
|
}
|
|
131
168
|
}
|
|
132
169
|
|
|
133
|
-
private handleClientSetup(
|
|
134
|
-
|
|
135
|
-
|
|
170
|
+
private handleClientSetup(
|
|
171
|
+
_message: MoqtMessage,
|
|
172
|
+
direction: "inbound" | "outbound",
|
|
173
|
+
): TransitionResult {
|
|
174
|
+
if (this._phase !== "idle") {
|
|
175
|
+
return {
|
|
176
|
+
ok: false,
|
|
177
|
+
violation: violation(
|
|
178
|
+
"SETUP_VIOLATION",
|
|
179
|
+
"CLIENT_SETUP already sent/received",
|
|
180
|
+
this._phase,
|
|
181
|
+
"client_setup",
|
|
182
|
+
),
|
|
183
|
+
};
|
|
136
184
|
}
|
|
137
185
|
|
|
138
|
-
if (direction ===
|
|
139
|
-
return {
|
|
186
|
+
if (direction === "outbound" && this._role !== "client") {
|
|
187
|
+
return {
|
|
188
|
+
ok: false,
|
|
189
|
+
violation: violation(
|
|
190
|
+
"ROLE_VIOLATION",
|
|
191
|
+
"Only client can send CLIENT_SETUP",
|
|
192
|
+
this._phase,
|
|
193
|
+
"client_setup",
|
|
194
|
+
),
|
|
195
|
+
};
|
|
140
196
|
}
|
|
141
197
|
|
|
142
|
-
this._phase =
|
|
198
|
+
this._phase = "setup";
|
|
143
199
|
return { ok: true, phase: this._phase, sideEffects: [] };
|
|
144
200
|
}
|
|
145
201
|
|
|
146
|
-
private handleServerSetup(
|
|
147
|
-
|
|
148
|
-
|
|
202
|
+
private handleServerSetup(
|
|
203
|
+
_message: MoqtMessage,
|
|
204
|
+
direction: "inbound" | "outbound",
|
|
205
|
+
): TransitionResult {
|
|
206
|
+
if (this._phase !== "setup") {
|
|
207
|
+
return {
|
|
208
|
+
ok: false,
|
|
209
|
+
violation: violation(
|
|
210
|
+
"SETUP_VIOLATION",
|
|
211
|
+
"SERVER_SETUP before CLIENT_SETUP",
|
|
212
|
+
this._phase,
|
|
213
|
+
"server_setup",
|
|
214
|
+
),
|
|
215
|
+
};
|
|
149
216
|
}
|
|
150
217
|
|
|
151
|
-
if (direction ===
|
|
152
|
-
return {
|
|
218
|
+
if (direction === "outbound" && this._role !== "server") {
|
|
219
|
+
return {
|
|
220
|
+
ok: false,
|
|
221
|
+
violation: violation(
|
|
222
|
+
"ROLE_VIOLATION",
|
|
223
|
+
"Only server can send SERVER_SETUP",
|
|
224
|
+
this._phase,
|
|
225
|
+
"server_setup",
|
|
226
|
+
),
|
|
227
|
+
};
|
|
153
228
|
}
|
|
154
229
|
|
|
155
|
-
this._phase =
|
|
156
|
-
return { ok: true, phase: this._phase, sideEffects: [{ type:
|
|
230
|
+
this._phase = "ready";
|
|
231
|
+
return { ok: true, phase: this._phase, sideEffects: [{ type: "session-ready" }] };
|
|
157
232
|
}
|
|
158
233
|
|
|
159
|
-
private handleGoAway(
|
|
160
|
-
|
|
161
|
-
|
|
234
|
+
private handleGoAway(
|
|
235
|
+
message: MoqtMessage,
|
|
236
|
+
_direction: "inbound" | "outbound",
|
|
237
|
+
sideEffects: SideEffect[],
|
|
238
|
+
): TransitionResult {
|
|
239
|
+
if (this._phase !== "ready" && this._phase !== "draining") {
|
|
240
|
+
return {
|
|
241
|
+
ok: false,
|
|
242
|
+
violation: violation(
|
|
243
|
+
"UNEXPECTED_MESSAGE",
|
|
244
|
+
`GOAWAY not valid in phase ${this._phase}`,
|
|
245
|
+
this._phase,
|
|
246
|
+
"goaway",
|
|
247
|
+
),
|
|
248
|
+
};
|
|
162
249
|
}
|
|
163
|
-
this._phase =
|
|
164
|
-
const goaway = message as import(
|
|
165
|
-
sideEffects.push({ type:
|
|
250
|
+
this._phase = "draining";
|
|
251
|
+
const goaway = message as import("../../core/types.js").GoAway;
|
|
252
|
+
sideEffects.push({ type: "session-draining", goAwayUri: goaway.newSessionUri });
|
|
166
253
|
return { ok: true, phase: this._phase, sideEffects };
|
|
167
254
|
}
|
|
168
255
|
|
|
169
256
|
private requireReady(msgType: MoqtMessageType): ProtocolViolation | null {
|
|
170
|
-
if (this._phase !==
|
|
257
|
+
if (this._phase !== "ready" && this._phase !== "draining") {
|
|
171
258
|
return violation(
|
|
172
|
-
this._phase ===
|
|
259
|
+
this._phase === "idle" || this._phase === "setup"
|
|
260
|
+
? "MESSAGE_BEFORE_SETUP"
|
|
261
|
+
: "UNEXPECTED_MESSAGE",
|
|
173
262
|
`${msgType} requires ready phase, current: ${this._phase}`,
|
|
174
263
|
this._phase,
|
|
175
264
|
msgType,
|
|
@@ -178,18 +267,30 @@ export class SessionFSM {
|
|
|
178
267
|
return null;
|
|
179
268
|
}
|
|
180
269
|
|
|
181
|
-
private handleSubscribe(
|
|
270
|
+
private handleSubscribe(
|
|
271
|
+
message: MoqtMessage,
|
|
272
|
+
_direction: "inbound" | "outbound",
|
|
273
|
+
sideEffects: SideEffect[],
|
|
274
|
+
): TransitionResult {
|
|
182
275
|
const err = this.requireReady(message.type);
|
|
183
276
|
if (err) return { ok: false, violation: err };
|
|
184
277
|
|
|
185
|
-
const sub = message as import(
|
|
278
|
+
const sub = message as import("../../core/types.js").Subscribe;
|
|
186
279
|
if (this._subscriptions.has(sub.subscribeId)) {
|
|
187
|
-
return {
|
|
280
|
+
return {
|
|
281
|
+
ok: false,
|
|
282
|
+
violation: violation(
|
|
283
|
+
"DUPLICATE_SUBSCRIBE_ID",
|
|
284
|
+
`Subscribe ID ${sub.subscribeId} already exists`,
|
|
285
|
+
this._phase,
|
|
286
|
+
message.type,
|
|
287
|
+
),
|
|
288
|
+
};
|
|
188
289
|
}
|
|
189
290
|
|
|
190
291
|
this._subscriptions.set(sub.subscribeId, {
|
|
191
292
|
subscribeId: sub.subscribeId,
|
|
192
|
-
phase:
|
|
293
|
+
phase: "pending",
|
|
193
294
|
trackNamespace: sub.trackNamespace,
|
|
194
295
|
trackName: sub.trackName,
|
|
195
296
|
});
|
|
@@ -197,144 +298,256 @@ export class SessionFSM {
|
|
|
197
298
|
return { ok: true, phase: this._phase, sideEffects };
|
|
198
299
|
}
|
|
199
300
|
|
|
200
|
-
private handleSubscribeOk(
|
|
301
|
+
private handleSubscribeOk(
|
|
302
|
+
message: MoqtMessage,
|
|
303
|
+
_direction: "inbound" | "outbound",
|
|
304
|
+
sideEffects: SideEffect[],
|
|
305
|
+
): TransitionResult {
|
|
201
306
|
const err = this.requireReady(message.type);
|
|
202
307
|
if (err) return { ok: false, violation: err };
|
|
203
308
|
|
|
204
|
-
const ok = message as import(
|
|
309
|
+
const ok = message as import("../../core/types.js").SubscribeOk;
|
|
205
310
|
const existing = this._subscriptions.get(ok.subscribeId);
|
|
206
311
|
if (!existing) {
|
|
207
|
-
return {
|
|
312
|
+
return {
|
|
313
|
+
ok: false,
|
|
314
|
+
violation: violation(
|
|
315
|
+
"UNKNOWN_SUBSCRIBE_ID",
|
|
316
|
+
`No subscription with ID ${ok.subscribeId}`,
|
|
317
|
+
this._phase,
|
|
318
|
+
message.type,
|
|
319
|
+
),
|
|
320
|
+
};
|
|
208
321
|
}
|
|
209
|
-
if (existing.phase !==
|
|
210
|
-
return {
|
|
322
|
+
if (existing.phase !== "pending") {
|
|
323
|
+
return {
|
|
324
|
+
ok: false,
|
|
325
|
+
violation: violation(
|
|
326
|
+
"STATE_VIOLATION",
|
|
327
|
+
`Subscription ${ok.subscribeId} is ${existing.phase}, not pending`,
|
|
328
|
+
this._phase,
|
|
329
|
+
message.type,
|
|
330
|
+
),
|
|
331
|
+
};
|
|
211
332
|
}
|
|
212
333
|
|
|
213
|
-
this._subscriptions.set(ok.subscribeId, { ...existing, phase:
|
|
214
|
-
sideEffects.push({ type:
|
|
334
|
+
this._subscriptions.set(ok.subscribeId, { ...existing, phase: "active" });
|
|
335
|
+
sideEffects.push({ type: "subscription-activated", subscribeId: ok.subscribeId });
|
|
215
336
|
return { ok: true, phase: this._phase, sideEffects };
|
|
216
337
|
}
|
|
217
338
|
|
|
218
|
-
private handleSubscribeError(
|
|
339
|
+
private handleSubscribeError(
|
|
340
|
+
message: MoqtMessage,
|
|
341
|
+
_direction: "inbound" | "outbound",
|
|
342
|
+
sideEffects: SideEffect[],
|
|
343
|
+
): TransitionResult {
|
|
219
344
|
const err = this.requireReady(message.type);
|
|
220
345
|
if (err) return { ok: false, violation: err };
|
|
221
346
|
|
|
222
|
-
const subErr = message as import(
|
|
347
|
+
const subErr = message as import("../../core/types.js").SubscribeError;
|
|
223
348
|
const existing = this._subscriptions.get(subErr.subscribeId);
|
|
224
349
|
if (!existing) {
|
|
225
|
-
return {
|
|
350
|
+
return {
|
|
351
|
+
ok: false,
|
|
352
|
+
violation: violation(
|
|
353
|
+
"UNKNOWN_SUBSCRIBE_ID",
|
|
354
|
+
`No subscription with ID ${subErr.subscribeId}`,
|
|
355
|
+
this._phase,
|
|
356
|
+
message.type,
|
|
357
|
+
),
|
|
358
|
+
};
|
|
226
359
|
}
|
|
227
|
-
if (existing.phase !==
|
|
228
|
-
return {
|
|
360
|
+
if (existing.phase !== "pending") {
|
|
361
|
+
return {
|
|
362
|
+
ok: false,
|
|
363
|
+
violation: violation(
|
|
364
|
+
"STATE_VIOLATION",
|
|
365
|
+
`Subscription ${subErr.subscribeId} is ${existing.phase}, not pending`,
|
|
366
|
+
this._phase,
|
|
367
|
+
message.type,
|
|
368
|
+
),
|
|
369
|
+
};
|
|
229
370
|
}
|
|
230
371
|
|
|
231
|
-
this._subscriptions.set(subErr.subscribeId, { ...existing, phase:
|
|
232
|
-
sideEffects.push({
|
|
372
|
+
this._subscriptions.set(subErr.subscribeId, { ...existing, phase: "error" });
|
|
373
|
+
sideEffects.push({
|
|
374
|
+
type: "subscription-ended",
|
|
375
|
+
subscribeId: subErr.subscribeId,
|
|
376
|
+
reason: subErr.reasonPhrase,
|
|
377
|
+
});
|
|
233
378
|
return { ok: true, phase: this._phase, sideEffects };
|
|
234
379
|
}
|
|
235
380
|
|
|
236
|
-
private handleSubscribeDone(
|
|
381
|
+
private handleSubscribeDone(
|
|
382
|
+
message: MoqtMessage,
|
|
383
|
+
_direction: "inbound" | "outbound",
|
|
384
|
+
sideEffects: SideEffect[],
|
|
385
|
+
): TransitionResult {
|
|
237
386
|
const err = this.requireReady(message.type);
|
|
238
387
|
if (err) return { ok: false, violation: err };
|
|
239
388
|
|
|
240
|
-
const done = message as import(
|
|
389
|
+
const done = message as import("../../core/types.js").SubscribeDone;
|
|
241
390
|
const existing = this._subscriptions.get(done.subscribeId);
|
|
242
391
|
if (!existing) {
|
|
243
|
-
return {
|
|
392
|
+
return {
|
|
393
|
+
ok: false,
|
|
394
|
+
violation: violation(
|
|
395
|
+
"UNKNOWN_SUBSCRIBE_ID",
|
|
396
|
+
`No subscription with ID ${done.subscribeId}`,
|
|
397
|
+
this._phase,
|
|
398
|
+
message.type,
|
|
399
|
+
),
|
|
400
|
+
};
|
|
244
401
|
}
|
|
245
402
|
|
|
246
|
-
this._subscriptions.set(done.subscribeId, { ...existing, phase:
|
|
247
|
-
sideEffects.push({
|
|
403
|
+
this._subscriptions.set(done.subscribeId, { ...existing, phase: "done" });
|
|
404
|
+
sideEffects.push({
|
|
405
|
+
type: "subscription-ended",
|
|
406
|
+
subscribeId: done.subscribeId,
|
|
407
|
+
reason: done.reasonPhrase,
|
|
408
|
+
});
|
|
248
409
|
return { ok: true, phase: this._phase, sideEffects };
|
|
249
410
|
}
|
|
250
411
|
|
|
251
|
-
private handleUnsubscribe(
|
|
412
|
+
private handleUnsubscribe(
|
|
413
|
+
message: MoqtMessage,
|
|
414
|
+
_direction: "inbound" | "outbound",
|
|
415
|
+
sideEffects: SideEffect[],
|
|
416
|
+
): TransitionResult {
|
|
252
417
|
const err = this.requireReady(message.type);
|
|
253
418
|
if (err) return { ok: false, violation: err };
|
|
254
419
|
|
|
255
|
-
const unsub = message as import(
|
|
420
|
+
const unsub = message as import("../../core/types.js").Unsubscribe;
|
|
256
421
|
const existing = this._subscriptions.get(unsub.subscribeId);
|
|
257
422
|
if (!existing) {
|
|
258
|
-
return {
|
|
423
|
+
return {
|
|
424
|
+
ok: false,
|
|
425
|
+
violation: violation(
|
|
426
|
+
"UNKNOWN_SUBSCRIBE_ID",
|
|
427
|
+
`No subscription with ID ${unsub.subscribeId}`,
|
|
428
|
+
this._phase,
|
|
429
|
+
message.type,
|
|
430
|
+
),
|
|
431
|
+
};
|
|
259
432
|
}
|
|
260
433
|
|
|
261
|
-
this._subscriptions.set(unsub.subscribeId, { ...existing, phase:
|
|
262
|
-
sideEffects.push({
|
|
434
|
+
this._subscriptions.set(unsub.subscribeId, { ...existing, phase: "done" });
|
|
435
|
+
sideEffects.push({
|
|
436
|
+
type: "subscription-ended",
|
|
437
|
+
subscribeId: unsub.subscribeId,
|
|
438
|
+
reason: "unsubscribed",
|
|
439
|
+
});
|
|
263
440
|
return { ok: true, phase: this._phase, sideEffects };
|
|
264
441
|
}
|
|
265
442
|
|
|
266
443
|
// Announce handlers
|
|
267
444
|
private namespaceKey(ns: string[]): string {
|
|
268
|
-
return ns.join(
|
|
445
|
+
return ns.join("/");
|
|
269
446
|
}
|
|
270
447
|
|
|
271
|
-
private handleAnnounce(
|
|
448
|
+
private handleAnnounce(
|
|
449
|
+
message: MoqtMessage,
|
|
450
|
+
_direction: "inbound" | "outbound",
|
|
451
|
+
sideEffects: SideEffect[],
|
|
452
|
+
): TransitionResult {
|
|
272
453
|
const err = this.requireReady(message.type);
|
|
273
454
|
if (err) return { ok: false, violation: err };
|
|
274
455
|
|
|
275
|
-
const ann = message as import(
|
|
456
|
+
const ann = message as import("../../core/types.js").Announce;
|
|
276
457
|
const key = this.namespaceKey(ann.trackNamespace);
|
|
277
458
|
|
|
278
|
-
this._announces.set(key, { namespace: ann.trackNamespace, phase:
|
|
459
|
+
this._announces.set(key, { namespace: ann.trackNamespace, phase: "pending" });
|
|
279
460
|
return { ok: true, phase: this._phase, sideEffects };
|
|
280
461
|
}
|
|
281
462
|
|
|
282
|
-
private handleAnnounceOk(
|
|
463
|
+
private handleAnnounceOk(
|
|
464
|
+
message: MoqtMessage,
|
|
465
|
+
_direction: "inbound" | "outbound",
|
|
466
|
+
sideEffects: SideEffect[],
|
|
467
|
+
): TransitionResult {
|
|
283
468
|
const err = this.requireReady(message.type);
|
|
284
469
|
if (err) return { ok: false, violation: err };
|
|
285
470
|
|
|
286
|
-
const ok = message as import(
|
|
471
|
+
const ok = message as import("../../core/types.js").AnnounceOk;
|
|
287
472
|
const key = this.namespaceKey(ok.trackNamespace);
|
|
288
473
|
const existing = this._announces.get(key);
|
|
289
474
|
if (!existing) {
|
|
290
|
-
return {
|
|
475
|
+
return {
|
|
476
|
+
ok: false,
|
|
477
|
+
violation: violation(
|
|
478
|
+
"UNEXPECTED_MESSAGE",
|
|
479
|
+
`No announce for namespace ${key}`,
|
|
480
|
+
this._phase,
|
|
481
|
+
message.type,
|
|
482
|
+
),
|
|
483
|
+
};
|
|
291
484
|
}
|
|
292
485
|
|
|
293
|
-
this._announces.set(key, { ...existing, phase:
|
|
294
|
-
sideEffects.push({ type:
|
|
486
|
+
this._announces.set(key, { ...existing, phase: "active" });
|
|
487
|
+
sideEffects.push({ type: "announce-activated", namespace: ok.trackNamespace });
|
|
295
488
|
return { ok: true, phase: this._phase, sideEffects };
|
|
296
489
|
}
|
|
297
490
|
|
|
298
|
-
private handleAnnounceError(
|
|
491
|
+
private handleAnnounceError(
|
|
492
|
+
message: MoqtMessage,
|
|
493
|
+
_direction: "inbound" | "outbound",
|
|
494
|
+
sideEffects: SideEffect[],
|
|
495
|
+
): TransitionResult {
|
|
299
496
|
const err = this.requireReady(message.type);
|
|
300
497
|
if (err) return { ok: false, violation: err };
|
|
301
498
|
|
|
302
|
-
const annErr = message as import(
|
|
499
|
+
const annErr = message as import("../../core/types.js").AnnounceError;
|
|
303
500
|
const key = this.namespaceKey(annErr.trackNamespace);
|
|
304
501
|
const existing = this._announces.get(key);
|
|
305
502
|
if (!existing) {
|
|
306
|
-
return {
|
|
503
|
+
return {
|
|
504
|
+
ok: false,
|
|
505
|
+
violation: violation(
|
|
506
|
+
"UNEXPECTED_MESSAGE",
|
|
507
|
+
`No announce for namespace ${key}`,
|
|
508
|
+
this._phase,
|
|
509
|
+
message.type,
|
|
510
|
+
),
|
|
511
|
+
};
|
|
307
512
|
}
|
|
308
513
|
|
|
309
|
-
this._announces.set(key, { ...existing, phase:
|
|
310
|
-
sideEffects.push({ type:
|
|
514
|
+
this._announces.set(key, { ...existing, phase: "error" });
|
|
515
|
+
sideEffects.push({ type: "announce-ended", namespace: annErr.trackNamespace });
|
|
311
516
|
return { ok: true, phase: this._phase, sideEffects };
|
|
312
517
|
}
|
|
313
518
|
|
|
314
|
-
private handleAnnounceCancel(
|
|
519
|
+
private handleAnnounceCancel(
|
|
520
|
+
message: MoqtMessage,
|
|
521
|
+
_direction: "inbound" | "outbound",
|
|
522
|
+
sideEffects: SideEffect[],
|
|
523
|
+
): TransitionResult {
|
|
315
524
|
const err = this.requireReady(message.type);
|
|
316
525
|
if (err) return { ok: false, violation: err };
|
|
317
526
|
|
|
318
|
-
const cancel = message as import(
|
|
527
|
+
const cancel = message as import("../../core/types.js").AnnounceCancel;
|
|
319
528
|
const key = this.namespaceKey(cancel.trackNamespace);
|
|
320
529
|
const existing = this._announces.get(key);
|
|
321
530
|
if (existing) {
|
|
322
531
|
this._announces.delete(key);
|
|
323
|
-
sideEffects.push({ type:
|
|
532
|
+
sideEffects.push({ type: "announce-ended", namespace: cancel.trackNamespace });
|
|
324
533
|
}
|
|
325
534
|
return { ok: true, phase: this._phase, sideEffects };
|
|
326
535
|
}
|
|
327
536
|
|
|
328
|
-
private handleUnannounce(
|
|
537
|
+
private handleUnannounce(
|
|
538
|
+
message: MoqtMessage,
|
|
539
|
+
_direction: "inbound" | "outbound",
|
|
540
|
+
sideEffects: SideEffect[],
|
|
541
|
+
): TransitionResult {
|
|
329
542
|
const err = this.requireReady(message.type);
|
|
330
543
|
if (err) return { ok: false, violation: err };
|
|
331
544
|
|
|
332
|
-
const unann = message as import(
|
|
545
|
+
const unann = message as import("../../core/types.js").Unannounce;
|
|
333
546
|
const key = this.namespaceKey(unann.trackNamespace);
|
|
334
547
|
const existing = this._announces.get(key);
|
|
335
548
|
if (existing) {
|
|
336
549
|
this._announces.delete(key);
|
|
337
|
-
sideEffects.push({ type:
|
|
550
|
+
sideEffects.push({ type: "announce-ended", namespace: unann.trackNamespace });
|
|
338
551
|
}
|
|
339
552
|
return { ok: true, phase: this._phase, sideEffects };
|
|
340
553
|
}
|
|
@@ -346,7 +559,7 @@ export class SessionFSM {
|
|
|
346
559
|
}
|
|
347
560
|
|
|
348
561
|
reset(): void {
|
|
349
|
-
this._phase =
|
|
562
|
+
this._phase = "idle";
|
|
350
563
|
this._subscriptions.clear();
|
|
351
564
|
this._announces.clear();
|
|
352
565
|
}
|