prismcast 1.3.3 → 1.4.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 +3 -2
- package/dist/app.js +32 -17
- package/dist/app.js.map +1 -1
- package/dist/browser/channelSelection.d.ts +3 -2
- package/dist/browser/channelSelection.js +43 -19
- package/dist/browser/channelSelection.js.map +1 -1
- package/dist/browser/index.d.ts +9 -13
- package/dist/browser/index.js +65 -75
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/tuning/hulu.js +613 -13
- package/dist/browser/tuning/hulu.js.map +1 -1
- package/dist/browser/tuning/sling.js +1 -1
- package/dist/browser/tuning/thumbnailRow.js +69 -71
- package/dist/browser/tuning/thumbnailRow.js.map +1 -1
- package/dist/browser/tuning/tileClick.js +111 -77
- package/dist/browser/tuning/tileClick.js.map +1 -1
- package/dist/browser/tuning/youtubeTv.js +5 -5
- package/dist/browser/tuning/youtubeTv.js.map +1 -1
- package/dist/browser/video.d.ts +3 -10
- package/dist/browser/video.js +91 -10
- package/dist/browser/video.js.map +1 -1
- package/dist/config/index.d.ts +9 -3
- package/dist/config/index.js +28 -28
- package/dist/config/index.js.map +1 -1
- package/dist/config/paths.d.ts +41 -0
- package/dist/config/paths.js +88 -0
- package/dist/config/paths.js.map +1 -0
- package/dist/config/providers.js +1 -1
- package/dist/config/sites.js +30 -13
- package/dist/config/sites.js.map +1 -1
- package/dist/config/userChannels.d.ts +1 -1
- package/dist/config/userChannels.js +10 -13
- package/dist/config/userChannels.js.map +1 -1
- package/dist/config/userConfig.d.ts +14 -7
- package/dist/config/userConfig.js +59 -34
- package/dist/config/userConfig.js.map +1 -1
- package/dist/index.d.ts +11 -1
- package/dist/index.js +187 -25
- package/dist/index.js.map +1 -1
- package/dist/routes/config.js +15 -7
- package/dist/routes/config.js.map +1 -1
- package/dist/routes/debug.js +41 -6
- package/dist/routes/debug.js.map +1 -1
- package/dist/routes/index.d.ts +1 -0
- package/dist/routes/index.js +3 -0
- package/dist/routes/index.js.map +1 -1
- package/dist/routes/logs.js +3 -3
- package/dist/routes/logs.js.map +1 -1
- package/dist/routes/playlist.d.ts +2 -2
- package/dist/routes/playlist.js +11 -9
- package/dist/routes/playlist.js.map +1 -1
- package/dist/routes/root.js +149 -6
- package/dist/routes/root.js.map +1 -1
- package/dist/routes/theme.js +4 -0
- package/dist/routes/theme.js.map +1 -1
- package/dist/routes/ui.js +2 -0
- package/dist/routes/ui.js.map +1 -1
- package/dist/routes/upgrade.d.ts +6 -0
- package/dist/routes/upgrade.js +68 -0
- package/dist/routes/upgrade.js.map +1 -0
- package/dist/service/commands.js +9 -7
- package/dist/service/commands.js.map +1 -1
- package/dist/service/generators.js +10 -15
- package/dist/service/generators.js.map +1 -1
- package/dist/streaming/fmp4Segmenter.d.ts +28 -0
- package/dist/streaming/fmp4Segmenter.js +140 -47
- package/dist/streaming/fmp4Segmenter.js.map +1 -1
- package/dist/streaming/hls.js +3 -1
- package/dist/streaming/hls.js.map +1 -1
- package/dist/streaming/lifecycle.js +13 -6
- package/dist/streaming/lifecycle.js.map +1 -1
- package/dist/streaming/mp4Parser.d.ts +19 -10
- package/dist/streaming/mp4Parser.js +39 -29
- package/dist/streaming/mp4Parser.js.map +1 -1
- package/dist/streaming/setup.d.ts +2 -0
- package/dist/streaming/setup.js +4 -1
- package/dist/streaming/setup.js.map +1 -1
- package/dist/types/index.d.ts +10 -7
- package/dist/types/index.js.map +1 -1
- package/dist/upgrade/commands.d.ts +6 -0
- package/dist/upgrade/commands.js +210 -0
- package/dist/upgrade/commands.js.map +1 -0
- package/dist/upgrade/detection.d.ts +15 -0
- package/dist/upgrade/detection.js +75 -0
- package/dist/upgrade/detection.js.map +1 -0
- package/dist/upgrade/index.d.ts +2 -0
- package/dist/upgrade/index.js +7 -0
- package/dist/upgrade/index.js.map +1 -0
- package/dist/utils/fileLogger.d.ts +2 -1
- package/dist/utils/fileLogger.js +10 -8
- package/dist/utils/fileLogger.js.map +1 -1
- package/dist/utils/logger.js +1 -1
- package/dist/utils/m3u.js +1 -7
- package/dist/utils/m3u.js.map +1 -1
- package/dist/utils/platform.d.ts +8 -2
- package/dist/utils/platform.js +26 -6
- package/dist/utils/platform.js.map +1 -1
- package/dist/utils/version.d.ts +18 -0
- package/dist/utils/version.js +3 -3
- package/dist/utils/version.js.map +1 -1
- package/package.json +6 -6
package/dist/app.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import type { ParsedArgs } from "./index.js";
|
|
1
2
|
/**
|
|
2
3
|
* Initializes and starts the HTTP server. Before accepting connections, we validate configuration, clean up stale Chrome processes, and warm up the browser
|
|
3
4
|
* instance.
|
|
4
|
-
* @param
|
|
5
|
+
* @param parsedArgs - Parsed command-line arguments containing flags and override values.
|
|
5
6
|
*/
|
|
6
|
-
export declare function startServer(
|
|
7
|
+
export declare function startServer(parsedArgs: ParsedArgs): Promise<void>;
|
package/dist/app.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* app.ts: Express application builder for PrismCast.
|
|
4
4
|
*/
|
|
5
5
|
import { CONFIG, displayConfiguration, initializeConfiguration, validateConfiguration } from "./config/index.js";
|
|
6
|
-
import { LOG, createMorganStream, formatError, getPackageVersion, isDebugLogging, resolveFFmpegPath, setConsoleLogging, startUpdateChecking, stopUpdateChecking } from "./utils/index.js";
|
|
6
|
+
import { LOG, createMorganStream, formatError, getCurrentPattern, getPackageVersion, isDebugLogging, resolveFFmpegPath, setConsoleLogging, startUpdateChecking, stopUpdateChecking } from "./utils/index.js";
|
|
7
7
|
import { closeBrowser, ensureDataDirectory, getCurrentBrowser, killStaleChrome, minimizeBrowserWindow, prepareExtension, setGracefulShutdown, startBrowserRestartChecking, startStalePageCleanup, stopBrowserRestartChecking, stopStalePageCleanup } from "./browser/index.js";
|
|
8
8
|
import { initializeFileLogger, shutdownFileLogger } from "./utils/fileLogger.js";
|
|
9
9
|
import { startHdhrServer, stopHdhrServer } from "./hdhr/index.js";
|
|
@@ -12,6 +12,7 @@ import { cleanupIdleStreams } from "./streaming/hls.js";
|
|
|
12
12
|
import consoleStamp from "console-stamp";
|
|
13
13
|
import express from "express";
|
|
14
14
|
import { getAllStreams } from "./streaming/registry.js";
|
|
15
|
+
import { getLogFilePath } from "./config/paths.js";
|
|
15
16
|
import { initializeUserChannels } from "./config/userChannels.js";
|
|
16
17
|
import morgan from "morgan";
|
|
17
18
|
import { setupRoutes } from "./routes/index.js";
|
|
@@ -19,7 +20,7 @@ import { terminateStream } from "./streaming/lifecycle.js";
|
|
|
19
20
|
import { validateProfiles } from "./config/profiles.js";
|
|
20
21
|
import { verifyCaptureSystem } from "./streaming/setup.js";
|
|
21
22
|
/* The logging mode is set at startup based on the --console CLI flag. When console logging is enabled, timestamps are added via console-stamp and output goes to
|
|
22
|
-
* stdout/stderr. When file logging is used (the default), output goes to
|
|
23
|
+
* stdout/stderr. When file logging is used (the default), output goes to the configured log file (default: prismcast.log in the data directory).
|
|
23
24
|
*/
|
|
24
25
|
// Track whether console logging is enabled, set during startServer().
|
|
25
26
|
let usingConsoleLogging = false;
|
|
@@ -213,19 +214,30 @@ async function buildApp() {
|
|
|
213
214
|
/**
|
|
214
215
|
* Initializes and starts the HTTP server. Before accepting connections, we validate configuration, clean up stale Chrome processes, and warm up the browser
|
|
215
216
|
* instance.
|
|
216
|
-
* @param
|
|
217
|
+
* @param parsedArgs - Parsed command-line arguments containing flags and override values.
|
|
217
218
|
*/
|
|
218
|
-
export async function startServer(
|
|
219
|
+
export async function startServer(parsedArgs) {
|
|
219
220
|
// Set logging mode early before any log calls.
|
|
220
|
-
usingConsoleLogging =
|
|
221
|
-
setConsoleLogging(
|
|
221
|
+
usingConsoleLogging = parsedArgs.consoleLogging;
|
|
222
|
+
setConsoleLogging(parsedArgs.consoleLogging);
|
|
222
223
|
// Apply console-stamp for timestamps only when using console logging.
|
|
223
|
-
if (
|
|
224
|
+
if (parsedArgs.consoleLogging) {
|
|
224
225
|
consoleStamp(console, { format: ":date(yyyy/mm/dd HH:MM:ss.l)" });
|
|
225
226
|
}
|
|
226
|
-
//
|
|
227
|
+
// Build CLI overrides from parsed arguments. These have the highest priority in the merge order (CLI > env > config.json > defaults).
|
|
228
|
+
const cliOverrides = {};
|
|
229
|
+
if (parsedArgs.chromeDataDir !== undefined) {
|
|
230
|
+
cliOverrides["paths.chromeDataDir"] = parsedArgs.chromeDataDir;
|
|
231
|
+
}
|
|
232
|
+
if (parsedArgs.logFile !== undefined) {
|
|
233
|
+
cliOverrides["paths.logFile"] = parsedArgs.logFile;
|
|
234
|
+
}
|
|
235
|
+
if (parsedArgs.port !== undefined) {
|
|
236
|
+
cliOverrides["server.port"] = parsedArgs.port;
|
|
237
|
+
}
|
|
238
|
+
// Initialize configuration from file and environment variables, then validate. CLI overrides are applied as the highest-priority merge pass.
|
|
227
239
|
try {
|
|
228
|
-
await initializeConfiguration();
|
|
240
|
+
await initializeConfiguration(cliOverrides);
|
|
229
241
|
validateConfiguration();
|
|
230
242
|
validateProfiles();
|
|
231
243
|
}
|
|
@@ -233,21 +245,24 @@ export async function startServer(useConsoleLogging = false) {
|
|
|
233
245
|
LOG.error(formatError(error));
|
|
234
246
|
process.exit(1);
|
|
235
247
|
}
|
|
236
|
-
displayConfiguration();
|
|
237
248
|
setupGracefulShutdown();
|
|
238
249
|
// Ensure the data directory exists before any operations that depend on it.
|
|
239
250
|
await ensureDataDirectory();
|
|
240
|
-
// Initialize file logger if not using console logging.
|
|
241
|
-
|
|
242
|
-
|
|
251
|
+
// Initialize file logger if not using console logging. This must happen after config loading (to resolve the log file path) and after ensureDataDirectory()
|
|
252
|
+
// (to create the parent directory). All startup log messages that should appear in the log file must come after this point.
|
|
253
|
+
if (!parsedArgs.consoleLogging) {
|
|
254
|
+
await initializeFileLogger(getLogFilePath(CONFIG), CONFIG.logging.maxSize);
|
|
243
255
|
}
|
|
244
|
-
// Log the version as the first
|
|
245
|
-
|
|
256
|
+
// Log the version and active configuration as the first messages captured by the file logger.
|
|
257
|
+
displayConfiguration();
|
|
246
258
|
// Log the debug filter status after the file logger is ready so the message is captured.
|
|
247
259
|
if (isDebugLogging()) {
|
|
248
260
|
const debugEnv = process.env.PRISMCAST_DEBUG;
|
|
249
261
|
if (debugEnv) {
|
|
250
|
-
LOG.info("Debug logging enabled with filter: %s.", debugEnv);
|
|
262
|
+
LOG.info("Debug logging enabled with filter: %s (from PRISMCAST_DEBUG).", debugEnv);
|
|
263
|
+
}
|
|
264
|
+
else if ((CONFIG.logging.debugFilter.length > 0) && (getCurrentPattern() === CONFIG.logging.debugFilter)) {
|
|
265
|
+
LOG.info("Debug logging enabled with filter: %s (from config).", CONFIG.logging.debugFilter);
|
|
251
266
|
}
|
|
252
267
|
else {
|
|
253
268
|
LOG.info("Debug logging enabled for all categories.");
|
|
@@ -263,7 +278,7 @@ export async function startServer(useConsoleLogging = false) {
|
|
|
263
278
|
}
|
|
264
279
|
LOG.info("Using FFmpeg at: %s", ffmpegPath);
|
|
265
280
|
}
|
|
266
|
-
// Load user channels from
|
|
281
|
+
// Load user channels from channels.json in the data directory if it exists.
|
|
267
282
|
await initializeUserChannels();
|
|
268
283
|
killStaleChrome();
|
|
269
284
|
// Warm up browser.
|
package/dist/app.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,MAAM,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAEjH,OAAO,EAAE,GAAG,EAAE,kBAAkB,EAAE,WAAW,EAAE,iBAAiB,EAAE,cAAc,EAAE,iBAAiB,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ChannelSelectorResult, ClickTarget, Nullable, ResolvedSiteProfile } from "../types/index.js";
|
|
1
|
+
import type { ChannelSelectionProfile, ChannelSelectorResult, ClickTarget, Nullable, ResolvedSiteProfile } from "../types/index.js";
|
|
2
2
|
import type { Page } from "puppeteer-core";
|
|
3
3
|
/**
|
|
4
4
|
* Returns a direct watch URL for the channel specified in the profile, if one can be resolved. Looks up the strategy entry's resolveDirectUrl hook and calls it
|
|
@@ -29,6 +29,7 @@ export declare function clearChannelSelectionCaches(): void;
|
|
|
29
29
|
*/
|
|
30
30
|
export declare function scrollAndClick(page: Page, target: ClickTarget): Promise<boolean>;
|
|
31
31
|
export declare function normalizeChannelName(name: string): string;
|
|
32
|
+
export declare function resolveMatchSelector(profile: ChannelSelectionProfile): string;
|
|
32
33
|
/**
|
|
33
34
|
* Logs available channel names from a provider's guide grid when channel selection fails. Produces an actionable log message listing channel names that users can
|
|
34
35
|
* use as `channelSelector` values in user-defined channels. When `presetSuffix` is provided, channels already covered by built-in preset definitions are filtered
|
|
@@ -54,7 +55,7 @@ export declare function logAvailableChannels(options: {
|
|
|
54
55
|
* tuneToChannel() after page navigation.
|
|
55
56
|
*
|
|
56
57
|
* The function handles:
|
|
57
|
-
* - Polling for channel
|
|
58
|
+
* - Polling for channel element readiness before strategy dispatch (when profile.channelSelection.matchSelector is set)
|
|
58
59
|
* - Strategy dispatch based on profile.channelSelection.strategy
|
|
59
60
|
* - No-op for single-channel sites (strategy "none" or no channelSelector)
|
|
60
61
|
* - Logging of selection attempts and results
|
|
@@ -12,9 +12,10 @@ import { yttvStrategy } from "./tuning/youtubeTv.js";
|
|
|
12
12
|
/* Multi-channel streaming sites (like USA Network) present multiple channels on a single page, with a program guide for each channel. Users must select which
|
|
13
13
|
* channel they want to watch by clicking on a show in the guide. This module coordinates the dispatch to per-provider strategy functions in the tuning/ directory.
|
|
14
14
|
*
|
|
15
|
-
* Each strategy is a self-contained file under tuning/ that exports a single ChannelStrategyEntry object. The coordinator handles pre-dispatch concerns
|
|
16
|
-
* polling, no-op checks) and post-dispatch logging. Strategy files may import scrollAndClick()
|
|
17
|
-
* import is safe because all cross-module calls happen inside async functions long after module
|
|
15
|
+
* Each strategy is a self-contained file under tuning/ that exports a single ChannelStrategyEntry object. The coordinator handles pre-dispatch concerns
|
|
16
|
+
* (matchSelector-based element polling, no-op checks) and post-dispatch logging. Strategy files may import scrollAndClick(), normalizeChannelName(), and
|
|
17
|
+
* resolveMatchSelector() from this coordinator — the circular import is safe because all cross-module calls happen inside async functions long after module
|
|
18
|
+
* evaluation completes.
|
|
18
19
|
*/
|
|
19
20
|
/* Adding a new channel selection provider:
|
|
20
21
|
*
|
|
@@ -23,16 +24,16 @@ import { yttvStrategy } from "./tuning/youtubeTv.js";
|
|
|
23
24
|
* - execute (required): The strategy function that selects the channel in the provider's guide UI.
|
|
24
25
|
* - clearCache: If your strategy caches state (row positions, URLs), provide a function that clears it.
|
|
25
26
|
* - resolveDirectUrl / invalidateDirectUrl: If your strategy discovers stable watch URLs that can be reused across tunes, provide cache lookup and invalidation.
|
|
26
|
-
* - usesImageSlug: Set to true if channelSelector is an image URL slug requiring load polling before dispatch.
|
|
27
27
|
* 3. Import the entry here and add it to the strategies registry with the strategy name as the key.
|
|
28
28
|
* 4. Add the strategy name to the ChannelSelectionStrategy union type in types/index.ts.
|
|
29
29
|
* 5. Add a site profile entry in config/sites.ts that references the new strategy name.
|
|
30
30
|
*
|
|
31
|
-
* The coordinator handles all cross-cutting concerns (dispatch, cache clearing, direct URL resolution,
|
|
32
|
-
* Strategy files may import scrollAndClick(), normalizeChannelName(), and logAvailableChannels() from this module for shared
|
|
31
|
+
* The coordinator handles all cross-cutting concerns (dispatch, cache clearing, direct URL resolution, matchSelector polling) through the ChannelStrategyEntry
|
|
32
|
+
* interface. Strategy files may import scrollAndClick(), normalizeChannelName(), resolveMatchSelector(), and logAvailableChannels() from this module for shared
|
|
33
|
+
* utilities.
|
|
33
34
|
*/
|
|
34
35
|
// Strategy dispatch registry. Maps strategy names from ChannelSelectionStrategy to their implementation entry. Adding a new provider requires a single entry here
|
|
35
|
-
// — all cross-cutting concerns (cache clearing, direct URL resolution,
|
|
36
|
+
// — all cross-cutting concerns (cache clearing, direct URL resolution, matchSelector polling) are driven by the entry's hooks.
|
|
36
37
|
const strategies = {
|
|
37
38
|
foxGrid: foxStrategy,
|
|
38
39
|
guideGrid: huluStrategy,
|
|
@@ -96,11 +97,22 @@ export async function scrollAndClick(page, target) {
|
|
|
96
97
|
}
|
|
97
98
|
// Normalizes a channel name for case-insensitive, whitespace-tolerant comparison. Trims leading and trailing whitespace, collapses internal whitespace sequences
|
|
98
99
|
// (including non-breaking spaces, tabs, and other Unicode whitespace matched by \s) into a single regular space, and lowercases. This handles data-testid values
|
|
99
|
-
// with trailing spaces
|
|
100
|
+
// with trailing spaces, double spaces, or non-breaking space characters that would otherwise cause exact match failures.
|
|
100
101
|
// Exported for use by tuning strategy files (hulu, sling).
|
|
101
102
|
export function normalizeChannelName(name) {
|
|
102
103
|
return name.trim().replace(/\s+/g, " ").toLowerCase();
|
|
103
104
|
}
|
|
105
|
+
// Resolves the CSS selector for finding a channel element. Interpolates the {channel} placeholder in the profile's matchSelector template with the channelSelector
|
|
106
|
+
// value. When matchSelector is not configured, falls back to image URL matching for backward compatibility.
|
|
107
|
+
// Exported for use by tuning strategy files (tileClick, thumbnailRow).
|
|
108
|
+
export function resolveMatchSelector(profile) {
|
|
109
|
+
const template = profile.channelSelection.matchSelector;
|
|
110
|
+
if (template) {
|
|
111
|
+
return template.replaceAll("{channel}", profile.channelSelector);
|
|
112
|
+
}
|
|
113
|
+
// Default to image URL slug matching for backward compatibility with profiles that don't specify matchSelector.
|
|
114
|
+
return "img[src*=\"" + profile.channelSelector + "\"]";
|
|
115
|
+
}
|
|
104
116
|
/**
|
|
105
117
|
* Logs available channel names from a provider's guide grid when channel selection fails. Produces an actionable log message listing channel names that users can
|
|
106
118
|
* use as `channelSelector` values in user-defined channels. When `presetSuffix` is provided, channels already covered by built-in preset definitions are filtered
|
|
@@ -160,7 +172,7 @@ export function logAvailableChannels(options) {
|
|
|
160
172
|
* tuneToChannel() after page navigation.
|
|
161
173
|
*
|
|
162
174
|
* The function handles:
|
|
163
|
-
* - Polling for channel
|
|
175
|
+
* - Polling for channel element readiness before strategy dispatch (when profile.channelSelection.matchSelector is set)
|
|
164
176
|
* - Strategy dispatch based on profile.channelSelection.strategy
|
|
165
177
|
* - No-op for single-channel sites (strategy "none" or no channelSelector)
|
|
166
178
|
* - Logging of selection attempts and results
|
|
@@ -174,25 +186,37 @@ export async function selectChannel(page, profile) {
|
|
|
174
186
|
if ((channelSelection.strategy === "none") || !isChannelSelectionProfile(profile)) {
|
|
175
187
|
return { success: true };
|
|
176
188
|
}
|
|
177
|
-
// Look up the strategy entry before image polling so we can check entry.usesImageSlug.
|
|
178
189
|
const entry = strategies[channelSelection.strategy];
|
|
179
190
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
180
191
|
if (!entry) {
|
|
181
192
|
LOG.warn("Unknown channel selection strategy: %s.", channelSelection.strategy);
|
|
182
193
|
return { reason: "Unknown channel selection strategy.", success: false };
|
|
183
194
|
}
|
|
184
|
-
// Poll for the channel
|
|
185
|
-
//
|
|
186
|
-
//
|
|
187
|
-
//
|
|
188
|
-
if (
|
|
195
|
+
// Poll for the channel element to appear and become visible. Only run when matchSelector is explicitly configured — the default fallback in
|
|
196
|
+
// resolveMatchSelector() is for strategy-internal use, and guide-based strategies that don't set matchSelector skip this wait entirely. For <img> elements, we
|
|
197
|
+
// also verify load completion (img.complete + naturalWidth) to prevent race conditions where the element exists with the correct src but hasn't finished
|
|
198
|
+
// rendering, which can cause layout instability and click failures.
|
|
199
|
+
if (channelSelection.matchSelector) {
|
|
200
|
+
const selector = resolveMatchSelector(profile);
|
|
189
201
|
try {
|
|
190
|
-
await page.waitForFunction((
|
|
191
|
-
|
|
192
|
-
|
|
202
|
+
await page.waitForFunction((sel) => {
|
|
203
|
+
const el = document.querySelector(sel);
|
|
204
|
+
if (!el) {
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
const rect = el.getBoundingClientRect();
|
|
208
|
+
if (!((rect.width > 0) && (rect.height > 0))) {
|
|
209
|
+
return false;
|
|
210
|
+
}
|
|
211
|
+
// For <img> elements, also verify the image has fully loaded.
|
|
212
|
+
if (el instanceof HTMLImageElement) {
|
|
213
|
+
return el.complete && (el.naturalWidth > 0);
|
|
214
|
+
}
|
|
215
|
+
return true;
|
|
216
|
+
}, { timeout: CONFIG.playback.channelSelectorDelay }, selector);
|
|
193
217
|
}
|
|
194
218
|
catch {
|
|
195
|
-
// Timeout — the
|
|
219
|
+
// Timeout — the element hasn't appeared or loaded yet. Proceed anyway and let the strategy evaluate and report not-found naturally.
|
|
196
220
|
}
|
|
197
221
|
}
|
|
198
222
|
// Dispatch to the appropriate strategy via the registry.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"channelSelection.js","sourceRoot":"","sources":["../../src/browser/channelSelection.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAErD
|
|
1
|
+
{"version":3,"file":"channelSelection.js","sourceRoot":"","sources":["../../src/browser/channelSelection.ts"],"names":[],"mappings":"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"}
|
package/dist/browser/index.d.ts
CHANGED
|
@@ -36,16 +36,11 @@ export declare function registerManagedPage(page: Page): void;
|
|
|
36
36
|
* @param page - The Puppeteer Page to unregister.
|
|
37
37
|
*/
|
|
38
38
|
export declare function unregisterManagedPage(page: Page): void;
|
|
39
|
-
/**
|
|
40
|
-
* Gets the current data directory path. This is where Chrome profile data and extension files are stored.
|
|
41
|
-
* @returns The data directory path.
|
|
42
|
-
*/
|
|
43
|
-
export declare function getDataDir(): string;
|
|
44
39
|
/**
|
|
45
40
|
* Ensures the data directory exists, creating it if necessary. This should be called during application startup before any operations that depend on the data
|
|
46
41
|
* directory (like browser launch or extension preparation).
|
|
47
42
|
*
|
|
48
|
-
* The data directory
|
|
43
|
+
* The data directory stores:
|
|
49
44
|
* - Chrome profile data (cookies, local storage, session state)
|
|
50
45
|
* - Extension files (when running as a packaged executable)
|
|
51
46
|
*/
|
|
@@ -56,12 +51,14 @@ export declare function ensureDataDirectory(): Promise<void>;
|
|
|
56
51
|
* find and terminate any Chrome processes whose command line contains our profile directory path, then polls pgrep to verify the processes have actually exited.
|
|
57
52
|
* After process cleanup, it removes stale lock files (SingletonLock, SingletonCookie, SingletonSocket) and DevToolsActivePort from the profile directory.
|
|
58
53
|
*
|
|
54
|
+
* The termination strategy escalates from SIGTERM to SIGKILL. SIGTERM is sent first, giving Chrome up to 5 seconds to flush its profile databases (LevelDB,
|
|
55
|
+
* extension state, session storage) and exit cleanly. If Chrome does not exit, SIGKILL is sent as a fallback. This escalation is critical when called from the
|
|
56
|
+
* process exit handler — Chrome may be running normally (e.g., after a capture probe timeout), and an immediate SIGKILL would corrupt its profile databases,
|
|
57
|
+
* poisoning the Docker volume for subsequent container restarts.
|
|
58
|
+
*
|
|
59
59
|
* The file cleanup is essential for Docker deployments. Container restarts destroy Chrome processes without giving them a chance to release profile locks, but the
|
|
60
60
|
* lock files persist in the mounted volume. Without removing them, Chrome cannot start in the new container, causing a crash loop.
|
|
61
61
|
*
|
|
62
|
-
* Waiting for exit is critical during service restarts. Without it, the new Chrome can launch while the old one is still releasing its profile lock and
|
|
63
|
-
* tabCapture extension state, causing stale capture errors that cascade into startup failures.
|
|
64
|
-
*
|
|
65
62
|
* This is called at startup before launching the browser and after closeBrowser() during shutdown. It's safe to call even when no stale processes or files exist.
|
|
66
63
|
*/
|
|
67
64
|
export declare function killStaleChrome(): void;
|
|
@@ -123,10 +120,9 @@ export declare function getBrowserPages(): Promise<Page[]>;
|
|
|
123
120
|
* Closes the browser and cleans up resources. This is called during graceful shutdown to ensure Chrome exits cleanly. After this call, the browser reference is
|
|
124
121
|
* cleared and any subsequent stream requests will launch a fresh browser.
|
|
125
122
|
*
|
|
126
|
-
* The function uses a
|
|
127
|
-
* 1. Try browser.close() with a 5-second timeout
|
|
128
|
-
* 2.
|
|
129
|
-
* 3. As a final fallback, use pkill to terminate any Chrome processes using our profile
|
|
123
|
+
* The function uses a two-stage approach to ensure Chrome actually exits:
|
|
124
|
+
* 1. Try browser.close() with a 5-second timeout (DevTools Protocol graceful close)
|
|
125
|
+
* 2. Run killStaleChrome() to catch anything Stage 1 missed, using SIGTERM→SIGKILL escalation to give Chrome a chance to flush its profile databases
|
|
130
126
|
*/
|
|
131
127
|
export declare function closeBrowser(): Promise<void>;
|
|
132
128
|
/**
|