prismcast 1.10.2 → 1.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (693) hide show
  1. package/dist/app.d.ts +6 -3
  2. package/dist/app.d.ts.map +1 -0
  3. package/dist/app.js +140 -86
  4. package/dist/app.js.map +1 -1
  5. package/dist/browser/blockedPage.d.ts +80 -0
  6. package/dist/browser/blockedPage.d.ts.map +1 -0
  7. package/dist/browser/blockedPage.js +209 -0
  8. package/dist/browser/blockedPage.js.map +1 -0
  9. package/dist/browser/browserSupervisor.d.ts +80 -0
  10. package/dist/browser/browserSupervisor.d.ts.map +1 -0
  11. package/dist/browser/browserSupervisor.js +186 -0
  12. package/dist/browser/browserSupervisor.js.map +1 -0
  13. package/dist/browser/cdp.d.ts +1 -0
  14. package/dist/browser/cdp.d.ts.map +1 -0
  15. package/dist/browser/cdp.js +6 -5
  16. package/dist/browser/cdp.js.map +1 -1
  17. package/dist/browser/channelSelection.d.ts +45 -14
  18. package/dist/browser/channelSelection.d.ts.map +1 -0
  19. package/dist/browser/channelSelection.js +81 -18
  20. package/dist/browser/channelSelection.js.map +1 -1
  21. package/dist/browser/consent.d.ts +152 -0
  22. package/dist/browser/consent.d.ts.map +1 -0
  23. package/dist/browser/consent.js +418 -0
  24. package/dist/browser/consent.js.map +1 -0
  25. package/dist/browser/display.d.ts +1 -0
  26. package/dist/browser/display.d.ts.map +1 -0
  27. package/dist/browser/hlsPlaylistObserver.d.ts +55 -0
  28. package/dist/browser/hlsPlaylistObserver.d.ts.map +1 -0
  29. package/dist/browser/hlsPlaylistObserver.js +132 -0
  30. package/dist/browser/hlsPlaylistObserver.js.map +1 -0
  31. package/dist/browser/index.d.ts +67 -40
  32. package/dist/browser/index.d.ts.map +1 -0
  33. package/dist/browser/index.js +508 -300
  34. package/dist/browser/index.js.map +1 -1
  35. package/dist/browser/launchGovernor.d.ts +89 -0
  36. package/dist/browser/launchGovernor.d.ts.map +1 -0
  37. package/dist/browser/launchGovernor.js +96 -0
  38. package/dist/browser/launchGovernor.js.map +1 -0
  39. package/dist/browser/login.d.ts +10 -2
  40. package/dist/browser/login.d.ts.map +1 -0
  41. package/dist/browser/login.js +36 -5
  42. package/dist/browser/login.js.map +1 -1
  43. package/dist/browser/manifestInterceptor.d.ts +102 -49
  44. package/dist/browser/manifestInterceptor.d.ts.map +1 -0
  45. package/dist/browser/manifestInterceptor.js +219 -237
  46. package/dist/browser/manifestInterceptor.js.map +1 -1
  47. package/dist/browser/pageStaleness.d.ts +30 -0
  48. package/dist/browser/pageStaleness.d.ts.map +1 -0
  49. package/dist/browser/pageStaleness.js +76 -0
  50. package/dist/browser/pageStaleness.js.map +1 -0
  51. package/dist/browser/precaching.d.ts +95 -3
  52. package/dist/browser/precaching.d.ts.map +1 -0
  53. package/dist/browser/precaching.js +499 -65
  54. package/dist/browser/precaching.js.map +1 -1
  55. package/dist/browser/tabNetworkObserver.d.ts +49 -0
  56. package/dist/browser/tabNetworkObserver.d.ts.map +1 -0
  57. package/dist/browser/tabNetworkObserver.js +144 -0
  58. package/dist/browser/tabNetworkObserver.js.map +1 -0
  59. package/dist/browser/tuning/cache.d.ts +61 -0
  60. package/dist/browser/tuning/cache.d.ts.map +1 -0
  61. package/dist/browser/tuning/cache.js +62 -0
  62. package/dist/browser/tuning/cache.js.map +1 -0
  63. package/dist/browser/tuning/comcastPolymer.d.ts +3 -2
  64. package/dist/browser/tuning/comcastPolymer.d.ts.map +1 -0
  65. package/dist/browser/tuning/comcastPolymer.js +79 -102
  66. package/dist/browser/tuning/comcastPolymer.js.map +1 -1
  67. package/dist/browser/tuning/cox.d.ts +1 -0
  68. package/dist/browser/tuning/cox.d.ts.map +1 -0
  69. package/dist/browser/tuning/directv.d.ts +1 -0
  70. package/dist/browser/tuning/directv.d.ts.map +1 -0
  71. package/dist/browser/tuning/directv.js +52 -46
  72. package/dist/browser/tuning/directv.js.map +1 -1
  73. package/dist/browser/tuning/fox.d.ts +1 -0
  74. package/dist/browser/tuning/fox.d.ts.map +1 -0
  75. package/dist/browser/tuning/fox.js +13 -12
  76. package/dist/browser/tuning/fox.js.map +1 -1
  77. package/dist/browser/tuning/gridSearch.d.ts +68 -0
  78. package/dist/browser/tuning/gridSearch.d.ts.map +1 -0
  79. package/dist/browser/tuning/gridSearch.js +85 -0
  80. package/dist/browser/tuning/gridSearch.js.map +1 -0
  81. package/dist/browser/tuning/hbo.d.ts +1 -0
  82. package/dist/browser/tuning/hbo.d.ts.map +1 -0
  83. package/dist/browser/tuning/hbo.js +73 -45
  84. package/dist/browser/tuning/hbo.js.map +1 -1
  85. package/dist/browser/tuning/hulu.d.ts +1 -0
  86. package/dist/browser/tuning/hulu.d.ts.map +1 -0
  87. package/dist/browser/tuning/hulu.js +128 -173
  88. package/dist/browser/tuning/hulu.js.map +1 -1
  89. package/dist/browser/tuning/shared.d.ts +75 -5
  90. package/dist/browser/tuning/shared.d.ts.map +1 -0
  91. package/dist/browser/tuning/shared.js +216 -6
  92. package/dist/browser/tuning/shared.js.map +1 -1
  93. package/dist/browser/tuning/sling.d.ts +1 -0
  94. package/dist/browser/tuning/sling.d.ts.map +1 -0
  95. package/dist/browser/tuning/sling.js +105 -126
  96. package/dist/browser/tuning/sling.js.map +1 -1
  97. package/dist/browser/tuning/spectrum.d.ts +1 -0
  98. package/dist/browser/tuning/spectrum.d.ts.map +1 -0
  99. package/dist/browser/tuning/spectrum.js +80 -125
  100. package/dist/browser/tuning/spectrum.js.map +1 -1
  101. package/dist/browser/tuning/thumbnailRow.d.ts +1 -0
  102. package/dist/browser/tuning/thumbnailRow.d.ts.map +1 -0
  103. package/dist/browser/tuning/thumbnailRow.js +8 -2
  104. package/dist/browser/tuning/thumbnailRow.js.map +1 -1
  105. package/dist/browser/tuning/tileClick.d.ts +1 -0
  106. package/dist/browser/tuning/tileClick.d.ts.map +1 -0
  107. package/dist/browser/tuning/tileClick.js +3 -2
  108. package/dist/browser/tuning/tileClick.js.map +1 -1
  109. package/dist/browser/tuning/xfinity.d.ts +1 -0
  110. package/dist/browser/tuning/xfinity.d.ts.map +1 -0
  111. package/dist/browser/tuning/youtubeTv.d.ts +1 -0
  112. package/dist/browser/tuning/youtubeTv.d.ts.map +1 -0
  113. package/dist/browser/tuning/youtubeTv.js +74 -127
  114. package/dist/browser/tuning/youtubeTv.js.map +1 -1
  115. package/dist/browser/video.d.ts +54 -14
  116. package/dist/browser/video.d.ts.map +1 -0
  117. package/dist/browser/video.js +296 -138
  118. package/dist/browser/video.js.map +1 -1
  119. package/dist/channels/index.d.ts +1 -0
  120. package/dist/channels/index.d.ts.map +1 -0
  121. package/dist/channels/index.js +12 -9
  122. package/dist/channels/index.js.map +1 -1
  123. package/dist/config/channelForm.d.ts +15 -1
  124. package/dist/config/channelForm.d.ts.map +1 -0
  125. package/dist/config/channelForm.js +28 -12
  126. package/dist/config/channelForm.js.map +1 -1
  127. package/dist/config/consistencyProbe.d.ts +1 -0
  128. package/dist/config/consistencyProbe.d.ts.map +1 -0
  129. package/dist/config/consistencyProbe.js +27 -21
  130. package/dist/config/consistencyProbe.js.map +1 -1
  131. package/dist/config/health.d.ts +41 -8
  132. package/dist/config/health.d.ts.map +1 -0
  133. package/dist/config/health.js +189 -38
  134. package/dist/config/health.js.map +1 -1
  135. package/dist/config/index.d.ts +55 -3
  136. package/dist/config/index.d.ts.map +1 -0
  137. package/dist/config/index.js +320 -69
  138. package/dist/config/index.js.map +1 -1
  139. package/dist/config/paths.d.ts +10 -9
  140. package/dist/config/paths.d.ts.map +1 -0
  141. package/dist/config/paths.js +11 -11
  142. package/dist/config/paths.js.map +1 -1
  143. package/dist/config/persistence.context.d.ts +1 -0
  144. package/dist/config/persistence.context.d.ts.map +1 -0
  145. package/dist/config/persistence.d.ts +13 -10
  146. package/dist/config/persistence.d.ts.map +1 -0
  147. package/dist/config/persistence.js +40 -21
  148. package/dist/config/persistence.js.map +1 -1
  149. package/dist/config/presets.d.ts +1 -0
  150. package/dist/config/presets.d.ts.map +1 -0
  151. package/dist/config/profiles.d.ts +22 -15
  152. package/dist/config/profiles.d.ts.map +1 -0
  153. package/dist/config/profiles.js +81 -47
  154. package/dist/config/profiles.js.map +1 -1
  155. package/dist/config/providerLineups.d.ts +47 -0
  156. package/dist/config/providerLineups.d.ts.map +1 -0
  157. package/dist/config/providerLineups.js +137 -0
  158. package/dist/config/providerLineups.js.map +1 -0
  159. package/dist/config/reactivity.d.ts +84 -0
  160. package/dist/config/reactivity.d.ts.map +1 -0
  161. package/dist/config/reactivity.js +226 -0
  162. package/dist/config/reactivity.js.map +1 -0
  163. package/dist/config/servicePacks.d.ts +18 -2
  164. package/dist/config/servicePacks.d.ts.map +1 -0
  165. package/dist/config/servicePacks.js +53 -11
  166. package/dist/config/servicePacks.js.map +1 -1
  167. package/dist/config/services.d.ts +21 -15
  168. package/dist/config/services.d.ts.map +1 -0
  169. package/dist/config/services.js +35 -24
  170. package/dist/config/services.js.map +1 -1
  171. package/dist/config/sites.d.ts +6 -4
  172. package/dist/config/sites.d.ts.map +1 -0
  173. package/dist/config/sites.js +15 -11
  174. package/dist/config/sites.js.map +1 -1
  175. package/dist/config/userChannels.d.ts +129 -30
  176. package/dist/config/userChannels.d.ts.map +1 -0
  177. package/dist/config/userChannels.js +333 -68
  178. package/dist/config/userChannels.js.map +1 -1
  179. package/dist/config/userConfig.d.ts +14 -9
  180. package/dist/config/userConfig.d.ts.map +1 -0
  181. package/dist/config/userConfig.js +87 -25
  182. package/dist/config/userConfig.js.map +1 -1
  183. package/dist/config/userProfiles.d.ts +10 -6
  184. package/dist/config/userProfiles.d.ts.map +1 -0
  185. package/dist/config/userProfiles.js +64 -39
  186. package/dist/config/userProfiles.js.map +1 -1
  187. package/dist/hdhr/channelMap.d.ts +1 -0
  188. package/dist/hdhr/channelMap.d.ts.map +1 -0
  189. package/dist/hdhr/deviceId.d.ts +1 -0
  190. package/dist/hdhr/deviceId.d.ts.map +1 -0
  191. package/dist/hdhr/discover.d.ts +1 -0
  192. package/dist/hdhr/discover.d.ts.map +1 -0
  193. package/dist/hdhr/discover.js +48 -47
  194. package/dist/hdhr/discover.js.map +1 -1
  195. package/dist/hdhr/getHandlers.d.ts +29 -0
  196. package/dist/hdhr/getHandlers.d.ts.map +1 -0
  197. package/dist/hdhr/getHandlers.js +196 -0
  198. package/dist/hdhr/getHandlers.js.map +1 -0
  199. package/dist/hdhr/identity.d.ts +36 -0
  200. package/dist/hdhr/identity.d.ts.map +1 -0
  201. package/dist/hdhr/identity.js +51 -0
  202. package/dist/hdhr/identity.js.map +1 -0
  203. package/dist/hdhr/index.d.ts +22 -4
  204. package/dist/hdhr/index.d.ts.map +1 -0
  205. package/dist/hdhr/index.js +229 -54
  206. package/dist/hdhr/index.js.map +1 -1
  207. package/dist/hdhr/protocol.d.ts +75 -0
  208. package/dist/hdhr/protocol.d.ts.map +1 -0
  209. package/dist/hdhr/protocol.js +264 -0
  210. package/dist/hdhr/protocol.js.map +1 -0
  211. package/dist/hdhr/tunerState.d.ts +24 -0
  212. package/dist/hdhr/tunerState.d.ts.map +1 -0
  213. package/dist/hdhr/tunerState.js +67 -0
  214. package/dist/hdhr/tunerState.js.map +1 -0
  215. package/dist/hdhr/udp.d.ts +43 -0
  216. package/dist/hdhr/udp.d.ts.map +1 -0
  217. package/dist/hdhr/udp.js +277 -0
  218. package/dist/hdhr/udp.js.map +1 -0
  219. package/dist/identity.d.ts +1 -0
  220. package/dist/identity.d.ts.map +1 -0
  221. package/dist/identity.js +13 -11
  222. package/dist/identity.js.map +1 -1
  223. package/dist/index.d.ts +1 -0
  224. package/dist/index.d.ts.map +1 -0
  225. package/dist/index.js +11 -12
  226. package/dist/index.js.map +1 -1
  227. package/dist/native/codecInference.d.ts +1 -0
  228. package/dist/native/codecInference.d.ts.map +1 -0
  229. package/dist/native/codecInference.js +50 -5
  230. package/dist/native/codecInference.js.map +1 -1
  231. package/dist/native/decrypt.d.ts +6 -2
  232. package/dist/native/decrypt.d.ts.map +1 -0
  233. package/dist/native/decrypt.js +15 -8
  234. package/dist/native/decrypt.js.map +1 -1
  235. package/dist/native/index.d.ts +40 -17
  236. package/dist/native/index.d.ts.map +1 -0
  237. package/dist/native/index.js +281 -120
  238. package/dist/native/index.js.map +1 -1
  239. package/dist/native/probe.d.ts +114 -18
  240. package/dist/native/probe.d.ts.map +1 -0
  241. package/dist/native/probe.js +452 -115
  242. package/dist/native/probe.js.map +1 -1
  243. package/dist/native/proxy.d.ts +57 -5
  244. package/dist/native/proxy.d.ts.map +1 -0
  245. package/dist/native/proxy.js +604 -170
  246. package/dist/native/proxy.js.map +1 -1
  247. package/dist/native/tokenExpiry.d.ts +1 -0
  248. package/dist/native/tokenExpiry.d.ts.map +1 -0
  249. package/dist/native/tokenExpiry.js +1 -1
  250. package/dist/routes/assets.d.ts +1 -0
  251. package/dist/routes/assets.d.ts.map +1 -0
  252. package/dist/routes/assets.js +4 -2
  253. package/dist/routes/assets.js.map +1 -1
  254. package/dist/routes/auth.d.ts +1 -0
  255. package/dist/routes/auth.d.ts.map +1 -0
  256. package/dist/routes/auth.js +0 -1
  257. package/dist/routes/auth.js.map +1 -1
  258. package/dist/routes/cdp.d.ts +5 -5
  259. package/dist/routes/cdp.d.ts.map +1 -0
  260. package/dist/routes/cdp.js +59 -20
  261. package/dist/routes/cdp.js.map +1 -1
  262. package/dist/routes/channels.d.ts +1 -0
  263. package/dist/routes/channels.d.ts.map +1 -0
  264. package/dist/routes/channels.js +2 -1
  265. package/dist/routes/channels.js.map +1 -1
  266. package/dist/routes/clientActions.d.ts +98 -0
  267. package/dist/routes/clientActions.d.ts.map +1 -0
  268. package/dist/routes/clientActions.js +113 -0
  269. package/dist/routes/clientActions.js.map +1 -0
  270. package/dist/routes/components.d.ts +5 -3
  271. package/dist/routes/components.d.ts.map +1 -0
  272. package/dist/routes/components.js +36 -39
  273. package/dist/routes/components.js.map +1 -1
  274. package/dist/routes/config/channels/endpoints/browse.d.ts +1 -0
  275. package/dist/routes/config/channels/endpoints/browse.d.ts.map +1 -0
  276. package/dist/routes/config/channels/endpoints/browse.js +23 -10
  277. package/dist/routes/config/channels/endpoints/browse.js.map +1 -1
  278. package/dist/routes/config/channels/endpoints/bulk.d.ts +1 -0
  279. package/dist/routes/config/channels/endpoints/bulk.d.ts.map +1 -0
  280. package/dist/routes/config/channels/endpoints/bulk.js +5 -3
  281. package/dist/routes/config/channels/endpoints/bulk.js.map +1 -1
  282. package/dist/routes/config/channels/endpoints/crud.d.ts +1 -0
  283. package/dist/routes/config/channels/endpoints/crud.d.ts.map +1 -0
  284. package/dist/routes/config/channels/endpoints/crud.js +85 -93
  285. package/dist/routes/config/channels/endpoints/crud.js.map +1 -1
  286. package/dist/routes/config/channels/endpoints/importExport.d.ts +1 -0
  287. package/dist/routes/config/channels/endpoints/importExport.d.ts.map +1 -0
  288. package/dist/routes/config/channels/endpoints/importExport.js +6 -3
  289. package/dist/routes/config/channels/endpoints/importExport.js.map +1 -1
  290. package/dist/routes/config/channels/endpoints/predefined.d.ts +1 -0
  291. package/dist/routes/config/channels/endpoints/predefined.d.ts.map +1 -0
  292. package/dist/routes/config/channels/endpoints/prefs.d.ts +1 -0
  293. package/dist/routes/config/channels/endpoints/prefs.d.ts.map +1 -0
  294. package/dist/routes/config/channels/endpoints/prefs.js +2 -1
  295. package/dist/routes/config/channels/endpoints/prefs.js.map +1 -1
  296. package/dist/routes/config/channels/endpoints/service.d.ts +2 -1
  297. package/dist/routes/config/channels/endpoints/service.d.ts.map +1 -0
  298. package/dist/routes/config/channels/endpoints/service.js +3 -1
  299. package/dist/routes/config/channels/endpoints/service.js.map +1 -1
  300. package/dist/routes/config/channels/endpoints/tags.d.ts +1 -0
  301. package/dist/routes/config/channels/endpoints/tags.d.ts.map +1 -0
  302. package/dist/routes/config/channels/endpoints/tags.js +13 -7
  303. package/dist/routes/config/channels/endpoints/tags.js.map +1 -1
  304. package/dist/routes/config/channels/healthBridge.d.ts +24 -0
  305. package/dist/routes/config/channels/healthBridge.d.ts.map +1 -0
  306. package/dist/routes/config/channels/healthBridge.js +71 -0
  307. package/dist/routes/config/channels/healthBridge.js.map +1 -0
  308. package/dist/routes/config/channels/http/handler.d.ts +1 -0
  309. package/dist/routes/config/channels/http/handler.d.ts.map +1 -0
  310. package/dist/routes/config/channels/http/playlistHint.d.ts +2 -1
  311. package/dist/routes/config/channels/http/playlistHint.d.ts.map +1 -0
  312. package/dist/routes/config/channels/http/playlistHint.js +16 -2
  313. package/dist/routes/config/channels/http/playlistHint.js.map +1 -1
  314. package/dist/routes/config/channels/http/serviceWarning.d.ts +4 -2
  315. package/dist/routes/config/channels/http/serviceWarning.d.ts.map +1 -0
  316. package/dist/routes/config/channels/http/serviceWarning.js +3 -2
  317. package/dist/routes/config/channels/http/serviceWarning.js.map +1 -1
  318. package/dist/routes/config/channels/index.d.ts +1 -0
  319. package/dist/routes/config/channels/index.d.ts.map +1 -0
  320. package/dist/routes/config/channels/setup.d.ts +1 -0
  321. package/dist/routes/config/channels/setup.d.ts.map +1 -0
  322. package/dist/routes/config/channels/table.d.ts +3 -3
  323. package/dist/routes/config/channels/table.d.ts.map +1 -0
  324. package/dist/routes/config/channels/table.js +148 -107
  325. package/dist/routes/config/channels/table.js.map +1 -1
  326. package/dist/routes/config/http/envelope.d.ts +1 -0
  327. package/dist/routes/config/http/envelope.d.ts.map +1 -0
  328. package/dist/routes/config/index.d.ts +35 -3
  329. package/dist/routes/config/index.d.ts.map +1 -0
  330. package/dist/routes/config/index.js +51 -2
  331. package/dist/routes/config/index.js.map +1 -1
  332. package/dist/routes/config/services.d.ts +5 -4
  333. package/dist/routes/config/services.d.ts.map +1 -0
  334. package/dist/routes/config/services.js +57 -43
  335. package/dist/routes/config/services.js.map +1 -1
  336. package/dist/routes/config/settings.d.ts +1 -0
  337. package/dist/routes/config/settings.d.ts.map +1 -0
  338. package/dist/routes/config/settings.js +98 -49
  339. package/dist/routes/config/settings.js.map +1 -1
  340. package/dist/routes/debug.d.ts +1 -0
  341. package/dist/routes/debug.d.ts.map +1 -0
  342. package/dist/routes/debug.js +277 -139
  343. package/dist/routes/debug.js.map +1 -1
  344. package/dist/routes/health.d.ts +39 -1
  345. package/dist/routes/health.d.ts.map +1 -0
  346. package/dist/routes/health.js +33 -27
  347. package/dist/routes/health.js.map +1 -1
  348. package/dist/routes/hls.d.ts +1 -0
  349. package/dist/routes/hls.d.ts.map +1 -0
  350. package/dist/routes/icons.d.ts +1 -0
  351. package/dist/routes/icons.d.ts.map +1 -0
  352. package/dist/routes/icons.js +1 -1
  353. package/dist/routes/index.d.ts +1 -0
  354. package/dist/routes/index.d.ts.map +1 -0
  355. package/dist/routes/logs.d.ts +1 -0
  356. package/dist/routes/logs.d.ts.map +1 -0
  357. package/dist/routes/logs.js +14 -4
  358. package/dist/routes/logs.js.map +1 -1
  359. package/dist/routes/mpegts.d.ts +1 -0
  360. package/dist/routes/mpegts.d.ts.map +1 -0
  361. package/dist/routes/play.d.ts +1 -0
  362. package/dist/routes/play.d.ts.map +1 -0
  363. package/dist/routes/playlist.d.ts +1 -0
  364. package/dist/routes/playlist.d.ts.map +1 -0
  365. package/dist/routes/playlist.js +7 -2
  366. package/dist/routes/playlist.js.map +1 -1
  367. package/dist/routes/root/content.d.ts +8 -5
  368. package/dist/routes/root/content.d.ts.map +1 -0
  369. package/dist/routes/root/content.js +29 -26
  370. package/dist/routes/root/content.js.map +1 -1
  371. package/dist/routes/root/index.d.ts +2 -1
  372. package/dist/routes/root/index.d.ts.map +1 -0
  373. package/dist/routes/root/index.js +26 -21
  374. package/dist/routes/root/index.js.map +1 -1
  375. package/dist/routes/root/scripts/channels.d.ts +6 -0
  376. package/dist/routes/root/scripts/channels.d.ts.map +1 -0
  377. package/dist/routes/root/scripts/channels.js +197 -118
  378. package/dist/routes/root/scripts/channels.js.map +1 -1
  379. package/dist/routes/root/scripts/clientEscape.d.ts +22 -0
  380. package/dist/routes/root/scripts/clientEscape.d.ts.map +1 -0
  381. package/dist/routes/root/scripts/clientEscape.js +41 -0
  382. package/dist/routes/root/scripts/clientEscape.js.map +1 -0
  383. package/dist/routes/root/scripts/clientUrl.d.ts +23 -0
  384. package/dist/routes/root/scripts/clientUrl.d.ts.map +1 -0
  385. package/dist/routes/root/scripts/clientUrl.js +44 -0
  386. package/dist/routes/root/scripts/clientUrl.js.map +1 -0
  387. package/dist/routes/root/scripts/config.d.ts +6 -0
  388. package/dist/routes/root/scripts/config.d.ts.map +1 -0
  389. package/dist/routes/root/scripts/config.js +110 -24
  390. package/dist/routes/root/scripts/config.js.map +1 -1
  391. package/dist/routes/root/scripts/index.d.ts +1 -0
  392. package/dist/routes/root/scripts/index.d.ts.map +1 -0
  393. package/dist/routes/root/scripts/shared.d.ts +1 -0
  394. package/dist/routes/root/scripts/shared.d.ts.map +1 -0
  395. package/dist/routes/root/scripts/shared.js +112 -26
  396. package/dist/routes/root/scripts/shared.js.map +1 -1
  397. package/dist/routes/root/scripts/status.d.ts +1 -0
  398. package/dist/routes/root/scripts/status.d.ts.map +1 -0
  399. package/dist/routes/root/scripts/status.handlers.d.ts +23 -33
  400. package/dist/routes/root/scripts/status.handlers.d.ts.map +1 -0
  401. package/dist/routes/root/scripts/status.handlers.js +46 -92
  402. package/dist/routes/root/scripts/status.handlers.js.map +1 -1
  403. package/dist/routes/root/scripts/status.js +21 -8
  404. package/dist/routes/root/scripts/status.js.map +1 -1
  405. package/dist/routes/root/styles.d.ts +1 -0
  406. package/dist/routes/root/styles.d.ts.map +1 -0
  407. package/dist/routes/root/styles.js +7 -4
  408. package/dist/routes/root/styles.js.map +1 -1
  409. package/dist/routes/services.d.ts +13 -1
  410. package/dist/routes/services.d.ts.map +1 -0
  411. package/dist/routes/services.js +81 -68
  412. package/dist/routes/services.js.map +1 -1
  413. package/dist/routes/sse.d.ts +1 -0
  414. package/dist/routes/sse.d.ts.map +1 -0
  415. package/dist/routes/sse.js +1 -1
  416. package/dist/routes/sse.js.map +1 -1
  417. package/dist/routes/streams.d.ts +2 -1
  418. package/dist/routes/streams.d.ts.map +1 -0
  419. package/dist/routes/streams.js +6 -4
  420. package/dist/routes/streams.js.map +1 -1
  421. package/dist/routes/theme.d.ts +3 -2
  422. package/dist/routes/theme.d.ts.map +1 -0
  423. package/dist/routes/theme.js +6 -5
  424. package/dist/routes/theme.js.map +1 -1
  425. package/dist/routes/ui.d.ts +3 -1
  426. package/dist/routes/ui.d.ts.map +1 -0
  427. package/dist/routes/ui.js +16 -4
  428. package/dist/routes/ui.js.map +1 -1
  429. package/dist/routes/upgrade.d.ts +1 -0
  430. package/dist/routes/upgrade.d.ts.map +1 -0
  431. package/dist/routes/upgrade.js +6 -2
  432. package/dist/routes/upgrade.js.map +1 -1
  433. package/dist/service/commands.context.d.ts +1 -0
  434. package/dist/service/commands.context.d.ts.map +1 -0
  435. package/dist/service/commands.context.js +4 -3
  436. package/dist/service/commands.context.js.map +1 -1
  437. package/dist/service/commands.d.ts +1 -0
  438. package/dist/service/commands.d.ts.map +1 -0
  439. package/dist/service/commands.js +10 -13
  440. package/dist/service/commands.js.map +1 -1
  441. package/dist/service/generators.context.d.ts +1 -0
  442. package/dist/service/generators.context.d.ts.map +1 -0
  443. package/dist/service/generators.context.js +1 -1
  444. package/dist/service/generators.context.js.map +1 -1
  445. package/dist/service/generators.d.ts +4 -3
  446. package/dist/service/generators.d.ts.map +1 -0
  447. package/dist/service/generators.js +111 -31
  448. package/dist/service/generators.js.map +1 -1
  449. package/dist/service/index.d.ts +1 -0
  450. package/dist/service/index.d.ts.map +1 -0
  451. package/dist/streaming/captureLock.d.ts +44 -0
  452. package/dist/streaming/captureLock.d.ts.map +1 -0
  453. package/dist/streaming/captureLock.js +95 -0
  454. package/dist/streaming/captureLock.js.map +1 -0
  455. package/dist/streaming/captureSession.d.ts +31 -0
  456. package/dist/streaming/captureSession.d.ts.map +1 -0
  457. package/dist/streaming/captureSession.js +54 -0
  458. package/dist/streaming/captureSession.js.map +1 -0
  459. package/dist/streaming/clients.d.ts +1 -0
  460. package/dist/streaming/clients.d.ts.map +1 -0
  461. package/dist/streaming/codec.d.ts +1 -0
  462. package/dist/streaming/codec.d.ts.map +1 -0
  463. package/dist/streaming/fmp4Segmenter.d.ts +29 -2
  464. package/dist/streaming/fmp4Segmenter.d.ts.map +1 -0
  465. package/dist/streaming/fmp4Segmenter.js +79 -26
  466. package/dist/streaming/fmp4Segmenter.js.map +1 -1
  467. package/dist/streaming/hls.d.ts +18 -7
  468. package/dist/streaming/hls.d.ts.map +1 -0
  469. package/dist/streaming/hls.js +220 -120
  470. package/dist/streaming/hls.js.map +1 -1
  471. package/dist/streaming/hlsResume.d.ts +1 -0
  472. package/dist/streaming/hlsResume.d.ts.map +1 -0
  473. package/dist/streaming/hlsResume.js +1 -1
  474. package/dist/streaming/hlsResume.js.map +1 -1
  475. package/dist/streaming/hlsSegments.d.ts +59 -2
  476. package/dist/streaming/hlsSegments.d.ts.map +1 -0
  477. package/dist/streaming/hlsSegments.js +147 -17
  478. package/dist/streaming/hlsSegments.js.map +1 -1
  479. package/dist/streaming/lifecycle.d.ts +4 -1
  480. package/dist/streaming/lifecycle.d.ts.map +1 -0
  481. package/dist/streaming/lifecycle.js +65 -85
  482. package/dist/streaming/lifecycle.js.map +1 -1
  483. package/dist/streaming/monitor.d.ts +6 -4
  484. package/dist/streaming/monitor.d.ts.map +1 -0
  485. package/dist/streaming/monitor.js +343 -145
  486. package/dist/streaming/monitor.js.map +1 -1
  487. package/dist/streaming/mp4Parser.d.ts +5 -4
  488. package/dist/streaming/mp4Parser.d.ts.map +1 -0
  489. package/dist/streaming/mp4Parser.js +36 -13
  490. package/dist/streaming/mp4Parser.js.map +1 -1
  491. package/dist/streaming/mpegts.d.ts +16 -0
  492. package/dist/streaming/mpegts.d.ts.map +1 -0
  493. package/dist/streaming/mpegts.js +61 -17
  494. package/dist/streaming/mpegts.js.map +1 -1
  495. package/dist/streaming/playlistBuilder.d.ts +1 -0
  496. package/dist/streaming/playlistBuilder.d.ts.map +1 -0
  497. package/dist/streaming/preroll.d.ts +32 -5
  498. package/dist/streaming/preroll.d.ts.map +1 -0
  499. package/dist/streaming/preroll.js +70 -32
  500. package/dist/streaming/preroll.js.map +1 -1
  501. package/dist/streaming/pretune.d.ts +26 -1
  502. package/dist/streaming/pretune.d.ts.map +1 -0
  503. package/dist/streaming/pretune.js +22 -24
  504. package/dist/streaming/pretune.js.map +1 -1
  505. package/dist/streaming/pretuneTimers.d.ts +24 -0
  506. package/dist/streaming/pretuneTimers.d.ts.map +1 -0
  507. package/dist/streaming/pretuneTimers.js +56 -0
  508. package/dist/streaming/pretuneTimers.js.map +1 -0
  509. package/dist/streaming/recovery.d.ts +139 -5
  510. package/dist/streaming/recovery.d.ts.map +1 -0
  511. package/dist/streaming/recovery.js +160 -16
  512. package/dist/streaming/recovery.js.map +1 -1
  513. package/dist/streaming/registry.d.ts +27 -9
  514. package/dist/streaming/registry.d.ts.map +1 -0
  515. package/dist/streaming/registry.js +21 -3
  516. package/dist/streaming/registry.js.map +1 -1
  517. package/dist/streaming/setup.d.ts +157 -29
  518. package/dist/streaming/setup.d.ts.map +1 -0
  519. package/dist/streaming/setup.js +1034 -458
  520. package/dist/streaming/setup.js.map +1 -1
  521. package/dist/streaming/showInfo.d.ts +21 -1
  522. package/dist/streaming/showInfo.d.ts.map +1 -0
  523. package/dist/streaming/showInfo.js +31 -16
  524. package/dist/streaming/showInfo.js.map +1 -1
  525. package/dist/streaming/statusEmitter.d.ts +10 -10
  526. package/dist/streaming/statusEmitter.d.ts.map +1 -0
  527. package/dist/streaming/statusEmitter.js +5 -8
  528. package/dist/streaming/statusEmitter.js.map +1 -1
  529. package/dist/types/channels.d.ts +16 -4
  530. package/dist/types/channels.d.ts.map +1 -0
  531. package/dist/types/channels.js +4 -2
  532. package/dist/types/channels.js.map +1 -1
  533. package/dist/types/config.d.ts +16 -5
  534. package/dist/types/config.d.ts.map +1 -0
  535. package/dist/types/index.d.ts +3 -2
  536. package/dist/types/index.d.ts.map +1 -0
  537. package/dist/types/profiles.d.ts +6 -4
  538. package/dist/types/profiles.d.ts.map +1 -0
  539. package/dist/types/selection.d.ts +31 -3
  540. package/dist/types/selection.d.ts.map +1 -0
  541. package/dist/types/selection.js +4 -2
  542. package/dist/types/selection.js.map +1 -1
  543. package/dist/types/shared.d.ts +1 -0
  544. package/dist/types/shared.d.ts.map +1 -0
  545. package/dist/types/streaming.d.ts +8 -0
  546. package/dist/types/streaming.d.ts.map +1 -0
  547. package/dist/upgrade/commands.context.d.ts +1 -0
  548. package/dist/upgrade/commands.context.d.ts.map +1 -0
  549. package/dist/upgrade/commands.context.js +14 -10
  550. package/dist/upgrade/commands.context.js.map +1 -1
  551. package/dist/upgrade/commands.d.ts +8 -15
  552. package/dist/upgrade/commands.d.ts.map +1 -0
  553. package/dist/upgrade/commands.js +27 -28
  554. package/dist/upgrade/commands.js.map +1 -1
  555. package/dist/upgrade/detection.context.d.ts +1 -0
  556. package/dist/upgrade/detection.context.d.ts.map +1 -0
  557. package/dist/upgrade/detection.context.js +4 -1
  558. package/dist/upgrade/detection.context.js.map +1 -1
  559. package/dist/upgrade/detection.d.ts +9 -7
  560. package/dist/upgrade/detection.d.ts.map +1 -0
  561. package/dist/upgrade/detection.js +23 -54
  562. package/dist/upgrade/detection.js.map +1 -1
  563. package/dist/upgrade/index.d.ts +2 -0
  564. package/dist/upgrade/index.d.ts.map +1 -0
  565. package/dist/upgrade/index.js +1 -0
  566. package/dist/upgrade/index.js.map +1 -1
  567. package/dist/upgrade/lifecycle.context.d.ts +20 -0
  568. package/dist/upgrade/lifecycle.context.d.ts.map +1 -0
  569. package/dist/upgrade/lifecycle.context.js +47 -0
  570. package/dist/upgrade/lifecycle.context.js.map +1 -0
  571. package/dist/upgrade/lifecycle.d.ts +72 -0
  572. package/dist/upgrade/lifecycle.d.ts.map +1 -0
  573. package/dist/upgrade/lifecycle.js +175 -0
  574. package/dist/upgrade/lifecycle.js.map +1 -0
  575. package/dist/upgrade/pathHandle.d.ts +30 -0
  576. package/dist/upgrade/pathHandle.d.ts.map +1 -0
  577. package/dist/upgrade/pathHandle.js +102 -0
  578. package/dist/upgrade/pathHandle.js.map +1 -0
  579. package/dist/utils/bootSession.context.d.ts +16 -0
  580. package/dist/utils/bootSession.context.d.ts.map +1 -0
  581. package/dist/utils/bootSession.context.js +60 -0
  582. package/dist/utils/bootSession.context.js.map +1 -0
  583. package/dist/utils/bootSession.d.ts +17 -0
  584. package/dist/utils/bootSession.d.ts.map +1 -0
  585. package/dist/utils/bootSession.js +20 -0
  586. package/dist/utils/bootSession.js.map +1 -0
  587. package/dist/utils/chromeFetch.d.ts +1 -0
  588. package/dist/utils/chromeFetch.d.ts.map +1 -0
  589. package/dist/utils/cliOutput.d.ts +1 -0
  590. package/dist/utils/cliOutput.d.ts.map +1 -0
  591. package/dist/utils/clock.d.ts +5 -4
  592. package/dist/utils/clock.d.ts.map +1 -0
  593. package/dist/utils/clock.js +19 -16
  594. package/dist/utils/clock.js.map +1 -1
  595. package/dist/utils/debugFilter.d.ts +9 -1
  596. package/dist/utils/debugFilter.d.ts.map +1 -0
  597. package/dist/utils/debugFilter.js +60 -33
  598. package/dist/utils/debugFilter.js.map +1 -1
  599. package/dist/utils/delay.d.ts +48 -15
  600. package/dist/utils/delay.d.ts.map +1 -0
  601. package/dist/utils/delay.js +73 -20
  602. package/dist/utils/delay.js.map +1 -1
  603. package/dist/utils/errors.d.ts +32 -0
  604. package/dist/utils/errors.d.ts.map +1 -0
  605. package/dist/utils/errors.js +45 -4
  606. package/dist/utils/errors.js.map +1 -1
  607. package/dist/utils/evaluate.d.ts +1 -0
  608. package/dist/utils/evaluate.d.ts.map +1 -0
  609. package/dist/utils/evaluate.js +29 -23
  610. package/dist/utils/evaluate.js.map +1 -1
  611. package/dist/utils/ffmpeg.context.d.ts +1 -0
  612. package/dist/utils/ffmpeg.context.d.ts.map +1 -0
  613. package/dist/utils/ffmpeg.context.js.map +1 -1
  614. package/dist/utils/ffmpeg.d.ts +29 -7
  615. package/dist/utils/ffmpeg.d.ts.map +1 -0
  616. package/dist/utils/ffmpeg.js +32 -14
  617. package/dist/utils/ffmpeg.js.map +1 -1
  618. package/dist/utils/fileLogger.d.ts +3 -1
  619. package/dist/utils/fileLogger.d.ts.map +1 -0
  620. package/dist/utils/fileLogger.js +64 -29
  621. package/dist/utils/fileLogger.js.map +1 -1
  622. package/dist/utils/format.d.ts +14 -1
  623. package/dist/utils/format.d.ts.map +1 -0
  624. package/dist/utils/format.js +19 -5
  625. package/dist/utils/format.js.map +1 -1
  626. package/dist/utils/index.d.ts +4 -0
  627. package/dist/utils/index.d.ts.map +1 -0
  628. package/dist/utils/index.js +3 -0
  629. package/dist/utils/index.js.map +1 -1
  630. package/dist/utils/logEmitter.d.ts +1 -0
  631. package/dist/utils/logEmitter.d.ts.map +1 -0
  632. package/dist/utils/logger.d.ts +1 -0
  633. package/dist/utils/logger.d.ts.map +1 -0
  634. package/dist/utils/logger.js +10 -6
  635. package/dist/utils/logger.js.map +1 -1
  636. package/dist/utils/m3u.d.ts +3 -2
  637. package/dist/utils/m3u.d.ts.map +1 -0
  638. package/dist/utils/m3u.js +4 -3
  639. package/dist/utils/m3u.js.map +1 -1
  640. package/dist/utils/markup.d.ts +13 -1
  641. package/dist/utils/markup.d.ts.map +1 -0
  642. package/dist/utils/markup.js +28 -4
  643. package/dist/utils/markup.js.map +1 -1
  644. package/dist/utils/memo.d.ts +3 -2
  645. package/dist/utils/memo.d.ts.map +1 -0
  646. package/dist/utils/memo.js +3 -3
  647. package/dist/utils/morganStream.d.ts +1 -0
  648. package/dist/utils/morganStream.d.ts.map +1 -0
  649. package/dist/utils/network.d.ts +1 -0
  650. package/dist/utils/network.d.ts.map +1 -0
  651. package/dist/utils/network.js +2 -2
  652. package/dist/utils/pid.d.ts +3 -25
  653. package/dist/utils/pid.d.ts.map +1 -0
  654. package/dist/utils/pid.js +10 -49
  655. package/dist/utils/pid.js.map +1 -1
  656. package/dist/utils/platform.d.ts +3 -1
  657. package/dist/utils/platform.d.ts.map +1 -0
  658. package/dist/utils/platform.js +2 -1
  659. package/dist/utils/platform.js.map +1 -1
  660. package/dist/utils/processInspector.context.d.ts +8 -0
  661. package/dist/utils/processInspector.context.d.ts.map +1 -0
  662. package/dist/utils/processInspector.context.js +106 -0
  663. package/dist/utils/processInspector.context.js.map +1 -0
  664. package/dist/utils/processInspector.d.ts +55 -0
  665. package/dist/utils/processInspector.d.ts.map +1 -0
  666. package/dist/utils/processInspector.js +127 -0
  667. package/dist/utils/processInspector.js.map +1 -0
  668. package/dist/utils/retry.d.ts +25 -2
  669. package/dist/utils/retry.d.ts.map +1 -0
  670. package/dist/utils/retry.js +33 -6
  671. package/dist/utils/retry.js.map +1 -1
  672. package/dist/utils/runtimeIdentity.context.d.ts +7 -0
  673. package/dist/utils/runtimeIdentity.context.d.ts.map +1 -0
  674. package/dist/utils/runtimeIdentity.context.js +43 -0
  675. package/dist/utils/runtimeIdentity.context.js.map +1 -0
  676. package/dist/utils/runtimeIdentity.d.ts +98 -0
  677. package/dist/utils/runtimeIdentity.d.ts.map +1 -0
  678. package/dist/utils/runtimeIdentity.js +181 -0
  679. package/dist/utils/runtimeIdentity.js.map +1 -0
  680. package/dist/utils/sanitize.d.ts +1 -0
  681. package/dist/utils/sanitize.d.ts.map +1 -0
  682. package/dist/utils/streamContext.d.ts +2 -1
  683. package/dist/utils/streamContext.d.ts.map +1 -0
  684. package/dist/utils/streamContext.js +1 -1
  685. package/dist/utils/timing.d.ts +2 -1
  686. package/dist/utils/timing.d.ts.map +1 -0
  687. package/dist/utils/timing.js +0 -5
  688. package/dist/utils/timing.js.map +1 -1
  689. package/dist/utils/version.d.ts +1 -0
  690. package/dist/utils/version.d.ts.map +1 -0
  691. package/dist/utils/version.js +47 -13
  692. package/dist/utils/version.js.map +1 -1
  693. package/package.json +26 -20
@@ -1,9 +1,11 @@
1
- import { DEFAULTS, mergeConfiguration, readConfig } from "./userConfig.js";
2
- import { LOG, displayLine, getCurrentPattern, getPackageVersion, initDebugFilter, isAnyDebugEnabled } from "../utils/index.js";
1
+ import { DEFAULTS, mergeConfiguration, mutateConfig, readConfig } from "./userConfig.js";
2
+ import { LOG, canonicalizeDebugPattern, displayLine, formatError, getCurrentPattern, getPackageVersion, initDebugFilter, isAnyDebugEnabled } from "../utils/index.js";
3
+ import { applyConfigChanges, computeConfigDiff, registerConfigChangeHandler } from "./reactivity.js";
3
4
  import { formatPresetStatus, getEffectivePreset, getValidPresetIds } from "./presets.js";
4
5
  import { getChromeDataDir, getConfigFilePath } from "./paths.js";
5
6
  import { RECOGNIZED_CODECS } from "../types/index.js";
6
7
  import path from "node:path";
8
+ const defaultConfigStore = { mutateConfig, readConfig };
7
9
  // The CONFIG object is initialized during startup. It starts as a copy of DEFAULTS and is replaced by the merged configuration.
8
10
  export let CONFIG = structuredClone(DEFAULTS);
9
11
  /**
@@ -14,38 +16,194 @@ export let configParseError = false;
14
16
  * The parse error message if configParseError is true.
15
17
  */
16
18
  export let configParseErrorMessage;
19
+ // Stashed CLI overrides from the most recent initializeConfiguration call. reloadConfiguration re-applies them so the priority chain (CLI > env > user > defaults)
20
+ // stays consistent across reloads. CLI overrides are a startup-only concern in practice; capturing them once and replaying them avoids losing the binding when a
21
+ // live reload runs in a process where the operator originally passed --port or --chrome-data-dir. The --data-dir flag is resolved separately, before
22
+ // configuration loads, and never flows through this stash.
23
+ let stashedCliOverrides;
24
+ // Whether a higher-priority debug source (the PRISMCAST_DEBUG env var or the --debug CLI flag) established the active debug filter before the persisted config
25
+ // filter was first applied. Captured once in initializeConfiguration, ahead of the persisted filter, so a later reloadConfiguration can re-apply a changed
26
+ // persisted filter live without ever clobbering an env/CLI override - that override must win for the entire process lifetime.
27
+ let envOrCliDebugOverride = false;
28
+ /* Serialization queue for reloadConfiguration. Each call chains onto the previous one, so overlapping reloads read and commit in call order. Without it, two
29
+ * concurrent save-then-reload requests can interleave such that the reload holding the older disk snapshot commits last, leaving the live binding on a state
30
+ * the user already replaced.
31
+ */
32
+ let reloadQueue = Promise.resolve();
33
+ // Whether validateConfiguration coerced a capture setting (forced FFmpeg mode, normalized captureCodecs) on the live CONFIG at startup. persistCoercedConfig
34
+ // reads this to decide whether to write the coerced values back to disk so the on-disk state matches the live binding. Without the write-back a config file
35
+ // holding an unsupported capture value (native mode) stays divergent from the coerced CONFIG forever, and the reload-validation path would then reject every
36
+ // later save on the resulting phantom capture diff.
37
+ let captureConfigCoercedAtStartup = false;
17
38
  /**
18
39
  * Initializes the configuration by loading the user config file, merging with defaults, applying environment variable overrides, and applying CLI overrides. This
19
40
  * must be called at startup before any code accesses CONFIG. After initialization, the CONFIG object contains the final merged values.
20
41
  * @param cliOverrides - Optional CLI flag overrides, applied at the highest priority level.
21
42
  */
22
- export async function initializeConfiguration(cliOverrides) {
43
+ export async function initializeConfiguration(cliOverrides, io = defaultConfigStore) {
23
44
  // Load user configuration from file. Schema migrations (legacy provider field renames, foxcom -> foxone in enabledServices) run automatically inside the
24
45
  // file store framework via the declarative configMigrations registry; ensureMigrated (called by the release boot coordinator at startup) persists any
25
46
  // upgrades to disk before this function runs. The data returned here is always at CURRENT_CONFIG_SCHEMA_VERSION.
26
- const result = await readConfig();
47
+ const result = await io.readConfig();
27
48
  configParseError = result.parseError;
28
49
  configParseErrorMessage = result.parseErrorMessage;
50
+ stashedCliOverrides = cliOverrides;
29
51
  if (result.recoveredFromBackup) {
30
52
  LOG.info("Configuration was recovered from backup after a corrupt main file.");
31
53
  }
32
- // Merge defaults, user config, environment variables, and CLI overrides.
54
+ // Capture whether a higher-priority debug source (PRISMCAST_DEBUG / --debug) already owns the active filter before we apply the persisted config filter, so a
55
+ // later reload can re-apply a changed persisted filter live without overriding env/CLI. Measured here, ahead of normalizeConfig/commitDebugFilter, it reflects
56
+ // env/CLI alone rather than the persisted filter applying to itself.
57
+ envOrCliDebugOverride = isAnyDebugEnabled();
58
+ // Merge defaults, user config, environment variables, and CLI overrides, then run the same post-merge normalization reload replays, and commit the persisted
59
+ // debug filter to the runtime. The two steps are kept separate so reload can normalize a candidate config without applying its filter until it is committed.
33
60
  CONFIG = mergeConfiguration(result.config, cliOverrides);
34
- // Apply persisted debug filter from config.json if no higher-priority source is active. The PRISMCAST_DEBUG env var and --debug CLI flag both call
35
- // initDebugFilter() before startServer() calls initializeConfiguration(), so isAnyDebugEnabled() is already true when either is set.
36
- if (!isAnyDebugEnabled() && (CONFIG.logging.debugFilter.length > 0)) {
37
- initDebugFilter(CONFIG.logging.debugFilter);
38
- // Normalize the in-memory value to the canonical form. The stored value may have extra whitespace around commas (e.g., "tuning:hulu, recovery") which
39
- // initDebugFilter strips during parsing. Keeping CONFIG in sync with getCurrentPattern() ensures comparisons elsewhere are reliable.
40
- CONFIG.logging.debugFilter = getCurrentPattern();
61
+ normalizeConfig(CONFIG);
62
+ commitDebugFilter();
63
+ LOG.info("Configuration initialized from defaults, user config, environment variables, and CLI overrides.");
64
+ }
65
+ /**
66
+ * Re-reads the user config file, re-merges with the original CLI overrides, applies post-merge normalizations, commits the result to the in-memory CONFIG
67
+ * binding, and dispatches the resulting diff to registered config-change handlers. This is the single entry point for "config changed - tell subsystems"; both
68
+ * the /config save handler and /config/import handler call it after writing to disk. The returned ApplyResult partitions the diff into changes that were
69
+ * applied live, deferred (requiring restart), or rejected (refused by a handler). Callers use the deferred count to decide whether to schedule a restart.
70
+ *
71
+ * Atomicity contract: failures during the read, merge, or normalize steps leave CONFIG completely untouched - the function builds the new shape in isolation
72
+ * and only reassigns the live binding after all of those steps succeed. Failures DURING handler dispatch, however, occur after the CONFIG reassignment: CONFIG
73
+ * already reflects the new on-disk state, but the handler chain may have run partway. The conservative answer is that handlers must not throw; they should
74
+ * report outcomes (including "rejected") instead. That atomicity-on-read behavior is exercised by index.reload.test.ts.
75
+ *
76
+ * Validation contract: before committing, the merged shape is re-checked against the same hard-error and capture-coercion checks the startup path enforces.
77
+ * A configuration that carries a hard error (out-of-range numeric, non-absolute path, conflicting HDHR port) or would need a capture coercion (native mode, a
78
+ * captureCodecs list missing the h264 baseline) is rejected rather than silently coerced: CONFIG stays on the previous valid state and every diffed change is
79
+ * reported as rejected so the operator sees why nothing took effect. This closes the window where a live save could commit an un-normalized capture
80
+ * configuration into the live binding without passing through validateConfiguration. The reject-on-invalid path is exercised by index.reload.test.ts.
81
+ *
82
+ * Serialization contract: calls are serialized on a module-level queue, so overlapping reloads read and commit in call order and the last reload to run always
83
+ * reads a snapshot at least as fresh as every write that preceded its call. A failed reload rejects to its own caller without breaking the chain for later
84
+ * ones. This extends the handler contract: a registered config-change handler must never call reloadConfiguration, because a queued reload awaiting a nested
85
+ * reload would deadlock the chain.
86
+ * @returns The aggregate result of dispatching the diff.
87
+ */
88
+ export async function reloadConfiguration(io = defaultConfigStore) {
89
+ const operation = reloadQueue.then(async () => doReloadConfiguration(io));
90
+ // Swallow errors on the chain reference so future reloads can proceed. The error still propagates to the caller via the returned promise.
91
+ // eslint-disable-next-line @typescript-eslint/no-empty-function -- Intentional no-op: errors are propagated to the caller via the returned promise.
92
+ reloadQueue = operation.catch(() => { });
93
+ return operation;
94
+ }
95
+ /**
96
+ * Executes one reload: read, merge, normalize, diff, validate, commit, dispatch. Called only through the queue in reloadConfiguration, which is what makes the
97
+ * read-to-commit sequence below atomic with respect to other reloads.
98
+ * @param io - The config store to read through.
99
+ * @returns The aggregate result of dispatching the diff.
100
+ */
101
+ async function doReloadConfiguration(io) {
102
+ // Re-read the on-disk config snapshot that mutateConfig just wrote, then build the new in-memory shape in isolation so normalizations do not mutate the
103
+ // previous snapshot before the diff is computed.
104
+ const result = await io.readConfig();
105
+ configParseError = result.parseError;
106
+ configParseErrorMessage = result.parseErrorMessage;
107
+ const nextConfig = mergeConfiguration(result.config, stashedCliOverrides);
108
+ // Normalize the candidate in place WITHOUT any global side effects (no runtime debug-filter change). The live debug filter is applied by commitDebugFilter
109
+ // only after this reload is known to be committed, so a rejected reload below never touches the running filter.
110
+ normalizeConfig(nextConfig);
111
+ // Compute the diff between the prior CONFIG and the freshly merged one before any reassignment. Reassignment is safe because ESM exports are live bindings -
112
+ // every import { CONFIG } reads through the binding at access time, so there is no stale-reference window.
113
+ const diff = computeConfigDiff(CONFIG, nextConfig);
114
+ // Re-validate the merged shape against the same hard-error and capture-coercion checks the startup path enforces. When it cannot be committed safely, leave
115
+ // CONFIG untouched and report every diffed change as rejected with the joined reason - the save was persisted to disk by the caller, but the live binding
116
+ // stays on the previous valid state until the operator corrects the source. The diff.length guard avoids fabricating rejected entries when there is nothing
117
+ // to apply (an empty diff cannot carry a regression).
118
+ const rejection = collectReloadRejection(nextConfig);
119
+ if ((diff.length > 0) && (rejection !== null)) {
120
+ const applyResult = { applied: [], deferred: [], rejected: diff.map((change) => ({ change, reason: rejection })) };
121
+ LOG.warn("Configuration reload rejected; the saved configuration violates an invariant and was not applied live.", { reason: rejection });
122
+ logReloadOutcome(diff, applyResult);
123
+ return applyResult;
124
+ }
125
+ CONFIG = nextConfig;
126
+ // Now that the new configuration is committed, apply its persisted debug filter to the live runtime. Kept out of normalizeConfig so the rejected path above
127
+ // can never change the running filter.
128
+ commitDebugFilter();
129
+ const applyResult = await applyConfigChanges(diff);
130
+ logReloadOutcome(diff, applyResult);
131
+ return applyResult;
132
+ }
133
+ /**
134
+ * Normalizes a configuration in place WITHOUT any global side effects: clamps an out-of-vocabulary quality preset to the default and rewrites the persisted
135
+ * debug-filter string to its canonical form. Pure with respect to process state - it touches only the passed config - so it is safe to run on a candidate
136
+ * nextConfig before reload decides whether to commit it. Shared by initializeConfiguration and reloadConfiguration so the two paths cannot drift. The live
137
+ * runtime debug filter is applied separately by commitDebugFilter, which runs only once a configuration is committed, so a rejected reload never changes the
138
+ * running filter.
139
+ * @param config - The freshly merged configuration to normalize in place.
140
+ */
141
+ function normalizeConfig(config) {
142
+ // Canonicalize the persisted debug-filter string (trim whitespace around commas, collapse duplicates) unless a higher-priority env/CLI source owns the filter.
143
+ // This keeps the committed CONFIG and the computed diff working with canonical values and avoids a phantom whitespace-only diff; it does NOT touch the runtime
144
+ // filter - commitDebugFilter performs that side effect after a configuration is committed.
145
+ if (!envOrCliDebugOverride) {
146
+ config.logging.debugFilter = canonicalizeDebugPattern(config.logging.debugFilter);
41
147
  }
42
- // Validate quality preset. Viewport is derived on-demand via getViewport() rather than stored in CONFIG.
148
+ // Validate quality preset. Viewport is derived on-demand via getPresetViewport() rather than stored in CONFIG.
43
149
  const validPresets = getValidPresetIds();
44
- if (!validPresets.includes(CONFIG.streaming.qualityPreset)) {
45
- LOG.warn("Invalid quality preset '%s'. Using default '%s'.", CONFIG.streaming.qualityPreset, DEFAULTS.streaming.qualityPreset);
46
- CONFIG.streaming.qualityPreset = DEFAULTS.streaming.qualityPreset;
150
+ if (!validPresets.includes(config.streaming.qualityPreset)) {
151
+ LOG.warn("Invalid quality preset '%s'. Using default '%s'.", config.streaming.qualityPreset, DEFAULTS.streaming.qualityPreset);
152
+ config.streaming.qualityPreset = DEFAULTS.streaming.qualityPreset;
47
153
  }
48
- LOG.info("Configuration initialized from defaults, user config, environment variables, and CLI overrides.");
154
+ }
155
+ /**
156
+ * Applies the committed CONFIG's persisted debug filter to the live runtime filter, when no higher-priority env/CLI source owns it and the canonical value
157
+ * differs from what is currently active. This is the global side effect split out of normalizeConfig: it runs only after a configuration is committed (at
158
+ * startup, and on a reload that passed validation), so a rejected reload leaves the running filter untouched. Re-applying a changed persisted filter here is
159
+ * what lets a debug-filter change delivered via /config/import take effect live instead of waiting for a restart; an emptied persisted filter clears the runtime
160
+ * filter the same way (initDebugFilter("") disables it).
161
+ */
162
+ function commitDebugFilter() {
163
+ if (!envOrCliDebugOverride && (CONFIG.logging.debugFilter !== getCurrentPattern())) {
164
+ initDebugFilter(CONFIG.logging.debugFilter);
165
+ }
166
+ }
167
+ /**
168
+ * Live-applies the "logging." subset of a config diff. The debug filter is applied live by commitDebugFilter during reloadConfiguration - the runtime filter is
169
+ * updated right after CONFIG is committed and before the diff dispatches - so it reports applied with no restart, which is what lets a debug-filter change take
170
+ * effect immediately instead of waiting for one. The remaining logging fields (httpLogLevel, maxSize) are consumed when the logger and HTTP middleware are wired
171
+ * at startup, so they defer to a restart.
172
+ *
173
+ * Exported so tests can invoke the dispatch directly with a synthetic diff. Registered with the reactivity primitive at module load (side effect below).
174
+ * @param changes - The subset of the diff whose path begins with "logging.".
175
+ * @returns Per-change outcomes.
176
+ */
177
+ // The ConfigChangeHandler contract is async (handlers that do real work, like the HDHomeRun handler, await it), but this handler's classification is purely
178
+ // synchronous - there is nothing to await. We keep the async signature so every handler reads the same way and conforms to the type directly.
179
+ export async function applyLoggingConfigChanges(changes) {
180
+ return changes.map((change) => {
181
+ if (change.path === "logging.debugFilter") {
182
+ return { kind: "applied", path: change.path };
183
+ }
184
+ return { kind: "deferred", path: change.path, reason: "this logging setting takes effect on the next restart" };
185
+ });
186
+ }
187
+ // Module-load side effect: register the logging live-apply handler once per process so a debug-filter change that commitDebugFilter already applied live
188
+ // does not also trigger a redundant restart. ESM modules load at most once per process, so this runs deterministically at boot before any settings save can fire.
189
+ // Tests that reset the reactivity registry can re-register by calling registerConfigChangeHandler("logging.", applyLoggingConfigChanges); the symbol is exported.
190
+ registerConfigChangeHandler("logging.", applyLoggingConfigChanges);
191
+ /**
192
+ * Logs a one-line summary of a reload outcome so operators can see which changes landed live versus which need a restart. Suppressed for empty diffs - the
193
+ * /config save handler can be called with no metadata fields changed (e.g., only system-state fields touched).
194
+ * @param diff - The diff that was dispatched.
195
+ * @param result - The aggregate apply result.
196
+ */
197
+ function logReloadOutcome(diff, result) {
198
+ if (diff.length === 0) {
199
+ return;
200
+ }
201
+ LOG.info("Configuration reloaded.", {
202
+ applied: result.applied.length,
203
+ deferred: result.deferred.length,
204
+ rejected: result.rejected.length,
205
+ total: diff.length
206
+ });
49
207
  }
50
208
  /**
51
209
  * Returns a deep copy of the default configuration. Used by the web UI to display default values and handle reset operations.
@@ -111,78 +269,170 @@ function checkBounds(name, value, min, max) {
111
269
  return null;
112
270
  }
113
271
  /**
114
- * Validates all configuration values and throws an error if any are invalid. This function runs at startup after configuration initialization. We collect all
115
- * validation errors before throwing to provide complete feedback rather than failing on the first error and requiring multiple restart cycles to find all problems.
116
- * @throws If any configuration value is invalid. The error message lists all invalid values.
272
+ * Describes the capture coercions a configuration would need, without mutating it. Pure so both the startup path (which then applies them) and the reload path
273
+ * (which rejects when any are present) can ask the same question against any config snapshot.
274
+ * @param config - The configuration to inspect.
275
+ * @returns The set of needed coercions; captureCodecs is null and forceFfmpegMode is false when none apply.
117
276
  */
118
- export function validateConfiguration() {
119
- // Collect all validation errors before throwing so the operator sees every problem at once. The check helper pushes non-null results into the errors array,
120
- // reducing each validation to a single line.
277
+ function collectCoercions(config) {
278
+ // Filter captureCodecs to recognized identifiers and guarantee the h264 universal baseline. RECOGNIZED_CODECS in types/streaming.ts is the single definition
279
+ // for all capture codec identifiers.
280
+ const recognizedCodecs = new Set(RECOGNIZED_CODECS);
281
+ const normalizedCodecs = config.streaming.captureCodecs.filter((codec) => recognizedCodecs.has(codec));
282
+ if (!normalizedCodecs.includes("h264")) {
283
+ normalizedCodecs.unshift("h264");
284
+ }
285
+ // Only report a captureCodecs coercion when the normalized list actually differs from the input - identical contents must not trip the reload rejection.
286
+ const captureCodecsChanged = (normalizedCodecs.length !== config.streaming.captureCodecs.length) ||
287
+ normalizedCodecs.some((codec, index) => (codec !== config.streaming.captureCodecs[index]));
288
+ return {
289
+ captureCodecs: captureCodecsChanged ? normalizedCodecs : null,
290
+ forceFfmpegMode: config.streaming.captureMode !== "ffmpeg"
291
+ };
292
+ }
293
+ /**
294
+ * Predicate: does this coercion set require any change? Used to record whether a startup write-back is needed.
295
+ * @param coercions - The coercions to test.
296
+ * @returns True when at least one coercion would change the configuration.
297
+ */
298
+ function hasCoercions(coercions) {
299
+ return (coercions.captureCodecs !== null) || coercions.forceFfmpegMode;
300
+ }
301
+ /**
302
+ * Applies the described coercions to a configuration in place, emitting the same operator-visible warning the startup path has always logged when forcing
303
+ * FFmpeg mode. Used only by the startup path; the reload path rejects rather than coerces.
304
+ * @param config - The configuration to mutate.
305
+ * @param coercions - The coercions to apply, as computed by collectCoercions.
306
+ */
307
+ function applyCoercions(config, coercions) {
308
+ if (coercions.captureCodecs !== null) {
309
+ config.streaming.captureCodecs = Array.from(coercions.captureCodecs);
310
+ }
311
+ if (coercions.forceFfmpegMode) {
312
+ LOG.warn("Native capture mode is disabled due to a Chrome fMP4 MediaRecorder bug. Forcing FFmpeg capture mode.");
313
+ config.streaming.captureMode = "ffmpeg";
314
+ }
315
+ }
316
+ /**
317
+ * Collects every hard configuration error - an always-fatal value that no coercion can repair - for the given configuration. Pure: it never mutates and never
318
+ * throws, so both validateConfiguration (which throws on a non-empty result at startup) and reloadConfiguration (which rejects the save) can reuse it.
319
+ * @param config - The configuration to validate.
320
+ * @returns The list of error messages; empty when the configuration has no hard errors.
321
+ */
322
+ function collectHardErrors(config) {
323
+ // Collect every hard error before returning so the operator sees all problems at once rather than fixing them one restart at a time. The check helper pushes
324
+ // non-null validator results, reducing each validation to a single line.
121
325
  const errors = [];
122
326
  const check = (result) => { if (result) {
123
327
  errors.push(result);
124
328
  } };
125
329
  // Server configuration.
126
- check(validatePositiveInt("PORT", CONFIG.server.port, 1, 65535));
330
+ check(validatePositiveInt("PORT", config.server.port, 1, 65535));
127
331
  // Streaming bitrates. Video: 100kbps-50Mbps. Audio: 32-512kbps.
128
- check(validatePositiveInt("VIDEO_BITRATE", CONFIG.streaming.videoBitsPerSecond, 100000, 50000000));
129
- check(validatePositiveInt("AUDIO_BITRATE", CONFIG.streaming.audioBitsPerSecond, 32000, 512000));
332
+ check(validatePositiveInt("VIDEO_BITRATE", config.streaming.videoBitsPerSecond, 100000, 50000000));
333
+ check(validatePositiveInt("AUDIO_BITRATE", config.streaming.audioBitsPerSecond, 32000, 512000));
130
334
  // Timeouts. 1 second minimum prevents premature failures. 10 minutes maximum prevents indefinite hangs.
131
- check(validatePositiveInt("NAV_TIMEOUT", CONFIG.streaming.navigationTimeout, 1000, 600000));
132
- check(validatePositiveInt("VIDEO_TIMEOUT", CONFIG.streaming.videoTimeout, 1000, 600000));
335
+ check(validatePositiveInt("NAV_TIMEOUT", config.streaming.navigationTimeout, 1000, 600000));
336
+ check(validatePositiveInt("VIDEO_TIMEOUT", config.streaming.videoTimeout, 1000, 600000));
133
337
  // Concurrent stream limit.
134
- check(validatePositiveInt("MAX_CONCURRENT_STREAMS", CONFIG.streaming.maxConcurrentStreams, 1, 100));
338
+ check(validatePositiveInt("MAX_CONCURRENT_STREAMS", config.streaming.maxConcurrentStreams, 1, 100));
135
339
  // Circuit breaker threshold.
136
- check(validatePositiveInt("CIRCUIT_BREAKER_THRESHOLD", CONFIG.recovery.circuitBreakerThreshold, 1, 100));
340
+ check(validatePositiveInt("CIRCUIT_BREAKER_THRESHOLD", config.recovery.circuitBreakerThreshold, 1, 100));
341
+ // Browser relaunch governor bounds.
342
+ check(validatePositiveInt("RELAUNCH_FAILURE_THRESHOLD", config.recovery.relaunchFailureThreshold, 1, 20));
343
+ check(validatePositiveInt("RELAUNCH_FAILURE_WINDOW", config.recovery.relaunchFailureWindow, 60000, 3600000));
344
+ check(validatePositiveInt("RELAUNCH_HEALTH_HOLD", config.recovery.relaunchHealthHold, 60000, 600000));
137
345
  // Stall threshold (float).
138
- check(validatePositiveNumber("STALL_THRESHOLD", CONFIG.playback.stallThreshold, 0.01, 5));
346
+ check(validatePositiveNumber("STALL_THRESHOLD", config.playback.stallThreshold, 0.01, 5));
139
347
  // Logging. 10KB minimum ensures meaningful content. 100MB maximum prevents excessive disk usage.
140
- check(validatePositiveInt("LOG_MAX_SIZE", CONFIG.logging.maxSize, 10240, 104857600));
348
+ check(validatePositiveInt("LOG_MAX_SIZE", config.logging.maxSize, 10240, 104857600));
141
349
  // HLS configuration.
142
- check(validatePositiveInt("HLS_SEGMENT_DURATION", CONFIG.hls.segmentDuration, 1, 10));
143
- check(validatePositiveInt("HLS_MAX_SEGMENTS", CONFIG.hls.maxSegments, 3, 60));
144
- check(validatePositiveInt("HLS_IDLE_TIMEOUT", CONFIG.hls.idleTimeout, 10000, 300000));
145
- // Validate and normalize captureCodecs. Ensure h264 is always present (universal baseline) and filter out unrecognized codec identifiers. The recognized set
146
- // is derived from RECOGNIZED_CODECS in types/streaming.ts - the single definition for all capture codec identifiers.
147
- const recognizedCodecSet = new Set(RECOGNIZED_CODECS);
148
- CONFIG.streaming.captureCodecs = CONFIG.streaming.captureCodecs.filter((c) => recognizedCodecSet.has(c));
149
- if (!CONFIG.streaming.captureCodecs.includes("h264")) {
150
- CONFIG.streaming.captureCodecs.unshift("h264");
151
- }
152
- // Force FFmpeg capture mode. Chrome's native fMP4 MediaRecorder produces corrupt output after 20-30 minutes of continuous recording. Until a future Chrome
153
- // release resolves this, native capture mode is disabled entirely.
154
- if (CONFIG.streaming.captureMode !== "ffmpeg") {
155
- LOG.warn("Native capture mode is disabled due to a Chrome fMP4 MediaRecorder bug. Forcing FFmpeg capture mode.");
156
- CONFIG.streaming.captureMode = "ffmpeg";
157
- }
350
+ check(validatePositiveInt("HLS_SEGMENT_DURATION", config.hls.segmentDuration, 1, 10));
351
+ check(validatePositiveInt("HLS_MAX_SEGMENTS", config.hls.maxSegments, 3, 60));
352
+ check(validatePositiveInt("HLS_IDLE_TIMEOUT", config.hls.idleTimeout, 10000, 300000));
158
353
  // Validate path overrides. When set, both chromeDataDir and logFile must be absolute paths to prevent ambiguity.
159
- if ((CONFIG.paths.chromeDataDir !== null) && !path.isAbsolute(CONFIG.paths.chromeDataDir)) {
160
- errors.push("paths.chromeDataDir must be an absolute path, got: " + CONFIG.paths.chromeDataDir);
161
- }
162
- if ((CONFIG.paths.logFile !== null) && !path.isAbsolute(CONFIG.paths.logFile)) {
163
- errors.push("paths.logFile must be an absolute path, got: " + CONFIG.paths.logFile);
164
- }
165
- // Validate HDHomeRun configuration when enabled.
166
- if (CONFIG.hdhr.enabled) {
167
- // HDHR requires FFmpeg for MPEG-TS remuxing. In native mode, FFmpeg is not guaranteed to be available. Disable HDHR and warn the operator. The string cast
168
- // suppresses TS2367 because captureMode is currently forced to "ffmpeg" above - this guard will become reachable again when native mode is re-enabled.
169
- if (CONFIG.streaming.captureMode === "native") {
170
- CONFIG.hdhr.enabled = false;
171
- LOG.warn("HDHomeRun emulation requires FFmpeg mode. Disabling HDHR because capture mode is set to native.");
172
- }
173
- else {
174
- check(validatePositiveInt("HDHR_PORT", CONFIG.hdhr.port, 1, 65535));
175
- // Warn if HDHR port conflicts with the main server port (same host).
176
- if ((CONFIG.hdhr.port === CONFIG.server.port) && ((CONFIG.server.host === "0.0.0.0") || (CONFIG.server.host === "::"))) {
177
- errors.push("HDHR_PORT (" + String(CONFIG.hdhr.port) + ") conflicts with the main server port.");
178
- }
354
+ if ((config.paths.chromeDataDir !== null) && !path.isAbsolute(config.paths.chromeDataDir)) {
355
+ errors.push("paths.chromeDataDir must be an absolute path, got: " + config.paths.chromeDataDir);
356
+ }
357
+ if ((config.paths.logFile !== null) && !path.isAbsolute(config.paths.logFile)) {
358
+ errors.push("paths.logFile must be an absolute path, got: " + config.paths.logFile);
359
+ }
360
+ // Validate the HDHomeRun port only when HDHR is enabled and the effective capture mode is FFmpeg. At startup applyCoercions has already forced FFmpeg mode
361
+ // before this runs, so the captureMode check is a defensive no-op here and the guard reduces to just "HDHR enabled". On reload, an un-coerced native-mode
362
+ // config skips this specific port check, but collectReloadRejection separately rejects it via the forceFfmpegMode reason before it could ever be committed
363
+ // with native mode active.
364
+ if (config.hdhr.enabled && (config.streaming.captureMode === "ffmpeg")) {
365
+ check(validatePositiveInt("HDHR_PORT", config.hdhr.port, 1, 65535));
366
+ // Reject if the HDHR port conflicts with the main server port (same host).
367
+ if ((config.hdhr.port === config.server.port) && ((config.server.host === "0.0.0.0") || (config.server.host === "::"))) {
368
+ errors.push("HDHR_PORT (" + String(config.hdhr.port) + ") conflicts with the main server port.");
179
369
  }
180
370
  }
181
- // If any validation errors occurred, throw with complete list for operator to fix all issues at once.
371
+ return errors;
372
+ }
373
+ /**
374
+ * Validates all configuration values and throws an error if any are invalid. This function runs at startup after configuration initialization. It first applies
375
+ * the capture coercions in place (filtering captureCodecs, forcing FFmpeg mode, with the same operator-visible warning as before), then collects every hard
376
+ * error against the coerced CONFIG and throws once with the complete list. Splitting the pure collectors (collectCoercions, collectHardErrors) from the in-place
377
+ * application lets reloadConfiguration reuse the same hard-error and capture-coercion checks without silently coercing a live save.
378
+ * @throws If any configuration value is invalid. The error message lists all invalid values.
379
+ */
380
+ export function validateConfiguration() {
381
+ const coercions = collectCoercions(CONFIG);
382
+ // Record whether a capture coercion was applied so persistCoercedConfig can write the corrected values back to disk and keep the on-disk state honest.
383
+ captureConfigCoercedAtStartup = hasCoercions(coercions);
384
+ applyCoercions(CONFIG, coercions);
385
+ const errors = collectHardErrors(CONFIG);
386
+ // If any validation errors occurred, throw with the complete list so the operator can fix every issue at once.
182
387
  if (errors.length > 0) {
183
388
  throw new Error("Configuration validation failed:\n " + errors.join("\n "));
184
389
  }
185
390
  }
391
+ /**
392
+ * Persists the capture configuration that validateConfiguration coerced at startup back to disk so the on-disk state matches the live CONFIG. A no-op unless a
393
+ * coercion actually occurred. Without this, a config file holding an unsupported capture value (native mode, or a captureCodecs list missing the h264 baseline)
394
+ * stays divergent from the coerced live CONFIG forever, and the reload-validation path would then reject every later save on the resulting phantom capture diff.
395
+ * filterDefaults strips any value equal to its default on write, so a config coerced back to the FFmpeg/h264 defaults leaves a clean file with no capture override.
396
+ * Failures degrade gracefully: the live CONFIG is already coerced, so a write failure only means the divergence persists until the next successful save or boot.
397
+ */
398
+ export async function persistCoercedConfig(io = defaultConfigStore) {
399
+ if (!captureConfigCoercedAtStartup) {
400
+ return;
401
+ }
402
+ try {
403
+ await io.mutateConfig((config) => {
404
+ config.streaming ??= {};
405
+ config.streaming.captureCodecs = Array.from(CONFIG.streaming.captureCodecs);
406
+ config.streaming.captureMode = CONFIG.streaming.captureMode;
407
+ });
408
+ LOG.info("Normalized capture configuration written to disk after a startup coercion.");
409
+ }
410
+ catch (error) {
411
+ LOG.warn("Failed to persist the normalized capture configuration to disk: %s.", formatError(error));
412
+ }
413
+ }
414
+ /**
415
+ * Determines whether a freshly merged configuration must be rejected on reload rather than committed. Returns a single human-readable reason when the
416
+ * configuration carries a hard error (an always-fatal value) or would require a capture coercion the reload path refuses to apply silently, or null when the
417
+ * configuration is safe to commit live. Most of the collected reason strings carry no trailing punctuation and are joined with a single space, so the combined
418
+ * text reads as one flowing line rather than separate sentences when it is surfaced verbatim to the operator in the settings-save response.
419
+ * @param config - The merged, normalized configuration about to be committed.
420
+ * @returns The joined rejection reason, or null when the configuration may be committed.
421
+ */
422
+ function collectReloadRejection(config) {
423
+ const reasons = collectHardErrors(config);
424
+ const coercions = collectCoercions(config);
425
+ if (coercions.forceFfmpegMode) {
426
+ reasons.push("Native capture mode is disabled and cannot be applied live; set capture mode to FFmpeg.");
427
+ }
428
+ if (coercions.captureCodecs !== null) {
429
+ reasons.push("Capture codecs must include the h264 baseline and contain only recognized identifiers.");
430
+ }
431
+ if (reasons.length === 0) {
432
+ return null;
433
+ }
434
+ return reasons.join(" ");
435
+ }
186
436
  /**
187
437
  * Emits a single indented configuration row in the "label: value" format used by the startup display. Routes through displayLine so the line stays free of the
188
438
  * sentence-normalization contract that LOG.info applies - a config dump is tabular display, not a sentence, and forcing a trailing period on every row would
@@ -217,6 +467,7 @@ export function displayConfiguration() {
217
467
  printConfigRow("Max retries", CONFIG.streaming.maxNavigationRetries);
218
468
  printConfigRow("Max concurrent streams", CONFIG.streaming.maxConcurrentStreams);
219
469
  displayLine(" Circuit breaker threshold: %s failures in %s minutes", CONFIG.recovery.circuitBreakerThreshold, Math.round(CONFIG.recovery.circuitBreakerWindow / 60000));
470
+ displayLine(" Browser relaunch governor: trips at %s failures in %s minutes, %s minute health hold", CONFIG.recovery.relaunchFailureThreshold, Math.round(CONFIG.recovery.relaunchFailureWindow / 60000), Math.round(CONFIG.recovery.relaunchHealthHold / 60000));
220
471
  printConfigRow("Chrome executable", CONFIG.browser.executablePath ?? "autodetect");
221
472
  displayLine(" HLS segment duration: %ss, max segments: %s", CONFIG.hls.segmentDuration, CONFIG.hls.maxSegments);
222
473
  printConfigRow("HDHomeRun emulation", CONFIG.hdhr.enabled ? "enabled (port " + String(CONFIG.hdhr.port) + ")" : "disabled");
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC3E,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC/H,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACzF,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,IAAI,MAAM,WAAW,CAAC;AA+B7B,gIAAgI;AAChI,MAAM,CAAC,IAAI,MAAM,GAAW,eAAe,CAAC,QAAQ,CAAC,CAAC;AAEtD;;GAEG;AACH,MAAM,CAAC,IAAI,gBAAgB,GAAG,KAAK,CAAC;AAEpC;;GAEG;AACH,MAAM,CAAC,IAAI,uBAA2C,CAAC;AAEvD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,YAA2B;IAEvE,yJAAyJ;IACzJ,sJAAsJ;IACtJ,iHAAiH;IACjH,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;IAElC,gBAAgB,GAAG,MAAM,CAAC,UAAU,CAAC;IACrC,uBAAuB,GAAG,MAAM,CAAC,iBAAiB,CAAC;IAEnD,IAAG,MAAM,CAAC,mBAAmB,EAAE,CAAC;QAE9B,GAAG,CAAC,IAAI,CAAC,oEAAoE,CAAC,CAAC;IACjF,CAAC;IAED,yEAAyE;IACzE,MAAM,GAAG,kBAAkB,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAEzD,mJAAmJ;IACnJ,qIAAqI;IACrI,IAAG,CAAC,iBAAiB,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC;QAEnE,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAE5C,sJAAsJ;QACtJ,qIAAqI;QACrI,MAAM,CAAC,OAAO,CAAC,WAAW,GAAG,iBAAiB,EAAE,CAAC;IACnD,CAAC;IAED,yGAAyG;IACzG,MAAM,YAAY,GAAG,iBAAiB,EAAE,CAAC;IAEzC,IAAG,CAAC,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC,EAAE,CAAC;QAE1D,GAAG,CAAC,IAAI,CAAC,kDAAkD,EAAE,MAAM,CAAC,SAAS,CAAC,aAAa,EAAE,QAAQ,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QAE/H,MAAM,CAAC,SAAS,CAAC,aAAa,GAAG,QAAQ,CAAC,SAAS,CAAC,aAAa,CAAC;IACpE,CAAC;IAED,GAAG,CAAC,IAAI,CAAC,iGAAiG,CAAC,CAAC;AAC9G,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW;IAEzB,OAAO,eAAe,CAAC,QAAQ,CAAC,CAAC;AACnC,CAAC;AAED;;;;;;GAMG;AAEH;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY,EAAE,KAAa,EAAE,GAAY,EAAE,GAAY;IAEzF,0EAA0E;IAC1E,IAAG,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC;QAE3C,OAAO,IAAI,GAAG,oCAAoC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IACrE,CAAC;IAED,OAAO,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAC5C,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAAY,EAAE,KAAa,EAAE,GAAY,EAAE,GAAY;IAE5F,yCAAyC;IACzC,IAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,EAAE,CAAC;QAEvC,OAAO,IAAI,GAAG,mCAAmC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IACpE,CAAC;IAED,OAAO,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAC5C,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,WAAW,CAAC,IAAY,EAAE,KAAa,EAAE,GAAuB,EAAE,GAAuB;IAEhG,IAAG,CAAC,GAAG,KAAK,SAAS,CAAC,IAAI,CAAC,KAAK,GAAG,GAAG,CAAC,EAAE,CAAC;QAExC,OAAO,IAAI,GAAG,oBAAoB,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC/E,CAAC;IAED,IAAG,CAAC,GAAG,KAAK,SAAS,CAAC,IAAI,CAAC,KAAK,GAAG,GAAG,CAAC,EAAE,CAAC;QAExC,OAAO,IAAI,GAAG,mBAAmB,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9E,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,qBAAqB;IAEnC,4JAA4J;IAC5J,6CAA6C;IAC7C,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,KAAK,GAAG,CAAC,MAAqB,EAAQ,EAAE,GAAG,IAAG,MAAM,EAAE,CAAC;QAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAAC,CAAC,CAAC,CAAC,CAAC;IAEvF,wBAAwB;IACxB,KAAK,CAAC,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;IAEjE,gEAAgE;IAChE,KAAK,CAAC,mBAAmB,CAAC,eAAe,EAAE,MAAM,CAAC,SAAS,CAAC,kBAAkB,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IACnG,KAAK,CAAC,mBAAmB,CAAC,eAAe,EAAE,MAAM,CAAC,SAAS,CAAC,kBAAkB,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;IAEhG,wGAAwG;IACxG,KAAK,CAAC,mBAAmB,CAAC,aAAa,EAAE,MAAM,CAAC,SAAS,CAAC,iBAAiB,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;IAC5F,KAAK,CAAC,mBAAmB,CAAC,eAAe,EAAE,MAAM,CAAC,SAAS,CAAC,YAAY,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;IAEzF,2BAA2B;IAC3B,KAAK,CAAC,mBAAmB,CAAC,wBAAwB,EAAE,MAAM,CAAC,SAAS,CAAC,oBAAoB,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IAEpG,6BAA6B;IAC7B,KAAK,CAAC,mBAAmB,CAAC,2BAA2B,EAAE,MAAM,CAAC,QAAQ,CAAC,uBAAuB,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IAEzG,2BAA2B;IAC3B,KAAK,CAAC,sBAAsB,CAAC,iBAAiB,EAAE,MAAM,CAAC,QAAQ,CAAC,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAE1F,iGAAiG;IACjG,KAAK,CAAC,mBAAmB,CAAC,cAAc,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;IAErF,qBAAqB;IACrB,KAAK,CAAC,mBAAmB,CAAC,sBAAsB,EAAE,MAAM,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IACtF,KAAK,CAAC,mBAAmB,CAAC,kBAAkB,EAAE,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IAC9E,KAAK,CAAC,mBAAmB,CAAC,kBAAkB,EAAE,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;IAEtF,6JAA6J;IAC7J,qHAAqH;IACrH,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAS,iBAAiB,CAAC,CAAC;IAE9D,MAAM,CAAC,SAAS,CAAC,aAAa,GAAG,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAEzG,IAAG,CAAC,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAEpD,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACjD,CAAC;IAED,2JAA2J;IAC3J,mEAAmE;IACnE,IAAG,MAAM,CAAC,SAAS,CAAC,WAAW,KAAK,QAAQ,EAAE,CAAC;QAE7C,GAAG,CAAC,IAAI,CAAC,sGAAsG,CAAC,CAAC;QAEjH,MAAM,CAAC,SAAS,CAAC,WAAW,GAAG,QAAQ,CAAC;IAC1C,CAAC;IAED,iHAAiH;IACjH,IAAG,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,CAAC;QAEzF,MAAM,CAAC,IAAI,CAAC,qDAAqD,GAAG,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IAClG,CAAC;IAED,IAAG,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QAE7E,MAAM,CAAC,IAAI,CAAC,+CAA+C,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACtF,CAAC;IAED,iDAAiD;IACjD,IAAG,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QAEvB,2JAA2J;QAC3J,uJAAuJ;QACvJ,IAAI,MAAM,CAAC,SAAS,CAAC,WAAsB,KAAK,QAAQ,EAAE,CAAC;YAEzD,MAAM,CAAC,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;YAE5B,GAAG,CAAC,IAAI,CAAC,iGAAiG,CAAC,CAAC;QAC9G,CAAC;aAAM,CAAC;YAEN,KAAK,CAAC,mBAAmB,CAAC,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;YAEpE,qEAAqE;YACrE,IAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,EAAE,CAAC;gBAEtH,MAAM,CAAC,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,wCAAwC,CAAC,CAAC;YACnG,CAAC;QACH,CAAC;IACH,CAAC;IAED,sGAAsG;IACtG,IAAG,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAErB,MAAM,IAAI,KAAK,CAAC,sCAAsC,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAChF,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,SAAS,cAAc,CAAC,KAAa,EAAE,KAAc;IAEnD,WAAW,CAAC,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AACnD,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,oBAAoB;IAElC,MAAM,YAAY,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAChD,MAAM,YAAY,GAAG,kBAAkB,CAAC,YAAY,CAAC,CAAC;IAEtD,WAAW,CAAC,4CAA4C,EAAE,iBAAiB,EAAE,CAAC,CAAC;IAC/E,cAAc,CAAC,oBAAoB,EAAE,iBAAiB,EAAE,CAAC,CAAC;IAC1D,cAAc,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC;IAC3D,cAAc,CAAC,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAClD,cAAc,CAAC,gBAAgB,EAAE,YAAY,CAAC,CAAC;IAC/C,cAAc,CAAC,gBAAgB,EAAE,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAC5E,cAAc,CAAC,eAAe,EAAE,MAAM,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;IACrE,cAAc,CAAC,aAAa,EAAE,MAAM,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;IACrE,cAAc,CAAC,wBAAwB,EAAE,MAAM,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;IAChF,WAAW,CAAC,wDAAwD,EAClE,MAAM,CAAC,QAAQ,CAAC,uBAAuB,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,oBAAoB,GAAG,KAAK,CAAC,CAAC,CAAC;IACrG,cAAc,CAAC,mBAAmB,EAAE,MAAM,CAAC,OAAO,CAAC,cAAc,IAAI,YAAY,CAAC,CAAC;IACnF,WAAW,CAAC,+CAA+C,EAAE,MAAM,CAAC,GAAG,CAAC,eAAe,EAAE,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACjH,cAAc,CAAC,qBAAqB,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,gBAAgB,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;IAE5H,6EAA6E;IAC7E,IAAG,YAAY,CAAC,QAAQ,IAAI,YAAY,CAAC,WAAW,EAAE,CAAC;QAErD,GAAG,CAAC,IAAI,CAAC,gFAAgF,EACvF,YAAY,CAAC,WAAW,CAAC,KAAK,EAAE,YAAY,CAAC,WAAW,CAAC,MAAM,EAC/D,YAAY,CAAC,gBAAgB,CAAC,EAAE,EAAE,YAAY,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;IACvE,CAAC;AAEH,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"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"}
@@ -30,20 +30,20 @@ export declare function getHealthFilePath(): string;
30
30
  * @returns The absolute path to profiles.json inside the data directory.
31
31
  */
32
32
  export declare function getProfilesFilePath(): string;
33
+ /**
34
+ * Returns the path to the persisted provider channel lineups file.
35
+ * @returns The absolute path to provider-lineups.json inside the data directory.
36
+ */
37
+ export declare function getProviderLineupsFilePath(): string;
33
38
  /**
34
39
  * Returns the path to the HLS resume state file.
35
40
  * @returns The absolute path to hls-resume.json inside the data directory.
36
41
  */
37
42
  export declare function getResumeFilePath(): string;
38
43
  /**
39
- * Returns the path to the Chrome PID file. Used for cross-platform process cleanup - the PID file survives crashes and allows the next startup to find and
40
- * terminate orphaned Chrome processes without relying on Unix-only tools like pkill/pgrep.
41
- * @returns The absolute path to chrome.pid inside the data directory.
42
- */
43
- export declare function getChromePidFilePath(): string;
44
- /**
45
- * Returns the path to the server PID file. Used to detect duplicate PrismCast instances - the PID file is written immediately after the instance check passes and
46
- * checked at the start of the next launch to prevent two instances from running simultaneously.
44
+ * Returns the path to the server identity file. Used to detect duplicate PrismCast instances - the file is written immediately after the instance-guard claim
45
+ * succeeds and is checked at the start of the next launch. Orphaned Chrome processes are discovered via the OS process table (utils/processInspector) using a
46
+ * command-line signature, so no separate Chrome PID file is needed.
47
47
  * @returns The absolute path to prismcast.pid inside the data directory.
48
48
  */
49
49
  export declare function getServerPidFilePath(): string;
@@ -94,7 +94,8 @@ export declare function getExtensionDir(config: Config): string;
94
94
  export declare function getLogFilePath(config: Config): string;
95
95
  /**
96
96
  * Returns the value of the PRISMCAST_DEBUG environment variable, if set. Centralizing this read keeps the index-signature access on process.env in one place and
97
- * gives tests a single seam to stub.
97
+ * gives tests a single place to stub.
98
98
  * @returns The PRISMCAST_DEBUG value, or undefined when unset.
99
99
  */
100
100
  export declare function getDebugEnv(): string | undefined;
101
+ //# sourceMappingURL=paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/config/paths.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAsBhD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAuB3D;AAED;;;GAGG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAQnC;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAG1C;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAG5C;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAG1C;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAG5C;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,IAAI,MAAM,CAGnD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAG1C;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAG7C;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAGzC;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CA0B3C;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,CAGhD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAG3C;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAGvD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAGtD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAGrD;AAED;;;;GAIG;AACH,wBAAgB,WAAW,IAAI,MAAM,GAAG,SAAS,CAGhD"}
@@ -77,6 +77,13 @@ export function getHealthFilePath() {
77
77
  export function getProfilesFilePath() {
78
78
  return path.join(getDataDir(), "profiles.json");
79
79
  }
80
+ /**
81
+ * Returns the path to the persisted provider channel lineups file.
82
+ * @returns The absolute path to provider-lineups.json inside the data directory.
83
+ */
84
+ export function getProviderLineupsFilePath() {
85
+ return path.join(getDataDir(), "provider-lineups.json");
86
+ }
80
87
  /**
81
88
  * Returns the path to the HLS resume state file.
82
89
  * @returns The absolute path to hls-resume.json inside the data directory.
@@ -85,16 +92,9 @@ export function getResumeFilePath() {
85
92
  return path.join(getDataDir(), "hls-resume.json");
86
93
  }
87
94
  /**
88
- * Returns the path to the Chrome PID file. Used for cross-platform process cleanup - the PID file survives crashes and allows the next startup to find and
89
- * terminate orphaned Chrome processes without relying on Unix-only tools like pkill/pgrep.
90
- * @returns The absolute path to chrome.pid inside the data directory.
91
- */
92
- export function getChromePidFilePath() {
93
- return path.join(getDataDir(), "chrome.pid");
94
- }
95
- /**
96
- * Returns the path to the server PID file. Used to detect duplicate PrismCast instances - the PID file is written immediately after the instance check passes and
97
- * checked at the start of the next launch to prevent two instances from running simultaneously.
95
+ * Returns the path to the server identity file. Used to detect duplicate PrismCast instances - the file is written immediately after the instance-guard claim
96
+ * succeeds and is checked at the start of the next launch. Orphaned Chrome processes are discovered via the OS process table (utils/processInspector) using a
97
+ * command-line signature, so no separate Chrome PID file is needed.
98
98
  * @returns The absolute path to prismcast.pid inside the data directory.
99
99
  */
100
100
  export function getServerPidFilePath() {
@@ -175,7 +175,7 @@ export function getLogFilePath(config) {
175
175
  }
176
176
  /**
177
177
  * Returns the value of the PRISMCAST_DEBUG environment variable, if set. Centralizing this read keeps the index-signature access on process.env in one place and
178
- * gives tests a single seam to stub.
178
+ * gives tests a single place to stub.
179
179
  * @returns The PRISMCAST_DEBUG value, or undefined when unset.
180
180
  */
181
181
  export function getDebugEnv() {