( hfId: string, originalContent: string, targetPath: string, sdkSession: Composition | null | undefined, deps: CutoverDeps, )
| 477 | } |
| 478 | |
| 479 | export async function sdkDeletePersist( |
| 480 | hfId: string, |
| 481 | originalContent: string, |
| 482 | targetPath: string, |
| 483 | sdkSession: Composition | null | undefined, |
| 484 | deps: CutoverDeps, |
| 485 | ): Promise<boolean> { |
| 486 | // Resolver tripwire — runs BEFORE the cutover gate (decoupled). |
| 487 | void recordResolverParity(sdkSession, hfId, "removeElement", () => |
| 488 | Promise.resolve(originalContent), |
| 489 | ); |
| 490 | // Dark-launch gate: flag OFF → legacy server delete path. |
| 491 | if (!STUDIO_SDK_CUTOVER_ENABLED) return false; |
| 492 | if (!sdkSession || !sdkSession.getElement(hfId)) return false; |
| 493 | if (wrongCompositionFile(deps, targetPath)) return false; |
| 494 | try { |
| 495 | const before = sdkSession.serialize(); |
| 496 | sdkSession.batch(() => sdkSession.removeElement(hfId)); |
| 497 | const after = sdkSession.serialize(); |
| 498 | if (after === before) return false; |
| 499 | await persistSdkSerialize(after, targetPath, originalContent, deps, { |
| 500 | label: "Delete element", |
| 501 | }); |
| 502 | trackStudioEvent("sdk_cutover_success", { hfId, opCount: 1 }); |
| 503 | return true; |
| 504 | } catch (err) { |
| 505 | trackStudioEvent("sdk_cutover_fallback", { hfId, error: String(err) }); |
| 506 | return false; |
| 507 | } |
| 508 | } |
no test coverage detected