prismcast 1.10.3 → 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 +1 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +103 -50
- 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 +23 -6
- package/dist/browser/hlsPlaylistObserver.d.ts.map +1 -0
- package/dist/browser/hlsPlaylistObserver.js +27 -8
- package/dist/browser/hlsPlaylistObserver.js.map +1 -1
- package/dist/browser/index.d.ts +44 -27
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +427 -244
- 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 +88 -35
- package/dist/browser/manifestInterceptor.d.ts.map +1 -0
- package/dist/browser/manifestInterceptor.js +165 -77
- 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 +2 -1
- package/dist/browser/tabNetworkObserver.d.ts.map +1 -0
- package/dist/browser/tabNetworkObserver.js +7 -3
- package/dist/browser/tabNetworkObserver.js.map +1 -1
- 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 +15 -11
- 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 +7 -1
- package/dist/config/paths.d.ts.map +1 -0
- package/dist/config/paths.js +8 -1
- 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 +21 -14
- package/dist/config/profiles.d.ts.map +1 -0
- package/dist/config/profiles.js +77 -43
- 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 +16 -10
- package/dist/config/services.d.ts.map +1 -0
- package/dist/config/services.js +27 -16
- package/dist/config/services.js.map +1 -1
- package/dist/config/sites.d.ts +4 -2
- package/dist/config/sites.d.ts.map +1 -0
- package/dist/config/sites.js +9 -5
- package/dist/config/sites.js.map +1 -1
- package/dist/config/userChannels.d.ts +23 -18
- package/dist/config/userChannels.d.ts.map +1 -0
- package/dist/config/userChannels.js +45 -34
- 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 +8 -4
- package/dist/config/userProfiles.d.ts.map +1 -0
- package/dist/config/userProfiles.js +48 -23
- 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 +4 -3
- 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 +39 -16
- package/dist/native/index.d.ts.map +1 -0
- package/dist/native/index.js +273 -103
- 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 +56 -1
- package/dist/native/proxy.d.ts.map +1 -0
- package/dist/native/proxy.js +604 -161
- 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 +4 -3
- package/dist/routes/clientActions.d.ts.map +1 -0
- package/dist/routes/components.d.ts +1 -0
- package/dist/routes/components.d.ts.map +1 -0
- package/dist/routes/components.js +2 -2
- 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 +49 -22
- 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 +1 -0
- package/dist/routes/config/channels/healthBridge.d.ts.map +1 -0
- package/dist/routes/config/channels/healthBridge.js +2 -2
- 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 +55 -27
- 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 +35 -24
- 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 +89 -43
- 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 +2 -2
- 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 +13 -3
- 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 +11 -12
- 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 +10 -8
- 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 +147 -97
- 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 +39 -22
- 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 +52 -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 +18 -6
- package/dist/routes/root/scripts/status.handlers.d.ts.map +1 -0
- package/dist/routes/root/scripts/status.handlers.js +38 -32
- package/dist/routes/root/scripts/status.handlers.js.map +1 -1
- package/dist/routes/root/scripts/status.js +15 -7
- 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 +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 +3 -2
- 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.d.ts +3 -2
- package/dist/service/generators.d.ts.map +1 -0
- package/dist/service/generators.js +108 -20
- 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 +219 -115
- 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 +58 -1
- 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 +31 -4
- package/dist/streaming/preroll.d.ts.map +1 -0
- package/dist/streaming/preroll.js +69 -27
- 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 +5 -2
- package/dist/streaming/statusEmitter.d.ts.map +1 -0
- package/dist/streaming/statusEmitter.js +5 -3
- package/dist/streaming/statusEmitter.js.map +1 -1
- package/dist/types/channels.d.ts +15 -12
- 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 +4 -2
- 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.d.ts +1 -0
- package/dist/upgrade/commands.d.ts.map +1 -0
- package/dist/upgrade/commands.js +1 -1
- 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 +2 -0
- package/dist/upgrade/detection.context.js.map +1 -1
- package/dist/upgrade/detection.d.ts +7 -6
- package/dist/upgrade/detection.d.ts.map +1 -0
- package/dist/upgrade/detection.js +4 -4
- package/dist/upgrade/index.d.ts +1 -0
- package/dist/upgrade/index.d.ts.map +1 -0
- package/dist/upgrade/lifecycle.context.d.ts +1 -0
- package/dist/upgrade/lifecycle.context.d.ts.map +1 -0
- package/dist/upgrade/lifecycle.d.ts +7 -7
- package/dist/upgrade/lifecycle.d.ts.map +1 -0
- package/dist/upgrade/lifecycle.js +9 -10
- package/dist/upgrade/lifecycle.js.map +1 -1
- package/dist/upgrade/pathHandle.d.ts +5 -3
- package/dist/upgrade/pathHandle.d.ts.map +1 -0
- package/dist/upgrade/pathHandle.js +3 -2
- package/dist/upgrade/pathHandle.js.map +1 -1
- package/dist/utils/bootSession.context.d.ts +1 -0
- package/dist/utils/bootSession.context.d.ts.map +1 -0
- package/dist/utils/bootSession.context.js +6 -5
- package/dist/utils/bootSession.context.js.map +1 -1
- package/dist/utils/bootSession.d.ts +1 -0
- package/dist/utils/bootSession.d.ts.map +1 -0
- package/dist/utils/bootSession.js.map +1 -1
- 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 +31 -13
- 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 +1 -0
- package/dist/utils/index.d.ts.map +1 -0
- 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 +4 -2
- package/dist/utils/markup.d.ts.map +1 -0
- package/dist/utils/markup.js +6 -5
- 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 +1 -0
- package/dist/utils/pid.d.ts.map +1 -0
- package/dist/utils/pid.js +3 -3
- 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 +1 -0
- package/dist/utils/processInspector.context.d.ts.map +1 -0
- package/dist/utils/processInspector.context.js +3 -1
- package/dist/utils/processInspector.context.js.map +1 -1
- package/dist/utils/processInspector.d.ts +4 -3
- package/dist/utils/processInspector.d.ts.map +1 -0
- package/dist/utils/processInspector.js +2 -0
- package/dist/utils/processInspector.js.map +1 -1
- package/dist/utils/retry.d.ts +24 -1
- package/dist/utils/retry.d.ts.map +1 -0
- package/dist/utils/retry.js +32 -5
- package/dist/utils/retry.js.map +1 -1
- package/dist/utils/runtimeIdentity.context.d.ts +1 -0
- package/dist/utils/runtimeIdentity.context.d.ts.map +1 -0
- package/dist/utils/runtimeIdentity.context.js +30 -0
- package/dist/utils/runtimeIdentity.context.js.map +1 -1
- package/dist/utils/runtimeIdentity.d.ts +6 -4
- package/dist/utils/runtimeIdentity.d.ts.map +1 -0
- package/dist/utils/runtimeIdentity.js +15 -5
- package/dist/utils/runtimeIdentity.js.map +1 -1
- 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 +1 -0
- package/dist/utils/timing.d.ts.map +1 -0
- package/dist/utils/version.d.ts +1 -0
- package/dist/utils/version.d.ts.map +1 -0
- package/dist/utils/version.js +7 -3
- package/dist/utils/version.js.map +1 -1
- package/package.json +26 -20
|
@@ -1,66 +1,117 @@
|
|
|
1
1
|
import type { Nullable } from "../types/index.ts";
|
|
2
2
|
import type { Page } from "puppeteer-core";
|
|
3
|
+
import type { RecognizedHlsPlaylistKind } from "../native/probe.ts";
|
|
4
|
+
import { observeHlsPlaylists } from "./hlsPlaylistObserver.ts";
|
|
5
|
+
export declare const FINALIZE_SETTLE_DELAY = 1500;
|
|
3
6
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
7
|
+
* A master playlist observation reduced to the facts selection needs: the declared child playlist URLs (for membership judgment), the wire-arrival ordinal, and
|
|
8
|
+
* the URL. Modeled as a record so a URL can never exist without its ordinal - the null-consistency question separate parallel locals would raise is
|
|
9
|
+
* unrepresentable.
|
|
10
|
+
*/
|
|
11
|
+
export interface InterceptedMasterFact {
|
|
12
|
+
readonly childUrls: readonly string[];
|
|
13
|
+
readonly ordinal: number;
|
|
14
|
+
readonly url: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* A media playlist observation reduced to the facts selection needs: its liveness, the wire-arrival ordinal, and the URL. Modeled as a record so a URL can never
|
|
18
|
+
* exist without its ordinal.
|
|
19
|
+
*/
|
|
20
|
+
export interface InterceptedMediaFact {
|
|
21
|
+
readonly live: boolean;
|
|
22
|
+
readonly ordinal: number;
|
|
23
|
+
readonly url: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Captured state used by selectInterceptedManifest() to choose the playlist appropriate for a given resolution mode. Modeled as a plain record so the selection
|
|
27
|
+
* logic is testable in isolation from the network plumbing that maintains the underlying state. Every judgment - including the pathname normalization membership
|
|
28
|
+
* relies on - lives in the selection function; this record carries only facts.
|
|
6
29
|
*/
|
|
7
30
|
export interface InterceptedManifestState {
|
|
8
|
-
directTune: boolean;
|
|
9
|
-
firstMasterUrl: Nullable<string>;
|
|
10
|
-
firstMediaUrl: Nullable<string>;
|
|
11
|
-
|
|
12
|
-
|
|
31
|
+
readonly directTune: boolean;
|
|
32
|
+
readonly firstMasterUrl: Nullable<string>;
|
|
33
|
+
readonly firstMediaUrl: Nullable<string>;
|
|
34
|
+
readonly latestMaster: Nullable<InterceptedMasterFact>;
|
|
35
|
+
readonly latestMedia: Nullable<InterceptedMediaFact>;
|
|
36
|
+
readonly markOrdinal: Nullable<number>;
|
|
13
37
|
}
|
|
14
38
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
|
|
39
|
+
* The outcome of selectInterceptedManifest(): the chosen URL and the kind selection decided it is. The kind is reported alongside the URL so no caller re-derives
|
|
40
|
+
* it by comparing URLs, which would be fragile when the same URL could sit in both the master and media records.
|
|
41
|
+
*/
|
|
42
|
+
export interface SelectedManifest {
|
|
43
|
+
readonly kind: RecognizedHlsPlaylistKind;
|
|
44
|
+
readonly url: string;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Selects the playlist appropriate for a given resolution mode from the captured state, reporting the URL together with the kind selection decided.
|
|
48
|
+
*
|
|
49
|
+
* Direct tunes take the earliest qualifying capture (firstMasterUrl before firstMediaUrl), master preferred, with the kind tagged by the slot that supplied the
|
|
50
|
+
* URL. The epoch never participates on the direct branch: a direct tune navigates by URL and its first capture answers.
|
|
51
|
+
*
|
|
52
|
+
* Guide tunes apply a three-signal rule over the latest captures:
|
|
53
|
+
*
|
|
54
|
+
* 1. No master captured: the media fallback (latestMedia's URL) or null. Liveness gates only the override of a master, never the sole available feed, so a VOD
|
|
55
|
+
* media playlist still answers when it is all that arrived.
|
|
56
|
+
* 2. Epoch declared and the master post-epoch (latestMaster.ordinal > markOrdinal): the master, categorically. A master observed after channel selection began
|
|
57
|
+
* answers the click. An absent epoch (mark never called) also leaves the master the winner, because without a click there is no fresher truth to prefer.
|
|
58
|
+
* 3. Override to the media only when every clause holds: an epoch exists (rule 2 falling through means the master is pre-epoch), latestMedia is live, the media
|
|
59
|
+
* is post-epoch (latestMedia.ordinal > markOrdinal - which structurally postdates the pre-epoch master, so no separate ordering clause is needed), and the
|
|
60
|
+
* media is a verified non-member of the master's children. Otherwise the master wins.
|
|
18
61
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
62
|
+
* Membership is member-conservative (see isVerifiedNonMemberOfMaster): anything short of a proven foreign pathname keeps the master, so the override engages only
|
|
63
|
+
* where a media playlist is demonstrably not one of the master's own children. Pure selection policy exported so the rule is testable in isolation from the
|
|
64
|
+
* network plumbing; the closure inside installManifestInterceptor() consumes it through the same shape.
|
|
21
65
|
*
|
|
22
|
-
* @param state - The captured
|
|
23
|
-
* @returns The selected
|
|
66
|
+
* @param state - The captured state at resolution time.
|
|
67
|
+
* @returns The selected playlist, or null when no URL matches the resolution mode.
|
|
24
68
|
*/
|
|
25
|
-
export declare function selectInterceptedManifest(state: InterceptedManifestState): Nullable<
|
|
69
|
+
export declare function selectInterceptedManifest(state: InterceptedManifestState): Nullable<SelectedManifest>;
|
|
26
70
|
/**
|
|
27
|
-
* Result of manifest interception. The URL may be either a master or a media playlist;
|
|
28
|
-
* not branch on which kind originally arrived. The underlying observer and its CDP sessions are owned and disposed
|
|
29
|
-
* references.
|
|
71
|
+
* Result of manifest interception. The URL may be either a master or a media playlist; selectedKind reports which selection chose, and the probe normalizes both
|
|
72
|
+
* kinds into a MediaFeed so downstream code does not branch on which kind originally arrived. The underlying observer and its CDP sessions are owned and disposed
|
|
73
|
+
* internally - callers do not hold session references.
|
|
30
74
|
*/
|
|
31
75
|
export interface ManifestInterceptionResult {
|
|
32
|
-
|
|
76
|
+
readonly manifestUrl: string;
|
|
77
|
+
readonly selectedKind: RecognizedHlsPlaylistKind;
|
|
33
78
|
}
|
|
34
79
|
/**
|
|
35
|
-
* Handle returned by installManifestInterceptor. Provides the interception promise, a finalize function to signal that channel selection is complete,
|
|
36
|
-
* explicit dispose path. Implements TC39 Symbol.dispose so callers may use the "using" keyword for
|
|
80
|
+
* Handle returned by installManifestInterceptor. Provides the interception promise, a finalize function to signal that channel selection is complete, an epoch
|
|
81
|
+
* stamp marking when channel selection begins, and an explicit dispose path. Implements TC39 Symbol.dispose so callers may use the "using" keyword for
|
|
82
|
+
* scope-bound cleanup, including on thrown errors.
|
|
37
83
|
*/
|
|
38
84
|
export interface ManifestInterceptorHandle extends Disposable {
|
|
39
85
|
readonly dispose: () => void;
|
|
40
86
|
readonly finalize: (directTune: boolean) => void;
|
|
87
|
+
readonly markChannelSelectionStart: () => void;
|
|
41
88
|
readonly promise: Promise<Nullable<ManifestInterceptionResult>>;
|
|
42
89
|
readonly [Symbol.dispose]: () => void;
|
|
43
90
|
}
|
|
44
91
|
/**
|
|
45
|
-
* Installs a long-lived HLS playlist observer that tracks observed
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
* whichever URL is appropriate for the tune type:
|
|
92
|
+
* Installs a long-lived HLS playlist observer that tracks observed playlists on the given page. Both master and media playlists are accepted; the first and latest
|
|
93
|
+
* URL per kind are tracked separately, guarded by wire-arrival order, so master-based and media-only sites both work without separate code paths. The returned
|
|
94
|
+
* handle provides a finalize(directTune) callback and a markChannelSelectionStart() epoch stamp; when finalize is called the observer resolves through
|
|
95
|
+
* selectInterceptedManifest with the playlist appropriate for the tune type:
|
|
50
96
|
*
|
|
51
|
-
* - directTune=true: resolves immediately
|
|
52
|
-
* navigated URL itself selects the channel and the player loads its manifest before
|
|
53
|
-
*
|
|
54
|
-
*
|
|
97
|
+
* - directTune=true: resolves immediately if a master manifest has already arrived (or after the settle delay when only a media-only manifest, or nothing, has
|
|
98
|
+
* arrived so far) with the first manifest captured. Used by sites where the navigated URL itself selects the channel and the player loads its manifest before
|
|
99
|
+
* the click handler returns. Master-first URL preferred over media-first.
|
|
100
|
+
* - directTune=false: resolves after the settle delay through the guide-tune rule (channel-selection epoch, playlist membership, liveness), so the tuned
|
|
101
|
+
* channel's playlist wins over a page-load default channel captured first. Used by guide-based sites where the channel-switch click triggers a new manifest
|
|
102
|
+
* fetch that may arrive milliseconds after the click handler returns.
|
|
55
103
|
*
|
|
56
|
-
* On timeout (finalize never called), the observer resolves
|
|
57
|
-
*
|
|
104
|
+
* On timeout (finalize never called), the observer resolves epoch-free through the same guide-tune rule with no epoch declared, so the categorical
|
|
105
|
+
* master-preferred outcome holds and a direct tune the timeout may be guarding is never exposed to the epoch rule. The underlying HLS observer is disposed
|
|
106
|
+
* automatically on resolution; callers do not hold CDP session references.
|
|
58
107
|
*
|
|
59
108
|
* @param page - The puppeteer page to monitor.
|
|
60
|
-
* @param timeout - Maximum time in milliseconds to wait for a manifest.
|
|
109
|
+
* @param timeout - Maximum time in milliseconds to wait for a manifest. Required: every caller sizes its interception window consciously to outlive the phases it
|
|
110
|
+
* observes, so no production caller relies on a shared default. Acts as a safety net if finalize() is never called.
|
|
111
|
+
* @param observeFactory - The HLS playlist observer factory (default observeHlsPlaylists); injectable so the selection state machine can run without a live browser.
|
|
61
112
|
* @returns The interceptor handle, or null if the observer could not be installed.
|
|
62
113
|
*/
|
|
63
|
-
export declare function installManifestInterceptor(page: Page, timeout?:
|
|
114
|
+
export declare function installManifestInterceptor(page: Page, timeout: number, observeFactory?: typeof observeHlsPlaylists): Promise<Nullable<ManifestInterceptorHandle>>;
|
|
64
115
|
/**
|
|
65
116
|
* Awaits the first master HLS manifest whose URL satisfies the supplied predicate. Used by tune-verification paths where the caller has just clicked or
|
|
66
117
|
* navigated to a target channel and wants to confirm the resulting stream belongs to that channel rather than to whatever default the page was previously
|
|
@@ -72,6 +123,8 @@ export declare function installManifestInterceptor(page: Page, timeout?: number)
|
|
|
72
123
|
* @param page - The puppeteer page to monitor.
|
|
73
124
|
* @param predicate - Test applied to each verified master manifest URL. Return true to accept the URL and resolve.
|
|
74
125
|
* @param timeout - Maximum time in milliseconds to wait for a matching manifest.
|
|
126
|
+
* @param observeFactory - The HLS playlist observer factory (default observeHlsPlaylists); injectable so the verification state machine can run without a live browser.
|
|
75
127
|
* @returns The matching URL, or null on timeout.
|
|
76
128
|
*/
|
|
77
|
-
export declare function awaitMatchingManifest(page: Page, predicate: (url: string) => boolean, timeout?: number): Promise<Nullable<string>>;
|
|
129
|
+
export declare function awaitMatchingManifest(page: Page, predicate: (url: string) => boolean, timeout?: number, observeFactory?: typeof observeHlsPlaylists): Promise<Nullable<string>>;
|
|
130
|
+
//# sourceMappingURL=manifestInterceptor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifestInterceptor.d.ts","sourceRoot":"","sources":["../../src/browser/manifestInterceptor.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AA6B/D,eAAO,MAAM,qBAAqB,OAAO,CAAC;AAK1C;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IAIpC,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IAGtC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAGzB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IAGnC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAGvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAGzB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IAGvC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAG7B,QAAQ,CAAC,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAG1C,QAAQ,CAAC,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAGzC,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC,qBAAqB,CAAC,CAAC;IAGvD,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,oBAAoB,CAAC,CAAC;IAIrD,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;CACxC;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAG/B,QAAQ,CAAC,IAAI,EAAE,yBAAyB,CAAC;IAGzC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAmCD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,wBAAwB,GAAG,QAAQ,CAAC,gBAAgB,CAAC,CAuCrG;AAED;;;;GAIG;AACH,MAAM,WAAW,0BAA0B;IAIzC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAG7B,QAAQ,CAAC,YAAY,EAAE,yBAAyB,CAAC;CAClD;AAED;;;;GAIG;AACH,MAAM,WAAW,yBAA0B,SAAQ,UAAU;IAI3D,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC;IAM7B,QAAQ,CAAC,QAAQ,EAAE,CAAC,UAAU,EAAE,OAAO,KAAK,IAAI,CAAC;IAKjD,QAAQ,CAAC,yBAAyB,EAAE,MAAM,IAAI,CAAC;IAI/C,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,0BAA0B,CAAC,CAAC,CAAC;IAGhE,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACvC;AA6BD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,0BAA0B,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAC1E,cAAc,GAAE,OAAO,mBAAyC,GAAG,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAAC,CAAC,CAoKhH;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,EACzF,OAAO,GAAE,MAA6B,EAAE,cAAc,GAAE,OAAO,mBAAyC,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CA8DrI"}
|
|
@@ -1,120 +1,196 @@
|
|
|
1
|
-
import { LOG, startTimer } from "../utils/index.js";
|
|
1
|
+
import { LOG, extractPathname, startTimer } from "../utils/index.js";
|
|
2
2
|
import { observeHlsPlaylists } from "./hlsPlaylistObserver.js";
|
|
3
3
|
/* This module hosts two consumer-facing state machines built on top of the HLS playlist observer (hlsPlaylistObserver.ts), which in turn rides on the tab-wide
|
|
4
4
|
* network observer (tabNetworkObserver.ts). The layering:
|
|
5
5
|
*
|
|
6
6
|
* tabNetworkObserver -> tab-wide CDP transport (OOPIF-aware via auto-attach + flatten)
|
|
7
|
-
* hlsPlaylistObserver -> HLS filter + body fetch + classify + per-URL dedup
|
|
8
|
-
* manifestInterceptor -> selection:
|
|
7
|
+
* hlsPlaylistObserver -> HLS filter + body fetch + classify + per-URL dedup + wire-arrival sequencing
|
|
8
|
+
* manifestInterceptor -> selection: the channel-selection epoch, playlist membership, the liveness override, finalize semantics, predicate match
|
|
9
9
|
*
|
|
10
|
-
*
|
|
10
|
+
* This module hosts the following consumer-facing state machines built on top of the HLS playlist observer:
|
|
11
11
|
*
|
|
12
|
-
* - installManifestInterceptor(): the long-lived capture used by native HLS setup. Accepts both master and media playlists, tracks first and latest
|
|
13
|
-
* kind, and resolves with the
|
|
14
|
-
*
|
|
12
|
+
* - installManifestInterceptor(): the long-lived capture used by native HLS setup. Accepts both master and media playlists, tracks the first and latest URL per
|
|
13
|
+
* kind, and resolves with the playlist appropriate for the tune type when finalize() is called. A direct tune (single-channel site navigated by URL) takes the
|
|
14
|
+
* first qualifying capture, master preferred. A guide tune (multi-channel site) judges the captures through three signals - a channel-selection epoch stamped
|
|
15
|
+
* when selection begins, playlist membership of a media playlist within the latest master's declared children, and media liveness - so the tuned channel's
|
|
16
|
+
* playlist is chosen even when a page-load default channel was captured first. See selectInterceptedManifest for the full rule.
|
|
15
17
|
* - awaitMatchingManifest(): the short-lived verification used after a guide-click tune. Accepts master playlists only and resolves with the first URL whose
|
|
16
18
|
* path satisfies a caller-supplied predicate. Media playlists are skipped at the consumer level because tune verification is a multi-channel concept that
|
|
17
19
|
* does not apply to direct-tune media-only sources.
|
|
18
20
|
*
|
|
19
|
-
* Race safety, URL filtering, body fetching, and
|
|
20
|
-
* and apply selection policy. Public callers do not hold CDP session references; the underlying
|
|
21
|
-
* when finalize, timeout, predicate match, or explicit dispose fires.
|
|
21
|
+
* Race safety, URL filtering, body fetching, classification, and wire-arrival sequencing all live below this module - we receive a stream of recognized HLS
|
|
22
|
+
* playlists with their kind, per-kind facts, and arrival ordinal, and apply selection policy. Public callers do not hold CDP session references; the underlying
|
|
23
|
+
* HLS observer disposes its tab network observer deterministically when finalize, timeout, predicate match, or explicit dispose fires.
|
|
22
24
|
*/
|
|
23
|
-
//
|
|
24
|
-
|
|
25
|
-
//
|
|
26
|
-
//
|
|
27
|
-
const FINALIZE_SETTLE_DELAY = 1500;
|
|
25
|
+
// Brief delay after finalize() is called to allow any in-flight manifest response to arrive. Applied for guide-based tunes (directTune=false), where the channel
|
|
26
|
+
// switch may trigger a manifest fetch that arrives milliseconds after the click handler returns, and for direct tunes that have not yet captured a master
|
|
27
|
+
// manifest. A direct tune skips this delay and resolves immediately only once a master manifest has already arrived. Exported so a caller sizing its own
|
|
28
|
+
// interception window (streaming/setup.ts) can include the settle window the window must outlive.
|
|
29
|
+
export const FINALIZE_SETTLE_DELAY = 1500;
|
|
28
30
|
// Default timeout for awaitMatchingManifest. Tune verification is a short-lived check after a click, so the budget is tighter than the native interception path.
|
|
29
31
|
const VERIFICATION_TIMEOUT = 8000;
|
|
30
32
|
/**
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* the
|
|
33
|
+
* Reports whether a media playlist is a verified NON-member of a master's declared children, comparing by pathname only. Membership is URL-identity policy, not
|
|
34
|
+
* manifest-format knowledge, which is why it lives here rather than in probe. Pathname-only because post-redirect response URLs diverge from a master's declared
|
|
35
|
+
* child URIs at the host far more often than at the path. The judgment is member-conservative: a media URL that cannot be parsed, an empty declared child list, or
|
|
36
|
+
* an empty effective set after dropping unparseable children all read as MEMBER (the master wins, degrading to the categorical rule, never a new failure). Only a
|
|
37
|
+
* parseable media pathname absent from a non-empty set of parseable child pathnames is a verified non-member.
|
|
34
38
|
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
39
|
+
* @param mediaUrl - The candidate media playlist URL.
|
|
40
|
+
* @param childUrls - The master's declared child playlist URLs.
|
|
41
|
+
* @returns True only when the media pathname is proven absent from a non-empty effective set of child pathnames.
|
|
42
|
+
*/
|
|
43
|
+
function isVerifiedNonMemberOfMaster(mediaUrl, childUrls) {
|
|
44
|
+
const mediaPathname = extractPathname(mediaUrl);
|
|
45
|
+
// A media URL we cannot parse cannot be proven foreign, so it reads as a member and the master wins.
|
|
46
|
+
if (mediaPathname === null) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
// Normalize the declared children to pathnames, dropping any that cannot be parsed. An empty declared list or a list that parses to nothing yields an empty
|
|
50
|
+
// effective set: with no children to compare against, membership cannot be disproven, so the master wins.
|
|
51
|
+
const childPathnames = childUrls.map((child) => extractPathname(child)).filter((pathname) => pathname !== null);
|
|
52
|
+
if (childPathnames.length === 0) {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
return !childPathnames.includes(mediaPathname);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Selects the playlist appropriate for a given resolution mode from the captured state, reporting the URL together with the kind selection decided.
|
|
37
59
|
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
60
|
+
* Direct tunes take the earliest qualifying capture (firstMasterUrl before firstMediaUrl), master preferred, with the kind tagged by the slot that supplied the
|
|
61
|
+
* URL. The epoch never participates on the direct branch: a direct tune navigates by URL and its first capture answers.
|
|
62
|
+
*
|
|
63
|
+
* Guide tunes apply a three-signal rule over the latest captures:
|
|
64
|
+
*
|
|
65
|
+
* 1. No master captured: the media fallback (latestMedia's URL) or null. Liveness gates only the override of a master, never the sole available feed, so a VOD
|
|
66
|
+
* media playlist still answers when it is all that arrived.
|
|
67
|
+
* 2. Epoch declared and the master post-epoch (latestMaster.ordinal > markOrdinal): the master, categorically. A master observed after channel selection began
|
|
68
|
+
* answers the click. An absent epoch (mark never called) also leaves the master the winner, because without a click there is no fresher truth to prefer.
|
|
69
|
+
* 3. Override to the media only when every clause holds: an epoch exists (rule 2 falling through means the master is pre-epoch), latestMedia is live, the media
|
|
70
|
+
* is post-epoch (latestMedia.ordinal > markOrdinal - which structurally postdates the pre-epoch master, so no separate ordering clause is needed), and the
|
|
71
|
+
* media is a verified non-member of the master's children. Otherwise the master wins.
|
|
72
|
+
*
|
|
73
|
+
* Membership is member-conservative (see isVerifiedNonMemberOfMaster): anything short of a proven foreign pathname keeps the master, so the override engages only
|
|
74
|
+
* where a media playlist is demonstrably not one of the master's own children. Pure selection policy exported so the rule is testable in isolation from the
|
|
75
|
+
* network plumbing; the closure inside installManifestInterceptor() consumes it through the same shape.
|
|
76
|
+
*
|
|
77
|
+
* @param state - The captured state at resolution time.
|
|
78
|
+
* @returns The selected playlist, or null when no URL matches the resolution mode.
|
|
40
79
|
*/
|
|
41
80
|
export function selectInterceptedManifest(state) {
|
|
42
81
|
if (state.directTune) {
|
|
43
|
-
|
|
82
|
+
if (state.firstMasterUrl !== null) {
|
|
83
|
+
return { kind: "master", url: state.firstMasterUrl };
|
|
84
|
+
}
|
|
85
|
+
if (state.firstMediaUrl !== null) {
|
|
86
|
+
return { kind: "media", url: state.firstMediaUrl };
|
|
87
|
+
}
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
const { latestMaster, latestMedia, markOrdinal } = state;
|
|
91
|
+
// Rule 1: no master captured. The media fallback answers regardless of liveness.
|
|
92
|
+
if (latestMaster === null) {
|
|
93
|
+
return (latestMedia === null) ? null : { kind: "media", url: latestMedia.url };
|
|
94
|
+
}
|
|
95
|
+
// Rule 2: a master observed after channel selection began answers the click categorically; an absent epoch keeps the master too.
|
|
96
|
+
if ((markOrdinal !== null) && (latestMaster.ordinal > markOrdinal)) {
|
|
97
|
+
return { kind: "master", url: latestMaster.url };
|
|
98
|
+
}
|
|
99
|
+
// Rule 3: override to a live, post-epoch, verified non-member media; otherwise the master wins.
|
|
100
|
+
if ((markOrdinal !== null) && (latestMedia !== null) && latestMedia.live && (latestMedia.ordinal > markOrdinal) &&
|
|
101
|
+
isVerifiedNonMemberOfMaster(latestMedia.url, latestMaster.childUrls)) {
|
|
102
|
+
return { kind: "media", url: latestMedia.url };
|
|
44
103
|
}
|
|
45
|
-
return
|
|
104
|
+
return { kind: "master", url: latestMaster.url };
|
|
46
105
|
}
|
|
47
106
|
/**
|
|
48
|
-
* Installs a long-lived HLS playlist observer that tracks observed
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
* whichever URL is appropriate for the tune type:
|
|
107
|
+
* Installs a long-lived HLS playlist observer that tracks observed playlists on the given page. Both master and media playlists are accepted; the first and latest
|
|
108
|
+
* URL per kind are tracked separately, guarded by wire-arrival order, so master-based and media-only sites both work without separate code paths. The returned
|
|
109
|
+
* handle provides a finalize(directTune) callback and a markChannelSelectionStart() epoch stamp; when finalize is called the observer resolves through
|
|
110
|
+
* selectInterceptedManifest with the playlist appropriate for the tune type:
|
|
53
111
|
*
|
|
54
|
-
* - directTune=true: resolves immediately
|
|
55
|
-
* navigated URL itself selects the channel and the player loads its manifest before
|
|
56
|
-
*
|
|
57
|
-
*
|
|
112
|
+
* - directTune=true: resolves immediately if a master manifest has already arrived (or after the settle delay when only a media-only manifest, or nothing, has
|
|
113
|
+
* arrived so far) with the first manifest captured. Used by sites where the navigated URL itself selects the channel and the player loads its manifest before
|
|
114
|
+
* the click handler returns. Master-first URL preferred over media-first.
|
|
115
|
+
* - directTune=false: resolves after the settle delay through the guide-tune rule (channel-selection epoch, playlist membership, liveness), so the tuned
|
|
116
|
+
* channel's playlist wins over a page-load default channel captured first. Used by guide-based sites where the channel-switch click triggers a new manifest
|
|
117
|
+
* fetch that may arrive milliseconds after the click handler returns.
|
|
58
118
|
*
|
|
59
|
-
* On timeout (finalize never called), the observer resolves
|
|
60
|
-
*
|
|
119
|
+
* On timeout (finalize never called), the observer resolves epoch-free through the same guide-tune rule with no epoch declared, so the categorical
|
|
120
|
+
* master-preferred outcome holds and a direct tune the timeout may be guarding is never exposed to the epoch rule. The underlying HLS observer is disposed
|
|
121
|
+
* automatically on resolution; callers do not hold CDP session references.
|
|
61
122
|
*
|
|
62
123
|
* @param page - The puppeteer page to monitor.
|
|
63
|
-
* @param timeout - Maximum time in milliseconds to wait for a manifest.
|
|
124
|
+
* @param timeout - Maximum time in milliseconds to wait for a manifest. Required: every caller sizes its interception window consciously to outlive the phases it
|
|
125
|
+
* observes, so no production caller relies on a shared default. Acts as a safety net if finalize() is never called.
|
|
126
|
+
* @param observeFactory - The HLS playlist observer factory (default observeHlsPlaylists); injectable so the selection state machine can run without a live browser.
|
|
64
127
|
* @returns The interceptor handle, or null if the observer could not be installed.
|
|
65
128
|
*/
|
|
66
|
-
export async function installManifestInterceptor(page, timeout =
|
|
129
|
+
export async function installManifestInterceptor(page, timeout, observeFactory = observeHlsPlaylists) {
|
|
67
130
|
const elapsed = startTimer();
|
|
68
|
-
// Track first
|
|
69
|
-
// the
|
|
70
|
-
//
|
|
71
|
-
let
|
|
72
|
-
let
|
|
73
|
-
let
|
|
74
|
-
let
|
|
131
|
+
// Track the first and latest observation per kind, plus the epoch fence. Slot updates are guarded by wire-arrival order, not delivery order: the first slot
|
|
132
|
+
// holds the lowest-ordinal arrival and the latest facts hold the highest, so a body fetch that resolves out of order still records arrival truth. Under
|
|
133
|
+
// in-order delivery this is byte-for-byte the earliest/most-recent behavior. manifestCount stays purely diagnostic for the log lines.
|
|
134
|
+
let firstMaster = null;
|
|
135
|
+
let firstMedia = null;
|
|
136
|
+
let latestMaster = null;
|
|
137
|
+
let latestMedia = null;
|
|
138
|
+
let markOrdinal = null;
|
|
75
139
|
let resolved = false;
|
|
76
140
|
let manifestCount = 0;
|
|
77
141
|
const { promise, resolve } = Promise.withResolvers();
|
|
78
|
-
const observer = await
|
|
142
|
+
const observer = await observeFactory(page, {
|
|
79
143
|
logCategory: "native:intercept",
|
|
80
144
|
onPlaylist: (playlist) => {
|
|
81
145
|
manifestCount++;
|
|
82
146
|
if (playlist.kind === "master") {
|
|
83
|
-
|
|
84
|
-
|
|
147
|
+
// First slot: the lowest ordinal wins, so a late delivery of an even-earlier arrival corrects it.
|
|
148
|
+
if ((firstMaster === null) || (playlist.sequence < firstMaster.ordinal)) {
|
|
149
|
+
firstMaster = { ordinal: playlist.sequence, url: playlist.url };
|
|
150
|
+
}
|
|
151
|
+
// Latest slot: the highest ordinal wins, so a late delivery of a lower arrival never displaces it.
|
|
152
|
+
if ((latestMaster === null) || (playlist.sequence > latestMaster.ordinal)) {
|
|
153
|
+
latestMaster = { childUrls: playlist.childUrls, ordinal: playlist.sequence, url: playlist.url };
|
|
154
|
+
}
|
|
85
155
|
}
|
|
86
|
-
else
|
|
87
|
-
|
|
88
|
-
|
|
156
|
+
else {
|
|
157
|
+
if ((firstMedia === null) || (playlist.sequence < firstMedia.ordinal)) {
|
|
158
|
+
firstMedia = { ordinal: playlist.sequence, url: playlist.url };
|
|
159
|
+
}
|
|
160
|
+
if ((latestMedia === null) || (playlist.sequence > latestMedia.ordinal)) {
|
|
161
|
+
latestMedia = { live: playlist.live, ordinal: playlist.sequence, url: playlist.url };
|
|
162
|
+
}
|
|
89
163
|
}
|
|
90
|
-
LOG.debug("native:intercept", "%s playlist captured (#%s) in %sms: %s.", playlist.kind, manifestCount, elapsed(), playlist.url.slice(0, 120));
|
|
164
|
+
LOG.debug("native:intercept", "%s playlist captured (#%s, seq %s) in %sms: %s.", playlist.kind, manifestCount, playlist.sequence, elapsed(), playlist.url.slice(0, 120));
|
|
91
165
|
}
|
|
92
166
|
});
|
|
93
167
|
if (!observer) {
|
|
94
168
|
return null;
|
|
95
169
|
}
|
|
96
|
-
//
|
|
97
|
-
//
|
|
98
|
-
const
|
|
170
|
+
// Builds the selection state from the closure locals. epochFree forces markOrdinal to null so the timeout path resolves without the epoch rule, which must
|
|
171
|
+
// never engage on a path a direct tune can reach.
|
|
172
|
+
const buildState = (directTune, epochFree) => ({
|
|
99
173
|
directTune,
|
|
100
|
-
firstMasterUrl,
|
|
101
|
-
firstMediaUrl,
|
|
102
|
-
|
|
103
|
-
|
|
174
|
+
firstMasterUrl: firstMaster?.url ?? null,
|
|
175
|
+
firstMediaUrl: firstMedia?.url ?? null,
|
|
176
|
+
latestMaster,
|
|
177
|
+
latestMedia,
|
|
178
|
+
markOrdinal: epochFree ? null : markOrdinal
|
|
104
179
|
});
|
|
105
180
|
// Centralized resolution helper. Used by the timeout, finalize, and dispose paths to settle the promise exactly once and tear down the observer regardless of
|
|
106
|
-
// which path won. The
|
|
107
|
-
const settle = (
|
|
181
|
+
// which path won. The selection honors the direct-vs-guide semantics and, for guide tunes, the epoch/membership/liveness rule via selectInterceptedManifest.
|
|
182
|
+
const settle = (options) => {
|
|
183
|
+
const { directTune, epochFree = false, reason } = options;
|
|
108
184
|
if (resolved) {
|
|
109
185
|
return;
|
|
110
186
|
}
|
|
111
187
|
resolved = true;
|
|
112
188
|
clearTimeout(timer);
|
|
113
|
-
const
|
|
114
|
-
if (
|
|
115
|
-
LOG.debug("native:intercept", "Interception %s in %sms with %s capture(s). Using %s: %s.", reason, elapsed(), manifestCount, directTune ? "first" : "latest",
|
|
189
|
+
const selection = selectInterceptedManifest(buildState(directTune, epochFree));
|
|
190
|
+
if (selection) {
|
|
191
|
+
LOG.debug("native:intercept", "Interception %s in %sms with %s capture(s). Using %s %s: %s.", reason, elapsed(), manifestCount, directTune ? "first" : "latest", selection.kind, selection.url.slice(0, 120));
|
|
116
192
|
observer.dispose();
|
|
117
|
-
resolve({
|
|
193
|
+
resolve({ manifestUrl: selection.url, selectedKind: selection.kind });
|
|
118
194
|
}
|
|
119
195
|
else {
|
|
120
196
|
LOG.debug("native:intercept", "Interception %s in %sms but no HLS playlist was captured.", reason, elapsed());
|
|
@@ -122,13 +198,14 @@ export async function installManifestInterceptor(page, timeout = INTERCEPTION_TI
|
|
|
122
198
|
resolve(null);
|
|
123
199
|
}
|
|
124
200
|
};
|
|
125
|
-
// Timeout guard. If finalize() is never called (defensive), settle
|
|
126
|
-
//
|
|
127
|
-
|
|
201
|
+
// Timeout guard. If finalize() is never called (defensive), settle epoch-free after the timeout: the timeout cannot know the tune kind, and the epoch rule must
|
|
202
|
+
// never engage on a path a direct tune can reach, so it resolves with the categorical master-preferred outcome. With the interception budget sized by the
|
|
203
|
+
// caller to outlive the tune (streaming/setup.ts), this path is last-resort defense rather than a routine finish.
|
|
204
|
+
const timer = setTimeout(() => { settle({ directTune: false, epochFree: true, reason: "timed out" }); }, timeout);
|
|
128
205
|
// Finalize function exposed on the returned handle. Called by the stream setup code after channel selection is complete. The resolution strategy depends on
|
|
129
206
|
// two factors: whether a qualifying manifest has already been captured, and whether the tune is direct or guide-based.
|
|
130
207
|
//
|
|
131
|
-
// -
|
|
208
|
+
// - Master manifest captured + direct tune: settle immediately (A&E, most TVE sites - manifest arrived during page load).
|
|
132
209
|
// - Manifest captured + guide tune: wait FINALIZE_SETTLE_DELAY (Fox guide, Hulu - a newer manifest from the channel switch may still arrive).
|
|
133
210
|
// - No manifest captured + either: wait FINALIZE_SETTLE_DELAY (Fox Sports - manifest fetch starts after video element appears, hasn't arrived yet).
|
|
134
211
|
const finalize = (directTune) => {
|
|
@@ -136,16 +213,26 @@ export async function installManifestInterceptor(page, timeout = INTERCEPTION_TI
|
|
|
136
213
|
return;
|
|
137
214
|
}
|
|
138
215
|
// For direct tunes, settle immediately if a master URL has already arrived. We do not short-circuit on a media-only first URL because a master may still
|
|
139
|
-
// be in flight - waiting the settle delay gives master
|
|
140
|
-
if (directTune &&
|
|
141
|
-
settle(true, "finalized");
|
|
216
|
+
// be in flight - waiting the settle delay gives the master-first preference a chance to take effect.
|
|
217
|
+
if (directTune && (firstMaster !== null)) {
|
|
218
|
+
settle({ directTune: true, reason: "finalized" });
|
|
142
219
|
}
|
|
143
220
|
else {
|
|
144
|
-
setTimeout(() => { settle(directTune, "finalized"); }, FINALIZE_SETTLE_DELAY);
|
|
221
|
+
setTimeout(() => { settle({ directTune, reason: "finalized" }); }, FINALIZE_SETTLE_DELAY);
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
// Stamps the observation epoch at which channel selection begins by fencing the observer's current wire sequence. Observations after the stamp answer the
|
|
225
|
+
// click; guide-tune selection prefers a master observed after this point. Callable again - the latest stamp wins - and a no-op once the interception has
|
|
226
|
+
// resolved, matching the finalize and dispose guard idiom.
|
|
227
|
+
const markChannelSelectionStart = () => {
|
|
228
|
+
if (resolved) {
|
|
229
|
+
return;
|
|
145
230
|
}
|
|
231
|
+
markOrdinal = observer.currentSequence();
|
|
232
|
+
LOG.debug("native:intercept", "Channel selection epoch stamped at wire sequence %s.", markOrdinal);
|
|
146
233
|
};
|
|
147
|
-
// Explicit dispose path for "using" syntax or caller-driven cancellation.
|
|
148
|
-
// callers awaiting the promise are never left hanging on a disposed observer.
|
|
234
|
+
// Explicit dispose path for "using" syntax or caller-driven cancellation. Safe to call more than once. Resolves the promise with null if it has not already
|
|
235
|
+
// settled, so callers awaiting the promise are never left hanging on a disposed observer.
|
|
149
236
|
const dispose = () => {
|
|
150
237
|
if (resolved) {
|
|
151
238
|
return;
|
|
@@ -156,7 +243,7 @@ export async function installManifestInterceptor(page, timeout = INTERCEPTION_TI
|
|
|
156
243
|
observer.dispose();
|
|
157
244
|
resolve(null);
|
|
158
245
|
};
|
|
159
|
-
return { dispose, finalize, promise, [Symbol.dispose]: dispose };
|
|
246
|
+
return { dispose, finalize, markChannelSelectionStart, promise, [Symbol.dispose]: dispose };
|
|
160
247
|
}
|
|
161
248
|
/**
|
|
162
249
|
* Awaits the first master HLS manifest whose URL satisfies the supplied predicate. Used by tune-verification paths where the caller has just clicked or
|
|
@@ -169,16 +256,17 @@ export async function installManifestInterceptor(page, timeout = INTERCEPTION_TI
|
|
|
169
256
|
* @param page - The puppeteer page to monitor.
|
|
170
257
|
* @param predicate - Test applied to each verified master manifest URL. Return true to accept the URL and resolve.
|
|
171
258
|
* @param timeout - Maximum time in milliseconds to wait for a matching manifest.
|
|
259
|
+
* @param observeFactory - The HLS playlist observer factory (default observeHlsPlaylists); injectable so the verification state machine can run without a live browser.
|
|
172
260
|
* @returns The matching URL, or null on timeout.
|
|
173
261
|
*/
|
|
174
|
-
export async function awaitMatchingManifest(page, predicate, timeout = VERIFICATION_TIMEOUT) {
|
|
262
|
+
export async function awaitMatchingManifest(page, predicate, timeout = VERIFICATION_TIMEOUT, observeFactory = observeHlsPlaylists) {
|
|
175
263
|
const elapsed = startTimer();
|
|
176
264
|
let resolved = false;
|
|
177
265
|
const { promise, resolve } = Promise.withResolvers();
|
|
178
266
|
// Tune verification is a multi-channel concept that only applies to master playlists - direct-tune media-only sources do not run a guide-click verification
|
|
179
267
|
// step because the page navigation itself selects the channel. We reject media playlists at the consumer level rather than asking the observer to filter so
|
|
180
268
|
// the observer keeps a single canonical contract (forward all recognized HLS playlists with their kind).
|
|
181
|
-
const observer = await
|
|
269
|
+
const observer = await observeFactory(page, {
|
|
182
270
|
logCategory: "native:intercept",
|
|
183
271
|
onPlaylist: (playlist) => {
|
|
184
272
|
if (resolved) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifestInterceptor.js","sourceRoot":"","sources":["../../src/browser/manifestInterceptor.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"manifestInterceptor.js","sourceRoot":"","sources":["../../src/browser/manifestInterceptor.ts"],"names":[],"mappings":"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"}
|