This issue is a bit of a specific use case, but would be very helpful to have.
I have a use case specifically where I have an array of objects that needs to have a reference to the parent array. The parent in this case is a fleet, and the objects are elements. The elements need to be able to check if they are still in the fleet. I also need to be able to send this object out to a web exposed API (without the circular references). By using SC to modify the JSON before it goes out, it will actually modify the ORIGINAL object, breaking any functionality the original object has.
const sc = require('smart-circular');
// function to see if this instance of exists in a fleet
Element.prototype.isInFleet = function() {
return this.fleet.indexOf(this) > -1;
}
// Element constructor
function Element(name,fleet) {
this.name = name;
this.fleet = fleet;
}
// fleet array of element instances
const fleet = [];
// create and push two element instances
fleet.push( new Element('foo', fleet) );
fleet.push( new Element('bar', fleet) );
console.log ( fleet[0].isInFleet() ) // true
const json = sc( fleet ); // we are creating a JSON object here by passing fleet
console.log( fleet[0].isInFleet() ); // This is now false because sc has modified fleet
console.log( fleet[0].fleet ) // '$[]'
As you are working primarily with objects, and generally don't want to modify the original one, unless explicitly clobbering the original object (e.g. x = sc(x) ), I propose that this module be modified to return a deep copy of the original, leaving the original untouched. The best implementation of this would likely be something similar to mapping using an object assign.
let list = this.printers.map(a => Object.assign({}, a));
Where list is the user's input argument. This should occur right away, and all circular reference removals should be done on this modified copy of "list", and THIS list should be returned as the resulting value of sc()