@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
|
@@ -1,46 +1,46 @@
|
|
|
1
|
-
import { BufferReader } from
|
|
2
|
-
import { BufferWriter } from
|
|
3
|
-
import { DecodeError } from '../../core/types.js';
|
|
1
|
+
import { BufferReader } from "../../core/buffer-reader.js";
|
|
2
|
+
import { BufferWriter } from "../../core/buffer-writer.js";
|
|
4
3
|
import type {
|
|
4
|
+
Announce,
|
|
5
|
+
AnnounceCancel,
|
|
6
|
+
AnnounceError,
|
|
7
|
+
AnnounceOk,
|
|
8
|
+
ClientSetup,
|
|
5
9
|
Codec,
|
|
6
10
|
DecodeResult,
|
|
11
|
+
Fetch,
|
|
12
|
+
FetchCancel,
|
|
13
|
+
FetchError,
|
|
14
|
+
FetchOk,
|
|
7
15
|
FilterType,
|
|
16
|
+
GoAway,
|
|
8
17
|
GroupOrderValue,
|
|
18
|
+
MaxSubscribeId,
|
|
9
19
|
MoqtMessage,
|
|
10
20
|
MoqtMessageType,
|
|
11
|
-
ClientSetup,
|
|
12
|
-
ServerSetup,
|
|
13
|
-
Subscribe,
|
|
14
|
-
SubscribeOk,
|
|
15
|
-
SubscribeError,
|
|
16
|
-
SubscribeDone,
|
|
17
|
-
SubscribeUpdate,
|
|
18
|
-
Unsubscribe,
|
|
19
|
-
Announce,
|
|
20
|
-
AnnounceOk,
|
|
21
|
-
AnnounceError,
|
|
22
|
-
AnnounceCancel,
|
|
23
|
-
Unannounce,
|
|
24
|
-
TrackStatusRequest,
|
|
25
|
-
TrackStatus,
|
|
26
|
-
ObjectStream,
|
|
27
21
|
ObjectDatagram,
|
|
28
|
-
|
|
22
|
+
ObjectStream,
|
|
23
|
+
ServerSetup,
|
|
29
24
|
StreamHeaderGroup,
|
|
30
25
|
StreamHeaderSubgroup,
|
|
31
|
-
|
|
26
|
+
StreamHeaderTrack,
|
|
27
|
+
Subscribe,
|
|
32
28
|
SubscribeAnnounces,
|
|
33
|
-
SubscribeAnnouncesOk,
|
|
34
29
|
SubscribeAnnouncesError,
|
|
30
|
+
SubscribeAnnouncesOk,
|
|
31
|
+
SubscribeDone,
|
|
32
|
+
SubscribeError,
|
|
33
|
+
SubscribeOk,
|
|
34
|
+
SubscribeUpdate,
|
|
35
|
+
TrackStatus,
|
|
36
|
+
TrackStatusRequest,
|
|
37
|
+
Unannounce,
|
|
38
|
+
Unsubscribe,
|
|
35
39
|
UnsubscribeAnnounces,
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
FetchCancel,
|
|
41
|
-
} from '../../core/types.js';
|
|
42
|
-
import { MESSAGE_TYPE_IDS } from './messages.js';
|
|
43
|
-
import { encodeVarInt, decodeVarInt } from './varint.js';
|
|
40
|
+
} from "../../core/types.js";
|
|
41
|
+
import { DecodeError } from "../../core/types.js";
|
|
42
|
+
import { MESSAGE_TYPE_IDS } from "./messages.js";
|
|
43
|
+
import { decodeVarInt, encodeVarInt } from "./varint.js";
|
|
44
44
|
|
|
45
45
|
// --- FilterType mapping ---
|
|
46
46
|
|
|
@@ -52,10 +52,10 @@ const FILTER_TYPE_TO_WIRE: Record<FilterType, bigint> = {
|
|
|
52
52
|
};
|
|
53
53
|
|
|
54
54
|
const WIRE_TO_FILTER_TYPE: Map<bigint, FilterType> = new Map([
|
|
55
|
-
[1n,
|
|
56
|
-
[2n,
|
|
57
|
-
[3n,
|
|
58
|
-
[4n,
|
|
55
|
+
[1n, "latest_group"],
|
|
56
|
+
[2n, "latest_object"],
|
|
57
|
+
[3n, "absolute_start"],
|
|
58
|
+
[4n, "absolute_range"],
|
|
59
59
|
]);
|
|
60
60
|
|
|
61
61
|
// --- GroupOrderValue mapping ---
|
|
@@ -67,9 +67,9 @@ const GROUP_ORDER_TO_WIRE: Record<GroupOrderValue, number> = {
|
|
|
67
67
|
};
|
|
68
68
|
|
|
69
69
|
const WIRE_TO_GROUP_ORDER: Map<number, GroupOrderValue> = new Map([
|
|
70
|
-
[0,
|
|
71
|
-
[1,
|
|
72
|
-
[2,
|
|
70
|
+
[0, "original"],
|
|
71
|
+
[1, "ascending"],
|
|
72
|
+
[2, "descending"],
|
|
73
73
|
]);
|
|
74
74
|
|
|
75
75
|
// --- Encode helpers ---
|
|
@@ -83,7 +83,11 @@ function readGroupOrder(reader: BufferReader): GroupOrderValue {
|
|
|
83
83
|
const wire = reader.readUint8();
|
|
84
84
|
const value = WIRE_TO_GROUP_ORDER.get(wire);
|
|
85
85
|
if (value === undefined) {
|
|
86
|
-
throw new DecodeError(
|
|
86
|
+
throw new DecodeError(
|
|
87
|
+
"CONSTRAINT_VIOLATION",
|
|
88
|
+
`Invalid group order value: ${wire}`,
|
|
89
|
+
reader.offset - 1,
|
|
90
|
+
);
|
|
87
91
|
}
|
|
88
92
|
return value;
|
|
89
93
|
}
|
|
@@ -101,7 +105,11 @@ const DATA_STREAM_TYPE_IDS: ReadonlySet<bigint> = new Set([
|
|
|
101
105
|
// --- Control message type (excludes data stream types) ---
|
|
102
106
|
type ControlMessageType = Exclude<
|
|
103
107
|
MoqtMessageType,
|
|
104
|
-
|
|
108
|
+
| "object_stream"
|
|
109
|
+
| "object_datagram"
|
|
110
|
+
| "stream_header_track"
|
|
111
|
+
| "stream_header_group"
|
|
112
|
+
| "stream_header_subgroup"
|
|
105
113
|
>;
|
|
106
114
|
|
|
107
115
|
// --- Encode functions for each message type (payload only, no type ID) ---
|
|
@@ -127,11 +135,11 @@ function encodeSubscribe(msg: Subscribe, writer: BufferWriter): void {
|
|
|
127
135
|
writer.writeUint8(msg.subscriberPriority);
|
|
128
136
|
writeGroupOrder(writer, msg.groupOrder);
|
|
129
137
|
writer.writeVarInt(FILTER_TYPE_TO_WIRE[msg.filterType]);
|
|
130
|
-
if (msg.filterType ===
|
|
138
|
+
if (msg.filterType === "absolute_start" || msg.filterType === "absolute_range") {
|
|
131
139
|
writer.writeVarInt(msg.startGroup!);
|
|
132
140
|
writer.writeVarInt(msg.startObject!);
|
|
133
141
|
}
|
|
134
|
-
if (msg.filterType ===
|
|
142
|
+
if (msg.filterType === "absolute_range") {
|
|
135
143
|
writer.writeVarInt(msg.endGroup!);
|
|
136
144
|
writer.writeVarInt(msg.endObject!);
|
|
137
145
|
}
|
|
@@ -356,7 +364,10 @@ const controlEncoders: Record<ControlMessageType, (msg: never, writer: BufferWri
|
|
|
356
364
|
goaway: encodeGoAway as (msg: never, writer: BufferWriter) => void,
|
|
357
365
|
subscribe_announces: encodeSubscribeAnnounces as (msg: never, writer: BufferWriter) => void,
|
|
358
366
|
subscribe_announces_ok: encodeSubscribeAnnouncesOk as (msg: never, writer: BufferWriter) => void,
|
|
359
|
-
subscribe_announces_error: encodeSubscribeAnnouncesError as (
|
|
367
|
+
subscribe_announces_error: encodeSubscribeAnnouncesError as (
|
|
368
|
+
msg: never,
|
|
369
|
+
writer: BufferWriter,
|
|
370
|
+
) => void,
|
|
360
371
|
unsubscribe_announces: encodeUnsubscribeAnnounces as (msg: never, writer: BufferWriter) => void,
|
|
361
372
|
max_subscribe_id: encodeMaxSubscribeId as (msg: never, writer: BufferWriter) => void,
|
|
362
373
|
fetch: encodeFetch as (msg: never, writer: BufferWriter) => void,
|
|
@@ -366,7 +377,9 @@ const controlEncoders: Record<ControlMessageType, (msg: never, writer: BufferWri
|
|
|
366
377
|
};
|
|
367
378
|
|
|
368
379
|
// Data stream encoders (write type + fields directly, no length framing)
|
|
369
|
-
const dataStreamEncoders: Partial<
|
|
380
|
+
const dataStreamEncoders: Partial<
|
|
381
|
+
Record<MoqtMessageType, (msg: never, writer: BufferWriter) => void>
|
|
382
|
+
> = {
|
|
370
383
|
object_stream: encodeObjectStream as (msg: never, writer: BufferWriter) => void,
|
|
371
384
|
object_datagram: encodeObjectDatagram as (msg: never, writer: BufferWriter) => void,
|
|
372
385
|
stream_header_track: encodeStreamHeaderTrack as (msg: never, writer: BufferWriter) => void,
|
|
@@ -379,20 +392,24 @@ const dataStreamEncoders: Partial<Record<MoqtMessageType, (msg: never, writer: B
|
|
|
379
392
|
function decodeClientSetup(reader: BufferReader): ClientSetup {
|
|
380
393
|
const numVersions = reader.readVarInt();
|
|
381
394
|
if (numVersions === 0n) {
|
|
382
|
-
throw new DecodeError(
|
|
395
|
+
throw new DecodeError(
|
|
396
|
+
"CONSTRAINT_VIOLATION",
|
|
397
|
+
"supported_versions must not be empty",
|
|
398
|
+
reader.offset,
|
|
399
|
+
);
|
|
383
400
|
}
|
|
384
401
|
const supportedVersions: bigint[] = [];
|
|
385
402
|
for (let i = 0n; i < numVersions; i++) {
|
|
386
403
|
supportedVersions.push(reader.readVarInt());
|
|
387
404
|
}
|
|
388
405
|
const parameters = reader.readParameters();
|
|
389
|
-
return { type:
|
|
406
|
+
return { type: "client_setup", supportedVersions, parameters };
|
|
390
407
|
}
|
|
391
408
|
|
|
392
409
|
function decodeServerSetup(reader: BufferReader): ServerSetup {
|
|
393
410
|
const selectedVersion = reader.readVarInt();
|
|
394
411
|
const parameters = reader.readParameters();
|
|
395
|
-
return { type:
|
|
412
|
+
return { type: "server_setup", selectedVersion, parameters };
|
|
396
413
|
}
|
|
397
414
|
|
|
398
415
|
function decodeSubscribe(reader: BufferReader): Subscribe {
|
|
@@ -405,11 +422,15 @@ function decodeSubscribe(reader: BufferReader): Subscribe {
|
|
|
405
422
|
const filterTypeWire = reader.readVarInt();
|
|
406
423
|
const filterType = WIRE_TO_FILTER_TYPE.get(filterTypeWire);
|
|
407
424
|
if (filterType === undefined) {
|
|
408
|
-
throw new DecodeError(
|
|
425
|
+
throw new DecodeError(
|
|
426
|
+
"CONSTRAINT_VIOLATION",
|
|
427
|
+
`Invalid filter type: ${filterTypeWire}`,
|
|
428
|
+
reader.offset,
|
|
429
|
+
);
|
|
409
430
|
}
|
|
410
431
|
|
|
411
432
|
const base = {
|
|
412
|
-
type:
|
|
433
|
+
type: "subscribe" as const,
|
|
413
434
|
subscribeId,
|
|
414
435
|
trackAlias,
|
|
415
436
|
trackNamespace,
|
|
@@ -420,13 +441,13 @@ function decodeSubscribe(reader: BufferReader): Subscribe {
|
|
|
420
441
|
parameters: undefined as unknown as Map<bigint, Uint8Array>,
|
|
421
442
|
};
|
|
422
443
|
|
|
423
|
-
if (filterType ===
|
|
444
|
+
if (filterType === "absolute_start") {
|
|
424
445
|
const startGroup = reader.readVarInt();
|
|
425
446
|
const startObject = reader.readVarInt();
|
|
426
447
|
base.parameters = reader.readParameters();
|
|
427
448
|
return { ...base, startGroup, startObject };
|
|
428
449
|
}
|
|
429
|
-
if (filterType ===
|
|
450
|
+
if (filterType === "absolute_range") {
|
|
430
451
|
const startGroup = reader.readVarInt();
|
|
431
452
|
const startObject = reader.readVarInt();
|
|
432
453
|
const endGroup = reader.readVarInt();
|
|
@@ -450,11 +471,27 @@ function decodeSubscribeOk(reader: BufferReader): SubscribeOk {
|
|
|
450
471
|
const largestGroupId = reader.readVarInt();
|
|
451
472
|
const largestObjectId = reader.readVarInt();
|
|
452
473
|
const parameters = reader.readParameters();
|
|
453
|
-
return {
|
|
474
|
+
return {
|
|
475
|
+
type: "subscribe_ok" as const,
|
|
476
|
+
subscribeId,
|
|
477
|
+
expires,
|
|
478
|
+
groupOrder,
|
|
479
|
+
contentExists,
|
|
480
|
+
largestGroupId,
|
|
481
|
+
largestObjectId,
|
|
482
|
+
parameters,
|
|
483
|
+
};
|
|
454
484
|
}
|
|
455
485
|
|
|
456
486
|
const parameters = reader.readParameters();
|
|
457
|
-
return {
|
|
487
|
+
return {
|
|
488
|
+
type: "subscribe_ok" as const,
|
|
489
|
+
subscribeId,
|
|
490
|
+
expires,
|
|
491
|
+
groupOrder,
|
|
492
|
+
contentExists,
|
|
493
|
+
parameters,
|
|
494
|
+
};
|
|
458
495
|
}
|
|
459
496
|
|
|
460
497
|
function decodeSubscribeError(reader: BufferReader): SubscribeError {
|
|
@@ -462,7 +499,7 @@ function decodeSubscribeError(reader: BufferReader): SubscribeError {
|
|
|
462
499
|
const errorCode = reader.readVarInt();
|
|
463
500
|
const reasonPhrase = reader.readString();
|
|
464
501
|
const trackAlias = reader.readVarInt();
|
|
465
|
-
return { type:
|
|
502
|
+
return { type: "subscribe_error", subscribeId, errorCode, reasonPhrase, trackAlias };
|
|
466
503
|
}
|
|
467
504
|
|
|
468
505
|
function decodeSubscribeDone(reader: BufferReader): SubscribeDone {
|
|
@@ -475,10 +512,18 @@ function decodeSubscribeDone(reader: BufferReader): SubscribeDone {
|
|
|
475
512
|
if (contentExists) {
|
|
476
513
|
const finalGroupId = reader.readVarInt();
|
|
477
514
|
const finalObjectId = reader.readVarInt();
|
|
478
|
-
return {
|
|
515
|
+
return {
|
|
516
|
+
type: "subscribe_done" as const,
|
|
517
|
+
subscribeId,
|
|
518
|
+
statusCode,
|
|
519
|
+
reasonPhrase,
|
|
520
|
+
contentExists,
|
|
521
|
+
finalGroupId,
|
|
522
|
+
finalObjectId,
|
|
523
|
+
};
|
|
479
524
|
}
|
|
480
525
|
|
|
481
|
-
return { type:
|
|
526
|
+
return { type: "subscribe_done" as const, subscribeId, statusCode, reasonPhrase, contentExists };
|
|
482
527
|
}
|
|
483
528
|
|
|
484
529
|
function decodeSubscribeUpdate(reader: BufferReader): SubscribeUpdate {
|
|
@@ -489,48 +534,57 @@ function decodeSubscribeUpdate(reader: BufferReader): SubscribeUpdate {
|
|
|
489
534
|
const endObject = reader.readVarInt();
|
|
490
535
|
const subscriberPriority = reader.readUint8();
|
|
491
536
|
const parameters = reader.readParameters();
|
|
492
|
-
return {
|
|
537
|
+
return {
|
|
538
|
+
type: "subscribe_update",
|
|
539
|
+
subscribeId,
|
|
540
|
+
startGroup,
|
|
541
|
+
startObject,
|
|
542
|
+
endGroup,
|
|
543
|
+
endObject,
|
|
544
|
+
subscriberPriority,
|
|
545
|
+
parameters,
|
|
546
|
+
};
|
|
493
547
|
}
|
|
494
548
|
|
|
495
549
|
function decodeUnsubscribe(reader: BufferReader): Unsubscribe {
|
|
496
550
|
const subscribeId = reader.readVarInt();
|
|
497
|
-
return { type:
|
|
551
|
+
return { type: "unsubscribe", subscribeId };
|
|
498
552
|
}
|
|
499
553
|
|
|
500
554
|
function decodeAnnounce(reader: BufferReader): Announce {
|
|
501
555
|
const trackNamespace = reader.readTuple();
|
|
502
556
|
const parameters = reader.readParameters();
|
|
503
|
-
return { type:
|
|
557
|
+
return { type: "announce", trackNamespace, parameters };
|
|
504
558
|
}
|
|
505
559
|
|
|
506
560
|
function decodeAnnounceOk(reader: BufferReader): AnnounceOk {
|
|
507
561
|
const trackNamespace = reader.readTuple();
|
|
508
|
-
return { type:
|
|
562
|
+
return { type: "announce_ok", trackNamespace };
|
|
509
563
|
}
|
|
510
564
|
|
|
511
565
|
function decodeAnnounceError(reader: BufferReader): AnnounceError {
|
|
512
566
|
const trackNamespace = reader.readTuple();
|
|
513
567
|
const errorCode = reader.readVarInt();
|
|
514
568
|
const reasonPhrase = reader.readString();
|
|
515
|
-
return { type:
|
|
569
|
+
return { type: "announce_error", trackNamespace, errorCode, reasonPhrase };
|
|
516
570
|
}
|
|
517
571
|
|
|
518
572
|
function decodeAnnounceCancel(reader: BufferReader): AnnounceCancel {
|
|
519
573
|
const trackNamespace = reader.readTuple();
|
|
520
574
|
const errorCode = reader.readVarInt();
|
|
521
575
|
const reasonPhrase = reader.readString();
|
|
522
|
-
return { type:
|
|
576
|
+
return { type: "announce_cancel", trackNamespace, errorCode, reasonPhrase };
|
|
523
577
|
}
|
|
524
578
|
|
|
525
579
|
function decodeUnannounce(reader: BufferReader): Unannounce {
|
|
526
580
|
const trackNamespace = reader.readTuple();
|
|
527
|
-
return { type:
|
|
581
|
+
return { type: "unannounce", trackNamespace };
|
|
528
582
|
}
|
|
529
583
|
|
|
530
584
|
function decodeTrackStatusRequest(reader: BufferReader): TrackStatusRequest {
|
|
531
585
|
const trackNamespace = reader.readTuple();
|
|
532
586
|
const trackName = reader.readString();
|
|
533
|
-
return { type:
|
|
587
|
+
return { type: "track_status_request", trackNamespace, trackName };
|
|
534
588
|
}
|
|
535
589
|
|
|
536
590
|
function decodeTrackStatus(reader: BufferReader): TrackStatus {
|
|
@@ -539,40 +593,40 @@ function decodeTrackStatus(reader: BufferReader): TrackStatus {
|
|
|
539
593
|
const statusCode = reader.readVarInt();
|
|
540
594
|
const lastGroupId = reader.readVarInt();
|
|
541
595
|
const lastObjectId = reader.readVarInt();
|
|
542
|
-
return { type:
|
|
596
|
+
return { type: "track_status", trackNamespace, trackName, statusCode, lastGroupId, lastObjectId };
|
|
543
597
|
}
|
|
544
598
|
|
|
545
599
|
function decodeGoAway(reader: BufferReader): GoAway {
|
|
546
600
|
const newSessionUri = reader.readString();
|
|
547
|
-
return { type:
|
|
601
|
+
return { type: "goaway", newSessionUri };
|
|
548
602
|
}
|
|
549
603
|
|
|
550
604
|
function decodeSubscribeAnnounces(reader: BufferReader): SubscribeAnnounces {
|
|
551
605
|
const trackNamespace = reader.readTuple();
|
|
552
606
|
const parameters = reader.readParameters();
|
|
553
|
-
return { type:
|
|
607
|
+
return { type: "subscribe_announces", trackNamespace, parameters };
|
|
554
608
|
}
|
|
555
609
|
|
|
556
610
|
function decodeSubscribeAnnouncesOk(reader: BufferReader): SubscribeAnnouncesOk {
|
|
557
611
|
const trackNamespace = reader.readTuple();
|
|
558
|
-
return { type:
|
|
612
|
+
return { type: "subscribe_announces_ok", trackNamespace };
|
|
559
613
|
}
|
|
560
614
|
|
|
561
615
|
function decodeSubscribeAnnouncesError(reader: BufferReader): SubscribeAnnouncesError {
|
|
562
616
|
const trackNamespace = reader.readTuple();
|
|
563
617
|
const errorCode = reader.readVarInt();
|
|
564
618
|
const reasonPhrase = reader.readString();
|
|
565
|
-
return { type:
|
|
619
|
+
return { type: "subscribe_announces_error", trackNamespace, errorCode, reasonPhrase };
|
|
566
620
|
}
|
|
567
621
|
|
|
568
622
|
function decodeUnsubscribeAnnounces(reader: BufferReader): UnsubscribeAnnounces {
|
|
569
623
|
const trackNamespace = reader.readTuple();
|
|
570
|
-
return { type:
|
|
624
|
+
return { type: "unsubscribe_announces", trackNamespace };
|
|
571
625
|
}
|
|
572
626
|
|
|
573
627
|
function decodeMaxSubscribeId(reader: BufferReader): MaxSubscribeId {
|
|
574
628
|
const subscribeId = reader.readVarInt();
|
|
575
|
-
return { type:
|
|
629
|
+
return { type: "max_subscribe_id", subscribeId };
|
|
576
630
|
}
|
|
577
631
|
|
|
578
632
|
function decodeFetch(reader: BufferReader): Fetch {
|
|
@@ -586,7 +640,19 @@ function decodeFetch(reader: BufferReader): Fetch {
|
|
|
586
640
|
const endGroup = reader.readVarInt();
|
|
587
641
|
const endObject = reader.readVarInt();
|
|
588
642
|
const parameters = reader.readParameters();
|
|
589
|
-
return {
|
|
643
|
+
return {
|
|
644
|
+
type: "fetch" as const,
|
|
645
|
+
subscribeId,
|
|
646
|
+
trackNamespace,
|
|
647
|
+
trackName,
|
|
648
|
+
subscriberPriority,
|
|
649
|
+
groupOrder,
|
|
650
|
+
startGroup,
|
|
651
|
+
startObject,
|
|
652
|
+
endGroup,
|
|
653
|
+
endObject,
|
|
654
|
+
parameters,
|
|
655
|
+
};
|
|
590
656
|
}
|
|
591
657
|
|
|
592
658
|
function decodeFetchOk(reader: BufferReader): FetchOk {
|
|
@@ -597,19 +663,27 @@ function decodeFetchOk(reader: BufferReader): FetchOk {
|
|
|
597
663
|
const largestGroupId = reader.readVarInt();
|
|
598
664
|
const largestObjectId = reader.readVarInt();
|
|
599
665
|
const parameters = reader.readParameters();
|
|
600
|
-
return {
|
|
666
|
+
return {
|
|
667
|
+
type: "fetch_ok" as const,
|
|
668
|
+
subscribeId,
|
|
669
|
+
groupOrder,
|
|
670
|
+
endOfTrack,
|
|
671
|
+
largestGroupId,
|
|
672
|
+
largestObjectId,
|
|
673
|
+
parameters,
|
|
674
|
+
};
|
|
601
675
|
}
|
|
602
676
|
|
|
603
677
|
function decodeFetchError(reader: BufferReader): FetchError {
|
|
604
678
|
const subscribeId = reader.readVarInt();
|
|
605
679
|
const errorCode = reader.readVarInt();
|
|
606
680
|
const reasonPhrase = reader.readString();
|
|
607
|
-
return { type:
|
|
681
|
+
return { type: "fetch_error", subscribeId, errorCode, reasonPhrase };
|
|
608
682
|
}
|
|
609
683
|
|
|
610
684
|
function decodeFetchCancel(reader: BufferReader): FetchCancel {
|
|
611
685
|
const subscribeId = reader.readVarInt();
|
|
612
|
-
return { type:
|
|
686
|
+
return { type: "fetch_cancel", subscribeId };
|
|
613
687
|
}
|
|
614
688
|
|
|
615
689
|
function decodeObjectStream(reader: BufferReader): ObjectStream {
|
|
@@ -620,7 +694,15 @@ function decodeObjectStream(reader: BufferReader): ObjectStream {
|
|
|
620
694
|
const publisherPriority = reader.readUint8();
|
|
621
695
|
const objectStatusRaw = Number(reader.readVarInt());
|
|
622
696
|
const payload = reader.readBytes(reader.remaining);
|
|
623
|
-
const base = {
|
|
697
|
+
const base = {
|
|
698
|
+
type: "object_stream" as const,
|
|
699
|
+
subscribeId,
|
|
700
|
+
trackAlias,
|
|
701
|
+
groupId,
|
|
702
|
+
objectId,
|
|
703
|
+
publisherPriority,
|
|
704
|
+
payload,
|
|
705
|
+
};
|
|
624
706
|
if (objectStatusRaw !== 0) {
|
|
625
707
|
return { ...base, objectStatus: objectStatusRaw };
|
|
626
708
|
}
|
|
@@ -635,7 +717,15 @@ function decodeObjectDatagram(reader: BufferReader): ObjectDatagram {
|
|
|
635
717
|
const publisherPriority = reader.readUint8();
|
|
636
718
|
const objectStatusRaw = Number(reader.readVarInt());
|
|
637
719
|
const payload = reader.readBytes(reader.remaining);
|
|
638
|
-
const base = {
|
|
720
|
+
const base = {
|
|
721
|
+
type: "object_datagram" as const,
|
|
722
|
+
subscribeId,
|
|
723
|
+
trackAlias,
|
|
724
|
+
groupId,
|
|
725
|
+
objectId,
|
|
726
|
+
publisherPriority,
|
|
727
|
+
payload,
|
|
728
|
+
};
|
|
639
729
|
if (objectStatusRaw !== 0) {
|
|
640
730
|
return { ...base, objectStatus: objectStatusRaw };
|
|
641
731
|
}
|
|
@@ -646,7 +736,7 @@ function decodeStreamHeaderTrack(reader: BufferReader): StreamHeaderTrack {
|
|
|
646
736
|
const subscribeId = reader.readVarInt();
|
|
647
737
|
const trackAlias = reader.readVarInt();
|
|
648
738
|
const publisherPriority = reader.readUint8();
|
|
649
|
-
return { type:
|
|
739
|
+
return { type: "stream_header_track", subscribeId, trackAlias, publisherPriority };
|
|
650
740
|
}
|
|
651
741
|
|
|
652
742
|
function decodeStreamHeaderGroup(reader: BufferReader): StreamHeaderGroup {
|
|
@@ -654,7 +744,7 @@ function decodeStreamHeaderGroup(reader: BufferReader): StreamHeaderGroup {
|
|
|
654
744
|
const trackAlias = reader.readVarInt();
|
|
655
745
|
const groupId = reader.readVarInt();
|
|
656
746
|
const publisherPriority = reader.readUint8();
|
|
657
|
-
return { type:
|
|
747
|
+
return { type: "stream_header_group", subscribeId, trackAlias, groupId, publisherPriority };
|
|
658
748
|
}
|
|
659
749
|
|
|
660
750
|
function decodeStreamHeaderSubgroup(reader: BufferReader): StreamHeaderSubgroup {
|
|
@@ -663,7 +753,14 @@ function decodeStreamHeaderSubgroup(reader: BufferReader): StreamHeaderSubgroup
|
|
|
663
753
|
const groupId = reader.readVarInt();
|
|
664
754
|
const subgroupId = reader.readVarInt();
|
|
665
755
|
const publisherPriority = reader.readUint8();
|
|
666
|
-
return {
|
|
756
|
+
return {
|
|
757
|
+
type: "stream_header_subgroup",
|
|
758
|
+
subscribeId,
|
|
759
|
+
trackAlias,
|
|
760
|
+
groupId,
|
|
761
|
+
subgroupId,
|
|
762
|
+
publisherPriority,
|
|
763
|
+
};
|
|
667
764
|
}
|
|
668
765
|
|
|
669
766
|
// --- Decode dispatch by wire type ID (control messages only) ---
|
|
@@ -777,7 +874,11 @@ function decodeMessageImpl(bytes: Uint8Array): DecodeResult<MoqtMessage> {
|
|
|
777
874
|
if (!decoder) {
|
|
778
875
|
return {
|
|
779
876
|
ok: false,
|
|
780
|
-
error: new DecodeError(
|
|
877
|
+
error: new DecodeError(
|
|
878
|
+
"UNKNOWN_MESSAGE_TYPE",
|
|
879
|
+
`Unknown data stream type ID: 0x${typeId.toString(16)}`,
|
|
880
|
+
0,
|
|
881
|
+
),
|
|
781
882
|
};
|
|
782
883
|
}
|
|
783
884
|
const message = decoder(reader);
|
|
@@ -786,12 +887,16 @@ function decodeMessageImpl(bytes: Uint8Array): DecodeResult<MoqtMessage> {
|
|
|
786
887
|
|
|
787
888
|
// Control message: read length, then decode payload from bounded sub-reader
|
|
788
889
|
const payloadLength = Number(reader.readVarInt());
|
|
789
|
-
const
|
|
890
|
+
const _headerBytes = reader.offset; // bytes consumed by type + length
|
|
790
891
|
|
|
791
892
|
if (reader.remaining < payloadLength) {
|
|
792
893
|
return {
|
|
793
894
|
ok: false,
|
|
794
|
-
error: new DecodeError(
|
|
895
|
+
error: new DecodeError(
|
|
896
|
+
"UNEXPECTED_END",
|
|
897
|
+
`Not enough bytes for payload: need ${payloadLength}, have ${reader.remaining}`,
|
|
898
|
+
reader.offset,
|
|
899
|
+
),
|
|
795
900
|
};
|
|
796
901
|
}
|
|
797
902
|
|
|
@@ -802,7 +907,11 @@ function decodeMessageImpl(bytes: Uint8Array): DecodeResult<MoqtMessage> {
|
|
|
802
907
|
if (!decoder) {
|
|
803
908
|
return {
|
|
804
909
|
ok: false,
|
|
805
|
-
error: new DecodeError(
|
|
910
|
+
error: new DecodeError(
|
|
911
|
+
"UNKNOWN_MESSAGE_TYPE",
|
|
912
|
+
`Unknown message type ID: 0x${typeId.toString(16)}`,
|
|
913
|
+
0,
|
|
914
|
+
),
|
|
806
915
|
};
|
|
807
916
|
}
|
|
808
917
|
|
|
@@ -832,7 +941,7 @@ function createStreamDecoderImpl(): TransformStream<Uint8Array, MoqtMessage> {
|
|
|
832
941
|
while (buffer.length > 0) {
|
|
833
942
|
const result = decodeMessageImpl(buffer);
|
|
834
943
|
if (!result.ok) {
|
|
835
|
-
if (result.error.code ===
|
|
944
|
+
if (result.error.code === "UNEXPECTED_END") {
|
|
836
945
|
// Need more data -- wait for next chunk
|
|
837
946
|
break;
|
|
838
947
|
}
|
|
@@ -850,7 +959,7 @@ function createStreamDecoderImpl(): TransformStream<Uint8Array, MoqtMessage> {
|
|
|
850
959
|
// If there is remaining data in the buffer, it is a truncated message
|
|
851
960
|
if (buffer.length > 0) {
|
|
852
961
|
controller.error(
|
|
853
|
-
new DecodeError(
|
|
962
|
+
new DecodeError("UNEXPECTED_END", "Stream ended with incomplete message data", 0),
|
|
854
963
|
);
|
|
855
964
|
}
|
|
856
965
|
},
|
|
@@ -861,7 +970,7 @@ function createStreamDecoderImpl(): TransformStream<Uint8Array, MoqtMessage> {
|
|
|
861
970
|
|
|
862
971
|
export function createDraft07Codec(): Codec {
|
|
863
972
|
return {
|
|
864
|
-
draft:
|
|
973
|
+
draft: "draft-ietf-moq-transport-07",
|
|
865
974
|
encodeMessage: encodeMessageImpl,
|
|
866
975
|
decodeMessage: decodeMessageImpl,
|
|
867
976
|
encodeVarInt,
|
|
@@ -1,59 +1,58 @@
|
|
|
1
|
-
export { encodeVarInt, decodeVarInt } from './varint.js';
|
|
2
|
-
export { createDraft07Codec } from './codec.js';
|
|
3
|
-
export { encodeParameters, decodeParameters } from './parameters.js';
|
|
4
|
-
export { MESSAGE_TYPE_IDS, MESSAGE_ID_TO_TYPE } from './messages.js';
|
|
5
|
-
export {
|
|
6
|
-
CONTROL_MESSAGES,
|
|
7
|
-
DATA_MESSAGES,
|
|
8
|
-
CLIENT_ONLY_MESSAGES,
|
|
9
|
-
SERVER_ONLY_MESSAGES,
|
|
10
|
-
getLegalOutgoing,
|
|
11
|
-
getLegalIncoming,
|
|
12
|
-
} from './rules.js';
|
|
13
|
-
|
|
14
1
|
// Re-export types consumers need
|
|
15
2
|
export type {
|
|
16
|
-
MoqtMessage,
|
|
17
|
-
DecodeResult,
|
|
18
|
-
DecodeErrorCode,
|
|
19
|
-
ClientSetup,
|
|
20
|
-
ServerSetup,
|
|
21
|
-
Subscribe,
|
|
22
|
-
SubscribeOk,
|
|
23
|
-
SubscribeError,
|
|
24
|
-
SubscribeDone,
|
|
25
|
-
Unsubscribe,
|
|
26
3
|
Announce,
|
|
27
|
-
AnnounceOk,
|
|
28
|
-
AnnounceError,
|
|
29
4
|
AnnounceCancel,
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
5
|
+
AnnounceError,
|
|
6
|
+
AnnounceOk,
|
|
7
|
+
ClientSetup,
|
|
8
|
+
DecodeErrorCode,
|
|
9
|
+
DecodeResult,
|
|
10
|
+
Fetch,
|
|
11
|
+
FetchCancel,
|
|
12
|
+
FetchError,
|
|
13
|
+
FetchOk,
|
|
14
|
+
FilterType,
|
|
15
|
+
GoAway,
|
|
16
|
+
GroupOrderValue,
|
|
17
|
+
MaxSubscribeId,
|
|
18
|
+
MoqtMessage,
|
|
19
|
+
MoqtMessageType,
|
|
34
20
|
ObjectDatagram,
|
|
35
|
-
|
|
21
|
+
ObjectStream,
|
|
22
|
+
ServerSetup,
|
|
36
23
|
StreamHeaderGroup,
|
|
37
24
|
StreamHeaderSubgroup,
|
|
38
|
-
|
|
25
|
+
StreamHeaderTrack,
|
|
26
|
+
Subscribe,
|
|
39
27
|
SubscribeAnnounces,
|
|
40
|
-
SubscribeAnnouncesOk,
|
|
41
28
|
SubscribeAnnouncesError,
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
29
|
+
SubscribeAnnouncesOk,
|
|
30
|
+
SubscribeDone,
|
|
31
|
+
SubscribeError,
|
|
32
|
+
SubscribeOk,
|
|
46
33
|
SubscribeUpdate,
|
|
34
|
+
TrackStatus,
|
|
35
|
+
TrackStatusRequest,
|
|
36
|
+
Unannounce,
|
|
37
|
+
Unsubscribe,
|
|
47
38
|
UnsubscribeAnnounces,
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
} from
|
|
53
|
-
export {
|
|
39
|
+
} from "../../core/types.js";
|
|
40
|
+
export { DecodeError } from "../../core/types.js";
|
|
41
|
+
export { createDraft07Codec } from "./codec.js";
|
|
42
|
+
export { MESSAGE_ID_TO_TYPE, MESSAGE_TYPE_IDS } from "./messages.js";
|
|
43
|
+
export { decodeParameters, encodeParameters } from "./parameters.js";
|
|
44
|
+
export {
|
|
45
|
+
CLIENT_ONLY_MESSAGES,
|
|
46
|
+
CONTROL_MESSAGES,
|
|
47
|
+
DATA_MESSAGES,
|
|
48
|
+
getLegalIncoming,
|
|
49
|
+
getLegalOutgoing,
|
|
50
|
+
SERVER_ONLY_MESSAGES,
|
|
51
|
+
} from "./rules.js";
|
|
52
|
+
export { decodeVarInt, encodeVarInt } from "./varint.js";
|
|
54
53
|
|
|
55
|
-
import {
|
|
56
|
-
import
|
|
54
|
+
import type { DecodeResult, MoqtMessage } from "../../core/types.js";
|
|
55
|
+
import { createDraft07Codec } from "./codec.js";
|
|
57
56
|
|
|
58
57
|
const defaultCodec = createDraft07Codec();
|
|
59
58
|
|