Skip to content

fix(studio): wire onTrySdkPersist to sdkCutoverPersist (cutover was unwired)#1463

Open
vanceingalls wants to merge 1 commit into
06-15-feat_studio_s7.5_remove_sdk_shadow_cutover_feature_flags_make_cutover_always-onfrom
06-15-fix_studio_wire_ontrysdkpersist_to_sdkcutoverpersist_cutover_was_unwired_
Open

fix(studio): wire onTrySdkPersist to sdkCutoverPersist (cutover was unwired)#1463
vanceingalls wants to merge 1 commit into
06-15-feat_studio_s7.5_remove_sdk_shadow_cutover_feature_flags_make_cutover_always-onfrom
06-15-fix_studio_wire_ontrysdkpersist_to_sdkcutoverpersist_cutover_was_unwired_

Conversation

@vanceingalls

@vanceingalls vanceingalls commented Jun 15, 2026

Copy link
Copy Markdown
Collaborator

What

Stage 7 s7.5 declared the SDK cutover "always-on" by removing the feature flag, but
onTrySdkPersist was never actually passed to useDomEditCommitssdkCutoverPersist was
dead code in production. Every DOM edit still went through the server patch path.

This PR wires the cutover for the op types already supported by sdkCutover.ts:
inline-stylesetStyle, text-contentsetText, attribute/html-attributesetAttribute.

Why

Without this wiring, Stages 3.1–3.5 (delete, timing, GSAP panel) have no foundation to build on.
Also fixes a correctness gap: s7.5 said cutover was active but it wasn't.

How

  • Added sdkSession?: Composition | null to UseDomEditSessionParams
  • In useDomEditSession, imported sdkCutoverPersist and built an onTrySdkPersist closure
    using deps already in scope (editHistory, writeProjectFile, reloadPreview, domEditSaveTimestampRef)
  • Passed sdkSession from App.tsx into useDomEditSession (all other CutoverDeps were already threaded)
  • onTrySdkPersist is undefined when sdkSession is null/absent — no behavior change without a session

App.tsx is exactly 600 lines (at the Studio file-size gate limit).

Test plan

  • bun run build — passes (all packages)
  • bun run test in packages/sdk — 226/226 pass
  • bun run test in packages/studio — 3 pre-existing failures in useDomEditSession.test.ts
    (stale test calling shouldUseSdkCutover with a now-removed flag param); all other tests pass
  • bunx oxlint + bunx oxfmt --check — no warnings or errors on changed files
  • Pre-commit hooks (filesize, lint, format, fallow, typecheck) — all pass
  • Manual Studio smoke: style/text edit → confirm sdk_cutover_success telemetry fires (not _fallback)

…nwired)

Stage 7 s7.5 removed the feature flag and declared cutover 'always-on',
but onTrySdkPersist was never actually passed to useDomEditCommits — the
sdkCutoverPersist function was dead code in production.

Thread sdkSession through useDomEditSession params, build the
onTrySdkPersist closure there (all CutoverDeps are already in scope),
and pass sdkSession from App.tsx. Style/text/attribute/html-attribute
commits now route through SDK dispatch instead of the server patch path.

Co-authored-by: Miguel Ángel <miguel07alm@protonmail.com>

vanceingalls commented Jun 15, 2026

Copy link
Copy Markdown
Collaborator Author

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more

This stack of pull requests is managed by Graphite. Learn more about stacking.

This was referenced Jun 15, 2026

@vanceingalls vanceingalls left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the matter of #1463onTrySdkPersist finally meets sdkCutoverPersist.

Intent

A correctness fix bolted to the end of #1462: s7.5 declared the cutover always-on but never actually threaded onTrySdkPersist into useDomEditCommits, leaving sdkCutoverPersist orphaned in production. This PR adds the missing closure and the sdkSession parameter that feeds it.

Per-file observations

  • packages/studio/src/hooks/useDomEditSession.ts:231-245 — the new onTrySdkPersist builds the closure inside the hook body using deps already in scope (editHistory, writeProjectFile, reloadPreview, domEditSaveTimestampRef). Conditional construction (sdkSession ? ... : undefined) keeps the no-session path identical to pre-PR behavior. Clean.
  • packages/studio/src/App.tsx:307sdkSession is restored as a parameter to useDomEditSession. This is the very line #1462 removed two PRs earlier; the symmetry is intentional but worth pointing out for archaeology: #1462's deletion was removing the shadow-dispatch wiring, and #1463's re-addition is adding the cutover wiring. Same prop, different consumer. A one-line comment on the call-site noting "now powers cutover, no longer shadow dispatch" would save a future grep.

Cross-PR contract drift

Per #1471's later rework, this onTrySdkPersist closure grows a fifth options argument (label/coalesceKey/skipRefresh) and a compositionPath field on the CutoverDeps. Both are forward-compatible — undefined trailing args are tolerated — so #1463 standing alone is not broken by the later expansion. But the fix shipped in #1463 silently loses the @font-face prepareContent guard until #1471 lands; any in-between merge of this PR would route font-bearing edits through the SDK and drop the injected font. Worth flagging in the PR description so the team treats #1471 as a same-train co-requisite, not a follow-up.

Stale-base hazard intersection

App.tsx is one of the stack's hotspot files (also touched by main's #1491 master-view fix and #1492 telemetry funnel). The diff at line 307 here is tiny — a single property addition inside the useDomEditSession props object — and unlikely to conflict with #1491/#1492's region of App.tsx. But auditable only against the actual rebase.

CI

Same inherited preflight format drift on gsapSerialize.ts; same downstream cascade. No logic failures on this PR's diff.

Verdict

clear-with-nits at 9bde352198a02352849ff8b722787d44fc11029a — the bug being fixed is real (dead sdkCutoverPersist since s7.5 shipped) and the fix is minimal. Worth noting in the PR body that prepareContent-bearing edits (custom-font injection) are silently routed through the SDK between this PR and #1471, so the train should land together. Re-verify if HEAD moves before stamp.

Review by Via

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant