prismcast 1.12.0 → 1.13.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 +41 -1
- package/dist/app.js +164 -76
- package/dist/app.js.map +1 -1
- package/dist/browser/blockedPage.d.ts +0 -1
- package/dist/browser/browserSupervisor.d.ts +34 -5
- package/dist/browser/browserSupervisor.js +39 -12
- package/dist/browser/browserSupervisor.js.map +1 -1
- package/dist/browser/cdp.d.ts +58 -6
- package/dist/browser/cdp.js +147 -9
- package/dist/browser/cdp.js.map +1 -1
- package/dist/browser/channelSelection.d.ts +18 -6
- package/dist/browser/channelSelection.js +47 -36
- package/dist/browser/channelSelection.js.map +1 -1
- package/dist/browser/consent.d.ts +33 -4
- package/dist/browser/consent.js +87 -50
- package/dist/browser/consent.js.map +1 -1
- package/dist/browser/display.d.ts +0 -1
- package/dist/browser/hlsPlaylistObserver.d.ts +3 -2
- package/dist/browser/hlsPlaylistObserver.js +11 -6
- package/dist/browser/hlsPlaylistObserver.js.map +1 -1
- package/dist/browser/index.d.ts +273 -59
- package/dist/browser/index.js +768 -255
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/launchGovernor.d.ts +0 -1
- package/dist/browser/login.d.ts +11 -10
- package/dist/browser/login.js +42 -33
- package/dist/browser/login.js.map +1 -1
- package/dist/browser/manifestInterceptor.d.ts +14 -5
- package/dist/browser/manifestInterceptor.js +26 -13
- package/dist/browser/manifestInterceptor.js.map +1 -1
- package/dist/browser/navigation.d.ts +28 -0
- package/dist/browser/navigation.js +57 -0
- package/dist/browser/navigation.js.map +1 -0
- package/dist/browser/pageStaleness.d.ts +1 -2
- package/dist/browser/pageStaleness.js +9 -9
- package/dist/browser/pageStaleness.js.map +1 -1
- package/dist/browser/precaching.d.ts +27 -13
- package/dist/browser/precaching.js +219 -73
- package/dist/browser/precaching.js.map +1 -1
- package/dist/browser/tabCapture.d.ts +97 -0
- package/dist/browser/tabCapture.js +314 -0
- package/dist/browser/tabCapture.js.map +1 -0
- package/dist/browser/tabNetworkObserver.d.ts +0 -1
- package/dist/browser/tabSelection.d.ts +117 -0
- package/dist/browser/tabSelection.js +547 -0
- package/dist/browser/tabSelection.js.map +1 -0
- package/dist/browser/tuning/cache.d.ts +0 -1
- package/dist/browser/tuning/comcastPolymer.d.ts +0 -1
- package/dist/browser/tuning/comcastPolymer.js +18 -19
- package/dist/browser/tuning/comcastPolymer.js.map +1 -1
- package/dist/browser/tuning/cox.d.ts +0 -1
- package/dist/browser/tuning/directv.d.ts +0 -1
- package/dist/browser/tuning/directv.js +12 -13
- package/dist/browser/tuning/directv.js.map +1 -1
- package/dist/browser/tuning/fox.d.ts +0 -1
- package/dist/browser/tuning/fox.js +2 -2
- package/dist/browser/tuning/fox.js.map +1 -1
- package/dist/browser/tuning/gridSearch.d.ts +0 -1
- package/dist/browser/tuning/hbo.d.ts +0 -1
- package/dist/browser/tuning/hbo.js +2 -2
- package/dist/browser/tuning/hbo.js.map +1 -1
- package/dist/browser/tuning/hulu.d.ts +14 -2
- package/dist/browser/tuning/hulu.js +150 -24
- package/dist/browser/tuning/hulu.js.map +1 -1
- package/dist/browser/tuning/shared.d.ts +1 -2
- package/dist/browser/tuning/shared.js +1 -1
- package/dist/browser/tuning/sling.d.ts +0 -1
- package/dist/browser/tuning/sling.js +17 -22
- package/dist/browser/tuning/sling.js.map +1 -1
- package/dist/browser/tuning/spectrum.d.ts +0 -1
- package/dist/browser/tuning/thumbnailRow.d.ts +0 -1
- package/dist/browser/tuning/tileClick.d.ts +0 -1
- package/dist/browser/tuning/xfinity.d.ts +0 -1
- package/dist/browser/tuning/youtubeTv.d.ts +0 -1
- package/dist/browser/tuning/youtubeTv.js +1 -2
- package/dist/browser/tuning/youtubeTv.js.map +1 -1
- package/dist/browser/video.d.ts +55 -33
- package/dist/browser/video.js +213 -169
- package/dist/browser/video.js.map +1 -1
- package/dist/browser/windowSync.d.ts +45 -0
- package/dist/browser/windowSync.js +153 -0
- package/dist/browser/windowSync.js.map +1 -0
- package/dist/channels/index.d.ts +7 -1
- package/dist/channels/index.js +24 -8
- package/dist/channels/index.js.map +1 -1
- package/dist/config/channelForm.d.ts +0 -1
- package/dist/config/channelIdentity.d.ts +27 -0
- package/dist/config/channelIdentity.js +72 -0
- package/dist/config/channelIdentity.js.map +1 -0
- package/dist/config/channelSort.d.ts +25 -0
- package/dist/config/channelSort.js +101 -0
- package/dist/config/channelSort.js.map +1 -0
- package/dist/config/consistencyProbe.d.ts +0 -1
- package/dist/config/consistencyProbe.js +1 -1
- package/dist/config/consistencyProbe.js.map +1 -1
- package/dist/config/health.d.ts +3 -2
- package/dist/config/health.js +41 -31
- package/dist/config/health.js.map +1 -1
- package/dist/config/index.d.ts +12 -1
- package/dist/config/index.js +77 -31
- package/dist/config/index.js.map +1 -1
- package/dist/config/paths.d.ts +17 -2
- package/dist/config/paths.js +21 -1
- package/dist/config/paths.js.map +1 -1
- package/dist/config/persistence.context.d.ts +0 -1
- package/dist/config/persistence.d.ts +8 -4
- package/dist/config/persistence.js +143 -82
- package/dist/config/persistence.js.map +1 -1
- package/dist/config/presets.d.ts +0 -1
- package/dist/config/profiles.d.ts +9 -4
- package/dist/config/profiles.js +39 -6
- package/dist/config/profiles.js.map +1 -1
- package/dist/config/providerLineups.d.ts +0 -1
- package/dist/config/providerLineups.js +0 -3
- package/dist/config/providerLineups.js.map +1 -1
- package/dist/config/reactivity.d.ts +0 -1
- package/dist/config/servicePacks.d.ts +0 -1
- package/dist/config/services.d.ts +1 -47
- package/dist/config/services.js +4 -135
- package/dist/config/services.js.map +1 -1
- package/dist/config/sites.d.ts +0 -9
- package/dist/config/sites.js +82 -98
- package/dist/config/sites.js.map +1 -1
- package/dist/config/userChannels.d.ts +22 -29
- package/dist/config/userChannels.js +47 -65
- package/dist/config/userChannels.js.map +1 -1
- package/dist/config/userConfig.d.ts +19 -4
- package/dist/config/userConfig.js +123 -25
- package/dist/config/userConfig.js.map +1 -1
- package/dist/config/userProfiles.d.ts +2 -3
- package/dist/config/userProfiles.js +16 -13
- package/dist/config/userProfiles.js.map +1 -1
- package/dist/hdhr/channelMap.d.ts +0 -1
- package/dist/hdhr/deviceId.d.ts +0 -1
- package/dist/hdhr/discover.d.ts +0 -1
- package/dist/hdhr/getHandlers.d.ts +0 -1
- package/dist/hdhr/identity.d.ts +0 -1
- package/dist/hdhr/index.d.ts +0 -1
- package/dist/hdhr/protocol.d.ts +1 -2
- package/dist/hdhr/protocol.js +1 -1
- package/dist/hdhr/tunerState.d.ts +0 -1
- package/dist/hdhr/udp.d.ts +0 -1
- package/dist/hdhr/udp.js +16 -4
- package/dist/hdhr/udp.js.map +1 -1
- package/dist/identity.d.ts +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +10 -3
- package/dist/index.js.map +1 -1
- package/dist/native/codecInference.d.ts +5 -4
- package/dist/native/codecInference.js +12 -7
- package/dist/native/codecInference.js.map +1 -1
- package/dist/native/decrypt.d.ts +10 -3
- package/dist/native/decrypt.js +9 -5
- package/dist/native/decrypt.js.map +1 -1
- package/dist/native/index.d.ts +26 -24
- package/dist/native/index.js +26 -20
- package/dist/native/index.js.map +1 -1
- package/dist/native/probe.d.ts +7 -10
- package/dist/native/probe.js +41 -37
- package/dist/native/probe.js.map +1 -1
- package/dist/native/proxy.d.ts +3 -4
- package/dist/native/proxy.js +91 -69
- package/dist/native/proxy.js.map +1 -1
- package/dist/native/tokenExpiry.d.ts +0 -1
- package/dist/routes/assets.d.ts +0 -1
- package/dist/routes/auth.d.ts +0 -1
- package/dist/routes/auth.js +1 -1
- package/dist/routes/auth.js.map +1 -1
- package/dist/routes/cdp.d.ts +11 -5
- package/dist/routes/cdp.js +91 -63
- package/dist/routes/cdp.js.map +1 -1
- package/dist/routes/channels.d.ts +0 -1
- package/dist/routes/clientActions.d.ts +0 -1
- package/dist/routes/components.d.ts +0 -1
- package/dist/routes/config/channels/endpoints/browse.d.ts +0 -1
- package/dist/routes/config/channels/endpoints/bulk.d.ts +0 -1
- package/dist/routes/config/channels/endpoints/bulk.js +3 -3
- package/dist/routes/config/channels/endpoints/bulk.js.map +1 -1
- package/dist/routes/config/channels/endpoints/crud.d.ts +0 -1
- package/dist/routes/config/channels/endpoints/crud.js +4 -3
- package/dist/routes/config/channels/endpoints/crud.js.map +1 -1
- package/dist/routes/config/channels/endpoints/importExport.d.ts +0 -1
- package/dist/routes/config/channels/endpoints/importExport.js +7 -3
- package/dist/routes/config/channels/endpoints/importExport.js.map +1 -1
- package/dist/routes/config/channels/endpoints/predefined.d.ts +0 -1
- package/dist/routes/config/channels/endpoints/prefs.d.ts +0 -1
- package/dist/routes/config/channels/endpoints/prefs.js +1 -1
- package/dist/routes/config/channels/endpoints/prefs.js.map +1 -1
- package/dist/routes/config/channels/endpoints/service.d.ts +0 -1
- package/dist/routes/config/channels/endpoints/service.js +8 -5
- package/dist/routes/config/channels/endpoints/service.js.map +1 -1
- package/dist/routes/config/channels/endpoints/tags.d.ts +0 -1
- package/dist/routes/config/channels/endpoints/tags.js +3 -3
- package/dist/routes/config/channels/endpoints/tags.js.map +1 -1
- package/dist/routes/config/channels/healthBridge.d.ts +4 -1
- package/dist/routes/config/channels/healthBridge.js +9 -5
- package/dist/routes/config/channels/healthBridge.js.map +1 -1
- package/dist/routes/config/channels/http/handler.d.ts +0 -1
- package/dist/routes/config/channels/http/playlistHint.d.ts +0 -1
- package/dist/routes/config/channels/http/serviceWarning.d.ts +0 -1
- package/dist/routes/config/channels/http/serviceWarning.js +1 -1
- package/dist/routes/config/channels/http/serviceWarning.js.map +1 -1
- package/dist/routes/config/channels/index.d.ts +0 -1
- package/dist/routes/config/channels/setup.d.ts +0 -1
- package/dist/routes/config/channels/table.d.ts +0 -1
- package/dist/routes/config/channels/table.js +66 -134
- package/dist/routes/config/channels/table.js.map +1 -1
- package/dist/routes/config/http/envelope.d.ts +1 -2
- package/dist/routes/config/index.d.ts +5 -5
- package/dist/routes/config/index.js +7 -5
- package/dist/routes/config/index.js.map +1 -1
- package/dist/routes/config/services.d.ts +0 -1
- package/dist/routes/config/services.js +17 -19
- package/dist/routes/config/services.js.map +1 -1
- package/dist/routes/config/settings.d.ts +6 -15
- package/dist/routes/config/settings.js +16 -35
- package/dist/routes/config/settings.js.map +1 -1
- package/dist/routes/debug.d.ts +0 -1
- package/dist/routes/debug.js +1 -1
- package/dist/routes/debug.js.map +1 -1
- package/dist/routes/health.d.ts +16 -8
- package/dist/routes/health.js +27 -12
- package/dist/routes/health.js.map +1 -1
- package/dist/routes/hls.d.ts +0 -1
- package/dist/routes/icons.d.ts +0 -1
- package/dist/routes/index.d.ts +0 -1
- package/dist/routes/logs.d.ts +3 -2
- package/dist/routes/logs.js +54 -14
- package/dist/routes/logs.js.map +1 -1
- package/dist/routes/mpegts.d.ts +0 -1
- package/dist/routes/play.d.ts +0 -1
- package/dist/routes/playlist.d.ts +0 -1
- package/dist/routes/playlist.js +2 -1
- package/dist/routes/playlist.js.map +1 -1
- package/dist/routes/root/content.d.ts +0 -1
- package/dist/routes/root/content.js +32 -11
- package/dist/routes/root/content.js.map +1 -1
- package/dist/routes/root/index.d.ts +10 -1
- package/dist/routes/root/index.js +17 -7
- package/dist/routes/root/index.js.map +1 -1
- package/dist/routes/root/scripts/channels.d.ts +0 -1
- package/dist/routes/root/scripts/channels.js +10 -20
- package/dist/routes/root/scripts/channels.js.map +1 -1
- package/dist/routes/root/scripts/clientEscape.d.ts +0 -1
- package/dist/routes/root/scripts/clientEscape.js +1 -1
- package/dist/routes/root/scripts/clientUrl.d.ts +0 -1
- package/dist/routes/root/scripts/config.d.ts +0 -1
- package/dist/routes/root/scripts/config.js +8 -29
- package/dist/routes/root/scripts/config.js.map +1 -1
- package/dist/routes/root/scripts/index.d.ts +0 -1
- package/dist/routes/root/scripts/shared.d.ts +0 -1
- package/dist/routes/root/scripts/shared.js +16 -13
- package/dist/routes/root/scripts/shared.js.map +1 -1
- package/dist/routes/root/scripts/status.d.ts +0 -1
- package/dist/routes/root/scripts/status.handlers.d.ts +3 -1
- package/dist/routes/root/scripts/status.handlers.js +52 -26
- package/dist/routes/root/scripts/status.handlers.js.map +1 -1
- package/dist/routes/root/styles.d.ts +0 -1
- package/dist/routes/root/styles.js +10 -18
- package/dist/routes/root/styles.js.map +1 -1
- package/dist/routes/services.d.ts +0 -1
- package/dist/routes/services.js +1 -1
- package/dist/routes/services.js.map +1 -1
- package/dist/routes/sse.d.ts +3 -2
- package/dist/routes/sse.js +7 -3
- package/dist/routes/sse.js.map +1 -1
- package/dist/routes/streams.d.ts +4 -2
- package/dist/routes/streams.js +8 -5
- package/dist/routes/streams.js.map +1 -1
- package/dist/routes/theme.d.ts +0 -1
- package/dist/routes/theme.js +3 -3
- package/dist/routes/theme.js.map +1 -1
- package/dist/routes/ui.d.ts +0 -1
- package/dist/routes/ui.js +5 -5
- package/dist/routes/ui.js.map +1 -1
- package/dist/routes/upgrade.d.ts +0 -1
- package/dist/routes/upgrade.js +2 -1
- package/dist/routes/upgrade.js.map +1 -1
- package/dist/service/commands.context.d.ts +0 -1
- package/dist/service/commands.context.js +7 -1
- package/dist/service/commands.context.js.map +1 -1
- package/dist/service/commands.d.ts +0 -1
- package/dist/service/generators.context.d.ts +0 -1
- package/dist/service/generators.d.ts +0 -1
- package/dist/service/index.d.ts +0 -1
- package/dist/streaming/captureLock.d.ts +1 -2
- package/dist/streaming/captureLock.js +8 -7
- package/dist/streaming/captureLock.js.map +1 -1
- package/dist/streaming/captureSession.d.ts +0 -1
- package/dist/streaming/clients.d.ts +4 -3
- package/dist/streaming/clients.js +5 -4
- package/dist/streaming/clients.js.map +1 -1
- package/dist/streaming/codec.d.ts +0 -1
- package/dist/streaming/fmp4Segmenter.d.ts +11 -6
- package/dist/streaming/fmp4Segmenter.js +39 -17
- package/dist/streaming/fmp4Segmenter.js.map +1 -1
- package/dist/streaming/hls.d.ts +96 -3
- package/dist/streaming/hls.js +282 -171
- package/dist/streaming/hls.js.map +1 -1
- package/dist/streaming/hlsResume.d.ts +8 -5
- package/dist/streaming/hlsResume.js +10 -8
- package/dist/streaming/hlsResume.js.map +1 -1
- package/dist/streaming/hlsSegments.d.ts +11 -8
- package/dist/streaming/hlsSegments.js +38 -18
- package/dist/streaming/hlsSegments.js.map +1 -1
- package/dist/streaming/lifecycle.d.ts +5 -4
- package/dist/streaming/lifecycle.js +43 -13
- package/dist/streaming/lifecycle.js.map +1 -1
- package/dist/streaming/monitor.d.ts +14 -3
- package/dist/streaming/monitor.js +447 -234
- package/dist/streaming/monitor.js.map +1 -1
- package/dist/streaming/mp4Parser.d.ts +0 -1
- package/dist/streaming/mpegts.d.ts +11 -1
- package/dist/streaming/mpegts.js +92 -28
- package/dist/streaming/mpegts.js.map +1 -1
- package/dist/streaming/playlistBuilder.d.ts +0 -1
- package/dist/streaming/preroll.d.ts +34 -15
- package/dist/streaming/preroll.js +32 -30
- package/dist/streaming/preroll.js.map +1 -1
- package/dist/streaming/pretune.d.ts +2 -3
- package/dist/streaming/pretune.js +45 -45
- package/dist/streaming/pretune.js.map +1 -1
- package/dist/streaming/pretuneTimers.d.ts +16 -12
- package/dist/streaming/pretuneTimers.js +27 -37
- package/dist/streaming/pretuneTimers.js.map +1 -1
- package/dist/streaming/recovery.d.ts +97 -9
- package/dist/streaming/recovery.js +96 -18
- package/dist/streaming/recovery.js.map +1 -1
- package/dist/streaming/registry.d.ts +102 -15
- package/dist/streaming/registry.js +90 -5
- package/dist/streaming/registry.js.map +1 -1
- package/dist/streaming/setup.d.ts +90 -32
- package/dist/streaming/setup.js +379 -248
- package/dist/streaming/setup.js.map +1 -1
- package/dist/streaming/showInfo.d.ts +8 -4
- package/dist/streaming/showInfo.js +54 -45
- package/dist/streaming/showInfo.js.map +1 -1
- package/dist/streaming/statusEmitter.d.ts +5 -3
- package/dist/streaming/statusEmitter.js +20 -8
- package/dist/streaming/statusEmitter.js.map +1 -1
- package/dist/types/channels.d.ts +0 -1
- package/dist/types/channels.js +0 -4
- package/dist/types/channels.js.map +1 -1
- package/dist/types/config.d.ts +0 -1
- package/dist/types/index.d.ts +4 -4
- package/dist/types/index.js +2 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/profiles.d.ts +51 -9
- package/dist/types/profiles.js +35 -1
- package/dist/types/profiles.js.map +1 -1
- package/dist/types/selection.d.ts +10 -1
- package/dist/types/shared.d.ts +0 -1
- package/dist/types/streaming.d.ts +8 -1
- package/dist/types/streaming.js +7 -0
- package/dist/types/streaming.js.map +1 -1
- package/dist/upgrade/commands.context.d.ts +0 -1
- package/dist/upgrade/commands.d.ts +0 -1
- package/dist/upgrade/commands.js +1 -1
- package/dist/upgrade/commands.js.map +1 -1
- package/dist/upgrade/detection.context.d.ts +0 -1
- package/dist/upgrade/detection.d.ts +1 -2
- package/dist/upgrade/index.d.ts +0 -1
- package/dist/upgrade/lifecycle.context.d.ts +2 -1
- package/dist/upgrade/lifecycle.context.js +9 -4
- package/dist/upgrade/lifecycle.context.js.map +1 -1
- package/dist/upgrade/lifecycle.d.ts +0 -1
- package/dist/upgrade/pathHandle.d.ts +0 -1
- package/dist/utils/bootSession.context.d.ts +0 -1
- package/dist/utils/bootSession.context.js +3 -2
- package/dist/utils/bootSession.context.js.map +1 -1
- package/dist/utils/bootSession.d.ts +0 -1
- package/dist/utils/chromeFetch.d.ts +0 -1
- package/dist/utils/cliOutput.d.ts +0 -1
- package/dist/utils/debugFilter.d.ts +0 -1
- package/dist/utils/debugFilter.js +5 -3
- package/dist/utils/debugFilter.js.map +1 -1
- package/dist/utils/delay.d.ts +65 -13
- package/dist/utils/delay.js +96 -23
- package/dist/utils/delay.js.map +1 -1
- package/dist/utils/errors.d.ts +0 -11
- package/dist/utils/errors.js +3 -14
- package/dist/utils/errors.js.map +1 -1
- package/dist/utils/evaluate.d.ts +11 -3
- package/dist/utils/evaluate.js +4 -3
- package/dist/utils/evaluate.js.map +1 -1
- package/dist/utils/ffmpeg.context.d.ts +0 -1
- package/dist/utils/ffmpeg.d.ts +1 -1
- package/dist/utils/ffmpeg.js +2 -1
- package/dist/utils/ffmpeg.js.map +1 -1
- package/dist/utils/fileLogger.d.ts +26 -7
- package/dist/utils/fileLogger.js +241 -102
- package/dist/utils/fileLogger.js.map +1 -1
- package/dist/utils/format.d.ts +36 -4
- package/dist/utils/format.js +66 -12
- package/dist/utils/format.js.map +1 -1
- package/dist/utils/index.d.ts +1 -2
- package/dist/utils/index.js +1 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/logEmitter.d.ts +0 -1
- package/dist/utils/logger.d.ts +0 -1
- package/dist/utils/m3u.d.ts +0 -1
- package/dist/utils/markup.d.ts +0 -1
- package/dist/utils/memo.d.ts +0 -1
- package/dist/utils/morganStream.d.ts +2 -3
- package/dist/utils/morganStream.js +6 -8
- package/dist/utils/morganStream.js.map +1 -1
- package/dist/utils/network.d.ts +0 -1
- package/dist/utils/never.d.ts +8 -0
- package/dist/utils/never.js +20 -0
- package/dist/utils/never.js.map +1 -0
- package/dist/utils/pid.d.ts +0 -1
- package/dist/utils/platform.d.ts +0 -1
- package/dist/utils/processInspector.context.d.ts +32 -2
- package/dist/utils/processInspector.context.js +117 -1
- package/dist/utils/processInspector.context.js.map +1 -1
- package/dist/utils/processInspector.d.ts +0 -32
- package/dist/utils/processInspector.js +10 -117
- package/dist/utils/processInspector.js.map +1 -1
- package/dist/utils/retry.d.ts +5 -4
- package/dist/utils/retry.js +43 -33
- package/dist/utils/retry.js.map +1 -1
- package/dist/utils/runtimeIdentity.context.d.ts +0 -1
- package/dist/utils/runtimeIdentity.context.js +3 -1
- package/dist/utils/runtimeIdentity.context.js.map +1 -1
- package/dist/utils/runtimeIdentity.d.ts +1 -1
- package/dist/utils/runtimeIdentity.js +1 -1
- package/dist/utils/runtimeIdentity.js.map +1 -1
- package/dist/utils/sanitize.d.ts +8 -1
- package/dist/utils/sanitize.js +19 -0
- package/dist/utils/sanitize.js.map +1 -1
- package/dist/utils/streamContext.d.ts +0 -1
- package/dist/utils/timing.d.ts +3 -4
- package/dist/utils/timing.js +4 -4
- package/dist/utils/timing.js.map +1 -1
- package/dist/utils/version.d.ts +14 -8
- package/dist/utils/version.js +35 -24
- package/dist/utils/version.js.map +1 -1
- package/package.json +7 -7
- package/dist/app.d.ts.map +0 -1
- package/dist/browser/blockedPage.d.ts.map +0 -1
- package/dist/browser/browserSupervisor.d.ts.map +0 -1
- package/dist/browser/cdp.d.ts.map +0 -1
- package/dist/browser/channelSelection.d.ts.map +0 -1
- package/dist/browser/consent.d.ts.map +0 -1
- package/dist/browser/display.d.ts.map +0 -1
- package/dist/browser/hlsPlaylistObserver.d.ts.map +0 -1
- package/dist/browser/index.d.ts.map +0 -1
- package/dist/browser/launchGovernor.d.ts.map +0 -1
- package/dist/browser/login.d.ts.map +0 -1
- package/dist/browser/manifestInterceptor.d.ts.map +0 -1
- package/dist/browser/pageStaleness.d.ts.map +0 -1
- package/dist/browser/precaching.d.ts.map +0 -1
- package/dist/browser/tabNetworkObserver.d.ts.map +0 -1
- package/dist/browser/tuning/cache.d.ts.map +0 -1
- package/dist/browser/tuning/comcastPolymer.d.ts.map +0 -1
- package/dist/browser/tuning/cox.d.ts.map +0 -1
- package/dist/browser/tuning/directv.d.ts.map +0 -1
- package/dist/browser/tuning/fox.d.ts.map +0 -1
- package/dist/browser/tuning/gridSearch.d.ts.map +0 -1
- package/dist/browser/tuning/hbo.d.ts.map +0 -1
- package/dist/browser/tuning/hulu.d.ts.map +0 -1
- package/dist/browser/tuning/shared.d.ts.map +0 -1
- package/dist/browser/tuning/sling.d.ts.map +0 -1
- package/dist/browser/tuning/spectrum.d.ts.map +0 -1
- package/dist/browser/tuning/thumbnailRow.d.ts.map +0 -1
- package/dist/browser/tuning/tileClick.d.ts.map +0 -1
- package/dist/browser/tuning/xfinity.d.ts.map +0 -1
- package/dist/browser/tuning/youtubeTv.d.ts.map +0 -1
- package/dist/browser/video.d.ts.map +0 -1
- package/dist/channels/index.d.ts.map +0 -1
- package/dist/config/channelForm.d.ts.map +0 -1
- package/dist/config/consistencyProbe.d.ts.map +0 -1
- package/dist/config/health.d.ts.map +0 -1
- package/dist/config/index.d.ts.map +0 -1
- package/dist/config/paths.d.ts.map +0 -1
- package/dist/config/persistence.context.d.ts.map +0 -1
- package/dist/config/persistence.d.ts.map +0 -1
- package/dist/config/presets.d.ts.map +0 -1
- package/dist/config/profiles.d.ts.map +0 -1
- package/dist/config/providerLineups.d.ts.map +0 -1
- package/dist/config/reactivity.d.ts.map +0 -1
- package/dist/config/servicePacks.d.ts.map +0 -1
- package/dist/config/services.d.ts.map +0 -1
- package/dist/config/sites.d.ts.map +0 -1
- package/dist/config/userChannels.d.ts.map +0 -1
- package/dist/config/userConfig.d.ts.map +0 -1
- package/dist/config/userProfiles.d.ts.map +0 -1
- package/dist/hdhr/channelMap.d.ts.map +0 -1
- package/dist/hdhr/deviceId.d.ts.map +0 -1
- package/dist/hdhr/discover.d.ts.map +0 -1
- package/dist/hdhr/getHandlers.d.ts.map +0 -1
- package/dist/hdhr/identity.d.ts.map +0 -1
- package/dist/hdhr/index.d.ts.map +0 -1
- package/dist/hdhr/protocol.d.ts.map +0 -1
- package/dist/hdhr/tunerState.d.ts.map +0 -1
- package/dist/hdhr/udp.d.ts.map +0 -1
- package/dist/identity.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/native/codecInference.d.ts.map +0 -1
- package/dist/native/decrypt.d.ts.map +0 -1
- package/dist/native/index.d.ts.map +0 -1
- package/dist/native/probe.d.ts.map +0 -1
- package/dist/native/proxy.d.ts.map +0 -1
- package/dist/native/tokenExpiry.d.ts.map +0 -1
- package/dist/routes/assets.d.ts.map +0 -1
- package/dist/routes/auth.d.ts.map +0 -1
- package/dist/routes/cdp.d.ts.map +0 -1
- package/dist/routes/channels.d.ts.map +0 -1
- package/dist/routes/clientActions.d.ts.map +0 -1
- package/dist/routes/components.d.ts.map +0 -1
- package/dist/routes/config/channels/endpoints/browse.d.ts.map +0 -1
- package/dist/routes/config/channels/endpoints/bulk.d.ts.map +0 -1
- package/dist/routes/config/channels/endpoints/crud.d.ts.map +0 -1
- package/dist/routes/config/channels/endpoints/importExport.d.ts.map +0 -1
- package/dist/routes/config/channels/endpoints/predefined.d.ts.map +0 -1
- package/dist/routes/config/channels/endpoints/prefs.d.ts.map +0 -1
- package/dist/routes/config/channels/endpoints/service.d.ts.map +0 -1
- package/dist/routes/config/channels/endpoints/tags.d.ts.map +0 -1
- package/dist/routes/config/channels/healthBridge.d.ts.map +0 -1
- package/dist/routes/config/channels/http/handler.d.ts.map +0 -1
- package/dist/routes/config/channels/http/playlistHint.d.ts.map +0 -1
- package/dist/routes/config/channels/http/serviceWarning.d.ts.map +0 -1
- package/dist/routes/config/channels/index.d.ts.map +0 -1
- package/dist/routes/config/channels/setup.d.ts.map +0 -1
- package/dist/routes/config/channels/table.d.ts.map +0 -1
- package/dist/routes/config/http/envelope.d.ts.map +0 -1
- package/dist/routes/config/index.d.ts.map +0 -1
- package/dist/routes/config/services.d.ts.map +0 -1
- package/dist/routes/config/settings.d.ts.map +0 -1
- package/dist/routes/debug.d.ts.map +0 -1
- package/dist/routes/health.d.ts.map +0 -1
- package/dist/routes/hls.d.ts.map +0 -1
- package/dist/routes/icons.d.ts.map +0 -1
- package/dist/routes/index.d.ts.map +0 -1
- package/dist/routes/logs.d.ts.map +0 -1
- package/dist/routes/mpegts.d.ts.map +0 -1
- package/dist/routes/play.d.ts.map +0 -1
- package/dist/routes/playlist.d.ts.map +0 -1
- package/dist/routes/root/content.d.ts.map +0 -1
- package/dist/routes/root/index.d.ts.map +0 -1
- package/dist/routes/root/scripts/channels.d.ts.map +0 -1
- package/dist/routes/root/scripts/clientEscape.d.ts.map +0 -1
- package/dist/routes/root/scripts/clientUrl.d.ts.map +0 -1
- package/dist/routes/root/scripts/config.d.ts.map +0 -1
- package/dist/routes/root/scripts/index.d.ts.map +0 -1
- package/dist/routes/root/scripts/shared.d.ts.map +0 -1
- package/dist/routes/root/scripts/status.d.ts.map +0 -1
- package/dist/routes/root/scripts/status.handlers.d.ts.map +0 -1
- package/dist/routes/root/styles.d.ts.map +0 -1
- package/dist/routes/services.d.ts.map +0 -1
- package/dist/routes/sse.d.ts.map +0 -1
- package/dist/routes/streams.d.ts.map +0 -1
- package/dist/routes/theme.d.ts.map +0 -1
- package/dist/routes/ui.d.ts.map +0 -1
- package/dist/routes/upgrade.d.ts.map +0 -1
- package/dist/service/commands.context.d.ts.map +0 -1
- package/dist/service/commands.d.ts.map +0 -1
- package/dist/service/generators.context.d.ts.map +0 -1
- package/dist/service/generators.d.ts.map +0 -1
- package/dist/service/index.d.ts.map +0 -1
- package/dist/streaming/captureLock.d.ts.map +0 -1
- package/dist/streaming/captureSession.d.ts.map +0 -1
- package/dist/streaming/clients.d.ts.map +0 -1
- package/dist/streaming/codec.d.ts.map +0 -1
- package/dist/streaming/fmp4Segmenter.d.ts.map +0 -1
- package/dist/streaming/hls.d.ts.map +0 -1
- package/dist/streaming/hlsResume.d.ts.map +0 -1
- package/dist/streaming/hlsSegments.d.ts.map +0 -1
- package/dist/streaming/lifecycle.d.ts.map +0 -1
- package/dist/streaming/monitor.d.ts.map +0 -1
- package/dist/streaming/mp4Parser.d.ts.map +0 -1
- package/dist/streaming/mpegts.d.ts.map +0 -1
- package/dist/streaming/playlistBuilder.d.ts.map +0 -1
- package/dist/streaming/preroll.d.ts.map +0 -1
- package/dist/streaming/pretune.d.ts.map +0 -1
- package/dist/streaming/pretuneTimers.d.ts.map +0 -1
- package/dist/streaming/recovery.d.ts.map +0 -1
- package/dist/streaming/registry.d.ts.map +0 -1
- package/dist/streaming/setup.d.ts.map +0 -1
- package/dist/streaming/showInfo.d.ts.map +0 -1
- package/dist/streaming/statusEmitter.d.ts.map +0 -1
- package/dist/types/channels.d.ts.map +0 -1
- package/dist/types/config.d.ts.map +0 -1
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/profiles.d.ts.map +0 -1
- package/dist/types/selection.d.ts.map +0 -1
- package/dist/types/shared.d.ts.map +0 -1
- package/dist/types/streaming.d.ts.map +0 -1
- package/dist/upgrade/commands.context.d.ts.map +0 -1
- package/dist/upgrade/commands.d.ts.map +0 -1
- package/dist/upgrade/detection.context.d.ts.map +0 -1
- package/dist/upgrade/detection.d.ts.map +0 -1
- package/dist/upgrade/index.d.ts.map +0 -1
- package/dist/upgrade/lifecycle.context.d.ts.map +0 -1
- package/dist/upgrade/lifecycle.d.ts.map +0 -1
- package/dist/upgrade/pathHandle.d.ts.map +0 -1
- package/dist/utils/bootSession.context.d.ts.map +0 -1
- package/dist/utils/bootSession.d.ts.map +0 -1
- package/dist/utils/chromeFetch.d.ts.map +0 -1
- package/dist/utils/cliOutput.d.ts.map +0 -1
- package/dist/utils/clock.d.ts +0 -15
- package/dist/utils/clock.d.ts.map +0 -1
- package/dist/utils/clock.js +0 -31
- package/dist/utils/clock.js.map +0 -1
- package/dist/utils/debugFilter.d.ts.map +0 -1
- package/dist/utils/delay.d.ts.map +0 -1
- package/dist/utils/errors.d.ts.map +0 -1
- package/dist/utils/evaluate.d.ts.map +0 -1
- package/dist/utils/ffmpeg.context.d.ts.map +0 -1
- package/dist/utils/ffmpeg.d.ts.map +0 -1
- package/dist/utils/fileLogger.d.ts.map +0 -1
- package/dist/utils/format.d.ts.map +0 -1
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/logEmitter.d.ts.map +0 -1
- package/dist/utils/logger.d.ts.map +0 -1
- package/dist/utils/m3u.d.ts.map +0 -1
- package/dist/utils/markup.d.ts.map +0 -1
- package/dist/utils/memo.d.ts.map +0 -1
- package/dist/utils/morganStream.d.ts.map +0 -1
- package/dist/utils/network.d.ts.map +0 -1
- package/dist/utils/pid.d.ts.map +0 -1
- package/dist/utils/platform.d.ts.map +0 -1
- package/dist/utils/processInspector.context.d.ts.map +0 -1
- package/dist/utils/processInspector.d.ts.map +0 -1
- package/dist/utils/retry.d.ts.map +0 -1
- package/dist/utils/runtimeIdentity.context.d.ts.map +0 -1
- package/dist/utils/runtimeIdentity.d.ts.map +0 -1
- package/dist/utils/sanitize.d.ts.map +0 -1
- package/dist/utils/streamContext.d.ts.map +0 -1
- package/dist/utils/timing.d.ts.map +0 -1
- package/dist/utils/version.d.ts.map +0 -1
package/dist/utils/fileLogger.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
import { assertNever } from "./never.js";
|
|
2
|
+
import { boundedWait } from "./delay.js";
|
|
1
3
|
import { formatTimestamp } from "./format.js";
|
|
2
4
|
import fs from "node:fs";
|
|
3
5
|
import { isAnyDebugEnabled } from "./debugFilter.js";
|
|
4
6
|
import path from "node:path";
|
|
5
7
|
import { styleText } from "node:util";
|
|
8
|
+
import { systemClock } from "homebridge-plugin-utils";
|
|
6
9
|
const { promises: fsPromises } = fs;
|
|
7
10
|
/* The file logger provides persistent logging to a configurable log file with automatic size-based trimming. When the log file exceeds the configured maximum
|
|
8
11
|
* size, it is trimmed to half the maximum size, keeping only complete lines (the most recent logs are preserved). This approach prevents unbounded log growth while
|
|
@@ -18,76 +21,129 @@ const { promises: fsPromises } = fs;
|
|
|
18
21
|
* 5. Terminal coloring - SGR escape codes are baked into the file output via styleText so that viewing the log with terminal commands (tail -f, less -R, cat)
|
|
19
22
|
* shows the same color scheme as console output. styleText emits both the opening color code and the trailing reset in one call, with validateStream disabled
|
|
20
23
|
* because the log file is not a TTY but we still want the codes preserved for downstream terminal viewers.
|
|
24
|
+
* 6. Startup window - The logger cannot open its file until the configuration that names the path and the size cap has been read, and reading it is itself
|
|
25
|
+
* worth logging. Entries emitted in the window state, before the one initialization, are held in the write buffer and appended by the first flush after it,
|
|
26
|
+
* so the log file opens with the boot messages that preceded it. The window is bounded, and the initialization leaves it whether it succeeds or fails.
|
|
21
27
|
*/
|
|
22
|
-
/* The file logger
|
|
23
|
-
* startup.
|
|
28
|
+
/* The file logger's module state: the lifecycle state that says where a line goes, plus the bookkeeping of the file it is open on. Every one of them is set up
|
|
29
|
+
* by the initializeFileLogger() call during server startup.
|
|
30
|
+
*/
|
|
31
|
+
// Where the logger is in its lifecycle. Only transition() assigns it, which is what gives the flush timer a single owner.
|
|
32
|
+
let state = { kind: "window" };
|
|
33
|
+
/* Buffer collecting log entries between flushes. It is the open file's bookkeeping rather than a member of the open state: the write path pushes to it once per
|
|
34
|
+
* line, and rebuilding a state object per line would allocate on every log call.
|
|
24
35
|
*/
|
|
25
|
-
// Path to the log file, set during initialization.
|
|
26
|
-
let logFilePath = null;
|
|
27
|
-
// Buffer for collecting log entries before flushing to disk.
|
|
28
36
|
let writeBuffer = [];
|
|
29
|
-
//
|
|
30
|
-
let approximateSize = 0;
|
|
31
|
-
// Counter for tracking writes since last file size check.
|
|
37
|
+
// Writes since the last file size check, beside the state for the same reason the buffer is - the write path bumps it once per line.
|
|
32
38
|
let writeCount = 0;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
*
|
|
39
|
-
* overwrite the just-appended lines with stale trimmed content - silently dropping log entries. Routing both paths through a single ordering primitive makes
|
|
40
|
-
* "read-modify-rename" and "append" mutually exclusive without an explicit lock. The tail never rejects: the helper that enqueues work swallows the settled
|
|
41
|
-
* outcome before chaining the next operation, so one failing operation cannot poison the chain for subsequent writes.
|
|
39
|
+
/* Tail of the write-ordering chain, the open file's bookkeeping rather than a member of its state. Every asynchronous mutation of the log file (buffer flushes
|
|
40
|
+
* and trims) is appended to this promise so that the operations run strictly one after another. Without this serialization a flush's appendFile could land
|
|
41
|
+
* between a trim's readFile and its rename, and the rename would then overwrite the just-appended lines with stale trimmed content - silently dropping log
|
|
42
|
+
* entries. Routing both paths through a single ordering primitive makes "read-modify-rename" and "append" mutually exclusive without an explicit lock. The tail
|
|
43
|
+
* never rejects: the helper that enqueues work swallows the settled outcome before chaining the next operation, so one failing operation cannot poison the chain
|
|
44
|
+
* for subsequent writes.
|
|
42
45
|
*/
|
|
43
46
|
let writeChain = Promise.resolve();
|
|
44
|
-
//
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
// Maximum log file size, set during initialization.
|
|
47
|
+
// How long shutdown waits for the outstanding write chain to drain. Generous enough for a trim's read, write, and rename on a busy disk, and short enough that a
|
|
48
|
+
// wedged filesystem operation cannot hold the process open through its own shutdown.
|
|
49
|
+
const SHUTDOWN_DRAIN_BOUND_MS = 5000;
|
|
50
|
+
// Maximum log file size, set during initialization. It is configuration the trim reads rather than lifecycle, so it stays beside the state.
|
|
49
51
|
let maxLogSize = 1048576;
|
|
52
|
+
/* The clock the flush interval arms on and the pause stamps read, set during initialization. It is per-run configuration the way the size cap is, so it stays
|
|
53
|
+
* beside the state rather than inside it: a member of the open variant would put the clock's lifetime where the file keeps lifecycle, and the closing and closed
|
|
54
|
+
* states read it too.
|
|
55
|
+
*/
|
|
56
|
+
let loggerClock = systemClock;
|
|
50
57
|
// Configuration Constants.
|
|
51
58
|
// Interval in milliseconds between buffer flushes.
|
|
52
59
|
const FLUSH_INTERVAL_MS = 1000;
|
|
53
60
|
// Number of writes between file size checks.
|
|
54
61
|
const SIZE_CHECK_FREQUENCY = 100;
|
|
55
|
-
// Duration in milliseconds
|
|
62
|
+
// Duration in milliseconds a paused file drops entries for before the next write retries it.
|
|
56
63
|
const ERROR_RETRY_DELAY_MS = 60000;
|
|
64
|
+
// The most entries the startup window holds. A push past the limit drops the oldest entry, because the newest lines are the ones that explain an exit.
|
|
65
|
+
const STARTUP_BUFFER_LIMIT = 1000;
|
|
66
|
+
// Lifecycle State.
|
|
67
|
+
/**
|
|
68
|
+
* Moves the logger to its next state. Every transition goes through here, and this is where the flush timer's lifetime is decided: a timer belongs to the
|
|
69
|
+
* states that carry one, so leaving them for a state that does not carry the same timer stops it, whichever transition is leaving.
|
|
70
|
+
* @param next - The state the logger enters.
|
|
71
|
+
*/
|
|
72
|
+
function transition(next) {
|
|
73
|
+
if (("timer" in state) && (!("timer" in next) || (next.timer !== state.timer))) {
|
|
74
|
+
state.timer[Symbol.dispose]();
|
|
75
|
+
}
|
|
76
|
+
state = next;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* The path of the file the logger writes through its buffer, while it has one: the open and closing states. The window has no file yet, the off state has
|
|
80
|
+
* none, and the closed state keeps its path for the synchronous append in writeLogEntry rather than for the buffered paths this reader serves.
|
|
81
|
+
* @returns The path, or null when no file is open.
|
|
82
|
+
*/
|
|
83
|
+
function openFilePath() {
|
|
84
|
+
switch (state.kind) {
|
|
85
|
+
case "open":
|
|
86
|
+
case "closing": {
|
|
87
|
+
return state.path;
|
|
88
|
+
}
|
|
89
|
+
case "window":
|
|
90
|
+
case "closed":
|
|
91
|
+
case "off": {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
default: {
|
|
95
|
+
return assertNever(state);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
57
99
|
// Initialization.
|
|
58
100
|
/**
|
|
59
|
-
* Initializes the file logger. Creates the log file if it does not exist. Must be called after the data directory is ensured to exist.
|
|
101
|
+
* Initializes the file logger. Creates the log file if it does not exist. Must be called after the data directory is ensured to exist. A call is the one
|
|
102
|
+
* initialization of the process: it enters open, leaving the window's entries in the buffer for the first flush to append, or off, discarding them. Either
|
|
103
|
+
* outcome leaves the startup window behind.
|
|
60
104
|
* @param logPath - Absolute path to the log file, resolved by the caller via getLogFilePath().
|
|
61
105
|
* @param maxSize - Maximum log file size in bytes from CONFIG.logging.maxSize.
|
|
106
|
+
* @param clock - The clock the flush interval arms on and the pause stamps read; defaults to the system clock.
|
|
62
107
|
*/
|
|
63
|
-
export async function initializeFileLogger(logPath, maxSize) {
|
|
64
|
-
|
|
108
|
+
export async function initializeFileLogger(logPath, maxSize, clock = systemClock) {
|
|
109
|
+
/* This runs before the first await below, because the states it leaves must not survive into that gap. A later initialization supersedes the file the last
|
|
110
|
+
* run closed, so a line landing inside these awaits is dropped rather than appended to a file this run has moved on from; a timer a still-open logger carried
|
|
111
|
+
* is stopped by the chokepoint on the way through; and the window is the one state left alone, because the lines it holds are the boot messages the first
|
|
112
|
+
* flush appends.
|
|
113
|
+
*/
|
|
114
|
+
if (state.kind !== "window") {
|
|
115
|
+
transition({ kind: "off" });
|
|
116
|
+
}
|
|
117
|
+
loggerClock = clock;
|
|
65
118
|
maxLogSize = maxSize;
|
|
66
119
|
try {
|
|
67
120
|
// Ensure the parent directory of the log file exists.
|
|
68
|
-
await fsPromises.mkdir(path.dirname(
|
|
69
|
-
//
|
|
121
|
+
await fsPromises.mkdir(path.dirname(logPath), { recursive: true });
|
|
122
|
+
// The stat asks one question - does the file exist - and its result is not needed beyond that, because an existing file is appended to as it stands and
|
|
123
|
+
// the periodic check reads the size from the disk when it needs one.
|
|
70
124
|
try {
|
|
71
|
-
|
|
72
|
-
approximateSize = stats.size;
|
|
125
|
+
await fsPromises.stat(logPath);
|
|
73
126
|
}
|
|
74
127
|
catch (error) {
|
|
75
128
|
// File does not exist, create it.
|
|
76
129
|
if (error.code === "ENOENT") {
|
|
77
|
-
await fsPromises.writeFile(
|
|
78
|
-
approximateSize = 0;
|
|
130
|
+
await fsPromises.writeFile(logPath, "", "utf-8");
|
|
79
131
|
}
|
|
80
132
|
else {
|
|
81
133
|
throw error;
|
|
82
134
|
}
|
|
83
135
|
}
|
|
84
|
-
//
|
|
85
|
-
|
|
136
|
+
// The timer belongs to the state that holds the file, so it is created with that state and disposed by the chokepoint when the logger leaves it.
|
|
137
|
+
const timer = clock.schedule(() => {
|
|
86
138
|
void flushLogBuffer();
|
|
87
|
-
}, FLUSH_INTERVAL_MS);
|
|
88
|
-
|
|
139
|
+
}, FLUSH_INTERVAL_MS, { repeat: true });
|
|
140
|
+
transition({ kind: "open", path: logPath, pausedSince: null, timer });
|
|
89
141
|
}
|
|
90
142
|
catch (error) {
|
|
143
|
+
// A failed initialization discards what the window held and leaves the logger where no state takes a line: no file will ever take those entries, and
|
|
144
|
+
// holding them would grow the buffer for the life of the process.
|
|
145
|
+
writeBuffer = [];
|
|
146
|
+
transition({ kind: "off" });
|
|
91
147
|
// Log to console since file logging failed, but do not throw - file logging is a best-effort feature.
|
|
92
148
|
// eslint-disable-next-line no-console
|
|
93
149
|
console.error("Failed to initialize file logger: %s. File logging disabled.", (error instanceof Error) ? error.message : String(error));
|
|
@@ -95,38 +151,84 @@ export async function initializeFileLogger(logPath, maxSize) {
|
|
|
95
151
|
}
|
|
96
152
|
// Log Entry Writing.
|
|
97
153
|
/**
|
|
98
|
-
*
|
|
154
|
+
* Formats one log entry as it appears in the file: the timestamp, the level tag (carrying the debug category when one is supplied), and the message, colored
|
|
155
|
+
* and newline-terminated. The buffered path and the post-shutdown append both call it, so the shape of a line is stated in one place. See the file's design
|
|
156
|
+
* block for the rationale behind baking SGR codes into the file output.
|
|
99
157
|
* @param level - Log level ("info", "warn", "error", "debug").
|
|
100
158
|
* @param message - The formatted log message.
|
|
101
159
|
* @param color - Color name accepted by node:util.styleText, or null for the default terminal color.
|
|
102
160
|
* @param categoryTag - Optional debug category tag (e.g., "recovery:tab"). Appended to the level prefix as [DEBUG:category].
|
|
161
|
+
* @returns The entry text, terminated by a newline.
|
|
103
162
|
*/
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
// Check if logging is disabled due to previous error and whether retry delay has passed.
|
|
109
|
-
if (isDisabled) {
|
|
110
|
-
if ((Date.now() - disabledAt) < ERROR_RETRY_DELAY_MS) {
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
// Re-enable logging and try again.
|
|
114
|
-
isDisabled = false;
|
|
115
|
-
}
|
|
116
|
-
// Format the log entry with timestamp and level. See the file's design block for the rationale behind baking SGR codes into the file output.
|
|
117
|
-
const timestamp = formatTimestamp();
|
|
163
|
+
function formatLogEntry(level, message, color, categoryTag) {
|
|
164
|
+
const timestamp = formatTimestamp(loggerClock.now());
|
|
118
165
|
const levelTag = categoryTag ? level.toUpperCase() + ":" + categoryTag : level.toUpperCase();
|
|
119
166
|
const levelPrefix = (level === "info") ? "" : "[" + levelTag + "] ";
|
|
120
167
|
const body = levelPrefix + message;
|
|
121
168
|
const coloredBody = color ? styleText(color, body, { validateStream: false }) : body;
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
169
|
+
return "[" + timestamp + "] " + coloredBody + "\n";
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Writes a log entry to the buffer. Entries are flushed to disk periodically.
|
|
173
|
+
* @param level - Log level ("info", "warn", "error", "debug").
|
|
174
|
+
* @param message - The formatted log message.
|
|
175
|
+
* @param color - Color name accepted by node:util.styleText, or null for the default terminal color.
|
|
176
|
+
* @param categoryTag - Optional debug category tag (e.g., "recovery:tab"). Appended to the level prefix as [DEBUG:category].
|
|
177
|
+
*/
|
|
178
|
+
export function writeLogEntry(level, message, color, categoryTag) {
|
|
179
|
+
switch (state.kind) {
|
|
180
|
+
case "window": {
|
|
181
|
+
writeBuffer.push(formatLogEntry(level, message, color, categoryTag));
|
|
182
|
+
/* The window has no open file, so it bounds itself where the open state runs a periodic size check instead. The bound is tested on every push, so the
|
|
183
|
+
* oldest entry makes room as soon as one entry too many arrives.
|
|
184
|
+
*/
|
|
185
|
+
if (writeBuffer.length > STARTUP_BUFFER_LIMIT) {
|
|
186
|
+
writeBuffer.shift();
|
|
187
|
+
}
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
case "open":
|
|
191
|
+
case "closing": {
|
|
192
|
+
if ((state.kind === "open") && (state.pausedSince !== null)) {
|
|
193
|
+
if ((loggerClock.now() - state.pausedSince) < ERROR_RETRY_DELAY_MS) {
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
/* The first write past the retry delay re-opens the file, and the next failure on it sets a fresh pause. Clearing the field here is what keeps it
|
|
197
|
+
* describing the file's standing rather than a moment that has passed, and it has no observable of its own, because every failure on the file the
|
|
198
|
+
* logger holds open refreshes the timestamp.
|
|
199
|
+
*/
|
|
200
|
+
transition({ ...state, pausedSince: null });
|
|
201
|
+
}
|
|
202
|
+
writeBuffer.push(formatLogEntry(level, message, color, categoryTag));
|
|
203
|
+
writeCount++;
|
|
204
|
+
// Check if we should verify actual file size.
|
|
205
|
+
if ((writeCount % SIZE_CHECK_FREQUENCY) === 0) {
|
|
206
|
+
void checkAndTrimFile();
|
|
207
|
+
}
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
case "closed": {
|
|
211
|
+
/* The logger has shut down and this line still belongs to the run that just ended, so it goes to that run's file. The append is synchronous because
|
|
212
|
+
* nothing asynchronous is left to carry it: the flush timer is stopped, the write chain has drained, and the process may exit on the next tick.
|
|
213
|
+
*/
|
|
214
|
+
try {
|
|
215
|
+
fs.appendFileSync(state.path, formatLogEntry(level, message, color, categoryTag), "utf-8");
|
|
216
|
+
}
|
|
217
|
+
catch (error) {
|
|
218
|
+
// eslint-disable-next-line no-console
|
|
219
|
+
console.error("Failed to write a log entry after shutdown: %s.", (error instanceof Error) ? error.message : String(error));
|
|
220
|
+
// A closed file that cannot be written is where the logger goes off, so the path is reported once rather than once per line.
|
|
221
|
+
transition({ kind: "off" });
|
|
222
|
+
}
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
case "off": {
|
|
226
|
+
// Nothing takes the entry: no file is open, no closed file is waiting for it, and the startup window is behind us.
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
default: {
|
|
230
|
+
assertNever(state);
|
|
231
|
+
}
|
|
130
232
|
}
|
|
131
233
|
}
|
|
132
234
|
// Write Ordering.
|
|
@@ -134,7 +236,7 @@ export function writeLogEntry(level, message, color, categoryTag) {
|
|
|
134
236
|
* Serializes an asynchronous log-file mutation against every other such mutation. The supplied operation is appended to the module-scoped write chain so that
|
|
135
237
|
* flushes and trims execute one at a time, never interleaving their read/append/rename steps. The returned promise resolves when this specific operation has
|
|
136
238
|
* settled. The chain itself is advanced with the settled (caught) result so a rejecting operation cannot poison subsequent writes - each operation is responsible
|
|
137
|
-
* for its own error handling
|
|
239
|
+
* for its own error handling.
|
|
138
240
|
* @param operation - The async mutation to run after all previously enqueued mutations have completed.
|
|
139
241
|
*/
|
|
140
242
|
async function serializeWrite(operation) {
|
|
@@ -150,12 +252,13 @@ async function serializeWrite(operation) {
|
|
|
150
252
|
* interleave with an in-flight trim, which would otherwise discard the appended lines when the trim renames its stale snapshot over the file.
|
|
151
253
|
*/
|
|
152
254
|
export async function flushLogBuffer() {
|
|
153
|
-
|
|
255
|
+
// The path is read once here so the serialized operation below writes to the file the logger held when the flush was issued, whatever the state does next.
|
|
256
|
+
const targetPath = openFilePath();
|
|
257
|
+
if ((targetPath === null) || (writeBuffer.length === 0)) {
|
|
154
258
|
return;
|
|
155
259
|
}
|
|
156
|
-
// Take the current buffer and reset.
|
|
260
|
+
// Take the current buffer and reset.
|
|
157
261
|
const entries = writeBuffer;
|
|
158
|
-
const targetPath = logFilePath;
|
|
159
262
|
writeBuffer = [];
|
|
160
263
|
const content = entries.join("");
|
|
161
264
|
return serializeWrite(async () => {
|
|
@@ -163,26 +266,51 @@ export async function flushLogBuffer() {
|
|
|
163
266
|
await fsPromises.appendFile(targetPath, content, "utf-8");
|
|
164
267
|
}
|
|
165
268
|
catch (error) {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
269
|
+
/* Every failure on the file the logger still holds open sets or refreshes the pause, so the delay before the next attempt runs from the latest failure
|
|
270
|
+
* rather than the first. A failure that settles while the logger is closing that file, or has already left it, touches no state: the final flush is the
|
|
271
|
+
* run's one attempt either way, and the drain bound lets a shutdown complete with an append still in flight, so a run that has since opened its own file
|
|
272
|
+
* must not inherit a pause the run before it earned.
|
|
273
|
+
*/
|
|
274
|
+
if ((state.kind === "open") && (state.path === targetPath)) {
|
|
275
|
+
transition({ ...state, pausedSince: loggerClock.now() });
|
|
276
|
+
// Log to console as fallback.
|
|
277
|
+
// eslint-disable-next-line no-console
|
|
278
|
+
console.error("Failed to write to log file: %s. File logging disabled for %s seconds.", (error instanceof Error) ? error.message : String(error), ERROR_RETRY_DELAY_MS / 1000);
|
|
279
|
+
}
|
|
280
|
+
else {
|
|
281
|
+
// Log to console as fallback.
|
|
282
|
+
// eslint-disable-next-line no-console
|
|
283
|
+
console.error("Failed to write to the log file: %s.", (error instanceof Error) ? error.message : String(error));
|
|
284
|
+
}
|
|
172
285
|
}
|
|
173
286
|
});
|
|
174
287
|
}
|
|
175
288
|
/**
|
|
176
|
-
* Flushes the write buffer to disk synchronously.
|
|
289
|
+
* Flushes the write buffer to disk synchronously. Shutdown reaches it while the logger is closing and writes to the configured log file, and the process exit
|
|
290
|
+
* handler reaches it on either side of initialization. The fallback path serves that second position - an exit in the startup window, where the buffer holds
|
|
291
|
+
* the window's entries and no log file was ever opened - and a logger holding a file of its own ignores it in favor of that file.
|
|
292
|
+
* @param fallbackPath - Absolute path to write to when the logger never initialized. Shutdown omits it, and so does console mode, whose lines never enter the buffer.
|
|
177
293
|
*/
|
|
178
|
-
export function flushLogBufferSync() {
|
|
179
|
-
if (
|
|
294
|
+
export function flushLogBufferSync(fallbackPath) {
|
|
295
|
+
if (writeBuffer.length === 0) {
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
// With no file of its own, the fallback path is the only thing that says where these entries should land, and without one there is nowhere to put them.
|
|
299
|
+
const openPath = openFilePath();
|
|
300
|
+
const targetPath = openPath ?? fallbackPath;
|
|
301
|
+
if (!targetPath) {
|
|
180
302
|
return;
|
|
181
303
|
}
|
|
182
304
|
const content = writeBuffer.join("");
|
|
183
305
|
writeBuffer = [];
|
|
184
306
|
try {
|
|
185
|
-
|
|
307
|
+
/* Only the fallback needs its parent directory created, and it shares the catch below so a read-only data directory yields the same console message a
|
|
308
|
+
* failed append does. A logger holding its own file created that directory at initialization, so repeating the syscall here would buy nothing.
|
|
309
|
+
*/
|
|
310
|
+
if (openPath === null) {
|
|
311
|
+
fs.mkdirSync(path.dirname(targetPath), { recursive: true });
|
|
312
|
+
}
|
|
313
|
+
fs.appendFileSync(targetPath, content, "utf-8");
|
|
186
314
|
}
|
|
187
315
|
catch (error) {
|
|
188
316
|
// Log to console as fallback.
|
|
@@ -195,24 +323,21 @@ export function flushLogBufferSync() {
|
|
|
195
323
|
* Checks the actual file size and trims if it exceeds the maximum.
|
|
196
324
|
*/
|
|
197
325
|
async function checkAndTrimFile() {
|
|
198
|
-
|
|
326
|
+
const targetPath = openFilePath();
|
|
327
|
+
if (targetPath === null) {
|
|
199
328
|
return;
|
|
200
329
|
}
|
|
201
330
|
try {
|
|
202
|
-
const stats = await fsPromises.stat(
|
|
203
|
-
approximateSize = stats.size;
|
|
331
|
+
const stats = await fsPromises.stat(targetPath);
|
|
204
332
|
// Skip trimming when debug logging is active. Debug sessions generate high-volume output that is valuable for diagnosis - trimming mid-session would discard
|
|
205
333
|
// the very data we are trying to capture.
|
|
206
|
-
if ((
|
|
334
|
+
if ((stats.size > maxLogSize) && !isAnyDebugEnabled()) {
|
|
207
335
|
await trimLogFile();
|
|
208
336
|
}
|
|
209
337
|
}
|
|
210
338
|
catch (error) {
|
|
211
|
-
//
|
|
212
|
-
|
|
213
|
-
approximateSize = 0;
|
|
214
|
-
}
|
|
215
|
-
// Log to console but continue operating.
|
|
339
|
+
// A file removed externally arrives here as the stat's ENOENT, and the warning is the whole response: the next append recreates the file, so logging
|
|
340
|
+
// continues into an empty one rather than stopping.
|
|
216
341
|
// eslint-disable-next-line no-console
|
|
217
342
|
console.warn("Error checking log file size: %s.", (error instanceof Error) ? error.message : String(error));
|
|
218
343
|
}
|
|
@@ -259,11 +384,12 @@ export function computeTrimmedLogContent(content, maxSize) {
|
|
|
259
384
|
* an appendFile cannot land between this function's readFile and its rename, so the rename never overwrites freshly appended lines with a stale snapshot.
|
|
260
385
|
*/
|
|
261
386
|
async function trimLogFile() {
|
|
262
|
-
|
|
387
|
+
// The path is read once here because a shutdown can move the state under the serialized operation below, and the rename has to land on the file the read
|
|
388
|
+
// came from rather than on wherever the logger has since gone.
|
|
389
|
+
const targetPath = openFilePath();
|
|
390
|
+
if (targetPath === null) {
|
|
263
391
|
return;
|
|
264
392
|
}
|
|
265
|
-
// Snapshot the path so a concurrent shutdown clearing logFilePath cannot redirect the rename target mid-operation.
|
|
266
|
-
const targetPath = logFilePath;
|
|
267
393
|
return serializeWrite(async () => {
|
|
268
394
|
try {
|
|
269
395
|
const content = await fsPromises.readFile(targetPath, "utf-8");
|
|
@@ -275,7 +401,6 @@ async function trimLogFile() {
|
|
|
275
401
|
const tempPath = targetPath + ".tmp";
|
|
276
402
|
await fsPromises.writeFile(tempPath, trimmedContent, "utf-8");
|
|
277
403
|
await fsPromises.rename(tempPath, targetPath);
|
|
278
|
-
approximateSize = trimmedContent.length;
|
|
279
404
|
}
|
|
280
405
|
catch (error) {
|
|
281
406
|
// Log to console but continue operating - trim will be retried on next check.
|
|
@@ -286,28 +411,42 @@ async function trimLogFile() {
|
|
|
286
411
|
}
|
|
287
412
|
// Shutdown.
|
|
288
413
|
/**
|
|
289
|
-
* Shuts down the file logger,
|
|
414
|
+
* Shuts down the file logger: enters the closing state, waits for the write chain to drain, then flushes any remaining buffer synchronously and enters closed.
|
|
415
|
+
*
|
|
416
|
+
* The flush timer stops the moment the logger enters closing, because the chokepoint disposes a timer the next state does not carry, so no periodic flush can
|
|
417
|
+
* fire into the drain.
|
|
418
|
+
*
|
|
419
|
+
* The drain is what keeps shutdown from racing the writes it is meant to finish. A trim holds the log file across a read, a temp write, and a rename; a synchronous
|
|
420
|
+
* final flush issued while that rename is still pending appends to the file the rename is about to replace, so the last entries of the run are discarded along with
|
|
421
|
+
* the stale snapshot. Awaiting the chain first puts the final flush strictly after every mutation already in flight.
|
|
422
|
+
*
|
|
423
|
+
* The wait is bounded because a wedged filesystem operation must not hold the process open through its own shutdown. When the bound lapses the flush and the move
|
|
424
|
+
* to closed proceed anyway, which is the same outcome an unbounded wait would eventually reach minus the hang.
|
|
425
|
+
*
|
|
426
|
+
* The closed state keeps the path of the file it closed, so a line logged after this point - the exit handler's Chrome cleanup, a late process-level handler - is
|
|
427
|
+
* appended to that file synchronously instead of falling into the gap between the shutdown and the process exit.
|
|
290
428
|
*/
|
|
291
|
-
export function shutdownFileLogger() {
|
|
292
|
-
|
|
429
|
+
export async function shutdownFileLogger() {
|
|
430
|
+
// The window, closed, and off states have no file to shut down, and returning here is what leaves a window's buffered entries for the exit handler's fallback.
|
|
431
|
+
if ((state.kind !== "open") && (state.kind !== "closing")) {
|
|
293
432
|
return;
|
|
294
433
|
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
434
|
+
const targetPath = state.path;
|
|
435
|
+
/* Entering closing stops the flush timer through the chokepoint, so no periodic flush fires into the drain, and it lifts any pause the open file carried: the
|
|
436
|
+
* drain buffers every line logged under it and the final flush is the run's one last attempt at them, which a pause - a bound on a cascade of periodic
|
|
437
|
+
* retries - has no reason to prevent.
|
|
438
|
+
*/
|
|
439
|
+
transition({ kind: "closing", path: targetPath });
|
|
440
|
+
// Drain the outstanding write chain so the synchronous flush below lands after every mutation already in flight rather than into a file a pending rename is
|
|
441
|
+
// about to replace. The chain never rejects - serializeWrite swallows each operation's outcome - so this only ever resolves or lapses.
|
|
442
|
+
await boundedWait(writeChain, SHUTDOWN_DRAIN_BOUND_MS, { clock: loggerClock });
|
|
300
443
|
// Flush remaining buffer synchronously.
|
|
301
444
|
flushLogBufferSync();
|
|
302
|
-
// Reset all module state so a subsequent initializeFileLogger() starts from a clean slate. The disabled-on-write-error flag in particular must not survive
|
|
303
|
-
// shutdown - if a prior run hit a write failure and entered the 60-second retry window, that window should not silently drop writes from the next run.
|
|
304
|
-
isInitialized = false;
|
|
305
|
-
isDisabled = false;
|
|
306
|
-
disabledAt = 0;
|
|
307
|
-
writeBuffer = [];
|
|
308
|
-
approximateSize = 0;
|
|
309
445
|
writeCount = 0;
|
|
310
|
-
|
|
446
|
+
writeBuffer = [];
|
|
447
|
+
// The closed state keeps the file this run wrote to, so a line logged from here on still reaches it rather than falling into the gap between the shutdown and
|
|
448
|
+
// the process exit.
|
|
449
|
+
transition({ kind: "closed", path: targetPath });
|
|
311
450
|
// Reset the write-ordering chain so the next run starts from a fresh, already-resolved tail rather than chaining onto the previous run's last operation.
|
|
312
451
|
writeChain = Promise.resolve();
|
|
313
452
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fileLogger.js","sourceRoot":"","sources":["../../src/utils/fileLogger.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"fileLogger.js","sourceRoot":"","sources":["../../src/utils/fileLogger.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/format.d.ts
CHANGED
|
@@ -3,9 +3,10 @@ import type { Nullable } from "../types/index.ts";
|
|
|
3
3
|
* Formats the current date and time as a log timestamp string: `yyyy/mm/dd hh:mm:ss.mmm AM/PM`. Uses 12-hour time with decimalized seconds and AM/PM.
|
|
4
4
|
* Single source of truth for all log timestamp formatting - used by the console wrapper in app.ts, the file logger, the Morgan HTTP request logger, and the SSE log
|
|
5
5
|
* emitter.
|
|
6
|
+
* @param now - The instant to format, as epoch milliseconds; defaults to the system clock's reading.
|
|
6
7
|
* @returns Formatted timestamp string.
|
|
7
8
|
*/
|
|
8
|
-
export declare function formatTimestamp(): string;
|
|
9
|
+
export declare function formatTimestamp(now?: number): string;
|
|
9
10
|
/**
|
|
10
11
|
* Formats a duration as a human-readable string. The format varies based on duration length:
|
|
11
12
|
* - Less than 60 seconds: "17s"
|
|
@@ -22,12 +23,36 @@ export declare function formatDuration(value: number, unit?: "ms" | "s"): string
|
|
|
22
23
|
* Formats a Unix millisecond timestamp as a human-readable relative time string (e.g., "2 minutes ago", "3 hours ago", "5 days ago"). Used for health indicator
|
|
23
24
|
* tooltips where absolute timestamps would be harder to interpret at a glance.
|
|
24
25
|
* @param timestamp - Unix millisecond timestamp.
|
|
26
|
+
* @param now - The instant the distance is measured from, as epoch milliseconds; defaults to the system clock's reading.
|
|
25
27
|
* @returns Relative time string.
|
|
26
28
|
*/
|
|
27
|
-
export declare function formatTimeAgo(timestamp: number): string;
|
|
29
|
+
export declare function formatTimeAgo(timestamp: number, now?: number): string;
|
|
30
|
+
/**
|
|
31
|
+
* Display labels for the standard vertical resolutions, keyed by the height in pixels. This is the single source of truth for the label a resolution is shown
|
|
32
|
+
* under: the native HLS quality suffix in the log, the stream detail's codec line in the web UI, and anything else that renders a resolution to a person all
|
|
33
|
+
* read it from here. A height with no entry has no standard label, and its caller falls back to the raw resolution string.
|
|
34
|
+
*/
|
|
35
|
+
export declare const RESOLUTION_LABELS: Record<string, string>;
|
|
36
|
+
/**
|
|
37
|
+
* Formats a pixel size as the "WIDTHxHEIGHT" string the codebase carries resolutions in. This is the one producer of that form, and it matches the shape the
|
|
38
|
+
* native probe reads verbatim out of a manifest's RESOLUTION attribute, so a resolution that came off the wire and one this function built are the same string
|
|
39
|
+
* to every consumer downstream - the label lookup below included.
|
|
40
|
+
* @param width - The width in pixels.
|
|
41
|
+
* @param height - The height in pixels.
|
|
42
|
+
* @returns The size as "WIDTHxHEIGHT".
|
|
43
|
+
*/
|
|
44
|
+
export declare function formatResolution(width: number, height: number): string;
|
|
45
|
+
/**
|
|
46
|
+
* Formats a "WIDTHxHEIGHT" resolution string as its standard display label, falling back to the resolution string itself when the height carries no standard
|
|
47
|
+
* label. The fallback is what keeps a non-standard rendition visible rather than dropped: a 1234x999 variant renders as "1234x999" instead of disappearing.
|
|
48
|
+
* @param resolution - The resolution as "WIDTHxHEIGHT".
|
|
49
|
+
* @returns The display label, or the resolution string when the height has no label.
|
|
50
|
+
*/
|
|
51
|
+
export declare function formatResolutionLabel(resolution: string): string;
|
|
28
52
|
/**
|
|
29
53
|
* Extracts a concise domain from a URL by keeping only the last two portions of the hostname (e.g., "watch.foodnetwork.com" becomes "foodnetwork.com",
|
|
30
|
-
* "www.hulu.com" becomes "hulu.com").
|
|
54
|
+
* "www.hulu.com" becomes "hulu.com"). An IP-literal host is returned whole, because an address has no registrable domain to shorten. Used as a standard domain key
|
|
55
|
+
* for DOMAIN_CONFIG lookups and as a display fallback when no service name is configured.
|
|
31
56
|
* @param url - The URL to extract the domain from.
|
|
32
57
|
* @returns The concise domain, or the original URL if parsing fails.
|
|
33
58
|
*/
|
|
@@ -42,6 +67,14 @@ export declare function extractDomain(url: string): string;
|
|
|
42
67
|
* @returns The pathname, or null when parsing fails.
|
|
43
68
|
*/
|
|
44
69
|
export declare function extractPathname(url: string): Nullable<string>;
|
|
70
|
+
/**
|
|
71
|
+
* Resolves a potentially relative URL against a base URL. Handles both absolute and relative URLs.
|
|
72
|
+
*
|
|
73
|
+
* @param url - The URL to resolve (may be relative or absolute).
|
|
74
|
+
* @param baseUrl - The base URL for resolving relative references.
|
|
75
|
+
* @returns The resolved absolute URL.
|
|
76
|
+
*/
|
|
77
|
+
export declare function resolveUrl(url: string, baseUrl: string): string;
|
|
45
78
|
/**
|
|
46
79
|
* Capitalizes the first letter of a string.
|
|
47
80
|
* @param str - The string to capitalize.
|
|
@@ -56,4 +89,3 @@ export declare function capitalize(str: string): string;
|
|
|
56
89
|
* @returns The JSON string.
|
|
57
90
|
*/
|
|
58
91
|
export declare function stringifySorted(data: unknown, indent?: number): string;
|
|
59
|
-
//# sourceMappingURL=format.d.ts.map
|