prismcast 1.5.2 → 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/README.md +44 -28
- package/dist/app.d.ts +5 -0
- package/dist/app.js +63 -5
- package/dist/app.js.map +1 -1
- 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 +31 -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 +31 -54
- package/dist/browser/index.js +334 -272
- 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 +15 -3
- 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 +14 -1
- package/dist/browser/tuning/directv.js.map +1 -1
- package/dist/browser/tuning/fox.js +14 -2
- package/dist/browser/tuning/fox.js.map +1 -1
- package/dist/browser/tuning/hbo.js +12 -1
- package/dist/browser/tuning/hbo.js.map +1 -1
- package/dist/browser/tuning/hulu.js +24 -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 +35 -5
- package/dist/browser/tuning/sling.js.map +1 -1
- package/dist/browser/tuning/spectrum.js +13 -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.d.ts +2 -0
- package/dist/browser/tuning/xfinity.js +14 -0
- package/dist/browser/tuning/xfinity.js.map +1 -0
- package/dist/browser/tuning/youtubeTv.js +15 -1
- package/dist/browser/tuning/youtubeTv.js.map +1 -1
- package/dist/browser/video.d.ts +20 -0
- package/dist/browser/video.js +168 -124
- package/dist/browser/video.js.map +1 -1
- package/dist/channels/index.d.ts +2 -2
- package/dist/channels/index.js +2075 -683
- package/dist/channels/index.js.map +1 -1
- package/dist/config/health.d.ts +28 -28
- package/dist/config/health.js +72 -54
- 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/paths.d.ts +12 -0
- package/dist/config/paths.js +16 -0
- package/dist/config/paths.js.map +1 -1
- package/dist/config/profiles.d.ts +3 -2
- package/dist/config/profiles.js +45 -34
- package/dist/config/profiles.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 +19 -5
- package/dist/config/providers.js +123 -93
- package/dist/config/providers.js.map +1 -1
- package/dist/config/sites.d.ts +28 -0
- package/dist/config/sites.js +104 -127
- package/dist/config/sites.js.map +1 -1
- package/dist/config/userChannels.d.ts +53 -2
- package/dist/config/userChannels.js +222 -13
- package/dist/config/userChannels.js.map +1 -1
- package/dist/config/userConfig.d.ts +2 -1
- package/dist/config/userConfig.js +6 -15
- package/dist/config/userConfig.js.map +1 -1
- package/dist/config/userProfiles.d.ts +0 -1
- package/dist/config/userProfiles.js +18 -10
- package/dist/config/userProfiles.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 +25 -22
- package/dist/index.js.map +1 -1
- package/dist/native/decrypt.d.ts +32 -0
- package/dist/native/decrypt.js +85 -0
- package/dist/native/decrypt.js.map +1 -0
- package/dist/native/index.d.ts +61 -0
- package/dist/native/index.js +342 -0
- package/dist/native/index.js.map +1 -0
- package/dist/native/intercept.d.ts +35 -0
- package/dist/native/intercept.js +184 -0
- package/dist/native/intercept.js.map +1 -0
- package/dist/native/probe.d.ts +49 -0
- package/dist/native/probe.js +294 -0
- package/dist/native/probe.js.map +1 -0
- package/dist/native/proxy.d.ts +54 -0
- package/dist/native/proxy.js +947 -0
- package/dist/native/proxy.js.map +1 -0
- 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 +369 -89
- 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 +73 -99
- package/dist/routes/config/providers.js.map +1 -1
- package/dist/routes/debug.js +5 -5
- package/dist/routes/debug.js.map +1 -1
- package/dist/routes/hls.js +12 -2
- package/dist/routes/hls.js.map +1 -1
- package/dist/routes/index.d.ts +0 -15
- package/dist/routes/index.js +2 -16
- 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 +124 -47
- 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 +49 -33
- package/dist/routes/root/scripts/status.js.map +1 -1
- package/dist/routes/root/styles.js +117 -10
- 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 +5 -0
- package/dist/streaming/fmp4Segmenter.js +146 -42
- package/dist/streaming/fmp4Segmenter.js.map +1 -1
- package/dist/streaming/hls.d.ts +24 -19
- package/dist/streaming/hls.js +603 -297
- package/dist/streaming/hls.js.map +1 -1
- package/dist/streaming/hlsResume.d.ts +16 -3
- package/dist/streaming/hlsResume.js +35 -8
- package/dist/streaming/hlsResume.js.map +1 -1
- package/dist/streaming/hlsSegments.d.ts +41 -2
- package/dist/streaming/hlsSegments.js +131 -28
- package/dist/streaming/hlsSegments.js.map +1 -1
- package/dist/streaming/lifecycle.js +27 -13
- package/dist/streaming/lifecycle.js.map +1 -1
- package/dist/streaming/monitor.d.ts +1 -0
- package/dist/streaming/monitor.js +862 -474
- package/dist/streaming/monitor.js.map +1 -1
- package/dist/streaming/mp4Parser.d.ts +52 -6
- package/dist/streaming/mp4Parser.js +156 -30
- package/dist/streaming/mp4Parser.js.map +1 -1
- package/dist/streaming/mpegts.d.ts +2 -2
- package/dist/streaming/mpegts.js +156 -109
- package/dist/streaming/mpegts.js.map +1 -1
- package/dist/streaming/playlistBuilder.d.ts +38 -0
- package/dist/streaming/playlistBuilder.js +66 -0
- package/dist/streaming/playlistBuilder.js.map +1 -0
- package/dist/streaming/preroll.d.ts +126 -0
- package/dist/streaming/preroll.js +434 -0
- package/dist/streaming/preroll.js.map +1 -0
- package/dist/streaming/pretune.d.ts +8 -0
- package/dist/streaming/pretune.js +226 -0
- package/dist/streaming/pretune.js.map +1 -0
- 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 +57 -9
- package/dist/streaming/registry.js +26 -7
- package/dist/streaming/registry.js.map +1 -1
- package/dist/streaming/setup.d.ts +8 -1
- package/dist/streaming/setup.js +71 -27
- package/dist/streaming/setup.js.map +1 -1
- package/dist/streaming/showInfo.d.ts +29 -4
- package/dist/streaming/showInfo.js +210 -38
- package/dist/streaming/showInfo.js.map +1 -1
- package/dist/streaming/statusEmitter.d.ts +20 -6
- package/dist/streaming/statusEmitter.js +31 -7
- package/dist/streaming/statusEmitter.js.map +1 -1
- package/dist/types/channels.d.ts +32 -0
- package/dist/types/config.d.ts +2 -2
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.js.map +1 -1
- package/dist/types/profiles.d.ts +13 -1
- package/dist/types/selection.d.ts +5 -1
- package/dist/types/shared.d.ts +1 -1
- package/dist/types/streaming.d.ts +7 -0
- package/dist/utils/chromeFetch.d.ts +20 -0
- package/dist/utils/chromeFetch.js +43 -0
- package/dist/utils/chromeFetch.js.map +1 -0
- package/dist/utils/debugFilter.d.ts +0 -5
- package/dist/utils/debugFilter.js +20 -11
- package/dist/utils/debugFilter.js.map +1 -1
- package/dist/utils/delay.d.ts +28 -0
- package/dist/utils/delay.js +35 -1
- 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 +14 -12
- package/dist/utils/ffmpeg.js +114 -134
- 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 +3 -0
- package/dist/utils/index.js +3 -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/pid.d.ts +40 -0
- package/dist/utils/pid.js +83 -0
- package/dist/utils/pid.js.map +1 -0
- 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 +7 -7
package/dist/config/health.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/* Copyright(C) 2024-2026, HJD (https://github.com/hjdhjd). All rights reserved.
|
|
2
2
|
*
|
|
3
|
-
* health.ts: Channel health and
|
|
3
|
+
* health.ts: Channel health and domain authentication state persistence for PrismCast.
|
|
4
4
|
*/
|
|
5
|
-
import { EventEmitter } from "events";
|
|
5
|
+
import { EventEmitter } from "node:events";
|
|
6
6
|
import { LOG } from "../utils/index.js";
|
|
7
7
|
import fs from "node:fs";
|
|
8
8
|
import { getHealthFilePath } from "./paths.js";
|
|
@@ -17,8 +17,8 @@ const HEALTH_TTL = 7 * 24 * 60 * 60 * 1000;
|
|
|
17
17
|
const FLUSH_DELAY = 2000;
|
|
18
18
|
// In-memory state.
|
|
19
19
|
const channelHealth = new Map();
|
|
20
|
-
//
|
|
21
|
-
const
|
|
20
|
+
// Domain auth is proven by success only. The presence of a non-expired timestamp means the user has successfully tuned at least one channel on the domain.
|
|
21
|
+
const domainAuth = new Map();
|
|
22
22
|
// Debounce timer for flushHealthState().
|
|
23
23
|
let flushTimer = null;
|
|
24
24
|
// Persistence.
|
|
@@ -31,7 +31,7 @@ export async function loadHealthState() {
|
|
|
31
31
|
const state = JSON.parse(content);
|
|
32
32
|
const now = Date.now();
|
|
33
33
|
channelHealth.clear();
|
|
34
|
-
|
|
34
|
+
domainAuth.clear();
|
|
35
35
|
// Load channel health entries, pruning stale ones. Runtime guard needed because the file may contain incomplete JSON.
|
|
36
36
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
37
37
|
if (state.channels) {
|
|
@@ -41,19 +41,19 @@ export async function loadHealthState() {
|
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
|
-
// Load
|
|
44
|
+
// Load domain auth entries (timestamps), pruning stale ones. Runtime guard needed because the file may contain incomplete JSON.
|
|
45
45
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
46
|
-
if (state.
|
|
47
|
-
for (const [key, timestamp] of Object.entries(state.
|
|
46
|
+
if (state.domains) {
|
|
47
|
+
for (const [key, timestamp] of Object.entries(state.domains)) {
|
|
48
48
|
if ((now - timestamp) < HEALTH_TTL) {
|
|
49
|
-
|
|
49
|
+
domainAuth.set(key, timestamp);
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
const channelCount = channelHealth.size;
|
|
54
|
-
const
|
|
55
|
-
if ((channelCount > 0) || (
|
|
56
|
-
LOG.info("Loaded health state: %d channel(s), %d
|
|
54
|
+
const domainCount = domainAuth.size;
|
|
55
|
+
if ((channelCount > 0) || (domainCount > 0)) {
|
|
56
|
+
LOG.info("Loaded health state: %d channel(s), %d domain(s).", channelCount, domainCount);
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
catch (error) {
|
|
@@ -64,78 +64,96 @@ export async function loadHealthState() {
|
|
|
64
64
|
LOG.warn("Failed to load health state: %s. Starting with empty health data.", (error instanceof Error) ? error.message : String(error));
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
|
+
// Whether a write is currently in progress. When true, the debounce timer defers instead of starting a concurrent write. After the write completes, if a flush was
|
|
68
|
+
// requested during the write, a new write is triggered immediately to capture the latest state.
|
|
69
|
+
let writeInProgress = false;
|
|
70
|
+
let flushPendingDuringWrite = false;
|
|
67
71
|
/**
|
|
68
|
-
* Writes the current in-memory health state to health.json. Debounced — multiple calls within FLUSH_DELAY are coalesced into a single write.
|
|
72
|
+
* Writes the current in-memory health state to health.json. Debounced — multiple calls within FLUSH_DELAY are coalesced into a single write. If a write is already
|
|
73
|
+
* in progress, the flush is deferred until the current write completes, then re-triggered to capture any state changes that occurred during the write.
|
|
69
74
|
*/
|
|
70
75
|
function flushHealthState() {
|
|
71
76
|
if (flushTimer) {
|
|
72
77
|
clearTimeout(flushTimer);
|
|
73
78
|
}
|
|
79
|
+
// If a write is in progress, mark that a flush was requested so it re-triggers after the write completes. This prevents overlapping writes to the same file.
|
|
80
|
+
if (writeInProgress) {
|
|
81
|
+
flushPendingDuringWrite = true;
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
74
84
|
flushTimer = setTimeout(() => {
|
|
75
85
|
flushTimer = null;
|
|
86
|
+
writeInProgress = true;
|
|
76
87
|
const state = {
|
|
77
88
|
channels: Object.fromEntries(channelHealth),
|
|
78
|
-
|
|
89
|
+
domains: Object.fromEntries(domainAuth)
|
|
79
90
|
};
|
|
80
91
|
// Sort keys for consistent output.
|
|
81
92
|
const sortedState = {
|
|
82
93
|
channels: Object.fromEntries(Object.entries(state.channels).sort(([a], [b]) => a.localeCompare(b))),
|
|
83
|
-
|
|
94
|
+
domains: Object.fromEntries(Object.entries(state.domains).sort(([a], [b]) => a.localeCompare(b)))
|
|
84
95
|
};
|
|
85
96
|
fsPromises.writeFile(getHealthFilePath(), JSON.stringify(sortedState, null, 2) + "\n", "utf-8").catch((error) => {
|
|
86
97
|
LOG.warn("Failed to write health state: %s.", (error instanceof Error) ? error.message : String(error));
|
|
98
|
+
}).finally(() => {
|
|
99
|
+
writeInProgress = false;
|
|
100
|
+
// If a flush was requested while the write was in progress, trigger it now to capture the latest state.
|
|
101
|
+
if (flushPendingDuringWrite) {
|
|
102
|
+
flushPendingDuringWrite = false;
|
|
103
|
+
flushHealthState();
|
|
104
|
+
}
|
|
87
105
|
});
|
|
88
106
|
}, FLUSH_DELAY);
|
|
89
107
|
}
|
|
90
108
|
// Public API.
|
|
91
109
|
/**
|
|
92
|
-
* Records a successful tune for a channel. Sets the channel's health to "success" and optionally marks the
|
|
93
|
-
*
|
|
94
|
-
*
|
|
110
|
+
* Records a successful tune for a channel. Sets the channel's health to "success" and optionally marks the domain as verified (authenticated). Triggers a debounced
|
|
111
|
+
* flush. The markAuth parameter allows callers to skip domain auth marking when a successful tune does not prove paid access (e.g., Sling Freestream channels succeed
|
|
112
|
+
* without a subscription).
|
|
95
113
|
* @param channelKey - The channel key (canonical key, e.g., "nbc").
|
|
96
|
-
* @param
|
|
97
|
-
* @param markAuth - Whether to also mark the
|
|
114
|
+
* @param domain - The auth domain for the currently selected provider variant.
|
|
115
|
+
* @param markAuth - Whether to also mark the domain as authenticated (default: true).
|
|
98
116
|
*/
|
|
99
|
-
export function markChannelSuccess(channelKey,
|
|
117
|
+
export function markChannelSuccess(channelKey, domain, markAuth = true) {
|
|
100
118
|
const now = Date.now();
|
|
101
|
-
channelHealth.set(channelKey, {
|
|
119
|
+
channelHealth.set(channelKey, { domain, status: "success", timestamp: now });
|
|
102
120
|
if (markAuth) {
|
|
103
|
-
|
|
121
|
+
domainAuth.set(domain, now);
|
|
104
122
|
}
|
|
105
123
|
flushHealthState();
|
|
106
|
-
healthEmitter.emit("healthChanged", { channelKey,
|
|
124
|
+
healthEmitter.emit("healthChanged", { channelKey, domain, status: "success", timestamp: now });
|
|
107
125
|
}
|
|
108
126
|
/**
|
|
109
|
-
* Records a
|
|
110
|
-
*
|
|
111
|
-
* @param
|
|
127
|
+
* Records a domain as authenticated without a specific channel context. Used when a domain action (e.g., precaching) proves the domain is accessible and logged in,
|
|
128
|
+
* even though no channel was tuned. Triggers a debounced flush and emits a health event with an empty channelKey.
|
|
129
|
+
* @param domain - The domain to mark as authenticated.
|
|
112
130
|
*/
|
|
113
|
-
export function
|
|
131
|
+
export function markDomainAuth(domain) {
|
|
114
132
|
const now = Date.now();
|
|
115
|
-
|
|
133
|
+
domainAuth.set(domain, now);
|
|
116
134
|
flushHealthState();
|
|
117
|
-
healthEmitter.emit("healthChanged", { channelKey: "",
|
|
135
|
+
healthEmitter.emit("healthChanged", { channelKey: "", domain, status: "success", timestamp: now });
|
|
118
136
|
}
|
|
119
137
|
/**
|
|
120
|
-
* Records a failed tune for a channel. Sets the channel's health to "failed". Does not affect
|
|
121
|
-
*
|
|
138
|
+
* Records a failed tune for a channel. Sets the channel's health to "failed". Does not affect domain auth — a single channel failure doesn't prove the domain is
|
|
139
|
+
* unauthenticated. Triggers a debounced flush.
|
|
122
140
|
* @param channelKey - The channel key (canonical key, e.g., "nbc").
|
|
123
|
-
* @param
|
|
141
|
+
* @param domain - The auth domain for the currently selected provider variant.
|
|
124
142
|
*/
|
|
125
|
-
export function markChannelFailure(channelKey,
|
|
143
|
+
export function markChannelFailure(channelKey, domain) {
|
|
126
144
|
const now = Date.now();
|
|
127
|
-
channelHealth.set(channelKey, {
|
|
145
|
+
channelHealth.set(channelKey, { domain, status: "failed", timestamp: now });
|
|
128
146
|
flushHealthState();
|
|
129
|
-
healthEmitter.emit("healthChanged", { channelKey,
|
|
147
|
+
healthEmitter.emit("healthChanged", { channelKey, domain, status: "failed", timestamp: now });
|
|
130
148
|
}
|
|
131
149
|
/**
|
|
132
|
-
* Returns the health status and timestamp for a channel. Returns null if no entry exists, the entry is stale (older than 7 days), or the stored
|
|
133
|
-
*
|
|
150
|
+
* Returns the health status and timestamp for a channel. Returns null if no entry exists, the entry is stale (older than 7 days), or the stored domain doesn't match
|
|
151
|
+
* the current one (domain changed).
|
|
134
152
|
* @param channelKey - The channel key (canonical key, e.g., "nbc").
|
|
135
|
-
* @param
|
|
153
|
+
* @param domain - The auth domain for the currently selected provider variant.
|
|
136
154
|
* @returns Object with status and timestamp, or null if unknown.
|
|
137
155
|
*/
|
|
138
|
-
export function getChannelHealth(channelKey,
|
|
156
|
+
export function getChannelHealth(channelKey, domain) {
|
|
139
157
|
const entry = channelHealth.get(channelKey);
|
|
140
158
|
if (!entry) {
|
|
141
159
|
return null;
|
|
@@ -144,20 +162,20 @@ export function getChannelHealth(channelKey, providerTag) {
|
|
|
144
162
|
if ((Date.now() - entry.timestamp) >= HEALTH_TTL) {
|
|
145
163
|
return null;
|
|
146
164
|
}
|
|
147
|
-
//
|
|
148
|
-
if (entry.
|
|
165
|
+
// Domain was switched — the stored result is for a different domain.
|
|
166
|
+
if (entry.domain !== domain) {
|
|
149
167
|
return null;
|
|
150
168
|
}
|
|
151
169
|
return { status: entry.status, timestamp: entry.timestamp };
|
|
152
170
|
}
|
|
153
171
|
/**
|
|
154
|
-
* Returns the timestamp when a
|
|
155
|
-
*
|
|
156
|
-
* @param
|
|
172
|
+
* Returns the timestamp when a domain was last verified as authenticated, or null if unknown. Verification is proven by at least one successful tune within the TTL
|
|
173
|
+
* window. A non-null return means the domain is verified; the value is the Unix millisecond timestamp of the most recent successful tune.
|
|
174
|
+
* @param domain - The domain to check.
|
|
157
175
|
* @returns Timestamp of last verification, or null if unknown (no entry or stale).
|
|
158
176
|
*/
|
|
159
|
-
export function
|
|
160
|
-
const timestamp =
|
|
177
|
+
export function getDomainAuth(domain) {
|
|
178
|
+
const timestamp = domainAuth.get(domain);
|
|
161
179
|
if (timestamp === undefined) {
|
|
162
180
|
return null;
|
|
163
181
|
}
|
|
@@ -169,27 +187,27 @@ export function getProviderAuth(providerTag) {
|
|
|
169
187
|
}
|
|
170
188
|
/**
|
|
171
189
|
* Returns a snapshot of current health state for SSE initial payloads. Stale entries (older than HEALTH_TTL) are excluded.
|
|
172
|
-
* @returns Snapshot with channel health and
|
|
190
|
+
* @returns Snapshot with channel health and domain auth maps.
|
|
173
191
|
*/
|
|
174
192
|
export function getHealthSnapshot() {
|
|
175
193
|
const now = Date.now();
|
|
176
194
|
const channels = {};
|
|
177
|
-
const
|
|
195
|
+
const domains = {};
|
|
178
196
|
for (const [key, entry] of channelHealth) {
|
|
179
197
|
if ((now - entry.timestamp) < HEALTH_TTL) {
|
|
180
|
-
channels[key] = {
|
|
198
|
+
channels[key] = { domain: entry.domain, status: entry.status, timestamp: entry.timestamp };
|
|
181
199
|
}
|
|
182
200
|
}
|
|
183
|
-
for (const [
|
|
201
|
+
for (const [domainKey, timestamp] of domainAuth) {
|
|
184
202
|
if ((now - timestamp) < HEALTH_TTL) {
|
|
185
|
-
|
|
203
|
+
domains[domainKey] = timestamp;
|
|
186
204
|
}
|
|
187
205
|
}
|
|
188
|
-
return { channels,
|
|
206
|
+
return { channels, domains };
|
|
189
207
|
}
|
|
190
208
|
/**
|
|
191
209
|
* Subscribes a callback to receive health change events. Returns an unsubscribe function. Follows the same pattern as subscribeToStatus in statusEmitter.ts.
|
|
192
|
-
* @param callback - Function to call when channel health or
|
|
210
|
+
* @param callback - Function to call when channel health or domain auth changes.
|
|
193
211
|
* @returns A function to unsubscribe the callback.
|
|
194
212
|
*/
|
|
195
213
|
export function subscribeToHealth(callback) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"health.js","sourceRoot":"","sources":["../../src/config/health.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"health.js","sourceRoot":"","sources":["../../src/config/health.ts"],"names":[],"mappings":"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"}
|
package/dist/config/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import { formatPresetStatus, getEffectivePreset, getValidPresetIds } from "./pre
|
|
|
4
4
|
import { getChromeDataDir, getConfigFilePath } from "./paths.js";
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
// The CONFIG object is initialized during startup. It starts as a copy of DEFAULTS and is replaced by the merged configuration.
|
|
7
|
-
export let CONFIG =
|
|
7
|
+
export let CONFIG = structuredClone(DEFAULTS);
|
|
8
8
|
/**
|
|
9
9
|
* Indicates whether a user config file parse error occurred during initialization. The web UI displays a warning when this is true.
|
|
10
10
|
*/
|
|
@@ -46,7 +46,7 @@ export async function initializeConfiguration(cliOverrides) {
|
|
|
46
46
|
* @returns A copy of the default configuration.
|
|
47
47
|
*/
|
|
48
48
|
export function getDefaults() {
|
|
49
|
-
return
|
|
49
|
+
return structuredClone(DEFAULTS);
|
|
50
50
|
}
|
|
51
51
|
/* Before starting the server, we validate all configuration values to catch errors early. Invalid configurations like negative timeouts or out-of-range bitrates
|
|
52
52
|
* would cause subtle runtime failures that are difficult to diagnose. By validating upfront, we provide clear error messages and prevent the server from starting
|
|
@@ -108,64 +108,32 @@ export function validatePositiveNumber(name, value, min, max) {
|
|
|
108
108
|
* @throws If any configuration value is invalid. The error message lists all invalid values.
|
|
109
109
|
*/
|
|
110
110
|
export function validateConfiguration() {
|
|
111
|
+
// Collect all validation errors before throwing so the operator sees every problem at once. The check helper pushes non-null results into the errors array,
|
|
112
|
+
// reducing each validation to a single line.
|
|
111
113
|
const errors = [];
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
//
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
//
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
}
|
|
136
|
-
// Validate concurrent stream limit. At least 1 stream must be allowed. Maximum of 100 prevents resource exhaustion on most systems.
|
|
137
|
-
const concurrentError = validatePositiveInt("MAX_CONCURRENT_STREAMS", CONFIG.streaming.maxConcurrentStreams, 1, 100);
|
|
138
|
-
if (concurrentError) {
|
|
139
|
-
errors.push(concurrentError);
|
|
140
|
-
}
|
|
141
|
-
// Validate circuit breaker. At least 1 failure required to trip. Maximum of 100 prevents the breaker from never tripping.
|
|
142
|
-
const circuitBreakerError = validatePositiveInt("CIRCUIT_BREAKER_THRESHOLD", CONFIG.recovery.circuitBreakerThreshold, 1, 100);
|
|
143
|
-
if (circuitBreakerError) {
|
|
144
|
-
errors.push(circuitBreakerError);
|
|
145
|
-
}
|
|
146
|
-
// Validate stall threshold (float).
|
|
147
|
-
const stallThresholdError = validatePositiveNumber("STALL_THRESHOLD", CONFIG.playback.stallThreshold, 0.01, 5);
|
|
148
|
-
if (stallThresholdError) {
|
|
149
|
-
errors.push(stallThresholdError);
|
|
150
|
-
}
|
|
151
|
-
// Validate logging configuration. Minimum size (10KB) ensures meaningful log content. Maximum (100MB) prevents excessive disk usage.
|
|
152
|
-
const logMaxSizeError = validatePositiveInt("LOG_MAX_SIZE", CONFIG.logging.maxSize, 10240, 104857600);
|
|
153
|
-
if (logMaxSizeError) {
|
|
154
|
-
errors.push(logMaxSizeError);
|
|
155
|
-
}
|
|
156
|
-
// Validate HLS configuration. Segment duration and max segments have sensible ranges.
|
|
157
|
-
const hlsSegmentDurationError = validatePositiveInt("HLS_SEGMENT_DURATION", CONFIG.hls.segmentDuration, 1, 10);
|
|
158
|
-
if (hlsSegmentDurationError) {
|
|
159
|
-
errors.push(hlsSegmentDurationError);
|
|
160
|
-
}
|
|
161
|
-
const hlsMaxSegmentsError = validatePositiveInt("HLS_MAX_SEGMENTS", CONFIG.hls.maxSegments, 3, 60);
|
|
162
|
-
if (hlsMaxSegmentsError) {
|
|
163
|
-
errors.push(hlsMaxSegmentsError);
|
|
164
|
-
}
|
|
165
|
-
const hlsIdleTimeoutError = validatePositiveInt("HLS_IDLE_TIMEOUT", CONFIG.hls.idleTimeout, 10000, 300000);
|
|
166
|
-
if (hlsIdleTimeoutError) {
|
|
167
|
-
errors.push(hlsIdleTimeoutError);
|
|
168
|
-
}
|
|
114
|
+
const check = (result) => { if (result) {
|
|
115
|
+
errors.push(result);
|
|
116
|
+
} };
|
|
117
|
+
// Server configuration.
|
|
118
|
+
check(validatePositiveInt("PORT", CONFIG.server.port, 1, 65535));
|
|
119
|
+
// Streaming bitrates. Video: 100kbps-50Mbps. Audio: 32-512kbps.
|
|
120
|
+
check(validatePositiveInt("VIDEO_BITRATE", CONFIG.streaming.videoBitsPerSecond, 100000, 50000000));
|
|
121
|
+
check(validatePositiveInt("AUDIO_BITRATE", CONFIG.streaming.audioBitsPerSecond, 32000, 512000));
|
|
122
|
+
// Timeouts. 1 second minimum prevents premature failures. 10 minutes maximum prevents indefinite hangs.
|
|
123
|
+
check(validatePositiveInt("NAV_TIMEOUT", CONFIG.streaming.navigationTimeout, 1000, 600000));
|
|
124
|
+
check(validatePositiveInt("VIDEO_TIMEOUT", CONFIG.streaming.videoTimeout, 1000, 600000));
|
|
125
|
+
// Concurrent stream limit.
|
|
126
|
+
check(validatePositiveInt("MAX_CONCURRENT_STREAMS", CONFIG.streaming.maxConcurrentStreams, 1, 100));
|
|
127
|
+
// Circuit breaker threshold.
|
|
128
|
+
check(validatePositiveInt("CIRCUIT_BREAKER_THRESHOLD", CONFIG.recovery.circuitBreakerThreshold, 1, 100));
|
|
129
|
+
// Stall threshold (float).
|
|
130
|
+
check(validatePositiveNumber("STALL_THRESHOLD", CONFIG.playback.stallThreshold, 0.01, 5));
|
|
131
|
+
// Logging. 10KB minimum ensures meaningful content. 100MB maximum prevents excessive disk usage.
|
|
132
|
+
check(validatePositiveInt("LOG_MAX_SIZE", CONFIG.logging.maxSize, 10240, 104857600));
|
|
133
|
+
// HLS configuration.
|
|
134
|
+
check(validatePositiveInt("HLS_SEGMENT_DURATION", CONFIG.hls.segmentDuration, 1, 10));
|
|
135
|
+
check(validatePositiveInt("HLS_MAX_SEGMENTS", CONFIG.hls.maxSegments, 3, 60));
|
|
136
|
+
check(validatePositiveInt("HLS_IDLE_TIMEOUT", CONFIG.hls.idleTimeout, 10000, 300000));
|
|
169
137
|
// Force FFmpeg capture mode. Chrome's native fMP4 MediaRecorder produces corrupt output after 20-30 minutes of continuous recording. Until a future Chrome
|
|
170
138
|
// release resolves this, native capture mode is disabled entirely.
|
|
171
139
|
if (CONFIG.streaming.captureMode !== "ffmpeg") {
|
|
@@ -182,16 +150,13 @@ export function validateConfiguration() {
|
|
|
182
150
|
// Validate HDHomeRun configuration when enabled.
|
|
183
151
|
if (CONFIG.hdhr.enabled) {
|
|
184
152
|
// HDHR requires FFmpeg for MPEG-TS remuxing. In native mode, FFmpeg is not guaranteed to be available. Disable HDHR and warn the operator. The string cast
|
|
185
|
-
// suppresses TS2367 because captureMode is currently forced to "ffmpeg" above
|
|
153
|
+
// suppresses TS2367 because captureMode is currently forced to "ffmpeg" above - this guard will become reachable again when native mode is re-enabled.
|
|
186
154
|
if (CONFIG.streaming.captureMode === "native") {
|
|
187
155
|
CONFIG.hdhr.enabled = false;
|
|
188
156
|
LOG.warn("HDHomeRun emulation requires FFmpeg mode. Disabling HDHR because capture mode is set to native.");
|
|
189
157
|
}
|
|
190
158
|
else {
|
|
191
|
-
|
|
192
|
-
if (hdhrPortError) {
|
|
193
|
-
errors.push(hdhrPortError);
|
|
194
|
-
}
|
|
159
|
+
check(validatePositiveInt("HDHR_PORT", CONFIG.hdhr.port, 1, 65535));
|
|
195
160
|
// Warn if HDHR port conflicts with the main server port (same host).
|
|
196
161
|
if ((CONFIG.hdhr.port === CONFIG.server.port) && ((CONFIG.server.host === "0.0.0.0") || (CONFIG.server.host === "::"))) {
|
|
197
162
|
errors.push("HDHR_PORT (" + String(CONFIG.hdhr.port) + ") conflicts with the main server port.");
|
package/dist/config/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC/E,OAAO,EAAE,GAAG,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAClH,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACzF,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACjE,OAAO,IAAI,MAAM,WAAW,CAAC;AA+B7B,gIAAgI;AAChI,MAAM,CAAC,IAAI,MAAM,GAAW,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"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"}
|
package/dist/config/paths.d.ts
CHANGED
|
@@ -35,6 +35,18 @@ export declare function getProfilesFilePath(): string;
|
|
|
35
35
|
* @returns The absolute path to hls-resume.json inside the data directory.
|
|
36
36
|
*/
|
|
37
37
|
export declare function getResumeFilePath(): string;
|
|
38
|
+
/**
|
|
39
|
+
* Returns the path to the Chrome PID file. Used for cross-platform process cleanup — the PID file survives crashes and allows the next startup to find and
|
|
40
|
+
* terminate orphaned Chrome processes without relying on Unix-only tools like pkill/pgrep.
|
|
41
|
+
* @returns The absolute path to chrome.pid inside the data directory.
|
|
42
|
+
*/
|
|
43
|
+
export declare function getChromePidFilePath(): string;
|
|
44
|
+
/**
|
|
45
|
+
* Returns the path to the server PID file. Used to detect duplicate PrismCast instances — the PID file is written immediately after the instance check passes and
|
|
46
|
+
* checked at the start of the next launch to prevent two instances from running simultaneously.
|
|
47
|
+
* @returns The absolute path to prismcast.pid inside the data directory.
|
|
48
|
+
*/
|
|
49
|
+
export declare function getServerPidFilePath(): string;
|
|
38
50
|
/**
|
|
39
51
|
* Returns the Chrome user data directory. When config.paths.chromeDataDir is set, that absolute path is used directly. Otherwise, the directory is built from the
|
|
40
52
|
* data directory and the configured profile name.
|
package/dist/config/paths.js
CHANGED
|
@@ -81,6 +81,22 @@ export function getProfilesFilePath() {
|
|
|
81
81
|
export function getResumeFilePath() {
|
|
82
82
|
return path.join(getDataDir(), "hls-resume.json");
|
|
83
83
|
}
|
|
84
|
+
/**
|
|
85
|
+
* Returns the path to the Chrome PID file. Used for cross-platform process cleanup — the PID file survives crashes and allows the next startup to find and
|
|
86
|
+
* terminate orphaned Chrome processes without relying on Unix-only tools like pkill/pgrep.
|
|
87
|
+
* @returns The absolute path to chrome.pid inside the data directory.
|
|
88
|
+
*/
|
|
89
|
+
export function getChromePidFilePath() {
|
|
90
|
+
return path.join(getDataDir(), "chrome.pid");
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Returns the path to the server PID file. Used to detect duplicate PrismCast instances — the PID file is written immediately after the instance check passes and
|
|
94
|
+
* checked at the start of the next launch to prevent two instances from running simultaneously.
|
|
95
|
+
* @returns The absolute path to prismcast.pid inside the data directory.
|
|
96
|
+
*/
|
|
97
|
+
export function getServerPidFilePath() {
|
|
98
|
+
return path.join(getDataDir(), "prismcast.pid");
|
|
99
|
+
}
|
|
84
100
|
/**
|
|
85
101
|
* Returns the Chrome user data directory. When config.paths.chromeDataDir is set, that absolute path is used directly. Otherwise, the directory is built from the
|
|
86
102
|
* data directory and the configured profile name.
|
package/dist/config/paths.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/config/paths.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B;;;;;;;;;;GAUG;AAEH,mGAAmG;AACnG,IAAI,eAAmC,CAAC;AAExC;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,UAAmB;IAEnD,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;IAElD,IAAG,UAAU,EAAE,CAAC;QAEd,sEAAsE;QACtE,eAAe,GAAG,UAAU,CAAC;IAC/B,CAAC;SAAM,IAAG,UAAU,EAAE,CAAC;QAErB,IAAG,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAEhC,sCAAsC;YACtC,OAAO,CAAC,KAAK,CAAC,2DAA2D,GAAG,UAAU,CAAC,CAAC;YAExF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,eAAe,GAAG,UAAU,CAAC;IAC/B,CAAC;SAAM,CAAC;QAEN,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,YAAY,CAAC,CAAC;IAC1D,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU;IAExB,IAAG,CAAC,eAAe,EAAE,CAAC;QAEpB,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;IACrF,CAAC;IAED,OAAO,eAAe,CAAC;AACzB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB;IAE/B,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,aAAa,CAAC,CAAC;AAChD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB;IAEjC,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,eAAe,CAAC,CAAC;AAClD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB;IAE/B,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,aAAa,CAAC,CAAC;AAChD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB;IAEjC,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,eAAe,CAAC,CAAC;AAClD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB;IAE/B,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,iBAAiB,CAAC,CAAC;AACpD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAc;IAE7C,OAAO,MAAM,CAAC,KAAK,CAAC,aAAa,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;AAC/F,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,MAAc;IAE5C,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;AAChE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,MAAc;IAE3C,OAAO,MAAM,CAAC,KAAK,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,eAAe,CAAC,CAAC;AAC1E,CAAC"}
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/config/paths.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B;;;;;;;;;;GAUG;AAEH,mGAAmG;AACnG,IAAI,eAAmC,CAAC;AAExC;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,UAAmB;IAEnD,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;IAElD,IAAG,UAAU,EAAE,CAAC;QAEd,sEAAsE;QACtE,eAAe,GAAG,UAAU,CAAC;IAC/B,CAAC;SAAM,IAAG,UAAU,EAAE,CAAC;QAErB,IAAG,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAEhC,sCAAsC;YACtC,OAAO,CAAC,KAAK,CAAC,2DAA2D,GAAG,UAAU,CAAC,CAAC;YAExF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,eAAe,GAAG,UAAU,CAAC;IAC/B,CAAC;SAAM,CAAC;QAEN,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,YAAY,CAAC,CAAC;IAC1D,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU;IAExB,IAAG,CAAC,eAAe,EAAE,CAAC;QAEpB,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;IACrF,CAAC;IAED,OAAO,eAAe,CAAC;AACzB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB;IAE/B,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,aAAa,CAAC,CAAC;AAChD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB;IAEjC,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,eAAe,CAAC,CAAC;AAClD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB;IAE/B,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,aAAa,CAAC,CAAC;AAChD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB;IAEjC,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,eAAe,CAAC,CAAC;AAClD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB;IAE/B,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,iBAAiB,CAAC,CAAC;AACpD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,oBAAoB;IAElC,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,YAAY,CAAC,CAAC;AAC/C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,oBAAoB;IAElC,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,eAAe,CAAC,CAAC;AAClD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAc;IAE7C,OAAO,MAAM,CAAC,KAAK,CAAC,aAAa,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;AAC/F,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,MAAc;IAE5C,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;AAChE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,MAAc;IAE3C,OAAO,MAAM,CAAC,KAAK,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,eAAe,CAAC,CAAC;AAC1E,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { DEFAULT_SITE_PROFILE, DOMAIN_CONFIG, SITE_PROFILES, getDomainConfig } from "./sites.js";
|
|
1
|
+
import { DEFAULT_SITE_PROFILE, DOMAIN_CONFIG, PROVIDER_PROFILES, SITE_PROFILES, getBuiltinProfile, getDomainConfig } from "./sites.js";
|
|
2
2
|
import type { ProfileCategory, ProfileResolutionResult, ResolvedSiteProfile } from "../types/index.js";
|
|
3
|
-
export { DEFAULT_SITE_PROFILE, DOMAIN_CONFIG, SITE_PROFILES, getDomainConfig };
|
|
3
|
+
export { DEFAULT_SITE_PROFILE, DOMAIN_CONFIG, PROVIDER_PROFILES, SITE_PROFILES, getBuiltinProfile, getDomainConfig };
|
|
4
4
|
/**
|
|
5
5
|
* Resolves a named profile from SITE_PROFILES, handling inheritance and merging with the default profile to ensure all required properties are present. Inheritance
|
|
6
6
|
* is resolved recursively, with child profile properties overriding parent properties.
|
|
@@ -43,6 +43,7 @@ export declare function getProfileForUrl(url: string | undefined): ProfileResolu
|
|
|
43
43
|
*/
|
|
44
44
|
export declare function getProfileForChannel(channel: {
|
|
45
45
|
channelSelector?: string;
|
|
46
|
+
dismissSelector?: string;
|
|
46
47
|
profile?: string;
|
|
47
48
|
scrollSelector?: string;
|
|
48
49
|
scrollTarget?: string;
|