@moqtap/codec 0.10.0 → 0.11.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 (213) hide show
  1. package/CHANGELOG.md +147 -0
  2. package/dist/auth-redaction-DsdLq4Qs.d.cts +102 -0
  3. package/dist/auth-redaction-DsdLq4Qs.d.ts +102 -0
  4. package/dist/{chunk-RYKQXBG6.cjs → chunk-27K5BUAG.cjs} +481 -517
  5. package/dist/{chunk-WCPENYNE.js → chunk-3RNQMGKA.js} +359 -390
  6. package/dist/{chunk-TSUZ6GJV.js → chunk-5AWIXOLB.js} +438 -469
  7. package/dist/{chunk-4XLYCT5Q.cjs → chunk-5IMHJIAZ.cjs} +52 -2
  8. package/dist/{chunk-KTNERCTZ.cjs → chunk-5JGZCKJO.cjs} +488 -518
  9. package/dist/{chunk-WCTMPDUX.cjs → chunk-73K4OSAN.cjs} +401 -432
  10. package/dist/{chunk-N2V7Z37J.js → chunk-7VQKRGRD.js} +19 -3
  11. package/dist/{chunk-BIBMDTU5.cjs → chunk-A3UCQOIB.cjs} +486 -517
  12. package/dist/{chunk-K2B3OVFK.js → chunk-A7PDMVXM.js} +24 -3
  13. package/dist/{chunk-VZHL2U2N.cjs → chunk-A7VQO6YC.cjs} +54 -38
  14. package/dist/{chunk-AQ445VV7.cjs → chunk-ACQHZLRZ.cjs} +66 -46
  15. package/dist/{chunk-L5DRACXS.js → chunk-BBICOMW6.js} +25 -3
  16. package/dist/{chunk-T4VWPKDG.cjs → chunk-BNIUVOCJ.cjs} +529 -599
  17. package/dist/{chunk-UKKDOOUO.cjs → chunk-CNC6ANS4.cjs} +58 -37
  18. package/dist/{chunk-OZRK73NQ.js → chunk-FDLQSWHK.js} +433 -469
  19. package/dist/{chunk-IJAF6PAY.js → chunk-FFNOE4UR.js} +19 -3
  20. package/dist/{chunk-CZNW3R5E.cjs → chunk-GMENT63T.cjs} +54 -38
  21. package/dist/{chunk-XCRCAUGI.cjs → chunk-HM7BLRVP.cjs} +291 -297
  22. package/dist/{chunk-XHAP2YST.js → chunk-HZONHFNO.js} +19 -3
  23. package/dist/{chunk-SDJTSMOW.cjs → chunk-ILYABWDK.cjs} +60 -38
  24. package/dist/{chunk-IDV2JYJ6.cjs → chunk-KRSFTZVO.cjs} +56 -40
  25. package/dist/{chunk-RIIA4ALQ.cjs → chunk-KSPH6KMH.cjs} +54 -38
  26. package/dist/{chunk-OUNN4IQB.cjs → chunk-KTY4LAUV.cjs} +482 -497
  27. package/dist/{chunk-RZTLQAKF.js → chunk-OJNLJT5D.js} +0 -1
  28. package/dist/{chunk-FT3HDNIB.js → chunk-PJK2ZS3I.js} +467 -537
  29. package/dist/{chunk-G53WYUXL.js → chunk-PSMZKHOC.js} +441 -456
  30. package/dist/{chunk-7RE6KSIY.cjs → chunk-Q5JQGHWY.cjs} +0 -1
  31. package/dist/{chunk-BX2N7TZM.js → chunk-SQTUQY5E.js} +31 -11
  32. package/dist/{chunk-CF5DDD3Q.js → chunk-WCRLAKDW.js} +239 -245
  33. package/dist/{chunk-KYVTM5VI.js → chunk-WL2YUEXH.js} +19 -3
  34. package/dist/{chunk-KGDVC4O6.js → chunk-YCNIVZS7.js} +439 -469
  35. package/dist/{chunk-KLPWJU6W.js → chunk-YRZQVNZO.js} +50 -0
  36. package/dist/{codec-CFWu5KVT.d.cts → codec-76xzrLTL.d.cts} +21 -2
  37. package/dist/{codec-gl4_QEva.d.ts → codec-8p40WdLg.d.ts} +20 -1
  38. package/dist/{codec-Dl_QIXMz.d.ts → codec-BN2Bu0KI.d.ts} +20 -1
  39. package/dist/{codec-Bux_Q40X.d.ts → codec-Bb6GKTrv.d.ts} +21 -2
  40. package/dist/{codec-EvybrBuY.d.cts → codec-BgpfHoAd.d.cts} +20 -1
  41. package/dist/{codec-alVA27Uc.d.ts → codec-BkheTXO7.d.ts} +20 -1
  42. package/dist/{codec-Czejcmxr.d.cts → codec-BwVDkokh.d.cts} +21 -2
  43. package/dist/{codec-BrTi4K7r.d.cts → codec-C5s1eBJX.d.cts} +21 -2
  44. package/dist/codec-CM5yd6n3.d.ts +38 -0
  45. package/dist/{codec-CWnf8mn_.d.cts → codec-Cb8HC3XV.d.cts} +21 -2
  46. package/dist/codec-Clu_skx8.d.cts +38 -0
  47. package/dist/{codec-DzkdW4kO.d.cts → codec-CpOpemR8.d.cts} +20 -1
  48. package/dist/{codec-CXCjya_G.d.cts → codec-Cshdl9Tt.d.cts} +20 -1
  49. package/dist/{codec-f7vxeVIS.d.cts → codec-DELe00w_.d.cts} +21 -2
  50. package/dist/{codec-DNmiG2e0.d.cts → codec-DHzKAUCa.d.cts} +20 -1
  51. package/dist/{codec--CVeqGQv.d.ts → codec-DdVBtvx7.d.ts} +20 -1
  52. package/dist/{codec-CBdOIfMY.d.ts → codec-DlxGuYMv.d.ts} +21 -2
  53. package/dist/{codec-BNy5syCU.d.ts → codec-DxtgPxJS.d.ts} +20 -1
  54. package/dist/{codec-guzqtfMk.d.cts → codec-GAY4lybi.d.cts} +20 -1
  55. package/dist/{codec-Cfo_z5ET.d.cts → codec-I8u2pfS4.d.cts} +20 -1
  56. package/dist/{codec-BxQTybUX.d.cts → codec-XLrnreeu.d.cts} +21 -2
  57. package/dist/{codec-DOmAmFkI.d.ts → codec-c0YEwwWn.d.ts} +20 -1
  58. package/dist/{codec-DaXjRrOV.d.ts → codec-ejDu-va6.d.ts} +21 -2
  59. package/dist/{codec-C3mdsGx3.d.ts → codec-kaBUzdpV.d.ts} +21 -2
  60. package/dist/{codec-CwZ6OCPP.d.ts → codec-mVYqkIUF.d.ts} +21 -2
  61. package/dist/{codec-08ZOr5wI.d.ts → codec-qSbO5nOa.d.ts} +21 -2
  62. package/dist/{codec-Cm3D261p.d.ts → codec-yYKGOipj.d.ts} +20 -1
  63. package/dist/{codec-Bd60SGKH.d.cts → codec-zfzg9uiy.d.cts} +20 -1
  64. package/dist/draft07.cjs +48 -4
  65. package/dist/draft07.d.cts +42 -2
  66. package/dist/draft07.d.ts +42 -2
  67. package/dist/draft07.js +49 -5
  68. package/dist/draft08.cjs +76 -3
  69. package/dist/draft08.d.cts +70 -2
  70. package/dist/draft08.d.ts +70 -2
  71. package/dist/draft08.js +77 -4
  72. package/dist/draft09.cjs +76 -3
  73. package/dist/draft09.d.cts +70 -2
  74. package/dist/draft09.d.ts +70 -2
  75. package/dist/draft09.js +77 -4
  76. package/dist/draft10.cjs +76 -3
  77. package/dist/draft10.d.cts +70 -2
  78. package/dist/draft10.d.ts +70 -2
  79. package/dist/draft10.js +77 -4
  80. package/dist/draft11.cjs +104 -3
  81. package/dist/draft11.d.cts +98 -2
  82. package/dist/draft11.d.ts +98 -2
  83. package/dist/draft11.js +105 -4
  84. package/dist/draft12.cjs +113 -3
  85. package/dist/draft12.d.cts +107 -2
  86. package/dist/draft12.d.ts +107 -2
  87. package/dist/draft12.js +114 -4
  88. package/dist/draft13.cjs +105 -3
  89. package/dist/draft13.d.cts +99 -2
  90. package/dist/draft13.d.ts +99 -2
  91. package/dist/draft13.js +106 -4
  92. package/dist/draft14.cjs +107 -3
  93. package/dist/draft14.d.cts +101 -28
  94. package/dist/draft14.d.ts +101 -28
  95. package/dist/draft14.js +108 -4
  96. package/dist/draft15-session.d.cts +1 -1
  97. package/dist/draft15-session.d.ts +1 -1
  98. package/dist/draft15.cjs +69 -3
  99. package/dist/draft15.d.cts +65 -22
  100. package/dist/draft15.d.ts +65 -22
  101. package/dist/draft15.js +70 -4
  102. package/dist/draft16-session.cjs +2 -2
  103. package/dist/draft16-session.d.cts +1 -1
  104. package/dist/draft16-session.d.ts +1 -1
  105. package/dist/draft16-session.js +1 -1
  106. package/dist/draft16.cjs +76 -8
  107. package/dist/draft16.d.cts +67 -13
  108. package/dist/draft16.d.ts +67 -13
  109. package/dist/draft16.js +73 -5
  110. package/dist/draft17-session.d.cts +1 -1
  111. package/dist/draft17-session.d.ts +1 -1
  112. package/dist/draft17.cjs +77 -3
  113. package/dist/draft17.d.cts +73 -4
  114. package/dist/draft17.d.ts +73 -4
  115. package/dist/draft17.js +78 -4
  116. package/dist/draft18-session.d.cts +1 -1
  117. package/dist/draft18-session.d.ts +1 -1
  118. package/dist/draft18.cjs +8 -3
  119. package/dist/draft18.d.cts +4 -3
  120. package/dist/draft18.d.ts +4 -3
  121. package/dist/draft18.js +9 -4
  122. package/dist/draft19-session.d.cts +1 -1
  123. package/dist/draft19-session.d.ts +1 -1
  124. package/dist/draft19.cjs +11 -4
  125. package/dist/draft19.d.cts +4 -3
  126. package/dist/draft19.d.ts +4 -3
  127. package/dist/draft19.js +12 -5
  128. package/dist/draft20-session.d.cts +1 -1
  129. package/dist/draft20-session.d.ts +1 -1
  130. package/dist/draft20.cjs +8 -3
  131. package/dist/draft20.d.cts +4 -3
  132. package/dist/draft20.d.ts +4 -3
  133. package/dist/draft20.js +9 -4
  134. package/dist/index.cjs +30 -30
  135. package/dist/index.d.cts +21 -20
  136. package/dist/index.d.ts +21 -20
  137. package/dist/index.js +15 -15
  138. package/dist/session.cjs +2 -2
  139. package/dist/session.d.cts +6 -6
  140. package/dist/session.d.ts +6 -6
  141. package/dist/session.js +1 -1
  142. package/dist/{types-C1rxh-id.d.cts → types-Btp416jt.d.cts} +8 -0
  143. package/dist/{types-C1rxh-id.d.ts → types-Btp416jt.d.ts} +8 -0
  144. package/dist/{types-CZTzbIzQ.d.cts → types-BxTL1NXw.d.cts} +7 -0
  145. package/dist/{types-CZTzbIzQ.d.ts → types-BxTL1NXw.d.ts} +7 -0
  146. package/dist/{types-pShrs3fN.d.cts → types-CuibHYcf.d.cts} +7 -0
  147. package/dist/{types-pShrs3fN.d.ts → types-CuibHYcf.d.ts} +7 -0
  148. package/dist/{types-CY-QWxd-.d.cts → types-CwN7AEoL.d.cts} +13 -1
  149. package/dist/{types-CY-QWxd-.d.ts → types-CwN7AEoL.d.ts} +13 -1
  150. package/dist/{types-D4bmW8rY.d.cts → types-DAnalt5K.d.cts} +7 -0
  151. package/dist/{types-D4bmW8rY.d.ts → types-DAnalt5K.d.ts} +7 -0
  152. package/dist/{types-Bg86GGVZ.d.cts → types-DxXNP32l.d.cts} +8 -0
  153. package/dist/{types-Bg86GGVZ.d.ts → types-DxXNP32l.d.ts} +8 -0
  154. package/package.json +3 -3
  155. package/src/core/auth-redaction.ts +192 -0
  156. package/src/drafts/draft07/codec.ts +40 -0
  157. package/src/drafts/draft07/error-codes.ts +44 -0
  158. package/src/drafts/draft07/index.ts +15 -0
  159. package/src/drafts/draft08/codec.ts +40 -0
  160. package/src/drafts/draft08/error-codes.ts +76 -0
  161. package/src/drafts/draft08/index.ts +21 -0
  162. package/src/drafts/draft09/codec.ts +40 -0
  163. package/src/drafts/draft09/error-codes.ts +76 -0
  164. package/src/drafts/draft09/index.ts +21 -0
  165. package/src/drafts/draft10/codec.ts +40 -0
  166. package/src/drafts/draft10/error-codes.ts +76 -0
  167. package/src/drafts/draft10/index.ts +21 -0
  168. package/src/drafts/draft11/codec.ts +60 -0
  169. package/src/drafts/draft11/error-codes.ts +106 -0
  170. package/src/drafts/draft11/index.ts +23 -0
  171. package/src/drafts/draft12/codec.ts +61 -0
  172. package/src/drafts/draft12/error-codes.ts +116 -0
  173. package/src/drafts/draft12/index.ts +25 -0
  174. package/src/drafts/draft13/codec.ts +69 -11
  175. package/src/drafts/draft13/error-codes.ts +107 -0
  176. package/src/drafts/draft13/index.ts +23 -0
  177. package/src/drafts/draft13/types.ts +1 -1
  178. package/src/drafts/draft14/codec.ts +65 -4
  179. package/src/drafts/draft14/data-streams.ts +331 -259
  180. package/src/drafts/draft14/error-codes.ts +109 -0
  181. package/src/drafts/draft14/index.ts +23 -0
  182. package/src/drafts/draft15/codec.ts +65 -8
  183. package/src/drafts/draft15/data-streams.ts +489 -444
  184. package/src/drafts/draft15/error-codes.ts +66 -0
  185. package/src/drafts/draft15/index.ts +15 -0
  186. package/src/drafts/draft15/types.ts +7 -0
  187. package/src/drafts/draft16/codec.ts +146 -52
  188. package/src/drafts/draft16/data-streams.ts +513 -442
  189. package/src/drafts/draft16/error-codes.ts +68 -0
  190. package/src/drafts/draft16/index.ts +15 -0
  191. package/src/drafts/draft16/messages.ts +4 -4
  192. package/src/drafts/draft16/session-fsm.ts +0 -1
  193. package/src/drafts/draft16/types.ts +22 -8
  194. package/src/drafts/draft17/codec.ts +73 -12
  195. package/src/drafts/draft17/data-streams.ts +567 -488
  196. package/src/drafts/draft17/index.ts +15 -0
  197. package/src/drafts/draft17/types.ts +7 -0
  198. package/src/drafts/draft18/codec.ts +66 -9
  199. package/src/drafts/draft18/data-streams.ts +570 -482
  200. package/src/drafts/draft18/index.ts +3 -0
  201. package/src/drafts/draft18/types.ts +16 -8
  202. package/src/drafts/draft19/codec.ts +70 -10
  203. package/src/drafts/draft19/data-streams.ts +570 -482
  204. package/src/drafts/draft19/error-codes.ts +3 -1
  205. package/src/drafts/draft19/index.ts +3 -0
  206. package/src/drafts/draft19/messages.ts +3 -1
  207. package/src/drafts/draft19/types.ts +22 -11
  208. package/src/drafts/draft20/codec.ts +90 -23
  209. package/src/drafts/draft20/data-streams.ts +610 -563
  210. package/src/drafts/draft20/index.ts +3 -0
  211. package/src/drafts/draft20/types.ts +14 -2
  212. package/dist/codec-BJ7BHuiZ.d.ts +0 -18
  213. package/dist/codec-C6Mx4bwz.d.cts +0 -18
@@ -3,8 +3,11 @@ import {
3
3
  MoqtBufferReader,
4
4
  MoqtBufferWriter,
5
5
  bytesToHex,
6
- hexToBytes
7
- } from "./chunk-KLPWJU6W.js";
6
+ hexToBytes,
7
+ recordAuthValueSpan,
8
+ redactWith,
9
+ withoutAuthValueSpans
10
+ } from "./chunk-YRZQVNZO.js";
8
11
 
9
12
  // src/drafts/draft20/messages.ts
10
13
  var MSG_REQUEST_UPDATE = 0x02n;
@@ -302,95 +305,107 @@ function resolveGroupId(first, delta, prevGroupId, offset) {
302
305
  }
303
306
  return groupId;
304
307
  }
308
+ function readSubgroupHeader(r) {
309
+ const typeFlags = r.readVarInt();
310
+ const flagsError = subgroupTypeFlagsError(typeFlags);
311
+ if (flagsError !== null) {
312
+ throw new DecodeError("CONSTRAINT_VIOLATION", flagsError, 0);
313
+ }
314
+ const streamType = Number(typeFlags);
315
+ const propertiesPresent = (streamType & 1) !== 0;
316
+ const subgroupMode = (streamType & 6) >> 1;
317
+ const hasSubgroupField = subgroupMode === 2;
318
+ const subgroupIsFirstObjId = subgroupMode === 1;
319
+ const endOfGroup = (streamType & 8) !== 0;
320
+ const hasPriority = (streamType & 32) === 0;
321
+ const firstObjectFlag = (streamType & 64) !== 0;
322
+ const trackAlias = r.readVarInt();
323
+ const groupId = r.readVarInt();
324
+ let subgroupId = 0n;
325
+ if (hasSubgroupField) {
326
+ subgroupId = r.readVarInt();
327
+ }
328
+ let publisherPriority = 128;
329
+ if (hasPriority) {
330
+ publisherPriority = r.readUint8();
331
+ }
332
+ return {
333
+ streamType,
334
+ propertiesPresent,
335
+ subgroupIsFirstObjId,
336
+ endOfGroup,
337
+ firstObjectFlag,
338
+ trackAlias,
339
+ groupId,
340
+ subgroupId,
341
+ publisherPriority
342
+ };
343
+ }
344
+ function readSubgroupObject(r, propertiesPresent, isFirst, prevObjectId, base) {
345
+ const byteOffset = base + r.offset;
346
+ const delta = r.readVarInt();
347
+ const objectId = isFirst ? delta : prevObjectId + 1n + delta;
348
+ const extensionData = new Uint8Array(0);
349
+ let objectProperties;
350
+ if (propertiesPresent) {
351
+ const propsLen = Number(r.readVarInt());
352
+ if (propsLen > 0) {
353
+ objectProperties = decodeObjectProperties(r, propsLen);
354
+ }
355
+ }
356
+ const payloadLength = Number(r.readVarInt());
357
+ let payload;
358
+ let status;
359
+ let payloadByteOffset;
360
+ if (payloadLength === 0) {
361
+ status = r.readVarInt();
362
+ payloadByteOffset = base + r.offset;
363
+ payload = new Uint8Array(0);
364
+ } else {
365
+ payloadByteOffset = base + r.offset;
366
+ payload = r.readBytesView(payloadLength);
367
+ }
368
+ const obj = {
369
+ type: "object",
370
+ byteOffset,
371
+ payloadByteOffset,
372
+ objectId,
373
+ objectIdDelta: delta,
374
+ payloadLength,
375
+ payload,
376
+ extensionData
377
+ };
378
+ if (status !== void 0) obj.status = status;
379
+ if (objectProperties !== void 0)
380
+ obj.objectProperties = objectProperties;
381
+ return obj;
382
+ }
305
383
  function decodeSubgroupStream(bytes) {
306
384
  try {
307
385
  const r = new MoqtBufferReader(bytes);
308
- const typeFlags = r.readVarInt();
309
- const flagsError = subgroupTypeFlagsError(typeFlags);
310
- if (flagsError !== null) {
311
- return { ok: false, error: new DecodeError("CONSTRAINT_VIOLATION", flagsError, 0) };
312
- }
313
- const streamType = Number(typeFlags);
314
- const propertiesPresent = (streamType & 1) !== 0;
315
- const subgroupMode = (streamType & 6) >> 1;
316
- const hasSubgroupField = subgroupMode === 2;
317
- const subgroupIsFirstObjId = subgroupMode === 1;
318
- const endOfGroup = (streamType & 8) !== 0;
319
- const hasPriority = (streamType & 32) === 0;
320
- const firstObject = (streamType & 64) !== 0;
321
- const trackAlias = r.readVarInt();
322
- const groupId = r.readVarInt();
323
- let subgroupId = 0n;
324
- if (hasSubgroupField) {
325
- subgroupId = r.readVarInt();
326
- }
327
- let publisherPriority = 128;
328
- if (hasPriority) {
329
- publisherPriority = r.readUint8();
330
- }
386
+ const h = readSubgroupHeader(r);
331
387
  const objects = [];
332
388
  let prevObjectId = -1n;
333
389
  let isFirst = true;
390
+ let subgroupId = h.subgroupId;
334
391
  while (r.remaining > 0) {
335
- const byteOffset = r.offset;
336
- const delta = r.readVarInt();
337
- let objectId;
338
- if (isFirst) {
339
- objectId = delta;
340
- if (subgroupIsFirstObjId) {
341
- subgroupId = objectId;
342
- }
343
- isFirst = false;
344
- } else {
345
- objectId = prevObjectId + 1n + delta;
346
- }
347
- const extensionData = new Uint8Array(0);
348
- let objectProperties;
349
- if (propertiesPresent) {
350
- const propsLen = Number(r.readVarInt());
351
- if (propsLen > 0) {
352
- objectProperties = decodeObjectProperties(r, propsLen);
353
- }
354
- }
355
- const payloadLength = Number(r.readVarInt());
356
- let payload;
357
- let status;
358
- let payloadByteOffset;
359
- if (payloadLength === 0) {
360
- status = r.readVarInt();
361
- payloadByteOffset = r.offset;
362
- payload = new Uint8Array(0);
363
- } else {
364
- payloadByteOffset = r.offset;
365
- payload = r.readBytesView(payloadLength);
366
- }
367
- const obj = {
368
- type: "object",
369
- byteOffset,
370
- payloadByteOffset,
371
- objectId,
372
- objectIdDelta: delta,
373
- payloadLength,
374
- payload,
375
- extensionData
376
- };
377
- if (status !== void 0) obj.status = status;
378
- if (objectProperties !== void 0)
379
- obj.objectProperties = objectProperties;
392
+ const obj = readSubgroupObject(r, h.propertiesPresent, isFirst, prevObjectId, 0);
393
+ if (isFirst && h.subgroupIsFirstObjId) subgroupId = obj.objectId;
394
+ isFirst = false;
380
395
  objects.push(obj);
381
- prevObjectId = objectId;
396
+ prevObjectId = obj.objectId;
382
397
  }
383
398
  const result = {
384
399
  type: "subgroup",
385
- headerType: streamType,
386
- trackAlias,
387
- groupId,
400
+ headerType: h.streamType,
401
+ trackAlias: h.trackAlias,
402
+ groupId: h.groupId,
388
403
  subgroupId,
389
- publisherPriority,
390
- objects
404
+ publisherPriority: h.publisherPriority,
405
+ objects,
406
+ ...h.endOfGroup ? { endOfGroup: true } : {},
407
+ ...h.firstObjectFlag ? { firstObject: true } : {}
391
408
  };
392
- if (endOfGroup) result.endOfGroup = true;
393
- if (firstObject) result.firstObject = true;
394
409
  return {
395
410
  ok: true,
396
411
  value: result,
@@ -490,6 +505,195 @@ function decodeDatagram(bytes) {
490
505
  throw e;
491
506
  }
492
507
  }
508
+ function newFetchObjectState() {
509
+ return { prevGroupId: 0n, prevSubgroupId: 0n, prevObjectId: 0n, prevPriority: 128, first: true };
510
+ }
511
+ function readFetchObject(r, base, st) {
512
+ const byteOffset = base + r.offset;
513
+ const flags = Number(r.readVarInt());
514
+ let groupId = st.prevGroupId;
515
+ let subgroupId = st.prevSubgroupId;
516
+ let objectId = st.prevObjectId + 1n;
517
+ let payloadLength;
518
+ let payload;
519
+ let payloadByteOffset;
520
+ const extensionData = new Uint8Array(0);
521
+ if (flags >= 128) {
522
+ if (!FETCH_END_OF_RANGE_MARKERS.has(flags)) {
523
+ throw new DecodeError(
524
+ "CONSTRAINT_VIOLATION",
525
+ `0x${flags.toString(16)} is neither a flag combination below 128 nor one of the three End of Range markers`,
526
+ r.offset
527
+ );
528
+ }
529
+ const groupDelta2 = r.readVarInt();
530
+ groupId = resolveGroupId(st.first, groupDelta2, st.prevGroupId, r.offset);
531
+ const objectDelta2 = r.readVarInt();
532
+ objectId = objectDelta2;
533
+ payloadLength = Number(r.readVarInt());
534
+ payloadByteOffset = base + r.offset;
535
+ payload = payloadLength > 0 ? r.readBytesView(payloadLength) : new Uint8Array(0);
536
+ const marker = {
537
+ type: "object",
538
+ byteOffset,
539
+ payloadByteOffset,
540
+ serializationFlags: flags,
541
+ groupId,
542
+ groupIdDelta: groupDelta2,
543
+ // A marker has no Subgroup ID or Priority of its own — Section
544
+ // 11.4.4.2 says neither field is present. The interface requires
545
+ // both, so they carry the last actual Object's values, which is also
546
+ // what a following Object that references "the prior Object" gets.
547
+ subgroupId: st.prevSubgroupId,
548
+ objectId,
549
+ objectIdDelta: objectDelta2,
550
+ publisherPriority: st.prevPriority,
551
+ payloadLength,
552
+ payload,
553
+ extensionData
554
+ };
555
+ st.prevGroupId = groupId;
556
+ st.prevObjectId = objectId;
557
+ st.first = false;
558
+ return marker;
559
+ }
560
+ if (flags & 64) {
561
+ const objectIdPresent2 = (flags & 4) !== 0;
562
+ const groupIdPresent2 = (flags & 8) !== 0;
563
+ const priorityPresent2 = (flags & 16) !== 0;
564
+ const propsPresent2 = (flags & 32) !== 0;
565
+ let groupDelta2;
566
+ if (groupIdPresent2) {
567
+ groupDelta2 = r.readVarInt();
568
+ groupId = resolveGroupId(st.first, groupDelta2, st.prevGroupId, r.offset);
569
+ }
570
+ let objectDelta2;
571
+ if (objectIdPresent2) {
572
+ objectDelta2 = r.readVarInt();
573
+ objectId = resolveObjectId(groupIdPresent2, objectDelta2, st.prevObjectId);
574
+ }
575
+ if (objectId > MAX_U64) {
576
+ throw new DecodeError("CONSTRAINT_VIOLATION", "computed Object ID exceeds 2^64 - 1", r.offset);
577
+ }
578
+ if (priorityPresent2) {
579
+ st.prevPriority = r.readUint8();
580
+ }
581
+ let objectProperties2;
582
+ if (propsPresent2) {
583
+ const propsLen = Number(r.readVarInt());
584
+ if (propsLen > 0) {
585
+ objectProperties2 = decodeObjectProperties(r, propsLen);
586
+ }
587
+ }
588
+ payloadLength = Number(r.readVarInt());
589
+ payloadByteOffset = base + r.offset;
590
+ payload = payloadLength > 0 ? r.readBytesView(payloadLength) : new Uint8Array(0);
591
+ const obj2 = {
592
+ type: "object",
593
+ byteOffset,
594
+ payloadByteOffset,
595
+ serializationFlags: flags,
596
+ groupId,
597
+ subgroupId: 0n,
598
+ objectId,
599
+ publisherPriority: st.prevPriority,
600
+ payloadLength,
601
+ payload,
602
+ extensionData
603
+ };
604
+ if (groupDelta2 !== void 0)
605
+ obj2.groupIdDelta = groupDelta2;
606
+ if (objectDelta2 !== void 0)
607
+ obj2.objectIdDelta = objectDelta2;
608
+ if (objectProperties2)
609
+ obj2.objectProperties = objectProperties2;
610
+ st.prevGroupId = groupId;
611
+ st.prevObjectId = objectId;
612
+ st.first = false;
613
+ return obj2;
614
+ }
615
+ const subgroupEncoding = flags & 3;
616
+ const objectIdPresent = (flags & 4) !== 0;
617
+ const groupIdPresent = (flags & 8) !== 0;
618
+ const priorityPresent = (flags & 16) !== 0;
619
+ const propsPresent = (flags & 32) !== 0;
620
+ let groupDelta;
621
+ if (groupIdPresent) {
622
+ groupDelta = r.readVarInt();
623
+ groupId = resolveGroupId(st.first, groupDelta, st.prevGroupId, r.offset);
624
+ } else if (st.first) {
625
+ throw new DecodeError(
626
+ "CONSTRAINT_VIOLATION",
627
+ "First fetch object must include groupId",
628
+ r.offset
629
+ );
630
+ }
631
+ if (subgroupEncoding === 0) {
632
+ subgroupId = 0n;
633
+ } else if (subgroupEncoding === 1 || subgroupEncoding === 2) {
634
+ if (st.first) {
635
+ throw new DecodeError(
636
+ "CONSTRAINT_VIOLATION",
637
+ "First fetch object cannot reference prior subgroupId",
638
+ r.offset
639
+ );
640
+ }
641
+ subgroupId = subgroupEncoding === 1 ? st.prevSubgroupId : st.prevSubgroupId + 1n;
642
+ } else {
643
+ subgroupId = r.readVarInt();
644
+ }
645
+ let objectDelta;
646
+ if (objectIdPresent) {
647
+ objectDelta = r.readVarInt();
648
+ objectId = resolveObjectId(groupIdPresent, objectDelta, st.prevObjectId);
649
+ } else if (st.first) {
650
+ throw new DecodeError(
651
+ "CONSTRAINT_VIOLATION",
652
+ "First fetch object must include objectId",
653
+ r.offset
654
+ );
655
+ }
656
+ if (objectId > MAX_U64) {
657
+ throw new DecodeError("CONSTRAINT_VIOLATION", "computed Object ID exceeds 2^64 - 1", r.offset);
658
+ }
659
+ if (priorityPresent) {
660
+ st.prevPriority = r.readUint8();
661
+ }
662
+ let objectProperties;
663
+ if (propsPresent) {
664
+ const propsLen = Number(r.readVarInt());
665
+ if (propsLen > 0) {
666
+ objectProperties = decodeObjectProperties(r, propsLen);
667
+ }
668
+ }
669
+ payloadLength = Number(r.readVarInt());
670
+ payloadByteOffset = base + r.offset;
671
+ payload = payloadLength > 0 ? r.readBytesView(payloadLength) : new Uint8Array(0);
672
+ const obj = {
673
+ type: "object",
674
+ byteOffset,
675
+ payloadByteOffset,
676
+ serializationFlags: flags,
677
+ groupId,
678
+ subgroupId,
679
+ objectId,
680
+ publisherPriority: st.prevPriority,
681
+ payloadLength,
682
+ payload,
683
+ extensionData
684
+ };
685
+ if (groupDelta !== void 0)
686
+ obj.groupIdDelta = groupDelta;
687
+ if (objectDelta !== void 0)
688
+ obj.objectIdDelta = objectDelta;
689
+ if (objectProperties)
690
+ obj.objectProperties = objectProperties;
691
+ st.prevGroupId = groupId;
692
+ st.prevSubgroupId = subgroupId;
693
+ st.prevObjectId = objectId;
694
+ st.first = false;
695
+ return obj;
696
+ }
493
697
  function decodeFetchStream(bytes) {
494
698
  try {
495
699
  const r = new MoqtBufferReader(bytes);
@@ -506,224 +710,9 @@ function decodeFetchStream(bytes) {
506
710
  }
507
711
  const requestId = r.readVarInt();
508
712
  const objects = [];
509
- let prevGroupId = 0n;
510
- let prevSubgroupId = 0n;
511
- let prevObjectId = 0n;
512
- let prevPriority = 128;
513
- let first = true;
713
+ const st = newFetchObjectState();
514
714
  while (r.remaining > 0) {
515
- const byteOffset = r.offset;
516
- const flags = Number(r.readVarInt());
517
- let groupId = prevGroupId;
518
- let subgroupId = prevSubgroupId;
519
- let objectId = prevObjectId + 1n;
520
- let payloadLength;
521
- let payload;
522
- let payloadByteOffset;
523
- const extensionData = new Uint8Array(0);
524
- if (flags >= 128) {
525
- if (!FETCH_END_OF_RANGE_MARKERS.has(flags)) {
526
- return {
527
- ok: false,
528
- error: new DecodeError(
529
- "CONSTRAINT_VIOLATION",
530
- `0x${flags.toString(16)} is neither a flag combination below 128 nor one of the three End of Range markers`,
531
- r.offset
532
- )
533
- };
534
- }
535
- const groupDelta2 = r.readVarInt();
536
- groupId = resolveGroupId(first, groupDelta2, prevGroupId, r.offset);
537
- const objectDelta2 = r.readVarInt();
538
- objectId = objectDelta2;
539
- payloadLength = Number(r.readVarInt());
540
- payloadByteOffset = r.offset;
541
- payload = payloadLength > 0 ? r.readBytesView(payloadLength) : new Uint8Array(0);
542
- const marker = {
543
- type: "object",
544
- byteOffset,
545
- payloadByteOffset,
546
- serializationFlags: flags,
547
- groupId,
548
- groupIdDelta: groupDelta2,
549
- // A marker has no Subgroup ID or Priority of its own — Section
550
- // 11.4.4.2 says neither field is present. The interface requires
551
- // both, so they carry the last actual Object's values, which is also
552
- // what a following Object that references "the prior Object" gets.
553
- subgroupId: prevSubgroupId,
554
- objectId,
555
- objectIdDelta: objectDelta2,
556
- publisherPriority: prevPriority,
557
- payloadLength,
558
- payload,
559
- extensionData
560
- };
561
- objects.push(marker);
562
- prevGroupId = groupId;
563
- prevObjectId = objectId;
564
- first = false;
565
- continue;
566
- }
567
- if (flags & 64) {
568
- const objectIdPresent2 = (flags & 4) !== 0;
569
- const groupIdPresent2 = (flags & 8) !== 0;
570
- const priorityPresent2 = (flags & 16) !== 0;
571
- const propsPresent2 = (flags & 32) !== 0;
572
- let groupDelta2;
573
- if (groupIdPresent2) {
574
- groupDelta2 = r.readVarInt();
575
- groupId = resolveGroupId(first, groupDelta2, prevGroupId, r.offset);
576
- }
577
- let objectDelta2;
578
- if (objectIdPresent2) {
579
- objectDelta2 = r.readVarInt();
580
- objectId = resolveObjectId(groupIdPresent2, objectDelta2, prevObjectId);
581
- }
582
- if (objectId > MAX_U64) {
583
- return {
584
- ok: false,
585
- error: new DecodeError(
586
- "CONSTRAINT_VIOLATION",
587
- "computed Object ID exceeds 2^64 - 1",
588
- r.offset
589
- )
590
- };
591
- }
592
- if (priorityPresent2) {
593
- prevPriority = r.readUint8();
594
- }
595
- let objectProperties2;
596
- if (propsPresent2) {
597
- const propsLen = Number(r.readVarInt());
598
- if (propsLen > 0) {
599
- objectProperties2 = decodeObjectProperties(r, propsLen);
600
- }
601
- }
602
- payloadLength = Number(r.readVarInt());
603
- payloadByteOffset = r.offset;
604
- payload = payloadLength > 0 ? r.readBytesView(payloadLength) : new Uint8Array(0);
605
- const obj2 = {
606
- type: "object",
607
- byteOffset,
608
- payloadByteOffset,
609
- serializationFlags: flags,
610
- groupId,
611
- subgroupId: 0n,
612
- objectId,
613
- publisherPriority: prevPriority,
614
- payloadLength,
615
- payload,
616
- extensionData
617
- };
618
- if (groupDelta2 !== void 0)
619
- obj2.groupIdDelta = groupDelta2;
620
- if (objectDelta2 !== void 0)
621
- obj2.objectIdDelta = objectDelta2;
622
- if (objectProperties2)
623
- obj2.objectProperties = objectProperties2;
624
- objects.push(obj2);
625
- prevGroupId = groupId;
626
- prevObjectId = objectId;
627
- first = false;
628
- continue;
629
- }
630
- const subgroupEncoding = flags & 3;
631
- const objectIdPresent = (flags & 4) !== 0;
632
- const groupIdPresent = (flags & 8) !== 0;
633
- const priorityPresent = (flags & 16) !== 0;
634
- const propsPresent = (flags & 32) !== 0;
635
- let groupDelta;
636
- if (groupIdPresent) {
637
- groupDelta = r.readVarInt();
638
- groupId = resolveGroupId(first, groupDelta, prevGroupId, r.offset);
639
- } else if (first) {
640
- return {
641
- ok: false,
642
- error: new DecodeError(
643
- "CONSTRAINT_VIOLATION",
644
- "First fetch object must include groupId",
645
- r.offset
646
- )
647
- };
648
- }
649
- if (subgroupEncoding === 0) {
650
- subgroupId = 0n;
651
- } else if (subgroupEncoding === 1 || subgroupEncoding === 2) {
652
- if (first) {
653
- return {
654
- ok: false,
655
- error: new DecodeError(
656
- "CONSTRAINT_VIOLATION",
657
- "First fetch object cannot reference prior subgroupId",
658
- r.offset
659
- )
660
- };
661
- }
662
- subgroupId = subgroupEncoding === 1 ? prevSubgroupId : prevSubgroupId + 1n;
663
- } else {
664
- subgroupId = r.readVarInt();
665
- }
666
- let objectDelta;
667
- if (objectIdPresent) {
668
- objectDelta = r.readVarInt();
669
- objectId = resolveObjectId(groupIdPresent, objectDelta, prevObjectId);
670
- } else if (first) {
671
- return {
672
- ok: false,
673
- error: new DecodeError(
674
- "CONSTRAINT_VIOLATION",
675
- "First fetch object must include objectId",
676
- r.offset
677
- )
678
- };
679
- }
680
- if (objectId > MAX_U64) {
681
- return {
682
- ok: false,
683
- error: new DecodeError(
684
- "CONSTRAINT_VIOLATION",
685
- "computed Object ID exceeds 2^64 - 1",
686
- r.offset
687
- )
688
- };
689
- }
690
- if (priorityPresent) {
691
- prevPriority = r.readUint8();
692
- }
693
- let objectProperties;
694
- if (propsPresent) {
695
- const propsLen = Number(r.readVarInt());
696
- if (propsLen > 0) {
697
- objectProperties = decodeObjectProperties(r, propsLen);
698
- }
699
- }
700
- payloadLength = Number(r.readVarInt());
701
- payloadByteOffset = r.offset;
702
- payload = payloadLength > 0 ? r.readBytesView(payloadLength) : new Uint8Array(0);
703
- const obj = {
704
- type: "object",
705
- byteOffset,
706
- payloadByteOffset,
707
- serializationFlags: flags,
708
- groupId,
709
- subgroupId,
710
- objectId,
711
- publisherPriority: prevPriority,
712
- payloadLength,
713
- payload,
714
- extensionData
715
- };
716
- if (groupDelta !== void 0)
717
- obj.groupIdDelta = groupDelta;
718
- if (objectDelta !== void 0)
719
- obj.objectIdDelta = objectDelta;
720
- if (objectProperties)
721
- obj.objectProperties = objectProperties;
722
- objects.push(obj);
723
- prevGroupId = groupId;
724
- prevSubgroupId = subgroupId;
725
- prevObjectId = objectId;
726
- first = false;
715
+ objects.push(readFetchObject(r, 0, st));
727
716
  }
728
717
  return {
729
718
  ok: true,
@@ -749,56 +738,70 @@ function decodeDataStream(streamType, bytes) {
749
738
  }
750
739
  }
751
740
  }
741
+ var StreamBuffer = class {
742
+ buf = new Uint8Array(0);
743
+ /** Bytes written into `buf`. */
744
+ len = 0;
745
+ /** Consumed prefix of `buf`; `base + offset` is the position in the stream. */
746
+ offset = 0;
747
+ /** Absolute position of `buf[0]` within the stream. */
748
+ base = 0;
749
+ get unread() {
750
+ return this.len - this.offset;
751
+ }
752
+ append(chunk) {
753
+ if (this.len + chunk.length > this.buf.length) {
754
+ const live = this.len - this.offset;
755
+ const needed = live + chunk.length;
756
+ let cap = Math.max(4096, this.buf.length);
757
+ while (cap < needed * 2) cap *= 2;
758
+ const next = new Uint8Array(cap);
759
+ next.set(this.buf.subarray(this.offset, this.len), 0);
760
+ this.buf = next;
761
+ this.base += this.offset;
762
+ this.len = live;
763
+ this.offset = 0;
764
+ }
765
+ this.buf.set(chunk, this.len);
766
+ this.len += chunk.length;
767
+ }
768
+ /**
769
+ * The written bytes, for a reader positioned at `offset`. Bounded by `len`
770
+ * rather than by capacity, so `BufferReader.remaining` counts real bytes and
771
+ * not the spare room after them.
772
+ */
773
+ written() {
774
+ return this.buf.subarray(0, this.len);
775
+ }
776
+ };
752
777
  function createSubgroupStreamDecoder() {
753
- let buffer = new Uint8Array(0);
754
- let offset = 0;
778
+ const b = new StreamBuffer();
779
+ let header = null;
755
780
  let headerEmitted = false;
756
781
  let prevObjectId = -1n;
757
- let firstObject = true;
758
- let _propertiesPresent = false;
782
+ let isFirst = true;
783
+ function emitHeader(controller, h, subgroupId) {
784
+ controller.enqueue({
785
+ type: "subgroup_header",
786
+ headerType: h.streamType,
787
+ trackAlias: h.trackAlias,
788
+ groupId: h.groupId,
789
+ subgroupId,
790
+ publisherPriority: h.publisherPriority,
791
+ ...h.endOfGroup ? { endOfGroup: true } : {},
792
+ ...h.firstObjectFlag ? { firstObject: true } : {}
793
+ });
794
+ headerEmitted = true;
795
+ }
759
796
  return new TransformStream({
760
797
  transform(chunk, controller) {
761
- if (offset > 0) {
762
- buffer = buffer.subarray(offset);
763
- offset = 0;
764
- }
765
- const newBuffer = new Uint8Array(buffer.length + chunk.length);
766
- newBuffer.set(buffer, 0);
767
- newBuffer.set(chunk, buffer.length);
768
- buffer = newBuffer;
769
- if (!headerEmitted) {
798
+ b.append(chunk);
799
+ const view = b.written();
800
+ if (header === null) {
770
801
  try {
771
- const r = new MoqtBufferReader(buffer.subarray(offset));
772
- const typeFlags = r.readVarInt();
773
- const flagsError = subgroupTypeFlagsError(typeFlags);
774
- if (flagsError !== null) {
775
- controller.error(new DecodeError("CONSTRAINT_VIOLATION", flagsError, 0));
776
- return;
777
- }
778
- const streamType = Number(typeFlags);
779
- _propertiesPresent = (streamType & 1) !== 0;
780
- const subgroupMode = (streamType & 6) >> 1;
781
- const hasSubgroupField = subgroupMode === 2;
782
- const hasPriority = (streamType & 32) === 0;
783
- const trackAlias = r.readVarInt();
784
- const groupId = r.readVarInt();
785
- let subgroupId = 0n;
786
- if (hasSubgroupField) {
787
- subgroupId = r.readVarInt();
788
- }
789
- let publisherPriority = 128;
790
- if (hasPriority) {
791
- publisherPriority = r.readUint8();
792
- }
793
- controller.enqueue({
794
- type: "subgroup_header",
795
- trackAlias,
796
- groupId,
797
- subgroupId,
798
- publisherPriority
799
- });
800
- headerEmitted = true;
801
- offset += r.offset;
802
+ const hr = new MoqtBufferReader(view, b.offset);
803
+ header = readSubgroupHeader(hr);
804
+ b.offset = hr.offset;
802
805
  } catch (e) {
803
806
  if (e instanceof DecodeError && e.code === "UNEXPECTED_END") {
804
807
  return;
@@ -806,72 +809,51 @@ function createSubgroupStreamDecoder() {
806
809
  controller.error(e);
807
810
  return;
808
811
  }
812
+ if (!header.subgroupIsFirstObjId) emitHeader(controller, header, header.subgroupId);
809
813
  }
810
- while (offset < buffer.length) {
814
+ const h = header;
815
+ if (h === null) return;
816
+ const r = new MoqtBufferReader(view, b.offset);
817
+ while (r.remaining > 0) {
818
+ const start = r.offset;
819
+ let obj;
811
820
  try {
812
- const r = new MoqtBufferReader(buffer.subarray(offset));
813
- const delta = r.readVarInt();
814
- let objectId;
815
- if (firstObject) {
816
- objectId = delta;
817
- firstObject = false;
818
- } else {
819
- objectId = prevObjectId + 1n + delta;
820
- }
821
- let extensionData = new Uint8Array(0);
822
- if (_propertiesPresent) {
823
- const extLen = Number(r.readVarInt());
824
- extensionData = extLen > 0 ? r.readBytesView(extLen) : new Uint8Array(0);
825
- }
826
- const payloadLength = Number(r.readVarInt());
827
- const payloadByteOffset = r.offset;
828
- const payload = payloadLength > 0 ? r.readBytesView(payloadLength) : new Uint8Array(0);
829
- controller.enqueue({
830
- type: "object",
831
- objectId,
832
- objectIdDelta: delta,
833
- payloadLength,
834
- payload,
835
- extensionData,
836
- byteOffset: 0,
837
- payloadByteOffset
838
- });
839
- offset += r.offset;
840
- prevObjectId = objectId;
821
+ obj = readSubgroupObject(r, h.propertiesPresent, isFirst, prevObjectId, b.base);
841
822
  } catch (e) {
842
823
  if (e instanceof DecodeError && e.code === "UNEXPECTED_END") {
843
- break;
824
+ b.offset = start;
825
+ return;
844
826
  }
845
827
  controller.error(e);
846
828
  return;
847
829
  }
830
+ if (!headerEmitted) emitHeader(controller, h, obj.objectId);
831
+ isFirst = false;
832
+ b.offset = r.offset;
833
+ prevObjectId = obj.objectId;
834
+ controller.enqueue(obj);
848
835
  }
849
836
  },
850
837
  flush(controller) {
851
- if (offset < buffer.length) {
838
+ if (header !== null && !headerEmitted) emitHeader(controller, header, 0n);
839
+ if (b.unread > 0) {
852
840
  controller.error(new DecodeError("UNEXPECTED_END", "Stream ended with incomplete data", 0));
853
841
  }
854
842
  }
855
843
  });
856
844
  }
857
845
  function createFetchStreamDecoder() {
858
- let buffer = new Uint8Array(0);
859
- let offset = 0;
846
+ const b = new StreamBuffer();
860
847
  let headerEmitted = false;
848
+ const st = newFetchObjectState();
861
849
  return new TransformStream({
862
850
  transform(chunk, controller) {
863
- if (offset > 0) {
864
- buffer = buffer.subarray(offset);
865
- offset = 0;
866
- }
867
- const newBuffer = new Uint8Array(buffer.length + chunk.length);
868
- newBuffer.set(buffer, 0);
869
- newBuffer.set(chunk, buffer.length);
870
- buffer = newBuffer;
851
+ b.append(chunk);
852
+ const view = b.written();
871
853
  if (!headerEmitted) {
872
854
  try {
873
- const r = new MoqtBufferReader(buffer.subarray(offset));
874
- const streamType = r.readVarInt();
855
+ const r2 = new MoqtBufferReader(view, b.offset);
856
+ const streamType = r2.readVarInt();
875
857
  if (streamType !== FETCH_STREAM_TYPE) {
876
858
  controller.error(
877
859
  new DecodeError(
@@ -882,10 +864,10 @@ function createFetchStreamDecoder() {
882
864
  );
883
865
  return;
884
866
  }
885
- const requestId = r.readVarInt();
867
+ const requestId = r2.readVarInt();
886
868
  controller.enqueue({ type: "fetch_header", requestId });
887
869
  headerEmitted = true;
888
- offset += r.offset;
870
+ b.offset = r2.offset;
889
871
  } catch (e) {
890
872
  if (e instanceof DecodeError && e.code === "UNEXPECTED_END") {
891
873
  return;
@@ -894,135 +876,82 @@ function createFetchStreamDecoder() {
894
876
  return;
895
877
  }
896
878
  }
897
- while (offset < buffer.length) {
879
+ const r = new MoqtBufferReader(view, b.offset);
880
+ while (r.remaining > 0) {
881
+ const start = r.offset;
882
+ let obj;
898
883
  try {
899
- const r = new MoqtBufferReader(buffer.subarray(offset));
900
- const flags = Number(r.readVarInt());
901
- if (flags >= 128) {
902
- if (!FETCH_END_OF_RANGE_MARKERS.has(flags)) {
903
- controller.error(
904
- new DecodeError(
905
- "CONSTRAINT_VIOLATION",
906
- `0x${flags.toString(16)} is neither a flag combination below 128 nor one of the three End of Range markers`,
907
- 0
908
- )
909
- );
910
- return;
911
- }
912
- r.readVarInt();
913
- const objectDelta = r.readVarInt();
914
- const markerPayloadLength = Number(r.readVarInt());
915
- const markerPayloadByteOffset = r.offset;
916
- controller.enqueue({
917
- type: "object",
918
- objectId: objectDelta,
919
- objectIdDelta: objectDelta,
920
- payloadLength: markerPayloadLength,
921
- payload: new Uint8Array(0),
922
- extensionData: new Uint8Array(0),
923
- byteOffset: 0,
924
- payloadByteOffset: markerPayloadByteOffset
925
- });
926
- offset += r.offset;
927
- continue;
928
- }
929
- const objectIdPresent = (flags & 4) !== 0;
930
- const groupIdPresent = (flags & 8) !== 0;
931
- const priorityPresent = (flags & 16) !== 0;
932
- const extensionsPresent = (flags & 32) !== 0;
933
- const subgroupEncoding = flags & 3;
934
- const datagramMode = (flags & 64) !== 0;
935
- if (groupIdPresent) r.readVarInt();
936
- if (!datagramMode && subgroupEncoding === 3) r.readVarInt();
937
- let objectId = 0n;
938
- let objectIdDelta;
939
- if (objectIdPresent) {
940
- objectIdDelta = r.readVarInt();
941
- objectId = objectIdDelta;
942
- }
943
- if (priorityPresent) r.readUint8();
944
- let extensionData = new Uint8Array(0);
945
- if (extensionsPresent) {
946
- const extLen = Number(r.readVarInt());
947
- extensionData = extLen > 0 ? r.readBytesView(extLen) : new Uint8Array(0);
948
- }
949
- const payloadLength = Number(r.readVarInt());
950
- const payloadByteOffset = r.offset;
951
- const payload = payloadLength > 0 ? r.readBytesView(payloadLength) : new Uint8Array(0);
952
- const event = {
953
- type: "object",
954
- objectId,
955
- payloadLength,
956
- payload,
957
- extensionData,
958
- byteOffset: 0,
959
- payloadByteOffset
960
- };
961
- if (objectIdDelta !== void 0)
962
- event.objectIdDelta = objectIdDelta;
963
- controller.enqueue(event);
964
- offset += r.offset;
884
+ obj = readFetchObject(r, b.base, st);
965
885
  } catch (e) {
966
886
  if (e instanceof DecodeError && e.code === "UNEXPECTED_END") {
967
- break;
887
+ b.offset = start;
888
+ return;
968
889
  }
969
890
  controller.error(e);
970
891
  return;
971
892
  }
893
+ b.offset = r.offset;
894
+ controller.enqueue(obj);
972
895
  }
973
896
  },
974
897
  flush(controller) {
975
- if (offset < buffer.length) {
898
+ if (b.unread > 0) {
976
899
  controller.error(new DecodeError("UNEXPECTED_END", "Stream ended with incomplete data", 0));
977
900
  }
978
901
  }
979
902
  });
980
903
  }
981
904
  function createDataStreamDecoder() {
982
- let buffer = new Uint8Array(0);
983
- let offset = 0;
984
- let inner = null;
985
- return new TransformStream({
986
- transform(chunk, controller) {
987
- if (offset > 0) {
988
- buffer = buffer.subarray(offset);
989
- offset = 0;
990
- }
991
- const newBuffer = new Uint8Array(buffer.length + chunk.length);
992
- newBuffer.set(buffer, 0);
993
- newBuffer.set(chunk, buffer.length);
994
- buffer = newBuffer;
995
- if (inner === null) {
996
- if (offset >= buffer.length) return;
997
- const firstByte = buffer[offset];
998
- if (isValidSubgroupType(firstByte)) {
999
- const decoder = createSubgroupStreamDecoder();
1000
- inner = decoder;
1001
- } else if (firstByte === 5) {
1002
- const decoder = createFetchStreamDecoder();
1003
- inner = decoder;
1004
- } else {
1005
- controller.error(
1006
- new DecodeError(
1007
- "CONSTRAINT_VIOLATION",
1008
- `Unknown data stream type: 0x${firstByte.toString(16)}`,
1009
- 0
1010
- )
1011
- );
1012
- return;
905
+ let writer = null;
906
+ let pump = Promise.resolve();
907
+ let broken = false;
908
+ function attach(inner, controller) {
909
+ writer = inner.writable.getWriter();
910
+ const reader = inner.readable.getReader();
911
+ pump = (async () => {
912
+ try {
913
+ for (; ; ) {
914
+ const { done, value } = await reader.read();
915
+ if (done) break;
916
+ controller.enqueue(value);
917
+ }
918
+ } catch (e) {
919
+ if (!broken) {
920
+ broken = true;
921
+ controller.error(e);
1013
922
  }
1014
923
  }
1015
- },
1016
- flush(controller) {
1017
- if (offset >= buffer.length) return;
1018
- const view = buffer.subarray(offset);
1019
- const firstByte = view[0];
1020
- let result;
924
+ })();
925
+ }
926
+ async function feed(bytes) {
927
+ if (writer === null || broken || bytes.length === 0) return;
928
+ try {
929
+ await writer.write(bytes);
930
+ } catch {
931
+ broken = true;
932
+ }
933
+ }
934
+ return new TransformStream({
935
+ async transform(chunk, controller) {
936
+ if (broken) return;
937
+ if (writer !== null) {
938
+ await feed(chunk);
939
+ return;
940
+ }
941
+ if (chunk.length === 0) return;
942
+ const firstByte = chunk[0];
1021
943
  if (isValidSubgroupType(firstByte)) {
1022
- result = decodeSubgroupStream(view);
944
+ attach(
945
+ createSubgroupStreamDecoder(),
946
+ controller
947
+ );
1023
948
  } else if (firstByte === 5) {
1024
- result = decodeFetchStream(view);
949
+ attach(
950
+ createFetchStreamDecoder(),
951
+ controller
952
+ );
1025
953
  } else {
954
+ broken = true;
1026
955
  controller.error(
1027
956
  new DecodeError(
1028
957
  "CONSTRAINT_VIOLATION",
@@ -1032,31 +961,15 @@ function createDataStreamDecoder() {
1032
961
  );
1033
962
  return;
1034
963
  }
1035
- if (!result.ok) {
1036
- controller.error(result.error);
1037
- return;
1038
- }
1039
- const stream = result.value;
1040
- if (stream.type === "subgroup") {
1041
- controller.enqueue({
1042
- type: "subgroup_header",
1043
- trackAlias: stream.trackAlias,
1044
- groupId: stream.groupId,
1045
- subgroupId: stream.subgroupId,
1046
- publisherPriority: stream.publisherPriority
1047
- });
1048
- for (const obj of stream.objects) {
1049
- controller.enqueue(obj);
1050
- }
1051
- } else if (stream.type === "fetch") {
1052
- controller.enqueue({
1053
- type: "fetch_header",
1054
- requestId: stream.requestId
1055
- });
1056
- for (const obj of stream.objects) {
1057
- controller.enqueue(obj);
1058
- }
964
+ await feed(chunk);
965
+ },
966
+ async flush() {
967
+ if (writer === null) return;
968
+ try {
969
+ await writer.close();
970
+ } catch {
1059
971
  }
972
+ await pump;
1060
973
  }
1061
974
  });
1062
975
  }
@@ -1188,10 +1101,9 @@ function decodeSetupOptions(reader, payloadEnd) {
1188
1101
  if (optType === SETUP_OPT_PATH) {
1189
1102
  result.path = textDecoder.decode(bytes);
1190
1103
  } else if (optType === SETUP_OPT_AUTHORIZATION_TOKEN) {
1191
- result.authorization_token = [
1192
- ...result.authorization_token ?? [],
1193
- decodeAuthorizationToken(new MoqtBufferReader(bytes))
1194
- ];
1104
+ const token = decodeAuthorizationToken(new MoqtBufferReader(bytes));
1105
+ noteAuthTokenValue(reader.offset - length, length, token);
1106
+ result.authorization_token = [...result.authorization_token ?? [], token];
1195
1107
  } else if (optType === SETUP_OPT_AUTHORITY) {
1196
1108
  result.authority = textDecoder.decode(bytes);
1197
1109
  } else if (optType === SETUP_OPT_MOQT_IMPLEMENTATION) {
@@ -1220,6 +1132,11 @@ function encodeAuthorizationToken(token, w) {
1220
1132
  w.writeBytes(tv);
1221
1133
  }
1222
1134
  }
1135
+ function noteAuthTokenValue(valueStart, valueLength, token) {
1136
+ const value = token.token_value;
1137
+ if (value === void 0 || value.byteLength === 0) return;
1138
+ recordAuthValueSpan(valueStart + valueLength - value.byteLength, value.byteLength);
1139
+ }
1223
1140
  function decodeAuthorizationToken(r) {
1224
1141
  const alias_type = r.readVarInt();
1225
1142
  const aliasType = Number(alias_type);
@@ -1402,24 +1319,24 @@ var PARAMETER_SCOPE = /* @__PURE__ */ new Map([
1402
1319
  [PARAM_SUBGROUP_DELIVERY_TIMEOUT, /* @__PURE__ */ new Set(["subscribe", "publish", "request_update"])],
1403
1320
  // 0x08 EXPIRES (10.2.16) — the one parameter that still names PUBLISH_OK.
1404
1321
  [PARAM_EXPIRES, /* @__PURE__ */ new Set(["subscribe_ok", "publish", "request_ok"])],
1405
- // 0x09 LARGEST_OBJECT (10.2.17) — gained PUBLISH_STATE_NOTIFY in draft-20.
1322
+ // 0x09 LARGEST_OBJECT (10.2.17) — PUBLISH_STATE_NOTIFY here; draft-19 (10.2.16) omits it.
1406
1323
  [
1407
1324
  PARAM_LARGEST_OBJECT,
1408
1325
  /* @__PURE__ */ new Set(["subscribe_ok", "publish", "request_ok", "publish_state_notify"])
1409
1326
  ],
1410
1327
  // 0x0A FILL_TIMEOUT (10.2.5) — FETCH, or nested inside FILL_PARAMETERS.
1411
1328
  [PARAM_FILL_TIMEOUT, /* @__PURE__ */ new Set(["fetch", FILL_SCOPE])],
1412
- // 0x10 FORWARD (10.2.18) — lost PUBLISH_OK, gained PUBLISH_STATE_NOTIFY.
1329
+ // 0x10 FORWARD (10.2.18) — PUBLISH_STATE_NOTIFY here where draft-19 (10.2.17) lists PUBLISH_OK.
1413
1330
  [
1414
1331
  PARAM_FORWARD,
1415
1332
  /* @__PURE__ */ new Set(["subscribe", "request_update", "publish", "subscribe_tracks", "publish_state_notify"])
1416
1333
  ],
1417
- // 0x20 SUBSCRIBER_PRIORITY (10.2.7) — lost PUBLISH_OK, gained PUBLISH.
1334
+ // 0x20 SUBSCRIBER_PRIORITY (10.2.7) — PUBLISH here where draft-19 lists PUBLISH_OK.
1418
1335
  [
1419
1336
  PARAM_SUBSCRIBER_PRIORITY,
1420
1337
  /* @__PURE__ */ new Set(["subscribe", "publish", "fetch", "request_update", FILL_SCOPE])
1421
1338
  ],
1422
- // 0x21 LOCATION_FILTER (10.2.9) — lost PUBLISH_OK, gained PUBLISH and PUBLISH_STATE_NOTIFY.
1339
+ // 0x21 LOCATION_FILTER (10.2.9) — PUBLISH and PUBLISH_STATE_NOTIFY here where draft-19 lists PUBLISH_OK.
1423
1340
  [
1424
1341
  PARAM_LOCATION_FILTER,
1425
1342
  /* @__PURE__ */ new Set([
@@ -1431,12 +1348,12 @@ var PARAMETER_SCOPE = /* @__PURE__ */ new Map([
1431
1348
  FILL_SCOPE
1432
1349
  ])
1433
1350
  ],
1434
- // 0x22 GROUP_ORDER (10.2.8) — gained PUBLISH and FILL_PARAMETERS nesting.
1351
+ // 0x22 GROUP_ORDER (10.2.8) — PUBLISH and FILL_PARAMETERS nesting here; draft-19 has neither.
1435
1352
  [PARAM_GROUP_ORDER, /* @__PURE__ */ new Set(["subscribe", "publish", "subscribe_tracks", "fetch", FILL_SCOPE])],
1436
1353
  // 0x23 FILL_PARAMETERS (10.2.15) — NEW. Subscriptions only, and never nested
1437
1354
  // in itself: a FETCH already is a fetch, so it has nothing to fill.
1438
1355
  [PARAM_FILL_PARAMETERS, /* @__PURE__ */ new Set(["subscribe", "request_update"])],
1439
- // 0x25-0x28 range filters (5.1.4) — lost PUBLISH_OK, gained FILL_PARAMETERS nesting.
1356
+ // 0x25-0x28 range filters (5.1.4) — permitted inside FILL_PARAMETERS (Table 6).
1440
1357
  [
1441
1358
  PARAM_SUBGROUP_FILTER,
1442
1359
  /* @__PURE__ */ new Set(["fetch", "subscribe", "subscribe_tracks", "request_update", FILL_SCOPE])
@@ -1453,11 +1370,11 @@ var PARAMETER_SCOPE = /* @__PURE__ */ new Map([
1453
1370
  PARAM_OBJECT_PROPERTY_FILTER,
1454
1371
  /* @__PURE__ */ new Set(["fetch", "subscribe", "subscribe_tracks", "request_update", FILL_SCOPE])
1455
1372
  ],
1456
- // 0x29 TRACK_PROPERTY_FILTER (10.2.14) — lost PUBLISH_OK; NOT permitted
1457
- // inside FILL_PARAMETERS. A relay forwarding a downstream FILL_PARAMETERS
1458
- // upstream has to strip it rather than trip this rule.
1373
+ // 0x29 TRACK_PROPERTY_FILTER (10.2.14) — NOT permitted inside
1374
+ // FILL_PARAMETERS: Table 6 omits it. A relay forwarding a downstream
1375
+ // FILL_PARAMETERS upstream has to strip it rather than trip this rule.
1459
1376
  [PARAM_TRACK_PROPERTY_FILTER, /* @__PURE__ */ new Set(["subscribe_tracks", "request_update"])],
1460
- // 0x32 NEW_GROUP_REQUEST (10.2.19) — lost PUBLISH_OK.
1377
+ // 0x32 NEW_GROUP_REQUEST (10.2.19) — draft-19 (10.2.18) also lists PUBLISH_OK.
1461
1378
  [PARAM_NEW_GROUP_REQUEST, /* @__PURE__ */ new Set(["subscribe", "request_update"])],
1462
1379
  // 0x34 TRACK_NAMESPACE_PREFIX (10.2.20) — REQUEST_UPDATE for a namespace subscription.
1463
1380
  [PARAM_TRACK_NAMESPACE_PREFIX, /* @__PURE__ */ new Set(["request_update"])],
@@ -1653,10 +1570,9 @@ function decodeParams(reader, messageType) {
1653
1570
  } else if (paramType === PARAM_AUTHORIZATION_TOKEN) {
1654
1571
  const length = Number(reader.readVarInt());
1655
1572
  const bytes = reader.readBytes(length);
1656
- result.authorization_token = [
1657
- ...result.authorization_token ?? [],
1658
- decodeAuthorizationToken(new MoqtBufferReader(bytes))
1659
- ];
1573
+ const token = decodeAuthorizationToken(new MoqtBufferReader(bytes));
1574
+ noteAuthTokenValue(reader.offset - length, length, token);
1575
+ result.authorization_token = [...result.authorization_token ?? [], token];
1660
1576
  } else if (paramType === PARAM_RENDEZVOUS_TIMEOUT) {
1661
1577
  result.rendezvous_timeout = reader.readVarInt();
1662
1578
  } else if (paramType === PARAM_SUBGROUP_DELIVERY_TIMEOUT) {
@@ -1723,7 +1639,7 @@ function decodeFillParameters(reader) {
1723
1639
  const length = Number(reader.readVarInt());
1724
1640
  const valueBytes = reader.readBytes(length);
1725
1641
  const nested = new MoqtBufferReader(valueBytes);
1726
- const params = decodeParams(nested, FILL_SCOPE);
1642
+ const params = withoutAuthValueSpans(() => decodeParams(nested, FILL_SCOPE));
1727
1643
  if (nested.remaining > 0) {
1728
1644
  throw new DecodeError(
1729
1645
  "CONSTRAINT_VIOLATION",
@@ -2325,6 +2241,19 @@ function createDraft20Codec() {
2325
2241
  createDataStreamDecoder
2326
2242
  };
2327
2243
  }
2244
+ function redactAuthTokens(bytes) {
2245
+ let payloadStart;
2246
+ try {
2247
+ const probe = new MoqtBufferReader(bytes);
2248
+ probe.readVarInt();
2249
+ probe.readUint8();
2250
+ probe.readUint8();
2251
+ payloadStart = probe.offset;
2252
+ } catch {
2253
+ return { bytes, redacted: 0, incomplete: false, decoded: false };
2254
+ }
2255
+ return redactWith(bytes, payloadStart, () => decodeMessage(bytes).ok);
2256
+ }
2328
2257
 
2329
2258
  export {
2330
2259
  MSG_REQUEST_UPDATE,
@@ -2370,5 +2299,6 @@ export {
2370
2299
  encodeMessage,
2371
2300
  decodeMessage,
2372
2301
  createStreamDecoder,
2373
- createDraft20Codec
2302
+ createDraft20Codec,
2303
+ redactAuthTokens
2374
2304
  };