Code Monkey home page Code Monkey logo

storage-mixin's Introduction

storage-mixin

Persist Ampersand.js models and collections to various storage backends.

Installation

npm install --save storage-mixin

Usage

Use this mixin with any existing model and collection to easily persist them to a number of different storage backends. The model needs

  • the mixin
  • idAttribute value (Ampersand's default is id)
  • namespace value
  • storage key to pass options to the mixin (see Options)
var Model = require('ampersand-model');
var storageMixin = require('storage-mixin');

var Spaceship = Model.extend(storageMixin, {
  idAttribute: 'name',
  namespace: 'StorableModels',
  storage: {
    backend: 'disk',
    basepath: '/tmp'
  },
  props: {
    // your property definitions, will be persisted to storage
    name: ['string', false, ''],
    warpDrive: ['boolean', false, false]
  },
  session: {
    // your session properties, will _not_ be persisted to storage
  }
  // ... other model methods
});

Now you can call call the .save() method on instantiated models.

var model = new StorableModel();
model.save({name: 'Apollo 13', warpDrive: false});

Options

Options are passed to the storage mixin via the storage key. If you only want to choose which backend to use and don't need to pass any further options along, the storage key can be a string with the backend name.

var StorableModel = Model.extend(storageMixin, {
  storage: 'disk',   // use disk storage with default basepath `.`
  props: {
    // ...
  }
});

If you want to further customize the storage mixin, use an object and provide additional options. The backend value is required, all other values are optional and backend-dependent.

var StorableModel = Model.extend(storageMixin, {
  storage: {    // use disk storage with a custom basepath
    backend: 'disk',   
    basepath: '/tmp/myapp/storage'    
  props: {
    // ...
  }
});

Backends

The following backends are currently supported: local, disk, remote, null, secure, splice.

The default is local.

local Backend

Stores objects in local storage of the browser. Only works in a browser context. The backend uses the localforage npm module under the hood and supports IndexedDB, WebSQL and localStorage drivers. A separate instance of the store is created for each namespace.

Additional Options

driver : The driver to be passed on to localforage. One of INDEXEDDB, LOCALSTORAGE or WEBSQL. The default is INDEXEDDB.

appName : The name of the IndexedDB database (not the data store inside the database, which is the model's namespace). Most users will never see this, but it's best practice to use your application name here. Default is storage-mixin.

disk Backend

Stores objects as .json files on disk. Only works in a node.js / server context, or in Electron renderer process where remote module is available to get access to the fs module.

The file location is <basepath>/<namespace>/<id>.json. <basepath> is provided as option. The <namespace> is set on the model directly, and the <id> is the property of the model specified by idAttribute. The first example on this page would be stored as:

/tmp/StorableModels/Apollo 13.json
Additional Options

basepath : The base path for file storage. The default is ..

remote Backend

This is a wrapper for ampersand-sync, that stores and retrieves models to/from a remote server via asynchronous ajax / xhr requests. Pass in the url value as an option or set it directly on the model.

Additional Options

url : The url to fetch the model/collection, see ampersand-model#url.

null Backend

This backend exists mostly for debugging and testing purposes. It does not store anything but will return with successful callbacks on all method calls. For reads, it will return an empty object {} for models, or an empty array [] for collections.

secure Backend

The secure backend wraps the keytar module to persist data into a secure keychain, keyring or password manager (works for OS X, Linux, Windows). There are some limitations though as the interface does not allow to list all keys in a given namespace. Therefore, to fetch a collection, it has to be pre-populated with models containing the ids.

// this won't work !
var collection = new StorableCollection();
collection.fetch();

// do this instead
var collection = new StorableCollection([
  {id: 'some id'}, {id: 'some other id'}, {id: 'third id'}
], {parse: true});
collection.fetch();

The static .clear() method that other storage backends possess is also a no-op in the secure backend for the same reason. Keys have to be deleted manually.

Additional Options

appName : Entries in the keychain have a key of <appName>/<namespace>. As this is visible to the user, you should use your application name here. Default is storage-mixin.

splice Backend

This is a hybrid backend that consists of a local and secure backend under the hood. It also receives a secureCondition function as an optional argument that takes a value and key and returns whether or not this key should be stored in the secure or local backend. On retrieval, it merges the two results from both backends together to form a complete object again.

This is particularly useful to store user-related data where some fields contain sensitive information and should not be stored as clear text, e.g. passwords.

Additional Options

appName : Passed to both the local and secure backends, that acts as a global scope (e.g. database name in IndexedDB, prefix in keychain keys). Use your application name here. Default is storage-mixin.

secureCondition : Function that decides which keys/values of a model should be stored in the secure backend vs. the local backend. The function takes a value and key and must return true for the keys that need to be stored securely. Default is:

function(val, key) {
  return key.match(/password/i);
}
Example
var Model = require('ampersand-model');
var storageMixin = require('storage-mixin');

var User = Model.extend(storageMixin, {
  idAttribute: 'id',
  namespace: 'Users',
  storage: {
    backend: 'splice',
    appName: 'My Cool App',
    secureCondition: function(val, key) {
      return key.match(/password/i);
    }
  },
  props: {
    id: 'string',            // stored in `local`
    name: 'string',          // stored in `local`
    email: 'string',         // stored in `local`
    lastLogin: 'date',       // stored in `local`
    password: 'string',      // stored in `secure`
    oldPassword: 'string'    // stored in `secure`
  }
});

License

Apache 2.0

storage-mixin's People

Contributors

dependabot-preview[bot] avatar durran avatar imlucas avatar mcasimir avatar pzrq avatar rueckstiess avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar

Forkers

isabella232

storage-mixin's Issues

Don't store empty objects {}

If the object to store is empty, we don't have to store at all. If the key does not exist, that's exactly what is returned anyway.

This would reduce the number of entries in the keychain with splice backend, as currently even if there's nothing to split out, an empty document is still stored in the keychain.

make module work in non-browser contexts

Running this in a non-browser context currently fails due to localForage throwing an error ReferenceError: self is not defined.

The module should be requirable in non-browser contexts and ideally support a subset of storage backends.

For IndexedDB in particular, perhaps a drop-in replacement of level could replace localForage and give access to IndexedDB-stored data, as Chrome uses LevelDB under the hood.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.