@hyperframes/core 0.8.120 → 0.8.122

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.
@@ -0,0 +1,64 @@
1
+ import { type RateSpec } from "../speedRamp.js";
2
+ export type TransportClockSnapshot = {
3
+ time: number;
4
+ playing: boolean;
5
+ rate: number;
6
+ duration: number;
7
+ source: "monotonic" | "audio";
8
+ };
9
+ export type AudioClockSource = {
10
+ el: HTMLMediaElement;
11
+ compositionStart: number;
12
+ mediaStart: number;
13
+ /** The clip's rate lane; a constant rate is read from `el.playbackRate`. */
14
+ rate?: RateSpec;
15
+ } | {
16
+ currentTimeSeconds: number;
17
+ };
18
+ export declare class TransportClock {
19
+ private _baseTime;
20
+ private _playStartMs;
21
+ private _rate;
22
+ private _duration;
23
+ private _playStart;
24
+ private _playEnd;
25
+ private _playHold;
26
+ private _nowMs;
27
+ private _audioSource;
28
+ /** Wall-clock time of the last `now()` read while playing; null while paused. */
29
+ private _lastReadMs;
30
+ private _lastNow;
31
+ constructor(opts?: {
32
+ initialTime?: number;
33
+ rate?: number;
34
+ duration?: number;
35
+ nowMs?: () => number;
36
+ });
37
+ now(): number;
38
+ private _elementTimeNeverBehind;
39
+ private _heldTimeWhenBehind;
40
+ /** Folds a >500ms gap since the last read into `_playStartMs` so it's never reported as played time. */
41
+ private _applyStallCorrection;
42
+ play(): boolean;
43
+ pause(): boolean;
44
+ seek(timeSeconds: number): void;
45
+ isPlaying(): boolean;
46
+ setRate(rate: number): void;
47
+ getRate(): number;
48
+ setDuration(duration: number): void;
49
+ getDuration(): number;
50
+ setPlayRange(start: number, end: number | null, fps: number): void;
51
+ getPlayStart(): number;
52
+ getEnd(): number;
53
+ /** Where a stop parks: the film's end, or a range's last frame, since the moment is [start, end). */
54
+ getStopTime(): number;
55
+ attachAudioSource(source: AudioClockSource): void;
56
+ detachAudioSource(): void;
57
+ /** The element the playhead currently follows, if the source is one. */
58
+ audioElement(): HTMLMediaElement | null;
59
+ hasAudioSource(): boolean;
60
+ getSource(): "monotonic" | "audio";
61
+ snapshot(): TransportClockSnapshot;
62
+ reachedEnd(): boolean;
63
+ }
64
+ //# sourceMappingURL=clock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clock.d.ts","sourceRoot":"","sources":["../../src/runtime/clock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAIlE,MAAM,MAAM,sBAAsB,GAAG;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,gBAAgB,GACxB;IACE,EAAE,EAAE,gBAAgB,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,4EAA4E;IAC5E,IAAI,CAAC,EAAE,QAAQ,CAAC;CACjB,GACD;IACE,kBAAkB,EAAE,MAAM,CAAC;CAC5B,CAAC;AAON,qBAAa,cAAc;IACzB,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,QAAQ,CAAY;IAC5B,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,YAAY,CAAiC;IACrD,iFAAiF;IACjF,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,QAAQ,CAAK;gBAET,IAAI,CAAC,EAAE;QACjB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,MAAM,CAAC;KACtB;IAOD,GAAG,IAAI,MAAM;IAgCb,OAAO,CAAC,uBAAuB;IAW/B,OAAO,CAAC,mBAAmB;IAM3B,wGAAwG;IACxG,OAAO,CAAC,qBAAqB;IAY7B,IAAI,IAAI,OAAO;IAaf,KAAK,IAAI,OAAO;IAOhB,IAAI,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAc/B,SAAS,IAAI,OAAO;IAIpB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAU3B,OAAO,IAAI,MAAM;IAIjB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAOnC,WAAW,IAAI,MAAM;IAIrB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAMlE,YAAY,IAAI,MAAM;IAItB,MAAM,IAAI,MAAM;IAIhB,qGAAqG;IACrG,WAAW,IAAI,MAAM;IAIrB,iBAAiB,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI;IAIjD,iBAAiB,IAAI,IAAI;IAWzB,wEAAwE;IACxE,YAAY,IAAI,gBAAgB,GAAG,IAAI;IAIvC,cAAc,IAAI,OAAO;IAIzB,SAAS,IAAI,WAAW,GAAG,OAAO;IASlC,QAAQ,IAAI,sBAAsB;IAUlC,UAAU,IAAI,OAAO;CAItB"}
@@ -0,0 +1,204 @@
1
+ import { timeAtSourceTime } from "../speedRamp.js";
2
+ import { MEDIA_HARD_SYNC_SECONDS } from "./media.js";
3
+ import { playRangeHoldTime } from "./protocol.js";
4
+ /** GSAP's own `lagSmoothing` default — see the PR body for why this clock needs its own copy. */
5
+ const STALL_THRESHOLD_MS = 500;
6
+ const STALL_ADJUSTED_LAG_MS = 33;
7
+ const HAVE_FUTURE_DATA = 3;
8
+ export class TransportClock {
9
+ _baseTime = 0;
10
+ _playStartMs = null;
11
+ _rate = 1;
12
+ _duration = Infinity;
13
+ _playStart = 0;
14
+ _playEnd = Infinity;
15
+ _playHold = Infinity;
16
+ _nowMs;
17
+ _audioSource = null;
18
+ /** Wall-clock time of the last `now()` read while playing; null while paused. */
19
+ _lastReadMs = null;
20
+ _lastNow = 0;
21
+ constructor(opts) {
22
+ this._baseTime = opts?.initialTime ?? 0;
23
+ this._rate = opts?.rate ?? 1;
24
+ this._duration = opts?.duration ?? Infinity;
25
+ this._nowMs = opts?.nowMs ?? (() => performance.now());
26
+ }
27
+ now() {
28
+ if (this._playStartMs === null)
29
+ return this._baseTime;
30
+ // Audio-master: drift is impossible because audio IS the clock. Clearing
31
+ // `_lastReadMs` (not stamping it) means the next monotonic read starts
32
+ // fresh from `_playStartMs` instead of a timestamp audio just made
33
+ // meaningless — see the PR body.
34
+ if (this._audioSource) {
35
+ let audioTime = null;
36
+ if ("currentTimeSeconds" in this._audioSource) {
37
+ audioTime = this._audioSource.currentTimeSeconds;
38
+ }
39
+ else {
40
+ audioTime = this._elementTimeNeverBehind(this._audioSource);
41
+ }
42
+ if (audioTime !== null) {
43
+ const t = Math.min(audioTime, this.getEnd());
44
+ this._baseTime = Math.max(0, t);
45
+ this._playStartMs = this._nowMs();
46
+ this._lastReadMs = null;
47
+ this._lastNow = this._baseTime;
48
+ return this._baseTime;
49
+ }
50
+ }
51
+ // Monotonic fallback
52
+ this._applyStallCorrection();
53
+ const elapsed = (this._nowMs() - this._playStartMs) / 1000;
54
+ const t = this._baseTime + elapsed * this._rate;
55
+ this._lastNow = Math.max(0, Math.min(t, this.getEnd()));
56
+ return this._lastNow;
57
+ }
58
+ _elementTimeNeverBehind(source) {
59
+ const { el, compositionStart, mediaStart, rate } = source;
60
+ if (el.paused || !Number.isFinite(el.currentTime))
61
+ return null;
62
+ if (el.seeking)
63
+ return this._lastNow;
64
+ const spec = rate ?? 1;
65
+ const time = timeAtSourceTime(spec, el.currentTime - mediaStart) + compositionStart;
66
+ return time >= this._lastNow ? time : this._heldTimeWhenBehind(el, this._lastNow - time, spec);
67
+ }
68
+ _heldTimeWhenBehind(el, behind, spec) {
69
+ if (el.loop && behind > timeAtSourceTime(spec, el.duration) / 2)
70
+ return null;
71
+ const buffering = el.readyState < HAVE_FUTURE_DATA;
72
+ return buffering || behind <= MEDIA_HARD_SYNC_SECONDS ? this._lastNow : null;
73
+ }
74
+ /** Folds a >500ms gap since the last read into `_playStartMs` so it's never reported as played time. */
75
+ _applyStallCorrection() {
76
+ if (this._playStartMs === null)
77
+ return;
78
+ const nowMs = this._nowMs();
79
+ if (this._lastReadMs !== null) {
80
+ const gapMs = nowMs - this._lastReadMs;
81
+ if (gapMs > STALL_THRESHOLD_MS) {
82
+ this._playStartMs += gapMs - STALL_ADJUSTED_LAG_MS;
83
+ }
84
+ }
85
+ this._lastReadMs = nowMs;
86
+ }
87
+ play() {
88
+ if (this._playStartMs !== null)
89
+ return false;
90
+ if (this._baseTime >= this.getEnd())
91
+ return false;
92
+ this._playStartMs = this._nowMs();
93
+ this._lastNow = this._baseTime;
94
+ // Not a stall: the gap since the clock was last read (possibly a long
95
+ // paused idle) says nothing about lost playback time, since none was
96
+ // playing. `_applyStallCorrection` treats null as "nothing to compare
97
+ // against yet" and starts the window fresh from the next read.
98
+ this._lastReadMs = null;
99
+ return true;
100
+ }
101
+ pause() {
102
+ if (this._playStartMs === null)
103
+ return false;
104
+ this._baseTime = this.now();
105
+ this._playStartMs = null;
106
+ return true;
107
+ }
108
+ seek(timeSeconds) {
109
+ const clamped = Number.isFinite(this._duration)
110
+ ? Math.max(0, Math.min(timeSeconds, this._duration))
111
+ : Math.max(0, timeSeconds);
112
+ this._baseTime = clamped;
113
+ this._lastNow = clamped;
114
+ if (this._playStartMs !== null) {
115
+ this._playStartMs = this._nowMs();
116
+ // Same reasoning as `play()`: the seek itself, not any elapsed gap
117
+ // since the last read, is why the reported time is moving now.
118
+ this._lastReadMs = null;
119
+ }
120
+ }
121
+ isPlaying() {
122
+ return this._playStartMs !== null;
123
+ }
124
+ setRate(rate) {
125
+ const safe = Number.isFinite(rate) && rate > 0 ? Math.max(0.1, Math.min(5, rate)) : 1;
126
+ if (this._playStartMs !== null) {
127
+ this._baseTime = this.now();
128
+ this._playStartMs = this._nowMs();
129
+ this._lastReadMs = null;
130
+ }
131
+ this._rate = safe;
132
+ }
133
+ getRate() {
134
+ return this._rate;
135
+ }
136
+ setDuration(duration) {
137
+ this._duration = Number.isFinite(duration) && duration > 0 ? duration : Infinity;
138
+ if (this._baseTime > this._duration) {
139
+ this._baseTime = this._duration;
140
+ }
141
+ }
142
+ getDuration() {
143
+ return this._duration;
144
+ }
145
+ setPlayRange(start, end, fps) {
146
+ this._playStart = Number.isFinite(start) && start > 0 ? start : 0;
147
+ this._playEnd = end !== null && Number.isFinite(end) && end > this._playStart ? end : Infinity;
148
+ this._playHold = playRangeHoldTime(this._playStart, this._playEnd, fps);
149
+ }
150
+ getPlayStart() {
151
+ return this._playStart;
152
+ }
153
+ getEnd() {
154
+ return Math.min(this._duration, this._playEnd);
155
+ }
156
+ /** Where a stop parks: the film's end, or a range's last frame, since the moment is [start, end). */
157
+ getStopTime() {
158
+ return this._playEnd < this._duration ? this._playHold : this.getEnd();
159
+ }
160
+ attachAudioSource(source) {
161
+ this._audioSource = source;
162
+ }
163
+ detachAudioSource() {
164
+ if (this._audioSource && this._playStartMs !== null) {
165
+ this._baseTime = this.now();
166
+ this._playStartMs = this._nowMs();
167
+ // Falling back to monotonic timing fresh, same reasoning as `play()`:
168
+ // any gap while audio was the time source is not a monotonic stall.
169
+ this._lastReadMs = null;
170
+ }
171
+ this._audioSource = null;
172
+ }
173
+ /** The element the playhead currently follows, if the source is one. */
174
+ audioElement() {
175
+ return this._audioSource && "el" in this._audioSource ? this._audioSource.el : null;
176
+ }
177
+ hasAudioSource() {
178
+ return this._audioSource !== null;
179
+ }
180
+ getSource() {
181
+ if (this._audioSource && this._playStartMs !== null) {
182
+ if ("currentTimeSeconds" in this._audioSource)
183
+ return "audio";
184
+ const { el } = this._audioSource;
185
+ if (!el.paused && Number.isFinite(el.currentTime))
186
+ return "audio";
187
+ }
188
+ return "monotonic";
189
+ }
190
+ snapshot() {
191
+ return {
192
+ time: this.now(),
193
+ playing: this.isPlaying(),
194
+ rate: this._rate,
195
+ duration: this._duration,
196
+ source: this.getSource(),
197
+ };
198
+ }
199
+ reachedEnd() {
200
+ const time = this.now();
201
+ return time >= this.getEnd() || (this._playStartMs === null && time >= this.getStopTime());
202
+ }
203
+ }
204
+ //# sourceMappingURL=clock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clock.js","sourceRoot":"","sources":["../../src/runtime/clock.ts"],"names":[],"mappings":"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"}
@@ -2,5 +2,5 @@
2
2
  export declare function parseLayoutDimension(value: string | null | undefined): number | null;
3
3
  /** The size the runtime reports to its host: whole px, read with `parseInt` as the renderer does. */
4
4
  export declare function parseCompositionDimension(value: string | null | undefined): number | null;
5
- export declare function findRootCompositionElement(): HTMLElement | null;
5
+ export declare function findRootCompositionElement(doc?: ParentNode): HTMLElement | null;
6
6
  //# sourceMappingURL=compositionDimension.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"compositionDimension.d.ts","sourceRoot":"","sources":["../../src/runtime/compositionDimension.ts"],"names":[],"mappings":"AAEA,8FAA8F;AAC9F,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAIpF;AAED,qGAAqG;AACrG,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAIzF;AAED,wBAAgB,0BAA0B,IAAI,WAAW,GAAG,IAAI,CAK/D"}
1
+ {"version":3,"file":"compositionDimension.d.ts","sourceRoot":"","sources":["../../src/runtime/compositionDimension.ts"],"names":[],"mappings":"AAEA,8FAA8F;AAC9F,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAIpF;AAED,qGAAqG;AACrG,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAIzF;AAED,wBAAgB,0BAA0B,CAAC,GAAG,GAAE,UAAqB,GAAG,WAAW,GAAG,IAAI,CAKzF"}
@@ -13,11 +13,11 @@ export function parseCompositionDimension(value) {
13
13
  const parsed = Number.parseInt(value, 10);
14
14
  return Number.isFinite(parsed) && parsed > 0 ? parsed : null;
15
15
  }
16
- export function findRootCompositionElement() {
17
- const explicitRoot = document.querySelector('[data-composition-id][data-root="true"]');
16
+ export function findRootCompositionElement(doc = document) {
17
+ const explicitRoot = doc.querySelector('[data-composition-id][data-root="true"]');
18
18
  if (isHtmlElement(explicitRoot))
19
19
  return explicitRoot;
20
20
  // The first composition in document order never sits inside another one.
21
- return document.querySelector("[data-composition-id]");
21
+ return doc.querySelector("[data-composition-id]");
22
22
  }
23
23
  //# sourceMappingURL=compositionDimension.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"compositionDimension.js","sourceRoot":"","sources":["../../src/runtime/compositionDimension.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,8FAA8F;AAC9F,MAAM,UAAU,oBAAoB,CAAC,KAAgC;IACnE,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IACtD,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IACxC,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/D,CAAC;AAED,qGAAqG;AACrG,MAAM,UAAU,yBAAyB,CAAC,KAAgC;IACxE,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IACtD,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC1C,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,0BAA0B;IACxC,MAAM,YAAY,GAAG,QAAQ,CAAC,aAAa,CAAC,yCAAyC,CAAC,CAAC;IACvF,IAAI,aAAa,CAAC,YAAY,CAAC;QAAE,OAAO,YAAY,CAAC;IACrD,yEAAyE;IACzE,OAAO,QAAQ,CAAC,aAAa,CAAc,uBAAuB,CAAC,CAAC;AACtE,CAAC"}
1
+ {"version":3,"file":"compositionDimension.js","sourceRoot":"","sources":["../../src/runtime/compositionDimension.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,8FAA8F;AAC9F,MAAM,UAAU,oBAAoB,CAAC,KAAgC;IACnE,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IACtD,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IACxC,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/D,CAAC;AAED,qGAAqG;AACrG,MAAM,UAAU,yBAAyB,CAAC,KAAgC;IACxE,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IACtD,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC1C,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,MAAkB,QAAQ;IACnE,MAAM,YAAY,GAAG,GAAG,CAAC,aAAa,CAAC,yCAAyC,CAAC,CAAC;IAClF,IAAI,aAAa,CAAC,YAAY,CAAC;QAAE,OAAO,YAAY,CAAC;IACrD,yEAAyE;IACzE,OAAO,GAAG,CAAC,aAAa,CAAc,uBAAuB,CAAC,CAAC;AACjE,CAAC"}
@@ -0,0 +1,44 @@
1
+ import { type CompositionDurationResult } from "@hyperframes/parsers/composition-duration";
2
+ import { findRootCompositionElement } from "./compositionDimension";
3
+ import { createRuntimeStartTimeResolver } from "./startResolver";
4
+ export { findRootCompositionElement };
5
+ /** One frame at 60 fps: a timeline, floor or fallback this short or shorter is no length at all. */
6
+ export declare const MIN_VALID_TIMELINE_DURATION_SECONDS: number;
7
+ type StartResolver = Pick<ReturnType<typeof createRuntimeStartTimeResolver>, "resolveStartForElement" | "resolveDurationForElement">;
8
+ /** The size the runtime reports to its host. */
9
+ export declare function readCompositionSize(root: Element): {
10
+ width: number | null;
11
+ height: number | null;
12
+ };
13
+ /** The latest end among the document's timed video and audio, at their absolute starts. */
14
+ export declare function resolveMediaWindowDurationSeconds(doc: ParentNode, media: {
15
+ mediaStart: (el: HTMLMediaElement) => number;
16
+ mediaDuration: (el: HTMLMediaElement) => number | null;
17
+ }): number | null;
18
+ /** The latest of the root's declared length and its direct sub-compositions' ends. */
19
+ export declare function resolveAuthoredCompositionFloorSeconds(root: Element, startResolver: StartResolver): number | null;
20
+ /** The last-resort length: the latest end among the root's timed clips. Until every clip's length
21
+ * is known it is unresolved, so a renderer that reads it once cannot lock in a short one.
22
+ * `unregisteredLottie`: a Lottie library is loaded, so animations may still register. */
23
+ export declare function resolveContentDerivedDuration(root: Element, startResolver: StartResolver, { unregisteredLottie }: {
24
+ unregisteredLottie: boolean;
25
+ }): CompositionDurationResult;
26
+ export type CompositionLengthInputs = {
27
+ declared: number | null;
28
+ timeline: () => number | null;
29
+ floors: () => ReadonlyArray<number | null>;
30
+ fallback: number;
31
+ derived: () => number;
32
+ };
33
+ /** A declared root length is the length (a longer timeline is cut off); else the timeline, the
34
+ * floors and the fallback, whichever is longest; else the length derived from the clips. */
35
+ export declare function resolveCompositionLengthSeconds(input: CompositionLengthInputs): number;
36
+ /** Size, frame rate and length of a composition nothing is running (a server-parsed or detached
37
+ * document): no timelines, no adapters, and media without a known source length is pending. */
38
+ export declare function readStaticCompositionMeta(doc: Document): {
39
+ width: number | null;
40
+ height: number | null;
41
+ fps: number;
42
+ durationSeconds: number;
43
+ } | null;
44
+ //# sourceMappingURL=compositionLength.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compositionLength.d.ts","sourceRoot":"","sources":["../../src/runtime/compositionLength.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,yBAAyB,EAC/B,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAAE,0BAA0B,EAA6B,MAAM,wBAAwB,CAAC;AAG/F,OAAO,EAAE,8BAA8B,EAAE,MAAM,iBAAiB,CAAC;AAGjE,OAAO,EAAE,0BAA0B,EAAE,CAAC;AAEtC,oGAAoG;AACpG,eAAO,MAAM,mCAAmC,QAAS,CAAC;AAE1D,KAAK,aAAa,GAAG,IAAI,CACvB,UAAU,CAAC,OAAO,8BAA8B,CAAC,EACjD,wBAAwB,GAAG,2BAA2B,CACvD,CAAC;AAKF,gDAAgD;AAChD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG;IAClD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CAKA;AAED,2FAA2F;AAC3F,wBAAgB,iCAAiC,CAC/C,GAAG,EAAE,UAAU,EACf,KAAK,EAAE;IACL,UAAU,EAAE,CAAC,EAAE,EAAE,gBAAgB,KAAK,MAAM,CAAC;IAC7C,aAAa,EAAE,CAAC,EAAE,EAAE,gBAAgB,KAAK,MAAM,GAAG,IAAI,CAAC;CACxD,GACA,MAAM,GAAG,IAAI,CAef;AAED,sFAAsF;AACtF,wBAAgB,sCAAsC,CACpD,IAAI,EAAE,OAAO,EACb,aAAa,EAAE,aAAa,GAC3B,MAAM,GAAG,IAAI,CAgBf;AAKD;;0FAE0F;AAC1F,wBAAgB,6BAA6B,CAC3C,IAAI,EAAE,OAAO,EACb,aAAa,EAAE,aAAa,EAC5B,EAAE,kBAAkB,EAAE,EAAE;IAAE,kBAAkB,EAAE,OAAO,CAAA;CAAE,GACtD,yBAAyB,CAiB3B;AAED,MAAM,MAAM,uBAAuB,GAAG;IACpC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IAExB,QAAQ,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IAC9B,MAAM,EAAE,MAAM,aAAa,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC3C,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,MAAM,CAAC;CACvB,CAAC;AAEF;6FAC6F;AAC7F,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,uBAAuB,GAAG,MAAM,CAgBtF;AAED;gGACgG;AAChG,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,QAAQ,GACZ;IAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAuB9F"}
@@ -0,0 +1,125 @@
1
+ import { resolveCompositionDuration, } from "@hyperframes/parsers/composition-duration";
2
+ import { findRootCompositionElement, parseCompositionDimension } from "./compositionDimension.js";
3
+ import { isMediaElement } from "./domRealm.js";
4
+ import { parseStrictFiniteTimingNumber, resolveMediaElementDurationSeconds } from "./playbackRate.js";
5
+ import { createRuntimeStartTimeResolver } from "./startResolver.js";
6
+ import { createRuntimeState } from "./state.js";
7
+ export { findRootCompositionElement };
8
+ /** One frame at 60 fps: a timeline, floor or fallback this short or shorter is no length at all. */
9
+ export const MIN_VALID_TIMELINE_DURATION_SECONDS = 1 / 60;
10
+ const aboveOneFrame = (seconds) => seconds !== null && seconds > MIN_VALID_TIMELINE_DURATION_SECONDS ? seconds : null;
11
+ /** The size the runtime reports to its host. */
12
+ export function readCompositionSize(root) {
13
+ return {
14
+ width: parseCompositionDimension(root.getAttribute("data-width")),
15
+ height: parseCompositionDimension(root.getAttribute("data-height")),
16
+ };
17
+ }
18
+ /** The latest end among the document's timed video and audio, at their absolute starts. */
19
+ export function resolveMediaWindowDurationSeconds(doc, media) {
20
+ const clipEnds = [];
21
+ for (const node of doc.querySelectorAll("video[data-start], audio[data-start]")) {
22
+ const start = media.mediaStart(node);
23
+ if (!Number.isFinite(start))
24
+ continue;
25
+ const duration = media.mediaDuration(node);
26
+ if (duration == null || duration <= MIN_VALID_TIMELINE_DURATION_SECONDS)
27
+ continue;
28
+ clipEnds.push(Math.max(0, start) + duration);
29
+ }
30
+ return aboveOneFrame(resolveCompositionDuration({ authoredDurationSeconds: null, clipEndsSeconds: clipEnds })
31
+ .seconds);
32
+ }
33
+ /** The latest of the root's declared length and its direct sub-compositions' ends. */
34
+ export function resolveAuthoredCompositionFloorSeconds(root, startResolver) {
35
+ const subCompositionEnds = [];
36
+ for (const node of root.querySelectorAll("[data-composition-id][data-start]")) {
37
+ if (node.parentElement?.closest("[data-composition-id]") !== root)
38
+ continue;
39
+ const start = startResolver.resolveStartForElement(node, 0);
40
+ const duration = startResolver.resolveDurationForElement(node);
41
+ if (!Number.isFinite(start) || duration == null || duration <= 0)
42
+ continue;
43
+ subCompositionEnds.push(Math.max(0, start) + duration);
44
+ }
45
+ const declared = parseStrictFiniteTimingNumber(root.getAttribute("data-duration"));
46
+ return aboveOneFrame(resolveCompositionDuration({
47
+ authoredDurationSeconds: null,
48
+ clipEndsSeconds: [declared, ...subCompositionEnds],
49
+ }).seconds);
50
+ }
51
+ const isCompositionHost = (node) => node.hasAttribute("data-composition-id") || node.hasAttribute("data-composition-src");
52
+ /** The last-resort length: the latest end among the root's timed clips. Until every clip's length
53
+ * is known it is unresolved, so a renderer that reads it once cannot lock in a short one.
54
+ * `unregisteredLottie`: a Lottie library is loaded, so animations may still register. */
55
+ export function resolveContentDerivedDuration(root, startResolver, { unregisteredLottie }) {
56
+ const clipEnds = [];
57
+ for (const node of root.querySelectorAll("[data-start]")) {
58
+ const start = startResolver.resolveStartForElement(node, 0);
59
+ if (!Number.isFinite(start))
60
+ continue;
61
+ const duration = startResolver.resolveDurationForElement(node);
62
+ if (duration != null)
63
+ clipEnds.push(Math.max(0, start) + duration);
64
+ else if (isMediaElement(node) || isCompositionHost(node))
65
+ clipEnds.push(null);
66
+ }
67
+ if (unregisteredLottie || root.querySelector("[data-lottie-src]"))
68
+ clipEnds.push(null);
69
+ const result = resolveCompositionDuration({
70
+ authoredDurationSeconds: null,
71
+ clipEndsSeconds: clipEnds,
72
+ });
73
+ return result.pendingClips > 0
74
+ ? { ...result, seconds: null, source: "unresolved", reason: "a clip's length is pending" }
75
+ : result;
76
+ }
77
+ /** A declared root length is the length (a longer timeline is cut off); else the timeline, the
78
+ * floors and the fallback, whichever is longest; else the length derived from the clips. */
79
+ export function resolveCompositionLengthSeconds(input) {
80
+ if (input.declared !== null && Number.isFinite(input.declared) && input.declared > 0) {
81
+ return input.declared;
82
+ }
83
+ const timeline = aboveOneFrame(input.timeline());
84
+ const floor = Math.max(0, ...input.floors().map((seconds) => seconds ?? 0));
85
+ const fallback = Number.isFinite(input.fallback) && input.fallback > MIN_VALID_TIMELINE_DURATION_SECONDS
86
+ ? input.fallback
87
+ : 0;
88
+ let seconds;
89
+ if (timeline !== null)
90
+ seconds = Math.max(timeline, floor, fallback);
91
+ else if (aboveOneFrame(floor) !== null)
92
+ seconds = Math.max(floor, fallback);
93
+ else if (fallback > 0)
94
+ seconds = fallback;
95
+ else
96
+ seconds = input.derived();
97
+ return seconds > 0 ? seconds : 0;
98
+ }
99
+ /** Size, frame rate and length of a composition nothing is running (a server-parsed or detached
100
+ * document): no timelines, no adapters, and media without a known source length is pending. */
101
+ export function readStaticCompositionMeta(doc) {
102
+ const root = findRootCompositionElement(doc);
103
+ if (!root)
104
+ return null;
105
+ const resolver = createRuntimeStartTimeResolver({
106
+ timelineRegistry: {},
107
+ includeAuthoredTimingAttrs: true,
108
+ documentRef: doc,
109
+ });
110
+ const durationSeconds = resolveCompositionLengthSeconds({
111
+ declared: parseStrictFiniteTimingNumber(root.getAttribute("data-duration")),
112
+ timeline: () => null,
113
+ floors: () => [
114
+ resolveMediaWindowDurationSeconds(doc, {
115
+ mediaStart: resolver.resolveMediaStartForElement,
116
+ mediaDuration: resolveMediaElementDurationSeconds,
117
+ }),
118
+ resolveAuthoredCompositionFloorSeconds(root, resolver),
119
+ ],
120
+ fallback: 0,
121
+ derived: () => resolveContentDerivedDuration(root, resolver, { unregisteredLottie: false }).seconds ?? 0,
122
+ });
123
+ return { ...readCompositionSize(root), fps: createRuntimeState().canonicalFps, durationSeconds };
124
+ }
125
+ //# sourceMappingURL=compositionLength.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compositionLength.js","sourceRoot":"","sources":["../../src/runtime/compositionLength.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,95 @@
1
+ import type { RuntimeDeterministicAdapter, RuntimeTimelineLike } from "./types";
2
+ import type { RuntimeMediaClip } from "./media";
3
+ import type { TransportClock } from "./clock";
4
+ export type RuntimeState = {
5
+ capturedTimeline: RuntimeTimelineLike | null;
6
+ isPlaying: boolean;
7
+ currentTime: number;
8
+ deterministicAdapters: RuntimeDeterministicAdapter[];
9
+ canonicalFps: number;
10
+ bridgeMuted: boolean;
11
+ bridgeVolume: number;
12
+ /**
13
+ * Internal mute of audible media output, owned by the audio-ownership
14
+ * protocol between the parent (`<hyperframes-player>`) and this runtime.
15
+ * Independent of `bridgeMuted` (the user's mute preference). When the
16
+ * parent takes over audible playback via parent-frame proxies, it sets
17
+ * this to `true` so the runtime keeps driving timed media for frame
18
+ * accuracy but produces no audio of its own.
19
+ */
20
+ mediaOutputMuted: boolean;
21
+ /**
22
+ * Disable runtime ownership of native media elements. Slideshow presenter
23
+ * mode keeps the slide timeline paused while users interact with embedded
24
+ * media, so the runtime must not auto-play, auto-pause, seek, or volume-sync
25
+ * those native elements on every transport tick.
26
+ */
27
+ nativeMediaSyncDisabled: boolean;
28
+ /**
29
+ * Disable the runtime's WebAudio replacement for native <audio> elements.
30
+ * Slideshow presenter/audience windows mirror native media element events
31
+ * across browsers, so muting those elements for WebAudio ownership breaks
32
+ * audible presenter playback and remote sync.
33
+ */
34
+ webAudioMediaDisabled: boolean;
35
+ /**
36
+ * Latch so the `media-autoplay-blocked` outbound message is posted at most
37
+ * once per runtime session. The parent only needs the first signal — it
38
+ * takes over playback and further rejections are the same problem.
39
+ */
40
+ mediaAutoplayBlockedPosted: boolean;
41
+ /**
42
+ * One-shot flag: force a hard media sync on the next tick. Set on
43
+ * play/pause/seek/rate transitions to immediately correct any
44
+ * accumulated sub-threshold drift from pause/play toggling.
45
+ * Consumed (reset to false) by `syncMediaForCurrentState`.
46
+ */
47
+ mediaForceSyncNextTick: boolean;
48
+ playbackRate: number;
49
+ bridgeLastPostedFrame: number;
50
+ bridgeLastPostedAt: number;
51
+ bridgeLastPostedPlaying: boolean;
52
+ bridgeLastPostedMuted: boolean;
53
+ /**
54
+ * Max interval (ms) between outbound timeline samples on the parent-frame
55
+ * control bridge. The bridge posts on every changed frame, but also at
56
+ * least once per this interval so a paused/idle timeline still confirms
57
+ * its position to any listener.
58
+ *
59
+ * **Cross-reference (do not change in isolation)**: the parent-frame
60
+ * audio-mirror loop in `<hyperframes-player>` waits for
61
+ * `MIRROR_REQUIRED_CONSECUTIVE_DRIFT_SAMPLES` consecutive over-threshold
62
+ * samples before issuing a `currentTime` correction. The product of
63
+ * those two constants is the worst-case A/V re-sync latency:
64
+ *
65
+ * worst_case_correction_latency_ms
66
+ * ≈ MIRROR_REQUIRED_CONSECUTIVE_DRIFT_SAMPLES × bridgeMaxPostIntervalMs
67
+ *
68
+ * Today: `2 × 80 ms = 160 ms`, which sits comfortably under the
69
+ * perceptual A/V re-sync tolerance. If you raise this interval, audit
70
+ * `MIRROR_REQUIRED_CONSECUTIVE_DRIFT_SAMPLES` in
71
+ * `packages/player/src/parent-media.ts` — leaving it at `2` will
72
+ * silently push correction latency past the tolerance budget.
73
+ */
74
+ bridgeMaxPostIntervalMs: number;
75
+ controlBridgeHandler: ((event: MessageEvent) => void) | null;
76
+ beforeUnloadHandler: (() => void) | null;
77
+ injectedCompStyles: HTMLStyleElement[];
78
+ injectedCompScripts: HTMLScriptElement[];
79
+ injectedCompLinks: HTMLLinkElement[];
80
+ cachedTimedMediaEls: Array<HTMLVideoElement | HTMLAudioElement>;
81
+ cachedMediaClips: RuntimeMediaClip[];
82
+ cachedVideoClips: RuntimeMediaClip[];
83
+ cachedMediaTimelineDurationSeconds: number;
84
+ tornDown: boolean;
85
+ /**
86
+ * Single-clock transport. The sole time authority — GSAP is always
87
+ * paused and seeked to `clock.now()` on each rAF tick. Eliminates
88
+ * the two-clock drift problem described in issue #668.
89
+ */
90
+ transportClock: TransportClock | null;
91
+ /** rAF ID for the single-clock tick loop. */
92
+ transportRafId: number | null;
93
+ };
94
+ export declare function createRuntimeState(): RuntimeState;
95
+ //# sourceMappingURL=state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/runtime/state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,2BAA2B,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAChF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,MAAM,MAAM,YAAY,GAAG;IACzB,gBAAgB,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAC7C,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,qBAAqB,EAAE,2BAA2B,EAAE,CAAC;IACrD,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB;;;;;;;OAOG;IACH,gBAAgB,EAAE,OAAO,CAAC;IAC1B;;;;;OAKG;IACH,uBAAuB,EAAE,OAAO,CAAC;IACjC;;;;;OAKG;IACH,qBAAqB,EAAE,OAAO,CAAC;IAC/B;;;;OAIG;IACH,0BAA0B,EAAE,OAAO,CAAC;IACpC;;;;;OAKG;IACH,sBAAsB,EAAE,OAAO,CAAC;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,uBAAuB,EAAE,OAAO,CAAC;IACjC,qBAAqB,EAAE,OAAO,CAAC;IAC/B;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,uBAAuB,EAAE,MAAM,CAAC;IAChC,oBAAoB,EAAE,CAAC,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IAC7D,mBAAmB,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC;IACzC,kBAAkB,EAAE,gBAAgB,EAAE,CAAC;IACvC,mBAAmB,EAAE,iBAAiB,EAAE,CAAC;IACzC,iBAAiB,EAAE,eAAe,EAAE,CAAC;IACrC,mBAAmB,EAAE,KAAK,CAAC,gBAAgB,GAAG,gBAAgB,CAAC,CAAC;IAChE,gBAAgB,EAAE,gBAAgB,EAAE,CAAC;IACrC,gBAAgB,EAAE,gBAAgB,EAAE,CAAC;IACrC,kCAAkC,EAAE,MAAM,CAAC;IAC3C,QAAQ,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,cAAc,EAAE,cAAc,GAAG,IAAI,CAAC;IACtC,6CAA6C;IAC7C,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B,CAAC;AAEF,wBAAgB,kBAAkB,IAAI,YAAY,CAiCjD"}
@@ -0,0 +1,35 @@
1
+ export function createRuntimeState() {
2
+ return {
3
+ capturedTimeline: null,
4
+ isPlaying: false,
5
+ currentTime: 0,
6
+ deterministicAdapters: [],
7
+ canonicalFps: 30,
8
+ bridgeMuted: false,
9
+ bridgeVolume: 1,
10
+ mediaOutputMuted: false,
11
+ nativeMediaSyncDisabled: false,
12
+ webAudioMediaDisabled: false,
13
+ mediaAutoplayBlockedPosted: false,
14
+ mediaForceSyncNextTick: false,
15
+ playbackRate: 1,
16
+ bridgeLastPostedFrame: -1,
17
+ bridgeLastPostedAt: 0,
18
+ bridgeLastPostedPlaying: false,
19
+ bridgeLastPostedMuted: false,
20
+ bridgeMaxPostIntervalMs: 80,
21
+ controlBridgeHandler: null,
22
+ beforeUnloadHandler: null,
23
+ injectedCompStyles: [],
24
+ injectedCompScripts: [],
25
+ injectedCompLinks: [],
26
+ cachedTimedMediaEls: [],
27
+ cachedMediaClips: [],
28
+ cachedVideoClips: [],
29
+ cachedMediaTimelineDurationSeconds: 0,
30
+ tornDown: false,
31
+ transportClock: null,
32
+ transportRafId: null,
33
+ };
34
+ }
35
+ //# sourceMappingURL=state.js.map