mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-23 17:52:49 +00:00
* perf(app): reduce avoidable work when opening large diffs Large snapshots were recursively reconstructed for reference stability, while native scroll worklets captured complete file models. Preserve identity at the data producers and prepare text for the visible window without rebuilding unchanged files. * test(app): await commit diff query completion without polling * chore(app): remove profiling artifacts from the source tree
99 lines
3.2 KiB
TypeScript
99 lines
3.2 KiB
TypeScript
import { replaceEqualDeep } from "@tanstack/react-query";
|
|
import type { ParsedDiffFile, SubscribeCheckoutDiffResponse } from "@getpaseo/protocol/messages";
|
|
|
|
type DiffPayload = Omit<SubscribeCheckoutDiffResponse["payload"], "subscriptionId">;
|
|
|
|
/** File identity owns text-model reuse. Never reconstruct the hunk/token graph. */
|
|
export function retainDiffFiles(
|
|
previous: ParsedDiffFile[],
|
|
incoming: ParsedDiffFile[],
|
|
): ParsedDiffFile[] {
|
|
if (previous === incoming) return previous;
|
|
const byPath = new Map(previous.map((file) => [file.path, file]));
|
|
let unchanged = previous.length === incoming.length;
|
|
const files = incoming.map((file, index) => {
|
|
const old = byPath.get(file.path);
|
|
const retained = old && equalFile(old, file) ? old : file;
|
|
unchanged &&= retained === previous[index];
|
|
return retained;
|
|
});
|
|
return unchanged ? previous : files;
|
|
}
|
|
|
|
export function shareCheckoutDiff(previous: unknown, incoming: unknown): DiffPayload {
|
|
const next = incoming as DiffPayload;
|
|
const old = previous as DiffPayload | undefined;
|
|
if (!old || old === next) return next;
|
|
const files = retainDiffFiles(old.files, next.files);
|
|
const error = replaceEqualDeep(old.error, next.error);
|
|
return files === old.files &&
|
|
error === old.error &&
|
|
old.cwd === next.cwd &&
|
|
old.requestId === next.requestId &&
|
|
old.diffTooLarge === next.diffTooLarge
|
|
? old
|
|
: { ...next, files, error };
|
|
}
|
|
|
|
export function shareCommitFileDiff(
|
|
previous: unknown,
|
|
incoming: unknown,
|
|
): { file: ParsedDiffFile | null } {
|
|
const next = incoming as { file: ParsedDiffFile | null };
|
|
const old = previous as typeof next | undefined;
|
|
return old &&
|
|
(old.file === next.file || (old.file && next.file && equalFile(old.file, next.file)))
|
|
? old
|
|
: next;
|
|
}
|
|
|
|
function equalFile(left: ParsedDiffFile, right: ParsedDiffFile): boolean {
|
|
if (left === right) return true;
|
|
if (
|
|
left.path !== right.path ||
|
|
left.oldPath !== right.oldPath ||
|
|
left.status !== right.status ||
|
|
left.isNew !== right.isNew ||
|
|
left.isDeleted !== right.isDeleted ||
|
|
left.additions !== right.additions ||
|
|
left.deletions !== right.deletions ||
|
|
left.hunks.length !== right.hunks.length
|
|
)
|
|
return false;
|
|
for (let h = 0; h < left.hunks.length; h++) {
|
|
const a = left.hunks[h]!;
|
|
const b = right.hunks[h]!;
|
|
if (a === b) continue;
|
|
if (
|
|
a.oldStart !== b.oldStart ||
|
|
a.oldCount !== b.oldCount ||
|
|
a.newStart !== b.newStart ||
|
|
a.newCount !== b.newCount ||
|
|
a.lines.length !== b.lines.length
|
|
)
|
|
return false;
|
|
if (!equalLines(a.lines, b.lines)) return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function equalLines(
|
|
left: ParsedDiffFile["hunks"][number]["lines"],
|
|
right: ParsedDiffFile["hunks"][number]["lines"],
|
|
): boolean {
|
|
for (let l = 0; l < left.length; l++) {
|
|
const x = left[l]!;
|
|
const y = right[l]!;
|
|
if (x === y) continue;
|
|
if (x.type !== y.type || x.content !== y.content) return false;
|
|
if (x.tokens === y.tokens) continue;
|
|
if (!x.tokens || !y.tokens || x.tokens.length !== y.tokens.length) return false;
|
|
for (let t = 0; t < x.tokens.length; t++) {
|
|
const p = x.tokens[t]!;
|
|
const q = y.tokens[t]!;
|
|
if (p.text !== q.text || p.style !== q.style) return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|