New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Strip circular references #7
Comments
This is already possible as follows: var jsan = require('jsan')
var obj = {}
obj.a = 1
obj.self = obj;
var set = new WeakSet();
var stringified = jsan.stringify(obj, (key, value) => {
if (set.has(value)) return '[CIRCULAR]';;
if (typeof value === 'object') set.add(value);
return value;
});
console.log(stringified) Hmm, I can't seem to save on http://requirebin.com/ but you can just copy paste it to see for yourself Does that solve your issue? |
I guess we obtain almost the same as just The problem however is that in case of var o = { t: 2 };
var obj = { e1: o, e2: o}
obj.a = 1
obj.self = obj;
console.log(customJsanStringify(obj) we get We should also account if we're including the parent, which maybe better to handle in |
Hmm, that's not a trivial problem. I guess we can detect something like that by checking that Line 79 in 0867ecf
|
I'll try to convince you :-D The idea is that most of the time people get circular references because they are including React components inside the object (accidentally or intended), and they are not interested to see the whole circular structure of that component. We have to remove them everytime we want to show the state or comparing states. Removing them outside If we implement it as an option, it shouldn't affect the perf of the default implementation: if (typeof value === 'object' && value !== null) {
+ if (options['circular'] === false && path.indexOf(foundPath) === 0) {
+ return '[CIRCULAR]';
+ }
var foundPath = map.get(value);
if (foundPath) {
return {$jsan: foundPath};
}
map.set(value, path);
} Or to gain some perf from not replacing paths inside if (typeof value === 'object' && value !== null) {
+ if (options['circular'] === false) {
+ if (path.indexOf(foundPath) === 0) {
+ return '[CIRCULAR]';
+ }
+ } else {
var foundPath = map.get(value);
if (foundPath) {
return {$jsan: foundPath};
}
+ }
map.set(value, path);
} Or even moving that part inside a function we can call, not to check function includePath() {
if (options['circular'] === false) {
return function() {
if (path.indexOf(foundPath) === 0) {
return '[CIRCULAR]';
}
}
}
return function() {
var foundPath = map.get(value);
if (foundPath) {
return {$jsan: foundPath};
}
}
} Of course, there are already solutions like |
Ok, I'm convinced. I've played around with it and it doesn't seem to have any perf hit I want to play around with the api some more first. I'll push a release soon 3dbebf0 |
published to https://github.com/kolodny/jsan/blob/master/test/unit.js#L77-L85 For your use case you would just pass in a string |
It works just amazing! Thanks a lot for your effort on this! |
While it's great that jsan can restore circular references, in many cases we want them stripped as it will affect rendering perf and could hang object traversing.
It would be useful to have an additional parameter to use it like so:
Or if it is more performant we could strip them while stringifying. I couldn't wrap my head around it, but it seems that it would be easier to do while parsing inside
retrocycle
.The text was updated successfully, but these errors were encountered: