refactor(*): 稳定期治理 - 收敛核心架构、错误语义并修复跨项目数据竞态

This commit is contained in:
ddCat
2026-09-09 22:02:10 +08:00
parent bacd502f5c
commit b5f3413ded
298 changed files with 12681 additions and 26428 deletions

View File

@@ -6,7 +6,7 @@ import { createGenerationTaskSubscriptionService, type GenerationTask } from "..
import { removeCreationConversationSnapshot, updateCreationConversationSnapshot } from "../src/services/creation-conversation-store";
test("Create exposes one accessible copy action beside each displayed user prompt", async () => {
const source = await Bun.file(new URL("../src/pages/create/index.tsx", import.meta.url)).text();
const source = await Bun.file(new URL("../src/pages/create/creation-workspace.tsx", import.meta.url)).text();
expect(source).toContain('aria-label="复制提示词"');
expect(source).toContain('copyText(visiblePrompt, "提示词已复制")');
});
@@ -95,8 +95,53 @@ test("Create refresh subscriptions share one durable scheduler observation witho
});
});
test("task subscription can reconnect after an observation failure", async () => {
let queryCalls = 0;
const terminal: GenerationTask = {
id: "dreamina:reconnect-task-0001",
projectId: "create-project-0001",
type: "canvas_video",
status: "succeeded",
prompt: "fixture",
attempts: 1,
createdAt: "2026-08-13T00:00:00.000Z",
updatedAt: "2026-08-13T00:01:00.000Z",
};
const service = createGenerationTaskSubscriptionService({
async queryTask() {
queryCalls += 1;
if (queryCalls === 1) throw new Error("temporary observation failure");
return terminal;
},
async waitTask() {
throw new Error("terminal task must not enter waitTask") as never;
},
});
const previousWarn = console.warn;
console.warn = () => undefined;
try {
const first = service.subscribe([terminal.id], () => undefined);
await new Promise((resolveTick) => setTimeout(resolveTick, 0));
first();
const observed: GenerationTask[] = [];
const second = service.subscribe([terminal.id], (task) => observed.push(task));
await new Promise((resolveTick) => setTimeout(resolveTick, 0));
second();
expect(queryCalls).toBe(2);
expect(observed.at(-1)).toMatchObject({ id: terminal.id, status: "succeeded" });
} finally {
console.warn = previousWarn;
}
});
test("Create durably correlates failures that happen before the first Runtime response", async () => {
const source = await Bun.file(new URL("../src/pages/create/index.tsx", import.meta.url)).text();
const source = [
await Bun.file(new URL("../src/pages/create/index.tsx", import.meta.url)).text(),
await Bun.file(new URL("../src/pages/create/creation-types.ts", import.meta.url)).text(),
].join("\n");
expect(source).toContain("generationErrorCode?: string");
expect(source).toContain("generationOperation?: string");
expect(source).toContain("generationOperation: task.operation");
@@ -311,15 +356,15 @@ test("creation result handoff falls back by stable result order only for a compl
});
test("Create forwards owned result assets through one new canvas and the project persists before clearing the handoff", () => {
const create = readFileSync(resolve(import.meta.dir, "../src/pages/create/index.tsx"), "utf8");
const workspace = readFileSync(resolve(import.meta.dir, "../src/pages/create/creation-workspace.tsx"), "utf8");
const canvasIndex = readFileSync(resolve(import.meta.dir, "../src/pages/canvas/index.tsx"), "utf8");
const canvasProject = readFileSync(resolve(import.meta.dir, "../src/pages/canvas/project.tsx"), "utf8");
expect(create).toContain('import { creationCanvasHandoffPath, creationResultAssetIds } from "@/lib/canvas/canvas-asset-handoff"');
expect(create).toContain("const resultAssetIds = resultUrls.length ? creationResultAssetIds(assets, { messageId: item.id, taskIds: item.taskIds || [], resultUrls }) : [];");
expect(create).toContain("const canvasHandoffPath = creationCanvasHandoffPath(resultAssetIds, resultUrls.length);");
expect(create).toContain('const canvasPath = canvasHandoffPath || "/canvas";');
expect(create).toContain('<Link to={canvasPath}>{canvasHandoffPath ? "添加到画布" : "打开画布"}</Link>');
expect(workspace).toContain('import { creationCanvasHandoffPath, creationResultAssetIds } from "@/lib/canvas/canvas-asset-handoff"');
expect(workspace).toContain("const resultAssetIds = resultUrls.length ? creationResultAssetIds(assets, { messageId: item.id, taskIds: item.taskIds || [], resultUrls }) : [];");
expect(workspace).toContain("const canvasHandoffPath = creationCanvasHandoffPath(resultAssetIds, resultUrls.length);");
expect(workspace).toContain('const canvasPath = canvasHandoffPath || "/canvas";');
expect(workspace).toContain('<Link to={canvasPath}>{canvasHandoffPath ? "添加到画布" : "打开画布"}</Link>');
expect(canvasIndex).toContain('const handoffMode = mode === "handoff"');
expect(canvasIndex).toContain('mode !== "new" && mode !== "recent" && mode !== "handoff"');
expect(canvasProject).toContain('import { canvasAssetHandoffAttempt, finalizeCanvasAssetHandoff, uninsertedCanvasAssetHandoffPayloads } from "@/lib/canvas/canvas-asset-handoff"');