mirror of
https://github.com/flynx/serialize.js.git
synced 2026-07-10 19:20:56 +00:00
docs...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
5a82e2e976
commit
a07b4d253a
138
README.md
138
README.md
@ -5,13 +5,12 @@ This extends the default JSON serialization adding the following:
|
|||||||
- Sparse array serialization
|
- Sparse array serialization
|
||||||
- `undefined`/`NaN` serialization
|
- `undefined`/`NaN` serialization
|
||||||
- Serialization of `Infinity`, `BigInt`'s, `Set`'s, `Map`'s
|
- Serialization of `Infinity`, `BigInt`'s, `Set`'s, `Map`'s
|
||||||
- Function serialization (off by default)
|
- Function serialization
|
||||||
- Deep and partial-deep cleen object copy
|
- Deep and partial-deep cleen object copy
|
||||||
|
|
||||||
Possible differences to JSON output:
|
Data not stored:
|
||||||
- Repeating long strings and BigInts are referenced by default instead of
|
- Attributes on arrays, maps, sets, and functions,
|
||||||
being reincluded in the output.
|
- Function closures.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Motivation
|
## Motivation
|
||||||
@ -40,6 +39,43 @@ var serialize = require('ig-serialize')
|
|||||||
|
|
||||||
## Introduction
|
## Introduction
|
||||||
|
|
||||||
|
`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.
|
||||||
|
|
||||||
|
See: ['MIN_LENGTH_REF'](#min_length_ref-options-min_length_ref)
|
||||||
|
|
||||||
|
|
||||||
### Serializing functions
|
### Serializing functions
|
||||||
|
|
||||||
@ -58,6 +94,12 @@ Thus, care must be taken when serializing structures containing function.
|
|||||||
|
|
||||||
## API
|
## API
|
||||||
|
|
||||||
|
### `eJSON`
|
||||||
|
|
||||||
|
An `JSON`-api-compatible object providing [`.stringify(..)`](#serialize-ejson-stringify) and [`.parse(..)`](#deserialize-ejson-parse)
|
||||||
|
static methods.
|
||||||
|
|
||||||
|
|
||||||
### `serialize(..)` / `eJSON.stringify(..)`
|
### `serialize(..)` / `eJSON.stringify(..)`
|
||||||
|
|
||||||
Serialize a JavaScript value into a JSON/eJSON string.
|
Serialize a JavaScript value into a JSON/eJSON string.
|
||||||
@ -147,23 +189,38 @@ eJSON.parse(<string>, {functions: <functions>})
|
|||||||
|
|
||||||
### `deepCopy(..)`
|
### `deepCopy(..)`
|
||||||
|
|
||||||
|
Deep-copy an object.
|
||||||
|
|
||||||
```
|
```
|
||||||
deepCopy(<value>)
|
deepCopy(<value>)
|
||||||
-> <value>
|
-> <value>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The returned object is a fully sanitized through serialization clean copy.
|
||||||
|
|
||||||
|
|
||||||
### `partialDeepCopy(..)`
|
### `partialDeepCopy(..)`
|
||||||
|
|
||||||
|
Partially deep-copy and object, retaining only references to functions.
|
||||||
|
|
||||||
```
|
```
|
||||||
partialDeepCopy(<value>)
|
partialDeepCopy(<value>)
|
||||||
-> <value>
|
-> <value>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
### `MIN_LENGTH_REF` / `<options>.min_length_ref`
|
### `MIN_LENGTH_REF` / `<options>.min_length_ref`
|
||||||
|
|
||||||
Defines the default minimum length of repeating string or bin-int to
|
Defines the default minimum length of repeating string or `BigInt`'s to
|
||||||
include as a reference in the output.
|
include as a reference in the output.
|
||||||
|
|
||||||
If set to `0`, referencing will be disabled.
|
If set to `0`, referencing will be disabled.
|
||||||
@ -171,9 +228,6 @@ If set to `0`, referencing will be disabled.
|
|||||||
Default: 96
|
Default: 96
|
||||||
|
|
||||||
|
|
||||||
### `DEBUG`
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Format
|
## Format
|
||||||
|
|
||||||
@ -194,22 +248,26 @@ structure traversed:
|
|||||||
- map -> pair of numbers -- the first indicates item order the second
|
- map -> pair of numbers -- the first indicates item order the second
|
||||||
if 0 selects the key, if 1 selects the value.
|
if 0 selects the key, if 1 selects the value.
|
||||||
|
|
||||||
Note that string path items are unambiguous and are always treated as
|
|
||||||
attributes.
|
|
||||||
|
|
||||||
An empty path indicates the root object.
|
An empty path indicates the root object.
|
||||||
|
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
### Referencing
|
### Referencing
|
||||||
|
|
||||||
If an object is encountered for a second time it will be serialized as
|
If an object is encountered for a second time it will be serialized as
|
||||||
a reference by path to the first occurrence.
|
a reference by path to the first occurrence.
|
||||||
|
|
||||||
Format:
|
Grammar:
|
||||||
```bnf
|
```bnf
|
||||||
<ref> ::=
|
<ref> ::=
|
||||||
'<REF[]>'
|
'<REF[]>'
|
||||||
| '<REF[' <path-items> ']>'
|
| '<REF[' <path-items> ']>
|
||||||
|
|
||||||
<path-items> ::=
|
<path-items> ::=
|
||||||
<item>
|
<item>
|
||||||
@ -258,7 +316,7 @@ serialize([null, undefined, NaN]) // -> '[null,undefined,NaN]'
|
|||||||
### Sparse arrays
|
### Sparse arrays
|
||||||
|
|
||||||
Sparse arrays are represented in the same way JavaScript handles them
|
Sparse arrays are represented in the same way JavaScript handles them
|
||||||
syntactically.
|
syntactically -- with commas separating empty "positions".
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
```javascript
|
```javascript
|
||||||
@ -266,10 +324,9 @@ serialize([,]) // -> '[,]'
|
|||||||
serialize([,,]) // -> '[,,]'
|
serialize([,,]) // -> '[,,]'
|
||||||
```
|
```
|
||||||
|
|
||||||
Note that trailing commas are ignored in the same way JavaScript ignores
|
Trailing commas are handled in the same way JavaScript handles them:
|
||||||
them:
|
|
||||||
```javascript
|
```javascript
|
||||||
// trailing comma...
|
// trailing commas are ignored...
|
||||||
serialize([1,]) // -> '[1]'
|
serialize([1,]) // -> '[1]'
|
||||||
|
|
||||||
// sparse element...
|
// sparse element...
|
||||||
@ -298,6 +355,10 @@ serialize(-Infinity) // -> '-Infinity'
|
|||||||
|
|
||||||
### Map / Set
|
### Map / Set
|
||||||
|
|
||||||
|
Maps and sets are stored in the same format as their respective constructor
|
||||||
|
calls, dropping the `new` keyword:
|
||||||
|
|
||||||
|
Grammar:
|
||||||
```bnf
|
```bnf
|
||||||
<map> ::=
|
<map> ::=
|
||||||
'Map([])
|
'Map([])
|
||||||
@ -311,7 +372,6 @@ serialize(-Infinity) // -> '-Infinity'
|
|||||||
'[' <value> ',' <value> ']'
|
'[' <value> ',' <value> ']'
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
```bnf
|
```bnf
|
||||||
<set> ::=
|
<set> ::=
|
||||||
'Set([])
|
'Set([])
|
||||||
@ -322,7 +382,7 @@ serialize(-Infinity) // -> '-Infinity'
|
|||||||
| <value> ',' <set-items>
|
| <value> ',' <set-items>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Examples:
|
||||||
```javascript
|
```javascript
|
||||||
serialize(new Set([1,2,3])) // -> 'Set([1,2,3])'
|
serialize(new Set([1,2,3])) // -> 'Set([1,2,3])'
|
||||||
serialize(new Map([['a', 1], ['b', 2]])) // -> 'Map([["a",1],["b",2]])'
|
serialize(new Map([['a', 1], ['b', 2]])) // -> 'Map([["a",1],["b",2]])'
|
||||||
@ -331,26 +391,44 @@ serialize(new Map([['a', 1], ['b', 2]])) // -> 'Map([["a",1],["b",2]])'
|
|||||||
|
|
||||||
### Functions
|
### Functions
|
||||||
|
|
||||||
|
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:
|
||||||
```bnf
|
```bnf
|
||||||
<func> ::=
|
<func> ::=
|
||||||
'<FUNC[' <length> ',(' <func-spec> ')]>
|
'<FUNC[' <length> ',(' <func-spec> ')]>
|
||||||
|
|
||||||
<func-spec> ::=
|
<func-spec> ::=
|
||||||
<code>
|
<code>
|
||||||
| <number>
|
| <index>
|
||||||
|
|
||||||
<length> ::=
|
<length> ::= <number>
|
||||||
<number>
|
|
||||||
|
<index> ::= <number>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
`<length>` is the length of the next block in chars, including the braces.
|
||||||
|
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
serialize(function(){}) // -> '<FUNC[14,(function(){})]>'
|
serialize(function(){}) // -> '<FUNC[14,(function(){})]>'
|
||||||
|
|
||||||
|
var functions = []
|
||||||
|
serialize(function(){}, {functions}) // -> '<FUNC[3,(0)]>'
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Note that deserializing functions is disabled by default as it can pose
|
||||||
|
a security risk if the input to `deserialize(..)` is not trusted.
|
||||||
|
(see: [`deserialize(..)`](#deserialize-ejson-parse))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Running tests
|
## Running tests
|
||||||
|
|
||||||
|
`serialize.js` uses ['test.js'](/flynx/test.js) for testing.
|
||||||
|
|
||||||
Get the development dependencies:
|
Get the development dependencies:
|
||||||
```shell
|
```shell
|
||||||
$ npm install -D
|
$ npm install -D
|
||||||
@ -363,10 +441,22 @@ $ npm test
|
|||||||
|
|
||||||
To run the tests directly:
|
To run the tests directly:
|
||||||
```shell
|
```shell
|
||||||
$ node ./test.js
|
$ ./test.js
|
||||||
|
```
|
||||||
|
|
||||||
|
To run the tests with modifier chains of length 3:
|
||||||
|
```shell
|
||||||
|
$ ./test.js -m 3
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
[BSD 3-Clause License](./LICENSE)
|
||||||
|
|
||||||
|
Copyright (c) 2014-2026, Alex A. Naanou,
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
|
||||||
<!-- vim:set nowrap : -->
|
<!-- vim:set nowrap : -->
|
||||||
|
|||||||
@ -771,7 +771,7 @@ function(str, options){
|
|||||||
|
|
||||||
var deepCopy =
|
var deepCopy =
|
||||||
module.deepCopy =
|
module.deepCopy =
|
||||||
function(obj, funcs){
|
function(obj, funcs=true){
|
||||||
var options = {functions: funcs}
|
var options = {functions: funcs}
|
||||||
return deserialize(
|
return deserialize(
|
||||||
serialize(obj, null, 0, options),
|
serialize(obj, null, 0, options),
|
||||||
@ -781,10 +781,7 @@ function(obj, funcs){
|
|||||||
var partialDeepCopy =
|
var partialDeepCopy =
|
||||||
module.partialDeepCopy =
|
module.partialDeepCopy =
|
||||||
function(obj, funcs=[]){
|
function(obj, funcs=[]){
|
||||||
var options = {functions: funcs}
|
return deepCopy(obj, funcs) }
|
||||||
return deserialize(
|
|
||||||
serialize(obj, null, 0, options),
|
|
||||||
options) }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user