fix(player,studio): resolve root timeline from DOM instead of last key (#247)

Bundled previews register a master composition alongside its sub-compositions
in `window.__timelines`, e.g. { main, intro, scene2, scene5 }. Both the
player's probe and studio's getAdapter() were using `keys[keys.length - 1]`
to pick the adapter, which returned whichever timeline was registered last.

That made the player report the final sub-composition's duration as the
video length (e.g. 3.2s instead of the master's 14s) and play/pause/seek
targeted that sub-composition instead of the full composition.

Look up the outermost `[data-composition-id]` element in the iframe DOM
and use its id to select the right timeline. Falls back to last-key when
no element is present (standalone sub-composition previews) so drill-down
views keep working.

Also restores `main`/`import` entry points on @hyperframes/player to
point at compiled dist output (the src/ paths broke workspace consumers
that only receive the published tarball).
This commit is contained in:
Miguel Ángel
2026-04-13 23:15:08 +02:00
committed by GitHub
parent 1dd898786c
commit f40447f2e8
3 changed files with 26 additions and 7 deletions
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@hyperframes/player",
"version": "0.2.5",
"version": "0.2.6",
"description": "Embeddable web component for HyperFrames compositions",
"repository": {
"type": "git",
@@ -11,13 +11,13 @@
"dist"
],
"type": "module",
"main": "./src/hyperframes-player.ts",
"types": "./src/hyperframes-player.ts",
"main": "./dist/hyperframes-player.js",
"types": "./dist/hyperframes-player.d.ts",
"exports": {
".": {
"types": "./src/hyperframes-player.ts",
"types": "./dist/hyperframes-player.d.ts",
"script": "./dist/hyperframes-player.global.js",
"import": "./src/hyperframes-player.ts",
"import": "./dist/hyperframes-player.js",
"require": "./dist/hyperframes-player.cjs"
}
},
+10 -1
View File
@@ -314,7 +314,16 @@ class HyperframesPlayer extends HTMLElement {
if (win.__timelines) {
const keys = Object.keys(win.__timelines);
if (keys.length > 0) {
const tl = win.__timelines[keys[keys.length - 1]];
// Resolve the root composition id from the DOM — the outermost
// `[data-composition-id]` element is the master. Bundled previews
// register the root composition alongside sub-compositions, and
// without this lookup Object.keys() order would make a
// sub-composition's duration hijack the overall video length.
const rootId = this.iframe.contentDocument
?.querySelector("[data-composition-id]")
?.getAttribute("data-composition-id");
const key = rootId && rootId in win.__timelines ? rootId : keys[keys.length - 1];
const tl = win.__timelines[key];
return { getDuration: () => tl.duration() };
}
}
@@ -238,7 +238,17 @@ export function useTimelinePlayer() {
if (win.__timelines) {
const keys = Object.keys(win.__timelines);
if (keys.length > 0) return wrapTimeline(win.__timelines[keys[keys.length - 1]]);
if (keys.length > 0) {
// Resolve the root composition id from the DOM — the outermost
// `[data-composition-id]` element is the master. Without this,
// Object.keys() order would let a sub-composition's timeline
// hijack play/pause/seek and the duration readout.
const rootId = iframe?.contentDocument
?.querySelector("[data-composition-id]")
?.getAttribute("data-composition-id");
const key = rootId && rootId in win.__timelines ? rootId : keys[keys.length - 1];
return wrapTimeline(win.__timelines[key]);
}
}
return null;