Diffine
Um motor de comparação e um visualizador lado a lado para texto e para imagens, publicados como biblioteca React e como pacote Flutter. Emparelha duas versões linha a linha e, dentro das linhas alteradas, palavra a palavra, compara duas imagens píxel a píxel e desenha o resultado com os dois lados à mesma altura, pelo que a aplicação não tem de construir nem a comparação nem o alinhamento.
Sobre este projeto
O Diffine descobre o que mudou entre duas versões e põe isso no ecrã, para texto e para imagens, em React e em Flutter. A comparação e a vista são uma só biblioteca, e não um pacote de diferenças com um visualizador por cima: as duas metades encontram-se num valor. O diffText devolve linhas, alterações e contagens, e o diffImage devolve uma máscara, as regiões alteradas como retângulos e as contagens, sem componente nem widget em nenhum dos dois. A vista é um dos consumidores desse valor e não o único caminho até ele, pelo que a mesma comparação pode ser impressa num terminal, executada num worker ou confrontada com um limiar numa compilação. Um patch unificado também é uma comparação: o parsePatch lê um e converte-o nesse mesmo valor, e o formatPatch volta a escrevê-lo.
O texto é emparelhado em dois níveis, numa só passagem. Primeiro juntam-se as linhas aos pares e depois, dentro de um par que foi editado e não substituído, as palavras ou os caracteres que se moveram mesmo. A vista desenha isso em dois painéis mantidos à mesma altura, com ligações sobre o intervalo, e cada parte dela é uma opção com um valor por omissão: os números de linha, a mudança de linha, o alinhamento, as ligações, a vista unificada e o recolhimento das linhas que ninguém editou. Um modo de edição coloca um campo sobre cada painel e volta a calcular a comparação a cada tecla premida. As imagens comparam-se lado a lado, sobrepostas em transparência, com uma cortina deslizante ou apenas pela máscara, e a comparação aceita uma tolerância, ignora a suavização deixada por um renderizador e encontra o deslocamento entre duas capturas que não estão alinhadas; o diffImages compara mais de duas de uma vez, e o imageSimilarity responde com um único número. Ler sem rato resulta, porque cada painel é uma região que recebe o foco, os botões que saltam de uma alteração para a seguinte têm um nome, e o que mudou é anunciado assim que se mexe.
A instalação é o pacote e uma linha de CSS na web, e uma importação em Flutter. Cada pacote tem uma única dependência: o de React acrescenta o highlight.js para o realce de sintaxe, carregado uma gramática de cada vez através de uma importação dinâmica, para que uma comparação de texto simples não descarregue nada dele, e o de Flutter acrescenta o characters, que o Flutter já inclui. O react e o react-dom são dependências de par, portanto usam-se as cópias que a aplicação já tem. Os dois pacotes partilham o motor e a paleta até ao último valor de cor, e o tema escuro segue a definição do sistema. O pacote React é ESM com declarações de TypeScript, e a sua raiz é apenas o motor, com os visualizadores em diffine-react/text-diff e diffine-react/image-diff, pelo que uma aplicação que só quer a comparação não arrasta nenhum visualizador atrás de si.
Funcionalidades
Site de documentação
Tipos de TypeScript
Vários idiomas
Verificado por testes
Multiplataforma
Acessível de origem
Modo escuro
Permite tree shaking
