@safejs/serializer
Version:
Serializer is a superset of JSON that includes recursive objects, dates, regular expressions, functions and others which you also can expand by yourself
111 lines • 4.07 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.BaseSerializer = void 0;
const refs_1 = require("../refs");
const types_1 = require("../types");
class Knowns {
constructor() {
this.nextIdx = 0;
this.list = new Map();
}
include(ref, known = {}) {
let v = this.list.get(ref);
if (v) {
Object.assign(v, known);
}
else {
v = this.add(ref, known);
}
if (!v.include) {
v.include = true;
v.idx = this.nextIdx;
this.nextIdx++;
}
return v;
}
has(ref) {
return this.list.has(ref);
}
get(ref) {
return this.list.get(ref);
}
add(ref, known = {}) {
const v = Object.assign({ include: false }, known);
this.list.set(ref, v);
return v;
}
getIncludes() {
return Array.from(this.list.values())
.filter((o) => o.include)
.sort((a, b) => a.idx - b.idx)
.map((o) => o.serialized);
}
}
class BaseSerializer {
static serialize(value, extraSerializers = {}) {
const serializers = Object.entries(extraSerializers).map(([id, s]) => (Object.assign(Object.assign({}, s), { ref: {}, id })));
const knowns = BaseSerializer.getKnowns(value, serializers);
const serialized = [value, ...knowns.getIncludes()];
return JSON.stringify(serialized, function (k) {
const v = this[k];
if (this === serialized && k !== "0") {
if (serializers.find((s) => s.ref === v)) {
return serializers.find((s) => s.ref === v).id;
}
return v;
}
const knownValue = knowns.get(v);
if (knownValue) {
if (knownValue.include)
return refs_1.refs.create(knownValue.idx);
return knownValue.serialized;
}
const serializer = BaseSerializer.findExtraSerializer(v, serializers);
if (serializer) {
const serialized = BaseSerializer.serializeByExtraSerializer(v, serializer);
if (knowns.has(serialized)) {
return refs_1.refs.create(knowns.get(serialized).idx);
}
return BaseSerializer.serializeByExtraSerializer(v, serializer);
}
return v;
});
}
static getKnowns(value, serializers) {
const knowns = new Knowns();
JSON.stringify(value, function (k) {
const v = this[k];
if (knowns.has(v)) {
const known = knowns.include(v);
return refs_1.refs.create(known.idx);
}
if (refs_1.refs.test(v)) {
const known = knowns.include(v, { serialized: v });
return refs_1.refs.create(known.idx);
}
const serializer = BaseSerializer.findExtraSerializer(v, serializers);
let serialized = v;
if (serializer) {
knowns.include(serializer.ref, { serialized: serializer.ref });
serialized = BaseSerializer.serializeByExtraSerializer(v, serializer);
}
if ((typeof v === "object" && v !== null) || typeof v === "symbol") {
knowns.add(v, { serialized });
}
return serialized;
});
return knowns;
}
static findExtraSerializer(v, serializers) {
for (const serializer of serializers) {
if (serializer.determine(v)) {
return serializer;
}
}
}
static serializeByExtraSerializer(v, serializer) {
return types_1.isConstantExtraSerializer(serializer) ? serializer.ref : [serializer.ref, serializer.serialize(v)];
}
}
exports.BaseSerializer = BaseSerializer;
//# sourceMappingURL=base-serializer.js.map