@oscarpalmer/atoms 0.110.2 → 0.111.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2622,9 +2622,11 @@ function tryStructuredClone(value, depth, references) {
2622
2622
  * Find the differences between two values
2623
2623
  * @param first First value to compare
2624
2624
  * @param second Second value to compare
2625
+ * @param options Comparison options
2625
2626
  * @returns The differences between the two values
2626
2627
  */
2627
- function diff(first, second) {
2628
+ function diff(first, second, options) {
2629
+ const relaxedNullish = typeof options === 'object' && options?.relaxedNullish === true;
2628
2630
  const result = {
2629
2631
  original: {
2630
2632
  from: first,
@@ -2633,7 +2635,8 @@ function diff(first, second) {
2633
2635
  type: 'partial',
2634
2636
  values: {},
2635
2637
  };
2636
- const same = Object.is(first, second);
2638
+ const same = (relaxedNullish && first == null && second == null) ||
2639
+ Object.is(first, second);
2637
2640
  const firstIsArrayOrObject = isArrayOrPlainObject(first);
2638
2641
  const secondIsArrayOrObject = isArrayOrPlainObject(second);
2639
2642
  if (same || (!firstIsArrayOrObject && !secondIsArrayOrObject)) {
@@ -2644,7 +2647,7 @@ function diff(first, second) {
2644
2647
  result.type = 'full';
2645
2648
  return result;
2646
2649
  }
2647
- const diffs = getDiffs(first, second);
2650
+ const diffs = getDiffs(first, second, relaxedNullish);
2648
2651
  const { length } = diffs;
2649
2652
  if (length === 0) {
2650
2653
  result.type = 'none';
@@ -2655,7 +2658,7 @@ function diff(first, second) {
2655
2658
  }
2656
2659
  return result;
2657
2660
  }
2658
- function getDiffs(first, second, prefix) {
2661
+ function getDiffs(first, second, relaxedNullish, prefix) {
2659
2662
  const changes = [];
2660
2663
  const checked = new Set();
2661
2664
  if (Array.isArray(first) && Array.isArray(second)) {
@@ -2682,28 +2685,27 @@ function getDiffs(first, second, prefix) {
2682
2685
  if (checked.has(key)) {
2683
2686
  continue;
2684
2687
  }
2688
+ checked.add(key);
2685
2689
  const from = first?.[key];
2686
2690
  const to = second?.[key];
2687
- if (!equal(from, to)) {
2688
- const prefixed = join([prefix, key], '.');
2689
- const change = {
2690
- from,
2691
- to,
2692
- key: prefixed,
2693
- };
2694
- const nested = isArrayOrPlainObject(from) || isArrayOrPlainObject(to);
2695
- const diffs = nested
2696
- ? getDiffs(from, to, prefixed)
2697
- : [];
2698
- if (!nested || (nested && diffs.length > 0)) {
2699
- changes.push(change);
2700
- }
2701
- const diffsLength = diffs.length;
2702
- for (let diffIndex = 0; diffIndex < diffsLength; diffIndex += 1) {
2703
- changes.push(diffs[diffIndex]);
2704
- }
2691
+ if ((relaxedNullish && from == null && to == null) || equal(from, to)) {
2692
+ continue;
2693
+ }
2694
+ const prefixed = join([prefix, key], '.');
2695
+ const change = {
2696
+ from,
2697
+ to,
2698
+ key: prefixed,
2699
+ };
2700
+ const nested = isArrayOrPlainObject(from) || isArrayOrPlainObject(to);
2701
+ const diffs = nested ? getDiffs(from, to, relaxedNullish, prefixed) : [];
2702
+ if (!nested || (nested && diffs.length > 0)) {
2703
+ changes.push(change);
2704
+ }
2705
+ const diffsLength = diffs.length;
2706
+ for (let diffIndex = 0; diffIndex < diffsLength; diffIndex += 1) {
2707
+ changes.push(diffs[diffIndex]);
2705
2708
  }
2706
- checked.add(key);
2707
2709
  }
2708
2710
  }
2709
2711
  return changes;
@@ -1,7 +1,8 @@
1
1
  import { isArrayOrPlainObject } from "../internal/is.js";
2
2
  import { join } from "../internal/string.js";
3
3
  import { equal } from "../internal/value/equal.js";
4
- function diff(first, second) {
4
+ function diff(first, second, options) {
5
+ const relaxedNullish = typeof options === "object" && options?.relaxedNullish === true;
5
6
  const result = {
6
7
  original: {
7
8
  from: first,
@@ -10,7 +11,7 @@ function diff(first, second) {
10
11
  type: "partial",
11
12
  values: {}
12
13
  };
13
- const same = Object.is(first, second);
14
+ const same = relaxedNullish && first == null && second == null || Object.is(first, second);
14
15
  const firstIsArrayOrObject = isArrayOrPlainObject(first);
15
16
  const secondIsArrayOrObject = isArrayOrPlainObject(second);
16
17
  if (same || !firstIsArrayOrObject && !secondIsArrayOrObject) {
@@ -21,7 +22,7 @@ function diff(first, second) {
21
22
  result.type = "full";
22
23
  return result;
23
24
  }
24
- const diffs = getDiffs(first, second);
25
+ const diffs = getDiffs(first, second, relaxedNullish);
25
26
  const { length } = diffs;
26
27
  if (length === 0) result.type = "none";
27
28
  for (let index = 0; index < length; index += 1) {
@@ -33,7 +34,7 @@ function diff(first, second) {
33
34
  }
34
35
  return result;
35
36
  }
36
- function getDiffs(first, second, prefix) {
37
+ function getDiffs(first, second, relaxedNullish, prefix) {
37
38
  const changes = [];
38
39
  const checked = /* @__PURE__ */ new Set();
39
40
  if (Array.isArray(first) && Array.isArray(second)) {
@@ -55,22 +56,21 @@ function getDiffs(first, second, prefix) {
55
56
  for (let innerIndex = 0; innerIndex < length; innerIndex += 1) {
56
57
  const key = keys[innerIndex];
57
58
  if (checked.has(key)) continue;
59
+ checked.add(key);
58
60
  const from = first?.[key];
59
61
  const to = second?.[key];
60
- if (!equal(from, to)) {
61
- const prefixed = join([prefix, key], ".");
62
- const change = {
63
- from,
64
- to,
65
- key: prefixed
66
- };
67
- const nested = isArrayOrPlainObject(from) || isArrayOrPlainObject(to);
68
- const diffs = nested ? getDiffs(from, to, prefixed) : [];
69
- if (!nested || nested && diffs.length > 0) changes.push(change);
70
- const diffsLength = diffs.length;
71
- for (let diffIndex = 0; diffIndex < diffsLength; diffIndex += 1) changes.push(diffs[diffIndex]);
72
- }
73
- checked.add(key);
62
+ if (relaxedNullish && from == null && to == null || equal(from, to)) continue;
63
+ const prefixed = join([prefix, key], ".");
64
+ const change = {
65
+ from,
66
+ to,
67
+ key: prefixed
68
+ };
69
+ const nested = isArrayOrPlainObject(from) || isArrayOrPlainObject(to);
70
+ const diffs = nested ? getDiffs(from, to, relaxedNullish, prefixed) : [];
71
+ if (!nested || nested && diffs.length > 0) changes.push(change);
72
+ const diffsLength = diffs.length;
73
+ for (let diffIndex = 0; diffIndex < diffsLength; diffIndex += 1) changes.push(diffs[diffIndex]);
74
74
  }
75
75
  }
76
76
  return changes;
package/package.json CHANGED
@@ -100,5 +100,5 @@
100
100
  },
101
101
  "type": "module",
102
102
  "types": "./types/index.d.ts",
103
- "version": "0.110.2"
103
+ "version": "0.111.1"
104
104
  }
package/src/value/diff.ts CHANGED
@@ -1,9 +1,13 @@
1
1
  import {isArrayOrPlainObject} from '../internal/is';
2
2
  import {join} from '../internal/string';
3
3
  import {equal} from '../internal/value/equal';
4
- import type {ArrayOrPlainObject} from '../models';
5
4
 
6
- export type DiffType = 'full' | 'none' | 'partial';
5
+ type DiffOptions = {
6
+ /**
7
+ * Should `null` and `undefined` be considered equal and ignored in results?
8
+ */
9
+ relaxedNullish?: boolean;
10
+ };
7
11
 
8
12
  /**
9
13
  * The result of a comparison beteen two values
@@ -25,6 +29,8 @@ export type DiffResult<First, Second = First> = {
25
29
  values: Record<string, DiffValue>;
26
30
  };
27
31
 
32
+ export type DiffType = 'full' | 'none' | 'partial';
33
+
28
34
  /**
29
35
  * The difference between two values
30
36
  */
@@ -47,12 +53,17 @@ type KeyedDiffValue = {
47
53
  * Find the differences between two values
48
54
  * @param first First value to compare
49
55
  * @param second Second value to compare
56
+ * @param options Comparison options
50
57
  * @returns The differences between the two values
51
58
  */
52
59
  export function diff<First, Second = First>(
53
60
  first: First,
54
61
  second: Second,
62
+ options?: DiffOptions,
55
63
  ): DiffResult<First, Second> {
64
+ const relaxedNullish =
65
+ typeof options === 'object' && options?.relaxedNullish === true;
66
+
56
67
  const result: DiffResult<First, Second> = {
57
68
  original: {
58
69
  from: first,
@@ -62,7 +73,9 @@ export function diff<First, Second = First>(
62
73
  values: {},
63
74
  };
64
75
 
65
- const same = Object.is(first, second);
76
+ const same =
77
+ (relaxedNullish && first == null && second == null) ||
78
+ Object.is(first, second);
66
79
 
67
80
  const firstIsArrayOrObject = isArrayOrPlainObject(first);
68
81
  const secondIsArrayOrObject = isArrayOrPlainObject(second);
@@ -79,10 +92,7 @@ export function diff<First, Second = First>(
79
92
  return result;
80
93
  }
81
94
 
82
- const diffs = getDiffs(
83
- first as ArrayOrPlainObject,
84
- second as ArrayOrPlainObject,
85
- );
95
+ const diffs = getDiffs(first, second, relaxedNullish);
86
96
 
87
97
  const {length} = diffs;
88
98
 
@@ -100,8 +110,9 @@ export function diff<First, Second = First>(
100
110
  }
101
111
 
102
112
  function getDiffs(
103
- first: ArrayOrPlainObject,
104
- second: ArrayOrPlainObject,
113
+ first: unknown,
114
+ second: unknown,
115
+ relaxedNullish: boolean,
105
116
  prefix?: string,
106
117
  ): KeyedDiffValue[] {
107
118
  const changes: KeyedDiffValue[] = [];
@@ -138,40 +149,36 @@ function getDiffs(
138
149
  continue;
139
150
  }
140
151
 
152
+ checked.add(key);
153
+
141
154
  const from = first?.[key as never];
142
155
  const to = second?.[key as never];
143
156
 
144
- if (!equal(from, to)) {
145
- const prefixed = join([prefix, key], '.');
146
-
147
- const change = {
148
- from,
149
- to,
150
- key: prefixed,
151
- };
157
+ if ((relaxedNullish && from == null && to == null) || equal(from, to)) {
158
+ continue;
159
+ }
152
160
 
153
- const nested = isArrayOrPlainObject(from) || isArrayOrPlainObject(to);
161
+ const prefixed = join([prefix, key], '.');
154
162
 
155
- const diffs = nested
156
- ? getDiffs(
157
- from as ArrayOrPlainObject,
158
- to as ArrayOrPlainObject,
159
- prefixed,
160
- )
161
- : [];
163
+ const change = {
164
+ from,
165
+ to,
166
+ key: prefixed,
167
+ };
162
168
 
163
- if (!nested || (nested && diffs.length > 0)) {
164
- changes.push(change);
165
- }
169
+ const nested = isArrayOrPlainObject(from) || isArrayOrPlainObject(to);
166
170
 
167
- const diffsLength = diffs.length;
171
+ const diffs = nested ? getDiffs(from, to, relaxedNullish, prefixed) : [];
168
172
 
169
- for (let diffIndex = 0; diffIndex < diffsLength; diffIndex += 1) {
170
- changes.push(diffs[diffIndex]);
171
- }
173
+ if (!nested || (nested && diffs.length > 0)) {
174
+ changes.push(change);
172
175
  }
173
176
 
174
- checked.add(key);
177
+ const diffsLength = diffs.length;
178
+
179
+ for (let diffIndex = 0; diffIndex < diffsLength; diffIndex += 1) {
180
+ changes.push(diffs[diffIndex]);
181
+ }
175
182
  }
176
183
  }
177
184
 
@@ -1,4 +1,9 @@
1
- export type DiffType = 'full' | 'none' | 'partial';
1
+ type DiffOptions = {
2
+ /**
3
+ * Should `null` and `undefined` be considered equal and ignored in results?
4
+ */
5
+ relaxedNullish?: boolean;
6
+ };
2
7
  /**
3
8
  * The result of a comparison beteen two values
4
9
  */
@@ -18,6 +23,7 @@ export type DiffResult<First, Second = First> = {
18
23
  */
19
24
  values: Record<string, DiffValue>;
20
25
  };
26
+ export type DiffType = 'full' | 'none' | 'partial';
21
27
  /**
22
28
  * The difference between two values
23
29
  */
@@ -35,6 +41,8 @@ export type DiffValue<First = unknown, Second = First> = {
35
41
  * Find the differences between two values
36
42
  * @param first First value to compare
37
43
  * @param second Second value to compare
44
+ * @param options Comparison options
38
45
  * @returns The differences between the two values
39
46
  */
40
- export declare function diff<First, Second = First>(first: First, second: Second): DiffResult<First, Second>;
47
+ export declare function diff<First, Second = First>(first: First, second: Second, options?: DiffOptions): DiffResult<First, Second>;
48
+ export {};