refactor(spf): rename startSequence engine config to presumedStartSequence

startSequence read ambiguously. Rename to presumedStartSequence across the
hls engine config, the anchorLiveTracks behavior, and the (HLS-agnostic)
anchorTrackToSequenceOrigin media primitive — conveying that it's the media
sequence presumed to be the stream origin. Kept HLS-free so the media-layer
primitive stays layering-clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Christian Pillsbury
2026-06-25 09:59:44 -07:00
co-authored by Claude Opus 4.8
parent 9b973b8e66
commit c7abf7df8e
4 changed files with 13 additions and 13 deletions
@@ -7,12 +7,12 @@ export interface AnchorToSequenceOriginOptions {
* — the spec default when `EXT-X-MEDIA-SEQUENCE` is absent, and the common
* encoder convention. Override when the true origin sequence is known.
*/
startSequence?: number;
presumedStartSequence?: number;
}
/**
* Re-origin a track's timeline to an estimated stream start (the segment at
* `startSequence`, default 0), so `startTime` reads as elapsed-since-stream-start
* `presumedStartSequence`, default 0), so `startTime` reads as elapsed-since-stream-start
* and `startDate` becomes the wall clock at that origin — the stream-absolute
* convention, from the manifest alone.
*
@@ -20,11 +20,11 @@ export interface AnchorToSequenceOriginOptions {
* is estimated from the observed segments' **average duration** — more reliable
* than `EXT-X-TARGETDURATION` (a spec ceiling that systematically
* over-estimates). The origin offset of the first PDT-bearing segment is
* `(its sequence startSequence) × averageDuration`; present segments keep
* `(its sequence presumedStartSequence) × averageDuration`; present segments keep
* their actual relative spacing, only the offset to the unseen origin is
* estimated.
*
* ROUGH and provisional: assumes `startSequence` is the true origin (often but
* ROUGH and provisional: assumes `presumedStartSequence` is the true origin (often but
* not always correct — configurable), roughly uniform durations, and no
* discontinuities in the unseen past; error grows with the sequence gap.
* Refined later from the buffer (`buffered`/`tfdt`), which is authoritative.
@@ -38,7 +38,7 @@ export interface AnchorToSequenceOriginOptions {
*/
export function anchorTrackToSequenceOrigin<Tracks extends Track>(
track: Tracks,
{ startSequence = 0 }: AnchorToSequenceOriginOptions = {}
{ presumedStartSequence = 0 }: AnchorToSequenceOriginOptions = {}
): Tracks {
const { segments } = track;
const anchorIndex = segments.findIndex((segment) => !isUndefined(segment.startDate));
@@ -50,7 +50,7 @@ export function anchorTrackToSequenceOrigin<Tracks extends Track>(
const mediaSequence = getMediaPlaylistMetadata(track)?.mediaSequence ?? 0;
const anchorSequence = mediaSequence + anchorIndex;
const averageDuration = segments.reduce((sum, segment) => sum + segment.duration, 0) / segments.length;
const originOffset = (anchorSequence - startSequence) * averageDuration;
const originOffset = (anchorSequence - presumedStartSequence) * averageDuration;
const shift = originOffset - anchor.startTime;
if (shift === 0) {
return track;
@@ -60,10 +60,10 @@ describe('anchorTrackToSequenceOrigin', () => {
expect(anchored.segments[0]?.startTime).toBe(40);
});
it('honors a configured startSequence (no shift when it equals the window start)', () => {
it('honors a configured presumedStartSequence (no shift when it equals the window start)', () => {
const track = makeTrack(85, [{ startTime: 0, duration: 4, pdt: 1000 }]);
// startSequence = 85 → originOffset 0 → already at origin → unchanged identity.
expect(anchorTrackToSequenceOrigin(track, { startSequence: 85 })).toBe(track);
// presumedStartSequence = 85 → originOffset 0 → already at origin → unchanged identity.
expect(anchorTrackToSequenceOrigin(track, { presumedStartSequence: 85 })).toBe(track);
});
it('preserves present segments actual spacing (only the origin offset is estimated)', () => {
@@ -41,7 +41,7 @@ export interface AnchorLiveTracksConfig {
* Sequence number assumed to be the stream origin (time 0). Default 0 —
* see `anchorTrackToSequenceOrigin`.
*/
startSequence?: number;
presumedStartSequence?: number;
}
function anchorLiveTracksSetup({
@@ -55,7 +55,7 @@ function anchorLiveTracksSetup({
};
config?: AnchorLiveTracksConfig;
}): () => void {
const { startSequence = 0 } = config;
const { presumedStartSequence = 0 } = config;
return effect(() => {
const presentation = state.presentation.get();
@@ -72,7 +72,7 @@ function anchorLiveTracksSetup({
const anchored: ResolvedTrack[] = [];
for (const track of selected) {
if (!track || !isResolvedTrack(track) || isUndefined(track.startDate)) continue;
const next = anchorTrackToSequenceOrigin(track, { startSequence });
const next = anchorTrackToSequenceOrigin(track, { presumedStartSequence });
// Identity-equal when already anchored (shift 0) → nothing to patch.
if (next !== track) anchored.push(next);
}
@@ -189,7 +189,7 @@ export interface SimpleHlsEngineConfig extends ShareSignalsConfig<SimpleHlsEngin
* timeline anchor (`anchorLiveTracks`). Default 0. Only meaningful for live
* sources; ignored for VoD (the anchor is a no-op without `#EXT-X-PROGRAM-DATE-TIME`).
*/
startSequence?: number;
presumedStartSequence?: number;
/**
* Live media-playlist re-run policy for the resolve* loaders' `RecurringRunner`:
* returns a promise that resolves when the playlist should reload, or `null` to