### Get Text Diff using JavaScript Source: https://github.com/donedeal0/superdiff/blob/main/README.md Compares two texts and returns a structured diff. This function can perform comparisons at the character, word, or sentence level, providing detailed insights into text changes. ```javascript import { getTextDiff } from "@donedeal0/superdiff"; ``` -------------------------------- ### Import and Configure streamListDiff Source: https://github.com/donedeal0/superdiff/blob/main/README.md Shows how to import the streamListDiff function for different environments and defines the input structure for streaming large datasets. ```javascript // Server import { streamListDiff } from "@donedeal0/superdiff/server"; // Browser import { streamListDiff } from "@donedeal0/superdiff/client"; ``` ```typescript interface StreamOptions { prevList: any; // Readable | FilePath | Record[], nextList: any; referenceKey: string; options: { showOnly?: ("added" | "deleted" | "moved" | "updated" | "equal")[]; chunksSize?: number; considerMoveAsUpdate?: boolean; useWorker?: boolean; showWarnings?: boolean; }; } ``` -------------------------------- ### Stream List Diffing with Arrays and Files Source: https://context7.com/donedeal0/superdiff/llms.txt Demonstrates how to use streamListDiff with arrays and File objects. It shows how to handle data events to process added, deleted, or updated items and how to configure chunk sizes and worker usage. ```typescript import { streamListDiff } from "@donedeal0/superdiff/client"; const prevVotes = [ { oderId: "001", odererName: "Alice", vote: "yes" }, { oderId: "002", odererName: "Bob", vote: "no" }, { oderId: "003", odererName: "Charlie", vote: "yes" } ]; const nextVotes = [ { oderId: "001", odererName: "Alice", vote: "no" }, { oderId: "003", odererName: "Charlie", vote: "yes" }, { oderId: "004", odererName: "Diana", vote: "yes" } ]; const voteDiff = streamListDiff(prevVotes, nextVotes, "oderId", { chunksSize: 10, useWorker: true }); voteDiff.on("data", (chunk) => { chunk.forEach((diff) => { switch (diff.status) { case "added": console.log(`New vote from ${diff.value?.odererName}`); break; case "deleted": console.log(`Removed vote from ${diff.previousValue?.odererName}`); break; case "updated": console.log(`${diff.value?.odererName} changed vote from ${diff.previousValue?.vote} to ${diff.value?.vote}`); break; } }); }); async function compareUploadedFiles(prevFile: File, nextFile: File) { const diff = streamListDiff(prevFile, nextFile, "id", { chunksSize: 500, showOnly: ["added", "deleted", "updated"] }); const results: any[] = []; diff.on("data", (chunk) => { results.push(...chunk); }); diff.on("finish", () => console.log(`Total changes: ${results.length}`)); } ``` -------------------------------- ### Compare text using getTextDiff Source: https://context7.com/donedeal0/superdiff/llms.txt Demonstrates how to use getTextDiff for word, character, and sentence-level comparisons. It also shows how to enable advanced features like move detection, case-insensitivity, and locale-specific settings. ```typescript import { getTextDiff } from "@donedeal0/superdiff"; const prevText = "The quick brown fox jumps over the lazy dog"; const nextText = "The quick red fox leaps over the sleepy dog"; const wordDiff = getTextDiff(prevText, nextText); const charDiff = getTextDiff("hello", "hallo", { separation: "character" }); const sentenceDiff = getTextDiff("I love coding. JavaScript is fun. Python is great.", "I love coding. TypeScript is better. Python is great.", { separation: "sentence" }); const moveDiff = getTextDiff("The brown fox jumped high", "The orange cat has jumped", { detectMoves: true, separation: "word" }); const flexibleDiff = getTextDiff("Hello, World!", "hello world", { ignoreCase: true, ignorePunctuation: true }); const japaneseDiff = getTextDiff("今日は天気がいいです", "今日は天気が悪いです", { accuracy: "high", locale: "ja-JP", separation: "word" }); ``` -------------------------------- ### Diff Text Comparison with Move Detection (diff) Source: https://github.com/donedeal0/superdiff/blob/main/README.md Illustrates using getTextDiff with move detection enabled. This provides a more semantically precise diff where direct token swaps are marked as 'updated' instead of deleted/added pairs. ```diff getTextDiff( - "The brown fox jumped high", + "The orange cat has jumped", { detectMoves: true, separation: "word" } ); { type: "text", + status: "updated", diff: [ { value: 'The', index: 0, previousIndex: 0, status: 'equal', }, + { + value: "orange", + index: 1, + previousValue: "brown", + previousIndex: null, + status: "updated", + }, + { + value: "cat", + index: 2, + previousValue: "fox", + previousIndex: null, + status: "updated", + }, + { + value: "has", + index: 3, + previousIndex: null, + status: "added", + }, + { + value: "jumped", + index: 4, + previousIndex: 3, + status: "moved", + }, - { - value: "high", - index: null, - previousIndex: 4, - status: "deleted", - } ], } ``` -------------------------------- ### Stream Object List Diffs with streamListDiff Source: https://context7.com/donedeal0/superdiff/llms.txt Demonstrates how to use streamListDiff to compare large datasets using arrays, JSON file paths, and Node.js Readable streams. It highlights configuration options like chunk sizes, worker thread usage, and filtering status types. ```typescript import { streamListDiff } from "@donedeal0/superdiff/server"; import { Readable } from "stream"; import path from "path"; // Example 1: Using arrays directly const prevList = [ { id: 1, name: "Item 1", status: "active" }, { id: 2, name: "Item 2", status: "active" }, { id: 3, name: "Item 3", status: "inactive" } ]; const nextList = [ { id: 0, name: "Item 0", status: "new" }, { id: 2, name: "Item 2 Updated", status: "active" }, { id: 3, name: "Item 3", status: "inactive" } ]; const diff = streamListDiff(prevList, nextList, "id", { chunksSize: 2 }); diff.on("data", (chunk) => { console.log("Received chunk:", chunk); }); diff.on("finish", () => console.log("Stream completed")); // Example 2: Using file paths for large JSON files const prevFilePath = path.resolve(__dirname, "./prev-data.json"); const nextFilePath = path.resolve(__dirname, "./next-data.json"); const fileDiff = streamListDiff(prevFilePath, nextFilePath, "id", { chunksSize: 100, showOnly: ["added", "deleted", "updated"], useWorker: true, showWarnings: false }); // Example 3: Using Node.js Readable streams const largeDataset = Array.from({ length: 100000 }, (_, i) => ({ id: i, value: `Item ${i}`, timestamp: Date.now() })); const prevStream = Readable.from(largeDataset, { objectMode: true }); const nextStream = Readable.from(largeDataset.map((item) => ({ ...item, value: `Updated ${item.value}` })), { objectMode: true }); const streamDiff = streamListDiff(prevStream, nextStream, "id", { chunksSize: 1000, useWorker: false }); ``` -------------------------------- ### Perform List Comparison with getListDiff Source: https://github.com/donedeal0/superdiff/blob/main/README.md Demonstrates how to compare two arrays and receive a structured difference object indicating additions, deletions, moves, and updates. ```javascript const result = getListDiff( ["mbappe", "mendes", "verratti", "ruiz"], ["mbappe", "messi", "ruiz"] ); ``` -------------------------------- ### Calculate Geo Difference with Superdiff Source: https://context7.com/donedeal0/superdiff/llms.txt Demonstrates how to use the getGeoDiff function to compare two geographical coordinates. It shows basic usage, specifying different units (miles, meters), enabling high accuracy with the Vincenty formula, and applying locale-aware formatting for different regions (French, German). It also illustrates tracking movement between locations and handling edge cases like identical or null coordinates. ```typescript import { getGeoDiff } from "@donedeal0/superdiff"; // Basic coordinate comparison (Paris to London) // Coordinates format: [Longitude, Latitude] const paris: [number, number] = [2.3522, 48.8566]; const london: [number, number] = [-0.1278, 51.5074]; const distance = getGeoDiff(paris, london); console.log(distance); // Output: // { // type: "geo", // status: "updated", // diff: { // coordinates: [-0.1278, 51.5074], // previousCoordinates: [2.3522, 48.8566], // direction: "north-west", // distance: 343.56, // label: "343.56 kilometers", // unit: "kilometer" // } // } // Using different units const distanceInMiles = getGeoDiff(paris, london, { unit: "mile" }); console.log(distanceInMiles.diff.label); // "213.47 miles" const distanceInMeters = getGeoDiff(paris, london, { unit: "meter" }); console.log(distanceInMeters.diff.label); // "343,560 meters" // High accuracy mode using Vincenty formula const preciseDistance = getGeoDiff(paris, london, { accuracy: "high", unit: "kilometer", maxDecimals: 4 }); console.log(preciseDistance.diff.distance); // 343.5616 (more precise) // Locale-aware formatting const frenchFormat = getGeoDiff(paris, london, { unit: "kilometer", locale: "fr-FR" }); console.log(frenchFormat.diff.label); // "343,56 kilomètres" const germanFormat = getGeoDiff(paris, london, { unit: "kilometer", locale: "de-DE" }); console.log(germanFormat.diff.label); // "343,56 Kilometer" // Track movement between positions const startPosition: [number, number] = [-122.4194, 37.7749]; // San Francisco const endPosition: [number, number] = [-118.2437, 34.0522]; // Los Angeles const tripDiff = getGeoDiff(startPosition, endPosition, { unit: "mile", maxDecimals: 1 }); console.log(`Traveled ${tripDiff.diff.distance} miles ${tripDiff.diff.direction}`); // Output: "Traveled 347.4 miles south-east" // Handle stationary case const sameLocation = getGeoDiff(paris, paris); console.log(sameLocation); // Output: // { // type: "geo", // status: "equal", // diff: { // coordinates: [2.3522, 48.8566], // previousCoordinates: [2.3522, 48.8566], // direction: "stationary", // distance: 0, // label: "0 kilometers", // unit: "kilometer" // } // } // Handle null/undefined coordinates const addedLocation = getGeoDiff(null, london); console.log(addedLocation.status); // "added" const deletedLocation = getGeoDiff(paris, null); console.log(deletedLocation.status); // "deleted" // All supported units const units = [ "centimeter", "foot", "inch", "kilometer", "meter", "mile", "mile-scandinavian", "millimeter", "yard" ] as const; units.forEach((unit) => { const result = getGeoDiff(paris, london, { unit }); console.log(`${unit}: ${result.diff.label}`); }); ``` -------------------------------- ### Diff Text Comparison without Move Detection (diff) Source: https://github.com/donedeal0/superdiff/blob/main/README.md Demonstrates how to use getTextDiff without move detection, resulting in updates being shown as separate added and deleted entries. This method uses the longest common subsequence algorithm. ```diff getTextDiff( - "The brown fox jumped high", + "The orange cat has jumped", { detectMoves: false, separation: "word" } ); { type: "text", + status: "updated", diff: [ { value: 'The', index: 0, previousIndex: 0, status: 'equal', }, - { - value: "brown", - index: null, - previousIndex: 1, - status: "deleted", - }, - { - value: "fox", - index: null, - previousIndex: 2, - status: "deleted", - }, + { + value: "orange", + index: 1, + previousIndex: null, + status: "added", + }, + { + value: "cat", + index: 2, + previousIndex: null, + status: "added", + }, + { + value: "has", + index: 3, + previousIndex: null, + status: "added", + }, { value: "jumped", index: 4, previousIndex: 3, status: "equal", }, - { - value: "high", - index: null, - previousIndex: 4, - status: "deleted", - } ], } ``` -------------------------------- ### POST /getTextDiff Source: https://github.com/donedeal0/superdiff/blob/main/README.md Compares two strings and returns a structured diff object based on the provided configuration options. ```APIDOC ## POST /getTextDiff ### Description Compares previousText and currentText to generate a list of changes including additions, deletions, and updates. ### Method POST ### Endpoint /getTextDiff ### Parameters #### Request Body - **previousText** (string) - Optional - The original text to compare. - **currentText** (string) - Optional - The current text to compare against. - **options** (object) - Optional - Configuration for the diffing algorithm. - **separation** (string) - Optional - 'character', 'word' (default), or 'sentence'. - **accuracy** (string) - Optional - 'normal' (default) or 'high'. - **detectMoves** (boolean) - Optional - If true, detects token moves (default: false). - **ignoreCase** (boolean) - Optional - If true, ignores case sensitivity (default: false). - **ignorePunctuation** (boolean) - Optional - If true, ignores punctuation (default: false). - **locale** (string) - Optional - Locale for locale-aware segmentation. ### Request Example { "previousText": "The brown fox jumped high", "currentText": "The orange cat has jumped", "options": { "detectMoves": false, "separation": "word" } } ### Response #### Success Response (200) - **type** (string) - Always 'text'. - **status** (string) - The overall status of the diff ('added', 'deleted', 'equal', 'updated'). - **diff** (array) - List of individual token changes. #### Response Example { "type": "text", "status": "updated", "diff": [ { "value": "The", "index": 0, "previousIndex": 0, "status": "equal" } ] } ``` -------------------------------- ### Compare Arrays with getListDiff (TypeScript) Source: https://context7.com/donedeal0/superdiff/llms.txt Demonstrates comparing arrays of primitive types and objects using the getListDiff function. It shows how to detect additions, deletions, moves, and updates, and how to use a referenceKey for stable object identity tracking. The function supports various comparison scenarios and options. ```typescript import { getListDiff } from "@donedeal0/superdiff"; // Compare arrays of primitives const prevPlayers = ["mbappe", "mendes", "verratti", "ruiz"]; const nextPlayers = ["mbappe", "messi", "ruiz"]; const playerDiff = getListDiff(prevPlayers, nextPlayers); console.log(playerDiff); // Compare arrays of objects with referenceKey for tracking identity const prevProducts = [ { id: 1, name: "Widget", price: 10 }, { id: 2, name: "Gadget", price: 20 }, { id: 3, name: "Gizmo", price: 30 } ]; const nextProducts = [ { id: 1, name: "Widget Pro", price: 15 }, { id: 3, name: "Gizmo", price: 30 }, { id: 4, name: "Doohickey", price: 25 } ]; const productDiff = getListDiff(prevProducts, nextProducts, { referenceKey: "id" }); console.log(productDiff); // Filter to show only added and deleted items const changesOnly = getListDiff(prevProducts, nextProducts, { referenceKey: "id", showOnly: ["added", "deleted"] }); console.log(changesOnly.diff); // Treat moves as updates const withMoveAsUpdate = getListDiff(["a", "b", "c"], ["c", "b", "a"], { considerMoveAsUpdate: true }); // All moved items will have status: "updated" instead of "moved" ``` -------------------------------- ### streamListDiff (Client/Browser) Source: https://context7.com/donedeal0/superdiff/llms.txt Compares two lists of objects in the browser and returns a stream of differences. ```APIDOC ## streamListDiff ### Description Streams the diff of two large object lists in a browser environment using the Web Streams API. Supports browser ReadableStream, File objects, and arrays. ### Method Function Call ### Parameters #### Arguments - **prev** (Array|File|ReadableStream) - Required - The previous list or data source. - **next** (Array|File|ReadableStream) - Required - The next list or data source. - **key** (string) - Required - The unique identifier property name used to compare objects. - **options** (Object) - Optional - Configuration object. - **chunksSize** (number) - Optional - Number of items to process per chunk. - **useWorker** (boolean) - Optional - Whether to perform comparison in a Web Worker. - **showOnly** (Array) - Optional - Filter results by status: 'added', 'deleted', or 'updated'. ### Request Example const diff = streamListDiff(prevData, nextData, "id", { chunksSize: 10, useWorker: true }); ### Response #### Success Response (Event-based) - **data** (Array) - Emits chunks of diff objects containing { status, value, previousValue }. - **finish** (void) - Emitted when comparison is complete. - **error** (Error) - Emitted if an error occurs during processing. #### Response Example { "status": "updated", "value": { "id": 1, "name": "Updated Name" }, "previousValue": { "id": 1, "name": "Original Name" } } ``` -------------------------------- ### Stream List Diffing with ReadableStream Source: https://context7.com/donedeal0/superdiff/llms.txt Shows how to integrate streamListDiff with the browser's native ReadableStream API for processing streaming data sources. ```typescript const createStream = (data: any[]) => { return new ReadableStream({ start(controller) { data.forEach((item) => controller.enqueue(item)); controller.close(); } }); }; const prevStream = createStream([{ id: 1, name: "A" }, { id: 2, name: "B" }]); const nextStream = createStream([{ id: 2, name: "B" }, { id: 3, name: "C" }]); const browserDiff = streamListDiff(prevStream, nextStream, "id"); browserDiff.on("data", (chunk) => console.log(chunk)); ``` -------------------------------- ### TypeScript Text Diff Input Parameters Source: https://github.com/donedeal0/superdiff/blob/main/README.md Defines the input parameters for the getTextDiff function, including previous and current text, and an options object for customization. The options allow control over separation, accuracy, move detection, and case/punctuation sensitivity. ```typescript previousText: string | null | undefined, currentText: string | null | undefined, options?: { separation?: "character" | "word" | "sentence", // "word" by default accuracy?: "normal" | "high", // "normal" by default detectMoves?: boolean // false by default ignoreCase?: boolean, // false by default ignorePunctuation?: boolean, // false by default locale?: Intl.Locale | string // undefined by default } ``` -------------------------------- ### Calculate Geographical Coordinate Differences Source: https://github.com/donedeal0/superdiff/blob/main/README.md This snippet demonstrates how to import and use the getGeoDiff function to compare two sets of coordinates. It highlights the input structure using GeoJSON format [longitude, latitude] and the resulting diff object. ```javascript import { getGeoDiff } from "@donedeal0/superdiff"; const result = getGeoDiff( [2.3522, 48.8566], [-0.1278, 51.5074] ); ``` ```typescript type GeoDiff = { type: "geo"; status: "added" | "deleted" | "error" | "equal" | "updated"; diff: { coordinates: [number, number] | null; previousCoordinates: [number, number] | null; distance: number; unit: "centimeter" | "foot" | "inch" | "kilometer" | "meter" | "mile" | "mile-scandinavian" | "millimeter" | "yard"; label: string, direction: "east" | "north" | "south" | "west" | "north-east" | "north-west" | "south-east" | "south-west" | "stationary"; }; }; ``` -------------------------------- ### Define List Comparison Input and Output Types Source: https://github.com/donedeal0/superdiff/blob/main/README.md Defines the TypeScript interfaces for input parameters and the resulting diff structure for the getListDiff function. ```typescript interface ListInput { prevList: T[]; nextList: T[]; options?: { showOnly?: ("added" | "deleted" | "moved" | "updated" | "equal")[]; referenceKey?: string; ignoreArrayOrder?: boolean; considerMoveAsUpdate?: boolean; }; } type ListDiff = { type: "list"; status: "added" | "deleted" | "equal" | "moved" | "updated"; diff: { value: unknown; index: number | null; previousIndex: number | null; status: "added" | "deleted" | "equal" | "moved" | "updated"; }[]; }; ``` -------------------------------- ### streamListDiff Source: https://github.com/donedeal0/superdiff/blob/main/README.md Compares two lists and returns a stream of differences. Supports ReadableStreams, Files, and arrays as input. ```APIDOC ## streamListDiff ### Description Compares two lists and returns a stream of differences. Supports ReadableStreams, Files, and arrays as input. ### Method N/A (Function) ### Endpoint N/A (Function) ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body - **prevList** (ReadableStream | File | Record[] | Record) - Required - The original object list. - **nextList** (ReadableStream | File | Record[] | Record) - Required - The new object list. - **referenceKey** (keyof Record) - Required - A key common to all objects in your lists (e.g. `id`). - **options** (object) - Optional - Configuration options for the diff. - **showOnly** (("added" | "deleted" | "moved" | "updated" | "equal")[]) - Optional - Filters the output to include only specified statuses. Defaults to all statuses. - **chunksSize** (number) - Optional - The number of object diffs returned by each streamed chunk. Defaults to 1 (0 = 1 object diff per chunk). - **considerMoveAsUpdate** (boolean) - Optional - If true, a `moved` status will be considered as `updated`. Defaults to false. - **useWorker** (boolean) - Optional - If true, the diff will be run in a web worker for performance. Recommended for large lists (+100,000 items). Defaults to true. - **showWarnings** (boolean) - Optional - If true, potential warnings will be displayed in the console. Defaults to true. ### Request Example ```diff const diff = streamListDiff( [ - { id: 1, name: "Item 1" }, { id: 2, name: "Item 2" }, { id: 3, name: "Item 3" } ], [ + { id: 0, name: "Item 0" }, { id: 2, name: "Item 2" }, + { id: 3, name: "Item Three" }, ], "id", { chunksSize: 2 } ); ``` ### Response #### Success Response (Stream) - **data** (StreamListDiff[]) - Emitted when a new chunk of object diffs is available. - **finish** () - Emitted when the stream processing is finished. - **error** (Error) - Emitted if an error occurs during stream processing. ```typescript interface StreamListener { on(event: "data", listener: (chunk: StreamListDiff[]) => void); on(event: "finish", listener: () => void); on(event: "error", listener: (error: Error) => void); } type StreamListDiff> = { value: T | null; index: number | null; previousValue: T | null; previousIndex: number | null; status: "added" | "deleted" | "moved" | "updated" | "equal"; }; ``` #### Response Example ```diff diff.on("data", (chunk) => { // first chunk received (2 object diffs) [ + { + value: { id: 0, name: "Item 0" }, + index: 0, + previousValue: null, + previousIndex: null, + status: "added" + }, - { - value: null, - index: null, - previousValue: { id: 1, name: "Item 1" }, - previousIndex: 0, - status: "deleted" - } ] // second chunk received (2 object diffs) [ { value: { id: 2, name: "Item 2" }, index: 1, previousValue: { id: 2, name: "Item 2" }, previousIndex: 1, status: "equal" }, + { + value: { id: 3, name: "Item Three" }, + index: 2, + previousValue: { id: 3, name: "Item 3" }, + previousIndex: 2, + status: "updated" + }, ] }); diff.on("finish", () => console.log("Your data has been processed. The full diff is available.")) diff.on("error", (err) => console.log(err)) ``` ``` -------------------------------- ### Compare Objects with getObjectDiff Source: https://github.com/donedeal0/superdiff/blob/main/README.md Compares two objects and returns a detailed diff for each value and its nested subvalues. It supports various options such as ignoring array order and filtering output by status or granularity. ```javascript import { getObjectDiff } from "@donedeal0/superdiff"; const diff = getObjectDiff( { id: 54, user: { name: "joe", member: true, hobbies: ["golf", "football"], age: 66 } }, { id: 54, user: { name: "joe", member: false, hobbies: ["golf", "chess"], age: 66 } } ); ``` ```typescript type ObjectDiff = { type: "object"; status: "added" | "deleted" | "equal" | "updated"; diff: Diff[]; }; type Diff = { key: string; value: unknown; previousValue: unknown; status: "added" | "deleted" | "equal" | "updated"; diff?: Diff[]; }; ``` -------------------------------- ### streamListDiff (Server-Side) Source: https://context7.com/donedeal0/superdiff/llms.txt Streams the diff of two large object lists in a Node.js server environment, ideal for processing millions of records without memory issues. Supports Node.js Readable streams, file paths, and arrays as input with optional worker thread processing for maximum performance. ```APIDOC ## streamListDiff (Server) ### Description Streams the diff of two large object lists in a Node.js server environment, ideal for processing millions of records without memory issues. Supports Node.js Readable streams, file paths, and arrays as input with optional worker thread processing for maximum performance. ### Method `streamListDiff` function (exports from `@donedeal0/superdiff/server`) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None (function arguments are used) **Arguments:** - `prev` (Array | string | Readable): The previous list of objects, a file path to a JSON array, or a Node.js Readable stream. - `next` (Array | string | Readable): The next list of objects, a file path to a JSON array, or a Node.js Readable stream. - `key` (string): The key to use for comparing objects in the lists. - `options` (object, optional): Configuration options for the diffing process. - `chunksSize` (number): The number of diffs to include in each chunk emitted by the stream. Defaults to 100. - `showOnly` (Array, optional): An array of diff statuses to include in the output (e.g., `['added', 'deleted', 'updated']`). Defaults to `['added', 'deleted', 'updated', 'equal']`. - `useWorker` (boolean): Whether to use worker threads for processing. Defaults to `false`. - `showWarnings` (boolean): Whether to show warnings during processing. Defaults to `true`. ### Request Example ```typescript import { streamListDiff } from "@donedeal0/superdiff/server"; import { Readable } from "stream"; import path from "path"; // Example 1: Using arrays directly const prevList = [ { id: 1, name: "Item 1", status: "active" }, { id: 2, name: "Item 2", status: "active" }, { id: 3, name: "Item 3", status: "inactive" } ]; const nextList = [ { id: 0, name: "Item 0", status: "new" }, { id: 2, name: "Item 2 Updated", status: "active" }, { id: 3, name: "Item 3", status: "inactive" } ]; const diff = streamListDiff(prevList, nextList, "id", { chunksSize: 2 }); diff.on("data", (chunk) => { console.log("Received chunk:", chunk); }); diff.on("finish", () => console.log("Stream completed")); diff.on("error", (err) => console.error("Stream error:", err)); // Example 2: Using file paths const prevFilePath = path.resolve(__dirname, "./prev-data.json"); const nextFilePath = path.resolve(__dirname, "./next-data.json"); const fileDiff = streamListDiff(prevFilePath, nextFilePath, "id", { chunksSize: 100, showOnly: ["added", "deleted", "updated"], useWorker: true, showWarnings: false }); fileDiff.on("data", (chunk) => { chunk.forEach((item) => { if (item.status === "added") { console.log(`New item: ${item.value?.id}`); } else if (item.status === "deleted") { console.log(`Removed item: ${item.previousValue?.id}`); } }); }); // Example 3: Using Node.js Readable streams const largeDataset = Array.from({ length: 100000 }, (_, i) => ({ id: i, value: `Item ${i}`, timestamp: Date.now() })); const prevStream = Readable.from(largeDataset, { objectMode: true }); const nextStream = Readable.from( largeDataset.map((item) => ({ ...item, value: `Updated ${item.value}` })), { objectMode: true } ); const streamDiff = streamListDiff(prevStream, nextStream, "id", { chunksSize: 1000, useWorker: false // Disable worker for Readable streams }); streamDiff.on("data", (chunk) => console.log(`Processed ${chunk.length} items`)); streamDiff.on("finish", () => console.log("All items processed")); ``` ### Response #### Success Response (Stream Events) - `data` (chunk): Emits chunks of diff objects. Each diff object has the following structure: - `value` (object | null): The new value of the object (for 'added' or 'updated'). - `index` (number | null): The index in the `next` list. - `previousValue` (object | null): The previous value of the object (for 'deleted' or 'updated'). - `previousIndex` (number | null): The index in the `prev` list. - `status` (string): The status of the diff ('added', 'deleted', 'updated', 'equal'). - `finish`: Emitted when the diffing process is complete. - `error` (Error): Emitted if an error occurs during processing. #### Response Example (Data Chunk) ```json [ { "value": { "id": 0, "name": "Item 0", "status": "new" }, "index": 0, "previousValue": null, "previousIndex": null, "status": "added" }, { "value": null, "index": null, "previousValue": { "id": 1, "name": "Item 1", "status": "active" }, "previousIndex": 0, "status": "deleted" } ] ``` ``` -------------------------------- ### Compare Objects Recursively with Superdiff Source: https://context7.com/donedeal0/superdiff/llms.txt Demonstrates how to use getObjectDiff to compare two objects recursively. It highlights basic diffing, filtering output by status and granularity, and ignoring array order during comparison. This function is useful for identifying changes in nested data structures. ```typescript import { getObjectDiff } from "@donedeal0/superdiff"; // Compare two user profile objects const prevUser = { id: 1, name: "John Doe", settings: { theme: "light", notifications: true, language: "en" }, roles: ["user", "editor"] }; const nextUser = { id: 1, name: "John Smith", settings: { theme: "dark", notifications: true, language: "en" }, roles: ["user", "admin"] }; // Basic diff const diff = getObjectDiff(prevUser, nextUser); console.log(diff); // Filter to show only updated fields with deep granularity const updatedOnly = getObjectDiff(prevUser, nextUser, { showOnly: { statuses: ["updated"], granularity: "deep" } }); console.log(updatedOnly); // Ignore array order when comparing const withIgnoreOrder = getObjectDiff( { tags: ["a", "b", "c"] }, { tags: ["c", "a", "b"] }, { ignoreArrayOrder: true } ); console.log(withIgnoreOrder.status); // "equal" ``` -------------------------------- ### getTextDiff Source: https://github.com/donedeal0/superdiff/blob/main/README.md Compares two texts and returns a structured diff at a character, word, or sentence level. ```APIDOC ## getTextDiff ### Description Compares two texts and returns a structured diff at a character, word, or sentence level. ### Method N/A (Function) ### Endpoint N/A (Function) ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```javascript import { getTextDiff } from "@donedeal0/superdiff"; ``` ### Response #### Success Response (200) - **diff** (object) - A structured representation of the differences between the two texts. #### Response Example ```javascript // Example response structure (details depend on implementation) { "diff": [ // ... diff details ... ] } ``` ``` -------------------------------- ### Function: getListDiff Source: https://context7.com/donedeal0/superdiff/llms.txt Compares two arrays and returns a detailed diff object indicating the status of each entry. ```APIDOC ## getListDiff ### Description Compares two arrays and returns a diff for each entry with support for detecting additions, deletions, moves, and updates. Supports duplicate values, primitive types, and objects with optional reference key tracking. ### Method Function Call ### Parameters #### Arguments - **prevArray** (Array) - Required - The initial array to compare from. - **nextArray** (Array) - Required - The target array to compare to. - **options** (Object) - Optional - Configuration object: - **referenceKey** (string) - Optional - Key to track object identity. - **showOnly** (Array) - Optional - Filter results by status (e.g., ["added", "deleted"]). - **considerMoveAsUpdate** (boolean) - Optional - If true, treats moved items as updated. ### Request Example getListDiff(prevArray, nextArray, { referenceKey: "id" }); ### Response #### Success Response - **type** (string) - Always "list". - **status** (string) - The overall status of the list comparison. - **diff** (Array) - An array of objects containing value, index, previousIndex, and status. #### Response Example { "type": "list", "status": "updated", "diff": [ { "value": "item", "index": 0, "previousIndex": 0, "status": "equal" } ] } ``` -------------------------------- ### Compare Lists with getListDiff Source: https://github.com/donedeal0/superdiff/blob/main/README.md Compares two arrays and returns a diff for each entry. This function supports duplicate values, primitive types, and objects within the arrays. ```javascript import { getListDiff } from "@donedeal0/superdiff"; ``` -------------------------------- ### Stream List Diffing in TypeScript Source: https://github.com/donedeal0/superdiff/blob/main/README.md Compares two lists of objects, supporting various input types like ReadableStreams, Files, and arrays. It provides options for filtering diff types, chunking output, and optimizing performance with workers. The output is streamed via events. ```typescript interface StreamListener { on(event: "data", listener: (chunk: StreamListDiff[]) => void); on(event: "finish", listener: () => void); on(event: "error", listener: (error: Error) => void); } type StreamListDiff> = { value: T | null; index: number | null; previousValue: T | null; previousIndex: number | null; status: "added" | "deleted" | "moved" | "updated" | "equal"; }; ``` ```typescript prevList: ReadableStream> | File | Record[], nextList: ReadableStream> | File | Record[], referenceKey: keyof Record, options: { showOnly?: ("added" | "deleted" | "moved" | "updated" | "equal")[], // [] by default chunksSize?: number, // 0 by default considerMoveAsUpdate?: boolean; // false by default useWorker?: boolean; // true by default showWarnings?: boolean; // true by default } ``` ```typescript // Server environment examples // const stream = [{ id: 1, name: "hello" }] // const stream = Readable.from(list, { objectMode: true }); // const stream = path.resolve(__dirname, "./list.json"); // Browser environment examples // const stream = [{ id: 1, name: "hello" }] // const stream = new ReadableStream({ // start(controller) { // list.forEach((value) => controller.enqueue(value)); // controller.close(); // }, // }); // const stream = new File([JSON.stringify(file)], "file.json", { type: "application/json" }); // const stream = e.target.files[0]; ``` ```diff const diff = streamListDiff( [ - { id: 1, name: "Item 1" }, { id: 2, name: "Item 2" }, { id: 3, name: "Item 3" } ], [ + { id: 0, name: "Item 0" }, { id: 2, name: "Item 2" }, + { id: 3, name: "Item Three" }, ], "id", { chunksSize: 2 } ); ``` ```diff diff.on("data", (chunk) => { // first chunk received (2 object diffs) [ + { + value: { id: 0, name: "Item 0" }, + index: 0, + previousValue: null, + previousIndex: null, + status: "added" + }, - { - value: null, - index: null, - previousValue: { id: 1, name: "Item 1" }, - previousIndex: 0, - status: "deleted" - } ] // second chunk received (2 object diffs) [ { value: { id: 2, name: "Item 2" }, index: 1, previousValue: { id: 2, name: "Item 2" }, previousIndex: 1, status: "equal" }, + { + value: { id: 3, name: "Item Three" }, + index: 2, + previousValue: { id: 3, name: "Item 3" }, + previousIndex: 2, + status: "updated" + }, ] }); diff.on("finish", () => console.log("Your data has been processed. The full diff is available.")) diff.on("error", (err) => console.log(err)) ``` -------------------------------- ### streamListDiff Source: https://github.com/donedeal0/superdiff/blob/main/README.md Streams the diff of two object lists, optimized for large datasets and performance. ```APIDOC ## POST /streamListDiff ### Description Streams the comparison of two large lists. Supports Node.js streams or file paths for memory-efficient processing. ### Method POST ### Endpoint /streamListDiff ### Parameters #### Request Body - **prevList** (Readable|FilePath|Array) - Required - Source list. - **nextList** (Readable|FilePath|Array) - Required - Target list. - **referenceKey** (String) - Required - Key to identify objects. - **options** (Object) - Optional - Configuration for streaming behavior (chunksSize, useWorker, etc.). ### Request Example { "prevList": "./list1.json", "nextList": "./list2.json", "referenceKey": "id" } ``` -------------------------------- ### getObjectDiff Source: https://context7.com/donedeal0/superdiff/llms.txt Compares two objects recursively and returns a structured diff for each key-value pair, including support for nested objects and custom filtering. ```APIDOC ## getObjectDiff ### Description Compares two objects recursively and returns a structured diff for each key-value pair, including nested objects. Supports options for ignoring array order and filtering output by status with basic or deep granularity. ### Method Function Call ### Parameters #### Arguments - **prevObject** (Object) - Required - The original object to compare from. - **nextObject** (Object) - Required - The new object to compare to. - **options** (Object) - Optional - Configuration object. - **ignoreArrayOrder** (boolean) - Optional - If true, treats arrays with same elements in different order as equal. - **showOnly** (Object) - Optional - Filter results by status or granularity. ### Request Example ```typescript import { getObjectDiff } from "@donedeal0/superdiff"; const diff = getObjectDiff(prevUser, nextUser, { ignoreArrayOrder: true, showOnly: { statuses: ["updated"], granularity: "deep" } }); ``` ### Response #### Success Response - **type** (string) - The type of the diff (e.g., "object"). - **status** (string) - The overall status (e.g., "updated", "equal"). - **diff** (Array) - An array of objects describing the changes for each key. #### Response Example { "type": "object", "status": "updated", "diff": [ { "key": "name", "value": "John Smith", "previousValue": "John Doe", "status": "updated" } ] } ```