import { diffArrays } from "diff";
import type { BlameRange } from "~/lib/code-intel";
const MAX_EDIT_LENGTH = 20_000;
const DIFF_TIMEOUT_MS = 1000;
/** Maps each new-version line index to its old-version index (-1 when added); null if the diff gave up. */
export function mapLines(oldLines: string[], newLines: string[]): Int32Array | null {
const changes = diffArrays(oldLines, newLines, { maxEditLength: MAX_EDIT_LENGTH, timeout: DIFF_TIMEOUT_MS });
if (!changes) return null;
const map = new Int32Array(newLines.length).fill(-1);
let oldIndex = 0;
let newIndex = 0;
for (const change of changes) {
const count = change.count;
if (change.added) newIndex += count;
else if (change.removed) oldIndex += count;
else {
for (let offset = 0; offset < count; offset++) map[newIndex + offset] = oldIndex + offset;
oldIndex += count;
newIndex += count;
}
}
return map;
}
export function splitLines(text: string): string[] {
const lines = text.split("\n");
if (lines.length > 1 && lines[lines.length - 1] === "") lines.pop();
return lines;
}
export function compressRanges(owners: Array<string | null>, fallback: string): BlameRange[] {
const ranges: BlameRange[] = [];
for (let line = 0; line < owners.length; line++) {
const sha = owners[line] ?? fallback;
const last = ranges[ranges.length - 1];
if (last && last.sha === sha) last.count++;
else ranges.push({ start: line, count: 1, sha });
}