@blockcast/mmt-container 0.1.0 → 0.3.0-main.ef68de90edb3

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 (799) hide show
  1. package/README.md +524 -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 +152 -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 +80 -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/block-policy.d.ts +314 -0
  22. package/dist/block-policy.d.ts.map +1 -0
  23. package/dist/block-policy.js +466 -0
  24. package/dist/block-policy.js.map +7 -0
  25. package/dist/browser-runtime.js +26549 -0
  26. package/dist/browser-runtime.js.map +7 -0
  27. package/dist/carp-catalog.d.ts +429 -0
  28. package/dist/carp-catalog.d.ts.map +1 -0
  29. package/dist/carp-catalog.js +985 -0
  30. package/dist/carp-catalog.js.map +7 -0
  31. package/dist/catalog-fec-params.d.ts +275 -0
  32. package/dist/catalog-fec-params.d.ts.map +1 -0
  33. package/dist/catalog-fec-params.js +702 -0
  34. package/dist/catalog-fec-params.js.map +7 -0
  35. package/dist/catalog-network-source.d.ts +42 -0
  36. package/dist/catalog-network-source.d.ts.map +1 -0
  37. package/dist/catalog-network-source.js +47 -0
  38. package/dist/catalog-network-source.js.map +7 -0
  39. package/dist/catalog-validator.d.ts +18 -0
  40. package/dist/catalog-validator.d.ts.map +1 -0
  41. package/dist/catalog-validator.js +7747 -0
  42. package/dist/catalog-validator.js.map +7 -0
  43. package/dist/cmaf-block-assembler.d.ts +285 -0
  44. package/dist/cmaf-block-assembler.d.ts.map +1 -0
  45. package/dist/cmaf-block-assembler.js +1966 -0
  46. package/dist/cmaf-block-assembler.js.map +7 -0
  47. package/dist/cmaf-group-batcher.d.ts +38 -0
  48. package/dist/cmaf-group-batcher.d.ts.map +1 -0
  49. package/dist/cmaf-group-batcher.js +176 -0
  50. package/dist/cmaf-group-batcher.js.map +7 -0
  51. package/dist/cmcd-producer.d.ts +104 -0
  52. package/dist/cmcd-producer.d.ts.map +1 -0
  53. package/dist/cmcd-producer.js +183 -0
  54. package/dist/cmcd-producer.js.map +7 -0
  55. package/dist/codec-utils.d.ts +384 -0
  56. package/dist/codec-utils.d.ts.map +1 -0
  57. package/dist/codec-utils.js +1546 -0
  58. package/dist/codec-utils.js.map +7 -0
  59. package/dist/conceal-timeline.d.ts +146 -0
  60. package/dist/conceal-timeline.d.ts.map +1 -0
  61. package/dist/conceal-timeline.js +137 -0
  62. package/dist/conceal-timeline.js.map +7 -0
  63. package/dist/delivery-gap.d.ts +75 -0
  64. package/dist/delivery-gap.d.ts.map +1 -0
  65. package/dist/delivery-gap.js +88 -0
  66. package/dist/delivery-gap.js.map +7 -0
  67. package/dist/duplicate-ledger.d.ts +197 -0
  68. package/dist/duplicate-ledger.d.ts.map +1 -0
  69. package/dist/duplicate-ledger.js +226 -0
  70. package/dist/duplicate-ledger.js.map +7 -0
  71. package/dist/fec-codec.d.ts +32 -0
  72. package/dist/fec-codec.d.ts.map +1 -0
  73. package/dist/fec-codec.js +47 -0
  74. package/dist/fec-codec.js.map +7 -0
  75. package/dist/fec-manager.d.ts +583 -0
  76. package/dist/fec-manager.d.ts.map +1 -0
  77. package/dist/fec-manager.js +3899 -0
  78. package/dist/fec-manager.js.map +7 -0
  79. package/dist/fec-starvation-detector.d.ts +59 -0
  80. package/dist/fec-starvation-detector.d.ts.map +1 -0
  81. package/dist/fec-starvation-detector.js +60 -0
  82. package/dist/fec-starvation-detector.js.map +7 -0
  83. package/dist/fec-state.d.ts +131 -0
  84. package/dist/fec-state.d.ts.map +1 -0
  85. package/dist/fec-state.js +87 -0
  86. package/dist/fec-state.js.map +7 -0
  87. package/dist/fec-worker-setup.d.ts +94 -0
  88. package/dist/fec-worker-setup.d.ts.map +1 -0
  89. package/dist/fec-worker-setup.js +673 -0
  90. package/dist/fec-worker-setup.js.map +7 -0
  91. package/dist/fmp4-completion.d.ts +30 -0
  92. package/dist/fmp4-completion.d.ts.map +1 -0
  93. package/dist/fmp4-completion.js +21 -0
  94. package/dist/fmp4-completion.js.map +7 -0
  95. package/dist/fmp4-reader.d.ts +37 -0
  96. package/dist/fmp4-reader.d.ts.map +1 -0
  97. package/dist/fmp4-reader.js +100 -0
  98. package/dist/fmp4-reader.js.map +7 -0
  99. package/dist/index.d.ts +44 -3
  100. package/dist/index.d.ts.map +1 -1
  101. package/dist/index.js +460 -14
  102. package/dist/index.js.map +7 -1
  103. package/dist/iso-block-locator.d.ts +118 -0
  104. package/dist/iso-block-locator.d.ts.map +1 -0
  105. package/dist/iso-block-locator.js +289 -0
  106. package/dist/iso-block-locator.js.map +7 -0
  107. package/dist/iso-bmff-timing.d.ts +78 -0
  108. package/dist/iso-bmff-timing.d.ts.map +1 -0
  109. package/dist/iso-bmff-timing.js +593 -0
  110. package/dist/iso-bmff-timing.js.map +7 -0
  111. package/dist/loc.d.ts +70 -75
  112. package/dist/loc.d.ts.map +1 -1
  113. package/dist/loc.js +106 -192
  114. package/dist/loc.js.map +7 -1
  115. package/dist/manifest-auth-plan.d.ts +30 -0
  116. package/dist/manifest-auth-plan.d.ts.map +1 -0
  117. package/dist/manifest-auth-plan.js +1266 -0
  118. package/dist/manifest-auth-plan.js.map +7 -0
  119. package/dist/media-router.d.ts +262 -0
  120. package/dist/media-router.d.ts.map +1 -0
  121. package/dist/media-router.js +584 -0
  122. package/dist/media-router.js.map +7 -0
  123. package/dist/mfu-reassembler.d.ts +313 -9
  124. package/dist/mfu-reassembler.d.ts.map +1 -1
  125. package/dist/mfu-reassembler.js +3051 -285
  126. package/dist/mfu-reassembler.js.map +7 -1
  127. package/dist/mfu-reassembly-policy.d.ts +24 -0
  128. package/dist/mfu-reassembly-policy.d.ts.map +1 -0
  129. package/dist/mfu-reassembly-policy.js +99 -0
  130. package/dist/mfu-reassembly-policy.js.map +7 -0
  131. package/dist/mmtp-container-parser.d.ts +568 -0
  132. package/dist/mmtp-container-parser.d.ts.map +1 -0
  133. package/dist/mmtp-container-parser.js +6580 -0
  134. package/dist/mmtp-container-parser.js.map +7 -0
  135. package/dist/mmtp-container-parser.no-modules.js +9616 -0
  136. package/dist/mmtp-container-parser.no-modules.js.map +7 -0
  137. package/dist/mmtp-decode-pipeline.d.ts +138 -0
  138. package/dist/mmtp-decode-pipeline.d.ts.map +1 -0
  139. package/dist/mmtp-decode-pipeline.js +6814 -0
  140. package/dist/mmtp-decode-pipeline.js.map +7 -0
  141. package/dist/mmtp-router.d.ts +679 -0
  142. package/dist/mmtp-router.d.ts.map +1 -0
  143. package/dist/mmtp-router.js +11278 -0
  144. package/dist/mmtp-router.js.map +7 -0
  145. package/dist/mmtp-to-cmaf.d.ts +187 -0
  146. package/dist/mmtp-to-cmaf.d.ts.map +1 -0
  147. package/dist/mmtp-to-cmaf.js +716 -0
  148. package/dist/mmtp-to-cmaf.js.map +7 -0
  149. package/dist/multicast-auth-catalog.d.ts +115 -0
  150. package/dist/multicast-auth-catalog.d.ts.map +1 -0
  151. package/dist/multicast-auth-catalog.js +202 -0
  152. package/dist/multicast-auth-catalog.js.map +7 -0
  153. package/dist/multicast-input.d.ts +141 -0
  154. package/dist/multicast-input.d.ts.map +1 -0
  155. package/dist/multicast-input.js +390 -0
  156. package/dist/multicast-input.js.map +7 -0
  157. package/dist/multicast-manager.d.ts +669 -0
  158. package/dist/multicast-manager.d.ts.map +1 -0
  159. package/dist/multicast-manager.js +19101 -0
  160. package/dist/multicast-manager.js.map +7 -0
  161. package/dist/multicast-transport.d.ts +271 -0
  162. package/dist/multicast-transport.d.ts.map +1 -0
  163. package/dist/multicast-transport.js +2264 -0
  164. package/dist/multicast-transport.js.map +7 -0
  165. package/dist/multicast-unwrap.d.ts +57 -0
  166. package/dist/multicast-unwrap.d.ts.map +1 -0
  167. package/dist/multicast-unwrap.js +418 -0
  168. package/dist/multicast-unwrap.js.map +7 -0
  169. package/dist/no-modules.d.ts +10 -0
  170. package/dist/no-modules.d.ts.map +1 -0
  171. package/dist/no-modules.js +9491 -0
  172. package/dist/no-modules.js.map +7 -0
  173. package/dist/phase14-catalog-override.d.ts +126 -0
  174. package/dist/phase14-catalog-override.d.ts.map +1 -0
  175. package/dist/phase14-catalog-override.js +155 -0
  176. package/dist/phase14-catalog-override.js.map +7 -0
  177. package/dist/repair-fetch.d.ts +270 -0
  178. package/dist/repair-fetch.d.ts.map +1 -0
  179. package/dist/repair-fetch.js +381 -0
  180. package/dist/repair-fetch.js.map +7 -0
  181. package/dist/repair-layers.d.ts +158 -0
  182. package/dist/repair-layers.d.ts.map +1 -0
  183. package/dist/repair-layers.js +344 -0
  184. package/dist/repair-layers.js.map +7 -0
  185. package/dist/sample-combiner.d.ts +212 -0
  186. package/dist/sample-combiner.d.ts.map +1 -0
  187. package/dist/sample-combiner.js +595 -0
  188. package/dist/sample-combiner.js.map +7 -0
  189. package/dist/signaling.d.ts +29 -0
  190. package/dist/signaling.d.ts.map +1 -0
  191. package/dist/signaling.js +572 -0
  192. package/dist/signaling.js.map +7 -0
  193. package/dist/source-auth.d.ts +2 -0
  194. package/dist/source-auth.d.ts.map +1 -0
  195. package/dist/source-auth.js +1209 -0
  196. package/dist/source-auth.js.map +7 -0
  197. package/dist/switching-set-alignment.d.ts +61 -0
  198. package/dist/switching-set-alignment.d.ts.map +1 -0
  199. package/dist/switching-set-alignment.js +70 -0
  200. package/dist/switching-set-alignment.js.map +7 -0
  201. package/dist/timestamp-codec.d.ts +34 -0
  202. package/dist/timestamp-codec.d.ts.map +1 -0
  203. package/dist/timestamp-codec.js +473 -0
  204. package/dist/timestamp-codec.js.map +7 -0
  205. package/dist/track-pipeline-setup.d.ts +83 -0
  206. package/dist/track-pipeline-setup.d.ts.map +1 -0
  207. package/dist/track-pipeline-setup.js +291 -0
  208. package/dist/track-pipeline-setup.js.map +7 -0
  209. package/dist/track-pipeline.d.ts +121 -0
  210. package/dist/track-pipeline.d.ts.map +1 -0
  211. package/dist/track-pipeline.js +209 -0
  212. package/dist/track-pipeline.js.map +7 -0
  213. package/dist/track-session.d.ts +414 -0
  214. package/dist/track-session.d.ts.map +1 -0
  215. package/dist/track-session.js +754 -0
  216. package/dist/track-session.js.map +7 -0
  217. package/dist/transport-pool.d.ts +69 -0
  218. package/dist/transport-pool.d.ts.map +1 -0
  219. package/dist/transport-pool.js +74 -0
  220. package/dist/transport-pool.js.map +7 -0
  221. package/dist/wasm-mfu-reassembler.d.ts +97 -0
  222. package/dist/wasm-mfu-reassembler.d.ts.map +1 -0
  223. package/dist/wasm-mfu-reassembler.js +2133 -0
  224. package/dist/wasm-mfu-reassembler.js.map +7 -0
  225. package/dist/wasm-mmtp-container-parser.d.ts +10 -0
  226. package/dist/wasm-mmtp-container-parser.d.ts.map +1 -0
  227. package/dist/wasm-mmtp-container-parser.js +6834 -0
  228. package/dist/wasm-mmtp-container-parser.js.map +7 -0
  229. package/node_modules/@blockcast/fec-worker/README.md +223 -0
  230. package/node_modules/@blockcast/fec-worker/dist/.build-stamp +0 -0
  231. package/node_modules/@blockcast/fec-worker/dist/block-order.d.ts +38 -0
  232. package/node_modules/@blockcast/fec-worker/dist/block-order.d.ts.map +1 -0
  233. package/node_modules/@blockcast/fec-worker/dist/block-order.js +78 -0
  234. package/node_modules/@blockcast/fec-worker/dist/block-order.js.map +1 -0
  235. package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.d.ts +93 -0
  236. package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.d.ts.map +1 -0
  237. package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.js +346 -0
  238. package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.js.map +1 -0
  239. package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.d.ts +380 -0
  240. package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.d.ts.map +1 -0
  241. package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.js +11 -0
  242. package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.js.map +1 -0
  243. package/node_modules/@blockcast/fec-worker/dist/fec-worker.d.ts +14 -0
  244. package/node_modules/@blockcast/fec-worker/dist/fec-worker.d.ts.map +1 -0
  245. package/node_modules/@blockcast/fec-worker/dist/fec-worker.js +859 -0
  246. package/node_modules/@blockcast/fec-worker/dist/fec-worker.js.map +7 -0
  247. package/node_modules/@blockcast/fec-worker/dist/index.d.ts +10 -0
  248. package/node_modules/@blockcast/fec-worker/dist/index.d.ts.map +1 -0
  249. package/node_modules/@blockcast/fec-worker/dist/index.js +8 -0
  250. package/node_modules/@blockcast/fec-worker/dist/index.js.map +1 -0
  251. package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.d.ts +20 -0
  252. package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.d.ts.map +1 -0
  253. package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.js +370 -0
  254. package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.js.map +7 -0
  255. package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.d.ts +104 -0
  256. package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.d.ts.map +1 -0
  257. package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.js +181 -0
  258. package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.js.map +1 -0
  259. package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.d.ts +194 -0
  260. package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.d.ts.map +1 -0
  261. package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.js +62 -0
  262. package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.js.map +1 -0
  263. package/node_modules/@blockcast/fec-worker/dist/transfer.d.ts +9 -0
  264. package/node_modules/@blockcast/fec-worker/dist/transfer.d.ts.map +1 -0
  265. package/node_modules/@blockcast/fec-worker/dist/transfer.js +13 -0
  266. package/node_modules/@blockcast/fec-worker/dist/transfer.js.map +1 -0
  267. package/node_modules/@blockcast/fec-worker/package.json +59 -0
  268. package/node_modules/@blockcast/fec-worker/src/block-order.ts +93 -0
  269. package/node_modules/@blockcast/fec-worker/src/fec-worker-client.ts +392 -0
  270. package/node_modules/@blockcast/fec-worker/src/fec-worker-types.ts +399 -0
  271. package/node_modules/@blockcast/fec-worker/src/fec-worker.ts +1502 -0
  272. package/node_modules/@blockcast/fec-worker/src/index.ts +35 -0
  273. package/node_modules/@blockcast/fec-worker/src/shred-fec-worker.ts +589 -0
  274. package/node_modules/@blockcast/fec-worker/src/shred-worker-client.ts +222 -0
  275. package/node_modules/@blockcast/fec-worker/src/shred-worker-types.ts +209 -0
  276. package/node_modules/@blockcast/fec-worker/src/transfer.ts +12 -0
  277. package/node_modules/@blockcast/mmt-alta-parse/README.md +181 -0
  278. package/node_modules/@blockcast/mmt-alta-parse/dist/.build-stamp +0 -0
  279. package/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts +57 -0
  280. package/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts.map +1 -0
  281. package/node_modules/@blockcast/mmt-alta-parse/dist/index.js +115 -0
  282. package/node_modules/@blockcast/mmt-alta-parse/dist/index.js.map +1 -0
  283. package/node_modules/@blockcast/mmt-alta-parse/package.json +50 -0
  284. package/node_modules/@blockcast/mmt-alta-parse/src/index.ts +136 -0
  285. package/node_modules/@blockcast/mmt-base/README.md +134 -0
  286. package/node_modules/@blockcast/mmt-base/dist/.build-stamp +0 -0
  287. package/node_modules/@blockcast/mmt-base/dist/fec-block-profile.d.ts +55 -0
  288. package/node_modules/@blockcast/mmt-base/dist/fec-block-profile.d.ts.map +1 -0
  289. package/node_modules/@blockcast/mmt-base/dist/fec-block-profile.js +128 -0
  290. package/node_modules/@blockcast/mmt-base/dist/fec-block-profile.js.map +1 -0
  291. package/node_modules/@blockcast/mmt-base/dist/index.d.ts +7 -0
  292. package/node_modules/@blockcast/mmt-base/dist/index.d.ts.map +1 -0
  293. package/node_modules/@blockcast/mmt-base/dist/index.js +7 -0
  294. package/node_modules/@blockcast/mmt-base/dist/index.js.map +1 -0
  295. package/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts +292 -0
  296. package/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts.map +1 -0
  297. package/node_modules/@blockcast/mmt-base/dist/mmtp.js +612 -0
  298. package/node_modules/@blockcast/mmt-base/dist/mmtp.js.map +1 -0
  299. package/node_modules/@blockcast/mmt-base/dist/net-constants.d.ts +18 -0
  300. package/node_modules/@blockcast/mmt-base/dist/net-constants.d.ts.map +1 -0
  301. package/node_modules/@blockcast/mmt-base/dist/net-constants.js +18 -0
  302. package/node_modules/@blockcast/mmt-base/dist/net-constants.js.map +1 -0
  303. package/node_modules/@blockcast/mmt-base/dist/ntp-short.d.ts +47 -0
  304. package/node_modules/@blockcast/mmt-base/dist/ntp-short.d.ts.map +1 -0
  305. package/node_modules/@blockcast/mmt-base/dist/ntp-short.js +54 -0
  306. package/node_modules/@blockcast/mmt-base/dist/ntp-short.js.map +1 -0
  307. package/node_modules/@blockcast/mmt-base/dist/serial-number.d.ts +57 -0
  308. package/node_modules/@blockcast/mmt-base/dist/serial-number.d.ts.map +1 -0
  309. package/node_modules/@blockcast/mmt-base/dist/serial-number.js +98 -0
  310. package/node_modules/@blockcast/mmt-base/dist/serial-number.js.map +1 -0
  311. package/node_modules/@blockcast/mmt-base/dist/signalling.d.ts +312 -0
  312. package/node_modules/@blockcast/mmt-base/dist/signalling.d.ts.map +1 -0
  313. package/node_modules/@blockcast/mmt-base/dist/signalling.js +637 -0
  314. package/node_modules/@blockcast/mmt-base/dist/signalling.js.map +1 -0
  315. package/node_modules/@blockcast/mmt-base/package.json +49 -0
  316. package/node_modules/@blockcast/mmt-base/src/fec-block-profile.ts +145 -0
  317. package/node_modules/@blockcast/mmt-base/src/index.ts +6 -0
  318. package/node_modules/@blockcast/mmt-base/src/mmtp.ts +892 -0
  319. package/node_modules/@blockcast/mmt-base/src/net-constants.ts +17 -0
  320. package/node_modules/@blockcast/mmt-base/src/ntp-short.ts +67 -0
  321. package/node_modules/@blockcast/mmt-base/src/serial-number.ts +107 -0
  322. package/node_modules/@blockcast/mmt-base/src/signalling.ts +862 -0
  323. package/node_modules/@blockcast/mmt-fec/README.md +271 -0
  324. package/node_modules/@blockcast/mmt-fec/dist/.build-stamp +0 -0
  325. package/node_modules/@blockcast/mmt-fec/dist/block-manager.d.ts +82 -0
  326. package/node_modules/@blockcast/mmt-fec/dist/block-manager.d.ts.map +1 -0
  327. package/node_modules/@blockcast/mmt-fec/dist/block-manager.js +296 -0
  328. package/node_modules/@blockcast/mmt-fec/dist/block-manager.js.map +1 -0
  329. package/node_modules/@blockcast/mmt-fec/dist/block-processor.d.ts +106 -0
  330. package/node_modules/@blockcast/mmt-fec/dist/block-processor.d.ts.map +1 -0
  331. package/node_modules/@blockcast/mmt-fec/dist/block-processor.js +288 -0
  332. package/node_modules/@blockcast/mmt-fec/dist/block-processor.js.map +1 -0
  333. package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.d.ts +46 -0
  334. package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.d.ts.map +1 -0
  335. package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.js +96 -0
  336. package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.js.map +1 -0
  337. package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.d.ts +33 -0
  338. package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.d.ts.map +1 -0
  339. package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.js +57 -0
  340. package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.js.map +1 -0
  341. package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.d.ts +205 -0
  342. package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.d.ts.map +1 -0
  343. package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.js +240 -0
  344. package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.js.map +1 -0
  345. package/node_modules/@blockcast/mmt-fec/dist/index.d.ts +28 -0
  346. package/node_modules/@blockcast/mmt-fec/dist/index.d.ts.map +1 -0
  347. package/node_modules/@blockcast/mmt-fec/dist/index.js +28 -0
  348. package/node_modules/@blockcast/mmt-fec/dist/index.js.map +1 -0
  349. package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.d.ts +20 -0
  350. package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.d.ts.map +1 -0
  351. package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.js +28 -0
  352. package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.js.map +1 -0
  353. package/node_modules/@blockcast/mmt-fec/dist/oti.d.ts +258 -0
  354. package/node_modules/@blockcast/mmt-fec/dist/oti.d.ts.map +1 -0
  355. package/node_modules/@blockcast/mmt-fec/dist/oti.js +382 -0
  356. package/node_modules/@blockcast/mmt-fec/dist/oti.js.map +1 -0
  357. package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.d.ts +41 -0
  358. package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.d.ts.map +1 -0
  359. package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.js +81 -0
  360. package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.js.map +1 -0
  361. package/node_modules/@blockcast/mmt-fec/dist/repair-group.d.ts +82 -0
  362. package/node_modules/@blockcast/mmt-fec/dist/repair-group.d.ts.map +1 -0
  363. package/node_modules/@blockcast/mmt-fec/dist/repair-group.js +170 -0
  364. package/node_modules/@blockcast/mmt-fec/dist/repair-group.js.map +1 -0
  365. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/README.md +181 -0
  366. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/.build-stamp +0 -0
  367. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts +57 -0
  368. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts.map +1 -0
  369. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.js +115 -0
  370. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.js.map +1 -0
  371. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/package.json +50 -0
  372. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/src/index.ts +136 -0
  373. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/README.md +134 -0
  374. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/.build-stamp +0 -0
  375. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/fec-block-profile.d.ts +55 -0
  376. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/fec-block-profile.d.ts.map +1 -0
  377. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/fec-block-profile.js +128 -0
  378. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/fec-block-profile.js.map +1 -0
  379. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.d.ts +7 -0
  380. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.d.ts.map +1 -0
  381. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.js +7 -0
  382. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.js.map +1 -0
  383. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts +292 -0
  384. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts.map +1 -0
  385. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.js +612 -0
  386. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.js.map +1 -0
  387. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/net-constants.d.ts +18 -0
  388. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/net-constants.d.ts.map +1 -0
  389. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/net-constants.js +18 -0
  390. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/net-constants.js.map +1 -0
  391. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/ntp-short.d.ts +47 -0
  392. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/ntp-short.d.ts.map +1 -0
  393. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/ntp-short.js +54 -0
  394. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/ntp-short.js.map +1 -0
  395. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/serial-number.d.ts +57 -0
  396. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/serial-number.d.ts.map +1 -0
  397. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/serial-number.js +98 -0
  398. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/serial-number.js.map +1 -0
  399. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/signalling.d.ts +312 -0
  400. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/signalling.d.ts.map +1 -0
  401. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/signalling.js +637 -0
  402. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/signalling.js.map +1 -0
  403. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/package.json +49 -0
  404. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/fec-block-profile.ts +145 -0
  405. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/index.ts +6 -0
  406. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/mmtp.ts +892 -0
  407. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/net-constants.ts +17 -0
  408. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/ntp-short.ts +67 -0
  409. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/serial-number.ts +107 -0
  410. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/signalling.ts +862 -0
  411. package/node_modules/@blockcast/mmt-fec/package.json +79 -0
  412. package/node_modules/@blockcast/mmt-fec/src/block-manager.ts +371 -0
  413. package/node_modules/@blockcast/mmt-fec/src/block-processor.ts +439 -0
  414. package/node_modules/@blockcast/mmt-fec/src/cmaf-recovery.ts +127 -0
  415. package/node_modules/@blockcast/mmt-fec/src/cmaf-symbols.ts +68 -0
  416. package/node_modules/@blockcast/mmt-fec/src/fec-block-mapper.ts +310 -0
  417. package/node_modules/@blockcast/mmt-fec/src/index.ts +94 -0
  418. package/node_modules/@blockcast/mmt-fec/src/loc-symbols.ts +34 -0
  419. package/node_modules/@blockcast/mmt-fec/src/oti.ts +463 -0
  420. package/node_modules/@blockcast/mmt-fec/src/reorder-buffer.ts +101 -0
  421. package/node_modules/@blockcast/mmt-fec/src/repair-group.ts +195 -0
  422. package/node_modules/@blockcast/mmt-manifest-verify/dist/.build-stamp +0 -0
  423. package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.d.ts +28 -0
  424. package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.d.ts.map +1 -0
  425. package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.js +128 -0
  426. package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.js.map +1 -0
  427. package/node_modules/@blockcast/mmt-manifest-verify/dist/index.d.ts +4 -0
  428. package/node_modules/@blockcast/mmt-manifest-verify/dist/index.d.ts.map +1 -0
  429. package/node_modules/@blockcast/mmt-manifest-verify/dist/index.js +4 -0
  430. package/node_modules/@blockcast/mmt-manifest-verify/dist/index.js.map +1 -0
  431. package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.d.ts +37 -0
  432. package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.d.ts.map +1 -0
  433. package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.js +179 -0
  434. package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.js.map +1 -0
  435. package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.d.ts +99 -0
  436. package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.d.ts.map +1 -0
  437. package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.js +492 -0
  438. package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.js.map +1 -0
  439. package/node_modules/@blockcast/mmt-manifest-verify/package.json +45 -0
  440. package/node_modules/@blockcast/mmt-manifest-verify/src/admission.ts +171 -0
  441. package/node_modules/@blockcast/mmt-manifest-verify/src/index.ts +3 -0
  442. package/node_modules/@blockcast/mmt-manifest-verify/src/source-auth.ts +230 -0
  443. package/node_modules/@blockcast/mmt-manifest-verify/src/verifier.ts +669 -0
  444. package/node_modules/@noble/hashes/LICENSE +21 -0
  445. package/node_modules/@noble/hashes/README.md +521 -0
  446. package/node_modules/@noble/hashes/_assert.d.ts +17 -0
  447. package/node_modules/@noble/hashes/_assert.d.ts.map +1 -0
  448. package/node_modules/@noble/hashes/_assert.js +18 -0
  449. package/node_modules/@noble/hashes/_assert.js.map +1 -0
  450. package/node_modules/@noble/hashes/_blake.d.ts +14 -0
  451. package/node_modules/@noble/hashes/_blake.d.ts.map +1 -0
  452. package/node_modules/@noble/hashes/_blake.js +50 -0
  453. package/node_modules/@noble/hashes/_blake.js.map +1 -0
  454. package/node_modules/@noble/hashes/_md.d.ts +51 -0
  455. package/node_modules/@noble/hashes/_md.d.ts.map +1 -0
  456. package/node_modules/@noble/hashes/_md.js +162 -0
  457. package/node_modules/@noble/hashes/_md.js.map +1 -0
  458. package/node_modules/@noble/hashes/_u64.d.ts +55 -0
  459. package/node_modules/@noble/hashes/_u64.d.ts.map +1 -0
  460. package/node_modules/@noble/hashes/_u64.js +90 -0
  461. package/node_modules/@noble/hashes/_u64.js.map +1 -0
  462. package/node_modules/@noble/hashes/argon2.d.ts +32 -0
  463. package/node_modules/@noble/hashes/argon2.d.ts.map +1 -0
  464. package/node_modules/@noble/hashes/argon2.js +401 -0
  465. package/node_modules/@noble/hashes/argon2.js.map +1 -0
  466. package/node_modules/@noble/hashes/blake1.d.ts +106 -0
  467. package/node_modules/@noble/hashes/blake1.d.ts.map +1 -0
  468. package/node_modules/@noble/hashes/blake1.js +459 -0
  469. package/node_modules/@noble/hashes/blake1.js.map +1 -0
  470. package/node_modules/@noble/hashes/blake2.d.ts +116 -0
  471. package/node_modules/@noble/hashes/blake2.d.ts.map +1 -0
  472. package/node_modules/@noble/hashes/blake2.js +420 -0
  473. package/node_modules/@noble/hashes/blake2.js.map +1 -0
  474. package/node_modules/@noble/hashes/blake2b.d.ts +11 -0
  475. package/node_modules/@noble/hashes/blake2b.d.ts.map +1 -0
  476. package/node_modules/@noble/hashes/blake2b.js +14 -0
  477. package/node_modules/@noble/hashes/blake2b.js.map +1 -0
  478. package/node_modules/@noble/hashes/blake2s.d.ts +20 -0
  479. package/node_modules/@noble/hashes/blake2s.d.ts.map +1 -0
  480. package/node_modules/@noble/hashes/blake2s.js +24 -0
  481. package/node_modules/@noble/hashes/blake2s.js.map +1 -0
  482. package/node_modules/@noble/hashes/blake3.d.ts +54 -0
  483. package/node_modules/@noble/hashes/blake3.d.ts.map +1 -0
  484. package/node_modules/@noble/hashes/blake3.js +255 -0
  485. package/node_modules/@noble/hashes/blake3.js.map +1 -0
  486. package/node_modules/@noble/hashes/crypto.d.ts +2 -0
  487. package/node_modules/@noble/hashes/crypto.d.ts.map +1 -0
  488. package/node_modules/@noble/hashes/crypto.js +5 -0
  489. package/node_modules/@noble/hashes/crypto.js.map +1 -0
  490. package/node_modules/@noble/hashes/cryptoNode.d.ts +2 -0
  491. package/node_modules/@noble/hashes/cryptoNode.d.ts.map +1 -0
  492. package/node_modules/@noble/hashes/cryptoNode.js +18 -0
  493. package/node_modules/@noble/hashes/cryptoNode.js.map +1 -0
  494. package/node_modules/@noble/hashes/eskdf.d.ts +47 -0
  495. package/node_modules/@noble/hashes/eskdf.d.ts.map +1 -0
  496. package/node_modules/@noble/hashes/eskdf.js +166 -0
  497. package/node_modules/@noble/hashes/eskdf.js.map +1 -0
  498. package/node_modules/@noble/hashes/esm/_assert.d.ts +17 -0
  499. package/node_modules/@noble/hashes/esm/_assert.d.ts.map +1 -0
  500. package/node_modules/@noble/hashes/esm/_assert.js +15 -0
  501. package/node_modules/@noble/hashes/esm/_assert.js.map +1 -0
  502. package/node_modules/@noble/hashes/esm/_blake.d.ts +14 -0
  503. package/node_modules/@noble/hashes/esm/_blake.d.ts.map +1 -0
  504. package/node_modules/@noble/hashes/esm/_blake.js +45 -0
  505. package/node_modules/@noble/hashes/esm/_blake.js.map +1 -0
  506. package/node_modules/@noble/hashes/esm/_md.d.ts +51 -0
  507. package/node_modules/@noble/hashes/esm/_md.d.ts.map +1 -0
  508. package/node_modules/@noble/hashes/esm/_md.js +155 -0
  509. package/node_modules/@noble/hashes/esm/_md.js.map +1 -0
  510. package/node_modules/@noble/hashes/esm/_u64.d.ts +55 -0
  511. package/node_modules/@noble/hashes/esm/_u64.d.ts.map +1 -0
  512. package/node_modules/@noble/hashes/esm/_u64.js +67 -0
  513. package/node_modules/@noble/hashes/esm/_u64.js.map +1 -0
  514. package/node_modules/@noble/hashes/esm/argon2.d.ts +32 -0
  515. package/node_modules/@noble/hashes/esm/argon2.d.ts.map +1 -0
  516. package/node_modules/@noble/hashes/esm/argon2.js +392 -0
  517. package/node_modules/@noble/hashes/esm/argon2.js.map +1 -0
  518. package/node_modules/@noble/hashes/esm/blake1.d.ts +106 -0
  519. package/node_modules/@noble/hashes/esm/blake1.d.ts.map +1 -0
  520. package/node_modules/@noble/hashes/esm/blake1.js +452 -0
  521. package/node_modules/@noble/hashes/esm/blake1.js.map +1 -0
  522. package/node_modules/@noble/hashes/esm/blake2.d.ts +116 -0
  523. package/node_modules/@noble/hashes/esm/blake2.d.ts.map +1 -0
  524. package/node_modules/@noble/hashes/esm/blake2.js +413 -0
  525. package/node_modules/@noble/hashes/esm/blake2.js.map +1 -0
  526. package/node_modules/@noble/hashes/esm/blake2b.d.ts +11 -0
  527. package/node_modules/@noble/hashes/esm/blake2b.d.ts.map +1 -0
  528. package/node_modules/@noble/hashes/esm/blake2b.js +11 -0
  529. package/node_modules/@noble/hashes/esm/blake2b.js.map +1 -0
  530. package/node_modules/@noble/hashes/esm/blake2s.d.ts +20 -0
  531. package/node_modules/@noble/hashes/esm/blake2s.d.ts.map +1 -0
  532. package/node_modules/@noble/hashes/esm/blake2s.js +21 -0
  533. package/node_modules/@noble/hashes/esm/blake2s.js.map +1 -0
  534. package/node_modules/@noble/hashes/esm/blake3.d.ts +54 -0
  535. package/node_modules/@noble/hashes/esm/blake3.d.ts.map +1 -0
  536. package/node_modules/@noble/hashes/esm/blake3.js +251 -0
  537. package/node_modules/@noble/hashes/esm/blake3.js.map +1 -0
  538. package/node_modules/@noble/hashes/esm/crypto.d.ts +2 -0
  539. package/node_modules/@noble/hashes/esm/crypto.d.ts.map +1 -0
  540. package/node_modules/@noble/hashes/esm/crypto.js +2 -0
  541. package/node_modules/@noble/hashes/esm/crypto.js.map +1 -0
  542. package/node_modules/@noble/hashes/esm/cryptoNode.d.ts +2 -0
  543. package/node_modules/@noble/hashes/esm/cryptoNode.d.ts.map +1 -0
  544. package/node_modules/@noble/hashes/esm/cryptoNode.js +15 -0
  545. package/node_modules/@noble/hashes/esm/cryptoNode.js.map +1 -0
  546. package/node_modules/@noble/hashes/esm/eskdf.d.ts +47 -0
  547. package/node_modules/@noble/hashes/esm/eskdf.d.ts.map +1 -0
  548. package/node_modules/@noble/hashes/esm/eskdf.js +160 -0
  549. package/node_modules/@noble/hashes/esm/eskdf.js.map +1 -0
  550. package/node_modules/@noble/hashes/esm/hkdf.d.ts +36 -0
  551. package/node_modules/@noble/hashes/esm/hkdf.d.ts.map +1 -0
  552. package/node_modules/@noble/hashes/esm/hkdf.js +82 -0
  553. package/node_modules/@noble/hashes/esm/hkdf.js.map +1 -0
  554. package/node_modules/@noble/hashes/esm/hmac.d.ts +35 -0
  555. package/node_modules/@noble/hashes/esm/hmac.d.ts.map +1 -0
  556. package/node_modules/@noble/hashes/esm/hmac.js +86 -0
  557. package/node_modules/@noble/hashes/esm/hmac.js.map +1 -0
  558. package/node_modules/@noble/hashes/esm/index.d.ts +2 -0
  559. package/node_modules/@noble/hashes/esm/index.d.ts.map +1 -0
  560. package/node_modules/@noble/hashes/esm/index.js +33 -0
  561. package/node_modules/@noble/hashes/esm/index.js.map +1 -0
  562. package/node_modules/@noble/hashes/esm/legacy.d.ts +71 -0
  563. package/node_modules/@noble/hashes/esm/legacy.d.ts.map +1 -0
  564. package/node_modules/@noble/hashes/esm/legacy.js +281 -0
  565. package/node_modules/@noble/hashes/esm/legacy.js.map +1 -0
  566. package/node_modules/@noble/hashes/esm/package.json +10 -0
  567. package/node_modules/@noble/hashes/esm/pbkdf2.d.ts +23 -0
  568. package/node_modules/@noble/hashes/esm/pbkdf2.d.ts.map +1 -0
  569. package/node_modules/@noble/hashes/esm/pbkdf2.js +97 -0
  570. package/node_modules/@noble/hashes/esm/pbkdf2.js.map +1 -0
  571. package/node_modules/@noble/hashes/esm/ripemd160.d.ts +13 -0
  572. package/node_modules/@noble/hashes/esm/ripemd160.d.ts.map +1 -0
  573. package/node_modules/@noble/hashes/esm/ripemd160.js +13 -0
  574. package/node_modules/@noble/hashes/esm/ripemd160.js.map +1 -0
  575. package/node_modules/@noble/hashes/esm/scrypt.d.ts +34 -0
  576. package/node_modules/@noble/hashes/esm/scrypt.d.ts.map +1 -0
  577. package/node_modules/@noble/hashes/esm/scrypt.js +228 -0
  578. package/node_modules/@noble/hashes/esm/scrypt.js.map +1 -0
  579. package/node_modules/@noble/hashes/esm/sha1.d.ts +11 -0
  580. package/node_modules/@noble/hashes/esm/sha1.d.ts.map +1 -0
  581. package/node_modules/@noble/hashes/esm/sha1.js +11 -0
  582. package/node_modules/@noble/hashes/esm/sha1.js.map +1 -0
  583. package/node_modules/@noble/hashes/esm/sha2.d.ts +159 -0
  584. package/node_modules/@noble/hashes/esm/sha2.d.ts.map +1 -0
  585. package/node_modules/@noble/hashes/esm/sha2.js +375 -0
  586. package/node_modules/@noble/hashes/esm/sha2.js.map +1 -0
  587. package/node_modules/@noble/hashes/esm/sha256.d.ts +20 -0
  588. package/node_modules/@noble/hashes/esm/sha256.d.ts.map +1 -0
  589. package/node_modules/@noble/hashes/esm/sha256.js +20 -0
  590. package/node_modules/@noble/hashes/esm/sha256.js.map +1 -0
  591. package/node_modules/@noble/hashes/esm/sha3-addons.d.ts +142 -0
  592. package/node_modules/@noble/hashes/esm/sha3-addons.d.ts.map +1 -0
  593. package/node_modules/@noble/hashes/esm/sha3-addons.js +393 -0
  594. package/node_modules/@noble/hashes/esm/sha3-addons.js.map +1 -0
  595. package/node_modules/@noble/hashes/esm/sha3.d.ts +53 -0
  596. package/node_modules/@noble/hashes/esm/sha3.d.ts.map +1 -0
  597. package/node_modules/@noble/hashes/esm/sha3.js +234 -0
  598. package/node_modules/@noble/hashes/esm/sha3.js.map +1 -0
  599. package/node_modules/@noble/hashes/esm/sha512.d.ts +26 -0
  600. package/node_modules/@noble/hashes/esm/sha512.d.ts.map +1 -0
  601. package/node_modules/@noble/hashes/esm/sha512.js +26 -0
  602. package/node_modules/@noble/hashes/esm/sha512.js.map +1 -0
  603. package/node_modules/@noble/hashes/esm/utils.d.ts +161 -0
  604. package/node_modules/@noble/hashes/esm/utils.d.ts.map +1 -0
  605. package/node_modules/@noble/hashes/esm/utils.js +281 -0
  606. package/node_modules/@noble/hashes/esm/utils.js.map +1 -0
  607. package/node_modules/@noble/hashes/hkdf.d.ts +36 -0
  608. package/node_modules/@noble/hashes/hkdf.d.ts.map +1 -0
  609. package/node_modules/@noble/hashes/hkdf.js +88 -0
  610. package/node_modules/@noble/hashes/hkdf.js.map +1 -0
  611. package/node_modules/@noble/hashes/hmac.d.ts +35 -0
  612. package/node_modules/@noble/hashes/hmac.d.ts.map +1 -0
  613. package/node_modules/@noble/hashes/hmac.js +91 -0
  614. package/node_modules/@noble/hashes/hmac.js.map +1 -0
  615. package/node_modules/@noble/hashes/index.d.ts +1 -0
  616. package/node_modules/@noble/hashes/index.d.ts.map +1 -0
  617. package/node_modules/@noble/hashes/index.js +33 -0
  618. package/node_modules/@noble/hashes/index.js.map +1 -0
  619. package/node_modules/@noble/hashes/legacy.d.ts +71 -0
  620. package/node_modules/@noble/hashes/legacy.d.ts.map +1 -0
  621. package/node_modules/@noble/hashes/legacy.js +287 -0
  622. package/node_modules/@noble/hashes/legacy.js.map +1 -0
  623. package/node_modules/@noble/hashes/package.json +266 -0
  624. package/node_modules/@noble/hashes/pbkdf2.d.ts +23 -0
  625. package/node_modules/@noble/hashes/pbkdf2.d.ts.map +1 -0
  626. package/node_modules/@noble/hashes/pbkdf2.js +101 -0
  627. package/node_modules/@noble/hashes/pbkdf2.js.map +1 -0
  628. package/node_modules/@noble/hashes/ripemd160.d.ts +13 -0
  629. package/node_modules/@noble/hashes/ripemd160.d.ts.map +1 -0
  630. package/node_modules/@noble/hashes/ripemd160.js +16 -0
  631. package/node_modules/@noble/hashes/ripemd160.js.map +1 -0
  632. package/node_modules/@noble/hashes/scrypt.d.ts +34 -0
  633. package/node_modules/@noble/hashes/scrypt.d.ts.map +1 -0
  634. package/node_modules/@noble/hashes/scrypt.js +232 -0
  635. package/node_modules/@noble/hashes/scrypt.js.map +1 -0
  636. package/node_modules/@noble/hashes/sha1.d.ts +11 -0
  637. package/node_modules/@noble/hashes/sha1.d.ts.map +1 -0
  638. package/node_modules/@noble/hashes/sha1.js +14 -0
  639. package/node_modules/@noble/hashes/sha1.js.map +1 -0
  640. package/node_modules/@noble/hashes/sha2.d.ts +159 -0
  641. package/node_modules/@noble/hashes/sha2.d.ts.map +1 -0
  642. package/node_modules/@noble/hashes/sha2.js +384 -0
  643. package/node_modules/@noble/hashes/sha2.js.map +1 -0
  644. package/node_modules/@noble/hashes/sha256.d.ts +20 -0
  645. package/node_modules/@noble/hashes/sha256.d.ts.map +1 -0
  646. package/node_modules/@noble/hashes/sha256.js +23 -0
  647. package/node_modules/@noble/hashes/sha256.js.map +1 -0
  648. package/node_modules/@noble/hashes/sha3-addons.d.ts +142 -0
  649. package/node_modules/@noble/hashes/sha3-addons.d.ts.map +1 -0
  650. package/node_modules/@noble/hashes/sha3-addons.js +402 -0
  651. package/node_modules/@noble/hashes/sha3-addons.js.map +1 -0
  652. package/node_modules/@noble/hashes/sha3.d.ts +53 -0
  653. package/node_modules/@noble/hashes/sha3.d.ts.map +1 -0
  654. package/node_modules/@noble/hashes/sha3.js +239 -0
  655. package/node_modules/@noble/hashes/sha3.js.map +1 -0
  656. package/node_modules/@noble/hashes/sha512.d.ts +26 -0
  657. package/node_modules/@noble/hashes/sha512.d.ts.map +1 -0
  658. package/node_modules/@noble/hashes/sha512.js +29 -0
  659. package/node_modules/@noble/hashes/sha512.js.map +1 -0
  660. package/node_modules/@noble/hashes/src/_assert.ts +22 -0
  661. package/node_modules/@noble/hashes/src/_blake.ts +50 -0
  662. package/node_modules/@noble/hashes/src/_md.ts +176 -0
  663. package/node_modules/@noble/hashes/src/_u64.ts +91 -0
  664. package/node_modules/@noble/hashes/src/argon2.ts +497 -0
  665. package/node_modules/@noble/hashes/src/blake1.ts +534 -0
  666. package/node_modules/@noble/hashes/src/blake2.ts +486 -0
  667. package/node_modules/@noble/hashes/src/blake2b.ts +10 -0
  668. package/node_modules/@noble/hashes/src/blake2s.ts +20 -0
  669. package/node_modules/@noble/hashes/src/blake3.ts +272 -0
  670. package/node_modules/@noble/hashes/src/crypto.ts +9 -0
  671. package/node_modules/@noble/hashes/src/cryptoNode.ts +15 -0
  672. package/node_modules/@noble/hashes/src/eskdf.ts +187 -0
  673. package/node_modules/@noble/hashes/src/hkdf.ts +88 -0
  674. package/node_modules/@noble/hashes/src/hmac.ts +94 -0
  675. package/node_modules/@noble/hashes/src/index.ts +31 -0
  676. package/node_modules/@noble/hashes/src/legacy.ts +293 -0
  677. package/node_modules/@noble/hashes/src/pbkdf2.ts +122 -0
  678. package/node_modules/@noble/hashes/src/ripemd160.ts +12 -0
  679. package/node_modules/@noble/hashes/src/scrypt.ts +257 -0
  680. package/node_modules/@noble/hashes/src/sha1.ts +10 -0
  681. package/node_modules/@noble/hashes/src/sha2.ts +402 -0
  682. package/node_modules/@noble/hashes/src/sha256.ts +24 -0
  683. package/node_modules/@noble/hashes/src/sha3-addons.ts +499 -0
  684. package/node_modules/@noble/hashes/src/sha3.ts +258 -0
  685. package/node_modules/@noble/hashes/src/sha512.ts +34 -0
  686. package/node_modules/@noble/hashes/src/utils.ts +395 -0
  687. package/node_modules/@noble/hashes/utils.d.ts +161 -0
  688. package/node_modules/@noble/hashes/utils.d.ts.map +1 -0
  689. package/node_modules/@noble/hashes/utils.js +313 -0
  690. package/node_modules/@noble/hashes/utils.js.map +1 -0
  691. package/package.json +179 -8
  692. package/schemas/catalog.schema.json +357 -0
  693. package/src/align.ts +239 -0
  694. package/src/audio-init-parser.ts +189 -0
  695. package/src/audio-ring-buffer.ts +120 -0
  696. package/src/authored-timing.ts +63 -0
  697. package/src/block-policy.ts +903 -0
  698. package/src/carp-catalog.ts +1065 -0
  699. package/src/catalog-fec-params.ts +729 -0
  700. package/src/catalog-network-source.ts +74 -0
  701. package/src/catalog-validator.ts +34 -0
  702. package/src/cmaf-block-assembler.ts +1255 -0
  703. package/src/cmaf-group-batcher.ts +104 -0
  704. package/src/cmcd-producer.ts +329 -0
  705. package/src/codec-utils.ts +1984 -0
  706. package/src/conceal-timeline.ts +293 -0
  707. package/src/delivery-gap.ts +147 -0
  708. package/src/duplicate-ledger.ts +372 -0
  709. package/src/fec-codec.ts +61 -0
  710. package/src/fec-manager.ts +4298 -0
  711. package/src/fec-starvation-detector.ts +128 -0
  712. package/src/fec-state.ts +219 -0
  713. package/src/fec-worker-setup.ts +283 -0
  714. package/src/fmp4-completion.ts +47 -0
  715. package/src/fmp4-reader.ts +112 -0
  716. package/src/index.ts +590 -21
  717. package/src/iso-block-locator.ts +329 -0
  718. package/src/iso-bmff-timing.ts +813 -0
  719. package/src/loc.ts +128 -154
  720. package/src/manifest-auth-plan.ts +107 -0
  721. package/src/media-router.ts +841 -0
  722. package/src/mfu-reassembler.ts +3480 -155
  723. package/src/mfu-reassembly-policy.ts +134 -0
  724. package/src/mmtp-container-parser.ts +2380 -0
  725. package/src/mmtp-decode-pipeline.ts +406 -0
  726. package/src/mmtp-router.ts +4860 -0
  727. package/src/mmtp-to-cmaf.ts +977 -0
  728. package/src/multicast-auth-catalog.ts +340 -0
  729. package/src/multicast-input.ts +793 -0
  730. package/src/multicast-manager.ts +2783 -0
  731. package/src/multicast-transport.ts +1058 -0
  732. package/src/multicast-unwrap.ts +132 -0
  733. package/src/no-modules.ts +21 -0
  734. package/src/phase14-catalog-override.ts +336 -0
  735. package/src/repair-fetch.ts +772 -0
  736. package/src/repair-layers.ts +533 -0
  737. package/src/sample-combiner.ts +938 -0
  738. package/src/signaling.ts +78 -0
  739. package/src/source-auth.ts +1 -0
  740. package/src/switching-set-alignment.ts +109 -0
  741. package/src/timestamp-codec.ts +265 -0
  742. package/src/track-pipeline-setup.ts +205 -0
  743. package/src/track-pipeline.ts +332 -0
  744. package/src/track-session.ts +1010 -0
  745. package/src/transport-pool.ts +128 -0
  746. package/src/wasm-mfu-reassembler.ts +405 -0
  747. package/src/wasm-mmtp-container-parser.ts +23 -0
  748. package/test-vectors/align.json +199 -0
  749. package/test-vectors/catalog/README.md +106 -0
  750. package/test-vectors/catalog/negative/archive-origin-with-path.json +33 -0
  751. package/test-vectors/catalog/negative/archive-unknown-field.json +34 -0
  752. package/test-vectors/catalog/negative/fec-block-profile-missing.json +51 -0
  753. package/test-vectors/catalog/negative/fec-block-profile-unknown.json +52 -0
  754. package/test-vectors/catalog/negative/fec-enhancement-repair-removed.json +28 -0
  755. package/test-vectors/catalog/negative/fec-repair-layer-geometry.json +33 -0
  756. package/test-vectors/catalog/negative/fec-repair-layer-missing-symbols.json +31 -0
  757. package/test-vectors/catalog/negative/fec-repair-multiple-depends.json +32 -0
  758. package/test-vectors/catalog/negative/fec-repair-overlay-with-layer.json +34 -0
  759. package/test-vectors/catalog/negative/fec-repair-priority-out-of-band.json +24 -0
  760. package/test-vectors/catalog/negative/fec-repair-source-symbols-without-scope.json +33 -0
  761. package/test-vectors/catalog/negative/legacy-selection-params.json +15 -0
  762. package/test-vectors/catalog/negative/media-track-repair-layer.json +16 -0
  763. package/test-vectors/catalog/negative/missing-mmtp-fields.json +12 -0
  764. package/test-vectors/catalog/negative/multicast-auth-padded-key.json +37 -0
  765. package/test-vectors/catalog/negative/multicast-auth-reused-track-format.json +53 -0
  766. package/test-vectors/catalog/negative/multicast-auth-trailing-pad-bits.json +37 -0
  767. package/test-vectors/catalog/negative/multicast-endpoint-missing-protocol-and-source.json +24 -0
  768. package/test-vectors/catalog/negative/multicast-network-source-empty.json +44 -0
  769. package/test-vectors/catalog/negative/multicast-packet-id-signaling.json +26 -0
  770. package/test-vectors/catalog/negative/network-source-object.json +25 -0
  771. package/test-vectors/catalog/negative/raptorq-source-symbols-over-max.json +24 -0
  772. package/test-vectors/catalog/negative/raptorq-unaligned-symbol.json +27 -0
  773. package/test-vectors/catalog/negative/repair-track-legacy-shape.json +19 -0
  774. package/test-vectors/catalog/negative/track-role-empty.json +16 -0
  775. package/test-vectors/catalog/negative/track-role-non-string.json +16 -0
  776. package/test-vectors/catalog/positive/archive-origin.json +34 -0
  777. package/test-vectors/catalog/positive/fec-iso-ssbg1.json +52 -0
  778. package/test-vectors/catalog/positive/fec-layered-repair.json +106 -0
  779. package/test-vectors/catalog/positive/fec-multicast.json +52 -0
  780. package/test-vectors/catalog/positive/flat-av.json +30 -0
  781. package/test-vectors/catalog/positive/multicast-auth-rotation.json +55 -0
  782. package/test-vectors/catalog/positive/multicast-native-ssm-no-network-source.json +43 -0
  783. package/test-vectors/catalog/positive/ticks-and-mixed-timescales.json +39 -0
  784. package/test-vectors/catalog/positive/track-role.json +49 -0
  785. package/test-vectors/catalog/releases/moqcast-native-v16-v1/catalog.json +65 -0
  786. package/test-vectors/catalog/releases/moqcast-native-v16-v1.archive.sha256 +1 -0
  787. package/test-vectors/catalog-multicast-auth-v1.json +26 -0
  788. package/test-vectors/catalog-validation.json +732 -0
  789. package/test-vectors/catalog-validator-public-api.mjs +25 -0
  790. package/test-vectors/generate-source-auth-fixture.mjs +114 -0
  791. package/test-vectors/hevc-x265-repeat-headers-v1.json +40 -0
  792. package/test-vectors/source-auth-v1.json +61 -0
  793. package/test-vectors/source-contiguity-v1.json +131 -0
  794. package/test-vectors/subsample-placement-v1.json +230 -0
  795. package/dist/mmtp.d.ts +0 -73
  796. package/dist/mmtp.d.ts.map +0 -1
  797. package/dist/mmtp.js +0 -210
  798. package/dist/mmtp.js.map +0 -1
  799. package/src/mmtp.ts +0 -277
@@ -0,0 +1,2264 @@
1
+ // node_modules/@blockcast/mmt-transport/dist/types.js
2
+ var MoqFecAlgorithm;
3
+ (function(MoqFecAlgorithm2) {
4
+ MoqFecAlgorithm2[MoqFecAlgorithm2["None"] = 0] = "None";
5
+ MoqFecAlgorithm2[MoqFecAlgorithm2["Xor"] = 1] = "Xor";
6
+ MoqFecAlgorithm2[MoqFecAlgorithm2["RaptorQ"] = 2] = "RaptorQ";
7
+ })(MoqFecAlgorithm || (MoqFecAlgorithm = {}));
8
+
9
+ // node_modules/@blockcast/mmt-transport/node_modules/@blockcast/mmt-alta-parse/dist/index.js
10
+ var MPU_HEADER_SIZE = 8;
11
+ var MPU_LENGTH_FIELD_SIZE = 2;
12
+ var MPU_HEADER_REMAINDER_SIZE = MPU_HEADER_SIZE - MPU_LENGTH_FIELD_SIZE;
13
+
14
+ // node_modules/@blockcast/mmt-transport/node_modules/@blockcast/mmt-base/dist/mmtp.js
15
+ var MPU_HEADER_SIZE2 = 8;
16
+ var MPU_LENGTH_FIELD_SIZE2 = 2;
17
+ var MPU_HEADER_REMAINDER_SIZE2 = MPU_HEADER_SIZE2 - MPU_LENGTH_FIELD_SIZE2;
18
+ var MMTP_SIGNALING_PACKET_ID = 0;
19
+ var MMTP_PACKET_ID_MAX = 65535;
20
+
21
+ // node_modules/@blockcast/mmt-transport/node_modules/@blockcast/mmt-base/dist/net-constants.js
22
+ var DEFAULT_AMT_RELAY_PORT = 2268;
23
+
24
+ // node_modules/@blockcast/mmt-transport/node_modules/@blockcast/mmt-base/dist/ntp-short.js
25
+ var NTP_SHORT_BITS = 32;
26
+ var NTP_SHORT_MODULUS = 2 ** NTP_SHORT_BITS;
27
+ var NTP_SHORT_HALF_RANGE = 2 ** (NTP_SHORT_BITS - 1);
28
+ function isNtpShort(value) {
29
+ return Number.isInteger(value) && value >= 0 && value < NTP_SHORT_MODULUS;
30
+ }
31
+ function compareNtpShort(a, b) {
32
+ if (!isNtpShort(a) || !isNtpShort(b)) {
33
+ throw new RangeError(`NTP-short values must be integers in [0, 2^${NTP_SHORT_BITS}), got ${String(a)} and ${String(b)}`);
34
+ }
35
+ if (a === b)
36
+ return "equal";
37
+ const forward = (a - b + NTP_SHORT_MODULUS) % NTP_SHORT_MODULUS;
38
+ if (forward < NTP_SHORT_HALF_RANGE)
39
+ return "after";
40
+ if (forward > NTP_SHORT_HALF_RANGE)
41
+ return "before";
42
+ return "unordered";
43
+ }
44
+
45
+ // node_modules/@blockcast/mmt-transport/node_modules/@blockcast/mmt-base/dist/fec-block-profile.js
46
+ var FEC_BLOCK_PROFILES = Object.freeze([
47
+ "k-padded-v1",
48
+ "iso-ssbg1-v1"
49
+ ]);
50
+
51
+ // node_modules/@blockcast/mmt-transport/dist/driad-discovery.js
52
+ var DRIADDiscovery = class {
53
+ cache = /* @__PURE__ */ new Map();
54
+ cacheExpiry = 3e5;
55
+ // 5 minutes
56
+ /**
57
+ * Discover AMT relays for a multicast source address (RFC 8777)
58
+ *
59
+ * @param source - The multicast source IP address (NOT the group!)
60
+ * @returns Array of discovered AMT relays that can tunnel traffic from this source
61
+ */
62
+ async discoverRelays(source) {
63
+ const cached = this.cache.get(source);
64
+ if (cached) {
65
+ return cached;
66
+ }
67
+ try {
68
+ const reversedSource = source.split(".").reverse().join(".");
69
+ const queryDomain = `${reversedSource}.amt.in-addr.arpa`;
70
+ console.log(`[DRIAD] Discovering relays for source ${source} via ${queryDomain}`);
71
+ const relays = await this.queryDRIADProxy(source);
72
+ if (relays.length > 0) {
73
+ this.cache.set(source, relays);
74
+ setTimeout(() => this.cache.delete(source), this.cacheExpiry);
75
+ }
76
+ return relays;
77
+ } catch (error) {
78
+ console.warn(`[DRIAD] Discovery failed for source ${source}:`, error);
79
+ return [];
80
+ }
81
+ }
82
+ /**
83
+ * Query DRIAD proxy service (browser-compatible)
84
+ */
85
+ async queryDRIADProxy(source) {
86
+ const proxyEndpoints = [
87
+ "https://driad.amt.net/api/v1/relays",
88
+ "https://multicast-gateway.cloudflare.com/driad"
89
+ ];
90
+ for (const endpoint of proxyEndpoints) {
91
+ try {
92
+ const response = await fetch(`${endpoint}?source=${encodeURIComponent(source)}`, {
93
+ method: "GET",
94
+ headers: { Accept: "application/json" },
95
+ signal: AbortSignal.timeout(5e3)
96
+ });
97
+ if (response.ok) {
98
+ const data = await response.json();
99
+ return data.relays || [];
100
+ }
101
+ } catch {
102
+ }
103
+ }
104
+ const dohRelay = await this.queryDNSOverHTTPS(source);
105
+ if (dohRelay) {
106
+ return [dohRelay];
107
+ }
108
+ return [];
109
+ }
110
+ /**
111
+ * Query DNS-over-HTTPS for DRIAD relay based on source address (RFC 8777)
112
+ */
113
+ async queryDNSOverHTTPS(source) {
114
+ try {
115
+ const reversedSource = source.split(".").reverse().join(".");
116
+ const queryName = `${reversedSource}.amt.in-addr.arpa`;
117
+ const dohUrl = `https://cloudflare-dns.com/dns-query?name=${queryName}&type=A`;
118
+ const response = await fetch(dohUrl, {
119
+ headers: { Accept: "application/dns-json" },
120
+ signal: AbortSignal.timeout(3e3)
121
+ });
122
+ if (!response.ok) {
123
+ return null;
124
+ }
125
+ const result = await response.json();
126
+ if (result.Answer && result.Answer.length > 0) {
127
+ return {
128
+ host: result.Answer[0].data,
129
+ port: DEFAULT_AMT_RELAY_PORT,
130
+ priority: 10,
131
+ weight: 100,
132
+ asn: 0
133
+ };
134
+ }
135
+ return null;
136
+ } catch (error) {
137
+ console.warn("[DRIAD] DNS-over-HTTPS query failed:", error);
138
+ return null;
139
+ }
140
+ }
141
+ /**
142
+ * Select best relay based on RTT measurements
143
+ */
144
+ async selectBestRelay(relays) {
145
+ if (relays.length === 0)
146
+ return null;
147
+ const measured = await Promise.all(relays.map(async (relay) => {
148
+ const rtt = await this.measureRTT(relay.host, relay.port);
149
+ return { ...relay, rtt };
150
+ }));
151
+ measured.sort((a, b) => {
152
+ if (a.priority !== b.priority)
153
+ return a.priority - b.priority;
154
+ return (a.rtt || Infinity) - (b.rtt || Infinity);
155
+ });
156
+ console.log(`[DRIAD] Selected relay: ${measured[0].host} (RTT: ${measured[0].rtt}ms)`);
157
+ return measured[0];
158
+ }
159
+ async measureRTT(host, _port) {
160
+ const start = performance.now();
161
+ try {
162
+ await fetch(`https://${host}/health`, {
163
+ method: "HEAD",
164
+ signal: AbortSignal.timeout(2e3),
165
+ mode: "no-cors"
166
+ });
167
+ return performance.now() - start;
168
+ } catch {
169
+ return Infinity;
170
+ }
171
+ }
172
+ /**
173
+ * Clear the relay cache
174
+ */
175
+ clearCache() {
176
+ this.cache.clear();
177
+ }
178
+ /**
179
+ * Get cached relays for a source address
180
+ */
181
+ getCached(source) {
182
+ return this.cache.get(source);
183
+ }
184
+ };
185
+ var driadDiscovery = new DRIADDiscovery();
186
+
187
+ // node_modules/@blockcast/mmt-transport/dist/multicast-tier.js
188
+ function endpointKey(endpoint) {
189
+ return `${endpoint.sourceAddress ?? ""}|${endpoint.groupAddress}|${endpoint.port}`;
190
+ }
191
+ function carriesMedia(endpoint) {
192
+ return endpoint.carriesMedia !== false;
193
+ }
194
+ function selectMulticastTier(endpoints, estimate) {
195
+ const media = endpoints.filter(carriesMedia);
196
+ if (media.length <= 1)
197
+ return media[0];
198
+ const ranked = media.filter((endpoint) => typeof endpoint.bandwidth === "number" && endpoint.bandwidth > 0).sort((a, b) => a.bandwidth - b.bandwidth);
199
+ if (ranked.length < 2)
200
+ return media[0];
201
+ if (estimate === void 0)
202
+ return ranked[0];
203
+ const budget = estimate * 0.8;
204
+ let selected;
205
+ for (const endpoint of ranked) {
206
+ if (endpoint.bandwidth <= budget)
207
+ selected = endpoint;
208
+ }
209
+ return selected ?? ranked[0];
210
+ }
211
+
212
+ // node_modules/@blockcast/mmt-transport/dist/abr-controller.js
213
+ var QUALITY_LEVELS = Object.freeze([
214
+ { name: "240p", bitrate: 3e5, width: 426, height: 240, fps: 15 },
215
+ { name: "360p", bitrate: 5e5, width: 640, height: 360, fps: 24 },
216
+ { name: "480p", bitrate: 1e6, width: 854, height: 480, fps: 30 },
217
+ { name: "720p", bitrate: 25e5, width: 1280, height: 720, fps: 30 },
218
+ { name: "1080p", bitrate: 5e6, width: 1920, height: 1080, fps: 30 },
219
+ { name: "1440p", bitrate: 8e6, width: 2560, height: 1440, fps: 30 },
220
+ { name: "4K", bitrate: 15e6, width: 3840, height: 2160, fps: 30 }
221
+ ].map((level) => Object.freeze(level)));
222
+ function positiveFinite(value) {
223
+ return typeof value === "number" && Number.isFinite(value) && value > 0;
224
+ }
225
+ function validateQualityLadder(ladder) {
226
+ if (!Array.isArray(ladder) || ladder.length === 0) {
227
+ throw new TypeError("[ABR] ladder must list at least one rendition (e.g. the catalog's video tracks)");
228
+ }
229
+ const names = /* @__PURE__ */ new Set();
230
+ for (const level of ladder) {
231
+ if (typeof level?.name !== "string" || level.name.length === 0) {
232
+ throw new TypeError("[ABR] every ladder rendition needs a name");
233
+ }
234
+ if (!positiveFinite(level.bitrate)) {
235
+ throw new RangeError(`[ABR] rendition ${level.name}: bitrate must be a positive finite number, got ${String(level.bitrate)}`);
236
+ }
237
+ for (const field of ["width", "height", "fps"]) {
238
+ if (level[field] !== void 0 && !positiveFinite(level[field])) {
239
+ throw new RangeError(`[ABR] rendition ${level.name}: ${field} must be a positive finite number when stated, got ${String(level[field])}`);
240
+ }
241
+ }
242
+ if (names.has(level.name))
243
+ throw new RangeError(`[ABR] rendition ${level.name} appears twice in the ladder`);
244
+ names.add(level.name);
245
+ }
246
+ return Object.freeze([...ladder].sort((a, b) => a.bitrate - b.bitrate).map((level) => Object.freeze({ ...level })));
247
+ }
248
+ var AdaptiveBitrateController = class {
249
+ /** The caller's renditions, ascending by bitrate (`validateQualityLadder`). */
250
+ ladder;
251
+ currentQualityIndex;
252
+ history = [];
253
+ historyWindow = 1e4;
254
+ // 10 second window
255
+ upgradeThreshold = 0.8;
256
+ // 80% of target bitrate sustained
257
+ downgradeThreshold = 0.5;
258
+ // 50% of target bitrate triggers downgrade
259
+ stabilityPeriod = 5e3;
260
+ // Wait 5s before upgrading
261
+ lastQualityChange = 0;
262
+ onQualityChange;
263
+ // FEC stats for effective loss rate calculation
264
+ fecStats = {
265
+ rawLossRate: 0,
266
+ effectiveLossRate: 0,
267
+ recoveryRate: 1,
268
+ fecEnabled: false
269
+ };
270
+ constructor(options) {
271
+ if (!options || typeof options !== "object") {
272
+ throw new TypeError("[ABR] AdaptiveBitrateController needs { ladder, initialQuality }");
273
+ }
274
+ this.ladder = validateQualityLadder(options.ladder);
275
+ this.currentQualityIndex = options.initialQuality === void 0 ? 0 : this.ladder.findIndex((q) => q.name === options.initialQuality);
276
+ if (this.currentQualityIndex < 0) {
277
+ throw new RangeError(`[ABR] initial rendition ${String(options.initialQuality)} is not in the ladder`);
278
+ }
279
+ }
280
+ setCallback(callback) {
281
+ this.onQualityChange = callback;
282
+ }
283
+ getCurrentQuality() {
284
+ return this.ladder[this.currentQualityIndex];
285
+ }
286
+ /** Selects the multicast (S,G) tier without replacing a player's unicast ABR manager. */
287
+ selectMulticastTier(endpoints, estimate = this.getMetrics().measuredBitrate || void 0) {
288
+ return selectMulticastTier(endpoints, estimate);
289
+ }
290
+ /**
291
+ * Record network sample for bitrate adaptation
292
+ *
293
+ * @param bytesReceived - Bytes received in this sample
294
+ * @param packetsLost - Packets lost (raw, before FEC recovery)
295
+ */
296
+ recordSample(bytesReceived, packetsLost) {
297
+ const now = Date.now();
298
+ this.history.push({ timestamp: now, bytesReceived, packetsLost });
299
+ this.history = this.history.filter((s) => now - s.timestamp < this.historyWindow);
300
+ const { measuredBitrate, lossRate: rawLossRate } = this.calculateMetrics();
301
+ const currentQuality = this.getCurrentQuality();
302
+ const effectiveLossRate = this.fecStats.fecEnabled ? this.fecStats.effectiveLossRate : rawLossRate;
303
+ if (now - this.lastQualityChange < this.stabilityPeriod) {
304
+ return;
305
+ }
306
+ if (effectiveLossRate > 0.05 || measuredBitrate < currentQuality.bitrate * this.downgradeThreshold) {
307
+ this.downgrade();
308
+ return;
309
+ }
310
+ if (measuredBitrate > currentQuality.bitrate * this.upgradeThreshold && effectiveLossRate < 0.01 && this.currentQualityIndex < this.ladder.length - 1) {
311
+ this.upgrade();
312
+ }
313
+ }
314
+ /**
315
+ * Update FEC statistics for ABR decisions
316
+ *
317
+ * Per draft-ramadan-moq-fec-00, ABR should use the effective loss rate
318
+ * (after FEC recovery) rather than raw transport loss rate.
319
+ *
320
+ * @param stats - FEC statistics from the FEC decoder
321
+ */
322
+ setFecStats(stats) {
323
+ this.fecStats = stats;
324
+ }
325
+ /**
326
+ * Get current FEC statistics
327
+ */
328
+ getFecStats() {
329
+ return { ...this.fecStats };
330
+ }
331
+ calculateMetrics() {
332
+ if (this.history.length < 2) {
333
+ return { measuredBitrate: 0, lossRate: 0 };
334
+ }
335
+ const totalBytes = this.history.reduce((sum, s) => sum + s.bytesReceived, 0);
336
+ const totalLost = this.history.reduce((sum, s) => sum + s.packetsLost, 0);
337
+ const duration = (this.history[this.history.length - 1].timestamp - this.history[0].timestamp) / 1e3;
338
+ const measuredBitrate = duration > 0 ? totalBytes * 8 / duration : 0;
339
+ const lossRate = totalLost / (this.history.length + totalLost);
340
+ return { measuredBitrate, lossRate };
341
+ }
342
+ upgrade() {
343
+ if (this.currentQualityIndex >= this.ladder.length - 1)
344
+ return;
345
+ this.currentQualityIndex++;
346
+ this.lastQualityChange = Date.now();
347
+ const newQuality = this.getCurrentQuality();
348
+ console.log(`[ABR] Upgrading to ${newQuality.name} (${newQuality.bitrate / 1e6}Mbps)`);
349
+ this.onQualityChange?.(newQuality);
350
+ }
351
+ downgrade() {
352
+ if (this.currentQualityIndex <= 0)
353
+ return;
354
+ this.currentQualityIndex--;
355
+ this.lastQualityChange = Date.now();
356
+ const newQuality = this.getCurrentQuality();
357
+ console.log(`[ABR] Downgrading to ${newQuality.name} (${newQuality.bitrate / 1e6}Mbps)`);
358
+ this.onQualityChange?.(newQuality);
359
+ }
360
+ /**
361
+ * Select a ladder rendition: the caller switched to it (a manual override,
362
+ * or a switch the caller made). Throws for a name the ladder does not carry.
363
+ */
364
+ setQuality(name) {
365
+ const index = this.ladder.findIndex((q) => q.name === name);
366
+ if (index < 0)
367
+ throw new RangeError(`[ABR] rendition ${name} is not in the ladder`);
368
+ this.currentQualityIndex = index;
369
+ this.lastQualityChange = Date.now();
370
+ this.onQualityChange?.(this.getCurrentQuality());
371
+ }
372
+ /**
373
+ * Get current metrics including both raw and effective loss rates
374
+ */
375
+ getMetrics() {
376
+ const { measuredBitrate, lossRate: rawLossRate } = this.calculateMetrics();
377
+ return {
378
+ measuredBitrate,
379
+ rawLossRate,
380
+ effectiveLossRate: this.fecStats.fecEnabled ? this.fecStats.effectiveLossRate : rawLossRate,
381
+ fecEnabled: this.fecStats.fecEnabled,
382
+ sampleCount: this.history.length
383
+ };
384
+ }
385
+ /**
386
+ * Reset history and start fresh
387
+ */
388
+ reset() {
389
+ this.history = [];
390
+ this.lastQualityChange = 0;
391
+ }
392
+ };
393
+
394
+ // node_modules/@blockcast/mmt-transport/dist/multicast-orchestrator.js
395
+ var DEFAULT_DWELL_MS = 3e3;
396
+ var DEFAULT_JOIN_DEADLINE_MS = 5e3;
397
+ var MulticastOrchestrator = class {
398
+ options;
399
+ #state = "stable";
400
+ #current;
401
+ #target;
402
+ #estimate;
403
+ #favored;
404
+ #joinStartedAt = 0;
405
+ /**
406
+ * Latest active-tier send time (NTP short), or undefined before the first.
407
+ * "Latest" is serial order, not the numerically largest value: after the
408
+ * field wraps, the largest value is the stale one.
409
+ */
410
+ #highWater;
411
+ #dwellMs;
412
+ #joinDeadlineMs;
413
+ constructor(options) {
414
+ this.options = options;
415
+ this.#dwellMs = options.dwellMs ?? DEFAULT_DWELL_MS;
416
+ this.#joinDeadlineMs = options.joinDeadlineMs ?? DEFAULT_JOIN_DEADLINE_MS;
417
+ if (!Number.isFinite(this.#dwellMs) || !Number.isFinite(this.#joinDeadlineMs) || this.#dwellMs <= 0 || this.#joinDeadlineMs <= 0) {
418
+ throw new Error("Multicast dwell and join deadline must be positive");
419
+ }
420
+ }
421
+ get state() {
422
+ return this.#state;
423
+ }
424
+ get current() {
425
+ return this.#current;
426
+ }
427
+ get target() {
428
+ return this.#target;
429
+ }
430
+ get estimate() {
431
+ return this.#estimate;
432
+ }
433
+ start() {
434
+ this.#current ??= this.options.initialEndpoint ?? selectMulticastTier(this.options.endpoints, void 0);
435
+ return this.#current;
436
+ }
437
+ onGoodput(sample) {
438
+ const bitrate = sample.bitrate;
439
+ if (!this.#current || this.options.adaptive === false)
440
+ return void 0;
441
+ if (this.#state === "joining")
442
+ return this.poll();
443
+ if (bitrate === void 0 || !Number.isFinite(bitrate))
444
+ return void 0;
445
+ this.#estimate = bitrate;
446
+ const desired = selectMulticastTier(this.options.endpoints, bitrate);
447
+ if (!desired)
448
+ return void 0;
449
+ const desiredKey = endpointKey(desired);
450
+ if (desiredKey === endpointKey(this.#current)) {
451
+ if (this.#favored?.source === "goodput")
452
+ this.#favored = void 0;
453
+ return void 0;
454
+ }
455
+ if (typeof desired.bandwidth !== "number" || typeof this.#current.bandwidth !== "number" || desired.bandwidth >= this.#current.bandwidth) {
456
+ if (this.#favored?.source === "goodput")
457
+ this.#favored = void 0;
458
+ return void 0;
459
+ }
460
+ const now = this.#now();
461
+ if (!this.#favored || this.#favored.key !== desiredKey || this.#favored.source !== "goodput") {
462
+ this.#favored = { key: desiredKey, since: now, source: "goodput" };
463
+ return void 0;
464
+ }
465
+ if (now - this.#favored.since < this.#dwellMs)
466
+ return void 0;
467
+ this.#state = "joining";
468
+ this.#target = desired;
469
+ this.#joinStartedAt = now;
470
+ this.#favored = void 0;
471
+ return { kind: "join-target", current: this.#current, target: desired };
472
+ }
473
+ onHeadroom(sample) {
474
+ if (!this.#current || this.options.adaptive === false || this.#state === "joining")
475
+ return void 0;
476
+ if (!sample.healthy) {
477
+ if (this.#favored?.source === "headroom")
478
+ this.#favored = void 0;
479
+ return void 0;
480
+ }
481
+ if (this.#favored?.source === "goodput")
482
+ return void 0;
483
+ const currentBandwidth = this.#current.bandwidth;
484
+ if (typeof currentBandwidth !== "number")
485
+ return void 0;
486
+ const desired = this.options.endpoints.filter((endpoint) => carriesMedia(endpoint) && typeof endpoint.bandwidth === "number" && endpoint.bandwidth > currentBandwidth).sort((a, b) => a.bandwidth - b.bandwidth)[0];
487
+ if (!desired) {
488
+ this.#favored = void 0;
489
+ return void 0;
490
+ }
491
+ const desiredKey = endpointKey(desired);
492
+ if (desiredKey === endpointKey(this.#current)) {
493
+ this.#favored = void 0;
494
+ return void 0;
495
+ }
496
+ const now = this.#now();
497
+ if (!this.#favored || this.#favored.key !== desiredKey) {
498
+ this.#favored = { key: desiredKey, since: now, source: "headroom" };
499
+ return void 0;
500
+ }
501
+ if (now - this.#favored.since < this.#dwellMs)
502
+ return void 0;
503
+ this.#state = "joining";
504
+ this.#target = desired;
505
+ this.#joinStartedAt = now;
506
+ this.#favored = void 0;
507
+ return { kind: "join-target", current: this.#current, target: desired };
508
+ }
509
+ /**
510
+ * Feed a packet from the active tier (to advance the high-water mark) or
511
+ * from the in-flight target (to find a committable RAP).
512
+ *
513
+ * Serial order is only the true order while the compared instants are less
514
+ * than `NTP_SHORT_HALF_RANGE` (2^15 s, ~9.1 h) apart. Feeding every
515
+ * active-tier packet keeps the mark that close to the live stream. A mark
516
+ * refreshed only by commits can fall further behind than that, and a
517
+ * target RAP may then compare as older, so the join is abandoned.
518
+ */
519
+ onTierPacket(packet) {
520
+ if (!this.#current)
521
+ return void 0;
522
+ const sentAt = tierPacketSendTime(packet);
523
+ if (packet.endpointKey === endpointKey(this.#current) && sentAt !== void 0 && (this.#highWater === void 0 || compareNtpShort(sentAt, this.#highWater) === "after")) {
524
+ this.#highWater = sentAt;
525
+ }
526
+ if (this.#state !== "joining" || !this.#target)
527
+ return void 0;
528
+ const expired = this.poll();
529
+ if (expired)
530
+ return expired;
531
+ if (packet.endpointKey !== endpointKey(this.#target) || !packet.keyframe || !packet.hasValidCodecConfig || sentAt === void 0 || !this.#reachesHighWater(sentAt))
532
+ return void 0;
533
+ const command = {
534
+ kind: "commit-swap",
535
+ target: this.#target,
536
+ old: this.#current
537
+ };
538
+ this.#highWater = sentAt;
539
+ this.#current = this.#target;
540
+ this.#target = void 0;
541
+ this.#state = "stable";
542
+ return command;
543
+ }
544
+ poll() {
545
+ if (this.#state !== "joining" || !this.#target || !this.#current)
546
+ return void 0;
547
+ if (this.#now() - this.#joinStartedAt < this.#joinDeadlineMs)
548
+ return void 0;
549
+ return this.cancel();
550
+ }
551
+ cancel() {
552
+ if (this.#state !== "joining" || !this.#target || !this.#current)
553
+ return void 0;
554
+ const command = {
555
+ kind: "abandon-join",
556
+ current: this.#current,
557
+ target: this.#target
558
+ };
559
+ this.#target = void 0;
560
+ this.#state = "stable";
561
+ return command;
562
+ }
563
+ /**
564
+ * Whether a target RAP sent at `sentAt` is at or beyond the active tier's
565
+ * high-water mark. A pair exactly half the NTP-short space apart has no
566
+ * serial order, so it cannot show that and does not commit.
567
+ */
568
+ #reachesHighWater(sentAt) {
569
+ if (this.#highWater === void 0)
570
+ return true;
571
+ const order = compareNtpShort(sentAt, this.#highWater);
572
+ return order === "after" || order === "equal";
573
+ }
574
+ #now() {
575
+ const now = this.options.now();
576
+ if (!Number.isFinite(now))
577
+ throw new Error("Multicast orchestrator clock must be finite");
578
+ return now;
579
+ }
580
+ };
581
+ function tierPacketSendTime(packet) {
582
+ if (!Number.isFinite(packet.timestamp))
583
+ return void 0;
584
+ if (!isNtpShort(packet.timestamp)) {
585
+ throw new RangeError(`Multicast tier packet timestamp must be an MMTP NTP-short send time, got ${packet.timestamp}`);
586
+ }
587
+ return packet.timestamp;
588
+ }
589
+
590
+ // node_modules/@blockcast/mmt-transport/dist/endpoint-config.js
591
+ function toWindowMulticastSubscribeConfig(input) {
592
+ if (input.mode !== void 0 && !["auto", "native", "tunnel"].includes(input.mode)) {
593
+ throw new TypeError(`Unsupported multicast mode: ${String(input.mode)}`);
594
+ }
595
+ if (input.packetIds !== void 0 && !Array.isArray(input.packetIds)) {
596
+ throw new TypeError(`multicast packetIds must be an array, got ${input.packetIds === null ? "null" : typeof input.packetIds}`);
597
+ }
598
+ if (input.packetIds?.some((id) => !isMulticastTrackPacketId(id)) || input.tracks?.some((track) => !isMulticastTrackPacketId(track.packetId))) {
599
+ throw new RangeError(`multicast packetId must be an integer from 1 to ${MMTP_PACKET_ID_MAX}; packetId 0 is the MMTP signaling flow and is never a track's`);
600
+ }
601
+ const base = {
602
+ group: input.group,
603
+ port: input.port,
604
+ ...input.source?.trim() ? { source: input.source.trim() } : {},
605
+ consume: "bytes",
606
+ ...input.packetIds?.length ? { packetIds: [...input.packetIds] } : {}
607
+ };
608
+ const relay = input.amtRelay?.trim();
609
+ const wantsAmt = input.mode === "tunnel" || input.mode !== "native" && relay !== void 0 && relay !== "";
610
+ if (!wantsAmt) {
611
+ const native = {
612
+ ...base,
613
+ origin: "ip-multicast",
614
+ ...input.tracks?.length ? { tracks: input.tracks.map(({ name, packetId }) => ({ name, packetId })) } : {}
615
+ };
616
+ return native;
617
+ }
618
+ const relayPort = input.amtRelayPort;
619
+ if (!relay || relayPort === void 0 || !isPositivePort(relayPort)) {
620
+ throw new TypeError("AMT requires a resolved relay and a valid relay port");
621
+ }
622
+ return {
623
+ ...base,
624
+ origin: "amt",
625
+ relay,
626
+ relayPort
627
+ };
628
+ }
629
+ function isValidMulticastGroupAddress(address) {
630
+ const value = address?.trim().toLowerCase();
631
+ if (!value)
632
+ return false;
633
+ if (value.startsWith("ff"))
634
+ return isValidIpv6MulticastAddress(value);
635
+ const parts = value.split(".");
636
+ if (parts.length !== 4)
637
+ return false;
638
+ const octets = parts.map((part) => {
639
+ if (!/^\d+$/.test(part))
640
+ return Number.NaN;
641
+ const octet = Number(part);
642
+ return Number.isInteger(octet) && octet >= 0 && octet <= 255 ? octet : Number.NaN;
643
+ });
644
+ return octets.every(Number.isInteger) && octets[0] >= 224 && octets[0] <= 239;
645
+ }
646
+ function normalizeMulticastEndpoint(endpoint) {
647
+ const groupAddress = endpoint.groupAddress.trim().toLowerCase();
648
+ const sourceAddress = endpoint.sourceAddress?.trim().toLowerCase() || void 0;
649
+ const amtRelay = endpoint.amtRelay?.trim().toLowerCase() || void 0;
650
+ if (!isValidMulticastGroupAddress(groupAddress) || !isPositivePort(endpoint.port))
651
+ return void 0;
652
+ if (endpoint.mode && !["auto", "native", "tunnel"].includes(endpoint.mode))
653
+ return void 0;
654
+ if (endpoint.amtRelayPort !== void 0 && !isPositivePort(endpoint.amtRelayPort))
655
+ return void 0;
656
+ return {
657
+ groupAddress,
658
+ ...sourceAddress ? { sourceAddress } : {},
659
+ port: endpoint.port,
660
+ ...endpoint.mode ? { mode: endpoint.mode } : {},
661
+ ...amtRelay ? { amtRelay } : {},
662
+ ...endpoint.amtRelayPort ? { amtRelayPort: endpoint.amtRelayPort } : {}
663
+ };
664
+ }
665
+ function multicastEndpointKey(endpoint) {
666
+ const normalized = normalizeMulticastEndpoint(endpoint);
667
+ if (!normalized)
668
+ throw new Error("Invalid multicast endpoint");
669
+ return JSON.stringify([
670
+ normalized.sourceAddress ?? "",
671
+ normalized.groupAddress,
672
+ normalized.port,
673
+ normalized.mode ?? "auto",
674
+ normalized.amtRelay ?? "",
675
+ normalized.amtRelayPort ?? ""
676
+ ]);
677
+ }
678
+ function isMulticastTrackPacketId(value) {
679
+ return Number.isInteger(value) && value > MMTP_SIGNALING_PACKET_ID && value <= MMTP_PACKET_ID_MAX;
680
+ }
681
+ function isValidIpv6MulticastAddress(value) {
682
+ if (!/^[0-9a-f:]+$/.test(value))
683
+ return false;
684
+ const compressed = value.includes("::");
685
+ if (value.indexOf("::") !== value.lastIndexOf("::"))
686
+ return false;
687
+ const groups = value.split(":").filter(Boolean);
688
+ if (groups.length === 0 || groups.length > 8)
689
+ return false;
690
+ if (!compressed && groups.length !== 8)
691
+ return false;
692
+ return groups.every((group) => /^[0-9a-f]{1,4}$/.test(group));
693
+ }
694
+ function isPositivePort(port) {
695
+ return Number.isInteger(port) && port > 0 && port <= 65535;
696
+ }
697
+
698
+ // node_modules/@blockcast/mmt-transport/dist/packet-batch.js
699
+ function subscriptionDeliversPacketBatches(subscription) {
700
+ return subscription.eventTypes?.includes("packets") === true;
701
+ }
702
+
703
+ // node_modules/@blockcast/mmt-transport/dist/multicast-subscription-pool.js
704
+ var MulticastSubscriptionPool = class {
705
+ #entries = /* @__PURE__ */ new Map();
706
+ #gatewayIds = /* @__PURE__ */ new WeakMap();
707
+ #nextGatewayId = 1;
708
+ async acquire(gateway, config, consumer) {
709
+ const endpoint = normalizeMulticastEndpoint({
710
+ groupAddress: config.group,
711
+ sourceAddress: config.source,
712
+ port: config.port,
713
+ mode: config.mode,
714
+ amtRelay: config.amtRelay,
715
+ amtRelayPort: config.amtRelayPort
716
+ });
717
+ if (!endpoint)
718
+ throw new Error("Invalid multicast endpoint");
719
+ if (typeof gateway.subscribe !== "function")
720
+ throw new Error("window.multicast.subscribe unavailable");
721
+ const key = multicastEndpointKey(endpoint);
722
+ const internalKey = `${this.#gatewayId(gateway)}|${key}`;
723
+ let record = this.#entries.get(internalKey);
724
+ if (!record) {
725
+ record = { claims: 0, entry: Promise.resolve(null) };
726
+ const createdRecord = record;
727
+ record.entry = this.#createEntry(gateway, endpoint, (entry2) => {
728
+ if (this.#entries.get(internalKey) === createdRecord)
729
+ this.#entries.delete(internalKey);
730
+ this.#detach(entry2);
731
+ }).catch((error) => {
732
+ if (this.#entries.get(internalKey) === createdRecord)
733
+ this.#entries.delete(internalKey);
734
+ throw error;
735
+ });
736
+ this.#entries.set(internalKey, record);
737
+ }
738
+ record.claims++;
739
+ let entry;
740
+ try {
741
+ entry = await record.entry;
742
+ } catch (error) {
743
+ record.claims--;
744
+ throw error;
745
+ }
746
+ if (entry.closed) {
747
+ record.claims--;
748
+ return this.acquire(gateway, config, consumer);
749
+ }
750
+ const token = Symbol(key);
751
+ entry.consumers.set(token, consumer);
752
+ let released = false;
753
+ return {
754
+ key,
755
+ release: async () => {
756
+ if (released)
757
+ return;
758
+ released = true;
759
+ entry.consumers.delete(token);
760
+ record.claims--;
761
+ if (record.claims > 0)
762
+ return;
763
+ if (this.#entries.get(internalKey) === record)
764
+ this.#entries.delete(internalKey);
765
+ this.#detach(entry);
766
+ if (!entry.closed)
767
+ await entry.subscription.unsubscribe();
768
+ }
769
+ };
770
+ }
771
+ get size() {
772
+ return this.#entries.size;
773
+ }
774
+ async #createEntry(gateway, endpoint, onClosed) {
775
+ const subscription = await gateway.subscribe(toWindowMulticastSubscribeConfig({
776
+ group: endpoint.groupAddress,
777
+ ...endpoint.sourceAddress ? { source: endpoint.sourceAddress } : {},
778
+ port: endpoint.port,
779
+ ...endpoint.mode ? { mode: endpoint.mode } : {},
780
+ ...endpoint.amtRelay ? { amtRelay: endpoint.amtRelay } : {},
781
+ ...endpoint.amtRelayPort ? { amtRelayPort: endpoint.amtRelayPort } : {}
782
+ }));
783
+ const consumers = /* @__PURE__ */ new Map();
784
+ let entry;
785
+ const packetListener = subscriptionDeliversPacketBatches(subscription) ? {
786
+ type: "packets",
787
+ listener: (event) => {
788
+ for (const data of event.detail) {
789
+ this.#dispatch(consumers, (consumer) => consumer.onBytes(data));
790
+ }
791
+ }
792
+ } : {
793
+ type: "bytes",
794
+ listener: (event) => {
795
+ this.#dispatch(consumers, (consumer) => consumer.onBytes(event.detail));
796
+ }
797
+ };
798
+ const stateListener = (event) => {
799
+ this.#dispatch(consumers, (consumer) => consumer.onState?.(event.detail));
800
+ if (event.detail === "closed" && !entry.closed) {
801
+ entry.closed = true;
802
+ onClosed(entry);
803
+ }
804
+ };
805
+ const errorListener = (event) => {
806
+ const error = event.detail instanceof Error ? event.detail : new Error(String(event.detail));
807
+ this.#dispatch(consumers, (consumer) => consumer.onError?.(error));
808
+ };
809
+ entry = { subscription, consumers, packetListener, stateListener, errorListener, closed: false };
810
+ if (packetListener.type === "packets") {
811
+ subscription.addEventListener("packets", packetListener.listener);
812
+ } else {
813
+ subscription.addEventListener("bytes", packetListener.listener);
814
+ }
815
+ subscription.addEventListener("state", stateListener);
816
+ subscription.addEventListener("error", errorListener);
817
+ return entry;
818
+ }
819
+ #gatewayId(gateway) {
820
+ const object = gateway;
821
+ let id = this.#gatewayIds.get(object);
822
+ if (!id) {
823
+ id = this.#nextGatewayId++;
824
+ this.#gatewayIds.set(object, id);
825
+ }
826
+ return id;
827
+ }
828
+ #detach(entry) {
829
+ const { packetListener } = entry;
830
+ if (packetListener.type === "packets") {
831
+ entry.subscription.removeEventListener("packets", packetListener.listener);
832
+ } else {
833
+ entry.subscription.removeEventListener("bytes", packetListener.listener);
834
+ }
835
+ entry.subscription.removeEventListener("state", entry.stateListener);
836
+ entry.subscription.removeEventListener("error", entry.errorListener);
837
+ }
838
+ #dispatch(consumers, callback) {
839
+ for (const consumer of consumers.values()) {
840
+ try {
841
+ callback(consumer);
842
+ } catch (error) {
843
+ console.error("[Transport] multicast consumer callback failed", error);
844
+ }
845
+ }
846
+ }
847
+ };
848
+ var multicastSubscriptionPool = new MulticastSubscriptionPool();
849
+
850
+ // node_modules/@blockcast/mmt-transport/dist/transport-manager.js
851
+ var TransportManager = class {
852
+ state = {
853
+ mode: "disconnected",
854
+ connected: false,
855
+ packetsReceived: 0,
856
+ bytesReceived: 0,
857
+ lastPacketTime: 0
858
+ };
859
+ capabilities = null;
860
+ subscription = null;
861
+ driad = new DRIADDiscovery();
862
+ /** Built by `connect()` from the caller's ladder; there is no built-in one. */
863
+ abr = null;
864
+ multicastOrchestrator = null;
865
+ onOrchestratorCommand;
866
+ connectionGeneration = 0;
867
+ onPacket;
868
+ onError;
869
+ onStateChange;
870
+ getWindow() {
871
+ return typeof window === "undefined" ? void 0 : window;
872
+ }
873
+ getWindowMulticastGateway() {
874
+ return this.getWindow()?.multicast;
875
+ }
876
+ async getGatewayCapabilities(gateway) {
877
+ if (!gateway?.capabilities)
878
+ return void 0;
879
+ try {
880
+ return typeof gateway.capabilities === "function" ? await gateway.capabilities() : gateway.capabilities;
881
+ } catch (error) {
882
+ console.warn("[Transport] window.multicast capabilities failed:", error);
883
+ return void 0;
884
+ }
885
+ }
886
+ async gatewaySupportsBytes(gateway) {
887
+ if (typeof gateway?.subscribe !== "function")
888
+ return false;
889
+ if (!gateway.capabilities)
890
+ return true;
891
+ const capabilities = await this.getGatewayCapabilities(gateway);
892
+ if (!capabilities)
893
+ return false;
894
+ const consumeModes = capabilities.consumeModes;
895
+ return !consumeModes || consumeModes.includes("bytes");
896
+ }
897
+ /**
898
+ * Detect available transport capabilities
899
+ */
900
+ async detectCapabilities() {
901
+ if (this.capabilities)
902
+ return this.capabilities;
903
+ const gateway = this.getWindowMulticastGateway();
904
+ const hasGatewayBytes = await this.gatewaySupportsBytes(gateway);
905
+ const win = this.getWindow();
906
+ this.capabilities = {
907
+ nativeSSM: hasGatewayBytes,
908
+ nativeIGMP: hasGatewayBytes,
909
+ directSockets: typeof win?.UDPSocket !== "undefined",
910
+ amt: false,
911
+ driad: true,
912
+ // DRIAD uses HTTP proxy, always available
913
+ fecDecode: false
914
+ };
915
+ console.log("[Transport] Capabilities:", this.capabilities);
916
+ return this.capabilities;
917
+ }
918
+ /**
919
+ * Connect using best available transport
920
+ *
921
+ * Promotion hierarchy:
922
+ * 1. window.multicast gateway bytes
923
+ * 2. AMT proxy (specified or discovered via DRIAD)
924
+ * 3. MOQ WebTransport (final fallback)
925
+ *
926
+ * The ABR ladder (`abrLadder`) and initial rendition (`initialQuality`)
927
+ * are checked first, before anything is torn down. A config that fails is
928
+ * refused with the same shape as an invalid endpoint, the error to the
929
+ * error callback and `false` resolved; unlike one, it is caught before the
930
+ * live subscription closes, so a refused reconnect leaves that subscription,
931
+ * its state and any connect already in flight untouched.
932
+ */
933
+ async connect(config) {
934
+ let abr;
935
+ try {
936
+ abr = new AdaptiveBitrateController({
937
+ ladder: config.abrLadder,
938
+ initialQuality: config.initialQuality?.name
939
+ });
940
+ } catch (error) {
941
+ const refused = error instanceof Error ? error : new Error(String(error));
942
+ if (this.onError)
943
+ this.onError(refused);
944
+ else
945
+ console.error("[Transport] ABR config refused, not connecting:", refused);
946
+ return false;
947
+ }
948
+ const generation = ++this.connectionGeneration;
949
+ this.subscription?.close();
950
+ this.subscription = null;
951
+ this.abr = null;
952
+ this.state = {
953
+ mode: "disconnected",
954
+ connected: false,
955
+ packetsReceived: 0,
956
+ bytesReceived: 0,
957
+ lastPacketTime: 0
958
+ };
959
+ this.onStateChange?.(this.state);
960
+ const endpoint = normalizeMulticastEndpoint({
961
+ groupAddress: config.group,
962
+ sourceAddress: config.source,
963
+ port: config.port,
964
+ mode: config.mode,
965
+ amtRelay: config.amtRelay,
966
+ amtRelayPort: config.amtRelayPort
967
+ });
968
+ if (!endpoint) {
969
+ const error = new Error("Invalid multicast endpoint configuration");
970
+ this.onError?.(error);
971
+ return false;
972
+ }
973
+ config = {
974
+ ...config,
975
+ group: endpoint.groupAddress,
976
+ source: endpoint.sourceAddress ?? "",
977
+ mode: endpoint.mode,
978
+ amtRelay: endpoint.amtRelay,
979
+ amtRelayPort: endpoint.amtRelayPort
980
+ };
981
+ const caps = await this.detectCapabilities();
982
+ if (generation !== this.connectionGeneration)
983
+ return false;
984
+ this.abr = abr;
985
+ abr.setCallback((quality) => {
986
+ this.state.quality = quality;
987
+ this.subscription?.onqualitychange?.(quality);
988
+ this.onStateChange?.(this.state);
989
+ });
990
+ let connected = false;
991
+ if (caps.nativeSSM || caps.nativeIGMP) {
992
+ console.log("[Transport] Attempting window.multicast...");
993
+ connected = await this.connectWindowMulticast(config, generation);
994
+ if (connected) {
995
+ if (generation !== this.connectionGeneration)
996
+ return false;
997
+ this.state.mode = "multicast";
998
+ return true;
999
+ }
1000
+ }
1001
+ if (!connected) {
1002
+ console.log("[Transport] Attempting AMT tunnel...");
1003
+ connected = await this.connectAmt(config, generation);
1004
+ if (connected) {
1005
+ if (generation !== this.connectionGeneration)
1006
+ return false;
1007
+ this.state.mode = "amt";
1008
+ return true;
1009
+ }
1010
+ }
1011
+ console.log("[Transport] All multicast transports failed, falling back to MOQ");
1012
+ return false;
1013
+ }
1014
+ /**
1015
+ * Connect via the lowercase window.multicast bytes gateway.
1016
+ */
1017
+ async connectWindowMulticast(config, generation) {
1018
+ try {
1019
+ const gateway = this.getWindowMulticastGateway();
1020
+ if (typeof gateway?.subscribe !== "function")
1021
+ return false;
1022
+ const lease = await multicastSubscriptionPool.acquire(gateway, config, {
1023
+ onBytes: (data) => {
1024
+ if (generation === this.connectionGeneration)
1025
+ this.handlePacket(data);
1026
+ },
1027
+ onState: (state) => {
1028
+ if (generation !== this.connectionGeneration)
1029
+ return;
1030
+ this.state.connected = state !== "closed";
1031
+ this.onStateChange?.(this.state);
1032
+ },
1033
+ onError: (error) => {
1034
+ if (generation !== this.connectionGeneration)
1035
+ return;
1036
+ console.error("[Transport] window.multicast error:", error);
1037
+ this.onError?.(error);
1038
+ }
1039
+ });
1040
+ if (generation !== this.connectionGeneration) {
1041
+ await lease.release();
1042
+ return false;
1043
+ }
1044
+ this.subscription = {
1045
+ id: lease.key,
1046
+ config,
1047
+ close: () => {
1048
+ void lease.release();
1049
+ }
1050
+ };
1051
+ this.state = {
1052
+ mode: "multicast",
1053
+ connected: true,
1054
+ group: config.group,
1055
+ source: config.source,
1056
+ quality: this.requireAbr().getCurrentQuality(),
1057
+ packetsReceived: 0,
1058
+ bytesReceived: 0,
1059
+ lastPacketTime: 0
1060
+ };
1061
+ console.log(`[Transport] Connected via window.multicast: (${config.source}, ${config.group})`);
1062
+ this.onStateChange?.(this.state);
1063
+ return true;
1064
+ } catch (error) {
1065
+ console.warn("[Transport] window.multicast failed:", error);
1066
+ return false;
1067
+ }
1068
+ }
1069
+ /**
1070
+ * Connect via AMT proxy (with optional DRIAD discovery)
1071
+ */
1072
+ async connectAmt(config, generation) {
1073
+ try {
1074
+ let amtRelay = config.amtRelay;
1075
+ if (!amtRelay && config.driadEnabled !== false && config.source) {
1076
+ console.log(`[Transport] Discovering AMT relay via DRIAD for source ${config.source}...`);
1077
+ const relays = await this.driad.discoverRelays(config.source);
1078
+ if (generation !== this.connectionGeneration)
1079
+ return false;
1080
+ const bestRelay = await this.driad.selectBestRelay(relays);
1081
+ if (generation !== this.connectionGeneration)
1082
+ return false;
1083
+ if (bestRelay) {
1084
+ amtRelay = bestRelay.host;
1085
+ this.state.amtRelay = amtRelay;
1086
+ }
1087
+ }
1088
+ if (!amtRelay) {
1089
+ console.warn("[Transport] No AMT relay available (DRIAD requires source address for SSM)");
1090
+ return false;
1091
+ }
1092
+ return await this.connectAmtProxy(config, amtRelay, generation);
1093
+ } catch (error) {
1094
+ console.warn("[Transport] AMT connection failed:", error);
1095
+ return false;
1096
+ }
1097
+ }
1098
+ /**
1099
+ * Connect via WebSocket-based AMT proxy (browser fallback)
1100
+ */
1101
+ async connectAmtProxy(config, amtRelay, generation) {
1102
+ try {
1103
+ const relayHost = amtRelay.includes(":") && !amtRelay.startsWith("[") ? `[${amtRelay}]` : amtRelay;
1104
+ const wsUrl = new URL(`wss://${relayHost}/amt-proxy`);
1105
+ wsUrl.searchParams.set("group", config.group);
1106
+ wsUrl.searchParams.set("source", config.source || "");
1107
+ wsUrl.searchParams.set("port", String(config.port));
1108
+ const ws = new WebSocket(wsUrl);
1109
+ return new Promise((resolve, reject) => {
1110
+ ws.binaryType = "arraybuffer";
1111
+ const timeout = setTimeout(() => {
1112
+ ws.close();
1113
+ reject(new Error("AMT proxy connection timeout"));
1114
+ }, 1e4);
1115
+ ws.onopen = () => {
1116
+ clearTimeout(timeout);
1117
+ if (generation !== this.connectionGeneration) {
1118
+ ws.close();
1119
+ resolve(false);
1120
+ return;
1121
+ }
1122
+ console.log(`[Transport] Connected to AMT proxy: ${amtRelay}`);
1123
+ this.subscription = {
1124
+ id: `amt-proxy-${Date.now()}`,
1125
+ config,
1126
+ close: () => ws.close()
1127
+ };
1128
+ this.state = {
1129
+ mode: "amt",
1130
+ connected: true,
1131
+ group: config.group,
1132
+ source: config.source,
1133
+ amtRelay,
1134
+ quality: this.requireAbr().getCurrentQuality(),
1135
+ packetsReceived: 0,
1136
+ bytesReceived: 0,
1137
+ lastPacketTime: 0
1138
+ };
1139
+ this.onStateChange?.(this.state);
1140
+ resolve(true);
1141
+ };
1142
+ ws.onmessage = (event) => {
1143
+ if (generation === this.connectionGeneration && event.data instanceof ArrayBuffer) {
1144
+ this.handlePacket(event.data);
1145
+ }
1146
+ };
1147
+ ws.onerror = (error) => {
1148
+ clearTimeout(timeout);
1149
+ if (generation !== this.connectionGeneration) {
1150
+ resolve(false);
1151
+ return;
1152
+ }
1153
+ console.error("[Transport] AMT proxy error:", error);
1154
+ reject(error);
1155
+ };
1156
+ ws.onclose = () => {
1157
+ clearTimeout(timeout);
1158
+ if (generation !== this.connectionGeneration) {
1159
+ resolve(false);
1160
+ return;
1161
+ }
1162
+ this.state.connected = false;
1163
+ this.onStateChange?.(this.state);
1164
+ resolve(false);
1165
+ };
1166
+ });
1167
+ } catch (error) {
1168
+ console.warn("[Transport] AMT proxy failed:", error);
1169
+ return false;
1170
+ }
1171
+ }
1172
+ /**
1173
+ * Handle received packet
1174
+ */
1175
+ handlePacket(data) {
1176
+ this.state.packetsReceived++;
1177
+ this.state.bytesReceived += data.byteLength;
1178
+ this.state.lastPacketTime = Date.now();
1179
+ this.abr?.recordSample(data.byteLength, 0);
1180
+ this.onPacket?.(data);
1181
+ }
1182
+ /**
1183
+ * Get current transport state
1184
+ */
1185
+ getState() {
1186
+ return { ...this.state };
1187
+ }
1188
+ /**
1189
+ * The rung of the live connection's `abrLadder` ABR is on; `null` when
1190
+ * there is no ladder (before `connect(config)` succeeds, after
1191
+ * `disconnect()`, or after a reconnect that was torn down and bailed).
1192
+ */
1193
+ getQuality() {
1194
+ return this.abr?.getCurrentQuality() ?? null;
1195
+ }
1196
+ /**
1197
+ * Force the rung named `name` of the live connection's `abrLadder`.
1198
+ * Throws `Error` when there is no ladder (see `getQuality()`), and
1199
+ * `RangeError` when the ladder has no rung of that name; it never falls
1200
+ * back to another rung.
1201
+ */
1202
+ setQuality(name) {
1203
+ this.requireAbr().setQuality(name);
1204
+ }
1205
+ /** The controller `connect()` built; before it there is no ladder to adapt over. */
1206
+ requireAbr() {
1207
+ if (!this.abr)
1208
+ throw new Error("[Transport] ABR has no ladder before connect(config)");
1209
+ return this.abr;
1210
+ }
1211
+ /** Configures multicast-only ABR while leaving the caller's MoQ ABR untouched. */
1212
+ configureMulticastTiers(options, onCommand) {
1213
+ this.dispatchOrchestratorCommand(this.multicastOrchestrator?.cancel());
1214
+ this.multicastOrchestrator = new MulticastOrchestrator(options);
1215
+ this.onOrchestratorCommand = onCommand;
1216
+ return this.multicastOrchestrator.start();
1217
+ }
1218
+ recordMulticastGoodput(bitrate) {
1219
+ return this.dispatchOrchestratorCommand(this.multicastOrchestrator?.onGoodput({ bitrate }));
1220
+ }
1221
+ recordMulticastHeadroom(healthy) {
1222
+ return this.dispatchOrchestratorCommand(this.multicastOrchestrator?.onHeadroom({ healthy }));
1223
+ }
1224
+ recordMulticastTierPacket(packet) {
1225
+ return this.dispatchOrchestratorCommand(this.multicastOrchestrator?.onTierPacket(packet));
1226
+ }
1227
+ pollMulticastTierSwitch() {
1228
+ return this.dispatchOrchestratorCommand(this.multicastOrchestrator?.poll());
1229
+ }
1230
+ /**
1231
+ * Set packet callback
1232
+ */
1233
+ setPacketCallback(callback) {
1234
+ this.onPacket = callback;
1235
+ }
1236
+ /**
1237
+ * Set error callback
1238
+ */
1239
+ setErrorCallback(callback) {
1240
+ this.onError = callback;
1241
+ }
1242
+ /**
1243
+ * Set state change callback
1244
+ */
1245
+ setStateCallback(callback) {
1246
+ this.onStateChange = callback;
1247
+ }
1248
+ /**
1249
+ * Disconnect
1250
+ */
1251
+ disconnect() {
1252
+ this.connectionGeneration++;
1253
+ this.subscription?.close();
1254
+ this.subscription = null;
1255
+ this.abr = null;
1256
+ this.dispatchOrchestratorCommand(this.multicastOrchestrator?.cancel());
1257
+ this.multicastOrchestrator = null;
1258
+ this.onOrchestratorCommand = void 0;
1259
+ this.state = {
1260
+ mode: "disconnected",
1261
+ connected: false,
1262
+ packetsReceived: 0,
1263
+ bytesReceived: 0,
1264
+ lastPacketTime: 0
1265
+ };
1266
+ this.onStateChange?.(this.state);
1267
+ }
1268
+ dispatchOrchestratorCommand(command) {
1269
+ if (command)
1270
+ this.onOrchestratorCommand?.(command);
1271
+ return command;
1272
+ }
1273
+ };
1274
+ var transportManager = new TransportManager();
1275
+
1276
+ // node_modules/@blockcast/mmt-transport/dist/moqt-priority.js
1277
+ var MAX_MOQT_PRIORITY = 255;
1278
+ function moqtPriority(value, field) {
1279
+ if (!Number.isInteger(value) || value < 0 || value > MAX_MOQT_PRIORITY) {
1280
+ throw new RangeError(`${field} must be an integer in [0, ${MAX_MOQT_PRIORITY}], got ${value}`);
1281
+ }
1282
+ return value;
1283
+ }
1284
+ function moqtSubscriberPriority(value) {
1285
+ return moqtPriority(value, "MOQT subscriber priority");
1286
+ }
1287
+ function moqtPublisherPriority(value) {
1288
+ return moqtPriority(value, "MOQT publisher priority");
1289
+ }
1290
+ var MOQT_SUBSCRIBER_PRIORITY = Object.freeze({
1291
+ catalog: moqtSubscriberPriority(0),
1292
+ /**
1293
+ * @deprecated A repair FETCH's SUBSCRIBER_PRIORITY is derived per request
1294
+ * from the catalog source and repair priorities (draft-ramadan-moq-fec
1295
+ * §11.4.5), not a player constant. Use the `subscriberPriority` that
1296
+ * `@blockcast/mmt-container`'s `wireRepairFetch` puts on each
1297
+ * `RepairFetchRequest` (`repairFetchSubscriberPriority`).
1298
+ */
1299
+ deadlineRepair: moqtSubscriberPriority(0),
1300
+ audio: moqtSubscriberPriority(1),
1301
+ video: moqtSubscriberPriority(2),
1302
+ /**
1303
+ * @deprecated See `deadlineRepair`: use the request's catalog-derived
1304
+ * `RepairFetchRequest.subscriberPriority` (draft-ramadan-moq-fec §11.4.5).
1305
+ */
1306
+ backgroundRepair: moqtSubscriberPriority(3)
1307
+ });
1308
+ var MOQT_PUBLISHER_PRIORITY = Object.freeze({
1309
+ catalog: moqtPublisherPriority(32),
1310
+ source: moqtPublisherPriority(128),
1311
+ repair: moqtPublisherPriority(240)
1312
+ });
1313
+
1314
+ // node_modules/@blockcast/mmt-transport/dist/amt-gateway.js
1315
+ var AMTGatewayManager = class {
1316
+ subscriptions = /* @__PURE__ */ new Map();
1317
+ messageHandler;
1318
+ pendingPackets = /* @__PURE__ */ new Map();
1319
+ driad = new DRIADDiscovery();
1320
+ constructor() {
1321
+ this.messageHandler = (event) => {
1322
+ const data = event.data;
1323
+ console.log(`[AMT] SW message received:`, data.type);
1324
+ if (data.type === "UDP_PACKET") {
1325
+ this.handlePacket(data);
1326
+ } else if (data.type === "SOCKET_ERROR") {
1327
+ this.handleSocketError(data);
1328
+ } else if (data.type === "DEBUG_LOG") {
1329
+ console.log(`[AMT SW Debug] ${data.message}`);
1330
+ }
1331
+ };
1332
+ if (typeof navigator !== "undefined" && navigator.serviceWorker) {
1333
+ navigator.serviceWorker.addEventListener("message", this.messageHandler);
1334
+ console.log("[AMT] Registered service worker message handler");
1335
+ } else {
1336
+ console.warn("[AMT] Service worker not available");
1337
+ }
1338
+ }
1339
+ /**
1340
+ * Subscribe via AMT tunnel
1341
+ */
1342
+ async subscribe(config) {
1343
+ const { key } = config;
1344
+ const keyStr = this.getKeyString(key);
1345
+ if (this.subscriptions.has(keyStr)) {
1346
+ console.log(`[AMT] Reusing existing subscription to ${keyStr}`);
1347
+ return keyStr;
1348
+ }
1349
+ try {
1350
+ let relayAddress;
1351
+ let discoveryMethod;
1352
+ const relayPort = config.relayPort || DEFAULT_AMT_RELAY_PORT;
1353
+ if (config.relayAddress) {
1354
+ relayAddress = config.relayAddress;
1355
+ discoveryMethod = "manual";
1356
+ console.log(`[AMT] Using configured relay ${relayAddress}:${relayPort}`);
1357
+ } else if (key.source) {
1358
+ console.log(`[AMT] No relay configured, discovering via DRIAD for source ${key.source}...`);
1359
+ const relays = await this.driad.discoverRelays(key.source);
1360
+ const bestRelay = await this.driad.selectBestRelay(relays);
1361
+ if (!bestRelay) {
1362
+ throw new Error(`AMT relay discovery failed for source ${key.source}. Please specify a relay address in the subscription configuration.`);
1363
+ }
1364
+ relayAddress = bestRelay.host;
1365
+ discoveryMethod = "driad";
1366
+ console.log(`[AMT] Discovered relay via DRIAD: ${relayAddress}:${relayPort}`);
1367
+ } else {
1368
+ throw new Error(`AMT relay discovery requires a source address for SSM (RFC 8777). Please specify either a relay address or source address.`);
1369
+ }
1370
+ const subscriptionId = keyStr;
1371
+ this.pendingPackets.set(subscriptionId, []);
1372
+ const subscription = {
1373
+ key,
1374
+ subscriptionId,
1375
+ config,
1376
+ handshakeComplete: false,
1377
+ relay: {
1378
+ address: relayAddress,
1379
+ port: relayPort,
1380
+ discoveryMethod,
1381
+ discoveredAt: Date.now()
1382
+ }
1383
+ };
1384
+ this.subscriptions.set(keyStr, subscription);
1385
+ console.log(`[AMT] Subscription created for ${keyStr} via ${relayAddress}:${relayPort}`);
1386
+ return keyStr;
1387
+ } catch (error) {
1388
+ const subscription = this.subscriptions.get(keyStr);
1389
+ if (subscription) {
1390
+ this.subscriptions.delete(keyStr);
1391
+ this.pendingPackets.delete(subscription.subscriptionId);
1392
+ }
1393
+ throw new Error(`Failed to subscribe via AMT: ${error instanceof Error ? error.message : String(error)}`);
1394
+ }
1395
+ }
1396
+ /**
1397
+ * Unsubscribe from AMT tunnel
1398
+ */
1399
+ async unsubscribe(handle) {
1400
+ const subscription = this.subscriptions.get(handle);
1401
+ if (!subscription) {
1402
+ throw new Error(`Subscription ${handle} not found`);
1403
+ }
1404
+ try {
1405
+ if (subscription.keepAliveTimer) {
1406
+ clearInterval(subscription.keepAliveTimer);
1407
+ }
1408
+ console.log(`[AMT] Unsubscribed from ${handle}`);
1409
+ } catch (error) {
1410
+ console.error("[AMT] Error during unsubscribe:", error);
1411
+ } finally {
1412
+ this.subscriptions.delete(handle);
1413
+ this.pendingPackets.delete(subscription.subscriptionId);
1414
+ }
1415
+ }
1416
+ /**
1417
+ * Get list of active subscriptions
1418
+ */
1419
+ getSubscriptions() {
1420
+ return Array.from(this.subscriptions.keys());
1421
+ }
1422
+ /**
1423
+ * Handle packet from service worker
1424
+ */
1425
+ handlePacket(message) {
1426
+ const { subscriptionId, data } = message;
1427
+ if (!subscriptionId)
1428
+ return;
1429
+ const subscription = this.subscriptions.get(subscriptionId);
1430
+ if (!subscription) {
1431
+ console.warn(`[AMT] Received packet for unknown subscription: ${subscriptionId}`);
1432
+ return;
1433
+ }
1434
+ if (!subscription.handshakeComplete) {
1435
+ const queue = this.pendingPackets.get(subscriptionId);
1436
+ const packetData2 = data;
1437
+ if (queue) {
1438
+ queue.push({
1439
+ data: packetData2.data,
1440
+ remoteAddress: packetData2.remoteAddress,
1441
+ remotePort: packetData2.remotePort
1442
+ });
1443
+ }
1444
+ return;
1445
+ }
1446
+ const packetData = data;
1447
+ const metadata = {
1448
+ sourceAddress: subscription.relay?.address || "unknown",
1449
+ sourcePort: subscription.relay?.port || 0,
1450
+ transport: "tunnel",
1451
+ timestamp: performance.now()
1452
+ };
1453
+ subscription.config.onPacket(packetData.data, metadata);
1454
+ }
1455
+ /**
1456
+ * Handle socket error from service worker
1457
+ */
1458
+ handleSocketError(message) {
1459
+ const { subscriptionId, error } = message;
1460
+ if (!subscriptionId)
1461
+ return;
1462
+ const subscription = this.subscriptions.get(subscriptionId);
1463
+ if (!subscription) {
1464
+ console.warn(`[AMT] Received error for unknown subscription: ${subscriptionId}`);
1465
+ return;
1466
+ }
1467
+ subscription.config.onError(new Error(error || "Unknown error"));
1468
+ }
1469
+ /**
1470
+ * Cleanup on destroy
1471
+ */
1472
+ destroy() {
1473
+ if (this.messageHandler && typeof navigator !== "undefined" && navigator.serviceWorker) {
1474
+ navigator.serviceWorker.removeEventListener("message", this.messageHandler);
1475
+ }
1476
+ const handles = Array.from(this.subscriptions.keys());
1477
+ for (const handle of handles) {
1478
+ this.unsubscribe(handle).catch((err) => {
1479
+ console.error(`[AMT] Error unsubscribing ${handle}:`, err);
1480
+ });
1481
+ }
1482
+ }
1483
+ /**
1484
+ * Get key string for HashMap
1485
+ */
1486
+ getKeyString(key) {
1487
+ const source = key.source ? `@${key.source}` : "";
1488
+ return `${key.group}:${key.port}${source}`;
1489
+ }
1490
+ };
1491
+ var amtGatewayManager = new AMTGatewayManager();
1492
+
1493
+ // ../mmt-alta-parse/dist/index.js
1494
+ var MPU_HEADER_SIZE3 = 8;
1495
+ var MPU_LENGTH_FIELD_SIZE3 = 2;
1496
+ var MPU_HEADER_REMAINDER_SIZE3 = MPU_HEADER_SIZE3 - MPU_LENGTH_FIELD_SIZE3;
1497
+
1498
+ // ../mmt-base/dist/mmtp.js
1499
+ var MMTP_HEADER_SIZE = 12;
1500
+ var MPU_HEADER_SIZE4 = 8;
1501
+ var MPU_LENGTH_FIELD_SIZE4 = 2;
1502
+ var MPU_HEADER_REMAINDER_SIZE4 = MPU_HEADER_SIZE4 - MPU_LENGTH_FIELD_SIZE4;
1503
+ var MMTP_SIGNALING_PACKET_ID2 = 0;
1504
+ var MMTP_PACKET_ID_MAX2 = 65535;
1505
+ function readMMTPPacketId(buffer) {
1506
+ if (buffer.length < MMTP_HEADER_SIZE)
1507
+ return null;
1508
+ const flags = buffer[0];
1509
+ if ((flags >> 6 & 3) !== 0)
1510
+ return null;
1511
+ let offset = MMTP_HEADER_SIZE;
1512
+ if ((flags & 32) !== 0) {
1513
+ if (offset + 4 > buffer.length)
1514
+ return null;
1515
+ offset += 4;
1516
+ }
1517
+ if ((flags & 2) !== 0) {
1518
+ if (offset + 4 > buffer.length)
1519
+ return null;
1520
+ const length = buffer[offset + 2] << 8 | buffer[offset + 3];
1521
+ if (offset + 4 + length > buffer.length)
1522
+ return null;
1523
+ }
1524
+ return buffer[2] << 8 | buffer[3];
1525
+ }
1526
+
1527
+ // ../mmt-base/dist/ntp-short.js
1528
+ var NTP_SHORT_BITS2 = 32;
1529
+ var NTP_SHORT_MODULUS2 = 2 ** NTP_SHORT_BITS2;
1530
+ var NTP_SHORT_HALF_RANGE2 = 2 ** (NTP_SHORT_BITS2 - 1);
1531
+
1532
+ // ../mmt-base/dist/fec-block-profile.js
1533
+ var FEC_BLOCK_PROFILES2 = Object.freeze([
1534
+ "k-padded-v1",
1535
+ "iso-ssbg1-v1"
1536
+ ]);
1537
+
1538
+ // src/multicast-transport.ts
1539
+ var JOIN_SUCCEEDED = Object.freeze({ ok: true });
1540
+ function providerErrorOf(error) {
1541
+ if (typeof error !== "object" || error === null) return void 0;
1542
+ const fields = error;
1543
+ let name;
1544
+ let message;
1545
+ let code;
1546
+ try {
1547
+ name = fields.name;
1548
+ message = fields.message;
1549
+ code = fields.code;
1550
+ } catch {
1551
+ return void 0;
1552
+ }
1553
+ if (typeof name !== "string" || typeof message !== "string") return void 0;
1554
+ return Object.freeze(typeof code === "string" ? { name, message, code } : { name, message });
1555
+ }
1556
+ var MAX_TRACKED_DROPPED_PIDS = 16;
1557
+ function getMulticastGlobals() {
1558
+ return globalThis;
1559
+ }
1560
+ function hasMulticastGateway() {
1561
+ return typeof getMulticastGlobals().multicast?.subscribe === "function";
1562
+ }
1563
+ function normalizeBytesEventDetail(detail) {
1564
+ const value = detail && typeof detail === "object" && "data" in detail ? detail.data : detail;
1565
+ if (value instanceof Uint8Array) return value;
1566
+ if (value instanceof ArrayBuffer) return new Uint8Array(value);
1567
+ if (ArrayBuffer.isView(value)) {
1568
+ return new Uint8Array(value.buffer, value.byteOffset, value.byteLength);
1569
+ }
1570
+ return null;
1571
+ }
1572
+ function packetFilterUpdater(subscription) {
1573
+ const update = subscription.setPacketIds;
1574
+ return typeof update === "function" ? update.bind(subscription) : void 0;
1575
+ }
1576
+ function sameIds(a, b) {
1577
+ if (a.size !== b.size) return false;
1578
+ for (const id of a) if (!b.has(id)) return false;
1579
+ return true;
1580
+ }
1581
+ var MulticastTransport = class _MulticastTransport {
1582
+ #onPacket;
1583
+ #subscription = null;
1584
+ #packetListener = null;
1585
+ #resolvedTransport;
1586
+ #videoConfirmed = false;
1587
+ #audioConfirmed = false;
1588
+ // One armed no-packets timer per silence window (BLO-36599). Packets only
1589
+ // record #lastPacketAtMs; the timer re-arms for the remainder when it wakes
1590
+ // inside the window, instead of a clear+set pair on every packet.
1591
+ #watchdog = null;
1592
+ #lastPacketAtMs = 0;
1593
+ #failbackWindowMs = null;
1594
+ #onTakeover = null;
1595
+ #onFailback = null;
1596
+ // Data-plane-live edge: the first packet this join accepted. Everything
1597
+ // before it is join latency, not silence (see #resetWatchdog).
1598
+ #dataPlaneLive = false;
1599
+ #onDataPlaneLive = null;
1600
+ #errorListener = null;
1601
+ #onDelivery = null;
1602
+ #delivery;
1603
+ #disposed = false;
1604
+ #stats = {
1605
+ packetsReceived: 0,
1606
+ bytesReceived: 0,
1607
+ packetsDroppedUnregisteredPid: 0,
1608
+ packetsDroppedUnparseable: 0,
1609
+ packetsDroppedSignaling: 0
1610
+ };
1611
+ // join() calls by how they resolved; see joinStats.
1612
+ #joinsSucceeded = 0;
1613
+ #joinsDeclined = {
1614
+ disposed: 0,
1615
+ unavailable: 0,
1616
+ superseded: 0,
1617
+ "invalid-request": 0,
1618
+ "provider-rejected": 0,
1619
+ "invalid-subscription": 0,
1620
+ "delivery-hook-failed": 0
1621
+ };
1622
+ // The newest resolved join's outcome (see lastJoinOutcome) and the join
1623
+ // generation it belongs to. Generations are issued in start order, so a
1624
+ // join that resolves after a newer join has recorded leaves it standing.
1625
+ #lastJoinOutcome = void 0;
1626
+ #lastJoinOutcomeGeneration = 0;
1627
+ #droppedPidCounts = /* @__PURE__ */ new Map();
1628
+ // Accepted bytes per MMTP packet_id; see bytesReceivedForPacketIds. Each
1629
+ // value is a mutable cell, so the per-packet update is one lookup and an
1630
+ // in-place add: no insertion once the key exists, and no re-boxed number
1631
+ // per packet once a count outgrows the small-integer range.
1632
+ #acceptedBytesByPacketId = /* @__PURE__ */ new Map();
1633
+ #packetIds = null;
1634
+ // What the live join delivers with each accepted packet. A field, not a
1635
+ // listener closure, so an in-place admission change (setContext) applies
1636
+ // from the next packet on without rejoining.
1637
+ #context = void 0;
1638
+ // The live join's provider-side filter. An in-place widening must reach it,
1639
+ // or the provider never delivers the new ID; null without a live join.
1640
+ #providerFilter = null;
1641
+ // IDs an in-place update withdrew while the provider may still be
1642
+ // delivering them. Their late packets are still counted as filtered, but
1643
+ // they are the expected tail of a deliberate change, not a provisioning
1644
+ // fault, so they are counted apart and do not raise the unadvertised-PID
1645
+ // warning.
1646
+ #withdrawnPacketIds = /* @__PURE__ */ new Set();
1647
+ #withdrawnPacketIdDrops = 0;
1648
+ // Distinct packet IDs dropped as provisioning faults: on the wire but in
1649
+ // no allow-list the join or an in-place update declared. Capped with
1650
+ // droppedPacketIds.
1651
+ #unadvertisedPacketIds = /* @__PURE__ */ new Set();
1652
+ #joinGeneration = 0;
1653
+ constructor(onPacket) {
1654
+ this.#onPacket = onPacket;
1655
+ }
1656
+ static isAvailable() {
1657
+ return hasMulticastGateway();
1658
+ }
1659
+ async join(config, context) {
1660
+ const generation = ++this.#joinGeneration;
1661
+ this.#releaseSubscription();
1662
+ this.#dataPlaneLive = false;
1663
+ if (this.#disposed) return this.#declined(generation, "disposed");
1664
+ if (!_MulticastTransport.isAvailable()) {
1665
+ console.warn("[MulticastTransport] Multicast API not available");
1666
+ return this.#declined(generation, "unavailable");
1667
+ }
1668
+ let failure = "invalid-request";
1669
+ try {
1670
+ const packetIds = config.packetIds?.length ? new Set(config.packetIds) : null;
1671
+ console.log(
1672
+ `[MulticastTransport] window.multicast.subscribe(${config.sourceAddress}, ${config.groupAddress}, ${config.port})`
1673
+ );
1674
+ const subscribeConfig = toWindowMulticastSubscribeConfig({
1675
+ source: config.sourceAddress,
1676
+ group: config.groupAddress,
1677
+ port: config.port,
1678
+ mode: config.mode,
1679
+ amtRelay: config.amtRelay,
1680
+ amtRelayPort: config.amtRelayPort,
1681
+ packetIds: config.packetIds,
1682
+ tracks: config.tracks
1683
+ });
1684
+ failure = "provider-rejected";
1685
+ const subscription = await getMulticastGlobals().multicast.subscribe(subscribeConfig);
1686
+ failure = "invalid-subscription";
1687
+ console.log(`[MulticastTransport] window.multicast.subscribe returned:`, !!subscription);
1688
+ if (this.#disposed || generation !== this.#joinGeneration) {
1689
+ void subscription.unsubscribe();
1690
+ return this.#declined(generation, this.#displacedReason());
1691
+ }
1692
+ if (typeof subscription.addEventListener !== "function") {
1693
+ if (typeof subscription.unsubscribe === "function") {
1694
+ void subscription.unsubscribe();
1695
+ }
1696
+ throw new Error("window.multicast subscription does not support bytes events");
1697
+ }
1698
+ this.#subscription = subscription;
1699
+ const live = () => !this.#disposed && generation === this.#joinGeneration;
1700
+ const packetListener = subscriptionDeliversPacketBatches(subscription) ? {
1701
+ type: "packets",
1702
+ listener: (event) => {
1703
+ if (!live()) return;
1704
+ this.#deliverBatch(event.detail, live);
1705
+ }
1706
+ } : {
1707
+ type: "bytes",
1708
+ listener: (event) => {
1709
+ if (!live()) return;
1710
+ if (this.#deliver(event.detail)) this.#resetWatchdog();
1711
+ }
1712
+ };
1713
+ this.#packetListener = packetListener;
1714
+ this.#packetIds = packetIds;
1715
+ this.#providerFilter = {
1716
+ acknowledged: packetIds,
1717
+ sent: 0,
1718
+ acknowledgedUpdate: 0,
1719
+ inFlight: 0
1720
+ };
1721
+ this.#context = context;
1722
+ if (packetIds) {
1723
+ for (const packetId of packetIds) {
1724
+ if (!this.#acceptedBytesByPacketId.has(packetId)) {
1725
+ this.#acceptedBytesByPacketId.set(packetId, { bytes: 0 });
1726
+ }
1727
+ }
1728
+ }
1729
+ this.#resolvedTransport = subscribeConfig.origin === "amt" ? "amt" : "native";
1730
+ const delivery = subscription.delivery ?? "datagram";
1731
+ if (delivery !== "datagram" && delivery !== "ordered-relay") {
1732
+ throw new Error(
1733
+ `window.multicast subscription declared unknown delivery ${String(delivery)}`
1734
+ );
1735
+ }
1736
+ this.#delivery = delivery;
1737
+ failure = "delivery-hook-failed";
1738
+ this.#onDelivery?.(delivery);
1739
+ failure = "invalid-subscription";
1740
+ const onError = (event) => {
1741
+ if (this.#disposed || generation !== this.#joinGeneration) return;
1742
+ this.#failBackOnSubscriptionError(event.detail);
1743
+ };
1744
+ this.#errorListener = onError;
1745
+ if (packetListener.type === "packets") {
1746
+ subscription.addEventListener("packets", packetListener.listener);
1747
+ } else {
1748
+ subscription.addEventListener("bytes", packetListener.listener);
1749
+ }
1750
+ subscription.addEventListener("error", onError);
1751
+ console.log(
1752
+ `[MulticastTransport] Joined ${config.groupAddress}:${config.port}`
1753
+ );
1754
+ return this.#joined(generation);
1755
+ } catch (err) {
1756
+ if (this.#disposed || generation !== this.#joinGeneration) {
1757
+ return this.#declined(generation, this.#displacedReason());
1758
+ }
1759
+ this.#releaseSubscription();
1760
+ console.error("[MulticastTransport] Failed to join SSM group:", err);
1761
+ return this.#declined(
1762
+ generation,
1763
+ failure,
1764
+ failure === "provider-rejected" ? providerErrorOf(err) : void 0
1765
+ );
1766
+ }
1767
+ }
1768
+ /** Record a join that resolved true; returns its result. */
1769
+ #joined(generation) {
1770
+ this.#joinsSucceeded++;
1771
+ this.#recordJoinOutcome(generation, JOIN_SUCCEEDED);
1772
+ return true;
1773
+ }
1774
+ /** Record a join that resolved false, and why; returns its result. */
1775
+ #declined(generation, reason, providerError) {
1776
+ this.#joinsDeclined[reason]++;
1777
+ this.#recordJoinOutcome(
1778
+ generation,
1779
+ Object.freeze(
1780
+ providerError === void 0 ? { ok: false, reason } : { ok: false, reason, providerError }
1781
+ )
1782
+ );
1783
+ return false;
1784
+ }
1785
+ /**
1786
+ * Why a join that no longer owns the transport resolved false. dispose()
1787
+ * advances the join generation too, so disposal is checked first.
1788
+ */
1789
+ #displacedReason() {
1790
+ return this.#disposed ? "disposed" : "superseded";
1791
+ }
1792
+ #recordJoinOutcome(generation, outcome) {
1793
+ if (generation <= this.#lastJoinOutcomeGeneration) return;
1794
+ this.#lastJoinOutcomeGeneration = generation;
1795
+ this.#lastJoinOutcome = outcome;
1796
+ }
1797
+ /**
1798
+ * One packet from the subscription: filter, count, and hand it to the
1799
+ * callback. Returns whether it was delivered; the caller notes liveness.
1800
+ */
1801
+ #deliver(detail) {
1802
+ const packet = normalizeBytesEventDetail(detail);
1803
+ if (!packet) {
1804
+ this.#stats.packetsDroppedUnparseable++;
1805
+ return false;
1806
+ }
1807
+ if (!this.#acceptPacket(packet)) return false;
1808
+ this.#onPacket(packet, this.#context);
1809
+ return true;
1810
+ }
1811
+ /**
1812
+ * One `packets` event. Each packet is delivered as a `bytes` event would
1813
+ * have delivered it, including isolation: a packet whose callback throws
1814
+ * does not cost the rest of its batch, as it would not have cost the next
1815
+ * `bytes` event. The first failure is rethrown once the batch is done, so
1816
+ * it reaches the event-listener error reporting a `bytes` listener's throw
1817
+ * reached; any further one is rethrown from its own microtask, which the
1818
+ * host reports the same way, so no failure is swallowed. A callback that
1819
+ * disposes the transport or starts another join ends the batch there, as
1820
+ * the per-packet guard would have ignored the remaining events.
1821
+ */
1822
+ #deliverBatch(batch, live) {
1823
+ if (!Array.isArray(batch)) {
1824
+ throw new TypeError("[MulticastTransport] packets event detail must be an array of packets");
1825
+ }
1826
+ let delivered = false;
1827
+ let failures = null;
1828
+ for (let i = 0; i < batch.length; i++) {
1829
+ try {
1830
+ if (this.#deliver(batch[i])) delivered = true;
1831
+ } catch (error) {
1832
+ if (failures === null) failures = [];
1833
+ failures.push(error);
1834
+ }
1835
+ if (!live()) break;
1836
+ }
1837
+ if (delivered && live()) this.#resetWatchdog();
1838
+ if (failures !== null) {
1839
+ for (let i = 1; i < failures.length; i++) {
1840
+ const failure = failures[i];
1841
+ queueMicrotask(() => {
1842
+ throw failure;
1843
+ });
1844
+ }
1845
+ throw failures[0];
1846
+ }
1847
+ }
1848
+ /** Feed a raw packet from an external source (e.g., AMT tunnel or ASM subscription). */
1849
+ feedPacket(data, context) {
1850
+ if (this.#disposed) return;
1851
+ const packet = data instanceof Uint8Array ? data : new Uint8Array(data);
1852
+ if (!this.#acceptPacket(packet)) return;
1853
+ this.#onPacket(packet, context);
1854
+ this.#resetWatchdog();
1855
+ }
1856
+ confirmVideo() {
1857
+ this.#videoConfirmed = true;
1858
+ this.#checkTakeover();
1859
+ }
1860
+ confirmAudio() {
1861
+ this.#audioConfirmed = true;
1862
+ this.#checkTakeover();
1863
+ }
1864
+ onTakeover(cb) {
1865
+ this.#onTakeover = cb;
1866
+ }
1867
+ onFailback(cb) {
1868
+ this.#onFailback = cb;
1869
+ }
1870
+ /**
1871
+ * Called on every successful join, before the joined subscription can
1872
+ * deliver a packet, with how that subscription delivers packets.
1873
+ */
1874
+ onDelivery(cb) {
1875
+ this.#onDelivery = cb;
1876
+ }
1877
+ /** How the current subscription delivers packets, once joined. */
1878
+ get delivery() {
1879
+ return this.#delivery;
1880
+ }
1881
+ /**
1882
+ * Fires once per join, at the first packet the join accepts (after the PID
1883
+ * filter; a rejected packet is not liveness). This is the data-plane-live
1884
+ * edge, where this transport's silence window starts. A join whose source
1885
+ * never sends never reaches it, so a host may start a media-arrival budget
1886
+ * here only if the provider bounds the join phase with a typed subscription
1887
+ * error (see SessionManager.joinActive); otherwise the host starts it when
1888
+ * the subscribe settles.
1889
+ */
1890
+ onDataPlaneLive(cb) {
1891
+ this.#onDataPlaneLive = cb;
1892
+ }
1893
+ /** Whether the current join has accepted a packet (see onDataPlaneLive). */
1894
+ get dataPlaneLive() {
1895
+ return this.#dataPlaneLive;
1896
+ }
1897
+ setFailbackWindowMs(windowMs) {
1898
+ if (!Number.isFinite(windowMs) || windowMs <= 0) {
1899
+ throw new Error(
1900
+ `[MulticastTransport] failbackWindowMs=${windowMs}. Derive a positive failback window from the stream catalog.`
1901
+ );
1902
+ }
1903
+ this.#failbackWindowMs = windowMs;
1904
+ if (this.#watchdog !== null) {
1905
+ clearTimeout(this.#watchdog);
1906
+ const silentMs = performance.now() - this.#lastPacketAtMs;
1907
+ this.#armWatchdog(Math.max(0, Math.ceil(windowMs - silentMs)));
1908
+ }
1909
+ }
1910
+ get stats() {
1911
+ return this.#stats;
1912
+ }
1913
+ /**
1914
+ * How the newest join() to resolve did: `{ ok: true }`, or `{ ok: false }`
1915
+ * with the typed reason it resolved false (and, for `provider-rejected`, the
1916
+ * provider's typed error fields). Undefined until a join resolves. Branch on
1917
+ * `reason` and `providerError.code`, never on log text or
1918
+ * `providerError.message`.
1919
+ *
1920
+ * Newest is by start order: a join that resolves after a newer join has
1921
+ * recorded its outcome does not replace it, so once `await join()` resolves
1922
+ * this names that join's outcome unless a newer join has already resolved.
1923
+ * It records how a join resolved, not whether it is still joined (see
1924
+ * `joined`); a join() that rejects instead of resolving records nothing,
1925
+ * the rejection being its report. Frozen: a later outcome replaces the
1926
+ * object, never changes it.
1927
+ */
1928
+ get lastJoinOutcome() {
1929
+ return this.#lastJoinOutcome;
1930
+ }
1931
+ /**
1932
+ * join() calls by how they resolved (see MulticastJoinStats). A fresh frozen
1933
+ * snapshot on every read, so a later join never changes one already read.
1934
+ * Kept apart from `stats`, which is the live counter object.
1935
+ */
1936
+ get joinStats() {
1937
+ return Object.freeze({
1938
+ succeeded: this.#joinsSucceeded,
1939
+ declined: Object.freeze({ ...this.#joinsDeclined })
1940
+ });
1941
+ }
1942
+ /**
1943
+ * Accepted bytes summed over `packetIds`: the `bytesReceived` share of those
1944
+ * MMTP packet_ids. Counted by the same rule, on every path that counts
1945
+ * `bytesReceived` (only packets that pass the ingress filter; packet_id 0
1946
+ * signaling never), and cumulative for the life of the transport, across
1947
+ * rejoins, as `bytesReceived` is. An id never accepted contributes 0. An
1948
+ * unparseable packet admitted by a join without an allow-list has no
1949
+ * packet_id, so it counts toward `bytesReceived` only.
1950
+ *
1951
+ * Use it to scope an ABR throughput sample to the active tier's source and
1952
+ * repair packet_ids when the join admits more than the active tier (a
1953
+ * shared group joined across rendition switches); `bytesReceived` is then
1954
+ * the whole allow-list's arrival, not the active tier's. A Set, so an id
1955
+ * shared by two tracks of the tier is counted once.
1956
+ *
1957
+ * Monotonic only for a fixed set: each id has counted since it was first
1958
+ * admitted, so after a tier switch the new set's sum is not a continuation
1959
+ * of the old one. A cumulative consumer takes a fresh baseline for the new
1960
+ * set and never differences across sets.
1961
+ */
1962
+ bytesReceivedForPacketIds(packetIds) {
1963
+ let bytes = 0;
1964
+ for (const packetId of packetIds) {
1965
+ bytes += this.#acceptedBytesByPacketId.get(packetId)?.bytes ?? 0;
1966
+ }
1967
+ return bytes;
1968
+ }
1969
+ /**
1970
+ * Per-PID drop breakdown, newest-capped at MAX_TRACKED_DROPPED_PIDS distinct
1971
+ * PIDs. This is what names the offender: `packetsDroppedUnregisteredPid`
1972
+ * says the ingress filter fired, this says it fired on 0x8001.
1973
+ */
1974
+ get droppedPacketIds() {
1975
+ return this.#droppedPidCounts;
1976
+ }
1977
+ /**
1978
+ * Distinct packet IDs dropped as provisioning faults: arriving on the wire
1979
+ * but in no allow-list the join or an in-place update (setPacketIds)
1980
+ * declared, the drops that raise the unadvertised-PID warning. A packet ID
1981
+ * an in-place update withdrew is not one (see withdrawnPacketIdDrops).
1982
+ * Cumulative across rejoins and capped with droppedPacketIds.
1983
+ */
1984
+ get unadvertisedPacketIds() {
1985
+ return this.#unadvertisedPacketIds;
1986
+ }
1987
+ /**
1988
+ * Packets dropped because an in-place update (setPacketIds) withdrew their
1989
+ * packet ID while the provider may still deliver it: the expected tail of
1990
+ * a deliberate change. A subset of packetsDroppedUnregisteredPid,
1991
+ * cumulative across rejoins.
1992
+ */
1993
+ get withdrawnPacketIdDrops() {
1994
+ return this.#withdrawnPacketIdDrops;
1995
+ }
1996
+ /** Whether a subscription is live: joined, and not yet released or replaced. */
1997
+ get joined() {
1998
+ return this.#subscription !== null;
1999
+ }
2000
+ /**
2001
+ * What the live join delivers with every accepted packet (the join's
2002
+ * `context`, or the last setContext), or undefined without a live join.
2003
+ */
2004
+ get context() {
2005
+ return this.#context;
2006
+ }
2007
+ /**
2008
+ * The live join's page-side packet-ID allow-list, or null when it admits
2009
+ * every packet ID (a join that carried none, or no live join).
2010
+ */
2011
+ get packetIds() {
2012
+ return this.#packetIds;
2013
+ }
2014
+ /**
2015
+ * Replace what the live join delivers with each accepted packet, from the
2016
+ * next packet on. The subscription (socket, group membership, AMT tunnel)
2017
+ * is untouched: this is how an in-place rendition switch moves the router's
2018
+ * ingress identities without leaving and re-joining the group.
2019
+ */
2020
+ setContext(context) {
2021
+ if (this.#subscription === null) {
2022
+ throw new Error(
2023
+ "[MulticastTransport] setContext needs a live join; join() carries the first context"
2024
+ );
2025
+ }
2026
+ this.#context = context;
2027
+ }
2028
+ /**
2029
+ * Replace the live join's packet-ID allow-list in place, without rejoining.
2030
+ *
2031
+ * The page-side filter changes synchronously, before this returns: the
2032
+ * next packet is admitted or dropped by the new list. The provider's own
2033
+ * filter is updated through the subscription's `setPacketIds` when it has
2034
+ * one; the returned promise settles with the provider's acknowledgement of
2035
+ * this update. It resolves at once, telling the provider nothing, only
2036
+ * when the provider cannot be told, or when no earlier update is still in
2037
+ * flight and the provider already forwards exactly this list.
2038
+ *
2039
+ * While an update is in flight the provider's filter is not known, so every
2040
+ * later update is sent: one skipped because it matched the last
2041
+ * acknowledged filter would let the in-flight update land after it, and
2042
+ * leave the provider forwarding a list nobody asked for last. Updates are
2043
+ * numbered in send order and the newest acknowledged one describes the
2044
+ * provider, so an acknowledgement that overtakes an older one is not undone
2045
+ * by it.
2046
+ *
2047
+ * A provider without `setPacketIds` can still be narrowed: its wider filter
2048
+ * keeps delivering the dropped IDs and the page-side filter discards them.
2049
+ * It cannot be widened, since it would never deliver the added IDs; that is
2050
+ * refused with a throw before anything changes. An ID this update withdraws
2051
+ * may keep arriving until the provider applies the narrower list; those
2052
+ * packets are counted as filtered like any other and in
2053
+ * withdrawnPacketIdDrops, but are not unadvertised packet IDs: their
2054
+ * arrival is the expected tail of this change rather than a provisioning
2055
+ * fault.
2056
+ */
2057
+ setPacketIds(packetIds) {
2058
+ const subscription = this.#subscription;
2059
+ const filter = this.#providerFilter;
2060
+ if (subscription === null || filter === null) {
2061
+ throw new Error(
2062
+ "[MulticastTransport] setPacketIds needs a live join; join() carries the first allow-list"
2063
+ );
2064
+ }
2065
+ if (!Array.isArray(packetIds) || packetIds.length === 0) {
2066
+ throw new RangeError(
2067
+ "[MulticastTransport] setPacketIds needs a non-empty packet-ID list: an in-place update names the packet IDs it admits"
2068
+ );
2069
+ }
2070
+ if (!packetIds.every(isMulticastTrackPacketId)) {
2071
+ throw new RangeError(
2072
+ `[MulticastTransport] packetId must be an integer from 1 to ${MMTP_PACKET_ID_MAX2}; packetId 0 is the MMTP signaling flow and is never a track's`
2073
+ );
2074
+ }
2075
+ const next = new Set(packetIds);
2076
+ const provider = filter.acknowledged;
2077
+ const update = packetFilterUpdater(subscription);
2078
+ if (update === void 0 && provider !== null) {
2079
+ const missing = [...next].filter((id) => !provider.has(id));
2080
+ if (missing.length > 0) {
2081
+ throw new Error(
2082
+ `[MulticastTransport] this subscription cannot widen its packet filter in place (the provider exposes no setPacketIds); rejoin to admit ${missing.join(", ")}`
2083
+ );
2084
+ }
2085
+ }
2086
+ const previous = this.#packetIds;
2087
+ this.#packetIds = next;
2088
+ for (const id of next) {
2089
+ this.#withdrawnPacketIds.delete(id);
2090
+ if (!this.#acceptedBytesByPacketId.has(id)) {
2091
+ this.#acceptedBytesByPacketId.set(id, { bytes: 0 });
2092
+ }
2093
+ }
2094
+ if (previous !== null) {
2095
+ for (const id of previous) if (!next.has(id)) this.#withdrawnPacketIds.add(id);
2096
+ }
2097
+ if (update === void 0) return Promise.resolve();
2098
+ if (filter.inFlight === 0 && provider !== null && sameIds(provider, next)) {
2099
+ return Promise.resolve();
2100
+ }
2101
+ const number = ++filter.sent;
2102
+ filter.inFlight++;
2103
+ let applied;
2104
+ try {
2105
+ applied = Promise.resolve(update([...next]));
2106
+ } catch (error) {
2107
+ applied = Promise.reject(error);
2108
+ }
2109
+ return applied.then(
2110
+ () => {
2111
+ if (this.#providerFilter !== filter) return;
2112
+ filter.inFlight--;
2113
+ if (number > filter.acknowledgedUpdate) {
2114
+ filter.acknowledgedUpdate = number;
2115
+ filter.acknowledged = next;
2116
+ }
2117
+ },
2118
+ (error) => {
2119
+ if (this.#providerFilter === filter) filter.inFlight--;
2120
+ throw error;
2121
+ }
2122
+ );
2123
+ }
2124
+ get resolvedTransport() {
2125
+ return this.#resolvedTransport;
2126
+ }
2127
+ dispose() {
2128
+ ++this.#joinGeneration;
2129
+ this.#disposed = true;
2130
+ this.#releaseSubscription();
2131
+ }
2132
+ #releaseSubscription() {
2133
+ if (this.#watchdog) clearTimeout(this.#watchdog);
2134
+ this.#watchdog = null;
2135
+ if (this.#subscription) {
2136
+ const packetListener = this.#packetListener;
2137
+ if (packetListener?.type === "packets") {
2138
+ this.#subscription.removeEventListener("packets", packetListener.listener);
2139
+ } else if (packetListener) {
2140
+ this.#subscription.removeEventListener("bytes", packetListener.listener);
2141
+ }
2142
+ if (this.#errorListener) {
2143
+ this.#subscription.removeEventListener("error", this.#errorListener);
2144
+ }
2145
+ void this.#subscription.unsubscribe();
2146
+ }
2147
+ this.#subscription = null;
2148
+ this.#packetListener = null;
2149
+ this.#errorListener = null;
2150
+ this.#resolvedTransport = void 0;
2151
+ this.#delivery = void 0;
2152
+ this.#packetIds = null;
2153
+ this.#providerFilter = null;
2154
+ this.#context = void 0;
2155
+ this.#withdrawnPacketIds.clear();
2156
+ }
2157
+ /** The ingress filter; an accepted packet is counted here, once. */
2158
+ #acceptPacket(packet) {
2159
+ const packetId = readMMTPPacketId(packet);
2160
+ if (packetId === null) {
2161
+ if (!this.#packetIds) {
2162
+ this.#countAccepted(packet, null);
2163
+ return true;
2164
+ }
2165
+ this.#stats.packetsDroppedUnparseable++;
2166
+ return false;
2167
+ }
2168
+ if (packetId === MMTP_SIGNALING_PACKET_ID2) {
2169
+ this.#stats.packetsDroppedSignaling++;
2170
+ return false;
2171
+ }
2172
+ if (!this.#packetIds || this.#packetIds.has(packetId)) {
2173
+ this.#countAccepted(packet, packetId);
2174
+ return true;
2175
+ }
2176
+ this.#recordUnregisteredPidDrop(packetId);
2177
+ return false;
2178
+ }
2179
+ /** Receive counters for one accepted packet; `packetId` is null when it has none. */
2180
+ #countAccepted(packet, packetId) {
2181
+ this.#stats.packetsReceived++;
2182
+ this.#stats.bytesReceived += packet.byteLength;
2183
+ if (packetId === null) return;
2184
+ const counter = this.#acceptedBytesByPacketId.get(packetId);
2185
+ if (counter !== void 0) {
2186
+ counter.bytes += packet.byteLength;
2187
+ } else {
2188
+ this.#acceptedBytesByPacketId.set(packetId, { bytes: packet.byteLength });
2189
+ }
2190
+ }
2191
+ #recordUnregisteredPidDrop(packetId) {
2192
+ this.#stats.packetsDroppedUnregisteredPid++;
2193
+ const withdrawn = this.#withdrawnPacketIds.has(packetId);
2194
+ if (withdrawn) this.#withdrawnPacketIdDrops++;
2195
+ const seen = this.#droppedPidCounts.get(packetId);
2196
+ if (seen !== void 0) {
2197
+ this.#droppedPidCounts.set(packetId, seen + 1);
2198
+ return;
2199
+ }
2200
+ if (this.#droppedPidCounts.size >= MAX_TRACKED_DROPPED_PIDS) return;
2201
+ this.#droppedPidCounts.set(packetId, 1);
2202
+ if (withdrawn) return;
2203
+ this.#unadvertisedPacketIds.add(packetId);
2204
+ console.warn(
2205
+ `[MulticastTransport] Dropping packetId=${packetId} (0x${packetId.toString(16)}): not in the advertised set [${[...this.#packetIds ?? []].join(", ")}]. If this is an FEC repair leg, the catalog is not advertising its packetId.`
2206
+ );
2207
+ }
2208
+ #checkTakeover() {
2209
+ if (this.#videoConfirmed && this.#audioConfirmed && this.#onTakeover) {
2210
+ const cb = this.#onTakeover;
2211
+ this.#onTakeover = null;
2212
+ cb();
2213
+ }
2214
+ }
2215
+ /**
2216
+ * Note liveness now; arm the no-packets timer if none is armed.
2217
+ *
2218
+ * Called only for accepted packets, so the first call of a join is the
2219
+ * data-plane-live edge and is what first arms the silence window: the window
2220
+ * measures silence of a flowing stream, which is undefined before the stream
2221
+ * has flowed.
2222
+ */
2223
+ #resetWatchdog() {
2224
+ this.#lastPacketAtMs = performance.now();
2225
+ if (!this.#dataPlaneLive) {
2226
+ this.#dataPlaneLive = true;
2227
+ this.#onDataPlaneLive?.();
2228
+ }
2229
+ if (this.#watchdog !== null) return;
2230
+ if (!this.#onFailback) return;
2231
+ if (this.#failbackWindowMs === null) {
2232
+ throw new Error(
2233
+ "[MulticastTransport] Failback watchdog requires a catalog-derived window"
2234
+ );
2235
+ }
2236
+ this.#armWatchdog(this.#failbackWindowMs);
2237
+ }
2238
+ #armWatchdog(delayMs) {
2239
+ this.#watchdog = setTimeout(() => {
2240
+ this.#watchdog = null;
2241
+ if (this.#disposed || !this.#onFailback || this.#failbackWindowMs === null) return;
2242
+ const silentMs = performance.now() - this.#lastPacketAtMs;
2243
+ if (silentMs < this.#failbackWindowMs) {
2244
+ this.#armWatchdog(Math.ceil(this.#failbackWindowMs - silentMs));
2245
+ return;
2246
+ }
2247
+ console.warn(
2248
+ `[MulticastTransport] No packets for ${this.#failbackWindowMs}ms; failing back to MoQ`
2249
+ );
2250
+ this.#onFailback({ kind: "silence", windowMs: this.#failbackWindowMs });
2251
+ }, delayMs);
2252
+ }
2253
+ /** Hand control back to MoQ for a provider-reported subscription failure. */
2254
+ #failBackOnSubscriptionError(error) {
2255
+ if (this.#watchdog !== null) clearTimeout(this.#watchdog);
2256
+ this.#watchdog = null;
2257
+ console.warn("[MulticastTransport] Subscription failed; failing back to MoQ:", error);
2258
+ this.#onFailback?.({ kind: "subscription-error", error });
2259
+ }
2260
+ };
2261
+ export {
2262
+ MulticastTransport
2263
+ };
2264
+ //# sourceMappingURL=multicast-transport.js.map