Skip to content

Commit

Permalink
🐛 Fix placeholders not being replaced in certain circular circumstances
Browse files Browse the repository at this point in the history
  • Loading branch information
skerit committed Jul 25, 2024
1 parent 7505416 commit fbd84a8
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 11 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
55 changes: 45 additions & 10 deletions lib/json-dry.js
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ class RootValue {
*
* @author Jelle De Loecker <jelle@elevenways.be>
* @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
Expand All @@ -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;
Expand Down Expand Up @@ -856,13 +868,30 @@ class RefValue extends Value {
}
}

/**
* Represent a value that will be replaced later
*
* @author Jelle De Loecker <jelle@elevenways.be>
* @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 <jelle@elevenways.be>
* @since 2.0.0
* @version 2.0.1
* @version 2.0.3
*/
class UndrierValue extends Value {

Expand All @@ -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;
}
Expand All @@ -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;

Expand All @@ -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;
}
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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 <jelle@elevenways.be>",
"keywords": [
"json",
Expand Down

0 comments on commit fbd84a8

Please sign in to comment.