File size: 3,303 Bytes
4d70170 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
const MAX_SERIALIZED_SIZE = 512 * 1024 // 1MB
function encode(data, replacer, list, seen) {
let stored, key, value, i, l
const seenIndex = seen.get(data)
if (seenIndex != null) {
return seenIndex
}
const index = list.length
const proto = Object.prototype.toString.call(data)
if (proto === '[object Object]') {
stored = {}
seen.set(data, index)
list.push(stored)
const keys = Object.keys(data)
for (i = 0, l = keys.length; i < l; i++) {
key = keys[i]
try {
value = data[key]
if (replacer) {
value = replacer.call(data, key, value)
}
}
catch (e) {
value = e
}
stored[key] = encode(value, replacer, list, seen)
}
}
else if (proto === '[object Array]') {
stored = []
seen.set(data, index)
list.push(stored)
for (i = 0, l = data.length; i < l; i++) {
try {
value = data[i]
if (replacer) {
value = replacer.call(data, i, value)
}
}
catch (e) {
value = e
}
stored[i] = encode(value, replacer, list, seen)
}
}
else {
list.push(data)
}
return index
}
function decode(list, reviver) {
let i = list.length
let j, k, data, key, value, proto
while (i--) {
data = list[i]
proto = Object.prototype.toString.call(data)
if (proto === '[object Object]') {
const keys = Object.keys(data)
for (j = 0, k = keys.length; j < k; j++) {
key = keys[j]
value = list[data[key]]
if (reviver) {
value = reviver.call(data, key, value)
}
data[key] = value
}
}
else if (proto === '[object Array]') {
for (j = 0, k = data.length; j < k; j++) {
value = list[data[j]]
if (reviver) {
value = reviver.call(data, j, value)
}
data[j] = value
}
}
}
}
export function stringifyCircularAutoChunks(data: any, replacer: (this: any, key: string, value: any) => any = null, space: number = null) {
let result
try {
result = arguments.length === 1
? JSON.stringify(data)
: JSON.stringify(data, replacer, space)
}
catch (e) {
result = stringifyStrictCircularAutoChunks(data, replacer, space)
}
if (result.length > MAX_SERIALIZED_SIZE) {
const chunkCount = Math.ceil(result.length / MAX_SERIALIZED_SIZE)
const chunks = []
for (let i = 0; i < chunkCount; i++) {
chunks.push(result.slice(i * MAX_SERIALIZED_SIZE, (i + 1) * MAX_SERIALIZED_SIZE))
}
return chunks
}
return result
}
export function parseCircularAutoChunks(data: any, reviver: (this: any, key: string, value: any) => any = null) {
if (Array.isArray(data)) {
data = data.join('')
}
const hasCircular = /^\s/.test(data)
if (!hasCircular) {
return arguments.length === 1
? JSON.parse(data)
: JSON.parse(data, reviver)
}
else {
const list = JSON.parse(data)
decode(list, reviver)
return list[0]
}
}
export function stringifyStrictCircularAutoChunks(data: any, replacer: (this: any, key: string, value: any) => any = null, space: number = null) {
const list = []
encode(data, replacer, list, new Map())
return space
? ` ${JSON.stringify(list, null, space)}`
: ` ${JSON.stringify(list)}`
}
|