@blockcast/mmt-container 0.1.0-main.149f78a4adae

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 (678) hide show
  1. package/README.md +432 -0
  2. package/dist/.build-stamp +0 -0
  3. package/dist/__tests__/test-utils.d.ts +71 -0
  4. package/dist/__tests__/test-utils.d.ts.map +1 -0
  5. package/dist/align.d.ts +148 -0
  6. package/dist/align.d.ts.map +1 -0
  7. package/dist/align.js +88 -0
  8. package/dist/align.js.map +7 -0
  9. package/dist/audio-init-parser.d.ts +66 -0
  10. package/dist/audio-init-parser.d.ts.map +1 -0
  11. package/dist/audio-init-parser.js +118 -0
  12. package/dist/audio-init-parser.js.map +7 -0
  13. package/dist/audio-ring-buffer.d.ts +50 -0
  14. package/dist/audio-ring-buffer.d.ts.map +1 -0
  15. package/dist/audio-ring-buffer.js +93 -0
  16. package/dist/audio-ring-buffer.js.map +7 -0
  17. package/dist/authored-timing.d.ts +32 -0
  18. package/dist/authored-timing.d.ts.map +1 -0
  19. package/dist/authored-timing.js +32 -0
  20. package/dist/authored-timing.js.map +7 -0
  21. package/dist/browser-runtime.js +17109 -0
  22. package/dist/browser-runtime.js.map +7 -0
  23. package/dist/carp-catalog.d.ts +318 -0
  24. package/dist/carp-catalog.d.ts.map +1 -0
  25. package/dist/carp-catalog.js +549 -0
  26. package/dist/carp-catalog.js.map +7 -0
  27. package/dist/catalog-fec-params.d.ts +82 -0
  28. package/dist/catalog-fec-params.d.ts.map +1 -0
  29. package/dist/catalog-fec-params.js +66 -0
  30. package/dist/catalog-fec-params.js.map +7 -0
  31. package/dist/catalog-network-source.d.ts +19 -0
  32. package/dist/catalog-network-source.d.ts.map +1 -0
  33. package/dist/catalog-network-source.js +22 -0
  34. package/dist/catalog-network-source.js.map +7 -0
  35. package/dist/catalog-validator.d.ts +18 -0
  36. package/dist/catalog-validator.d.ts.map +1 -0
  37. package/dist/catalog-validator.js +7747 -0
  38. package/dist/catalog-validator.js.map +7 -0
  39. package/dist/cmaf-block-assembler.d.ts +168 -0
  40. package/dist/cmaf-block-assembler.d.ts.map +1 -0
  41. package/dist/cmaf-block-assembler.js +1755 -0
  42. package/dist/cmaf-block-assembler.js.map +7 -0
  43. package/dist/cmaf-group-batcher.d.ts +38 -0
  44. package/dist/cmaf-group-batcher.d.ts.map +1 -0
  45. package/dist/cmaf-group-batcher.js +195 -0
  46. package/dist/cmaf-group-batcher.js.map +7 -0
  47. package/dist/cmcd-producer.d.ts +104 -0
  48. package/dist/cmcd-producer.d.ts.map +1 -0
  49. package/dist/cmcd-producer.js +207 -0
  50. package/dist/cmcd-producer.js.map +7 -0
  51. package/dist/codec-utils.d.ts +235 -0
  52. package/dist/codec-utils.d.ts.map +1 -0
  53. package/dist/codec-utils.js +1225 -0
  54. package/dist/codec-utils.js.map +7 -0
  55. package/dist/fec-codec.d.ts +32 -0
  56. package/dist/fec-codec.d.ts.map +1 -0
  57. package/dist/fec-codec.js +47 -0
  58. package/dist/fec-codec.js.map +7 -0
  59. package/dist/fec-manager.d.ts +266 -0
  60. package/dist/fec-manager.d.ts.map +1 -0
  61. package/dist/fec-manager.js +1447 -0
  62. package/dist/fec-manager.js.map +7 -0
  63. package/dist/fec-starvation-detector.d.ts +59 -0
  64. package/dist/fec-starvation-detector.d.ts.map +1 -0
  65. package/dist/fec-starvation-detector.js +75 -0
  66. package/dist/fec-starvation-detector.js.map +7 -0
  67. package/dist/fec-worker-setup.d.ts +76 -0
  68. package/dist/fec-worker-setup.d.ts.map +1 -0
  69. package/dist/fec-worker-setup.js +603 -0
  70. package/dist/fec-worker-setup.js.map +7 -0
  71. package/dist/fmp4-completion.d.ts +30 -0
  72. package/dist/fmp4-completion.d.ts.map +1 -0
  73. package/dist/fmp4-completion.js +21 -0
  74. package/dist/fmp4-completion.js.map +7 -0
  75. package/dist/fmp4-reader.d.ts +37 -0
  76. package/dist/fmp4-reader.d.ts.map +1 -0
  77. package/dist/fmp4-reader.js +100 -0
  78. package/dist/fmp4-reader.js.map +7 -0
  79. package/dist/index.d.ts +47 -0
  80. package/dist/index.d.ts.map +1 -0
  81. package/dist/index.js +330 -0
  82. package/dist/index.js.map +7 -0
  83. package/dist/iso-bmff-timing.d.ts +47 -0
  84. package/dist/iso-bmff-timing.d.ts.map +1 -0
  85. package/dist/iso-bmff-timing.js +526 -0
  86. package/dist/iso-bmff-timing.js.map +7 -0
  87. package/dist/loc.d.ts +68 -0
  88. package/dist/loc.d.ts.map +1 -0
  89. package/dist/loc.js +143 -0
  90. package/dist/loc.js.map +7 -0
  91. package/dist/manifest-auth-plan.d.ts +30 -0
  92. package/dist/manifest-auth-plan.d.ts.map +1 -0
  93. package/dist/manifest-auth-plan.js +1267 -0
  94. package/dist/manifest-auth-plan.js.map +7 -0
  95. package/dist/media-router.d.ts +338 -0
  96. package/dist/media-router.d.ts.map +1 -0
  97. package/dist/media-router.js +802 -0
  98. package/dist/media-router.js.map +7 -0
  99. package/dist/mfu-reassembler.d.ts +264 -0
  100. package/dist/mfu-reassembler.d.ts.map +1 -0
  101. package/dist/mfu-reassembler.js +2668 -0
  102. package/dist/mfu-reassembler.js.map +7 -0
  103. package/dist/mfu-reassembly-policy.d.ts +24 -0
  104. package/dist/mfu-reassembly-policy.d.ts.map +1 -0
  105. package/dist/mfu-reassembly-policy.js +99 -0
  106. package/dist/mfu-reassembly-policy.js.map +7 -0
  107. package/dist/mmtp-container-parser.d.ts +304 -0
  108. package/dist/mmtp-container-parser.d.ts.map +1 -0
  109. package/dist/mmtp-container-parser.js +5378 -0
  110. package/dist/mmtp-container-parser.js.map +7 -0
  111. package/dist/mmtp-container-parser.no-modules.js +7853 -0
  112. package/dist/mmtp-container-parser.no-modules.js.map +7 -0
  113. package/dist/mmtp-decode-pipeline.d.ts +96 -0
  114. package/dist/mmtp-decode-pipeline.d.ts.map +1 -0
  115. package/dist/mmtp-decode-pipeline.js +5589 -0
  116. package/dist/mmtp-decode-pipeline.js.map +7 -0
  117. package/dist/mmtp-router.d.ts +383 -0
  118. package/dist/mmtp-router.d.ts.map +1 -0
  119. package/dist/mmtp-router.js +8384 -0
  120. package/dist/mmtp-router.js.map +7 -0
  121. package/dist/mmtp-to-cmaf.d.ts +166 -0
  122. package/dist/mmtp-to-cmaf.d.ts.map +1 -0
  123. package/dist/mmtp-to-cmaf.js +781 -0
  124. package/dist/mmtp-to-cmaf.js.map +7 -0
  125. package/dist/multicast-auth-catalog.d.ts +115 -0
  126. package/dist/multicast-auth-catalog.d.ts.map +1 -0
  127. package/dist/multicast-auth-catalog.js +202 -0
  128. package/dist/multicast-auth-catalog.js.map +7 -0
  129. package/dist/multicast-input.d.ts +107 -0
  130. package/dist/multicast-input.d.ts.map +1 -0
  131. package/dist/multicast-input.js +256 -0
  132. package/dist/multicast-input.js.map +7 -0
  133. package/dist/multicast-manager.d.ts +330 -0
  134. package/dist/multicast-manager.d.ts.map +1 -0
  135. package/dist/multicast-manager.js +11032 -0
  136. package/dist/multicast-manager.js.map +7 -0
  137. package/dist/multicast-transport.d.ts +62 -0
  138. package/dist/multicast-transport.d.ts.map +1 -0
  139. package/dist/multicast-transport.js +338 -0
  140. package/dist/multicast-transport.js.map +7 -0
  141. package/dist/multicast-unwrap.d.ts +57 -0
  142. package/dist/multicast-unwrap.d.ts.map +1 -0
  143. package/dist/multicast-unwrap.js +384 -0
  144. package/dist/multicast-unwrap.js.map +7 -0
  145. package/dist/no-modules.d.ts +9 -0
  146. package/dist/no-modules.d.ts.map +1 -0
  147. package/dist/no-modules.js +7819 -0
  148. package/dist/no-modules.js.map +7 -0
  149. package/dist/phase14-catalog-override.d.ts +126 -0
  150. package/dist/phase14-catalog-override.d.ts.map +1 -0
  151. package/dist/phase14-catalog-override.js +155 -0
  152. package/dist/phase14-catalog-override.js.map +7 -0
  153. package/dist/repair-fetch.d.ts +58 -0
  154. package/dist/repair-fetch.d.ts.map +1 -0
  155. package/dist/repair-fetch.js +117 -0
  156. package/dist/repair-fetch.js.map +7 -0
  157. package/dist/sample-combiner.d.ts +182 -0
  158. package/dist/sample-combiner.d.ts.map +1 -0
  159. package/dist/sample-combiner.js +571 -0
  160. package/dist/sample-combiner.js.map +7 -0
  161. package/dist/signaling.d.ts +29 -0
  162. package/dist/signaling.d.ts.map +1 -0
  163. package/dist/signaling.js +232 -0
  164. package/dist/signaling.js.map +7 -0
  165. package/dist/source-auth.d.ts +2 -0
  166. package/dist/source-auth.d.ts.map +1 -0
  167. package/dist/source-auth.js +1220 -0
  168. package/dist/source-auth.js.map +7 -0
  169. package/dist/switching-set-alignment.d.ts +61 -0
  170. package/dist/switching-set-alignment.d.ts.map +1 -0
  171. package/dist/switching-set-alignment.js +85 -0
  172. package/dist/switching-set-alignment.js.map +7 -0
  173. package/dist/timestamp-codec.d.ts +34 -0
  174. package/dist/timestamp-codec.d.ts.map +1 -0
  175. package/dist/timestamp-codec.js +456 -0
  176. package/dist/timestamp-codec.js.map +7 -0
  177. package/dist/track-pipeline-setup.d.ts +72 -0
  178. package/dist/track-pipeline-setup.d.ts.map +1 -0
  179. package/dist/track-pipeline-setup.js +306 -0
  180. package/dist/track-pipeline-setup.js.map +7 -0
  181. package/dist/track-pipeline.d.ts +121 -0
  182. package/dist/track-pipeline.d.ts.map +1 -0
  183. package/dist/track-pipeline.js +229 -0
  184. package/dist/track-pipeline.js.map +7 -0
  185. package/dist/track-session.d.ts +269 -0
  186. package/dist/track-session.d.ts.map +1 -0
  187. package/dist/track-session.js +597 -0
  188. package/dist/track-session.js.map +7 -0
  189. package/dist/transport-pool.d.ts +69 -0
  190. package/dist/transport-pool.d.ts.map +1 -0
  191. package/dist/transport-pool.js +88 -0
  192. package/dist/transport-pool.js.map +7 -0
  193. package/dist/wasm-mfu-reassembler.d.ts +81 -0
  194. package/dist/wasm-mfu-reassembler.d.ts.map +1 -0
  195. package/dist/wasm-mfu-reassembler.js +1915 -0
  196. package/dist/wasm-mfu-reassembler.js.map +7 -0
  197. package/dist/wasm-mmtp-container-parser.d.ts +10 -0
  198. package/dist/wasm-mmtp-container-parser.d.ts.map +1 -0
  199. package/dist/wasm-mmtp-container-parser.js +5635 -0
  200. package/dist/wasm-mmtp-container-parser.js.map +7 -0
  201. package/node_modules/@blockcast/fec-worker/README.md +213 -0
  202. package/node_modules/@blockcast/fec-worker/dist/.build-stamp +0 -0
  203. package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.d.ts +80 -0
  204. package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.d.ts.map +1 -0
  205. package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.js +270 -0
  206. package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.js.map +1 -0
  207. package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.d.ts +252 -0
  208. package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.d.ts.map +1 -0
  209. package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.js +11 -0
  210. package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.js.map +1 -0
  211. package/node_modules/@blockcast/fec-worker/dist/fec-worker.d.ts +14 -0
  212. package/node_modules/@blockcast/fec-worker/dist/fec-worker.d.ts.map +1 -0
  213. package/node_modules/@blockcast/fec-worker/dist/fec-worker.js +565 -0
  214. package/node_modules/@blockcast/fec-worker/dist/fec-worker.js.map +7 -0
  215. package/node_modules/@blockcast/fec-worker/dist/index.d.ts +10 -0
  216. package/node_modules/@blockcast/fec-worker/dist/index.d.ts.map +1 -0
  217. package/node_modules/@blockcast/fec-worker/dist/index.js +8 -0
  218. package/node_modules/@blockcast/fec-worker/dist/index.js.map +1 -0
  219. package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.d.ts +20 -0
  220. package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.d.ts.map +1 -0
  221. package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.js +349 -0
  222. package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.js.map +7 -0
  223. package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.d.ts +104 -0
  224. package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.d.ts.map +1 -0
  225. package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.js +181 -0
  226. package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.js.map +1 -0
  227. package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.d.ts +179 -0
  228. package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.d.ts.map +1 -0
  229. package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.js +47 -0
  230. package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.js.map +1 -0
  231. package/node_modules/@blockcast/fec-worker/dist/transfer.d.ts +9 -0
  232. package/node_modules/@blockcast/fec-worker/dist/transfer.d.ts.map +1 -0
  233. package/node_modules/@blockcast/fec-worker/dist/transfer.js +13 -0
  234. package/node_modules/@blockcast/fec-worker/dist/transfer.js.map +1 -0
  235. package/node_modules/@blockcast/fec-worker/package.json +59 -0
  236. package/node_modules/@blockcast/fec-worker/src/fec-worker-client.ts +309 -0
  237. package/node_modules/@blockcast/fec-worker/src/fec-worker-types.ts +268 -0
  238. package/node_modules/@blockcast/fec-worker/src/fec-worker.ts +1048 -0
  239. package/node_modules/@blockcast/fec-worker/src/index.ts +32 -0
  240. package/node_modules/@blockcast/fec-worker/src/shred-fec-worker.ts +558 -0
  241. package/node_modules/@blockcast/fec-worker/src/shred-worker-client.ts +222 -0
  242. package/node_modules/@blockcast/fec-worker/src/shred-worker-types.ts +194 -0
  243. package/node_modules/@blockcast/fec-worker/src/transfer.ts +12 -0
  244. package/node_modules/@blockcast/mmt-alta-parse/README.md +181 -0
  245. package/node_modules/@blockcast/mmt-alta-parse/dist/.build-stamp +0 -0
  246. package/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts +57 -0
  247. package/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts.map +1 -0
  248. package/node_modules/@blockcast/mmt-alta-parse/dist/index.js +115 -0
  249. package/node_modules/@blockcast/mmt-alta-parse/dist/index.js.map +1 -0
  250. package/node_modules/@blockcast/mmt-alta-parse/package.json +50 -0
  251. package/node_modules/@blockcast/mmt-alta-parse/src/index.ts +136 -0
  252. package/node_modules/@blockcast/mmt-base/README.md +120 -0
  253. package/node_modules/@blockcast/mmt-base/dist/.build-stamp +0 -0
  254. package/node_modules/@blockcast/mmt-base/dist/index.d.ts +2 -0
  255. package/node_modules/@blockcast/mmt-base/dist/index.d.ts.map +1 -0
  256. package/node_modules/@blockcast/mmt-base/dist/index.js +2 -0
  257. package/node_modules/@blockcast/mmt-base/dist/index.js.map +1 -0
  258. package/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts +275 -0
  259. package/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts.map +1 -0
  260. package/node_modules/@blockcast/mmt-base/dist/mmtp.js +644 -0
  261. package/node_modules/@blockcast/mmt-base/dist/mmtp.js.map +1 -0
  262. package/node_modules/@blockcast/mmt-base/package.json +49 -0
  263. package/node_modules/@blockcast/mmt-base/src/index.ts +1 -0
  264. package/node_modules/@blockcast/mmt-base/src/mmtp.ts +898 -0
  265. package/node_modules/@blockcast/mmt-fec/README.md +270 -0
  266. package/node_modules/@blockcast/mmt-fec/dist/.build-stamp +0 -0
  267. package/node_modules/@blockcast/mmt-fec/dist/block-manager.d.ts +80 -0
  268. package/node_modules/@blockcast/mmt-fec/dist/block-manager.d.ts.map +1 -0
  269. package/node_modules/@blockcast/mmt-fec/dist/block-manager.js +294 -0
  270. package/node_modules/@blockcast/mmt-fec/dist/block-manager.js.map +1 -0
  271. package/node_modules/@blockcast/mmt-fec/dist/block-processor.d.ts +72 -0
  272. package/node_modules/@blockcast/mmt-fec/dist/block-processor.d.ts.map +1 -0
  273. package/node_modules/@blockcast/mmt-fec/dist/block-processor.js +192 -0
  274. package/node_modules/@blockcast/mmt-fec/dist/block-processor.js.map +1 -0
  275. package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.d.ts +46 -0
  276. package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.d.ts.map +1 -0
  277. package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.js +96 -0
  278. package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.js.map +1 -0
  279. package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.d.ts +33 -0
  280. package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.d.ts.map +1 -0
  281. package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.js +57 -0
  282. package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.js.map +1 -0
  283. package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.d.ts +185 -0
  284. package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.d.ts.map +1 -0
  285. package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.js +273 -0
  286. package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.js.map +1 -0
  287. package/node_modules/@blockcast/mmt-fec/dist/index.d.ts +22 -0
  288. package/node_modules/@blockcast/mmt-fec/dist/index.d.ts.map +1 -0
  289. package/node_modules/@blockcast/mmt-fec/dist/index.js +22 -0
  290. package/node_modules/@blockcast/mmt-fec/dist/index.js.map +1 -0
  291. package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.d.ts +20 -0
  292. package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.d.ts.map +1 -0
  293. package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.js +28 -0
  294. package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.js.map +1 -0
  295. package/node_modules/@blockcast/mmt-fec/dist/oti.d.ts +174 -0
  296. package/node_modules/@blockcast/mmt-fec/dist/oti.d.ts.map +1 -0
  297. package/node_modules/@blockcast/mmt-fec/dist/oti.js +256 -0
  298. package/node_modules/@blockcast/mmt-fec/dist/oti.js.map +1 -0
  299. package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.d.ts +41 -0
  300. package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.d.ts.map +1 -0
  301. package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.js +81 -0
  302. package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.js.map +1 -0
  303. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/README.md +181 -0
  304. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/.build-stamp +0 -0
  305. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts +57 -0
  306. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts.map +1 -0
  307. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.js +115 -0
  308. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.js.map +1 -0
  309. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/package.json +50 -0
  310. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/src/index.ts +136 -0
  311. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/README.md +120 -0
  312. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/.build-stamp +0 -0
  313. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.d.ts +2 -0
  314. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.d.ts.map +1 -0
  315. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.js +2 -0
  316. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.js.map +1 -0
  317. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts +275 -0
  318. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts.map +1 -0
  319. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.js +644 -0
  320. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.js.map +1 -0
  321. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/package.json +49 -0
  322. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/index.ts +1 -0
  323. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/mmtp.ts +898 -0
  324. package/node_modules/@blockcast/mmt-fec/package.json +79 -0
  325. package/node_modules/@blockcast/mmt-fec/src/block-manager.ts +369 -0
  326. package/node_modules/@blockcast/mmt-fec/src/block-processor.ts +277 -0
  327. package/node_modules/@blockcast/mmt-fec/src/cmaf-recovery.ts +127 -0
  328. package/node_modules/@blockcast/mmt-fec/src/cmaf-symbols.ts +68 -0
  329. package/node_modules/@blockcast/mmt-fec/src/fec-block-mapper.ts +332 -0
  330. package/node_modules/@blockcast/mmt-fec/src/index.ts +77 -0
  331. package/node_modules/@blockcast/mmt-fec/src/loc-symbols.ts +34 -0
  332. package/node_modules/@blockcast/mmt-fec/src/oti.ts +319 -0
  333. package/node_modules/@blockcast/mmt-fec/src/reorder-buffer.ts +101 -0
  334. package/node_modules/@blockcast/mmt-manifest-verify/dist/.build-stamp +0 -0
  335. package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.d.ts +28 -0
  336. package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.d.ts.map +1 -0
  337. package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.js +128 -0
  338. package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.js.map +1 -0
  339. package/node_modules/@blockcast/mmt-manifest-verify/dist/index.d.ts +4 -0
  340. package/node_modules/@blockcast/mmt-manifest-verify/dist/index.d.ts.map +1 -0
  341. package/node_modules/@blockcast/mmt-manifest-verify/dist/index.js +4 -0
  342. package/node_modules/@blockcast/mmt-manifest-verify/dist/index.js.map +1 -0
  343. package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.d.ts +37 -0
  344. package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.d.ts.map +1 -0
  345. package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.js +179 -0
  346. package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.js.map +1 -0
  347. package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.d.ts +90 -0
  348. package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.d.ts.map +1 -0
  349. package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.js +462 -0
  350. package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.js.map +1 -0
  351. package/node_modules/@blockcast/mmt-manifest-verify/package.json +45 -0
  352. package/node_modules/@blockcast/mmt-manifest-verify/src/admission.ts +171 -0
  353. package/node_modules/@blockcast/mmt-manifest-verify/src/index.ts +3 -0
  354. package/node_modules/@blockcast/mmt-manifest-verify/src/source-auth.ts +230 -0
  355. package/node_modules/@blockcast/mmt-manifest-verify/src/verifier.ts +636 -0
  356. package/node_modules/@noble/hashes/LICENSE +21 -0
  357. package/node_modules/@noble/hashes/README.md +521 -0
  358. package/node_modules/@noble/hashes/_assert.d.ts +17 -0
  359. package/node_modules/@noble/hashes/_assert.d.ts.map +1 -0
  360. package/node_modules/@noble/hashes/_assert.js +18 -0
  361. package/node_modules/@noble/hashes/_assert.js.map +1 -0
  362. package/node_modules/@noble/hashes/_blake.d.ts +14 -0
  363. package/node_modules/@noble/hashes/_blake.d.ts.map +1 -0
  364. package/node_modules/@noble/hashes/_blake.js +50 -0
  365. package/node_modules/@noble/hashes/_blake.js.map +1 -0
  366. package/node_modules/@noble/hashes/_md.d.ts +51 -0
  367. package/node_modules/@noble/hashes/_md.d.ts.map +1 -0
  368. package/node_modules/@noble/hashes/_md.js +162 -0
  369. package/node_modules/@noble/hashes/_md.js.map +1 -0
  370. package/node_modules/@noble/hashes/_u64.d.ts +55 -0
  371. package/node_modules/@noble/hashes/_u64.d.ts.map +1 -0
  372. package/node_modules/@noble/hashes/_u64.js +90 -0
  373. package/node_modules/@noble/hashes/_u64.js.map +1 -0
  374. package/node_modules/@noble/hashes/argon2.d.ts +32 -0
  375. package/node_modules/@noble/hashes/argon2.d.ts.map +1 -0
  376. package/node_modules/@noble/hashes/argon2.js +401 -0
  377. package/node_modules/@noble/hashes/argon2.js.map +1 -0
  378. package/node_modules/@noble/hashes/blake1.d.ts +106 -0
  379. package/node_modules/@noble/hashes/blake1.d.ts.map +1 -0
  380. package/node_modules/@noble/hashes/blake1.js +459 -0
  381. package/node_modules/@noble/hashes/blake1.js.map +1 -0
  382. package/node_modules/@noble/hashes/blake2.d.ts +116 -0
  383. package/node_modules/@noble/hashes/blake2.d.ts.map +1 -0
  384. package/node_modules/@noble/hashes/blake2.js +420 -0
  385. package/node_modules/@noble/hashes/blake2.js.map +1 -0
  386. package/node_modules/@noble/hashes/blake2b.d.ts +11 -0
  387. package/node_modules/@noble/hashes/blake2b.d.ts.map +1 -0
  388. package/node_modules/@noble/hashes/blake2b.js +14 -0
  389. package/node_modules/@noble/hashes/blake2b.js.map +1 -0
  390. package/node_modules/@noble/hashes/blake2s.d.ts +20 -0
  391. package/node_modules/@noble/hashes/blake2s.d.ts.map +1 -0
  392. package/node_modules/@noble/hashes/blake2s.js +24 -0
  393. package/node_modules/@noble/hashes/blake2s.js.map +1 -0
  394. package/node_modules/@noble/hashes/blake3.d.ts +54 -0
  395. package/node_modules/@noble/hashes/blake3.d.ts.map +1 -0
  396. package/node_modules/@noble/hashes/blake3.js +255 -0
  397. package/node_modules/@noble/hashes/blake3.js.map +1 -0
  398. package/node_modules/@noble/hashes/crypto.d.ts +2 -0
  399. package/node_modules/@noble/hashes/crypto.d.ts.map +1 -0
  400. package/node_modules/@noble/hashes/crypto.js +5 -0
  401. package/node_modules/@noble/hashes/crypto.js.map +1 -0
  402. package/node_modules/@noble/hashes/cryptoNode.d.ts +2 -0
  403. package/node_modules/@noble/hashes/cryptoNode.d.ts.map +1 -0
  404. package/node_modules/@noble/hashes/cryptoNode.js +18 -0
  405. package/node_modules/@noble/hashes/cryptoNode.js.map +1 -0
  406. package/node_modules/@noble/hashes/eskdf.d.ts +47 -0
  407. package/node_modules/@noble/hashes/eskdf.d.ts.map +1 -0
  408. package/node_modules/@noble/hashes/eskdf.js +166 -0
  409. package/node_modules/@noble/hashes/eskdf.js.map +1 -0
  410. package/node_modules/@noble/hashes/esm/_assert.d.ts +17 -0
  411. package/node_modules/@noble/hashes/esm/_assert.d.ts.map +1 -0
  412. package/node_modules/@noble/hashes/esm/_assert.js +15 -0
  413. package/node_modules/@noble/hashes/esm/_assert.js.map +1 -0
  414. package/node_modules/@noble/hashes/esm/_blake.d.ts +14 -0
  415. package/node_modules/@noble/hashes/esm/_blake.d.ts.map +1 -0
  416. package/node_modules/@noble/hashes/esm/_blake.js +45 -0
  417. package/node_modules/@noble/hashes/esm/_blake.js.map +1 -0
  418. package/node_modules/@noble/hashes/esm/_md.d.ts +51 -0
  419. package/node_modules/@noble/hashes/esm/_md.d.ts.map +1 -0
  420. package/node_modules/@noble/hashes/esm/_md.js +155 -0
  421. package/node_modules/@noble/hashes/esm/_md.js.map +1 -0
  422. package/node_modules/@noble/hashes/esm/_u64.d.ts +55 -0
  423. package/node_modules/@noble/hashes/esm/_u64.d.ts.map +1 -0
  424. package/node_modules/@noble/hashes/esm/_u64.js +67 -0
  425. package/node_modules/@noble/hashes/esm/_u64.js.map +1 -0
  426. package/node_modules/@noble/hashes/esm/argon2.d.ts +32 -0
  427. package/node_modules/@noble/hashes/esm/argon2.d.ts.map +1 -0
  428. package/node_modules/@noble/hashes/esm/argon2.js +392 -0
  429. package/node_modules/@noble/hashes/esm/argon2.js.map +1 -0
  430. package/node_modules/@noble/hashes/esm/blake1.d.ts +106 -0
  431. package/node_modules/@noble/hashes/esm/blake1.d.ts.map +1 -0
  432. package/node_modules/@noble/hashes/esm/blake1.js +452 -0
  433. package/node_modules/@noble/hashes/esm/blake1.js.map +1 -0
  434. package/node_modules/@noble/hashes/esm/blake2.d.ts +116 -0
  435. package/node_modules/@noble/hashes/esm/blake2.d.ts.map +1 -0
  436. package/node_modules/@noble/hashes/esm/blake2.js +413 -0
  437. package/node_modules/@noble/hashes/esm/blake2.js.map +1 -0
  438. package/node_modules/@noble/hashes/esm/blake2b.d.ts +11 -0
  439. package/node_modules/@noble/hashes/esm/blake2b.d.ts.map +1 -0
  440. package/node_modules/@noble/hashes/esm/blake2b.js +11 -0
  441. package/node_modules/@noble/hashes/esm/blake2b.js.map +1 -0
  442. package/node_modules/@noble/hashes/esm/blake2s.d.ts +20 -0
  443. package/node_modules/@noble/hashes/esm/blake2s.d.ts.map +1 -0
  444. package/node_modules/@noble/hashes/esm/blake2s.js +21 -0
  445. package/node_modules/@noble/hashes/esm/blake2s.js.map +1 -0
  446. package/node_modules/@noble/hashes/esm/blake3.d.ts +54 -0
  447. package/node_modules/@noble/hashes/esm/blake3.d.ts.map +1 -0
  448. package/node_modules/@noble/hashes/esm/blake3.js +251 -0
  449. package/node_modules/@noble/hashes/esm/blake3.js.map +1 -0
  450. package/node_modules/@noble/hashes/esm/crypto.d.ts +2 -0
  451. package/node_modules/@noble/hashes/esm/crypto.d.ts.map +1 -0
  452. package/node_modules/@noble/hashes/esm/crypto.js +2 -0
  453. package/node_modules/@noble/hashes/esm/crypto.js.map +1 -0
  454. package/node_modules/@noble/hashes/esm/cryptoNode.d.ts +2 -0
  455. package/node_modules/@noble/hashes/esm/cryptoNode.d.ts.map +1 -0
  456. package/node_modules/@noble/hashes/esm/cryptoNode.js +15 -0
  457. package/node_modules/@noble/hashes/esm/cryptoNode.js.map +1 -0
  458. package/node_modules/@noble/hashes/esm/eskdf.d.ts +47 -0
  459. package/node_modules/@noble/hashes/esm/eskdf.d.ts.map +1 -0
  460. package/node_modules/@noble/hashes/esm/eskdf.js +160 -0
  461. package/node_modules/@noble/hashes/esm/eskdf.js.map +1 -0
  462. package/node_modules/@noble/hashes/esm/hkdf.d.ts +36 -0
  463. package/node_modules/@noble/hashes/esm/hkdf.d.ts.map +1 -0
  464. package/node_modules/@noble/hashes/esm/hkdf.js +82 -0
  465. package/node_modules/@noble/hashes/esm/hkdf.js.map +1 -0
  466. package/node_modules/@noble/hashes/esm/hmac.d.ts +35 -0
  467. package/node_modules/@noble/hashes/esm/hmac.d.ts.map +1 -0
  468. package/node_modules/@noble/hashes/esm/hmac.js +86 -0
  469. package/node_modules/@noble/hashes/esm/hmac.js.map +1 -0
  470. package/node_modules/@noble/hashes/esm/index.d.ts +2 -0
  471. package/node_modules/@noble/hashes/esm/index.d.ts.map +1 -0
  472. package/node_modules/@noble/hashes/esm/index.js +33 -0
  473. package/node_modules/@noble/hashes/esm/index.js.map +1 -0
  474. package/node_modules/@noble/hashes/esm/legacy.d.ts +71 -0
  475. package/node_modules/@noble/hashes/esm/legacy.d.ts.map +1 -0
  476. package/node_modules/@noble/hashes/esm/legacy.js +281 -0
  477. package/node_modules/@noble/hashes/esm/legacy.js.map +1 -0
  478. package/node_modules/@noble/hashes/esm/package.json +10 -0
  479. package/node_modules/@noble/hashes/esm/pbkdf2.d.ts +23 -0
  480. package/node_modules/@noble/hashes/esm/pbkdf2.d.ts.map +1 -0
  481. package/node_modules/@noble/hashes/esm/pbkdf2.js +97 -0
  482. package/node_modules/@noble/hashes/esm/pbkdf2.js.map +1 -0
  483. package/node_modules/@noble/hashes/esm/ripemd160.d.ts +13 -0
  484. package/node_modules/@noble/hashes/esm/ripemd160.d.ts.map +1 -0
  485. package/node_modules/@noble/hashes/esm/ripemd160.js +13 -0
  486. package/node_modules/@noble/hashes/esm/ripemd160.js.map +1 -0
  487. package/node_modules/@noble/hashes/esm/scrypt.d.ts +34 -0
  488. package/node_modules/@noble/hashes/esm/scrypt.d.ts.map +1 -0
  489. package/node_modules/@noble/hashes/esm/scrypt.js +228 -0
  490. package/node_modules/@noble/hashes/esm/scrypt.js.map +1 -0
  491. package/node_modules/@noble/hashes/esm/sha1.d.ts +11 -0
  492. package/node_modules/@noble/hashes/esm/sha1.d.ts.map +1 -0
  493. package/node_modules/@noble/hashes/esm/sha1.js +11 -0
  494. package/node_modules/@noble/hashes/esm/sha1.js.map +1 -0
  495. package/node_modules/@noble/hashes/esm/sha2.d.ts +159 -0
  496. package/node_modules/@noble/hashes/esm/sha2.d.ts.map +1 -0
  497. package/node_modules/@noble/hashes/esm/sha2.js +375 -0
  498. package/node_modules/@noble/hashes/esm/sha2.js.map +1 -0
  499. package/node_modules/@noble/hashes/esm/sha256.d.ts +20 -0
  500. package/node_modules/@noble/hashes/esm/sha256.d.ts.map +1 -0
  501. package/node_modules/@noble/hashes/esm/sha256.js +20 -0
  502. package/node_modules/@noble/hashes/esm/sha256.js.map +1 -0
  503. package/node_modules/@noble/hashes/esm/sha3-addons.d.ts +142 -0
  504. package/node_modules/@noble/hashes/esm/sha3-addons.d.ts.map +1 -0
  505. package/node_modules/@noble/hashes/esm/sha3-addons.js +393 -0
  506. package/node_modules/@noble/hashes/esm/sha3-addons.js.map +1 -0
  507. package/node_modules/@noble/hashes/esm/sha3.d.ts +53 -0
  508. package/node_modules/@noble/hashes/esm/sha3.d.ts.map +1 -0
  509. package/node_modules/@noble/hashes/esm/sha3.js +234 -0
  510. package/node_modules/@noble/hashes/esm/sha3.js.map +1 -0
  511. package/node_modules/@noble/hashes/esm/sha512.d.ts +26 -0
  512. package/node_modules/@noble/hashes/esm/sha512.d.ts.map +1 -0
  513. package/node_modules/@noble/hashes/esm/sha512.js +26 -0
  514. package/node_modules/@noble/hashes/esm/sha512.js.map +1 -0
  515. package/node_modules/@noble/hashes/esm/utils.d.ts +161 -0
  516. package/node_modules/@noble/hashes/esm/utils.d.ts.map +1 -0
  517. package/node_modules/@noble/hashes/esm/utils.js +281 -0
  518. package/node_modules/@noble/hashes/esm/utils.js.map +1 -0
  519. package/node_modules/@noble/hashes/hkdf.d.ts +36 -0
  520. package/node_modules/@noble/hashes/hkdf.d.ts.map +1 -0
  521. package/node_modules/@noble/hashes/hkdf.js +88 -0
  522. package/node_modules/@noble/hashes/hkdf.js.map +1 -0
  523. package/node_modules/@noble/hashes/hmac.d.ts +35 -0
  524. package/node_modules/@noble/hashes/hmac.d.ts.map +1 -0
  525. package/node_modules/@noble/hashes/hmac.js +91 -0
  526. package/node_modules/@noble/hashes/hmac.js.map +1 -0
  527. package/node_modules/@noble/hashes/index.d.ts +1 -0
  528. package/node_modules/@noble/hashes/index.d.ts.map +1 -0
  529. package/node_modules/@noble/hashes/index.js +33 -0
  530. package/node_modules/@noble/hashes/index.js.map +1 -0
  531. package/node_modules/@noble/hashes/legacy.d.ts +71 -0
  532. package/node_modules/@noble/hashes/legacy.d.ts.map +1 -0
  533. package/node_modules/@noble/hashes/legacy.js +287 -0
  534. package/node_modules/@noble/hashes/legacy.js.map +1 -0
  535. package/node_modules/@noble/hashes/package.json +266 -0
  536. package/node_modules/@noble/hashes/pbkdf2.d.ts +23 -0
  537. package/node_modules/@noble/hashes/pbkdf2.d.ts.map +1 -0
  538. package/node_modules/@noble/hashes/pbkdf2.js +101 -0
  539. package/node_modules/@noble/hashes/pbkdf2.js.map +1 -0
  540. package/node_modules/@noble/hashes/ripemd160.d.ts +13 -0
  541. package/node_modules/@noble/hashes/ripemd160.d.ts.map +1 -0
  542. package/node_modules/@noble/hashes/ripemd160.js +16 -0
  543. package/node_modules/@noble/hashes/ripemd160.js.map +1 -0
  544. package/node_modules/@noble/hashes/scrypt.d.ts +34 -0
  545. package/node_modules/@noble/hashes/scrypt.d.ts.map +1 -0
  546. package/node_modules/@noble/hashes/scrypt.js +232 -0
  547. package/node_modules/@noble/hashes/scrypt.js.map +1 -0
  548. package/node_modules/@noble/hashes/sha1.d.ts +11 -0
  549. package/node_modules/@noble/hashes/sha1.d.ts.map +1 -0
  550. package/node_modules/@noble/hashes/sha1.js +14 -0
  551. package/node_modules/@noble/hashes/sha1.js.map +1 -0
  552. package/node_modules/@noble/hashes/sha2.d.ts +159 -0
  553. package/node_modules/@noble/hashes/sha2.d.ts.map +1 -0
  554. package/node_modules/@noble/hashes/sha2.js +384 -0
  555. package/node_modules/@noble/hashes/sha2.js.map +1 -0
  556. package/node_modules/@noble/hashes/sha256.d.ts +20 -0
  557. package/node_modules/@noble/hashes/sha256.d.ts.map +1 -0
  558. package/node_modules/@noble/hashes/sha256.js +23 -0
  559. package/node_modules/@noble/hashes/sha256.js.map +1 -0
  560. package/node_modules/@noble/hashes/sha3-addons.d.ts +142 -0
  561. package/node_modules/@noble/hashes/sha3-addons.d.ts.map +1 -0
  562. package/node_modules/@noble/hashes/sha3-addons.js +402 -0
  563. package/node_modules/@noble/hashes/sha3-addons.js.map +1 -0
  564. package/node_modules/@noble/hashes/sha3.d.ts +53 -0
  565. package/node_modules/@noble/hashes/sha3.d.ts.map +1 -0
  566. package/node_modules/@noble/hashes/sha3.js +239 -0
  567. package/node_modules/@noble/hashes/sha3.js.map +1 -0
  568. package/node_modules/@noble/hashes/sha512.d.ts +26 -0
  569. package/node_modules/@noble/hashes/sha512.d.ts.map +1 -0
  570. package/node_modules/@noble/hashes/sha512.js +29 -0
  571. package/node_modules/@noble/hashes/sha512.js.map +1 -0
  572. package/node_modules/@noble/hashes/src/_assert.ts +22 -0
  573. package/node_modules/@noble/hashes/src/_blake.ts +50 -0
  574. package/node_modules/@noble/hashes/src/_md.ts +176 -0
  575. package/node_modules/@noble/hashes/src/_u64.ts +91 -0
  576. package/node_modules/@noble/hashes/src/argon2.ts +497 -0
  577. package/node_modules/@noble/hashes/src/blake1.ts +534 -0
  578. package/node_modules/@noble/hashes/src/blake2.ts +486 -0
  579. package/node_modules/@noble/hashes/src/blake2b.ts +10 -0
  580. package/node_modules/@noble/hashes/src/blake2s.ts +20 -0
  581. package/node_modules/@noble/hashes/src/blake3.ts +272 -0
  582. package/node_modules/@noble/hashes/src/crypto.ts +9 -0
  583. package/node_modules/@noble/hashes/src/cryptoNode.ts +15 -0
  584. package/node_modules/@noble/hashes/src/eskdf.ts +187 -0
  585. package/node_modules/@noble/hashes/src/hkdf.ts +88 -0
  586. package/node_modules/@noble/hashes/src/hmac.ts +94 -0
  587. package/node_modules/@noble/hashes/src/index.ts +31 -0
  588. package/node_modules/@noble/hashes/src/legacy.ts +293 -0
  589. package/node_modules/@noble/hashes/src/pbkdf2.ts +122 -0
  590. package/node_modules/@noble/hashes/src/ripemd160.ts +12 -0
  591. package/node_modules/@noble/hashes/src/scrypt.ts +257 -0
  592. package/node_modules/@noble/hashes/src/sha1.ts +10 -0
  593. package/node_modules/@noble/hashes/src/sha2.ts +402 -0
  594. package/node_modules/@noble/hashes/src/sha256.ts +24 -0
  595. package/node_modules/@noble/hashes/src/sha3-addons.ts +499 -0
  596. package/node_modules/@noble/hashes/src/sha3.ts +258 -0
  597. package/node_modules/@noble/hashes/src/sha512.ts +34 -0
  598. package/node_modules/@noble/hashes/src/utils.ts +395 -0
  599. package/node_modules/@noble/hashes/utils.d.ts +161 -0
  600. package/node_modules/@noble/hashes/utils.d.ts.map +1 -0
  601. package/node_modules/@noble/hashes/utils.js +313 -0
  602. package/node_modules/@noble/hashes/utils.js.map +1 -0
  603. package/package.json +203 -0
  604. package/schemas/catalog.schema.json +283 -0
  605. package/src/align.ts +235 -0
  606. package/src/audio-init-parser.ts +189 -0
  607. package/src/audio-ring-buffer.ts +120 -0
  608. package/src/authored-timing.ts +63 -0
  609. package/src/carp-catalog.ts +776 -0
  610. package/src/catalog-fec-params.ts +167 -0
  611. package/src/catalog-network-source.ts +49 -0
  612. package/src/catalog-validator.ts +34 -0
  613. package/src/cmaf-block-assembler.ts +1058 -0
  614. package/src/cmaf-group-batcher.ts +104 -0
  615. package/src/cmcd-producer.ts +329 -0
  616. package/src/codec-utils.ts +1539 -0
  617. package/src/fec-codec.ts +61 -0
  618. package/src/fec-manager.ts +1939 -0
  619. package/src/fec-starvation-detector.ts +128 -0
  620. package/src/fec-worker-setup.ts +177 -0
  621. package/src/fmp4-completion.ts +47 -0
  622. package/src/fmp4-reader.ts +112 -0
  623. package/src/index.ts +443 -0
  624. package/src/iso-bmff-timing.ts +688 -0
  625. package/src/loc.ts +181 -0
  626. package/src/manifest-auth-plan.ts +107 -0
  627. package/src/media-router.ts +1185 -0
  628. package/src/mfu-reassembler.ts +2842 -0
  629. package/src/mfu-reassembly-policy.ts +134 -0
  630. package/src/mmtp-container-parser.ts +1498 -0
  631. package/src/mmtp-decode-pipeline.ts +315 -0
  632. package/src/mmtp-router.ts +3027 -0
  633. package/src/mmtp-to-cmaf.ts +956 -0
  634. package/src/multicast-auth-catalog.ts +340 -0
  635. package/src/multicast-input.ts +439 -0
  636. package/src/multicast-manager.ts +1503 -0
  637. package/src/multicast-transport.ts +320 -0
  638. package/src/multicast-unwrap.ts +132 -0
  639. package/src/no-modules.ts +20 -0
  640. package/src/phase14-catalog-override.ts +336 -0
  641. package/src/repair-fetch.ts +217 -0
  642. package/src/sample-combiner.ts +846 -0
  643. package/src/signaling.ts +78 -0
  644. package/src/source-auth.ts +1 -0
  645. package/src/switching-set-alignment.ts +109 -0
  646. package/src/timestamp-codec.ts +265 -0
  647. package/src/track-pipeline-setup.ts +189 -0
  648. package/src/track-pipeline.ts +332 -0
  649. package/src/track-session.ts +778 -0
  650. package/src/transport-pool.ts +128 -0
  651. package/src/wasm-mfu-reassembler.ts +372 -0
  652. package/src/wasm-mmtp-container-parser.ts +23 -0
  653. package/test-vectors/align.json +199 -0
  654. package/test-vectors/catalog/README.md +25 -0
  655. package/test-vectors/catalog/negative/legacy-selection-params.json +15 -0
  656. package/test-vectors/catalog/negative/missing-mmtp-fields.json +12 -0
  657. package/test-vectors/catalog/negative/multicast-auth-padded-key.json +37 -0
  658. package/test-vectors/catalog/negative/multicast-auth-reused-track-format.json +53 -0
  659. package/test-vectors/catalog/negative/multicast-auth-trailing-pad-bits.json +37 -0
  660. package/test-vectors/catalog/negative/multicast-endpoint-missing-protocol-and-source.json +24 -0
  661. package/test-vectors/catalog/negative/network-source-object.json +25 -0
  662. package/test-vectors/catalog/negative/raptorq-unaligned-symbol.json +26 -0
  663. package/test-vectors/catalog/negative/repair-track-legacy-shape.json +18 -0
  664. package/test-vectors/catalog/negative/track-role-empty.json +16 -0
  665. package/test-vectors/catalog/negative/track-role-non-string.json +16 -0
  666. package/test-vectors/catalog/positive/fec-multicast.json +51 -0
  667. package/test-vectors/catalog/positive/flat-av.json +30 -0
  668. package/test-vectors/catalog/positive/multicast-auth-rotation.json +55 -0
  669. package/test-vectors/catalog/positive/ticks-and-mixed-timescales.json +39 -0
  670. package/test-vectors/catalog/positive/track-role.json +49 -0
  671. package/test-vectors/catalog/releases/moqcast-native-v16-v1/catalog.json +65 -0
  672. package/test-vectors/catalog/releases/moqcast-native-v16-v1.archive.sha256 +1 -0
  673. package/test-vectors/catalog-multicast-auth-v1.json +26 -0
  674. package/test-vectors/catalog-validation.json +148 -0
  675. package/test-vectors/catalog-validator-public-api.mjs +25 -0
  676. package/test-vectors/generate-source-auth-fixture.mjs +114 -0
  677. package/test-vectors/source-auth-v1.json +61 -0
  678. package/test-vectors/subsample-placement-v1.json +230 -0
@@ -0,0 +1,778 @@
1
+ /**
2
+ * TrackSession — per-track transport state machine.
3
+ * SessionManager — orchestrates all sessions + TransportPool.
4
+ *
5
+ * Implements Patent Claim 9 (draft-ramadan-moq-fec APPLICATION-1):
6
+ * (a) subscribe unicast
7
+ * (b) simultaneously join multicast
8
+ * (c) render from unicast during join
9
+ * (d) activate multicast on RAP, suppress unicast
10
+ * (e) cross-transport FEC repair during transition
11
+ * (f) hysteresis before switching away from multicast
12
+ * (g) re-subscribe unicast on sustained failure
13
+ *
14
+ * PIM: manages transport state without inspecting packet contents.
15
+ */
16
+
17
+ import {
18
+ TransportPool,
19
+ type Subscription,
20
+ type SubscriptionMode,
21
+ type AcquireOptions,
22
+ type DirectSocketHealth,
23
+ type TransportPoolOptions,
24
+ } from './transport-pool.js'
25
+ import { deriveFecInterleaveDepth } from '@blockcast/mmt-fec'
26
+
27
+ // ---------------------------------------------------------------------------
28
+ // Types
29
+ // ---------------------------------------------------------------------------
30
+
31
+ export type TrackState =
32
+ | 'idle'
33
+ | 'unicast'
34
+ | 'unicast-fallback'
35
+ | 'joining'
36
+ | 'multicast'
37
+ | 'amt'
38
+ | 'failing'
39
+
40
+ export interface TrackSessionConfig {
41
+ trackName: string
42
+ trackType: 'video' | 'audio'
43
+ packetId: number
44
+ /** FEC interleave depth from catalog (ms). Used for hysteresis timer. */
45
+ fecInterleaveMs: number
46
+ /** FEC K from catalog. Used for audio worklet latency calculation. */
47
+ fecK: number
48
+ /** FEC repair symbols per block (P). NOT symbol size. */
49
+ fecRepairCount: number
50
+ /** FEC symbol size in bytes (T). Required for WASM decoder OTI. */
51
+ fecSymbolSize: number
52
+ /** MoQ repair track name from catalog FEC config. */
53
+ repairTrackName?: string
54
+ /** Frame samples from initData parsing (audio-init-parser.ts). */
55
+ frameSamples?: number
56
+ /** Audio sample rate from catalog. */
57
+ sampleRate?: number
58
+ /** Ordered transport preference: best first. */
59
+ preferredTransports: SubscriptionMode[]
60
+ /** Subscription key for multicast/AMT: "(S,G,port)". */
61
+ multicastKey?: string
62
+ /** MoQ track name for unicast subscription. */
63
+ moqTrackName?: string
64
+ /** AMT relay address (if AMT is in preference chain). */
65
+ amtRelay?: string
66
+ /** MoQ relay URL (for WebTransport subscription). */
67
+ moqRelayUrl?: string
68
+ }
69
+
70
+ // ---------------------------------------------------------------------------
71
+ // PIM callbacks (protocol-independent — transport state only)
72
+ // ---------------------------------------------------------------------------
73
+
74
+ export interface SessionManagerCallbacks {
75
+ /** Fired on every transport state transition. */
76
+ onStateChange?(trackName: string, from: TrackState, to: TrackState): void
77
+ /** Fired to suppress/unsuppress unicast for this track (transport arbitration). */
78
+ onSuppress?(trackName: string, suppressed: boolean): void
79
+ /**
80
+ * Fired when a track sat in `joining` for SessionManager.takeoverDeadlineMs
81
+ * without a RAP (BLO-9413/D9). The session has already returned to `unicast`
82
+ * (nothing was suppressed, so nothing to restore) — the host should abandon
83
+ * the multicast attempt (e.g. MediaRouter.failbackToMoq()) so the router
84
+ * stops waiting for a keyframe that is never coming.
85
+ */
86
+ onTakeoverTimeout?(trackName: string): void
87
+ }
88
+
89
+ // ---------------------------------------------------------------------------
90
+ // MMTP application-layer extension (FEC lifecycle, media resets)
91
+ // ---------------------------------------------------------------------------
92
+
93
+ /**
94
+ * MMTP track events (discriminated union).
95
+ * Each protocol layer defines its own event union — MMTP events cover
96
+ * media resets, latency, and FEC lifecycle.
97
+ */
98
+ export type MmtpTrackEvent =
99
+ | { type: 'reset' }
100
+ | { type: 'latency'; latencyMs: number }
101
+ | { type: 'fec-setup' }
102
+ | { type: 'fec-teardown' }
103
+
104
+ /**
105
+ * MMTP application-layer extension of SessionManagerCallbacks.
106
+ * Single onTrackEvent dispatches all MMTP-specific events.
107
+ * PIM consumers use the base SessionManagerCallbacks (no onTrackEvent).
108
+ *
109
+ * IWA can define its own subinterface with its own TrackEvent union
110
+ * (e.g., IwaTrackEvent for socket health, AMT state) using the same pattern.
111
+ */
112
+ export interface MmtpSessionCallbacks extends SessionManagerCallbacks {
113
+ onTrackEvent?(trackName: string, event: MmtpTrackEvent, config: TrackSessionConfig): void
114
+ }
115
+
116
+ /**
117
+ * Loss-hysteresis window covering the signaled interleave window plus jitter.
118
+ *
119
+ * This path lacks media cadence, so it intentionally does not estimate a full
120
+ * source-plus-repair production horizon. FECManager uses
121
+ * computeFecDeliveryWindowMs with media cadence when configuring block
122
+ * inactivity deadlines.
123
+ *
124
+ * `fecK` no longer feeds the math; it is still validated as a catalog
125
+ * well-formedness guard and kept in the signature for positional API compat
126
+ * (removal is a follow-up with the next cross-repo pin bump).
127
+ */
128
+ export function computeFecLossWindowMs(fecInterleaveMs: number, fecK: number, jitterBufferMs?: number): number {
129
+ return computeFecDeliveryWindowMs({
130
+ interleaveDepthMs: fecInterleaveMs,
131
+ sourceSymbols: fecK,
132
+ jitterBufferMs,
133
+ })
134
+ }
135
+
136
+ export interface FecDeliveryWindowConfig {
137
+ interleaveDepthMs: number
138
+ sourceSymbols: number
139
+ repairSymbols?: number
140
+ symbolSize?: number
141
+ mediaUnitsPerSecond?: number
142
+ bandwidthBps?: number
143
+ /**
144
+ * Jitter + one-way-delay + reorder budget in ms (draft-ramadan-moq-fec §9),
145
+ * sourced from the catalog `jitterBufferMs`. Added on top of the max-of-spans
146
+ * core; it is NOT a multiplier. See the margin-policy note in the function.
147
+ */
148
+ jitterBufferMs?: number
149
+ }
150
+
151
+ /**
152
+ * Catalog-derived silence window that covers interleave geometry plus the time
153
+ * required to produce or serialize a complete source+repair block. The catalog
154
+ * field remains D media units; this function does not feed mapper geometry.
155
+ */
156
+ export function computeFecDeliveryWindowMs(
157
+ config: FecDeliveryWindowConfig,
158
+ ): number {
159
+ const fecInterleaveMs = config.interleaveDepthMs
160
+ const fecK = config.sourceSymbols
161
+ if (fecInterleaveMs <= 0) {
162
+ throw new Error(
163
+ `[TrackSession] fecInterleaveMs=${fecInterleaveMs}. ` +
164
+ `Derive a positive FEC interleave window from the stream catalog.`
165
+ )
166
+ }
167
+ if (fecK <= 0) {
168
+ throw new Error(
169
+ `[TrackSession] fecK=${fecK}. ` +
170
+ `Derive a positive FEC source-symbol count from the stream catalog.`
171
+ )
172
+ }
173
+
174
+ const spansMs = [fecInterleaveMs]
175
+ if (config.mediaUnitsPerSecond && config.mediaUnitsPerSecond > 0) {
176
+ const mediaUnitMs = 1000 / config.mediaUnitsPerSecond
177
+ // interleaveDepthMs is integer catalog signaling while media-unit duration
178
+ // is often fractional (for example 4/30s = 133.33ms). Recover D using the
179
+ // producer's nearest-ms quantization, then cover every source and repair
180
+ // round-robin cycle. A decoder cannot recover a partial MFU until the
181
+ // repair tail arrives, so a K-only deadline expires the source fragments
182
+ // before the final repair symbols that complete them.
183
+ const interleaveUnits = deriveFecInterleaveDepth(fecInterleaveMs, mediaUnitMs)
184
+ const deliverySymbols = fecK + Math.max(0, config.repairSymbols ?? 0)
185
+ spansMs.push(deliverySymbols * interleaveUnits * mediaUnitMs)
186
+ }
187
+ if (
188
+ config.symbolSize &&
189
+ config.symbolSize > 0 &&
190
+ config.bandwidthBps &&
191
+ config.bandwidthBps > 0
192
+ ) {
193
+ const repairSymbols = Math.max(0, config.repairSymbols ?? 0)
194
+ spansMs.push(
195
+ ((fecK + repairSymbols) * config.symbolSize * 8 * 1000) /
196
+ config.bandwidthBps,
197
+ )
198
+ }
199
+
200
+ // draft-ramadan-moq-fec §9: the recovery timeout is a DERIVED budget —
201
+ // max(interleave span, source+repair production horizon, block serialization) PLUS
202
+ // an ADDITIVE margin for jitter + one-way delay + reorder. It MUST NOT be a
203
+ // fixed multiple of the interleave span (this replaces the retired `* 3` /
204
+ // `* 2` safety factors). The margin is the catalog `jitterBufferMs`.
205
+ //
206
+ // MARGIN-POLICY (operator sign-off — see PR): no catalog currently emits
207
+ // `jitterBufferMs`. Rather than throw (which would break every existing
208
+ // catalog) or invent a magic constant, the default margin is the un-rounded
209
+ // interleave window — the spec's natural reorder-budget bound and already a
210
+ // catalog value. Emit `jitterBufferMs` in the catalog to set it explicitly.
211
+ const coreMs = Math.max(...spansMs)
212
+ const marginMs =
213
+ config.jitterBufferMs !== undefined && config.jitterBufferMs >= 0
214
+ ? config.jitterBufferMs
215
+ : fecInterleaveMs
216
+ return Math.ceil(coreMs) + Math.ceil(marginMs)
217
+ }
218
+
219
+ /** Convert the shared FEC delivery deadline into an integer media timescale. */
220
+ export function computeFecDeliveryWindowMediaUnits(
221
+ config: FecDeliveryWindowConfig,
222
+ timestampTimescale: number,
223
+ ): number {
224
+ if (!Number.isFinite(timestampTimescale) || timestampTimescale <= 0) {
225
+ throw new Error(
226
+ `[TrackSession] timestampTimescale=${timestampTimescale}. ` +
227
+ 'Derive a positive media timescale from the container.',
228
+ )
229
+ }
230
+ const deliveryWindow = Math.ceil(
231
+ computeFecDeliveryWindowMs(config) * timestampTimescale / 1000,
232
+ )
233
+ if (!Number.isSafeInteger(deliveryWindow)) {
234
+ throw new Error('[TrackSession] FEC delivery window exceeds the media timestamp range.')
235
+ }
236
+ return deliveryWindow
237
+ }
238
+
239
+ // ---------------------------------------------------------------------------
240
+ // TrackSession
241
+ // ---------------------------------------------------------------------------
242
+
243
+ export class TrackSession {
244
+ readonly config: TrackSessionConfig
245
+ #state: TrackState = 'idle'
246
+ #subscription: Subscription | null = null
247
+ #hysteresisTimer: ReturnType<typeof setTimeout> | null = null
248
+ #joinDeadlineTimer: ReturnType<typeof setTimeout> | null = null
249
+ #previousPrimary: SubscriptionMode | null = null
250
+ #manager: SessionManager
251
+ // Single suppression authority flag (BLO-9413 failback coherence): every
252
+ // suppress this session fires is recorded here, and every path that leaves
253
+ // a suppressed state unwinds through #unsuppress(). Before this flag,
254
+ // unsubscribe() only un-suppressed from multicast/amt — a session torn down
255
+ // from `failing` (exactly where a starving track sits) was re-subscribed to
256
+ // unicast with the host's media still muted: MoQ playing into a dead sink.
257
+ #suppressFired = false
258
+
259
+ constructor(config: TrackSessionConfig, manager: SessionManager) {
260
+ this.config = config
261
+ this.#manager = manager
262
+ }
263
+
264
+ // -----------------------------------------------------------------------
265
+ // State
266
+ // -----------------------------------------------------------------------
267
+
268
+ get state(): TrackState { return this.#state }
269
+ get subscription(): Subscription | null { return this.#subscription }
270
+
271
+ /** True while this session's onSuppress(true) is outstanding (no matching
272
+ * onSuppress(false) yet). Test/assertion surface for failback coherence. */
273
+ get isSuppressed(): boolean { return this.#suppressFired }
274
+
275
+ /** Current active transport mode, or null if idle. */
276
+ get transport(): SubscriptionMode | null {
277
+ switch (this.#state) {
278
+ case 'multicast': return 'multicast'
279
+ case 'amt': return 'amt'
280
+ case 'unicast': return 'moq'
281
+ case 'unicast-fallback': return 'moq' // SSM bridge absent — MoQ unicast is the only source
282
+ case 'joining': return 'moq' // MoQ still primary during join
283
+ case 'failing': return this.#previousPrimary
284
+ default: return null
285
+ }
286
+ }
287
+
288
+ // -----------------------------------------------------------------------
289
+ // Computed (no magic numbers)
290
+ // -----------------------------------------------------------------------
291
+
292
+ /** Audio worklet latency: max(fecInterleaveMs, frameDurationMs * fecK).
293
+ * Returns undefined if frame duration unknown (no initData). */
294
+ get audioLatencyMs(): number | undefined {
295
+ const fd = this.frameDurationMs
296
+ if (fd === undefined) {
297
+ return this.config.fecInterleaveMs > 0 ? this.config.fecInterleaveMs : undefined
298
+ }
299
+ return Math.max(this.config.fecInterleaveMs, fd * this.config.fecK)
300
+ }
301
+
302
+ /** Frame duration in ms, derived from frameSamples + sampleRate. */
303
+ get frameDurationMs(): number | undefined {
304
+ const { frameSamples, sampleRate } = this.config
305
+ if (!frameSamples || !sampleRate || sampleRate <= 0) return undefined
306
+ return (frameSamples / sampleRate) * 1000
307
+ }
308
+
309
+ // -----------------------------------------------------------------------
310
+ // Transitions (Patent Claim 9)
311
+ // -----------------------------------------------------------------------
312
+
313
+ /** idle → unicast: player subscribes to this track. */
314
+ subscribe(): void {
315
+ if (this.#state !== 'idle') return
316
+ this.#transition('unicast')
317
+
318
+ // Emit audio latency on first subscribe
319
+ if (this.config.trackType === 'audio') {
320
+ const latency = this.audioLatencyMs
321
+ if (latency !== undefined) {
322
+ this.#manager.mmtp?.onTrackEvent?.(this.config.trackName, { type: 'latency', latencyMs: latency }, this.config)
323
+ }
324
+ }
325
+ }
326
+
327
+ /** unicast → joining: multicast/AMT capability detected, join in progress. */
328
+ joinStarted(): void {
329
+ if (this.#state !== 'unicast') return
330
+ this.#transition('joining')
331
+ // FEC decoders must be ready before multicast data arrives (Claim 9e: cross-transport repair)
332
+ this.#manager.mmtp?.onTrackEvent?.(this.config.trackName, { type: 'fec-setup' }, this.config)
333
+ }
334
+
335
+ /**
336
+ * any non-fallback state → unicast-fallback. Used when the SSM bridge is
337
+ * absent (vanilla Chromium / no extension) and the host falls back to a
338
+ * MoQ unicast subscription per track. Terminal-ish: activateMulticast,
339
+ * failbackAll, and transportFailed are no-ops while in this state.
340
+ *
341
+ * Fires fec-setup so the per-track repair worker spins up — repair packets
342
+ * still flow over the MoQ repair-track subscription, so FEC source+repair
343
+ * can converge as in the multicast path.
344
+ *
345
+ * Audio latency is NOT re-emitted here: subscribe() already fires latency
346
+ * once on the idle → unicast edge, and enterUnicastFallback is only ever
347
+ * reached from a non-idle state (SessionManager skips idle sessions).
348
+ */
349
+ enterUnicastFallback(): void {
350
+ if (this.#state === 'unicast-fallback') return
351
+ this.#clearHysteresis()
352
+ this.#transition('unicast-fallback')
353
+ // Suppress the redundant unicast media decoder. On the no-bridge path the
354
+ // host feeds MoQ-unicast source packets into MulticastManager (the render
355
+ // consumer); a second base-media subscribe (the @moq/watch decoder) would
356
+ // split the single connection's QUIC flow-control budget and stall delivery
357
+ // (BLO-8969). Fire suppress here, on the fallback edge, so the decoder is
358
+ // gated off before it subscribes rather than after the relay forward task
359
+ // has already wedged.
360
+ this.#suppress()
361
+ this.#manager.mmtp?.onTrackEvent?.(this.config.trackName, { type: 'fec-setup' }, this.config)
362
+ }
363
+
364
+ /**
365
+ * unicast-fallback → unicast. Called when the SSM bridge appears mid-session
366
+ * (extension installed after fallback engaged). Host first aborts the fallback
367
+ * drainers, then transitions sessions back to unicast so the regular
368
+ * multicast/AMT preference chain can take over via joinStarted().
369
+ */
370
+ exitUnicastFallback(): void {
371
+ if (this.#state !== 'unicast-fallback') return
372
+ this.#transition('unicast')
373
+ // Un-suppress the unicast decoder: the bridge appeared mid-session, so the
374
+ // host tears down the fallback drainers and the regular preference chain
375
+ // (joinStarted -> joining -> rapReceived) will re-suppress on multicast RAP.
376
+ this.#unsuppress()
377
+ }
378
+
379
+ /**
380
+ * joining → multicast or amt: RAP received on the joined transport (Claim 9d).
381
+ * Resets audio worklet, then suppresses MoQ.
382
+ */
383
+ rapReceived(mode: 'multicast' | 'amt'): void {
384
+ if (this.#state !== 'joining') return
385
+ this.#previousPrimary = mode
386
+ this.#transition(mode)
387
+ if (this.config.trackType === 'audio') {
388
+ this.#manager.mmtp?.onTrackEvent?.(this.config.trackName, { type: 'reset' }, this.config)
389
+ }
390
+ this.#suppress()
391
+ }
392
+
393
+ /** multicast/amt → failing: loss detected, start hysteresis timer (Claim 9f). */
394
+ lossDetected(): void {
395
+ if (this.#state !== 'multicast' && this.#state !== 'amt') return
396
+ this.#previousPrimary = this.#state as SubscriptionMode
397
+ this.#transition('failing')
398
+
399
+ // Hysteresis timer: sustained loss before failback (Claim 9f). The window
400
+ // covers a complete FEC block plus safety margin: the catalog interleave
401
+ // value IS the block span (interleaveDepthMs, §5.1), scaled by the same
402
+ // safety factor FECManager uses for its block timeout.
403
+ const hysteresisMs = computeFecLossWindowMs(this.config.fecInterleaveMs, this.config.fecK)
404
+ this.#hysteresisTimer = setTimeout(() => {
405
+ this.hysteresisExpired()
406
+ }, hysteresisMs)
407
+ }
408
+
409
+ /** failing → previous primary: loss recovered within hysteresis window. */
410
+ lossRecovered(): void {
411
+ if (this.#state !== 'failing') return
412
+ this.#clearHysteresis()
413
+ if (this.#previousPrimary) {
414
+ this.#transition(this.#previousPrimary as TrackState)
415
+ }
416
+ }
417
+
418
+ /**
419
+ * Transport failed (AMT relay down, multicast interface gone).
420
+ * Try next transport in preference chain.
421
+ */
422
+ transportFailed(): void {
423
+ this.#clearHysteresis()
424
+ // Unicast-fallback is terminal — the host owns the subscription and
425
+ // SessionManager transport machinery does not arbitrate it.
426
+ if (this.#state === 'unicast-fallback') return
427
+ const current = this.#previousPrimary ?? this.transport
428
+ const prefs = this.config.preferredTransports
429
+ const currentIdx = current ? prefs.indexOf(current) : -1
430
+ const nextMode = prefs[currentIdx + 1]
431
+
432
+ if (nextMode) {
433
+ // Failover to next in chain
434
+ if (nextMode === 'moq') {
435
+ this.#transition('unicast')
436
+ this.#unsuppress()
437
+ if (this.config.trackType === 'audio') {
438
+ this.#manager.mmtp?.onTrackEvent?.(this.config.trackName, { type: 'reset' }, this.config)
439
+ }
440
+ } else {
441
+ // Next is multicast or AMT — start joining. `joining` means MoQ is
442
+ // primary again (see transport getter) — if the failed transport had
443
+ // suppressed unicast, restore it for the join window or the viewer
444
+ // watches black video until the next RAP (which may never come).
445
+ this.#transition('joining')
446
+ this.#unsuppress()
447
+ }
448
+ } else {
449
+ // End of chain — fall back to unicast (Claim 9g)
450
+ this.#transition('unicast')
451
+ this.#unsuppress()
452
+ if (this.config.trackType === 'audio') {
453
+ this.#manager.mmtp?.onTrackEvent?.(this.config.trackName, { type: 'reset' }, this.config)
454
+ }
455
+ }
456
+ }
457
+
458
+ /** Hysteresis expired → failback to next transport (Claim 9g). */
459
+ hysteresisExpired(): void {
460
+ if (this.#state !== 'failing') return
461
+ this.#clearHysteresis()
462
+ this.transportFailed()
463
+ }
464
+
465
+ /** → idle: player unsubscribes / tab close / cleanup. */
466
+ unsubscribe(): void {
467
+ this.#clearHysteresis()
468
+ if (this.#state !== 'idle') {
469
+ this.#transition('idle')
470
+ // Unwind any outstanding suppression regardless of which state we left.
471
+ // The old `wasActive` check (multicast/amt only) leaked suppression when
472
+ // tearing down from `failing` or `unicast-fallback` — failbackAll()'s
473
+ // unsubscribe→subscribe cycle then re-entered unicast with the host's
474
+ // media still muted (BLO-9413 freeze: "failing back" logged, video dead).
475
+ this.#unsuppress()
476
+ }
477
+ }
478
+
479
+ /** True when SessionManager.enterUnicastFallback put this track into the
480
+ * host-driven unicast subscription mode. Host can iterate sessions to
481
+ * decide whether to keep its fallback drainer alive across MediaRouter
482
+ * arbitration events. */
483
+ get isUnicastFallback(): boolean {
484
+ return this.#state === 'unicast-fallback'
485
+ }
486
+
487
+ dispose(): void {
488
+ this.#clearHysteresis()
489
+ this.#clearJoinDeadline()
490
+ this.#state = 'idle'
491
+ this.#subscription = null
492
+ }
493
+
494
+ // -----------------------------------------------------------------------
495
+ // Internal
496
+ // -----------------------------------------------------------------------
497
+
498
+ #transition(to: TrackState): void {
499
+ const from = this.#state
500
+ if (from === to) return
501
+ this.#state = to
502
+ // Takeover deadline (BLO-9413/D9): every entry into `joining` arms it
503
+ // (joinStarted AND transportFailed-failover both route through here);
504
+ // every exit cancels it. Without this, a transport that accepts the
505
+ // subscribe but never delivers a RAP parks the session in `joining`
506
+ // forever (observed live in the Phase-0 headless repro).
507
+ if (from === 'joining') this.#clearJoinDeadline()
508
+ if (to === 'joining') this.#armJoinDeadline()
509
+ // FEC teardown: leaving FEC-active states → non-FEC state
510
+ const fecActive = (s: TrackState) =>
511
+ s === 'joining' ||
512
+ s === 'multicast' ||
513
+ s === 'amt' ||
514
+ s === 'failing' ||
515
+ s === 'unicast-fallback'
516
+ if (fecActive(from) && !fecActive(to)) {
517
+ this.#manager.mmtp?.onTrackEvent?.(this.config.trackName, { type: 'fec-teardown' }, this.config)
518
+ }
519
+ this.#manager.callbacks?.onStateChange?.(this.config.trackName, from, to)
520
+ }
521
+
522
+ #clearHysteresis(): void {
523
+ if (this.#hysteresisTimer !== null) {
524
+ clearTimeout(this.#hysteresisTimer)
525
+ this.#hysteresisTimer = null
526
+ }
527
+ }
528
+
529
+ #armJoinDeadline(): void {
530
+ this.#clearJoinDeadline()
531
+ const deadlineMs = this.#manager.takeoverDeadlineMs
532
+ if (deadlineMs <= 0) return // disabled
533
+ this.#joinDeadlineTimer = setTimeout(() => {
534
+ this.#joinDeadlineTimer = null
535
+ if (this.#state !== 'joining') return
536
+ // No RAP within the deadline: return to unicast. MoQ was never
537
+ // suppressed in `joining`, so there is nothing to restore — this edge
538
+ // must stay silent on onSuppress (asserted in tests).
539
+ this.#transition('unicast')
540
+ this.#manager.callbacks?.onTakeoverTimeout?.(this.config.trackName)
541
+ }, deadlineMs)
542
+ }
543
+
544
+ #clearJoinDeadline(): void {
545
+ if (this.#joinDeadlineTimer !== null) {
546
+ clearTimeout(this.#joinDeadlineTimer)
547
+ this.#joinDeadlineTimer = null
548
+ }
549
+ }
550
+
551
+ /** Fire onSuppress(true) exactly once per suppression epoch. */
552
+ #suppress(): void {
553
+ if (this.#suppressFired) return
554
+ this.#suppressFired = true
555
+ this.#manager.callbacks?.onSuppress?.(this.config.trackName, true)
556
+ }
557
+
558
+ /** Unwind an outstanding suppression; no-op when none is outstanding. */
559
+ #unsuppress(): void {
560
+ if (!this.#suppressFired) return
561
+ this.#suppressFired = false
562
+ this.#manager.callbacks?.onSuppress?.(this.config.trackName, false)
563
+ }
564
+ }
565
+
566
+ // ---------------------------------------------------------------------------
567
+ // SessionManager
568
+ // ---------------------------------------------------------------------------
569
+
570
+ export class SessionManager {
571
+ readonly pool: TransportPool
572
+ readonly sessions = new Map<string, TrackSession>()
573
+ callbacks: SessionManagerCallbacks | null = null
574
+ /**
575
+ * Takeover deadline (BLO-9413/D9): max time a session may sit in `joining`
576
+ * without a RAP before returning to `unicast` and firing onTakeoverTimeout.
577
+ * MoQ is never suppressed during `joining`, so expiry is a silent abandon —
578
+ * playback never glitches. Hosts tune per stream (e.g. GOP length); 0
579
+ * disables.
580
+ */
581
+ takeoverDeadlineMs = 5000
582
+
583
+ /** Narrow to MMTP callbacks (onTrackEvent). Safe — optional chaining handles PIM-only consumers. */
584
+ get mmtp(): MmtpSessionCallbacks | null {
585
+ return this.callbacks as MmtpSessionCallbacks | null
586
+ }
587
+
588
+ constructor(poolOptions?: TransportPoolOptions) {
589
+ this.pool = new TransportPool(poolOptions)
590
+
591
+ // Wire pool failure → per-track failover
592
+ this.pool.onSubscriptionFailed(sub => {
593
+ for (const trackName of sub.consumers) {
594
+ const session = this.sessions.get(trackName)
595
+ if (session) session.transportFailed()
596
+ }
597
+ })
598
+ }
599
+
600
+ // -----------------------------------------------------------------------
601
+ // Track management
602
+ // -----------------------------------------------------------------------
603
+
604
+ /** Add a track session from catalog config. */
605
+ addTrack(config: TrackSessionConfig): TrackSession {
606
+ if (this.sessions.has(config.trackName)) {
607
+ throw new Error(`[SessionManager] Track "${config.trackName}" already exists`)
608
+ }
609
+ const session = new TrackSession(config, this)
610
+ this.sessions.set(config.trackName, session)
611
+ return session
612
+ }
613
+
614
+ /** Remove a track session. Releases subscription with grace period. */
615
+ removeTrack(trackName: string): void {
616
+ const session = this.sessions.get(trackName)
617
+ if (!session) return
618
+ session.unsubscribe()
619
+
620
+ // Release pool subscription
621
+ const subKey = session.config.multicastKey ?? session.config.moqTrackName
622
+ if (subKey) this.pool.releaseSubscription(subKey, trackName)
623
+
624
+ session.dispose()
625
+ this.sessions.delete(trackName)
626
+ }
627
+
628
+ // -----------------------------------------------------------------------
629
+ // Atomic multi-track operations
630
+ // -----------------------------------------------------------------------
631
+
632
+ /**
633
+ * All tracks with multicast RAP → multicast state (atomic).
634
+ * Called when MediaRouter fires onSourceSwitch('multicast').
635
+ * Prevents split-brain between video and audio.
636
+ *
637
+ * A takeover deadline can return a track from `joining` to `unicast` while
638
+ * the multicast socket keeps delivering packets. If a valid RAP arrives
639
+ * later, allow that late-RAP edge to suppress unicast and promote multicast.
640
+ */
641
+ activateMulticast(): void {
642
+ for (const [, session] of this.sessions) {
643
+ if (session.state === 'unicast') {
644
+ session.joinStarted()
645
+ }
646
+ if (session.state === 'joining') {
647
+ session.rapReceived('multicast')
648
+ }
649
+ }
650
+ }
651
+
652
+ /**
653
+ * All tracks with AMT RAP → amt state (atomic).
654
+ */
655
+ activateAmt(): void {
656
+ for (const [, session] of this.sessions) {
657
+ if (session.state === 'unicast') {
658
+ session.joinStarted()
659
+ }
660
+ if (session.state === 'joining') {
661
+ session.rapReceived('amt')
662
+ }
663
+ }
664
+ }
665
+
666
+ /**
667
+ * All tracks → unicast (failback, atomic).
668
+ * Called when MulticastManager fires onFailback().
669
+ * unicast-fallback sessions are skipped — the host owns those subscriptions
670
+ * and they must drain uninterrupted across transport-state events.
671
+ *
672
+ * Coherence invariant (BLO-9413): after this returns, every non-fallback
673
+ * session is `unicast` (or `idle`) AND unsuppressed — unsubscribe() unwinds
674
+ * any outstanding suppression regardless of the state it tears down from
675
+ * (`failing` included; see TrackSession.#suppressFired).
676
+ */
677
+ failbackAll(): void {
678
+ for (const [, session] of this.sessions) {
679
+ if (
680
+ session.state !== 'idle' &&
681
+ session.state !== 'unicast' &&
682
+ session.state !== 'unicast-fallback'
683
+ ) {
684
+ session.unsubscribe()
685
+ session.subscribe() // re-enter unicast
686
+ }
687
+ }
688
+ }
689
+
690
+ /**
691
+ * All tracks → unicast-fallback (atomic).
692
+ * Called by the host when the multicast gateway is absent and
693
+ * the player will subscribe to source tracks over MoQ unicast and feed
694
+ * packets via MulticastManager.feedUnicastSource() (or manager.router
695
+ * directly). Sessions in this state stay terminal until the host calls
696
+ * unsubscribe() / disposes the SessionManager.
697
+ */
698
+ enterUnicastFallback(): void {
699
+ for (const [, session] of this.sessions) {
700
+ if (session.state === 'idle') continue
701
+ session.enterUnicastFallback()
702
+ }
703
+ }
704
+
705
+ /**
706
+ * True if any session is currently in unicast-fallback. Hosts use this to
707
+ * gate `multicastTrack.close()` on failback events — closing the shared
708
+ * broadcast would kill the host's fallback drainers.
709
+ */
710
+ hasActiveFallback(): boolean {
711
+ for (const [, session] of this.sessions) {
712
+ if (session.isUnicastFallback) return true
713
+ }
714
+ return false
715
+ }
716
+
717
+ /**
718
+ * All fallback tracks → unicast (atomic).
719
+ * Called when the SSM bridge appears mid-session and the host has aborted
720
+ * the fallback drainers. The session re-enters the regular preference chain
721
+ * via joinStarted() (issued by the host immediately after).
722
+ */
723
+ exitUnicastFallback(): void {
724
+ for (const [, session] of this.sessions) {
725
+ if (session.isUnicastFallback) session.exitUnicastFallback()
726
+ }
727
+ }
728
+
729
+ // -----------------------------------------------------------------------
730
+ // Cleanup lifecycle
731
+ // -----------------------------------------------------------------------
732
+
733
+ /** Tab closed — release all subscriptions for this tab (grace period). */
734
+ tabClosed(tabId: string): void {
735
+ // All tracks owned by this tab → idle
736
+ for (const [trackName, session] of this.sessions) {
737
+ session.unsubscribe()
738
+ this.pool.releaseAllForConsumer(trackName)
739
+ }
740
+ }
741
+
742
+ /** Bridge WebTransport connection dropped — same as tab close. */
743
+ bridgeDisconnected(): void {
744
+ this.tabClosed('bridge')
745
+ }
746
+
747
+ /**
748
+ * Track selection changed (user or ABR).
749
+ * Old track released (grace period), new track subscribed.
750
+ */
751
+ trackSelectionChanged(oldTrackName: string, newConfig: TrackSessionConfig): void {
752
+ this.removeTrack(oldTrackName)
753
+ const session = this.addTrack(newConfig)
754
+ session.subscribe()
755
+ }
756
+
757
+ // -----------------------------------------------------------------------
758
+ // Query
759
+ // -----------------------------------------------------------------------
760
+
761
+ /** Get a track session by name. */
762
+ getTrack(trackName: string): TrackSession | undefined {
763
+ return this.sessions.get(trackName)
764
+ }
765
+
766
+ // -----------------------------------------------------------------------
767
+ // Cleanup
768
+ // -----------------------------------------------------------------------
769
+
770
+ dispose(): void {
771
+ for (const [, session] of this.sessions) {
772
+ session.dispose()
773
+ }
774
+ this.sessions.clear()
775
+ this.pool.dispose()
776
+ this.callbacks = null
777
+ }
778
+ }