forked from aws/agentcore-cli
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathdiff.ts
More file actions
82 lines (77 loc) · 2.37 KB
/
Copy pathdiff.ts
File metadata and controls
82 lines (77 loc) · 2.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/**
* Simple line-based diff utility using LCS (Longest Common Subsequence).
* Used by schema editors to show changes before saving.
*/
export interface DiffLine {
prefix: string;
value: string;
color?: 'green' | 'red';
}
/**
* Computes a line-based diff between original and current text.
* Returns an array of lines with prefixes (+, -, or space) and optional colors.
*/
export function diffLines(original: string[], current: string[]): DiffLine[] {
const rows = original.length;
const cols = current.length;
const dp: number[][] = Array.from({ length: rows + 1 }, () => Array.from({ length: cols + 1 }, () => 0));
for (let i = rows - 1; i >= 0; i -= 1) {
const row = dp[i];
if (!row) continue;
for (let j = cols - 1; j >= 0; j -= 1) {
const originalLine = original[i] ?? '';
const currentLine = current[j] ?? '';
if (originalLine === currentLine) {
row[j] = (dp[i + 1]?.[j + 1] ?? 0) + 1;
} else {
row[j] = Math.max(dp[i + 1]?.[j] ?? 0, row[j + 1] ?? 0);
}
}
}
const ops: { type: 'equal' | 'add' | 'remove'; value: string }[] = [];
let i = 0;
let j = 0;
while (i < rows && j < cols) {
const originalLine = original[i];
const currentLine = current[j];
if (originalLine !== undefined && currentLine !== undefined && originalLine === currentLine) {
ops.push({ type: 'equal', value: currentLine });
i += 1;
j += 1;
} else if ((dp[i + 1]?.[j] ?? 0) >= (dp[i]?.[j + 1] ?? 0)) {
if (originalLine !== undefined) {
ops.push({ type: 'remove', value: originalLine });
}
i += 1;
} else {
if (currentLine !== undefined) {
ops.push({ type: 'add', value: currentLine });
}
j += 1;
}
}
while (i < rows) {
const originalLine = original[i];
if (originalLine !== undefined) {
ops.push({ type: 'remove', value: originalLine });
}
i += 1;
}
while (j < cols) {
const currentLine = current[j];
if (currentLine !== undefined) {
ops.push({ type: 'add', value: currentLine });
}
j += 1;
}
return ops.map(op => {
switch (op.type) {
case 'add':
return { prefix: '+', value: op.value, color: 'green' as const };
case 'remove':
return { prefix: '-', value: op.value, color: 'red' as const };
case 'equal':
return { prefix: ' ', value: op.value };
}
});
}