Files
ttstd-infinite-canvas/web/src/lib/canvas/canvas-media-versions.ts
T
WindC0X 0e251c3c8f feat(canvas): 画布媒体工作流 - 支持批量连线、失败重试与模型能力增强
合并 PR #230。保留当前主线样式与组件结构,吸收批量连线、失败批次重试、媒体模型能力和相关后端增强,并修复集成检查发现的分辨率选择器启用条件与测试稳定性问题。
2026-08-15 15:48:16 +08:00

51 lines
2.4 KiB
TypeScript

import { nanoid } from "nanoid";
import { nextCanvasVersionLabel } from "@/lib/canvas/canvas-layout";
import type { CanvasNodeData, CanvasNodeMetadata } from "@/types/canvas";
function snapshotMetadata(metadata: CanvasNodeMetadata | undefined, rootId: string, label: string): CanvasNodeMetadata {
const snapshot = { ...metadata, versionOfNodeId: rootId, versionLabel: label, versionPrimary: false };
delete snapshot.taskId;
delete snapshot.taskStatus;
delete snapshot.taskProgress;
delete snapshot.taskStage;
delete snapshot.taskCreatedAt;
delete snapshot.taskUpdatedAt;
delete snapshot.errorDetails;
delete snapshot.generationErrorCode;
delete snapshot.failedPromptFingerprint;
delete snapshot.isBatchRoot;
delete snapshot.batchRootId;
delete snapshot.batchChildIds;
delete snapshot.batchFailedCount;
delete snapshot.primaryImageId;
delete snapshot.imageBatchExpanded;
snapshot.status = snapshot.content ? "success" : "idle";
return snapshot;
}
// 原位生成保留稳定节点 ID,同时把生成前媒体快照放入同一版本族。
export function prepareInPlaceMediaVersion(nodes: CanvasNodeData[], nodeId: string): CanvasNodeData[] {
const source = nodes.find((node) => node.id === nodeId);
if (!source?.metadata?.content) return nodes;
const rootId = source.metadata.versionOfNodeId || source.id;
const snapshotLabel = source.metadata.versionLabel || "A";
const nextLabel = nextCanvasVersionLabel(rootId, source.metadata.versionLabel ? nodes : [{ ...source, metadata: { ...source.metadata, versionOfNodeId: rootId, versionLabel: "A" } }, ...nodes.filter((node) => node.id !== source.id)]);
const snapshot: CanvasNodeData = {
...source,
id: nanoid(),
title: `${source.title.replace(/ · [A-Z]$/, "")} · ${snapshotLabel}`,
position: { x: source.position.x + 36, y: source.position.y + 36 },
parentId: undefined,
metadata: snapshotMetadata(source.metadata, rootId, snapshotLabel),
};
return [
...nodes.map((node) => {
if ((node.metadata?.versionOfNodeId || node.id) !== rootId) return node;
if (node.id !== source.id) return { ...node, metadata: { ...node.metadata, versionPrimary: false } };
return { ...node, metadata: { ...node.metadata, versionOfNodeId: rootId, versionLabel: nextLabel, versionPrimary: true } };
}),
snapshot,
];
}