50 lines
2.4 KiB
TypeScript
50 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.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,
|
||
];
|
||
}
|