Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/sejori/super_cereal

Serialize object graphs into key-value pairs 🥣
https://github.com/sejori/super_cereal

deno graph-algorithms object-oriented-programming serialization

Last synced: 3 months ago
JSON representation

Serialize object graphs into key-value pairs 🥣

Awesome Lists containing this project

README

        

# Super Cereal 🥣

A super serial-izer that can turn any in-memory object graph into key/value string pairs (and back again)!

Supports the following objects/types:
- All primitive values (string, number, bool, etc)
- Classes and inherited classes (base class must extend `Model`)
- Object (with circular refs)
- Response
- Array
- Function
- Map
- Set
- Map
- Date

**TL;DR:** You get to keep your lovely graph structure and all of your lovely class methods too.

## But how?

```
import { Store, Model } from "./mod.ts";

const storeObj: Record = {};

const store = new Store({
get: (id: string) => storeObj[id],
set: (id: string, value: string) => storeObj[id] = value
});

class Person extends Model {
name: string;
friends: Person[] = [];

constructor(name: string) {
super(store, arguments);
this.name = name;
}

addFriend(friend: Person) {
this.friends.push(friend);
friend.friends.push(this);
}
}

const jim = new Person("Jim");
const bob = new Person("Bob");
jim.addFriend(bob);

// jim now has a circular reference via bob - no problem!
const jimId = jim.save();
const freshJim = store.load(jimId) as Person;

console.log(freshJim.friends);

const steve = new Person("Steve");

// class methods retained
freshJim.addFriend(steve);

console.log(freshJim.friends);
```

The Al-Gore-ithm does a depth-first-search through the object structure leaving unique IDs on non-primitive values. It then serializes and stores objects by ID, replacing all refs with the corresponding ID to "unlink" the structure so it never gets stuck in a circular reference loop.

First instantiate a `Store` then simply pass objects into its `save` method. If you want to serialize your own classes, make sure your base classes extend `Model` and call `super(store, arguments)` in their constuctors. This allows the store to reinstantiate them with their initial arguments before using `Object.assign` to apply deserialized property values.

Note: Classes that extend `Model` inherit the `save` method so you can call it directly from them!

## But why?

I wanted a tool that could serialize any in-memory data structure with classes and store it in a key-value store. This allows for browser-based storage of OOP software state that can extend to the edge/cloud.

The goal was to require minimal additional class boilerplate and I think this fits the bill nicely. The only caveat is that you have use `store.load(id) as Classname` to keep accurate TS syntax highlighting (there is currently no way for TS to infer this and generic types don't work with nested structures).