@blockcast/mmt-container 0.3.0-main.dd5b3a8dcbc8 → 0.3.0-main.e4bf1a9cc227

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 (530) hide show
  1. package/dist/browser-runtime.js +332 -134
  2. package/dist/browser-runtime.js.map +4 -4
  3. package/dist/carp-catalog.d.ts +2 -2
  4. package/dist/carp-catalog.d.ts.map +1 -1
  5. package/dist/carp-catalog.js +2 -2
  6. package/dist/carp-catalog.js.map +2 -2
  7. package/dist/catalog-fec-params.d.ts +26 -6
  8. package/dist/catalog-fec-params.d.ts.map +1 -1
  9. package/dist/catalog-fec-params.js +27 -13
  10. package/dist/catalog-fec-params.js.map +2 -2
  11. package/dist/delta-fallback-config.d.ts +42 -0
  12. package/dist/delta-fallback-config.d.ts.map +1 -0
  13. package/dist/delta-fallback-config.js +59 -0
  14. package/dist/delta-fallback-config.js.map +7 -0
  15. package/dist/fec-manager.d.ts +5 -4
  16. package/dist/fec-manager.d.ts.map +1 -1
  17. package/dist/fec-manager.js +116 -45
  18. package/dist/fec-manager.js.map +2 -2
  19. package/dist/fec-state.d.ts +7 -28
  20. package/dist/fec-state.d.ts.map +1 -1
  21. package/dist/fec-state.js +2 -2
  22. package/dist/fec-state.js.map +2 -2
  23. package/dist/fec-worker-setup.d.ts +7 -3
  24. package/dist/fec-worker-setup.d.ts.map +1 -1
  25. package/dist/fec-worker-setup.js +58 -20
  26. package/dist/fec-worker-setup.js.map +2 -2
  27. package/dist/index.d.ts +3 -2
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +8 -0
  30. package/dist/index.js.map +2 -2
  31. package/dist/media-router.d.ts +19 -8
  32. package/dist/media-router.d.ts.map +1 -1
  33. package/dist/media-router.js +25 -15
  34. package/dist/media-router.js.map +2 -2
  35. package/dist/mmtp-container-parser.no-modules.js +4 -5
  36. package/dist/mmtp-container-parser.no-modules.js.map +2 -2
  37. package/dist/mmtp-router.d.ts +1 -1
  38. package/dist/mmtp-router.d.ts.map +1 -1
  39. package/dist/mmtp-router.js +1 -1
  40. package/dist/mmtp-router.js.map +2 -2
  41. package/dist/multicast-manager.d.ts +2 -2
  42. package/dist/multicast-manager.d.ts.map +1 -1
  43. package/dist/multicast-manager.js +193 -94
  44. package/dist/multicast-manager.js.map +3 -3
  45. package/dist/multicast-transport.d.ts +1 -1
  46. package/dist/multicast-transport.d.ts.map +1 -1
  47. package/dist/multicast-transport.js +42 -12
  48. package/dist/multicast-transport.js.map +3 -3
  49. package/dist/no-modules.js +3 -4
  50. package/dist/no-modules.js.map +2 -2
  51. package/dist/track-session.d.ts.map +1 -1
  52. package/dist/track-session.js +4 -0
  53. package/dist/track-session.js.map +2 -2
  54. package/package.json +8 -14
  55. package/schemas/catalog.schema.json +1 -1
  56. package/src/carp-catalog.ts +5 -4
  57. package/src/catalog-fec-params.ts +64 -29
  58. package/src/delta-fallback-config.ts +72 -0
  59. package/src/fec-manager.ts +180 -52
  60. package/src/fec-state.ts +8 -29
  61. package/src/fec-worker-setup.ts +90 -48
  62. package/src/index.ts +8 -0
  63. package/src/media-router.ts +47 -22
  64. package/src/mmtp-router.ts +2 -2
  65. package/src/multicast-manager.ts +36 -36
  66. package/src/multicast-transport.ts +16 -9
  67. package/src/track-session.ts +11 -0
  68. package/test-vectors/catalog-timing.json +356 -0
  69. package/node_modules/@blockcast/fec-worker/README.md +0 -223
  70. package/node_modules/@blockcast/fec-worker/dist/.build-stamp +0 -0
  71. package/node_modules/@blockcast/fec-worker/dist/block-order.d.ts +0 -22
  72. package/node_modules/@blockcast/fec-worker/dist/block-order.d.ts.map +0 -1
  73. package/node_modules/@blockcast/fec-worker/dist/block-order.js +0 -48
  74. package/node_modules/@blockcast/fec-worker/dist/block-order.js.map +0 -1
  75. package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.d.ts +0 -92
  76. package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.d.ts.map +0 -1
  77. package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.js +0 -345
  78. package/node_modules/@blockcast/fec-worker/dist/fec-worker-client.js.map +0 -1
  79. package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.d.ts +0 -373
  80. package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.d.ts.map +0 -1
  81. package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.js +0 -11
  82. package/node_modules/@blockcast/fec-worker/dist/fec-worker-types.js.map +0 -1
  83. package/node_modules/@blockcast/fec-worker/dist/fec-worker.d.ts +0 -14
  84. package/node_modules/@blockcast/fec-worker/dist/fec-worker.d.ts.map +0 -1
  85. package/node_modules/@blockcast/fec-worker/dist/fec-worker.js +0 -764
  86. package/node_modules/@blockcast/fec-worker/dist/fec-worker.js.map +0 -7
  87. package/node_modules/@blockcast/fec-worker/dist/index.d.ts +0 -10
  88. package/node_modules/@blockcast/fec-worker/dist/index.d.ts.map +0 -1
  89. package/node_modules/@blockcast/fec-worker/dist/index.js +0 -8
  90. package/node_modules/@blockcast/fec-worker/dist/index.js.map +0 -1
  91. package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.d.ts +0 -20
  92. package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.d.ts.map +0 -1
  93. package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.js +0 -370
  94. package/node_modules/@blockcast/fec-worker/dist/shred-fec-worker.js.map +0 -7
  95. package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.d.ts +0 -104
  96. package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.d.ts.map +0 -1
  97. package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.js +0 -181
  98. package/node_modules/@blockcast/fec-worker/dist/shred-worker-client.js.map +0 -1
  99. package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.d.ts +0 -194
  100. package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.d.ts.map +0 -1
  101. package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.js +0 -62
  102. package/node_modules/@blockcast/fec-worker/dist/shred-worker-types.js.map +0 -1
  103. package/node_modules/@blockcast/fec-worker/dist/transfer.d.ts +0 -9
  104. package/node_modules/@blockcast/fec-worker/dist/transfer.d.ts.map +0 -1
  105. package/node_modules/@blockcast/fec-worker/dist/transfer.js +0 -13
  106. package/node_modules/@blockcast/fec-worker/dist/transfer.js.map +0 -1
  107. package/node_modules/@blockcast/fec-worker/package.json +0 -59
  108. package/node_modules/@blockcast/fec-worker/src/block-order.ts +0 -59
  109. package/node_modules/@blockcast/fec-worker/src/fec-worker-client.ts +0 -391
  110. package/node_modules/@blockcast/fec-worker/src/fec-worker-types.ts +0 -392
  111. package/node_modules/@blockcast/fec-worker/src/fec-worker.ts +0 -1386
  112. package/node_modules/@blockcast/fec-worker/src/index.ts +0 -35
  113. package/node_modules/@blockcast/fec-worker/src/shred-fec-worker.ts +0 -589
  114. package/node_modules/@blockcast/fec-worker/src/shred-worker-client.ts +0 -222
  115. package/node_modules/@blockcast/fec-worker/src/shred-worker-types.ts +0 -209
  116. package/node_modules/@blockcast/fec-worker/src/transfer.ts +0 -12
  117. package/node_modules/@blockcast/mmt-alta-parse/README.md +0 -181
  118. package/node_modules/@blockcast/mmt-alta-parse/dist/.build-stamp +0 -0
  119. package/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts +0 -57
  120. package/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts.map +0 -1
  121. package/node_modules/@blockcast/mmt-alta-parse/dist/index.js +0 -115
  122. package/node_modules/@blockcast/mmt-alta-parse/dist/index.js.map +0 -1
  123. package/node_modules/@blockcast/mmt-alta-parse/package.json +0 -50
  124. package/node_modules/@blockcast/mmt-alta-parse/src/index.ts +0 -136
  125. package/node_modules/@blockcast/mmt-base/README.md +0 -134
  126. package/node_modules/@blockcast/mmt-base/dist/.build-stamp +0 -0
  127. package/node_modules/@blockcast/mmt-base/dist/fec-block-profile.d.ts +0 -55
  128. package/node_modules/@blockcast/mmt-base/dist/fec-block-profile.d.ts.map +0 -1
  129. package/node_modules/@blockcast/mmt-base/dist/fec-block-profile.js +0 -132
  130. package/node_modules/@blockcast/mmt-base/dist/fec-block-profile.js.map +0 -1
  131. package/node_modules/@blockcast/mmt-base/dist/index.d.ts +0 -7
  132. package/node_modules/@blockcast/mmt-base/dist/index.d.ts.map +0 -1
  133. package/node_modules/@blockcast/mmt-base/dist/index.js +0 -7
  134. package/node_modules/@blockcast/mmt-base/dist/index.js.map +0 -1
  135. package/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts +0 -292
  136. package/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts.map +0 -1
  137. package/node_modules/@blockcast/mmt-base/dist/mmtp.js +0 -612
  138. package/node_modules/@blockcast/mmt-base/dist/mmtp.js.map +0 -1
  139. package/node_modules/@blockcast/mmt-base/dist/net-constants.d.ts +0 -18
  140. package/node_modules/@blockcast/mmt-base/dist/net-constants.d.ts.map +0 -1
  141. package/node_modules/@blockcast/mmt-base/dist/net-constants.js +0 -18
  142. package/node_modules/@blockcast/mmt-base/dist/net-constants.js.map +0 -1
  143. package/node_modules/@blockcast/mmt-base/dist/ntp-short.d.ts +0 -47
  144. package/node_modules/@blockcast/mmt-base/dist/ntp-short.d.ts.map +0 -1
  145. package/node_modules/@blockcast/mmt-base/dist/ntp-short.js +0 -54
  146. package/node_modules/@blockcast/mmt-base/dist/ntp-short.js.map +0 -1
  147. package/node_modules/@blockcast/mmt-base/dist/serial-number.d.ts +0 -28
  148. package/node_modules/@blockcast/mmt-base/dist/serial-number.d.ts.map +0 -1
  149. package/node_modules/@blockcast/mmt-base/dist/serial-number.js +0 -44
  150. package/node_modules/@blockcast/mmt-base/dist/serial-number.js.map +0 -1
  151. package/node_modules/@blockcast/mmt-base/dist/signalling.d.ts +0 -314
  152. package/node_modules/@blockcast/mmt-base/dist/signalling.d.ts.map +0 -1
  153. package/node_modules/@blockcast/mmt-base/dist/signalling.js +0 -637
  154. package/node_modules/@blockcast/mmt-base/dist/signalling.js.map +0 -1
  155. package/node_modules/@blockcast/mmt-base/package.json +0 -49
  156. package/node_modules/@blockcast/mmt-base/src/fec-block-profile.ts +0 -145
  157. package/node_modules/@blockcast/mmt-base/src/index.ts +0 -6
  158. package/node_modules/@blockcast/mmt-base/src/mmtp.ts +0 -892
  159. package/node_modules/@blockcast/mmt-base/src/net-constants.ts +0 -17
  160. package/node_modules/@blockcast/mmt-base/src/ntp-short.ts +0 -67
  161. package/node_modules/@blockcast/mmt-base/src/serial-number.ts +0 -49
  162. package/node_modules/@blockcast/mmt-base/src/signalling.ts +0 -860
  163. package/node_modules/@blockcast/mmt-fec/README.md +0 -271
  164. package/node_modules/@blockcast/mmt-fec/dist/.build-stamp +0 -0
  165. package/node_modules/@blockcast/mmt-fec/dist/block-manager.d.ts +0 -82
  166. package/node_modules/@blockcast/mmt-fec/dist/block-manager.d.ts.map +0 -1
  167. package/node_modules/@blockcast/mmt-fec/dist/block-manager.js +0 -296
  168. package/node_modules/@blockcast/mmt-fec/dist/block-manager.js.map +0 -1
  169. package/node_modules/@blockcast/mmt-fec/dist/block-processor.d.ts +0 -105
  170. package/node_modules/@blockcast/mmt-fec/dist/block-processor.d.ts.map +0 -1
  171. package/node_modules/@blockcast/mmt-fec/dist/block-processor.js +0 -222
  172. package/node_modules/@blockcast/mmt-fec/dist/block-processor.js.map +0 -1
  173. package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.d.ts +0 -46
  174. package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.d.ts.map +0 -1
  175. package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.js +0 -96
  176. package/node_modules/@blockcast/mmt-fec/dist/cmaf-recovery.js.map +0 -1
  177. package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.d.ts +0 -33
  178. package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.d.ts.map +0 -1
  179. package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.js +0 -57
  180. package/node_modules/@blockcast/mmt-fec/dist/cmaf-symbols.js.map +0 -1
  181. package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.d.ts +0 -149
  182. package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.d.ts.map +0 -1
  183. package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.js +0 -161
  184. package/node_modules/@blockcast/mmt-fec/dist/fec-block-mapper.js.map +0 -1
  185. package/node_modules/@blockcast/mmt-fec/dist/index.d.ts +0 -28
  186. package/node_modules/@blockcast/mmt-fec/dist/index.d.ts.map +0 -1
  187. package/node_modules/@blockcast/mmt-fec/dist/index.js +0 -28
  188. package/node_modules/@blockcast/mmt-fec/dist/index.js.map +0 -1
  189. package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.d.ts +0 -20
  190. package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.d.ts.map +0 -1
  191. package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.js +0 -28
  192. package/node_modules/@blockcast/mmt-fec/dist/loc-symbols.js.map +0 -1
  193. package/node_modules/@blockcast/mmt-fec/dist/oti.d.ts +0 -258
  194. package/node_modules/@blockcast/mmt-fec/dist/oti.d.ts.map +0 -1
  195. package/node_modules/@blockcast/mmt-fec/dist/oti.js +0 -382
  196. package/node_modules/@blockcast/mmt-fec/dist/oti.js.map +0 -1
  197. package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.d.ts +0 -41
  198. package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.d.ts.map +0 -1
  199. package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.js +0 -81
  200. package/node_modules/@blockcast/mmt-fec/dist/reorder-buffer.js.map +0 -1
  201. package/node_modules/@blockcast/mmt-fec/dist/repair-group.d.ts +0 -82
  202. package/node_modules/@blockcast/mmt-fec/dist/repair-group.d.ts.map +0 -1
  203. package/node_modules/@blockcast/mmt-fec/dist/repair-group.js +0 -170
  204. package/node_modules/@blockcast/mmt-fec/dist/repair-group.js.map +0 -1
  205. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/README.md +0 -181
  206. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/.build-stamp +0 -0
  207. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts +0 -57
  208. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.d.ts.map +0 -1
  209. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.js +0 -115
  210. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/dist/index.js.map +0 -1
  211. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/package.json +0 -50
  212. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-alta-parse/src/index.ts +0 -136
  213. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/README.md +0 -134
  214. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/.build-stamp +0 -0
  215. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/fec-block-profile.d.ts +0 -55
  216. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/fec-block-profile.d.ts.map +0 -1
  217. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/fec-block-profile.js +0 -132
  218. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/fec-block-profile.js.map +0 -1
  219. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.d.ts +0 -7
  220. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.d.ts.map +0 -1
  221. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.js +0 -7
  222. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/index.js.map +0 -1
  223. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts +0 -292
  224. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.d.ts.map +0 -1
  225. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.js +0 -612
  226. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/mmtp.js.map +0 -1
  227. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/net-constants.d.ts +0 -18
  228. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/net-constants.d.ts.map +0 -1
  229. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/net-constants.js +0 -18
  230. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/net-constants.js.map +0 -1
  231. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/ntp-short.d.ts +0 -47
  232. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/ntp-short.d.ts.map +0 -1
  233. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/ntp-short.js +0 -54
  234. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/ntp-short.js.map +0 -1
  235. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/serial-number.d.ts +0 -28
  236. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/serial-number.d.ts.map +0 -1
  237. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/serial-number.js +0 -44
  238. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/serial-number.js.map +0 -1
  239. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/signalling.d.ts +0 -314
  240. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/signalling.d.ts.map +0 -1
  241. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/signalling.js +0 -637
  242. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/dist/signalling.js.map +0 -1
  243. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/package.json +0 -49
  244. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/fec-block-profile.ts +0 -145
  245. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/index.ts +0 -6
  246. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/mmtp.ts +0 -892
  247. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/net-constants.ts +0 -17
  248. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/ntp-short.ts +0 -67
  249. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/serial-number.ts +0 -49
  250. package/node_modules/@blockcast/mmt-fec/node_modules/@blockcast/mmt-base/src/signalling.ts +0 -860
  251. package/node_modules/@blockcast/mmt-fec/package.json +0 -79
  252. package/node_modules/@blockcast/mmt-fec/src/block-manager.ts +0 -371
  253. package/node_modules/@blockcast/mmt-fec/src/block-processor.ts +0 -360
  254. package/node_modules/@blockcast/mmt-fec/src/cmaf-recovery.ts +0 -127
  255. package/node_modules/@blockcast/mmt-fec/src/cmaf-symbols.ts +0 -68
  256. package/node_modules/@blockcast/mmt-fec/src/fec-block-mapper.ts +0 -225
  257. package/node_modules/@blockcast/mmt-fec/src/index.ts +0 -93
  258. package/node_modules/@blockcast/mmt-fec/src/loc-symbols.ts +0 -34
  259. package/node_modules/@blockcast/mmt-fec/src/oti.ts +0 -463
  260. package/node_modules/@blockcast/mmt-fec/src/reorder-buffer.ts +0 -101
  261. package/node_modules/@blockcast/mmt-fec/src/repair-group.ts +0 -195
  262. package/node_modules/@blockcast/mmt-manifest-verify/dist/.build-stamp +0 -0
  263. package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.d.ts +0 -28
  264. package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.d.ts.map +0 -1
  265. package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.js +0 -128
  266. package/node_modules/@blockcast/mmt-manifest-verify/dist/admission.js.map +0 -1
  267. package/node_modules/@blockcast/mmt-manifest-verify/dist/index.d.ts +0 -4
  268. package/node_modules/@blockcast/mmt-manifest-verify/dist/index.d.ts.map +0 -1
  269. package/node_modules/@blockcast/mmt-manifest-verify/dist/index.js +0 -4
  270. package/node_modules/@blockcast/mmt-manifest-verify/dist/index.js.map +0 -1
  271. package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.d.ts +0 -37
  272. package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.d.ts.map +0 -1
  273. package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.js +0 -179
  274. package/node_modules/@blockcast/mmt-manifest-verify/dist/source-auth.js.map +0 -1
  275. package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.d.ts +0 -99
  276. package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.d.ts.map +0 -1
  277. package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.js +0 -492
  278. package/node_modules/@blockcast/mmt-manifest-verify/dist/verifier.js.map +0 -1
  279. package/node_modules/@blockcast/mmt-manifest-verify/package.json +0 -45
  280. package/node_modules/@blockcast/mmt-manifest-verify/src/admission.ts +0 -171
  281. package/node_modules/@blockcast/mmt-manifest-verify/src/index.ts +0 -3
  282. package/node_modules/@blockcast/mmt-manifest-verify/src/source-auth.ts +0 -230
  283. package/node_modules/@blockcast/mmt-manifest-verify/src/verifier.ts +0 -669
  284. package/node_modules/@noble/hashes/LICENSE +0 -21
  285. package/node_modules/@noble/hashes/README.md +0 -521
  286. package/node_modules/@noble/hashes/_assert.d.ts +0 -17
  287. package/node_modules/@noble/hashes/_assert.d.ts.map +0 -1
  288. package/node_modules/@noble/hashes/_assert.js +0 -18
  289. package/node_modules/@noble/hashes/_assert.js.map +0 -1
  290. package/node_modules/@noble/hashes/_blake.d.ts +0 -14
  291. package/node_modules/@noble/hashes/_blake.d.ts.map +0 -1
  292. package/node_modules/@noble/hashes/_blake.js +0 -50
  293. package/node_modules/@noble/hashes/_blake.js.map +0 -1
  294. package/node_modules/@noble/hashes/_md.d.ts +0 -51
  295. package/node_modules/@noble/hashes/_md.d.ts.map +0 -1
  296. package/node_modules/@noble/hashes/_md.js +0 -162
  297. package/node_modules/@noble/hashes/_md.js.map +0 -1
  298. package/node_modules/@noble/hashes/_u64.d.ts +0 -55
  299. package/node_modules/@noble/hashes/_u64.d.ts.map +0 -1
  300. package/node_modules/@noble/hashes/_u64.js +0 -90
  301. package/node_modules/@noble/hashes/_u64.js.map +0 -1
  302. package/node_modules/@noble/hashes/argon2.d.ts +0 -32
  303. package/node_modules/@noble/hashes/argon2.d.ts.map +0 -1
  304. package/node_modules/@noble/hashes/argon2.js +0 -401
  305. package/node_modules/@noble/hashes/argon2.js.map +0 -1
  306. package/node_modules/@noble/hashes/blake1.d.ts +0 -106
  307. package/node_modules/@noble/hashes/blake1.d.ts.map +0 -1
  308. package/node_modules/@noble/hashes/blake1.js +0 -459
  309. package/node_modules/@noble/hashes/blake1.js.map +0 -1
  310. package/node_modules/@noble/hashes/blake2.d.ts +0 -116
  311. package/node_modules/@noble/hashes/blake2.d.ts.map +0 -1
  312. package/node_modules/@noble/hashes/blake2.js +0 -420
  313. package/node_modules/@noble/hashes/blake2.js.map +0 -1
  314. package/node_modules/@noble/hashes/blake2b.d.ts +0 -11
  315. package/node_modules/@noble/hashes/blake2b.d.ts.map +0 -1
  316. package/node_modules/@noble/hashes/blake2b.js +0 -14
  317. package/node_modules/@noble/hashes/blake2b.js.map +0 -1
  318. package/node_modules/@noble/hashes/blake2s.d.ts +0 -20
  319. package/node_modules/@noble/hashes/blake2s.d.ts.map +0 -1
  320. package/node_modules/@noble/hashes/blake2s.js +0 -24
  321. package/node_modules/@noble/hashes/blake2s.js.map +0 -1
  322. package/node_modules/@noble/hashes/blake3.d.ts +0 -54
  323. package/node_modules/@noble/hashes/blake3.d.ts.map +0 -1
  324. package/node_modules/@noble/hashes/blake3.js +0 -255
  325. package/node_modules/@noble/hashes/blake3.js.map +0 -1
  326. package/node_modules/@noble/hashes/crypto.d.ts +0 -2
  327. package/node_modules/@noble/hashes/crypto.d.ts.map +0 -1
  328. package/node_modules/@noble/hashes/crypto.js +0 -5
  329. package/node_modules/@noble/hashes/crypto.js.map +0 -1
  330. package/node_modules/@noble/hashes/cryptoNode.d.ts +0 -2
  331. package/node_modules/@noble/hashes/cryptoNode.d.ts.map +0 -1
  332. package/node_modules/@noble/hashes/cryptoNode.js +0 -18
  333. package/node_modules/@noble/hashes/cryptoNode.js.map +0 -1
  334. package/node_modules/@noble/hashes/eskdf.d.ts +0 -47
  335. package/node_modules/@noble/hashes/eskdf.d.ts.map +0 -1
  336. package/node_modules/@noble/hashes/eskdf.js +0 -166
  337. package/node_modules/@noble/hashes/eskdf.js.map +0 -1
  338. package/node_modules/@noble/hashes/esm/_assert.d.ts +0 -17
  339. package/node_modules/@noble/hashes/esm/_assert.d.ts.map +0 -1
  340. package/node_modules/@noble/hashes/esm/_assert.js +0 -15
  341. package/node_modules/@noble/hashes/esm/_assert.js.map +0 -1
  342. package/node_modules/@noble/hashes/esm/_blake.d.ts +0 -14
  343. package/node_modules/@noble/hashes/esm/_blake.d.ts.map +0 -1
  344. package/node_modules/@noble/hashes/esm/_blake.js +0 -45
  345. package/node_modules/@noble/hashes/esm/_blake.js.map +0 -1
  346. package/node_modules/@noble/hashes/esm/_md.d.ts +0 -51
  347. package/node_modules/@noble/hashes/esm/_md.d.ts.map +0 -1
  348. package/node_modules/@noble/hashes/esm/_md.js +0 -155
  349. package/node_modules/@noble/hashes/esm/_md.js.map +0 -1
  350. package/node_modules/@noble/hashes/esm/_u64.d.ts +0 -55
  351. package/node_modules/@noble/hashes/esm/_u64.d.ts.map +0 -1
  352. package/node_modules/@noble/hashes/esm/_u64.js +0 -67
  353. package/node_modules/@noble/hashes/esm/_u64.js.map +0 -1
  354. package/node_modules/@noble/hashes/esm/argon2.d.ts +0 -32
  355. package/node_modules/@noble/hashes/esm/argon2.d.ts.map +0 -1
  356. package/node_modules/@noble/hashes/esm/argon2.js +0 -392
  357. package/node_modules/@noble/hashes/esm/argon2.js.map +0 -1
  358. package/node_modules/@noble/hashes/esm/blake1.d.ts +0 -106
  359. package/node_modules/@noble/hashes/esm/blake1.d.ts.map +0 -1
  360. package/node_modules/@noble/hashes/esm/blake1.js +0 -452
  361. package/node_modules/@noble/hashes/esm/blake1.js.map +0 -1
  362. package/node_modules/@noble/hashes/esm/blake2.d.ts +0 -116
  363. package/node_modules/@noble/hashes/esm/blake2.d.ts.map +0 -1
  364. package/node_modules/@noble/hashes/esm/blake2.js +0 -413
  365. package/node_modules/@noble/hashes/esm/blake2.js.map +0 -1
  366. package/node_modules/@noble/hashes/esm/blake2b.d.ts +0 -11
  367. package/node_modules/@noble/hashes/esm/blake2b.d.ts.map +0 -1
  368. package/node_modules/@noble/hashes/esm/blake2b.js +0 -11
  369. package/node_modules/@noble/hashes/esm/blake2b.js.map +0 -1
  370. package/node_modules/@noble/hashes/esm/blake2s.d.ts +0 -20
  371. package/node_modules/@noble/hashes/esm/blake2s.d.ts.map +0 -1
  372. package/node_modules/@noble/hashes/esm/blake2s.js +0 -21
  373. package/node_modules/@noble/hashes/esm/blake2s.js.map +0 -1
  374. package/node_modules/@noble/hashes/esm/blake3.d.ts +0 -54
  375. package/node_modules/@noble/hashes/esm/blake3.d.ts.map +0 -1
  376. package/node_modules/@noble/hashes/esm/blake3.js +0 -251
  377. package/node_modules/@noble/hashes/esm/blake3.js.map +0 -1
  378. package/node_modules/@noble/hashes/esm/crypto.d.ts +0 -2
  379. package/node_modules/@noble/hashes/esm/crypto.d.ts.map +0 -1
  380. package/node_modules/@noble/hashes/esm/crypto.js +0 -2
  381. package/node_modules/@noble/hashes/esm/crypto.js.map +0 -1
  382. package/node_modules/@noble/hashes/esm/cryptoNode.d.ts +0 -2
  383. package/node_modules/@noble/hashes/esm/cryptoNode.d.ts.map +0 -1
  384. package/node_modules/@noble/hashes/esm/cryptoNode.js +0 -15
  385. package/node_modules/@noble/hashes/esm/cryptoNode.js.map +0 -1
  386. package/node_modules/@noble/hashes/esm/eskdf.d.ts +0 -47
  387. package/node_modules/@noble/hashes/esm/eskdf.d.ts.map +0 -1
  388. package/node_modules/@noble/hashes/esm/eskdf.js +0 -160
  389. package/node_modules/@noble/hashes/esm/eskdf.js.map +0 -1
  390. package/node_modules/@noble/hashes/esm/hkdf.d.ts +0 -36
  391. package/node_modules/@noble/hashes/esm/hkdf.d.ts.map +0 -1
  392. package/node_modules/@noble/hashes/esm/hkdf.js +0 -82
  393. package/node_modules/@noble/hashes/esm/hkdf.js.map +0 -1
  394. package/node_modules/@noble/hashes/esm/hmac.d.ts +0 -35
  395. package/node_modules/@noble/hashes/esm/hmac.d.ts.map +0 -1
  396. package/node_modules/@noble/hashes/esm/hmac.js +0 -86
  397. package/node_modules/@noble/hashes/esm/hmac.js.map +0 -1
  398. package/node_modules/@noble/hashes/esm/index.d.ts +0 -2
  399. package/node_modules/@noble/hashes/esm/index.d.ts.map +0 -1
  400. package/node_modules/@noble/hashes/esm/index.js +0 -33
  401. package/node_modules/@noble/hashes/esm/index.js.map +0 -1
  402. package/node_modules/@noble/hashes/esm/legacy.d.ts +0 -71
  403. package/node_modules/@noble/hashes/esm/legacy.d.ts.map +0 -1
  404. package/node_modules/@noble/hashes/esm/legacy.js +0 -281
  405. package/node_modules/@noble/hashes/esm/legacy.js.map +0 -1
  406. package/node_modules/@noble/hashes/esm/package.json +0 -10
  407. package/node_modules/@noble/hashes/esm/pbkdf2.d.ts +0 -23
  408. package/node_modules/@noble/hashes/esm/pbkdf2.d.ts.map +0 -1
  409. package/node_modules/@noble/hashes/esm/pbkdf2.js +0 -97
  410. package/node_modules/@noble/hashes/esm/pbkdf2.js.map +0 -1
  411. package/node_modules/@noble/hashes/esm/ripemd160.d.ts +0 -13
  412. package/node_modules/@noble/hashes/esm/ripemd160.d.ts.map +0 -1
  413. package/node_modules/@noble/hashes/esm/ripemd160.js +0 -13
  414. package/node_modules/@noble/hashes/esm/ripemd160.js.map +0 -1
  415. package/node_modules/@noble/hashes/esm/scrypt.d.ts +0 -34
  416. package/node_modules/@noble/hashes/esm/scrypt.d.ts.map +0 -1
  417. package/node_modules/@noble/hashes/esm/scrypt.js +0 -228
  418. package/node_modules/@noble/hashes/esm/scrypt.js.map +0 -1
  419. package/node_modules/@noble/hashes/esm/sha1.d.ts +0 -11
  420. package/node_modules/@noble/hashes/esm/sha1.d.ts.map +0 -1
  421. package/node_modules/@noble/hashes/esm/sha1.js +0 -11
  422. package/node_modules/@noble/hashes/esm/sha1.js.map +0 -1
  423. package/node_modules/@noble/hashes/esm/sha2.d.ts +0 -159
  424. package/node_modules/@noble/hashes/esm/sha2.d.ts.map +0 -1
  425. package/node_modules/@noble/hashes/esm/sha2.js +0 -375
  426. package/node_modules/@noble/hashes/esm/sha2.js.map +0 -1
  427. package/node_modules/@noble/hashes/esm/sha256.d.ts +0 -20
  428. package/node_modules/@noble/hashes/esm/sha256.d.ts.map +0 -1
  429. package/node_modules/@noble/hashes/esm/sha256.js +0 -20
  430. package/node_modules/@noble/hashes/esm/sha256.js.map +0 -1
  431. package/node_modules/@noble/hashes/esm/sha3-addons.d.ts +0 -142
  432. package/node_modules/@noble/hashes/esm/sha3-addons.d.ts.map +0 -1
  433. package/node_modules/@noble/hashes/esm/sha3-addons.js +0 -393
  434. package/node_modules/@noble/hashes/esm/sha3-addons.js.map +0 -1
  435. package/node_modules/@noble/hashes/esm/sha3.d.ts +0 -53
  436. package/node_modules/@noble/hashes/esm/sha3.d.ts.map +0 -1
  437. package/node_modules/@noble/hashes/esm/sha3.js +0 -234
  438. package/node_modules/@noble/hashes/esm/sha3.js.map +0 -1
  439. package/node_modules/@noble/hashes/esm/sha512.d.ts +0 -26
  440. package/node_modules/@noble/hashes/esm/sha512.d.ts.map +0 -1
  441. package/node_modules/@noble/hashes/esm/sha512.js +0 -26
  442. package/node_modules/@noble/hashes/esm/sha512.js.map +0 -1
  443. package/node_modules/@noble/hashes/esm/utils.d.ts +0 -161
  444. package/node_modules/@noble/hashes/esm/utils.d.ts.map +0 -1
  445. package/node_modules/@noble/hashes/esm/utils.js +0 -281
  446. package/node_modules/@noble/hashes/esm/utils.js.map +0 -1
  447. package/node_modules/@noble/hashes/hkdf.d.ts +0 -36
  448. package/node_modules/@noble/hashes/hkdf.d.ts.map +0 -1
  449. package/node_modules/@noble/hashes/hkdf.js +0 -88
  450. package/node_modules/@noble/hashes/hkdf.js.map +0 -1
  451. package/node_modules/@noble/hashes/hmac.d.ts +0 -35
  452. package/node_modules/@noble/hashes/hmac.d.ts.map +0 -1
  453. package/node_modules/@noble/hashes/hmac.js +0 -91
  454. package/node_modules/@noble/hashes/hmac.js.map +0 -1
  455. package/node_modules/@noble/hashes/index.d.ts +0 -1
  456. package/node_modules/@noble/hashes/index.d.ts.map +0 -1
  457. package/node_modules/@noble/hashes/index.js +0 -33
  458. package/node_modules/@noble/hashes/index.js.map +0 -1
  459. package/node_modules/@noble/hashes/legacy.d.ts +0 -71
  460. package/node_modules/@noble/hashes/legacy.d.ts.map +0 -1
  461. package/node_modules/@noble/hashes/legacy.js +0 -287
  462. package/node_modules/@noble/hashes/legacy.js.map +0 -1
  463. package/node_modules/@noble/hashes/package.json +0 -266
  464. package/node_modules/@noble/hashes/pbkdf2.d.ts +0 -23
  465. package/node_modules/@noble/hashes/pbkdf2.d.ts.map +0 -1
  466. package/node_modules/@noble/hashes/pbkdf2.js +0 -101
  467. package/node_modules/@noble/hashes/pbkdf2.js.map +0 -1
  468. package/node_modules/@noble/hashes/ripemd160.d.ts +0 -13
  469. package/node_modules/@noble/hashes/ripemd160.d.ts.map +0 -1
  470. package/node_modules/@noble/hashes/ripemd160.js +0 -16
  471. package/node_modules/@noble/hashes/ripemd160.js.map +0 -1
  472. package/node_modules/@noble/hashes/scrypt.d.ts +0 -34
  473. package/node_modules/@noble/hashes/scrypt.d.ts.map +0 -1
  474. package/node_modules/@noble/hashes/scrypt.js +0 -232
  475. package/node_modules/@noble/hashes/scrypt.js.map +0 -1
  476. package/node_modules/@noble/hashes/sha1.d.ts +0 -11
  477. package/node_modules/@noble/hashes/sha1.d.ts.map +0 -1
  478. package/node_modules/@noble/hashes/sha1.js +0 -14
  479. package/node_modules/@noble/hashes/sha1.js.map +0 -1
  480. package/node_modules/@noble/hashes/sha2.d.ts +0 -159
  481. package/node_modules/@noble/hashes/sha2.d.ts.map +0 -1
  482. package/node_modules/@noble/hashes/sha2.js +0 -384
  483. package/node_modules/@noble/hashes/sha2.js.map +0 -1
  484. package/node_modules/@noble/hashes/sha256.d.ts +0 -20
  485. package/node_modules/@noble/hashes/sha256.d.ts.map +0 -1
  486. package/node_modules/@noble/hashes/sha256.js +0 -23
  487. package/node_modules/@noble/hashes/sha256.js.map +0 -1
  488. package/node_modules/@noble/hashes/sha3-addons.d.ts +0 -142
  489. package/node_modules/@noble/hashes/sha3-addons.d.ts.map +0 -1
  490. package/node_modules/@noble/hashes/sha3-addons.js +0 -402
  491. package/node_modules/@noble/hashes/sha3-addons.js.map +0 -1
  492. package/node_modules/@noble/hashes/sha3.d.ts +0 -53
  493. package/node_modules/@noble/hashes/sha3.d.ts.map +0 -1
  494. package/node_modules/@noble/hashes/sha3.js +0 -239
  495. package/node_modules/@noble/hashes/sha3.js.map +0 -1
  496. package/node_modules/@noble/hashes/sha512.d.ts +0 -26
  497. package/node_modules/@noble/hashes/sha512.d.ts.map +0 -1
  498. package/node_modules/@noble/hashes/sha512.js +0 -29
  499. package/node_modules/@noble/hashes/sha512.js.map +0 -1
  500. package/node_modules/@noble/hashes/src/_assert.ts +0 -22
  501. package/node_modules/@noble/hashes/src/_blake.ts +0 -50
  502. package/node_modules/@noble/hashes/src/_md.ts +0 -176
  503. package/node_modules/@noble/hashes/src/_u64.ts +0 -91
  504. package/node_modules/@noble/hashes/src/argon2.ts +0 -497
  505. package/node_modules/@noble/hashes/src/blake1.ts +0 -534
  506. package/node_modules/@noble/hashes/src/blake2.ts +0 -486
  507. package/node_modules/@noble/hashes/src/blake2b.ts +0 -10
  508. package/node_modules/@noble/hashes/src/blake2s.ts +0 -20
  509. package/node_modules/@noble/hashes/src/blake3.ts +0 -272
  510. package/node_modules/@noble/hashes/src/crypto.ts +0 -9
  511. package/node_modules/@noble/hashes/src/cryptoNode.ts +0 -15
  512. package/node_modules/@noble/hashes/src/eskdf.ts +0 -187
  513. package/node_modules/@noble/hashes/src/hkdf.ts +0 -88
  514. package/node_modules/@noble/hashes/src/hmac.ts +0 -94
  515. package/node_modules/@noble/hashes/src/index.ts +0 -31
  516. package/node_modules/@noble/hashes/src/legacy.ts +0 -293
  517. package/node_modules/@noble/hashes/src/pbkdf2.ts +0 -122
  518. package/node_modules/@noble/hashes/src/ripemd160.ts +0 -12
  519. package/node_modules/@noble/hashes/src/scrypt.ts +0 -257
  520. package/node_modules/@noble/hashes/src/sha1.ts +0 -10
  521. package/node_modules/@noble/hashes/src/sha2.ts +0 -402
  522. package/node_modules/@noble/hashes/src/sha256.ts +0 -24
  523. package/node_modules/@noble/hashes/src/sha3-addons.ts +0 -499
  524. package/node_modules/@noble/hashes/src/sha3.ts +0 -258
  525. package/node_modules/@noble/hashes/src/sha512.ts +0 -34
  526. package/node_modules/@noble/hashes/src/utils.ts +0 -395
  527. package/node_modules/@noble/hashes/utils.d.ts +0 -161
  528. package/node_modules/@noble/hashes/utils.d.ts.map +0 -1
  529. package/node_modules/@noble/hashes/utils.js +0 -313
  530. package/node_modules/@noble/hashes/utils.js.map +0 -1
@@ -87,6 +87,8 @@ var init_fec_worker_client = __esm({
87
87
  }
88
88
  /**
89
89
  * Configure the Worker with FEC parameters and WASM module.
90
+ * `interleaveMs: 0` is a valid no-span catalog value; in that mode the
91
+ * caller supplies a positive receiver-local `deliveryWindowMs`.
90
92
  * wasmModule is transferred (not neutered — WebAssembly.Module is shareable).
91
93
  * altaPublicKey is PKCS#8 SPKI DER bytes (self-describing — algorithm detected from OID).
92
94
  * Transferred (detached from sender).
@@ -6700,7 +6702,7 @@ function validateCmsfMmtpCatalog(value) {
6700
6702
  const tracks = catalog["tracks"];
6701
6703
  const trackRecords = [];
6702
6704
  const positiveInteger2 = (input) => Number.isSafeInteger(input) && input > 0;
6703
- const positiveNumber = (input) => typeof input === "number" && Number.isFinite(input) && input > 0;
6705
+ const positiveNumber2 = (input) => typeof input === "number" && Number.isFinite(input) && input > 0;
6704
6706
  for (let index = 0; index < tracks.length; index++) {
6705
6707
  const raw = tracks[index];
6706
6708
  const path = `$.tracks[${index}]`;
@@ -6745,7 +6747,7 @@ function validateCmsfMmtpCatalog(value) {
6745
6747
  if (groupDurationTicks !== void 0 && !positiveInteger2(groupDurationTicks)) {
6746
6748
  catalogError("track_group_duration_ticks", `${path}.groupDurationTicks`, "must be a positive integer");
6747
6749
  }
6748
- if (keyframeIntervalMs !== void 0 && !positiveNumber(keyframeIntervalMs) || keyframeIntervalTicks !== void 0 && !positiveInteger2(keyframeIntervalTicks)) {
6750
+ if (keyframeIntervalMs !== void 0 && !positiveNumber2(keyframeIntervalMs) || keyframeIntervalTicks !== void 0 && !positiveInteger2(keyframeIntervalTicks)) {
6749
6751
  catalogError("track_keyframe_interval", path, "keyframe interval fields must be positive numbers");
6750
6752
  }
6751
6753
  if (packaging === "fec-repair") {
@@ -6793,8 +6795,8 @@ function validateCmsfMmtpCatalog(value) {
6793
6795
  "repair layers are self-describing fec-repair tracks (depends, repairLayer); fec.enhancementRepair is not supported"
6794
6796
  );
6795
6797
  }
6796
- if (config["interleaveDepthMs"] !== void 0 && !positiveInteger2(config["interleaveDepthMs"])) {
6797
- catalogError("track_fec", `${path}.fec.interleaveDepthMs`, "must be a positive integer");
6798
+ if (config["interleaveDepthMs"] !== void 0 && (!Number.isSafeInteger(config["interleaveDepthMs"]) || config["interleaveDepthMs"] < 0)) {
6799
+ catalogError("track_fec", `${path}.fec.interleaveDepthMs`, "must be a non-negative safe integer");
6798
6800
  }
6799
6801
  if (algorithm !== "none") {
6800
6802
  for (const field of ["sourceSymbols", "repairSymbols", "symbolSize"]) {
@@ -9651,7 +9653,7 @@ function processFecBlock(blockData, options) {
9651
9653
  // ../fec/dist/oti.js
9652
9654
  function catalogFecInterleaveMs(fec) {
9653
9655
  const ms = fec?.interleaveDepthMs;
9654
- return typeof ms === "number" && ms > 0 && Number.isFinite(ms) ? ms : void 0;
9656
+ return typeof ms === "number" && Number.isSafeInteger(ms) && ms >= 0 ? ms : void 0;
9655
9657
  }
9656
9658
  function deriveFecInterleaveDepth(interleaveDepthMs, mediaUnitDurationMs) {
9657
9659
  if (!Number.isFinite(interleaveDepthMs) || interleaveDepthMs <= 0) {
@@ -9684,6 +9686,8 @@ function deriveFecRetentionBlocks(deliveryWindowMs, interleaveDepthMs) {
9684
9686
  throw new Error(`[FEC] retention of ${Math.ceil(deliveryWindowMs / interleaveDepthMs) + 1} blocks exceeds the 255 the decoder and the ISO/IEC 23008-1 AL-FEC signaling byte accept (deliveryWindowMs=${deliveryWindowMs}ms over interleaveDepthMs=${interleaveDepthMs}ms). Fix the catalog geometry: a span this short cannot carry a window this wide.`);
9685
9687
  }
9686
9688
  var MAX_FEC_RETENTION_BLOCKS = 255;
9689
+ var LOCAL_FEC_RETENTION_BLOCKS = 2;
9690
+ var LOCAL_FEC_TIMEOUT_MS = 500;
9687
9691
  function tryDeriveFecRetentionBlocks(deliveryWindowMs, interleaveDepthMs) {
9688
9692
  if (!Number.isFinite(interleaveDepthMs) || !(interleaveDepthMs > 0))
9689
9693
  return void 0;
@@ -9996,6 +10000,10 @@ var TrackSession = class {
9996
10000
  /** multicast/amt → failing: loss detected, start hysteresis timer (Claim 9f). */
9997
10001
  lossDetected() {
9998
10002
  if (this.#state !== "multicast" && this.#state !== "amt") return;
10003
+ if (this.config.fecInterleaveMs === 0 || this.config.fecInterleaveMs === void 0) {
10004
+ this.transportFailed();
10005
+ return;
10006
+ }
9999
10007
  this.#previousPrimary = this.#state;
10000
10008
  this.#transition("failing");
10001
10009
  const hysteresisMs = computeFecLossWindowMs(
@@ -10802,7 +10810,7 @@ var IsoBlockLocator = class _IsoBlockLocator {
10802
10810
  };
10803
10811
 
10804
10812
  // src/fec-state.ts
10805
- var MIN_INTERLEAVE_DEPTH_MS = 33;
10813
+ var MIN_INTERLEAVE_DEPTH_MS = 1;
10806
10814
  var FEC_INACTIVE_REASONS = Object.freeze([
10807
10815
  "no-catalog-fec",
10808
10816
  "reliable-moq",
@@ -10829,7 +10837,7 @@ function isoBlockSpanUsable(fec) {
10829
10837
  const block = recordOf(fec);
10830
10838
  if (block === void 0 || block["blockProfile"] !== "iso-ssbg1-v1") return true;
10831
10839
  const ms = block["interleaveDepthMs"];
10832
- return typeof ms === "number" && Number.isFinite(ms) && ms >= MIN_INTERLEAVE_DEPTH_MS;
10840
+ return ms === void 0 || typeof ms === "number" && Number.isSafeInteger(ms) && ms >= 0;
10833
10841
  }
10834
10842
  function requireBoolean(value, field) {
10835
10843
  if (typeof value !== "boolean") {
@@ -11380,8 +11388,8 @@ var FECManager = class _FECManager {
11380
11388
  this.#decoderBlockOwners = /* @__PURE__ */ new WeakMap();
11381
11389
  this.#fecK = 4;
11382
11390
  this.#fecSymbolSize = 0;
11383
- this.#fecTimeoutMs = 500;
11384
- // default 500ms; refined by setFramerate() when fps known
11391
+ this.#fecTimeoutMs = LOCAL_FEC_TIMEOUT_MS;
11392
+ // local default; refined by setFramerate() when fps known
11385
11393
  this.#trackConfigs = /* @__PURE__ */ new Map();
11386
11394
  this.#fecStats = newFecCounters();
11387
11395
  this.#fecTrackStats = /* @__PURE__ */ new Map();
@@ -11857,6 +11865,14 @@ var FECManager = class _FECManager {
11857
11865
  * derivation; do not re-derive a horizon at either call site.
11858
11866
  */
11859
11867
  #orderedHorizonBlocksFor(packetId, config) {
11868
+ if (config.interleaveDepthMs === 0) {
11869
+ if (Number.isFinite(config.timeoutMs) && config.timeoutMs > 0) {
11870
+ return LOCAL_FEC_RETENTION_BLOCKS;
11871
+ }
11872
+ throw new Error(
11873
+ `[FECManager] packetId=${packetId}: local FEC cleanup requires a positive timeout (got ${config.timeoutMs})`
11874
+ );
11875
+ }
11860
11876
  if (!_FECManager.#hasOrderedGeometry(config)) {
11861
11877
  throw new Error(
11862
11878
  `[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}.`
@@ -11870,7 +11886,7 @@ var FECManager = class _FECManager {
11870
11886
  * two can never disagree about which streams settle by stream order.
11871
11887
  */
11872
11888
  static #hasOrderedGeometry(config) {
11873
- return config.interleaveDepthMs >= MIN_INTERLEAVE_DEPTH_MS && // `fps` is no longer an input to the horizon, but it still gates WHICH
11889
+ return _FECManager.#hasCatalogTiming(config) && // `fps` is no longer an input to the horizon, but it still gates WHICH
11874
11890
  // streams settle by stream order at all: a track with no usable
11875
11891
  // media-unit rate fell back to datagram semantics before this and must
11876
11892
  // keep doing so. Removing this widens ordered-relay settlement to streams
@@ -11910,6 +11926,9 @@ var FECManager = class _FECManager {
11910
11926
  * argument: narrower IS the failing direction.
11911
11927
  */
11912
11928
  #derivableOrderedHorizon(config, packetId) {
11929
+ if (config.interleaveDepthMs === 0) {
11930
+ return Number.isFinite(config.timeoutMs) && config.timeoutMs > 0 ? LOCAL_FEC_RETENTION_BLOCKS : void 0;
11931
+ }
11913
11932
  if (!_FECManager.#hasOrderedGeometry(config)) return void 0;
11914
11933
  try {
11915
11934
  const blocks = tryDeriveFecRetentionBlocks(config.timeoutMs, config.interleaveDepthMs);
@@ -12023,7 +12042,7 @@ var FECManager = class _FECManager {
12023
12042
  if (this.#completedBlocks.has(key) || this.#pendingWorkerCleanups.has(key) || this.#repairRequestedBlocks.has(key)) return;
12024
12043
  const authoredLength = this.#blockAuthoredLengths.get(key);
12025
12044
  const received = (this.#blockSourceCounts.get(key) ?? 0) + (this.#blockRepairRsIds.get(key)?.size ?? 0);
12026
- if (this.onRepairNeeded && (authoredLength === void 0 || received < authoredLength)) {
12045
+ if (this.#hasCatalogTimingForPacket(packetId) && this.onRepairNeeded && (authoredLength === void 0 || received < authoredLength)) {
12027
12046
  this.#requestRepair(sbn, packetId, catalogTrackName, true);
12028
12047
  return;
12029
12048
  }
@@ -12179,7 +12198,7 @@ var FECManager = class _FECManager {
12179
12198
  }
12180
12199
  #requestRepair(sbn, packetId, catalogTrackName, settledByOrder = false) {
12181
12200
  const key = this.#blockKey(sbn, packetId, catalogTrackName);
12182
- if (this.#completedBlocks.has(key) || !this.onRepairNeeded || this.#repairRequestedBlocks.has(key)) return;
12201
+ if (this.#completedBlocks.has(key) || !this.#hasCatalogTimingForPacket(packetId) || !this.onRepairNeeded || this.#repairRequestedBlocks.has(key)) return;
12183
12202
  const deadline = this.#repairDeadlines.get(key);
12184
12203
  if (deadline?.handle != null) clearTimeout(deadline.handle);
12185
12204
  this.#repairDeadlines.set(key, null);
@@ -12259,6 +12278,7 @@ var FECManager = class _FECManager {
12259
12278
  }
12260
12279
  /** A block's live class without creating classifier state for the stream. */
12261
12280
  #peekClass(sbn, packetId, catalogTrackName) {
12281
+ if (!this.#hasCatalogTimingForPacket(packetId)) return "unknown";
12262
12282
  const classifier = this.#classifiers.get(this.#streamKey(packetId, catalogTrackName));
12263
12283
  if (classifier) return classifier.classOf(sbn);
12264
12284
  return this.#geometryFor(packetId, catalogTrackName).trackKind === "audio" ? "audio" : "unknown";
@@ -12385,7 +12405,9 @@ var FECManager = class _FECManager {
12385
12405
  const key = this.#blockKey(sbn, packetId, catalogTrackName);
12386
12406
  if (this.#blockResolutionFor(key) !== "untracked") return;
12387
12407
  this.#materializedBlocks.add(key);
12388
- this.#classifierFor(packetId, catalogTrackName).touch(sbn);
12408
+ if (this.#hasCatalogTimingForPacket(packetId)) {
12409
+ this.#classifierFor(packetId, catalogTrackName).touch(sbn);
12410
+ }
12389
12411
  this.onBlockVanished?.(sbn, packetId, catalogTrackName);
12390
12412
  if (repairable) {
12391
12413
  this.noteBlockActivity(sbn, packetId, catalogTrackName, true);
@@ -12436,9 +12458,23 @@ var FECManager = class _FECManager {
12436
12458
  #resolveTrackConfig(packetId) {
12437
12459
  return this.#trackConfigs.get(packetId) ?? this.#defaultTrackConfig();
12438
12460
  }
12461
+ /**
12462
+ * Whether this track has the catalog's elapsed-time FEC policy. A zero span
12463
+ * is a deliberate no-deadline signal; it still leaves the wire geometry
12464
+ * usable for in-band decode, but it cannot drive classification, repair
12465
+ * fetches or layer adaptation.
12466
+ */
12467
+ static #hasCatalogTiming(config) {
12468
+ return Number.isSafeInteger(config.interleaveDepthMs) && config.interleaveDepthMs >= MIN_INTERLEAVE_DEPTH_MS;
12469
+ }
12470
+ #hasCatalogTimingForPacket(packetId) {
12471
+ return _FECManager.#hasCatalogTiming(this.#resolveTrackConfig(packetId));
12472
+ }
12439
12473
  #computeTimeout(config) {
12440
- if (config.timeoutMs && config.timeoutMs > 0) return config.timeoutMs;
12441
- if (config.interleaveDepthMs >= MIN_INTERLEAVE_DEPTH_MS) {
12474
+ if (typeof config.timeoutMs === "number" && Number.isFinite(config.timeoutMs) && config.timeoutMs > 0) {
12475
+ return config.timeoutMs;
12476
+ }
12477
+ if (Number.isSafeInteger(config.interleaveDepthMs) && config.interleaveDepthMs >= MIN_INTERLEAVE_DEPTH_MS) {
12442
12478
  return Math.max(
12443
12479
  this.#fecTimeoutMs,
12444
12480
  computeFecDeliveryWindowMs({
@@ -12463,14 +12499,17 @@ var FECManager = class _FECManager {
12463
12499
  */
12464
12500
  #refreshDeliveryGapWindow() {
12465
12501
  let windowMs;
12466
- const consider = (geometry) => {
12502
+ const consider = (geometry, packetId) => {
12503
+ if (!this.#hasCatalogTimingForPacket(packetId)) return;
12467
12504
  if (geometry?.trackKind !== "video" || geometry.mode !== "classifying") return;
12468
12505
  const { ticks, timescale } = geometry.keyframeInterval;
12469
12506
  const ms = ticks / timescale * 1e3;
12470
12507
  if (Number.isFinite(ms) && ms > 0 && (windowMs === void 0 || ms > windowMs)) windowMs = ms;
12471
12508
  };
12472
- for (const geometry of this.#streamGeometries.values()) consider(geometry);
12473
- for (const config of this.#trackConfigs.values()) consider(config.geometry);
12509
+ for (const [streamKey, geometry] of this.#streamGeometries) {
12510
+ consider(geometry, this.#parseStreamKey(streamKey).packetId);
12511
+ }
12512
+ for (const [packetId, config] of this.#trackConfigs) consider(config.geometry, packetId);
12474
12513
  this.#deliveryGaps.setWindowMs(windowMs);
12475
12514
  }
12476
12515
  /**
@@ -12498,6 +12537,7 @@ var FECManager = class _FECManager {
12498
12537
  return Math.max(config.timeoutMs, Math.ceil(config.interleaveDepthMs + gapMs));
12499
12538
  }
12500
12539
  #repairDeadlineMs(config, waitMs = this.#multicastWaitMs(config)) {
12540
+ if (!_FECManager.#hasCatalogTiming(config)) return waitMs;
12501
12541
  const halfFailBoundMs = Math.ceil(waitMs / 2);
12502
12542
  if (config.k > 0 && config.interleaveDepthMs >= MIN_INTERLEAVE_DEPTH_MS && config.fps !== void 0 && Number.isFinite(config.fps) && config.fps > 0) {
12503
12543
  const mediaUnitMs = 1e3 / config.fps;
@@ -12512,10 +12552,12 @@ var FECManager = class _FECManager {
12512
12552
  }
12513
12553
  /**
12514
12554
  * One block lifetime: the inactivity fail bound plus the D-28 repair grace,
12515
- * at the widest wait the catalog allows (#maxMulticastWaitMs). Everything
12516
- * derived from it (terminal retention, the release gate's hold ceiling, the
12517
- * duplicate ledgers, the owed-cleanup bound) is compared across time, so it
12518
- * must not follow the live measurement.
12555
+ * at the widest wait the catalog allows (#maxMulticastWaitMs). For a track
12556
+ * without a catalog span this is receiver-local cleanup time only; no repair
12557
+ * grace is added. Everything derived from it (terminal retention, the
12558
+ * release gate's hold ceiling, the duplicate ledgers, the owed-cleanup
12559
+ * bound) is compared across time, so it must not follow the live
12560
+ * measurement.
12519
12561
  */
12520
12562
  #blockLifetimeMs(config) {
12521
12563
  const waitMs = this.#maxMulticastWaitMs(config);
@@ -12531,6 +12573,7 @@ var FECManager = class _FECManager {
12531
12573
  return Math.min(waitMs + this.#repairGraceMs(config, waitMs), this.#blockLifetimeMs(config));
12532
12574
  }
12533
12575
  #repairGraceMs(config, waitMs) {
12576
+ if (!_FECManager.#hasCatalogTiming(config)) return 0;
12534
12577
  return Math.max(1, waitMs - this.#repairDeadlineMs(config, waitMs));
12535
12578
  }
12536
12579
  #armBlockTimeout(sbn, packetId, catalogTrackName, delayMs) {
@@ -12617,13 +12660,19 @@ var FECManager = class _FECManager {
12617
12660
  * stream; every other field stays per packetId.
12618
12661
  */
12619
12662
  #upsertTrackConfig(packetId, config, catalogTrackName) {
12620
- const previous = this.#trackConfigs.get(packetId) ?? this.#defaultTrackConfig();
12663
+ const previousTrack = this.#trackConfigs.get(packetId);
12664
+ const previous = previousTrack ?? this.#defaultTrackConfig();
12621
12665
  const streamScopedGeometry = catalogTrackName !== void 0 && config.geometry !== void 0 ? config.geometry : void 0;
12622
12666
  if (streamScopedGeometry !== void 0) {
12623
12667
  const { geometry: _streamGeometry, ...packetLevel } = config;
12624
12668
  config = packetLevel;
12625
12669
  }
12626
12670
  const timingChanged = config.k !== void 0 || config.interleaveDepthMs !== void 0 || config.fps !== void 0;
12671
+ if (config.timeoutMs !== void 0 && (!Number.isFinite(config.timeoutMs) || config.timeoutMs < 0)) {
12672
+ throw new Error(
12673
+ `[FECManager] packetId=${packetId}: timeoutMs=${config.timeoutMs} must be a finite non-negative cleanup budget`
12674
+ );
12675
+ }
12627
12676
  if (config.blockProfile !== void 0) {
12628
12677
  parseFecBlockProfile(config.blockProfile, `packetId=${packetId} fec.blockProfile`);
12629
12678
  }
@@ -12633,33 +12682,44 @@ var FECManager = class _FECManager {
12633
12682
  `[FECManager] packetId=${packetId}: fec.blockProfile is required ("iso-ssbg1-v1"); configure the track from its catalog`
12634
12683
  );
12635
12684
  }
12636
- const ownInterleaveDepthMs = config.interleaveDepthMs ?? this.#trackConfigs.get(packetId)?.interleaveDepthMs;
12637
- if (ownInterleaveDepthMs === void 0 || !Number.isFinite(ownInterleaveDepthMs) || ownInterleaveDepthMs < MIN_INTERLEAVE_DEPTH_MS) {
12685
+ const ownInterleaveDepthMs = config.interleaveDepthMs ?? previousTrack?.interleaveDepthMs ?? 0;
12686
+ if (!Number.isSafeInteger(ownInterleaveDepthMs) || ownInterleaveDepthMs !== 0 && ownInterleaveDepthMs < MIN_INTERLEAVE_DEPTH_MS) {
12638
12687
  throw new Error(
12639
- `[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`
12688
+ `[FECManager] packetId=${packetId}: fec.interleaveDepthMs must be absent, 0, or a finite value >= ${MIN_INTERLEAVE_DEPTH_MS} ms (got ${String(ownInterleaveDepthMs)})`
12640
12689
  );
12641
12690
  }
12691
+ const hasCatalogTiming = _FECManager.#hasCatalogTiming({ interleaveDepthMs: ownInterleaveDepthMs });
12642
12692
  const next = {
12643
12693
  blockProfile,
12644
12694
  k: config.k ?? previous.k,
12645
12695
  symbolSize: config.symbolSize != null && config.symbolSize > 0 ? config.symbolSize : previous.symbolSize,
12646
- interleaveDepthMs: config.interleaveDepthMs ?? previous.interleaveDepthMs,
12696
+ interleaveDepthMs: ownInterleaveDepthMs,
12647
12697
  fps: config.fps ?? previous.fps,
12648
12698
  timeoutMs: config.timeoutMs ?? (timingChanged ? 0 : previous.timeoutMs),
12649
12699
  ...(config.trackKind ?? previous.trackKind) === void 0 ? {} : { trackKind: config.trackKind ?? previous.trackKind },
12650
12700
  ...(config.codec ?? previous.codec) === void 0 ? {} : { codec: config.codec ?? previous.codec },
12651
12701
  ...(config.geometry ?? previous.geometry) === void 0 ? {} : { geometry: config.geometry ?? previous.geometry }
12652
12702
  };
12653
- next.timeoutMs = this.#computeTimeout(next);
12703
+ if (!hasCatalogTiming) {
12704
+ next.timeoutMs = config.timeoutMs !== void 0 && config.timeoutMs > 0 ? config.timeoutMs : previousTrack !== void 0 && previousTrack.interleaveDepthMs === 0 ? previousTrack.timeoutMs : LOCAL_FEC_TIMEOUT_MS;
12705
+ } else {
12706
+ next.timeoutMs = this.#computeTimeout(next);
12707
+ }
12654
12708
  if (this.#multicastSymbolDelivery === "ordered-relay") {
12655
12709
  this.#orderedHorizonBlocksFor(packetId, next);
12656
12710
  }
12711
+ const timingPolicyChanged = _FECManager.#hasCatalogTiming(previous) !== hasCatalogTiming;
12712
+ if (timingPolicyChanged && !hasCatalogTiming) {
12713
+ for (const key of [...this.#repairDeadlines.keys()]) {
12714
+ if (this.#belongsToPacket(key, packetId)) this.#clearRepairDeadline(key);
12715
+ }
12716
+ }
12657
12717
  if (previous.blockProfile !== void 0 && previous.k !== next.k) {
12658
12718
  this.#dropIsoLocators(packetId);
12659
12719
  }
12660
12720
  this.#trackConfigs.set(packetId, next);
12661
12721
  this.#refreshDeliveryGapWindow();
12662
- let policyChanged = config.geometry !== void 0 && JSON.stringify(config.geometry) !== JSON.stringify(previous.geometry) || config.trackKind !== void 0 && config.trackKind !== previous.trackKind;
12722
+ let policyChanged = timingPolicyChanged || config.geometry !== void 0 && JSON.stringify(config.geometry) !== JSON.stringify(previous.geometry) || config.trackKind !== void 0 && config.trackKind !== previous.trackKind;
12663
12723
  if (streamScopedGeometry !== void 0) {
12664
12724
  const streamKey = this.#streamKey(packetId, catalogTrackName);
12665
12725
  if (JSON.stringify(streamScopedGeometry) !== JSON.stringify(this.#streamGeometries.get(streamKey))) {
@@ -12674,8 +12734,9 @@ var FECManager = class _FECManager {
12674
12734
  if (!this.#belongsToPacket(key, packetId)) continue;
12675
12735
  const stream = this.#parseStreamKey(key);
12676
12736
  const geometry = this.#geometryFor(stream.packetId, stream.catalogTrackName);
12677
- if (JSON.stringify(geometry) === JSON.stringify(classifier.geometry)) continue;
12737
+ if (hasCatalogTiming && JSON.stringify(geometry) === JSON.stringify(classifier.geometry)) continue;
12678
12738
  this.#classifiers.delete(key);
12739
+ if (!hasCatalogTiming) continue;
12679
12740
  this.#applyClassifierChanges(stream.packetId, stream.catalogTrackName, classifier.retire());
12680
12741
  }
12681
12742
  }
@@ -13303,10 +13364,11 @@ var FECManager = class _FECManager {
13303
13364
  * for late symbols and for the in-order release gate. It is also the gate's
13304
13365
  * hold ceiling (MmtpRouter's holdLimitMs): a retired block reads back as
13305
13366
  * untracked, which the gate counts as lost, so no frame may still be waiting
13306
- * on a block that can retire. The window is one interleave depth for a gap's
13307
- * last block to finish arriving, one block lifetime to fail it, and one more
13308
- * for an owed Worker cleanup that can keep a failing block pending. Every
13309
- * term comes from the track's catalog geometry; there is no separate cap.
13367
+ * on a block that can retire. With a positive catalog span the window is one
13368
+ * interleave depth for a gap's last block to finish arriving, one block
13369
+ * lifetime to fail it, and one more for an owed Worker cleanup. With an
13370
+ * absent/zero span it is a receiver-local cleanup bound only; it creates no
13371
+ * catalog FEC deadline.
13310
13372
  */
13311
13373
  terminalRetentionMsForPacket(packetId) {
13312
13374
  const config = this.#resolveTrackConfig(packetId);
@@ -13374,11 +13436,12 @@ var FECManager = class _FECManager {
13374
13436
  */
13375
13437
  #isoRetentionBlocks(packetId) {
13376
13438
  const config = this.#trackConfigs.get(packetId);
13377
- if (config?.blockProfile === void 0 || !(config.interleaveDepthMs >= MIN_INTERLEAVE_DEPTH_MS)) {
13439
+ if (config?.blockProfile === void 0) {
13378
13440
  throw new Error(
13379
- `[FECManager] packetId=${packetId} has no iso-ssbg1-v1 block span to derive block-location retention from`
13441
+ `[FECManager] packetId=${packetId} has no configured iso-ssbg1-v1 block profile`
13380
13442
  );
13381
13443
  }
13444
+ if (!_FECManager.#hasCatalogTiming(config)) return LOCAL_FEC_RETENTION_BLOCKS;
13382
13445
  const blocks = Math.ceil(this.terminalRetentionMsForPacket(packetId) / config.interleaveDepthMs) + 1;
13383
13446
  if (!Number.isSafeInteger(blocks) || blocks <= 0) {
13384
13447
  throw new Error(`[FECManager] packetId=${packetId} iso-ssbg1-v1 retention of ${blocks} blocks is not derivable`);
@@ -13520,6 +13583,7 @@ var FECManager = class _FECManager {
13520
13583
  }
13521
13584
  /** Current classifier mode of a stream. */
13522
13585
  classifierModeFor(packetId, catalogTrackName) {
13586
+ if (!this.#hasCatalogTimingForPacket(packetId)) return { mode: "all-protected", reason: null };
13523
13587
  const classifier = this.#classifierFor(packetId, catalogTrackName);
13524
13588
  return { mode: classifier.mode, reason: classifier.reason };
13525
13589
  }
@@ -13529,10 +13593,12 @@ var FECManager = class _FECManager {
13529
13593
  * it does not. A stream with no classifier yet has shown nothing against it.
13530
13594
  */
13531
13595
  mpuBoundsRapsFor(packetId, catalogTrackName) {
13596
+ if (!this.#hasCatalogTimingForPacket(packetId)) return false;
13532
13597
  return this.#classifiers.get(this.#streamKey(packetId, catalogTrackName))?.mpuBoundsRaps ?? true;
13533
13598
  }
13534
13599
  /** A block's class now, or frozen at its resolution. */
13535
13600
  blockClassFor(sbn, packetId, catalogTrackName) {
13601
+ if (!this.#hasCatalogTimingForPacket(packetId)) return "unknown";
13536
13602
  const frozen = this.#resolvedBlockClasses.get(this.#blockKey(sbn, packetId, catalogTrackName));
13537
13603
  if (frozen !== void 0) return frozen;
13538
13604
  return this.#peekClass(sbn, packetId, catalogTrackName);
@@ -13554,7 +13620,7 @@ var FECManager = class _FECManager {
13554
13620
  * invariant (consecutive MPUs exactly one keyframe interval apart).
13555
13621
  */
13556
13622
  noteReleasedRap(packetId, catalogTrackName, mpu, presentationTime, mediaTimescale) {
13557
- if (!this.#trackConfigs.has(packetId)) return;
13623
+ if (!this.#trackConfigs.has(packetId) || !this.#hasCatalogTimingForPacket(packetId)) return;
13558
13624
  this.#applyClassifierChanges(
13559
13625
  packetId,
13560
13626
  catalogTrackName,
@@ -13570,18 +13636,27 @@ var FECManager = class _FECManager {
13570
13636
  // -----------------------------------------------------------------------
13571
13637
  /** Configure FEC parameters. */
13572
13638
  configure(config) {
13639
+ if (config.interleaveDepthMs != null && (!Number.isSafeInteger(config.interleaveDepthMs) || config.interleaveDepthMs < 0)) {
13640
+ throw new Error(
13641
+ `[FECManager] interleaveDepthMs=${config.interleaveDepthMs} must be a non-negative safe integer in milliseconds`
13642
+ );
13643
+ }
13644
+ if (config.timeoutMs != null && (!Number.isFinite(config.timeoutMs) || config.timeoutMs < 0)) {
13645
+ throw new Error(
13646
+ `[FECManager] timeoutMs=${config.timeoutMs} must be a finite non-negative cleanup budget`
13647
+ );
13648
+ }
13573
13649
  if (config.k != null) this.#fecK = config.k;
13574
13650
  if (config.symbolSize != null && config.symbolSize > 0) this.#fecSymbolSize = config.symbolSize;
13575
13651
  if (config.interleaveDepthMs != null) this.#fecInterleaveDepthMs = config.interleaveDepthMs;
13576
13652
  if (config.fps != null && Number.isFinite(config.fps) && config.fps > 0) {
13577
13653
  this.#fecFps = config.fps;
13578
13654
  }
13579
- if (config.interleaveDepthMs != null && config.interleaveDepthMs > 0 && config.interleaveDepthMs < MIN_INTERLEAVE_DEPTH_MS) {
13580
- console.warn(`[FECManager] interleaveDepthMs=${config.interleaveDepthMs} looks like frame count, not milliseconds (\xA75.1 requires ms). Expected range: ${MIN_INTERLEAVE_DEPTH_MS}-10000ms.`);
13581
- }
13582
13655
  if (config.timeoutMs != null && config.timeoutMs > 0) {
13583
13656
  this.#fecTimeoutMs = config.timeoutMs;
13584
- } else if (config.interleaveDepthMs != null && config.interleaveDepthMs >= MIN_INTERLEAVE_DEPTH_MS) {
13657
+ } else if (config.interleaveDepthMs === 0) {
13658
+ this.#fecTimeoutMs = LOCAL_FEC_TIMEOUT_MS;
13659
+ } else if (config.interleaveDepthMs != null && Number.isSafeInteger(config.interleaveDepthMs) && config.interleaveDepthMs >= MIN_INTERLEAVE_DEPTH_MS) {
13585
13660
  this.#fecTimeoutMs = computeFecDeliveryWindowMs({
13586
13661
  interleaveDepthMs: config.interleaveDepthMs,
13587
13662
  sourceSymbols: this.#fecK,
@@ -13590,7 +13665,7 @@ var FECManager = class _FECManager {
13590
13665
  });
13591
13666
  }
13592
13667
  for (const [packetId, track] of this.#trackConfigs) {
13593
- if (track.timeoutMs < this.#fecTimeoutMs) {
13668
+ if (_FECManager.#hasCatalogTiming(track) && track.timeoutMs < this.#fecTimeoutMs) {
13594
13669
  this.#trackConfigs.set(packetId, { ...track, timeoutMs: this.#fecTimeoutMs });
13595
13670
  }
13596
13671
  }
@@ -13870,7 +13945,7 @@ var FECManager = class _FECManager {
13870
13945
  if (this.#fpsDetected || fps <= 0) return;
13871
13946
  this.#fpsDetected = true;
13872
13947
  this.#fecFps = fps;
13873
- if (this.#fecInterleaveDepthMs >= MIN_INTERLEAVE_DEPTH_MS) {
13948
+ if (Number.isSafeInteger(this.#fecInterleaveDepthMs) && this.#fecInterleaveDepthMs >= MIN_INTERLEAVE_DEPTH_MS) {
13874
13949
  this.#fecTimeoutMs = computeFecDeliveryWindowMs({
13875
13950
  interleaveDepthMs: this.#fecInterleaveDepthMs,
13876
13951
  sourceSymbols: this.#fecK,
@@ -13879,7 +13954,7 @@ var FECManager = class _FECManager {
13879
13954
  });
13880
13955
  }
13881
13956
  for (const [packetId, config] of this.#trackConfigs) {
13882
- if (config.fps !== void 0 || config.interleaveDepthMs < MIN_INTERLEAVE_DEPTH_MS) continue;
13957
+ if (config.fps !== void 0 || !Number.isSafeInteger(config.interleaveDepthMs) || config.interleaveDepthMs < MIN_INTERLEAVE_DEPTH_MS) continue;
13883
13958
  this.#trackConfigs.set(packetId, {
13884
13959
  ...config,
13885
13960
  fps,
@@ -14143,11 +14218,13 @@ var FECManager = class _FECManager {
14143
14218
  this.#failBlock(sbn, packetId, catalogTrackName);
14144
14219
  return;
14145
14220
  }
14146
- this.#applyClassifierChanges(
14147
- packetId,
14148
- catalogTrackName,
14149
- this.#classifierFor(packetId, catalogTrackName).observe(sbn, evidence)
14150
- );
14221
+ if (_FECManager.#hasCatalogTiming(trackConfig)) {
14222
+ this.#applyClassifierChanges(
14223
+ packetId,
14224
+ catalogTrackName,
14225
+ this.#classifierFor(packetId, catalogTrackName).observe(sbn, evidence)
14226
+ );
14227
+ }
14151
14228
  const count = (this.#blockSourceCounts.get(key) ?? 0) + 1;
14152
14229
  this.#blockSourceCounts.set(key, count);
14153
14230
  if (count === 1) this.#indexBlockKey(key, sbn, packetId);
@@ -14206,7 +14283,7 @@ var FECManager = class _FECManager {
14206
14283
  throw new Error(`[FECManager] packetId=${packetId} has no positive fail bound (timeoutMs=${timeoutMs})`);
14207
14284
  }
14208
14285
  const repairDeadline = this.#repairDeadlines.get(key);
14209
- if (this.onRepairNeeded && !repairRequested && (repairDeadline === void 0 || sourceProgress)) {
14286
+ if (this.#hasCatalogTimingForPacket(packetId) && this.onRepairNeeded && !repairRequested && (repairDeadline === void 0 || sourceProgress)) {
14210
14287
  this.#armRepairDeadline(
14211
14288
  key,
14212
14289
  sbn,
@@ -17353,7 +17430,7 @@ var MmtpRouter = class {
17353
17430
  /** Update MFU reassembly timeout. Source and FEC-recovery paths share the
17354
17431
  * parser's single reassembler (BLO-8151), so one update covers both. */
17355
17432
  setMfuTimeoutMs(ms) {
17356
- if (ms <= 0) throw new Error("[MmtpRouter] mfuTimeoutMs must be > 0");
17433
+ if (ms !== null && ms <= 0) throw new Error("[MmtpRouter] mfuTimeoutMs must be > 0");
17357
17434
  this.#parser.setMfuTimeoutMs(ms);
17358
17435
  }
17359
17436
  /** Update parser frame reordering for unordered multicast delivery.
@@ -20031,22 +20108,22 @@ var MoqFecAlgorithm;
20031
20108
  MoqFecAlgorithm2[MoqFecAlgorithm2["RaptorQ"] = 2] = "RaptorQ";
20032
20109
  })(MoqFecAlgorithm || (MoqFecAlgorithm = {}));
20033
20110
 
20034
- // node_modules/@blockcast/mmt-transport/node_modules/@blockcast/mmt-alta-parse/dist/index.js
20111
+ // node_modules/@blockcast/mmt-alta-parse/dist/index.js
20035
20112
  var MPU_HEADER_SIZE3 = 8;
20036
20113
  var MPU_LENGTH_FIELD_SIZE3 = 2;
20037
20114
  var MPU_HEADER_REMAINDER_SIZE3 = MPU_HEADER_SIZE3 - MPU_LENGTH_FIELD_SIZE3;
20038
20115
 
20039
- // node_modules/@blockcast/mmt-transport/node_modules/@blockcast/mmt-base/dist/mmtp.js
20116
+ // node_modules/@blockcast/mmt-base/dist/mmtp.js
20040
20117
  var MPU_HEADER_SIZE4 = 8;
20041
20118
  var MPU_LENGTH_FIELD_SIZE4 = 2;
20042
20119
  var MPU_HEADER_REMAINDER_SIZE4 = MPU_HEADER_SIZE4 - MPU_LENGTH_FIELD_SIZE4;
20043
20120
  var MMTP_SIGNALING_PACKET_ID2 = 0;
20044
20121
  var MMTP_PACKET_ID_MAX2 = 65535;
20045
20122
 
20046
- // node_modules/@blockcast/mmt-transport/node_modules/@blockcast/mmt-base/dist/net-constants.js
20123
+ // node_modules/@blockcast/mmt-base/dist/net-constants.js
20047
20124
  var DEFAULT_AMT_RELAY_PORT2 = 2268;
20048
20125
 
20049
- // node_modules/@blockcast/mmt-transport/node_modules/@blockcast/mmt-base/dist/ntp-short.js
20126
+ // node_modules/@blockcast/mmt-base/dist/ntp-short.js
20050
20127
  var NTP_SHORT_BITS2 = 32;
20051
20128
  var NTP_SHORT_MODULUS2 = 2 ** NTP_SHORT_BITS2;
20052
20129
  var NTP_SHORT_HALF_RANGE2 = 2 ** (NTP_SHORT_BITS2 - 1);
@@ -20067,7 +20144,7 @@ function compareNtpShort(a, b) {
20067
20144
  return "unordered";
20068
20145
  }
20069
20146
 
20070
- // node_modules/@blockcast/mmt-transport/node_modules/@blockcast/mmt-base/dist/fec-block-profile.js
20147
+ // node_modules/@blockcast/mmt-base/dist/fec-block-profile.js
20071
20148
  var FEC_BLOCK_PROFILES2 = Object.freeze([
20072
20149
  "iso-ssbg1-v1"
20073
20150
  ]);
@@ -20460,10 +20537,12 @@ var MulticastOrchestrator = class {
20460
20537
  }
20461
20538
  onGoodput(sample) {
20462
20539
  const bitrate = sample.bitrate;
20463
- if (!this.#current || this.options.adaptive === false)
20540
+ if (!this.#current)
20464
20541
  return void 0;
20465
20542
  if (this.#state === "joining")
20466
20543
  return this.poll();
20544
+ if (this.options.adaptive === false)
20545
+ return void 0;
20467
20546
  if (bitrate === void 0 || !Number.isFinite(bitrate))
20468
20547
  return void 0;
20469
20548
  this.#estimate = bitrate;
@@ -20530,6 +20609,27 @@ var MulticastOrchestrator = class {
20530
20609
  this.#favored = void 0;
20531
20610
  return { kind: "join-target", current: this.#current, target: desired };
20532
20611
  }
20612
+ /**
20613
+ * Join `target` because the viewer selected it, not because goodput or
20614
+ * headroom ranked it. It runs whether or not the orchestrator adapts, and
20615
+ * takes the path an adaptive join takes: commit on the target's RAP at or
20616
+ * beyond the high-water mark, abandon at the join deadline. While it is
20617
+ * pending nothing re-ranks the ladder; goodput only advances the deadline.
20618
+ *
20619
+ * Returns undefined, changing nothing, while another join is pending (cancel
20620
+ * it first), when `target` is the current tier, or when it carries no media.
20621
+ */
20622
+ select(target) {
20623
+ if (!this.#current || this.#state === "joining" || !carriesMedia(target))
20624
+ return void 0;
20625
+ if (endpointKey(target) === endpointKey(this.#current))
20626
+ return void 0;
20627
+ this.#state = "joining";
20628
+ this.#target = target;
20629
+ this.#joinStartedAt = this.#now();
20630
+ this.#favored = void 0;
20631
+ return { kind: "join-target", current: this.#current, target };
20632
+ }
20533
20633
  /**
20534
20634
  * Feed a packet from the active tier (to advance the high-water mark) or
20535
20635
  * from the in-flight target (to find a committable RAP).
@@ -21569,7 +21669,7 @@ var MulticastTransport = class _MulticastTransport {
21569
21669
  // inside the window, instead of a clear+set pair on every packet.
21570
21670
  #watchdog = null;
21571
21671
  #lastPacketAtMs = 0;
21572
- #failbackWindowMs = null;
21672
+ #failbackWindowMs;
21573
21673
  #onTakeover = null;
21574
21674
  #onFailback = null;
21575
21675
  // Data-plane-live edge: the first packet this join accepted. Everything
@@ -21874,14 +21974,20 @@ var MulticastTransport = class _MulticastTransport {
21874
21974
  return this.#dataPlaneLive;
21875
21975
  }
21876
21976
  setFailbackWindowMs(windowMs) {
21877
- if (!Number.isFinite(windowMs) || windowMs <= 0) {
21977
+ if (windowMs !== null && (!Number.isFinite(windowMs) || windowMs <= 0)) {
21878
21978
  throw new Error(
21879
21979
  `[MulticastTransport] failbackWindowMs=${windowMs}. Derive a positive failback window from the stream catalog.`
21880
21980
  );
21881
21981
  }
21882
21982
  this.#failbackWindowMs = windowMs;
21883
- if (this.#watchdog !== null) {
21884
- clearTimeout(this.#watchdog);
21983
+ if (windowMs === null) {
21984
+ if (this.#watchdog !== null) clearTimeout(this.#watchdog);
21985
+ this.#watchdog = null;
21986
+ return;
21987
+ }
21988
+ if (this.#watchdog !== null) clearTimeout(this.#watchdog);
21989
+ this.#watchdog = null;
21990
+ if (this.#dataPlaneLive && this.#onFailback) {
21885
21991
  const silentMs = performance.now() - this.#lastPacketAtMs;
21886
21992
  this.#armWatchdog(Math.max(0, Math.ceil(windowMs - silentMs)));
21887
21993
  }
@@ -22207,7 +22313,8 @@ var MulticastTransport = class _MulticastTransport {
22207
22313
  }
22208
22314
  if (this.#watchdog !== null) return;
22209
22315
  if (!this.#onFailback) return;
22210
- if (this.#failbackWindowMs === null) {
22316
+ if (this.#failbackWindowMs === null) return;
22317
+ if (this.#failbackWindowMs === void 0) {
22211
22318
  throw new Error(
22212
22319
  "[MulticastTransport] Failback watchdog requires a catalog-derived window"
22213
22320
  );
@@ -22217,7 +22324,7 @@ var MulticastTransport = class _MulticastTransport {
22217
22324
  #armWatchdog(delayMs) {
22218
22325
  this.#watchdog = setTimeout(() => {
22219
22326
  this.#watchdog = null;
22220
- if (this.#disposed || !this.#onFailback || this.#failbackWindowMs === null) return;
22327
+ if (this.#disposed || !this.#onFailback || this.#failbackWindowMs == null) return;
22221
22328
  const silentMs = performance.now() - this.#lastPacketAtMs;
22222
22329
  if (silentMs < this.#failbackWindowMs) {
22223
22330
  this.#armWatchdog(Math.ceil(this.#failbackWindowMs - silentMs));
@@ -22276,6 +22383,23 @@ function resolveCatalogTrackGroupDurationMs(catalog, track) {
22276
22383
  const renditions = track.type === "audio" ? catalog?.audio?.renditions : catalog?.video?.renditions;
22277
22384
  return catalogGroupDurationMs(renditions?.[track.name]);
22278
22385
  }
22386
+ function positiveNumber(value) {
22387
+ return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : void 0;
22388
+ }
22389
+ function catalogKeyframeCadenceMs(rendition) {
22390
+ if (!rendition) return void 0;
22391
+ const timescale = positiveNumber(rendition.timescale);
22392
+ const ticksToMs = (ticks) => {
22393
+ const value = positiveNumber(ticks);
22394
+ return value !== void 0 && timescale !== void 0 ? value * 1e3 / timescale : void 0;
22395
+ };
22396
+ return ticksToMs(rendition.keyframeIntervalTicks) ?? positiveNumber(rendition.keyframeIntervalMs) ?? ticksToMs(rendition.keyframeDurationTicks) ?? positiveNumber(rendition.keyframeDurationMs) ?? ticksToMs(rendition.gopDurationTicks) ?? positiveNumber(rendition.gopDurationMs);
22397
+ }
22398
+ function catalogFecMediaUnitsPerSecond(type, rendition, endpointSampleRate) {
22399
+ if (type === "video") return positiveNumber(rendition?.framerate);
22400
+ const sampleRate = positiveNumber(endpointSampleRate ?? rendition?.sampleRate ?? rendition?.timescale);
22401
+ return sampleRate === void 0 ? void 0 : sampleRate / 1024;
22402
+ }
22279
22403
  var NO_FEC = {
22280
22404
  fecK: 0,
22281
22405
  fecRepairCount: 0,
@@ -22406,6 +22530,11 @@ function catalogRepairTarget(catalog, source) {
22406
22530
  const sourceName = typeof source === "string" ? source : source.name;
22407
22531
  const msf = msfTracks(catalog);
22408
22532
  const entry = msf?.tracks.find((t) => t["name"] === sourceName);
22533
+ const hang = catalog;
22534
+ const roles = typeof source === "string" ? ["video", "audio"] : source.type === "video" ? ["video"] : source.type === "audio" ? ["audio"] : ["video", "audio"];
22535
+ const rendition = roles.map((role) => hang[role]?.renditions?.[sourceName]).find((r) => recordOf2(r) !== void 0);
22536
+ const fec = rendition === void 0 ? recordOf2(entry?.["fec"]) : recordOf2(rendition.fec);
22537
+ if (!fec || !(catalogFecInterleaveMs(fec) ?? 0)) return null;
22409
22538
  const sourcePriority = entry === void 0 ? null : moqtPriority2(entry["priority"]);
22410
22539
  return { repairTrack: layerZero.repairTrackName, sourcePriority, repairPriority: layerZero.priority };
22411
22540
  }
@@ -22440,17 +22569,10 @@ function blockProfileUnavailable(value, path, declaresFecInstance) {
22440
22569
  }
22441
22570
  function isoSpanUnavailable(fec, path, declaresFecInstance) {
22442
22571
  if (!declaresFecInstance || isoBlockSpanUsable(fec)) return void 0;
22443
- if (fec["interleaveDepthMs"] === void 0) {
22444
- return Object.freeze({
22445
- code: "track_fec_block_span",
22446
- path,
22447
- message: `[repair-layers:track_fec_block_span] ${path}: is absent; iso-ssbg1-v1 requires a declared block span, which bounds its block location`
22448
- });
22449
- }
22450
22572
  return Object.freeze({
22451
22573
  code: "track_fec",
22452
22574
  path,
22453
- message: `[repair-layers:track_fec] ${path}: iso-ssbg1-v1 requires a block span of at least ${MIN_INTERLEAVE_DEPTH_MS} ms, which bounds its block location`
22575
+ message: `[repair-layers:track_fec] ${path}: must be a non-negative safe integer in milliseconds`
22454
22576
  });
22455
22577
  }
22456
22578
  function catalogFecUnavailable(fec, fecPath) {
@@ -22487,9 +22609,7 @@ function fecParams(catalog, track, rendition, fps, sampleRate) {
22487
22609
  // The wire RSB_length: every base layer's packets carry the base total (§7.1).
22488
22610
  fecTotalRepairCount: repair?.totalBaseRepairSymbols ?? fec.repairSymbols ?? 0,
22489
22611
  fecSymbolSize: fec.symbolSize ?? 0,
22490
- // interleaveDepthMs is the FEC block span in MILLISECONDS (§5.1) — the
22491
- // only interleave key the catalog carries post-BLO-14526. Receivers
22492
- // derive D by positive round-half-up of span / GOP duration where needed.
22612
+ // Zero/absence leaves the elapsed deadline unknown; geometry stays in-band.
22493
22613
  fecInterleaveMs: catalogFecInterleaveMs(fec) ?? 0,
22494
22614
  // Additive, never a multiplier on the span: jitter belongs to the network
22495
22615
  // path and the span belongs to the encoder, so scaling one by the other
@@ -22867,6 +22987,7 @@ function repairTrackNamesBySource(tracks) {
22867
22987
  var MulticastManager = class {
22868
22988
  #fec;
22869
22989
  #router;
22990
+ #hostMfuTimeoutMs;
22870
22991
  #transport;
22871
22992
  #reportedFecDiagnosticsFailure = false;
22872
22993
  // ── Stream-global FEC timing reduction ──
@@ -22965,6 +23086,7 @@ var MulticastManager = class {
22965
23086
  this.#emitRepairLifecycle(decision);
22966
23087
  }
22967
23088
  });
23089
+ this.#hostMfuTimeoutMs = this.#router.reassembler.timeoutMs;
22968
23090
  this.#transport = new MulticastTransport((packet, ingress) => {
22969
23091
  this.#router.feedPacket(packet, "multicast", void 0, ingress);
22970
23092
  });
@@ -23181,7 +23303,6 @@ var MulticastManager = class {
23181
23303
  ...this.#streamFecBaseline ? [this.#streamFecBaseline] : [],
23182
23304
  ...this.#trackFecTiming.values()
23183
23305
  ];
23184
- if (contributions.length === 0) return;
23185
23306
  let deliveryWindowMs;
23186
23307
  let minimumFailbackWindowMs;
23187
23308
  let mfuTimeoutMs;
@@ -23213,15 +23334,9 @@ var MulticastManager = class {
23213
23334
  }
23214
23335
  }
23215
23336
  const failbackWindowMs = deliveryWindowMs === void 0 ? minimumFailbackWindowMs : Math.max(deliveryWindowMs, minimumFailbackWindowMs ?? 0);
23216
- if (failbackWindowMs !== void 0) {
23217
- this.#transport.setFailbackWindowMs(failbackWindowMs);
23218
- }
23219
- if (mfuTimeoutMs !== void 0) {
23220
- this.#router.setMfuTimeoutMs(mfuTimeoutMs);
23221
- }
23222
- if (reorderWindowFrames !== void 0) {
23223
- this.#router.setReorderWindow(reorderWindowFrames);
23224
- }
23337
+ this.#transport.setFailbackWindowMs(failbackWindowMs ?? null);
23338
+ this.#router.setMfuTimeoutMs(mfuTimeoutMs ?? this.#hostMfuTimeoutMs);
23339
+ this.#router.setReorderWindow(reorderWindowFrames ?? 0);
23225
23340
  }
23226
23341
  /**
23227
23342
  * Configure one track's FEC geometry, block mapper, and block-inactivity
@@ -23248,9 +23363,9 @@ var MulticastManager = class {
23248
23363
  `[MulticastManager] configureTrackFec(${packetId}) catalogTrackName must be non-empty when given`
23249
23364
  );
23250
23365
  }
23251
- if (config.fecK === void 0 || config.fecInterleaveDepthMs === void 0) {
23366
+ if (config.fecK === void 0) {
23252
23367
  throw new Error(
23253
- `[MulticastManager] configureTrackFec(${packetId}) requires fecK and fecInterleaveDepthMs. Derive the per-track FEC geometry from the stream catalog.`
23368
+ `[MulticastManager] configureTrackFec(${packetId}) requires fecK. Derive the per-track FEC geometry from the stream catalog.`
23254
23369
  );
23255
23370
  }
23256
23371
  const blockProfile = parseFecBlockProfile(
@@ -23258,7 +23373,10 @@ var MulticastManager = class {
23258
23373
  `[MulticastManager] configureTrackFec(${packetId}) fecBlockProfile`
23259
23374
  );
23260
23375
  assertPositiveGeometry("fecK", config.fecK);
23261
- assertPositiveGeometry("fecInterleaveDepthMs", config.fecInterleaveDepthMs);
23376
+ const interleaveDepthMs = config.fecInterleaveDepthMs ?? 0;
23377
+ if (!Number.isSafeInteger(interleaveDepthMs) || interleaveDepthMs < 0) {
23378
+ throw new Error("[MulticastManager] fecInterleaveDepthMs must be a non-negative safe integer");
23379
+ }
23262
23380
  assertPositiveGeometry("fecSymbolSize", config.fecSymbolSize);
23263
23381
  assertPositiveGeometry("fps", config.fps);
23264
23382
  assertPositiveGeometry("bandwidth", config.bandwidth);
@@ -23274,8 +23392,8 @@ var MulticastManager = class {
23274
23392
  "fecReorderToleranceMs",
23275
23393
  config.fecReorderToleranceMs
23276
23394
  );
23277
- const deliveryWindowMs = config.fecInterleaveDepthMs >= MIN_INTERLEAVE_DEPTH_MS ? computeFecDeliveryWindowMs({
23278
- interleaveDepthMs: config.fecInterleaveDepthMs,
23395
+ const deliveryWindowMs = interleaveDepthMs >= MIN_INTERLEAVE_DEPTH_MS ? computeFecDeliveryWindowMs({
23396
+ interleaveDepthMs,
23279
23397
  sourceSymbols: config.fecK,
23280
23398
  repairSymbols: config.fecRepairSymbols,
23281
23399
  symbolSize: config.fecSymbolSize,
@@ -23284,10 +23402,10 @@ var MulticastManager = class {
23284
23402
  jitterBufferMs: config.fecReorderToleranceMs
23285
23403
  }) : void 0;
23286
23404
  const trackKind = config.trackKind ?? this.#router.trackKindFor(packetId);
23287
- const geometry = trackKind === void 0 ? void 0 : deriveBlockClassifierGeometry({
23405
+ const geometry = trackKind === void 0 || interleaveDepthMs === 0 ? void 0 : deriveBlockClassifierGeometry({
23288
23406
  trackKind,
23289
23407
  framerate: config.fps,
23290
- interleaveDepthMs: config.fecInterleaveDepthMs,
23408
+ interleaveDepthMs,
23291
23409
  timescale: config.timescale,
23292
23410
  keyframeIntervalTicks: config.keyframeIntervalTicks,
23293
23411
  keyframeIntervalMs: config.keyframeIntervalMs
@@ -23296,7 +23414,7 @@ var MulticastManager = class {
23296
23414
  blockProfile,
23297
23415
  k: config.fecK,
23298
23416
  symbolSize: config.fecSymbolSize,
23299
- interleaveDepthMs: config.fecInterleaveDepthMs,
23417
+ interleaveDepthMs,
23300
23418
  fps: config.fps,
23301
23419
  timeoutMs: deliveryWindowMs,
23302
23420
  ...trackKind === void 0 ? {} : { trackKind },
@@ -23307,7 +23425,7 @@ var MulticastManager = class {
23307
23425
  this.#configureTrackMapper(packetId, fecConfig);
23308
23426
  this.#trackFecTiming.set(packetId, {
23309
23427
  deliveryWindowMs,
23310
- interleaveDepthMs: config.fecInterleaveDepthMs,
23428
+ interleaveDepthMs,
23311
23429
  fps: config.fps,
23312
23430
  k: config.fecK,
23313
23431
  repairSymbols: config.fecRepairSymbols,
@@ -23316,6 +23434,10 @@ var MulticastManager = class {
23316
23434
  this.#applyStreamGlobalFecTiming();
23317
23435
  }
23318
23436
  configureFec(config) {
23437
+ const interleaveDepthMs = config.fecInterleaveDepthMs ?? 0;
23438
+ if (!Number.isSafeInteger(interleaveDepthMs) || interleaveDepthMs < 0) {
23439
+ throw new Error("[MulticastManager] fecInterleaveDepthMs must be a non-negative safe integer");
23440
+ }
23319
23441
  const minimumFailbackWindowMs = config.minimumFailbackWindowMs;
23320
23442
  if (minimumFailbackWindowMs !== void 0 && (!Number.isFinite(minimumFailbackWindowMs) || minimumFailbackWindowMs <= 0)) {
23321
23443
  throw new Error(
@@ -23327,7 +23449,7 @@ var MulticastManager = class {
23327
23449
  config.fecReorderToleranceMs
23328
23450
  );
23329
23451
  const deliveryWindowMs = config.fecK && config.fecK > 0 && config.fecInterleaveDepthMs && config.fecInterleaveDepthMs >= MIN_INTERLEAVE_DEPTH_MS ? computeFecDeliveryWindowMs({
23330
- interleaveDepthMs: config.fecInterleaveDepthMs,
23452
+ interleaveDepthMs,
23331
23453
  sourceSymbols: config.fecK,
23332
23454
  repairSymbols: config.fecRepairSymbols,
23333
23455
  symbolSize: config.fecSymbolSize,
@@ -23338,13 +23460,13 @@ var MulticastManager = class {
23338
23460
  this.#fec.configure({
23339
23461
  k: config.fecK,
23340
23462
  symbolSize: config.fecSymbolSize,
23341
- interleaveDepthMs: config.fecInterleaveDepthMs,
23463
+ interleaveDepthMs,
23342
23464
  fps: config.fps,
23343
23465
  timeoutMs: deliveryWindowMs
23344
23466
  });
23345
23467
  this.#streamFecBaseline = {
23346
23468
  deliveryWindowMs,
23347
- interleaveDepthMs: config.fecInterleaveDepthMs,
23469
+ interleaveDepthMs,
23348
23470
  fps: config.fps,
23349
23471
  k: config.fecK,
23350
23472
  repairSymbols: config.fecRepairSymbols,
@@ -23393,6 +23515,7 @@ var MulticastManager = class {
23393
23515
  }
23394
23516
  setMfuTimeoutMs(ms) {
23395
23517
  this.#router.setMfuTimeoutMs(ms);
23518
+ this.#hostMfuTimeoutMs = this.#router.reassembler.timeoutMs;
23396
23519
  }
23397
23520
  setTrackCodec(packetId, codec) {
23398
23521
  this.#router.setTrackCodec(packetId, codec);
@@ -23749,7 +23872,9 @@ var MulticastManager = class {
23749
23872
  for (const [key, stats] of [...this.#blockPolicyStats]) {
23750
23873
  if (stats.packetId === stream.packetId) this.#blockPolicyStats.delete(key);
23751
23874
  }
23752
- this.#trackFecTiming.delete(stream.packetId);
23875
+ if (this.#trackFecTiming.delete(stream.packetId)) {
23876
+ this.#applyStreamGlobalFecTiming();
23877
+ }
23753
23878
  this.#multiTrackFecTracks.delete(stream.packetId);
23754
23879
  this.#fec.releasePacket(stream.packetId);
23755
23880
  }
@@ -23989,7 +24114,7 @@ var MulticastManager = class {
23989
24114
  blockProfile,
23990
24115
  k: fecCfg.sourceSymbols,
23991
24116
  symbolSize: fecCfg.symbolSize,
23992
- interleaveDepthMs: fecCfg.interleaveDepthMs,
24117
+ interleaveDepthMs: fecCfg.interleaveDepthMs ?? 0,
23993
24118
  fps: track.framerate,
23994
24119
  trackKind: "video"
23995
24120
  },
@@ -24000,7 +24125,7 @@ var MulticastManager = class {
24000
24125
  blockProfile,
24001
24126
  k: fecCfg.sourceSymbols,
24002
24127
  symbolSize: fecCfg.symbolSize,
24003
- interleaveDepthMs: fecCfg.interleaveDepthMs,
24128
+ interleaveDepthMs: fecCfg.interleaveDepthMs ?? 0,
24004
24129
  fps: track.framerate
24005
24130
  });
24006
24131
  this.#router.setPacketIdType(track.packetId, "video");
@@ -24013,8 +24138,8 @@ var MulticastManager = class {
24013
24138
  * although its `fec` block declares one (draft-ramadan-moq-fec §5.1): no
24014
24139
  * implemented `blockProfile` (`track_fec_block_profile_unimplemented`, e.g.
24015
24140
  * the retired `k-padded-v1`; `track_fec_block_profile` when absent), or an
24016
- * `iso-ssbg1-v1` span it cannot use (`track_fec_block_span` when absent,
24017
- * `track_fec` when declared but unusable). The same reason the hang
24141
+ * invalid `iso-ssbg1-v1` span (`track_fec`). Absent/zero spans keep in-band
24142
+ * decoding enabled. The same reason the hang
24018
24143
  * resolver reports (`catalogFecUnavailable`). Undefined for every other
24019
24144
  * track, and for every track before the first call; each call replaces the
24020
24145
  * previous call's answers.
@@ -24236,32 +24361,63 @@ var MulticastManager = class {
24236
24361
 
24237
24362
  // src/fec-worker-setup.ts
24238
24363
  async function setupFecWorkerForTrack(opts) {
24239
- if (!Number.isFinite(opts.fecInterleaveMs) || opts.fecInterleaveMs <= 0) {
24364
+ if (!Number.isFinite(opts.fecInterleaveMs) || !Number.isSafeInteger(opts.fecInterleaveMs) || opts.fecInterleaveMs < 0) {
24240
24365
  throw new Error(
24241
- `[FEC] interleaveDepthMs (opts.fecInterleaveMs) must be finite and > 0 (got ${opts.fecInterleaveMs})`
24366
+ `[FEC] interleaveDepthMs (opts.fecInterleaveMs) must be a finite non-negative integer (got ${opts.fecInterleaveMs})`
24242
24367
  );
24243
24368
  }
24244
- if (!Number.isFinite(opts.mediaUnitDurationMs) || opts.mediaUnitDurationMs <= 0) {
24369
+ if (opts.fecReorderToleranceMs !== void 0 && (!Number.isFinite(opts.fecReorderToleranceMs) || opts.fecReorderToleranceMs < 0)) {
24245
24370
  throw new Error(
24246
- `[FEC] mediaUnitDurationMs must be finite and > 0 (got ${opts.mediaUnitDurationMs})`
24371
+ `[FEC] fecReorderToleranceMs must be finite and >= 0 (got ${opts.fecReorderToleranceMs})`
24372
+ );
24373
+ }
24374
+ const hasCatalogTiming = opts.fecInterleaveMs > 0;
24375
+ const validateWorkerGeometry = () => {
24376
+ if (!Number.isSafeInteger(opts.fecK) || opts.fecK <= 0) {
24377
+ throw new Error(`[FEC] fecK must be a finite positive integer (got ${opts.fecK})`);
24378
+ }
24379
+ if (!Number.isSafeInteger(opts.fecSymbolSize) || opts.fecSymbolSize <= 0 || opts.fecSymbolSize % 8 !== 0) {
24380
+ throw new Error(
24381
+ `[FEC] fecSymbolSize must be a positive 8-byte-aligned integer (got ${opts.fecSymbolSize})`
24382
+ );
24383
+ }
24384
+ if (!Number.isSafeInteger(opts.fecRepairCount) || opts.fecRepairCount <= 0) {
24385
+ throw new Error(
24386
+ `[FEC] fecRepairCount must be a finite positive integer (got ${opts.fecRepairCount})`
24387
+ );
24388
+ }
24389
+ };
24390
+ let deliveryWindowMs;
24391
+ let interleaveDepthBlocks;
24392
+ if (!hasCatalogTiming) {
24393
+ validateWorkerGeometry();
24394
+ deliveryWindowMs = LOCAL_FEC_TIMEOUT_MS;
24395
+ interleaveDepthBlocks = LOCAL_FEC_RETENTION_BLOCKS;
24396
+ } else {
24397
+ const mediaUnitDurationMs = opts.mediaUnitDurationMs;
24398
+ if (typeof mediaUnitDurationMs !== "number" || !Number.isFinite(mediaUnitDurationMs) || mediaUnitDurationMs <= 0) {
24399
+ throw new Error(
24400
+ `[FEC] mediaUnitDurationMs must be finite and > 0 (got ${mediaUnitDurationMs})`
24401
+ );
24402
+ }
24403
+ validateWorkerGeometry();
24404
+ deliveryWindowMs = computeFecDeliveryWindowMs({
24405
+ interleaveDepthMs: opts.fecInterleaveMs,
24406
+ sourceSymbols: opts.fecK,
24407
+ repairSymbols: opts.fecRepairCount,
24408
+ symbolSize: opts.fecSymbolSize,
24409
+ mediaUnitsPerSecond: 1e3 / mediaUnitDurationMs,
24410
+ jitterBufferMs: opts.fecReorderToleranceMs
24411
+ });
24412
+ interleaveDepthBlocks = deriveFecRetentionBlocks(
24413
+ deliveryWindowMs,
24414
+ opts.fecInterleaveMs
24247
24415
  );
24248
24416
  }
24249
24417
  const blockProfile = parseFecBlockProfile(
24250
24418
  opts.fecBlockProfile,
24251
24419
  `[FEC] ${opts.trackName} fec.blockProfile`
24252
24420
  );
24253
- const deliveryWindowMs = computeFecDeliveryWindowMs({
24254
- interleaveDepthMs: opts.fecInterleaveMs,
24255
- sourceSymbols: opts.fecK,
24256
- repairSymbols: opts.fecRepairCount,
24257
- symbolSize: opts.fecSymbolSize,
24258
- mediaUnitsPerSecond: 1e3 / opts.mediaUnitDurationMs,
24259
- jitterBufferMs: opts.fecReorderToleranceMs
24260
- });
24261
- const interleaveDepthBlocks = deriveFecRetentionBlocks(
24262
- deliveryWindowMs,
24263
- opts.fecInterleaveMs
24264
- );
24265
24421
  const origin = typeof location !== "undefined" && location.origin ? location.origin : "http://localhost";
24266
24422
  const workerUrl = new URL(opts.assetUrls.fecWorker, origin);
24267
24423
  const FecWorkerCtor = await Promise.resolve().then(() => (init_dist(), dist_exports));
@@ -24315,9 +24471,10 @@ async function setupFecWorkerForTrack(opts) {
24315
24471
  k: opts.fecK,
24316
24472
  symbolSize: opts.fecSymbolSize,
24317
24473
  interleaveDepthMs: opts.fecInterleaveMs,
24318
- // FEC timing is expressed in media units. For audio this is the access-unit
24319
- // cadence (for example 1024/48kHz), not a video-only framerate field.
24320
- fps: 1e3 / opts.mediaUnitDurationMs,
24474
+ // No-span tracks have no catalog media cadence. The manager still gets
24475
+ // the local cleanup budget, but it must not use a guessed fps for timing
24476
+ // or classification.
24477
+ ...hasCatalogTiming ? { fps: 1e3 / opts.mediaUnitDurationMs } : {},
24321
24478
  timeoutMs: deliveryWindowMs
24322
24479
  }, opts.trackName);
24323
24480
  } catch (e) {
@@ -24357,6 +24514,28 @@ var TrackSourceConflictError = class extends Error {
24357
24514
  };
24358
24515
  var DEFAULT_CROSSFADE_FRAMES = 10;
24359
24516
  var DEFAULT_MAX_OVERLAY_BUFFER = 128;
24517
+ function assertDeltaFallbackConfig(cfg, prefix) {
24518
+ if (!isPositiveFinite2(cfg.framerate)) throw new Error(`${prefix}: framerate required and must be > 0`);
24519
+ if (!isPositiveFinite2(cfg.sourceSymbols))
24520
+ throw new Error(`${prefix}: sourceSymbols (K_delta) required and must be > 0`);
24521
+ if (!isPositiveFinite2(cfg.repairSymbols))
24522
+ throw new Error(`${prefix}: repairSymbols (P_delta) required and must be > 0`);
24523
+ if (cfg.deltaFailWindowBlocks !== void 0 && !(Number.isInteger(cfg.deltaFailWindowBlocks) && cfg.deltaFailWindowBlocks > 0)) {
24524
+ throw new Error(`${prefix}: deltaFailWindowBlocks must be a positive integer when present`);
24525
+ }
24526
+ if (cfg.deltaProbeIntervalMs !== void 0 && !isPositiveFinite2(cfg.deltaProbeIntervalMs))
24527
+ throw new Error(`${prefix}: deltaProbeIntervalMs must be > 0 when present`);
24528
+ if (cfg.interleaveDepthMs !== void 0 && !isPositiveFinite2(cfg.interleaveDepthMs))
24529
+ throw new Error(`${prefix}: interleaveDepthMs must be > 0 when present`);
24530
+ if (cfg.deltaProbeIntervalMs === void 0 && cfg.interleaveDepthMs === void 0) {
24531
+ throw new Error(
24532
+ `${prefix}: either deltaProbeIntervalMs or interleaveDepthMs required for probe interval derivation`
24533
+ );
24534
+ }
24535
+ }
24536
+ function isPositiveFinite2(value) {
24537
+ return typeof value === "number" && Number.isFinite(value) && value > 0;
24538
+ }
24360
24539
  var MediaRouter = class {
24361
24540
  #active = "moq";
24362
24541
  #multicastVideoKeyed = false;
@@ -24518,20 +24697,7 @@ var MediaRouter = class {
24518
24697
  * Calling again resets deltaActive=true and clears the window buffer (stream restart).
24519
24698
  */
24520
24699
  configureDelta(cfg) {
24521
- if (typeof cfg.framerate !== "number" || !Number.isFinite(cfg.framerate) || cfg.framerate <= 0) {
24522
- throw new Error("[MediaRouter] configureDelta: framerate required and must be > 0");
24523
- }
24524
- if (typeof cfg.sourceSymbols !== "number" || cfg.sourceSymbols <= 0) {
24525
- throw new Error("[MediaRouter] configureDelta: sourceSymbols (K_delta) required and must be > 0");
24526
- }
24527
- if (typeof cfg.repairSymbols !== "number" || cfg.repairSymbols <= 0) {
24528
- throw new Error("[MediaRouter] configureDelta: repairSymbols (P_delta) required and must be > 0");
24529
- }
24530
- if (cfg.deltaProbeIntervalMs === void 0 && cfg.interleaveDepthMs === void 0) {
24531
- throw new Error(
24532
- "[MediaRouter] configureDelta: either deltaProbeIntervalMs or interleaveDepthMs required for probe interval derivation"
24533
- );
24534
- }
24700
+ assertDeltaFallbackConfig(cfg, "[MediaRouter] configureDelta");
24535
24701
  this.#deltaWindowSize = cfg.deltaFailWindowBlocks ?? Math.ceil(cfg.framerate);
24536
24702
  this.#deltaFailThresholdRatio = cfg.repairSymbols / cfg.sourceSymbols;
24537
24703
  this.#deltaRecoverThresholdRatio = this.#deltaFailThresholdRatio / 2;
@@ -24908,6 +25074,35 @@ var MediaRouter = class {
24908
25074
  }
24909
25075
  };
24910
25076
 
25077
+ // src/delta-fallback-config.ts
25078
+ function resolveDeltaFallback(base, delta) {
25079
+ const repair = base.fec?.repairTrack;
25080
+ if (!repair) throw new Error(`[delta-fallback] base track "${base.name}" missing fec.repairTrack`);
25081
+ const deltaFec = delta.fec;
25082
+ if (!deltaFec?.repairTrack) throw new Error(`[delta-fallback] delta track "${delta.name}" missing fec.repairTrack`);
25083
+ if (deltaFec.repairTrack !== repair)
25084
+ throw new Error(
25085
+ `[delta-fallback] inconsistent repair tracks: ${base.name} references "${repair}" but ${delta.name} references "${deltaFec.repairTrack}"`
25086
+ );
25087
+ if (!(typeof base.framerate === "number" && Number.isFinite(base.framerate) && base.framerate > 0))
25088
+ throw new Error(`[delta-fallback] base track "${base.name}" missing positive framerate`);
25089
+ if (!(isPositive(deltaFec.sourceSymbols) && isPositive(deltaFec.repairSymbols)))
25090
+ throw new Error(`[delta-fallback] delta track "${delta.name}" missing positive fec.sourceSymbols/repairSymbols`);
25091
+ const config = {
25092
+ framerate: base.framerate,
25093
+ sourceSymbols: deltaFec.sourceSymbols,
25094
+ repairSymbols: deltaFec.repairSymbols,
25095
+ deltaFailWindowBlocks: base.fec?.deltaFailWindowBlocks ?? deltaFec.deltaFailWindowBlocks,
25096
+ deltaProbeIntervalMs: base.fec?.deltaProbeIntervalMs ?? deltaFec.deltaProbeIntervalMs,
25097
+ interleaveDepthMs: base.fec?.interleaveDepthMs ?? deltaFec.interleaveDepthMs
25098
+ };
25099
+ assertDeltaFallbackConfig(config, `[delta-fallback] group ${base.name}/${delta.name}`);
25100
+ return { repairTrackName: repair, config };
25101
+ }
25102
+ function isPositive(value) {
25103
+ return typeof value === "number" && Number.isFinite(value) && value > 0;
25104
+ }
25105
+
24911
25106
  // src/align.ts
24912
25107
  function secondsFromTicks(ticks, timescale) {
24913
25108
  if (!Number.isFinite(ticks)) {
@@ -26333,8 +26528,10 @@ export {
26333
26528
  catalogAmtNetworkSource,
26334
26529
  catalogDeclaresFec,
26335
26530
  catalogFecInterleaveMs,
26531
+ catalogFecMediaUnitsPerSecond,
26336
26532
  catalogFecUnavailable,
26337
26533
  catalogGroupDurationMs,
26534
+ catalogKeyframeCadenceMs,
26338
26535
  catalogRepairTarget,
26339
26536
  classifyH264Keyframe,
26340
26537
  classifyHevcKeyframe,
@@ -26432,6 +26629,7 @@ export {
26432
26629
  repairReachability,
26433
26630
  resolveCatalogTrackFec,
26434
26631
  resolveCatalogTrackGroupDurationMs,
26632
+ resolveDeltaFallback,
26435
26633
  resolveFecState,
26436
26634
  resolveGlobalMmtWasmBindings,
26437
26635
  resolveGroupDurationMs,