2026-02-19 01:26:39 +03:00
|
|
|
# serialize.js: Extended JSON serilization
|
2026-01-01 12:57:24 +03:00
|
|
|
|
2026-01-21 21:57:27 +03:00
|
|
|
JSON-like extended serialization/deserialization, and serialization-based
|
|
|
|
|
object isolated deep and semi-deep copying library.
|
2026-01-21 04:52:00 +03:00
|
|
|
|
2026-01-21 21:57:27 +03:00
|
|
|
This extends the default JSON specification adding the following:
|
2026-01-01 12:57:24 +03:00
|
|
|
- Recursive data structure serialization
|
2026-01-17 15:21:47 +03:00
|
|
|
- Sparse array serialization
|
2026-01-01 12:57:24 +03:00
|
|
|
- `undefined`/`NaN` serialization
|
2026-01-17 15:21:47 +03:00
|
|
|
- Serialization of `Infinity`, `BigInt`'s, `Set`'s, `Map`'s
|
2026-01-18 16:33:31 +03:00
|
|
|
- Function serialization
|
2026-01-01 12:57:24 +03:00
|
|
|
- Deep and partial-deep cleen object copy
|
|
|
|
|
|
2026-01-18 16:33:31 +03:00
|
|
|
Data not stored:
|
|
|
|
|
- Attributes on arrays, maps, sets, and functions,
|
|
|
|
|
- Function closures.
|
2026-01-01 12:57:24 +03:00
|
|
|
|
2026-02-19 18:28:55 +03:00
|
|
|
Note that this a strict superset of JSON, this if only JSON-supported
|
|
|
|
|
data is serialized the output will be strict JSON.
|
|
|
|
|
|
2026-01-01 12:57:24 +03:00
|
|
|
|
|
|
|
|
## Motivation
|
|
|
|
|
|
2026-01-01 23:56:20 +03:00
|
|
|
This was originally built as a companion to a testing module for a
|
|
|
|
|
programming class, illustrating several concepts, including: guaranteed
|
|
|
|
|
clean isolation of data structures via serialization, instrumenting code
|
|
|
|
|
and tooling design, basic parsing, among others.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## Installation
|
|
|
|
|
|
2026-01-17 03:14:24 +03:00
|
|
|
For basic use:
|
2026-01-14 18:04:57 +03:00
|
|
|
```shell
|
|
|
|
|
$ npm install ig-serilaize
|
|
|
|
|
```
|
|
|
|
|
|
2026-01-18 16:46:15 +03:00
|
|
|
Or just download and drop [serialize.js](./serialize.js) into your code.
|
2026-01-14 18:04:57 +03:00
|
|
|
|
|
|
|
|
|
2026-01-17 03:14:24 +03:00
|
|
|
```javascript
|
2026-01-18 05:31:11 +03:00
|
|
|
var serialize = require('ig-serialize')
|
2026-01-17 03:14:24 +03:00
|
|
|
```
|
|
|
|
|
|
2026-01-01 23:56:20 +03:00
|
|
|
|
|
|
|
|
## Introduction
|
|
|
|
|
|
2026-01-18 16:33:31 +03:00
|
|
|
`serialize.js` provides two toolsets:
|
|
|
|
|
|
|
|
|
|
1. A means to serialize and deserialize complex data structures into an
|
|
|
|
|
extended JSON format.
|
|
|
|
|
```javascript
|
|
|
|
|
var obj = {
|
|
|
|
|
sparse_array: [,,,,1],
|
|
|
|
|
bad_number: NaN,
|
|
|
|
|
really_large_number: 99999999999999999999999n,
|
|
|
|
|
}
|
|
|
|
|
obj.recursive = obj
|
|
|
|
|
obj.re_reference = obj.sparse_array
|
|
|
|
|
|
|
|
|
|
var str = serialize(obj)
|
|
|
|
|
|
|
|
|
|
// ...
|
|
|
|
|
|
|
|
|
|
var copy = deserialize(str)
|
|
|
|
|
```
|
|
|
|
|
This is useful when requiering serialization of data structures more
|
|
|
|
|
complex than pure JSON can handle.
|
|
|
|
|
2. A means to cleanly copy deep data structures with guaranteed isolation.
|
|
|
|
|
```javascript
|
|
|
|
|
var obj = {
|
|
|
|
|
// ...
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var copy = deepCopy(obj)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Long strings and large `BigInt`'s
|
|
|
|
|
|
|
|
|
|
Repeating strings and `BigInt`'s longer that `MIN_LENGTH_REF` are stored
|
|
|
|
|
by reference by default.
|
|
|
|
|
|
2026-01-18 16:46:15 +03:00
|
|
|
See: [`MIN_LENGTH_REF`](#min_length_ref--optionsmin_length_ref)
|
2026-01-18 16:33:31 +03:00
|
|
|
|
2026-01-01 23:56:20 +03:00
|
|
|
|
|
|
|
|
### Serializing functions
|
|
|
|
|
|
|
|
|
|
Due to how JavaScript is designed it is not possible to trivially and
|
|
|
|
|
fully clone a function with all of it's references, `.serilaize(..)` will
|
|
|
|
|
not attempt to clone any state a function may have, this will lead to
|
|
|
|
|
loosing:
|
|
|
|
|
|
|
|
|
|
- Function closure
|
|
|
|
|
- Attributes set on the function or any of it's prototypes, including the
|
|
|
|
|
`.__proto__` value if it was changed.
|
|
|
|
|
|
|
|
|
|
Thus, care must be taken when serializing structures containing function.
|
|
|
|
|
|
|
|
|
|
|
2026-01-14 18:18:06 +03:00
|
|
|
|
2026-01-01 23:56:20 +03:00
|
|
|
## API
|
|
|
|
|
|
2026-01-18 16:33:31 +03:00
|
|
|
### `eJSON`
|
|
|
|
|
|
2026-01-18 16:46:15 +03:00
|
|
|
An `JSON`-api-compatible object providing [`.stringify(..)`](#serialize--ejsonstringify) and [`.parse(..)`](#deserialize--ejsonparse)
|
2026-01-18 16:33:31 +03:00
|
|
|
static methods.
|
|
|
|
|
|
|
|
|
|
|
2026-01-14 18:28:56 +03:00
|
|
|
### `serialize(..)` / `eJSON.stringify(..)`
|
2026-01-14 18:18:06 +03:00
|
|
|
|
2026-01-15 15:24:05 +03:00
|
|
|
Serialize a JavaScript value into a JSON/eJSON string.
|
2026-01-15 15:07:37 +03:00
|
|
|
```
|
|
|
|
|
serialize(<value>)
|
|
|
|
|
eJSON.stringify(<value>)
|
|
|
|
|
-> <string>
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
More control:
|
|
|
|
|
```
|
|
|
|
|
serialize(obj, options){
|
|
|
|
|
serialize(obj, indent, depth=0, options){
|
|
|
|
|
-> <string>
|
|
|
|
|
```
|
|
|
|
|
|
2026-01-16 16:21:59 +03:00
|
|
|
Options format:
|
|
|
|
|
```
|
|
|
|
|
{
|
|
|
|
|
// pretty-printing indent...
|
|
|
|
|
// (default: undefined)
|
|
|
|
|
indent: undefined,
|
|
|
|
|
|
|
|
|
|
// outout root indent...
|
|
|
|
|
// (default: 0)
|
|
|
|
|
depth: 0,
|
|
|
|
|
|
|
|
|
|
// minimal referenced string/bigint length...
|
|
|
|
|
// (default: MIN_LENGTH_REF)
|
|
|
|
|
min_length_ref: MIN_LENGTH_REF,
|
|
|
|
|
|
|
|
|
|
// functions list...
|
|
|
|
|
// (default: undefined)
|
|
|
|
|
functions: undefined,
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
2026-01-15 15:07:37 +03:00
|
|
|
Supported options:
|
|
|
|
|
- `indent` controls formatting and nested value indent, if set to a number
|
|
|
|
|
that number of spaces will be used to indent nested values if given a
|
|
|
|
|
string that string is used for indenting, note that only whitespace is
|
|
|
|
|
supported currently.
|
|
|
|
|
Default: `undefined` (disabled)
|
|
|
|
|
- `depth` if given is a number of `indent`'s, used to set top level indent
|
|
|
|
|
depth of the returned string, this can be useful when pretty-printing
|
|
|
|
|
or nesting the output.
|
|
|
|
|
Default: `0`
|
|
|
|
|
- `min_length_ref` sets the minimal length of a string or big-int value
|
|
|
|
|
for referencing when encountered repeatedly.
|
|
|
|
|
If set to `0` or `Infinity` referencing of strings and big-ints will
|
|
|
|
|
be is disabled.
|
|
|
|
|
Default: 'MIN_LENGTH_REF'
|
|
|
|
|
- `functions` if passed an array, encounterd functions will be pushed to
|
|
|
|
|
it and stored in the output by index.
|
|
|
|
|
Default: `undefined`
|
|
|
|
|
|
|
|
|
|
|
2026-01-15 15:39:51 +03:00
|
|
|
### `deserialize(..)` / `eJSON.parse(..)`
|
2026-01-14 18:18:06 +03:00
|
|
|
|
2026-01-15 15:24:05 +03:00
|
|
|
Deserialize a JSON/eJSON into a value.
|
2026-01-15 15:07:37 +03:00
|
|
|
```
|
|
|
|
|
deserialize(<string>)
|
|
|
|
|
eJSON.parse(<string>)
|
|
|
|
|
-> <value>
|
|
|
|
|
```
|
|
|
|
|
|
2026-01-15 15:24:05 +03:00
|
|
|
Deserializing function is disabled by default as it can be a security
|
|
|
|
|
risk if the eJSON came from an untrusted source.
|
|
|
|
|
|
|
|
|
|
Enable function deserialization:
|
|
|
|
|
```
|
|
|
|
|
deserialize(<string>, true)
|
|
|
|
|
eJSON.parse(<string>, true)
|
|
|
|
|
deserialize(<string>, {functions: true})
|
|
|
|
|
eJSON.parse(<string>, {functions: true})
|
|
|
|
|
-> <value>
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Passing a function list (generated by `serialize(<value>, {functions: <functions>})`)
|
|
|
|
|
for deserialization:
|
|
|
|
|
```
|
|
|
|
|
deserialize(<string>, {functions: <functions>})
|
|
|
|
|
eJSON.parse(<string>, {functions: <functions>})
|
|
|
|
|
-> <value>
|
|
|
|
|
```
|
|
|
|
|
|
2026-01-15 15:07:37 +03:00
|
|
|
|
2026-01-14 18:28:56 +03:00
|
|
|
### `deepCopy(..)`
|
2026-01-14 18:18:06 +03:00
|
|
|
|
2026-01-18 16:33:31 +03:00
|
|
|
Deep-copy an object.
|
|
|
|
|
|
2026-01-15 15:07:37 +03:00
|
|
|
```
|
|
|
|
|
deepCopy(<value>)
|
|
|
|
|
-> <value>
|
|
|
|
|
```
|
|
|
|
|
|
2026-01-18 16:33:31 +03:00
|
|
|
The returned object is a fully sanitized through serialization clean copy.
|
|
|
|
|
|
2026-01-15 15:07:37 +03:00
|
|
|
|
2026-01-14 18:28:56 +03:00
|
|
|
### `partialDeepCopy(..)`
|
2026-01-14 18:18:06 +03:00
|
|
|
|
2026-01-18 16:33:31 +03:00
|
|
|
Partially deep-copy and object, retaining only references to functions.
|
|
|
|
|
|
2026-01-15 15:07:37 +03:00
|
|
|
```
|
|
|
|
|
partialDeepCopy(<value>)
|
|
|
|
|
-> <value>
|
|
|
|
|
```
|
|
|
|
|
|
2026-01-18 16:33:31 +03:00
|
|
|
The returned object is a partially sanitized through serialization clean
|
|
|
|
|
copy with function references copied as-is from the input retaining and
|
|
|
|
|
"transferring" all associated function state like attributes and closures.
|
|
|
|
|
|
|
|
|
|
Note that this is by definition a _controlled state leak_ from input
|
|
|
|
|
object to copy, so care must be taken to _control_ object-specific state
|
|
|
|
|
in function closures and attributes -- keeping function state independent
|
|
|
|
|
from object state is _in general_ a good practice.
|
|
|
|
|
|
2026-01-14 18:18:06 +03:00
|
|
|
|
2026-01-14 18:28:56 +03:00
|
|
|
### `MIN_LENGTH_REF` / `<options>.min_length_ref`
|
2026-01-14 18:18:06 +03:00
|
|
|
|
2026-01-18 16:33:31 +03:00
|
|
|
Defines the default minimum length of repeating string or `BigInt`'s to
|
2026-01-14 18:28:56 +03:00
|
|
|
include as a reference in the output.
|
2026-01-01 23:56:20 +03:00
|
|
|
|
2026-01-14 18:28:56 +03:00
|
|
|
If set to `0`, referencing will be disabled.
|
2026-01-01 23:56:20 +03:00
|
|
|
|
2026-01-14 18:28:56 +03:00
|
|
|
Default: 96
|
|
|
|
|
|
|
|
|
|
|
2026-01-01 23:56:20 +03:00
|
|
|
|
2026-01-09 15:39:24 +03:00
|
|
|
## Format
|
|
|
|
|
|
2026-01-11 03:51:26 +03:00
|
|
|
The output of `.serialize(..)` is a strict superset of [standard JSON](https://www.json.org/json-en.html),
|
2026-01-10 03:44:59 +03:00
|
|
|
while the input format is a bit more relaxed than in several details.
|
2026-01-09 15:39:24 +03:00
|
|
|
|
2026-01-10 03:44:59 +03:00
|
|
|
|
|
|
|
|
### Structural paths
|
|
|
|
|
|
2026-01-17 14:43:29 +03:00
|
|
|
Paths are used for internal references in cases when objects are
|
|
|
|
|
encountered multiple times, e.g. in recursion.
|
|
|
|
|
|
2026-01-18 16:39:43 +03:00
|
|
|
A path is an array of keys, the semantics of each key depend on the data
|
2026-01-17 14:43:29 +03:00
|
|
|
structure traversed:
|
2026-01-18 16:39:43 +03:00
|
|
|
- `Array` expects a number
|
|
|
|
|
- `Set` expects a number -- item order in set
|
|
|
|
|
- `Map` expects pair of consecutive numbers -- the first indicates item
|
|
|
|
|
order the second if `0` selects the key, if `1` selects the value.
|
|
|
|
|
- `Object` expects a string
|
2026-01-17 14:43:29 +03:00
|
|
|
|
2026-01-17 15:21:47 +03:00
|
|
|
An empty path indicates the root object.
|
2026-01-17 14:43:29 +03:00
|
|
|
|
|
|
|
|
|
2026-01-18 16:33:31 +03:00
|
|
|
Notes:
|
|
|
|
|
- String path items are unambiguous and are always treated as attributes.
|
|
|
|
|
This enables referencing of attributes of any object like arrays, maps, ...etc.
|
|
|
|
|
- Map/set paths are structured as if sets and maps are represented by
|
|
|
|
|
arrays structured as their respective constructors expect as input.
|
|
|
|
|
|
|
|
|
|
|
2026-01-17 14:47:48 +03:00
|
|
|
### Referencing
|
2026-01-10 03:44:59 +03:00
|
|
|
|
2026-01-17 14:43:29 +03:00
|
|
|
If an object is encountered for a second time it will be serialized as
|
|
|
|
|
a reference by path to the first occurrence.
|
|
|
|
|
|
2026-01-18 16:33:31 +03:00
|
|
|
Grammar:
|
2026-01-17 14:43:29 +03:00
|
|
|
```bnf
|
|
|
|
|
<ref> ::=
|
2026-01-18 05:29:30 +03:00
|
|
|
'<REF[]>'
|
2026-01-18 16:33:31 +03:00
|
|
|
| '<REF[' <path-items> ']>
|
2026-01-17 14:43:29 +03:00
|
|
|
|
|
|
|
|
<path-items> ::=
|
|
|
|
|
<item>
|
|
|
|
|
| <item> ',' <path-items>
|
|
|
|
|
|
|
|
|
|
<item> ::=
|
|
|
|
|
<number>
|
|
|
|
|
| <string>
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Example:
|
2026-01-17 14:47:48 +03:00
|
|
|
```javascript
|
|
|
|
|
// a recursive array...
|
2026-01-17 14:43:29 +03:00
|
|
|
var o = []
|
|
|
|
|
o.o = o
|
|
|
|
|
|
|
|
|
|
// root object reference...
|
|
|
|
|
serialize(o) // -> '[<REF[]>]'
|
|
|
|
|
|
|
|
|
|
// array item...
|
|
|
|
|
serialize([o]) // -> '[[<REF[0]>]]'
|
|
|
|
|
|
|
|
|
|
// set item...
|
|
|
|
|
// NOTE: the path here is the same as in the above example -- since we
|
|
|
|
|
// use ordered topology for paths sets do not differ from arrays.
|
|
|
|
|
serialize(new Set([o])) // -> 'Set([[<REF[0]>]])'
|
|
|
|
|
|
|
|
|
|
// map key...
|
|
|
|
|
serialize(new Map([[o, 'value']])) // -> 'Map([[[<REF[0,0]>],"value"]])'
|
|
|
|
|
|
|
|
|
|
// map value...
|
|
|
|
|
serialize(new Map([['key', o]])) // -> 'Map([["key",[<REF[0,1]>]]])'
|
2026-01-17 14:47:48 +03:00
|
|
|
```
|
2026-01-17 14:43:29 +03:00
|
|
|
|
2026-01-13 03:20:11 +03:00
|
|
|
|
2026-01-17 15:21:47 +03:00
|
|
|
### Null types
|
|
|
|
|
|
|
|
|
|
In addition to `null`, serialize.js adds support for `undefined` and
|
|
|
|
|
`NaN` which are stored as-is.
|
|
|
|
|
|
|
|
|
|
Example:
|
|
|
|
|
```javascript
|
|
|
|
|
serialize([null, undefined, NaN]) // -> '[null,undefined,NaN]'
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Sparse arrays
|
|
|
|
|
|
|
|
|
|
Sparse arrays are represented in the same way JavaScript handles them
|
2026-01-18 16:33:31 +03:00
|
|
|
syntactically -- with commas separating empty "positions".
|
2026-01-17 15:21:47 +03:00
|
|
|
|
|
|
|
|
Example:
|
|
|
|
|
```javascript
|
|
|
|
|
serialize([,]) // -> '[,]'
|
|
|
|
|
serialize([,,]) // -> '[,,]'
|
|
|
|
|
```
|
|
|
|
|
|
2026-01-18 16:33:31 +03:00
|
|
|
Trailing commas are handled in the same way JavaScript handles them:
|
2026-01-17 15:21:47 +03:00
|
|
|
```javascript
|
2026-01-18 16:33:31 +03:00
|
|
|
// trailing commas are ignored...
|
2026-01-17 15:21:47 +03:00
|
|
|
serialize([1,]) // -> '[1]'
|
|
|
|
|
|
|
|
|
|
// sparse element...
|
|
|
|
|
serialize([1,,]) // -> '[1,,]'
|
|
|
|
|
```
|
2026-01-10 03:44:59 +03:00
|
|
|
|
2026-01-18 04:34:38 +03:00
|
|
|
|
2026-01-10 03:44:59 +03:00
|
|
|
### BigInt
|
|
|
|
|
|
2026-01-18 04:34:38 +03:00
|
|
|
Serialized as represented in JavaScript.
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
serialize(9999999999n) // -> '9999999999n'
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
2026-01-17 15:21:47 +03:00
|
|
|
### Infinity
|
|
|
|
|
|
2026-01-18 04:34:38 +03:00
|
|
|
Serialized as represented in JavaScript
|
|
|
|
|
|
|
|
|
|
```javascript
|
|
|
|
|
serialize(Infinity) // -> 'Infinity'
|
|
|
|
|
serialize(-Infinity) // -> '-Infinity'
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
2026-01-10 03:44:59 +03:00
|
|
|
### Map / Set
|
|
|
|
|
|
2026-01-18 16:33:31 +03:00
|
|
|
Maps and sets are stored in the same format as their respective constructor
|
|
|
|
|
calls, dropping the `new` keyword:
|
|
|
|
|
|
|
|
|
|
Grammar:
|
2026-01-18 05:29:30 +03:00
|
|
|
```bnf
|
|
|
|
|
<map> ::=
|
|
|
|
|
'Map([])
|
|
|
|
|
| 'Map([' <map-items> '])
|
|
|
|
|
|
|
|
|
|
<map-items> ::=
|
|
|
|
|
<map-item>
|
|
|
|
|
| <map-item> ',' <map-items>
|
|
|
|
|
|
|
|
|
|
<map-item> ::=
|
|
|
|
|
'[' <value> ',' <value> ']'
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
```bnf
|
|
|
|
|
<set> ::=
|
|
|
|
|
'Set([])
|
|
|
|
|
| 'Set([' <set-items> '])
|
|
|
|
|
|
|
|
|
|
<set-items> ::=
|
|
|
|
|
<value>
|
|
|
|
|
| <value> ',' <set-items>
|
|
|
|
|
```
|
|
|
|
|
|
2026-01-18 16:33:31 +03:00
|
|
|
Examples:
|
2026-01-18 04:34:38 +03:00
|
|
|
```javascript
|
|
|
|
|
serialize(new Set([1,2,3])) // -> 'Set([1,2,3])'
|
|
|
|
|
serialize(new Map([['a', 1], ['b', 2]])) // -> 'Map([["a",1],["b",2]])'
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
2026-01-10 03:44:59 +03:00
|
|
|
### Functions
|
|
|
|
|
|
2026-01-18 16:33:31 +03:00
|
|
|
A function can be stored in one of two ways:
|
|
|
|
|
1. As code (default)
|
|
|
|
|
2. As a function index, if an array to store function references is given.
|
|
|
|
|
|
|
|
|
|
Grammar:
|
2026-01-18 05:29:30 +03:00
|
|
|
```bnf
|
|
|
|
|
<func> ::=
|
|
|
|
|
'<FUNC[' <length> ',(' <func-spec> ')]>
|
|
|
|
|
|
|
|
|
|
<func-spec> ::=
|
|
|
|
|
<code>
|
2026-01-18 16:33:31 +03:00
|
|
|
| <index>
|
2026-01-18 05:29:30 +03:00
|
|
|
|
2026-01-18 16:33:31 +03:00
|
|
|
<length> ::= <number>
|
|
|
|
|
|
|
|
|
|
<index> ::= <number>
|
2026-01-18 05:29:30 +03:00
|
|
|
```
|
|
|
|
|
|
2026-01-18 16:33:31 +03:00
|
|
|
`<length>` is the length of the next block in chars, including the braces.
|
|
|
|
|
|
|
|
|
|
|
2026-01-18 05:09:23 +03:00
|
|
|
```javascript
|
|
|
|
|
serialize(function(){}) // -> '<FUNC[14,(function(){})]>'
|
2026-01-18 16:33:31 +03:00
|
|
|
|
|
|
|
|
var functions = []
|
|
|
|
|
serialize(function(){}, {functions}) // -> '<FUNC[3,(0)]>'
|
2026-01-18 05:09:23 +03:00
|
|
|
```
|
2026-01-10 03:44:59 +03:00
|
|
|
|
2026-01-18 16:33:31 +03:00
|
|
|
Note that deserializing functions is disabled by default as it can pose
|
|
|
|
|
a security risk if the input to `deserialize(..)` is not trusted.
|
2026-01-18 16:46:15 +03:00
|
|
|
(see: [`deserialize(..)`](#deserialize--ejsonparse))
|
2026-01-18 16:33:31 +03:00
|
|
|
|
2026-01-10 03:44:59 +03:00
|
|
|
|
|
|
|
|
|
2026-01-17 03:14:24 +03:00
|
|
|
## Running tests
|
|
|
|
|
|
2026-01-18 16:33:31 +03:00
|
|
|
`serialize.js` uses ['test.js'](/flynx/test.js) for testing.
|
|
|
|
|
|
2026-01-17 03:14:24 +03:00
|
|
|
Get the development dependencies:
|
|
|
|
|
```shell
|
|
|
|
|
$ npm install -D
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Run the tests:
|
|
|
|
|
```shell
|
|
|
|
|
$ npm test
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
To run the tests directly:
|
|
|
|
|
```shell
|
2026-01-18 16:33:31 +03:00
|
|
|
$ ./test.js
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
To run the tests with modifier chains of length 3:
|
|
|
|
|
```shell
|
|
|
|
|
$ ./test.js -m 3
|
2026-01-17 03:14:24 +03:00
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
2026-01-10 03:44:59 +03:00
|
|
|
|
2026-02-19 18:28:55 +03:00
|
|
|
## Alternatives
|
|
|
|
|
|
|
|
|
|
### https://github.com/WebReflection/flatted
|
|
|
|
|
|
|
|
|
|
A very similar library that takes a different approach to the output
|
|
|
|
|
format (not JSON-compatible), lacks copying utils, and does not
|
|
|
|
|
support function serialization, but is smaller, and adds other language
|
|
|
|
|
support.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### https://github.com/ungap/structured-clone/
|
|
|
|
|
|
|
|
|
|
As above but slightly different approach to things, more types, cloning.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-01-18 16:33:31 +03:00
|
|
|
## License
|
|
|
|
|
|
|
|
|
|
[BSD 3-Clause License](./LICENSE)
|
|
|
|
|
|
|
|
|
|
Copyright (c) 2014-2026, Alex A. Naanou,
|
|
|
|
|
All rights reserved.
|
|
|
|
|
|
2026-01-01 12:57:24 +03:00
|
|
|
|
2026-01-17 15:21:47 +03:00
|
|
|
<!-- vim:set nowrap : -->
|