var traverse = require(‘circularjs’);
exports.encode= function (orig,skipDelete) {
var known= [], nodes= [], keyss= []; if (traverse.isNode(orig)) { // structure traverse(orig, function (node,keys) { var x= known[node.__visited]= Array.isArray(node) ? [] : {}; nodes.push(node); keyss.push(keys); },true); // values nodes.forEach(function (node,idx) { var o= known[node.__visited], keys= keyss[idx]; if (keys) keys.forEach(function (key) { var val= node[key]; if (val&&traverse.isNode(val)) o[key]= { _: val.__visited }; else o[key]= val; }); else node.forEach(function (val,key) { if (val&&traverse.isNode(val)) o[key]= { _: val.__visited }; else o[key]= val; }); }); if (!skipDelete) nodes.forEach(function (node) { delete node.__visited; }); return known; } else return orig;
};
exports.decode= function (encoded,eachNode) {
if (Array.isArray(encoded)) { var fn= function (node,idx) { if (Array.isArray(node)) node.forEach(function (val,key) { if (val&&traverse.isNode(val)) node[key]= encoded[val._]; }); else Object.keys(node).forEach(function (key) { var val= node[key]; if (val&&traverse.isNode(val)) node[key]= encoded[val._]; }); }; if (eachNode) fn= (function (fn) { return function (node,idx) { eachNode(node); fn(node,idx); }; })(fn); encoded.forEach(fn); return encoded[0]; } else return encoded;
};
exports.stringify= function (orig) {
return JSON.stringify(exports.encode(orig));
};
exports.parse= function (s,eachNode) {
return exports.decode(JSON.parse(s),eachNode);
};