prismcast 1.10.2 → 1.10.3
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 +5 -3
- package/dist/app.js +42 -41
- package/dist/app.js.map +1 -1
- package/dist/browser/hlsPlaylistObserver.d.ts +38 -0
- package/dist/browser/hlsPlaylistObserver.js +113 -0
- package/dist/browser/hlsPlaylistObserver.js.map +1 -0
- package/dist/browser/index.d.ts +26 -16
- package/dist/browser/index.js +95 -70
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/manifestInterceptor.d.ts +29 -29
- package/dist/browser/manifestInterceptor.js +106 -212
- package/dist/browser/manifestInterceptor.js.map +1 -1
- package/dist/browser/tabNetworkObserver.d.ts +48 -0
- package/dist/browser/tabNetworkObserver.js +140 -0
- package/dist/browser/tabNetworkObserver.js.map +1 -0
- package/dist/config/consistencyProbe.js +13 -11
- package/dist/config/consistencyProbe.js.map +1 -1
- package/dist/config/paths.d.ts +3 -8
- package/dist/config/paths.js +3 -10
- package/dist/config/paths.js.map +1 -1
- package/dist/config/profiles.d.ts +1 -1
- package/dist/config/profiles.js +6 -6
- package/dist/config/profiles.js.map +1 -1
- package/dist/config/services.d.ts +5 -5
- package/dist/config/services.js +8 -8
- package/dist/config/services.js.map +1 -1
- package/dist/config/sites.d.ts +2 -2
- package/dist/config/sites.js +6 -6
- package/dist/config/sites.js.map +1 -1
- package/dist/config/userChannels.d.ts +108 -14
- package/dist/config/userChannels.js +291 -37
- package/dist/config/userChannels.js.map +1 -1
- package/dist/config/userConfig.js +1 -1
- package/dist/config/userConfig.js.map +1 -1
- package/dist/config/userProfiles.d.ts +3 -3
- package/dist/config/userProfiles.js +19 -19
- package/dist/config/userProfiles.js.map +1 -1
- package/dist/index.js +7 -9
- package/dist/index.js.map +1 -1
- package/dist/native/index.d.ts +1 -1
- package/dist/native/index.js +9 -18
- package/dist/native/index.js.map +1 -1
- package/dist/native/proxy.d.ts +1 -4
- package/dist/native/proxy.js +0 -9
- package/dist/native/proxy.js.map +1 -1
- package/dist/routes/clientActions.d.ts +97 -0
- package/dist/routes/clientActions.js +113 -0
- package/dist/routes/clientActions.js.map +1 -0
- package/dist/routes/components.d.ts +4 -3
- package/dist/routes/components.js +36 -39
- package/dist/routes/components.js.map +1 -1
- package/dist/routes/config/channels/endpoints/browse.js.map +1 -1
- package/dist/routes/config/channels/endpoints/crud.js +37 -72
- package/dist/routes/config/channels/endpoints/crud.js.map +1 -1
- package/dist/routes/config/channels/endpoints/importExport.js.map +1 -1
- package/dist/routes/config/channels/healthBridge.d.ts +23 -0
- package/dist/routes/config/channels/healthBridge.js +71 -0
- package/dist/routes/config/channels/healthBridge.js.map +1 -0
- package/dist/routes/config/channels/table.js +97 -84
- package/dist/routes/config/channels/table.js.map +1 -1
- package/dist/routes/config/services.js +25 -22
- package/dist/routes/config/services.js.map +1 -1
- package/dist/routes/config/settings.js +9 -6
- package/dist/routes/config/settings.js.map +1 -1
- package/dist/routes/debug.js +277 -139
- package/dist/routes/debug.js.map +1 -1
- package/dist/routes/logs.js +1 -1
- package/dist/routes/logs.js.map +1 -1
- package/dist/routes/root/content.js +18 -14
- package/dist/routes/root/content.js.map +1 -1
- package/dist/routes/root/index.js +17 -14
- package/dist/routes/root/index.js.map +1 -1
- package/dist/routes/root/scripts/channels.js +50 -21
- package/dist/routes/root/scripts/channels.js.map +1 -1
- package/dist/routes/root/scripts/config.js +72 -3
- package/dist/routes/root/scripts/config.js.map +1 -1
- package/dist/routes/root/scripts/shared.js +60 -0
- package/dist/routes/root/scripts/shared.js.map +1 -1
- package/dist/routes/root/scripts/status.handlers.d.ts +5 -27
- package/dist/routes/root/scripts/status.handlers.js +8 -60
- package/dist/routes/root/scripts/status.handlers.js.map +1 -1
- package/dist/routes/root/scripts/status.js +6 -1
- package/dist/routes/root/scripts/status.js.map +1 -1
- package/dist/routes/streams.js +5 -3
- package/dist/routes/streams.js.map +1 -1
- package/dist/service/commands.context.js +1 -1
- package/dist/service/commands.context.js.map +1 -1
- package/dist/service/generators.context.js +1 -1
- package/dist/service/generators.context.js.map +1 -1
- package/dist/service/generators.d.ts +1 -1
- package/dist/service/generators.js +3 -11
- package/dist/service/generators.js.map +1 -1
- package/dist/streaming/hls.js +1 -5
- package/dist/streaming/hls.js.map +1 -1
- package/dist/streaming/hlsSegments.d.ts +1 -1
- package/dist/streaming/hlsSegments.js.map +1 -1
- package/dist/streaming/preroll.d.ts +1 -1
- package/dist/streaming/preroll.js +1 -5
- package/dist/streaming/preroll.js.map +1 -1
- package/dist/streaming/statusEmitter.d.ts +5 -8
- package/dist/streaming/statusEmitter.js +0 -5
- package/dist/streaming/statusEmitter.js.map +1 -1
- package/dist/types/channels.d.ts +9 -0
- package/dist/types/channels.js.map +1 -1
- package/dist/types/profiles.d.ts +2 -2
- package/dist/upgrade/commands.context.js +14 -10
- package/dist/upgrade/commands.context.js.map +1 -1
- package/dist/upgrade/commands.d.ts +7 -15
- package/dist/upgrade/commands.js +27 -28
- package/dist/upgrade/commands.js.map +1 -1
- package/dist/upgrade/detection.context.js +2 -1
- package/dist/upgrade/detection.context.js.map +1 -1
- package/dist/upgrade/detection.d.ts +2 -1
- package/dist/upgrade/detection.js +20 -51
- package/dist/upgrade/detection.js.map +1 -1
- package/dist/upgrade/index.d.ts +1 -0
- package/dist/upgrade/index.js +1 -0
- package/dist/upgrade/index.js.map +1 -1
- package/dist/upgrade/lifecycle.context.d.ts +19 -0
- package/dist/upgrade/lifecycle.context.js +47 -0
- package/dist/upgrade/lifecycle.context.js.map +1 -0
- package/dist/upgrade/lifecycle.d.ts +72 -0
- package/dist/upgrade/lifecycle.js +176 -0
- package/dist/upgrade/lifecycle.js.map +1 -0
- package/dist/upgrade/pathHandle.d.ts +28 -0
- package/dist/upgrade/pathHandle.js +101 -0
- package/dist/upgrade/pathHandle.js.map +1 -0
- package/dist/utils/bootSession.context.d.ts +15 -0
- package/dist/utils/bootSession.context.js +59 -0
- package/dist/utils/bootSession.context.js.map +1 -0
- package/dist/utils/bootSession.d.ts +16 -0
- package/dist/utils/bootSession.js +20 -0
- package/dist/utils/bootSession.js.map +1 -0
- package/dist/utils/clock.js +1 -1
- package/dist/utils/ffmpeg.js +1 -1
- package/dist/utils/ffmpeg.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/markup.d.ts +10 -0
- package/dist/utils/markup.js +23 -0
- package/dist/utils/markup.js.map +1 -1
- package/dist/utils/pid.d.ts +2 -25
- package/dist/utils/pid.js +10 -49
- package/dist/utils/pid.js.map +1 -1
- package/dist/utils/processInspector.context.d.ts +7 -0
- package/dist/utils/processInspector.context.js +104 -0
- package/dist/utils/processInspector.context.js.map +1 -0
- package/dist/utils/processInspector.d.ts +54 -0
- package/dist/utils/processInspector.js +125 -0
- package/dist/utils/processInspector.js.map +1 -0
- package/dist/utils/retry.d.ts +1 -1
- package/dist/utils/retry.js +1 -1
- package/dist/utils/retry.js.map +1 -1
- package/dist/utils/runtimeIdentity.context.d.ts +6 -0
- package/dist/utils/runtimeIdentity.context.js +13 -0
- package/dist/utils/runtimeIdentity.context.js.map +1 -0
- package/dist/utils/runtimeIdentity.d.ts +96 -0
- package/dist/utils/runtimeIdentity.js +171 -0
- package/dist/utils/runtimeIdentity.js.map +1 -0
- package/dist/utils/timing.d.ts +1 -1
- package/dist/utils/timing.js +0 -5
- package/dist/utils/timing.js.map +1 -1
- package/dist/utils/version.js +40 -10
- package/dist/utils/version.js.map +1 -1
- package/package.json +2 -2
package/dist/config/sites.js
CHANGED
|
@@ -159,7 +159,7 @@ export const SITE_PROFILES = {
|
|
|
159
159
|
summary: "Multi-channel (thumbnail row, needs selector)"
|
|
160
160
|
},
|
|
161
161
|
// Base profile for sites that respond to the f key for fullscreen toggle. This is the most common fullscreen mechanism, following YouTube-style keyboard
|
|
162
|
-
// shortcuts. The f key is sent as a keyboard event to the page, triggering the player's
|
|
162
|
+
// shortcuts. The f key is sent as a keyboard event to the page, triggering the player's builtin fullscreen toggle. This works with most standard video players.
|
|
163
163
|
keyboardFullscreen: {
|
|
164
164
|
category: "keyboard",
|
|
165
165
|
description: "Base profile for sites that respond to the f key for fullscreen toggle.",
|
|
@@ -296,8 +296,8 @@ export const DOMAIN_CONFIG = {
|
|
|
296
296
|
* @returns The matching DomainConfig entry, or undefined if no match is found.
|
|
297
297
|
*/
|
|
298
298
|
export function getDomainConfig(url) {
|
|
299
|
-
// User domain mappings take precedence over
|
|
300
|
-
//
|
|
299
|
+
// User domain mappings take precedence over builtin mappings. The lookup order is: user full hostname -> builtin full hostname -> user concise domain ->
|
|
300
|
+
// builtin concise domain. This allows users to override specific subdomain mappings or base domain mappings independently.
|
|
301
301
|
const userDomains = getUserDomains();
|
|
302
302
|
try {
|
|
303
303
|
const hostname = new URL(url).hostname;
|
|
@@ -306,7 +306,7 @@ export function getDomainConfig(url) {
|
|
|
306
306
|
if (userHostnameMatch) {
|
|
307
307
|
return userHostnameMatch;
|
|
308
308
|
}
|
|
309
|
-
// Try the
|
|
309
|
+
// Try the builtin full hostname for subdomain-specific overrides (e.g., "tv.youtube.com" before "youtube.com").
|
|
310
310
|
const hostnameMatch = DOMAIN_CONFIG[hostname];
|
|
311
311
|
if (hostnameMatch) {
|
|
312
312
|
return hostnameMatch;
|
|
@@ -339,8 +339,8 @@ export function registerProviderModuleProfile(name, profile) {
|
|
|
339
339
|
providerModuleProfiles.set(name, profile);
|
|
340
340
|
}
|
|
341
341
|
/**
|
|
342
|
-
* Looks up a
|
|
343
|
-
* profiles. This is the single lookup function for all
|
|
342
|
+
* Looks up a builtin profile by name, checking the general SITE_PROFILES table, the static PROVIDER_PROFILES table, and dynamically registered provider module
|
|
343
|
+
* profiles. This is the single lookup function for all builtin profile resolution - callers should use this instead of accessing any table directly.
|
|
344
344
|
* @param name - The profile name to look up.
|
|
345
345
|
* @returns The matching SiteProfile, or undefined if not found in any source.
|
|
346
346
|
*/
|
package/dist/config/sites.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sites.js","sourceRoot":"","sources":["../../src/config/sites.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"sites.js","sourceRoot":"","sources":["../../src/config/sites.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Channel, ChannelDelta, ChannelIdentity, ChannelListingEntry, ChannelMap, ChannelSortField, CustomizableField, ResolvedChannel, ResolvedChannelMap, SortDirection, StoredChannel, StoredChannelMap } from "../types/index.ts";
|
|
2
|
-
import {
|
|
2
|
+
import type { Migration, ValidationIssue } from "./persistence.ts";
|
|
3
3
|
/**
|
|
4
4
|
* User-defined channel with all channel properties.
|
|
5
5
|
*/
|
|
@@ -44,9 +44,10 @@ export declare function hasChannelsParseError(): boolean;
|
|
|
44
44
|
export declare function getChannelsParseErrorMessage(): string | undefined;
|
|
45
45
|
/**
|
|
46
46
|
* Compound data type for the channels file store. Carries channel entries alongside the metadata keys that are stored in the same JSON file. The framework
|
|
47
|
-
* uses schemaVersion and migrationsApplied for migration tracking; everything else is application-owned.
|
|
47
|
+
* uses schemaVersion and migrationsApplied for migration tracking; everything else is application-owned. Exported so test code that drives the in-place
|
|
48
|
+
* normalizer (which mutates both channels and serviceSelections atomically) can build a minimal envelope without depending on parseChannelsFile.
|
|
48
49
|
*/
|
|
49
|
-
interface ChannelsFileData {
|
|
50
|
+
export interface ChannelsFileData {
|
|
50
51
|
channels: StoredChannelMap;
|
|
51
52
|
migrationsApplied: string[];
|
|
52
53
|
schemaVersion: number;
|
|
@@ -63,9 +64,9 @@ interface ChannelsFileData {
|
|
|
63
64
|
declare function parseChannelsFile(raw: string): ChannelsFileData;
|
|
64
65
|
/**
|
|
65
66
|
* Normalizes a single stored entry as a delta against a base channel. Delta fields are dropped when they are no-ops: undefined values, nulls against a base
|
|
66
|
-
* that has no such field, and values that match the base exactly. Array-valued fields use
|
|
67
|
-
* for the fields listed in CANONICAL_SORTED_ARRAY_FIELDS so authoring-order differences do not defeat the match. Non-delta fields (e.g.,
|
|
68
|
-
* through unchanged so the stored entry retains its relationship metadata.
|
|
67
|
+
* that has no such field, and values that match the base exactly. Array-valued fields use isDeepStrictEqual for structural equality, with sortTags applied to
|
|
68
|
+
* both sides for the fields listed in CANONICAL_SORTED_ARRAY_FIELDS so authoring-order differences do not defeat the match. Non-delta fields (e.g.,
|
|
69
|
+
* canonicalKey) pass through unchanged so the stored entry retains its relationship metadata.
|
|
69
70
|
* @param stored - The raw stored entry.
|
|
70
71
|
* @param base - The base Channel to diff against (predefined definition for overrides, resolved canonical for variants).
|
|
71
72
|
* @returns The normalized entry, or null when every field is a no-op and the entry would carry no information.
|
|
@@ -173,23 +174,100 @@ declare function buildResolvedCanonicals(stored: StoredChannelMap): ResolvedChan
|
|
|
173
174
|
* @returns The entry with null-valued fields removed.
|
|
174
175
|
*/
|
|
175
176
|
declare function stripNulls(stored: StoredChannel): StoredChannel;
|
|
177
|
+
/**
|
|
178
|
+
* Returns the identity-only subset of a ChannelDelta - the fields enumerated by CHANNEL_IDENTITY_KEYS. Used by the per-field write router (PUT handler) and
|
|
179
|
+
* the storage normalizer's heal path to split a full delta into identity-only and binding-only halves so each half is routed to the correct stored entry.
|
|
180
|
+
* @param delta - The delta to project.
|
|
181
|
+
* @returns A new delta with only identity fields retained.
|
|
182
|
+
*/
|
|
183
|
+
export declare function pickIdentityFields(delta: ChannelDelta): ChannelDelta;
|
|
184
|
+
/**
|
|
185
|
+
* Returns the binding-only subset of a ChannelDelta - the fields enumerated by CHANNEL_BINDING_KEYS. Peer to pickIdentityFields; together they cover the
|
|
186
|
+
* delta surface and partition it cleanly.
|
|
187
|
+
* @param delta - The delta to project.
|
|
188
|
+
* @returns A new delta with only binding fields retained.
|
|
189
|
+
*/
|
|
190
|
+
export declare function pickBindingFields(delta: ChannelDelta): ChannelDelta;
|
|
191
|
+
/**
|
|
192
|
+
* Applies a binding delta to an existing variant entry with replace semantics: any prior binding fields on the existing entry are stripped first, then the
|
|
193
|
+
* new delta's binding fields are applied. Non-binding fields (notably canonicalKey) on the existing entry are preserved. Returns null when the resulting
|
|
194
|
+
* entry would be empty.
|
|
195
|
+
*
|
|
196
|
+
* Used by the producer (handlePredefinedEdit) when the user submits a form with explicit values - the form values are the authoritative declaration of the
|
|
197
|
+
* variant's binding state, so any pre-existing binding override on the variant entry is wiped.
|
|
198
|
+
*
|
|
199
|
+
* Pair with mergeVariantBinding (preserve-existing semantics) below. The two functions name the precedence rule explicitly so future callers pick the right
|
|
200
|
+
* semantic for their context.
|
|
201
|
+
* @param existing - The existing variant entry, if any.
|
|
202
|
+
* @param delta - The new binding-only delta. The producer is asserting these are the authoritative values.
|
|
203
|
+
* @returns The merged stored entry, or null when the result would be empty.
|
|
204
|
+
*/
|
|
205
|
+
export declare function replaceVariantBinding(existing: StoredChannel | undefined, delta: ChannelDelta): StoredChannel | null;
|
|
206
|
+
/**
|
|
207
|
+
* Merges a binding delta into an existing variant entry with preserve-existing semantics: existing variant fields win on conflicts; the delta only fills
|
|
208
|
+
* fields the variant doesn't already declare. Always returns a non-empty entry (caller is expected to invoke this only when delta has something to contribute).
|
|
209
|
+
*
|
|
210
|
+
* Used by the storage normalizer's canonical-binding overlap heal. The heal context is healing legacy data, not recording a new explicit user intent - the
|
|
211
|
+
* variant's prior customization is more recent or at least equally legitimate as the canonical-side stored binding being moved over, so the variant wins.
|
|
212
|
+
*
|
|
213
|
+
* Pair with replaceVariantBinding (replace semantics) above. The two functions name the precedence rule explicitly.
|
|
214
|
+
* @param existing - The existing variant entry, if any. Existing fields take precedence on conflicts.
|
|
215
|
+
* @param delta - The binding-only delta whose fields fill any gaps the existing entry doesn't declare.
|
|
216
|
+
* @returns The merged stored entry. Always non-empty (delta contributes at least the keys the existing didn't have).
|
|
217
|
+
*/
|
|
218
|
+
export declare function mergeVariantBinding(existing: StoredChannel | undefined, delta: ChannelDelta): StoredChannel;
|
|
219
|
+
/**
|
|
220
|
+
* Intersects a binding delta with a criterion delta by key, returning a new binding-only delta containing fields that appear in BOTH and using values from
|
|
221
|
+
* the primary delta. Used by the URL-inferred branch of the per-field write router: when a user submits a form with no pre-selected variant but a URL that
|
|
222
|
+
* implies a sibling, the producer must avoid treating unset form fields as explicit clears against the inferred variant's predefined defaults. Restricting
|
|
223
|
+
* the variant-relative delta to fields the user actually changed (relative to the canonical) prevents that silent destruction of tuning data.
|
|
224
|
+
*
|
|
225
|
+
* Pure function - operates on two deltas independently of any storage state. Generic over the criterion: any binding field present on `criterion` makes
|
|
226
|
+
* `primary`'s value for that field eligible to land on the result.
|
|
227
|
+
* @param primary - The delta whose values populate the result.
|
|
228
|
+
* @param criterion - The delta whose key set restricts which fields propagate.
|
|
229
|
+
* @returns A new binding-only delta with primary's values for keys present in both, restricted to CHANNEL_BINDING_KEYS.
|
|
230
|
+
*/
|
|
231
|
+
export declare function intersectBindingDeltas(primary: ChannelDelta, criterion: ChannelDelta): ChannelDelta;
|
|
232
|
+
/**
|
|
233
|
+
* Given a canonical key and a URL, returns the sibling variant key whose effective URL extracts to the same domain. Returns undefined when no sibling matches -
|
|
234
|
+
* that is the legitimate "Custom URL" case where the user genuinely has a non-predefined URL.
|
|
235
|
+
*
|
|
236
|
+
* Used by both the producer (handlePredefinedEdit in routes/config/channels/endpoints/crud.ts) and the storage normalizer (normalizeChannelDeltas) to enforce
|
|
237
|
+
* the rule that a canonical override's binding fields must not duplicate a sibling variant's domain. When a sibling matches, the user's intent is "default this
|
|
238
|
+
* channel to the sibling's service" - architecturally expressed via serviceSelections, not via overriding the canonical URL. Both call sites share this single
|
|
239
|
+
* helper so the inference rule lives in exactly one place.
|
|
240
|
+
*
|
|
241
|
+
* Pure function. Walks predefined and user-stored siblings, sorts by key for determinism (multiple variants with the same domain pick the alphabetically-first
|
|
242
|
+
* one), and returns the first match. Effective URL is the user-stored override (if any string-valued) layered onto the predefined variant URL - same precedence
|
|
243
|
+
* as resolveVariant.
|
|
244
|
+
* @param canonicalKey - The canonical channel key whose siblings should be searched.
|
|
245
|
+
* @param submittedUrl - The URL being matched. Empty/undefined returns undefined.
|
|
246
|
+
* @param channels - The stored channels map snapshot for finding user-defined sibling variants.
|
|
247
|
+
* @returns The matching variant key, or undefined when no sibling's URL domain matches.
|
|
248
|
+
*/
|
|
249
|
+
export declare function inferTargetVariant(canonicalKey: string, submittedUrl: string | null | undefined, channels: StoredChannelMap): string | undefined;
|
|
176
250
|
/**
|
|
177
251
|
* Normalizes the stored channels map to its minimal delta form. Each entry is classified, diffed against its applicable base, and any no-op fields are
|
|
178
|
-
* stripped. Standalone user channels have no base, so nulls are stripped but everything else is preserved.
|
|
252
|
+
* stripped. Standalone user channels have no base, so nulls are stripped but everything else is preserved. Mutates the data in place so the caller's reference
|
|
253
|
+
* (the file store framework's data envelope) reflects normalized state on return - matching the migration `apply` convention so the same shape is used wherever
|
|
254
|
+
* the framework runs writes.
|
|
179
255
|
*
|
|
180
256
|
* The flow is uniform across kinds:
|
|
181
257
|
*
|
|
182
|
-
* - Canonical (predefined with user override): base is the predefined channel.
|
|
258
|
+
* - Canonical (predefined with user override): base is the predefined channel. Before delta minimization, any binding fields whose URL extracts to a sibling
|
|
259
|
+
* variant's domain are healed by routing them to the matching variant entry and recording a serviceSelections redirect - the same per-field routing the
|
|
260
|
+
* producer (handlePredefinedEdit) performs at write time. This makes the rule "canonical overrides only carry canonical-service binding" structurally
|
|
261
|
+
* self-healing for any data path that misses the producer (legacy data, hand-edited files, future producers).
|
|
183
262
|
* - Variant: base is the resolved canonical layered with the predefined variant's service fields (the view the user sees in the form/table, so the delta
|
|
184
263
|
* records only what differs from that).
|
|
185
264
|
* - Standalone: no base, null values are stripped as a storage convention.
|
|
186
265
|
*
|
|
187
266
|
* Entries whose normalized delta is empty collapse to nothing and get dropped - a redundant override carries no information, and resolution falls through to
|
|
188
267
|
* the default.
|
|
189
|
-
* @param
|
|
190
|
-
* @returns The normalized channel map.
|
|
268
|
+
* @param data - The full channels file data envelope. Channels and serviceSelections are both mutated in place.
|
|
191
269
|
*/
|
|
192
|
-
declare function normalizeChannelDeltas(
|
|
270
|
+
declare function normalizeChannelDeltas(data: ChannelsFileData): void;
|
|
193
271
|
/**
|
|
194
272
|
* Prepares channels data for writing to disk. Injects metadata from module state (serviceSelections, tagRegistry) into the serializable output. The metadata
|
|
195
273
|
* is always pulled from module state rather than from the file data, because route handlers may have modified metadata in memory since the last file read.
|
|
@@ -253,6 +331,22 @@ declare function detectIdentityFieldLoss(before: StoredChannelMap, after: Stored
|
|
|
253
331
|
* @throws FileStoreParseError if channels.json contains invalid JSON and the .bak rotation is also unparseable.
|
|
254
332
|
*/
|
|
255
333
|
export declare function mutateChannels(fn: (data: ChannelsFileData) => void): Promise<void>;
|
|
334
|
+
/**
|
|
335
|
+
* Runs the startup channels-file cleanup pass. Combines two boot-time concerns into one atomic write so they share a single disk transaction:
|
|
336
|
+
*
|
|
337
|
+
* - Stale service-selections cleanup: any selection whose variant key no longer exists (deleted predefined variant, removed user channel) is removed by
|
|
338
|
+
* buildServiceGroups in module state; this pass mirrors that cleanup to disk so the file matches the runtime view across restarts.
|
|
339
|
+
* - Canonical-binding overlap heal: invoked indirectly by the post-callback normalizer (normalizeChannelDeltas) which runs against the freshly-read data
|
|
340
|
+
* inside mutateChannels. Any canonical override carrying binding whose URL extracts to a sibling variant's domain is healed in place - binding stripped
|
|
341
|
+
* from the canonical, propagated to the matching variant entry, serviceSelections updated. The normalizer always runs post-callback; the heal happening
|
|
342
|
+
* automatically is the load-bearing behavior, not the explicit body of this function.
|
|
343
|
+
*
|
|
344
|
+
* Existence as a named function is the architectural point: a bare `mutateChannels(() => {})` would correctly trigger the normalizer but obscure the intent
|
|
345
|
+
* at the call site. The name documents what the pass does so callers see "run startup cleanup" rather than "do nothing inside a mutation."
|
|
346
|
+
* @param staleSelections - Service-selection keys to delete from data.serviceSelections. Empty array is allowed (heal-only path).
|
|
347
|
+
* @throws FileStoreParseError if the channels file contains invalid JSON.
|
|
348
|
+
*/
|
|
349
|
+
export declare function runStartupChannelsCleanup(staleSelections: readonly string[]): Promise<void>;
|
|
256
350
|
/**
|
|
257
351
|
* Deletes a user channel by key.
|
|
258
352
|
* @param key - The channel key to delete.
|
|
@@ -295,7 +389,7 @@ export declare function resetUserChannels(): Promise<void>;
|
|
|
295
389
|
* are user-created standalones that happen to share the hyphenated key shape (e.g., "abc-kabc" as a local affiliate with its own channel number and station
|
|
296
390
|
* ID) and must be left alone - stamping them would mark them for delta normalization and silently destroy the user's custom identity.
|
|
297
391
|
*
|
|
298
|
-
* Array-valued identity fields (tags) compare via
|
|
392
|
+
* Array-valued identity fields (tags) compare via isDeepStrictEqual after sortTags canonicalizes both sides, so historical write order does not defeat the match.
|
|
299
393
|
* @param channels - The raw stored channel entries.
|
|
300
394
|
* @returns Keys that should receive a canonicalKey stamp. Empty when nothing needs migrating.
|
|
301
395
|
*/
|
|
@@ -756,8 +850,8 @@ export declare function validateImportedChannels(data: unknown, validProfiles: s
|
|
|
756
850
|
/**
|
|
757
851
|
* Sorts tags case-insensitively using locale-aware comparison. This is the single source of truth for tag ordering. Every write path (parseTagInput, PATCH
|
|
758
852
|
* handlers, computePredefinedDelta, transformChannelTags, setTagRegistry) routes through this so stored tag arrays share one canonical ordering. The channels
|
|
759
|
-
* normalizer is a READER of that invariant - it uses sortTags on both sides when comparing a delta's tags against a predefined's tags, making the
|
|
760
|
-
*
|
|
853
|
+
* normalizer is a READER of that invariant - it uses sortTags on both sides when comparing a delta's tags against a predefined's tags, making the
|
|
854
|
+
* isDeepStrictEqual comparison canonical regardless of how either side was originally populated.
|
|
761
855
|
* @param tags - Any iterable of tag strings (array, Set, generator). Not mutated.
|
|
762
856
|
* @returns A new array with the same elements in canonical case-insensitive order.
|
|
763
857
|
*/
|