Comparing version 2.0.0 to 2.0.1
@@ -0,1 +1,8 @@ | ||
## 2.0.1 (2023-01-23) | ||
* Optimize speed by always setting the `root` property | ||
* Optimize speed by removing the class member initializers | ||
* Optimize the clone methods | ||
* Store driers & undriers in a map instead of an object | ||
## 2.0.0 (2023-01-14) | ||
@@ -2,0 +9,0 @@ |
"use strict"; | ||
const GET_REGEX = /^\/(.*)\/(.*)/, | ||
UNDRIERS = {}, | ||
DRIERS = {}, | ||
UNDRIERS = new Map(), | ||
DRIERS = new Map(), | ||
REFS = '~refs', | ||
@@ -23,3 +23,3 @@ ROOT = '~root'; | ||
* @since 2.0.0 | ||
* @version 2.0.0 | ||
* @version 2.0.1 | ||
* | ||
@@ -31,3 +31,3 @@ * @param {Object} holder The object that holds the value | ||
*/ | ||
constructor(holder, key, value, parent) { | ||
constructor(holder, key, value, parent, root) { | ||
this.holder = holder; | ||
@@ -37,2 +37,3 @@ this.key = key; | ||
this.parent = parent; | ||
this.root = root; | ||
@@ -154,13 +155,2 @@ if (parent) { | ||
} | ||
/** | ||
* Get the `RootValue` instance | ||
* | ||
* @author Jelle De Loecker <jelle@elevenways.be> | ||
* @since 2.0.0 | ||
* @version 2.0.0 | ||
*/ | ||
get root() { | ||
return this.parent.root; | ||
} | ||
} | ||
@@ -173,9 +163,5 @@ | ||
* @since 2.0.0 | ||
* @version 2.0.0 | ||
* @version 2.0.1 | ||
*/ | ||
class RootValue { | ||
values = new Map(); | ||
has_replacer = false; | ||
current_type = undefined; | ||
duplicates = []; | ||
@@ -187,3 +173,3 @@ /** | ||
* @since 2.0.0 | ||
* @version 2.0.0 | ||
* @version 2.0.1 | ||
* | ||
@@ -193,9 +179,15 @@ * @param {*} root The actual value that needs to be dried | ||
*/ | ||
constructor(root, replacer) { | ||
constructor(root, replacer) { | ||
this.value = root; | ||
this.root = this; | ||
this.current_type = undefined; | ||
this.duplicates = []; | ||
this.values = new Map(); | ||
if (replacer) { | ||
this.replacer = replacer; | ||
this.has_replacer = true; | ||
} else { | ||
this.has_replacer = false; | ||
} | ||
@@ -291,3 +283,3 @@ | ||
* @since 2.0.0 | ||
* @version 2.0.0 | ||
* @version 2.0.1 | ||
* | ||
@@ -301,3 +293,3 @@ * @param {Object} holder The object that holds the value | ||
if (!value) { | ||
return new Value(holder, key, value, parent); | ||
return new Value(holder, key, value, parent, this); | ||
} | ||
@@ -314,3 +306,3 @@ | ||
if (typeof ref == 'number') { | ||
result = new RefValue(holder, key, value, parent); | ||
result = new RefValue(holder, key, value, parent, this); | ||
} else if (typeof dry_type == 'string') { | ||
@@ -320,17 +312,17 @@ if (dry_type == 'root') { | ||
} else if (dry_type == 'toDry') { | ||
result = new CustomReviverValue(holder, key, value, parent); | ||
} else if (UNDRIERS[dry_type]) { | ||
result = new UndrierValue(holder, key, value, parent); | ||
result = new CustomReviverValue(holder, key, value, parent, this); | ||
} else if (UNDRIERS.has(dry_type)) { | ||
result = new UndrierValue(holder, key, value, parent, this); | ||
} else if (dry_type === '+Infinity') { | ||
return new NumberValue(holder, key, Infinity, parent); | ||
return new NumberValue(holder, key, Infinity, parent, this); | ||
} else if (dry_type === '-Infinity') { | ||
return new NumberValue(holder, key, -Infinity, parent); | ||
return new NumberValue(holder, key, -Infinity, parent, this); | ||
} else if (dry_type === 'regexp') { | ||
return new RegExpValue(holder, key, value, parent); | ||
return new RegExpValue(holder, key, value, parent, this); | ||
} else if (dry_type === 'date') { | ||
return new DateValue(holder, key, value, parent); | ||
return new DateValue(holder, key, value, parent, this); | ||
} else if (dry_type === 'escape') { | ||
return new EscapedObjectValue(holder, key, value.value, parent); | ||
return new EscapedObjectValue(holder, key, value.value, parent, this); | ||
} else { | ||
result = new UnknownUndrierValue(holder, key, value, parent); | ||
result = new UnknownUndrierValue(holder, key, value, parent, this); | ||
} | ||
@@ -352,3 +344,3 @@ } | ||
* @since 2.0.0 | ||
* @version 2.0.0 | ||
* @version 2.0.1 | ||
* | ||
@@ -365,19 +357,19 @@ * @param {Object} holder The object that holds the value | ||
case 'function': | ||
return new FunctionValue(holder, key, value, parent); | ||
return new FunctionValue(holder, key, value, parent, this); | ||
case 'object': | ||
if (Array.isArray(value)) { | ||
return new ArrayValue(holder, key, value, parent); | ||
return new ArrayValue(holder, key, value, parent, this); | ||
} else { | ||
return new ObjectValue(holder, key, value, parent); | ||
return new ObjectValue(holder, key, value, parent, this); | ||
} | ||
case 'string': | ||
return new StringValue(holder, key, value, parent); | ||
return new StringValue(holder, key, value, parent, this); | ||
case 'number': | ||
return new NumberValue(holder, key, value, parent); | ||
return new NumberValue(holder, key, value, parent, this); | ||
default: | ||
return new Value(holder, key, value, parent); | ||
return new Value(holder, key, value, parent, this); | ||
} | ||
@@ -531,3 +523,3 @@ } | ||
* @since 2.0.0 | ||
* @version 2.0.0 | ||
* @version 2.0.1 | ||
*/ | ||
@@ -547,4 +539,4 @@ class ObjectValue extends Value { | ||
if (DRIERS[class_name] != null) { | ||
result = DRIERS[class_name].fnc(this.holder, this.key, value); | ||
if (DRIERS.has(class_name)) { | ||
result = DRIERS.get(class_name).fnc(this.holder, this.key, value); | ||
@@ -866,3 +858,3 @@ result = { | ||
* @since 2.0.0 | ||
* @version 2.0.0 | ||
* @version 2.0.1 | ||
*/ | ||
@@ -937,3 +929,3 @@ class UndrierValue extends Value { | ||
let undrier = UNDRIERS[value.dry].fnc, | ||
let undrier = UNDRIERS.get(value.dry).fnc, | ||
result = this.root.revive(null, null, value.value, this); | ||
@@ -976,3 +968,3 @@ | ||
* @since 2.0.0 | ||
* @version 2.0.0 | ||
* @version 2.0.1 | ||
*/ | ||
@@ -983,3 +975,3 @@ class CustomReviverValue extends UndrierValue { | ||
value = (new ObjectValue(this.holder, this.key, value, this)).undriedValue(); | ||
value = (new ObjectValue(this.holder, this.key, value, this, this.root)).undriedValue(); | ||
@@ -1013,3 +1005,3 @@ let constructor = findClass(value), | ||
* @since 1.0.0 | ||
* @version 1.1.0 | ||
* @version 2.0.1 | ||
* | ||
@@ -1019,3 +1011,3 @@ * @param {Object} obj | ||
* @param {Array} extra_args Extra arguments for the custom method | ||
* @param {WeakMap} wm | ||
* @param {Map} wm | ||
* | ||
@@ -1026,6 +1018,6 @@ * @return {Object} | ||
if (custom_method instanceof WeakMap) { | ||
if (custom_method && typeof custom_method === 'object') { | ||
wm = custom_method; | ||
custom_method = null; | ||
} else if (extra_args instanceof WeakMap) { | ||
} else if (extra_args && !Array.isArray(extra_args)) { | ||
wm = extra_args; | ||
@@ -1036,3 +1028,3 @@ extra_args = null; | ||
if (!wm) { | ||
wm = new WeakMap(); | ||
wm = new Map(); | ||
wm.source = obj; | ||
@@ -1090,3 +1082,3 @@ wm.custom_method = custom_method; | ||
* @since 1.0.0 | ||
* @version 1.1.0 | ||
* @version 2.0.1 | ||
* | ||
@@ -1096,3 +1088,3 @@ * @param {Object} obj | ||
* @param {Array} extra_args Extra arguments for the custom method | ||
* @param {WeakMap} wm | ||
* @param {Map} wm | ||
* | ||
@@ -1103,3 +1095,3 @@ * @return {Object} | ||
var entry_type, | ||
let entry_type, | ||
name_type, | ||
@@ -1116,10 +1108,15 @@ target, | ||
if (Array.isArray(obj)) { | ||
len = obj.length; | ||
target = []; | ||
keys = []; | ||
for (i = 0; i < len; i++) { | ||
keys.push(i); | ||
} | ||
} else { | ||
target = {}; | ||
keys = Object.keys(obj); | ||
len = keys.length; | ||
} | ||
keys = Object.keys(obj); | ||
len = keys.length; | ||
// Remember the root object and its clone | ||
@@ -1131,90 +1128,100 @@ wm.set(obj, target); | ||
entry = obj[key]; | ||
if (!entry) { | ||
target[key] = entry; | ||
continue; | ||
} | ||
entry_type = typeof entry; | ||
if (entry && (entry_type == 'object' || entry_type == 'function')) { | ||
if (entry_type !== 'object' && entry_type !== 'function') { | ||
target[key] = entry; | ||
continue; | ||
} | ||
if (entry_type == 'function' && !DRIERS.Function) { | ||
continue; | ||
} | ||
if (entry_type === 'function' && !DRIERS.has('Function')) { | ||
continue; | ||
} | ||
// If this has been cloned before, use that | ||
if (wm.has(entry)) { | ||
target[key] = wm.get(entry); | ||
continue; | ||
} | ||
// If this has been cloned before, use that | ||
if (wm.has(entry)) { | ||
target[key] = wm.get(entry); | ||
continue; | ||
} | ||
if (entry.constructor) { | ||
name_type = entry.constructor.name; | ||
let new_value; | ||
if (custom_method && entry[custom_method]) { | ||
target[key] = entry[custom_method].apply(entry, extra_args); | ||
} else if (DRIERS[name_type] != null) { | ||
// Look for a registered drier function | ||
temp = DRIERS[name_type].fnc(obj, key, entry); | ||
if (entry.constructor != null) { | ||
name_type = entry.constructor.name; | ||
if (UNDRIERS[name_type]) { | ||
target[key] = UNDRIERS[name_type].fnc(target, key, temp); | ||
} else { | ||
target[key] = temp; | ||
} | ||
} else if (entry.dryClone) { | ||
// Look for dryClone after | ||
target[key] = entry.dryClone(wm, custom_method); | ||
} else if (entry.toDry) { | ||
// Perform the toDry function | ||
let uncloned_dried = entry.toDry(); | ||
if (custom_method && entry[custom_method] != null) { | ||
new_value = entry[custom_method].apply(entry, extra_args); | ||
} else if (DRIERS.has(name_type)) { | ||
// Look for a registered drier function | ||
temp = DRIERS.get(name_type).fnc(obj, key, entry); | ||
// Remember this temporary object to prevent infinite loops | ||
wm.set(entry, uncloned_dried); | ||
if (UNDRIERS.has(name_type)) { | ||
new_value = UNDRIERS.get(name_type).fnc(target, key, temp); | ||
} else { | ||
new_value = temp; | ||
} | ||
} else if (entry.dryClone) { | ||
// Look for dryClone after | ||
new_value = entry.dryClone(wm, custom_method); | ||
} else if (entry.toDry) { | ||
// Perform the toDry function | ||
let uncloned_dried = entry.toDry(); | ||
// Clone the value, | ||
// because returned objects aren't necesarilly cloned yet | ||
let cloned_dried = real_clone(uncloned_dried, custom_method, extra_args, wm).value; | ||
// Remember this temporary object to prevent infinite loops | ||
wm.set(entry, uncloned_dried); | ||
// Perform the undry function | ||
if (entry.constructor.unDry) { | ||
target[key] = entry.constructor.unDry(cloned_dried, custom_method || true, wm.whenDone); | ||
} else { | ||
// If there is no undry function, the clone will be a simple object | ||
target[key] = cloned_dried; | ||
} | ||
// Clone the value, | ||
// because returned objects aren't necesarilly cloned yet | ||
let cloned_dried = real_clone(uncloned_dried, custom_method, extra_args, wm).value; | ||
// Remember both entries (for circular undry references) | ||
wm.drymap.set(cloned_dried, target[key]); | ||
wm.drymap.set(uncloned_dried, target[key]); | ||
// Perform the undry function | ||
if (entry.constructor.unDry) { | ||
new_value = entry.constructor.unDry(cloned_dried, custom_method || true, wm.whenDone); | ||
} else { | ||
// If there is no undry function, the clone will be a simple object | ||
new_value = cloned_dried; | ||
} | ||
} else if (name_type == 'Date') { | ||
target[key] = new Date(entry); | ||
} else if (name_type == 'RegExp') { | ||
temp = entry.toString(); | ||
split = temp.match(/^\/(.*?)\/([gim]*)$/); | ||
// Remember both entries (for circular undry references) | ||
wm.drymap.set(cloned_dried, new_value); | ||
wm.drymap.set(uncloned_dried, new_value); | ||
if (split) { | ||
target[key] = RegExp(split[1], split[2]); | ||
} else { | ||
target[key] = RegExp(temp); | ||
} | ||
} else if (typeof entry.clone == 'function') { | ||
// If it supplies a clone method, use that | ||
target[key] = entry.clone(); | ||
} else if (entry.toJSON) { | ||
temp = entry.toJSON(); | ||
} else if (name_type === 'Date') { | ||
new_value = new Date(entry); | ||
} else if (name_type === 'RegExp') { | ||
temp = entry.toString(); | ||
split = temp.match(/^\/(.*?)\/([gim]*)$/); | ||
if (temp && typeof temp == 'object') { | ||
temp = real_clone(temp, custom_method, extra_args, wm); | ||
} | ||
target[key] = temp; | ||
if (split) { | ||
new_value = RegExp(split[1], split[2]); | ||
} else { | ||
target[key] = real_clone(entry, custom_method, extra_args, wm); | ||
new_value = RegExp(temp); | ||
} | ||
} else if (typeof entry.clone == 'function') { | ||
// If it supplies a clone method, use that | ||
new_value = entry.clone(); | ||
} else if (entry.toJSON) { | ||
temp = entry.toJSON(); | ||
if (temp && typeof temp === 'object') { | ||
temp = real_clone(temp, custom_method, extra_args, wm); | ||
} | ||
new_value = temp; | ||
} else { | ||
target[key] = real_clone(entry, custom_method, extra_args, wm); | ||
new_value = real_clone(entry, custom_method, extra_args, wm); | ||
} | ||
// Remember this clone for later | ||
wm.set(entry, target[key]); | ||
} else { | ||
target[key] = entry; | ||
new_value = real_clone(entry, custom_method, extra_args, wm); | ||
} | ||
target[key] = new_value; | ||
// Remember this clone for later | ||
wm.set(entry, new_value); | ||
} | ||
@@ -1230,3 +1237,3 @@ | ||
* @since 1.0.0 | ||
* @version 1.0.0 | ||
* @version 2.0.1 | ||
* | ||
@@ -1247,6 +1254,6 @@ * @param {Function|String} constructor What constructor to listen to | ||
DRIERS[path] = { | ||
DRIERS.set(path, { | ||
fnc : fnc, | ||
options : options || {} | ||
}; | ||
}); | ||
} | ||
@@ -1259,3 +1266,3 @@ | ||
* @since 1.0.0 | ||
* @version 1.0.0 | ||
* @version 2.0.1 | ||
* | ||
@@ -1276,6 +1283,6 @@ * @param {Function|String} constructor What constructor to listen to | ||
UNDRIERS[path] = { | ||
UNDRIERS.set(path, { | ||
fnc : fnc, | ||
options : options || {} | ||
}; | ||
}); | ||
} | ||
@@ -1498,3 +1505,3 @@ | ||
* @since 0.4.2 | ||
* @version 1.0.0 | ||
* @version 2.0.1 | ||
* | ||
@@ -1516,3 +1523,3 @@ * @param {Object} obj The object to walk over | ||
if (!seen) { | ||
seen = new WeakMap(); | ||
seen = new Map(); | ||
} | ||
@@ -1519,0 +1526,0 @@ |
{ | ||
"name": "json-dry", | ||
"description": "Don't repeat yourself, JSON: Add support for (circular) references, class instances, ...", | ||
"version": "2.0.0", | ||
"version": "2.0.1", | ||
"author": "Jelle De Loecker <jelle@elevenways.be>", | ||
@@ -6,0 +6,0 @@ "keywords": [ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
49462
1353
0