Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: stream large lists diff #26

Merged
merged 8 commits into from
Oct 6, 2024
Merged

chore: stream large lists diff #26

merged 8 commits into from
Oct 6, 2024

Conversation

DoneDeal0
Copy link
Owner

@DoneDeal0 DoneDeal0 commented Oct 4, 2024

NEW FEATURE

streamListDiff()

import { streamListDiff } from "@donedeal0/superdiff";

Streams the diff of two object lists, ideal for large lists and maximum performance.

FORMAT

Input

 prevList: Record<string, unknown>[],
 nextList: Record<string, unknown>[],
 referenceProperty: keyof Record<string, unknown>,
 options: {
  showOnly?: ("added" | "deleted" | "moved" | "updated" | "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 streamed chunk. (e.g. 0 = 1 object diff by chunk, 10 = 10 object diffs by chunk).
    • 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 a moved value will be considered as updated.

Output

The objects diff are grouped in arrays - called chunks - and are consumed thanks to an event listener. You have access to 3 events:

  • data: to be notified when a new chunk of object diffs is available.
  • finish: to be notified when the stream is complete.
  • error: to be notified of an error during the stream.
interface StreamListener<T extends Record<string, unknown>> {
  on<E extends keyof EmitterEvents<T>>(
    event: E,
    listener: Listener<EmitterEvents<T>[E]>,
  ): this;
}

type EmitterEvents<T extends Record<string, unknown>> = {
  data: [StreamListDiff<T>[]];
  error: [Error];
  finish: [];
};


type StreamListDiff<T extends Record<string, unknown>> = {
  currentValue: T | null;
  previousValue: T | null;
  prevIndex: number | null;
  newIndex: number | null;
  indexDiff: number | null;
  status: "added" | "deleted" | "moved" | "updated" | "equal";
};

USAGE

Input

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.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)
      [
        {
          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))

ADDITIONAL FIXES

  • use SWC to speed up the tests.
  • Add aliases (@models, @lib).
  • clean devDependencies.
  • restructure the codebase with folders.
  • Update README.md.

@DoneDeal0 DoneDeal0 self-assigned this Oct 4, 2024
@DoneDeal0 DoneDeal0 changed the title chore: stream large lists diff [DRAFT] chore: stream large lists diff Oct 4, 2024
@DoneDeal0 DoneDeal0 added the enhancement New feature or request label Oct 4, 2024
@DoneDeal0 DoneDeal0 changed the title [DRAFT] chore: stream large lists diff chore: stream large lists diff Oct 6, 2024
@DoneDeal0 DoneDeal0 marked this pull request as ready for review October 6, 2024 15:19
@DoneDeal0 DoneDeal0 merged commit 8ffb9ea into master Oct 6, 2024
1 check passed
@DoneDeal0 DoneDeal0 deleted the stream-list-diff branch October 6, 2024 18:28
Copy link

github-actions bot commented Oct 7, 2024

🎉 This PR is included in version 2.1.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request released
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant