feat(canvas): 画布工作台 - 新增生成副本并修复大型画布性能、素材同步与删除校验

统一图片与视频副本的生成落点并保留参考连接。\n优化大型画布节点虚拟化、媒体懒加载、拖拽与详情进入路径。\n修复素材主版本 ID 同步及删除时的画布独立引用校验。
This commit is contained in:
ddCat
2026-09-01 14:57:05 +08:00
parent 434f63e153
commit 3f4a9ea3d0
45 changed files with 1348 additions and 286 deletions

View File

@@ -1,7 +1,7 @@
import { describe, expect, test } from "bun:test";
import { canvasNodeMaterialSummary, canvasNodeSearchContext, canvasNodeSearchTimes, searchCanvasNodes } from "@/lib/canvas/canvas-node-search";
import { normalizeCanvasNodeTimestamps, stampCanvasNodeChanges } from "@/lib/canvas/canvas-node-timestamps";
import { normalizeCanvasNodeTimestamps, stampCanvasNodeChanges, updateCanvasNodes } from "@/lib/canvas/canvas-node-timestamps";
import { CanvasNodeType, type CanvasNodeData } from "@/types/canvas";
function node(id: string, patch: Partial<CanvasNodeData> = {}): CanvasNodeData {
@@ -48,6 +48,21 @@ describe("canvas node timestamps", () => {
const updated = stampCanvasNodeChanges([previous], [hydrated], "2026-08-28T02:00:00.000Z");
expect(updated[0]?.updatedAt).toBe("2026-08-28T01:00:00.000Z");
});
test("batches media metadata updates while preserving untouched node references", () => {
const first = node("first");
const second = node("second");
const nodes = [first, second];
const next = updateCanvasNodes(nodes, new Map([
["first", (current) => ({ ...current, metadata: { ...current.metadata, naturalWidth: 1920 } })],
["second", (current) => ({ ...current, metadata: { ...current.metadata, naturalHeight: 1080 } })],
]), "2026-08-28T03:00:00.000Z");
expect(next).not.toBe(nodes);
expect(next[0]).not.toBe(first);
expect(next[1]).not.toBe(second);
expect(next[0].metadata?.naturalWidth).toBe(1920);
expect(next[1].metadata?.naturalHeight).toBe(1080);
});
});
describe("canvas node search", () => {