Skip to content

Commit 268dc6a

Browse files
committed
feat: use workers for streamListDiff
1 parent 4d22c68 commit 268dc6a

31 files changed

+3867
-966
lines changed

.gitignore

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
/node_modules
22
dist
3-
.eslintcache
3+
.eslintcache
4+
# Ignore generated worker files
5+
src/lib/stream-list-diff/server/worker/node-worker.cjs

README.md

+17-14
Original file line numberDiff line numberDiff line change
@@ -104,12 +104,12 @@ type ObjectDiff = {
104104
diff: Diff[];
105105
};
106106

107-
/** recursive diff in case of subproperties */
108107
type Diff = {
109108
property: string;
110109
previousValue: unknown;
111110
currentValue: unknown;
112111
status: "added" | "deleted" | "equal" | "updated";
112+
// recursive diff in case of subproperties
113113
diff?: Diff[];
114114
};
115115
```
@@ -307,13 +307,15 @@ getListDiff(
307307

308308
```js
309309
// If you are in a server environment
310-
import { streamListDiff } from "@donedeal0/superdiff/server";
310+
import { streamListDiff } from "@donedeal0/superdiff/server.cjs";
311311
// If you are in a browser environment
312312
import { streamListDiff } from "@donedeal0/superdiff/client";
313313
```
314314

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

317+
ℹ️ `streamListDiff` requires ESM support for browser usage. It will work out of the box if you use a modern bundler (Webpack, Rollup) or JavaScript framework (Next.js, Vue.js).
318+
317319
#### FORMAT
318320

319321
**Input**
@@ -330,6 +332,8 @@ Streams the diff of two object lists, ideal for large lists and maximum performa
330332
showOnly?: ("added" | "deleted" | "moved" | "updated" | "equal")[], // [] by default
331333
chunksSize?: number, // 0 by default
332334
considerMoveAsUpdate?: boolean; // false by default
335+
useWorker?: boolean; // true by default
336+
showWarnings?: boolean; // true by default
333337
}
334338
```
335339

@@ -345,6 +349,9 @@ Streams the diff of two object lists, ideal for large lists and maximum performa
345349
showOnly?: ("added" | "deleted" | "moved" | "updated" | "equal")[], // [] by default
346350
chunksSize?: number, // 0 by default
347351
considerMoveAsUpdate?: boolean; // false by default
352+
useWorker?: boolean; // true by default
353+
showWarnings?: boolean; // true by default
354+
348355
}
349356
```
350357

@@ -355,6 +362,10 @@ Streams the diff of two object lists, ideal for large lists and maximum performa
355362
- `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).
356363
- `showOnly` gives you the option to return only the values whose status you are interested in (e.g. `["added", "equal"]`).
357364
- `considerMoveAsUpdate`: if set to `true` a `moved` value will be considered as `updated`.
365+
- `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).
366+
- `showWarnings`: if set to `true`, potential warnings will be displayed in the console.
367+
368+
> ⚠️ Warning: 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.
358369
359370
**Output**
360371

@@ -364,20 +375,12 @@ The objects diff are grouped into arrays - called `chunks` - and are consumed th
364375
- `error`: to be notified if an error occurs during the stream.
365376

366377
```ts
367-
interface StreamListener<T extends Record<string, unknown>> {
368-
on<E extends keyof EmitterEvents<T>>(
369-
event: E,
370-
listener: Listener<EmitterEvents<T>[E]>,
371-
): this;
378+
interface StreamListener<T> {
379+
on(event: "data", listener: (chunk: StreamListDiff<T>[]) => void);
380+
on(event: "finish", listener: () => void);
381+
on(event: "error", listener: (error: Error) => void);
372382
}
373383

374-
type EmitterEvents<T extends Record<string, unknown>> = {
375-
data: [StreamListDiff<T>[]];
376-
error: [Error];
377-
finish: [];
378-
};
379-
380-
381384
type StreamListDiff<T extends Record<string, unknown>> = {
382385
currentValue: T | null;
383386
previousValue: T | null;

eslint.config.mjs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import tseslint from "typescript-eslint";
33

44
export default [
55
{ files: ["**/*.{js,mjs,cjs,ts}"] },
6-
{ ignores: ["dist", "jest.config.js"] },
6+
{ ignores: ["dist", "jest.config.js", "src/lib/stream-list-diff/server/worker/node-worker.cjs"] },
77
{ settings: { react: { version: "detect" } } },
88
pluginJs.configs.recommended,
99
...tseslint.configs.recommended,

index.ts

Whitespace-only changes.

jest.config.js jest.config.ts

+9-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
module.exports = {
1+
import type { Config } from "jest";
2+
3+
const config: Config = {
24
transform: {
3-
"^.+\\.(ts|js)$": [
5+
"^.+\\.(ts|js)$": [
46
"@swc/jest",
57
{
68
jsc: {
@@ -11,13 +13,17 @@ module.exports = {
1113
dynamicImport: true,
1214
},
1315
paths: {
16+
"@mocks/*": ["./src/mocks/*"],
1417
"@models/*": ["./src/models/*"],
1518
"@lib/*": ["./src/lib/*"],
16-
1719
},
1820
target: "esnext",
1921
},
2022
},
2123
],
2224
},
25+
testEnvironment: "node",
26+
setupFilesAfterEnv: ["<rootDir>/jest.setup.ts"],
2327
};
28+
29+
export default config;

jest.setup.ts

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { TextEncoder, TextDecoder } from "util";
2+
3+
global.TextEncoder = TextEncoder;
4+
//@ts-expect-error - the TextDecoder is valid
5+
global.TextDecoder = TextDecoder;

0 commit comments

Comments
 (0)