json-dry
Advanced tools
Comparing version 1.0.12 to 1.1.0
@@ -0,1 +1,6 @@ | ||
## 1.1.0 (2020-11-12) | ||
* Added `whenDone` function parameter to the `unDry` & `unDryFunction` function calls | ||
* Fixed infinite loop issue when using `Dry.clone()` that relies on `unDry` methods | ||
## 1.0.12 (2019-11-22) | ||
@@ -2,0 +7,0 @@ |
@@ -441,3 +441,3 @@ "use strict"; | ||
* @since 1.0.0 | ||
* @version 1.0.10 | ||
* @version 1.1.0 | ||
* | ||
@@ -470,2 +470,12 @@ * @param {Object} obj | ||
if (!wm.when_done_queue) { | ||
wm.when_done_queue = []; | ||
wm.drymap = new Map(); | ||
wm.whenDone = function whenDone(fnc) { | ||
if (!fnc) return; | ||
wm.when_done_queue.push(fnc); | ||
}; | ||
} | ||
if (custom_method) { | ||
@@ -475,3 +485,26 @@ extra_args = [wm].concat(extra_args); | ||
return real_clone({'_': obj}, custom_method, extra_args, wm)['_']; | ||
let result = real_clone({'_': obj}, custom_method, extra_args, wm)['_'], | ||
i; | ||
if (wm.when_done_queue.length) { | ||
let temp_val, | ||
key; | ||
// Iterate over all the objects created with the `toDry` method | ||
wm.drymap.forEach(function each(val, temp) { | ||
for (key in temp) { | ||
temp_val = temp[key]; | ||
if (wm.drymap.has(temp_val)) { | ||
temp[key] = wm.drymap.get(temp_val); | ||
} | ||
} | ||
}); | ||
for (i = 0; i < wm.when_done_queue.length; i++) { | ||
wm.when_done_queue[i](); | ||
} | ||
} | ||
return result; | ||
} | ||
@@ -484,3 +517,3 @@ | ||
* @since 1.0.0 | ||
* @version 1.0.10 | ||
* @version 1.1.0 | ||
* | ||
@@ -555,15 +588,23 @@ * @param {Object} obj | ||
// Perform the toDry function | ||
temp = entry.toDry(); | ||
let uncloned_dried = entry.toDry(); | ||
// Remember this temporary object to prevent infinite loops | ||
wm.set(entry, uncloned_dried); | ||
// Clone the value, | ||
// because returned objects aren't necesarilly cloned yet | ||
temp = real_clone(temp, custom_method, extra_args, wm).value; | ||
let cloned_dried = real_clone(uncloned_dried, custom_method, extra_args, wm).value; | ||
// Perform the undry function | ||
if (entry.constructor.unDry) { | ||
target[key] = entry.constructor.unDry(temp, custom_method || true); | ||
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] = temp; | ||
target[key] = cloned_dried; | ||
} | ||
// Remember both entries (for circular undry references) | ||
wm.drymap.set(cloned_dried, target[key]); | ||
wm.drymap.set(uncloned_dried, target[key]); | ||
} else if (name_type == 'Date') { | ||
@@ -1179,3 +1220,3 @@ target[key] = new Date(entry); | ||
* @since 1.0.0 | ||
* @version 1.0.11 | ||
* @version 1.1.0 | ||
* | ||
@@ -1189,2 +1230,3 @@ * @param {Object} value | ||
var undry_paths = new Map(), | ||
when_done = [], | ||
retrieve = {}, | ||
@@ -1219,2 +1261,7 @@ reviver, | ||
function whenDone(fnc) { | ||
if (!fnc) return; | ||
when_done.push(fnc); | ||
} | ||
// To remember which objects have already been revived | ||
@@ -1236,5 +1283,5 @@ seen = new WeakMap(); | ||
if (entry.unDryConstructor) { | ||
entry.undried = entry.unDryConstructor.unDry(entry.value, false); | ||
entry.undried = entry.unDryConstructor.unDry(entry.value, false, whenDone); | ||
} else if (entry.unDryFunction) { | ||
entry.undried = entry.unDryFunction(entry, null, entry.value); | ||
entry.undried = entry.unDryFunction(entry, null, entry.value, whenDone); | ||
} else { | ||
@@ -1298,5 +1345,9 @@ entry.undried = entry.value; | ||
if (result.undried != null && result.dry) { | ||
return result.undried; | ||
result = result.undried; | ||
} | ||
for (i = 0; i < when_done.length; i++) { | ||
when_done[i](); | ||
} | ||
return result; | ||
@@ -1303,0 +1354,0 @@ } |
{ | ||
"name": "json-dry", | ||
"description": "Don't repeat yourself, JSON: Add support for (circular) references, class instances, ...", | ||
"version": "1.0.12", | ||
"version": "1.1.0", | ||
"author": "Jelle De Loecker <jelle@develry.be>", | ||
@@ -15,11 +15,11 @@ "keywords": [ | ||
"scripts": { | ||
"test" : "node_modules/.bin/mocha --reporter spec", | ||
"test" : "mocha --exit --reporter spec --bail --timeout 5000 --file test/dry.js", | ||
"coverage" : "./node_modules/istanbul/lib/cli.js cover _mocha", | ||
"report-coverage" : "cat ./coverage/lcov.info | coveralls" | ||
"report-coverage" : "codecov" | ||
}, | ||
"license": "MIT", | ||
"devDependencies": { | ||
"coveralls" : "^2.11.6", | ||
"istanbul" : "^0.4.5", | ||
"mocha" : "1.20.x", | ||
"codecov" : "~3.7.0", | ||
"nyc" : "^15.1.0", | ||
"mocha" : "~8.0.1", | ||
"protoblast" : "skerit/protoblast#3218106" | ||
@@ -26,0 +26,0 @@ }, |
@@ -159,3 +159,31 @@ # JSON-dry | ||
## Serializing & reviving instances with circular references | ||
Some classes contain references to each other, for example: | ||
```js | ||
let alpha = new Alpha(), | ||
beta = new Beta(); | ||
alpha.beta = beta; | ||
beta.alpha = alpha; | ||
``` | ||
The problem is that when you serialize & then try to revive this, one of the `unDry` methods will receive an un-revived placeholder. This can obviously cause issues, especially when setting the property has side-effects. So a new argument `whenDone` has been added to the `unDry` method, like so: | ||
```js | ||
Alpha.prototype.unDry = function unDry(obj, custom_method, whenDone) { | ||
let alpha = new Alpha(); | ||
whenDone(function() { | ||
alpha.beta = obj.beta; | ||
}); | ||
return alpha; | ||
} | ||
``` | ||
`whenDone` functions will be called just before the `Dry.undry()` function exits, so all the references will have been revived by then. | ||
### toObject | ||
@@ -162,0 +190,0 @@ |
43780
1109
284