feat(sdk): getVariableValue({ base: true }) reads pre-override declared defaults#2499
Conversation
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
miga-heygen
left a comment
There was a problem hiding this comment.
Review — #2499 feat(sdk): getVariableValue({ base: true }) reads pre-override declared defaults
Verdict: LGTM
SSOT check
| Item | Owner |
|---|---|
| Base snapshot capture | openComposition() — single site, BEFORE applyOverrideSet |
| Base vs live decision | getVariableValue() — single branch: opts?.base && id in baseVariableDefaults |
| Type signature | types.ts — single interface update |
The baseVariableDefaults are readonly and captured once. Mid-session declared variables correctly fall through to the live default (their declaration IS their base). readDeclaredDefaults runs before applyOverrideSet — the timing is load-bearing and correctly placed.
Tests: 4 cases covering override fold, setVariableValue stability, undeclared id, and mid-session declaration. No blockers.
james-russo-rames-d-jusso
left a comment
There was a problem hiding this comment.
Reviewed at db5e0622. Layering on Miga's LGTM.
Blockers
(none)
Concerns
(none)
Nits
(none)
Green notes
🟢 Snapshot capture ordering is load-bearing and correctly placed. readDeclaredDefaults(...) runs on packages/sdk/src/session.ts:903 — AFTER parseMutable(html) on :895, BEFORE applyOverrideSet(parsed, opts.overrides) on :910. Any reordering would silently corrupt the base snapshot (post-fold declarations would leak override values into baseVariableDefaults and getVariableValue({ base: true }) would return the currently-active value, not the authored one). Worth adding a runtime assertion or a comment inline on those three lines if this file gets touched again, but the current test suite pins the invariant by construction: the "override fold" test would break if the order flipped.
🟢 id in this.baseVariableDefaults reads authored props, not prototype-inherited. readDeclaredDefaults returns a plain object literal (I traced it in the module) so in is safe. The "mid-session declared" fallthrough behaves correctly — new declarations don't appear on the base snapshot, so id in baseVariableDefaults is false and we fall to getVariableValues() (the live default).
🟢 API surface addition is optional-only. getVariableValue(id) → getVariableValue(id, opts?) — no caller break, no docs churn on existing usage. The type in types.ts matches. Small, well-scoped.
🟢 Undo-to-base semantics: session-lifetime snapshot vs. current-declaration base. The captured snapshot is fixed at open, so undeclare → redeclare mid-session returns the ORIGINAL open-time default rather than the current declaration's default. Docs say "as authored at open" — matches the code. For the stated use case (host replaying an undo that removes a var.<id> override), this is correct — the original template's authored default is what an undo-to-base should restore. If a future use case wants "current declaration's base," it'd need a separate option; the current shape doesn't preclude that.
Verdict framing
Small, well-scoped SDK reader that plugs a real host-side undo-replay gap. LGTM from my side.

Summary
Part 1/4 of the SDK gap-closure stack. Adds
getVariableValue(id, { base: true })so hosts can recover a variable’s declared default as authored when the session opened.Why
T3 overrides and later
setVariableValuecalls destructively fold values into declaration defaults. Without a snapshot, a host replaying an undo-to-base cannot recover the authored value.Implementation
{ base?: boolean }parameter to the runtime and publicCompositioninterface.Validation
src/session.variables.test.ts: 14 tests passing, including four new base-default cases.