Repository navigation
fix(core): a host inside a scene keeps its own timeline when its file shares a composition id - #7143
Conversation
… shares a composition id
There was a problem hiding this comment.
Verdict: APPROVE · 0 blocker · 1 important · 0 nits · head b27c744e
- important:
packages/core/src/compiler/inlineSubCompositions.ts:476-480: the optional Comments ratchet fails on this head. The file's comment share rose from 20.1% to 20.3% because of 2 added comment lines: the extra docstring line at:228and the new inline comment at:480. Cutting one of them should turn it green. The check isn't required, so it doesn't block this approval.
What I checked
- The test fails without the fix. I reverted only
inlineSubCompositions.tstoorigin/main. The new test then fails withexpected [ 'caption-style', 'caption-style' ] to deeply equal ArrayContaining ["take-a","take-b"], and the repeated-scenes goldens fail too. At head, both files pass, 5/5 tests. - The new path matches existing ones. A nested host now takes the same branch as a top-level host the map has already met, and as the producer path that passes no map. The producer already read nested hosts from their own attribute, so after this change the bundler and the producer agree.
- Host id differs from the file's root id.
planCompositionAssemblythen finds noinnerRoot, so the whole body, including the file's own root, is mounted under the host. That is the same as the top-level mismatch case. One consequence:data-width/data-height,data-timeline-lockedanddata-no-timelineare no longer copied from the inner root onto a nested host. Top-level hosts already behave this way. - Host id matches the file's root id. The root is flattened, and its now-redundant
data-composition-idis dropped. The host still carries the id, which is the golden diff. - No other sites need the change.
hostIdentityMapis read only here. - CI: at the time of review,
PR capturesandpreview-regressionwere green andCommentshad failed (it isn't required). The requiredCI/regression/Windows checks were still running.
There was a problem hiding this comment.
Verdict: APPROVE · 0 resolved, 1 open, 0 new · b27c744e → 99396333. The only code change is the removed inline comment. The optional Comments ratchet is still red: the file is 20.2% (168/832) against 20.1% at the base, because of the extra docstring line at inlineSubCompositions.ts:228-229. Folding that back to one line turns it green. This does not block.
There was a problem hiding this comment.
Verdict: APPROVE · 1 resolved, 0 open, 0 new · 99396333 → 186df662. The only change is the docstring, now reworded to its original 3-line length, and it still describes the behavior correctly. That should clear the Comments ratchet; its run on this head was still in progress when I approved.
…heygen-com#7155; review through 1ff4cef - heygen-com#7143: inline nested sub-composition timelines (pageBuild goldens follow upstream). - heygen-com#7151: makeOutputFolder skips mkdirSync for existing folders, so drive-root outputs like C:\ no longer fail with EPERM. - heygen-com#7154: a page that never becomes ready reports PAGE_NEVER_READY instead of a generic evaluate timeout (adapted by hand). - heygen-com#7155: cloud upload error handling. Watermarks: commit 1ff4cef, PR 7157; monitored 88. Ledger in docs/UPSTREAM_REVIEW_2026-11-04_CONTINUED.md. Co-authored-by: Miguel Ángel <[email protected]> Co-Authored-By: Claude Opus 5.5 <[email protected]>
What changed
A sub-composition host that sits inside a scene now registers its script's timeline under its own
data-composition-id, as a host inindex.htmlalready does. Before, the bundler read every host's identity from the map it builds over the root document's hosts; a host inside a scene is not in that map, so it got no runtime id and its script fell back to its file's authored id. Two such hosts whose files share an authored id (two caption layers made from one caption style, say) then registered one timeline key: the first host played the second one's content and the second played none.inlineSubCompositionsnow uses the map's entry when there is one and reads a host it lacks from its own attribute, which is what the no-map path already does.What I measured
Two caption layers of one style (each file's root and timeline id is the style's name), one per take, under hosts
caption-…-a-1andcaption-…-b-1; snapshot at 1 s (take A plays) and 8 s (take B plays):__hfTimelineCompIdindex.htmlhtmlBundler.nestedTimelines.test.tsbefore the fix: fails,expected [ 'caption-style', 'caption-style' ] to deeply equal ArrayContaining ["take-a", "take-b"]. After: passes, 3 runs in a row.pageBuild.golden.test.ts: the repeated-scenes project nests abadgescene in eachcard. Its goldens change in one way only: the nested badge's flattened inner root drops adata-composition-id="badge"that repeated its host's id. That is how a top-level scene's inner root already reads when its id equals its host's; the host still carriesdata-composition-id="badge". Updated withvitest -u.fails without the fix:
packages/core/src/compiler/htmlBundler.nestedTimelines.test.ts"gives each host inside a scene its own timeline, even when their files share a composition id".What I did NOT exercise
badge) still share one timeline key, as before this change: nested hosts get no per-instance ids the way top-level duplicates do. Not touched here.runtime/compositionLoader.ts, used when a page loads compositions live) is not changed; the snapshot above goes through the bundler.Size
Small on purpose: one decision in the bundler and the test that pins it, a separate fix from any per-instance ids for nested duplicates, so either can be reverted alone.
Size: stands alone, it is the engine half of a reported bug whose app half shipped.