Skip to content

πŸ“œ A powerful, customizable diff-match-patch library for Svelte with TypeScript support

License

Notifications You must be signed in to change notification settings

humanspeak/svelte-diff-match-patch

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

18 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

@humanspeak/svelte-diff-match-patch

A powerful, customizable diff-match-patch component for Svelte with TypeScript support.

NPM version Build Status Coverage Status License Downloads CodeQL Install size Code Style: Trunk TypeScript Types Maintenance

Features

  • πŸš€ High-performance diff algorithm implementation
  • πŸ’ͺ Complete TypeScript support with strict typing
  • 🎨 Customizable diff rendering with CSS classes OR svelte snippets
  • πŸ”’ Safe and efficient text comparison
  • 🎯 Configurable cleanup algorithms (semantic and efficiency)
  • πŸ§ͺ Comprehensive test coverage (vitest and playwright)
  • πŸ”„ Svelte 5 runes compatibility
  • ⚑ Configurable timeout for large text comparisons
  • πŸ“Š Detailed timing and diff statistics
  • 🎨 Customizable diff highlighting styles
  • πŸ” Real-time diff updates

Recent Updates

New Features

  • Added detailed timing information for diff operations
  • Enhanced cleanup algorithms for better diff results
  • Improved performance for large text comparisons
  • Added TypeScript types for all component props and events
  • Implemented proper state management with Svelte 5 runes

Testing Improvements

  • Enhanced Playwright E2E test coverage
  • Added comprehensive tests for cleanup algorithms
  • Improved test reliability with proper component mounting checks

Installation

npm i -S @humanspeak/svelte-diff-match-patch

Or with your preferred package manager:

pnpm add @humanspeak/svelte-diff-match-patch
yarn add @humanspeak/svelte-diff-match-patch

Basic Usage

<script lang="ts">
    import SvelteDiffMatchPatch from '@humanspeak/svelte-diff-match-patch'

    let originalText = $state(`I am the very model of a modern Major-General,
I've information vegetable, animal, and mineral,
I know the kings of England, and I quote the fights historical,
From Marathon to Waterloo, in order categorical.`)

    let modifiedText = $state(`I am the very model of a cartoon individual,
My animation's comical, unusual, and whimsical,
I'm quite adept at funny gags, comedic theory I have read,
From wicked puns and stupid jokes to anvils that drop on your head.`)

    const onProcessing = (timing, diff) => {
        console.log('Diff timing:', timing)
        console.log('Diff result:', diff)
    }
</script>

<SvelteDiffMatchPatch
    {originalText}
    {modifiedText}
    timeout={1}
    cleanupSemantic={false}
    cleanupEfficiency={4}
    {onProcessing}
    rendererClasses={{
        remove: 'diff-remove',
        insert: 'diff-insert',
        equal: 'diff-equal'
    }}
/>

<style>
    :global(.diff-remove) {
        background-color: #ffd7d5;
        text-decoration: line-through;
    }
    :global(.diff-insert) {
        background-color: #d4ffd4;
    }
</style>

TypeScript Support

The package is written in TypeScript and includes full type definitions:

import type {
    SvelteDiffMatchPatchTiming,
    SvelteDiffMatchPatchDiff,
    SvelteDiffMatchPatchProps
} from '@humanspeak/svelte-diff-match-patch'

Props

Prop Type Default Description
originalText string - The original text to compare against
modifiedText string - The modified text to compare with original
timeout number 1 Timeout in seconds for diff computation
cleanupSemantic boolean false Enable semantic cleanup for better readability
cleanupEfficiency number 4 Efficiency cleanup level (0-4)
onProcessing function - Callback for timing and diff information
rendererClasses object - CSS classes for diff highlighting

Custom Rendering with Snippets

You can customize how the diff is rendered using Svelte snippets. This gives you full control over the HTML structure and styling of each diff part.

<script lang="ts">
    import SvelteDiffMatchPatch from '@humanspeak/svelte-diff-match-patch'

    let originalText = $state(`I am the very model of a modern Major-General,
I've information vegetable, animal, and mineral,
I know the kings of England, and I quote the fights historical,
From Marathon to Waterloo, in order categorical.`)

    let modifiedText = $state(`I am the very model of a cartoon individual,
My animation's comical, unusual, and whimsical,
I'm quite adept at funny gags, comedic theory I have read,
From wicked puns and stupid jokes to anvils that drop on your head.`)
</script>

<SvelteDiffMatchPatch {originalText} {modifiedText}>
    {#snippet remove(text: string)}
        <span class="diff-snippet-remove">{text}</span>
    {/snippet}
    {#snippet insert(text: string)}
        <span class="diff-snippet-insert">{text}</span>
    {/snippet}
    {#snippet equal(text: string)}
        <span class="diff-snippet-equal">{text}</span>
    {/snippet}
    {#snippet lineBreak()}
        <br /><br />
    {/snippet}
</SvelteDiffMatchPatch>

<style>
    :global(.diff-snippet-remove) {
        background-color: #ffd7d5;
        text-decoration: line-through;
    }
    :global(.diff-snippet-insert) {
        background-color: #d4ffd4;
    }
</style>

Available Snippets

Snippet Parameters Description
remove text Renders removed text (in originalText only)
insert text Renders inserted text (in modifiedText only)
equal text Renders unchanged text (in both texts)
lineBreak - Renders line breaks between diff sections

You can use these snippets to:

  • Customize the HTML structure of each diff part
  • Apply custom styling to different types of changes
  • Add additional elements or attributes
  • Implement custom animations or transitions
  • Add tooltips or other interactive elements

If you don't provide snippets, the component will use the default rendering with the rendererClasses prop.

Events

The component emits a processing event with timing and diff information:

<script lang="ts">
    import type {
        SvelteDiffMatchPatchTiming,
        SvelteDiffMatchPatchDiff
    } from '@humanspeak/svelte-diff-match-patch'

    const onProcessing = (timing: SvelteDiffMatchPatchTiming, diff: SvelteDiffMatchPatchDiff) => {
        console.log('Diff computation time:', timing.computeTime)
        console.log('Cleanup time:', timing.cleanupTime)
        console.log('Total changes:', diff.length)
    }
</script>

<SvelteDiffMatchPatch {originalText} {modifiedText} {onProcessing} />

Cleanup Algorithms

Semantic Cleanup

When cleanupSemantic is enabled, the diff algorithm will:

  • Factor out commonalities that are likely to be coincidental
  • Improve human readability of the diff
  • May increase computation time for large texts

Efficiency Cleanup

The cleanupEfficiency level (0-4) controls how aggressively the algorithm:

  • Factors out short commonalities
  • Reduces computational overhead
  • Higher values mean more aggressive cleanup

Performance Considerations

  • For large texts, consider increasing the timeout value
  • Use cleanupSemantic for better readability in small to medium texts
  • Use cleanupEfficiency for better performance in large texts
  • Monitor the onProcessing callback for timing information

License

MIT Β© Humanspeak, Inc.

Credits

Made with β™₯ by Humanspeak

About

πŸ“œ A powerful, customizable diff-match-patch library for Svelte with TypeScript support

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

 

Packages

No packages published