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.
- package/dist/app.d.ts +6 -3
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +140 -86
- package/dist/app.js.map +1 -1
- package/dist/browser/blockedPage.d.ts +80 -0
- package/dist/browser/blockedPage.d.ts.map +1 -0
- package/dist/browser/blockedPage.js +209 -0
- package/dist/browser/blockedPage.js.map +1 -0
- package/dist/browser/browserSupervisor.d.ts +80 -0
- package/dist/browser/browserSupervisor.d.ts.map +1 -0
- package/dist/browser/browserSupervisor.js +186 -0
- package/dist/browser/browserSupervisor.js.map +1 -0
- package/dist/browser/cdp.d.ts +1 -0
- package/dist/browser/cdp.d.ts.map +1 -0
- package/dist/browser/cdp.js +6 -5
- package/dist/browser/cdp.js.map +1 -1
- package/dist/browser/channelSelection.d.ts +45 -14
- package/dist/browser/channelSelection.d.ts.map +1 -0
- package/dist/browser/channelSelection.js +81 -18
- package/dist/browser/channelSelection.js.map +1 -1
- package/dist/browser/consent.d.ts +152 -0
- package/dist/browser/consent.d.ts.map +1 -0
- package/dist/browser/consent.js +418 -0
- package/dist/browser/consent.js.map +1 -0
- package/dist/browser/display.d.ts +1 -0
- package/dist/browser/display.d.ts.map +1 -0
- package/dist/browser/hlsPlaylistObserver.d.ts +55 -0
- package/dist/browser/hlsPlaylistObserver.d.ts.map +1 -0
- package/dist/browser/hlsPlaylistObserver.js +132 -0
- package/dist/browser/hlsPlaylistObserver.js.map +1 -0
- package/dist/browser/index.d.ts +67 -40
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +508 -300
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/launchGovernor.d.ts +89 -0
- package/dist/browser/launchGovernor.d.ts.map +1 -0
- package/dist/browser/launchGovernor.js +96 -0
- package/dist/browser/launchGovernor.js.map +1 -0
- package/dist/browser/login.d.ts +10 -2
- package/dist/browser/login.d.ts.map +1 -0
- package/dist/browser/login.js +36 -5
- package/dist/browser/login.js.map +1 -1
- package/dist/browser/manifestInterceptor.d.ts +102 -49
- package/dist/browser/manifestInterceptor.d.ts.map +1 -0
- package/dist/browser/manifestInterceptor.js +219 -237
- package/dist/browser/manifestInterceptor.js.map +1 -1
- package/dist/browser/pageStaleness.d.ts +30 -0
- package/dist/browser/pageStaleness.d.ts.map +1 -0
- package/dist/browser/pageStaleness.js +76 -0
- package/dist/browser/pageStaleness.js.map +1 -0
- package/dist/browser/precaching.d.ts +95 -3
- package/dist/browser/precaching.d.ts.map +1 -0
- package/dist/browser/precaching.js +499 -65
- package/dist/browser/precaching.js.map +1 -1
- package/dist/browser/tabNetworkObserver.d.ts +49 -0
- package/dist/browser/tabNetworkObserver.d.ts.map +1 -0
- package/dist/browser/tabNetworkObserver.js +144 -0
- package/dist/browser/tabNetworkObserver.js.map +1 -0
- package/dist/browser/tuning/cache.d.ts +61 -0
- package/dist/browser/tuning/cache.d.ts.map +1 -0
- package/dist/browser/tuning/cache.js +62 -0
- package/dist/browser/tuning/cache.js.map +1 -0
- package/dist/browser/tuning/comcastPolymer.d.ts +3 -2
- package/dist/browser/tuning/comcastPolymer.d.ts.map +1 -0
- package/dist/browser/tuning/comcastPolymer.js +79 -102
- package/dist/browser/tuning/comcastPolymer.js.map +1 -1
- package/dist/browser/tuning/cox.d.ts +1 -0
- package/dist/browser/tuning/cox.d.ts.map +1 -0
- package/dist/browser/tuning/directv.d.ts +1 -0
- package/dist/browser/tuning/directv.d.ts.map +1 -0
- package/dist/browser/tuning/directv.js +52 -46
- package/dist/browser/tuning/directv.js.map +1 -1
- package/dist/browser/tuning/fox.d.ts +1 -0
- package/dist/browser/tuning/fox.d.ts.map +1 -0
- package/dist/browser/tuning/fox.js +13 -12
- package/dist/browser/tuning/fox.js.map +1 -1
- package/dist/browser/tuning/gridSearch.d.ts +68 -0
- package/dist/browser/tuning/gridSearch.d.ts.map +1 -0
- package/dist/browser/tuning/gridSearch.js +85 -0
- package/dist/browser/tuning/gridSearch.js.map +1 -0
- package/dist/browser/tuning/hbo.d.ts +1 -0
- package/dist/browser/tuning/hbo.d.ts.map +1 -0
- package/dist/browser/tuning/hbo.js +73 -45
- package/dist/browser/tuning/hbo.js.map +1 -1
- package/dist/browser/tuning/hulu.d.ts +1 -0
- package/dist/browser/tuning/hulu.d.ts.map +1 -0
- package/dist/browser/tuning/hulu.js +128 -173
- package/dist/browser/tuning/hulu.js.map +1 -1
- package/dist/browser/tuning/shared.d.ts +75 -5
- package/dist/browser/tuning/shared.d.ts.map +1 -0
- package/dist/browser/tuning/shared.js +216 -6
- package/dist/browser/tuning/shared.js.map +1 -1
- package/dist/browser/tuning/sling.d.ts +1 -0
- package/dist/browser/tuning/sling.d.ts.map +1 -0
- package/dist/browser/tuning/sling.js +105 -126
- package/dist/browser/tuning/sling.js.map +1 -1
- package/dist/browser/tuning/spectrum.d.ts +1 -0
- package/dist/browser/tuning/spectrum.d.ts.map +1 -0
- package/dist/browser/tuning/spectrum.js +80 -125
- package/dist/browser/tuning/spectrum.js.map +1 -1
- package/dist/browser/tuning/thumbnailRow.d.ts +1 -0
- package/dist/browser/tuning/thumbnailRow.d.ts.map +1 -0
- package/dist/browser/tuning/thumbnailRow.js +8 -2
- package/dist/browser/tuning/thumbnailRow.js.map +1 -1
- package/dist/browser/tuning/tileClick.d.ts +1 -0
- package/dist/browser/tuning/tileClick.d.ts.map +1 -0
- package/dist/browser/tuning/tileClick.js +3 -2
- package/dist/browser/tuning/tileClick.js.map +1 -1
- package/dist/browser/tuning/xfinity.d.ts +1 -0
- package/dist/browser/tuning/xfinity.d.ts.map +1 -0
- package/dist/browser/tuning/youtubeTv.d.ts +1 -0
- package/dist/browser/tuning/youtubeTv.d.ts.map +1 -0
- package/dist/browser/tuning/youtubeTv.js +74 -127
- package/dist/browser/tuning/youtubeTv.js.map +1 -1
- package/dist/browser/video.d.ts +54 -14
- package/dist/browser/video.d.ts.map +1 -0
- package/dist/browser/video.js +296 -138
- package/dist/browser/video.js.map +1 -1
- package/dist/channels/index.d.ts +1 -0
- package/dist/channels/index.d.ts.map +1 -0
- package/dist/channels/index.js +12 -9
- package/dist/channels/index.js.map +1 -1
- package/dist/config/channelForm.d.ts +15 -1
- package/dist/config/channelForm.d.ts.map +1 -0
- package/dist/config/channelForm.js +28 -12
- package/dist/config/channelForm.js.map +1 -1
- package/dist/config/consistencyProbe.d.ts +1 -0
- package/dist/config/consistencyProbe.d.ts.map +1 -0
- package/dist/config/consistencyProbe.js +27 -21
- package/dist/config/consistencyProbe.js.map +1 -1
- package/dist/config/health.d.ts +41 -8
- package/dist/config/health.d.ts.map +1 -0
- package/dist/config/health.js +189 -38
- package/dist/config/health.js.map +1 -1
- package/dist/config/index.d.ts +55 -3
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +320 -69
- package/dist/config/index.js.map +1 -1
- package/dist/config/paths.d.ts +10 -9
- package/dist/config/paths.d.ts.map +1 -0
- package/dist/config/paths.js +11 -11
- package/dist/config/paths.js.map +1 -1
- package/dist/config/persistence.context.d.ts +1 -0
- package/dist/config/persistence.context.d.ts.map +1 -0
- package/dist/config/persistence.d.ts +13 -10
- package/dist/config/persistence.d.ts.map +1 -0
- package/dist/config/persistence.js +40 -21
- package/dist/config/persistence.js.map +1 -1
- package/dist/config/presets.d.ts +1 -0
- package/dist/config/presets.d.ts.map +1 -0
- package/dist/config/profiles.d.ts +22 -15
- package/dist/config/profiles.d.ts.map +1 -0
- package/dist/config/profiles.js +81 -47
- package/dist/config/profiles.js.map +1 -1
- package/dist/config/providerLineups.d.ts +47 -0
- package/dist/config/providerLineups.d.ts.map +1 -0
- package/dist/config/providerLineups.js +137 -0
- package/dist/config/providerLineups.js.map +1 -0
- package/dist/config/reactivity.d.ts +84 -0
- package/dist/config/reactivity.d.ts.map +1 -0
- package/dist/config/reactivity.js +226 -0
- package/dist/config/reactivity.js.map +1 -0
- package/dist/config/servicePacks.d.ts +18 -2
- package/dist/config/servicePacks.d.ts.map +1 -0
- package/dist/config/servicePacks.js +53 -11
- package/dist/config/servicePacks.js.map +1 -1
- package/dist/config/services.d.ts +21 -15
- package/dist/config/services.d.ts.map +1 -0
- package/dist/config/services.js +35 -24
- package/dist/config/services.js.map +1 -1
- package/dist/config/sites.d.ts +6 -4
- package/dist/config/sites.d.ts.map +1 -0
- package/dist/config/sites.js +15 -11
- package/dist/config/sites.js.map +1 -1
- package/dist/config/userChannels.d.ts +129 -30
- package/dist/config/userChannels.d.ts.map +1 -0
- package/dist/config/userChannels.js +333 -68
- package/dist/config/userChannels.js.map +1 -1
- package/dist/config/userConfig.d.ts +14 -9
- package/dist/config/userConfig.d.ts.map +1 -0
- package/dist/config/userConfig.js +87 -25
- package/dist/config/userConfig.js.map +1 -1
- package/dist/config/userProfiles.d.ts +10 -6
- package/dist/config/userProfiles.d.ts.map +1 -0
- package/dist/config/userProfiles.js +64 -39
- package/dist/config/userProfiles.js.map +1 -1
- package/dist/hdhr/channelMap.d.ts +1 -0
- package/dist/hdhr/channelMap.d.ts.map +1 -0
- package/dist/hdhr/deviceId.d.ts +1 -0
- package/dist/hdhr/deviceId.d.ts.map +1 -0
- package/dist/hdhr/discover.d.ts +1 -0
- package/dist/hdhr/discover.d.ts.map +1 -0
- package/dist/hdhr/discover.js +48 -47
- package/dist/hdhr/discover.js.map +1 -1
- package/dist/hdhr/getHandlers.d.ts +29 -0
- package/dist/hdhr/getHandlers.d.ts.map +1 -0
- package/dist/hdhr/getHandlers.js +196 -0
- package/dist/hdhr/getHandlers.js.map +1 -0
- package/dist/hdhr/identity.d.ts +36 -0
- package/dist/hdhr/identity.d.ts.map +1 -0
- package/dist/hdhr/identity.js +51 -0
- package/dist/hdhr/identity.js.map +1 -0
- package/dist/hdhr/index.d.ts +22 -4
- package/dist/hdhr/index.d.ts.map +1 -0
- package/dist/hdhr/index.js +229 -54
- package/dist/hdhr/index.js.map +1 -1
- package/dist/hdhr/protocol.d.ts +75 -0
- package/dist/hdhr/protocol.d.ts.map +1 -0
- package/dist/hdhr/protocol.js +264 -0
- package/dist/hdhr/protocol.js.map +1 -0
- package/dist/hdhr/tunerState.d.ts +24 -0
- package/dist/hdhr/tunerState.d.ts.map +1 -0
- package/dist/hdhr/tunerState.js +67 -0
- package/dist/hdhr/tunerState.js.map +1 -0
- package/dist/hdhr/udp.d.ts +43 -0
- package/dist/hdhr/udp.d.ts.map +1 -0
- package/dist/hdhr/udp.js +277 -0
- package/dist/hdhr/udp.js.map +1 -0
- package/dist/identity.d.ts +1 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +13 -11
- package/dist/identity.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -12
- package/dist/index.js.map +1 -1
- package/dist/native/codecInference.d.ts +1 -0
- package/dist/native/codecInference.d.ts.map +1 -0
- package/dist/native/codecInference.js +50 -5
- package/dist/native/codecInference.js.map +1 -1
- package/dist/native/decrypt.d.ts +6 -2
- package/dist/native/decrypt.d.ts.map +1 -0
- package/dist/native/decrypt.js +15 -8
- package/dist/native/decrypt.js.map +1 -1
- package/dist/native/index.d.ts +40 -17
- package/dist/native/index.d.ts.map +1 -0
- package/dist/native/index.js +281 -120
- package/dist/native/index.js.map +1 -1
- package/dist/native/probe.d.ts +114 -18
- package/dist/native/probe.d.ts.map +1 -0
- package/dist/native/probe.js +452 -115
- package/dist/native/probe.js.map +1 -1
- package/dist/native/proxy.d.ts +57 -5
- package/dist/native/proxy.d.ts.map +1 -0
- package/dist/native/proxy.js +604 -170
- package/dist/native/proxy.js.map +1 -1
- package/dist/native/tokenExpiry.d.ts +1 -0
- package/dist/native/tokenExpiry.d.ts.map +1 -0
- package/dist/native/tokenExpiry.js +1 -1
- package/dist/routes/assets.d.ts +1 -0
- package/dist/routes/assets.d.ts.map +1 -0
- package/dist/routes/assets.js +4 -2
- package/dist/routes/assets.js.map +1 -1
- package/dist/routes/auth.d.ts +1 -0
- package/dist/routes/auth.d.ts.map +1 -0
- package/dist/routes/auth.js +0 -1
- package/dist/routes/auth.js.map +1 -1
- package/dist/routes/cdp.d.ts +5 -5
- package/dist/routes/cdp.d.ts.map +1 -0
- package/dist/routes/cdp.js +59 -20
- package/dist/routes/cdp.js.map +1 -1
- package/dist/routes/channels.d.ts +1 -0
- package/dist/routes/channels.d.ts.map +1 -0
- package/dist/routes/channels.js +2 -1
- package/dist/routes/channels.js.map +1 -1
- package/dist/routes/clientActions.d.ts +98 -0
- package/dist/routes/clientActions.d.ts.map +1 -0
- package/dist/routes/clientActions.js +113 -0
- package/dist/routes/clientActions.js.map +1 -0
- package/dist/routes/components.d.ts +5 -3
- package/dist/routes/components.d.ts.map +1 -0
- package/dist/routes/components.js +36 -39
- package/dist/routes/components.js.map +1 -1
- package/dist/routes/config/channels/endpoints/browse.d.ts +1 -0
- package/dist/routes/config/channels/endpoints/browse.d.ts.map +1 -0
- package/dist/routes/config/channels/endpoints/browse.js +23 -10
- package/dist/routes/config/channels/endpoints/browse.js.map +1 -1
- package/dist/routes/config/channels/endpoints/bulk.d.ts +1 -0
- package/dist/routes/config/channels/endpoints/bulk.d.ts.map +1 -0
- package/dist/routes/config/channels/endpoints/bulk.js +5 -3
- package/dist/routes/config/channels/endpoints/bulk.js.map +1 -1
- package/dist/routes/config/channels/endpoints/crud.d.ts +1 -0
- package/dist/routes/config/channels/endpoints/crud.d.ts.map +1 -0
- package/dist/routes/config/channels/endpoints/crud.js +85 -93
- package/dist/routes/config/channels/endpoints/crud.js.map +1 -1
- package/dist/routes/config/channels/endpoints/importExport.d.ts +1 -0
- package/dist/routes/config/channels/endpoints/importExport.d.ts.map +1 -0
- package/dist/routes/config/channels/endpoints/importExport.js +6 -3
- package/dist/routes/config/channels/endpoints/importExport.js.map +1 -1
- package/dist/routes/config/channels/endpoints/predefined.d.ts +1 -0
- package/dist/routes/config/channels/endpoints/predefined.d.ts.map +1 -0
- package/dist/routes/config/channels/endpoints/prefs.d.ts +1 -0
- package/dist/routes/config/channels/endpoints/prefs.d.ts.map +1 -0
- package/dist/routes/config/channels/endpoints/prefs.js +2 -1
- package/dist/routes/config/channels/endpoints/prefs.js.map +1 -1
- package/dist/routes/config/channels/endpoints/service.d.ts +2 -1
- package/dist/routes/config/channels/endpoints/service.d.ts.map +1 -0
- package/dist/routes/config/channels/endpoints/service.js +3 -1
- package/dist/routes/config/channels/endpoints/service.js.map +1 -1
- package/dist/routes/config/channels/endpoints/tags.d.ts +1 -0
- package/dist/routes/config/channels/endpoints/tags.d.ts.map +1 -0
- package/dist/routes/config/channels/endpoints/tags.js +13 -7
- package/dist/routes/config/channels/endpoints/tags.js.map +1 -1
- package/dist/routes/config/channels/healthBridge.d.ts +24 -0
- package/dist/routes/config/channels/healthBridge.d.ts.map +1 -0
- package/dist/routes/config/channels/healthBridge.js +71 -0
- package/dist/routes/config/channels/healthBridge.js.map +1 -0
- package/dist/routes/config/channels/http/handler.d.ts +1 -0
- package/dist/routes/config/channels/http/handler.d.ts.map +1 -0
- package/dist/routes/config/channels/http/playlistHint.d.ts +2 -1
- package/dist/routes/config/channels/http/playlistHint.d.ts.map +1 -0
- package/dist/routes/config/channels/http/playlistHint.js +16 -2
- package/dist/routes/config/channels/http/playlistHint.js.map +1 -1
- package/dist/routes/config/channels/http/serviceWarning.d.ts +4 -2
- package/dist/routes/config/channels/http/serviceWarning.d.ts.map +1 -0
- package/dist/routes/config/channels/http/serviceWarning.js +3 -2
- package/dist/routes/config/channels/http/serviceWarning.js.map +1 -1
- package/dist/routes/config/channels/index.d.ts +1 -0
- package/dist/routes/config/channels/index.d.ts.map +1 -0
- package/dist/routes/config/channels/setup.d.ts +1 -0
- package/dist/routes/config/channels/setup.d.ts.map +1 -0
- package/dist/routes/config/channels/table.d.ts +3 -3
- package/dist/routes/config/channels/table.d.ts.map +1 -0
- package/dist/routes/config/channels/table.js +148 -107
- package/dist/routes/config/channels/table.js.map +1 -1
- package/dist/routes/config/http/envelope.d.ts +1 -0
- package/dist/routes/config/http/envelope.d.ts.map +1 -0
- package/dist/routes/config/index.d.ts +35 -3
- package/dist/routes/config/index.d.ts.map +1 -0
- package/dist/routes/config/index.js +51 -2
- package/dist/routes/config/index.js.map +1 -1
- package/dist/routes/config/services.d.ts +5 -4
- package/dist/routes/config/services.d.ts.map +1 -0
- package/dist/routes/config/services.js +57 -43
- package/dist/routes/config/services.js.map +1 -1
- package/dist/routes/config/settings.d.ts +1 -0
- package/dist/routes/config/settings.d.ts.map +1 -0
- package/dist/routes/config/settings.js +98 -49
- package/dist/routes/config/settings.js.map +1 -1
- package/dist/routes/debug.d.ts +1 -0
- package/dist/routes/debug.d.ts.map +1 -0
- package/dist/routes/debug.js +277 -139
- package/dist/routes/debug.js.map +1 -1
- package/dist/routes/health.d.ts +39 -1
- package/dist/routes/health.d.ts.map +1 -0
- package/dist/routes/health.js +33 -27
- package/dist/routes/health.js.map +1 -1
- package/dist/routes/hls.d.ts +1 -0
- package/dist/routes/hls.d.ts.map +1 -0
- package/dist/routes/icons.d.ts +1 -0
- package/dist/routes/icons.d.ts.map +1 -0
- package/dist/routes/icons.js +1 -1
- package/dist/routes/index.d.ts +1 -0
- package/dist/routes/index.d.ts.map +1 -0
- package/dist/routes/logs.d.ts +1 -0
- package/dist/routes/logs.d.ts.map +1 -0
- package/dist/routes/logs.js +14 -4
- package/dist/routes/logs.js.map +1 -1
- package/dist/routes/mpegts.d.ts +1 -0
- package/dist/routes/mpegts.d.ts.map +1 -0
- package/dist/routes/play.d.ts +1 -0
- package/dist/routes/play.d.ts.map +1 -0
- package/dist/routes/playlist.d.ts +1 -0
- package/dist/routes/playlist.d.ts.map +1 -0
- package/dist/routes/playlist.js +7 -2
- package/dist/routes/playlist.js.map +1 -1
- package/dist/routes/root/content.d.ts +8 -5
- package/dist/routes/root/content.d.ts.map +1 -0
- package/dist/routes/root/content.js +29 -26
- package/dist/routes/root/content.js.map +1 -1
- package/dist/routes/root/index.d.ts +2 -1
- package/dist/routes/root/index.d.ts.map +1 -0
- package/dist/routes/root/index.js +26 -21
- package/dist/routes/root/index.js.map +1 -1
- package/dist/routes/root/scripts/channels.d.ts +6 -0
- package/dist/routes/root/scripts/channels.d.ts.map +1 -0
- package/dist/routes/root/scripts/channels.js +197 -118
- package/dist/routes/root/scripts/channels.js.map +1 -1
- package/dist/routes/root/scripts/clientEscape.d.ts +22 -0
- package/dist/routes/root/scripts/clientEscape.d.ts.map +1 -0
- package/dist/routes/root/scripts/clientEscape.js +41 -0
- package/dist/routes/root/scripts/clientEscape.js.map +1 -0
- package/dist/routes/root/scripts/clientUrl.d.ts +23 -0
- package/dist/routes/root/scripts/clientUrl.d.ts.map +1 -0
- package/dist/routes/root/scripts/clientUrl.js +44 -0
- package/dist/routes/root/scripts/clientUrl.js.map +1 -0
- package/dist/routes/root/scripts/config.d.ts +6 -0
- package/dist/routes/root/scripts/config.d.ts.map +1 -0
- package/dist/routes/root/scripts/config.js +110 -24
- package/dist/routes/root/scripts/config.js.map +1 -1
- package/dist/routes/root/scripts/index.d.ts +1 -0
- package/dist/routes/root/scripts/index.d.ts.map +1 -0
- package/dist/routes/root/scripts/shared.d.ts +1 -0
- package/dist/routes/root/scripts/shared.d.ts.map +1 -0
- package/dist/routes/root/scripts/shared.js +112 -26
- package/dist/routes/root/scripts/shared.js.map +1 -1
- package/dist/routes/root/scripts/status.d.ts +1 -0
- package/dist/routes/root/scripts/status.d.ts.map +1 -0
- package/dist/routes/root/scripts/status.handlers.d.ts +23 -33
- package/dist/routes/root/scripts/status.handlers.d.ts.map +1 -0
- package/dist/routes/root/scripts/status.handlers.js +46 -92
- package/dist/routes/root/scripts/status.handlers.js.map +1 -1
- package/dist/routes/root/scripts/status.js +21 -8
- package/dist/routes/root/scripts/status.js.map +1 -1
- package/dist/routes/root/styles.d.ts +1 -0
- package/dist/routes/root/styles.d.ts.map +1 -0
- package/dist/routes/root/styles.js +7 -4
- package/dist/routes/root/styles.js.map +1 -1
- package/dist/routes/services.d.ts +13 -1
- package/dist/routes/services.d.ts.map +1 -0
- package/dist/routes/services.js +81 -68
- package/dist/routes/services.js.map +1 -1
- package/dist/routes/sse.d.ts +1 -0
- package/dist/routes/sse.d.ts.map +1 -0
- package/dist/routes/sse.js +1 -1
- package/dist/routes/sse.js.map +1 -1
- package/dist/routes/streams.d.ts +2 -1
- package/dist/routes/streams.d.ts.map +1 -0
- package/dist/routes/streams.js +6 -4
- package/dist/routes/streams.js.map +1 -1
- package/dist/routes/theme.d.ts +3 -2
- package/dist/routes/theme.d.ts.map +1 -0
- package/dist/routes/theme.js +6 -5
- package/dist/routes/theme.js.map +1 -1
- package/dist/routes/ui.d.ts +3 -1
- package/dist/routes/ui.d.ts.map +1 -0
- package/dist/routes/ui.js +16 -4
- package/dist/routes/ui.js.map +1 -1
- package/dist/routes/upgrade.d.ts +1 -0
- package/dist/routes/upgrade.d.ts.map +1 -0
- package/dist/routes/upgrade.js +6 -2
- package/dist/routes/upgrade.js.map +1 -1
- package/dist/service/commands.context.d.ts +1 -0
- package/dist/service/commands.context.d.ts.map +1 -0
- package/dist/service/commands.context.js +4 -3
- package/dist/service/commands.context.js.map +1 -1
- package/dist/service/commands.d.ts +1 -0
- package/dist/service/commands.d.ts.map +1 -0
- package/dist/service/commands.js +10 -13
- package/dist/service/commands.js.map +1 -1
- package/dist/service/generators.context.d.ts +1 -0
- package/dist/service/generators.context.d.ts.map +1 -0
- package/dist/service/generators.context.js +1 -1
- package/dist/service/generators.context.js.map +1 -1
- package/dist/service/generators.d.ts +4 -3
- package/dist/service/generators.d.ts.map +1 -0
- package/dist/service/generators.js +111 -31
- package/dist/service/generators.js.map +1 -1
- package/dist/service/index.d.ts +1 -0
- package/dist/service/index.d.ts.map +1 -0
- package/dist/streaming/captureLock.d.ts +44 -0
- package/dist/streaming/captureLock.d.ts.map +1 -0
- package/dist/streaming/captureLock.js +95 -0
- package/dist/streaming/captureLock.js.map +1 -0
- package/dist/streaming/captureSession.d.ts +31 -0
- package/dist/streaming/captureSession.d.ts.map +1 -0
- package/dist/streaming/captureSession.js +54 -0
- package/dist/streaming/captureSession.js.map +1 -0
- package/dist/streaming/clients.d.ts +1 -0
- package/dist/streaming/clients.d.ts.map +1 -0
- package/dist/streaming/codec.d.ts +1 -0
- package/dist/streaming/codec.d.ts.map +1 -0
- package/dist/streaming/fmp4Segmenter.d.ts +29 -2
- package/dist/streaming/fmp4Segmenter.d.ts.map +1 -0
- package/dist/streaming/fmp4Segmenter.js +79 -26
- package/dist/streaming/fmp4Segmenter.js.map +1 -1
- package/dist/streaming/hls.d.ts +18 -7
- package/dist/streaming/hls.d.ts.map +1 -0
- package/dist/streaming/hls.js +220 -120
- package/dist/streaming/hls.js.map +1 -1
- package/dist/streaming/hlsResume.d.ts +1 -0
- package/dist/streaming/hlsResume.d.ts.map +1 -0
- package/dist/streaming/hlsResume.js +1 -1
- package/dist/streaming/hlsResume.js.map +1 -1
- package/dist/streaming/hlsSegments.d.ts +59 -2
- package/dist/streaming/hlsSegments.d.ts.map +1 -0
- package/dist/streaming/hlsSegments.js +147 -17
- package/dist/streaming/hlsSegments.js.map +1 -1
- package/dist/streaming/lifecycle.d.ts +4 -1
- package/dist/streaming/lifecycle.d.ts.map +1 -0
- package/dist/streaming/lifecycle.js +65 -85
- package/dist/streaming/lifecycle.js.map +1 -1
- package/dist/streaming/monitor.d.ts +6 -4
- package/dist/streaming/monitor.d.ts.map +1 -0
- package/dist/streaming/monitor.js +343 -145
- package/dist/streaming/monitor.js.map +1 -1
- package/dist/streaming/mp4Parser.d.ts +5 -4
- package/dist/streaming/mp4Parser.d.ts.map +1 -0
- package/dist/streaming/mp4Parser.js +36 -13
- package/dist/streaming/mp4Parser.js.map +1 -1
- package/dist/streaming/mpegts.d.ts +16 -0
- package/dist/streaming/mpegts.d.ts.map +1 -0
- package/dist/streaming/mpegts.js +61 -17
- package/dist/streaming/mpegts.js.map +1 -1
- package/dist/streaming/playlistBuilder.d.ts +1 -0
- package/dist/streaming/playlistBuilder.d.ts.map +1 -0
- package/dist/streaming/preroll.d.ts +32 -5
- package/dist/streaming/preroll.d.ts.map +1 -0
- package/dist/streaming/preroll.js +70 -32
- package/dist/streaming/preroll.js.map +1 -1
- package/dist/streaming/pretune.d.ts +26 -1
- package/dist/streaming/pretune.d.ts.map +1 -0
- package/dist/streaming/pretune.js +22 -24
- package/dist/streaming/pretune.js.map +1 -1
- package/dist/streaming/pretuneTimers.d.ts +24 -0
- package/dist/streaming/pretuneTimers.d.ts.map +1 -0
- package/dist/streaming/pretuneTimers.js +56 -0
- package/dist/streaming/pretuneTimers.js.map +1 -0
- package/dist/streaming/recovery.d.ts +139 -5
- package/dist/streaming/recovery.d.ts.map +1 -0
- package/dist/streaming/recovery.js +160 -16
- package/dist/streaming/recovery.js.map +1 -1
- package/dist/streaming/registry.d.ts +27 -9
- package/dist/streaming/registry.d.ts.map +1 -0
- package/dist/streaming/registry.js +21 -3
- package/dist/streaming/registry.js.map +1 -1
- package/dist/streaming/setup.d.ts +157 -29
- package/dist/streaming/setup.d.ts.map +1 -0
- package/dist/streaming/setup.js +1034 -458
- package/dist/streaming/setup.js.map +1 -1
- package/dist/streaming/showInfo.d.ts +21 -1
- package/dist/streaming/showInfo.d.ts.map +1 -0
- package/dist/streaming/showInfo.js +31 -16
- package/dist/streaming/showInfo.js.map +1 -1
- package/dist/streaming/statusEmitter.d.ts +10 -10
- package/dist/streaming/statusEmitter.d.ts.map +1 -0
- package/dist/streaming/statusEmitter.js +5 -8
- package/dist/streaming/statusEmitter.js.map +1 -1
- package/dist/types/channels.d.ts +16 -4
- package/dist/types/channels.d.ts.map +1 -0
- package/dist/types/channels.js +4 -2
- package/dist/types/channels.js.map +1 -1
- package/dist/types/config.d.ts +16 -5
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/index.d.ts +3 -2
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/profiles.d.ts +6 -4
- package/dist/types/profiles.d.ts.map +1 -0
- package/dist/types/selection.d.ts +31 -3
- package/dist/types/selection.d.ts.map +1 -0
- package/dist/types/selection.js +4 -2
- package/dist/types/selection.js.map +1 -1
- package/dist/types/shared.d.ts +1 -0
- package/dist/types/shared.d.ts.map +1 -0
- package/dist/types/streaming.d.ts +8 -0
- package/dist/types/streaming.d.ts.map +1 -0
- package/dist/upgrade/commands.context.d.ts +1 -0
- package/dist/upgrade/commands.context.d.ts.map +1 -0
- package/dist/upgrade/commands.context.js +14 -10
- package/dist/upgrade/commands.context.js.map +1 -1
- package/dist/upgrade/commands.d.ts +8 -15
- package/dist/upgrade/commands.d.ts.map +1 -0
- package/dist/upgrade/commands.js +27 -28
- package/dist/upgrade/commands.js.map +1 -1
- package/dist/upgrade/detection.context.d.ts +1 -0
- package/dist/upgrade/detection.context.d.ts.map +1 -0
- package/dist/upgrade/detection.context.js +4 -1
- package/dist/upgrade/detection.context.js.map +1 -1
- package/dist/upgrade/detection.d.ts +9 -7
- package/dist/upgrade/detection.d.ts.map +1 -0
- package/dist/upgrade/detection.js +23 -54
- package/dist/upgrade/detection.js.map +1 -1
- package/dist/upgrade/index.d.ts +2 -0
- package/dist/upgrade/index.d.ts.map +1 -0
- package/dist/upgrade/index.js +1 -0
- package/dist/upgrade/index.js.map +1 -1
- package/dist/upgrade/lifecycle.context.d.ts +20 -0
- package/dist/upgrade/lifecycle.context.d.ts.map +1 -0
- package/dist/upgrade/lifecycle.context.js +47 -0
- package/dist/upgrade/lifecycle.context.js.map +1 -0
- package/dist/upgrade/lifecycle.d.ts +72 -0
- package/dist/upgrade/lifecycle.d.ts.map +1 -0
- package/dist/upgrade/lifecycle.js +175 -0
- package/dist/upgrade/lifecycle.js.map +1 -0
- package/dist/upgrade/pathHandle.d.ts +30 -0
- package/dist/upgrade/pathHandle.d.ts.map +1 -0
- package/dist/upgrade/pathHandle.js +102 -0
- package/dist/upgrade/pathHandle.js.map +1 -0
- package/dist/utils/bootSession.context.d.ts +16 -0
- package/dist/utils/bootSession.context.d.ts.map +1 -0
- package/dist/utils/bootSession.context.js +60 -0
- package/dist/utils/bootSession.context.js.map +1 -0
- package/dist/utils/bootSession.d.ts +17 -0
- package/dist/utils/bootSession.d.ts.map +1 -0
- package/dist/utils/bootSession.js +20 -0
- package/dist/utils/bootSession.js.map +1 -0
- package/dist/utils/chromeFetch.d.ts +1 -0
- package/dist/utils/chromeFetch.d.ts.map +1 -0
- package/dist/utils/cliOutput.d.ts +1 -0
- package/dist/utils/cliOutput.d.ts.map +1 -0
- package/dist/utils/clock.d.ts +5 -4
- package/dist/utils/clock.d.ts.map +1 -0
- package/dist/utils/clock.js +19 -16
- package/dist/utils/clock.js.map +1 -1
- package/dist/utils/debugFilter.d.ts +9 -1
- package/dist/utils/debugFilter.d.ts.map +1 -0
- package/dist/utils/debugFilter.js +60 -33
- package/dist/utils/debugFilter.js.map +1 -1
- package/dist/utils/delay.d.ts +48 -15
- package/dist/utils/delay.d.ts.map +1 -0
- package/dist/utils/delay.js +73 -20
- package/dist/utils/delay.js.map +1 -1
- package/dist/utils/errors.d.ts +32 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +45 -4
- package/dist/utils/errors.js.map +1 -1
- package/dist/utils/evaluate.d.ts +1 -0
- package/dist/utils/evaluate.d.ts.map +1 -0
- package/dist/utils/evaluate.js +29 -23
- package/dist/utils/evaluate.js.map +1 -1
- package/dist/utils/ffmpeg.context.d.ts +1 -0
- package/dist/utils/ffmpeg.context.d.ts.map +1 -0
- package/dist/utils/ffmpeg.context.js.map +1 -1
- package/dist/utils/ffmpeg.d.ts +29 -7
- package/dist/utils/ffmpeg.d.ts.map +1 -0
- package/dist/utils/ffmpeg.js +32 -14
- package/dist/utils/ffmpeg.js.map +1 -1
- package/dist/utils/fileLogger.d.ts +3 -1
- package/dist/utils/fileLogger.d.ts.map +1 -0
- package/dist/utils/fileLogger.js +64 -29
- package/dist/utils/fileLogger.js.map +1 -1
- package/dist/utils/format.d.ts +14 -1
- package/dist/utils/format.d.ts.map +1 -0
- package/dist/utils/format.js +19 -5
- package/dist/utils/format.js.map +1 -1
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +3 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/logEmitter.d.ts +1 -0
- package/dist/utils/logEmitter.d.ts.map +1 -0
- package/dist/utils/logger.d.ts +1 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +10 -6
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/m3u.d.ts +3 -2
- package/dist/utils/m3u.d.ts.map +1 -0
- package/dist/utils/m3u.js +4 -3
- package/dist/utils/m3u.js.map +1 -1
- package/dist/utils/markup.d.ts +13 -1
- package/dist/utils/markup.d.ts.map +1 -0
- package/dist/utils/markup.js +28 -4
- package/dist/utils/markup.js.map +1 -1
- package/dist/utils/memo.d.ts +3 -2
- package/dist/utils/memo.d.ts.map +1 -0
- package/dist/utils/memo.js +3 -3
- package/dist/utils/morganStream.d.ts +1 -0
- package/dist/utils/morganStream.d.ts.map +1 -0
- package/dist/utils/network.d.ts +1 -0
- package/dist/utils/network.d.ts.map +1 -0
- package/dist/utils/network.js +2 -2
- package/dist/utils/pid.d.ts +3 -25
- package/dist/utils/pid.d.ts.map +1 -0
- package/dist/utils/pid.js +10 -49
- package/dist/utils/pid.js.map +1 -1
- package/dist/utils/platform.d.ts +3 -1
- package/dist/utils/platform.d.ts.map +1 -0
- package/dist/utils/platform.js +2 -1
- package/dist/utils/platform.js.map +1 -1
- package/dist/utils/processInspector.context.d.ts +8 -0
- package/dist/utils/processInspector.context.d.ts.map +1 -0
- package/dist/utils/processInspector.context.js +106 -0
- package/dist/utils/processInspector.context.js.map +1 -0
- package/dist/utils/processInspector.d.ts +55 -0
- package/dist/utils/processInspector.d.ts.map +1 -0
- package/dist/utils/processInspector.js +127 -0
- package/dist/utils/processInspector.js.map +1 -0
- package/dist/utils/retry.d.ts +25 -2
- package/dist/utils/retry.d.ts.map +1 -0
- package/dist/utils/retry.js +33 -6
- package/dist/utils/retry.js.map +1 -1
- package/dist/utils/runtimeIdentity.context.d.ts +7 -0
- package/dist/utils/runtimeIdentity.context.d.ts.map +1 -0
- package/dist/utils/runtimeIdentity.context.js +43 -0
- package/dist/utils/runtimeIdentity.context.js.map +1 -0
- package/dist/utils/runtimeIdentity.d.ts +98 -0
- package/dist/utils/runtimeIdentity.d.ts.map +1 -0
- package/dist/utils/runtimeIdentity.js +181 -0
- package/dist/utils/runtimeIdentity.js.map +1 -0
- package/dist/utils/sanitize.d.ts +1 -0
- package/dist/utils/sanitize.d.ts.map +1 -0
- package/dist/utils/streamContext.d.ts +2 -1
- package/dist/utils/streamContext.d.ts.map +1 -0
- package/dist/utils/streamContext.js +1 -1
- package/dist/utils/timing.d.ts +2 -1
- package/dist/utils/timing.d.ts.map +1 -0
- package/dist/utils/timing.js +0 -5
- package/dist/utils/timing.js.map +1 -1
- package/dist/utils/version.d.ts +1 -0
- package/dist/utils/version.d.ts.map +1 -0
- package/dist/utils/version.js +47 -13
- package/dist/utils/version.js.map +1 -1
- package/package.json +26 -20
package/dist/config/health.js
CHANGED
|
@@ -6,8 +6,10 @@ import { EventEmitter } from "node:events";
|
|
|
6
6
|
import { LOG } from "../utils/index.js";
|
|
7
7
|
import { createFileStore } from "./persistence.js";
|
|
8
8
|
import { getHealthFilePath } from "./paths.js";
|
|
9
|
-
// Health event emitter. Fires on every
|
|
9
|
+
// Health event emitter. Fires on every domain auth or channel health mutation so SSE clients receive real-time indicator updates.
|
|
10
10
|
const healthEmitter = new EventEmitter();
|
|
11
|
+
// The health bridge (installHealthBridge) is the only production subscriber, holding one listener for the life of the process. We still lift the cap from Node's
|
|
12
|
+
// default of 10 to 100 as headroom for the test suite's repeated subscribe/unsubscribe cycles within a shared process, avoiding a spurious MaxListenersExceededWarning.
|
|
11
13
|
healthEmitter.setMaxListeners(100);
|
|
12
14
|
// Constants.
|
|
13
15
|
// Entries older than 7 days are pruned at load time.
|
|
@@ -16,20 +18,73 @@ const HEALTH_TTL = 7 * 24 * 60 * 60 * 1000;
|
|
|
16
18
|
const FLUSH_DELAY = 2000;
|
|
17
19
|
// Returns true if the given timestamp is older than HEALTH_TTL.
|
|
18
20
|
const isHealthExpired = (timestamp) => (Date.now() - timestamp) >= HEALTH_TTL;
|
|
21
|
+
/* Returns true when a domain auth entry has aged out. Only verified entries expire - verification is aging evidence with a shelf life. Needs-sign-in entries are
|
|
22
|
+
* exempt: they describe a standing account condition that only new evidence (a sign-in followed by success, or an unproven-access discovery) resolves. This predicate
|
|
23
|
+
* is the single expression of that status-aware TTL rule, shared by the load filter, the bulk prune, and the single-key read path.
|
|
24
|
+
*/
|
|
25
|
+
const isDomainAuthExpired = (entry) => (entry.status === "verified") && isHealthExpired(entry.timestamp);
|
|
26
|
+
/* Converts a persisted domain auth value to the entry shape. Bare numbers are the legacy timestamp form, whose presence meant verified. The v1 to v2 schema migration
|
|
27
|
+
* converts whole files through this function, and the load path applies it per-value as well: an older binary performing a forward-compatible read of a v2 file
|
|
28
|
+
* writes bare numbers back into it without downgrading the schema version, so the migration never re-runs for that file and tolerance has to live at the load
|
|
29
|
+
* boundary too. One converter, two call sites, one definition of the legacy form.
|
|
30
|
+
*/
|
|
31
|
+
const adoptDomainAuthValue = (value) => (typeof value === "number") ? { status: "verified", timestamp: value } : value;
|
|
19
32
|
// In-memory state.
|
|
20
33
|
const channelHealth = new Map();
|
|
21
|
-
// Domain
|
|
34
|
+
// Domain authentication state. The unknown state is the absence of an entry; verified and needs-sign-in are entry-valued per DomainAuthEntry.
|
|
22
35
|
const domainAuth = new Map();
|
|
23
36
|
// Debounce timer for flushHealthState().
|
|
24
37
|
let flushTimer = null;
|
|
38
|
+
/* Whether the initial load has hydrated the maps above. Both maps start empty, so they describe real state only once loadHealthState has read health.json into
|
|
39
|
+
* them...writeHealthState consults this so a shutdown signal arriving before the load completes cannot overwrite a populated health.json with the empty maps.
|
|
40
|
+
*/
|
|
41
|
+
let healthStateLoaded = false;
|
|
42
|
+
/* Drops every expired entry from the in-memory maps so the maps stay bounded for the life of the process. Without this the maps would only ever grow - read paths
|
|
43
|
+
* only delete the single stale key they touch, never the untouched remainder, so a channel tuned once and never revisited would linger forever. We run this at the
|
|
44
|
+
* single write chokepoint (writeHealthState) so the on-disk record never carries stale entries, and again from getHealthSnapshot so a long-lived process that stops
|
|
45
|
+
* mutating still sheds its expired state.
|
|
46
|
+
*/
|
|
47
|
+
const pruneExpiredEntries = () => {
|
|
48
|
+
for (const [key, entry] of channelHealth) {
|
|
49
|
+
if (isHealthExpired(entry.timestamp)) {
|
|
50
|
+
channelHealth.delete(key);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
for (const [key, entry] of domainAuth) {
|
|
54
|
+
if (isDomainAuthExpired(entry)) {
|
|
55
|
+
domainAuth.delete(key);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
};
|
|
25
59
|
// Persistence.
|
|
26
|
-
/* Current schema version for health.json.
|
|
27
|
-
*
|
|
60
|
+
/* Current schema version for health.json.
|
|
61
|
+
*
|
|
62
|
+
* Version history:
|
|
63
|
+
* 1 - Original. Domain auth entries are bare Unix millisecond timestamps; the presence of a non-expired value means verified.
|
|
64
|
+
* 2 - Status-bearing domain auth. Each domain value becomes { status, timestamp } so a domain can carry the needs-sign-in state alongside verified.
|
|
65
|
+
*/
|
|
66
|
+
const CURRENT_HEALTH_SCHEMA_VERSION = 2;
|
|
67
|
+
/* Declarative schema migrations. The file store framework runs these in order from the file's stored schemaVersion up to CURRENT_HEALTH_SCHEMA_VERSION, stamping the
|
|
68
|
+
* new version and recording the description in migrationsApplied after each application. Apply functions mutate the data in place.
|
|
28
69
|
*/
|
|
29
|
-
const
|
|
70
|
+
const healthMigrations = {
|
|
71
|
+
2: {
|
|
72
|
+
apply: (data) => {
|
|
73
|
+
/* Cast to the pre-migration shape: v1 files store bare-number timestamps that the parser passes through unmodified so this migration can transform them.
|
|
74
|
+
* Values already in the entry shape pass through the converter untouched, so the migration is safe to run more than once over partially-converted content.
|
|
75
|
+
*/
|
|
76
|
+
const domains = data.domains;
|
|
77
|
+
for (const [domain, value] of Object.entries(domains)) {
|
|
78
|
+
domains[domain] = adoptDomainAuthValue(value);
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
description: "Convert bare-number domain auth timestamps to status-bearing entries"
|
|
82
|
+
}
|
|
83
|
+
};
|
|
30
84
|
/* Transactional store for health.json. The parser tolerates the absence of either top-level data field so older files (and partial writes from prior versions
|
|
31
|
-
* predating both keys) load cleanly.
|
|
32
|
-
*
|
|
85
|
+
* predating both keys) load cleanly. Legacy bare-number domain values pass through the parser unmodified - the framework runs migrations after parse, so the v1 to v2
|
|
86
|
+
* migration is what transforms them. The beforeWrite hook emits framework metadata alongside the data; data fields are emitted unconditionally since the runtime
|
|
87
|
+
* always populates them on every flush.
|
|
33
88
|
*/
|
|
34
89
|
const healthStore = createFileStore({
|
|
35
90
|
beforeWrite: (data) => {
|
|
@@ -43,7 +98,10 @@ const healthStore = createFileStore({
|
|
|
43
98
|
defaultValue: () => ({ channels: {}, domains: {}, migrationsApplied: [], schemaVersion: CURRENT_HEALTH_SCHEMA_VERSION }),
|
|
44
99
|
getSchemaVersion: (data) => data.schemaVersion,
|
|
45
100
|
label: "health state",
|
|
101
|
+
migrations: healthMigrations,
|
|
46
102
|
parse: (raw) => {
|
|
103
|
+
// The domains field is typed as a value union here rather than as the current entry shape: v1 files hold bare numbers, and the migration (which runs after
|
|
104
|
+
// parse) is what converts them. Parse must hand those values through unmodified or the migration would have nothing to transform.
|
|
47
105
|
const parsed = JSON.parse(raw);
|
|
48
106
|
let schemaVersion = 1;
|
|
49
107
|
if ((typeof parsed.schemaVersion === "number") && Number.isFinite(parsed.schemaVersion) && (parsed.schemaVersion >= 1)) {
|
|
@@ -59,17 +117,20 @@ const healthStore = createFileStore({
|
|
|
59
117
|
}
|
|
60
118
|
return {
|
|
61
119
|
channels: parsed.channels ?? {},
|
|
62
|
-
domains: parsed.domains ?? {},
|
|
120
|
+
domains: (parsed.domains ?? {}),
|
|
63
121
|
migrationsApplied,
|
|
64
122
|
schemaVersion
|
|
65
123
|
};
|
|
66
124
|
},
|
|
67
125
|
path: getHealthFilePath,
|
|
126
|
+
recordMigration: (data, description) => {
|
|
127
|
+
data.migrationsApplied.push(description);
|
|
128
|
+
},
|
|
68
129
|
setSchemaVersion: (data, version) => { data.schemaVersion = version; }
|
|
69
130
|
});
|
|
70
131
|
/**
|
|
71
|
-
* Loads the health state from health.json into memory.
|
|
72
|
-
*
|
|
132
|
+
* Loads the health state from health.json into memory. Expired entries are pruned during loading. Called once at startup from app.ts. Loading is also what arms
|
|
133
|
+
* persistence - writeHealthState serializes the in-memory maps only once this function has hydrated them from disk.
|
|
73
134
|
*/
|
|
74
135
|
export async function loadHealthState() {
|
|
75
136
|
const result = await healthStore.read();
|
|
@@ -80,11 +141,16 @@ export async function loadHealthState() {
|
|
|
80
141
|
channelHealth.set(key, entry);
|
|
81
142
|
}
|
|
82
143
|
}
|
|
83
|
-
for (const [key,
|
|
84
|
-
|
|
85
|
-
|
|
144
|
+
for (const [key, value] of Object.entries(result.data.domains)) {
|
|
145
|
+
// Adopt each value at the load boundary. Post-migration data is already entry-shaped; the conversion covers bare numbers written by an older binary into a
|
|
146
|
+
// v2-stamped file, which the migration runner never revisits.
|
|
147
|
+
const entry = adoptDomainAuthValue(value);
|
|
148
|
+
if (!isDomainAuthExpired(entry)) {
|
|
149
|
+
domainAuth.set(key, entry);
|
|
86
150
|
}
|
|
87
151
|
}
|
|
152
|
+
// The maps hold what health.json describes from here on, so the write chokepoint may persist them.
|
|
153
|
+
healthStateLoaded = true;
|
|
88
154
|
if (result.recoveredFromBackup) {
|
|
89
155
|
LOG.info("Health state was recovered from backup after a corrupt main file.");
|
|
90
156
|
}
|
|
@@ -94,6 +160,29 @@ export async function loadHealthState() {
|
|
|
94
160
|
LOG.info("Loaded health state for %d channels and %d domains.", channelCount, domainCount);
|
|
95
161
|
}
|
|
96
162
|
}
|
|
163
|
+
/**
|
|
164
|
+
* Writes the current in-memory health maps to health.json via the transactional file store. Health writes always emit the full state - there is no per-key delta
|
|
165
|
+
* semantic. Shared by the debounced flushHealthState (on the timer) and the immediate flushHealthStateNow (on shutdown), so both go through one write definition.
|
|
166
|
+
* The write is gated on the initial load, so neither path can persist the empty startup state over a populated file.
|
|
167
|
+
* @returns A promise that resolves when the store has committed the write.
|
|
168
|
+
*/
|
|
169
|
+
async function writeHealthState() {
|
|
170
|
+
/* Until the initial load has run, the in-memory maps are empty rather than authoritative, and serializing them would replace a populated health.json with
|
|
171
|
+
* nothing. A shutdown signal arriving between the signal handlers being installed and the load completing takes exactly that path. The skip is silent because
|
|
172
|
+
* there is genuinely nothing to persist yet. The gate governs this function's serialization of the in-memory maps and nothing else - the file store framework's
|
|
173
|
+
* schema-migration persist is a separate, disk-derived write that must proceed regardless of whether this module has loaded.
|
|
174
|
+
*/
|
|
175
|
+
if (!healthStateLoaded) {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
// Shed expired entries before serializing so the on-disk record never carries stale state and the in-memory maps stay bounded across the process lifetime. This is
|
|
179
|
+
// the periodic chokepoint - every mark* mutation schedules a flush through here, so pruning at this point keeps both memory and disk free of expired entries.
|
|
180
|
+
pruneExpiredEntries();
|
|
181
|
+
await healthStore.mutate((state) => {
|
|
182
|
+
state.channels = Object.fromEntries(channelHealth);
|
|
183
|
+
state.domains = Object.fromEntries(domainAuth);
|
|
184
|
+
});
|
|
185
|
+
}
|
|
97
186
|
/**
|
|
98
187
|
* Writes the current in-memory health state to health.json via the transactional file store. Debounced - multiple calls within FLUSH_DELAY are coalesced into a
|
|
99
188
|
* single write. The store's serialization queue handles the case where a flush fires while a prior mutation is still in flight, so no in-module write-in-progress
|
|
@@ -105,15 +194,52 @@ function flushHealthState() {
|
|
|
105
194
|
}
|
|
106
195
|
flushTimer = setTimeout(() => {
|
|
107
196
|
flushTimer = null;
|
|
108
|
-
void
|
|
109
|
-
// Replace the on-disk state with a fresh snapshot of the in-memory maps. Health writes always emit the full state - there is no per-key delta semantic.
|
|
110
|
-
state.channels = Object.fromEntries(channelHealth);
|
|
111
|
-
state.domains = Object.fromEntries(domainAuth);
|
|
112
|
-
}).catch((error) => {
|
|
197
|
+
void writeHealthState().catch((error) => {
|
|
113
198
|
LOG.warn("Failed to write health state: %s.", (error instanceof Error) ? error.message : String(error));
|
|
114
199
|
});
|
|
115
200
|
}, FLUSH_DELAY);
|
|
116
201
|
}
|
|
202
|
+
/**
|
|
203
|
+
* Flushes the health state to disk immediately, cancelling any pending debounced write and awaiting the on-disk write. Called during graceful shutdown so the final
|
|
204
|
+
* health update is durably written even when the process exits inside the FLUSH_DELAY debounce window. Writing unconditionally (rather than only when a debounce is
|
|
205
|
+
* pending) also drains any in-flight mutation behind the store's serialization queue, guaranteeing the on-disk record matches the final in-memory state.
|
|
206
|
+
* @returns A promise that resolves when the final health-state write has committed.
|
|
207
|
+
*/
|
|
208
|
+
export async function flushHealthStateNow() {
|
|
209
|
+
if (flushTimer) {
|
|
210
|
+
clearTimeout(flushTimer);
|
|
211
|
+
flushTimer = null;
|
|
212
|
+
}
|
|
213
|
+
// Best-effort write: a store failure during shutdown is logged but must not propagate, or it would abort the rest of the shutdown teardown (the caller awaits this
|
|
214
|
+
// without its own guard). This mirrors the debounced path's .catch above - both write paths log and continue on error rather than throwing.
|
|
215
|
+
try {
|
|
216
|
+
await writeHealthState();
|
|
217
|
+
}
|
|
218
|
+
catch (error) {
|
|
219
|
+
LOG.warn("Failed to write health state during shutdown: %s.", (error instanceof Error) ? error.message : String(error));
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
// Write chokepoints. Every domain auth transition flows through one of two private mutators below (verified, removal) or the inline needs-sign-in write in
|
|
223
|
+
// markDomainAuthRequired, so the entry shape and the flush-plus-emit sequence for each transition are written in exactly one place.
|
|
224
|
+
/* Sets a domain's auth entry to verified, schedules a flush, and emits the change event. The single write chokepoint for the verified transition - both
|
|
225
|
+
* markChannelSuccess's markAuth path (channel-scoped event) and markDomainAuth (domain-scoped event with an empty channelKey) flow through here, so each caller
|
|
226
|
+
* produces exactly one event and the entry it describes is constructed in exactly one place.
|
|
227
|
+
*/
|
|
228
|
+
function setDomainVerified(channelKey, domain, timestamp) {
|
|
229
|
+
domainAuth.set(domain, { status: "verified", timestamp });
|
|
230
|
+
flushHealthState();
|
|
231
|
+
healthEmitter.emit("healthChanged", { channelKey, domain, status: "success", timestamp });
|
|
232
|
+
}
|
|
233
|
+
/* Removes a domain's auth entry, returning the domain to the unknown state, then schedules a flush and emits the change event. The single deletion chokepoint. The
|
|
234
|
+
* emitted status is "failed": the event union has no member for unknown because no consumer branches on status (the health bridge re-renders affected rows from
|
|
235
|
+
* current truth), and "failed" is the one value that collides with neither the verified transition ("success") nor the needs-sign-in transition ("needsLogin"),
|
|
236
|
+
* keeping the three domain-scoped transitions distinguishable to subscribers.
|
|
237
|
+
*/
|
|
238
|
+
function removeDomainAuth(domain) {
|
|
239
|
+
domainAuth.delete(domain);
|
|
240
|
+
flushHealthState();
|
|
241
|
+
healthEmitter.emit("healthChanged", { channelKey: "", domain, status: "failed", timestamp: Date.now() });
|
|
242
|
+
}
|
|
117
243
|
// Public API.
|
|
118
244
|
/**
|
|
119
245
|
* Records a successful tune for a channel. Sets the channel's health to "success" and optionally marks the domain as verified (authenticated). Triggers a debounced
|
|
@@ -126,8 +252,10 @@ function flushHealthState() {
|
|
|
126
252
|
export function markChannelSuccess(channelKey, domain, markAuth = true) {
|
|
127
253
|
const now = Date.now();
|
|
128
254
|
channelHealth.set(channelKey, { domain, status: "success", timestamp: now });
|
|
255
|
+
// The verified write chokepoint emits the channel-scoped success event on our behalf, so both paths produce exactly one event per call with the same payload.
|
|
129
256
|
if (markAuth) {
|
|
130
|
-
|
|
257
|
+
setDomainVerified(channelKey, domain, now);
|
|
258
|
+
return;
|
|
131
259
|
}
|
|
132
260
|
flushHealthState();
|
|
133
261
|
healthEmitter.emit("healthChanged", { channelKey, domain, status: "success", timestamp: now });
|
|
@@ -138,10 +266,30 @@ export function markChannelSuccess(channelKey, domain, markAuth = true) {
|
|
|
138
266
|
* @param domain - The domain to mark as authenticated.
|
|
139
267
|
*/
|
|
140
268
|
export function markDomainAuth(domain) {
|
|
269
|
+
setDomainVerified("", domain, Date.now());
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Records that a domain needs sign-in. Used when a confirmed provider authentication wall is observed during channel discovery. Overwrites any existing entry for
|
|
273
|
+
* the domain, triggers a debounced flush, and emits a health event with an empty channelKey and the "needsLogin" status.
|
|
274
|
+
* @param domain - The domain that needs sign-in.
|
|
275
|
+
*/
|
|
276
|
+
export function markDomainAuthRequired(domain) {
|
|
141
277
|
const now = Date.now();
|
|
142
|
-
domainAuth.set(domain, now);
|
|
278
|
+
domainAuth.set(domain, { status: "needsLogin", timestamp: now });
|
|
143
279
|
flushHealthState();
|
|
144
|
-
healthEmitter.emit("healthChanged", { channelKey: "", domain, status: "
|
|
280
|
+
healthEmitter.emit("healthChanged", { channelKey: "", domain, status: "needsLogin", timestamp: now });
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Clears a domain's needs-sign-in entry, returning the domain to the unknown state. Used when a non-empty discovery proves the auth wall is gone but the provider's
|
|
284
|
+
* validation cannot prove paid access (e.g., Sling's free-tier lineup appears without a subscription) - the red state must not outlive the wall it reported, but the
|
|
285
|
+
* domain has not earned verified either. A no-op unless the domain's current state is needs-sign-in: verified entries are never deleted by unproven-access evidence.
|
|
286
|
+
* @param domain - The domain whose needs-sign-in entry should be cleared.
|
|
287
|
+
*/
|
|
288
|
+
export function clearDomainAuthRequirement(domain) {
|
|
289
|
+
if (domainAuth.get(domain)?.status !== "needsLogin") {
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
removeDomainAuth(domain);
|
|
145
293
|
}
|
|
146
294
|
/**
|
|
147
295
|
* Records a failed tune for a channel. Sets the channel's health to "failed". Does not affect domain auth - a single channel failure doesn't prove the domain is
|
|
@@ -167,8 +315,10 @@ export function getChannelHealth(channelKey, domain) {
|
|
|
167
315
|
if (!entry) {
|
|
168
316
|
return null;
|
|
169
317
|
}
|
|
170
|
-
// Stale entry - older than TTL.
|
|
318
|
+
// Stale entry - older than TTL. We delete it here as well as returning null so that a key that is read but never re-marked does not linger in memory; this read path
|
|
319
|
+
// touches exactly one key, so we prune just that key rather than paying for a full-map scan.
|
|
171
320
|
if (isHealthExpired(entry.timestamp)) {
|
|
321
|
+
channelHealth.delete(channelKey);
|
|
172
322
|
return null;
|
|
173
323
|
}
|
|
174
324
|
// Domain was switched - the stored result is for a different domain.
|
|
@@ -178,38 +328,39 @@ export function getChannelHealth(channelKey, domain) {
|
|
|
178
328
|
return { status: entry.status, timestamp: entry.timestamp };
|
|
179
329
|
}
|
|
180
330
|
/**
|
|
181
|
-
* Returns
|
|
182
|
-
*
|
|
331
|
+
* Returns a domain's authentication state entry, or null when the domain is unknown (no entry, or a verified entry older than the TTL). Needs-sign-in entries are
|
|
332
|
+
* exempt from the TTL per the module's status-aware expiry rule.
|
|
183
333
|
* @param domain - The domain to check.
|
|
184
|
-
* @returns
|
|
334
|
+
* @returns The domain's auth entry, or null if unknown.
|
|
185
335
|
*/
|
|
186
|
-
export function
|
|
187
|
-
const
|
|
188
|
-
if (
|
|
336
|
+
export function getDomainAuthState(domain) {
|
|
337
|
+
const entry = domainAuth.get(domain);
|
|
338
|
+
if (!entry) {
|
|
189
339
|
return null;
|
|
190
340
|
}
|
|
191
|
-
// Stale entry -
|
|
192
|
-
|
|
341
|
+
// Stale entry - only verified entries age out. We delete it here as well as returning null so that a domain that is read but never re-marked does not linger in
|
|
342
|
+
// memory; this read path touches exactly one key, so we prune just that key rather than paying for a full-map scan.
|
|
343
|
+
if (isDomainAuthExpired(entry)) {
|
|
344
|
+
domainAuth.delete(domain);
|
|
193
345
|
return null;
|
|
194
346
|
}
|
|
195
|
-
return timestamp;
|
|
347
|
+
return { status: entry.status, timestamp: entry.timestamp };
|
|
196
348
|
}
|
|
197
349
|
/**
|
|
198
350
|
* Returns a snapshot of current health state for SSE initial payloads. Stale entries (older than HEALTH_TTL) are excluded.
|
|
199
351
|
* @returns Snapshot with channel health and domain auth maps.
|
|
200
352
|
*/
|
|
201
353
|
export function getHealthSnapshot() {
|
|
354
|
+
// Snapshots iterate the entire map, so this is the natural read-side chokepoint to shed expired entries. A long-lived process that stops mutating still drops its
|
|
355
|
+
// stale state on the next SSE client connection, which is when snapshots are taken.
|
|
356
|
+
pruneExpiredEntries();
|
|
202
357
|
const channels = {};
|
|
203
358
|
const domains = {};
|
|
204
359
|
for (const [key, entry] of channelHealth) {
|
|
205
|
-
|
|
206
|
-
channels[key] = { domain: entry.domain, status: entry.status, timestamp: entry.timestamp };
|
|
207
|
-
}
|
|
360
|
+
channels[key] = { domain: entry.domain, status: entry.status, timestamp: entry.timestamp };
|
|
208
361
|
}
|
|
209
|
-
for (const [domainKey,
|
|
210
|
-
|
|
211
|
-
domains[domainKey] = timestamp;
|
|
212
|
-
}
|
|
362
|
+
for (const [domainKey, entry] of domainAuth) {
|
|
363
|
+
domains[domainKey] = { status: entry.status, timestamp: entry.timestamp };
|
|
213
364
|
}
|
|
214
365
|
return { channels, domains };
|
|
215
366
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"health.js","sourceRoot":"","sources":["../../src/config/health.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"health.js","sourceRoot":"","sources":["../../src/config/health.ts"],"names":[],"mappings":"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"}
|
package/dist/config/index.d.ts
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
|
+
import type { ApplyResult, ChangeOutcome, ConfigChange } from "./reactivity.ts";
|
|
1
2
|
import type { Config, Nullable } from "../types/index.ts";
|
|
3
|
+
import { mutateConfig, readConfig } from "./userConfig.ts";
|
|
2
4
|
/**
|
|
3
5
|
* CLI override map. Keys are dot-separated CONFIG_METADATA paths (e.g., "server.port", "paths.chromeDataDir"). Values are the parsed CLI flag values. Applied as the
|
|
4
6
|
* highest-priority merge pass in mergeConfiguration().
|
|
5
7
|
*/
|
|
6
8
|
export type CliOverrides = Record<string, unknown>;
|
|
9
|
+
export interface ConfigStore {
|
|
10
|
+
readonly mutateConfig: typeof mutateConfig;
|
|
11
|
+
readonly readConfig: typeof readConfig;
|
|
12
|
+
}
|
|
7
13
|
export declare let CONFIG: Config;
|
|
8
14
|
/**
|
|
9
15
|
* Indicates whether a user config file parse error occurred during initialization. The web UI displays a warning when this is true.
|
|
@@ -18,7 +24,42 @@ export declare let configParseErrorMessage: string | undefined;
|
|
|
18
24
|
* must be called at startup before any code accesses CONFIG. After initialization, the CONFIG object contains the final merged values.
|
|
19
25
|
* @param cliOverrides - Optional CLI flag overrides, applied at the highest priority level.
|
|
20
26
|
*/
|
|
21
|
-
export declare function initializeConfiguration(cliOverrides?: CliOverrides): Promise<void>;
|
|
27
|
+
export declare function initializeConfiguration(cliOverrides?: CliOverrides, io?: ConfigStore): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* 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
|
|
30
|
+
* binding, and dispatches the resulting diff to registered config-change handlers. This is the single entry point for "config changed - tell subsystems"; both
|
|
31
|
+
* the /config save handler and /config/import handler call it after writing to disk. The returned ApplyResult partitions the diff into changes that were
|
|
32
|
+
* applied live, deferred (requiring restart), or rejected (refused by a handler). Callers use the deferred count to decide whether to schedule a restart.
|
|
33
|
+
*
|
|
34
|
+
* Atomicity contract: failures during the read, merge, or normalize steps leave CONFIG completely untouched - the function builds the new shape in isolation
|
|
35
|
+
* and only reassigns the live binding after all of those steps succeed. Failures DURING handler dispatch, however, occur after the CONFIG reassignment: CONFIG
|
|
36
|
+
* 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
|
|
37
|
+
* report outcomes (including "rejected") instead. That atomicity-on-read behavior is exercised by index.reload.test.ts.
|
|
38
|
+
*
|
|
39
|
+
* Validation contract: before committing, the merged shape is re-checked against the same hard-error and capture-coercion checks the startup path enforces.
|
|
40
|
+
* 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
|
|
41
|
+
* captureCodecs list missing the h264 baseline) is rejected rather than silently coerced: CONFIG stays on the previous valid state and every diffed change is
|
|
42
|
+
* 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
|
|
43
|
+
* configuration into the live binding without passing through validateConfiguration. The reject-on-invalid path is exercised by index.reload.test.ts.
|
|
44
|
+
*
|
|
45
|
+
* 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
|
|
46
|
+
* 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
|
|
47
|
+
* ones. This extends the handler contract: a registered config-change handler must never call reloadConfiguration, because a queued reload awaiting a nested
|
|
48
|
+
* reload would deadlock the chain.
|
|
49
|
+
* @returns The aggregate result of dispatching the diff.
|
|
50
|
+
*/
|
|
51
|
+
export declare function reloadConfiguration(io?: ConfigStore): Promise<ApplyResult>;
|
|
52
|
+
/**
|
|
53
|
+
* Live-applies the "logging." subset of a config diff. The debug filter is applied live by commitDebugFilter during reloadConfiguration - the runtime filter is
|
|
54
|
+
* 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
|
|
55
|
+
* effect immediately instead of waiting for one. The remaining logging fields (httpLogLevel, maxSize) are consumed when the logger and HTTP middleware are wired
|
|
56
|
+
* at startup, so they defer to a restart.
|
|
57
|
+
*
|
|
58
|
+
* Exported so tests can invoke the dispatch directly with a synthetic diff. Registered with the reactivity primitive at module load (side effect below).
|
|
59
|
+
* @param changes - The subset of the diff whose path begins with "logging.".
|
|
60
|
+
* @returns Per-change outcomes.
|
|
61
|
+
*/
|
|
62
|
+
export declare function applyLoggingConfigChanges(changes: readonly ConfigChange[]): Promise<readonly ChangeOutcome[]>;
|
|
22
63
|
/**
|
|
23
64
|
* Returns a deep copy of the default configuration. Used by the web UI to display default values and handle reset operations.
|
|
24
65
|
* @returns A copy of the default configuration.
|
|
@@ -44,11 +85,21 @@ export declare function validatePositiveInt(name: string, value: number, min?: n
|
|
|
44
85
|
*/
|
|
45
86
|
export declare function validatePositiveNumber(name: string, value: number, min?: number, max?: number): Nullable<string>;
|
|
46
87
|
/**
|
|
47
|
-
* Validates all configuration values and throws an error if any are invalid. This function runs at startup after configuration initialization.
|
|
48
|
-
*
|
|
88
|
+
* Validates all configuration values and throws an error if any are invalid. This function runs at startup after configuration initialization. It first applies
|
|
89
|
+
* the capture coercions in place (filtering captureCodecs, forcing FFmpeg mode, with the same operator-visible warning as before), then collects every hard
|
|
90
|
+
* error against the coerced CONFIG and throws once with the complete list. Splitting the pure collectors (collectCoercions, collectHardErrors) from the in-place
|
|
91
|
+
* application lets reloadConfiguration reuse the same hard-error and capture-coercion checks without silently coercing a live save.
|
|
49
92
|
* @throws If any configuration value is invalid. The error message lists all invalid values.
|
|
50
93
|
*/
|
|
51
94
|
export declare function validateConfiguration(): void;
|
|
95
|
+
/**
|
|
96
|
+
* 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
|
|
97
|
+
* coercion actually occurred. Without this, a config file holding an unsupported capture value (native mode, or a captureCodecs list missing the h264 baseline)
|
|
98
|
+
* 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.
|
|
99
|
+
* 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.
|
|
100
|
+
* 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.
|
|
101
|
+
*/
|
|
102
|
+
export declare function persistCoercedConfig(io?: ConfigStore): Promise<void>;
|
|
52
103
|
/**
|
|
53
104
|
* Displays the active configuration at startup. This helps operators verify their settings and diagnose connection issues. We log only the most commonly adjusted
|
|
54
105
|
* values to keep output concise while providing useful debugging information.
|
|
@@ -61,3 +112,4 @@ export declare function validateConfiguration(): void;
|
|
|
61
112
|
* why their stream resolution may be lower than configured.
|
|
62
113
|
*/
|
|
63
114
|
export declare function displayConfiguration(): void;
|
|
115
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAChF,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAgC,YAAY,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAoCzF;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAOnD,MAAM,WAAW,WAAW;IAE1B,QAAQ,CAAC,YAAY,EAAE,OAAO,YAAY,CAAC;IAC3C,QAAQ,CAAC,UAAU,EAAE,OAAO,UAAU,CAAC;CACxC;AAKD,eAAO,IAAI,MAAM,EAAE,MAAkC,CAAC;AAEtD;;GAEG;AACH,eAAO,IAAI,gBAAgB,SAAQ,CAAC;AAEpC;;GAEG;AACH,eAAO,IAAI,uBAAuB,EAAE,MAAM,GAAG,SAAS,CAAC;AAyBvD;;;;GAIG;AACH,wBAAsB,uBAAuB,CAAC,YAAY,CAAC,EAAE,YAAY,EAAE,EAAE,GAAE,WAAgC,GAAG,OAAO,CAAC,IAAI,CAAC,CA4B9H;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,mBAAmB,CAAC,EAAE,GAAE,WAAgC,GAAG,OAAO,CAAC,WAAW,CAAC,CASpG;AAoGD;;;;;;;;;GASG;AAGH,wBAAsB,yBAAyB,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,OAAO,CAAC,SAAS,aAAa,EAAE,CAAC,CAWnH;AA6BD;;;GAGG;AACH,wBAAgB,WAAW,IAAI,MAAM,CAGpC;AAUD;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAS7G;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAShH;AAiLD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAgB5C;AAED;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CAAC,EAAE,GAAE,WAAgC,GAAG,OAAO,CAAC,IAAI,CAAC,CAqB9F;AA6CD;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CA8B3C"}
|