@naturalcycles/js-lib
Version:
Standard library for universal (browser + Node.js) javascript
40 lines (39 loc) • 1.42 kB
JavaScript
/**
* JSON.stringify that avoids circular references, prints them as [Circular ~]
*
* Based on: https://github.com/moll/json-stringify-safe/
*/
export function _safeJsonStringify(obj, replacer, spaces, cycleReplacer) {
try {
// Try native first (as it's ~3 times faster)
return JSON.stringify(obj, replacer, spaces);
}
catch {
// Native failed - resort to the "safe" serializer
return JSON.stringify(obj, serializer(replacer, cycleReplacer), spaces);
}
}
/* eslint-disable @typescript-eslint/no-unused-expressions, no-bitwise, no-implicit-coercion */
function serializer(replacer, cycleReplacer) {
const stack = [];
const keys = [];
cycleReplacer ??= (_key, value) => {
if (stack[0] === value)
return '[Circular ~]';
return '[Circular ~.' + keys.slice(0, stack.indexOf(value)).join('.') + ']';
};
return function (key, value) {
if (stack.length > 0) {
const thisPos = stack.indexOf(this);
~thisPos ? stack.splice(thisPos + 1) : stack.push(this);
~thisPos ? keys.splice(thisPos, Infinity, key) : keys.push(key);
if (~stack.indexOf(value)) {
value = cycleReplacer.call(this, key, value);
}
}
else {
stack.push(value);
}
return replacer == null ? value : replacer.call(this, key, value);
};
}