mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-10 22:20:14 +00:00
fix(studio): resync the shared SDK session after a Design-panel variable promote
Reported as "template variables are broken": binding an element's field to a variable via the flat inspector's "◇ var" promote chip (or editing an already-bound field's value) wrote the correct bytes to disk, but the Variables tab kept showing the pre-edit value until the whole Studio page was hard-reloaded. Root cause: DesignPanelPromoteProvider deliberately opens its OWN SDK session (`useSdkSession(projectId, selection.sourceFile ?? activeCompPath)`) so that promoting inside a sub-composition binds the variable in the sub-comp's own file, not the host's. For the common case — a top-level element, same file as `activeCompPath` — this session is a SEPARATE in-memory `Composition` instance from the shared one `VariablesPanel` (Variables tab, Slideshow, etc.) reads. A persist through the promote provider's session never fires the shared session's own "change" event. Worse, the shared session's file-change listener runs `isSelfWriteEcho(path, content)` to decide whether to reload — but `sdkSelfWriteRegistry` is keyed by file path only, not by session instance (its own doc comment assumes "the studio process has a single SDK session lifecycle at a time"). It sees the promote provider's write registered under the same path and concludes it's its own echo, permanently suppressing the reload it actually needs. Threaded `forceReloadSdkSession` (the same mechanism every other server-side-write path in Studio already uses for exactly this "resync after a write I didn't make myself" case) from App.tsx through StudioRightPanel into DesignPanelPromoteProvider, and call it after every successful promote/setDefault persist — unconditionally, not gated on the promote target matching activeCompPath, since re-opening a file that didn't change is a harmless no-op re-parse and a path-equality guard here already produced one subtly wrong comparison (activeCompPath can be null while the shared session still defaults to "index.html") before landing on this simpler version. Verified live: editing a variable-bound field's value now updates the Variables tab immediately, no reload required. App.tsx crossed the 600-line file-size gate after threading the new prop; extracted the tiny handleAddAssetAtPlayhead wrapper into its own useAddAssetAtPlayhead hook (with a regression test) to bring it back under. Full studio suite (2639 tests) green against a fresh main; typecheck/ oxlint/oxfmt clean.
This commit is contained in:
@@ -51,6 +51,19 @@ export interface StudioRightPanelProps {
|
||||
/** Dependencies for the Slideshow persist callback, threaded from App.tsx. */
|
||||
sdkSession: Composition | null;
|
||||
publishSdkSession: NonNullable<UseSlideshowPersistParams["publishSdkSession"]>;
|
||||
/**
|
||||
* Forces THIS `sdkSession` to re-open from disk. DesignPanelPromoteProvider
|
||||
* opens its own separate SDK session scoped to the selected element's own
|
||||
* file (needed so promoting inside a sub-composition binds a variable there,
|
||||
* not on the host) — for a top-level selection that's the SAME file this
|
||||
* session already has open, so a write through that other session leaves
|
||||
* this one holding stale in-memory content. The self-write-echo registry
|
||||
* that normally suppresses redundant reloads is keyed by file path only, not
|
||||
* by session instance, so it wrongly treats the sibling session's write as
|
||||
* "our own echo" and never reloads on its own — this must be called
|
||||
* explicitly after such a write.
|
||||
*/
|
||||
forceReloadSdkSession?: () => void;
|
||||
reloadPreview: () => void;
|
||||
domEditSaveTimestampRef: MutableRefObject<number>;
|
||||
recordEdit: (entry: {
|
||||
@@ -71,6 +84,7 @@ export function StudioRightPanel({
|
||||
onToggleRecording,
|
||||
sdkSession,
|
||||
publishSdkSession,
|
||||
forceReloadSdkSession,
|
||||
reloadPreview,
|
||||
domEditSaveTimestampRef,
|
||||
recordEdit,
|
||||
@@ -336,6 +350,7 @@ export function StudioRightPanel({
|
||||
recordEdit={recordEdit}
|
||||
reloadPreview={reloadPreview}
|
||||
domEditSaveTimestampRef={domEditSaveTimestampRef}
|
||||
forceReloadSharedSdkSession={forceReloadSdkSession}
|
||||
>
|
||||
<PropertyPanel
|
||||
projectId={projectId}
|
||||
|
||||
Reference in New Issue
Block a user