Skip to content

Commit 7414998

Browse files
committed
🎨 improve @coven/compare.
1 parent 0c2750f commit 7414998

15 files changed

+64
-54
lines changed

β€Ž@coven/compare/CreateDifference.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import type { DifferencePath } from "./DifferencePath.ts";
88
* ```typescript
99
* const createDifference = {
1010
* kind: "CREATE",
11-
* path: ["foo", "bar"],
11+
* path: ["property", "path"],
1212
* right: "new value",
1313
* } as const satisfies CreateDifference<string>;
1414
* ```
@@ -19,6 +19,7 @@ export type CreateDifference<Right = unknown> = {
1919
* Creation kind.
2020
*/
2121
readonly kind: typeof CREATE;
22+
2223
/**
2324
* New value.
2425
*/
+17
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,20 @@
11
import type { Difference } from "./Difference.ts";
22

3+
/**
4+
* Curried function returned by `compare` function when it already took a `left`
5+
* (original) value.
6+
*
7+
* @example
8+
* ```typescript
9+
* const compare = <Left>(left: string): CurriedComparison<string> =>
10+
* function* (right) {
11+
* yield {
12+
* // Difference object
13+
* }
14+
* }
15+
* ```
16+
*
17+
* @template Right Right value to compare
18+
* @returns Generator that yields `Difference` objects.
19+
*/
320
export type CurriedComparison<Right> = (right: Right) => Generator<Difference>;

β€Ž@coven/compare/DeleteDifference.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,16 @@ import type { DifferencePath } from "./DifferencePath.ts";
1212
* path: ["foo", "bar"],
1313
* } as const satisfies DeleteDifference<string>;
1414
* ```
15-
* @template Left Type of the removed value.
15+
* @template Left Type of the removed/original value.
1616
*/
1717
export type DeleteDifference<Left = unknown> = {
1818
/**
1919
* Deletion kind.
2020
*/
2121
readonly kind: typeof DELETE;
22+
2223
/**
23-
* Original value.
24+
* Removed/original value.
2425
*/
2526
readonly left: Left;
2627
} & DifferencePath;

β€Ž@coven/compare/UpdateDifference.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ import type { DifferencePath } from "./DifferencePath.ts";
1313
* right: "new value",
1414
* } as const satisfies UpdateDifference<string, string>;
1515
* ```
16-
* @template Left Type of the new value.
17-
* @template Right Type of the original value.
16+
* @template Left Type of the original value.
17+
* @template Right Type of the new value.
1818
*/
1919
export type UpdateDifference<Left = unknown, Right = unknown> = {
2020
/**

β€Ž@coven/compare/compare.ts

+15-10
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1+
import { is, isObject } from "@coven/predicates";
12
import type { Just } from "@coven/types";
3+
import { always } from "@coven/utils";
24
import type { CurriedComparison } from "./CurriedComparison.ts";
35
import type { Difference } from "./Difference.ts";
46
import { compareObjects } from "./compareObjects.ts";
5-
import { isObject } from "./isObject.ts";
67
import { valueToDifference } from "./valueToDifference.ts";
78

9+
// deno-lint-ignore no-boolean-literal-for-arguments
10+
const alwaysFalse = always(false);
11+
812
/**
913
* Function to compare a `left` and a `right` value, by doing a deep comparison
1014
* and yielding the differences found with a descriptive object.
@@ -28,6 +32,8 @@ export const compare = (left: unknown): CurriedComparison<unknown> => {
2832
const valuesToDifferenceLeft = valueToDifference(left);
2933
const leftIsObject = isObject(left);
3034
const compareObjectsLeft = leftIsObject ? compareObjects(left) : undefined;
35+
const isLeft = is(left);
36+
const isLeftConstructor = leftIsObject ? is(left.constructor) : alwaysFalse;
3137

3238
return leftIsObject
3339
/**
@@ -37,13 +43,12 @@ export const compare = (left: unknown): CurriedComparison<unknown> => {
3743
* @yields Differences.
3844
*/
3945
? function* (right): Generator<Difference> {
40-
Object.is(left, right)
41-
? undefined
42-
: isObject(right) && left.constructor === right.constructor
43-
? yield* (
44-
compareObjectsLeft as Just<typeof compareObjectsLeft>
45-
)(right)
46-
: yield valuesToDifferenceLeft(right);
46+
isLeft(right) ? undefined : yield* (
47+
isObject(right) &&
48+
isLeftConstructor((right as object).constructor)
49+
? compareObjectsLeft as Just<typeof compareObjectsLeft>
50+
: valuesToDifferenceLeft
51+
)(right);
4752
}
4853
/**
4954
* Curried {@link compare} with `left` set in context.
@@ -52,8 +57,8 @@ export const compare = (left: unknown): CurriedComparison<unknown> => {
5257
* @yields Differences.
5358
*/
5459
: function* (right): Generator<Difference> {
55-
Object.is(left, right) ? undefined : (
56-
yield valuesToDifferenceLeft(right)
60+
isLeft(right) ? undefined : (
61+
yield* valuesToDifferenceLeft(right)
5762
);
5863
};
5964
};

β€Ž@coven/compare/compareIterables.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { getIterator } from "@coven/iterables";
12
import { compare } from "./compare.ts";
23
import { DONE, MISSING, NEXT, VALUE } from "./constants.ts";
34
import type { CurriedComparison } from "./CurriedComparison.ts";
@@ -20,15 +21,15 @@ import { pathPrepend } from "./pathPrepend.ts";
2021
export const compareIterables = <LeftItem>(
2122
left: Iterable<LeftItem>,
2223
): CurriedComparison<Iterable<LeftItem>> => {
23-
const leftIterator = left[Symbol.iterator]();
24+
const leftIterator = getIterator(left);
2425

2526
/**
2627
* Curried {@link compareIterables} with `left` set in context.
2728
* @param right Right/New iterable.
2829
* @returns Generator with differences.
2930
*/
3031
return function* (right): Generator<Difference> {
31-
const rightIterator = right[Symbol.iterator]();
32+
const rightIterator = getIterator(right);
3233

3334
for (
3435
let index = 0,

β€Ž@coven/compare/compareObjects.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export const compareObjects = (left: object): CurriedComparison<object> => {
3434
* @returns Generator with differences.
3535
*/
3636
? function* (right): Generator<Difference> {
37-
yield* Symbol.iterator in right
37+
yield* isIterable(right)
3838
? (compareIterableLeft as Just<typeof compareIterableLeft>)(
3939
right as Iterable<object>,
4040
)

β€Ž@coven/compare/deno.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
22
"name": "@coven/compare",
3-
"version": "0.0.8",
3+
"version": "0.1.0",
44
"exports": "./mod.ts"
55
}

β€Ž@coven/compare/getKeys.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { isObject } from "./isObject.ts";
1+
import { isObject } from "@coven/predicates";
22

33
/**
44
* Recursively get all object keys going up the prototype chain.

β€Ž@coven/compare/isObject.ts

-15
This file was deleted.

β€Ž@coven/compare/mod.ts

-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ export type { DeleteDifference } from "./DeleteDifference.ts";
2020
export type { Difference } from "./Difference.ts";
2121
export type { DifferencePath } from "./DifferencePath.ts";
2222
export { getKeys } from "./getKeys.ts";
23-
export { isObject } from "./isObject.ts";
2423
export { pathPrepend } from "./pathPrepend.ts";
2524
export type { UpdateDifference } from "./UpdateDifference.ts";
2625
export { valueToDifference } from "./valueToDifference.ts";

β€Ž@coven/compare/pathPrepend.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import { prepend } from "@coven/iterables";
2+
import { set } from "@coven/utils";
23
import type { Difference } from "./Difference.ts";
34
import { PATH } from "./constants.ts";
45

6+
const setPath = set(PATH);
7+
58
/**
69
* Prepends the given property to the given {@link Difference}'s path.
710
*
@@ -24,8 +27,5 @@ export const pathPrepend = <SourceDifference extends Difference>(
2427
* @yields Difference's path with prepended `prepend`.
2528
*/
2629
return ({ [PATH]: path, ...difference }) =>
27-
({
28-
...difference,
29-
[PATH]: prependProperty(path ?? []),
30-
}) as SourceDifference;
30+
setPath(prependProperty(path ?? []))(difference) as SourceDifference;
3131
};

β€Ž@coven/compare/valueToDifference.ts

+12-11
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { CurriedComparison } from "./CurriedComparison.ts";
12
import type { Difference } from "./Difference.ts";
23
import {
34
CREATE,
@@ -25,32 +26,32 @@ import {
2526
* ```
2627
* @see {@link Difference}
2728
* @param left Left/Original value.
28-
* @returns Curried function with `left` in context.
29+
* @returns Curried generator with `left` in context.
2930
*/
3031
export const valueToDifference = (
3132
left: unknown,
32-
): (right: unknown) => Difference =>
33+
): CurriedComparison<unknown> =>
3334
left === MISSING
3435
/**
3536
* Curried {@link valueToDifference} with `left` in context.
3637
* @param right Right/New value.
3738
* @returns Difference object.
3839
*/
39-
? (right: unknown) =>
40-
({
41-
...(right === MISSING ? undefined : (
42-
{ [KIND]: CREATE, [RIGHT]: right }
43-
)),
44-
}) as Difference
40+
? function* (right: unknown): Generator<Difference> {
41+
right === MISSING
42+
? undefined
43+
: yield ({ [KIND]: CREATE, [RIGHT]: right });
44+
}
4545
/**
4646
* Curried {@link valueToDifference} with `left` in context.
4747
* @param right Right/New value.
4848
* @returns Difference object.
4949
*/
50-
: (right: unknown) =>
51-
({
50+
: function* (right: unknown): Generator<Difference> {
51+
yield ({
5252
[LEFT]: left,
5353
...(right === MISSING
5454
? { [KIND]: DELETE }
5555
: { [KIND]: UPDATE, [RIGHT]: right }),
56-
}) as Difference;
56+
});
57+
};

β€Žtests/@coven/compare/pathPrepend.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Deno.test("Prepend key to existing path", () =>
1818
{ kind: DELETE, left: "πŸ§™πŸ»β€β™€οΈ", path: [13, 42] },
1919
));
2020

21-
Deno.test("Prepend key to missing path", () =>
21+
Deno.test("Prepend key to missing path yields prepended key", () =>
2222
assertEquals(flatCompare(prepend13({ kind: DELETE, left: "πŸ§™πŸ»β€β™€οΈ" })), {
2323
kind: DELETE,
2424
left: "πŸ§™πŸ»β€β™€οΈ",
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { type Difference, MISSING, valueToDifference } from "@coven/compare";
1+
import { MISSING, valueToDifference } from "@coven/compare";
22
import { assertEquals } from "@std/assert";
33

44
Deno.test("When both values are missing returns an empty difference", () =>
5-
assertEquals(valueToDifference(MISSING)(MISSING), {} as Difference));
5+
assertEquals([...valueToDifference(MISSING)(MISSING)], []));

0 commit comments

Comments
Β (0)