feat(canvas): 条件读取与历史 - 减少画布同步传输并校准版本
This commit is contained in:
@@ -12,11 +12,30 @@ export function sameCanvasContent(left: CanvasProject | undefined, right: Canvas
|
||||
if (!left || !right) return false;
|
||||
const a = canvasContentSnapshot(left) as Record<string, unknown>;
|
||||
const b = canvasContentSnapshot(right) as Record<string, unknown>;
|
||||
return [...new Set([...Object.keys(a), ...Object.keys(b)])].every((key) => a[key] === b[key] || canonicalize(a[key]) === canonicalize(b[key]));
|
||||
return [...new Set([...Object.keys(a), ...Object.keys(b)])].every((key) => {
|
||||
if (a[key] === b[key]) return true;
|
||||
if ((key === "nodes" || key === "connections") && Array.isArray(a[key]) && Array.isArray(b[key])) {
|
||||
const leftItems = a[key] as unknown[];
|
||||
const rightItems = b[key] as unknown[];
|
||||
return leftItems.length === rightItems.length && leftItems.every((item, index) => item === rightItems[index] || canonicalValue(item) === canonicalValue(rightItems[index]));
|
||||
}
|
||||
return canonicalValue(a[key]) === canonicalValue(b[key]);
|
||||
});
|
||||
}
|
||||
|
||||
type ContentSnapshot = ReturnType<typeof canvasContentSnapshot>;
|
||||
const contentHashes = new WeakMap<CanvasProject["nodes"], { content: ContentSnapshot; hash: Promise<string> }>();
|
||||
// Canvas content trees are immutable, so unchanged node objects can reuse their serialized comparison value.
|
||||
const canonicalValueCache = new WeakMap<object, string>();
|
||||
|
||||
function canonicalValue(value: unknown) {
|
||||
if (!value || typeof value !== "object") return canonicalize(value);
|
||||
const cached = canonicalValueCache.get(value);
|
||||
if (cached) return cached;
|
||||
const serialized = canonicalize(value);
|
||||
canonicalValueCache.set(value, serialized);
|
||||
return serialized;
|
||||
}
|
||||
|
||||
// Store updates are immutable. Reuse a hash across viewport/revision-only copies;
|
||||
// any content field/reference change invalidates it. Weak keys bound its lifetime.
|
||||
|
||||
Reference in New Issue
Block a user