Better serialization in Javascript with alpha-serializer

Published

I bet you already heard about JSON and you know that in order to convert regular an object to JSON you just need to call JSON.stringify and JSON.parse in order to get the object back. Short but not so beautiful story. The worst part about JSON is that it's not symmetric. That means once you serialize and deserialize object the final result might differ from the original one. Simple example:

const date = new Date();
const serialized = JSON.stringify(date); // "2018-09-07T04:56:13.568Z"
const result = JSON.parse(serialized); // "2018-09-07T04:56:13.568Z"

As you see the final object is not a Date object anymore so whenever you serialize an object with a Date and send it over the wire to the browser you won't be able to get the Date object back.

That's not the end. There are much more native javascript objects that are not "properly" serialized

JSON.stringify(new Map([['key', 'value']])); // "{}"
JSON.stringify(new Set(['value', 'value2'])); // "{}"
JSON.stringify(new Error('test')); // "{}"

Why is that?

That's because serialization formats suppose to work the same on different platforms. For example when you're serializing an object defined in Javascript and deserializing it on a platform thas has no support for original object. This might be annoying if you're working in Javascript environment only (which is pretty common nowadays).

Solution

alpha-serializer is the answer for your problems. This package abstract whole serialization, allows to change serialization formats via adapter and register custom types.

const {serialize, deserialize} = require('alpha-serializer');

const sMap = serialize(new Map([['key', 'value']])); // {"@type":"Map","value":[["key","value"]]}

const map = deserialize(sMap);
map instanceof Map; // true
map.get('key'); // "value"

// similar to dates
const sDate = serialize(new Date(1000)); // {"@type":"Date","value":"1970-01-01T00:00:01.000Z"}

const date = deserialize(sDate);
date instanceof Date; // true
date.getTime(); // 1000

Alpha-serializer changes representation of an object by adding extra "@type" property that represent the type of the value and allows symmetric deserialization. By default alpha-serializer supports Date, Map and Set (more planned).

Obviously custom types are also allowed

const {Serializable, serialize, deserialize} = require('alpha-serializer');

@Serializable({name: 'Foo'})
class Foo {
    constructor(bar) {
        this.foo = bar;
    } 
}

const obj = new Foo('some value');

const result = deserialize(serialize(obj));
result instanceof Foo; // true
result.foo; // 'some value'

Not only JSON

JSON is not always the best format fo certain tasks. For example when saving object representation on the disk as JSON will take much more space than binary format. For this purpose alpha-serializer allows to change the adapter to one that suits your needs.

const {MsgpackAdapter} = require('alpha-serializer-msgpack');
const {serializer} = require('alpha-serializer');

serializer.adapter = new MsgpackAdapter();
const result = serializer.deserialize(
    serializer.serialize(new Date(1000))
);

result instanceof Date; // true
result.getTime(); // 1000
Łukasz Kużyński - Wookieb
Thoughts, tips about programming and related subjects to make your job easier and more pleasant so you won't burnout quickly.
Copyright © Łukasz Kużyński - Wookieb 2023 • All rights reserved.