This custom json replacer/reviver allow you to store more types as json and still keep it as valid json.
- Allow you to stringify/parse
- BigInt
- Infinity
- NaN
- Date
- typed arrays & ArrayBuffers as web-safe base64
- Maps & Sets
- Error & TypeError
var obj = {
bigint: 2n,
date: new Date(),
pInf: Infinity,
arr: [2,3],
nInf: -Infinity,
map: new Map([['a', 'b']]),
set: new Set(['a', new Date(), 'a']),
reg: /^f/g,
err: new Error('fail'),
typo: new TypeError('typo'),
empty: null,
binary: new Uint16Array([97]),
buff: new ArrayBuffer(20),
obj: {bday: new Date('1996-08-29')},
str: 'str',
bool: true,
num: 3,
nan: NaN,
invDate: new Date('!'),
// Experimental... creating blob/files are sync but reading it is async.
file: {$f: [[new Uint8Array([97])], 'sample.txt', {type: 'text/javascript'}]},
blob: {$d: [['abc'], {type: 'text/javascript'}]}
}
var str = JSON.stringify(obj, replacer, 2)
var res = JSON.parse(str, reviver)
console.log(str)
console.log(obj)
console.log(res) // pretty much the same as obj
This is simular to bson (ejson) but with a much smaller footprint and different data types
If you change
res.binary
tonew Uint16Array([1000])
you'll see that the values are wrapped into 8-bit slots.The issue is that
new Uint8Array(val)
truncates values to fit. I made these changes to fix:typedarray.buffer
toencode
and read it back fromdecode
decode
to align the ArrayBuffer to the correct number of bytes (others the ctors error)The second change technically makes typed arrays that have a couple bytes too long after a JSON roundtrip if the number of bytes isn't perfectly aligned with the 4/3 byte ratio that the encoding uses. It's not noticeable programmatic with normal usage of TypeArray interface, but if you grab the underlying buffer you may be surprised to find an extra 1 or 2 nil bytes at the end. I couldn't figure out how to resolve this.
Full Code