npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

rhaboo

v3.2.2

Published

Persistent JS Objects

Downloads

14

Readme

Rhaboo

Website at http://rhaboo.org

Please star the repo if you use it - Thx.

Thanks to brasofilo for the logo.

What is it?

This library gives a JS programmer persistence whilst staying close to the JS object model. In other words, it makes ordinary JS objects (including deeply nested ones) persist as if by magic. The underlying storage is either localStorage or sessionStorage, as you choose.

The usual approach to this problem is to stringify and parse the entire object, but that gives lousy performance on large datasets. For instance, if you had an array of 999 diary entries and the user added a 1000th, then the entire history would have to be parsed and re-stringified. Rhaboo is more cunning than that.

Another problem with stringify/parse is that they innacurately recreate objects, especially arrays. For instance, properties of arrays with non-numeric names are ignored and all sparse positions are filled with null. This library recreates objects and arrays more precisely.

It's highly portable because it only relies on HTML5's localStorage. So you can use it on these browsers: http://caniuse.com/#feat=namevalue-storage

Persistence code is deferred with setTimeout so the user interface remains snappy even when a lot of data changes are occuring.

Quick Installation

  1. Download rhaboo.min.js and include it with a script tag.

  2. Install with

   npm install rhaboo

and point your browser at:

   file://<wherever you npm-installed it>/node_modules/rhaboo/generate-tests/generated-pages/page.0.html

to check that it installed ok. Include the library in your HTML file:

   <script src="node_modules/rhaboo/rhaboo.min.js"></script>

Installation for building or generating tests

Clone the rhaboo repo and then in its directory do:

   npm install grunt grunt-contrib-uglify grunt-browserify seedrandom ajon parunpar
   grunt    # be patient with this
   firefox generate-tests/generated-pages/page.0.html

(If grunt just exits immediately without output, you may have mistakenly installed a debian package called node. You need to uninstall that and do this instead. If you installed grunt while that package was installed, you can hack the #! of which grunt to say nodejs instead of node.)

Usage

Make a persistent object like this:

   var mystore = Rhaboo.persistent("Some unique name"); //localStorage
   //or
   var mystore = Rhaboo.perishable("Some unique name"); //sessionStorage

(Honestly, 'new' is not desired here.)

The library immediately attempts to restore this object from localStorage. If it remains empty then this must be the first time your program was run on this machine, so you detect that fact and populate your store. On subsequent runs the contents of mystore will be as you left them.

You can read from it exactly like any other object:

   console.log(mystore.foo); 

but to modify it, instead of writing:

   mystore.foo = 123;  //Wrong!!!

or equivalently:

   mystore["foo"] = 123;  //Wrong!!!

you should write:

   mystore.write("foo", 123);  //Right!!!

It's an ugly substitution but at least it's one-to-one so it doesn't affect your overall design.

You use that same write function for inserting new properties and modifying existing ones.

Deletion of properties calls for another substitution. Instead of:

   delete mystore.foo;  //Wrong!!!

you should write:

   mystore.erase("foo");  //Right!!!

(Contrary to popular belief, setting a property to undefined is not the same as deleting it.) For arrays, splice should be used.

You can also pass a complex object to write:

   mystore.write("foo", {   
     pinky: [],   
     perky: true,   
     porky: [   
       "The",   
       3,   
       "Musketeers",   
       new Date(),
       {}   
     ]   
   } );

and apply write to its nested objects:

   mystore.foo.porky.write(1, 4);

All the standard array modifying functions work persistently:

   mystore.foo.pinky.push("bar");  
   mystore.foo.pinky.reverse();

There's no function to delete everything in a persistent, but that could be made simple by keeping everything in a single property of the persistent:

   mystore.write('killable', { 
      game: 'tiddlywinks', 
      player: { name: 'zorro', gender: 'm', hiscore: 10 
   } );
   mystore.erase('killable');

You may have multiple root persistents, i.e. calls to Rhaboo.persistent/perishable - there's no performance penalty for this. You may have multiple persistent references to the same persistent object or sub-object within a given persistent or perishable, but please don't put references to perishable objects inside persistent ones or vice versa (there's no check for this - it will just go bonkers.) You may put non-numerically named properties into arrays or set object or array entries to null, undefined or non-existent. The persisted objects will behave just like those im memory. Regex- and function-valued properties are not supported.

Rhaboo adds a property called _rhaboo to each object it makes persistent, but this won't show up in standard iterations of the form:

   for ( var key in object ) {
      if ( object.hasOwnProperty(key) ) {
         var val = object[key];
         ...
      }
   }

because Object.prototype.hasOwnProperty has been replaced with one that returns false for _rhaboo.

Browserification

If you use node.js modules or browserify, you can treat src/arr.js as the module which delivers all of rhaboo. In src/unbrowserify.js (which is what browserify renders into ./rhaboo.max.js) you can see how the module.exports from arr.js is assigned to something called Rhaboo at global scope. This is to hand rhaboo's facilities to people who can't write "require" cos they're in a browser and don't use browserify.

Variants

'Sand' and 'rocks' are two different strategies for optimising the internal storage format. Both are subject to ongoing experiments. You can include e.g. 'rhaboo.rocks.min.js' if you have a special preference, but for the time being, 'rhaboo.min.js' provides something that works.