CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-jsondiffpatch

JSON diff & patch library with support for objects, arrays, text diffs, and multiple output formats

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

diffpatcher-class.mddocs/

DiffPatcher Class

Object-oriented interface providing full control over diff and patch operations with customizable options and processing pipeline access.

Capabilities

Constructor

Creates a new DiffPatcher instance with optional configuration.

/**
 * Create DiffPatcher instance with custom options
 * @param options - Configuration options for diff/patch behavior
 */
class DiffPatcher {
  constructor(options?: Options);
}

Usage Examples:

import { DiffPatcher } from "jsondiffpatch";

// Default instance
const patcher = new DiffPatcher();

// Custom configuration
const customPatcher = new DiffPatcher({
  objectHash: (obj) => obj.id || obj.name,
  arrays: {
    detectMove: true,
    includeValueOnMove: false
  },
  textDiff: {
    minLength: 60
  },
  cloneDiffValues: true
});

Diff Method

Generates a delta representing the differences between two values.

/**
 * Generate diff between two values
 * @param left - Original value
 * @param right - Target value
 * @returns Delta representing changes needed to transform left into right
 */
diff(left: unknown, right: unknown): Delta;

Usage Examples:

const patcher = new DiffPatcher();

// Object diff
const objectDelta = patcher.diff(
  { name: "Alice", age: 25, tags: ["user"] },
  { name: "Alice", age: 26, tags: ["user", "admin"], active: true }
);
// Result: { age: [25, 26], tags: { _t: "a", 1: ["admin"] }, active: [true] }

// Array diff with move detection
const arrayDelta = patcher.diff(
  [{ id: 1, name: "A" }, { id: 2, name: "B" }, { id: 3, name: "C" }],
  [{ id: 2, name: "B" }, { id: 3, name: "C" }, { id: 1, name: "A" }]
);

Patch Method

Applies a delta to a value to produce the target value.

/**
 * Apply patch to transform a value
 * @param left - Original value to patch
 * @param delta - Delta to apply
 * @returns Transformed value
 */
patch(left: unknown, delta: Delta): unknown;

Usage Examples:

const patcher = new DiffPatcher();

const original = { name: "Alice", age: 25, tags: ["user"] };
const delta = { age: [25, 26], tags: { _t: "a", 1: ["admin"] }, active: [true] };

const result = patcher.patch(original, delta);
// Result: { name: "Alice", age: 26, tags: ["user", "admin"], active: true }

// Patch preserves original by default (unless cloneDiffValues is false)
console.log(original); // Still { name: "Alice", age: 25, tags: ["user"] }

Unpatch Method

Applies the reverse of a delta to revert changes.

/**
 * Apply reverse patch to revert changes
 * @param right - Target value to unpatch
 * @param delta - Original delta to reverse
 * @returns Original value before patch was applied
 */
unpatch(right: unknown, delta: Delta): unknown;

Usage Examples:

const patcher = new DiffPatcher();

const target = { name: "Alice", age: 26, tags: ["user", "admin"], active: true };
const delta = { age: [25, 26], tags: { _t: "a", 1: ["admin"] }, active: [true] };

const original = patcher.unpatch(target, delta);
// Result: { name: "Alice", age: 25, tags: ["user"] }

Reverse Method

Creates a reversed delta that can undo the original delta's changes.

/**
 * Reverse a delta to create undo operation
 * @param delta - Delta to reverse
 * @returns Reversed delta
 */
reverse(delta: Delta): Delta;

Usage Examples:

const patcher = new DiffPatcher();

const originalDelta = { age: [25, 26], role: ["admin"] };
const reversedDelta = patcher.reverse(originalDelta);
// Result: { age: [26, 25], role: [undefined, 0, 0] }

// Use reversed delta for undo functionality
const target = { name: "Alice", age: 26, role: "admin" };
const undone = patcher.patch(target, reversedDelta);
// Result: { name: "Alice", age: 25 }

Clone Method

Creates a deep clone of any value using the same cloning logic as internal operations.

/**
 * Create deep clone of a value
 * @param value - Value to clone
 * @returns Deep cloned copy
 */
clone(value: unknown): unknown;

Usage Examples:

const patcher = new DiffPatcher();

const original = {
  user: { name: "Alice", permissions: ["read", "write"] },
  metadata: { created: new Date(), version: 1 }
};

const cloned = patcher.clone(original);

// Modify clone without affecting original
cloned.user.name = "Bob";
cloned.user.permissions.push("admin");

console.log(original.user.name); // "Alice"
console.log(original.user.permissions); // ["read", "write"]

Options Method

Gets or sets the DiffPatcher instance options.

/**
 * Get or set DiffPatcher options
 * @param options - New options to set (optional)
 * @returns Current options object
 */
options(options?: Options): Options;

Usage Examples:

const patcher = new DiffPatcher();

// Get current options
const currentOptions = patcher.options();
console.log(currentOptions.arrays?.detectMove); // true (default)

// Update options
patcher.options({
  arrays: {
    detectMove: false,
    includeValueOnMove: true
  },
  objectHash: (obj) => obj.id
});

// Options are merged with existing options
const updatedOptions = patcher.options();
console.log(updatedOptions.cloneDiffValues); // true (preserved from defaults)

Advanced Usage

Custom Object Hashing

const patcher = new DiffPatcher({
  objectHash: (item, index) => {
    // Use id field for object matching
    if (item && typeof item === 'object' && 'id' in item) {
      return String(item.id);
    }
    // Use name field as fallback
    if (item && typeof item === 'object' && 'name' in item) {
      return String(item.name);
    }
    // Default to position-based matching
    return undefined;
  }
});

const delta = patcher.diff(
  [{ id: 1, name: "Alice" }, { id: 2, name: "Bob" }],
  [{ id: 2, name: "Bob" }, { id: 1, name: "Alice", role: "admin" }]
);
// Detects move and modification based on id matching

Property Filtering

const patcher = new DiffPatcher({
  propertyFilter: (name, context) => {
    // Skip private properties
    if (name.startsWith('_')) return false;
    
    // Skip computed properties in certain contexts
    if (name === 'computed' && context.left && context.left.type === 'temp') {
      return false;
    }
    
    return true;
  }
});

const delta = patcher.diff(
  { name: "Alice", _private: "secret", computed: "temp" },
  { name: "Bob", _private: "changed", computed: "updated" }
);
// Only includes changes to 'name' property

Text Diff Integration

// Using with-text-diffs module
import { DiffPatcher } from "jsondiffpatch/with-text-diffs";

const textPatcher = new DiffPatcher({
  textDiff: {
    minLength: 40 // Only diff strings longer than 40 characters
  }
});

const delta = textPatcher.diff(
  "The quick brown fox jumps over the lazy dog",
  "The quick brown fox jumped over the lazy cat"
);
// Creates text diff instead of simple replacement

Properties

Processor Access

/**
 * Access to internal processor for advanced pipeline customization
 */
readonly processor: Processor;

The processor property provides access to the internal processing pipeline for advanced customization of diff, patch, and reverse operations through filter manipulation.

docs

core-operations.md

diffpatcher-class.md

formatters.md

index.md

options-configuration.md

tile.json