Skip to content

Commit

Permalink
change enum
Browse files Browse the repository at this point in the history
  • Loading branch information
therohk committed Sep 6, 2024
1 parent 90c834b commit f700236
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 48 deletions.
21 changes: 19 additions & 2 deletions __tests__/type-datum.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { emptyObject, isArrayOf, isArrayOfAny, isArrayOfSame, isObject, isString, isVectorArray } from "../src/type-utils";
import { deepClone, flattenObject, unflattenObject } from "../src/datum-utils";
import { deepDiffFlat } from "../src/diff-high";
import { areArraysEqual, deepClone, deepEquals, flattenObject, unflattenObject } from "../src/datum-utils";
import { deepDiffFlat, deepDiffTyped } from "../src/diff-high";

describe("validate-utils", () => {

Expand Down Expand Up @@ -69,4 +69,21 @@ describe("validate-utils", () => {
expect(two).toEqual(twoBkp);
});

test('objects match with deep equality checks', async () => {

const lhsO = { o: [{ a: 1 }, { b: 2 }], v: ["11", "22", "33"] };
const rhsO = { o: [{ a: 1 }, { b: 2 }], v: ["11", "22", "33"] };

expect(areArraysEqual(lhsO.v, rhsO.v)).toBeTruthy();
expect(areArraysEqual(lhsO.o, rhsO.o)).toBeFalsy();
expect(areArraysEqual(lhsO.o, lhsO.o)).toBeTruthy();

expect(deepEquals(lhsO.v, rhsO.v)).toBeTruthy();
expect(deepEquals(lhsO.o, rhsO.o)).toBeTruthy();

expect(deepDiffFlat(rhsO, lhsO, true)).toMatchObject([{}, {}]);
expect(deepDiffTyped<any>(lhsO, rhsO)).toEqual({});
expect(deepDiffTyped<any>(rhsO, lhsO)).toEqual({});
});

});
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export { deepDiffTyped } from "./diff-high";

export { UpdateCode } from "./merge-low";
export { UpdateCode as MC } from "./merge-low";
export { type MergeCode } from "./merge-low";
export { updateCodeInfo } from "./merge-high";

export { shallowMerge, immutableMerge } from "./merge-high";
Expand Down
25 changes: 13 additions & 12 deletions src/merge-conf.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import { isArrayOfAny, emptyObject, isNullish, isObject, isString, TupleObj } from "./type-utils";
import { createGlobRegex, deepClone, getObjectKeys } from "./datum-utils";
import { deepDiffTyped } from "./diff-high";
import { UpdateCode, mergeScalarField, mergeVectorField } from "./merge-low";
import { UpdateCode, MergeCode, mergeScalarField, mergeVectorField } from "./merge-low";
import { updateCodeInfo } from "./merge-high";

export type DetailConfig = {
[key: string]: UpdateCode | DetailConfig;
[key: string]: MergeCode | DetailConfig;
};

export type MergeConfig = {
scalar?: UpdateCode, //default
vector?: UpdateCode, //array types
nested?: UpdateCode, //object types
[glob: string]: UpdateCode | MergeConfig | undefined,
scalar?: MergeCode, //default
vector?: MergeCode, //array types
nested?: MergeCode, //object types
[glob: string]: MergeCode | MergeConfig | undefined,
};

//-----------------------------------------------------------------------------
Expand All @@ -36,6 +36,7 @@ export function detailMerge(
for (const label of mergeKeys) {
const mergeCode = mergeCodes[label]!;
if (!isString(mergeCode)) {
//todo should nest for empty target
if ((isObject(target[label]) && isObject(source[label]))
? detailMerge(target[label], source[label], mergeCode)
: mergeScalarField(target, source, label, UpdateCode.I)
Expand Down Expand Up @@ -99,7 +100,7 @@ export function selectDetailKeys(
export function customMerge<T extends TupleObj>(
target: T,
source: Partial<T>,
mergeConf: MergeConfig | UpdateCode,
mergeConf: MergeConfig | MergeCode,
excludeKeys?: string[],
): Partial<T> | false {
//implement externally
Expand Down Expand Up @@ -139,7 +140,7 @@ export function customMerge<T extends TupleObj>(
*/
export const fillUpdateCodes = (
source: any,
mergeConf: MergeConfig | UpdateCode,
mergeConf: MergeConfig | MergeCode,
excludeKeys?: string[],
blockUnset: boolean = false,
): DetailConfig => {
Expand Down Expand Up @@ -181,7 +182,7 @@ export const fillUpdateCodes = (
if (globIndex >= 0) {
const globConf = mergeConf[globKeys[globIndex]!];
if (isString(globConf)) {
mergeCodes[srcLabel] = globConf as UpdateCode;
mergeCodes[srcLabel] = globConf as MergeCode;
continue;
} else if (isObject(srcValue)) {
mergeCodes[srcLabel] = fillUpdateCodes(srcValue, globConf!, [], blockUnset);
Expand Down Expand Up @@ -214,9 +215,9 @@ export function immutableCustomMerge(
mergeConf: MergeConfig,
skipFill?: boolean,
): any {
const mergeCodes = skipFill
? mergeConf as DetailConfig
: fillUpdateCodes(source, mergeConf);
const mergeCodes = !skipFill
? fillUpdateCodes(source, mergeConf)
: mergeConf as DetailConfig;
const targetCopy = deepClone(target);
detailMerge(targetCopy, source, mergeCodes);
return targetCopy;
Expand Down
30 changes: 15 additions & 15 deletions src/merge-high.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { isArrayOfAny, emptyObject, isObject, isString } from "./type-utils";
import { deepClone, getObjectKeys } from "./datum-utils";
import { deepDiffTyped } from "./diff-high";
import { UpdateCode, mergeScalarField, mergeVectorField } from "./merge-low";
import { MergeCode, UpdateCode, mergeScalarField, mergeVectorField } from "./merge-low";

export type MergeCode = `${UpdateCode}`;
export type MergePerms = {
enable: boolean;
insert?: boolean;
Expand All @@ -12,7 +11,7 @@ export type MergePerms = {
};

export function updateCodeInfo(
mergeCode: UpdateCode | MergeCode,
mergeCode: MergeCode,
): MergePerms {
if (!isString(mergeCode)) {
return { enable: false };
Expand Down Expand Up @@ -48,8 +47,8 @@ export function updateCodeInfo(
export function shallowMerge(
target: any,
source: any,
scalarCode: UpdateCode,
vectorCode?: UpdateCode,
scalarCode: MergeCode,
vectorCode?: MergeCode,
excludeKeys?: string[],
includeKeys?: string[], //for delete
): boolean {
Expand Down Expand Up @@ -79,8 +78,8 @@ export function shallowMerge(
export function immutableMerge(
target: any,
source: any,
scalarCode: UpdateCode,
vectorCode?: UpdateCode,
scalarCode: MergeCode,
vectorCode?: MergeCode,
): any {
const targetCopy = deepClone(target);
shallowMerge(targetCopy, source, scalarCode, vectorCode);
Expand All @@ -95,8 +94,8 @@ export function immutableMerge(
export function diffFromMerge(
target: any,
source: any,
scalarCode: UpdateCode,
vectorCode?: UpdateCode,
scalarCode: MergeCode,
vectorCode?: MergeCode,
): any | false {
const targetCopy = immutableMerge(target, source, scalarCode, vectorCode);
const delta = deepDiffTyped(target, targetCopy);
Expand All @@ -114,9 +113,9 @@ export function diffFromMerge(
export function deepMerge(
target: { [key: string]: any },
source: { [key: string]: any },
scalarCode: UpdateCode,
vectorCode: UpdateCode,
nestedCode: UpdateCode,
scalarCode: MergeCode,
vectorCode: MergeCode,
nestedCode: MergeCode,
): boolean {
const sourceKeys = getObjectKeys(source);
if (!sourceKeys?.length) {
Expand All @@ -131,6 +130,7 @@ export function deepMerge(
continue;
}
//recursive call for objects
//todo should nest for empty target
if (isObject(target[label]) && isObject(source[label])) {
if (nestedCode === UpdateCode.N)
continue;
Expand Down Expand Up @@ -162,9 +162,9 @@ export function deepMerge(
export function immutableDeepMerge(
target: { [key: string]: any },
source: { [key: string]: any },
scalarCode: UpdateCode,
vectorCode?: UpdateCode,
nestedCode?: UpdateCode,
scalarCode: MergeCode,
vectorCode?: MergeCode,
nestedCode?: MergeCode,
): any {
const targetCopy = deepClone(target);
deepMerge(targetCopy, source,
Expand Down
40 changes: 21 additions & 19 deletions src/merge-low.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,33 @@ import { concat, differenceWith, intersectionWith, unionWith, isEqual } from "lo
import { isArrayOfAny, isNullish } from "./type-utils";
import { areArraysEqual, deepClone } from "./datum-utils";

export enum UpdateCode {
T = "T", //touch, blank update
C = "C", //create instance
export const UpdateCode = {
T: "T", //touch, blank update
C: "C", //create instance
// scalar/def codes
N = "N", //ignore change
Y = "Y", //accept any change
B = "B", //insert or update, no delete
U = "U", //update or delete only
H = "H", //update only if exists
I = "I", //insert only
D = "D", //delete only
N: "N", //ignore change
Y: "Y", //accept any change
B: "B", //insert or update, no delete
U: "U", //update or delete only
H: "H", //update only if exists
I: "I", //insert only
D: "D", //delete only
// vector/xref codes
XR = "XR", //full replace
XM = "XM", //set union, vector merge
XD = "XD", //set difference, delete given values
XI = "XI", //set intersection, delete missing values
XS = "XS", //preserve order insert (allows dupes)
XF = "XF", //insert from start (allows dupes)
};
XR: "XR", //full replace
XM: "XM", //set union, vector merge
XD: "XD", //set difference, delete given values
XI: "XI", //set intersection, delete missing values
XS: "XS", //preserve order insert (allows dupes)
XF: "XF", //insert from start (allows dupes)
} as const;

export type MergeCode = typeof UpdateCode[keyof typeof UpdateCode];

export function mergeScalarField(
target: any,
source: any,
label: string,
mergeCode: UpdateCode,
mergeCode: MergeCode,
): boolean {
const sourceHas = !isNullish(source[label]);
const targetHas = target.hasOwnProperty(label); //!isNullish(target[label]);
Expand Down Expand Up @@ -89,7 +91,7 @@ export function mergeVectorField(
target: any,
source: any,
label: string,
mergeCode: UpdateCode,
mergeCode: MergeCode,
): boolean {
let sourceVals = source[label]; //get(source, label);
if (isNullish(sourceVals)) {
Expand Down

0 comments on commit f700236

Please sign in to comment.