-
Notifications
You must be signed in to change notification settings - Fork 27
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
make decirc function public #34
base: master
Are you sure you want to change the base?
Conversation
If we expose it publically it also needs documentation and unit tests We may also want to consider the API |
Makes sense, I can do that - in general is this a change that you'd be interested in? For the simple case of needing to decycle an existing JS object, small objects jump from 100k -> 600k ops in our benchmarks, and large objects jump even more, so this has been great for us (rather than doing a Do you already have thoughts on possible changes to the API for this function? I would throw function decycle(
val: any,
opts: {
parent?: any;
parentKey?: string;
stack?: any[];
} = {}
) {
const { parent, parentKey, stack = [] } = opts;
// ... implementation
} |
cc @BridgeAR (sorry got the handle wrong) |
Yup, we're just as interested in benchmarks and performance as you are :). Without getting into too much detail our primary use case is:
Let me know if it doesn't make sense or you need more detail. |
Does this mean that there are potential cases where decirc would be used but stringify wouldn't? If that is true, decirc should be a separate module - and fast safe stringify can rely on it |
I agree that moving the decirc function to a separate module will be best in this case. It will definitely not hurt one way or the other and if there are people who need such a functionality, it can be used that way. @davidmarkclements are you going to open such a module or should I do that? |
If you've got time go ahead - otherwise I can - either way let's both be contribs |
Definitely +1 in splitting. Add me as well (also on npm)! |
- expose new decycle function instead of decirc - add replacer option to customze how circular refs are replaced - add benchmarks for decycle - add a simple test for decycle
Ok after a bit of investigation, the original interface I proposed is definitely not the way to go. Passing around objects as function arguments decreases performance significantly (see below). decycle (decirc) original
decycle (decirc) with obj argument
Since we're actively working with this stuff I'm continuing to make changes, feel free to use any or none of it. I'm also happy to help contribute if you guys want. I went ahead and added an option for a custom replacer, and added the key to the stack. This allows easy tracking of where the original circular reference was pointing to, by using a simple custom replacer. You can find an example of how we use this to replace with a JSON pointer instead of '[Circular]' in the tests file. The performance impact of the custom replacer is pretty negligible: original
with replacer
|
to better represent the idea of replacing circular refs with a json pointer to their target
We find it quite useful to remove circular references without having to go through a full stringify and then re-parse.