Browse Source

chore: update jsdoc

pull/28/head
Antoine Lanoe 6 months ago
parent
commit
c2d80ead95
  1. 1
      .prettierignore
  2. 82
      README.md
  3. 1
      src/client.ts
  4. 1
      src/index.ts
  5. 16
      src/lib/stream-list-diff/client/index.ts
  6. 48
      src/lib/stream-list-diff/client/stream-list-diff-client.test.ts
  7. 2
      src/lib/stream-list-diff/index.ts
  8. 17
      src/lib/stream-list-diff/server/index.ts
  9. 2
      src/lib/utils/index.ts
  10. 1
      src/server.ts
  11. 29
      tsup.config.ts

1
.prettierignore

@ -5,4 +5,3 @@ jest.config.js @@ -5,4 +5,3 @@ jest.config.js
package-lock.json
README.md
tsconfig.json
tsup.config.ts

82
README.md

@ -40,7 +40,7 @@ I am grateful to the generous donors of **Superdiff**! @@ -40,7 +40,7 @@ I am grateful to the generous donors of **Superdiff**!
## FEATURES
**Superdiff** exports 6 functions:
**Superdiff** exports 5 functions:
```ts
// Returns a complete diff of two objects
@ -52,9 +52,6 @@ getListDiff(prevList, nextList) @@ -52,9 +52,6 @@ getListDiff(prevList, nextList)
// Streams the diff of two object lists, ideal for large lists and maximum performance
streamListDiff(prevList, nextList, referenceProperty)
// Similar to streamListDiff, but for browser use
streamListDiffClient(prevList, nextList, referenceProperty)
// Checks whether two values are equal
isEqual(dataA, dataB)
@ -310,9 +307,9 @@ getListDiff( @@ -310,9 +307,9 @@ getListDiff(
```js
// If you are in a server environment
import { streamListDiff } from "@donedeal0/superdiff";
import { streamListDiff } from "@donedeal0/superdiff/server";
// If you are in a browser environment
import { streamListDiffClient } from "@donedeal0/superdiff";
import { streamListDiff } from "@donedeal0/superdiff/client";
```
Streams the diff of two object lists, ideal for large lists and maximum performance.
@ -321,12 +318,11 @@ Streams the diff of two object lists, ideal for large lists and maximum performa @@ -321,12 +318,11 @@ Streams the diff of two object lists, ideal for large lists and maximum performa
**Input**
#### streamListDiff (server)
#### Server
> In a server environment, `Readable` refers to Node.js streams, and `FilePath` refers to the path of a file (e.g., `./list.json`). Examples are provided in the #usage section below.
```ts
// streamListDiff
prevList: Readable | FilePath | Record<string, unknown>[],
nextList: Readable | FilePath | Record<string, unknown>[],
referenceProperty: keyof Record<string, unknown>,
@ -337,7 +333,7 @@ Streams the diff of two object lists, ideal for large lists and maximum performa @@ -337,7 +333,7 @@ Streams the diff of two object lists, ideal for large lists and maximum performa
}
```
#### streamListDiffClient (browser)
#### Browser
> In a browser environment, `ReadableStream` refers to the browser's streaming API, and `File` refers to an uploaded or local file. Examples are provided in the #usage section below.
@ -495,74 +491,6 @@ diff.on("finish", () => console.log("Your data has been processed. The full diff @@ -495,74 +491,6 @@ diff.on("finish", () => console.log("Your data has been processed. The full diff
diff.on("error", (err) => console.log(err))
```
**Using `fetch`**
A common use case would be to do a live diff against a stream, in order to avoid loading the entire dataset into memory. Here are two examples, for browser and server use:
Browser:
```ts
import { streamListDiffClient } from "@donedeal0/superdiff";
async function streamDiffFromAPI() {
try {
const response = await fetch("https://example.com/api/streaming-data");
const reader = response.body.getReader();
const stream = new ReadableStream({
async start(controller) {
let result;
while (!(result = await reader.read()).done) {
controller.enqueue(result.value); // Push the next chunk into the stream
}
controller.close(); // Close the stream when done
},
});
const prevStream = [{ id: 1, name: "Joe" }, { id: 2, name: "Jane" }] // Some previous list or stream
const diff = streamListDiffClient(prevStream, stream, 'id', { chunksSize: 5 });
diff.on("data", (diffChunk) => console.log(diffChunk));
diff.on("finish", () => console.log("Stream diff complete"));
} catch (err) {
console.error(err);
}
}
```
Server:
```ts
import fetch from "node-fetch";
import { Readable } from "stream";
import { streamListDiff } from "@donedeal0/superdiff";
async function streamDiffFromAPI() {
try {
const response = await fetch("https://example.com/api/streaming-data");
const reader = response.body.getReader();
const stream = new Readable({
async read() {
let result;
while (!(result = await reader.read()).done) {
this.push(result.value); // Push the next chunk into the stream
}
this.push(null); // Close the stream when done
},
});
const prevList = [{ id: 1, name: "Joe" }, { id: 2, name: "Jane" }]; // Some previous list or stream
const prevListStream = Readable.from(prevList, { objectMode: true })
const diff = streamListDiff(prevListStream, stream, 'id', { chunksSize: 5 });
diff.on("data", (diffChunk) => console.log(diffChunk));
diff.on("finish", () => console.log("Stream diff complete"));
} catch (err) {
console.error(err);
}
}
```
<hr/>
### isEqual()

1
src/client.ts

@ -0,0 +1 @@ @@ -0,0 +1 @@
export { streamListDiff } from "./lib/stream-list-diff/client";

1
src/index.ts

@ -1,7 +1,6 @@ @@ -1,7 +1,6 @@
export { getObjectDiff } from "./lib/object-diff";
export { getListDiff } from "./lib/list-diff";
export { isEqual, isObject } from "./lib/utils";
export * from "./lib/stream-list-diff";
export * from "./models/list";
export * from "./models/object";
export * from "./models/stream";

16
src/lib/stream-list-diff/client/index.ts

@ -1,4 +1,3 @@ @@ -1,4 +1,3 @@
import { isClient } from "@lib/utils";
import {
DataBuffer,
DEFAULT_LIST_STREAM_OPTIONS,
@ -246,26 +245,21 @@ async function getValidClientStream<T extends Record<string, unknown>>( @@ -246,26 +245,21 @@ async function getValidClientStream<T extends Record<string, unknown>>(
/**
* Streams the diff of two object lists
* @param {Record<string, unknown>[]} prevList - The original object list.
* @param {Record<string, unknown>[]} nextList - The new object list.
* @param {ReferenceProperty<T>} referenceProperty - A common property in all the objects of your lists (e.g. `id`)
* @param {ReadableStream | File | Record<string, unknown>[]} prevList - The original object list.
* @param {ReadableStream | File | Record<string, unknown>[]} nextList - The new object list.
* @param {string} 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 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
* @returns StreamListener
*/
export function streamListDiffClient<T extends Record<string, unknown>>(
export function streamListDiff<T extends Record<string, unknown>>(
prevList: ReadableStream<T> | File | T[],
nextList: ReadableStream<T> | File | T[],
referenceProperty: ReferenceProperty<T>,
options: ListStreamOptions = DEFAULT_LIST_STREAM_OPTIONS,
): StreamListener<T> {
if (!isClient()) {
throw new Error(
"streamListDiffClient can only be used in a browser environment. Please use streamListDiff instead.",
);
}
const emitter = new EventEmitter<EmitterEvents<T>>();
setTimeout(async () => {
try {

48
src/lib/stream-list-diff/client/stream-list-diff-client.test.ts

@ -5,7 +5,7 @@ import "blob-polyfill"; @@ -5,7 +5,7 @@ import "blob-polyfill";
import { ReadableStream } from "web-streams-polyfill";
import { LIST_STATUS } from "@models/list";
import { StreamListDiff } from "@models/stream";
import { streamListDiffClient } from ".";
import { streamListDiff } from ".";
import prevListFile from "../../../mocks/prevList.json";
import nextListFile from "../../../mocks/nextList.json";
@ -18,7 +18,7 @@ describe("data emission", () => { @@ -18,7 +18,7 @@ describe("data emission", () => {
{ id: 1, name: "Item 1" },
{ id: 2, name: "Item 2" },
];
const diff = streamListDiffClient([], nextList, "id", { chunksSize: 2 });
const diff = streamListDiff([], nextList, "id", { chunksSize: 2 });
const expectedChunks = [
{
@ -53,7 +53,7 @@ describe("data emission", () => { @@ -53,7 +53,7 @@ describe("data emission", () => {
{ id: 1, name: "Item 1" },
{ id: 2, name: "Item 2" },
];
const diff = streamListDiffClient(prevList, [], "id", { chunksSize: 2 });
const diff = streamListDiff(prevList, [], "id", { chunksSize: 2 });
const expectedChunks = [
{
@ -93,7 +93,7 @@ describe("data emission", () => { @@ -93,7 +93,7 @@ describe("data emission", () => {
{ id: 2, name: "Item 2" },
{ id: 3, name: "Item 3" },
];
const diff = streamListDiffClient(prevList, nextList, "id");
const diff = streamListDiff(prevList, nextList, "id");
const expectedChunks = [
[
@ -164,7 +164,7 @@ describe("data emission", () => { @@ -164,7 +164,7 @@ describe("data emission", () => {
{ id: 9, name: "Item 9" },
{ id: 8, name: "Item 8" },
];
const diff = streamListDiffClient(prevList, nextList, "id", {
const diff = streamListDiff(prevList, nextList, "id", {
chunksSize: 5,
});
@ -291,7 +291,7 @@ describe("data emission", () => { @@ -291,7 +291,7 @@ describe("data emission", () => {
{ id: 5, name: "Item 5" },
];
const diff = streamListDiffClient(prevList, nextList, "id", {
const diff = streamListDiff(prevList, nextList, "id", {
chunksSize: 150,
});
@ -362,7 +362,7 @@ describe("data emission", () => { @@ -362,7 +362,7 @@ describe("data emission", () => {
{ id: 3, name: "Item 3" },
{ id: 5, name: "Item 5" },
];
const diff = streamListDiffClient(prevList, nextList, "id", {
const diff = streamListDiff(prevList, nextList, "id", {
chunksSize: 5,
considerMoveAsUpdate: true,
});
@ -434,7 +434,7 @@ describe("data emission", () => { @@ -434,7 +434,7 @@ describe("data emission", () => {
{ id: 3, name: "Item 3" },
{ id: 5, name: "Item 5" },
];
const diff = streamListDiffClient(prevList, nextList, "id", {
const diff = streamListDiff(prevList, nextList, "id", {
chunksSize: 5,
showOnly: ["added", "deleted"],
});
@ -522,7 +522,7 @@ describe("data emission", () => { @@ -522,7 +522,7 @@ describe("data emission", () => {
{ id: 9, name: "Item 9" },
{ id: 8, name: "Item 8" },
];
const diff = streamListDiffClient(prevList, nextList, "id", {
const diff = streamListDiff(prevList, nextList, "id", {
chunksSize: 5,
});
@ -751,7 +751,7 @@ describe("input handling", () => { @@ -751,7 +751,7 @@ describe("input handling", () => {
},
});
const diff = streamListDiffClient(prevStream, nextStream, "id", {
const diff = streamListDiff(prevStream, nextStream, "id", {
chunksSize: 5,
});
@ -775,7 +775,7 @@ describe("input handling", () => { @@ -775,7 +775,7 @@ describe("input handling", () => {
type: "application/json",
});
const diff = streamListDiffClient(prevFile, nextFile, "id", {
const diff = streamListDiff(prevFile, nextFile, "id", {
chunksSize: 5,
});
@ -801,7 +801,7 @@ describe("input handling", () => { @@ -801,7 +801,7 @@ describe("input handling", () => {
type: "application/json",
});
const diff = streamListDiffClient(prevStream, nextFile, "id", {
const diff = streamListDiff(prevStream, nextFile, "id", {
chunksSize: 5,
});
@ -824,7 +824,7 @@ describe("input handling", () => { @@ -824,7 +824,7 @@ describe("input handling", () => {
},
});
const diff = streamListDiffClient(prevStream, nextList, "id", {
const diff = streamListDiff(prevStream, nextList, "id", {
chunksSize: 5,
});
@ -844,7 +844,7 @@ describe("input handling", () => { @@ -844,7 +844,7 @@ describe("input handling", () => {
type: "application/json",
});
const diff = streamListDiffClient(prevFile, nextList, "id", {
const diff = streamListDiff(prevFile, nextList, "id", {
chunksSize: 5,
});
@ -863,7 +863,7 @@ describe("input handling", () => { @@ -863,7 +863,7 @@ describe("input handling", () => {
describe("finish event", () => {
it("emits 'finish' event if no prevList nor nextList is provided", (done) => {
const diff = streamListDiffClient([], [], "id");
const diff = streamListDiff([], [], "id");
diff.on("finish", () => done());
});
it("emits 'finish' event when all the chunks have been processed", (done) => {
@ -875,7 +875,7 @@ describe("finish event", () => { @@ -875,7 +875,7 @@ describe("finish event", () => {
{ id: 2, name: "Item 2" },
{ id: 3, name: "Item 3" },
];
const diff = streamListDiffClient(prevList, nextList, "id");
const diff = streamListDiff(prevList, nextList, "id");
diff.on("finish", () => done());
});
});
@ -893,7 +893,7 @@ describe("error event", () => { @@ -893,7 +893,7 @@ describe("error event", () => {
];
// @ts-expect-error prevList is invalid by design for the test
const diff = streamListDiffClient(prevList, nextList, "id");
const diff = streamListDiff(prevList, nextList, "id");
diff.on("error", (err) => {
expect(err["message"]).toEqual(
@ -915,7 +915,7 @@ describe("error event", () => { @@ -915,7 +915,7 @@ describe("error event", () => {
];
// @ts-expect-error nextList is invalid by design for the test
const diff = streamListDiffClient(prevList, nextList, "id");
const diff = streamListDiff(prevList, nextList, "id");
diff.on("error", (err) => {
expect(err["message"]).toEqual(
@ -932,7 +932,7 @@ describe("error event", () => { @@ -932,7 +932,7 @@ describe("error event", () => {
{ id: 2, name: "Item 2" },
];
const diff = streamListDiffClient(prevList, nextList, "id");
const diff = streamListDiff(prevList, nextList, "id");
diff.on("error", (err) => {
expect(err["message"]).toEqual(
@ -949,7 +949,7 @@ describe("error event", () => { @@ -949,7 +949,7 @@ describe("error event", () => {
];
const nextList = [{ id: 1, name: "Item 1" }, { name: "Item 2" }];
const diff = streamListDiffClient(prevList, nextList, "id");
const diff = streamListDiff(prevList, nextList, "id");
diff.on("error", (err) => {
expect(err["message"]).toEqual(
@ -966,7 +966,7 @@ describe("error event", () => { @@ -966,7 +966,7 @@ describe("error event", () => {
];
const nextList = [{ id: 1, name: "Item 1" }, { name: "Item 2" }];
const diff = streamListDiffClient(prevList, nextList, "id", {
const diff = streamListDiff(prevList, nextList, "id", {
chunksSize: -3,
});
@ -982,7 +982,7 @@ describe("error event", () => { @@ -982,7 +982,7 @@ describe("error event", () => {
const nextList = [{ id: 1, name: "Item 1" }, { name: "Item 2" }];
// @ts-expect-error - prevList is invalid by design for the test
const diff = streamListDiffClient({ name: "hello" }, nextList, "id");
const diff = streamListDiff({ name: "hello" }, nextList, "id");
diff.on("error", (err) => {
expect(err["message"]).toEqual(
@ -995,7 +995,7 @@ describe("error event", () => { @@ -995,7 +995,7 @@ describe("error event", () => {
const prevList = [{ id: 1, name: "Item 1" }, { name: "Item 2" }];
// @ts-expect-error - nextList is invalid by design for the test
const diff = streamListDiffClient(prevList, null, "id");
const diff = streamListDiff(prevList, null, "id");
diff.on("error", (err) => {
expect(err["message"]).toEqual(
@ -1025,7 +1025,7 @@ describe("performance", () => { @@ -1025,7 +1025,7 @@ describe("performance", () => {
nextList[20_000].value = "updated-value-20000"; // Another updated entry
nextList.push({ id: numEntries, value: `new-value-${numEntries}` }); // 1 added entry
const diffListener = streamListDiffClient<{ id: number; value: string }>(
const diffListener = streamListDiff<{ id: number; value: string }>(
prevList,
nextList,
"id",

2
src/lib/stream-list-diff/index.ts

@ -1,2 +0,0 @@ @@ -1,2 +0,0 @@
export { streamListDiffClient } from "./client";
export { streamListDiff } from "./server";

17
src/lib/stream-list-diff/server/index.ts

@ -8,7 +8,6 @@ import { @@ -8,7 +8,6 @@ import {
ListStreamOptions,
ReferenceProperty,
} from "@models/stream";
import { isClient } from "@lib/utils";
import {
Emitter,
EmitterEvents,
@ -232,17 +231,23 @@ function getValidStream<T>( @@ -232,17 +231,23 @@ function getValidStream<T>(
throw new Error(`Invalid ${listType}. Expected Readable, Array, or File.`);
}
/**
* Streams the diff of two object lists
* @param {Readable | FilePath | Record<string, unknown>[]} prevList - The original object list.
* @param {Readable | FilePath | Record<string, unknown>[]} nextList - The new object list.
* @param {string} 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 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 StreamListener
*/
export function streamListDiff<T extends Record<string, unknown>>(
prevStream: Readable | FilePath | T[],
nextStream: Readable | FilePath | T[],
referenceProperty: ReferenceProperty<T>,
options: ListStreamOptions = DEFAULT_LIST_STREAM_OPTIONS,
): StreamListener<T> {
if (isClient()) {
throw new Error(
"streamListDiff can only be used in Node environment. Please use streamListDiffClient instead.",
);
}
const emitter = new EventEmitter<EmitterEvents<T>>();
setTimeout(async () => {
try {

2
src/lib/utils/index.ts

@ -38,5 +38,3 @@ export function isEqual( @@ -38,5 +38,3 @@ export function isEqual(
export function isObject(value: unknown): value is Record<string, unknown> {
return !!value && typeof value === "object" && !Array.isArray(value);
}
export const isClient = () => typeof window !== "undefined";

1
src/server.ts

@ -0,0 +1 @@ @@ -0,0 +1 @@
export { streamListDiff } from "./lib/stream-list-diff/server";

29
tsup.config.ts

@ -1,12 +1,31 @@ @@ -1,12 +1,31 @@
import { defineConfig } from "tsup";
import { defineConfig, Options } from "tsup";
export default defineConfig({
entry: ["src/index.ts"],
format: ["cjs", "esm"],
const sharedConfig: Options = {
dts: true,
splitting: true,
clean: true,
treeshake: true,
shims: true,
minify: true,
});
};
export default defineConfig([
{
entry: ["src/index.ts"],
format: ["cjs", "esm"],
...sharedConfig,
platform: "neutral",
},
{
entry: ["src/server.ts"],
format: ["cjs", "esm"],
...sharedConfig,
platform: "node",
},
{
entry: ["src/client.ts"],
format: ["cjs", "esm"],
...sharedConfig,
platform: "browser",
},
]);

Loading…
Cancel
Save