UNPKG

@sandboxed/diff

Version:

A zero dependency, high-performance, security-conscious JavaScript diffing library

128 lines (97 loc) 4.26 kB
# @sandboxed/diff A **zero dependency, high-performance, security-conscious** JavaScript diffing library for comparing complex data structures with ease. ## Features - ⚡️ **Zero dependencies** – lightweight and no external libraries required - 📝 Detects **additions, deletions, and modifications** - 💡 Supports **Primitives, Objects, Arrays, Maps, and Sets** - 🔄 **Handles circular references** safely - 🛠️ **Highly configurable** to fit different use cases - 🚨 **Built with security in mind** to prevent prototype pollution and other risks - 💻 Works in both **Node.js and browser environments** ## Installation ``` npm install @sandboxed/diff yarn add @sandboxed/diff ``` ### Supports `esm` and `cjs` Works with both ESM (`import`) and CJS (`require`). Use the syntax that matches your environment: ```javascript // ESM import diff, { ChangeType } from '@sandboxed/diff'; // CJS option 1 const diff = require('@sandboxed/diff').default; const { ChangeType } = require('@sandboxed/diff'); // CJS option 2 const { default: diff, ChangeType } = require('@sandboxed/diff'); ``` ## Usage #### `diff(lhs: any, rhs: any, config?: DiffConfig): Diff` ```javascript import diff, { ChangeType } from '@sandboxed/diff'; const a = { name: "Alice", age: 25 }; const b = { name: "Alice", age: 26, city: "New York" }; const result = diff(a, b); console.log(result); console.log(result.toDiffString()); console.log(result.equal); // false ``` **Output**: ```javascript [ { type: 'noop', str: '{', depth: 0, path: [] }, { type: 'noop', str: '"name": "Alice",', depth: 1, path: [ 'name', { deleted: false, value: 'Alice' } ] }, { type: 'remove', str: '"age": 25,', depth: 1, path: [ 'age', { deleted: true, value: 25 } ] }, { type: 'update', str: '"age": 26,', depth: 1, path: [ 'age', { deleted: false, value: 26 } ] }, { type: 'add', str: '"city": "New York",', depth: 1, path: [ 'city', { deleted: false, value: 'New York' } ] }, { type: 'noop', str: '}', depth: 0, path: [] } ] // --- { "name": "Alice", - "age": 25, ! "age": 26, + "city": "New York", } ``` ## Config | option | Description | |-|-| |[config.include](/docs/config.md#include-changetype--changetype)| Include only these change types from the diff result. Can be combined with `exclude`. | |[config.exclude](/docs/config.md#exclude-changetype--changetype)| Excludes the change types from the diff result. Can be combined with `include`. | |[config.strict](/docs/config.md#strict-boolean)| Performs loose type check if disabled. | |[config.showUpdatedOnly](/docs/config.md#showupdatedonly-boolean)| `@sandboxed/diff` creates a `ChangeType.REMOVE` entry for every `ChangeType.UPDATE`. This flags prevents this behavior. | |[config.pathHints](/docs/config.md#pathhints-pathints)| Hashmap of `map` and `set` path hints. These strings will be used in the `path` array to provide a hit about the object's type. | |[config.redactKeys](/docs/config.md#redactkeys-arraystring)| List of keys that should be redacted from the output. Works with `string` based keys and serialized `Symbol`. | |[config.maxDepth](/docs/config.md#maxdepth-number)| Max depth that the diffing function can traverse. | |[config.maxKeys](/docs/config.md#maxkeys-number)| Max keys the diffing function can traverse. | |[config.timeout](/docs/config.md#timeout-number)| Milliseconds before throwing a timeout error. | ## Utils | util | Description | |-|-| |[toDiffString](/docs/utils.md#diff-string-output)| Generates the diff string representation of the diff result. | |[equal](/docs/utils.md#equality-detection)| Determines whether the inputs are structurally equal based on the diff result. | ## Motivation Many diffing libraries are optimized for either structured output or human-readable text, but rarely both. `@sandboxed/diff` is designed to provide a structured diff result along with a utility to generate a string representation, making it easy to use in both programmatic logic and UI rendering. Trade-off: It may be **slower than other libraries**, but if you prioritize structured diffs with a built-in string representation, `@sandboxed/diff` is a great fit. ## LICENSE [MIT](LICENSE)