@moqtap/codec 0.8.1 → 0.9.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/CHANGELOG.md +49 -0
- package/README.md +16 -4
- package/dist/chunk-BMJMY6FX.cjs +868 -0
- package/dist/chunk-MAXEHYVB.cjs +2362 -0
- package/dist/{chunk-3YAR3I3S.js → chunk-Q7NSUXXB.js} +3 -1
- package/dist/{chunk-VWXUT5R2.cjs → chunk-TVSFDQYE.cjs} +3 -1
- package/dist/chunk-WX5PU7HF.js +868 -0
- package/dist/chunk-YJGOD3Y4.js +2362 -0
- package/dist/{codec-BLYAy2OP.d.ts → codec--CVeqGQv.d.ts} +1 -1
- package/dist/{codec-DujHf55Z.d.ts → codec-BJ7BHuiZ.d.ts} +1 -1
- package/dist/{codec-D47r_-Rl.d.ts → codec-BKsVu3Fr.d.ts} +1 -1
- package/dist/{codec-BNS3gS77.d.ts → codec-BMwgZIgG.d.ts} +1 -1
- package/dist/{codec-CI0BjmHc.d.ts → codec-BNy5syCU.d.ts} +1 -1
- package/dist/{codec-v6Vloc7H.d.ts → codec-BQa6Qsav.d.ts} +1 -1
- package/dist/codec-Bym-K2q2.d.cts +49 -0
- package/dist/{codec-D2JbI2tp.d.ts → codec-C006F75E.d.ts} +1 -1
- package/dist/codec-C5evFHL-.d.ts +49 -0
- package/dist/{codec-DQWQSam3.d.cts → codec-C6Mx4bwz.d.cts} +1 -1
- package/dist/{codec-DL0njGkL.d.ts → codec-CA6nbbEk.d.ts} +1 -1
- package/dist/{codec-D89DWXbv.d.cts → codec-CSBFdPgP.d.cts} +1 -1
- package/dist/{codec-DvcJgYKq.d.cts → codec-CXCjya_G.d.cts} +1 -1
- package/dist/{codec-hvkJfCF5.d.cts → codec-C_xxsbKy.d.cts} +1 -1
- package/dist/{codec-BOyrk_C9.d.cts → codec-Cfo_z5ET.d.cts} +1 -1
- package/dist/{codec-xeuGZY77.d.cts → codec-CgZdadPt.d.cts} +2 -2
- package/dist/{codec-WwwUipaU.d.ts → codec-Cl73EfRW.d.ts} +1 -1
- package/dist/{codec-BOtv3R5j.d.cts → codec-CtvFK4aV.d.cts} +1 -1
- package/dist/{codec-DAePx2NL.d.ts → codec-CviAa4lp.d.ts} +2 -2
- package/dist/{codec-DJmV04i0.d.ts → codec-D4RvFQmu.d.ts} +1 -1
- package/dist/{codec-cou9XBMF.d.cts → codec-DAyiF5sq.d.cts} +1 -1
- package/dist/{codec-CyApDKwf.d.cts → codec-DJmqoIsp.d.cts} +1 -1
- package/dist/{codec-NMsTK0GX.d.cts → codec-DchsPfr3.d.cts} +1 -1
- package/dist/{codec-DplRgIKq.d.ts → codec-Dl_QIXMz.d.ts} +1 -1
- package/dist/{codec-N3g1lxQQ.d.cts → codec-DzLvG8Wb.d.cts} +1 -1
- package/dist/{codec-D95gT98n.d.cts → codec-DzkdW4kO.d.cts} +1 -1
- package/dist/{codec-CWj5iTxA.d.ts → codec-O-1Js7h4.d.ts} +1 -1
- package/dist/{codec-BqqoYdh_.d.cts → codec-vddqy0KY.d.cts} +1 -1
- package/dist/draft07-session.d.cts +3 -3
- package/dist/draft07-session.d.ts +3 -3
- package/dist/draft07.d.cts +3 -3
- package/dist/draft07.d.ts +3 -3
- package/dist/draft08-session.d.cts +3 -3
- package/dist/draft08-session.d.ts +3 -3
- package/dist/draft08.d.cts +4 -4
- package/dist/draft08.d.ts +4 -4
- package/dist/draft09-session.d.cts +3 -3
- package/dist/draft09-session.d.ts +3 -3
- package/dist/draft09.d.cts +4 -4
- package/dist/draft09.d.ts +4 -4
- package/dist/draft10-session.d.cts +3 -3
- package/dist/draft10-session.d.ts +3 -3
- package/dist/draft10.d.cts +4 -4
- package/dist/draft10.d.ts +4 -4
- package/dist/draft11-session.d.cts +3 -3
- package/dist/draft11-session.d.ts +3 -3
- package/dist/draft11.d.cts +4 -4
- package/dist/draft11.d.ts +4 -4
- package/dist/draft12-session.d.cts +3 -3
- package/dist/draft12-session.d.ts +3 -3
- package/dist/draft12.d.cts +4 -4
- package/dist/draft12.d.ts +4 -4
- package/dist/draft13-session.d.cts +3 -3
- package/dist/draft13-session.d.ts +3 -3
- package/dist/draft13.d.cts +4 -4
- package/dist/draft13.d.ts +4 -4
- package/dist/draft14-session.d.cts +3 -3
- package/dist/draft14-session.d.ts +3 -3
- package/dist/draft14.d.cts +4 -4
- package/dist/draft14.d.ts +4 -4
- package/dist/draft15-session.d.cts +3 -3
- package/dist/draft15-session.d.ts +3 -3
- package/dist/draft15.d.cts +4 -4
- package/dist/draft15.d.ts +4 -4
- package/dist/draft16-session.d.cts +3 -3
- package/dist/draft16-session.d.ts +3 -3
- package/dist/draft16.d.cts +4 -4
- package/dist/draft16.d.ts +4 -4
- package/dist/draft17-session.d.cts +3 -3
- package/dist/draft17-session.d.ts +3 -3
- package/dist/draft17.d.cts +3 -3
- package/dist/draft17.d.ts +3 -3
- package/dist/draft18-session.d.cts +3 -3
- package/dist/draft18-session.d.ts +3 -3
- package/dist/draft18.d.cts +3 -3
- package/dist/draft18.d.ts +3 -3
- package/dist/draft19-session.d.cts +3 -3
- package/dist/draft19-session.d.ts +3 -3
- package/dist/draft19.cjs +2 -2
- package/dist/draft19.d.cts +3 -3
- package/dist/draft19.d.ts +3 -3
- package/dist/draft19.js +1 -1
- package/dist/draft20-session.cjs +8 -0
- package/dist/draft20-session.d.cts +195 -0
- package/dist/draft20-session.d.ts +195 -0
- package/dist/draft20-session.js +8 -0
- package/dist/draft20.cjs +217 -0
- package/dist/draft20.d.cts +175 -0
- package/dist/draft20.d.ts +175 -0
- package/dist/draft20.js +217 -0
- package/dist/index.cjs +9 -3
- package/dist/index.d.cts +32 -17
- package/dist/index.d.ts +32 -17
- package/dist/index.js +8 -2
- package/dist/{session-types-KsqyVp6y.d.cts → session-types-B9idsih-.d.cts} +13 -1
- package/dist/{session-types-C0l_-Ups.d.ts → session-types-Dn7b3RZM.d.ts} +13 -1
- package/dist/session.cjs +5 -1
- package/dist/session.d.cts +5 -3
- package/dist/session.d.ts +5 -3
- package/dist/session.js +5 -1
- package/dist/types-CWCQwuvy.d.cts +359 -0
- package/dist/types-CWCQwuvy.d.ts +359 -0
- package/dist/{types-CdCSIfvI.d.cts → types-DG5_iKuv.d.cts} +1 -1
- package/dist/{types-CdCSIfvI.d.ts → types-DG5_iKuv.d.ts} +1 -1
- package/package.json +16 -3
- package/src/core/session-types.ts +7 -0
- package/src/core/types.ts +1 -0
- package/src/drafts/draft19/codec.ts +4 -2
- package/src/drafts/draft20/codec.ts +1737 -0
- package/src/drafts/draft20/data-streams.ts +1291 -0
- package/src/drafts/draft20/error-codes.ts +135 -0
- package/src/drafts/draft20/index.ts +165 -0
- package/src/drafts/draft20/messages.ts +68 -0
- package/src/drafts/draft20/rules.ts +107 -0
- package/src/drafts/draft20/session-fsm.ts +1063 -0
- package/src/drafts/draft20/session.ts +21 -0
- package/src/drafts/draft20/types.ts +455 -0
- package/src/index.ts +20 -2
- package/src/session.ts +4 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
// Draft-20 error and status code registries.
|
|
2
|
+
//
|
|
3
|
+
// Three codes were removed relative to draft-19 and none was added or
|
|
4
|
+
// renumbered. Each removal leaves an unassigned hole at the old codepoint,
|
|
5
|
+
// so the constants below are gone and the value is listed in the matching
|
|
6
|
+
// RETIRED_* set.
|
|
7
|
+
//
|
|
8
|
+
// The draft DOES say what a receiver does with an unassigned code, in
|
|
9
|
+
// Section 14: treat it as INTERNAL_ERROR for its context, and MUST NOT close
|
|
10
|
+
// the session over it in a REQUEST_ERROR or PUBLISH_DONE. So none of the sets
|
|
11
|
+
// below is a decode gate -- see the note above them.
|
|
12
|
+
|
|
13
|
+
/** draft-20 Section 15.11.1, Table 18 (prose Section 3.5). */
|
|
14
|
+
export const SessionTerminationCode = {
|
|
15
|
+
NoError: 0x0n,
|
|
16
|
+
InternalError: 0x1n,
|
|
17
|
+
Unauthorized: 0x2n,
|
|
18
|
+
ProtocolViolation: 0x3n,
|
|
19
|
+
InvalidRequestId: 0x4n,
|
|
20
|
+
DuplicateTrackAlias: 0x5n,
|
|
21
|
+
KeyValueFormattingError: 0x6n,
|
|
22
|
+
InvalidPath: 0x8n,
|
|
23
|
+
MalformedPath: 0x9n,
|
|
24
|
+
GoawayTimeout: 0x10n,
|
|
25
|
+
ControlMessageTimeout: 0x11n,
|
|
26
|
+
DataStreamTimeout: 0x12n,
|
|
27
|
+
AuthTokenCacheOverflow: 0x13n,
|
|
28
|
+
DuplicateAuthTokenAlias: 0x14n,
|
|
29
|
+
// 0x15 VERSION_NEGOTIATION_FAILED — REMOVED in draft-20. Version negotiation
|
|
30
|
+
// moved to ALPN / WT-Available-Protocols in draft-15, so there is no longer a
|
|
31
|
+
// SETUP-time negotiation that can fail. See RETIRED_SESSION_TERMINATION_CODES.
|
|
32
|
+
MalformedAuthToken: 0x16n,
|
|
33
|
+
UnknownAuthTokenAlias: 0x17n,
|
|
34
|
+
ExpiredAuthToken: 0x18n,
|
|
35
|
+
InvalidAuthority: 0x19n,
|
|
36
|
+
MalformedAuthority: 0x1an,
|
|
37
|
+
TooManyRequestUpdates: 0x1bn,
|
|
38
|
+
} as const
|
|
39
|
+
export type SessionTerminationCodeValue =
|
|
40
|
+
(typeof SessionTerminationCode)[keyof typeof SessionTerminationCode]
|
|
41
|
+
|
|
42
|
+
/** draft-20 Section 15.11.2, Table 19 (prose Section 10.6.2). */
|
|
43
|
+
export const RequestErrorCode = {
|
|
44
|
+
InternalError: 0x0n,
|
|
45
|
+
Unauthorized: 0x1n,
|
|
46
|
+
Timeout: 0x2n,
|
|
47
|
+
NotSupported: 0x3n,
|
|
48
|
+
MalformedAuthToken: 0x4n,
|
|
49
|
+
ExpiredAuthToken: 0x5n,
|
|
50
|
+
GoingAway: 0x6n,
|
|
51
|
+
ExcessiveLoad: 0x9n,
|
|
52
|
+
DoesNotExist: 0x10n,
|
|
53
|
+
InvalidRange: 0x11n,
|
|
54
|
+
MalformedTrack: 0x12n,
|
|
55
|
+
Uninterested: 0x20n,
|
|
56
|
+
PrefixOverlap: 0x30n,
|
|
57
|
+
NamespaceTooLarge: 0x31n,
|
|
58
|
+
// 0x32 INVALID_JOINING_REQUEST_ID — REMOVED in draft-20 along with the whole
|
|
59
|
+
// joining-fetch mechanism (draft-19 Section 10.12.2). A draft-20 FETCH names
|
|
60
|
+
// its own track inline and never references another request, so there is no
|
|
61
|
+
// joining Request ID left to be invalid. See RETIRED_REQUEST_ERROR_CODES.
|
|
62
|
+
UnsupportedExtension: 0x33n,
|
|
63
|
+
Redirect: 0x34n,
|
|
64
|
+
ConflictingFilters: 0x35n,
|
|
65
|
+
InvalidFilter: 0x36n,
|
|
66
|
+
} as const
|
|
67
|
+
export type RequestErrorCodeValue = (typeof RequestErrorCode)[keyof typeof RequestErrorCode]
|
|
68
|
+
|
|
69
|
+
/** draft-20 Section 15.11.3, Table 20 (prose Section 10.12). */
|
|
70
|
+
export const PublishDoneCode = {
|
|
71
|
+
InternalError: 0x0n,
|
|
72
|
+
Unauthorized: 0x1n,
|
|
73
|
+
TrackEnded: 0x2n,
|
|
74
|
+
// 0x3 SUBSCRIPTION_ENDED — REMOVED in draft-20. The behaviour went with it:
|
|
75
|
+
// Section 5.1.2 now says "A publisher does not end a subscription solely
|
|
76
|
+
// because the Largest Object advances past the end of the current Location
|
|
77
|
+
// Filter", which is the only thing this code used to report.
|
|
78
|
+
// See RETIRED_PUBLISH_DONE_CODES.
|
|
79
|
+
GoingAway: 0x4n,
|
|
80
|
+
TooFarBehind: 0x5n,
|
|
81
|
+
Expired: 0x6n,
|
|
82
|
+
UpdateFailed: 0x8n,
|
|
83
|
+
ExcessiveLoad: 0x9n,
|
|
84
|
+
MalformedTrack: 0x12n,
|
|
85
|
+
} as const
|
|
86
|
+
export type PublishDoneCodeValue = (typeof PublishDoneCode)[keyof typeof PublishDoneCode]
|
|
87
|
+
|
|
88
|
+
/** draft-20 Section 15.11.4, Table 21 (prose Section 3.3.4) — unchanged from draft-19. */
|
|
89
|
+
export const DataStreamResetCode = {
|
|
90
|
+
InternalError: 0x0n,
|
|
91
|
+
Cancelled: 0x1n,
|
|
92
|
+
DeliveryTimeout: 0x2n,
|
|
93
|
+
SessionClosed: 0x3n,
|
|
94
|
+
GoingAway: 0x4n,
|
|
95
|
+
TooFarBehind: 0x5n,
|
|
96
|
+
UnknownObjectStatus: 0x6n,
|
|
97
|
+
ExpiredAuthToken: 0x7n,
|
|
98
|
+
ExcessiveLoad: 0x9n,
|
|
99
|
+
MalformedTrack: 0x12n,
|
|
100
|
+
} as const
|
|
101
|
+
export type DataStreamResetCodeValue =
|
|
102
|
+
(typeof DataStreamResetCode)[keyof typeof DataStreamResetCode]
|
|
103
|
+
|
|
104
|
+
/*
|
|
105
|
+
* Retired codepoints.
|
|
106
|
+
*
|
|
107
|
+
* draft-20 states no rule for what a receiver does with a code that is not in
|
|
108
|
+
* a registry, so the decoder does not police the registries in general: an
|
|
109
|
+
* unrecognised-but-unassigned code may well be a codepoint a later draft
|
|
110
|
+
* assigns, and refusing it would make this codec useless as an observer of a
|
|
111
|
+
* newer peer.
|
|
112
|
+
*
|
|
113
|
+
* A code draft-19 assigned and draft-20 deleted is not refused either. It is
|
|
114
|
+
* tempting to: such a code is not merely "unknown to us" but known to be wrong
|
|
115
|
+
* for this version, and seeing one suggests the peer is speaking an older draft
|
|
116
|
+
* on a connection that negotiated moqt-20. But Section 14's "MUST NOT close the
|
|
117
|
+
* session because it received an unknown error code in a REQUEST_ERROR or
|
|
118
|
+
* PUBLISH_DONE" draws no distinction between a code that was never assigned and
|
|
119
|
+
* one that used to be, and the same paragraph is in draft-19 verbatim.
|
|
120
|
+
*
|
|
121
|
+
* So the sets below are advisory. They name what a caller may want to surface
|
|
122
|
+
* — "this peer looks like draft-19" is a genuinely useful diagnostic — and
|
|
123
|
+
* nothing in the decode path consults them.
|
|
124
|
+
*/
|
|
125
|
+
export const RETIRED_SESSION_TERMINATION_CODES: ReadonlySet<bigint> = new Set([
|
|
126
|
+
0x15n, // VERSION_NEGOTIATION_FAILED (draft-19 Section 3.5)
|
|
127
|
+
])
|
|
128
|
+
|
|
129
|
+
export const RETIRED_REQUEST_ERROR_CODES: ReadonlySet<bigint> = new Set([
|
|
130
|
+
0x32n, // INVALID_JOINING_REQUEST_ID (draft-19 Section 10.6.2)
|
|
131
|
+
])
|
|
132
|
+
|
|
133
|
+
export const RETIRED_PUBLISH_DONE_CODES: ReadonlySet<bigint> = new Set([
|
|
134
|
+
0x3n, // SUBSCRIPTION_ENDED (draft-19 Section 10.11)
|
|
135
|
+
])
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
// Draft-20 codec entry point
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Draft-20's real identifier is the protocol string `moqt-20`.
|
|
5
|
+
*
|
|
6
|
+
* draft-20 Section 3.1: "MOQT uses ALPN in QUIC and 'WT-Available-Protocols' in
|
|
7
|
+
* WebTransport to perform version negotiation. […] ALPNs used to identify IETF
|
|
8
|
+
* drafts are created by appending the draft number to 'moqt-'. […] Note: Draft
|
|
9
|
+
* versions prior to -15 all used moq-00 ALPN, followed by version negotiation
|
|
10
|
+
* in the SETUP messages."
|
|
11
|
+
*
|
|
12
|
+
* So this is what a draft-20 peer actually negotiates with, and it is the only
|
|
13
|
+
* identifier that appears anywhere in a draft-20 session.
|
|
14
|
+
*/
|
|
15
|
+
export const PROTOCOL_STRING = 'moqt-20'
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The `0xff000000 + N` identifier for draft 20.
|
|
19
|
+
*
|
|
20
|
+
* **This is a derived identifier, not an observed wire value.** No draft-20
|
|
21
|
+
* peer ever sends it. The `0xff0000NN` scheme belonged to the SETUP-time
|
|
22
|
+
* version negotiation that drafts before -15 used; from draft-15 on the version
|
|
23
|
+
* is negotiated by ALPN / `WT-Available-Protocols` and no version number
|
|
24
|
+
* appears on the wire at all. It is kept only so that code indexing drafts by a
|
|
25
|
+
* numeric key — {@link DRAFT_VERSIONS} in the package root, trace formats,
|
|
26
|
+
* anything that predates the change — has a stable key for draft-20.
|
|
27
|
+
*
|
|
28
|
+
* Anything that reports a version to a user should report
|
|
29
|
+
* {@link PROTOCOL_STRING} instead, and should not claim to have observed this
|
|
30
|
+
* number.
|
|
31
|
+
*/
|
|
32
|
+
export const DRAFT_VERSION = 0xff000014n
|
|
33
|
+
|
|
34
|
+
export type { Draft20Codec } from './codec.js'
|
|
35
|
+
export {
|
|
36
|
+
createDataStreamDecoder,
|
|
37
|
+
createDraft20Codec,
|
|
38
|
+
createFetchStreamDecoder,
|
|
39
|
+
createStreamDecoder,
|
|
40
|
+
createSubgroupStreamDecoder,
|
|
41
|
+
decodeDatagram,
|
|
42
|
+
decodeDataStream,
|
|
43
|
+
decodeFetchStream,
|
|
44
|
+
decodeMessage,
|
|
45
|
+
decodeSubgroupStream,
|
|
46
|
+
encodeDatagram,
|
|
47
|
+
encodeFetchStream,
|
|
48
|
+
encodeMessage,
|
|
49
|
+
encodeSubgroupStream,
|
|
50
|
+
UNKNOWN_STREAM_COUNT,
|
|
51
|
+
} from './codec.js'
|
|
52
|
+
export type {
|
|
53
|
+
DataStreamResetCodeValue,
|
|
54
|
+
PublishDoneCodeValue,
|
|
55
|
+
RequestErrorCodeValue,
|
|
56
|
+
SessionTerminationCodeValue,
|
|
57
|
+
} from './error-codes.js'
|
|
58
|
+
export {
|
|
59
|
+
DataStreamResetCode,
|
|
60
|
+
PublishDoneCode,
|
|
61
|
+
RETIRED_PUBLISH_DONE_CODES,
|
|
62
|
+
RETIRED_REQUEST_ERROR_CODES,
|
|
63
|
+
RETIRED_SESSION_TERMINATION_CODES,
|
|
64
|
+
RequestErrorCode,
|
|
65
|
+
SessionTerminationCode,
|
|
66
|
+
} from './error-codes.js'
|
|
67
|
+
|
|
68
|
+
export {
|
|
69
|
+
MESSAGE_ID_MAP,
|
|
70
|
+
MESSAGE_TYPE_MAP,
|
|
71
|
+
MSG_FETCH,
|
|
72
|
+
MSG_FETCH_OK,
|
|
73
|
+
MSG_GOAWAY,
|
|
74
|
+
MSG_NAMESPACE,
|
|
75
|
+
MSG_NAMESPACE_DONE,
|
|
76
|
+
MSG_PUBLISH,
|
|
77
|
+
MSG_PUBLISH_DONE,
|
|
78
|
+
MSG_PUBLISH_NAMESPACE,
|
|
79
|
+
MSG_PUBLISH_OK,
|
|
80
|
+
MSG_PUBLISH_SKIPPED,
|
|
81
|
+
MSG_PUBLISH_STATE_NOTIFY,
|
|
82
|
+
MSG_REQUEST_ERROR,
|
|
83
|
+
MSG_REQUEST_OK,
|
|
84
|
+
MSG_REQUEST_UPDATE,
|
|
85
|
+
MSG_SETUP,
|
|
86
|
+
MSG_SUBSCRIBE,
|
|
87
|
+
MSG_SUBSCRIBE_NAMESPACE,
|
|
88
|
+
MSG_SUBSCRIBE_OK,
|
|
89
|
+
MSG_SUBSCRIBE_TRACKS,
|
|
90
|
+
MSG_TRACK_STATUS,
|
|
91
|
+
SETUP_OPT_AUTHORITY,
|
|
92
|
+
SETUP_OPT_AUTHORIZATION_TOKEN,
|
|
93
|
+
SETUP_OPT_MAX_AUTH_TOKEN_CACHE_SIZE,
|
|
94
|
+
SETUP_OPT_MAX_FILTER_RANGES,
|
|
95
|
+
SETUP_OPT_MAX_REQUEST_UPDATES,
|
|
96
|
+
SETUP_OPT_MOQT_IMPLEMENTATION,
|
|
97
|
+
SETUP_OPT_PATH,
|
|
98
|
+
} from './messages.js'
|
|
99
|
+
|
|
100
|
+
export {
|
|
101
|
+
BIDIRECTIONAL_MESSAGES,
|
|
102
|
+
CLIENT_ONLY_MESSAGES,
|
|
103
|
+
CONTROL_MESSAGES,
|
|
104
|
+
getLegalIncoming,
|
|
105
|
+
getLegalOutgoing,
|
|
106
|
+
REQUEST_STREAM_OPENERS,
|
|
107
|
+
SERVER_ONLY_MESSAGES,
|
|
108
|
+
} from './rules.js'
|
|
109
|
+
export type {
|
|
110
|
+
FillFetchStreamPhase,
|
|
111
|
+
FillFetchStreamState,
|
|
112
|
+
ProtocolViolation,
|
|
113
|
+
PublisherSide,
|
|
114
|
+
RequestKind,
|
|
115
|
+
SessionPhase,
|
|
116
|
+
SideEffect,
|
|
117
|
+
TransitionResult,
|
|
118
|
+
ValidationResult,
|
|
119
|
+
} from './session.js'
|
|
120
|
+
export { createDraft20SessionState, Draft20SessionFSM } from './session.js'
|
|
121
|
+
|
|
122
|
+
export type {
|
|
123
|
+
DatagramObject,
|
|
124
|
+
DataStreamEvent,
|
|
125
|
+
DataStreamHeader,
|
|
126
|
+
Draft20BaseMessage,
|
|
127
|
+
Draft20DataStream,
|
|
128
|
+
Draft20Fetch,
|
|
129
|
+
Draft20FetchOk,
|
|
130
|
+
Draft20FillParameters,
|
|
131
|
+
Draft20GoAway,
|
|
132
|
+
Draft20Message,
|
|
133
|
+
Draft20MessageType,
|
|
134
|
+
Draft20Namespace,
|
|
135
|
+
Draft20NamespaceDone,
|
|
136
|
+
Draft20Params,
|
|
137
|
+
Draft20Publish,
|
|
138
|
+
Draft20PublishDone,
|
|
139
|
+
Draft20PublishNamespace,
|
|
140
|
+
Draft20PublishSkipped,
|
|
141
|
+
Draft20PublishStateNotify,
|
|
142
|
+
Draft20RequestError,
|
|
143
|
+
Draft20RequestOk,
|
|
144
|
+
Draft20RequestUpdate,
|
|
145
|
+
Draft20Setup,
|
|
146
|
+
Draft20SetupOptions,
|
|
147
|
+
Draft20Subscribe,
|
|
148
|
+
Draft20SubscribeNamespace,
|
|
149
|
+
Draft20SubscribeOk,
|
|
150
|
+
Draft20SubscribeTracks,
|
|
151
|
+
Draft20TrackProperties,
|
|
152
|
+
Draft20TrackStatus,
|
|
153
|
+
FetchObjectPayload,
|
|
154
|
+
FetchStream,
|
|
155
|
+
FetchStreamHeader,
|
|
156
|
+
LargestObject,
|
|
157
|
+
LocationFilter,
|
|
158
|
+
ObjectPayload,
|
|
159
|
+
RangeFilter,
|
|
160
|
+
RangeFilterRange,
|
|
161
|
+
Redirect,
|
|
162
|
+
SubgroupStream,
|
|
163
|
+
SubgroupStreamHeader,
|
|
164
|
+
UnknownParam,
|
|
165
|
+
} from './types.js'
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// Draft-20 message type wire IDs (draft-20 Section 10, Table 5).
|
|
2
|
+
//
|
|
3
|
+
// No codepoint moved between draft-19 and draft-20 and none was removed.
|
|
4
|
+
// Exactly one row was added: PUBLISH_STATE_NOTIFY (0x22).
|
|
5
|
+
|
|
6
|
+
export const MSG_REQUEST_UPDATE = 0x02n
|
|
7
|
+
export const MSG_SUBSCRIBE = 0x03n
|
|
8
|
+
export const MSG_SUBSCRIBE_OK = 0x04n
|
|
9
|
+
export const MSG_REQUEST_ERROR = 0x05n
|
|
10
|
+
export const MSG_PUBLISH_NAMESPACE = 0x06n
|
|
11
|
+
export const MSG_REQUEST_OK = 0x07n
|
|
12
|
+
export const MSG_NAMESPACE = 0x08n
|
|
13
|
+
export const MSG_PUBLISH_DONE = 0x0bn
|
|
14
|
+
export const MSG_TRACK_STATUS = 0x0dn
|
|
15
|
+
export const MSG_NAMESPACE_DONE = 0x0en
|
|
16
|
+
export const MSG_PUBLISH_SKIPPED = 0x0fn
|
|
17
|
+
export const MSG_GOAWAY = 0x10n
|
|
18
|
+
export const MSG_FETCH = 0x16n
|
|
19
|
+
export const MSG_FETCH_OK = 0x18n
|
|
20
|
+
export const MSG_PUBLISH = 0x1dn
|
|
21
|
+
/** NEW in draft-20 — Section 10.10. Unilateral publisher→subscriber notification. */
|
|
22
|
+
export const MSG_PUBLISH_STATE_NOTIFY = 0x22n
|
|
23
|
+
// PUBLISH_OK is not a codepoint of its own: it is a REQUEST_OK (0x07) sent in
|
|
24
|
+
// reply to a PUBLISH (draft-20 Section 10.5). Same for REQUEST_UPDATE_OK,
|
|
25
|
+
// TRACK_STATUS_OK, SUBSCRIBE_NAMESPACE_OK, SUBSCRIBE_TRACKS_OK and
|
|
26
|
+
// PUBLISH_NAMESPACE_OK.
|
|
27
|
+
export const MSG_PUBLISH_OK = MSG_REQUEST_OK
|
|
28
|
+
export const MSG_SUBSCRIBE_NAMESPACE = 0x50n
|
|
29
|
+
export const MSG_SUBSCRIBE_TRACKS = 0x51n
|
|
30
|
+
export const MSG_SETUP = 0x2f00n
|
|
31
|
+
|
|
32
|
+
// Setup option type IDs (KVP encoding, version-independent namespace).
|
|
33
|
+
// Unchanged from draft-19 (draft-20 Section 15.4, Table 10).
|
|
34
|
+
export const SETUP_OPT_PATH = 0x01n
|
|
35
|
+
export const SETUP_OPT_AUTHORIZATION_TOKEN = 0x03n
|
|
36
|
+
export const SETUP_OPT_MAX_AUTH_TOKEN_CACHE_SIZE = 0x04n
|
|
37
|
+
export const SETUP_OPT_AUTHORITY = 0x05n
|
|
38
|
+
export const SETUP_OPT_MAX_FILTER_RANGES = 0x06n
|
|
39
|
+
export const SETUP_OPT_MOQT_IMPLEMENTATION = 0x07n
|
|
40
|
+
export const SETUP_OPT_MAX_REQUEST_UPDATES = 0x08n
|
|
41
|
+
|
|
42
|
+
// Map from wire ID to message type name
|
|
43
|
+
export const MESSAGE_TYPE_MAP: ReadonlyMap<bigint, string> = new Map([
|
|
44
|
+
[MSG_SETUP, 'setup'],
|
|
45
|
+
[MSG_SUBSCRIBE, 'subscribe'],
|
|
46
|
+
[MSG_SUBSCRIBE_OK, 'subscribe_ok'],
|
|
47
|
+
[MSG_REQUEST_UPDATE, 'request_update'],
|
|
48
|
+
[MSG_PUBLISH_STATE_NOTIFY, 'publish_state_notify'],
|
|
49
|
+
[MSG_PUBLISH, 'publish'],
|
|
50
|
+
[MSG_PUBLISH_DONE, 'publish_done'],
|
|
51
|
+
[MSG_PUBLISH_NAMESPACE, 'publish_namespace'],
|
|
52
|
+
[MSG_NAMESPACE, 'namespace'],
|
|
53
|
+
[MSG_NAMESPACE_DONE, 'namespace_done'],
|
|
54
|
+
[MSG_SUBSCRIBE_NAMESPACE, 'subscribe_namespace'],
|
|
55
|
+
[MSG_SUBSCRIBE_TRACKS, 'subscribe_tracks'],
|
|
56
|
+
[MSG_PUBLISH_SKIPPED, 'publish_skipped'],
|
|
57
|
+
[MSG_FETCH, 'fetch'],
|
|
58
|
+
[MSG_FETCH_OK, 'fetch_ok'],
|
|
59
|
+
[MSG_TRACK_STATUS, 'track_status'],
|
|
60
|
+
[MSG_REQUEST_OK, 'request_ok'],
|
|
61
|
+
[MSG_REQUEST_ERROR, 'request_error'],
|
|
62
|
+
[MSG_GOAWAY, 'goaway'],
|
|
63
|
+
])
|
|
64
|
+
|
|
65
|
+
// Reverse map from message type name to wire ID
|
|
66
|
+
export const MESSAGE_ID_MAP: ReadonlyMap<string, bigint> = new Map(
|
|
67
|
+
[...MESSAGE_TYPE_MAP.entries()].map(([id, name]) => [name, id]),
|
|
68
|
+
)
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import type { Draft20MessageType } from './types.js'
|
|
2
|
+
|
|
3
|
+
// All draft-20 control messages (draft-20 Section 10, Table 5)
|
|
4
|
+
export const CONTROL_MESSAGES: ReadonlySet<Draft20MessageType> = new Set([
|
|
5
|
+
'setup',
|
|
6
|
+
'subscribe',
|
|
7
|
+
'subscribe_ok',
|
|
8
|
+
'request_update',
|
|
9
|
+
'publish_state_notify',
|
|
10
|
+
'publish',
|
|
11
|
+
'publish_done',
|
|
12
|
+
'publish_namespace',
|
|
13
|
+
'namespace',
|
|
14
|
+
'namespace_done',
|
|
15
|
+
'subscribe_namespace',
|
|
16
|
+
'subscribe_tracks',
|
|
17
|
+
'publish_skipped',
|
|
18
|
+
'fetch',
|
|
19
|
+
'fetch_ok',
|
|
20
|
+
'track_status',
|
|
21
|
+
'request_ok',
|
|
22
|
+
'request_error',
|
|
23
|
+
'goaway',
|
|
24
|
+
])
|
|
25
|
+
|
|
26
|
+
// Draft-20 has a single SETUP message — both roles can send it
|
|
27
|
+
export const CLIENT_ONLY_MESSAGES: ReadonlySet<Draft20MessageType> = new Set<Draft20MessageType>()
|
|
28
|
+
|
|
29
|
+
export const SERVER_ONLY_MESSAGES: ReadonlySet<Draft20MessageType> = new Set<Draft20MessageType>()
|
|
30
|
+
|
|
31
|
+
// Messages that are bidirectional (both client and server can send)
|
|
32
|
+
export const BIDIRECTIONAL_MESSAGES: ReadonlySet<Draft20MessageType> = new Set([
|
|
33
|
+
'setup',
|
|
34
|
+
'subscribe',
|
|
35
|
+
'subscribe_ok',
|
|
36
|
+
'request_update',
|
|
37
|
+
'publish_state_notify',
|
|
38
|
+
'publish',
|
|
39
|
+
'publish_done',
|
|
40
|
+
'publish_namespace',
|
|
41
|
+
'namespace',
|
|
42
|
+
'namespace_done',
|
|
43
|
+
'subscribe_namespace',
|
|
44
|
+
'subscribe_tracks',
|
|
45
|
+
'publish_skipped',
|
|
46
|
+
'fetch',
|
|
47
|
+
'fetch_ok',
|
|
48
|
+
'track_status',
|
|
49
|
+
'request_ok',
|
|
50
|
+
'request_error',
|
|
51
|
+
'goaway',
|
|
52
|
+
])
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* The seven message types that may be the FIRST message on a new bidirectional
|
|
56
|
+
* (request) stream — draft-20 Section 3.3, and the rows marked "First" in the
|
|
57
|
+
* Section 10 registry. Unchanged from draft-19.
|
|
58
|
+
*
|
|
59
|
+
* "Bidirectional streams MUST NOT begin with any other message type unless
|
|
60
|
+
* negotiated. If they do, the peer MUST close the Session with a
|
|
61
|
+
* PROTOCOL_VIOLATION." Note GOAWAY (0x10) is marked "Control, Request" but not
|
|
62
|
+
* "First": it may travel on either kind of stream but may never open one.
|
|
63
|
+
*/
|
|
64
|
+
export const REQUEST_STREAM_OPENERS: ReadonlySet<Draft20MessageType> = new Set([
|
|
65
|
+
'subscribe',
|
|
66
|
+
'publish',
|
|
67
|
+
'fetch',
|
|
68
|
+
'track_status',
|
|
69
|
+
'publish_namespace',
|
|
70
|
+
'subscribe_namespace',
|
|
71
|
+
'subscribe_tracks',
|
|
72
|
+
])
|
|
73
|
+
|
|
74
|
+
// Messages legal in each session phase
|
|
75
|
+
export function getLegalOutgoing(
|
|
76
|
+
phase: string,
|
|
77
|
+
_role: 'client' | 'server',
|
|
78
|
+
): Set<Draft20MessageType> {
|
|
79
|
+
const legal = new Set<Draft20MessageType>()
|
|
80
|
+
|
|
81
|
+
switch (phase) {
|
|
82
|
+
case 'idle':
|
|
83
|
+
legal.add('setup')
|
|
84
|
+
break
|
|
85
|
+
case 'setup':
|
|
86
|
+
legal.add('setup')
|
|
87
|
+
break
|
|
88
|
+
case 'ready': {
|
|
89
|
+
for (const msg of BIDIRECTIONAL_MESSAGES) {
|
|
90
|
+
legal.add(msg)
|
|
91
|
+
}
|
|
92
|
+
break
|
|
93
|
+
}
|
|
94
|
+
case 'draining':
|
|
95
|
+
break
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return legal
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export function getLegalIncoming(
|
|
102
|
+
phase: string,
|
|
103
|
+
role: 'client' | 'server',
|
|
104
|
+
): Set<Draft20MessageType> {
|
|
105
|
+
const remoteRole = role === 'client' ? 'server' : 'client'
|
|
106
|
+
return getLegalOutgoing(phase, remoteRole)
|
|
107
|
+
}
|