Skip to content

Commit 87c4f78

Browse files
committed
feat: replace assignInWith and memoize
1 parent 05479eb commit 87c4f78

File tree

1 file changed

+49
-14
lines changed

1 file changed

+49
-14
lines changed

src/morphism.ts

+49-14
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,36 @@
1-
import { assignInWith, set, memoize } from 'lodash';
1+
import { set } from 'lodash';
22

33
const aggregator = (paths: any, object: any) => {
44
return paths.reduce((delta: any, path: any) => {
55
return set(delta, path, get(object, path));
66
}, {});
77
};
88

9-
// function memoize(a: any): any {
10-
// const f: { [k: string]: any } = () => {};
11-
// f.cache = {};
12-
// return f;
13-
// }
14-
// function assignInWith(a: any, b: any, c?: any) {}
9+
const memoize = (func: any, resolver?: any) => {
10+
if (typeof func !== 'function' || (resolver != null && typeof resolver !== 'function')) {
11+
throw new TypeError('Expected a function');
12+
}
13+
const memoized: any = function(...args: any[]) {
14+
const key = resolver ? resolver.apply(this, args) : args[0];
15+
const cache = memoized.cache;
16+
17+
if (cache.has(key)) {
18+
return cache.get(key);
19+
}
20+
const result = func.apply(this, args);
21+
memoized.cache = cache.set(key, result) || cache;
22+
return result;
23+
};
24+
memoized.cache = new Map();
25+
return memoized;
26+
};
27+
28+
function assignInWith(target: any, source: any, customizer: (targetValue: any, sourceValue: any) => any) {
29+
Object.entries(source).forEach(([field, value]) => {
30+
target[field] = customizer(target[field], value);
31+
});
32+
return target;
33+
}
1534
// // function set(a: any, b: any, c?: any) {}
1635

1736
function isUndefined(value: any) {
@@ -83,14 +102,14 @@ function transformValuesFromObject(object: any, schema: Schema, items: any[], co
83102
return { [targetProperty]: aggregator(action, object) };
84103
} else if (isObject(action)) {
85104
// Action<Object>: a path and a function: [ destination : { path: 'source', fn:(fieldValue, items) }]
86-
let value;
87-
if (Array.isArray(action.path)) {
88-
value = aggregator(action.path, object);
89-
} else if (isString(action.path)) {
90-
value = get(object, action.path);
91-
}
92105
let result;
93106
try {
107+
let value;
108+
if (Array.isArray(action.path)) {
109+
value = aggregator(action.path, object);
110+
} else if (isString(action.path)) {
111+
value = get(object, action.path);
112+
}
94113
result = action.fn.call(undefined, value, object, items, constructed);
95114
} catch (e) {
96115
e.message = `Unable to set target property [${targetProperty}].
@@ -168,7 +187,16 @@ Morphism = (schema: Schema, items?: any, type?: any): typeof type => {
168187

169188
const customizer = (data: any) => {
170189
const undefinedValueCheck = (destination: any, source: any) => {
171-
if (isUndefined(source)) return destination;
190+
// Take the Object class value property if the incoming property is undefined
191+
if (isUndefined(source)) {
192+
if (!isUndefined(destination)) {
193+
return destination;
194+
} else {
195+
return; // No Black Magic Fuckery here, if the source and the destination are undefined, we don't do anything
196+
}
197+
} else {
198+
return source;
199+
}
172200
};
173201
return assignInWith(constructed, data, undefinedValueCheck);
174202
};
@@ -288,3 +316,10 @@ Morphism.mappers = MorphismRegistry.mappers;
288316
/** API */
289317

290318
export default Morphism;
319+
320+
class UndefinedFinalValue extends Error {
321+
constructor(message?: string) {
322+
super(message); // 'Error' breaks prototype chain here
323+
Object.setPrototypeOf(this, new.target.prototype); // restore prototype chain
324+
}
325+
}

0 commit comments

Comments
 (0)