@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 @@ import {
|
|
|
2
2
|
BufferReader,
|
|
3
3
|
BufferWriter,
|
|
4
4
|
DecodeError
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-A27S7HW7.js";
|
|
6
6
|
|
|
7
7
|
// src/drafts/draft07/messages.ts
|
|
8
8
|
var MESSAGE_TYPE_IDS = {
|
|
@@ -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 DecodeError(
|
|
100
|
+
throw new 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 DecodeError(
|
|
348
|
+
throw new 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 DecodeError(
|
|
376
|
+
throw new 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],
|
|
@@ -681,18 +769,26 @@ function decodeMessageImpl(bytes) {
|
|
|
681
769
|
if (!decoder2) {
|
|
682
770
|
return {
|
|
683
771
|
ok: false,
|
|
684
|
-
error: new DecodeError(
|
|
772
|
+
error: new 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 DecodeError(
|
|
787
|
+
error: new 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,7 +797,11 @@ function decodeMessageImpl(bytes) {
|
|
|
701
797
|
if (!decoder) {
|
|
702
798
|
return {
|
|
703
799
|
ok: false,
|
|
704
|
-
error: new DecodeError(
|
|
800
|
+
error: new DecodeError(
|
|
801
|
+
"UNKNOWN_MESSAGE_TYPE",
|
|
802
|
+
`Unknown message type ID: 0x${typeId.toString(16)}`,
|
|
803
|
+
0
|
|
804
|
+
)
|
|
705
805
|
};
|
|
706
806
|
}
|
|
707
807
|
const payloadReader = new BufferReader(payloadBytes, 0);
|
|
@@ -39,10 +39,20 @@ var SessionFSM = (_class = class {
|
|
|
39
39
|
checkRole(message, direction) {
|
|
40
40
|
const senderRole = direction === "outbound" ? this._role : this._role === "client" ? "server" : "client";
|
|
41
41
|
if (_chunkQYG6KGOVcjs.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 (_chunkQYG6KGOVcjs.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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 });
|