diff --git a/CHANGELOG.md b/CHANGELOG.md index 67726a1..2a2bce8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.3 (WIP) + +* Fix placeholders not being replaced in certain circular circumstances + ## 2.0.2 (2023-10-05) * Add `BigInt` support diff --git a/lib/json-dry.js b/lib/json-dry.js index da410ba..6d2d1d5 100644 --- a/lib/json-dry.js +++ b/lib/json-dry.js @@ -233,7 +233,7 @@ class RootValue { * * @author Jelle De Loecker * @since 2.0.0 - * @version 2.0.0 + * @version 2.0.3 * * @param {Object} original_holder The object that holds the value * @param {String} key The key this value is held under @@ -254,7 +254,19 @@ class RootValue { result = value; } else { result = this.createReviverValueWrapper(original_holder, key, value, parent); + result = result.undriedValue(new_holder, key); + + if (result && result instanceof Placeholder) { + if (result.done) { + result = result.result; + } else { + result.waiters.push({ + holder: new_holder, + key : key, + }); + } + } } } else { result = value; @@ -856,13 +868,30 @@ class RefValue extends Value { } } +/** + * Represent a value that will be replaced later + * + * @author Jelle De Loecker + * @since 2.0.3 + * @version 2.0.3 + */ +class Placeholder { + constructor(holder, key) { + this.holder = holder; + this.key = key; + this.result = undefined; + this.done = false; + this.waiters = []; + } +} + /** * Represent a value that needs reviving using registered undriers * (Only used during undrying) * * @author Jelle De Loecker * @since 2.0.0 - * @version 2.0.1 + * @version 2.0.3 */ class UndrierValue extends Value { @@ -874,9 +903,9 @@ class UndrierValue extends Value { this.placeholders = []; } - let placeholder = Symbol(); + let placeholder = new Placeholder(holder, key); - this.placeholders.push([holder, key, placeholder]); + this.placeholders.push(placeholder); return placeholder; } @@ -895,16 +924,15 @@ class UndrierValue extends Value { if (this.placeholders) { let placeholder, holder, - entry, key; while (this.placeholders.length) { - entry = this.placeholders.shift(); - - holder = entry[0]; - key = entry[1]; - placeholder = entry[2]; + placeholder = this.placeholders.shift(); + placeholder.done = true; + placeholder.result = result; + holder = placeholder.holder; + key = placeholder.key; holder[key] = result; @@ -924,6 +952,13 @@ class UndrierValue extends Value { walk(holder, fixer); } } + + if (placeholder.waiters.length) { + while (placeholder.waiters.length) { + let waiter = placeholder.waiters.shift(); + waiter.holder[waiter.key] = result; + } + } } } diff --git a/package.json b/package.json index 4d27073..d2d068b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "json-dry", "description": "Don't repeat yourself, JSON: Add support for (circular) references, class instances, ...", - "version": "2.0.2", + "version": "2.0.3-alpha", "author": "Jelle De Loecker ", "keywords": [ "json",