A fully typed reactive state management library with very little boilerplate.
Installations
npm install @arborjs/json
Developer Guide
Typescript
Yes
Module System
ESM
Node Version
20.8.0
NPM Version
10.1.0
Score
66.6
Supply Chain
98
Quality
76.6
Maintenance
100
Vulnerability
100
License
Releases
Unable to fetch releases
Contributors
Unable to fetch Contributors
Languages
TypeScript (96.6%)
JavaScript (3.4%)
validate.email 🚀
Verify real, reachable, and deliverable emails with instant MX records, SMTP checks, and disposable email detection.
Developer
drborges
Download Statistics
Total Downloads
1,233
Last Day
6
Last Week
10
Last Month
15
Last Year
283
GitHub Statistics
MIT License
14 Stars
806 Commits
2 Forks
2 Watchers
17 Branches
3 Contributors
Updated on Feb 25, 2025
Bundle Size
1.69 kB
Minified
783.00 B
Minified + Gzipped
Package Meta Information
Latest Version
0.0.1-alpha.7
Package Id
@arborjs/json@0.0.1-alpha.7
Unpacked Size
13.65 kB
Size
4.47 kB
File Count
9
NPM Version
10.1.0
Node Version
20.8.0
Published on
Nov 03, 2024
Oops! Something went wrong.
Dev Dependencies
5
@arborjs/json
Type-preserving serialization/deserialization for user-defined types via an API similar to JSON.stringify
and JSON.parse
+ some decorator "magic".
Installation
npm
1npm install @arborjs/json
yarn
1yarn add @arborjs/json
Usage
For most use cases, the usage is extremely simple, with very little boilerplate:
- Decorate your class with the
serializable
decorator; - Use the
stringify
function to serialize instances of the decorated class; - Use the
parse
function to deserialize data strings representing instances of the decorated class.
1import { serializable, stringify, parse } from "@arborjs/json" 2 3@serializable 4class Todo { 5 constructor(readonly uuid: string, public text: string) {} 6} 7 8const todo = new Todo("my-uuid", "Clean the house") 9 10const serialized = stringify(todo) 11=> '{"$value":{"uuid":"my-uuid","text":"Clean the house"},"$type":"Todo"}' 12 13const deserialized = parse(serialized) 14expect(deserialized).toEqual(todo) 15expect(deserialized).toBeInstanceOf(Todo) 16=> true
Managing multiple serializers
In case you need to manage multiple instances of the Json
serializer in your app, you can:
- Create an instance of the
Json
class; - Decorate your classes with the decorators provided by the
Json
instance; - Leverage the
Json#stringify
to serialize your object; - And
Json#parse
to deserialize the string data back into an instance of your serialized type.
Example:
- Instantiate the
Json
class:
1import { Json } from `@arborjs/json` 2 3// NOTE: we'll be referencing this variable in the following snippets 4const json = new Json()
- Decorate your class so it can be known by the
Json
instance:
1@json.serializable 2class Todo { 3 constructor(readonly uuid: string, public text: string) {} 4}
- Serialize the object:
1const todo = new Todo("my-uuid", "Clean the house") 2 3const serialized = json.stringify(todo) 4=> '{"$value":{"uuid":"my-uuid","text":"Clean the house"},"$type":"Todo"}'
- Deserialize the string data back into an instance of the Todo class:
1const deserialized = json.parse(serialized) 2 3expect(deserialized).toEqual(todo) 4=> true
Custom serialization/deserialization logic
In certain situations, you will want to provide your own serialization/deserialization logic, here's how to achieve that:
1@json.serializable 2class TodoList extends Map<string, Todo> { 3 constructor(...todos: Todo[]) { 4 super(todos.map((todo) => [todo.uuid, todo])) 5 } 6 7 /* 8 * Provide your own deserialization logic 9 */ 10 static fromJSON(value: SerializedBy<TodoList>) { 11 return new TodoList(...value) 12 } 13 14 /* 15 * Provide your own serialization logic 16 */ 17 toJSON() { 18 return Array.from(this.values()) 19 } 20}
Handling type name clashes
In case you end up with different types sharing the same name in your application, you can tell @arborjs/json
which serialization keys to use to identify each type:
1// models/users/Settings.ts 2@json.serializableAs("UserSettings") 3class Settings { 4 constructor( 5 readonly uuid: string, 6 readonly userId: string, 7 public active: boolean 8 ) {} 9} 10 11// models/projects/Settings.ts 12@json.serializableAs("ProjectSettings") 13class Settings { 14 constructor( 15 readonly uuid: string, 16 readonly projectId: string, 17 public status: ProjectStatus 18 ) {} 19}
The serializableAs
decorator instructs @arborjs/json
to use the provided key to identify the decorated type so that it can differentiate different types with the same name in its registry, ultimatelly allowing proper serialization/deserialization of these types:
1const userSettings = new UserSettings("user-settings-uuid", "user-id", true) 2const projectSettings = new ProjectSettings("project-settings-uuid", "project-id", "in progress") 3 4const serializedUserSettings = json.stringify(userSettings) 5=> '{"$value":{"uuid":"user-settings-uuid","userId":"user-id","active":true},"$type":"UserSettings"}' 6 7const serializedProjectSettings = json.stringify(projectSettings) 8=> '{"$value":{"uuid":"project-settings-uuid","projectId":"project-id","status":"in progress"},"$type":"ProjectSettings"}'
Reducing boilerplate
You may choose to move the Json
serializer setup into different modules to make its usage a little more friendly and with less boilerplate to the final user:
1// src/json1.ts 2import { Json } from "@arborjs/json" 3 4const json = new Json() 5export const parse = json.parse.bind(json) 6export const stringify = json.stringify.bind(json) 7export const serializable = json.serializable.bind(json) 8export const serializableAs = json.serializableAs.bind(json) 9 10// src/json2.ts 11import { Json } from "@arborjs/json" 12 13const json = new Json() 14export const parse = json.parse.bind(json) 15export const stringify = json.stringify.bind(json) 16export const serializable = json.serializable.bind(json) 17export const serializableAs = json.serializableAs.bind(json)
License
All packages in this monorepo are MIT licensed.

No vulnerabilities found.

No security vulnerabilities found.