summaryrefslogtreecommitdiff
path: root/together/node_modules/fast-safe-stringify/index.js
diff options
context:
space:
mode:
Diffstat (limited to 'together/node_modules/fast-safe-stringify/index.js')
-rw-r--r--together/node_modules/fast-safe-stringify/index.js229
1 files changed, 229 insertions, 0 deletions
diff --git a/together/node_modules/fast-safe-stringify/index.js b/together/node_modules/fast-safe-stringify/index.js
new file mode 100644
index 0000000..ecf7e51
--- /dev/null
+++ b/together/node_modules/fast-safe-stringify/index.js
@@ -0,0 +1,229 @@
+module.exports = stringify
+stringify.default = stringify
+stringify.stable = deterministicStringify
+stringify.stableStringify = deterministicStringify
+
+var LIMIT_REPLACE_NODE = '[...]'
+var CIRCULAR_REPLACE_NODE = '[Circular]'
+
+var arr = []
+var replacerStack = []
+
+function defaultOptions () {
+ return {
+ depthLimit: Number.MAX_SAFE_INTEGER,
+ edgesLimit: Number.MAX_SAFE_INTEGER
+ }
+}
+
+// Regular stringify
+function stringify (obj, replacer, spacer, options) {
+ if (typeof options === 'undefined') {
+ options = defaultOptions()
+ }
+
+ decirc(obj, '', 0, [], undefined, 0, options)
+ var res
+ try {
+ if (replacerStack.length === 0) {
+ res = JSON.stringify(obj, replacer, spacer)
+ } else {
+ res = JSON.stringify(obj, replaceGetterValues(replacer), spacer)
+ }
+ } catch (_) {
+ return JSON.stringify('[unable to serialize, circular reference is too complex to analyze]')
+ } finally {
+ while (arr.length !== 0) {
+ var part = arr.pop()
+ if (part.length === 4) {
+ Object.defineProperty(part[0], part[1], part[3])
+ } else {
+ part[0][part[1]] = part[2]
+ }
+ }
+ }
+ return res
+}
+
+function setReplace (replace, val, k, parent) {
+ var propertyDescriptor = Object.getOwnPropertyDescriptor(parent, k)
+ if (propertyDescriptor.get !== undefined) {
+ if (propertyDescriptor.configurable) {
+ Object.defineProperty(parent, k, { value: replace })
+ arr.push([parent, k, val, propertyDescriptor])
+ } else {
+ replacerStack.push([val, k, replace])
+ }
+ } else {
+ parent[k] = replace
+ arr.push([parent, k, val])
+ }
+}
+
+function decirc (val, k, edgeIndex, stack, parent, depth, options) {
+ depth += 1
+ var i
+ if (typeof val === 'object' && val !== null) {
+ for (i = 0; i < stack.length; i++) {
+ if (stack[i] === val) {
+ setReplace(CIRCULAR_REPLACE_NODE, val, k, parent)
+ return
+ }
+ }
+
+ if (
+ typeof options.depthLimit !== 'undefined' &&
+ depth > options.depthLimit
+ ) {
+ setReplace(LIMIT_REPLACE_NODE, val, k, parent)
+ return
+ }
+
+ if (
+ typeof options.edgesLimit !== 'undefined' &&
+ edgeIndex + 1 > options.edgesLimit
+ ) {
+ setReplace(LIMIT_REPLACE_NODE, val, k, parent)
+ 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, i, stack, val, depth, options)
+ }
+ } else {
+ var keys = Object.keys(val)
+ for (i = 0; i < keys.length; i++) {
+ var key = keys[i]
+ decirc(val[key], key, i, stack, val, depth, options)
+ }
+ }
+ 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, options) {
+ if (typeof options === 'undefined') {
+ options = defaultOptions()
+ }
+
+ var tmp = deterministicDecirc(obj, '', 0, [], undefined, 0, options) || obj
+ var res
+ try {
+ if (replacerStack.length === 0) {
+ res = JSON.stringify(tmp, replacer, spacer)
+ } else {
+ res = JSON.stringify(tmp, replaceGetterValues(replacer), spacer)
+ }
+ } catch (_) {
+ return JSON.stringify('[unable to serialize, circular reference is too complex to analyze]')
+ } finally {
+ // Ensure that we restore the object as it was.
+ while (arr.length !== 0) {
+ var part = arr.pop()
+ if (part.length === 4) {
+ Object.defineProperty(part[0], part[1], part[3])
+ } else {
+ part[0][part[1]] = part[2]
+ }
+ }
+ }
+ return res
+}
+
+function deterministicDecirc (val, k, edgeIndex, stack, parent, depth, options) {
+ depth += 1
+ var i
+ if (typeof val === 'object' && val !== null) {
+ for (i = 0; i < stack.length; i++) {
+ if (stack[i] === val) {
+ setReplace(CIRCULAR_REPLACE_NODE, val, k, parent)
+ return
+ }
+ }
+ try {
+ if (typeof val.toJSON === 'function') {
+ return
+ }
+ } catch (_) {
+ return
+ }
+
+ if (
+ typeof options.depthLimit !== 'undefined' &&
+ depth > options.depthLimit
+ ) {
+ setReplace(LIMIT_REPLACE_NODE, val, k, parent)
+ return
+ }
+
+ if (
+ typeof options.edgesLimit !== 'undefined' &&
+ edgeIndex + 1 > options.edgesLimit
+ ) {
+ setReplace(LIMIT_REPLACE_NODE, val, k, parent)
+ 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, i, stack, val, depth, options)
+ }
+ } 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, i, stack, val, depth, options)
+ tmp[key] = val[key]
+ }
+ if (typeof parent !== 'undefined') {
+ arr.push([parent, k, val])
+ parent[k] = tmp
+ } else {
+ return tmp
+ }
+ }
+ stack.pop()
+ }
+}
+
+// wraps replacer function to handle values we couldn't replace
+// and mark them as replaced value
+function replaceGetterValues (replacer) {
+ replacer =
+ typeof replacer !== 'undefined'
+ ? replacer
+ : function (k, v) {
+ return v
+ }
+ return function (key, val) {
+ if (replacerStack.length > 0) {
+ for (var i = 0; i < replacerStack.length; i++) {
+ var part = replacerStack[i]
+ if (part[1] === key && part[0] === val) {
+ val = part[2]
+ replacerStack.splice(i, 1)
+ break
+ }
+ }
+ }
+ return replacer.call(this, key, val)
+ }
+}