seriall 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +216 -2
- package/dist/index.cjs +4 -1
- package/dist/index.mjs +4 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,2 +1,216 @@
|
|
|
1
|
-
# Seriall
|
|
2
|
-
|
|
1
|
+
# Seriall
|
|
2
|
+
|
|
3
|
+
## TL;DR
|
|
4
|
+
|
|
5
|
+
**Seriall serializes JavaScript object graphs while preserving references, circular references, special primitive values, built-in types, and registered custom classes.**
|
|
6
|
+
|
|
7
|
+
The only **unsuported datatypes** out-of-the-box are:
|
|
8
|
+
|
|
9
|
+
- ⚠️ Custom classes instances with **js-private fields** (prefixed with `#`),
|
|
10
|
+
|
|
11
|
+
there are still configurable workarounds, just no out-of-the-box solution
|
|
12
|
+
|
|
13
|
+
typescript `private` visibility is generally supported ✅
|
|
14
|
+
|
|
15
|
+
- 🚫 Any **function / whole class**, for security reasons (e.g: `serialize(MyClass)` or `serialize(myFunction)`)
|
|
16
|
+
|
|
17
|
+
even though even this is theoretically configurable
|
|
18
|
+
|
|
19
|
+
Seriall **does not use `eval` or dynamically execute serialized JavaScript code**. Serialized functions and classes are not supported by default, which helps keep deserialization data-only.
|
|
20
|
+
|
|
21
|
+
It **conserves refenrential integrity**, so circularly referenced arrays/objects, and cross referenced arrays/objects can be serialized
|
|
22
|
+
|
|
23
|
+
It **can out-of-the-box register custom classes**, and recreates their instances at deserialization time
|
|
24
|
+
|
|
25
|
+
It is **highly configurable**, through the usage of `transformers`
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
|
|
29
|
+
Inside an npm project: `npm install seriall` or `yarn install seriall`
|
|
30
|
+
|
|
31
|
+
## Usage
|
|
32
|
+
|
|
33
|
+
### Basic usage
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
// example.ts
|
|
37
|
+
|
|
38
|
+
import { Serializer } from "seriall";
|
|
39
|
+
|
|
40
|
+
const { serialize, deserialize } = new Serializer();
|
|
41
|
+
|
|
42
|
+
// ------- create test data -------
|
|
43
|
+
|
|
44
|
+
const nested = { name: "Gömböc" };
|
|
45
|
+
|
|
46
|
+
const myData: any = {
|
|
47
|
+
nestedObjects: [nested, nested],
|
|
48
|
+
name: "It works!",
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
myData.self = myData;
|
|
52
|
+
|
|
53
|
+
// ------- serialize data -------
|
|
54
|
+
|
|
55
|
+
const str = serialize(myData);
|
|
56
|
+
|
|
57
|
+
// ------- ------- -------
|
|
58
|
+
// `str` can now go through a network for instance, and be deserialized at the other end like so:
|
|
59
|
+
// ------- ------- -------
|
|
60
|
+
|
|
61
|
+
const revivedData = deserialize(str);
|
|
62
|
+
|
|
63
|
+
console.log(revivedData.self === revivedData);
|
|
64
|
+
// true
|
|
65
|
+
console.log(revivedData.nestedObjects[0] === revivedData.nestedObjects[1]);
|
|
66
|
+
// true
|
|
67
|
+
console.log(revivedData.nestedObjects[0]);
|
|
68
|
+
// {name: "Gömböc"}
|
|
69
|
+
console.log(revivedData.name);
|
|
70
|
+
// It works!
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Registering custom classes
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
// example.ts
|
|
77
|
+
|
|
78
|
+
import { Serializer, SerializableClass } from "seriall";
|
|
79
|
+
|
|
80
|
+
// ------- create a new serializer -------
|
|
81
|
+
|
|
82
|
+
const serializer = new Serializer();
|
|
83
|
+
|
|
84
|
+
// ------- create and register custom classes -------
|
|
85
|
+
|
|
86
|
+
class Address extends SerializableClass {
|
|
87
|
+
country: string;
|
|
88
|
+
city: string;
|
|
89
|
+
constructor(country: string, city: string) {
|
|
90
|
+
super();
|
|
91
|
+
this.country = country;
|
|
92
|
+
this.city = city;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
getFullAddress() {
|
|
96
|
+
return `${this.city}, ${this.country}`;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
serializer.registerClass("adr", Address);
|
|
101
|
+
|
|
102
|
+
class User extends SerializableClass {
|
|
103
|
+
name: string;
|
|
104
|
+
friends: User[] = [];
|
|
105
|
+
address: Address | undefined;
|
|
106
|
+
constructor(name: string) {
|
|
107
|
+
super();
|
|
108
|
+
this.name = name;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
serializer.registerClass("usr", User);
|
|
113
|
+
|
|
114
|
+
// ------- create test data -------
|
|
115
|
+
|
|
116
|
+
const mary = new User("Mary");
|
|
117
|
+
const john = new User("John");
|
|
118
|
+
const paris = new Address("France", "Paris");
|
|
119
|
+
|
|
120
|
+
mary.address = paris;
|
|
121
|
+
john.address = paris;
|
|
122
|
+
mary.friends.push(john);
|
|
123
|
+
john.friends.push(mary);
|
|
124
|
+
|
|
125
|
+
const str = serializer.serialize(mary);
|
|
126
|
+
|
|
127
|
+
// ------- ------- -------
|
|
128
|
+
// `str` can now go through a network for instance, and be deserialized at the other end like so:
|
|
129
|
+
// ------- ------- -------
|
|
130
|
+
|
|
131
|
+
const revived = serializer.deserialize(str);
|
|
132
|
+
|
|
133
|
+
console.log(revived.name);
|
|
134
|
+
// mary
|
|
135
|
+
console.log(revived.address.getFullAddress());
|
|
136
|
+
// Paris, France
|
|
137
|
+
console.log(revived.friends[0].name);
|
|
138
|
+
// john
|
|
139
|
+
console.log(revived.friends[0].friends[0] === revived);
|
|
140
|
+
// true
|
|
141
|
+
console.log(revived.address === revived.friends[0].address);
|
|
142
|
+
// true
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Supported
|
|
146
|
+
|
|
147
|
+
As mentionned earlyer, seriall supports any graph data (objects or arrays), while preserving referential integrity
|
|
148
|
+
|
|
149
|
+
It also natively support any non-json-primitives:
|
|
150
|
+
|
|
151
|
+
- `undefined`, `null`, `Infinity`, `-Infinity`, `-0`, `NaN`
|
|
152
|
+
|
|
153
|
+
as well as JS-specific data-types:
|
|
154
|
+
|
|
155
|
+
- `Symbols`, `BigInts`
|
|
156
|
+
|
|
157
|
+
native classes instances
|
|
158
|
+
|
|
159
|
+
- `Date`, `RegExp`, `Set`, `Map`
|
|
160
|
+
|
|
161
|
+
and boxed primitives
|
|
162
|
+
|
|
163
|
+
- `String`, `Number`, `Boolean`
|
|
164
|
+
|
|
165
|
+
## Import Notes
|
|
166
|
+
|
|
167
|
+
Seriall is exported in both cjs and mjs.
|
|
168
|
+
|
|
169
|
+
It therefore supports both CommonJS import (`require`) and ES Module import (`import`)
|
|
170
|
+
|
|
171
|
+
It also exposes both `.d.cts` and `.d.mts` declaration files, and provides therefore type-safety in both environment.
|
|
172
|
+
|
|
173
|
+
### JavaScript
|
|
174
|
+
|
|
175
|
+
**CommonJS**
|
|
176
|
+
|
|
177
|
+
```ts
|
|
178
|
+
// demo.mjs
|
|
179
|
+
import { Serializer } from "seriall";
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
**ES Module**
|
|
183
|
+
|
|
184
|
+
```ts
|
|
185
|
+
// demo.cjs
|
|
186
|
+
const { Serializer } = require("seriall");
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Typescript
|
|
190
|
+
|
|
191
|
+
**CommonJS**
|
|
192
|
+
|
|
193
|
+
```ts
|
|
194
|
+
// demo.mts
|
|
195
|
+
import { Serializer } from "seriall";
|
|
196
|
+
// Serializer is properly typed
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
**ES Module**
|
|
200
|
+
|
|
201
|
+
either
|
|
202
|
+
|
|
203
|
+
```ts
|
|
204
|
+
// demo.cts
|
|
205
|
+
import seriall = require("seriall");
|
|
206
|
+
const { Serializer } = seriall;
|
|
207
|
+
// Serializer is now typed properly
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
or
|
|
211
|
+
|
|
212
|
+
```ts
|
|
213
|
+
// demo.cts
|
|
214
|
+
const { Serializer } = require("seriall") as typeof import("seriall");
|
|
215
|
+
// Serializer is now typed properly
|
|
216
|
+
```
|
package/dist/index.cjs
CHANGED
|
@@ -268,7 +268,10 @@ var primitivesTransformers = [
|
|
|
268
268
|
encode: (node) => {
|
|
269
269
|
const obj = [];
|
|
270
270
|
for (const key of Reflect.ownKeys(node)) {
|
|
271
|
-
|
|
271
|
+
const value = node[key];
|
|
272
|
+
if (typeof value !== "function") {
|
|
273
|
+
obj.push([key, node[key]]);
|
|
274
|
+
}
|
|
272
275
|
}
|
|
273
276
|
return obj;
|
|
274
277
|
},
|
package/dist/index.mjs
CHANGED
|
@@ -240,7 +240,10 @@ var primitivesTransformers = [
|
|
|
240
240
|
encode: (node) => {
|
|
241
241
|
const obj = [];
|
|
242
242
|
for (const key of Reflect.ownKeys(node)) {
|
|
243
|
-
|
|
243
|
+
const value = node[key];
|
|
244
|
+
if (typeof value !== "function") {
|
|
245
|
+
obj.push([key, node[key]]);
|
|
246
|
+
}
|
|
244
247
|
}
|
|
245
248
|
return obj;
|
|
246
249
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "seriall",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "A flexible js serializer, capable of serializing/deserializing any js data, while preserving referential integrity, non-json-primitive values, and even custom class instances",
|
|
5
5
|
"author": {
|
|
6
6
|
"email": "loic.duvail.pro@gmail.com",
|