diff --git a/README.md b/README.md index 255351d..bf84553 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ This library compares two arrays or objects and returns a full diff of their dif All other existing solutions return a strange diff format that often requires additional parsing. They are also limited to object comparison. -**Superdiff** gives you a complete diff for both array and objects in a very readable format. Last but not least, it's battle-tested and super fast. Import. Enjoy. 👍 +**Superdiff** gives you a complete diff for both array and objects in a very readable format. Last but not least, it's battle-tested, has zero dependencies, and is super fast. Import. Enjoy. 👍
@@ -40,64 +40,159 @@ I am grateful to the generous donors of **Superdiff**! **Superdiff** exports 4 functions: +```ts +// Compares two objects and return a diff for each value and their potential subvalues +getObjectDiff(prevObject, nextObject) +// Compares two arrays and returns a diff for each value +getListDiff(prevList, nextList) +// Streams the diff of two object lists, ideal for large lists and maximum performance +streamListDiff(prevList, nextList, referenceProperty) +// Checks whether two values are equal +isEqual(dataA, dataB) +// Checks whether a value is an object +isObject(data) +``` +
+ ### getObjectDiff() ```js import { getObjectDiff } from "@donedeal0/superdiff"; ``` -Compares two objects and return a diff for each value and their potential subvalues: +Compares two objects and return a diff for each value and their potential subvalues. Supports deeply nested objects with any kind of values. -- property name -- status: `added`, `deleted`, `equal`, `updated` -- previous value, current value -- supports deeply nested objects with any kind of values +**Format** -format: +input + +```ts +prevData: Record; +nextData: Record; +options?: { + ignoreArrayOrder?: boolean, // false by default, + showOnly?: { + statuses: ("added" | "deleted" | "updated" | "equal")[], // [] by default + granularity?: "basic" | "deep" // "basic" by default + } +} +``` + +- `prevData`: the original object +- `nextData`: the new object +- `options` + - `ignoreArrayOrder`: if set to `true`, `["hello", "world"]` and `["world", "hello"]` will be treated as `equal`, because the two arrays have the same value, just not in the same order. + - `showOnly`: returns only the values whose status you are interested in. It takes two parameters: + + - `statuses`: status you want to see in the output (e.g. `["added", "equal"]`) + - `granularity`: + - `basic` returns only the main properties whose status matches your query. + - `deep` can return main properties if some of their subproperties' status match your request. The subproperties are filtered accordingly. + +output ```ts type ObjectDiff = { type: "object"; status: "added" | "deleted" | "equal" | "updated"; - diff: { - property: string; - previousValue: unknown; - currentValue: unknow; - status: "added" | "deleted" | "equal" | "updated"; - // only appears if some subproperties have been added/deleted/updated - diff?: { - property: string; - previousValue: unknown; - currentValue: unknown; - status: "added" | "deleted" | "equal" | "updated"; - // recursive diff in case of subproperties - diff?: SubDiff[]; - }[]; - }[]; + diff: Diff[]; }; -``` -**Options** +/** recursive diff in case of subproperties */ +type Diff = { + property: string; + previousValue: unknown; + currentValue: unknown; + status: "added" | "deleted" | "equal" | "updated"; + diff?: Diff[]; +}; +``` +**Usage** -You can add a third `options` parameter to `getObjectDiff`. +input -```ts -{ - ignoreArrayOrder?: boolean // false by default, - showOnly?: { - statuses: ("added" | "deleted" | "updated" | "equal")[], // [] by default - granularity?: "basic" | "deep" // "basic" by default +```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, + }, } -} +); ``` -- `ignoreArrayOrder`: if set to `true`, `["hello", "world"]` and `["world", "hello"]` will be treated as `equal`, because the two arrays have the same value, just not in the same order. -- `showOnly`: returns only the values whose status you are interested in. It takes two parameters: +output - - `statuses`: status you want to see in the output (e.g. `["added", "equal"]`) - - `granularity`: - - `basic` returns only the main properties whose status matches your query. - - `deep` can return main properties if some of their subproperties' status match your request. The subproperties are filtered accordingly. +```diff +{ + type: "object", ++ status: "updated", + diff: [ + { + property: "id", + previousValue: 54, + currentValue: 54, + status: "equal", + }, + { + property: "user", + previousValue: { + name: "joe", + member: true, + hobbies: ["golf", "football"], + age: 66, + }, + currentValue: { + name: "joe", + member: false, + hobbies: ["golf", "chess"], + age: 66, + }, ++ status: "updated", + diff: [ + { + property: "name", + previousValue: "joe", + currentValue: "joe", + status: "equal", + }, ++ { ++ property: "member", ++ previousValue: true, ++ currentValue: false, ++ status: "updated", ++ }, ++ { ++ property: "hobbies", ++ previousValue: ["golf", "football"], ++ currentValue: ["golf", "chess"], ++ status: "updated", ++ }, + { + property: "age", + previousValue: 66, + currentValue: 66, + status: "equal", + }, + ], + }, + ], + } +``` +
### getListDiff() @@ -105,15 +200,31 @@ You can add a third `options` parameter to `getObjectDiff`. import { getListDiff } from "@donedeal0/superdiff"; ``` -Compares two arrays and returns a diff for each value: +Compares two arrays and returns a diff for each entry. Supports duplicate values, primitive values and objects. -- index change: `prevIndex`, `newIndex`, `indexDiff` -- status: `added`, `deleted`, `equal`, `moved`, `updated` -- value -- supports arrays of primitive values and objects -- supports arrays with duplicate values +**Format** + +input + +```ts + prevList: T[]; + nextList: T[]; + options?: { + showOnly?: ("added" | "deleted" | "moved" | "updated" | "equal")[], // [] by default + referenceProperty?: string, // "" by default + ignoreArrayOrder?: boolean, // false by default, + considerMoveAsUpdate?: boolean // false by default + } +``` +- `prevList`: the original list +- `nextList`: the new list +- `options` + - `showOnly` gives you the option to return only the values whose status you are interested in (e.g. `["added", "equal"]`). + - `referenceProperty` will consider an object to be updated instead of added or deleted if one of its properties remains stable, such as its `id`. This option has no effect on other datatypes. + - `ignoreArrayOrder`: if set to `true`, `["hello", "world"]` and `["world", "hello"]` will be treated as `equal`, because the two arrays have the same value, just not in the same order. + - `considerMoveAsUpdate`: if set to `true` the `moved` value will be considered as `updated`. -format: +output ```ts type ListDiff = { @@ -128,56 +239,7 @@ type ListDiff = { }[]; }; ``` - -**Options** - -You can add a third `options` parameter to `getListDiff`. - -```ts -{ - showOnly?: ("added" | "deleted" | "moved" | "updated" | "equal")[], // [] by default - referenceProperty?: string; // "" by default - ignoreArrayOrder?: boolean // false by default, -} -``` - -- `showOnly` gives you the option to return only the values whose status you are interested in (e.g. `["added", "equal"]`). -- `referenceProperty` will consider an object to be updated instead of added or deleted if one of its properties remains stable, such as its `id`. This option has no effect on other datatypes. -- `ignoreArrayOrder`: if set to `true`, `["hello", "world"]` and `["world", "hello"]` will be treated as `equal`, because the two arrays have the same value, just not in the same order. - -### isEqual() - -```js -import { isEqual } from "@donedeal0/superdiff"; -``` - -Tests whether two values are equal. - -**Options** - -You can add a third `options` parameter to `isEqual`. - -```ts -{ - ignoreArrayOrder?: boolean // false by default, -} -``` - -- `ignoreArrayOrder`: if set to `true`, `["hello", "world"]` and `["world", "hello"]` will be treated as `equal`, because the two arrays have the same value, just not in the same order. - -### isObject() - -```js -import { isObject } from "@donedeal0/superdiff"; -``` - -Tests whether a value is an object. - -
- -## EXAMPLES - -### getListDiff() +**Usage** input @@ -233,96 +295,146 @@ output ], } ``` +
-### getObjectDiff() +### streamListDiff() + +```js +import { streamListDiff } from "@donedeal0/superdiff"; +``` + +Streams the diff of two object lists, ideal for large lists and maximum performance. + +**Format** input -```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, - }, - } -); +```ts + prevList: T[], + nextList: T[], + referenceProperty: ReferenceProperty, + options: { + showOnly?: returns only the values whose status you are interested in. (e.g. `["added", "equal"]`), // [] by default + chunksSize?: number, // // 0 by default + considerMoveAsUpdate? boolean; // false by default +} ``` +- `prevList`: the original object list. +- `nextList`: the new object list. +- `referenceProperty`: a common property in all the objects of your lists (e.g. `id`). +- `options` + - `chunksSize` the number of object diffs returned by each stream chunk. If set to `0`, each stream will return a single object diff. If set to `10` each stream will return 10 object diffs. + - `showOnly` gives you the option to return only the values whose status you are interested in (e.g. `["added", "equal"]`). + - `considerMoveAsUpdate`: if set to `true` the `moved` value will be considered as `updated`. + output +```ts +type StreamListDiff> = { + currentValue: T | null; + previousValue: T | null; + prevIndex: number | null; + newIndex: number | null; + indexDiff: number | null; + status: "added" | "deleted" | "moved" | "updated" | "equal"; +}; +``` + +**Usage** + +input + ```diff -{ - type: "object", -+ status: "updated", - diff: [ - { - property: "id", - previousValue: 54, - currentValue: 54, - status: "equal", - }, +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 } + ); +``` + +output + +```diff +diff.on("data", (chunk) => { + // first chunk received (2 object diffs) + [ ++ { ++ previousValue: null, ++ currentValue: { id: 0, name: 'Item 0' }, ++ prevIndex: null, ++ newIndex: 0, ++ indexDiff: null, ++ status: 'added' ++ }, +- { +- previousValue: { id: 1, name: 'Item 1' }, +- currentValue: null, +- prevIndex: 0, +- newIndex: null, +- indexDiff: null, +- status: 'deleted' +- } + ] + // second chunk received (2 object diffs) + [ { - property: "user", - previousValue: { - name: "joe", - member: true, - hobbies: ["golf", "football"], - age: 66, - }, - currentValue: { - name: "joe", - member: false, - hobbies: ["golf", "chess"], - age: 66, - }, -+ status: "updated", - diff: [ - { - property: "name", - previousValue: "joe", - currentValue: "joe", - status: "equal", - }, -+ { -+ property: "member", -+ previousValue: true, -+ currentValue: false, -+ status: "updated", -+ }, -+ { -+ property: "hobbies", -+ previousValue: ["golf", "football"], -+ currentValue: ["golf", "chess"], -+ status: "updated", -+ }, - { - property: "age", - previousValue: 66, - currentValue: 66, - status: "equal", - }, - ], + previousValue: { id: 2, name: 'Item 2' }, + currentValue: { id: 2, name: 'Item 2' }, + prevIndex: 1, + newIndex: 1, + indexDiff: 0, + status: 'equal' }, - ], - } ++ { ++ previousValue: { id: 3, name: 'Item 3' }, ++ currentValue: { id: 3, name: 'Item Three' }, ++ prevIndex: 2, ++ newIndex: 2, ++ indexDiff: 0, ++ status: 'updated' ++ }, + ] +}); + +diff.on("finish", () => console.log("The full diff is available")) +diff.on("error", (err)=> console.log(err)) ``` +
### isEqual() ```js +import { isEqual } from "@donedeal0/superdiff"; +``` + +Checks whether two values are equal. + +**Options** + +You can add a third `options` parameter to `isEqual`. + +```ts +{ + ignoreArrayOrder?: boolean // false by default, +} +``` + +- `ignoreArrayOrder`: if set to `true`, `["hello", "world"]` and `["world", "hello"]` will be treated as `equal`, because the two arrays have the same value, just not in the same order. + +**Usage** + + +```ts isEqual( [ { name: "joe", age: 99 }, @@ -337,25 +449,36 @@ isEqual( output -```js +```ts false; ``` +
### isObject() +```js +import { isObject } from "@donedeal0/superdiff"; +``` + +Tests whether a value is an object. + +**Usage** + input -```js +```ts isObject(["hello", "world"]); ``` output -```js +```ts false; ``` -More examples are available in the source code tests. +
+ +### More examples are available in the source code tests.
@@ -365,7 +488,7 @@ DoneDeal0 ## SUPPORT -If you or your company uses **Superdiff**, please show your support by becoming a sponsor! Your name and company logo will be displayed on the `README.md`. https://github.com/sponsors/DoneDeal0 +If you or your company uses **Superdiff**, please show your support by becoming a sponsor! Your name and company logo will be displayed on the `README.md`. Premium support is also available. https://github.com/sponsors/DoneDeal0
diff --git a/src/index.ts b/src/index.ts index ca0a6d8..798227b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,7 @@ export { getObjectDiff } from "./lib/object-diff"; export { getListDiff } from "./lib/list-diff"; export { isEqual, isObject } from "./lib/utils"; -export { streamListsDiff } from "./lib/stream-list-diff"; +export { streamListDiff } from "./lib/stream-list-diff"; export * from "./models/list"; export * from "./models/object"; export * from "./models/stream"; diff --git a/src/lib/stream-list-diff/emitter.ts b/src/lib/stream-list-diff/emitter.ts index 4d27b30..b768784 100644 --- a/src/lib/stream-list-diff/emitter.ts +++ b/src/lib/stream-list-diff/emitter.ts @@ -1,4 +1,4 @@ -import { StreamListsDiff } from "@models/stream"; +import { StreamListDiff } from "@models/stream"; type Listener = (...args: T) => void; @@ -9,7 +9,7 @@ export enum StreamEvent { } export type Emitter> = EventEmitter<{ - data: [StreamListsDiff[]]; + data: [StreamListDiff[]]; error: [Error]; finish: []; }>; @@ -33,12 +33,12 @@ export class EventEmitter> { } export type EmitterEvents> = { - data: [StreamListsDiff[]]; + data: [StreamListDiff[]]; error: [Error]; finish: []; }; -export interface ReadOnlyEmitter> { +export interface StreamListener> { on>( event: E, listener: Listener[E]>, diff --git a/src/lib/stream-list-diff/index.ts b/src/lib/stream-list-diff/index.ts index d47c1bc..e949619 100644 --- a/src/lib/stream-list-diff/index.ts +++ b/src/lib/stream-list-diff/index.ts @@ -2,7 +2,7 @@ import { DEFAULT_LIST_STREAM_OPTIONS, ListStreamOptions, ReferenceProperty, - StreamListsDiff, + StreamListDiff, StreamReferences, } from "@models/stream"; import { LIST_STATUS } from "@models/list"; @@ -11,17 +11,17 @@ import { Emitter, EmitterEvents, EventEmitter, - ReadOnlyEmitter, + StreamListener, StreamEvent, } from "./emitter"; function outputDiffChunk>( emitter: Emitter, ) { - let chunks: StreamListsDiff[] = []; + let chunks: StreamListDiff[] = []; return function handleDiffChunk( - chunk: StreamListsDiff, + chunk: StreamListDiff, isLastChunk: boolean, options: ListStreamOptions, ): void { @@ -50,9 +50,9 @@ function formatSingleListStreamDiff>( isPrevious: boolean, status: LIST_STATUS, options: ListStreamOptions, -): StreamListsDiff[] | null { +): StreamListDiff[] | null { let isValid = true; - const diff: StreamListsDiff[] = []; + const diff: StreamListDiff[] = []; for (let i = 0; i < list.length; i++) { const data = list[i]; if (!isObject(data)) { @@ -292,7 +292,7 @@ function getDiffChunks>( ); } } - listsReferences.delete(key); // to free up memory + listsReferences.delete(key); } return emitter.emit(StreamEvent.Finish); @@ -304,17 +304,17 @@ function getDiffChunks>( * @param {Record[]} nextList - The new object list. * @param {ReferenceProperty} referenceProperty - A common property in all the objects of your lists (e.g. `id`) * @param {ListStreamOptions} options - Options to refine your output. - - `chunksSize`: the number of object diffs returned by each stream chunk. If set to `0`, each stream will return a single object diff. If set to `10` each stream will return 10 object diffs. (default is `0`) + - `chunksSize`: the number of object diffs returned by each streamed chunk. (e.g. `0` = 1 object diff by chunk, `10` = 10 object diffs by chunk). - `showOnly`: returns only the values whose status you are interested in. (e.g. `["added", "equal"]`) - `considerMoveAsUpdate`: if set to `true` a `moved` object will be considered as `updated` * @returns EventEmitter */ -export function streamListsDiff>( +export function streamListDiff>( prevList: T[], nextList: T[], referenceProperty: ReferenceProperty, options: ListStreamOptions = DEFAULT_LIST_STREAM_OPTIONS, -): ReadOnlyEmitter { +): StreamListener { const emitter = new EventEmitter>(); setTimeout(() => { try { @@ -323,5 +323,5 @@ export function streamListsDiff>( return emitter.emit(StreamEvent.Error, err as Error); } }, 0); - return emitter as ReadOnlyEmitter; + return emitter as StreamListener; } diff --git a/src/lib/stream-list-diff/stream-list-diff.test.ts b/src/lib/stream-list-diff/stream-list-diff.test.ts index 2a171a7..5d8795c 100644 --- a/src/lib/stream-list-diff/stream-list-diff.test.ts +++ b/src/lib/stream-list-diff/stream-list-diff.test.ts @@ -1,14 +1,14 @@ import { LIST_STATUS } from "@models/list"; -import { streamListsDiff } from "."; -import { StreamListsDiff } from "@models/stream"; +import { streamListDiff } from "."; +import { StreamListDiff } from "@models/stream"; -describe("streamListsDiff data", () => { +describe("streamListDiff data", () => { it("emits 'data' event and consider the all the nextList added if no prevList is provided", (done) => { const nextList = [ { id: 1, name: "Item 1" }, { id: 2, name: "Item 2" }, ]; - const diff = streamListsDiff([], nextList, "id", { chunksSize: 2 }); + const diff = streamListDiff([], nextList, "id", { chunksSize: 2 }); const expectedChunks = [ { @@ -43,7 +43,7 @@ describe("streamListsDiff data", () => { { id: 1, name: "Item 1" }, { id: 2, name: "Item 2" }, ]; - const diff = streamListsDiff(prevList, [], "id", { chunksSize: 2 }); + const diff = streamListDiff(prevList, [], "id", { chunksSize: 2 }); const expectedChunks = [ { @@ -82,7 +82,7 @@ describe("streamListsDiff data", () => { { id: 2, name: "Item 2" }, { id: 3, name: "Item 3" }, ]; - const diff = streamListsDiff(prevList, nextList, "id"); + const diff = streamListDiff(prevList, nextList, "id"); const expectedChunks = [ [ @@ -153,7 +153,7 @@ describe("streamListsDiff data", () => { { id: 9, name: "Item 9" }, { id: 8, name: "Item 8" }, ]; - const diff = streamListsDiff(prevList, nextList, "id", { chunksSize: 5 }); + const diff = streamListDiff(prevList, nextList, "id", { chunksSize: 5 }); const expectedChunks = [ [ @@ -277,7 +277,7 @@ describe("streamListsDiff data", () => { { id: 3, name: "Item 3" }, { id: 5, name: "Item 5" }, ]; - const diff = streamListsDiff(prevList, nextList, "id", { chunksSize: 150 }); + const diff = streamListDiff(prevList, nextList, "id", { chunksSize: 150 }); const expectedChunks = [ { @@ -346,7 +346,7 @@ describe("streamListsDiff data", () => { { id: 3, name: "Item 3" }, { id: 5, name: "Item 5" }, ]; - const diff = streamListsDiff(prevList, nextList, "id", { + const diff = streamListDiff(prevList, nextList, "id", { chunksSize: 5, considerMoveAsUpdate: true, }); @@ -418,7 +418,7 @@ describe("streamListsDiff data", () => { { id: 3, name: "Item 3" }, { id: 5, name: "Item 5" }, ]; - const diff = streamListsDiff(prevList, nextList, "id", { + const diff = streamListDiff(prevList, nextList, "id", { chunksSize: 5, showOnly: ["added", "deleted"], }); @@ -506,7 +506,7 @@ describe("streamListsDiff data", () => { { id: 9, name: "Item 9" }, { id: 8, name: "Item 8" }, ]; - const diff = streamListsDiff(prevList, nextList, "id", { chunksSize: 5 }); + const diff = streamListDiff(prevList, nextList, "id", { chunksSize: 5 }); const expectedChunks = [ [ @@ -663,9 +663,9 @@ describe("streamListsDiff data", () => { }); }); -describe("streamListsDiff finish", () => { +describe("streamListDiff finish", () => { it("emits 'finish' event if no prevList nor nextList is provided", (done) => { - const diff = streamListsDiff([], [], "id"); + const diff = streamListDiff([], [], "id"); diff.on("finish", () => done()); }); it("emits 'finish' event when all the chunks have been processed", (done) => { @@ -677,12 +677,12 @@ describe("streamListsDiff finish", () => { { id: 2, name: "Item 2" }, { id: 3, name: "Item 3" }, ]; - const diff = streamListsDiff(prevList, nextList, "id"); + const diff = streamListDiff(prevList, nextList, "id"); diff.on("finish", () => done()); }); }); -describe("streamListsDiff error", () => { +describe("streamListDiff error", () => { test("emits 'error' event when prevList has invalid data", (done) => { const prevList = [ { id: 1, name: "Item 1" }, @@ -695,7 +695,7 @@ describe("streamListsDiff error", () => { ]; // @ts-expect-error prevList is invalid by design for the test - const diff = streamListsDiff(prevList, nextList, "id"); + const diff = streamListDiff(prevList, nextList, "id"); diff.on("error", (err) => { expect(err["message"]).toEqual( @@ -717,7 +717,7 @@ describe("streamListsDiff error", () => { ]; // @ts-expect-error nextList is invalid by design for the test - const diff = streamListsDiff(prevList, nextList, "id"); + const diff = streamListDiff(prevList, nextList, "id"); diff.on("error", (err) => { expect(err["message"]).toEqual( @@ -734,7 +734,7 @@ describe("streamListsDiff error", () => { { id: 2, name: "Item 2" }, ]; - const diff = streamListsDiff(prevList, nextList, "id"); + const diff = streamListDiff(prevList, nextList, "id"); diff.on("error", (err) => { expect(err["message"]).toEqual( @@ -751,7 +751,7 @@ describe("streamListsDiff error", () => { ]; const nextList = [{ id: 1, name: "Item 1" }, { name: "Item 2" }]; - const diff = streamListsDiff(prevList, nextList, "id"); + const diff = streamListDiff(prevList, nextList, "id"); diff.on("error", (err) => { expect(err["message"]).toEqual( @@ -768,7 +768,7 @@ describe("streamListsDiff error", () => { ]; const nextList = [{ id: 1, name: "Item 1" }, { name: "Item 2" }]; - const diff = streamListsDiff(prevList, nextList, "id", { chunksSize: -3 }); + const diff = streamListDiff(prevList, nextList, "id", { chunksSize: -3 }); diff.on("error", (err) => { expect(err["message"]).toEqual( @@ -793,9 +793,9 @@ describe("Performance", () => { ...generateLargeList(5000, "next"), ]; - const receivedChunks: StreamListsDiff<{ id: string; value: number }>[] = []; + const receivedChunks: StreamListDiff<{ id: string; value: number }>[] = []; let chunkCount = 0; - const diffStream = streamListsDiff(prevList, nextList, "id", { + const diffStream = streamListDiff(prevList, nextList, "id", { chunksSize: 1000, }); @@ -835,9 +835,9 @@ describe("Performance", () => { ...generateLargeList(50000, "next"), ]; - const receivedChunks: StreamListsDiff<{ id: string; value: number }>[] = []; + const receivedChunks: StreamListDiff<{ id: string; value: number }>[] = []; let chunkCount = 0; - const diffStream = streamListsDiff(prevList, nextList, "id", { + const diffStream = streamListDiff(prevList, nextList, "id", { chunksSize: 10_000, }); @@ -864,46 +864,4 @@ describe("Performance", () => { done(); }); }); - // it("should correctly stream diff for 1.000.000 entries", (done) => { - // const generateLargeList = (size: number, idPrefix: string) => { - // return Array.from({ length: size }, (_, i) => ({ - // id: `${idPrefix}-${i}`, - // value: i, - // })); - // }; - // const prevList = generateLargeList(1_000_000, "prev"); - // const nextList = [ - // ...generateLargeList(500_000, "prev"), - // ...generateLargeList(500_000, "next"), - // ]; - - // const receivedChunks: StreamListsDiff<{ id: string; value: number }>[] = []; - // let chunkCount = 0; - // const diffStream = streamListsDiff(prevList, nextList, "id", { - // chunksSize: 100_000, - // }); - - // diffStream.on("data", (chunk) => { - // receivedChunks.push(...chunk); - // chunkCount++; - // }); - - // diffStream.on("finish", () => { - // const deletions = receivedChunks.filter( - // (diff) => diff.status === LIST_STATUS.DELETED, - // ); - // const additions = receivedChunks.filter( - // (diff) => diff.status === LIST_STATUS.ADDED, - // ); - // const updates = receivedChunks.filter( - // (diff) => diff.status === LIST_STATUS.EQUAL, - // ); - // expect(receivedChunks.length).toBe(1_500_000); // 50.000 deletions + 50.000 equal + 50.000 additions - // expect(chunkCount).toBe(15); - // expect(deletions.length).toBe(500000); - // expect(additions.length).toBe(500000); - // expect(updates.length).toBe(500000); - // done(); - // }); - // }); }); diff --git a/src/models/stream/index.ts b/src/models/stream/index.ts index 0bda847..d932ebd 100644 --- a/src/models/stream/index.ts +++ b/src/models/stream/index.ts @@ -1,6 +1,6 @@ import { LIST_STATUS } from "@models/list"; -export type StreamListsDiff> = { +export type StreamListDiff> = { currentValue: T | null; previousValue: T | null; prevIndex: number | null;