@blockcast/mmt-container 0.3.0 → 0.4.0-main.1cd3cdea89da

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 (605) hide show
  1. package/README.md +33 -16
  2. package/dist/browser-runtime.js +14814 -14255
  3. package/dist/browser-runtime.js.map +4 -4
  4. package/dist/carp-catalog.d.ts +24 -19
  5. package/dist/carp-catalog.d.ts.map +1 -1
  6. package/dist/carp-catalog.js +29 -14
  7. package/dist/carp-catalog.js.map +4 -4
  8. package/dist/catalog-fec-params.d.ts +88 -28
  9. package/dist/catalog-fec-params.d.ts.map +1 -1
  10. package/dist/catalog-fec-params.js +60 -23
  11. package/dist/catalog-fec-params.js.map +4 -4
  12. package/dist/catalog-network-source.js +1 -7
  13. package/dist/catalog-network-source.js.map +4 -4
  14. package/dist/cmaf-block-assembler.d.ts +0 -2
  15. package/dist/cmaf-block-assembler.d.ts.map +1 -1
  16. package/dist/cmaf-block-assembler.js +0 -1
  17. package/dist/cmaf-block-assembler.js.map +2 -2
  18. package/dist/cmcd-producer.d.ts.map +1 -1
  19. package/dist/cmcd-producer.js +0 -4
  20. package/dist/cmcd-producer.js.map +2 -2
  21. package/dist/delivery-catalog.d.ts +124 -0
  22. package/dist/delivery-catalog.d.ts.map +1 -0
  23. package/dist/delivery-catalog.js +1857 -0
  24. package/dist/delivery-catalog.js.map +7 -0
  25. package/dist/delta-fallback-config.d.ts +42 -0
  26. package/dist/delta-fallback-config.d.ts.map +1 -0
  27. package/dist/delta-fallback-config.js +59 -0
  28. package/dist/delta-fallback-config.js.map +7 -0
  29. package/dist/fec-manager.d.ts +52 -30
  30. package/dist/fec-manager.d.ts.map +1 -1
  31. package/dist/fec-manager.js +338 -293
  32. package/dist/fec-manager.js.map +4 -4
  33. package/dist/fec-state.d.ts +19 -31
  34. package/dist/fec-state.d.ts.map +1 -1
  35. package/dist/fec-state.js +4 -10
  36. package/dist/fec-state.js.map +4 -4
  37. package/dist/fec-worker-setup.d.ts +18 -14
  38. package/dist/fec-worker-setup.d.ts.map +1 -1
  39. package/dist/fec-worker-setup.js +81 -96
  40. package/dist/fec-worker-setup.js.map +4 -4
  41. package/dist/index.d.ts +5 -3
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/index.js +16 -0
  44. package/dist/index.js.map +2 -2
  45. package/dist/iso-block-locator.js +1 -7
  46. package/dist/iso-block-locator.js.map +4 -4
  47. package/dist/media-router.d.ts +20 -8
  48. package/dist/media-router.d.ts.map +1 -1
  49. package/dist/media-router.js +46 -21
  50. package/dist/media-router.js.map +2 -2
  51. package/dist/mfu-reassembler.js +24 -30
  52. package/dist/mfu-reassembler.js.map +4 -4
  53. package/dist/mmtp-container-parser.d.ts +14 -11
  54. package/dist/mmtp-container-parser.d.ts.map +1 -1
  55. package/dist/mmtp-container-parser.js +126 -99
  56. package/dist/mmtp-container-parser.js.map +4 -4
  57. package/dist/mmtp-container-parser.no-modules.js +151 -108
  58. package/dist/mmtp-container-parser.no-modules.js.map +4 -4
  59. package/dist/mmtp-decode-pipeline.js +126 -99
  60. package/dist/mmtp-decode-pipeline.js.map +4 -4
  61. package/dist/mmtp-router.d.ts +51 -29
  62. package/dist/mmtp-router.d.ts.map +1 -1
  63. package/dist/mmtp-router.js +260 -326
  64. package/dist/mmtp-router.js.map +4 -4
  65. package/dist/multicast-input.js +1 -7
  66. package/dist/multicast-input.js.map +4 -4
  67. package/dist/multicast-manager.d.ts +72 -6
  68. package/dist/multicast-manager.d.ts.map +1 -1
  69. package/dist/multicast-manager.js +882 -673
  70. package/dist/multicast-manager.js.map +4 -4
  71. package/dist/multicast-transport.d.ts +1 -1
  72. package/dist/multicast-transport.d.ts.map +1 -1
  73. package/dist/multicast-transport.js +44 -26
  74. package/dist/multicast-transport.js.map +4 -4
  75. package/dist/multicast-unwrap.js +29 -35
  76. package/dist/multicast-unwrap.js.map +4 -4
  77. package/dist/no-modules.js +147 -106
  78. package/dist/no-modules.js.map +4 -4
  79. package/dist/repair-fetch.d.ts +116 -21
  80. package/dist/repair-fetch.d.ts.map +1 -1
  81. package/dist/repair-fetch.js +114 -34
  82. package/dist/repair-fetch.js.map +4 -4
  83. package/dist/repair-layers.d.ts +18 -7
  84. package/dist/repair-layers.d.ts.map +1 -1
  85. package/dist/repair-layers.js +12 -10
  86. package/dist/repair-layers.js.map +4 -4
  87. package/dist/signaling.js +2 -11
  88. package/dist/signaling.js.map +4 -4
  89. package/dist/timestamp-codec.js +24 -30
  90. package/dist/timestamp-codec.js.map +4 -4
  91. package/dist/track-session.d.ts +7 -0
  92. package/dist/track-session.d.ts.map +1 -1
  93. package/dist/track-session.js +15 -8
  94. package/dist/track-session.js.map +2 -2
  95. package/dist/wasm-mfu-reassembler.js +1 -7
  96. package/dist/wasm-mfu-reassembler.js.map +4 -4
  97. package/dist/wasm-mmtp-container-parser.js +126 -99
  98. package/dist/wasm-mmtp-container-parser.js.map +4 -4
  99. package/package.json +7 -14
  100. package/schemas/catalog.schema.json +3 -3
  101. package/src/carp-catalog.ts +46 -24
  102. package/src/catalog-fec-params.ts +173 -64
  103. package/src/cmaf-block-assembler.ts +1 -4
  104. package/src/cmcd-producer.ts +0 -6
  105. package/src/delivery-catalog.ts +498 -0
  106. package/src/delta-fallback-config.ts +72 -0
  107. package/src/fec-manager.ts +457 -334
  108. package/src/fec-state.ts +20 -32
  109. package/src/fec-worker-setup.ts +109 -90
  110. package/src/index.ts +32 -0
  111. package/src/media-router.ts +59 -21
  112. package/src/mmtp-container-parser.ts +106 -20
  113. package/src/mmtp-router.ts +189 -330
  114. package/src/multicast-manager.ts +265 -86
  115. package/src/multicast-transport.ts +16 -9
  116. package/src/repair-fetch.ts +273 -43
  117. package/src/repair-layers.ts +28 -8
  118. package/src/track-session.ts +28 -9
  119. package/test-vectors/catalog/README.md +37 -17
  120. package/test-vectors/catalog/negative/fec-block-profile-retired.json +52 -0
  121. package/test-vectors/catalog/negative/fec-enhancement-repair-removed.json +1 -1
  122. package/test-vectors/catalog/negative/fec-repair-layer-geometry.json +1 -1
  123. package/test-vectors/catalog/negative/fec-repair-layer-missing-symbols.json +1 -1
  124. package/test-vectors/catalog/negative/fec-repair-multiple-depends.json +1 -1
  125. package/test-vectors/catalog/negative/fec-repair-overlay-with-layer.json +1 -1
  126. package/test-vectors/catalog/negative/fec-repair-priority-out-of-band.json +1 -1
  127. package/test-vectors/catalog/negative/fec-repair-source-symbols-without-scope.json +1 -1
  128. package/test-vectors/catalog/negative/multicast-endpoint-relay-address.json +39 -0
  129. package/test-vectors/catalog/negative/multicast-network-source-empty.json +1 -1
  130. package/test-vectors/catalog/negative/raptorq-source-symbols-over-max.json +1 -1
  131. package/test-vectors/catalog/negative/raptorq-unaligned-symbol.json +1 -1
  132. package/test-vectors/catalog/positive/fec-layered-repair.json +2 -2
  133. package/test-vectors/catalog/positive/fec-multicast.json +2 -1
  134. package/test-vectors/catalog/positive/multicast-amt-manual-relay.json +38 -0
  135. package/test-vectors/catalog/positive/multicast-native-ssm-no-network-source.json +2 -1
  136. package/test-vectors/catalog-timing.json +356 -0
  137. package/test-vectors/catalog-validation.json +40 -5
  138. package/test-vectors/delivery-catalog/README.md +11 -0
  139. package/test-vectors/delivery-catalog/negative/missing-block-profile.json +58 -0
  140. package/test-vectors/delivery-catalog/negative/packet-id-signaling.json +59 -0
  141. package/test-vectors/delivery-catalog/negative/retired-k-padded-block-profile.json +59 -0
  142. package/test-vectors/delivery-catalog/positive/dash.json +56 -0
  143. package/test-vectors/delivery-catalog/positive/mmtp-source-only.json +43 -0
  144. package/node_modules/@blockcast/fec-worker/README.md +0 -223
  145. package/node_modules/@blockcast/fec-worker/dist/.build-stamp +0 -0
  146. package/node_modules/@blockcast/fec-worker/dist/block-order.d.ts +0 -38
  147. package/node_modules/@blockcast/fec-worker/dist/block-order.d.ts.map +0 -1
  148. package/node_modules/@blockcast/fec-worker/dist/block-order.js +0 -78
  149. package/node_modules/@blockcast/fec-worker/dist/block-order.js.map +0 -1
  150. package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.d.ts +0 -93
  151. package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.d.ts.map +0 -1
  152. package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.js +0 -346
  153. package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.js.map +0 -1
  154. package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.d.ts +0 -380
  155. package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.d.ts.map +0 -1
  156. package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.js +0 -11
  157. package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.js.map +0 -1
  158. package/node_modules/@blockcast/fec-worker/dist/fec-worker.d.ts +0 -14
  159. package/node_modules/@blockcast/fec-worker/dist/fec-worker.d.ts.map +0 -1
  160. package/node_modules/@blockcast/fec-worker/dist/fec-worker.js +0 -859
  161. package/node_modules/@blockcast/fec-worker/dist/fec-worker.js.map +0 -7
  162. package/node_modules/@blockcast/fec-worker/dist/index.d.ts +0 -10
  163. package/node_modules/@blockcast/fec-worker/dist/index.d.ts.map +0 -1
  164. package/node_modules/@blockcast/fec-worker/dist/index.js +0 -8
  165. package/node_modules/@blockcast/fec-worker/dist/index.js.map +0 -1
  166. package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.d.ts +0 -20
  167. package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.d.ts.map +0 -1
  168. package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.js +0 -370
  169. package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.js.map +0 -7
  170. package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.d.ts +0 -104
  171. package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.d.ts.map +0 -1
  172. package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.js +0 -181
  173. package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.js.map +0 -1
  174. package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.d.ts +0 -194
  175. package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.d.ts.map +0 -1
  176. package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.js +0 -62
  177. package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.js.map +0 -1
  178. package/node_modules/@blockcast/fec-worker/dist/transfer.d.ts +0 -9
  179. package/node_modules/@blockcast/fec-worker/dist/transfer.d.ts.map +0 -1
  180. package/node_modules/@blockcast/fec-worker/dist/transfer.js +0 -13
  181. package/node_modules/@blockcast/fec-worker/dist/transfer.js.map +0 -1
  182. package/node_modules/@blockcast/fec-worker/package.json +0 -59
  183. package/node_modules/@blockcast/fec-worker/src/block-order.ts +0 -93
  184. package/node_modules/@blockcast/fec-worker/src/fec-worker-client.ts +0 -392
  185. package/node_modules/@blockcast/fec-worker/src/fec-worker-types.ts +0 -399
  186. package/node_modules/@blockcast/fec-worker/src/fec-worker.ts +0 -1502
  187. package/node_modules/@blockcast/fec-worker/src/index.ts +0 -35
  188. package/node_modules/@blockcast/fec-worker/src/shred-fec-worker.ts +0 -589
  189. package/node_modules/@blockcast/fec-worker/src/shred-worker-client.ts +0 -222
  190. package/node_modules/@blockcast/fec-worker/src/shred-worker-types.ts +0 -209
  191. package/node_modules/@blockcast/fec-worker/src/transfer.ts +0 -12
  192. package/node_modules/@blockcast/mmt-alta-parse/README.md +0 -181
  193. package/node_modules/@blockcast/mmt-alta-parse/dist/.build-stamp +0 -0
  194. package/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts +0 -57
  195. package/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts.map +0 -1
  196. package/node_modules/@blockcast/mmt-alta-parse/dist/index.js +0 -115
  197. package/node_modules/@blockcast/mmt-alta-parse/dist/index.js.map +0 -1
  198. package/node_modules/@blockcast/mmt-alta-parse/package.json +0 -50
  199. package/node_modules/@blockcast/mmt-alta-parse/src/index.ts +0 -136
  200. package/node_modules/@blockcast/mmt-base/README.md +0 -134
  201. package/node_modules/@blockcast/mmt-base/dist/.build-stamp +0 -0
  202. package/node_modules/@blockcast/mmt-base/dist/fec-block-profile.d.ts +0 -55
  203. package/node_modules/@blockcast/mmt-base/dist/fec-block-profile.d.ts.map +0 -1
  204. package/node_modules/@blockcast/mmt-base/dist/fec-block-profile.js +0 -128
  205. package/node_modules/@blockcast/mmt-base/dist/fec-block-profile.js.map +0 -1
  206. package/node_modules/@blockcast/mmt-base/dist/index.d.ts +0 -7
  207. package/node_modules/@blockcast/mmt-base/dist/index.d.ts.map +0 -1
  208. package/node_modules/@blockcast/mmt-base/dist/index.js +0 -7
  209. package/node_modules/@blockcast/mmt-base/dist/index.js.map +0 -1
  210. package/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts +0 -292
  211. package/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts.map +0 -1
  212. package/node_modules/@blockcast/mmt-base/dist/mmtp.js +0 -612
  213. package/node_modules/@blockcast/mmt-base/dist/mmtp.js.map +0 -1
  214. package/node_modules/@blockcast/mmt-base/dist/net-constants.d.ts +0 -18
  215. package/node_modules/@blockcast/mmt-base/dist/net-constants.d.ts.map +0 -1
  216. package/node_modules/@blockcast/mmt-base/dist/net-constants.js +0 -18
  217. package/node_modules/@blockcast/mmt-base/dist/net-constants.js.map +0 -1
  218. package/node_modules/@blockcast/mmt-base/dist/ntp-short.d.ts +0 -47
  219. package/node_modules/@blockcast/mmt-base/dist/ntp-short.d.ts.map +0 -1
  220. package/node_modules/@blockcast/mmt-base/dist/ntp-short.js +0 -54
  221. package/node_modules/@blockcast/mmt-base/dist/ntp-short.js.map +0 -1
  222. package/node_modules/@blockcast/mmt-base/dist/serial-number.d.ts +0 -57
  223. package/node_modules/@blockcast/mmt-base/dist/serial-number.d.ts.map +0 -1
  224. package/node_modules/@blockcast/mmt-base/dist/serial-number.js +0 -98
  225. package/node_modules/@blockcast/mmt-base/dist/serial-number.js.map +0 -1
  226. package/node_modules/@blockcast/mmt-base/dist/signalling.d.ts +0 -312
  227. package/node_modules/@blockcast/mmt-base/dist/signalling.d.ts.map +0 -1
  228. package/node_modules/@blockcast/mmt-base/dist/signalling.js +0 -637
  229. package/node_modules/@blockcast/mmt-base/dist/signalling.js.map +0 -1
  230. package/node_modules/@blockcast/mmt-base/package.json +0 -49
  231. package/node_modules/@blockcast/mmt-base/src/fec-block-profile.ts +0 -145
  232. package/node_modules/@blockcast/mmt-base/src/index.ts +0 -6
  233. package/node_modules/@blockcast/mmt-base/src/mmtp.ts +0 -892
  234. package/node_modules/@blockcast/mmt-base/src/net-constants.ts +0 -17
  235. package/node_modules/@blockcast/mmt-base/src/ntp-short.ts +0 -67
  236. package/node_modules/@blockcast/mmt-base/src/serial-number.ts +0 -107
  237. package/node_modules/@blockcast/mmt-base/src/signalling.ts +0 -862
  238. package/node_modules/@blockcast/mmt-fec/README.md +0 -271
  239. package/node_modules/@blockcast/mmt-fec/dist/.build-stamp +0 -0
  240. package/node_modules/@blockcast/mmt-fec/dist/block-manager.d.ts +0 -82
  241. package/node_modules/@blockcast/mmt-fec/dist/block-manager.d.ts.map +0 -1
  242. package/node_modules/@blockcast/mmt-fec/dist/block-manager.js +0 -296
  243. package/node_modules/@blockcast/mmt-fec/dist/block-manager.js.map +0 -1
  244. package/node_modules/@blockcast/mmt-fec/dist/block-processor.d.ts +0 -106
  245. package/node_modules/@blockcast/mmt-fec/dist/block-processor.d.ts.map +0 -1
  246. package/node_modules/@blockcast/mmt-fec/dist/block-processor.js +0 -288
  247. package/node_modules/@blockcast/mmt-fec/dist/block-processor.js.map +0 -1
  248. package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.d.ts +0 -46
  249. package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.d.ts.map +0 -1
  250. package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.js +0 -96
  251. package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.js.map +0 -1
  252. package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.d.ts +0 -33
  253. package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.d.ts.map +0 -1
  254. package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.js +0 -57
  255. package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.js.map +0 -1
  256. package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.d.ts +0 -205
  257. package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.d.ts.map +0 -1
  258. package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.js +0 -240
  259. package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.js.map +0 -1
  260. package/node_modules/@blockcast/mmt-fec/dist/index.d.ts +0 -28
  261. package/node_modules/@blockcast/mmt-fec/dist/index.d.ts.map +0 -1
  262. package/node_modules/@blockcast/mmt-fec/dist/index.js +0 -28
  263. package/node_modules/@blockcast/mmt-fec/dist/index.js.map +0 -1
  264. package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.d.ts +0 -20
  265. package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.d.ts.map +0 -1
  266. package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.js +0 -28
  267. package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.js.map +0 -1
  268. package/node_modules/@blockcast/mmt-fec/dist/oti.d.ts +0 -258
  269. package/node_modules/@blockcast/mmt-fec/dist/oti.d.ts.map +0 -1
  270. package/node_modules/@blockcast/mmt-fec/dist/oti.js +0 -382
  271. package/node_modules/@blockcast/mmt-fec/dist/oti.js.map +0 -1
  272. package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.d.ts +0 -41
  273. package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.d.ts.map +0 -1
  274. package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.js +0 -81
  275. package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.js.map +0 -1
  276. package/node_modules/@blockcast/mmt-fec/dist/repair-group.d.ts +0 -82
  277. package/node_modules/@blockcast/mmt-fec/dist/repair-group.d.ts.map +0 -1
  278. package/node_modules/@blockcast/mmt-fec/dist/repair-group.js +0 -170
  279. package/node_modules/@blockcast/mmt-fec/dist/repair-group.js.map +0 -1
  280. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/README.md +0 -181
  281. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/.build-stamp +0 -0
  282. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts +0 -57
  283. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts.map +0 -1
  284. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.js +0 -115
  285. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.js.map +0 -1
  286. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/package.json +0 -50
  287. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/src/index.ts +0 -136
  288. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/README.md +0 -134
  289. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/.build-stamp +0 -0
  290. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/fec-block-profile.d.ts +0 -55
  291. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/fec-block-profile.d.ts.map +0 -1
  292. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/fec-block-profile.js +0 -128
  293. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/fec-block-profile.js.map +0 -1
  294. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.d.ts +0 -7
  295. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.d.ts.map +0 -1
  296. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.js +0 -7
  297. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.js.map +0 -1
  298. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts +0 -292
  299. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts.map +0 -1
  300. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.js +0 -612
  301. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.js.map +0 -1
  302. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/net-constants.d.ts +0 -18
  303. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/net-constants.d.ts.map +0 -1
  304. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/net-constants.js +0 -18
  305. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/net-constants.js.map +0 -1
  306. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/ntp-short.d.ts +0 -47
  307. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/ntp-short.d.ts.map +0 -1
  308. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/ntp-short.js +0 -54
  309. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/ntp-short.js.map +0 -1
  310. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/serial-number.d.ts +0 -57
  311. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/serial-number.d.ts.map +0 -1
  312. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/serial-number.js +0 -98
  313. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/serial-number.js.map +0 -1
  314. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/signalling.d.ts +0 -312
  315. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/signalling.d.ts.map +0 -1
  316. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/signalling.js +0 -637
  317. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/signalling.js.map +0 -1
  318. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/package.json +0 -49
  319. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/fec-block-profile.ts +0 -145
  320. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/index.ts +0 -6
  321. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/mmtp.ts +0 -892
  322. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/net-constants.ts +0 -17
  323. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/ntp-short.ts +0 -67
  324. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/serial-number.ts +0 -107
  325. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/signalling.ts +0 -862
  326. package/node_modules/@blockcast/mmt-fec/package.json +0 -79
  327. package/node_modules/@blockcast/mmt-fec/src/block-manager.ts +0 -371
  328. package/node_modules/@blockcast/mmt-fec/src/block-processor.ts +0 -439
  329. package/node_modules/@blockcast/mmt-fec/src/cmaf-recovery.ts +0 -127
  330. package/node_modules/@blockcast/mmt-fec/src/cmaf-symbols.ts +0 -68
  331. package/node_modules/@blockcast/mmt-fec/src/fec-block-mapper.ts +0 -310
  332. package/node_modules/@blockcast/mmt-fec/src/index.ts +0 -94
  333. package/node_modules/@blockcast/mmt-fec/src/loc-symbols.ts +0 -34
  334. package/node_modules/@blockcast/mmt-fec/src/oti.ts +0 -463
  335. package/node_modules/@blockcast/mmt-fec/src/reorder-buffer.ts +0 -101
  336. package/node_modules/@blockcast/mmt-fec/src/repair-group.ts +0 -195
  337. package/node_modules/@blockcast/mmt-manifest-verify/dist/.build-stamp +0 -0
  338. package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.d.ts +0 -28
  339. package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.d.ts.map +0 -1
  340. package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.js +0 -128
  341. package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.js.map +0 -1
  342. package/node_modules/@blockcast/mmt-manifest-verify/dist/index.d.ts +0 -4
  343. package/node_modules/@blockcast/mmt-manifest-verify/dist/index.d.ts.map +0 -1
  344. package/node_modules/@blockcast/mmt-manifest-verify/dist/index.js +0 -4
  345. package/node_modules/@blockcast/mmt-manifest-verify/dist/index.js.map +0 -1
  346. package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.d.ts +0 -37
  347. package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.d.ts.map +0 -1
  348. package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.js +0 -179
  349. package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.js.map +0 -1
  350. package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.d.ts +0 -99
  351. package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.d.ts.map +0 -1
  352. package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.js +0 -492
  353. package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.js.map +0 -1
  354. package/node_modules/@blockcast/mmt-manifest-verify/package.json +0 -45
  355. package/node_modules/@blockcast/mmt-manifest-verify/src/admission.ts +0 -171
  356. package/node_modules/@blockcast/mmt-manifest-verify/src/index.ts +0 -3
  357. package/node_modules/@blockcast/mmt-manifest-verify/src/source-auth.ts +0 -230
  358. package/node_modules/@blockcast/mmt-manifest-verify/src/verifier.ts +0 -669
  359. package/node_modules/@noble/hashes/LICENSE +0 -21
  360. package/node_modules/@noble/hashes/README.md +0 -521
  361. package/node_modules/@noble/hashes/_assert.d.ts +0 -17
  362. package/node_modules/@noble/hashes/_assert.d.ts.map +0 -1
  363. package/node_modules/@noble/hashes/_assert.js +0 -18
  364. package/node_modules/@noble/hashes/_assert.js.map +0 -1
  365. package/node_modules/@noble/hashes/_blake.d.ts +0 -14
  366. package/node_modules/@noble/hashes/_blake.d.ts.map +0 -1
  367. package/node_modules/@noble/hashes/_blake.js +0 -50
  368. package/node_modules/@noble/hashes/_blake.js.map +0 -1
  369. package/node_modules/@noble/hashes/_md.d.ts +0 -51
  370. package/node_modules/@noble/hashes/_md.d.ts.map +0 -1
  371. package/node_modules/@noble/hashes/_md.js +0 -162
  372. package/node_modules/@noble/hashes/_md.js.map +0 -1
  373. package/node_modules/@noble/hashes/_u64.d.ts +0 -55
  374. package/node_modules/@noble/hashes/_u64.d.ts.map +0 -1
  375. package/node_modules/@noble/hashes/_u64.js +0 -90
  376. package/node_modules/@noble/hashes/_u64.js.map +0 -1
  377. package/node_modules/@noble/hashes/argon2.d.ts +0 -32
  378. package/node_modules/@noble/hashes/argon2.d.ts.map +0 -1
  379. package/node_modules/@noble/hashes/argon2.js +0 -401
  380. package/node_modules/@noble/hashes/argon2.js.map +0 -1
  381. package/node_modules/@noble/hashes/blake1.d.ts +0 -106
  382. package/node_modules/@noble/hashes/blake1.d.ts.map +0 -1
  383. package/node_modules/@noble/hashes/blake1.js +0 -459
  384. package/node_modules/@noble/hashes/blake1.js.map +0 -1
  385. package/node_modules/@noble/hashes/blake2.d.ts +0 -116
  386. package/node_modules/@noble/hashes/blake2.d.ts.map +0 -1
  387. package/node_modules/@noble/hashes/blake2.js +0 -420
  388. package/node_modules/@noble/hashes/blake2.js.map +0 -1
  389. package/node_modules/@noble/hashes/blake2b.d.ts +0 -11
  390. package/node_modules/@noble/hashes/blake2b.d.ts.map +0 -1
  391. package/node_modules/@noble/hashes/blake2b.js +0 -14
  392. package/node_modules/@noble/hashes/blake2b.js.map +0 -1
  393. package/node_modules/@noble/hashes/blake2s.d.ts +0 -20
  394. package/node_modules/@noble/hashes/blake2s.d.ts.map +0 -1
  395. package/node_modules/@noble/hashes/blake2s.js +0 -24
  396. package/node_modules/@noble/hashes/blake2s.js.map +0 -1
  397. package/node_modules/@noble/hashes/blake3.d.ts +0 -54
  398. package/node_modules/@noble/hashes/blake3.d.ts.map +0 -1
  399. package/node_modules/@noble/hashes/blake3.js +0 -255
  400. package/node_modules/@noble/hashes/blake3.js.map +0 -1
  401. package/node_modules/@noble/hashes/crypto.d.ts +0 -2
  402. package/node_modules/@noble/hashes/crypto.d.ts.map +0 -1
  403. package/node_modules/@noble/hashes/crypto.js +0 -5
  404. package/node_modules/@noble/hashes/crypto.js.map +0 -1
  405. package/node_modules/@noble/hashes/cryptoNode.d.ts +0 -2
  406. package/node_modules/@noble/hashes/cryptoNode.d.ts.map +0 -1
  407. package/node_modules/@noble/hashes/cryptoNode.js +0 -18
  408. package/node_modules/@noble/hashes/cryptoNode.js.map +0 -1
  409. package/node_modules/@noble/hashes/eskdf.d.ts +0 -47
  410. package/node_modules/@noble/hashes/eskdf.d.ts.map +0 -1
  411. package/node_modules/@noble/hashes/eskdf.js +0 -166
  412. package/node_modules/@noble/hashes/eskdf.js.map +0 -1
  413. package/node_modules/@noble/hashes/esm/_assert.d.ts +0 -17
  414. package/node_modules/@noble/hashes/esm/_assert.d.ts.map +0 -1
  415. package/node_modules/@noble/hashes/esm/_assert.js +0 -15
  416. package/node_modules/@noble/hashes/esm/_assert.js.map +0 -1
  417. package/node_modules/@noble/hashes/esm/_blake.d.ts +0 -14
  418. package/node_modules/@noble/hashes/esm/_blake.d.ts.map +0 -1
  419. package/node_modules/@noble/hashes/esm/_blake.js +0 -45
  420. package/node_modules/@noble/hashes/esm/_blake.js.map +0 -1
  421. package/node_modules/@noble/hashes/esm/_md.d.ts +0 -51
  422. package/node_modules/@noble/hashes/esm/_md.d.ts.map +0 -1
  423. package/node_modules/@noble/hashes/esm/_md.js +0 -155
  424. package/node_modules/@noble/hashes/esm/_md.js.map +0 -1
  425. package/node_modules/@noble/hashes/esm/_u64.d.ts +0 -55
  426. package/node_modules/@noble/hashes/esm/_u64.d.ts.map +0 -1
  427. package/node_modules/@noble/hashes/esm/_u64.js +0 -67
  428. package/node_modules/@noble/hashes/esm/_u64.js.map +0 -1
  429. package/node_modules/@noble/hashes/esm/argon2.d.ts +0 -32
  430. package/node_modules/@noble/hashes/esm/argon2.d.ts.map +0 -1
  431. package/node_modules/@noble/hashes/esm/argon2.js +0 -392
  432. package/node_modules/@noble/hashes/esm/argon2.js.map +0 -1
  433. package/node_modules/@noble/hashes/esm/blake1.d.ts +0 -106
  434. package/node_modules/@noble/hashes/esm/blake1.d.ts.map +0 -1
  435. package/node_modules/@noble/hashes/esm/blake1.js +0 -452
  436. package/node_modules/@noble/hashes/esm/blake1.js.map +0 -1
  437. package/node_modules/@noble/hashes/esm/blake2.d.ts +0 -116
  438. package/node_modules/@noble/hashes/esm/blake2.d.ts.map +0 -1
  439. package/node_modules/@noble/hashes/esm/blake2.js +0 -413
  440. package/node_modules/@noble/hashes/esm/blake2.js.map +0 -1
  441. package/node_modules/@noble/hashes/esm/blake2b.d.ts +0 -11
  442. package/node_modules/@noble/hashes/esm/blake2b.d.ts.map +0 -1
  443. package/node_modules/@noble/hashes/esm/blake2b.js +0 -11
  444. package/node_modules/@noble/hashes/esm/blake2b.js.map +0 -1
  445. package/node_modules/@noble/hashes/esm/blake2s.d.ts +0 -20
  446. package/node_modules/@noble/hashes/esm/blake2s.d.ts.map +0 -1
  447. package/node_modules/@noble/hashes/esm/blake2s.js +0 -21
  448. package/node_modules/@noble/hashes/esm/blake2s.js.map +0 -1
  449. package/node_modules/@noble/hashes/esm/blake3.d.ts +0 -54
  450. package/node_modules/@noble/hashes/esm/blake3.d.ts.map +0 -1
  451. package/node_modules/@noble/hashes/esm/blake3.js +0 -251
  452. package/node_modules/@noble/hashes/esm/blake3.js.map +0 -1
  453. package/node_modules/@noble/hashes/esm/crypto.d.ts +0 -2
  454. package/node_modules/@noble/hashes/esm/crypto.d.ts.map +0 -1
  455. package/node_modules/@noble/hashes/esm/crypto.js +0 -2
  456. package/node_modules/@noble/hashes/esm/crypto.js.map +0 -1
  457. package/node_modules/@noble/hashes/esm/cryptoNode.d.ts +0 -2
  458. package/node_modules/@noble/hashes/esm/cryptoNode.d.ts.map +0 -1
  459. package/node_modules/@noble/hashes/esm/cryptoNode.js +0 -15
  460. package/node_modules/@noble/hashes/esm/cryptoNode.js.map +0 -1
  461. package/node_modules/@noble/hashes/esm/eskdf.d.ts +0 -47
  462. package/node_modules/@noble/hashes/esm/eskdf.d.ts.map +0 -1
  463. package/node_modules/@noble/hashes/esm/eskdf.js +0 -160
  464. package/node_modules/@noble/hashes/esm/eskdf.js.map +0 -1
  465. package/node_modules/@noble/hashes/esm/hkdf.d.ts +0 -36
  466. package/node_modules/@noble/hashes/esm/hkdf.d.ts.map +0 -1
  467. package/node_modules/@noble/hashes/esm/hkdf.js +0 -82
  468. package/node_modules/@noble/hashes/esm/hkdf.js.map +0 -1
  469. package/node_modules/@noble/hashes/esm/hmac.d.ts +0 -35
  470. package/node_modules/@noble/hashes/esm/hmac.d.ts.map +0 -1
  471. package/node_modules/@noble/hashes/esm/hmac.js +0 -86
  472. package/node_modules/@noble/hashes/esm/hmac.js.map +0 -1
  473. package/node_modules/@noble/hashes/esm/index.d.ts +0 -2
  474. package/node_modules/@noble/hashes/esm/index.d.ts.map +0 -1
  475. package/node_modules/@noble/hashes/esm/index.js +0 -33
  476. package/node_modules/@noble/hashes/esm/index.js.map +0 -1
  477. package/node_modules/@noble/hashes/esm/legacy.d.ts +0 -71
  478. package/node_modules/@noble/hashes/esm/legacy.d.ts.map +0 -1
  479. package/node_modules/@noble/hashes/esm/legacy.js +0 -281
  480. package/node_modules/@noble/hashes/esm/legacy.js.map +0 -1
  481. package/node_modules/@noble/hashes/esm/package.json +0 -10
  482. package/node_modules/@noble/hashes/esm/pbkdf2.d.ts +0 -23
  483. package/node_modules/@noble/hashes/esm/pbkdf2.d.ts.map +0 -1
  484. package/node_modules/@noble/hashes/esm/pbkdf2.js +0 -97
  485. package/node_modules/@noble/hashes/esm/pbkdf2.js.map +0 -1
  486. package/node_modules/@noble/hashes/esm/ripemd160.d.ts +0 -13
  487. package/node_modules/@noble/hashes/esm/ripemd160.d.ts.map +0 -1
  488. package/node_modules/@noble/hashes/esm/ripemd160.js +0 -13
  489. package/node_modules/@noble/hashes/esm/ripemd160.js.map +0 -1
  490. package/node_modules/@noble/hashes/esm/scrypt.d.ts +0 -34
  491. package/node_modules/@noble/hashes/esm/scrypt.d.ts.map +0 -1
  492. package/node_modules/@noble/hashes/esm/scrypt.js +0 -228
  493. package/node_modules/@noble/hashes/esm/scrypt.js.map +0 -1
  494. package/node_modules/@noble/hashes/esm/sha1.d.ts +0 -11
  495. package/node_modules/@noble/hashes/esm/sha1.d.ts.map +0 -1
  496. package/node_modules/@noble/hashes/esm/sha1.js +0 -11
  497. package/node_modules/@noble/hashes/esm/sha1.js.map +0 -1
  498. package/node_modules/@noble/hashes/esm/sha2.d.ts +0 -159
  499. package/node_modules/@noble/hashes/esm/sha2.d.ts.map +0 -1
  500. package/node_modules/@noble/hashes/esm/sha2.js +0 -375
  501. package/node_modules/@noble/hashes/esm/sha2.js.map +0 -1
  502. package/node_modules/@noble/hashes/esm/sha256.d.ts +0 -20
  503. package/node_modules/@noble/hashes/esm/sha256.d.ts.map +0 -1
  504. package/node_modules/@noble/hashes/esm/sha256.js +0 -20
  505. package/node_modules/@noble/hashes/esm/sha256.js.map +0 -1
  506. package/node_modules/@noble/hashes/esm/sha3-addons.d.ts +0 -142
  507. package/node_modules/@noble/hashes/esm/sha3-addons.d.ts.map +0 -1
  508. package/node_modules/@noble/hashes/esm/sha3-addons.js +0 -393
  509. package/node_modules/@noble/hashes/esm/sha3-addons.js.map +0 -1
  510. package/node_modules/@noble/hashes/esm/sha3.d.ts +0 -53
  511. package/node_modules/@noble/hashes/esm/sha3.d.ts.map +0 -1
  512. package/node_modules/@noble/hashes/esm/sha3.js +0 -234
  513. package/node_modules/@noble/hashes/esm/sha3.js.map +0 -1
  514. package/node_modules/@noble/hashes/esm/sha512.d.ts +0 -26
  515. package/node_modules/@noble/hashes/esm/sha512.d.ts.map +0 -1
  516. package/node_modules/@noble/hashes/esm/sha512.js +0 -26
  517. package/node_modules/@noble/hashes/esm/sha512.js.map +0 -1
  518. package/node_modules/@noble/hashes/esm/utils.d.ts +0 -161
  519. package/node_modules/@noble/hashes/esm/utils.d.ts.map +0 -1
  520. package/node_modules/@noble/hashes/esm/utils.js +0 -281
  521. package/node_modules/@noble/hashes/esm/utils.js.map +0 -1
  522. package/node_modules/@noble/hashes/hkdf.d.ts +0 -36
  523. package/node_modules/@noble/hashes/hkdf.d.ts.map +0 -1
  524. package/node_modules/@noble/hashes/hkdf.js +0 -88
  525. package/node_modules/@noble/hashes/hkdf.js.map +0 -1
  526. package/node_modules/@noble/hashes/hmac.d.ts +0 -35
  527. package/node_modules/@noble/hashes/hmac.d.ts.map +0 -1
  528. package/node_modules/@noble/hashes/hmac.js +0 -91
  529. package/node_modules/@noble/hashes/hmac.js.map +0 -1
  530. package/node_modules/@noble/hashes/index.d.ts +0 -1
  531. package/node_modules/@noble/hashes/index.d.ts.map +0 -1
  532. package/node_modules/@noble/hashes/index.js +0 -33
  533. package/node_modules/@noble/hashes/index.js.map +0 -1
  534. package/node_modules/@noble/hashes/legacy.d.ts +0 -71
  535. package/node_modules/@noble/hashes/legacy.d.ts.map +0 -1
  536. package/node_modules/@noble/hashes/legacy.js +0 -287
  537. package/node_modules/@noble/hashes/legacy.js.map +0 -1
  538. package/node_modules/@noble/hashes/package.json +0 -266
  539. package/node_modules/@noble/hashes/pbkdf2.d.ts +0 -23
  540. package/node_modules/@noble/hashes/pbkdf2.d.ts.map +0 -1
  541. package/node_modules/@noble/hashes/pbkdf2.js +0 -101
  542. package/node_modules/@noble/hashes/pbkdf2.js.map +0 -1
  543. package/node_modules/@noble/hashes/ripemd160.d.ts +0 -13
  544. package/node_modules/@noble/hashes/ripemd160.d.ts.map +0 -1
  545. package/node_modules/@noble/hashes/ripemd160.js +0 -16
  546. package/node_modules/@noble/hashes/ripemd160.js.map +0 -1
  547. package/node_modules/@noble/hashes/scrypt.d.ts +0 -34
  548. package/node_modules/@noble/hashes/scrypt.d.ts.map +0 -1
  549. package/node_modules/@noble/hashes/scrypt.js +0 -232
  550. package/node_modules/@noble/hashes/scrypt.js.map +0 -1
  551. package/node_modules/@noble/hashes/sha1.d.ts +0 -11
  552. package/node_modules/@noble/hashes/sha1.d.ts.map +0 -1
  553. package/node_modules/@noble/hashes/sha1.js +0 -14
  554. package/node_modules/@noble/hashes/sha1.js.map +0 -1
  555. package/node_modules/@noble/hashes/sha2.d.ts +0 -159
  556. package/node_modules/@noble/hashes/sha2.d.ts.map +0 -1
  557. package/node_modules/@noble/hashes/sha2.js +0 -384
  558. package/node_modules/@noble/hashes/sha2.js.map +0 -1
  559. package/node_modules/@noble/hashes/sha256.d.ts +0 -20
  560. package/node_modules/@noble/hashes/sha256.d.ts.map +0 -1
  561. package/node_modules/@noble/hashes/sha256.js +0 -23
  562. package/node_modules/@noble/hashes/sha256.js.map +0 -1
  563. package/node_modules/@noble/hashes/sha3-addons.d.ts +0 -142
  564. package/node_modules/@noble/hashes/sha3-addons.d.ts.map +0 -1
  565. package/node_modules/@noble/hashes/sha3-addons.js +0 -402
  566. package/node_modules/@noble/hashes/sha3-addons.js.map +0 -1
  567. package/node_modules/@noble/hashes/sha3.d.ts +0 -53
  568. package/node_modules/@noble/hashes/sha3.d.ts.map +0 -1
  569. package/node_modules/@noble/hashes/sha3.js +0 -239
  570. package/node_modules/@noble/hashes/sha3.js.map +0 -1
  571. package/node_modules/@noble/hashes/sha512.d.ts +0 -26
  572. package/node_modules/@noble/hashes/sha512.d.ts.map +0 -1
  573. package/node_modules/@noble/hashes/sha512.js +0 -29
  574. package/node_modules/@noble/hashes/sha512.js.map +0 -1
  575. package/node_modules/@noble/hashes/src/_assert.ts +0 -22
  576. package/node_modules/@noble/hashes/src/_blake.ts +0 -50
  577. package/node_modules/@noble/hashes/src/_md.ts +0 -176
  578. package/node_modules/@noble/hashes/src/_u64.ts +0 -91
  579. package/node_modules/@noble/hashes/src/argon2.ts +0 -497
  580. package/node_modules/@noble/hashes/src/blake1.ts +0 -534
  581. package/node_modules/@noble/hashes/src/blake2.ts +0 -486
  582. package/node_modules/@noble/hashes/src/blake2b.ts +0 -10
  583. package/node_modules/@noble/hashes/src/blake2s.ts +0 -20
  584. package/node_modules/@noble/hashes/src/blake3.ts +0 -272
  585. package/node_modules/@noble/hashes/src/crypto.ts +0 -9
  586. package/node_modules/@noble/hashes/src/cryptoNode.ts +0 -15
  587. package/node_modules/@noble/hashes/src/eskdf.ts +0 -187
  588. package/node_modules/@noble/hashes/src/hkdf.ts +0 -88
  589. package/node_modules/@noble/hashes/src/hmac.ts +0 -94
  590. package/node_modules/@noble/hashes/src/index.ts +0 -31
  591. package/node_modules/@noble/hashes/src/legacy.ts +0 -293
  592. package/node_modules/@noble/hashes/src/pbkdf2.ts +0 -122
  593. package/node_modules/@noble/hashes/src/ripemd160.ts +0 -12
  594. package/node_modules/@noble/hashes/src/scrypt.ts +0 -257
  595. package/node_modules/@noble/hashes/src/sha1.ts +0 -10
  596. package/node_modules/@noble/hashes/src/sha2.ts +0 -402
  597. package/node_modules/@noble/hashes/src/sha256.ts +0 -24
  598. package/node_modules/@noble/hashes/src/sha3-addons.ts +0 -499
  599. package/node_modules/@noble/hashes/src/sha3.ts +0 -258
  600. package/node_modules/@noble/hashes/src/sha512.ts +0 -34
  601. package/node_modules/@noble/hashes/src/utils.ts +0 -395
  602. package/node_modules/@noble/hashes/utils.d.ts +0 -161
  603. package/node_modules/@noble/hashes/utils.d.ts.map +0 -1
  604. package/node_modules/@noble/hashes/utils.js +0 -313
  605. package/node_modules/@noble/hashes/utils.js.map +0 -1
@@ -1,20 +1,22 @@
1
1
  // src/track-session.ts
2
2
  import { fecBlockBudgetMs } from "@blockcast/mmt-fec";
3
3
  function computeFecDeliveryWindowMs(config) {
4
- const fecInterleaveMs = config.interleaveDepthMs;
5
4
  const fecK = config.sourceSymbols;
6
- if (!Number.isFinite(fecInterleaveMs) || fecInterleaveMs <= 0) {
5
+ if (!Number.isFinite(fecK) || fecK <= 0) {
7
6
  throw new Error(
8
- `[TrackSession] fecInterleaveMs=${fecInterleaveMs}. Derive a positive FEC interleave window from the stream catalog.`
7
+ `[TrackSession] fecK=${fecK}. Derive a positive FEC source-symbol count from the stream catalog.`
9
8
  );
10
9
  }
11
- if (!Number.isFinite(fecK) || fecK <= 0) {
10
+ return fecSpanDeliveryWindowMs(config.interleaveDepthMs, config.jitterBufferMs);
11
+ }
12
+ function fecSpanDeliveryWindowMs(interleaveDepthMs, jitterBufferMs) {
13
+ if (!Number.isFinite(interleaveDepthMs) || interleaveDepthMs <= 0) {
12
14
  throw new Error(
13
- `[TrackSession] fecK=${fecK}. Derive a positive FEC source-symbol count from the stream catalog.`
15
+ `[TrackSession] fecInterleaveMs=${interleaveDepthMs}. Derive a positive FEC interleave window from the stream catalog.`
14
16
  );
15
17
  }
16
- if (config.jitterBufferMs === void 0) return Math.ceil(fecInterleaveMs);
17
- return fecBlockBudgetMs(fecInterleaveMs, config.jitterBufferMs);
18
+ if (jitterBufferMs === void 0) return Math.ceil(interleaveDepthMs);
19
+ return fecBlockBudgetMs(interleaveDepthMs, jitterBufferMs);
18
20
  }
19
21
 
20
22
  // src/delivery-gap.ts
@@ -106,19 +108,16 @@ var DeliveryGapEstimator = class {
106
108
  import {
107
109
  deriveFecInterleaveDepth as deriveFecInterleaveDepth2,
108
110
  deriveFecRetentionBlocks,
109
- tryDeriveFecRetentionBlocks
111
+ tryDeriveFecRetentionBlocks,
112
+ LOCAL_FEC_RETENTION_BLOCKS,
113
+ LOCAL_FEC_TIMEOUT_MS
110
114
  } from "@blockcast/mmt-fec";
111
115
 
112
- // ../mmt-alta-parse/dist/index.js
116
+ // ../mmt-base/dist/mmtp.js
113
117
  var MPU_HEADER_SIZE = 8;
114
118
  var MPU_LENGTH_FIELD_SIZE = 2;
115
119
  var MPU_HEADER_REMAINDER_SIZE = MPU_HEADER_SIZE - MPU_LENGTH_FIELD_SIZE;
116
120
 
117
- // ../mmt-base/dist/mmtp.js
118
- var MPU_HEADER_SIZE2 = 8;
119
- var MPU_LENGTH_FIELD_SIZE2 = 2;
120
- var MPU_HEADER_REMAINDER_SIZE2 = MPU_HEADER_SIZE2 - MPU_LENGTH_FIELD_SIZE2;
121
-
122
121
  // ../mmt-base/dist/ntp-short.js
123
122
  var NTP_SHORT_BITS = 32;
124
123
  var NTP_SHORT_MODULUS = 2 ** NTP_SHORT_BITS;
@@ -146,49 +145,21 @@ function serial32Precedes(a, b) {
146
145
  const distance = serial32Distance(a, b);
147
146
  return distance !== 0 && distance < SERIAL32_HALF;
148
147
  }
149
- function kStrideBlockStart(sbn, k) {
150
- assertUint32(sbn, "sbn");
151
- if (!Number.isInteger(k) || k < 1 || k >= SERIAL32_HALF) {
152
- throw new RangeError(`k must be a positive integer below 2^31 (got ${k})`);
153
- }
154
- const high = Math.floor(sbn / 65536);
155
- const low = sbn % 65536;
156
- return (high * k % SERIAL32_SPAN * 65536 + low * k) % SERIAL32_SPAN;
157
- }
158
- function kStrideBlockPrecedes(a, b, k) {
159
- return serial32Precedes(kStrideBlockStart(a, k), kStrideBlockStart(b, k));
160
- }
161
- function kStrideBlocksBehind(a, b, k) {
162
- const from = kStrideBlockStart(a, k);
163
- const to = kStrideBlockStart(b, k);
164
- if (!serial32Precedes(from, to))
165
- return 0;
166
- return Math.ceil(serial32Distance(from, to) / k);
167
- }
168
- function isKStrideBlock(sbn, k) {
169
- return Number.isInteger(sbn) && sbn >= 0 && sbn < SERIAL32_SPAN && Number.isInteger(k) && k >= 1 && k < SERIAL32_HALF;
170
- }
171
- function kStrideNextBlock(sbn, k) {
172
- assertUint32(sbn, "sbn");
173
- kStrideBlockStart(sbn, k);
174
- return (sbn + 1) * k >= SERIAL32_SPAN ? 0 : sbn + 1;
175
- }
176
148
 
177
149
  // ../mmt-base/dist/fec-block-profile.js
178
150
  var FEC_BLOCK_PROFILES = Object.freeze([
179
- "k-padded-v1",
180
151
  "iso-ssbg1-v1"
181
152
  ]);
182
153
  function isFecBlockProfile(value) {
183
- return value === "k-padded-v1" || value === "iso-ssbg1-v1";
154
+ return value === "iso-ssbg1-v1";
184
155
  }
185
156
  function parseFecBlockProfile(value, where) {
186
157
  if (isFecBlockProfile(value))
187
158
  return value;
188
159
  if (value === void 0) {
189
- throw new Error(`${where} is required: name the FEC block profile ("k-padded-v1" or "iso-ssbg1-v1")`);
160
+ throw new Error(`${where} is required: name the FEC block profile ("iso-ssbg1-v1")`);
190
161
  }
191
- throw new Error(`${where} must be "k-padded-v1" or "iso-ssbg1-v1" (got ${JSON.stringify(value)})`);
162
+ throw new Error(`${where} must be "iso-ssbg1-v1" (got ${JSON.stringify(value)})`);
192
163
  }
193
164
  var SSBG1_LENGTH_FIELD_BYTES = 2;
194
165
  function ssbg1MaxPacketLength(symbolSize) {
@@ -441,7 +412,7 @@ var IsoBlockLocator = class _IsoBlockLocator {
441
412
  };
442
413
 
443
414
  // src/fec-state.ts
444
- var MIN_INTERLEAVE_DEPTH_MS = 33;
415
+ var MIN_INTERLEAVE_DEPTH_MS = 1;
445
416
  var FEC_INACTIVE_REASONS = Object.freeze([
446
417
  "no-catalog-fec",
447
418
  "reliable-moq",
@@ -836,7 +807,6 @@ var FECManager = class _FECManager {
836
807
  constructor() {
837
808
  // Per-track WASM RaptorQ decoders, keyed by physical stream identity.
838
809
  this.#fecDecoders = /* @__PURE__ */ new Map();
839
- /** @deprecated Use setFecDecoder(packetId, ...). Backwards-compat shim. */
840
810
  // Per-track Worker-backed FEC decoders, keyed by physical stream identity.
841
811
  // Worker-backed tracks use async decode — recovered frames arrive via onFrame callback,
842
812
  // not synchronous return from feedSourceSymbol/feedRepairSymbol.
@@ -851,10 +821,9 @@ var FECManager = class _FECManager {
851
821
  // source/repair symbols do not split across two RaptorQ states.
852
822
  this.#syncDecoderBlockOwners = /* @__PURE__ */ new Map();
853
823
  this.#decoderBlockOwners = /* @__PURE__ */ new WeakMap();
854
- this.#fecK = 4;
855
824
  this.#fecSymbolSize = 0;
856
- this.#fecTimeoutMs = 500;
857
- // default 500ms; refined by setFramerate() when fps known
825
+ this.#fecTimeoutMs = LOCAL_FEC_TIMEOUT_MS;
826
+ // local default; refined by setFramerate() when fps known
858
827
  this.#trackConfigs = /* @__PURE__ */ new Map();
859
828
  this.#fecStats = newFecCounters();
860
829
  this.#fecTrackStats = /* @__PURE__ */ new Map();
@@ -894,14 +863,17 @@ var FECManager = class _FECManager {
894
863
  this.#blockSourceEsis = /* @__PURE__ */ new Map();
895
864
  // Authored SSB_length per block (ISO/IEC 23008-1 §C.5.3), learned from the
896
865
  // first repair symbol. The FFmpeg moq_mmt publisher closes a block every D
897
- // media units, usually before it holds K symbols, and fec-raptorq
898
- // force_complete() encodes it as a K-symbol RaptorQ block whose ESIs
899
- // SSB_length..K-1 are zero padding that is never sent. Such a block is clean
900
- // at SSB_length source arrivals and recoverable from SSB_length received
866
+ // media units, usually before it holds K symbols; under iso-ssbg1-v1
867
+ // (ssbg_mode1) that block is K' = SSB_length symbols, its repair ESIs start
868
+ // at SSB_length, and K is only the maximum. Such a block is clean at
869
+ // SSB_length source arrivals and recoverable from SSB_length received
901
870
  // symbols; waiting for K fails every one of them.
902
871
  this.#blockAuthoredLengths = /* @__PURE__ */ new Map();
903
872
  this.#ssbLengthConflictCount = 0;
904
873
  this.#blockRepairRsIds = /* @__PURE__ */ new Map();
874
+ // RSB_length per block (C.5.3 Repair FEC Payload ID): how many repair
875
+ // symbols its repair group carries. Same lifecycle as #blockRepairRsIds.
876
+ this.#blockRsbLengths = /* @__PURE__ */ new Map();
905
877
  // Blocks already recovered — prevents late source symbols from restarting timeouts.
906
878
  // WASM removes blocks after recovery; late symbols create empty blocks returning null,
907
879
  // which would falsely start new timeouts without this guard.
@@ -1014,14 +986,16 @@ var FECManager = class _FECManager {
1014
986
  this.#resolvedBlockClasses = /* @__PURE__ */ new Map();
1015
987
  // Blocks already reported through onBlockRepaired (once per block).
1016
988
  this.#repairedBlocks = /* @__PURE__ */ new Set();
1017
- // Blocks created without any symbol because every symbol vanished.
989
+ // Blocks created before any symbol of theirs was tracked: the repair-less
990
+ // spans placeIsoRepair materializes (onBlockVanished).
1018
991
  this.#materializedBlocks = /* @__PURE__ */ new Set();
1019
992
  // packetIds whose ordered-relay horizon became underivable and fell back to
1020
993
  // the datagram deadline. Bounds the warn in #derivableOrderedHorizon to once
1021
994
  // per stream. Not only throws: the ordinary out-of-range case is detected by
1022
995
  // arithmetic and never throws at all.
1023
996
  this.#orderedHorizonWarnedFor = /* @__PURE__ */ new Set();
1024
- // Highest SBN seen per stream and when, for vanished-block detection.
997
+ // Newest block start (SS_Start) seen per stream and when: the frontier for
998
+ // source-discontinuity detection and isoSpanResolution.
1025
999
  this.#highestSbn = /* @__PURE__ */ new Map();
1026
1000
  // iso-ssbg1-v1 block location per stream (streamKey). A source belongs to a
1027
1001
  // block only once a repair symbol stated the block's (SS_Start, SSB_length).
@@ -1115,7 +1089,10 @@ var FECManager = class _FECManager {
1115
1089
  #releasedWorkerClients;
1116
1090
  #syncDecoderBlockOwners;
1117
1091
  #decoderBlockOwners;
1118
- #fecK;
1092
+ // The stream-global K a configure() call stated, reported as fecStats.k.
1093
+ // It never resolves a packetId: a packetId has only its own track config
1094
+ // (BLO-45953), and K does not feed the delivery-window math.
1095
+ #streamK;
1119
1096
  #fecSymbolSize;
1120
1097
  #fecTimeoutMs;
1121
1098
  #trackConfigs;
@@ -1137,6 +1114,7 @@ var FECManager = class _FECManager {
1137
1114
  #blockAuthoredLengths;
1138
1115
  #ssbLengthConflictCount;
1139
1116
  #blockRepairRsIds;
1117
+ #blockRsbLengths;
1140
1118
  #completedBlocks;
1141
1119
  #terminalExpiryMs;
1142
1120
  #terminalQueues;
@@ -1277,7 +1255,8 @@ var FECManager = class _FECManager {
1277
1255
  this.#completedBlocks.add(key);
1278
1256
  if (clean) this.#cleanlyCompletedBlocks.add(key);
1279
1257
  this.#indexBlockKey(key, sbn, packetId);
1280
- const expiresAtMs = nowMs + this.terminalRetentionMsForPacket(packetId);
1258
+ const config = this.#trackConfig(packetId);
1259
+ const expiresAtMs = nowMs + config.interleaveDepthMs + 2 * this.#blockLifetimeMs(config);
1281
1260
  this.#terminalExpiryMs.set(key, expiresAtMs);
1282
1261
  let queue = this.#terminalQueues.get(packetId);
1283
1262
  if (!queue) {
@@ -1313,8 +1292,9 @@ var FECManager = class _FECManager {
1313
1292
  * retention the Worker and the WASM decoder are configured with, because it
1314
1293
  * comes from the same function they do (`deriveFecRetentionBlocks`, over the
1315
1294
  * block's delivery window and its span). The decoder retires every block
1316
- * more than this many SBNs behind the newest one it saw (`cleanup_by_sbn`),
1317
- * so settling earlier than this would decide a block the decoder would still
1295
+ * more than this many blocks behind the newest SS_Start it saw, counted
1296
+ * from below by `isoBlocksBehindLowerBound` (`cleanup_by_ss_start`), so
1297
+ * settling earlier than this would decide a block the decoder would still
1318
1298
  * have recovered.
1319
1299
  *
1320
1300
  * This used to call `deriveFecInterleaveDepth`, which returns D -- MEDIA
@@ -1327,6 +1307,14 @@ var FECManager = class _FECManager {
1327
1307
  * derivation; do not re-derive a horizon at either call site.
1328
1308
  */
1329
1309
  #orderedHorizonBlocksFor(packetId, config) {
1310
+ if (config.interleaveDepthMs === 0) {
1311
+ if (Number.isFinite(config.timeoutMs) && config.timeoutMs > 0) {
1312
+ return LOCAL_FEC_RETENTION_BLOCKS;
1313
+ }
1314
+ throw new Error(
1315
+ `[FECManager] packetId=${packetId}: local FEC cleanup requires a positive timeout (got ${config.timeoutMs})`
1316
+ );
1317
+ }
1330
1318
  if (!_FECManager.#hasOrderedGeometry(config)) {
1331
1319
  throw new Error(
1332
1320
  `[FECManager] packetId=${packetId}: ordered-relay settlement derives the decoder's interleave horizon from the catalog interleaveDepthMs (>= ${MIN_INTERLEAVE_DEPTH_MS}ms), the media-unit rate and the block delivery window; got interleaveDepthMs=${config.interleaveDepthMs} fps=${String(config.fps)} timeoutMs=${config.timeoutMs}.`
@@ -1340,7 +1328,7 @@ var FECManager = class _FECManager {
1340
1328
  * two can never disagree about which streams settle by stream order.
1341
1329
  */
1342
1330
  static #hasOrderedGeometry(config) {
1343
- return config.interleaveDepthMs >= MIN_INTERLEAVE_DEPTH_MS && // `fps` is no longer an input to the horizon, but it still gates WHICH
1331
+ return _FECManager.#hasCatalogTiming(config) && // `fps` is no longer an input to the horizon, but it still gates WHICH
1344
1332
  // streams settle by stream order at all: a track with no usable
1345
1333
  // media-unit rate fell back to datagram semantics before this and must
1346
1334
  // keep doing so. Removing this widens ordered-relay settlement to streams
@@ -1380,6 +1368,9 @@ var FECManager = class _FECManager {
1380
1368
  * argument: narrower IS the failing direction.
1381
1369
  */
1382
1370
  #derivableOrderedHorizon(config, packetId) {
1371
+ if (config.interleaveDepthMs === 0) {
1372
+ return Number.isFinite(config.timeoutMs) && config.timeoutMs > 0 ? LOCAL_FEC_RETENTION_BLOCKS : void 0;
1373
+ }
1383
1374
  if (!_FECManager.#hasOrderedGeometry(config)) return void 0;
1384
1375
  try {
1385
1376
  const blocks = tryDeriveFecRetentionBlocks(config.timeoutMs, config.interleaveDepthMs);
@@ -1412,19 +1403,20 @@ var FECManager = class _FECManager {
1412
1403
  /**
1413
1404
  * The stream's interleave horizon, or undefined when its geometry cannot
1414
1405
  * define one. Two different streams reach that case, with different causes:
1415
- * a packetId that was never configured, and so resolves to the manager
1416
- * defaults (explicitly configured tracks are refused an underivable geometry
1406
+ * a packetId that was never configured, which has no geometry at all
1407
+ * (explicitly configured tracks are refused an underivable geometry
1417
1408
  * at config time — #upsertTrackConfig, setMulticastSymbolDelivery); or a
1418
1409
  * configured track whose timeoutMs was later widened past the 255-block
1419
1410
  * ceiling without re-validating, which #derivableOrderedHorizon catches
1420
1411
  * rather than throwing from the packet-feed path. Either way the stream
1421
- * keeps datagram semantics instead of throwing. The manager defaults can
1412
+ * keeps datagram semantics instead of throwing. A track's configuration can
1422
1413
  * also change under a stream that already holds blocks, so a caller cannot
1423
1414
  * assume a horizon that was defined when a block was held is still defined
1424
1415
  * (see #advanceOrderedFrontier).
1425
1416
  */
1426
1417
  #orderedHorizonBlocks(packetId) {
1427
- return this.#derivableOrderedHorizon(this.#resolveTrackConfig(packetId), packetId);
1418
+ const config = this.#trackConfigs.get(packetId);
1419
+ return config === void 0 ? void 0 : this.#derivableOrderedHorizon(config, packetId);
1428
1420
  }
1429
1421
  /** True while a block of an ordered-relay stream can still receive symbols. */
1430
1422
  #withinOrderedHorizon(key) {
@@ -1458,7 +1450,7 @@ var FECManager = class _FECManager {
1458
1450
  */
1459
1451
  #advanceOrderedFrontier(streamKey, sbn, packetId, catalogTrackName) {
1460
1452
  const previous = this.#orderedFrontiers.get(streamKey);
1461
- const frontier = previous === void 0 || this.#blockPrecedes(previous, sbn, packetId) ? sbn : previous;
1453
+ const frontier = previous === void 0 || this.#blockPrecedes(previous, sbn) ? sbn : previous;
1462
1454
  if (frontier !== previous) this.#orderedFrontiers.set(streamKey, frontier);
1463
1455
  const pending = this.#orderedPendingBlocks.get(streamKey);
1464
1456
  if (!pending) return;
@@ -1493,7 +1485,7 @@ var FECManager = class _FECManager {
1493
1485
  if (this.#completedBlocks.has(key) || this.#pendingWorkerCleanups.has(key) || this.#repairRequestedBlocks.has(key)) return;
1494
1486
  const authoredLength = this.#blockAuthoredLengths.get(key);
1495
1487
  const received = (this.#blockSourceCounts.get(key) ?? 0) + (this.#blockRepairRsIds.get(key)?.size ?? 0);
1496
- if (this.onRepairNeeded && (authoredLength === void 0 || received < authoredLength)) {
1488
+ if (this.#hasCatalogTimingForPacket(packetId) && this.onRepairNeeded && (authoredLength === void 0 || received < authoredLength)) {
1497
1489
  this.#requestRepair(sbn, packetId, catalogTrackName, true);
1498
1490
  return;
1499
1491
  }
@@ -1649,7 +1641,7 @@ var FECManager = class _FECManager {
1649
1641
  }
1650
1642
  #requestRepair(sbn, packetId, catalogTrackName, settledByOrder = false) {
1651
1643
  const key = this.#blockKey(sbn, packetId, catalogTrackName);
1652
- if (this.#completedBlocks.has(key) || !this.onRepairNeeded || this.#repairRequestedBlocks.has(key)) return;
1644
+ if (this.#completedBlocks.has(key) || !this.#hasCatalogTimingForPacket(packetId) || !this.onRepairNeeded || this.#repairRequestedBlocks.has(key)) return;
1653
1645
  const deadline = this.#repairDeadlines.get(key);
1654
1646
  if (deadline?.handle != null) clearTimeout(deadline.handle);
1655
1647
  this.#repairDeadlines.set(key, null);
@@ -1729,6 +1721,7 @@ var FECManager = class _FECManager {
1729
1721
  }
1730
1722
  /** A block's live class without creating classifier state for the stream. */
1731
1723
  #peekClass(sbn, packetId, catalogTrackName) {
1724
+ if (!this.#hasCatalogTimingForPacket(packetId)) return "unknown";
1732
1725
  const classifier = this.#classifiers.get(this.#streamKey(packetId, catalogTrackName));
1733
1726
  if (classifier) return classifier.classOf(sbn);
1734
1727
  return this.#geometryFor(packetId, catalogTrackName).trackKind === "audio" ? "audio" : "unknown";
@@ -1750,8 +1743,8 @@ var FECManager = class _FECManager {
1750
1743
  // Deliberately one block tighter than deriveFecRetentionBlocks over the same
1751
1744
  // inputs (that function's `+ 1`). Different question: the retention horizon
1752
1745
  // asks how long the decoder still ACCEPTS symbols for a block, this asks how
1753
- // far back a block that vanished entirely may still be repairable (see
1754
- // #noteSbnSeen).
1746
+ // many blocks a stream can live behind (or ahead of) its frontier before a
1747
+ // source symbol there is a discontinuity rather than loss (see #noteSbnSeen).
1755
1748
  // The extra block of retention is slack for a block still being fed; a block
1756
1749
  // nothing has been heard from does not get it. Not the units defect — but it
1757
1750
  // is the next place the two can drift, so change both or neither.
@@ -1760,27 +1753,28 @@ var FECManager = class _FECManager {
1760
1753
  return Math.ceil(config.timeoutMs / config.interleaveDepthMs);
1761
1754
  }
1762
1755
  /**
1763
- * Record that a symbol for block `sbn` arrived and materialise any blocks
1764
- * that vanished entirely between the stream's highest SBN and this one.
1756
+ * Record that a symbol for block `sbn` (the block's SS_Start) arrived and
1757
+ * advance the stream's frontier, the newest block start seen.
1765
1758
  *
1766
- * The newest ceil(timeoutMs / interleaveDepthMs) vanished blocks may still
1767
- * be repairable, so they get the normal repair and fail deadlines, armed
1768
- * from now. Older ones are already past their fail bound and fail now, as
1769
- * class `unknown`. A SOURCE symbol whose SBN goes back further than one
1770
- * live window, or jumps further than the stream could have produced since
1771
- * its last symbol, is a source discontinuity, not loss. A repair symbol can
1772
- * only advance the frontier: a D-28 fetch legitimately answers for an old
1773
- * block, so it never signals a discontinuity.
1759
+ * A SOURCE symbol whose block goes back further than one live window, or
1760
+ * jumps further than the stream could have produced since its last symbol,
1761
+ * is a source discontinuity, not loss. A repair symbol can only advance the
1762
+ * frontier: a D-28 fetch legitimately answers for an old block, so it never
1763
+ * signals a discontinuity.
1774
1764
  *
1775
1765
  * The producer closes a block at its Dth media-unit boundary OR when K
1776
- * source symbols filled it, so one interleave span can start several
1777
- * blocks (every large keyframe does). What bounds a forward jump is
1778
- * therefore packet evidence, not a block rate: with the MMTP
1779
- * packet_sequence_number (contiguous per packet_id, ISO/IEC 23008-1) of
1780
- * both source symbols, every block strictly between them holds at least one
1781
- * of the packets sent strictly between them, and K-closes can add at most
1782
- * one block per K of those packets on top of the D-closes elapsed time
1783
- * allows. Without it, only the D-close rate is known.
1766
+ * source symbols filled it, so one interleave span can start several blocks
1767
+ * (every large keyframe does). What bounds a forward jump is therefore
1768
+ * packet evidence, not a block rate: SS_ID advances by one per FEC source
1769
+ * packet (ISO/IEC 23008-1 C.5.2) and the MMTP packet_sequence_number by one
1770
+ * per packet of the packet_id, so with both source symbols'
1771
+ * packet_sequence_number a block start can move at most the packets sent
1772
+ * between them plus the anchor's own offset into its block (< K). Without
1773
+ * it, only the D-close rate is known.
1774
+ *
1775
+ * Vanished blocks are not enumerated here: their starts are unknown until a
1776
+ * repair states them. The SS_IDs between two stated blocks become one
1777
+ * repair-less span when the later block's repair arrives (placeIsoRepair).
1784
1778
  */
1785
1779
  #noteSbnSeen(sbn, packetId, catalogTrackName, symbol, packetSequenceNumber) {
1786
1780
  const streamKey = this.#streamKey(packetId, catalogTrackName);
@@ -1789,7 +1783,7 @@ var FECManager = class _FECManager {
1789
1783
  const anchor = this.#sourceAnchors.get(streamKey);
1790
1784
  const psn = symbol === "source" && packetSequenceNumber !== void 0 && Number.isSafeInteger(packetSequenceNumber) && packetSequenceNumber >= 0 && packetSequenceNumber <= 4294967295 ? packetSequenceNumber : void 0;
1791
1785
  const anchorHere = () => {
1792
- if (psn !== void 0 && (anchor === void 0 || !this.#blockPrecedes(sbn, anchor.sbn, packetId))) {
1786
+ if (psn !== void 0 && (anchor === void 0 || !this.#blockPrecedes(sbn, anchor.sbn))) {
1793
1787
  this.#sourceAnchors.set(streamKey, { sbn, psn, atMs: now });
1794
1788
  }
1795
1789
  };
@@ -1805,9 +1799,9 @@ var FECManager = class _FECManager {
1805
1799
  anchorHere();
1806
1800
  return;
1807
1801
  }
1808
- const config = this.#resolveTrackConfig(packetId);
1802
+ const config = this.#trackConfig(packetId);
1809
1803
  const window = this.#liveWindowBlocks(config);
1810
- if (!this.#blockPrecedes(previous.sbn, sbn, packetId)) {
1804
+ if (!this.#blockPrecedes(previous.sbn, sbn)) {
1811
1805
  if (symbol === "source" && window !== null && this.#blocksBehind(sbn, previous.sbn, packetId) > window) {
1812
1806
  discontinuity();
1813
1807
  return;
@@ -1818,15 +1812,9 @@ var FECManager = class _FECManager {
1818
1812
  const missing = this.#blocksBehind(previous.sbn, sbn, packetId) - 1;
1819
1813
  let plausible = true;
1820
1814
  if (window !== null) {
1821
- if (this.#isIso(packetId) && psn !== void 0 && anchor !== void 0 && this.#blockPrecedes(anchor.sbn, sbn, packetId) && psn !== anchor.psn) {
1815
+ if (psn !== void 0 && anchor !== void 0 && this.#blockPrecedes(anchor.sbn, sbn) && psn !== anchor.psn) {
1822
1816
  const sent = psn - anchor.psn >>> 0;
1823
1817
  plausible = sent <= 2147483647 && serial32Distance(anchor.sbn, sbn) <= sent + config.k;
1824
- } else if (psn !== void 0 && anchor !== void 0 && this.#blockPrecedes(anchor.sbn, sbn, packetId) && psn !== anchor.psn) {
1825
- const sent = psn - anchor.psn >>> 0;
1826
- const between = this.#blocksBehind(anchor.sbn, sbn, packetId) - 1;
1827
- const dCloses = window + Math.ceil((now - anchor.atMs) / config.interleaveDepthMs);
1828
- const kCloses = config.k > 0 ? Math.ceil(sent / config.k) : sent;
1829
- plausible = sent <= 2147483647 && between <= sent - 1 && between <= dCloses + kCloses;
1830
1818
  } else {
1831
1819
  plausible = missing <= window + Math.ceil((now - previous.atMs) / config.interleaveDepthMs);
1832
1820
  }
@@ -1838,48 +1826,31 @@ var FECManager = class _FECManager {
1838
1826
  }
1839
1827
  this.#highestSbn.set(streamKey, { sbn, atMs: now });
1840
1828
  anchorHere();
1841
- if (this.#isIso(packetId)) return;
1842
- if (missing <= 0 || window === null) return;
1843
- let vanished = previous.sbn;
1844
- for (let i = 0; i < missing; i++) {
1845
- vanished = this.#nextBlock(vanished, packetId);
1846
- this.#materializeBlock(
1847
- vanished,
1848
- packetId,
1849
- catalogTrackName,
1850
- this.#blocksBehind(vanished, sbn, packetId) <= window
1851
- );
1852
- }
1853
1829
  }
1854
1830
  /*
1855
- * Block order for one stream (BLO-35597 iso:5). SS_ID is a 32-bit serial
1856
- * number (ISO/IEC 23008-1 C.5.2), so blocks are ordered by RFC 1982
1857
- * comparison of their first SS_ID (sbn * K mod 2^32). That is identical to
1858
- * comparing SBNs with < for every stream that has not wrapped SS_ID; only
1859
- * the order across the wrap changes. A block outside K-stride geometry has
1860
- * no SS_ID position, so it keeps the SBN order it always had.
1861
- */
1862
- #blockPrecedes(a, b, packetId) {
1863
- if (this.#isIso(packetId)) return serial32Precedes(a, b);
1864
- const k = this.kForPacket(packetId);
1865
- return isKStrideBlock(a, k) && isKStrideBlock(b, k) ? kStrideBlockPrecedes(a, b, k) : a < b;
1866
- }
1867
- /** Blocks `a` lies behind `b` (0 when it does not precede it). */
1868
- #blocksBehind(a, b, packetId) {
1869
- if (this.#isIso(packetId)) return isoBlocksBehindLowerBound(a, b, this.kForPacket(packetId));
1870
- const k = this.kForPacket(packetId);
1871
- return isKStrideBlock(a, k) && isKStrideBlock(b, k) ? kStrideBlocksBehind(a, b, k) : Math.max(0, b - a);
1831
+ * Block order for one stream (BLO-35597 iso:5). A block is keyed by its
1832
+ * SS_Start and SS_ID is a 32-bit serial number (ISO/IEC 23008-1 C.5.2), so
1833
+ * blocks are ordered by RFC 1982 comparison of their starts. Only configured
1834
+ * streams hold blocks: every entry point refuses an unconfigured packetId.
1835
+ */
1836
+ #blockPrecedes(a, b) {
1837
+ return serial32Precedes(a, b);
1872
1838
  }
1873
- /** The block after `sbn`, stepping to block 0 where SS_ID wraps. */
1874
- #nextBlock(sbn, packetId) {
1875
- const k = this.kForPacket(packetId);
1876
- return isKStrideBlock(sbn, k) ? kStrideNextBlock(sbn, k) : sbn + 1;
1839
+ /**
1840
+ * Blocks `a` lies behind `b` (0 when it does not precede it). Blocks vary
1841
+ * in length (K' = SSB_length <= K), so only a lower bound is known: the one
1842
+ * metric the decoder and the worker retire by too.
1843
+ */
1844
+ #blocksBehind(a, b, packetId) {
1845
+ return isoBlocksBehindLowerBound(a, b, this.#trackConfig(packetId).k);
1877
1846
  }
1878
1847
  #materializeBlock(sbn, packetId, catalogTrackName, repairable) {
1879
1848
  const key = this.#blockKey(sbn, packetId, catalogTrackName);
1880
1849
  if (this.#blockResolutionFor(key) !== "untracked") return;
1881
1850
  this.#materializedBlocks.add(key);
1882
- this.#classifierFor(packetId, catalogTrackName).touch(sbn);
1851
+ if (this.#hasCatalogTimingForPacket(packetId)) {
1852
+ this.#classifierFor(packetId, catalogTrackName).touch(sbn);
1853
+ }
1883
1854
  this.onBlockVanished?.(sbn, packetId, catalogTrackName);
1884
1855
  if (repairable) {
1885
1856
  this.noteBlockActivity(sbn, packetId, catalogTrackName, true);
@@ -1918,21 +1889,39 @@ var FECManager = class _FECManager {
1918
1889
  });
1919
1890
  if (this.#lifecycleTrace.length > 64) this.#lifecycleTrace.splice(0, 32);
1920
1891
  }
1921
- #defaultTrackConfig() {
1922
- return {
1923
- k: this.#fecK,
1924
- symbolSize: this.#fecSymbolSize,
1925
- interleaveDepthMs: this.#fecInterleaveDepthMs,
1926
- fps: this.#fecFps,
1927
- timeoutMs: this.#fecTimeoutMs
1928
- };
1892
+ /**
1893
+ * A configured packetId's track config. There is no manager-wide default
1894
+ * (BLO-45953): an unconfigured packetId does no FEC work, so every caller
1895
+ * here is reached only behind a configuration gate and this throw marks a
1896
+ * broken invariant, never a packet-path outcome.
1897
+ */
1898
+ #trackConfig(packetId) {
1899
+ const config = this.#trackConfigs.get(packetId);
1900
+ if (config === void 0) {
1901
+ throw new Error(
1902
+ `[FECManager] packetId=${packetId} was never configured; configure the track from its catalog (configureTrack/setFecWorker/setFecDecoder) first`
1903
+ );
1904
+ }
1905
+ return config;
1929
1906
  }
1930
- #resolveTrackConfig(packetId) {
1931
- return this.#trackConfigs.get(packetId) ?? this.#defaultTrackConfig();
1907
+ /**
1908
+ * Whether this track has the catalog's elapsed-time FEC policy. A zero span
1909
+ * is a deliberate no-deadline signal; it still leaves the wire geometry
1910
+ * usable for in-band decode, but it cannot drive classification, repair
1911
+ * fetches or layer adaptation.
1912
+ */
1913
+ static #hasCatalogTiming(config) {
1914
+ return Number.isSafeInteger(config.interleaveDepthMs) && config.interleaveDepthMs >= MIN_INTERLEAVE_DEPTH_MS;
1915
+ }
1916
+ #hasCatalogTimingForPacket(packetId) {
1917
+ const config = this.#trackConfigs.get(packetId);
1918
+ return config !== void 0 && _FECManager.#hasCatalogTiming(config);
1932
1919
  }
1933
1920
  #computeTimeout(config) {
1934
- if (config.timeoutMs && config.timeoutMs > 0) return config.timeoutMs;
1935
- if (config.interleaveDepthMs >= MIN_INTERLEAVE_DEPTH_MS) {
1921
+ if (typeof config.timeoutMs === "number" && Number.isFinite(config.timeoutMs) && config.timeoutMs > 0) {
1922
+ return config.timeoutMs;
1923
+ }
1924
+ if (Number.isSafeInteger(config.interleaveDepthMs) && config.interleaveDepthMs >= MIN_INTERLEAVE_DEPTH_MS) {
1936
1925
  return Math.max(
1937
1926
  this.#fecTimeoutMs,
1938
1927
  computeFecDeliveryWindowMs({
@@ -1957,14 +1946,17 @@ var FECManager = class _FECManager {
1957
1946
  */
1958
1947
  #refreshDeliveryGapWindow() {
1959
1948
  let windowMs;
1960
- const consider = (geometry) => {
1949
+ const consider = (geometry, packetId) => {
1950
+ if (!this.#hasCatalogTimingForPacket(packetId)) return;
1961
1951
  if (geometry?.trackKind !== "video" || geometry.mode !== "classifying") return;
1962
1952
  const { ticks, timescale } = geometry.keyframeInterval;
1963
1953
  const ms = ticks / timescale * 1e3;
1964
1954
  if (Number.isFinite(ms) && ms > 0 && (windowMs === void 0 || ms > windowMs)) windowMs = ms;
1965
1955
  };
1966
- for (const geometry of this.#streamGeometries.values()) consider(geometry);
1967
- for (const config of this.#trackConfigs.values()) consider(config.geometry);
1956
+ for (const [streamKey, geometry] of this.#streamGeometries) {
1957
+ consider(geometry, this.#parseStreamKey(streamKey).packetId);
1958
+ }
1959
+ for (const [packetId, config] of this.#trackConfigs) consider(config.geometry, packetId);
1968
1960
  this.#deliveryGaps.setWindowMs(windowMs);
1969
1961
  }
1970
1962
  /**
@@ -1992,6 +1984,7 @@ var FECManager = class _FECManager {
1992
1984
  return Math.max(config.timeoutMs, Math.ceil(config.interleaveDepthMs + gapMs));
1993
1985
  }
1994
1986
  #repairDeadlineMs(config, waitMs = this.#multicastWaitMs(config)) {
1987
+ if (!_FECManager.#hasCatalogTiming(config)) return waitMs;
1995
1988
  const halfFailBoundMs = Math.ceil(waitMs / 2);
1996
1989
  if (config.k > 0 && config.interleaveDepthMs >= MIN_INTERLEAVE_DEPTH_MS && config.fps !== void 0 && Number.isFinite(config.fps) && config.fps > 0) {
1997
1990
  const mediaUnitMs = 1e3 / config.fps;
@@ -2006,10 +1999,12 @@ var FECManager = class _FECManager {
2006
1999
  }
2007
2000
  /**
2008
2001
  * One block lifetime: the inactivity fail bound plus the D-28 repair grace,
2009
- * at the widest wait the catalog allows (#maxMulticastWaitMs). Everything
2010
- * derived from it (terminal retention, the release gate's hold ceiling, the
2011
- * duplicate ledgers, the owed-cleanup bound) is compared across time, so it
2012
- * must not follow the live measurement.
2002
+ * at the widest wait the catalog allows (#maxMulticastWaitMs). For a track
2003
+ * without a catalog span this is receiver-local cleanup time only; no repair
2004
+ * grace is added. Everything derived from it (terminal retention, the
2005
+ * release gate's hold ceiling, the duplicate ledgers, the owed-cleanup
2006
+ * bound) is compared across time, so it must not follow the live
2007
+ * measurement.
2013
2008
  */
2014
2009
  #blockLifetimeMs(config) {
2015
2010
  const waitMs = this.#maxMulticastWaitMs(config);
@@ -2025,6 +2020,7 @@ var FECManager = class _FECManager {
2025
2020
  return Math.min(waitMs + this.#repairGraceMs(config, waitMs), this.#blockLifetimeMs(config));
2026
2021
  }
2027
2022
  #repairGraceMs(config, waitMs) {
2023
+ if (!_FECManager.#hasCatalogTiming(config)) return 0;
2028
2024
  return Math.max(1, waitMs - this.#repairDeadlineMs(config, waitMs));
2029
2025
  }
2030
2026
  #armBlockTimeout(sbn, packetId, catalogTrackName, delayMs) {
@@ -2111,51 +2107,72 @@ var FECManager = class _FECManager {
2111
2107
  * stream; every other field stays per packetId.
2112
2108
  */
2113
2109
  #upsertTrackConfig(packetId, config, catalogTrackName) {
2114
- const previous = this.#trackConfigs.get(packetId) ?? this.#defaultTrackConfig();
2110
+ const previousTrack = this.#trackConfigs.get(packetId);
2111
+ const k = config.k ?? previousTrack?.k;
2112
+ if (k === void 0 || !Number.isSafeInteger(k) || k <= 0) {
2113
+ throw new Error(
2114
+ `[FECManager] packetId=${packetId}: fec.k=${String(k)} must be a positive integer; configure the track from its catalog`
2115
+ );
2116
+ }
2117
+ const previous = previousTrack ?? {};
2115
2118
  const streamScopedGeometry = catalogTrackName !== void 0 && config.geometry !== void 0 ? config.geometry : void 0;
2116
2119
  if (streamScopedGeometry !== void 0) {
2117
2120
  const { geometry: _streamGeometry, ...packetLevel } = config;
2118
2121
  config = packetLevel;
2119
2122
  }
2120
2123
  const timingChanged = config.k !== void 0 || config.interleaveDepthMs !== void 0 || config.fps !== void 0;
2124
+ if (config.timeoutMs !== void 0 && (!Number.isFinite(config.timeoutMs) || config.timeoutMs < 0)) {
2125
+ throw new Error(
2126
+ `[FECManager] packetId=${packetId}: timeoutMs=${config.timeoutMs} must be a finite non-negative cleanup budget`
2127
+ );
2128
+ }
2121
2129
  if (config.blockProfile !== void 0) {
2122
2130
  parseFecBlockProfile(config.blockProfile, `packetId=${packetId} fec.blockProfile`);
2123
2131
  }
2124
2132
  const blockProfile = config.blockProfile ?? previous.blockProfile;
2125
2133
  if (blockProfile === void 0) {
2126
2134
  throw new Error(
2127
- `[FECManager] packetId=${packetId}: fec.blockProfile is required ("k-padded-v1" or "iso-ssbg1-v1"); configure the track from its catalog`
2135
+ `[FECManager] packetId=${packetId}: fec.blockProfile is required ("iso-ssbg1-v1"); configure the track from its catalog`
2128
2136
  );
2129
2137
  }
2130
- if (blockProfile === "iso-ssbg1-v1") {
2131
- const ownInterleaveDepthMs = config.interleaveDepthMs ?? this.#trackConfigs.get(packetId)?.interleaveDepthMs;
2132
- if (ownInterleaveDepthMs === void 0 || !Number.isFinite(ownInterleaveDepthMs) || ownInterleaveDepthMs < MIN_INTERLEAVE_DEPTH_MS) {
2133
- throw new Error(
2134
- `[FECManager] packetId=${packetId}: iso-ssbg1-v1 requires the catalog fec.interleaveDepthMs (>= ${MIN_INTERLEAVE_DEPTH_MS} ms; got ${String(ownInterleaveDepthMs)}): it bounds how long block location keeps stated blocks and held sources`
2135
- );
2136
- }
2138
+ const ownInterleaveDepthMs = config.interleaveDepthMs ?? previousTrack?.interleaveDepthMs ?? 0;
2139
+ if (!Number.isSafeInteger(ownInterleaveDepthMs) || ownInterleaveDepthMs !== 0 && ownInterleaveDepthMs < MIN_INTERLEAVE_DEPTH_MS) {
2140
+ throw new Error(
2141
+ `[FECManager] packetId=${packetId}: fec.interleaveDepthMs must be absent, 0, or a finite value >= ${MIN_INTERLEAVE_DEPTH_MS} ms (got ${String(ownInterleaveDepthMs)})`
2142
+ );
2137
2143
  }
2144
+ const hasCatalogTiming = _FECManager.#hasCatalogTiming({ interleaveDepthMs: ownInterleaveDepthMs });
2138
2145
  const next = {
2139
2146
  blockProfile,
2140
- k: config.k ?? previous.k,
2141
- symbolSize: config.symbolSize != null && config.symbolSize > 0 ? config.symbolSize : previous.symbolSize,
2142
- interleaveDepthMs: config.interleaveDepthMs ?? previous.interleaveDepthMs,
2143
- fps: config.fps ?? previous.fps,
2144
- timeoutMs: config.timeoutMs ?? (timingChanged ? 0 : previous.timeoutMs),
2147
+ k,
2148
+ symbolSize: config.symbolSize != null && config.symbolSize > 0 ? config.symbolSize : previousTrack?.symbolSize ?? 0,
2149
+ interleaveDepthMs: ownInterleaveDepthMs,
2150
+ fps: config.fps ?? previous.fps ?? this.#fecFps,
2151
+ timeoutMs: config.timeoutMs ?? (timingChanged ? 0 : previous.timeoutMs ?? 0),
2145
2152
  ...(config.trackKind ?? previous.trackKind) === void 0 ? {} : { trackKind: config.trackKind ?? previous.trackKind },
2146
2153
  ...(config.codec ?? previous.codec) === void 0 ? {} : { codec: config.codec ?? previous.codec },
2147
2154
  ...(config.geometry ?? previous.geometry) === void 0 ? {} : { geometry: config.geometry ?? previous.geometry }
2148
2155
  };
2149
- next.timeoutMs = this.#computeTimeout(next);
2156
+ if (!hasCatalogTiming) {
2157
+ next.timeoutMs = config.timeoutMs !== void 0 && config.timeoutMs > 0 ? config.timeoutMs : previousTrack !== void 0 && previousTrack.interleaveDepthMs === 0 ? previousTrack.timeoutMs : LOCAL_FEC_TIMEOUT_MS;
2158
+ } else {
2159
+ next.timeoutMs = this.#computeTimeout(next);
2160
+ }
2150
2161
  if (this.#multicastSymbolDelivery === "ordered-relay") {
2151
2162
  this.#orderedHorizonBlocksFor(packetId, next);
2152
2163
  }
2153
- if (previous.blockProfile !== void 0 && (previous.blockProfile !== blockProfile || blockProfile === "iso-ssbg1-v1" && previous.k !== next.k)) {
2164
+ const timingPolicyChanged = _FECManager.#hasCatalogTiming({ interleaveDepthMs: previous.interleaveDepthMs ?? 0 }) !== hasCatalogTiming;
2165
+ if (timingPolicyChanged && !hasCatalogTiming) {
2166
+ for (const key of [...this.#repairDeadlines.keys()]) {
2167
+ if (this.#belongsToPacket(key, packetId)) this.#clearRepairDeadline(key);
2168
+ }
2169
+ }
2170
+ if (previous.blockProfile !== void 0 && previous.k !== next.k) {
2154
2171
  this.#dropIsoLocators(packetId);
2155
2172
  }
2156
2173
  this.#trackConfigs.set(packetId, next);
2157
2174
  this.#refreshDeliveryGapWindow();
2158
- let policyChanged = config.geometry !== void 0 && JSON.stringify(config.geometry) !== JSON.stringify(previous.geometry) || config.trackKind !== void 0 && config.trackKind !== previous.trackKind;
2175
+ let policyChanged = timingPolicyChanged || config.geometry !== void 0 && JSON.stringify(config.geometry) !== JSON.stringify(previous.geometry) || config.trackKind !== void 0 && config.trackKind !== previous.trackKind;
2159
2176
  if (streamScopedGeometry !== void 0) {
2160
2177
  const streamKey = this.#streamKey(packetId, catalogTrackName);
2161
2178
  if (JSON.stringify(streamScopedGeometry) !== JSON.stringify(this.#streamGeometries.get(streamKey))) {
@@ -2170,20 +2187,14 @@ var FECManager = class _FECManager {
2170
2187
  if (!this.#belongsToPacket(key, packetId)) continue;
2171
2188
  const stream = this.#parseStreamKey(key);
2172
2189
  const geometry = this.#geometryFor(stream.packetId, stream.catalogTrackName);
2173
- if (JSON.stringify(geometry) === JSON.stringify(classifier.geometry)) continue;
2190
+ if (hasCatalogTiming && JSON.stringify(geometry) === JSON.stringify(classifier.geometry)) continue;
2174
2191
  this.#classifiers.delete(key);
2192
+ if (!hasCatalogTiming) continue;
2175
2193
  this.#applyClassifierChanges(stream.packetId, stream.catalogTrackName, classifier.retire());
2176
2194
  }
2177
2195
  }
2178
2196
  return next;
2179
2197
  }
2180
- #normalizeSymbolData(packetId, data) {
2181
- const symbolSize = this.symbolSizeForPacket(packetId);
2182
- if (symbolSize <= 0 || data.byteLength === symbolSize) return data;
2183
- const normalized = new Uint8Array(symbolSize);
2184
- normalized.set(data.subarray(0, symbolSize));
2185
- return normalized;
2186
- }
2187
2198
  #blockKeysFor(sbn, packetId, catalogTrackName) {
2188
2199
  if (packetId != null && catalogTrackName !== void 0) {
2189
2200
  return [this.#blockKey(sbn, packetId, catalogTrackName)];
@@ -2244,7 +2255,7 @@ var FECManager = class _FECManager {
2244
2255
  ...stats,
2245
2256
  packetId,
2246
2257
  blocksComplete: trackTotal,
2247
- k: this.#resolveTrackConfig(packetId).k,
2258
+ k: this.#trackConfigs.get(packetId)?.k,
2248
2259
  recoveryRate: trackAffected > 0 ? stats.blocksRecovered / trackAffected * 100 : 100,
2249
2260
  packetLossRate: trackTotal > 0 ? trackAffected / trackTotal * 100 : 0
2250
2261
  };
@@ -2256,7 +2267,7 @@ var FECManager = class _FECManager {
2256
2267
  (block) => block.multicastSymbols > 0 && block.moqSymbols > 0
2257
2268
  ).length,
2258
2269
  recentBlockPathCounts: Array.from(this.#blockPathCounts.values()).slice(-24),
2259
- k: this.#fecK,
2270
+ k: this.#streamK,
2260
2271
  // True recovery rate: of blocks that HAD loss, how many were recovered?
2261
2272
  recoveryRate: affected > 0 ? s.blocksRecovered / affected * 100 : 100,
2262
2273
  packetLossRate: total > 0 ? affected / total * 100 : 0,
@@ -2269,7 +2280,6 @@ var FECManager = class _FECManager {
2269
2280
  },
2270
2281
  blocks: stats.blocks.map((block) => ({ ...block })),
2271
2282
  decoder: stats.decoder ? { ...stats.decoder } : void 0,
2272
- altaFailedDetails: stats.altaFailedDetails?.map((detail) => ({ ...detail })),
2273
2283
  packetId
2274
2284
  })),
2275
2285
  repairSymbolSizeMismatches: this.#repairSymbolSizeMismatchCount,
@@ -2376,6 +2386,7 @@ var FECManager = class _FECManager {
2376
2386
  resetMap(this.#blockSourceEsis);
2377
2387
  resetMap(this.#blockAuthoredLengths);
2378
2388
  resetMap(this.#blockRepairRsIds);
2389
+ resetMap(this.#blockRsbLengths);
2379
2390
  resetMap(this.#blockPathCounts);
2380
2391
  resetMap(this.#blockAnchorsMs);
2381
2392
  resetMap(this.#blockCatalogTrackNames);
@@ -2493,6 +2504,7 @@ var FECManager = class _FECManager {
2493
2504
  dropMap(this.#blockSourceEsis);
2494
2505
  dropMap(this.#blockAuthoredLengths);
2495
2506
  dropMap(this.#blockRepairRsIds);
2507
+ dropMap(this.#blockRsbLengths);
2496
2508
  dropMap(this.#blockPathCounts);
2497
2509
  dropMap(this.#blockAnchorsMs);
2498
2510
  dropMap(this.#blockCatalogTrackNames);
@@ -2551,15 +2563,20 @@ var FECManager = class _FECManager {
2551
2563
  }
2552
2564
  }
2553
2565
  }
2554
- /** Record a transport symbol and reject later duplicates of the same packetId/SBN/ESI. */
2566
+ /**
2567
+ * Record a transport symbol and reject later duplicates of the same
2568
+ * packetId/SBN/ESI. `sbn` is the block's SS_Start. A packetId with no
2569
+ * configured block profile has no block geometry: its symbol is refused
2570
+ * (false) and no block state is created for it.
2571
+ */
2555
2572
  feedSymbolFromSource(packetId, sbn, esi, _data, source, catalogTrackName) {
2573
+ if (!this.#hasBlockProfile(packetId)) return false;
2556
2574
  const blockKey = this.#blockKey(sbn, packetId, catalogTrackName);
2557
2575
  const streamKey = this.#streamKey(packetId, catalogTrackName);
2558
2576
  if (source === "multicast" && this.#multicastSymbolDelivery === "ordered-relay") {
2559
2577
  this.#advanceOrderedFrontier(streamKey, sbn, packetId, catalogTrackName);
2560
2578
  }
2561
- const k = this.kForPacket(packetId);
2562
- const sourceSymbols = this.#isIso(packetId) ? this.#isoLocatorFor(packetId, catalogTrackName).blockAt(sbn)?.length ?? k : k;
2579
+ const sourceSymbols = this.#isoLocatorFor(packetId, catalogTrackName).blockAt(sbn)?.length ?? this.#trackConfig(packetId).k;
2563
2580
  const isSourceSymbol = esi >= 0 && esi < sourceSymbols;
2564
2581
  const isStartupPartial = this.#startupPartialBlocks.has(blockKey);
2565
2582
  const isReadyMulticastRepair = this.#startupRequireRepairReady && source === "multicast" && !isSourceSymbol && this.#startupRepairReadyPackets.has(streamKey);
@@ -2677,14 +2694,14 @@ var FECManager = class _FECManager {
2677
2694
  for (const [key] of this.#activeBlocks) {
2678
2695
  const { packetId, sbn } = this.#parseBlockKey(key);
2679
2696
  const count = this.#blockSourceCounts.get(key) ?? 0;
2680
- const k = this.#blockAuthoredLengths.get(key) ?? this.kForPacket(packetId);
2697
+ const k = this.#blockAuthoredLengths.get(key) ?? this.#trackConfig(packetId).k;
2681
2698
  blocks.push({ sbn, packetId, state: "collecting", sourceCount: count, k, progress: k > 0 ? Math.min(count / k, 1) : 0 });
2682
2699
  }
2683
2700
  const completed = [...this.#completedBlocks].slice(-16);
2684
2701
  for (const key of completed) {
2685
2702
  const { packetId, sbn } = this.#parseBlockKey(key);
2686
2703
  if (!this.#activeBlocks.has(key)) {
2687
- const k = this.kForPacket(packetId);
2704
+ const k = this.#trackConfig(packetId).k;
2688
2705
  blocks.push({ sbn, packetId, state: "complete", sourceCount: k, k, progress: 1 });
2689
2706
  }
2690
2707
  }
@@ -2695,25 +2712,23 @@ var FECManager = class _FECManager {
2695
2712
  get wasmDecoder() {
2696
2713
  return this.#fecDecoders.values().next().value?.client ?? null;
2697
2714
  }
2698
- get k() {
2699
- return this.#fecK;
2700
- }
2715
+ /** A configured packetId's K; undefined for an unconfigured one (no FEC work). */
2701
2716
  kForPacket(packetId) {
2702
- return this.#resolveTrackConfig(packetId).k;
2717
+ return this.#trackConfigs.get(packetId)?.k;
2703
2718
  }
2704
2719
  /** FEC symbol size in bytes. */
2705
2720
  get symbolSize() {
2706
2721
  return this.#fecSymbolSize;
2707
2722
  }
2708
2723
  symbolSizeForPacket(packetId) {
2709
- return this.#resolveTrackConfig(packetId).symbolSize;
2724
+ return this.#trackConfigs.get(packetId)?.symbolSize;
2710
2725
  }
2711
2726
  /** FEC block span in milliseconds (0 = no interleaving). */
2712
2727
  get interleaveDepthMs() {
2713
2728
  return this.#fecInterleaveDepthMs;
2714
2729
  }
2715
2730
  interleaveDepthMsForPacket(packetId) {
2716
- return this.#resolveTrackConfig(packetId).interleaveDepthMs;
2731
+ return this.#trackConfigs.get(packetId)?.interleaveDepthMs;
2717
2732
  }
2718
2733
  /**
2719
2734
  * Record one multicast MMTP packet arrival (every packet of the leg, FEC
@@ -2731,7 +2746,8 @@ var FECManager = class _FECManager {
2731
2746
  * plus the larger of the catalog tolerance and the measured delivery gap.
2732
2747
  */
2733
2748
  timeoutMsForPacket(packetId) {
2734
- return this.#multicastWaitMs(this.#resolveTrackConfig(packetId));
2749
+ const config = this.#trackConfigs.get(packetId);
2750
+ return config === void 0 ? void 0 : this.#multicastWaitMs(config);
2735
2751
  }
2736
2752
  /**
2737
2753
  * Largest multicast delivery gap measured over the current window (ms), and
@@ -2743,6 +2759,31 @@ var FECManager = class _FECManager {
2743
2759
  windowMs: this.#deliveryGaps.windowMs
2744
2760
  };
2745
2761
  }
2762
+ /**
2763
+ * An open block's accepted sources, distinct repair RS_IDs, authored K'
2764
+ * (SSB_length) and RSB_length (each undefined until a repair stated it).
2765
+ * Undefined for a block that is not open.
2766
+ */
2767
+ blockSymbolCounts(sbn, packetId, catalogTrackName) {
2768
+ const key = this.#blockKey(sbn, packetId, catalogTrackName);
2769
+ if (!this.#activeBlocks.has(key)) return void 0;
2770
+ return {
2771
+ sources: this.#blockSourceCounts.get(key) ?? 0,
2772
+ repairs: this.#blockRepairRsIds.get(key)?.size ?? 0,
2773
+ authoredLength: this.#blockAuthoredLengths.get(key),
2774
+ repairGroupLength: this.#blockRsbLengths.get(key)
2775
+ };
2776
+ }
2777
+ /**
2778
+ * Record a block's RSB_length from one of its repair symbols (the router
2779
+ * parses it from the Repair FEC Payload ID). The largest stated value wins.
2780
+ */
2781
+ noteRepairGroupLength(sbn, packetId, rsbLength, catalogTrackName) {
2782
+ if (!Number.isSafeInteger(rsbLength) || rsbLength <= 0) return;
2783
+ const key = this.#blockKey(sbn, packetId, catalogTrackName);
2784
+ if (!this.#activeBlocks.has(key)) return;
2785
+ if ((this.#blockRsbLengths.get(key) ?? 0) < rsbLength) this.#blockRsbLengths.set(key, rsbLength);
2786
+ }
2746
2787
  /**
2747
2788
  * Receiver-local time of a block's first accepted symbol, or undefined for
2748
2789
  * a block no symbol reached (one materialized because a later SBN arrived).
@@ -2787,27 +2828,31 @@ var FECManager = class _FECManager {
2787
2828
  }
2788
2829
  /** Resolved per-track D-28 repair request deadline in milliseconds. */
2789
2830
  repairDeadlineMsForPacket(packetId) {
2790
- return this.#repairDeadlineMs(this.#resolveTrackConfig(packetId));
2831
+ const config = this.#trackConfigs.get(packetId);
2832
+ return config === void 0 ? void 0 : this.#repairDeadlineMs(config);
2791
2833
  }
2792
2834
  /**
2793
2835
  * One block lifetime: the longest a block stays open after its last symbol
2794
2836
  * (inactivity fail bound plus D-28 repair grace).
2795
2837
  */
2796
2838
  blockLifetimeMsForPacket(packetId) {
2797
- return this.#blockLifetimeMs(this.#resolveTrackConfig(packetId));
2839
+ const config = this.#trackConfigs.get(packetId);
2840
+ return config === void 0 ? void 0 : this.#blockLifetimeMs(config);
2798
2841
  }
2799
2842
  /**
2800
2843
  * How long a terminal (clean, recovered or failed) block stays authoritative,
2801
2844
  * for late symbols and for the in-order release gate. It is also the gate's
2802
2845
  * hold ceiling (MmtpRouter's holdLimitMs): a retired block reads back as
2803
2846
  * untracked, which the gate counts as lost, so no frame may still be waiting
2804
- * on a block that can retire. The window is one interleave depth for a gap's
2805
- * last block to finish arriving, one block lifetime to fail it, and one more
2806
- * for an owed Worker cleanup that can keep a failing block pending. Every
2807
- * term comes from the track's catalog geometry; there is no separate cap.
2847
+ * on a block that can retire. With a positive catalog span the window is one
2848
+ * interleave depth for a gap's last block to finish arriving, one block
2849
+ * lifetime to fail it, and one more for an owed Worker cleanup. With an
2850
+ * absent/zero span it is a receiver-local cleanup bound only; it creates no
2851
+ * catalog FEC deadline.
2808
2852
  */
2809
2853
  terminalRetentionMsForPacket(packetId) {
2810
- const config = this.#resolveTrackConfig(packetId);
2854
+ const config = this.#trackConfigs.get(packetId);
2855
+ if (config === void 0) return void 0;
2811
2856
  return config.interleaveDepthMs + 2 * this.#blockLifetimeMs(config);
2812
2857
  }
2813
2858
  /** Remaining fetch budget for a specific repair-requested block. */
@@ -2818,7 +2863,8 @@ var FECManager = class _FECManager {
2818
2863
  if (deadlineMs !== void 0) {
2819
2864
  return Math.max(1, Math.ceil(deadlineMs - performance.now()));
2820
2865
  }
2821
- const trackConfig = this.#resolveTrackConfig(packetId);
2866
+ const trackConfig = this.#trackConfigs.get(packetId);
2867
+ if (trackConfig === void 0) return void 0;
2822
2868
  return Math.max(1, trackConfig.timeoutMs - this.#repairDeadlineMs(trackConfig));
2823
2869
  }
2824
2870
  /** True once configureTrack/setFecDecoder/setFecWorker configured this packetId. */
@@ -2829,14 +2875,19 @@ var FECManager = class _FECManager {
2829
2875
  blockProfileForPacket(packetId) {
2830
2876
  return this.#trackConfigs.get(packetId)?.blockProfile;
2831
2877
  }
2832
- #isIso(packetId) {
2833
- return this.#trackConfigs.get(packetId)?.blockProfile === "iso-ssbg1-v1";
2878
+ /**
2879
+ * Whether a packetId has a configured block geometry. iso-ssbg1-v1 is the
2880
+ * only profile, so every configured track has it; a packetId never
2881
+ * configured (or released) has none and gets no FEC block tracking.
2882
+ */
2883
+ #hasBlockProfile(packetId) {
2884
+ return this.#trackConfigs.get(packetId)?.blockProfile !== void 0;
2834
2885
  }
2835
2886
  #isoLocatorFor(packetId, catalogTrackName) {
2836
2887
  const streamKey = this.#streamKey(packetId, catalogTrackName);
2837
2888
  let locator = this.#isoLocators.get(streamKey);
2838
2889
  if (!locator) {
2839
- locator = new IsoBlockLocator(this.kForPacket(packetId), this.#isoRetentionBlocks(packetId));
2890
+ locator = new IsoBlockLocator(this.#trackConfig(packetId).k, this.#isoRetentionBlocks(packetId));
2840
2891
  this.#isoLocators.set(streamKey, locator);
2841
2892
  }
2842
2893
  return locator;
@@ -2867,12 +2918,14 @@ var FECManager = class _FECManager {
2867
2918
  */
2868
2919
  #isoRetentionBlocks(packetId) {
2869
2920
  const config = this.#trackConfigs.get(packetId);
2870
- if (config?.blockProfile !== "iso-ssbg1-v1" || !(config.interleaveDepthMs >= MIN_INTERLEAVE_DEPTH_MS)) {
2921
+ if (config?.blockProfile === void 0) {
2871
2922
  throw new Error(
2872
- `[FECManager] packetId=${packetId} has no iso-ssbg1-v1 block span to derive block-location retention from`
2923
+ `[FECManager] packetId=${packetId} has no configured iso-ssbg1-v1 block profile`
2873
2924
  );
2874
2925
  }
2875
- const blocks = Math.ceil(this.terminalRetentionMsForPacket(packetId) / config.interleaveDepthMs) + 1;
2926
+ if (!_FECManager.#hasCatalogTiming(config)) return LOCAL_FEC_RETENTION_BLOCKS;
2927
+ const terminalRetentionMs = config.interleaveDepthMs + 2 * this.#blockLifetimeMs(config);
2928
+ const blocks = Math.ceil(terminalRetentionMs / config.interleaveDepthMs) + 1;
2876
2929
  if (!Number.isSafeInteger(blocks) || blocks <= 0) {
2877
2930
  throw new Error(`[FECManager] packetId=${packetId} iso-ssbg1-v1 retention of ${blocks} blocks is not derivable`);
2878
2931
  }
@@ -2880,7 +2933,8 @@ var FECManager = class _FECManager {
2880
2933
  }
2881
2934
  /** Whether an iso-ssbg1-v1 protected packet fits one ssbg_mode1 symbol (len + 2 <= T). */
2882
2935
  isoSourceFits(packetId, packetLength) {
2883
- return ssbg1FitsSymbol(packetLength, this.symbolSizeForPacket(packetId));
2936
+ const symbolSize = this.#trackConfigs.get(packetId)?.symbolSize;
2937
+ return symbolSize !== void 0 && ssbg1FitsSymbol(packetLength, symbolSize);
2884
2938
  }
2885
2939
  /**
2886
2940
  * Locate an iso-ssbg1-v1 source by range membership in a block a repair
@@ -2941,11 +2995,11 @@ var FECManager = class _FECManager {
2941
2995
  * that could hold them is pending or not yet stated by a repair, else the
2942
2996
  * starts of the blocks that failed or vanished.
2943
2997
  *
2944
- * `untracked` reads exactly as in the k-padded-v1 release gate
2945
- * (MmtpRouter #createFecReleaseGate): a block holding either released
2946
- * frame's SS_ID (`fromSsId` or `toSsId`) delivered that frame, so untracked
2947
- * there means it resolved and retired; a block starting after the stream's frontier (`highestSbn`,
2948
- * an SS_Start here) may still be heard from; a block at or behind the
2998
+ * `untracked` reads as the release gate reads it (MmtpRouter
2999
+ * #createFecReleaseGate): a block holding either released frame's SS_ID
3000
+ * (`fromSsId` or `toSsId`) delivered that frame, so untracked there means it
3001
+ * resolved and retired; a block starting after the stream's frontier
3002
+ * (`highestSbn`, an SS_Start) may still be heard from; a block at or behind the
2949
3003
  * frontier that no symbol of this manager ever reached vanished, and its
2950
3004
  * media is lost.
2951
3005
  */
@@ -3013,6 +3067,7 @@ var FECManager = class _FECManager {
3013
3067
  }
3014
3068
  /** Current classifier mode of a stream. */
3015
3069
  classifierModeFor(packetId, catalogTrackName) {
3070
+ if (!this.#hasCatalogTimingForPacket(packetId)) return { mode: "all-protected", reason: null };
3016
3071
  const classifier = this.#classifierFor(packetId, catalogTrackName);
3017
3072
  return { mode: classifier.mode, reason: classifier.reason };
3018
3073
  }
@@ -3022,10 +3077,12 @@ var FECManager = class _FECManager {
3022
3077
  * it does not. A stream with no classifier yet has shown nothing against it.
3023
3078
  */
3024
3079
  mpuBoundsRapsFor(packetId, catalogTrackName) {
3080
+ if (!this.#hasCatalogTimingForPacket(packetId)) return false;
3025
3081
  return this.#classifiers.get(this.#streamKey(packetId, catalogTrackName))?.mpuBoundsRaps ?? true;
3026
3082
  }
3027
3083
  /** A block's class now, or frozen at its resolution. */
3028
3084
  blockClassFor(sbn, packetId, catalogTrackName) {
3085
+ if (!this.#hasCatalogTimingForPacket(packetId)) return "unknown";
3029
3086
  const frozen = this.#resolvedBlockClasses.get(this.#blockKey(sbn, packetId, catalogTrackName));
3030
3087
  if (frozen !== void 0) return frozen;
3031
3088
  return this.#peekClass(sbn, packetId, catalogTrackName);
@@ -3047,7 +3104,7 @@ var FECManager = class _FECManager {
3047
3104
  * invariant (consecutive MPUs exactly one keyframe interval apart).
3048
3105
  */
3049
3106
  noteReleasedRap(packetId, catalogTrackName, mpu, presentationTime, mediaTimescale) {
3050
- if (!this.#trackConfigs.has(packetId)) return;
3107
+ if (!this.#trackConfigs.has(packetId) || !this.#hasCatalogTimingForPacket(packetId)) return;
3051
3108
  this.#applyClassifierChanges(
3052
3109
  packetId,
3053
3110
  catalogTrackName,
@@ -3063,27 +3120,34 @@ var FECManager = class _FECManager {
3063
3120
  // -----------------------------------------------------------------------
3064
3121
  /** Configure FEC parameters. */
3065
3122
  configure(config) {
3066
- if (config.k != null) this.#fecK = config.k;
3123
+ if (config.interleaveDepthMs != null && (!Number.isSafeInteger(config.interleaveDepthMs) || config.interleaveDepthMs < 0)) {
3124
+ throw new Error(
3125
+ `[FECManager] interleaveDepthMs=${config.interleaveDepthMs} must be a non-negative safe integer in milliseconds`
3126
+ );
3127
+ }
3128
+ if (config.timeoutMs != null && (!Number.isFinite(config.timeoutMs) || config.timeoutMs < 0)) {
3129
+ throw new Error(
3130
+ `[FECManager] timeoutMs=${config.timeoutMs} must be a finite non-negative cleanup budget`
3131
+ );
3132
+ }
3133
+ if (config.k != null && (!Number.isSafeInteger(config.k) || config.k <= 0)) {
3134
+ throw new Error(`[FECManager] k=${config.k} must be a positive integer`);
3135
+ }
3136
+ if (config.k != null) this.#streamK = config.k;
3067
3137
  if (config.symbolSize != null && config.symbolSize > 0) this.#fecSymbolSize = config.symbolSize;
3068
3138
  if (config.interleaveDepthMs != null) this.#fecInterleaveDepthMs = config.interleaveDepthMs;
3069
3139
  if (config.fps != null && Number.isFinite(config.fps) && config.fps > 0) {
3070
3140
  this.#fecFps = config.fps;
3071
3141
  }
3072
- if (config.interleaveDepthMs != null && config.interleaveDepthMs > 0 && config.interleaveDepthMs < MIN_INTERLEAVE_DEPTH_MS) {
3073
- console.warn(`[FECManager] interleaveDepthMs=${config.interleaveDepthMs} looks like frame count, not milliseconds (\xA75.1 requires ms). Expected range: ${MIN_INTERLEAVE_DEPTH_MS}-10000ms.`);
3074
- }
3075
3142
  if (config.timeoutMs != null && config.timeoutMs > 0) {
3076
3143
  this.#fecTimeoutMs = config.timeoutMs;
3077
- } else if (config.interleaveDepthMs != null && config.interleaveDepthMs >= MIN_INTERLEAVE_DEPTH_MS) {
3078
- this.#fecTimeoutMs = computeFecDeliveryWindowMs({
3079
- interleaveDepthMs: config.interleaveDepthMs,
3080
- sourceSymbols: this.#fecK,
3081
- symbolSize: this.#fecSymbolSize,
3082
- mediaUnitsPerSecond: config.fps
3083
- });
3144
+ } else if (config.interleaveDepthMs === 0) {
3145
+ this.#fecTimeoutMs = LOCAL_FEC_TIMEOUT_MS;
3146
+ } else if (config.interleaveDepthMs != null && Number.isSafeInteger(config.interleaveDepthMs) && config.interleaveDepthMs >= MIN_INTERLEAVE_DEPTH_MS) {
3147
+ this.#fecTimeoutMs = fecSpanDeliveryWindowMs(config.interleaveDepthMs);
3084
3148
  }
3085
3149
  for (const [packetId, track] of this.#trackConfigs) {
3086
- if (track.timeoutMs < this.#fecTimeoutMs) {
3150
+ if (_FECManager.#hasCatalogTiming(track) && track.timeoutMs < this.#fecTimeoutMs) {
3087
3151
  this.#trackConfigs.set(packetId, { ...track, timeoutMs: this.#fecTimeoutMs });
3088
3152
  }
3089
3153
  }
@@ -3142,7 +3206,7 @@ var FECManager = class _FECManager {
3142
3206
  );
3143
3207
  }
3144
3208
  if (config) this.#upsertTrackConfig(packetId, config, catalogTrackName);
3145
- const workerK = this.#resolveTrackConfig(packetId).k;
3209
+ const workerK = this.#trackConfig(packetId).k;
3146
3210
  this.#workerClients.set(streamKey, client);
3147
3211
  this.#releasedWorkerClients.delete(client);
3148
3212
  client.onFrame((data, meta) => {
@@ -3322,7 +3386,7 @@ var FECManager = class _FECManager {
3322
3386
  return;
3323
3387
  }
3324
3388
  this.#settleOwedCleanup(key, "cleanup-ack-timeout");
3325
- }, Math.ceil(this.#liveBlockLifetimeMs(this.#resolveTrackConfig(packetId))))
3389
+ }, Math.ceil(this.#liveBlockLifetimeMs(this.#trackConfig(packetId))))
3326
3390
  };
3327
3391
  this.#pendingWorkerCleanupBounds.set(key, bound);
3328
3392
  }
@@ -3363,16 +3427,11 @@ var FECManager = class _FECManager {
3363
3427
  if (this.#fpsDetected || fps <= 0) return;
3364
3428
  this.#fpsDetected = true;
3365
3429
  this.#fecFps = fps;
3366
- if (this.#fecInterleaveDepthMs >= MIN_INTERLEAVE_DEPTH_MS) {
3367
- this.#fecTimeoutMs = computeFecDeliveryWindowMs({
3368
- interleaveDepthMs: this.#fecInterleaveDepthMs,
3369
- sourceSymbols: this.#fecK,
3370
- symbolSize: this.#fecSymbolSize,
3371
- mediaUnitsPerSecond: fps
3372
- });
3430
+ if (Number.isSafeInteger(this.#fecInterleaveDepthMs) && this.#fecInterleaveDepthMs >= MIN_INTERLEAVE_DEPTH_MS) {
3431
+ this.#fecTimeoutMs = fecSpanDeliveryWindowMs(this.#fecInterleaveDepthMs);
3373
3432
  }
3374
3433
  for (const [packetId, config] of this.#trackConfigs) {
3375
- if (config.fps !== void 0 || config.interleaveDepthMs < MIN_INTERLEAVE_DEPTH_MS) continue;
3434
+ if (config.fps !== void 0 || !Number.isSafeInteger(config.interleaveDepthMs) || config.interleaveDepthMs < MIN_INTERLEAVE_DEPTH_MS) continue;
3376
3435
  this.#trackConfigs.set(packetId, {
3377
3436
  ...config,
3378
3437
  fps,
@@ -3401,51 +3460,33 @@ var FECManager = class _FECManager {
3401
3460
  * Caller is responsible for routing recovered data and updating
3402
3461
  * block completion state via `markBlockCompleted()`.
3403
3462
  */
3404
- feedSourceSymbol(packetId, ssId, symbolData, alta, catalogTrackName) {
3463
+ feedSourceSymbol(packetId, ssId, symbolData, catalogTrackName) {
3405
3464
  this.#fecStats.sourcePackets++;
3406
3465
  this.#statsForPacket(packetId).sourcePackets++;
3407
- let sbn;
3408
- let fecData;
3409
- if (this.#isIso(packetId)) {
3410
- const locator = this.#isoLocatorFor(packetId, catalogTrackName);
3411
- const located = locator.locate(ssId);
3412
- if (located === null) {
3413
- throw new Error(
3414
- `[FECManager] iso-ssbg1-v1 source SS_ID=${ssId} (packetId=${packetId}) has no stated block; hold it until a repair places it (placeIsoRepair)`
3415
- );
3416
- }
3417
- locator.observe(ssId);
3418
- if (!ssbg1FitsSymbol(symbolData.byteLength, this.symbolSizeForPacket(packetId))) {
3419
- this.#isoSourceOversizeCount++;
3420
- return null;
3421
- }
3422
- sbn = located.block.start;
3423
- fecData = symbolData;
3424
- } else {
3425
- fecData = this.#normalizeSymbolData(packetId, symbolData);
3426
- sbn = Math.floor(ssId / this.kForPacket(packetId));
3466
+ if (!this.#hasBlockProfile(packetId)) return null;
3467
+ const locator = this.#isoLocatorFor(packetId, catalogTrackName);
3468
+ const located = locator.locate(ssId);
3469
+ if (located === null) {
3470
+ throw new Error(
3471
+ `[FECManager] iso-ssbg1-v1 source SS_ID=${ssId} (packetId=${packetId}) has no stated block; hold it until a repair places it (placeIsoRepair)`
3472
+ );
3473
+ }
3474
+ locator.observe(ssId);
3475
+ if (!ssbg1FitsSymbol(symbolData.byteLength, this.#trackConfig(packetId).symbolSize)) {
3476
+ this.#isoSourceOversizeCount++;
3477
+ return null;
3427
3478
  }
3479
+ const sbn = located.block.start;
3428
3480
  const blockKey = this.#blockKey(sbn, packetId, catalogTrackName);
3429
3481
  const syncBlockOwner = this.#syncDecoderBlockOwners.get(blockKey);
3430
3482
  const workerClient = this.#routableWorkerForPacket(packetId, catalogTrackName);
3431
3483
  if (workerClient && !syncBlockOwner) {
3432
3484
  if (!this.#claimDecoderBlock(workerClient, sbn, catalogTrackName)) return null;
3433
- const buf = fecData !== symbolData ? fecData.buffer : fecData.buffer.slice(
3434
- fecData.byteOffset,
3435
- fecData.byteOffset + fecData.byteLength
3485
+ const buf = symbolData.buffer.slice(
3486
+ symbolData.byteOffset,
3487
+ symbolData.byteOffset + symbolData.byteLength
3436
3488
  );
3437
- if (alta) {
3438
- const authBuf = alta.auth.buffer.slice(
3439
- alta.auth.byteOffset,
3440
- alta.auth.byteOffset + alta.auth.byteLength
3441
- );
3442
- workerClient.feedSource(ssId, buf, performance.now(), {
3443
- auth: authBuf,
3444
- payloadEnd: alta.payloadEnd
3445
- });
3446
- } else {
3447
- workerClient.feedSource(ssId, buf, performance.now());
3448
- }
3489
+ workerClient.feedSource(ssId, buf, performance.now());
3449
3490
  return null;
3450
3491
  }
3451
3492
  const entry = this.#decoderForPacket(packetId, catalogTrackName);
@@ -3455,7 +3496,7 @@ var FECManager = class _FECManager {
3455
3496
  this.#syncDecoderBlockOwners.set(blockKey, client);
3456
3497
  let recovered = null;
3457
3498
  try {
3458
- recovered = client.add_source(ssId, fecData, performance.now());
3499
+ recovered = client.add_source(ssId, symbolData, performance.now());
3459
3500
  } catch {
3460
3501
  }
3461
3502
  this.#retireIsoUnplaced(client, packetId, catalogTrackName);
@@ -3474,7 +3515,8 @@ var FECManager = class _FECManager {
3474
3515
  feedRepairSymbol(packetId, ssStart, ssbLength, rsId, repairData, catalogTrackName) {
3475
3516
  this.#fecStats.repairPackets++;
3476
3517
  this.#statsForPacket(packetId).repairPackets++;
3477
- const symbolSize = this.symbolSizeForPacket(packetId);
3518
+ if (!this.#hasBlockProfile(packetId)) return null;
3519
+ const symbolSize = this.#trackConfig(packetId).symbolSize;
3478
3520
  if (symbolSize > 0 && repairData.byteLength !== symbolSize) {
3479
3521
  this.#repairSymbolSizeMismatchCount++;
3480
3522
  if (this.#repairSymbolSizeMismatchCount <= 5 || this.#repairSymbolSizeMismatchCount % 100 === 0) {
@@ -3485,18 +3527,12 @@ var FECManager = class _FECManager {
3485
3527
  return null;
3486
3528
  }
3487
3529
  const fecData = repairData;
3488
- const k = this.kForPacket(packetId);
3489
- let sbn;
3490
- if (this.#isIso(packetId)) {
3491
- const block = this.#isoLocatorFor(packetId, catalogTrackName).blockAt(ssStart);
3492
- if (ssbLength <= 0 || ssbLength > k || block === void 0 || block.span || block.length !== ssbLength) {
3493
- return null;
3494
- }
3495
- sbn = ssStart;
3496
- } else {
3497
- if (ssbLength <= 0 || ssbLength > k || ssStart % k !== 0) return null;
3498
- sbn = Math.floor(ssStart / k);
3530
+ const k = this.#trackConfig(packetId).k;
3531
+ const block = this.#isoLocatorFor(packetId, catalogTrackName).blockAt(ssStart);
3532
+ if (ssbLength <= 0 || ssbLength > k || block === void 0 || block.span || block.length !== ssbLength) {
3533
+ return null;
3499
3534
  }
3535
+ const sbn = ssStart;
3500
3536
  this.#noteSbnSeen(sbn, packetId, catalogTrackName, "repair");
3501
3537
  this.noteBlockActivity(sbn, packetId, catalogTrackName);
3502
3538
  const blockKey = this.#blockKey(sbn, packetId, catalogTrackName);
@@ -3534,8 +3570,9 @@ var FECManager = class _FECManager {
3534
3570
  * Record a block's authored SSB_length from a repair symbol. Returns false,
3535
3571
  * leaving the block unchanged, when the symbol contradicts the block: a
3536
3572
  * different SSB_length than an earlier repair symbol declared is dropped,
3537
- * and an SSB_length that places an already-received source ESI inside the
3538
- * zero padding fails the block, since its geometry can no longer be trusted.
3573
+ * and an SSB_length that places an already-received source ESI at or past
3574
+ * the block's end fails the block, since its geometry can no longer be
3575
+ * trusted.
3539
3576
  */
3540
3577
  #noteAuthoredLength(blockKey, sbn, packetId, ssbLength, catalogTrackName) {
3541
3578
  const known = this.#blockAuthoredLengths.get(blockKey);
@@ -3602,7 +3639,7 @@ var FECManager = class _FECManager {
3602
3639
  * a sweep tied to expiry alone would never run there.
3603
3640
  */
3604
3641
  #retireIsoUnplaced(decoder, packetId, catalogTrackName) {
3605
- if (!this.#isIso(packetId)) return;
3642
+ if (!this.#hasBlockProfile(packetId)) return;
3606
3643
  const newest = this.#isoLocators.get(this.#streamKey(packetId, catalogTrackName))?.newest;
3607
3644
  if (newest === void 0) return;
3608
3645
  try {
@@ -3647,11 +3684,13 @@ var FECManager = class _FECManager {
3647
3684
  this.#failBlock(sbn, packetId, catalogTrackName);
3648
3685
  return;
3649
3686
  }
3650
- this.#applyClassifierChanges(
3651
- packetId,
3652
- catalogTrackName,
3653
- this.#classifierFor(packetId, catalogTrackName).observe(sbn, evidence)
3654
- );
3687
+ if (_FECManager.#hasCatalogTiming(trackConfig)) {
3688
+ this.#applyClassifierChanges(
3689
+ packetId,
3690
+ catalogTrackName,
3691
+ this.#classifierFor(packetId, catalogTrackName).observe(sbn, evidence)
3692
+ );
3693
+ }
3655
3694
  const count = (this.#blockSourceCounts.get(key) ?? 0) + 1;
3656
3695
  this.#blockSourceCounts.set(key, count);
3657
3696
  if (count === 1) this.#indexBlockKey(key, sbn, packetId);
@@ -3684,6 +3723,7 @@ var FECManager = class _FECManager {
3684
3723
  this.#blockSourceEsis.delete(key);
3685
3724
  this.#blockAuthoredLengths.delete(key);
3686
3725
  this.#blockRepairRsIds.delete(key);
3726
+ this.#blockRsbLengths.delete(key);
3687
3727
  this.#markTerminal(key, sbn, packetId, true);
3688
3728
  this.#markPathBlockComplete(sbn, packetId, catalogTrackName);
3689
3729
  if (catalogTrackName === void 0) {
@@ -3695,6 +3735,7 @@ var FECManager = class _FECManager {
3695
3735
  }
3696
3736
  /** Refresh deadlines after accepted block activity. */
3697
3737
  noteBlockActivity(sbn, packetId, catalogTrackName, sourceProgress = false) {
3738
+ if (!this.#trackConfigs.has(packetId)) return;
3698
3739
  const key = this.#blockKey(sbn, packetId, catalogTrackName);
3699
3740
  if (this.#completedBlocks.has(key)) return;
3700
3741
  if (this.#pendingWorkerCleanups.has(key)) return;
@@ -3704,13 +3745,13 @@ var FECManager = class _FECManager {
3704
3745
  this.#holdForOrderedSettlement(key, sbn, packetId, catalogTrackName);
3705
3746
  return;
3706
3747
  }
3707
- const trackConfig = this.#resolveTrackConfig(packetId);
3748
+ const trackConfig = this.#trackConfig(packetId);
3708
3749
  const timeoutMs = this.#multicastWaitMs(trackConfig);
3709
3750
  if (!(timeoutMs > 0)) {
3710
3751
  throw new Error(`[FECManager] packetId=${packetId} has no positive fail bound (timeoutMs=${timeoutMs})`);
3711
3752
  }
3712
3753
  const repairDeadline = this.#repairDeadlines.get(key);
3713
- if (this.onRepairNeeded && !repairRequested && (repairDeadline === void 0 || sourceProgress)) {
3754
+ if (this.#hasCatalogTimingForPacket(packetId) && this.onRepairNeeded && !repairRequested && (repairDeadline === void 0 || sourceProgress)) {
3714
3755
  this.#armRepairDeadline(
3715
3756
  key,
3716
3757
  sbn,
@@ -3734,6 +3775,7 @@ var FECManager = class _FECManager {
3734
3775
  this.#blockSourceEsis.delete(key);
3735
3776
  this.#blockAuthoredLengths.delete(key);
3736
3777
  this.#blockRepairRsIds.delete(key);
3778
+ this.#blockRsbLengths.delete(key);
3737
3779
  this.#syncDecoderBlockOwners.delete(key);
3738
3780
  this.#markTerminal(key, sbn, packetId, false);
3739
3781
  this.#failedBlocks.add(key);
@@ -3771,6 +3813,7 @@ var FECManager = class _FECManager {
3771
3813
  this.#blockSourceEsis.delete(key);
3772
3814
  this.#blockAuthoredLengths.delete(key);
3773
3815
  this.#blockRepairRsIds.delete(key);
3816
+ this.#blockRsbLengths.delete(key);
3774
3817
  this.#clearBlockTimer(key);
3775
3818
  this.onBlockResolved?.(block.sbn, block.packetId, block.catalogTrackName);
3776
3819
  }
@@ -3780,6 +3823,7 @@ var FECManager = class _FECManager {
3780
3823
  }
3781
3824
  /** Mark a block as completed externally (e.g., after routing recovered data). */
3782
3825
  markBlockCompleted(sbn, packetId, catalogTrackName) {
3826
+ if (packetId != null && !this.#trackConfigs.has(packetId)) return;
3783
3827
  for (const key of this.#blockKeysFor(sbn, packetId, catalogTrackName)) {
3784
3828
  this.#resolveCompleted(key);
3785
3829
  }
@@ -3860,6 +3904,7 @@ var FECManager = class _FECManager {
3860
3904
  this.#blockSourceEsis.clear();
3861
3905
  this.#blockAuthoredLengths.clear();
3862
3906
  this.#blockRepairRsIds.clear();
3907
+ this.#blockRsbLengths.clear();
3863
3908
  this.#completedBlocks.clear();
3864
3909
  this.#cleanlyCompletedBlocks.clear();
3865
3910
  this.#repairRequestedBlocks.clear();