chat-server/node_modules/fast-safe-stringify/index.js

104 lines
2.5 KiB
JavaScript

module.exports = stringify
stringify.default = stringify
stringify.stable = deterministicStringify
stringify.stableStringify = deterministicStringify
var arr = []
// Regular stringify
function stringify (obj, replacer, spacer) {
decirc(obj, '', [], undefined)
var res = JSON.stringify(obj, replacer, spacer)
while (arr.length !== 0) {
var part = arr.pop()
part[0][part[1]] = part[2]
}
return res
}
function decirc (val, k, stack, parent) {
var i
if (typeof val === 'object' && val !== null) {
for (i = 0; i < stack.length; i++) {
if (stack[i] === val) {
parent[k] = '[Circular]'
arr.push([parent, k, val])
return
}
}
stack.push(val)
// Optimize for Arrays. Big arrays could kill the performance otherwise!
if (Array.isArray(val)) {
for (i = 0; i < val.length; i++) {
decirc(val[i], i, stack, val)
}
} else {
var keys = Object.keys(val)
for (i = 0; i < keys.length; i++) {
var key = keys[i]
decirc(val[key], key, stack, val)
}
}
stack.pop()
}
}
// Stable-stringify
function compareFunction (a, b) {
if (a < b) {
return -1
}
if (a > b) {
return 1
}
return 0
}
function deterministicStringify (obj, replacer, spacer) {
var tmp = deterministicDecirc(obj, '', [], undefined) || obj
var res = JSON.stringify(tmp, replacer, spacer)
while (arr.length !== 0) {
var part = arr.pop()
part[0][part[1]] = part[2]
}
return res
}
function deterministicDecirc (val, k, stack, parent) {
var i
if (typeof val === 'object' && val !== null) {
for (i = 0; i < stack.length; i++) {
if (stack[i] === val) {
parent[k] = '[Circular]'
arr.push([parent, k, val])
return
}
}
if (typeof val.toJSON === 'function') {
return
}
stack.push(val)
// Optimize for Arrays. Big arrays could kill the performance otherwise!
if (Array.isArray(val)) {
for (i = 0; i < val.length; i++) {
deterministicDecirc(val[i], i, stack, val)
}
} else {
// Create a temporary object in the required way
var tmp = {}
var keys = Object.keys(val).sort(compareFunction)
for (i = 0; i < keys.length; i++) {
var key = keys[i]
deterministicDecirc(val[key], key, stack, val)
tmp[key] = val[key]
}
if (parent !== undefined) {
arr.push([parent, k, val])
parent[k] = tmp
} else {
return tmp
}
}
stack.pop()
}
}