vite-plugin-entry-shaking-debugger
Version:
Debugger for vite-plugin-entry-shaking
163 lines (141 loc) • 5.19 kB
text/typescript
import { diff_match_patch as Diff } from 'diff-match-patch';
/** Diffs request payload sent to Worker. */
export interface DiffsRequestPayload {
/** Absolute path to the file. */
id: string;
/** Original source content. */
from: string;
/** Updated source content. */
to: string;
}
/** Diffs response payload received from Worker. */
export interface DiffsResponsePayload {
/** Absolute path to the file. */
id: string;
/** All diffs content (source code with diff lines). */
result: string;
}
type DiffAction = -1 | 0 | 1;
type DiffDefinition = [DiffAction, string];
const equalsOrDeletes = [Diff.DIFF_DELETE, Diff.DIFF_EQUAL] as [DiffAction, DiffAction];
const equalsOrInserts = [Diff.DIFF_INSERT, Diff.DIFF_EQUAL] as [DiffAction, DiffAction];
self.onmessage = (message: MessageEvent) => {
const { id, from, to } = message.data as DiffsRequestPayload;
const diffs = getDiffs(from, to) as DiffDefinition[];
const result = concatDiffs(diffs);
const output: DiffsResponsePayload = { id, result };
self.postMessage(output);
};
function getDiffs(from: string, to: string) {
const diff = new Diff();
const result = diff.diff_main(from, to);
diff.diff_cleanupSemantic(result);
return result;
}
/**
* I'm way too stupid so this is disgusting and absolutely not robust at all.
* Sorry, but please feel free to contribute and do it the propery way :)
*/
function concatDiffs(diffs: DiffDefinition[]) {
const allLines: string[] = [];
let incrementalAddition: string | undefined;
let incrementalRemoval: string | undefined;
const addLine = (op: number, line: string) => {
switch (op) {
case Diff.DIFF_INSERT:
allLines.push(`${line} // [!code ++]`);
break;
case Diff.DIFF_DELETE:
allLines.push(`${line} // [!code --]`);
break;
default:
allLines.push(line);
}
};
diffs.forEach((diff) => {
const [op, text] = diff;
if (text === '\n') {
if (incrementalRemoval) addLine(Diff.DIFF_DELETE, incrementalRemoval);
if (incrementalAddition) addLine(Diff.DIFF_INSERT, incrementalAddition);
addLine(op, '');
return;
}
const lines = text.split('\n');
const lastLineIndex = lines.length - 1;
if (lines.length === 1) {
if (!incrementalAddition && !incrementalRemoval) {
const [line] = lines;
incrementalAddition = line;
incrementalRemoval = line;
}
if (incrementalRemoval && op === Diff.DIFF_DELETE) incrementalRemoval += lines[0];
if (incrementalAddition && op === Diff.DIFF_INSERT) incrementalAddition += lines[0];
return;
}
lines.forEach((line, index) => {
// First item.
if (index === 0) {
// If there isn't any incremental addition or removal, add the line.
if (!incrementalAddition && !incrementalRemoval) {
addLine(op, line);
}
// If there is an incremental removal, add the line and clear.
if (incrementalRemoval && equalsOrDeletes.includes(op)) {
addLine(Diff.DIFF_DELETE, incrementalRemoval + line);
incrementalRemoval = undefined;
}
// If there is an incremental addition, add the line and clear.
if (incrementalAddition && equalsOrInserts.includes(op)) {
addLine(Diff.DIFF_INSERT, incrementalAddition + line);
incrementalAddition = undefined;
}
return;
}
// If last item and unterminated line.
if (index === lastLineIndex) {
const isEOL = !line.trim().length;
// If there isn't any incremental addition or removal and is EOL, add the line.
if (!incrementalAddition && !incrementalRemoval && isEOL) {
return;
}
if (isEOL) {
// If there is an incremental removal and is EOLadd the line and clear.
if (incrementalRemoval && equalsOrDeletes.includes(op)) {
addLine(op, incrementalRemoval + line);
incrementalRemoval = undefined;
}
// If there is an incremental addition and is EOL add the line and clear.
if (incrementalAddition && equalsOrInserts.includes(op)) {
addLine(op, incrementalAddition + line);
incrementalAddition = undefined;
}
return;
}
switch (op) {
case Diff.DIFF_INSERT:
incrementalAddition = (incrementalAddition ?? '') + line;
break;
case Diff.DIFF_DELETE:
incrementalRemoval = (incrementalRemoval ?? '') + line;
break;
default:
incrementalRemoval = (incrementalRemoval ?? '') + line;
incrementalAddition = (incrementalAddition ?? '') + line;
break;
}
}
if (!incrementalAddition && !incrementalRemoval) {
addLine(Diff.DIFF_EQUAL, line);
return;
}
if (!incrementalAddition && op === Diff.DIFF_INSERT) {
addLine(Diff.DIFF_INSERT, line);
}
if (!incrementalRemoval && op === Diff.DIFF_DELETE) {
addLine(Diff.DIFF_DELETE, line);
}
});
});
const output = allLines.join('\n');
return output;
}