• Stars
    star
    157
  • Rank 238,399 (Top 5 %)
  • Language
    JavaScript
  • Created almost 12 years ago
  • Updated about 7 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

JSON on steroids.

Cryo

JSON on steroids.

Built for node.js and browsers. Cryo is inspired by Python's pickle and works similarly to JSON.stringify() and JSON.parse(). Cryo.stringify() and Cryo.parse() improve on JSON in these circumstances:

Installation

node.js

$ npm install cryo

browser

With Bower:

bower install cryo

Add the latest minified build to your project as a script:

<script type='text/javascript' src='cryo-0.0.4.js'></script>

Use

Cryo has a very simple API that mimicks JSON:

  • Cryo.stringify(item, [callbacks])
  • Cryo.parse(string, [callbacks])
var Cryo = require('cryo');

var obj = {
  name: 'Hunter',
  created: new Date(),
  hello: function() {
    console.log(this.name + ' said hello in ' + this.created.getFullYear() + '!');
  }
};

var frozen = Cryo.stringify(obj);
var hydrated = Cryo.parse(frozen);

hydrated.hello(); // Hunter said hello in 2013!

More powerful JSON

Undefined

Cryo takes a verbatim snapshot of all your properties, including those that are undefined - which JSON ignores.

var Cryo = require('../lib/cryo');

var obj = {
  defaultValue: undefined
};

var withJSON = JSON.parse(JSON.stringify(obj));
console.log(withJSON.hasOwnProperty('defaultValue'));   // false

var withCryo = Cryo.parse(Cryo.stringify(obj));
console.log(withCryo.hasOwnProperty('defaultValue'));   // true

Date

Cryo successfully works with Date objects, which JSON.stringify() mangles into strings.

var Cryo = require('../lib/cryo');

var now = new Date();

var withJSON = JSON.parse(JSON.stringify(now));
console.log(withJSON instanceof Date);              // false

var withCryo = Cryo.parse(Cryo.stringify(now));
console.log(withCryo instanceof Date);              // true

References

JSON.stringify() makes multiple copies of single objects, losing object relationships. When several references to the same object are stringified with JSON, those references are turned into clones of each other. Cryo maintains object references so the restored objects are identical to the originals. This is easier to understand with an example:

var Cryo = require('../lib/cryo');

var userList = [{ name: 'Abe' }, { name: 'Bob' }, { name: 'Carl' }];
var state = {
  users: userList,
  activeUser: userList[1]
};

var withJSON = JSON.parse(JSON.stringify(state));
console.log(withJSON.activeUser === withJSON.users[1]);   // false

var withCryo = Cryo.parse(Cryo.stringify(state));
console.log(withCryo.activeUser === withCryo.users[1]);   // true

Infinity

Cryo successfully stringifies and parses Infinity, which JSON mangles into null.

var Cryo = require('../lib/cryo');

var number = Infinity;

var withJSON = JSON.parse(JSON.stringify(number));
console.log(withJSON === Infinity);                 // false

var withCryo = Cryo.parse(Cryo.stringify(number));
console.log(withCryo === Infinity);                 // true

Properties

Objects, Arrays, Dates, and Functions can all hold properties, but JSON will only stringify properties on Objects. Cryo will recover properties from all containers:

var Cryo = require('../lib/cryo');

function first() {}
first.second = new Date();
first.second.third = [1, 2, 3];
first.second.third.fourth = { name: 'Hunter' };

try {
  var withJSON = JSON.parse(JSON.stringify(first));
  console.log(withJSON.second.third.fourth.name === 'Hunter');
} catch(e) {
  console.log('error');                                       // error
}

var withCryo = Cryo.parse(Cryo.stringify(first));
console.log(withCryo.second.third.fourth.name === 'Hunter');  // true

Functions

Cryo will stringify functions, which JSON ignores.

Note: Usually, if you've come up with a solution that needs to serialize functions, a better solution exists that doesn't. However, sometimes this can be enormously useful. Cryo will make faithful hydrated functions and objects with properties that are functions.

var Cryo = require('../lib/cryo');

function fn() {
  console.log('Hello, world!');
}

try {
  var withJSON = JSON.parse(JSON.stringify(fn));
  withJSON();
} catch(e) {
  console.log('error');                             // error
}

var withCryo = Cryo.parse(Cryo.stringify(fn));
withCryo();                                         // Hello, world!

Custom Types

Cryo can allow you to stringify and parse custom types by using the optional callbacks argument. The prepare for stringify is called before each item is stringified, allowing you to alter an object just before it's serialized. The finalize callback for parse is called after each item is re-created, allowing you to alter an object just after it's de-serialized:

function Person() {}
var person = new Person();
person.friends = [new Person()];

var stringified = Cryo.stringify(person, { prepare: function(obj) {
  // store any object's constructor name under a variable called
  // __class__ which can later be be used to restore the object's
  // prototype.
  obj.__class__ = obj.constructor.name;
}});
var parsed = Cryo.parse(stringified, { finalize: function(obj) {
  // look for objects that define a __class__ and restore their
  // prototype by finding the class on the global window (you may need
  // to look elsewhere for the class).
  if (obj.__class__ && window[obj.__class__]) {
    obj.__proto__ = window[obj.__class__].prototype;
    delete obj.__class__;
  }
}});

parsed instanceof Person; // true
parsed.friends[0] instanceof Person; // true

Controlling Serialization

By default, all own properties of an object will be serialized. However, you can specify a custom isSerializable method as part of callbacks to pass to stringify to change this behavior. By default it is defined as such:

Cryo.stringify(data, { isSerializable: function(item, key) {
  return item.hasOwnProperty(key);
}});

DOM

JSON chokes when you try to stringify an object with a reference to a DOM node, giving Uncaught TypeError: Converting circular structure to JSON. Cryo will ignore DOM nodes so you can serialize such objects without hassle.

var obj = {
  button: document.getElementById('my-button');
  message: 'Hello'
};

try {
  var withJSON = JSON.parse(JSON.stringify(obj));
  console.log(withJSON.message === 'Hello');
} catch(e) {
  console.log('error');                             // error
}

var withCryo = Cryo.parse(Cryo.stringify(obj));
console.log(withCryo.message === 'Hello');          // true

Stringified Output

Cryo.stringify() returns valid JSON data with non-compatible types encoded as strings. Thus, anything you can do with JSON, you can do with Cryo.

Here is the stringified result from the hello, world example:

{
  "root":"_CRYO_REF_2",
  "references":[
    {
      "contents": {},
      "value":"_CRYO_DATE_1358245390835"
    },
    {
      "contents": {},
      "value":"_CRYO_FUNCTION_function () {\n    console.log(this.name + ' said hello in ' + this.created.getFullYear() + '!');\n  }"
    },
    {
      "contents":{
        "name":"Hunter",
        "created":"_CRYO_REF_0",
        "hello":"_CRYO_REF_1"
      },
      "value":"_CRYO_OBJECT_"
    }
  ]
}

Tests

Tests require node.js.

$ git clone git://github.com/hunterloftis/cryo.git
$ cd cryo
$ make setup
$ make test

More Repositories

1

pbr

a Physically Based Renderer (PBR) in Go
Go
1,136
star
2

newton

A playful, particle-based physics engine designed from the ground up for JavaScript.
JavaScript
917
star
3

throng

A simple worker-manager for clustered Node.js apps
JavaScript
856
star
4

playfuljs-demos

680
star
5

awaiting

The async/await utility for browsers and Node.js.
JavaScript
674
star
6

playfuljs

www.playfuljs.com
CSS
520
star
7

stoppable

Node's `server.close` the way you expected it to work.
JavaScript
403
star
8

jackrabbit

Simple AMQP / RabbitMQ job queues for node based on amqplib
JavaScript
293
star
9

oneweekend

Ray Tracing book series implemented in Golang, chapter-by-chapter
Go
153
star
10

notes

Notes about things.
147
star
11

knockout.namespaces

Namespaces plugin for KnockoutJS
JavaScript
57
star
12

pathtracer

A simple, naive path tracer in JavaScript
JavaScript
50
star
13

summarize

Node.js module to extract and summarize html content
JavaScript
41
star
14

pbr2

Go
38
star
15

component-test

An experiment to see what a simple node app would look like with "Components" from the @visionmedia blog
JavaScript
29
star
16

nodevember-14

JavaScript
28
star
17

heroku-node-errcodes

Examples of intentionally triggering various Heroku H* errors with Node.js
JavaScript
21
star
18

heroku-destroy-temp

Heroku CLI plugin to destroy temporary apps.
JavaScript
13
star
19

ludumstar

JavaScript
12
star
20

backbone.viewmodel

ViewModels with UI Bindings for Backbone (ala KnockoutJS, Flex, .NET, MVVM pattern)
JavaScript
7
star
21

dotfiles

personal dotfiles (steam deck dev machine)
Shell
7
star
22

itemize

A lazy, fluent web crawler for Node.js with a modern async/await API.
JavaScript
6
star
23

heroku-cli-node

A Heroku CLI plugin for Node.js app development
JavaScript
5
star
24

tetrinet

JavaScript
5
star
25

node-boilerplate

Structure for your node.js project
JavaScript
4
star
26

lanes

Simple, generic, sticky routing for clustered Node.js apps
JavaScript
4
star
27

server-jsx

Render react views on your node.js server
JavaScript
4
star
28

blit

2D Sprites that render to WebGL
JavaScript
4
star
29

cltjs-node

Node.js in 30 minutes
JavaScript
3
star
30

nko-quickstart

"Hello, world" with deployment instructions.
JavaScript
3
star
31

mongoose-file

Attach a file to a mongoose Schema
JavaScript
3
star
32

docker-plugin

JavaScript
3
star
33

babylonterrain

Testing babylonjs with terrain generation
JavaScript
3
star
34

music-city-game

Workshop for Music City Code 2019
JavaScript
3
star
35

storj

An attempt at the interesting Storj challenge
Go
2
star
36

blitzkrieg

Middleware to provide an authorized domain for blitz.io load testing in Node.js.
JavaScript
2
star
37

space-snake

Ludum Dare 38: A Small World
JavaScript
2
star
38

node-production

Running Node all the way from development to production on Heroku.
JavaScript
2
star
39

okay.js

A knockout knockoff
JavaScript
2
star
40

get-large-json

Test for getting large in-memory json objects
JavaScript
2
star
41

hunterloftis.com

Personal homepage
JavaScript
2
star
42

heroku-buildpack-sfdx

Shell
1
star
43

heroku-buildpack-empty

Quick example of a no-op buildpack
Shell
1
star
44

simplenode

A simple boilerplate for single-page node projects deployable on Ubuntu VPS.
JavaScript
1
star
45

heroku-node-template

Easily template new node projects with best practices for Heroku.
JavaScript
1
star
46

ld39

JavaScript
1
star
47

backpacksncats

Our blog
CSS
1
star
48

Quarry

JavaScript
1
star
49

node-dev-env

Dockerfile
1
star
50

arduino_wiimotionplus

Reading wii motionplus data with the arduino
C++
1
star
51

handoff

JavaScript
1
star
52

socket.io-chat-distributed

Socket.io chat scaled across multiple nodes, backed by redis
HTML
1
star
53

df-micro-web

JavaScript
1
star
54

deno-pointers

Testing out Deno with a little state
TypeScript
1
star
55

game-workshop

JavaScript
1
star
56

dogfight

JavaScript
1
star
57

mongoose-timestamps

A simple mongoose plugin for storing last created and last modified information
1
star
58

loopbusy

Node.js middleware to send 503s and keep your server alive when it's too busy to queue more requests.
JavaScript
1
star
59

processing_wiimotionplus

Renders position data sent over serial by the WMP Arduino code
Java
1
star