@moqtap/codec 0.2.1 → 0.2.2

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/package.json CHANGED
@@ -1,192 +1,192 @@
1
- {
2
- "name": "@moqtap/codec",
3
- "version": "0.2.1",
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.js",
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.js",
42
- "require": "./dist/draft7.cjs"
43
- },
44
- "./draft8": {
45
- "bun": "./src/drafts/draft08/index.ts",
46
- "types": "./dist/draft8.d.ts",
47
- "import": "./dist/draft8.js",
48
- "require": "./dist/draft8.cjs"
49
- },
50
- "./draft8/session": {
51
- "bun": "./src/drafts/draft08/session.ts",
52
- "types": "./dist/draft8-session.d.ts",
53
- "import": "./dist/draft8-session.js",
54
- "require": "./dist/draft8-session.cjs"
55
- },
56
- "./draft9": {
57
- "bun": "./src/drafts/draft09/index.ts",
58
- "types": "./dist/draft9.d.ts",
59
- "import": "./dist/draft9.js",
60
- "require": "./dist/draft9.cjs"
61
- },
62
- "./draft9/session": {
63
- "bun": "./src/drafts/draft09/session.ts",
64
- "types": "./dist/draft9-session.d.ts",
65
- "import": "./dist/draft9-session.js",
66
- "require": "./dist/draft9-session.cjs"
67
- },
68
- "./draft10": {
69
- "bun": "./src/drafts/draft10/index.ts",
70
- "types": "./dist/draft10.d.ts",
71
- "import": "./dist/draft10.js",
72
- "require": "./dist/draft10.cjs"
73
- },
74
- "./draft10/session": {
75
- "bun": "./src/drafts/draft10/session.ts",
76
- "types": "./dist/draft10-session.d.ts",
77
- "import": "./dist/draft10-session.js",
78
- "require": "./dist/draft10-session.cjs"
79
- },
80
- "./draft11": {
81
- "bun": "./src/drafts/draft11/index.ts",
82
- "types": "./dist/draft11.d.ts",
83
- "import": "./dist/draft11.js",
84
- "require": "./dist/draft11.cjs"
85
- },
86
- "./draft11/session": {
87
- "bun": "./src/drafts/draft11/session.ts",
88
- "types": "./dist/draft11-session.d.ts",
89
- "import": "./dist/draft11-session.js",
90
- "require": "./dist/draft11-session.cjs"
91
- },
92
- "./draft12": {
93
- "bun": "./src/drafts/draft12/index.ts",
94
- "types": "./dist/draft12.d.ts",
95
- "import": "./dist/draft12.js",
96
- "require": "./dist/draft12.cjs"
97
- },
98
- "./draft12/session": {
99
- "bun": "./src/drafts/draft12/session.ts",
100
- "types": "./dist/draft12-session.d.ts",
101
- "import": "./dist/draft12-session.js",
102
- "require": "./dist/draft12-session.cjs"
103
- },
104
- "./draft13": {
105
- "bun": "./src/drafts/draft13/index.ts",
106
- "types": "./dist/draft13.d.ts",
107
- "import": "./dist/draft13.js",
108
- "require": "./dist/draft13.cjs"
109
- },
110
- "./draft13/session": {
111
- "bun": "./src/drafts/draft13/session.ts",
112
- "types": "./dist/draft13-session.d.ts",
113
- "import": "./dist/draft13-session.js",
114
- "require": "./dist/draft13-session.cjs"
115
- },
116
- "./draft14": {
117
- "bun": "./src/drafts/draft14/index.ts",
118
- "types": "./dist/draft14.d.ts",
119
- "import": "./dist/draft14.js",
120
- "require": "./dist/draft14.cjs"
121
- },
122
- "./session": {
123
- "bun": "./src/session.ts",
124
- "types": "./dist/session.d.ts",
125
- "import": "./dist/session.js",
126
- "require": "./dist/session.cjs"
127
- },
128
- "./draft7/session": {
129
- "bun": "./src/drafts/draft07/session.ts",
130
- "types": "./dist/draft7-session.d.ts",
131
- "import": "./dist/draft7-session.js",
132
- "require": "./dist/draft7-session.cjs"
133
- },
134
- "./draft14/session": {
135
- "bun": "./src/drafts/draft14/session.ts",
136
- "types": "./dist/draft14-session.d.ts",
137
- "import": "./dist/draft14-session.js",
138
- "require": "./dist/draft14-session.cjs"
139
- },
140
- "./draft15": {
141
- "bun": "./src/drafts/draft15/index.ts",
142
- "types": "./dist/draft15.d.ts",
143
- "import": "./dist/draft15.js",
144
- "require": "./dist/draft15.cjs"
145
- },
146
- "./draft15/session": {
147
- "bun": "./src/drafts/draft15/session.ts",
148
- "types": "./dist/draft15-session.d.ts",
149
- "import": "./dist/draft15-session.js",
150
- "require": "./dist/draft15-session.cjs"
151
- },
152
- "./draft16": {
153
- "bun": "./src/drafts/draft16/index.ts",
154
- "types": "./dist/draft16.d.ts",
155
- "import": "./dist/draft16.js",
156
- "require": "./dist/draft16.cjs"
157
- },
158
- "./draft16/session": {
159
- "bun": "./src/drafts/draft16/session.ts",
160
- "types": "./dist/draft16-session.d.ts",
161
- "import": "./dist/draft16-session.js",
162
- "require": "./dist/draft16-session.cjs"
163
- },
164
- "./draft17": {
165
- "bun": "./src/drafts/draft17/index.ts",
166
- "types": "./dist/draft17.d.ts",
167
- "import": "./dist/draft17.js",
168
- "require": "./dist/draft17.cjs"
169
- },
170
- "./draft17/session": {
171
- "bun": "./src/drafts/draft17/session.ts",
172
- "types": "./dist/draft17-session.d.ts",
173
- "import": "./dist/draft17-session.js",
174
- "require": "./dist/draft17-session.cjs"
175
- }
176
- },
177
- "files": [
178
- "dist",
179
- "src",
180
- "!src/__tests__"
181
- ],
182
- "scripts": {
183
- "build": "tsup",
184
- "test": "vitest run"
185
- },
186
- "devDependencies": {
187
- "@moqtap/test-vectors": "^0.7.1",
188
- "tsup": "^8.0.0",
189
- "typescript": "^5.5.0",
190
- "vitest": "^3.0.0"
191
- }
192
- }
1
+ {
2
+ "name": "@moqtap/codec",
3
+ "version": "0.2.2",
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.js",
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.js",
42
+ "require": "./dist/draft7.cjs"
43
+ },
44
+ "./draft8": {
45
+ "bun": "./src/drafts/draft08/index.ts",
46
+ "types": "./dist/draft8.d.ts",
47
+ "import": "./dist/draft8.js",
48
+ "require": "./dist/draft8.cjs"
49
+ },
50
+ "./draft8/session": {
51
+ "bun": "./src/drafts/draft08/session.ts",
52
+ "types": "./dist/draft8-session.d.ts",
53
+ "import": "./dist/draft8-session.js",
54
+ "require": "./dist/draft8-session.cjs"
55
+ },
56
+ "./draft9": {
57
+ "bun": "./src/drafts/draft09/index.ts",
58
+ "types": "./dist/draft9.d.ts",
59
+ "import": "./dist/draft9.js",
60
+ "require": "./dist/draft9.cjs"
61
+ },
62
+ "./draft9/session": {
63
+ "bun": "./src/drafts/draft09/session.ts",
64
+ "types": "./dist/draft9-session.d.ts",
65
+ "import": "./dist/draft9-session.js",
66
+ "require": "./dist/draft9-session.cjs"
67
+ },
68
+ "./draft10": {
69
+ "bun": "./src/drafts/draft10/index.ts",
70
+ "types": "./dist/draft10.d.ts",
71
+ "import": "./dist/draft10.js",
72
+ "require": "./dist/draft10.cjs"
73
+ },
74
+ "./draft10/session": {
75
+ "bun": "./src/drafts/draft10/session.ts",
76
+ "types": "./dist/draft10-session.d.ts",
77
+ "import": "./dist/draft10-session.js",
78
+ "require": "./dist/draft10-session.cjs"
79
+ },
80
+ "./draft11": {
81
+ "bun": "./src/drafts/draft11/index.ts",
82
+ "types": "./dist/draft11.d.ts",
83
+ "import": "./dist/draft11.js",
84
+ "require": "./dist/draft11.cjs"
85
+ },
86
+ "./draft11/session": {
87
+ "bun": "./src/drafts/draft11/session.ts",
88
+ "types": "./dist/draft11-session.d.ts",
89
+ "import": "./dist/draft11-session.js",
90
+ "require": "./dist/draft11-session.cjs"
91
+ },
92
+ "./draft12": {
93
+ "bun": "./src/drafts/draft12/index.ts",
94
+ "types": "./dist/draft12.d.ts",
95
+ "import": "./dist/draft12.js",
96
+ "require": "./dist/draft12.cjs"
97
+ },
98
+ "./draft12/session": {
99
+ "bun": "./src/drafts/draft12/session.ts",
100
+ "types": "./dist/draft12-session.d.ts",
101
+ "import": "./dist/draft12-session.js",
102
+ "require": "./dist/draft12-session.cjs"
103
+ },
104
+ "./draft13": {
105
+ "bun": "./src/drafts/draft13/index.ts",
106
+ "types": "./dist/draft13.d.ts",
107
+ "import": "./dist/draft13.js",
108
+ "require": "./dist/draft13.cjs"
109
+ },
110
+ "./draft13/session": {
111
+ "bun": "./src/drafts/draft13/session.ts",
112
+ "types": "./dist/draft13-session.d.ts",
113
+ "import": "./dist/draft13-session.js",
114
+ "require": "./dist/draft13-session.cjs"
115
+ },
116
+ "./draft14": {
117
+ "bun": "./src/drafts/draft14/index.ts",
118
+ "types": "./dist/draft14.d.ts",
119
+ "import": "./dist/draft14.js",
120
+ "require": "./dist/draft14.cjs"
121
+ },
122
+ "./session": {
123
+ "bun": "./src/session.ts",
124
+ "types": "./dist/session.d.ts",
125
+ "import": "./dist/session.js",
126
+ "require": "./dist/session.cjs"
127
+ },
128
+ "./draft7/session": {
129
+ "bun": "./src/drafts/draft07/session.ts",
130
+ "types": "./dist/draft7-session.d.ts",
131
+ "import": "./dist/draft7-session.js",
132
+ "require": "./dist/draft7-session.cjs"
133
+ },
134
+ "./draft14/session": {
135
+ "bun": "./src/drafts/draft14/session.ts",
136
+ "types": "./dist/draft14-session.d.ts",
137
+ "import": "./dist/draft14-session.js",
138
+ "require": "./dist/draft14-session.cjs"
139
+ },
140
+ "./draft15": {
141
+ "bun": "./src/drafts/draft15/index.ts",
142
+ "types": "./dist/draft15.d.ts",
143
+ "import": "./dist/draft15.js",
144
+ "require": "./dist/draft15.cjs"
145
+ },
146
+ "./draft15/session": {
147
+ "bun": "./src/drafts/draft15/session.ts",
148
+ "types": "./dist/draft15-session.d.ts",
149
+ "import": "./dist/draft15-session.js",
150
+ "require": "./dist/draft15-session.cjs"
151
+ },
152
+ "./draft16": {
153
+ "bun": "./src/drafts/draft16/index.ts",
154
+ "types": "./dist/draft16.d.ts",
155
+ "import": "./dist/draft16.js",
156
+ "require": "./dist/draft16.cjs"
157
+ },
158
+ "./draft16/session": {
159
+ "bun": "./src/drafts/draft16/session.ts",
160
+ "types": "./dist/draft16-session.d.ts",
161
+ "import": "./dist/draft16-session.js",
162
+ "require": "./dist/draft16-session.cjs"
163
+ },
164
+ "./draft17": {
165
+ "bun": "./src/drafts/draft17/index.ts",
166
+ "types": "./dist/draft17.d.ts",
167
+ "import": "./dist/draft17.js",
168
+ "require": "./dist/draft17.cjs"
169
+ },
170
+ "./draft17/session": {
171
+ "bun": "./src/drafts/draft17/session.ts",
172
+ "types": "./dist/draft17-session.d.ts",
173
+ "import": "./dist/draft17-session.js",
174
+ "require": "./dist/draft17-session.cjs"
175
+ }
176
+ },
177
+ "files": [
178
+ "dist",
179
+ "src",
180
+ "!src/__tests__"
181
+ ],
182
+ "scripts": {
183
+ "build": "tsup",
184
+ "test": "vitest run"
185
+ },
186
+ "devDependencies": {
187
+ "@moqtap/test-vectors": "^0.7.3",
188
+ "tsup": "^8.0.0",
189
+ "typescript": "^5.5.0",
190
+ "vitest": "^3.0.0"
191
+ }
192
+ }
@@ -804,10 +804,15 @@ export function encodeMessage(message: Draft11Message): Uint8Array {
804
804
  encodePayload(message, payloadWriter);
805
805
  const payload = payloadWriter.finish();
806
806
 
807
- // Draft-11 uses varint framing (not uint16 BE like draft-14/15)
807
+ if (payload.byteLength > 0xffff) {
808
+ throw new Error(`Payload too large for 16-bit length: ${payload.byteLength}`);
809
+ }
810
+
811
+ // Write framed message: type(varint) + length(uint16 BE) + payload
808
812
  const writer = new BufferWriter();
809
813
  writer.writeVarInt(typeId);
810
- writer.writeVarInt(payload.byteLength);
814
+ writer.writeUint8((payload.byteLength >> 8) & 0xff);
815
+ writer.writeUint8(payload.byteLength & 0xff);
811
816
  writer.writeBytes(payload);
812
817
  return writer.finish();
813
818
  }
@@ -874,13 +879,18 @@ function encodePayload(msg: Draft11Message, w: BufferWriter): void {
874
879
  }
875
880
 
876
881
  /**
877
- * Decode a draft-11 control message from bytes (type + varint length + payload).
882
+ * Decode a draft-11 control message from bytes (type + uint16 length + payload).
878
883
  */
879
884
  export function decodeMessage(bytes: Uint8Array): DecodeResult<Draft11Message> {
880
885
  try {
881
886
  const reader = new BufferReader(bytes);
882
887
  const typeId = reader.readVarInt();
883
- const payloadLength = Number(reader.readVarInt());
888
+
889
+ // Read 16-bit big-endian payload length
890
+ const lenHi = reader.readUint8();
891
+ const lenLo = reader.readUint8();
892
+ const payloadLength = (lenHi << 8) | lenLo;
893
+
884
894
  const payloadBytes = reader.readBytes(payloadLength);
885
895
  const payloadReader = new BufferReader(payloadBytes);
886
896
 
@@ -38,7 +38,6 @@ import {
38
38
  PARAM_DELIVERY_TIMEOUT,
39
39
  SETUP_PARAM_MAX_REQUEST_ID,
40
40
  SETUP_PARAM_PATH,
41
- VARINT_FRAMED_MESSAGES,
42
41
  } from "./messages.js";
43
42
  import type {
44
43
  DatagramObject,
@@ -936,17 +935,11 @@ export function encodeMessage(message: Draft12Message): Uint8Array {
936
935
  const writer = new BufferWriter();
937
936
  writer.writeVarInt(typeId);
938
937
 
939
- if (VARINT_FRAMED_MESSAGES.has(typeId)) {
940
- // PUBLISH family: varint length framing
941
- writer.writeVarInt(payload.byteLength);
942
- } else {
943
- // All other messages: uint16 BE length framing
944
- if (payload.byteLength > 0xffff) {
945
- throw new Error(`Payload too large for 16-bit length: ${payload.byteLength}`);
946
- }
947
- writer.writeUint8((payload.byteLength >> 8) & 0xff);
948
- writer.writeUint8(payload.byteLength & 0xff);
938
+ if (payload.byteLength > 0xffff) {
939
+ throw new Error(`Payload too large for 16-bit length: ${payload.byteLength}`);
949
940
  }
941
+ writer.writeUint8((payload.byteLength >> 8) & 0xff);
942
+ writer.writeUint8(payload.byteLength & 0xff);
950
943
 
951
944
  writer.writeBytes(payload);
952
945
  return writer.finish();
@@ -1027,16 +1020,10 @@ export function decodeMessage(bytes: Uint8Array): DecodeResult<Draft12Message> {
1027
1020
  const reader = new BufferReader(bytes);
1028
1021
  const typeId = reader.readVarInt();
1029
1022
 
1030
- let payloadLength: number;
1031
- if (VARINT_FRAMED_MESSAGES.has(typeId)) {
1032
- // PUBLISH family: varint length framing
1033
- payloadLength = Number(reader.readVarInt());
1034
- } else {
1035
- // All other messages: uint16 BE length framing
1036
- const lenHi = reader.readUint8();
1037
- const lenLo = reader.readUint8();
1038
- payloadLength = (lenHi << 8) | lenLo;
1039
- }
1023
+ // Read 16-bit big-endian payload length
1024
+ const lenHi = reader.readUint8();
1025
+ const lenLo = reader.readUint8();
1026
+ const payloadLength = (lenHi << 8) | lenLo;
1040
1027
 
1041
1028
  const payloadBytes = reader.readBytes(payloadLength);
1042
1029
  const payloadReader = new BufferReader(payloadBytes);
@@ -39,7 +39,6 @@ import {
39
39
  PARAM_DELIVERY_TIMEOUT,
40
40
  SETUP_PARAM_MAX_REQUEST_ID,
41
41
  SETUP_PARAM_PATH,
42
- VARINT_FRAMED_MESSAGES,
43
42
  } from "./messages.js";
44
43
  import type {
45
44
  DatagramObject,
@@ -1018,17 +1017,11 @@ export function encodeMessage(message: Draft13Message): Uint8Array {
1018
1017
  const writer = new BufferWriter();
1019
1018
  writer.writeVarInt(typeId);
1020
1019
 
1021
- if (VARINT_FRAMED_MESSAGES.has(typeId)) {
1022
- // PUBLISH family: varint length framing
1023
- writer.writeVarInt(payload.byteLength);
1024
- } else {
1025
- // All other messages: uint16 BE length framing
1026
- if (payload.byteLength > 0xffff) {
1027
- throw new Error(`Payload too large for 16-bit length: ${payload.byteLength}`);
1028
- }
1029
- writer.writeUint8((payload.byteLength >> 8) & 0xff);
1030
- writer.writeUint8(payload.byteLength & 0xff);
1020
+ if (payload.byteLength > 0xffff) {
1021
+ throw new Error(`Payload too large for 16-bit length: ${payload.byteLength}`);
1031
1022
  }
1023
+ writer.writeUint8((payload.byteLength >> 8) & 0xff);
1024
+ writer.writeUint8(payload.byteLength & 0xff);
1032
1025
 
1033
1026
  writer.writeBytes(payload);
1034
1027
  return writer.finish();
@@ -1111,16 +1104,10 @@ export function decodeMessage(bytes: Uint8Array): DecodeResult<Draft13Message> {
1111
1104
  const reader = new BufferReader(bytes);
1112
1105
  const typeId = reader.readVarInt();
1113
1106
 
1114
- let payloadLength: number;
1115
- if (VARINT_FRAMED_MESSAGES.has(typeId)) {
1116
- // PUBLISH family: varint length framing
1117
- payloadLength = Number(reader.readVarInt());
1118
- } else {
1119
- // All other messages: uint16 BE length framing
1120
- const lenHi = reader.readUint8();
1121
- const lenLo = reader.readUint8();
1122
- payloadLength = (lenHi << 8) | lenLo;
1123
- }
1107
+ // Read 16-bit big-endian payload length
1108
+ const lenHi = reader.readUint8();
1109
+ const lenLo = reader.readUint8();
1110
+ const payloadLength = (lenHi << 8) | lenLo;
1124
1111
 
1125
1112
  const payloadBytes = reader.readBytes(payloadLength);
1126
1113
  const payloadReader = new BufferReader(payloadBytes);