npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@jitar/serialization

v0.7.4

Published

JavaScript serialization library for the Jitar runtime.

Downloads

14

Readme

Jitar Serialization

This package provides extensible serialization for automating end-to-end data transportation. It's used in the Jitar project, but can also be used as standalone library in any project.

By default it supports:

  • Primitives (bool, number, string, etc.)
  • Arrays / Maps / Sets
  • Objects / Classes
  • Typed Arrays (Data buffer)

You can also write and add your own.

Installation

To add this package to your project run:

npm install @jitar/serialization

Basic usage

Serializers are created by the SerializerBuilder class. Once a serializer is created it can be used for serialization and deserialization of all type of values mentioned above.

import { SerializerBuilder } from '@jitar/serializer';

const set = new Set().add('apple').add('banana');
const map = new Map().set('bicycle', 1).set('car', 2).set('plane', 3);
const array = [ set, map ];

const serializer = SerializerBuilder.build();
const serializedArray = serializer.serialize(array);
const deserializedArray = serializer.deserialize(serializedArray);

console.log(deserializedArray);

// [
//   Set(2) { 'apple', 'banana' },
//   Map(3) { 'bicycle' => 1, 'car' => 2, 'plane' => 3 }
// ]

Class serialization

In order to (de)serialize class instances, the serializer needs to know the source location of the class so it can be imported and instantiated. The source must be defined as a class property.

import { SerializerBuilder, Loadable } from '@jitar/serializer';

class Person
{
    #name: string;
    #age: string;

    construction(name: string, age: string)
    {
        this.#name = name;
        this.#age = age;
    }

    get name() { return this.#name; }
    get age() { return this.#name; }

    toString(): string { `${this.#name} is ${this.#age}` }
}

// Set the source like this
(Person as Loadable).source = import.meta.url;

const peter = new Person('Peter', 42);

const serializer = SerializerBuilder.build();
const serializedPeter = serializer.serialize(peter);
const deserializedPeter = serializer.deserialize(serializedPeter);

console.log(deserializedPeter.toString()); // Peter is 42

Bring your own class loader

The SerializerBuilder uses a default class loader if no other loader is provided. This is fine is most cases, but for other cases you can implement your own class loader.

import { ClassLoader } from '@jitar/serializer';

export default class MyClassLoader implements ClassLoader
{
    async loadClass(loadable: Loadable): Promise<Function>
    {
        // Do your magic here.
        // The Loadable type provides the source and the class name.
    }
}

Simply provide your class loader to the SerializerBuilder to use it.

import { SerializerBuilder } from '@jitar/serializer';
import MyClassLoader from './MyClassLoader';

const serializer = SerializerBuilder.build(new MyClassLoader());

// The serializer now uses your class loader

Extending the serializer

You can write and add your own (de)serializers by extending the ValueSerializer and implement its four abstract functions.

  1. canSerialize - check if the value meets all the requirements to be serialized by this serializer.
  2. canDeserialize - check if the value meets all the requirements to be deserialized by this serializer.
  3. serialize - serialize the value.
  4. deserialize - deserialize the value.

For example, this is how the ArraySerializer looks like.

import { ValueSerializer } from '@jitar/serializer';

export default class ArraySerializer extends ValueSerializer
{
    canSerialize(value: unknown): boolean
    {
        return value instanceof Array;
    }

    canDeserialize(value: unknown): boolean
    {
        return value instanceof Array;
    }
    
    async serialize(array: unknown[]): Promise<unknown[]>
    {
        const values: unknown[] = [];

        for (const value of array)
        {
            values.push(await this.serializeOther(value));
        }

        return values;
    }

    async deserialize(array: unknown[]): Promise<unknown[]>
    {
        return await Promise.all(array.map(async (value) => await this.deserializeOther(value)));
    }
}

The this.deserializeOther(value) function lets the main serializer handle the serialization of the (unknown) sub value.

Value serializers can easily be added to the main serializer.

import { SerializerBuilder } from '@jitar/serializer';
import MySerializer from './MySerializer';

const serializer = SerializerBuilder.build();
serializer.addSerializer(new MySerializer());

// Your serializer is now being used

Last added value serializers are first in line to check if they can (de)serialize a value. This means that you can override any of the default serializers.