Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Initial persistence API draft

Persistence API - draft 0.1

This is a initial proposal on having a very simple persistence layer

Requirements

  • Persist data on local storage as a type of buffer
  • Enable data to be created/saved/persisted/queryied/removed to/from the server side

References

Features

Store - aerogear.store

An object representing the interface to the storage mechanism. Data is buffered locally (IndexedDB with fallback to LocalStorage), then asynchronously stored to the server.

Create - aerogear.store( [String storeName, String type] )

Instantiate aerogear.store. Providing a storeName prevents naming collisions on local storage and situations when the applications share the same storage. The default key is a GUID which can be retrieved via .storeName. A type can be provided as the initial type of store to try. Options for type include IndexedDB, local and session with each falling back to the next in the list. Default type is IndexedDB.

// Create an instance of aerogear.store
var myStore = aerogear.store( "myStoreName", "IndexedDB" );
myStore.key // Retrieve the storage GUID

Store data - aerogear.store.save( String key, mixed value [, hash options] )

Save data to the local store. If this is new data, the data is created on the server, otherwise, the data on the server is updated. If a time to live isn't specified, the local data is assumed valid. If time to live is 0, the data is always checked against the server version before returning.

// Store a string
myStore.save( "key1", "value1" );

// Store an object
myStore.save( "key2", { val2: "value2" } );

// Pass a set of key/value pairs representing options like callbacks and time to live
myStore.save( "key3", { val3: "value3" }, {
    ajax: {
        success: function( data, textStatus, jqXHR ) {
            console.log( "Success" );
        },
        error: function( jqXHR, textStatus, errorThrown ) {
            console.log( "Error" );
        },
    }
    expire: 60000
});
Save Options

The following items can be passed to the save method as part of a hash of key/value pairs:

  • ajax - (default: {}) A hash of key/value pairs which can include any option accepeted by the jQuery.ajax method
  • expire - (default: false) An integer value stating the amount of time, in milliseconds, to assume the data stored locally is valid. After that time, the next read will pull from the server before serving up to the client. By default, this value is false meaning that the data never expires and is always valid and to update a call to sync must be made. A value of 0, in effect, disables the local store by requiring a call to the server before each read. The data is still kept updated with each pull in case this value is updated.

Retrieve data - aerogear.store.read

Retrieve data from the local store.

// Get a particular item from the store
var val1 = myStore.read( "key1" );

// Get a set of key/value pairs of all data in the store
var allData = myStore.read();

Delete data

Remove data from the local store and asynchronously remove that data from the server.

// Remove a particular item from the store
myStore.delete( "key1" );

// Delete all data from the store
myStore.delete();

Sync data

We assume the data on the server is always correct unless specified otherwise.

// Update the data in the local store from the data on the server
myStore.sync();

// Update the data on the server with the data on the client
myStore.sync( true );

Open Questions

  1. Lawchair throws exceptions when IndexedDB is not available. Must check https://github.com/brianleroux/lawnchair/blob/master/src/adapters/indexed-db.js#L94
  • IndexedDB is not a concern for while
  • Since we have fallbacks that we know will work, i am not concerned with this. We do need to plan for handling question #3 though
  1. Server side REST interfaces
  • Bruno, can you take a stab at specing this out similar to what i have done for the client side?
  1. What will happen when the application reach the quota limit? If the application handle QuotaExceededError. Which is the best approach catch or throw it? http://dev.w3.org/html5/webstorage/#disk-space (I'm not 100% sure if the browsers respect this specification - @abstractj)

Radar

  • sessionStorage - we could have tons of data that doesn't need to be stored permanently like login/logout. (Maybe we can postpone it to draft 0.2 or not)

  • JSONP concerns?

  • Should be addressed by jQuery.ajax but keep it in mind

  • Security concerns

  • I think this should be addressed in another API. I'm thinking something like aerogear.gate or aerogear.sentry (i really like that one :)) which would have options for things like basic auth, openID, etc. but then the create API for store would be modified to provide credentials

  • Secure storage

  • I would like to create an alternative to users like aerogear.secure.store("myStorage") or aerogear.safeStorage"). That allows to user to save and retrieve encrypted data as alternative. (The key won't be stored at the local storage - @abstractj)

  • Authentication for security spec

  • I would like to evaluate it http://xauth.org/spec/ @abstractj

  • Useful resource to be checked http://en.wikipedia.org/wiki/Secure_Remote_Password_protocol

  • JavaScript implementation on it https://github.com/clipperz/javascript-crypto-library

  • XSS attacks can bypass the same origin policy by tricking a site into delivering malicious code. This is more tricky to do and low priority, but I would like to let on Radar (@abstractj)

Note: This is probably a topic to think and write in another API

  • Persistent storage let hostile sites read the data from other domains (See the section 7.3 Implementation risks - http://www.w3.org/TR/2009/WD-webstorage-20091222/). Is more tricky to hack local storage than expected we must check it in the future (@abstractj).

Draft 0.2

  • How to require modules? -> AMD usage (http://requirejs.org/docs/whyamd.html)
  • If we modularize, need to think on a larger scale. I'm thinking that we would have an aerogear core that would then include the other pieces (store, security?, ...). Other things to think on with this is a build process both for us to test, release, create customized downloads, and also for the user to custom build themselves.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment