UNPKG

@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
"use strict"; 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