@moqtap/codec 0.1.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.
Files changed (71) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +95 -0
  3. package/dist/chunk-23YG7F46.js +764 -0
  4. package/dist/chunk-2NARXGVA.cjs +194 -0
  5. package/dist/chunk-3BSZ55L3.cjs +307 -0
  6. package/dist/chunk-5WFXFLL4.cjs +1185 -0
  7. package/dist/chunk-DC4L6ZIT.js +307 -0
  8. package/dist/chunk-GDRGWFEK.cjs +498 -0
  9. package/dist/chunk-IQPDRQVC.js +1185 -0
  10. package/dist/chunk-QYG6KGOV.cjs +101 -0
  11. package/dist/chunk-UOBWHJA5.js +101 -0
  12. package/dist/chunk-WNTXF3DE.cjs +764 -0
  13. package/dist/chunk-YBSEOSSP.js +194 -0
  14. package/dist/chunk-YPXLV5YK.js +498 -0
  15. package/dist/codec-CTvFtQQI.d.cts +86 -0
  16. package/dist/codec-qPzfmLNu.d.ts +86 -0
  17. package/dist/draft14-session.cjs +6 -0
  18. package/dist/draft14-session.d.cts +8 -0
  19. package/dist/draft14-session.d.ts +8 -0
  20. package/dist/draft14-session.js +6 -0
  21. package/dist/draft14.cjs +121 -0
  22. package/dist/draft14.d.cts +96 -0
  23. package/dist/draft14.d.ts +96 -0
  24. package/dist/draft14.js +121 -0
  25. package/dist/draft7-session.cjs +7 -0
  26. package/dist/draft7-session.d.cts +7 -0
  27. package/dist/draft7-session.d.ts +7 -0
  28. package/dist/draft7-session.js +7 -0
  29. package/dist/draft7.cjs +60 -0
  30. package/dist/draft7.d.cts +72 -0
  31. package/dist/draft7.d.ts +72 -0
  32. package/dist/draft7.js +60 -0
  33. package/dist/index.cjs +40 -0
  34. package/dist/index.d.cts +40 -0
  35. package/dist/index.d.ts +40 -0
  36. package/dist/index.js +40 -0
  37. package/dist/session-types-B9NIf7_F.d.ts +101 -0
  38. package/dist/session-types-CCo-oA-d.d.cts +101 -0
  39. package/dist/session.cjs +27 -0
  40. package/dist/session.d.cts +24 -0
  41. package/dist/session.d.ts +24 -0
  42. package/dist/session.js +27 -0
  43. package/dist/types-CIk5W10V.d.cts +249 -0
  44. package/dist/types-CIk5W10V.d.ts +249 -0
  45. package/dist/types-ClXELFGN.d.cts +241 -0
  46. package/dist/types-ClXELFGN.d.ts +241 -0
  47. package/package.json +84 -0
  48. package/src/core/buffer-reader.ts +107 -0
  49. package/src/core/buffer-writer.ts +91 -0
  50. package/src/core/errors.ts +1 -0
  51. package/src/core/session-types.ts +103 -0
  52. package/src/core/types.ts +363 -0
  53. package/src/drafts/draft07/announce-fsm.ts +2 -0
  54. package/src/drafts/draft07/codec.ts +874 -0
  55. package/src/drafts/draft07/index.ts +70 -0
  56. package/src/drafts/draft07/messages.ts +44 -0
  57. package/src/drafts/draft07/parameters.ts +12 -0
  58. package/src/drafts/draft07/rules.ts +75 -0
  59. package/src/drafts/draft07/session-fsm.ts +353 -0
  60. package/src/drafts/draft07/session.ts +21 -0
  61. package/src/drafts/draft07/subscription-fsm.ts +3 -0
  62. package/src/drafts/draft07/varint.ts +23 -0
  63. package/src/drafts/draft14/codec.ts +1330 -0
  64. package/src/drafts/draft14/index.ts +132 -0
  65. package/src/drafts/draft14/messages.ts +76 -0
  66. package/src/drafts/draft14/rules.ts +70 -0
  67. package/src/drafts/draft14/session-fsm.ts +480 -0
  68. package/src/drafts/draft14/session.ts +26 -0
  69. package/src/drafts/draft14/types.ts +365 -0
  70. package/src/index.ts +85 -0
  71. package/src/session.ts +58 -0
@@ -0,0 +1,241 @@
1
+ type Draft = 'draft-ietf-moq-transport-07' | 'draft-ietf-moq-transport-14';
2
+ type DraftShorthand = '07' | '14';
3
+ type MoqtMessageType = 'client_setup' | 'server_setup' | 'subscribe' | 'subscribe_ok' | 'subscribe_error' | 'subscribe_done' | 'subscribe_update' | 'unsubscribe' | 'announce' | 'announce_ok' | 'announce_error' | 'announce_cancel' | 'unannounce' | 'track_status_request' | 'track_status' | 'object_stream' | 'object_datagram' | 'stream_header_track' | 'stream_header_group' | 'stream_header_subgroup' | 'goaway' | 'subscribe_announces' | 'subscribe_announces_ok' | 'subscribe_announces_error' | 'unsubscribe_announces' | 'max_subscribe_id' | 'fetch' | 'fetch_ok' | 'fetch_error' | 'fetch_cancel';
4
+ interface BaseMessage {
5
+ readonly type: MoqtMessageType;
6
+ }
7
+ interface ClientSetup extends BaseMessage {
8
+ readonly type: 'client_setup';
9
+ readonly supportedVersions: bigint[];
10
+ readonly parameters: Map<bigint, Uint8Array>;
11
+ }
12
+ interface ServerSetup extends BaseMessage {
13
+ readonly type: 'server_setup';
14
+ readonly selectedVersion: bigint;
15
+ readonly parameters: Map<bigint, Uint8Array>;
16
+ }
17
+ interface Subscribe extends BaseMessage {
18
+ readonly type: 'subscribe';
19
+ readonly subscribeId: bigint;
20
+ readonly trackAlias: bigint;
21
+ readonly trackNamespace: string[];
22
+ readonly trackName: string;
23
+ readonly subscriberPriority: number;
24
+ readonly groupOrder: GroupOrderValue;
25
+ readonly filterType: FilterType;
26
+ readonly startGroup?: bigint;
27
+ readonly startObject?: bigint;
28
+ readonly endGroup?: bigint;
29
+ readonly endObject?: bigint;
30
+ readonly parameters: Map<bigint, Uint8Array>;
31
+ }
32
+ type FilterType = 'latest_group' | 'latest_object' | 'absolute_start' | 'absolute_range';
33
+ interface SubscribeOk extends BaseMessage {
34
+ readonly type: 'subscribe_ok';
35
+ readonly subscribeId: bigint;
36
+ readonly expires: bigint;
37
+ readonly groupOrder: GroupOrderValue;
38
+ readonly contentExists: boolean;
39
+ readonly largestGroupId?: bigint;
40
+ readonly largestObjectId?: bigint;
41
+ readonly parameters: Map<bigint, Uint8Array>;
42
+ }
43
+ type GroupOrderValue = 'ascending' | 'descending' | 'original';
44
+ interface SubscribeError extends BaseMessage {
45
+ readonly type: 'subscribe_error';
46
+ readonly subscribeId: bigint;
47
+ readonly errorCode: bigint;
48
+ readonly reasonPhrase: string;
49
+ readonly trackAlias: bigint;
50
+ }
51
+ interface SubscribeDone extends BaseMessage {
52
+ readonly type: 'subscribe_done';
53
+ readonly subscribeId: bigint;
54
+ readonly statusCode: bigint;
55
+ readonly reasonPhrase: string;
56
+ readonly contentExists: boolean;
57
+ readonly finalGroupId?: bigint;
58
+ readonly finalObjectId?: bigint;
59
+ }
60
+ interface SubscribeUpdate extends BaseMessage {
61
+ readonly type: 'subscribe_update';
62
+ readonly subscribeId: bigint;
63
+ readonly startGroup: bigint;
64
+ readonly startObject: bigint;
65
+ readonly endGroup: bigint;
66
+ readonly endObject: bigint;
67
+ readonly subscriberPriority: number;
68
+ readonly parameters: Map<bigint, Uint8Array>;
69
+ }
70
+ interface Unsubscribe extends BaseMessage {
71
+ readonly type: 'unsubscribe';
72
+ readonly subscribeId: bigint;
73
+ }
74
+ interface Announce extends BaseMessage {
75
+ readonly type: 'announce';
76
+ readonly trackNamespace: string[];
77
+ readonly parameters: Map<bigint, Uint8Array>;
78
+ }
79
+ interface AnnounceOk extends BaseMessage {
80
+ readonly type: 'announce_ok';
81
+ readonly trackNamespace: string[];
82
+ }
83
+ interface AnnounceError extends BaseMessage {
84
+ readonly type: 'announce_error';
85
+ readonly trackNamespace: string[];
86
+ readonly errorCode: bigint;
87
+ readonly reasonPhrase: string;
88
+ }
89
+ interface AnnounceCancel extends BaseMessage {
90
+ readonly type: 'announce_cancel';
91
+ readonly trackNamespace: string[];
92
+ readonly errorCode: bigint;
93
+ readonly reasonPhrase: string;
94
+ }
95
+ interface Unannounce extends BaseMessage {
96
+ readonly type: 'unannounce';
97
+ readonly trackNamespace: string[];
98
+ }
99
+ interface TrackStatusRequest extends BaseMessage {
100
+ readonly type: 'track_status_request';
101
+ readonly trackNamespace: string[];
102
+ readonly trackName: string;
103
+ }
104
+ interface TrackStatus extends BaseMessage {
105
+ readonly type: 'track_status';
106
+ readonly trackNamespace: string[];
107
+ readonly trackName: string;
108
+ readonly statusCode: bigint;
109
+ readonly lastGroupId: bigint;
110
+ readonly lastObjectId: bigint;
111
+ }
112
+ interface ObjectStream extends BaseMessage {
113
+ readonly type: 'object_stream';
114
+ readonly subscribeId: bigint;
115
+ readonly trackAlias: bigint;
116
+ readonly groupId: bigint;
117
+ readonly objectId: bigint;
118
+ readonly publisherPriority: number;
119
+ readonly objectStatus?: number;
120
+ readonly payload: Uint8Array;
121
+ }
122
+ interface ObjectDatagram extends BaseMessage {
123
+ readonly type: 'object_datagram';
124
+ readonly subscribeId: bigint;
125
+ readonly trackAlias: bigint;
126
+ readonly groupId: bigint;
127
+ readonly objectId: bigint;
128
+ readonly publisherPriority: number;
129
+ readonly objectStatus?: number;
130
+ readonly payload: Uint8Array;
131
+ }
132
+ interface StreamHeaderTrack extends BaseMessage {
133
+ readonly type: 'stream_header_track';
134
+ readonly subscribeId: bigint;
135
+ readonly trackAlias: bigint;
136
+ readonly publisherPriority: number;
137
+ }
138
+ interface StreamHeaderGroup extends BaseMessage {
139
+ readonly type: 'stream_header_group';
140
+ readonly subscribeId: bigint;
141
+ readonly trackAlias: bigint;
142
+ readonly groupId: bigint;
143
+ readonly publisherPriority: number;
144
+ }
145
+ interface StreamHeaderSubgroup extends BaseMessage {
146
+ readonly type: 'stream_header_subgroup';
147
+ readonly subscribeId: bigint;
148
+ readonly trackAlias: bigint;
149
+ readonly groupId: bigint;
150
+ readonly subgroupId: bigint;
151
+ readonly publisherPriority: number;
152
+ }
153
+ interface GoAway extends BaseMessage {
154
+ readonly type: 'goaway';
155
+ readonly newSessionUri: string;
156
+ }
157
+ interface SubscribeAnnounces extends BaseMessage {
158
+ readonly type: 'subscribe_announces';
159
+ readonly trackNamespace: string[];
160
+ readonly parameters: Map<bigint, Uint8Array>;
161
+ }
162
+ interface SubscribeAnnouncesOk extends BaseMessage {
163
+ readonly type: 'subscribe_announces_ok';
164
+ readonly trackNamespace: string[];
165
+ }
166
+ interface SubscribeAnnouncesError extends BaseMessage {
167
+ readonly type: 'subscribe_announces_error';
168
+ readonly trackNamespace: string[];
169
+ readonly errorCode: bigint;
170
+ readonly reasonPhrase: string;
171
+ }
172
+ interface UnsubscribeAnnounces extends BaseMessage {
173
+ readonly type: 'unsubscribe_announces';
174
+ readonly trackNamespace: string[];
175
+ }
176
+ interface MaxSubscribeId extends BaseMessage {
177
+ readonly type: 'max_subscribe_id';
178
+ readonly subscribeId: bigint;
179
+ }
180
+ interface Fetch extends BaseMessage {
181
+ readonly type: 'fetch';
182
+ readonly subscribeId: bigint;
183
+ readonly trackNamespace: string[];
184
+ readonly trackName: string;
185
+ readonly subscriberPriority: number;
186
+ readonly groupOrder: GroupOrderValue;
187
+ readonly startGroup: bigint;
188
+ readonly startObject: bigint;
189
+ readonly endGroup: bigint;
190
+ readonly endObject: bigint;
191
+ readonly parameters: Map<bigint, Uint8Array>;
192
+ }
193
+ interface FetchOk extends BaseMessage {
194
+ readonly type: 'fetch_ok';
195
+ readonly subscribeId: bigint;
196
+ readonly groupOrder: GroupOrderValue;
197
+ readonly endOfTrack: boolean;
198
+ readonly largestGroupId: bigint;
199
+ readonly largestObjectId: bigint;
200
+ readonly parameters: Map<bigint, Uint8Array>;
201
+ }
202
+ interface FetchError extends BaseMessage {
203
+ readonly type: 'fetch_error';
204
+ readonly subscribeId: bigint;
205
+ readonly errorCode: bigint;
206
+ readonly reasonPhrase: string;
207
+ }
208
+ interface FetchCancel extends BaseMessage {
209
+ readonly type: 'fetch_cancel';
210
+ readonly subscribeId: bigint;
211
+ }
212
+ type MoqtMessage = ClientSetup | ServerSetup | Subscribe | SubscribeOk | SubscribeError | SubscribeDone | SubscribeUpdate | Unsubscribe | Announce | AnnounceOk | AnnounceError | AnnounceCancel | Unannounce | TrackStatusRequest | TrackStatus | ObjectStream | ObjectDatagram | StreamHeaderTrack | StreamHeaderGroup | StreamHeaderSubgroup | GoAway | SubscribeAnnounces | SubscribeAnnouncesOk | SubscribeAnnouncesError | UnsubscribeAnnounces | MaxSubscribeId | Fetch | FetchOk | FetchError | FetchCancel;
213
+ interface BaseCodec<M = MoqtMessage> {
214
+ readonly draft: Draft;
215
+ encodeMessage(message: M): Uint8Array;
216
+ decodeMessage(bytes: Uint8Array): DecodeResult<M>;
217
+ }
218
+ interface Codec extends BaseCodec<MoqtMessage> {
219
+ encodeVarInt(value: number | bigint): Uint8Array;
220
+ decodeVarInt(bytes: Uint8Array, offset?: number): DecodeResult<bigint>;
221
+ createStreamDecoder(): TransformStream<Uint8Array, MoqtMessage>;
222
+ }
223
+ interface CodecOptions {
224
+ draft: Draft | DraftShorthand;
225
+ }
226
+ type DecodeResult<T> = {
227
+ ok: true;
228
+ value: T;
229
+ bytesRead: number;
230
+ } | {
231
+ ok: false;
232
+ error: DecodeError;
233
+ };
234
+ type DecodeErrorCode = 'UNEXPECTED_END' | 'INVALID_VARINT' | 'UNKNOWN_MESSAGE_TYPE' | 'INVALID_PARAMETER' | 'CONSTRAINT_VIOLATION';
235
+ declare class DecodeError extends Error {
236
+ readonly code: DecodeErrorCode;
237
+ readonly offset: number;
238
+ constructor(code: DecodeErrorCode, message: string, offset: number);
239
+ }
240
+
241
+ export { type Announce as A, type BaseCodec as B, type CodecOptions as C, DecodeError as D, type SubscribeOk as E, type Fetch as F, type GoAway as G, type SubscribeUpdate as H, type TrackStatusRequest as I, type Unsubscribe as J, type UnsubscribeAnnounces as K, type MaxSubscribeId as M, type ObjectDatagram as O, type ServerSetup as S, type TrackStatus as T, type Unannounce as U, type Codec as a, type AnnounceCancel as b, type AnnounceError as c, type AnnounceOk as d, type ClientSetup as e, type DecodeErrorCode as f, type DecodeResult as g, type Draft as h, type DraftShorthand as i, type FetchCancel as j, type FetchError as k, type FetchOk as l, type FilterType as m, type GroupOrderValue as n, type MoqtMessage as o, type MoqtMessageType as p, type ObjectStream as q, type StreamHeaderGroup as r, type StreamHeaderSubgroup as s, type StreamHeaderTrack as t, type Subscribe as u, type SubscribeAnnounces as v, type SubscribeAnnouncesError as w, type SubscribeAnnouncesOk as x, type SubscribeDone as y, type SubscribeError as z };
@@ -0,0 +1,241 @@
1
+ type Draft = 'draft-ietf-moq-transport-07' | 'draft-ietf-moq-transport-14';
2
+ type DraftShorthand = '07' | '14';
3
+ type MoqtMessageType = 'client_setup' | 'server_setup' | 'subscribe' | 'subscribe_ok' | 'subscribe_error' | 'subscribe_done' | 'subscribe_update' | 'unsubscribe' | 'announce' | 'announce_ok' | 'announce_error' | 'announce_cancel' | 'unannounce' | 'track_status_request' | 'track_status' | 'object_stream' | 'object_datagram' | 'stream_header_track' | 'stream_header_group' | 'stream_header_subgroup' | 'goaway' | 'subscribe_announces' | 'subscribe_announces_ok' | 'subscribe_announces_error' | 'unsubscribe_announces' | 'max_subscribe_id' | 'fetch' | 'fetch_ok' | 'fetch_error' | 'fetch_cancel';
4
+ interface BaseMessage {
5
+ readonly type: MoqtMessageType;
6
+ }
7
+ interface ClientSetup extends BaseMessage {
8
+ readonly type: 'client_setup';
9
+ readonly supportedVersions: bigint[];
10
+ readonly parameters: Map<bigint, Uint8Array>;
11
+ }
12
+ interface ServerSetup extends BaseMessage {
13
+ readonly type: 'server_setup';
14
+ readonly selectedVersion: bigint;
15
+ readonly parameters: Map<bigint, Uint8Array>;
16
+ }
17
+ interface Subscribe extends BaseMessage {
18
+ readonly type: 'subscribe';
19
+ readonly subscribeId: bigint;
20
+ readonly trackAlias: bigint;
21
+ readonly trackNamespace: string[];
22
+ readonly trackName: string;
23
+ readonly subscriberPriority: number;
24
+ readonly groupOrder: GroupOrderValue;
25
+ readonly filterType: FilterType;
26
+ readonly startGroup?: bigint;
27
+ readonly startObject?: bigint;
28
+ readonly endGroup?: bigint;
29
+ readonly endObject?: bigint;
30
+ readonly parameters: Map<bigint, Uint8Array>;
31
+ }
32
+ type FilterType = 'latest_group' | 'latest_object' | 'absolute_start' | 'absolute_range';
33
+ interface SubscribeOk extends BaseMessage {
34
+ readonly type: 'subscribe_ok';
35
+ readonly subscribeId: bigint;
36
+ readonly expires: bigint;
37
+ readonly groupOrder: GroupOrderValue;
38
+ readonly contentExists: boolean;
39
+ readonly largestGroupId?: bigint;
40
+ readonly largestObjectId?: bigint;
41
+ readonly parameters: Map<bigint, Uint8Array>;
42
+ }
43
+ type GroupOrderValue = 'ascending' | 'descending' | 'original';
44
+ interface SubscribeError extends BaseMessage {
45
+ readonly type: 'subscribe_error';
46
+ readonly subscribeId: bigint;
47
+ readonly errorCode: bigint;
48
+ readonly reasonPhrase: string;
49
+ readonly trackAlias: bigint;
50
+ }
51
+ interface SubscribeDone extends BaseMessage {
52
+ readonly type: 'subscribe_done';
53
+ readonly subscribeId: bigint;
54
+ readonly statusCode: bigint;
55
+ readonly reasonPhrase: string;
56
+ readonly contentExists: boolean;
57
+ readonly finalGroupId?: bigint;
58
+ readonly finalObjectId?: bigint;
59
+ }
60
+ interface SubscribeUpdate extends BaseMessage {
61
+ readonly type: 'subscribe_update';
62
+ readonly subscribeId: bigint;
63
+ readonly startGroup: bigint;
64
+ readonly startObject: bigint;
65
+ readonly endGroup: bigint;
66
+ readonly endObject: bigint;
67
+ readonly subscriberPriority: number;
68
+ readonly parameters: Map<bigint, Uint8Array>;
69
+ }
70
+ interface Unsubscribe extends BaseMessage {
71
+ readonly type: 'unsubscribe';
72
+ readonly subscribeId: bigint;
73
+ }
74
+ interface Announce extends BaseMessage {
75
+ readonly type: 'announce';
76
+ readonly trackNamespace: string[];
77
+ readonly parameters: Map<bigint, Uint8Array>;
78
+ }
79
+ interface AnnounceOk extends BaseMessage {
80
+ readonly type: 'announce_ok';
81
+ readonly trackNamespace: string[];
82
+ }
83
+ interface AnnounceError extends BaseMessage {
84
+ readonly type: 'announce_error';
85
+ readonly trackNamespace: string[];
86
+ readonly errorCode: bigint;
87
+ readonly reasonPhrase: string;
88
+ }
89
+ interface AnnounceCancel extends BaseMessage {
90
+ readonly type: 'announce_cancel';
91
+ readonly trackNamespace: string[];
92
+ readonly errorCode: bigint;
93
+ readonly reasonPhrase: string;
94
+ }
95
+ interface Unannounce extends BaseMessage {
96
+ readonly type: 'unannounce';
97
+ readonly trackNamespace: string[];
98
+ }
99
+ interface TrackStatusRequest extends BaseMessage {
100
+ readonly type: 'track_status_request';
101
+ readonly trackNamespace: string[];
102
+ readonly trackName: string;
103
+ }
104
+ interface TrackStatus extends BaseMessage {
105
+ readonly type: 'track_status';
106
+ readonly trackNamespace: string[];
107
+ readonly trackName: string;
108
+ readonly statusCode: bigint;
109
+ readonly lastGroupId: bigint;
110
+ readonly lastObjectId: bigint;
111
+ }
112
+ interface ObjectStream extends BaseMessage {
113
+ readonly type: 'object_stream';
114
+ readonly subscribeId: bigint;
115
+ readonly trackAlias: bigint;
116
+ readonly groupId: bigint;
117
+ readonly objectId: bigint;
118
+ readonly publisherPriority: number;
119
+ readonly objectStatus?: number;
120
+ readonly payload: Uint8Array;
121
+ }
122
+ interface ObjectDatagram extends BaseMessage {
123
+ readonly type: 'object_datagram';
124
+ readonly subscribeId: bigint;
125
+ readonly trackAlias: bigint;
126
+ readonly groupId: bigint;
127
+ readonly objectId: bigint;
128
+ readonly publisherPriority: number;
129
+ readonly objectStatus?: number;
130
+ readonly payload: Uint8Array;
131
+ }
132
+ interface StreamHeaderTrack extends BaseMessage {
133
+ readonly type: 'stream_header_track';
134
+ readonly subscribeId: bigint;
135
+ readonly trackAlias: bigint;
136
+ readonly publisherPriority: number;
137
+ }
138
+ interface StreamHeaderGroup extends BaseMessage {
139
+ readonly type: 'stream_header_group';
140
+ readonly subscribeId: bigint;
141
+ readonly trackAlias: bigint;
142
+ readonly groupId: bigint;
143
+ readonly publisherPriority: number;
144
+ }
145
+ interface StreamHeaderSubgroup extends BaseMessage {
146
+ readonly type: 'stream_header_subgroup';
147
+ readonly subscribeId: bigint;
148
+ readonly trackAlias: bigint;
149
+ readonly groupId: bigint;
150
+ readonly subgroupId: bigint;
151
+ readonly publisherPriority: number;
152
+ }
153
+ interface GoAway extends BaseMessage {
154
+ readonly type: 'goaway';
155
+ readonly newSessionUri: string;
156
+ }
157
+ interface SubscribeAnnounces extends BaseMessage {
158
+ readonly type: 'subscribe_announces';
159
+ readonly trackNamespace: string[];
160
+ readonly parameters: Map<bigint, Uint8Array>;
161
+ }
162
+ interface SubscribeAnnouncesOk extends BaseMessage {
163
+ readonly type: 'subscribe_announces_ok';
164
+ readonly trackNamespace: string[];
165
+ }
166
+ interface SubscribeAnnouncesError extends BaseMessage {
167
+ readonly type: 'subscribe_announces_error';
168
+ readonly trackNamespace: string[];
169
+ readonly errorCode: bigint;
170
+ readonly reasonPhrase: string;
171
+ }
172
+ interface UnsubscribeAnnounces extends BaseMessage {
173
+ readonly type: 'unsubscribe_announces';
174
+ readonly trackNamespace: string[];
175
+ }
176
+ interface MaxSubscribeId extends BaseMessage {
177
+ readonly type: 'max_subscribe_id';
178
+ readonly subscribeId: bigint;
179
+ }
180
+ interface Fetch extends BaseMessage {
181
+ readonly type: 'fetch';
182
+ readonly subscribeId: bigint;
183
+ readonly trackNamespace: string[];
184
+ readonly trackName: string;
185
+ readonly subscriberPriority: number;
186
+ readonly groupOrder: GroupOrderValue;
187
+ readonly startGroup: bigint;
188
+ readonly startObject: bigint;
189
+ readonly endGroup: bigint;
190
+ readonly endObject: bigint;
191
+ readonly parameters: Map<bigint, Uint8Array>;
192
+ }
193
+ interface FetchOk extends BaseMessage {
194
+ readonly type: 'fetch_ok';
195
+ readonly subscribeId: bigint;
196
+ readonly groupOrder: GroupOrderValue;
197
+ readonly endOfTrack: boolean;
198
+ readonly largestGroupId: bigint;
199
+ readonly largestObjectId: bigint;
200
+ readonly parameters: Map<bigint, Uint8Array>;
201
+ }
202
+ interface FetchError extends BaseMessage {
203
+ readonly type: 'fetch_error';
204
+ readonly subscribeId: bigint;
205
+ readonly errorCode: bigint;
206
+ readonly reasonPhrase: string;
207
+ }
208
+ interface FetchCancel extends BaseMessage {
209
+ readonly type: 'fetch_cancel';
210
+ readonly subscribeId: bigint;
211
+ }
212
+ type MoqtMessage = ClientSetup | ServerSetup | Subscribe | SubscribeOk | SubscribeError | SubscribeDone | SubscribeUpdate | Unsubscribe | Announce | AnnounceOk | AnnounceError | AnnounceCancel | Unannounce | TrackStatusRequest | TrackStatus | ObjectStream | ObjectDatagram | StreamHeaderTrack | StreamHeaderGroup | StreamHeaderSubgroup | GoAway | SubscribeAnnounces | SubscribeAnnouncesOk | SubscribeAnnouncesError | UnsubscribeAnnounces | MaxSubscribeId | Fetch | FetchOk | FetchError | FetchCancel;
213
+ interface BaseCodec<M = MoqtMessage> {
214
+ readonly draft: Draft;
215
+ encodeMessage(message: M): Uint8Array;
216
+ decodeMessage(bytes: Uint8Array): DecodeResult<M>;
217
+ }
218
+ interface Codec extends BaseCodec<MoqtMessage> {
219
+ encodeVarInt(value: number | bigint): Uint8Array;
220
+ decodeVarInt(bytes: Uint8Array, offset?: number): DecodeResult<bigint>;
221
+ createStreamDecoder(): TransformStream<Uint8Array, MoqtMessage>;
222
+ }
223
+ interface CodecOptions {
224
+ draft: Draft | DraftShorthand;
225
+ }
226
+ type DecodeResult<T> = {
227
+ ok: true;
228
+ value: T;
229
+ bytesRead: number;
230
+ } | {
231
+ ok: false;
232
+ error: DecodeError;
233
+ };
234
+ type DecodeErrorCode = 'UNEXPECTED_END' | 'INVALID_VARINT' | 'UNKNOWN_MESSAGE_TYPE' | 'INVALID_PARAMETER' | 'CONSTRAINT_VIOLATION';
235
+ declare class DecodeError extends Error {
236
+ readonly code: DecodeErrorCode;
237
+ readonly offset: number;
238
+ constructor(code: DecodeErrorCode, message: string, offset: number);
239
+ }
240
+
241
+ export { type Announce as A, type BaseCodec as B, type CodecOptions as C, DecodeError as D, type SubscribeOk as E, type Fetch as F, type GoAway as G, type SubscribeUpdate as H, type TrackStatusRequest as I, type Unsubscribe as J, type UnsubscribeAnnounces as K, type MaxSubscribeId as M, type ObjectDatagram as O, type ServerSetup as S, type TrackStatus as T, type Unannounce as U, type Codec as a, type AnnounceCancel as b, type AnnounceError as c, type AnnounceOk as d, type ClientSetup as e, type DecodeErrorCode as f, type DecodeResult as g, type Draft as h, type DraftShorthand as i, type FetchCancel as j, type FetchError as k, type FetchOk as l, type FilterType as m, type GroupOrderValue as n, type MoqtMessage as o, type MoqtMessageType as p, type ObjectStream as q, type StreamHeaderGroup as r, type StreamHeaderSubgroup as s, type StreamHeaderTrack as t, type Subscribe as u, type SubscribeAnnounces as v, type SubscribeAnnouncesError as w, type SubscribeAnnouncesOk as x, type SubscribeDone as y, type SubscribeError as z };
package/package.json ADDED
@@ -0,0 +1,84 @@
1
+ {
2
+ "name": "@moqtap/codec",
3
+ "version": "0.1.0",
4
+ "description": "MoQT wire-format codec and session state machine — multi-draft, zero dependencies",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "author": "moqtap",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/moqtap/moqtap-js.git",
11
+ "directory": "packages/codec"
12
+ },
13
+ "homepage": "https://github.com/moqtap/moqtap-js/tree/master/packages/codec",
14
+ "bugs": "https://github.com/moqtap/moqtap-js/issues",
15
+ "keywords": [
16
+ "moqt",
17
+ "moq",
18
+ "media-over-quic",
19
+ "webtransport",
20
+ "codec",
21
+ "protocol",
22
+ "ietf",
23
+ "quic",
24
+ "streaming",
25
+ "real-time"
26
+ ],
27
+ "sideEffects": false,
28
+ "engines": {
29
+ "node": ">=18"
30
+ },
31
+ "exports": {
32
+ ".": {
33
+ "bun": "./src/index.ts",
34
+ "types": "./dist/index.d.ts",
35
+ "import": "./dist/index.mjs",
36
+ "require": "./dist/index.cjs"
37
+ },
38
+ "./draft7": {
39
+ "bun": "./src/drafts/draft07/index.ts",
40
+ "types": "./dist/draft7.d.ts",
41
+ "import": "./dist/draft7.mjs",
42
+ "require": "./dist/draft7.cjs"
43
+ },
44
+ "./draft14": {
45
+ "bun": "./src/drafts/draft14/index.ts",
46
+ "types": "./dist/draft14.d.ts",
47
+ "import": "./dist/draft14.mjs",
48
+ "require": "./dist/draft14.cjs"
49
+ },
50
+ "./session": {
51
+ "bun": "./src/session.ts",
52
+ "types": "./dist/session.d.ts",
53
+ "import": "./dist/session.mjs",
54
+ "require": "./dist/session.cjs"
55
+ },
56
+ "./draft7/session": {
57
+ "bun": "./src/drafts/draft07/session.ts",
58
+ "types": "./dist/draft7-session.d.ts",
59
+ "import": "./dist/draft7-session.mjs",
60
+ "require": "./dist/draft7-session.cjs"
61
+ },
62
+ "./draft14/session": {
63
+ "bun": "./src/drafts/draft14/session.ts",
64
+ "types": "./dist/draft14-session.d.ts",
65
+ "import": "./dist/draft14-session.mjs",
66
+ "require": "./dist/draft14-session.cjs"
67
+ }
68
+ },
69
+ "files": [
70
+ "dist",
71
+ "src",
72
+ "!src/__tests__"
73
+ ],
74
+ "scripts": {
75
+ "build": "tsup",
76
+ "test": "vitest run"
77
+ },
78
+ "devDependencies": {
79
+ "@moqtap/test-vectors": "^0.1.0",
80
+ "tsup": "^8.0.0",
81
+ "typescript": "^5.5.0",
82
+ "vitest": "^3.0.0"
83
+ }
84
+ }
@@ -0,0 +1,107 @@
1
+ import { DecodeError } from './types.js';
2
+
3
+ export class BufferReader {
4
+ private readonly view: DataView;
5
+ private pos: number;
6
+
7
+ constructor(readonly buffer: Uint8Array, offset = 0) {
8
+ this.view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
9
+ this.pos = offset;
10
+ }
11
+
12
+ get offset(): number {
13
+ return this.pos;
14
+ }
15
+
16
+ get remaining(): number {
17
+ return this.buffer.byteLength - this.pos;
18
+ }
19
+
20
+ readUint8(): number {
21
+ if (this.remaining < 1) {
22
+ throw new DecodeError('UNEXPECTED_END', 'Not enough bytes to read uint8', this.pos);
23
+ }
24
+ const value = this.view.getUint8(this.pos);
25
+ this.pos += 1;
26
+ return value;
27
+ }
28
+
29
+ readBytes(length: number): Uint8Array {
30
+ if (this.remaining < length) {
31
+ throw new DecodeError('UNEXPECTED_END', `Not enough bytes: need ${length}, have ${this.remaining}`, this.pos);
32
+ }
33
+ const slice = this.buffer.slice(this.pos, this.pos + length);
34
+ this.pos += length;
35
+ return slice;
36
+ }
37
+
38
+ readVarInt(): bigint {
39
+ if (this.remaining < 1) {
40
+ throw new DecodeError('UNEXPECTED_END', 'Not enough bytes for varint', this.pos);
41
+ }
42
+ const first = this.view.getUint8(this.pos);
43
+ const prefix = first >> 6;
44
+ let length: number;
45
+ let value: bigint;
46
+
47
+ switch (prefix) {
48
+ case 0:
49
+ length = 1;
50
+ value = BigInt(first & 0x3f);
51
+ break;
52
+ case 1:
53
+ length = 2;
54
+ if (this.remaining < 2) {
55
+ throw new DecodeError('UNEXPECTED_END', 'Not enough bytes for 2-byte varint', this.pos);
56
+ }
57
+ value = BigInt(this.view.getUint16(this.pos) & 0x3fff);
58
+ break;
59
+ case 2:
60
+ length = 4;
61
+ if (this.remaining < 4) {
62
+ throw new DecodeError('UNEXPECTED_END', 'Not enough bytes for 4-byte varint', this.pos);
63
+ }
64
+ value = BigInt(this.view.getUint32(this.pos)) & 0x3fffffffn;
65
+ break;
66
+ case 3:
67
+ length = 8;
68
+ if (this.remaining < 8) {
69
+ throw new DecodeError('UNEXPECTED_END', 'Not enough bytes for 8-byte varint', this.pos);
70
+ }
71
+ value = this.view.getBigUint64(this.pos) & 0x3fffffffffffffffn;
72
+ break;
73
+ default:
74
+ throw new DecodeError('INVALID_VARINT', 'Invalid varint prefix', this.pos);
75
+ }
76
+
77
+ this.pos += length;
78
+ return value;
79
+ }
80
+
81
+ readString(): string {
82
+ const length = Number(this.readVarInt());
83
+ const bytes = this.readBytes(length);
84
+ return new TextDecoder().decode(bytes);
85
+ }
86
+
87
+ readTuple(): string[] {
88
+ const count = Number(this.readVarInt());
89
+ const result: string[] = [];
90
+ for (let i = 0; i < count; i++) {
91
+ result.push(this.readString());
92
+ }
93
+ return result;
94
+ }
95
+
96
+ readParameters(): Map<bigint, Uint8Array> {
97
+ const count = Number(this.readVarInt());
98
+ const params = new Map<bigint, Uint8Array>();
99
+ for (let i = 0; i < count; i++) {
100
+ const key = this.readVarInt();
101
+ const length = Number(this.readVarInt());
102
+ const value = this.readBytes(length);
103
+ params.set(key, value);
104
+ }
105
+ return params;
106
+ }
107
+ }