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:
$ npm install cryo
With Bower:
bower install cryo
Add the latest minified build to your project as a script:
<scripttype='text/javascript' src='cryo-0.0.4.js'></script>Cryo has a very simple API that mimicks JSON:
Cryo.stringify(item)Cryo.parse(string)
varCryo=require('cryo');varobj={name: 'Hunter',created: newDate(),hello: function(){console.log(this.name+' said hello in '+this.created.getFullYear()+'!');}};varfrozen=Cryo.stringify(obj);varhydrated=Cryo.parse(frozen);hydrated.hello();// Hunter said hello in 2013!Cryo takes a verbatim snapshot of all your properties, including those that are undefined - which JSON ignores.
varCryo=require('../lib/cryo');varobj={defaultValue: undefined};varwithJSON=JSON.parse(JSON.stringify(obj));console.log(withJSON.hasOwnProperty('defaultValue'));// falsevarwithCryo=Cryo.parse(Cryo.stringify(obj));console.log(withCryo.hasOwnProperty('defaultValue'));// trueCryo successfully works with Date objects, which JSON.stringify() mangles into strings.
varCryo=require('../lib/cryo');varnow=newDate();varwithJSON=JSON.parse(JSON.stringify(now));console.log(withJSONinstanceofDate);// falsevarwithCryo=Cryo.parse(Cryo.stringify(now));console.log(withCryoinstanceofDate);// trueJSON.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:
varCryo=require('../lib/cryo');varuserList=[{name: 'Abe'},{name: 'Bob'},{name: 'Carl'}];varstate={users: userList,activeUser: userList[1]};varwithJSON=JSON.parse(JSON.stringify(state));console.log(withJSON.activeUser===withJSON.users[1]);// falsevarwithCryo=Cryo.parse(Cryo.stringify(state));console.log(withCryo.activeUser===withCryo.users[1]);// trueCryo successfully stringifies and parses Infinity, which JSON mangles into null.
varCryo=require('../lib/cryo');varnumber=Infinity;varwithJSON=JSON.parse(JSON.stringify(number));console.log(withJSON===Infinity);// falsevarwithCryo=Cryo.parse(Cryo.stringify(number));console.log(withCryo===Infinity);// trueObjects, Arrays, Dates, and Functions can all hold properties, but JSON will only stringify properties on Objects. Cryo will recover properties from all containers:
varCryo=require('../lib/cryo');functionfirst(){}first.second=newDate();first.second.third=[1,2,3];first.second.third.fourth={name: 'Hunter'};try{varwithJSON=JSON.parse(JSON.stringify(first));console.log(withJSON.second.third.fourth.name==='Hunter');}catch(e){console.log('error');// error}varwithCryo=Cryo.parse(Cryo.stringify(first));console.log(withCryo.second.third.fourth.name==='Hunter');// trueCryo 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.
varCryo=require('../lib/cryo');functionfn(){console.log('Hello, world!');}try{varwithJSON=JSON.parse(JSON.stringify(fn));withJSON();}catch(e){console.log('error');// error}varwithCryo=Cryo.parse(Cryo.stringify(fn));withCryo();// Hello, world!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.
varobj={button: document.getElementById('my-button');
message: 'Hello'};try{varwithJSON=JSON.parse(JSON.stringify(obj));console.log(withJSON.message==='Hello');}catch(e){console.log('error');// error}varwithCryo=Cryo.parse(Cryo.stringify(obj));console.log(withCryo.message==='Hello');// trueCryo.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 require node.js.
$ git clone git://github.com/hunterloftis/cryo.git
$ cd cryo
$ make setup
$ make test