superserial
After data transfer, when the object needs to be restored, JSON
has many
limitations. It does not support values such as Infinity
and NaN
, and does
not provide circular references.
superserial provides serialization in any way you can imagine.
Useage
import { Serializer } from "https://deno.land/x/superserial/mod.ts";
const serializer = new Serializer();
const nodes = [{ self: null as any, siblings: [] as any[] }, {
self: null as any,
siblings: [] as any[],
}];
nodes[0].self = nodes[0];
nodes[0].siblings = nodes;
nodes[1].self = nodes[1];
nodes[1].siblings = nodes;
const serialized = serializer.serialize(nodes);
console.log(serialized);
// [$1,$2];{"self":$1,"siblings":$0};{"self":$2,"siblings":$0}
Index
Extending types
undefined
BigInt
RegExp
Number
NaN
Infinity
,-Infinity
const output = serializer.serialize({
string: "string",
true: true,
false: false,
number: 3.141592,
null: null,
und: undefined,
nan: NaN,
inf: Infinity,
ninf: -Infinity,
regex: /abc/gmi,
});
console.log(output);
// {"string":"string","true":true,"false":false,"number":3.141592,"null":null,"und":undefined,"nan":NaN,"inf":Infinity,"ninf":-Infinity,"regex":/abc/gim}
Circular Reference
Existing JSON functions do not support circular references, but superserial has solved this problem.
const nodes = [{ self: null as any, siblings: [] as any[] }, {
self: null as any,
siblings: [] as any[],
}];
nodes[0].self = nodes[0];
nodes[0].siblings = nodes;
nodes[1].self = nodes[1];
nodes[1].siblings = nodes;
const serialized = serializer.serialize(nodes);
console.log(serialized);
// [$1,$2];{"self":$1,"siblings":$0};{"self":$2,"siblings":$0}
const deserialized = serializer.deserialize(serialized) as typeof nodes;
console.log(deserialized === deserialized[0].siblings); // true
console.log(deserialized[0] === deserialized[0].self); // true
console.log(deserialized === deserialized[1].siblings); // true
console.log(deserialized[1] === deserialized[1].self);
Class Support
Classes contain methods, getters, etc., but JSON doesn’t fully support them. superserial includes features that make it easy to use.
The class to be used for deserialize
is defined when the Serializer is
created.
class TestUser {
constructor(
public name: string,
public birth: number,
) {
}
get age() {
return new Date().getFullYear() - this.birth;
}
}
const serializer = new Serializer({ classes: { TestUser } });
Serializes the object and then deserializes it again. Since the original class object is converted as it is, all getters and methods can be used as they are.
const serialized = serializer.serialize(new TestUser("wan2land", 2000));
console.log(serialized);
// TestUser{"name":"wan2land","birth":2000}
const user = serializer.deserialize(serialized);
console.log(user); // TestUser { name: "wan2land", birth: 2000 }
console.log(user.age); // 22
toSerialize / toDeserialize
Private variables can be converted using two special symbols (toSerialize
,
toDeserialize
).
import {
Serializer,
toDeserialize,
toSerialize,
} from "https://deno.land/x/superserial/mod.ts";
class TestUser {
static [toDeserialize](data: { name: string; serializedBirth: number }) {
const user = new TestUser(data.name, 0);
user.#_birth = data.serializedBirth;
return user;
}
#_birth: number;
constructor(
public name: string,
birth: number,
) {
this.#_birth = birth;
}
getBirth() {
return this.#_birth;
}
[toSerialize]() {
return {
name: this.name,
serializedBirth: this.#_birth,
};
}
}
const serializer = new Serializer({ classes: { TestUser } });
const serialized = serializer.serialize(new TestUser("wan2land", 2000));
console.log(serialized);
// TestUser{"name":"wan2land","serializedBirth":2000}
const user = serializer.deserialize<TestUser>(serialized);
console.log(user); // TestUser { name: "wan2land" }
console.log(user.getBirth()); // 2000
TODO
-
function
type