Skip to content

lkwr/jasone

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Jasone

A lightweight, extensible JSON encoder and decoder which supports custom types.

NOTICE: Jasone is still in early development and might not be stable yet.

Features

  • 🚀 Fast & Lightweight: Minimal footprint.
  • 🔌 Extensible: Easily add custom types.
  • 💻 TypeScript: Written in TypeScript for type safety and better DX.

Installation

# npm
npm install jasone

# pnpm
pnpm add jasone

# yarn
yarn add jasone

# bun
bun add jasone

Basic Usage

Encoding

import { Jasone } from "jasone";

const data = { myDate: new Date("2025-04-05T14:30:00.000+02:00") };
const encoded = JSON.stringify(Jasone.encode(data));

console.log(encoded); // {"myDate":{"$":1,"timestamp":1743856200000}}

Decoding

import { decode } from "jasone";

const encoded = '{"myDate":{"$":1,"timestamp":1743856200000}}';
const decoded = Jasone.decode(JSON.parse(encoded));

console.log(decoded); // { myDate: new Date("2025-04-05T14:30:00.000+02:00") }

Advanced Usage

Adding custom types is really easy. You just need to create an transformer object and register it with Jasone.

import { Jasone } from "jasone";

class Car {
  constructor(public brand: string, public model: string) {}

  // ...
}

// use the `createType` helper
const myType = createType({
  // the match function is used to determine if the transformer can encode the given value
  matches: (value) => value instanceof Car,

  // the type id is used to identify the type on the encoded object
  // (this needs to be unique and a string, numbers are currently reserved for built-in types)
  typeId: "Car"

  // the encode function which receives the matched value and need to return an valid JSON object
  encode: (car) => ({ brand: car.brand, model: car.model }),

  // the decode function which receives the encoded JSON object and needs to return a original value
  decode: ({brand, model}) => new Car(brand, model),
});

For classes, you can also use a bit more performant way of creating the transformer object:

const myType = createType({
  // by using the `target` property, under the hood, Jasone will use the constructor to match
  // the type. Which is more performant than using the `matches` property.
  target: Car,
  typeId: "Car",
  encode: (car) => ({brand: car.brand, model: car.model}),
  decode: ({brand, model}) => new Car(brand, model),
});

Now the only thing left is to register the type with Jasone:

Jasone.register(myType);

And that's it! If you want multiple instances of Jasone with different types, simply create a new instance like so:

const jasone = new Jasone({
  types: [myType],
});

Or

const jasone = new Jasone();

jasone.register(myType);

Contributing

Contributions are welcome! Please open an issue or submit a pull request.

License

This project is licensed under the MIT License.

Releases

No releases published

Packages

No packages published