@moqtap/codec 0.9.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 (232) hide show
  1. package/CHANGELOG.md +173 -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-PU2KV7VP.cjs → chunk-27K5BUAG.cjs} +485 -515
  5. package/dist/{chunk-BV6MITLO.js → chunk-3RNQMGKA.js} +365 -390
  6. package/dist/{chunk-2XH6PHXR.js → chunk-5AWIXOLB.js} +442 -467
  7. package/dist/{chunk-4XLYCT5Q.cjs → chunk-5IMHJIAZ.cjs} +52 -2
  8. package/dist/{chunk-TVSFDQYE.cjs → chunk-5JGZCKJO.cjs} +513 -531
  9. package/dist/{chunk-IADVBKEJ.cjs → chunk-73K4OSAN.cjs} +407 -432
  10. package/dist/{chunk-N2V7Z37J.js → chunk-7VQKRGRD.js} +19 -3
  11. package/dist/{chunk-UZO5Z2XT.cjs → chunk-A3UCQOIB.cjs} +490 -515
  12. package/dist/{chunk-JKMYAUGY.js → chunk-A7PDMVXM.js} +35 -11
  13. package/dist/{chunk-VZHL2U2N.cjs → chunk-A7VQO6YC.cjs} +54 -38
  14. package/dist/{chunk-KCH4BQXK.cjs → chunk-ACQHZLRZ.cjs} +73 -47
  15. package/dist/{chunk-H6DTAIWM.js → chunk-BBICOMW6.js} +47 -19
  16. package/dist/{chunk-MAXEHYVB.cjs → chunk-BNIUVOCJ.cjs} +554 -612
  17. package/dist/{chunk-QGIHC6BA.cjs → chunk-CNC6ANS4.cjs} +70 -46
  18. package/dist/{chunk-NH4L6NIY.js → chunk-FDLQSWHK.js} +437 -467
  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-7ENEWAMZ.cjs → chunk-HM7BLRVP.cjs} +305 -305
  22. package/dist/{chunk-XHAP2YST.js → chunk-HZONHFNO.js} +19 -3
  23. package/dist/{chunk-EVCPBFSR.cjs → chunk-ILYABWDK.cjs} +83 -55
  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-UA5XFP4O.cjs → chunk-KTY4LAUV.cjs} +485 -494
  27. package/dist/{chunk-RZTLQAKF.js → chunk-OJNLJT5D.js} +0 -1
  28. package/dist/{chunk-YJGOD3Y4.js → chunk-PJK2ZS3I.js} +492 -550
  29. package/dist/{chunk-TMXRYOBS.js → chunk-PSMZKHOC.js} +444 -453
  30. package/dist/{chunk-7RE6KSIY.cjs → chunk-Q5JQGHWY.cjs} +0 -1
  31. package/dist/{chunk-23KRITJ6.js → chunk-SQTUQY5E.js} +37 -11
  32. package/dist/{chunk-XQGEOFGE.js → chunk-WCRLAKDW.js} +253 -253
  33. package/dist/{chunk-KYVTM5VI.js → chunk-WL2YUEXH.js} +19 -3
  34. package/dist/{chunk-Q7NSUXXB.js → chunk-YCNIVZS7.js} +464 -482
  35. package/dist/{chunk-KLPWJU6W.js → chunk-YRZQVNZO.js} +50 -0
  36. package/dist/{codec-Bym-K2q2.d.cts → codec-76xzrLTL.d.cts} +21 -2
  37. package/dist/{codec-BKsVu3Fr.d.ts → codec-8p40WdLg.d.ts} +21 -2
  38. package/dist/{codec-Dl_QIXMz.d.ts → codec-BN2Bu0KI.d.ts} +20 -1
  39. package/dist/{codec-D4RvFQmu.d.ts → codec-Bb6GKTrv.d.ts} +21 -2
  40. package/dist/{codec-DAyiF5sq.d.cts → codec-BgpfHoAd.d.cts} +21 -2
  41. package/dist/{codec-CA6nbbEk.d.ts → codec-BkheTXO7.d.ts} +21 -2
  42. package/dist/{codec-DchsPfr3.d.cts → codec-BwVDkokh.d.cts} +21 -2
  43. package/dist/{codec-CgZdadPt.d.cts → codec-C5s1eBJX.d.cts} +21 -2
  44. package/dist/codec-CM5yd6n3.d.ts +38 -0
  45. package/dist/{codec-DJmqoIsp.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-CSBFdPgP.d.cts → codec-DELe00w_.d.cts} +21 -2
  50. package/dist/{codec-C_xxsbKy.d.cts → codec-DHzKAUCa.d.cts} +21 -2
  51. package/dist/{codec--CVeqGQv.d.ts → codec-DdVBtvx7.d.ts} +20 -1
  52. package/dist/{codec-CviAa4lp.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-CtvFK4aV.d.cts → codec-GAY4lybi.d.cts} +21 -2
  55. package/dist/{codec-Cfo_z5ET.d.cts → codec-I8u2pfS4.d.cts} +20 -1
  56. package/dist/{codec-vddqy0KY.d.cts → codec-XLrnreeu.d.cts} +21 -2
  57. package/dist/{codec-O-1Js7h4.d.ts → codec-c0YEwwWn.d.ts} +21 -2
  58. package/dist/{codec-Cl73EfRW.d.ts → codec-ejDu-va6.d.ts} +21 -2
  59. package/dist/{codec-C006F75E.d.ts → codec-kaBUzdpV.d.ts} +21 -2
  60. package/dist/{codec-C5evFHL-.d.ts → codec-mVYqkIUF.d.ts} +21 -2
  61. package/dist/{codec-BMwgZIgG.d.ts → codec-qSbO5nOa.d.ts} +21 -2
  62. package/dist/{codec-BQa6Qsav.d.ts → codec-yYKGOipj.d.ts} +21 -2
  63. package/dist/{codec-DzLvG8Wb.d.cts → codec-zfzg9uiy.d.cts} +21 -2
  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-session.d.cts +1 -1
  81. package/dist/draft11-session.d.ts +1 -1
  82. package/dist/draft11.cjs +104 -3
  83. package/dist/draft11.d.cts +100 -4
  84. package/dist/draft11.d.ts +100 -4
  85. package/dist/draft11.js +105 -4
  86. package/dist/draft12-session.d.cts +1 -1
  87. package/dist/draft12-session.d.ts +1 -1
  88. package/dist/draft12.cjs +113 -3
  89. package/dist/draft12.d.cts +109 -4
  90. package/dist/draft12.d.ts +109 -4
  91. package/dist/draft12.js +114 -4
  92. package/dist/draft13-session.d.cts +1 -1
  93. package/dist/draft13-session.d.ts +1 -1
  94. package/dist/draft13.cjs +105 -3
  95. package/dist/draft13.d.cts +101 -4
  96. package/dist/draft13.d.ts +101 -4
  97. package/dist/draft13.js +106 -4
  98. package/dist/draft14-session.d.cts +1 -1
  99. package/dist/draft14-session.d.ts +1 -1
  100. package/dist/draft14.cjs +107 -3
  101. package/dist/draft14.d.cts +103 -30
  102. package/dist/draft14.d.ts +103 -30
  103. package/dist/draft14.js +108 -4
  104. package/dist/draft15-session.d.cts +1 -1
  105. package/dist/draft15-session.d.ts +1 -1
  106. package/dist/draft15.cjs +69 -3
  107. package/dist/draft15.d.cts +65 -22
  108. package/dist/draft15.d.ts +65 -22
  109. package/dist/draft15.js +70 -4
  110. package/dist/draft16-session.cjs +2 -2
  111. package/dist/draft16-session.d.cts +1 -1
  112. package/dist/draft16-session.d.ts +1 -1
  113. package/dist/draft16-session.js +1 -1
  114. package/dist/draft16.cjs +76 -8
  115. package/dist/draft16.d.cts +67 -13
  116. package/dist/draft16.d.ts +67 -13
  117. package/dist/draft16.js +73 -5
  118. package/dist/draft17-session.d.cts +1 -1
  119. package/dist/draft17-session.d.ts +1 -1
  120. package/dist/draft17.cjs +77 -3
  121. package/dist/draft17.d.cts +73 -4
  122. package/dist/draft17.d.ts +73 -4
  123. package/dist/draft17.js +78 -4
  124. package/dist/draft18-session.d.cts +1 -1
  125. package/dist/draft18-session.d.ts +1 -1
  126. package/dist/draft18.cjs +8 -3
  127. package/dist/draft18.d.cts +4 -3
  128. package/dist/draft18.d.ts +4 -3
  129. package/dist/draft18.js +9 -4
  130. package/dist/draft19-session.d.cts +1 -1
  131. package/dist/draft19-session.d.ts +1 -1
  132. package/dist/draft19.cjs +11 -4
  133. package/dist/draft19.d.cts +4 -3
  134. package/dist/draft19.d.ts +4 -3
  135. package/dist/draft19.js +12 -5
  136. package/dist/draft20-session.d.cts +1 -1
  137. package/dist/draft20-session.d.ts +1 -1
  138. package/dist/draft20.cjs +8 -3
  139. package/dist/draft20.d.cts +4 -3
  140. package/dist/draft20.d.ts +4 -3
  141. package/dist/draft20.js +9 -4
  142. package/dist/index.cjs +30 -30
  143. package/dist/index.d.cts +25 -24
  144. package/dist/index.d.ts +25 -24
  145. package/dist/index.js +15 -15
  146. package/dist/session.cjs +2 -2
  147. package/dist/session.d.cts +10 -10
  148. package/dist/session.d.ts +10 -10
  149. package/dist/session.js +1 -1
  150. package/dist/{types-zHgCS6o5.d.cts → types-Btp416jt.d.cts} +15 -7
  151. package/dist/{types-zHgCS6o5.d.ts → types-Btp416jt.d.ts} +15 -7
  152. package/dist/{types-Cm9fjeYC.d.cts → types-BxTL1NXw.d.cts} +9 -2
  153. package/dist/{types-Cm9fjeYC.d.ts → types-BxTL1NXw.d.ts} +9 -2
  154. package/dist/{types-Bio-91Rt.d.cts → types-CI_SX4Xe.d.cts} +2 -2
  155. package/dist/{types-Bio-91Rt.d.ts → types-CI_SX4Xe.d.ts} +2 -2
  156. package/dist/{types-HI_bbXka.d.cts → types-CmqT0jUf.d.cts} +1 -1
  157. package/dist/{types-HI_bbXka.d.ts → types-CmqT0jUf.d.ts} +1 -1
  158. package/dist/{types-CPaYBsMG.d.cts → types-CuibHYcf.d.cts} +9 -2
  159. package/dist/{types-CPaYBsMG.d.ts → types-CuibHYcf.d.ts} +9 -2
  160. package/dist/{types-CWCQwuvy.d.cts → types-CwN7AEoL.d.cts} +24 -12
  161. package/dist/{types-CWCQwuvy.d.ts → types-CwN7AEoL.d.ts} +24 -12
  162. package/dist/{types-Ck45Ex5S.d.cts → types-D0kTgUuL.d.cts} +1 -1
  163. package/dist/{types-Ck45Ex5S.d.ts → types-D0kTgUuL.d.ts} +1 -1
  164. package/dist/{types-D9eiB_9A.d.cts → types-DAnalt5K.d.cts} +9 -2
  165. package/dist/{types-D9eiB_9A.d.ts → types-DAnalt5K.d.ts} +9 -2
  166. package/dist/{types-CXlSn0I9.d.cts → types-DjxexghA.d.cts} +2 -2
  167. package/dist/{types-CXlSn0I9.d.ts → types-DjxexghA.d.ts} +2 -2
  168. package/dist/{types-Cqp10JtB.d.cts → types-DxXNP32l.d.cts} +10 -2
  169. package/dist/{types-Cqp10JtB.d.ts → types-DxXNP32l.d.ts} +10 -2
  170. package/package.json +3 -3
  171. package/src/core/auth-redaction.ts +192 -0
  172. package/src/drafts/draft07/codec.ts +40 -0
  173. package/src/drafts/draft07/error-codes.ts +44 -0
  174. package/src/drafts/draft07/index.ts +15 -0
  175. package/src/drafts/draft08/codec.ts +40 -0
  176. package/src/drafts/draft08/error-codes.ts +76 -0
  177. package/src/drafts/draft08/index.ts +21 -0
  178. package/src/drafts/draft09/codec.ts +40 -0
  179. package/src/drafts/draft09/error-codes.ts +76 -0
  180. package/src/drafts/draft09/index.ts +21 -0
  181. package/src/drafts/draft10/codec.ts +40 -0
  182. package/src/drafts/draft10/error-codes.ts +76 -0
  183. package/src/drafts/draft10/index.ts +21 -0
  184. package/src/drafts/draft11/codec.ts +71 -8
  185. package/src/drafts/draft11/error-codes.ts +106 -0
  186. package/src/drafts/draft11/index.ts +23 -0
  187. package/src/drafts/draft11/types.ts +1 -1
  188. package/src/drafts/draft12/codec.ts +83 -16
  189. package/src/drafts/draft12/error-codes.ts +116 -0
  190. package/src/drafts/draft12/index.ts +25 -0
  191. package/src/drafts/draft12/types.ts +2 -2
  192. package/src/drafts/draft13/codec.ts +75 -11
  193. package/src/drafts/draft13/error-codes.ts +107 -0
  194. package/src/drafts/draft13/index.ts +23 -0
  195. package/src/drafts/draft13/types.ts +3 -3
  196. package/src/drafts/draft14/codec.ts +79 -12
  197. package/src/drafts/draft14/data-streams.ts +331 -259
  198. package/src/drafts/draft14/error-codes.ts +109 -0
  199. package/src/drafts/draft14/index.ts +23 -0
  200. package/src/drafts/draft14/types.ts +1 -1
  201. package/src/drafts/draft15/codec.ts +71 -8
  202. package/src/drafts/draft15/data-streams.ts +489 -444
  203. package/src/drafts/draft15/error-codes.ts +66 -0
  204. package/src/drafts/draft15/index.ts +15 -0
  205. package/src/drafts/draft15/types.ts +9 -2
  206. package/src/drafts/draft16/codec.ts +149 -49
  207. package/src/drafts/draft16/data-streams.ts +513 -442
  208. package/src/drafts/draft16/error-codes.ts +68 -0
  209. package/src/drafts/draft16/index.ts +15 -0
  210. package/src/drafts/draft16/messages.ts +4 -4
  211. package/src/drafts/draft16/session-fsm.ts +0 -1
  212. package/src/drafts/draft16/types.ts +24 -10
  213. package/src/drafts/draft17/codec.ts +77 -10
  214. package/src/drafts/draft17/data-streams.ts +567 -488
  215. package/src/drafts/draft17/index.ts +15 -0
  216. package/src/drafts/draft17/types.ts +9 -2
  217. package/src/drafts/draft18/codec.ts +70 -7
  218. package/src/drafts/draft18/data-streams.ts +570 -482
  219. package/src/drafts/draft18/index.ts +3 -0
  220. package/src/drafts/draft18/types.ts +18 -10
  221. package/src/drafts/draft19/codec.ts +95 -23
  222. package/src/drafts/draft19/data-streams.ts +570 -482
  223. package/src/drafts/draft19/error-codes.ts +3 -1
  224. package/src/drafts/draft19/index.ts +3 -0
  225. package/src/drafts/draft19/messages.ts +3 -1
  226. package/src/drafts/draft19/types.ts +32 -18
  227. package/src/drafts/draft20/codec.ts +115 -36
  228. package/src/drafts/draft20/data-streams.ts +610 -563
  229. package/src/drafts/draft20/index.ts +3 -0
  230. package/src/drafts/draft20/types.ts +31 -13
  231. package/dist/codec-BJ7BHuiZ.d.ts +0 -18
  232. 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
  }
@@ -1079,12 +992,12 @@ function encodeSetupOptions(opts, writer) {
1079
992
  }
1080
993
  });
1081
994
  }
1082
- if (opts.authorization_token !== void 0) {
995
+ for (const token of opts.authorization_token ?? []) {
1083
996
  entries.push({
1084
997
  type: SETUP_OPT_AUTHORIZATION_TOKEN,
1085
998
  encode: (w) => {
1086
999
  const tmpW = new MoqtBufferWriter(64);
1087
- encodeAuthorizationToken(opts.authorization_token, tmpW);
1000
+ encodeAuthorizationToken(token, tmpW);
1088
1001
  const raw = tmpW.finish();
1089
1002
  w.writeVarInt(BigInt(raw.byteLength));
1090
1003
  w.writeBytes(raw);
@@ -1188,7 +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 = decodeAuthorizationToken(new MoqtBufferReader(bytes));
1104
+ const token = decodeAuthorizationToken(new MoqtBufferReader(bytes));
1105
+ noteAuthTokenValue(reader.offset - length, length, token);
1106
+ result.authorization_token = [...result.authorization_token ?? [], token];
1192
1107
  } else if (optType === SETUP_OPT_AUTHORITY) {
1193
1108
  result.authority = textDecoder.decode(bytes);
1194
1109
  } else if (optType === SETUP_OPT_MOQT_IMPLEMENTATION) {
@@ -1217,6 +1132,11 @@ function encodeAuthorizationToken(token, w) {
1217
1132
  w.writeBytes(tv);
1218
1133
  }
1219
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
+ }
1220
1140
  function decodeAuthorizationToken(r) {
1221
1141
  const alias_type = r.readVarInt();
1222
1142
  const aliasType = Number(alias_type);
@@ -1399,24 +1319,24 @@ var PARAMETER_SCOPE = /* @__PURE__ */ new Map([
1399
1319
  [PARAM_SUBGROUP_DELIVERY_TIMEOUT, /* @__PURE__ */ new Set(["subscribe", "publish", "request_update"])],
1400
1320
  // 0x08 EXPIRES (10.2.16) — the one parameter that still names PUBLISH_OK.
1401
1321
  [PARAM_EXPIRES, /* @__PURE__ */ new Set(["subscribe_ok", "publish", "request_ok"])],
1402
- // 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.
1403
1323
  [
1404
1324
  PARAM_LARGEST_OBJECT,
1405
1325
  /* @__PURE__ */ new Set(["subscribe_ok", "publish", "request_ok", "publish_state_notify"])
1406
1326
  ],
1407
1327
  // 0x0A FILL_TIMEOUT (10.2.5) — FETCH, or nested inside FILL_PARAMETERS.
1408
1328
  [PARAM_FILL_TIMEOUT, /* @__PURE__ */ new Set(["fetch", FILL_SCOPE])],
1409
- // 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.
1410
1330
  [
1411
1331
  PARAM_FORWARD,
1412
1332
  /* @__PURE__ */ new Set(["subscribe", "request_update", "publish", "subscribe_tracks", "publish_state_notify"])
1413
1333
  ],
1414
- // 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.
1415
1335
  [
1416
1336
  PARAM_SUBSCRIBER_PRIORITY,
1417
1337
  /* @__PURE__ */ new Set(["subscribe", "publish", "fetch", "request_update", FILL_SCOPE])
1418
1338
  ],
1419
- // 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.
1420
1340
  [
1421
1341
  PARAM_LOCATION_FILTER,
1422
1342
  /* @__PURE__ */ new Set([
@@ -1428,12 +1348,12 @@ var PARAMETER_SCOPE = /* @__PURE__ */ new Map([
1428
1348
  FILL_SCOPE
1429
1349
  ])
1430
1350
  ],
1431
- // 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.
1432
1352
  [PARAM_GROUP_ORDER, /* @__PURE__ */ new Set(["subscribe", "publish", "subscribe_tracks", "fetch", FILL_SCOPE])],
1433
1353
  // 0x23 FILL_PARAMETERS (10.2.15) — NEW. Subscriptions only, and never nested
1434
1354
  // in itself: a FETCH already is a fetch, so it has nothing to fill.
1435
1355
  [PARAM_FILL_PARAMETERS, /* @__PURE__ */ new Set(["subscribe", "request_update"])],
1436
- // 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).
1437
1357
  [
1438
1358
  PARAM_SUBGROUP_FILTER,
1439
1359
  /* @__PURE__ */ new Set(["fetch", "subscribe", "subscribe_tracks", "request_update", FILL_SCOPE])
@@ -1450,11 +1370,11 @@ var PARAMETER_SCOPE = /* @__PURE__ */ new Map([
1450
1370
  PARAM_OBJECT_PROPERTY_FILTER,
1451
1371
  /* @__PURE__ */ new Set(["fetch", "subscribe", "subscribe_tracks", "request_update", FILL_SCOPE])
1452
1372
  ],
1453
- // 0x29 TRACK_PROPERTY_FILTER (10.2.14) — lost PUBLISH_OK; NOT permitted
1454
- // inside FILL_PARAMETERS. A relay forwarding a downstream FILL_PARAMETERS
1455
- // 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.
1456
1376
  [PARAM_TRACK_PROPERTY_FILTER, /* @__PURE__ */ new Set(["subscribe_tracks", "request_update"])],
1457
- // 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.
1458
1378
  [PARAM_NEW_GROUP_REQUEST, /* @__PURE__ */ new Set(["subscribe", "request_update"])],
1459
1379
  // 0x34 TRACK_NAMESPACE_PREFIX (10.2.20) — REQUEST_UPDATE for a namespace subscription.
1460
1380
  [PARAM_TRACK_NAMESPACE_PREFIX, /* @__PURE__ */ new Set(["request_update"])],
@@ -1469,12 +1389,12 @@ function encodeParams(params, writer) {
1469
1389
  encode: (w) => w.writeVarInt(params.object_delivery_timeout)
1470
1390
  });
1471
1391
  }
1472
- if (params.authorization_token !== void 0) {
1392
+ for (const token of params.authorization_token ?? []) {
1473
1393
  entries.push({
1474
1394
  type: PARAM_AUTHORIZATION_TOKEN,
1475
1395
  encode: (w) => {
1476
1396
  const tmpW = new MoqtBufferWriter(64);
1477
- encodeAuthorizationToken(params.authorization_token, tmpW);
1397
+ encodeAuthorizationToken(token, tmpW);
1478
1398
  const raw = tmpW.finish();
1479
1399
  w.writeVarInt(BigInt(raw.byteLength));
1480
1400
  w.writeBytes(raw);
@@ -1554,34 +1474,34 @@ function encodeParams(params, writer) {
1554
1474
  }
1555
1475
  });
1556
1476
  }
1557
- if (params.subgroup_filter !== void 0) {
1477
+ for (const filter of params.subgroup_filter ?? []) {
1558
1478
  entries.push({
1559
1479
  type: PARAM_SUBGROUP_FILTER,
1560
- encode: (w) => encodeRangeFilter(params.subgroup_filter, false, w)
1480
+ encode: (w) => encodeRangeFilter(filter, false, w)
1561
1481
  });
1562
1482
  }
1563
- if (params.objectid_filter !== void 0) {
1483
+ for (const filter of params.objectid_filter ?? []) {
1564
1484
  entries.push({
1565
1485
  type: PARAM_OBJECTID_FILTER,
1566
- encode: (w) => encodeRangeFilter(params.objectid_filter, false, w)
1486
+ encode: (w) => encodeRangeFilter(filter, false, w)
1567
1487
  });
1568
1488
  }
1569
- if (params.priority_filter !== void 0) {
1489
+ for (const filter of params.priority_filter ?? []) {
1570
1490
  entries.push({
1571
1491
  type: PARAM_PRIORITY_FILTER,
1572
- encode: (w) => encodeRangeFilter(params.priority_filter, false, w)
1492
+ encode: (w) => encodeRangeFilter(filter, false, w)
1573
1493
  });
1574
1494
  }
1575
- if (params.object_property_filter !== void 0) {
1495
+ for (const filter of params.object_property_filter ?? []) {
1576
1496
  entries.push({
1577
1497
  type: PARAM_OBJECT_PROPERTY_FILTER,
1578
- encode: (w) => encodeRangeFilter(params.object_property_filter, true, w)
1498
+ encode: (w) => encodeRangeFilter(filter, true, w)
1579
1499
  });
1580
1500
  }
1581
- if (params.track_property_filter !== void 0) {
1501
+ for (const filter of params.track_property_filter ?? []) {
1582
1502
  entries.push({
1583
1503
  type: PARAM_TRACK_PROPERTY_FILTER,
1584
- encode: (w) => encodeRangeFilter(params.track_property_filter, true, w)
1504
+ encode: (w) => encodeRangeFilter(filter, true, w)
1585
1505
  });
1586
1506
  }
1587
1507
  if (params.new_group_request !== void 0) {
@@ -1650,7 +1570,9 @@ function decodeParams(reader, messageType) {
1650
1570
  } else if (paramType === PARAM_AUTHORIZATION_TOKEN) {
1651
1571
  const length = Number(reader.readVarInt());
1652
1572
  const bytes = reader.readBytes(length);
1653
- result.authorization_token = decodeAuthorizationToken(new MoqtBufferReader(bytes));
1573
+ const token = decodeAuthorizationToken(new MoqtBufferReader(bytes));
1574
+ noteAuthTokenValue(reader.offset - length, length, token);
1575
+ result.authorization_token = [...result.authorization_token ?? [], token];
1654
1576
  } else if (paramType === PARAM_RENDEZVOUS_TIMEOUT) {
1655
1577
  result.rendezvous_timeout = reader.readVarInt();
1656
1578
  } else if (paramType === PARAM_SUBGROUP_DELIVERY_TIMEOUT) {
@@ -1674,15 +1596,21 @@ function decodeParams(reader, messageType) {
1674
1596
  } else if (paramType === PARAM_FILL_PARAMETERS) {
1675
1597
  result.fill_parameters = decodeFillParameters(reader);
1676
1598
  } else if (paramType === PARAM_SUBGROUP_FILTER) {
1677
- result.subgroup_filter = decodeRangeFilter(reader, false);
1599
+ result.subgroup_filter = [...result.subgroup_filter ?? [], decodeRangeFilter(reader, false)];
1678
1600
  } else if (paramType === PARAM_OBJECTID_FILTER) {
1679
- result.objectid_filter = decodeRangeFilter(reader, false);
1601
+ result.objectid_filter = [...result.objectid_filter ?? [], decodeRangeFilter(reader, false)];
1680
1602
  } else if (paramType === PARAM_PRIORITY_FILTER) {
1681
- result.priority_filter = decodeRangeFilter(reader, false);
1603
+ result.priority_filter = [...result.priority_filter ?? [], decodeRangeFilter(reader, false)];
1682
1604
  } else if (paramType === PARAM_OBJECT_PROPERTY_FILTER) {
1683
- result.object_property_filter = decodeRangeFilter(reader, true);
1605
+ result.object_property_filter = [
1606
+ ...result.object_property_filter ?? [],
1607
+ decodeRangeFilter(reader, true)
1608
+ ];
1684
1609
  } else if (paramType === PARAM_TRACK_PROPERTY_FILTER) {
1685
- result.track_property_filter = decodeRangeFilter(reader, true);
1610
+ result.track_property_filter = [
1611
+ ...result.track_property_filter ?? [],
1612
+ decodeRangeFilter(reader, true)
1613
+ ];
1686
1614
  } else if (paramType === PARAM_NEW_GROUP_REQUEST) {
1687
1615
  result.new_group_request = reader.readVarInt();
1688
1616
  } else if (paramType === PARAM_TRACK_NAMESPACE_PREFIX) {
@@ -1711,7 +1639,7 @@ function decodeFillParameters(reader) {
1711
1639
  const length = Number(reader.readVarInt());
1712
1640
  const valueBytes = reader.readBytes(length);
1713
1641
  const nested = new MoqtBufferReader(valueBytes);
1714
- const params = decodeParams(nested, FILL_SCOPE);
1642
+ const params = withoutAuthValueSpans(() => decodeParams(nested, FILL_SCOPE));
1715
1643
  if (nested.remaining > 0) {
1716
1644
  throw new DecodeError(
1717
1645
  "CONSTRAINT_VIOLATION",
@@ -2313,6 +2241,19 @@ function createDraft20Codec() {
2313
2241
  createDataStreamDecoder
2314
2242
  };
2315
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
+ }
2316
2257
 
2317
2258
  export {
2318
2259
  MSG_REQUEST_UPDATE,
@@ -2358,5 +2299,6 @@ export {
2358
2299
  encodeMessage,
2359
2300
  decodeMessage,
2360
2301
  createStreamDecoder,
2361
- createDraft20Codec
2302
+ createDraft20Codec,
2303
+ redactAuthTokens
2362
2304
  };