serialize-es6
v1.0.1
Published
Serialize/Deserialize complex ES6 objects. Circular references OK!
Downloads
6
Maintainers
Readme
serialize-es6 1.0.0
Go directly to the Usage section if you want only the quick rundown.
This package provides the stringify()
and parse()
functions for serialization and
deserialization of complex elements, which are defined to be any element that can be built
from plain(*) objects, plain functions, ES6 data-types, and Node's Buffer. Circular
references are handled. Like JSON, String validation is provided, i.e, when parsing an
invalid string an exception will be thrown indicating why the string is invalid.
(*) A plain object is an object whose internal prototype is Object.prototype
, and whose
properties are enumerable, writable, and configurable. In particular this includes literal objects.
A plain function is a function that relies only on its local variables, the "this" object,
and global variables. This for example rules out class methods.
Stringification is closely modeled after console notation, i.e., stringify(x)
is based on the
string seen when you write console.log(x)
. See Console-Notation.md for a comparison.
It's emphasized that the objects handled can be very complex.
- Data-types can have properties that themselves are complex.
- For example, Booleans can have properties that are DataViews whose properties are Maps.
- Keys of Sets and key/values of Maps may be complex objects.
- For example, Sets may have members that are Maps whose keys are ArrayBuffers and values are TypedArrays.
- Circular and duplicate references may have ends in the members of a Set, the keys and values of a Map, or the buffers of DataViews/TypedArrays/Buffers.
- Plain functions are handled, and themselves may have complex properties.
Of particular note, this packages does not handle property descriptors. As a consequence it also neither handles non-enumerable properties nor getters/setters. A future package, tentatively named Serialize-Advanced will handle these, and the two packages will be kept separate. See the Serialize vs Serialize-Advanced section in Supplement.md.
If you don't need the complexity, the author also has the json-es6 package.
Exports
|Export 1|Description|
|---|---|
|stringify(x,max, tab)
|Serializes the object x
. max
and tab
are optional parameters.|
|stringify parameter|parameter description|
|max
| max = 0
results in pretty formatting. Otherwise compact formatting where once max+ characters are written a new line is started. Defaults to 100.|
|tab
|The character or string used for tabbing according to object depth. Defaults to two spaces \x20\x20
.|
|||
|Export 2|Description|
|parse(s)
|Parses the string s
to obtain a primitive or object. Validates the string: exception thrown if invalid with explanation.|
Usage
const {stringify, parse} = require('serialize-es6')
const x = object built from plain objects, plain
functions, ES6-data-types, and Node's Buffer
const sx = stringify(x) // serialize x
const y = parse(sx) // deserialize
const sy = stringify(y) // serialize y
console.log(sx === sy) // logs true
y is a deep copy of x (*). Any circular or duplicate references
in x are preserved in y.
(*) Since the internal states of Symbols, WeakSets, and WeakMaps
can't be read, these three data-types can not be serialized.
Thus if the object tree of x has any of these data-types
then the caveat is that y will not be a deep copy of x
because the internal states of the corresponding
Symbols/WeakSets/WeakMaps will be different.
Formatting Serialization
Pretty Formatting
If you want human readability, choose pretty formatting. Otherwise, it's not all that possible to make output highly readable.
const {stringify, parse} = require('Serialize')
const x = very complex object built from plain objects,
ES6-data-types, and Node's Buffer
const sx = stringify(x, 0) // serialize x
const y = parse(sx) // deserialize
const sy = stringify(y, 0) // serialize y
console.log(sx === sy) // logs true
Since the second parameter is 0, the serialiation sx will be
formatted in "pretty" fashion, nicely tabbed according to object
depth, i.e, it's close to one item per line, and is very readable.
Compact Formatting
const {stringify, parse} = require('Serialize')
const x = very complex object built from plain objects,
ES6-data-types, and Node's Buffer
const sx = stringify(x, 30) // serialize x
const y = parse(sx) // deserialize
const sy = stringify(y, 30) // serialize y
console.log(sx === sy) // logs true
Since the second paramteter is greater than 0, the serialiation
sx will be formatted in "compact" fashion. Once the algorithm
realizes that a line has passed 30 characters in length it
will look for a good break to start a new line nicely tabbed
according to object depth.
The default second parameter is 100.
An Example of a Complex Object that is Complicated
const x = new Set([
new Uint8Array([5,6]).buffer,
new Map([[/abc/g,2]]),
])
x.a = {a:new Date(), b:x} // circular reference
x.c = function foo() {const x = this; }
x is a complex object because it has been built from Sets, Maps,
ArrayBuffers, plain objects, Dates, and plain functions.
stringify(x, 30), a compact form, is displayed below
Set {ArrayBuffer(2) {5 6}, Map {
RegExp(/abc/g) => 2},
'a':{'a':Date(2022-06-11T13:25:45.074Z),
'b':@}, 'c':function foo() {const x = this; }}
As you can see it's not totally run-in like JSON, but
if you want total readabiltiy, use pretty notation by
changing the second parameter 30 to 0. See Supplement.md
Testing
Testing before publication was extensive.
Version History
|Version|Published|Remarks| |---|---|---| |1.0.0|6-11-2022|Serialization idea originally from meouzer.com published in 2019. Meouzer.com like this package serialized "everything". Go there if you want to see the browser's Window serialized.|