> For the complete documentation index, see [llms.txt](https://donedeal0.gitbook.io/superdiff/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://donedeal0.gitbook.io/superdiff/features/streamlistdiff/server.md).

# server

## IMPORT

```typescript
import { streamListDiff } from "@donedeal0/superdiff/server";
```

***

## FORMAT

### Input

> In a server environment, `Readable` refers to NodeJS streams, and `FilePath` refers to the path of a file (e.g., `./list.json`). Examples are provided in the #usage section below.

```typescript
 prevList: Readable | FilePath | Record<string, unknown>[],
 nextList: Readable | FilePath | Record<string, unknown>[],
 referenceKey: keyof Record<string, unknown>,
 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
}
```

* `prevList`: the original object list.
* `nextList`: the new object list.
* `referenceKey`: a key common to all objects in your lists (e.g. `id`).
* `options`
  * `chunksSize` the number of object diffs returned by each streamed chunk. (e.g. `0` = 1 object diff per chunk, `10` = 10 object diffs per 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`.
  * `useWorker`: if set to `true`, the diff will be run in a worker for maximum performance. Only recommended for large lists (e.g. +100,000 items).
  * `showWarnings`: if set to `true`, potential warnings will be displayed in the console.

{% hint style="danger" %}
Using Readable streams may impact workers' performance since they need to be converted to arrays. Consider using arrays or files for optimal performance. Alternatively, you can turn the `useWorker` option off.
{% endhint %}

### Output

The objects diff are grouped into 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 finished.
* `error`: to be notified if an error occurs during the stream.

```typescript
interface StreamListener<T> {
  on(event: "data", listener: (chunk: StreamListDiff<T>[]) => void);
  on(event: "finish", listener: () => void);
  on(event: "error", listener: (error: Error) => void);
}

type StreamListDiff<T extends Record<string, unknown>> = {
  value: T | null;
  index: number | null;
  previousValue: T | null;
  previousIndex: number | null;
  status: "added" | "deleted" | "moved" | "updated" | "equal";
};
```

***

## USAGE

### Input

> Array

```typescript

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 }
    );
```

> Stream

```typescript
const previousStream = Readable.from(previousArray, { objectMode: true });
    
const nextStream = Readable.from(nextArray, { objectMode: true });
    
const diff = streamListDiff(previousStream, nextStream, "id", { chunksSize: 2 });
```

> File

```typescript
const previousFile = path.resolve(__dirname, "./previousArrayFile.json"); 
                              
const nextFile = path.resolve(__dirname, "./previousArrayFile.json");
                              
const diff = streamListDiff(previousFile, nextFile, "id", { chunksSize: 10 });
 
```

> 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 }
    );
```

### Output

```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))
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://donedeal0.gitbook.io/superdiff/features/streamlistdiff/server.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
