prismcast 1.6.0 → 1.7.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/browser/cdp.js +1 -1
- package/dist/browser/cdp.js.map +1 -1
- package/dist/browser/channelSelection.d.ts +10 -34
- package/dist/browser/channelSelection.js +19 -96
- package/dist/browser/channelSelection.js.map +1 -1
- package/dist/browser/display.d.ts +19 -0
- package/dist/browser/display.js +16 -11
- package/dist/browser/display.js.map +1 -1
- package/dist/browser/index.d.ts +9 -46
- package/dist/browser/index.js +136 -191
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/login.d.ts +65 -0
- package/dist/browser/login.js +193 -0
- package/dist/browser/login.js.map +1 -0
- package/dist/browser/precaching.js +12 -0
- package/dist/browser/precaching.js.map +1 -1
- package/dist/browser/tuning/comcastPolymer.d.ts +23 -0
- package/dist/browser/tuning/comcastPolymer.js +655 -0
- package/dist/browser/tuning/comcastPolymer.js.map +1 -0
- package/dist/browser/tuning/cox.d.ts +2 -0
- package/dist/browser/tuning/cox.js +14 -0
- package/dist/browser/tuning/cox.js.map +1 -0
- package/dist/browser/tuning/directv.js +1 -1
- package/dist/browser/tuning/directv.js.map +1 -1
- package/dist/browser/tuning/fox.js +2 -2
- package/dist/browser/tuning/fox.js.map +1 -1
- package/dist/browser/tuning/hbo.js +1 -1
- package/dist/browser/tuning/hbo.js.map +1 -1
- package/dist/browser/tuning/hulu.js +1 -1
- package/dist/browser/tuning/hulu.js.map +1 -1
- package/dist/browser/tuning/shared.d.ts +46 -0
- package/dist/browser/tuning/shared.js +100 -0
- package/dist/browser/tuning/shared.js.map +1 -0
- package/dist/browser/tuning/sling.js +1 -1
- package/dist/browser/tuning/sling.js.map +1 -1
- package/dist/browser/tuning/spectrum.js +1 -1
- package/dist/browser/tuning/spectrum.js.map +1 -1
- package/dist/browser/tuning/thumbnailRow.js +1 -1
- package/dist/browser/tuning/thumbnailRow.js.map +1 -1
- package/dist/browser/tuning/tileClick.js +1 -1
- package/dist/browser/tuning/tileClick.js.map +1 -1
- package/dist/browser/tuning/xfinity.js +10 -603
- package/dist/browser/tuning/xfinity.js.map +1 -1
- package/dist/browser/tuning/youtubeTv.js +1 -1
- package/dist/browser/tuning/youtubeTv.js.map +1 -1
- package/dist/browser/video.d.ts +18 -0
- package/dist/browser/video.js +69 -107
- package/dist/browser/video.js.map +1 -1
- package/dist/channels/index.d.ts +2 -2
- package/dist/channels/index.js +2075 -800
- package/dist/channels/index.js.map +1 -1
- package/dist/config/health.js +20 -2
- package/dist/config/health.js.map +1 -1
- package/dist/config/index.js +29 -64
- package/dist/config/index.js.map +1 -1
- package/dist/config/providerPacks.js +4 -1
- package/dist/config/providerPacks.js.map +1 -1
- package/dist/config/providers.d.ts +12 -5
- package/dist/config/providers.js +110 -94
- package/dist/config/providers.js.map +1 -1
- package/dist/config/sites.js +15 -9
- package/dist/config/sites.js.map +1 -1
- package/dist/config/userChannels.d.ts +50 -2
- package/dist/config/userChannels.js +212 -10
- package/dist/config/userChannels.js.map +1 -1
- package/dist/config/userConfig.d.ts +1 -1
- package/dist/config/userConfig.js +2 -15
- package/dist/config/userConfig.js.map +1 -1
- package/dist/hdhr/channelMap.d.ts +1 -1
- package/dist/hdhr/channelMap.js +4 -4
- package/dist/hdhr/channelMap.js.map +1 -1
- package/dist/index.js +9 -15
- package/dist/index.js.map +1 -1
- package/dist/native/index.d.ts +3 -0
- package/dist/native/index.js +2 -1
- package/dist/native/index.js.map +1 -1
- package/dist/native/probe.d.ts +4 -3
- package/dist/native/probe.js +36 -12
- package/dist/native/probe.js.map +1 -1
- package/dist/native/proxy.d.ts +2 -0
- package/dist/native/proxy.js +369 -326
- package/dist/native/proxy.js.map +1 -1
- package/dist/routes/components.d.ts +43 -0
- package/dist/routes/components.js +122 -0
- package/dist/routes/components.js.map +1 -1
- package/dist/routes/config/channels/index.d.ts +2 -2
- package/dist/routes/config/channels/index.js +1 -1
- package/dist/routes/config/channels/index.js.map +1 -1
- package/dist/routes/config/channels/routes.js +443 -65
- package/dist/routes/config/channels/routes.js.map +1 -1
- package/dist/routes/config/channels/table.d.ts +76 -0
- package/dist/routes/config/channels/table.js +352 -66
- package/dist/routes/config/channels/table.js.map +1 -1
- package/dist/routes/config/index.d.ts +1 -1
- package/dist/routes/config/index.js +1 -1
- package/dist/routes/config/index.js.map +1 -1
- package/dist/routes/config/providers.d.ts +6 -6
- package/dist/routes/config/providers.js +69 -95
- package/dist/routes/config/providers.js.map +1 -1
- package/dist/routes/index.d.ts +0 -16
- package/dist/routes/index.js +0 -17
- package/dist/routes/index.js.map +1 -1
- package/dist/routes/providers.js +106 -3
- package/dist/routes/providers.js.map +1 -1
- package/dist/routes/root/content.js +55 -38
- package/dist/routes/root/content.js.map +1 -1
- package/dist/routes/root/index.js +2 -1
- package/dist/routes/root/index.js.map +1 -1
- package/dist/routes/root/scripts/channels.js +772 -312
- package/dist/routes/root/scripts/channels.js.map +1 -1
- package/dist/routes/root/scripts/config.js +596 -544
- 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.js +1 -0
- package/dist/routes/root/scripts/index.js.map +1 -1
- package/dist/routes/root/scripts/shared.d.ts +6 -0
- package/dist/routes/root/scripts/shared.js +391 -0
- package/dist/routes/root/scripts/shared.js.map +1 -0
- package/dist/routes/root/scripts/status.js +36 -21
- package/dist/routes/root/scripts/status.js.map +1 -1
- package/dist/routes/root/styles.js +113 -8
- package/dist/routes/root/styles.js.map +1 -1
- package/dist/service/commands.js +2 -1
- package/dist/service/commands.js.map +1 -1
- package/dist/streaming/fmp4Segmenter.d.ts +2 -0
- package/dist/streaming/fmp4Segmenter.js +7 -4
- package/dist/streaming/fmp4Segmenter.js.map +1 -1
- package/dist/streaming/hls.js +269 -188
- package/dist/streaming/hls.js.map +1 -1
- package/dist/streaming/hlsResume.d.ts +9 -3
- package/dist/streaming/hlsResume.js +13 -6
- package/dist/streaming/hlsResume.js.map +1 -1
- package/dist/streaming/hlsSegments.d.ts +1 -2
- package/dist/streaming/hlsSegments.js +48 -46
- package/dist/streaming/hlsSegments.js.map +1 -1
- package/dist/streaming/lifecycle.js +8 -12
- package/dist/streaming/lifecycle.js.map +1 -1
- package/dist/streaming/monitor.js +625 -585
- package/dist/streaming/monitor.js.map +1 -1
- package/dist/streaming/mpegts.js +1 -1
- package/dist/streaming/mpegts.js.map +1 -1
- package/dist/streaming/preroll.d.ts +40 -20
- package/dist/streaming/preroll.js +147 -86
- package/dist/streaming/preroll.js.map +1 -1
- package/dist/streaming/recovery.d.ts +0 -6
- package/dist/streaming/recovery.js +0 -8
- package/dist/streaming/recovery.js.map +1 -1
- package/dist/streaming/registry.d.ts +36 -9
- package/dist/streaming/registry.js +6 -9
- package/dist/streaming/registry.js.map +1 -1
- package/dist/streaming/setup.d.ts +1 -1
- package/dist/streaming/setup.js +44 -21
- package/dist/streaming/setup.js.map +1 -1
- package/dist/streaming/showInfo.d.ts +7 -6
- package/dist/streaming/showInfo.js +156 -36
- package/dist/streaming/showInfo.js.map +1 -1
- package/dist/streaming/statusEmitter.d.ts +14 -2
- package/dist/streaming/statusEmitter.js +22 -4
- package/dist/streaming/statusEmitter.js.map +1 -1
- package/dist/types/channels.d.ts +31 -0
- package/dist/types/config.d.ts +2 -2
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/profiles.d.ts +8 -3
- package/dist/types/selection.d.ts +1 -0
- package/dist/types/shared.d.ts +1 -1
- package/dist/utils/debugFilter.d.ts +0 -5
- package/dist/utils/debugFilter.js +5 -11
- package/dist/utils/debugFilter.js.map +1 -1
- package/dist/utils/delay.d.ts +12 -0
- package/dist/utils/delay.js +20 -0
- package/dist/utils/delay.js.map +1 -1
- package/dist/utils/evaluate.js +6 -11
- package/dist/utils/evaluate.js.map +1 -1
- package/dist/utils/ffmpeg.d.ts +13 -5
- package/dist/utils/ffmpeg.js +32 -11
- package/dist/utils/ffmpeg.js.map +1 -1
- package/dist/utils/format.d.ts +6 -0
- package/dist/utils/format.js +8 -0
- package/dist/utils/format.js.map +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/logEmitter.js +1 -1
- package/dist/utils/logEmitter.js.map +1 -1
- package/dist/utils/retry.d.ts +15 -9
- package/dist/utils/retry.js +7 -23
- package/dist/utils/retry.js.map +1 -1
- package/dist/utils/timing.d.ts +5 -0
- package/dist/utils/timing.js +13 -0
- package/dist/utils/timing.js.map +1 -0
- package/dist/utils/version.js +2 -2
- package/dist/utils/version.js.map +1 -1
- package/package.json +5 -5
package/dist/types/profiles.d.ts
CHANGED
|
@@ -15,15 +15,19 @@ import type { Nullable } from "./shared.js";
|
|
|
15
15
|
* cell. Used by Sling TV.
|
|
16
16
|
* - "spectrumGrid": Find channel by callsign or display name in a non-virtualized AngularJS guide grid, extract the Gracenote tmsid from channel logo URLs,
|
|
17
17
|
* and navigate directly to the watch URL. Caches all ~442 streamable channels on first tune. Used by Spectrum TV.
|
|
18
|
+
* - "coxDirect": Wait for the Comcast Polymer SPA's channelMap to populate, find the target channel by callSign, and call `_watchChannelEventHandler` to switch
|
|
19
|
+
* channels in-page. A fire-and-forget poll dismisses the Watch Now modal if it appears. Used by Cox Contour TV. Shares implementation with xfinityDirect via
|
|
20
|
+
* the comcastPolymer factory.
|
|
18
21
|
* - "thumbnailRow": Find channel element using the profile's matchSelector (defaults to image URL matching), click adjacent element on the same row. Used by
|
|
19
22
|
* USA Network.
|
|
20
23
|
* - "tileClick": Find channel element using the profile's matchSelector (defaults to image URL matching), click tile, then optionally click play button if
|
|
21
24
|
* playSelector is configured. Used by Disney+.
|
|
22
|
-
* - "xfinityDirect": Wait for the Polymer SPA's channelMap to populate, find the target channel by callSign, and call `_watchChannelEventHandler` to switch
|
|
23
|
-
* channels in-page. A fire-and-forget poll dismisses the Watch Now modal if it appears. Used by Xfinity Stream.
|
|
25
|
+
* - "xfinityDirect": Wait for the Comcast Polymer SPA's channelMap to populate, find the target channel by callSign, and call `_watchChannelEventHandler` to switch
|
|
26
|
+
* channels in-page. A fire-and-forget poll dismisses the Watch Now modal if it appears. Used by Xfinity Stream. Shares implementation with coxDirect via the
|
|
27
|
+
* comcastPolymer factory.
|
|
24
28
|
* - "youtubeGrid": Find channel by aria-label in a non-virtualized EPG grid, extract the watch URL, and navigate directly. Used by YouTube TV.
|
|
25
29
|
*/
|
|
26
|
-
export type ChannelSelectionStrategy = "directvGrid" | "foxGrid" | "guideGrid" | "hboGrid" | "none" | "slingGrid" | "spectrumGrid" | "thumbnailRow" | "tileClick" | "xfinityDirect" | "youtubeGrid";
|
|
30
|
+
export type ChannelSelectionStrategy = "coxDirect" | "directvGrid" | "foxGrid" | "guideGrid" | "hboGrid" | "none" | "slingGrid" | "spectrumGrid" | "thumbnailRow" | "tileClick" | "xfinityDirect" | "youtubeGrid";
|
|
27
31
|
/**
|
|
28
32
|
* Configuration for channel selection behavior within a site profile.
|
|
29
33
|
*/
|
|
@@ -105,6 +109,7 @@ export interface ProfileResolutionResult {
|
|
|
105
109
|
*/
|
|
106
110
|
export interface DomainConfig {
|
|
107
111
|
dismissSelector?: string;
|
|
112
|
+
iconUrl?: string;
|
|
108
113
|
loginUrl?: string;
|
|
109
114
|
maxContinuousPlayback?: number;
|
|
110
115
|
profile?: string;
|
package/dist/types/shared.d.ts
CHANGED
|
@@ -3,5 +3,5 @@
|
|
|
3
3
|
* @typeParam T - The type that can be nullable.
|
|
4
4
|
*/
|
|
5
5
|
export type Nullable<T> = T | null;
|
|
6
|
-
export type ChannelSortField = "channelNumber" | "channelSelector" | "key" | "name" | "profile" | "provider" | "stationId";
|
|
6
|
+
export type ChannelSortField = "channelNumber" | "channelSelector" | "hdhrEnabled" | "key" | "name" | "profile" | "provider" | "stationId";
|
|
7
7
|
export type SortDirection = "asc" | "desc";
|
|
@@ -31,8 +31,3 @@ export interface DebugCategory {
|
|
|
31
31
|
* Parent groups (e.g., "streaming", "timing", "tuning") are derived by the UI from the colon-separated namespaces — only leaf categories are declared here.
|
|
32
32
|
*/
|
|
33
33
|
export declare const DEBUG_CATEGORIES: readonly DebugCategory[];
|
|
34
|
-
/**
|
|
35
|
-
* Creates a lightweight elapsed-time closure using performance.now(). Call the returned function to get the elapsed milliseconds since creation.
|
|
36
|
-
* @returns A closure that returns elapsed milliseconds as a number.
|
|
37
|
-
*/
|
|
38
|
-
export declare function startTimer(): () => number;
|
|
@@ -120,9 +120,9 @@ export function getCurrentPattern() {
|
|
|
120
120
|
* Parent groups (e.g., "streaming", "timing", "tuning") are derived by the UI from the colon-separated namespaces — only leaf categories are declared here.
|
|
121
121
|
*/
|
|
122
122
|
export const DEBUG_CATEGORIES = [
|
|
123
|
-
{ category: "browser", description: "Browser lifecycle: launch, close, stale page cleanup, restart." },
|
|
123
|
+
{ category: "browser:lifecycle", description: "Browser lifecycle: launch, close, stale page cleanup, restart." },
|
|
124
124
|
{ category: "browser:video", description: "Video context, fullscreen, volume locking, playback." },
|
|
125
|
-
{ category: "config", description: "Provider groups, version checking." },
|
|
125
|
+
{ category: "config:general", description: "Provider groups, version checking." },
|
|
126
126
|
{ category: "native:coordinator", description: "Native streaming decisions: interception result, probe result, capture teardown, proxy start." },
|
|
127
127
|
{ category: "native:decrypt", description: "AES-128 decryption: key fetch, IV source (explicit vs. sequence), segment sizes." },
|
|
128
128
|
{ category: "native:intercept", description: "CDP manifest interception: listener installed, .m3u8 URLs observed, master identified, timeout." },
|
|
@@ -132,7 +132,7 @@ export const DEBUG_CATEGORIES = [
|
|
|
132
132
|
{ category: "native:proxy", description: "Manifest polling, segment fetch/store, playlist generation, segment rotation, key rotation." },
|
|
133
133
|
{ category: "native:token", description: "Token refresh: expiry parsed, timer scheduled, refresh triggered, manifest acquired." },
|
|
134
134
|
{ category: "precache", description: "Channel lineup precaching: deferred runs, provider filter skips." },
|
|
135
|
-
{ category: "recovery", description: "General recovery: browser re-minimize, monitor abort." },
|
|
135
|
+
{ category: "recovery:general", description: "General recovery: browser re-minimize, monitor abort." },
|
|
136
136
|
{ category: "recovery:context", description: "Video context: frame detachment, re-search." },
|
|
137
137
|
{ category: "recovery:nav", description: "Page navigation recovery: new tab detection, URL validation." },
|
|
138
138
|
{ category: "recovery:resolution", description: "Video resolution monitoring: ABR degradation detection, grace periods, recovery escalation." },
|
|
@@ -142,6 +142,7 @@ export const DEBUG_CATEGORIES = [
|
|
|
142
142
|
{ category: "retry", description: "Retry attempts, page-closed aborts." },
|
|
143
143
|
{ category: "streaming:ffmpeg", description: "FFmpeg stderr output, pipe errors." },
|
|
144
144
|
{ category: "streaming:hls", description: "HLS segment storage, page close errors." },
|
|
145
|
+
{ category: "streaming:logos", description: "Channel logo cache: DVR device extraction, TMS station lookups, cache population." },
|
|
145
146
|
{ category: "streaming:mpegts", description: "MPEG-TS client connections, FFmpeg remuxer spawn and errors." },
|
|
146
147
|
{ category: "streaming:preroll", description: "Preroll lifecycle: fMP4 generation, preroll playlist delivery, transition to live content." },
|
|
147
148
|
{ category: "streaming:pretune", description: "Predictive channel pretuning: DVR job polling, timer scheduling, tune triggers." },
|
|
@@ -155,6 +156,7 @@ export const DEBUG_CATEGORIES = [
|
|
|
155
156
|
{ category: "timing:startup", description: "Stream startup: init segment, first playlist, capture ready." },
|
|
156
157
|
{ category: "timing:tab", description: "Tab replacement: old tab cleanup, new page creation." },
|
|
157
158
|
{ category: "timing:tune", description: "Tune waterfall: navigation, channel selection, video ready." },
|
|
159
|
+
{ category: "tuning:cox", description: "Cox Contour TV: channelmap API interception, SPA channel switching, Watch Now modal dismissal." },
|
|
158
160
|
{ category: "tuning:directv", description: "DirecTV Stream: interceptor tuning, cache, logo click fallback." },
|
|
159
161
|
{ category: "tuning:hbo", description: "HBO Max: tab URL discovery, channel rail, navigation." },
|
|
160
162
|
{ category: "tuning:hulu", description: "Hulu Live guide grid: binary search, cache, click retries." },
|
|
@@ -164,12 +166,4 @@ export const DEBUG_CATEGORIES = [
|
|
|
164
166
|
{ category: "tuning:xfinity", description: "Xfinity Stream: channelmap API interception, SPA channel switching, Watch Now modal dismissal." },
|
|
165
167
|
{ category: "tuning:yttv", description: "YouTube TV EPG grid navigation." }
|
|
166
168
|
];
|
|
167
|
-
/**
|
|
168
|
-
* Creates a lightweight elapsed-time closure using performance.now(). Call the returned function to get the elapsed milliseconds since creation.
|
|
169
|
-
* @returns A closure that returns elapsed milliseconds as a number.
|
|
170
|
-
*/
|
|
171
|
-
export function startTimer() {
|
|
172
|
-
const start = performance.now();
|
|
173
|
-
return () => Math.round(performance.now() - start);
|
|
174
|
-
}
|
|
175
169
|
//# sourceMappingURL=debugFilter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"debugFilter.js","sourceRoot":"","sources":["../../src/utils/debugFilter.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"debugFilter.js","sourceRoot":"","sources":["../../src/utils/debugFilter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;;GAYG;AAEH,gHAAgH;AAChH,IAAI,UAAU,GAAG,KAAK,CAAC;AAEvB,uFAAuF;AACvF,IAAI,eAAe,GAAG,KAAK,CAAC;AAE5B,iDAAiD;AACjD,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;AAErC,4FAA4F;AAC5F,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;AAErC;;;;;;GAMG;AACH,SAAS,UAAU,CAAC,QAAgB,EAAE,QAAqB;IAEzD,IAAG,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QAE1B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAI,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAE9B,IAAG,QAAQ,CAAC,UAAU,CAAC,OAAO,GAAG,GAAG,CAAC,EAAE,CAAC;YAEtC,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,OAAe;IAE7C,eAAe;IACf,UAAU,CAAC,KAAK,EAAE,CAAC;IACnB,UAAU,CAAC,KAAK,EAAE,CAAC;IACnB,eAAe,GAAG,KAAK,CAAC;IACxB,UAAU,GAAG,KAAK,CAAC;IAEnB,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAElF,IAAG,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAEtB,OAAO;IACT,CAAC;IAED,KAAI,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAExB,IAAG,IAAI,KAAK,GAAG,EAAE,CAAC;YAEhB,eAAe,GAAG,IAAI,CAAC;QACzB,CAAC;aAAM,IAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAE/B,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;QACpC,CAAC;aAAM,CAAC;YAEN,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAED,UAAU,GAAG,IAAI,CAAC;AACpB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAgB;IAEhD,IAAG,CAAC,UAAU,EAAE,CAAC;QAEf,OAAO,KAAK,CAAC;IACf,CAAC;IAED,2CAA2C;IAC3C,IAAG,UAAU,CAAC,QAAQ,EAAE,UAAU,CAAC,EAAE,CAAC;QAEpC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAG,eAAe,EAAE,CAAC;QAEnB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,UAAU,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;AAC1C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB;IAE/B,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB;IAE/B,IAAG,CAAC,UAAU,EAAE,CAAC;QAEf,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,IAAG,eAAe,EAAE,CAAC;QAEnB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAClB,CAAC;IAED,yCAAyC;IACzC,KAAI,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;QAE9B,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC;IAC1B,CAAC;IAED,2CAA2C;IAC3C,KAAI,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;QAE9B,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC;AAaD;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAA6B;IAExD,EAAE,QAAQ,EAAE,mBAAmB,EAAE,WAAW,EAAE,gEAAgE,EAAE;IAChH,EAAE,QAAQ,EAAE,eAAe,EAAE,WAAW,EAAE,sDAAsD,EAAE;IAClG,EAAE,QAAQ,EAAE,gBAAgB,EAAE,WAAW,EAAE,oCAAoC,EAAE;IACjF,EAAE,QAAQ,EAAE,oBAAoB,EAAE,WAAW,EAAE,+FAA+F,EAAE;IAChJ,EAAE,QAAQ,EAAE,gBAAgB,EAAE,WAAW,EAAE,kFAAkF,EAAE;IAC/H,EAAE,QAAQ,EAAE,kBAAkB,EAAE,WAAW,EAAE,iGAAiG,EAAE;IAChJ,EAAE,QAAQ,EAAE,iBAAiB,EAAE,WAAW,EAAE,gGAAgG,EAAE;IAC9I,EAAE,QAAQ,EAAE,gBAAgB,EAAE,WAAW,EAAE,2FAA2F,EAAE;IACxI,EAAE,QAAQ,EAAE,cAAc,EAAE,WAAW,EAAE,qGAAqG,EAAE;IAChJ,EAAE,QAAQ,EAAE,cAAc,EAAE,WAAW,EAAE,6FAA6F,EAAE;IACxI,EAAE,QAAQ,EAAE,cAAc,EAAE,WAAW,EAAE,sFAAsF,EAAE;IACjI,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,kEAAkE,EAAE;IACzG,EAAE,QAAQ,EAAE,kBAAkB,EAAE,WAAW,EAAE,uDAAuD,EAAE;IACtG,EAAE,QAAQ,EAAE,kBAAkB,EAAE,WAAW,EAAE,6CAA6C,EAAE;IAC5F,EAAE,QAAQ,EAAE,cAAc,EAAE,WAAW,EAAE,8DAA8D,EAAE;IACzG,EAAE,QAAQ,EAAE,qBAAqB,EAAE,WAAW,EAAE,6FAA6F,EAAE;IAC/I,EAAE,QAAQ,EAAE,mBAAmB,EAAE,WAAW,EAAE,0CAA0C,EAAE;IAC1F,EAAE,QAAQ,EAAE,cAAc,EAAE,WAAW,EAAE,8DAA8D,EAAE;IACzG,EAAE,QAAQ,EAAE,iBAAiB,EAAE,WAAW,EAAE,qEAAqE,EAAE;IACnH,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,qCAAqC,EAAE;IACzE,EAAE,QAAQ,EAAE,kBAAkB,EAAE,WAAW,EAAE,oCAAoC,EAAE;IACnF,EAAE,QAAQ,EAAE,eAAe,EAAE,WAAW,EAAE,yCAAyC,EAAE;IACrF,EAAE,QAAQ,EAAE,iBAAiB,EAAE,WAAW,EAAE,mFAAmF,EAAE;IACjI,EAAE,QAAQ,EAAE,kBAAkB,EAAE,WAAW,EAAE,8DAA8D,EAAE;IAC7G,EAAE,QAAQ,EAAE,mBAAmB,EAAE,WAAW,EAAE,4FAA4F,EAAE;IAC5I,EAAE,QAAQ,EAAE,mBAAmB,EAAE,WAAW,EAAE,iFAAiF,EAAE;IACjI,EAAE,QAAQ,EAAE,qBAAqB,EAAE,WAAW,EAAE,4DAA4D,EAAE;IAC9G,EAAE,QAAQ,EAAE,iBAAiB,EAAE,WAAW,EAAE,oEAAoE,EAAE;IAClH,EAAE,QAAQ,EAAE,oBAAoB,EAAE,WAAW,EAAE,iDAAiD,EAAE;IAClG,EAAE,QAAQ,EAAE,gBAAgB,EAAE,WAAW,EAAE,mEAAmE,EAAE;IAChH,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,6BAA6B,EAAE;IACtE,EAAE,QAAQ,EAAE,eAAe,EAAE,WAAW,EAAE,yFAAyF,EAAE;IACrI,EAAE,QAAQ,EAAE,iBAAiB,EAAE,WAAW,EAAE,wDAAwD,EAAE;IACtG,EAAE,QAAQ,EAAE,gBAAgB,EAAE,WAAW,EAAE,8DAA8D,EAAE;IAC3G,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,sDAAsD,EAAE;IAC/F,EAAE,QAAQ,EAAE,aAAa,EAAE,WAAW,EAAE,6DAA6D,EAAE;IACvG,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,gGAAgG,EAAE;IACzI,EAAE,QAAQ,EAAE,gBAAgB,EAAE,WAAW,EAAE,iEAAiE,EAAE;IAC9G,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,uDAAuD,EAAE;IAChG,EAAE,QAAQ,EAAE,aAAa,EAAE,WAAW,EAAE,4DAA4D,EAAE;IACtG,EAAE,QAAQ,EAAE,cAAc,EAAE,WAAW,EAAE,2DAA2D,EAAE;IACtG,EAAE,QAAQ,EAAE,iBAAiB,EAAE,WAAW,EAAE,0EAA0E,EAAE;IACxH,EAAE,QAAQ,EAAE,kBAAkB,EAAE,WAAW,EAAE,4FAA4F,EAAE;IAC3I,EAAE,QAAQ,EAAE,gBAAgB,EAAE,WAAW,EAAE,gGAAgG,EAAE;IAC7I,EAAE,QAAQ,EAAE,aAAa,EAAE,WAAW,EAAE,iCAAiC,EAAE;CAC5E,CAAC"}
|
package/dist/utils/delay.d.ts
CHANGED
|
@@ -14,6 +14,18 @@ export interface CancellableTimeout {
|
|
|
14
14
|
* @returns An object with the timeout promise and a cancel function.
|
|
15
15
|
*/
|
|
16
16
|
export declare function cancellableTimeout(ms: number): CancellableTimeout;
|
|
17
|
+
/**
|
|
18
|
+
* Races a promise against a timeout. If the promise resolves before the timeout, its value is returned. If the timeout fires first, the provided error is thrown
|
|
19
|
+
* (or a default Error if none is provided). The timer is always cleaned up via .finally() to prevent orphaned event loop references.
|
|
20
|
+
*
|
|
21
|
+
* This is the single implementation of the timeout-race-with-cleanup pattern. All code paths that need "promise with timeout" should use this rather than manually
|
|
22
|
+
* constructing timer/promise/race/cleanup sequences.
|
|
23
|
+
* @param promise - The promise to race against the timeout.
|
|
24
|
+
* @param timeoutMs - The timeout duration in milliseconds.
|
|
25
|
+
* @param timeoutError - Optional error to throw on timeout. Defaults to a generic Error with the timeout duration.
|
|
26
|
+
* @returns The resolved value of the promise.
|
|
27
|
+
*/
|
|
28
|
+
export declare function raceWithTimeout<T>(promise: Promise<T>, timeoutMs: number, timeoutError?: Error): Promise<T>;
|
|
17
29
|
/**
|
|
18
30
|
* Creates a promise that resolves after the specified delay. This is a convenience wrapper around setTimeout that allows using async/await syntax for delays.
|
|
19
31
|
* @param ms - The delay duration in milliseconds.
|
package/dist/utils/delay.js
CHANGED
|
@@ -16,6 +16,26 @@ export function cancellableTimeout(ms) {
|
|
|
16
16
|
});
|
|
17
17
|
return { cancel: () => { clearTimeout(timer); }, promise };
|
|
18
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* Races a promise against a timeout. If the promise resolves before the timeout, its value is returned. If the timeout fires first, the provided error is thrown
|
|
21
|
+
* (or a default Error if none is provided). The timer is always cleaned up via .finally() to prevent orphaned event loop references.
|
|
22
|
+
*
|
|
23
|
+
* This is the single implementation of the timeout-race-with-cleanup pattern. All code paths that need "promise with timeout" should use this rather than manually
|
|
24
|
+
* constructing timer/promise/race/cleanup sequences.
|
|
25
|
+
* @param promise - The promise to race against the timeout.
|
|
26
|
+
* @param timeoutMs - The timeout duration in milliseconds.
|
|
27
|
+
* @param timeoutError - Optional error to throw on timeout. Defaults to a generic Error with the timeout duration.
|
|
28
|
+
* @returns The resolved value of the promise.
|
|
29
|
+
*/
|
|
30
|
+
export async function raceWithTimeout(promise, timeoutMs, timeoutError) {
|
|
31
|
+
let timer;
|
|
32
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
33
|
+
timer = setTimeout(() => {
|
|
34
|
+
reject(timeoutError ?? new Error("Operation timed out after " + String(timeoutMs) + "ms."));
|
|
35
|
+
}, timeoutMs);
|
|
36
|
+
});
|
|
37
|
+
return Promise.race([promise, timeoutPromise]).finally(() => { clearTimeout(timer); });
|
|
38
|
+
}
|
|
19
39
|
/**
|
|
20
40
|
* Creates a promise that resolves after the specified delay. This is a convenience wrapper around setTimeout that allows using async/await syntax for delays.
|
|
21
41
|
* @param ms - The delay duration in milliseconds.
|
package/dist/utils/delay.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delay.js","sourceRoot":"","sources":["../../src/utils/delay.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAYH;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,EAAU;IAE3C,IAAI,KAAoC,CAAC;IAEzC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAQ,CAAC,OAAO,EAAE,EAAE;QAE7C,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,OAAO,EAAE,MAAM,EAAE,GAAS,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;AACnE,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,EAAU;IAEpC,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;QAEnC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
1
|
+
{"version":3,"file":"delay.js","sourceRoot":"","sources":["../../src/utils/delay.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAYH;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,EAAU;IAE3C,IAAI,KAAoC,CAAC;IAEzC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAQ,CAAC,OAAO,EAAE,EAAE;QAE7C,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,OAAO,EAAE,MAAM,EAAE,GAAS,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;AACnE,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAI,OAAmB,EAAE,SAAiB,EAAE,YAAoB;IAEnG,IAAI,KAAoC,CAAC;IAEzC,MAAM,cAAc,GAAG,IAAI,OAAO,CAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE;QAEtD,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAEtB,MAAM,CAAC,YAAY,IAAI,IAAI,KAAK,CAAC,4BAA4B,GAAG,MAAM,CAAC,SAAS,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC;QAC9F,CAAC,EAAE,SAAS,CAAC,CAAC;IAChB,CAAC,CAAC,CAAC;IAEH,OAAO,OAAO,CAAC,IAAI,CAAC,CAAE,OAAO,EAAE,cAAc,CAAE,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3F,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,EAAU;IAEpC,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;QAEnC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/dist/utils/evaluate.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getStreamId } from "./streamContext.js";
|
|
2
|
+
import { raceWithTimeout } from "./delay.js";
|
|
2
3
|
/* This module provides a wrapper around Puppeteer's page.evaluate() and frame.evaluate() that adds two critical safety mechanisms:
|
|
3
4
|
*
|
|
4
5
|
* 1. Abort signal: When a stream is terminated, its AbortController is triggered, immediately rejecting all pending evaluate calls for that stream. This prevents zombie
|
|
@@ -97,13 +98,9 @@ export async function evaluateWithAbort(context, pageFunction, args, timeoutMs)
|
|
|
97
98
|
// Attach a no-op catch to suppress unhandled rejection warnings. When we abort or timeout, the underlying CDP call is still pending and will eventually resolve or
|
|
98
99
|
// reject. Without this, we'd get unhandled rejection warnings when the CDP call completes after we've moved on.
|
|
99
100
|
evaluatePromise.catch(() => { });
|
|
100
|
-
//
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
reject(new EvaluateTimeoutError(timeout));
|
|
104
|
-
}, timeout);
|
|
105
|
-
});
|
|
106
|
-
// If we have an abort signal, create an abort promise.
|
|
101
|
+
// Race evaluate against timeout using the shared utility. Timer cleanup is handled by raceWithTimeout's .finally().
|
|
102
|
+
const timeoutRace = raceWithTimeout(evaluatePromise, timeout, new EvaluateTimeoutError(timeout));
|
|
103
|
+
// If we have an abort signal, add a third racer that rejects when the abort fires.
|
|
107
104
|
if (signal) {
|
|
108
105
|
const abortPromise = new Promise((_, reject) => {
|
|
109
106
|
// Check if already aborted (race condition protection).
|
|
@@ -115,10 +112,8 @@ export async function evaluateWithAbort(context, pageFunction, args, timeoutMs)
|
|
|
115
112
|
reject(new EvaluateAbortError());
|
|
116
113
|
}, { once: true });
|
|
117
114
|
});
|
|
118
|
-
|
|
119
|
-
return Promise.race([evaluatePromise, timeoutPromise, abortPromise]);
|
|
115
|
+
return Promise.race([timeoutRace, abortPromise]);
|
|
120
116
|
}
|
|
121
|
-
|
|
122
|
-
return Promise.race([evaluatePromise, timeoutPromise]);
|
|
117
|
+
return timeoutRace;
|
|
123
118
|
}
|
|
124
119
|
//# sourceMappingURL=evaluate.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"evaluate.js","sourceRoot":"","sources":["../../src/utils/evaluate.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"evaluate.js","sourceRoot":"","sources":["../../src/utils/evaluate.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/ffmpeg.d.ts
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import type { Readable, Writable } from "node:stream";
|
|
2
2
|
import type { ChildProcess } from "node:child_process";
|
|
3
|
+
/**
|
|
4
|
+
* Returns the path to the bundled ffmpeg-for-homebridge binary if it exists on disk. This binary ships as an npm dependency and has a full encoder set (libx264,
|
|
5
|
+
* libx265, zoompan, overlay) regardless of what the user has installed. Used by preroll generation to guarantee HEVC encoding availability without depending on
|
|
6
|
+
* the Channels DVR FFmpeg (which has a minimal encoder set) or a system installation.
|
|
7
|
+
* @returns The absolute path to the bundled FFmpeg, or undefined if the package did not resolve or the binary is missing.
|
|
8
|
+
*/
|
|
9
|
+
export declare function getBundledFFmpegPath(): string | undefined;
|
|
3
10
|
/**
|
|
4
11
|
* Resolves the FFmpeg executable path. Checks Channels DVR (macOS, Windows, Linux), then the bundled ffmpeg-for-homebridge, then system PATH. The resolved path is
|
|
5
12
|
* cached for subsequent calls.
|
|
@@ -16,14 +23,15 @@ export interface FFmpegProcess {
|
|
|
16
23
|
stdout: Readable;
|
|
17
24
|
}
|
|
18
25
|
/**
|
|
19
|
-
* Spawns an FFmpeg process configured to
|
|
20
|
-
*
|
|
26
|
+
* Spawns an FFmpeg process configured to remux Matroska to fMP4. Video is passed through unchanged (codec copy); audio is transcoded from Opus to AAC for HLS
|
|
27
|
+
* compatibility. The video codec (H264 or HEVC) is determined by Chrome's MediaRecorder based on hardware capabilities. The process reads from stdin and writes
|
|
28
|
+
* to stdout, allowing it to be integrated into a Node.js stream pipeline.
|
|
21
29
|
*
|
|
22
30
|
* FFmpeg arguments:
|
|
23
31
|
* - `-hide_banner -loglevel warning`: Reduce noise, only show warnings/errors
|
|
24
|
-
* - `-probesize 16384`: Limit input probing to 16KB (Chrome's
|
|
32
|
+
* - `-probesize 16384`: Limit input probing to 16KB (Chrome's Matroska header fits well under this) to minimize startup delay
|
|
25
33
|
* - `-i pipe:0`: Read input from stdin
|
|
26
|
-
* - `-c:v copy`: Copy video stream without re-encoding (
|
|
34
|
+
* - `-c:v copy`: Copy video stream without re-encoding (passthrough)
|
|
27
35
|
* - `-c:a aac -b:a <bitrate>`: Transcode audio to AAC at specified bitrate
|
|
28
36
|
* - `-f mp4`: Output MP4 container format
|
|
29
37
|
* - `-movflags frag_keyframe+empty_moov+default_base_moof`: Streaming-friendly fMP4 flags
|
|
@@ -38,7 +46,7 @@ export interface FFmpegProcess {
|
|
|
38
46
|
export declare function spawnFFmpeg(audioBitrate: number, onError: (error: Error) => void, streamId?: string, comment?: string): FFmpegProcess;
|
|
39
47
|
/**
|
|
40
48
|
* Spawns an FFmpeg process configured to remux fMP4 input to MPEG-TS output with codec copy. The process reads a continuous fMP4 stream (init segment followed by
|
|
41
|
-
* media segments) from stdin and writes MPEG-TS to stdout. No transcoding occurs — both video
|
|
49
|
+
* media segments) from stdin and writes MPEG-TS to stdout. No transcoding occurs — both video and audio are copied unchanged — so CPU usage is minimal.
|
|
42
50
|
*
|
|
43
51
|
* FFmpeg arguments:
|
|
44
52
|
* - `-hide_banner -loglevel warning`: Reduce noise, only show warnings/errors
|
package/dist/utils/ffmpeg.js
CHANGED
|
@@ -6,14 +6,29 @@ import { join } from "node:path";
|
|
|
6
6
|
import { spawn } from "node:child_process";
|
|
7
7
|
// The ffmpeg-for-homebridge package has incorrect type definitions (declares named export but JS uses default export). Cast to the correct type.
|
|
8
8
|
const ffmpegPath = ffmpegForHomebridge;
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
// FFmpeg stderr noise patterns that are suppressed from logging. The -nostats flag suppresses most progress output, but some FFmpeg builds or versions may still
|
|
10
|
+
// emit these patterns. The filter acts as a safety net to keep logs clean.
|
|
11
|
+
const FFMPEG_NOISE_PATTERNS = ["Press [q] to stop", "frame=", "size=", "time=", "bitrate=", "speed="];
|
|
12
|
+
/**
|
|
13
|
+
* Returns the path to the bundled ffmpeg-for-homebridge binary if it exists on disk. This binary ships as an npm dependency and has a full encoder set (libx264,
|
|
14
|
+
* libx265, zoompan, overlay) regardless of what the user has installed. Used by preroll generation to guarantee HEVC encoding availability without depending on
|
|
15
|
+
* the Channels DVR FFmpeg (which has a minimal encoder set) or a system installation.
|
|
16
|
+
* @returns The absolute path to the bundled FFmpeg, or undefined if the package did not resolve or the binary is missing.
|
|
17
|
+
*/
|
|
18
|
+
export function getBundledFFmpegPath() {
|
|
19
|
+
if (ffmpegPath && existsSync(ffmpegPath)) {
|
|
20
|
+
return ffmpegPath;
|
|
21
|
+
}
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
/* When using Matroska capture mode, Chrome's MediaRecorder outputs a Matroska container with video (H264 or HEVC depending on hardware capabilities) and Opus audio.
|
|
25
|
+
* For HLS compatibility, we need an fMP4 container with AAC audio. FFmpeg handles this conversion:
|
|
11
26
|
*
|
|
12
27
|
* - Video: Passed through unchanged (copy codec) - no quality loss, minimal CPU
|
|
13
28
|
* - Audio: Transcoded from Opus to AAC - lightweight operation
|
|
14
|
-
* - Container: Converted from
|
|
29
|
+
* - Container: Converted from Matroska to fragmented MP4 with streaming-friendly flags
|
|
15
30
|
*
|
|
16
|
-
* The FFmpeg process runs for the lifetime of the stream, reading
|
|
31
|
+
* The FFmpeg process runs for the lifetime of the stream, reading Matroska from stdin and writing fMP4 to stdout. This output feeds directly into the existing fMP4
|
|
17
32
|
* segmenter.
|
|
18
33
|
*/
|
|
19
34
|
/* FFmpeg can be located in several places depending on how it was installed. We check in order of preference:
|
|
@@ -139,8 +154,7 @@ function spawnFFmpegProcess({ args, label, onError, streamId }) {
|
|
|
139
154
|
return;
|
|
140
155
|
}
|
|
141
156
|
const message = data.toString().trim();
|
|
142
|
-
|
|
143
|
-
if (noisePatterns.some((pattern) => message.includes(pattern))) {
|
|
157
|
+
if (FFMPEG_NOISE_PATTERNS.some((pattern) => message.includes(pattern))) {
|
|
144
158
|
return;
|
|
145
159
|
}
|
|
146
160
|
if (message.length > 0) {
|
|
@@ -186,14 +200,15 @@ function spawnFFmpegProcess({ args, label, onError, streamId }) {
|
|
|
186
200
|
}
|
|
187
201
|
// Public FFmpeg Spawners.
|
|
188
202
|
/**
|
|
189
|
-
* Spawns an FFmpeg process configured to
|
|
190
|
-
*
|
|
203
|
+
* Spawns an FFmpeg process configured to remux Matroska to fMP4. Video is passed through unchanged (codec copy); audio is transcoded from Opus to AAC for HLS
|
|
204
|
+
* compatibility. The video codec (H264 or HEVC) is determined by Chrome's MediaRecorder based on hardware capabilities. The process reads from stdin and writes
|
|
205
|
+
* to stdout, allowing it to be integrated into a Node.js stream pipeline.
|
|
191
206
|
*
|
|
192
207
|
* FFmpeg arguments:
|
|
193
208
|
* - `-hide_banner -loglevel warning`: Reduce noise, only show warnings/errors
|
|
194
|
-
* - `-probesize 16384`: Limit input probing to 16KB (Chrome's
|
|
209
|
+
* - `-probesize 16384`: Limit input probing to 16KB (Chrome's Matroska header fits well under this) to minimize startup delay
|
|
195
210
|
* - `-i pipe:0`: Read input from stdin
|
|
196
|
-
* - `-c:v copy`: Copy video stream without re-encoding (
|
|
211
|
+
* - `-c:v copy`: Copy video stream without re-encoding (passthrough)
|
|
197
212
|
* - `-c:a aac -b:a <bitrate>`: Transcode audio to AAC at specified bitrate
|
|
198
213
|
* - `-f mp4`: Output MP4 container format
|
|
199
214
|
* - `-movflags frag_keyframe+empty_moov+default_base_moof`: Streaming-friendly fMP4 flags
|
|
@@ -210,7 +225,10 @@ export function spawnFFmpeg(audioBitrate, onError, streamId, comment) {
|
|
|
210
225
|
const aacEncoder = process.platform === "darwin" ? "aac_at" : "aac";
|
|
211
226
|
const ffmpegArgs = [
|
|
212
227
|
"-hide_banner",
|
|
228
|
+
"-nostats",
|
|
213
229
|
"-loglevel", "warning",
|
|
230
|
+
"-fflags", "+discardcorrupt",
|
|
231
|
+
"-err_detect", "ignore_err",
|
|
214
232
|
"-probesize", "16384",
|
|
215
233
|
"-i", "pipe:0",
|
|
216
234
|
"-c:v", "copy",
|
|
@@ -234,7 +252,7 @@ export function spawnFFmpeg(audioBitrate, onError, streamId, comment) {
|
|
|
234
252
|
}
|
|
235
253
|
/**
|
|
236
254
|
* Spawns an FFmpeg process configured to remux fMP4 input to MPEG-TS output with codec copy. The process reads a continuous fMP4 stream (init segment followed by
|
|
237
|
-
* media segments) from stdin and writes MPEG-TS to stdout. No transcoding occurs — both video
|
|
255
|
+
* media segments) from stdin and writes MPEG-TS to stdout. No transcoding occurs — both video and audio are copied unchanged — so CPU usage is minimal.
|
|
238
256
|
*
|
|
239
257
|
* FFmpeg arguments:
|
|
240
258
|
* - `-hide_banner -loglevel warning`: Reduce noise, only show warnings/errors
|
|
@@ -250,7 +268,10 @@ export function spawnFFmpeg(audioBitrate, onError, streamId, comment) {
|
|
|
250
268
|
export function spawnMpegTsRemuxer(onError, streamId) {
|
|
251
269
|
const ffmpegArgs = [
|
|
252
270
|
"-hide_banner",
|
|
271
|
+
"-nostats",
|
|
253
272
|
"-loglevel", "warning",
|
|
273
|
+
"-fflags", "+discardcorrupt",
|
|
274
|
+
"-err_detect", "ignore_err",
|
|
254
275
|
"-probesize", "16384",
|
|
255
276
|
"-f", "mp4",
|
|
256
277
|
"-i", "pipe:0",
|
package/dist/utils/ffmpeg.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ffmpeg.js","sourceRoot":"","sources":["../../src/utils/ffmpeg.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"ffmpeg.js","sourceRoot":"","sources":["../../src/utils/ffmpeg.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/format.d.ts
CHANGED
|
@@ -21,3 +21,9 @@ export declare function formatTimeAgo(timestamp: number): string;
|
|
|
21
21
|
* @returns The concise domain, or the original URL if parsing fails.
|
|
22
22
|
*/
|
|
23
23
|
export declare function extractDomain(url: string): string;
|
|
24
|
+
/**
|
|
25
|
+
* Capitalizes the first letter of a string.
|
|
26
|
+
* @param str - The string to capitalize.
|
|
27
|
+
* @returns The string with the first letter capitalized.
|
|
28
|
+
*/
|
|
29
|
+
export declare function capitalize(str: string): string;
|
package/dist/utils/format.js
CHANGED
|
@@ -65,4 +65,12 @@ export function extractDomain(url) {
|
|
|
65
65
|
return url;
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
|
+
/**
|
|
69
|
+
* Capitalizes the first letter of a string.
|
|
70
|
+
* @param str - The string to capitalize.
|
|
71
|
+
* @returns The string with the first letter capitalized.
|
|
72
|
+
*/
|
|
73
|
+
export function capitalize(str) {
|
|
74
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
75
|
+
}
|
|
68
76
|
//# sourceMappingURL=format.js.map
|
package/dist/utils/format.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/utils/format.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,EAAU;IAEvC,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,YAAY,GAAG,EAAE,CAAC;IAElC,IAAG,KAAK,GAAG,CAAC,EAAE,CAAC;QAEb,OAAO,CAAE,MAAM,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,GAAG,CAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAChE,CAAC;IAED,IAAG,OAAO,GAAG,CAAC,EAAE,CAAC;QAEf,OAAO,CAAE,MAAM,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,GAAG,CAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAClE,CAAC;IAED,OAAO,CAAE,MAAM,CAAC,OAAO,CAAC,EAAE,GAAG,CAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC3C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,SAAiB;IAE7C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,GAAG,IAAI,CAAC,CAAC;IAE5D,IAAG,OAAO,GAAG,EAAE,EAAE,CAAC;QAEhB,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;IAEzC,IAAG,OAAO,GAAG,EAAE,EAAE,CAAC;QAEhB,OAAO,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;IAC5E,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;IAEvC,IAAG,KAAK,GAAG,EAAE,EAAE,CAAC;QAEd,OAAO,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;IACpE,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;IAEpC,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;AAChE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,GAAW;IAEvC,IAAI,CAAC;QAEH,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC;QACvC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAElC,uHAAuH;QACvH,IAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAEpB,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACnC,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;IAAC,MAAM,CAAC;QAEP,OAAO,GAAG,CAAC;IACb,CAAC;AACH,CAAC"}
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/utils/format.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,EAAU;IAEvC,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,YAAY,GAAG,EAAE,CAAC;IAElC,IAAG,KAAK,GAAG,CAAC,EAAE,CAAC;QAEb,OAAO,CAAE,MAAM,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,GAAG,CAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAChE,CAAC;IAED,IAAG,OAAO,GAAG,CAAC,EAAE,CAAC;QAEf,OAAO,CAAE,MAAM,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,GAAG,CAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAClE,CAAC;IAED,OAAO,CAAE,MAAM,CAAC,OAAO,CAAC,EAAE,GAAG,CAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC3C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,SAAiB;IAE7C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,GAAG,IAAI,CAAC,CAAC;IAE5D,IAAG,OAAO,GAAG,EAAE,EAAE,CAAC;QAEhB,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;IAEzC,IAAG,OAAO,GAAG,EAAE,EAAE,CAAC;QAEhB,OAAO,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;IAC5E,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;IAEvC,IAAG,KAAK,GAAG,EAAE,EAAE,CAAC;QAEd,OAAO,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;IACpE,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;IAEpC,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;AAChE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,GAAW;IAEvC,IAAI,CAAC;QAEH,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC;QACvC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAElC,uHAAuH;QACvH,IAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAEpB,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACnC,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;IAAC,MAAM,CAAC;QAEP,OAAO,GAAG,CAAC;IACb,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,GAAW;IAEpC,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACpD,CAAC"}
|
package/dist/utils/index.d.ts
CHANGED
package/dist/utils/index.js
CHANGED
package/dist/utils/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,mBAAmB,CAAC;AAClC,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,mBAAmB,CAAC;AAClC,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC"}
|
package/dist/utils/logEmitter.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
*
|
|
3
3
|
* logEmitter.ts: Event emitter for real-time log streaming via SSE.
|
|
4
4
|
*/
|
|
5
|
-
import { EventEmitter } from "events";
|
|
5
|
+
import { EventEmitter } from "node:events";
|
|
6
6
|
/* A singleton EventEmitter that broadcasts log entries to all subscribed SSE clients. When a log entry is written via LOG.info/warn/error, the entry is emitted here
|
|
7
7
|
* for real-time streaming to connected browsers.
|
|
8
8
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logEmitter.js","sourceRoot":"","sources":["../../src/utils/logEmitter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"logEmitter.js","sourceRoot":"","sources":["../../src/utils/logEmitter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAc3C;;GAEG;AAEH,MAAM,UAAU,GAAG,IAAI,YAAY,EAAE,CAAC;AAEtC,oJAAoJ;AACpJ,UAAU,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;AAEhC;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,KAAe;IAE1C,UAAU,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAChC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,QAAmC;IAEjE,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAE/B,OAAO,GAAS,EAAE;QAEhB,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAClC,CAAC,CAAC;AACJ,CAAC"}
|
package/dist/utils/retry.d.ts
CHANGED
|
@@ -1,15 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options for retryOperation. Groups all parameters into a single object to avoid positional parameter sprawl and make the function extensible.
|
|
3
|
+
*/
|
|
4
|
+
export interface RetryOptions<T> {
|
|
5
|
+
backoffJitter?: number;
|
|
6
|
+
description: string;
|
|
7
|
+
earlySuccessCheck?: () => Promise<boolean>;
|
|
8
|
+
maxAttempts: number;
|
|
9
|
+
maxBackoffDelay?: number;
|
|
10
|
+
operation: () => Promise<T>;
|
|
11
|
+
shouldAbort?: () => boolean;
|
|
12
|
+
timeoutMs: number;
|
|
13
|
+
}
|
|
1
14
|
/**
|
|
2
15
|
* Implements a generic retry mechanism with exponential backoff and jitter. This function attempts an operation multiple times, waiting progressively longer between
|
|
3
16
|
* attempts to avoid overwhelming failing services. The exponential backoff with jitter prevents thundering herd problems where many clients retry simultaneously.
|
|
4
|
-
* @param
|
|
5
|
-
* @param maxAttempts - Maximum number of attempts before giving up.
|
|
6
|
-
* @param timeoutMs - Timeout in milliseconds for each individual attempt.
|
|
7
|
-
* @param description - Human-readable description for logging purposes.
|
|
8
|
-
* @param earlySuccessCheck - Optional async function called after timeout errors. If it returns a truthy value, that value is returned as success instead of
|
|
9
|
-
* retrying. Useful for cases where the operation succeeded but took too long.
|
|
10
|
-
* @param shouldAbort - Optional function called before each attempt. If it returns true, retries are aborted immediately. Useful for checking if the page was closed
|
|
11
|
-
* during the backoff delay.
|
|
17
|
+
* @param options - Retry configuration including the operation, attempt limits, timeouts, and optional backoff tuning.
|
|
12
18
|
* @returns The result of the operation if successful.
|
|
13
19
|
* @throws The last error encountered if all attempts fail.
|
|
14
20
|
*/
|
|
15
|
-
export declare function retryOperation<T>(
|
|
21
|
+
export declare function retryOperation<T>(options: RetryOptions<T>): Promise<T | undefined>;
|
package/dist/utils/retry.js
CHANGED
|
@@ -3,27 +3,17 @@
|
|
|
3
3
|
* retry.ts: Retry logic with exponential backoff for PrismCast.
|
|
4
4
|
*/
|
|
5
5
|
import { formatError, isSessionClosedError } from "./errors.js";
|
|
6
|
-
import { CONFIG } from "../config/index.js";
|
|
7
6
|
import { LOG } from "./logger.js";
|
|
8
|
-
|
|
9
|
-
* slow page loads, the system automatically retries with increasing delays. The exponential backoff prevents overwhelming struggling services, while jitter prevents
|
|
10
|
-
* multiple clients from synchronizing their retry attempts.
|
|
11
|
-
*/
|
|
7
|
+
import { raceWithTimeout } from "./delay.js";
|
|
12
8
|
/**
|
|
13
9
|
* Implements a generic retry mechanism with exponential backoff and jitter. This function attempts an operation multiple times, waiting progressively longer between
|
|
14
10
|
* attempts to avoid overwhelming failing services. The exponential backoff with jitter prevents thundering herd problems where many clients retry simultaneously.
|
|
15
|
-
* @param
|
|
16
|
-
* @param maxAttempts - Maximum number of attempts before giving up.
|
|
17
|
-
* @param timeoutMs - Timeout in milliseconds for each individual attempt.
|
|
18
|
-
* @param description - Human-readable description for logging purposes.
|
|
19
|
-
* @param earlySuccessCheck - Optional async function called after timeout errors. If it returns a truthy value, that value is returned as success instead of
|
|
20
|
-
* retrying. Useful for cases where the operation succeeded but took too long.
|
|
21
|
-
* @param shouldAbort - Optional function called before each attempt. If it returns true, retries are aborted immediately. Useful for checking if the page was closed
|
|
22
|
-
* during the backoff delay.
|
|
11
|
+
* @param options - Retry configuration including the operation, attempt limits, timeouts, and optional backoff tuning.
|
|
23
12
|
* @returns The result of the operation if successful.
|
|
24
13
|
* @throws The last error encountered if all attempts fail.
|
|
25
14
|
*/
|
|
26
|
-
export async function retryOperation(
|
|
15
|
+
export async function retryOperation(options) {
|
|
16
|
+
const { backoffJitter = 1000, description, earlySuccessCheck, maxAttempts, maxBackoffDelay = 3000, operation, shouldAbort, timeoutMs } = options;
|
|
27
17
|
let lastError = null;
|
|
28
18
|
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
29
19
|
// Check if we should abort before starting this attempt. This catches cases where the page was closed during the backoff delay between retries.
|
|
@@ -34,14 +24,8 @@ export async function retryOperation(operation, maxAttempts, timeoutMs, descript
|
|
|
34
24
|
LOG.debug("retry", "Retrying %s (attempt %s of %s).", description, attempt, maxAttempts);
|
|
35
25
|
}
|
|
36
26
|
try {
|
|
37
|
-
// Race the operation against a timeout to prevent hanging on operations that never complete.
|
|
38
|
-
const timeoutPromise = new Promise((_, reject) => {
|
|
39
|
-
setTimeout(() => {
|
|
40
|
-
reject(new Error(["Operation timed out after ", String(timeoutMs), "ms."].join("")));
|
|
41
|
-
}, timeoutMs);
|
|
42
|
-
});
|
|
43
27
|
// eslint-disable-next-line no-await-in-loop
|
|
44
|
-
return await
|
|
28
|
+
return await raceWithTimeout(operation(), timeoutMs);
|
|
45
29
|
}
|
|
46
30
|
catch (error) {
|
|
47
31
|
lastError = error;
|
|
@@ -68,8 +52,8 @@ export async function retryOperation(operation, maxAttempts, timeoutMs, descript
|
|
|
68
52
|
LOG.warn("Attempt %s failed for %s: %s", attempt, description, formatError(error));
|
|
69
53
|
// Between retry attempts, wait with exponential backoff plus random jitter.
|
|
70
54
|
if (attempt < maxAttempts) {
|
|
71
|
-
const baseDelay = Math.min(1000 * Math.pow(2, attempt - 1),
|
|
72
|
-
const jitter = Math.random() *
|
|
55
|
+
const baseDelay = Math.min(1000 * Math.pow(2, attempt - 1), maxBackoffDelay);
|
|
56
|
+
const jitter = Math.random() * backoffJitter;
|
|
73
57
|
// eslint-disable-next-line no-await-in-loop
|
|
74
58
|
await new Promise((resolve) => {
|
|
75
59
|
setTimeout(resolve, baseDelay + jitter);
|
package/dist/utils/retry.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/utils/retry.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/utils/retry.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAuC7C;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAI,OAAwB;IAE9D,MAAM,EAAE,aAAa,GAAG,IAAI,EAAE,WAAW,EAAE,iBAAiB,EAAE,WAAW,EAAE,eAAe,GAAG,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;IAEjJ,IAAI,SAAS,GAAY,IAAI,CAAC;IAE9B,KAAI,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,WAAW,EAAE,OAAO,EAAE,EAAE,CAAC;QAEvD,gJAAgJ;QAChJ,IAAG,WAAW,EAAE,EAAE,EAAE,CAAC;YAEnB,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;QAC1E,CAAC;QAED,IAAG,OAAO,GAAG,CAAC,EAAE,CAAC;YAEf,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,iCAAiC,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;QAC3F,CAAC;QAED,IAAI,CAAC;YAEH,4CAA4C;YAC5C,OAAO,MAAM,eAAe,CAAC,SAAS,EAAE,EAAE,SAAS,CAAC,CAAC;QACvD,CAAC;QAAC,OAAM,KAAK,EAAE,CAAC;YAEd,SAAS,GAAG,KAAK,CAAC;YAElB,8HAA8H;YAC9H,IAAG,oBAAoB,CAAC,KAAK,CAAC,EAAE,CAAC;gBAE/B,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,2CAA2C,EAAE,WAAW,CAAC,CAAC;gBAE7E,MAAM,KAAK,CAAC;YACd,CAAC;YAED,6JAA6J;YAC7J,gKAAgK;YAChK,IAAG,iBAAiB,IAAI,WAAW,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;gBAEjE,IAAI,CAAC;oBAEH,4CAA4C;oBAC5C,MAAM,aAAa,GAAG,MAAM,iBAAiB,EAAE,CAAC;oBAEhD,IAAG,aAAa,EAAE,CAAC;wBAEjB,OAAO;oBACT,CAAC;gBACH,CAAC;gBAAC,OAAM,WAAW,EAAE,CAAC;oBAEpB,yDAAyD;gBAC3D,CAAC;YACH,CAAC;YAED,oIAAoI;YACpI,GAAG,CAAC,IAAI,CAAC,8BAA8B,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;YAEnF,4EAA4E;YAC5E,IAAG,OAAO,GAAG,WAAW,EAAE,CAAC;gBAEzB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC;gBAC7E,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,aAAa,CAAC;gBAE7C,4CAA4C;gBAC5C,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;oBAElC,UAAU,CAAC,OAAO,EAAE,SAAS,GAAG,MAAM,CAAC,CAAC;gBAC1C,CAAC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,SAAS,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates a lightweight elapsed-time closure using performance.now(). Call the returned function to get the elapsed milliseconds since creation.
|
|
3
|
+
* @returns A closure that returns elapsed milliseconds as a number.
|
|
4
|
+
*/
|
|
5
|
+
export declare function startTimer(): () => number;
|