UNPKG

vite-plugin-entry-shaking-debugger

Version:
163 lines (141 loc) 5.19 kB
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; }