mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-10 22:20:14 +00:00
fix(studio): make sdk cutover transactional (#2155)
This commit is contained in:
@@ -1,7 +1,11 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { createEmptyEditHistory } from "../utils/editHistory";
|
||||
import type { EditHistoryStorageAdapter } from "../utils/editHistoryStorage";
|
||||
import { createMemoryEditHistoryStorage } from "../utils/editHistoryStorage";
|
||||
import {
|
||||
serializeStudioFileMutation,
|
||||
serializeStudioFileMutations,
|
||||
} from "../utils/studioFileMutationCoordinator";
|
||||
import {
|
||||
createPersistentEditHistoryController,
|
||||
createPersistentEditHistoryStore,
|
||||
@@ -213,6 +217,50 @@ describe("createPersistentEditHistoryController", () => {
|
||||
expect(store.snapshot().canRedo).toBe(true);
|
||||
});
|
||||
|
||||
it("waits for same-file mutations before checking an undo hash", async () => {
|
||||
const storage = createMemoryEditHistoryStorage();
|
||||
const store = createPersistentEditHistoryStore({
|
||||
projectId: "project-1",
|
||||
storage,
|
||||
initialState: createEmptyEditHistory(),
|
||||
now: () => 100,
|
||||
onChange: () => {},
|
||||
});
|
||||
await store.recordEdit({
|
||||
label: "Edit source",
|
||||
kind: "source",
|
||||
files: { "index.html": { before: "before", after: "after" } },
|
||||
});
|
||||
|
||||
let disk = "after";
|
||||
let release!: () => void;
|
||||
const blocked = new Promise<void>((resolve) => {
|
||||
release = resolve;
|
||||
});
|
||||
const writeFile = vi.fn(async (_path: string, content: string) => {
|
||||
disk = content;
|
||||
});
|
||||
const priorMutation = serializeStudioFileMutation(writeFile, "index.html", async () => {
|
||||
await blocked;
|
||||
disk = "newer-edit";
|
||||
});
|
||||
const readFile = vi.fn(async () => disk);
|
||||
const undo = store.undo({
|
||||
readFile,
|
||||
writeFile,
|
||||
serialize: (paths, task) => serializeStudioFileMutations(writeFile, paths, task),
|
||||
});
|
||||
|
||||
await Promise.resolve();
|
||||
expect(readFile).not.toHaveBeenCalled();
|
||||
release();
|
||||
await priorMutation;
|
||||
await expect(undo).resolves.toMatchObject({ ok: false, reason: "content-mismatch" });
|
||||
expect(disk).toBe("newer-edit");
|
||||
expect(writeFile).not.toHaveBeenCalled();
|
||||
expect(store.snapshot().canUndo).toBe(true);
|
||||
});
|
||||
|
||||
it("returns per-file restored/previous content so the preview can soft-apply", async () => {
|
||||
const storage = createMemoryEditHistoryStorage();
|
||||
const store = createPersistentEditHistoryStore({
|
||||
|
||||
Reference in New Issue
Block a user