Compare commits
	
		
			19 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 2e4745b189 | |||
| 21098984f1 | |||
| b2fdf0aba2 | |||
| 7b459f1f87 | |||
| 3a2ada1ce0 | |||
| a881915cfe | |||
| 5e9e9d8a41 | |||
| 780b7583a1 | |||
| c4efbba4da | |||
| 6f7b83ea15 | |||
| 1a9a10c24e | |||
| 9cdcdf98d9 | |||
| a430f94fce | |||
| 699f673b79 | |||
| 4e61155c7e | |||
| a704e4ad02 | |||
| 16fb1c730e | |||
| 6dba7f09f8 | |||
| dfe7ca8752 | 
							
								
								
									
										99
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										99
									
								
								README.md
									
									
									
									
									
								
							@ -1,61 +1,71 @@
 | 
			
		||||
jsonStorage
 | 
			
		||||
JsonStorage
 | 
			
		||||
====
 | 
			
		||||
 | 
			
		||||
A light abstraction for DOMStorage (such as localStorage).
 | 
			
		||||
A light, sensible abstraction for DOMStorage (such as localStorage).
 | 
			
		||||
 | 
			
		||||
Installation
 | 
			
		||||
===
 | 
			
		||||
 | 
			
		||||
Ender.JS (Browser)
 | 
			
		||||
Bower (Browser)
 | 
			
		||||
 | 
			
		||||
    ender build json-storage
 | 
			
		||||
```bash
 | 
			
		||||
bower install json-storage
 | 
			
		||||
# or
 | 
			
		||||
wget https://git.coolaj86.com/coolaj86/json-storage.js/raw/branch/master/json-storage.js
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Node.JS (Server)
 | 
			
		||||
 | 
			
		||||
    npm install localStorage json-storage
 | 
			
		||||
```bash
 | 
			
		||||
npm install -S localStorage json-storage
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Usage
 | 
			
		||||
===
 | 
			
		||||
 | 
			
		||||
Made fo for Node.JS and Ender.JS (browser-side).
 | 
			
		||||
Made for Node.js and Bower (browser-side).
 | 
			
		||||
 | 
			
		||||
    var localStorage = require('localStorage')
 | 
			
		||||
      , JsonStorage = require('json-storage')
 | 
			
		||||
      , store = JsonStorage.create(localStorage, 'my-widget-namespace')
 | 
			
		||||
```javascript
 | 
			
		||||
var localStorage = require('localStorage')
 | 
			
		||||
  , JsonStorage = require('json-storage').JsonStorage
 | 
			
		||||
  , store = JsonStorage.create(localStorage, 'my-widget-namespace', { stringify: true })
 | 
			
		||||
  , myValue = {
 | 
			
		||||
        foo: "bar"
 | 
			
		||||
      , baz: "quux"
 | 
			
		||||
    }
 | 
			
		||||
  ;
 | 
			
		||||
 | 
			
		||||
    store.set('myKey', myValue); 
 | 
			
		||||
    myValue = store.get('myKey');
 | 
			
		||||
store.set('myKey', myValue);
 | 
			
		||||
myValue = store.get('myKey');
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
NOTE: When using with Node and the `localStorage` module,
 | 
			
		||||
you may wish to pass the `{ stringify: false }` option to prevent double stringification.
 | 
			
		||||
 | 
			
		||||
API
 | 
			
		||||
===
 | 
			
		||||
 | 
			
		||||
  * `create(DOMStorage, namespace)`
 | 
			
		||||
    * `DOMStorage` should be globalStorage, sessionStorage, or localStorage
 | 
			
		||||
    * `namespace` is optional string which allows multiple non-conflicting storage containers
 | 
			
		||||
  * `get(key)`
 | 
			
		||||
  * `set(key, value)`
 | 
			
		||||
  * `remove(key)`
 | 
			
		||||
  * `clear()`
 | 
			
		||||
  * `keys()`
 | 
			
		||||
  * `size()`
 | 
			
		||||
  * `toJSON()`
 | 
			
		||||
  * `JsonStorage.create(DOMStorage, namespace, opts)`
 | 
			
		||||
    * `DOMStorage` should be globalStorage, sessionStorage, or localStorage. Defaults to window.localStorage if set to `null`.
 | 
			
		||||
    * `namespace` is optional string which allows multiple non-conflicting storage containers. For example you could pass two widgets different storage containers and not worry about naming conflicts:
 | 
			
		||||
      * `Gizmos.create(JsonStorage.create(null, 'my-gizmos'))`
 | 
			
		||||
      * `Gadgets.create(JsonStorage.create(null, 'my-gadgets'))`
 | 
			
		||||
      * Namespacing can be turned off by explicitly setting `false`
 | 
			
		||||
        * `Gadgets.create(JsonStorage.create(null, false))`
 | 
			
		||||
    * `opts`
 | 
			
		||||
      * `stringify` set to `false` in `node` to avoid double stringifying
 | 
			
		||||
  * `store.get(key)`
 | 
			
		||||
  * `store.set(key, value)`
 | 
			
		||||
  * `store.remove(key)`
 | 
			
		||||
  * `store.clear()`
 | 
			
		||||
  * `store.keys()`
 | 
			
		||||
  * `store.size()`
 | 
			
		||||
  * `store.toJSON()`
 | 
			
		||||
  * `JSON.stringify(store)`
 | 
			
		||||
 | 
			
		||||
Upgrading from localStorage and 1.0.x to 1.1.x
 | 
			
		||||
===
 | 
			
		||||
**NOTE**: You cannot omit optional parameters. Use `null` if you want accepts the defaults for some things and provide a values for others. For example: `JsonStorage.create(null, null, { stringify: false })`
 | 
			
		||||
 | 
			
		||||
1.1.x automatically attempts to upgrade your DOMStorage to use namespaces in backwards-compatible way.
 | 
			
		||||
 | 
			
		||||
However, you can prevent this behaviour:
 | 
			
		||||
 | 
			
		||||
    localStorage.getItem('_json-storage-namespaced_', true);
 | 
			
		||||
 | 
			
		||||
null vs undefined in JSON
 | 
			
		||||
JSON / DOMStorage Conversion Gotchas
 | 
			
		||||
===
 | 
			
		||||
 | 
			
		||||
These notes do not reflect a bugs or defects in this library,
 | 
			
		||||
@ -65,6 +75,8 @@ they're simply to inform you of a few 'gotchas' inherent in JSON / DOMStorage co
 | 
			
		||||
If they do, you're probably doing something wrong in the first place.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### `undefined` vs `null`
 | 
			
		||||
 | 
			
		||||
It is not valid to set `undefined` in JSON. So setting a key to `undefined` will remove it from the store.
 | 
			
		||||
 | 
			
		||||
This means that `store.set('x')` is the same as `store.remove('x')`.
 | 
			
		||||
@ -74,13 +86,34 @@ To save `undefined`, use `null` instead.
 | 
			
		||||
 | 
			
		||||
Note that both values that exist as `null` and values that don't exist at all will return `null`.
 | 
			
		||||
 | 
			
		||||
    store.set('existing-key', null);
 | 
			
		||||
    null === store.get('existing-key');
 | 
			
		||||
    null === store.get('non-existant-key');
 | 
			
		||||
```javascript
 | 
			
		||||
store.set('existing-key', null);
 | 
			
		||||
null === store.get('existing-key');
 | 
			
		||||
null === store.get('non-existant-key');
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### `null` vs `"null"`
 | 
			
		||||
 | 
			
		||||
The special case of `null` as `"null"`, aka `"\"null\""`:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
typeof null        // object
 | 
			
		||||
typeof "null"      // string
 | 
			
		||||
typeof "\"null\""  // string
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
`null`, and `"null"` both parse as `null` the "object", instead of one being the string (which would be `"\"null\""`).
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
JSON.parse(null)       // null (object)
 | 
			
		||||
JSON.parse("null")     // null (object)
 | 
			
		||||
JSON.parse("\"null\"") // 'null' (string)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Objects containing `null`, however, parse as expected `{ "foo": null, "bar": "null" }` will parse as `foo` being `null` but `bar` being `"null"`, much unlike the value `"null"` being parsed on its own.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
JSON.parse('{ "foo": null }')    // { foo: null }
 | 
			
		||||
JSON.parse('{ "foo": "null" }')  // { foo: 'null' }
 | 
			
		||||
```
 | 
			
		||||
							
								
								
									
										28
									
								
								bower.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								bower.json
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,28 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "json-storage",
 | 
			
		||||
  "version": "2.0.1",
 | 
			
		||||
  "homepage": "https://github.com/coolaj86/json-storage-js",
 | 
			
		||||
  "authors": [
 | 
			
		||||
    "AJ ONeal <coolaj86@gmail.com>"
 | 
			
		||||
  ],
 | 
			
		||||
  "description": "A wrapper for storage engines which use the W3C Storage API",
 | 
			
		||||
  "main": "json-storage.js",
 | 
			
		||||
  "keywords": [
 | 
			
		||||
    "dom",
 | 
			
		||||
    "storage",
 | 
			
		||||
    "json",
 | 
			
		||||
    "w3c",
 | 
			
		||||
    "localStorage",
 | 
			
		||||
    "sessionStorage",
 | 
			
		||||
    "globalStorage",
 | 
			
		||||
    "Storage"
 | 
			
		||||
  ],
 | 
			
		||||
  "license": "Apache2",
 | 
			
		||||
  "ignore": [
 | 
			
		||||
    "**/.*",
 | 
			
		||||
    "node_modules",
 | 
			
		||||
    "bower_components",
 | 
			
		||||
    "test",
 | 
			
		||||
    "tests"
 | 
			
		||||
  ]
 | 
			
		||||
}
 | 
			
		||||
@ -1,282 +0,0 @@
 | 
			
		||||
(function () {
 | 
			
		||||
  "use strict";
 | 
			
		||||
 | 
			
		||||
  var localStorage = require('localStorage')
 | 
			
		||||
    , JsonStorage = require('json-storage')
 | 
			
		||||
    , jsonStorage = JsonStorage(localStorage)
 | 
			
		||||
    , db = jsonStorage
 | 
			
		||||
    , uuidgen = require('node-uuid')
 | 
			
		||||
    , schemamap = {}
 | 
			
		||||
    ;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  function create(schema) {
 | 
			
		||||
    var models = {};
 | 
			
		||||
 | 
			
		||||
    function createModel(lsmodel, prefix, submodels, uuid) {
 | 
			
		||||
      //
 | 
			
		||||
      // New Model
 | 
			
		||||
      //
 | 
			
		||||
      function LModel(obj) {
 | 
			
		||||
        var lmodel = this;
 | 
			
		||||
 | 
			
		||||
        // Add any already-appended submodels
 | 
			
		||||
        // TODO DRY this up
 | 
			
		||||
        submodels.forEach(function (subname) {
 | 
			
		||||
          var sub_ids = '_' + subname + '_ids'
 | 
			
		||||
            , subs = obj[subname]
 | 
			
		||||
            , suuid = schemamap[subname].uuid || 'uuid';
 | 
			
		||||
 | 
			
		||||
          // Just in case the object is already created
 | 
			
		||||
          if ('function' === typeof obj.__lookupGetter__(subname)) {
 | 
			
		||||
            return;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          if (false === Array.isArray(subs)) {
 | 
			
		||||
            return;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          obj[sub_ids] = [];
 | 
			
		||||
          lmodel[sub_ids] = obj[sub_ids];
 | 
			
		||||
 | 
			
		||||
          subs.forEach(function (sub) {
 | 
			
		||||
            if (!sub[suuid]) {
 | 
			
		||||
              sub[suuid] = uuidgen();
 | 
			
		||||
            }
 | 
			
		||||
            models[subname].set(sub[suuid], sub);
 | 
			
		||||
            lmodel[sub_ids].push(sub[suuid]);
 | 
			
		||||
          });
 | 
			
		||||
 | 
			
		||||
          obj[subname] = undefined;
 | 
			
		||||
          delete obj[subname];
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Copy object to this
 | 
			
		||||
        Object.keys(obj).forEach(function (k) {
 | 
			
		||||
          lmodel[k] = obj[k];
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // create uuid if it has none
 | 
			
		||||
        if (undefined === obj[uuid]) {
 | 
			
		||||
          obj[uuid] = uuidgen();
 | 
			
		||||
          lmodel[uuid] = obj[uuid];
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // A simple save method
 | 
			
		||||
      LModel.prototype.save = function () {
 | 
			
		||||
        lsmodel.set(this[uuid], this);
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      // getters for submodels
 | 
			
		||||
      submodels.forEach(function (subname) {
 | 
			
		||||
        var sub_ids = '_' + subname + '_ids';
 | 
			
		||||
 | 
			
		||||
        LModel.prototype.__defineGetter__(subname, function () {
 | 
			
		||||
          // not all submodels exist at "compile-time"
 | 
			
		||||
          var submodel = models[subname]
 | 
			
		||||
            , lmodel = this
 | 
			
		||||
            , subs
 | 
			
		||||
            , suuid = schemamap[subname].uuid || 'uuid';
 | 
			
		||||
 | 
			
		||||
          lmodel[sub_ids] = lmodel[sub_ids] || [];
 | 
			
		||||
 | 
			
		||||
          subs = submodel.some(lmodel[sub_ids]);
 | 
			
		||||
 | 
			
		||||
          // modify collection, but leave as array with forEach
 | 
			
		||||
          // XXX maybe create prototype with forEach
 | 
			
		||||
          subs.add = function (obj) {
 | 
			
		||||
            subs.push(obj);
 | 
			
		||||
            if (undefined === obj[suuid]) {
 | 
			
		||||
              submodel.add(obj);
 | 
			
		||||
            } else {
 | 
			
		||||
              submodel.set(obj[suuid], obj);
 | 
			
		||||
            }
 | 
			
		||||
            lmodel[sub_ids].push(obj[suuid]);
 | 
			
		||||
            lmodel.save();
 | 
			
		||||
          };
 | 
			
		||||
 | 
			
		||||
          return subs;
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      return LModel;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // A database abstraction
 | 
			
		||||
    function Model(model) {
 | 
			
		||||
      var lsmodel = this
 | 
			
		||||
        , prefix = model.name
 | 
			
		||||
        , submodels = model.has_many || []
 | 
			
		||||
        , uuid = model.uuid || 'uuid'
 | 
			
		||||
        , LModel = createModel(lsmodel, prefix, submodels, uuid);
 | 
			
		||||
 | 
			
		||||
      lsmodel.create = function (a, b, c) {
 | 
			
		||||
        return new LModel(a, b, c)
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      // clear
 | 
			
		||||
      lsmodel.clear = function () {
 | 
			
		||||
        return db.set(prefix + '-lsm', []);
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      // all keys
 | 
			
		||||
      lsmodel.keys = function () {
 | 
			
		||||
        return db.get(prefix + '-lsm');
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      // all items
 | 
			
		||||
      lsmodel.all = function () {
 | 
			
		||||
        var items = [];
 | 
			
		||||
        lsmodel.keys().forEach(function (uuid) {
 | 
			
		||||
          var item = lsmodel.get(uuid)
 | 
			
		||||
          // TODO this should be a useless check
 | 
			
		||||
          if (null === item) {
 | 
			
		||||
            lsmodel.remove(uuid);
 | 
			
		||||
            return;
 | 
			
		||||
          }
 | 
			
		||||
          items.push(item);
 | 
			
		||||
        });
 | 
			
		||||
        return items;
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      // TODO query accepts objects
 | 
			
		||||
      lsmodel.query = function (obj) {
 | 
			
		||||
        //
 | 
			
		||||
        return null;
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      // pass in your filter function
 | 
			
		||||
      lsmodel.filter = function (test) {
 | 
			
		||||
        var all = lsmodel.all(),
 | 
			
		||||
          results = [];
 | 
			
		||||
 | 
			
		||||
        all.forEach(function (one) {
 | 
			
		||||
          if (!test(one)) {
 | 
			
		||||
            return;
 | 
			
		||||
          }
 | 
			
		||||
          results.push(one);
 | 
			
		||||
        });
 | 
			
		||||
        return results;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      lsmodel.some = function (uuids) {
 | 
			
		||||
        var results = [];
 | 
			
		||||
 | 
			
		||||
        uuids.forEach(function (uuid) {
 | 
			
		||||
          var one = lsmodel.get(uuid);
 | 
			
		||||
          // push null elements to keep array indices
 | 
			
		||||
          results.push(one);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        return results;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // TODO query object
 | 
			
		||||
      lsmodel.get = function (uuid) {
 | 
			
		||||
        var item = db.get(uuid);
 | 
			
		||||
        if (null === item) {
 | 
			
		||||
          return null;
 | 
			
		||||
        }
 | 
			
		||||
        return new LModel(item);
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      lsmodel.set = function (uuid, val) {
 | 
			
		||||
        var keys;
 | 
			
		||||
 | 
			
		||||
        if (null === val || undefined === val) {
 | 
			
		||||
          return db.remove(uuid);
 | 
			
		||||
        }
 | 
			
		||||
        keys = db.get(prefix + '-lsm') || [];
 | 
			
		||||
 | 
			
		||||
        // add the key if it didn't exist
 | 
			
		||||
        if (-1 === keys.indexOf(uuid)) {
 | 
			
		||||
          keys.push(uuid);
 | 
			
		||||
          db.set(prefix + '-lsm', keys);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        submodels.forEach(function (mod) {
 | 
			
		||||
          var children = val[mod] || [];
 | 
			
		||||
 | 
			
		||||
          // TODO decouple or create new objects
 | 
			
		||||
          children.forEach(function (child) {
 | 
			
		||||
            var e;
 | 
			
		||||
            if (null === child) {
 | 
			
		||||
              return;
 | 
			
		||||
            }
 | 
			
		||||
            if ('string' === typeof child) {
 | 
			
		||||
              return;
 | 
			
		||||
            }
 | 
			
		||||
            if ('string' !== typeof child.uuid) {
 | 
			
		||||
              return;
 | 
			
		||||
            }
 | 
			
		||||
            // TODO other[mod].set(uuid, child);
 | 
			
		||||
          });
 | 
			
		||||
        });
 | 
			
		||||
        /*
 | 
			
		||||
        console.log('\n\n val');
 | 
			
		||||
        console.log(val);
 | 
			
		||||
        console.log('\n\n');
 | 
			
		||||
        */
 | 
			
		||||
        db.set(uuid, val)
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      // Remove an item from the table list and the db
 | 
			
		||||
      lsmodel.remove = function (uuid) {
 | 
			
		||||
        var keys = db.get(prefix + '-lsm')
 | 
			
		||||
          , i;
 | 
			
		||||
 | 
			
		||||
        keys.forEach(function (key, j) {
 | 
			
		||||
          if (key === uuid) {
 | 
			
		||||
            i = j;
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        if (undefined === i) {
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
        db.remove(uuid);
 | 
			
		||||
        keys.splice(i,1);
 | 
			
		||||
        db.set(prefix + '-lsm', keys);
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      // Remove all objects from the table list and db
 | 
			
		||||
      lsmodel.clear = function () {
 | 
			
		||||
        lsmodel.keys().forEach(function (uuid) {
 | 
			
		||||
          db.remove(uuid);
 | 
			
		||||
        });
 | 
			
		||||
        db.set(prefix + '-lsm', []);
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      lsmodel.add = function (val) {
 | 
			
		||||
        var obj = lsmodel.create(val);
 | 
			
		||||
        obj.save();
 | 
			
		||||
        return obj;
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // TODO compare versions of schema
 | 
			
		||||
    db.set('schema-lsm', schema);
 | 
			
		||||
 | 
			
		||||
    schema.forEach(function (scheme) {
 | 
			
		||||
      var table = scheme.name
 | 
			
		||||
        , x = db.get(table + '-lsm')
 | 
			
		||||
        ;
 | 
			
		||||
 | 
			
		||||
      // Pre-create the "models" tableshould always have 
 | 
			
		||||
      schemamap[scheme.name] = scheme;
 | 
			
		||||
      if (!Array.isArray(x)) {
 | 
			
		||||
        db.set(table + '-lsm', []);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      models[scheme.name] = new Model(scheme);
 | 
			
		||||
    });
 | 
			
		||||
    
 | 
			
		||||
    return models;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  module.exports = create;
 | 
			
		||||
}());
 | 
			
		||||
@ -1,20 +0,0 @@
 | 
			
		||||
{
 | 
			
		||||
  "author": "AJ ONeal <coolaj86@gmail.com> (http://coolaj86.info)",
 | 
			
		||||
  "name": "json-storage-model",
 | 
			
		||||
  "description": "An abstraction for models to be stored in json-storage",
 | 
			
		||||
  "keywords": ["ender", "model", "json-storage", "localStorage", "sessionStorage", "globalStorage", "Storage"],
 | 
			
		||||
  "version": "0.9.1",
 | 
			
		||||
  "repository": {
 | 
			
		||||
    "type": "git",
 | 
			
		||||
    "url": "git://github.com/coolaj86/json-storage-js.git"
 | 
			
		||||
  },
 | 
			
		||||
  "engines": {
 | 
			
		||||
    "node": ">= v0.2.0"
 | 
			
		||||
  },
 | 
			
		||||
  "main": "index",
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
      "json-storage": ">= 1.0.0"
 | 
			
		||||
    , "node-uuid": ">= 0.0.0"
 | 
			
		||||
  },
 | 
			
		||||
  "devDependencies": {}
 | 
			
		||||
}
 | 
			
		||||
@ -1,247 +0,0 @@
 | 
			
		||||
(function () {
 | 
			
		||||
  "use strict";
 | 
			
		||||
 | 
			
		||||
  var Model = require('json-storage-model')
 | 
			
		||||
    , assert = require('assert')
 | 
			
		||||
    , schema
 | 
			
		||||
    , lsmAll = {}
 | 
			
		||||
    , Returns
 | 
			
		||||
    , Batches;
 | 
			
		||||
 | 
			
		||||
  schema = [
 | 
			
		||||
    {
 | 
			
		||||
      name: "returns",
 | 
			
		||||
      has_many: ['batches'],
 | 
			
		||||
      uuid: "key"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      name: "batches",
 | 
			
		||||
      has_many: ['products']
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      name: "products"
 | 
			
		||||
    }
 | 
			
		||||
  ];
 | 
			
		||||
 | 
			
		||||
  function setup() {
 | 
			
		||||
    lsmAll = new Model(schema);
 | 
			
		||||
    //console.log(lsmAll);
 | 
			
		||||
    Returns = lsmAll.returns;
 | 
			
		||||
    Batches = lsmAll.batches;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function empty() {
 | 
			
		||||
    assert.deepEqual([], Returns.keys());
 | 
			
		||||
    assert.deepEqual([], Returns.all());
 | 
			
		||||
    assert.deepEqual([], Returns.some([]));
 | 
			
		||||
    assert.deepEqual([null], Returns.some(['x']));
 | 
			
		||||
    assert.deepEqual([null, null], Returns.some(['x','y']));
 | 
			
		||||
    assert.deepEqual(null, Returns.get('nada'));
 | 
			
		||||
    Returns.clear();
 | 
			
		||||
    assert.deepEqual([], Returns.keys());
 | 
			
		||||
    assert.deepEqual([], Returns.all());
 | 
			
		||||
    assert.deepEqual([], Returns.some([]));
 | 
			
		||||
    assert.deepEqual([null], Returns.some(['x']));
 | 
			
		||||
    assert.deepEqual([null, null], Returns.some(['x','y']));
 | 
			
		||||
    assert.deepEqual(null, Returns.get('nada'));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function errors() {
 | 
			
		||||
    var errcount = 0;
 | 
			
		||||
    // TODO make throw
 | 
			
		||||
    try {
 | 
			
		||||
      Returns.get();
 | 
			
		||||
    } catch(e) {
 | 
			
		||||
      errcount += 1;
 | 
			
		||||
    }
 | 
			
		||||
    //assert.equal(1, errcount);
 | 
			
		||||
    console.log('skipped `throw error on get(undefined)`');
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
      Returns.some();
 | 
			
		||||
    } catch(e) {
 | 
			
		||||
      errcount += 1;
 | 
			
		||||
    }
 | 
			
		||||
    assert.equal(1, errcount);
 | 
			
		||||
 | 
			
		||||
    Returns.some([]);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function createWithoutKey() {
 | 
			
		||||
    var ret = Returns.create({
 | 
			
		||||
        memo: "031811-IHC",
 | 
			
		||||
      })
 | 
			
		||||
      , ret2;
 | 
			
		||||
 | 
			
		||||
    assert.ok(ret.key);
 | 
			
		||||
    assert.equal("031811-IHC", ret.memo);
 | 
			
		||||
 | 
			
		||||
    ret2 = Returns.get(ret.key);
 | 
			
		||||
    assert.equal(null, ret2);
 | 
			
		||||
 | 
			
		||||
    ret.test1 = true;
 | 
			
		||||
    ret.save();
 | 
			
		||||
 | 
			
		||||
    ret2 = Returns.get(ret.key);
 | 
			
		||||
    assert.equal("031811-IHC", ret2.memo);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function createWithKey() {
 | 
			
		||||
    var ret = Returns.create({
 | 
			
		||||
        key: "ajs-test",
 | 
			
		||||
        memo: "031811-IHC",
 | 
			
		||||
      })
 | 
			
		||||
      , ret2;
 | 
			
		||||
 | 
			
		||||
    ret2 = Returns.get(ret.key);
 | 
			
		||||
    assert.ok(!ret2);
 | 
			
		||||
 | 
			
		||||
    assert.equal("ajs-test", ret.key);
 | 
			
		||||
    ret.save();
 | 
			
		||||
 | 
			
		||||
    ret2 = Returns.get(ret.key);
 | 
			
		||||
    assert.ok(ret2.memo);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function insertRemove() {
 | 
			
		||||
    var keys = []
 | 
			
		||||
      , all = []
 | 
			
		||||
      , ids = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
 | 
			
		||||
      , k;
 | 
			
		||||
 | 
			
		||||
    Returns.clear();
 | 
			
		||||
 | 
			
		||||
    // add
 | 
			
		||||
    function populate() {
 | 
			
		||||
      all = [];
 | 
			
		||||
      keys = [];
 | 
			
		||||
      ids.forEach(function (id, i) {
 | 
			
		||||
                            // this is private logic
 | 
			
		||||
        all.push({ key: id, _batches_ids: [] });
 | 
			
		||||
        keys.push(all[i].key);
 | 
			
		||||
        Returns.create(all[i]).save();
 | 
			
		||||
      });
 | 
			
		||||
      assert.deepEqual(all, Returns.all());
 | 
			
		||||
      assert.deepEqual(keys, Returns.keys());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Remove from first
 | 
			
		||||
    populate();
 | 
			
		||||
    for (k = 0; k < ids.length; k += 1) {
 | 
			
		||||
      Returns.remove(ids[k]);
 | 
			
		||||
    }
 | 
			
		||||
    assert.deepEqual([], Returns.all());
 | 
			
		||||
    assert.deepEqual([], Returns.keys());
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // Remove from last
 | 
			
		||||
    populate();
 | 
			
		||||
    for (k = ids.length - 1; k >= 0; k -= 1) {
 | 
			
		||||
      Returns.remove(ids[k]);
 | 
			
		||||
    }
 | 
			
		||||
    assert.deepEqual([], Returns.all());
 | 
			
		||||
    assert.deepEqual([], Returns.keys());
 | 
			
		||||
 | 
			
		||||
    // Remove from middle
 | 
			
		||||
    populate();
 | 
			
		||||
    ids.sort(function () { return 0.5 - Math.random(); });
 | 
			
		||||
    for (k = ids.length - 1; k >= 0; k -= 1) {
 | 
			
		||||
      Returns.remove(ids[k]);
 | 
			
		||||
    }
 | 
			
		||||
    assert.deepEqual([], Returns.all());
 | 
			
		||||
    assert.deepEqual([], Returns.keys());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // testing all, keys, some, filter
 | 
			
		||||
  function all() {
 | 
			
		||||
    var keys = [],
 | 
			
		||||
      all = [],
 | 
			
		||||
      some,
 | 
			
		||||
      ids = [];
 | 
			
		||||
 | 
			
		||||
    Returns.clear();
 | 
			
		||||
    assert.deepEqual(all, Returns.all());
 | 
			
		||||
    assert.deepEqual(keys, Returns.keys());
 | 
			
		||||
 | 
			
		||||
    all.push({ key: "one", memo: "3131-mtn", _batches_ids: [] });
 | 
			
		||||
    keys.push(all[0].key);
 | 
			
		||||
    Returns.create(all[0]).save();
 | 
			
		||||
    
 | 
			
		||||
    all.push({ key: "two", memo: "3232-hlt", _batches_ids: [] });
 | 
			
		||||
    keys.push(all[1].key);
 | 
			
		||||
    Returns.create(all[1]).save();
 | 
			
		||||
 | 
			
		||||
    all.push({ key: "three", memo: "4123-hbc", _batches_ids: [] });
 | 
			
		||||
    keys.push(all[2].key);
 | 
			
		||||
    Returns.create(all[2]).save();
 | 
			
		||||
    
 | 
			
		||||
    all.push({ key: "four", memo: "4441-dtf", _batches_ids: [] });
 | 
			
		||||
    keys.push(all[3].key);
 | 
			
		||||
    Returns.create(all[3]).save();
 | 
			
		||||
    
 | 
			
		||||
    all.push({ key: "five", memo: "4412-abn", _batches_ids: [] });
 | 
			
		||||
    keys.push(all[4].key);
 | 
			
		||||
    Returns.create(all[4]).save();
 | 
			
		||||
 | 
			
		||||
    some = Returns.filter(function (ret) {
 | 
			
		||||
      return /^4\d/.test(ret.memo);
 | 
			
		||||
    });
 | 
			
		||||
    assert.equal(3, some.length);
 | 
			
		||||
 | 
			
		||||
    some.forEach(function (one) {
 | 
			
		||||
      ids.push(one.key);
 | 
			
		||||
    });
 | 
			
		||||
    assert.deepEqual(some, Returns.some(ids));
 | 
			
		||||
    
 | 
			
		||||
    assert.deepEqual(all, Returns.all());
 | 
			
		||||
    assert.deepEqual(keys, Returns.keys());
 | 
			
		||||
    assert.deepEqual(all.slice(1,3), Returns.some(["two", "three"]));
 | 
			
		||||
 | 
			
		||||
    assert.deepEqual(keys, Returns.keys());
 | 
			
		||||
 | 
			
		||||
    console.log('skipping not-implemented `query`');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function relate() {
 | 
			
		||||
    var batches = [
 | 
			
		||||
        {
 | 
			
		||||
          uuid: "a",
 | 
			
		||||
          name: "chuck",
 | 
			
		||||
          _products_ids: []
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          name: "daryl",
 | 
			
		||||
          _products_ids: []
 | 
			
		||||
        }
 | 
			
		||||
      ]
 | 
			
		||||
      , ret = Returns.create({})
 | 
			
		||||
      , batch;
 | 
			
		||||
 | 
			
		||||
    // Add relation
 | 
			
		||||
    ret.save();
 | 
			
		||||
    ret = Returns.get(ret.key);
 | 
			
		||||
    ret.batches.add(batches[0]);
 | 
			
		||||
    assert.deepEqual(Batches.all()[0], batches[0]);
 | 
			
		||||
    assert.deepEqual(ret.batches[0], batches[0]);
 | 
			
		||||
    ret.save();
 | 
			
		||||
 | 
			
		||||
    // create with an existing relation
 | 
			
		||||
    ret = Returns.create({ batches: batches });
 | 
			
		||||
    batches[1].uuid = ret.batches[1].uuid;
 | 
			
		||||
 | 
			
		||||
    console.log('skipping assert which requires visual inspection');
 | 
			
		||||
    //assert.deepEqual(batches, ret.batches);
 | 
			
		||||
    //console.log(Batches.all());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  setup();
 | 
			
		||||
  empty();
 | 
			
		||||
  errors();
 | 
			
		||||
  createWithoutKey();
 | 
			
		||||
  createWithKey();
 | 
			
		||||
  insertRemove();
 | 
			
		||||
  all();
 | 
			
		||||
  relate();
 | 
			
		||||
 | 
			
		||||
  console.log("All tests passed");
 | 
			
		||||
}());
 | 
			
		||||
							
								
								
									
										140
									
								
								json-storage.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								json-storage.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,140 @@
 | 
			
		||||
/*jshint -W054 */
 | 
			
		||||
;(function (exports) {
 | 
			
		||||
  'use strict';
 | 
			
		||||
 | 
			
		||||
  var proto
 | 
			
		||||
    , delim = ':'
 | 
			
		||||
    ;
 | 
			
		||||
 | 
			
		||||
  function stringify(obj) {
 | 
			
		||||
    var str;
 | 
			
		||||
    try {
 | 
			
		||||
      str = JSON.stringify(obj);
 | 
			
		||||
    } catch(e) {
 | 
			
		||||
      str = "";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return str;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function parse(str) {
 | 
			
		||||
    var obj = null;
 | 
			
		||||
    try {
 | 
			
		||||
      obj = JSON.parse(str);
 | 
			
		||||
    } catch(e) {}
 | 
			
		||||
 | 
			
		||||
    return obj;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function JsonStorage(w3cStorage, namespace, opts) {
 | 
			
		||||
    var me = this
 | 
			
		||||
      ;
 | 
			
		||||
 | 
			
		||||
    if (!(this instanceof JsonStorage)) {
 | 
			
		||||
      return new JsonStorage(w3cStorage, namespace, opts);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!w3cStorage) {
 | 
			
		||||
      w3cStorage = window.localStorage;
 | 
			
		||||
    } else if ('function' !== typeof w3cStorage.getItem) {
 | 
			
		||||
      throw new Error('You must supply a W3C DOM Storage mechanism such as window.localStorage or window.sessionStorage');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    me._opts = opts || {};
 | 
			
		||||
    if (false === me._opts.stringify) {
 | 
			
		||||
      me._stringify = false;
 | 
			
		||||
    } else {
 | 
			
		||||
      me._stringify = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // if we didn't always add at least the delimeter
 | 
			
		||||
    // then if a keyname with the delim, it would be more
 | 
			
		||||
    // complicated to figure it out
 | 
			
		||||
    this._namespace = delim;
 | 
			
		||||
    this._namespace += (namespace || 'jss');
 | 
			
		||||
    if (false === namespace) {
 | 
			
		||||
      this._namespace = '';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this._store = w3cStorage;
 | 
			
		||||
    this._keysAreDirty = true;
 | 
			
		||||
    this._keys = [];
 | 
			
		||||
  }
 | 
			
		||||
  proto = JsonStorage.prototype;
 | 
			
		||||
  
 | 
			
		||||
  proto.clear = function () {
 | 
			
		||||
    this._keysAreDirty = true;
 | 
			
		||||
    this.keys().forEach(function (key) {
 | 
			
		||||
      this.remove(key);
 | 
			
		||||
    }, this);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  proto.remove = function (key) {
 | 
			
		||||
    this._keysAreDirty = true;
 | 
			
		||||
    this._store.removeItem(key + this._namespace);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  proto.get = function (key) {
 | 
			
		||||
    var item = this._store.getItem(key + this._namespace)
 | 
			
		||||
      ;
 | 
			
		||||
 | 
			
		||||
    if ('undefined' === typeof item) {
 | 
			
		||||
      item = null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (this._stringify) {
 | 
			
		||||
      item = parse(item);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return item;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  proto.set = function (key, val) {
 | 
			
		||||
    this._keysAreDirty = true;
 | 
			
		||||
    return this._store.setItem(key + this._namespace, this._stringify && stringify(val) || val);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  proto.keys = function () {
 | 
			
		||||
    var i
 | 
			
		||||
      , key
 | 
			
		||||
      , delimAt
 | 
			
		||||
      ;
 | 
			
		||||
 | 
			
		||||
    if (!this._keysAreDirty) {
 | 
			
		||||
      return this._keys.concat([]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this._keys = [];
 | 
			
		||||
    for (i = 0; i < this._store.length; i += 1) {
 | 
			
		||||
      key = this._store.key(i) || '';
 | 
			
		||||
 | 
			
		||||
      delimAt = key.lastIndexOf(this._namespace);
 | 
			
		||||
      // test if this key belongs to this widget
 | 
			
		||||
      if (!this._namespace || (-1 !== delimAt)) {
 | 
			
		||||
        this._keys.push(key.substr(0, delimAt));
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    this._keysAreDirty = false;
 | 
			
		||||
 | 
			
		||||
    return this._keys.concat([]);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  proto.size = function () {
 | 
			
		||||
    return this._store.length;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  proto.toJSON = function () {
 | 
			
		||||
    var json = {}
 | 
			
		||||
      ;
 | 
			
		||||
 | 
			
		||||
    this.keys().forEach(function (key) {
 | 
			
		||||
      json[key] = this.get(key);
 | 
			
		||||
    }, this);
 | 
			
		||||
 | 
			
		||||
    return json;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  JsonStorage.create = JsonStorage;
 | 
			
		||||
 | 
			
		||||
  exports.JsonStorage = JsonStorage;
 | 
			
		||||
}('undefined' !== typeof exports && exports || new Function('return this')()));
 | 
			
		||||
@ -1,176 +0,0 @@
 | 
			
		||||
(function () {
 | 
			
		||||
  "use strict";
 | 
			
		||||
 | 
			
		||||
  var Future = require('future')
 | 
			
		||||
    , __id_ = 'id'
 | 
			
		||||
    , nameToString = function () {
 | 
			
		||||
        return this.name;
 | 
			
		||||
      };
 | 
			
		||||
  
 | 
			
		||||
  function RowType(table) {
 | 
			
		||||
    var name = table.name,
 | 
			
		||||
      columns = table.columns,
 | 
			
		||||
      klass;
 | 
			
		||||
 | 
			
		||||
    klass = function (id, arr) {
 | 
			
		||||
      /*
 | 
			
		||||
      // Extending Array doesn't work very well
 | 
			
		||||
 | 
			
		||||
      var self = this;
 | 
			
		||||
      arr.forEach(function (item, i) {
 | 
			
		||||
        self[i] = item;
 | 
			
		||||
      });
 | 
			
		||||
      */
 | 
			
		||||
      if (!(__id_ in this)) {
 | 
			
		||||
        this[__id_] = id;
 | 
			
		||||
      }
 | 
			
		||||
      this.arr = arr;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // TODO make more directive-like
 | 
			
		||||
    // TODO create a delegates_to directive
 | 
			
		||||
    klass.prototype.toString = table.toString || nameToString;
 | 
			
		||||
 | 
			
		||||
    columns.forEach(function (column, i) {
 | 
			
		||||
      klass.prototype.__defineGetter__(column, function () {
 | 
			
		||||
        return this.arr[i];
 | 
			
		||||
        //return this[i];
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
    return klass;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function createIndexes(tables) {
 | 
			
		||||
    Object.keys(tables).forEach(function (name) {
 | 
			
		||||
      var table = tables[name],
 | 
			
		||||
        index,
 | 
			
		||||
        krow;
 | 
			
		||||
 | 
			
		||||
      if (!table.columns) {
 | 
			
		||||
        console.log("missing columns");
 | 
			
		||||
        console.log(table);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      table.klass = RowType(table);
 | 
			
		||||
 | 
			
		||||
      index = table.indexed = {};
 | 
			
		||||
 | 
			
		||||
      table.rows.forEach(function (row, z) {
 | 
			
		||||
        // TODO no need to index
 | 
			
		||||
        var krow = new table.klass(z, row);
 | 
			
		||||
        //krow.id = z;
 | 
			
		||||
        index[krow[__id_]] = krow;
 | 
			
		||||
        table.rows[z] = krow;
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function createRelationships(tables) {
 | 
			
		||||
    Object.keys(tables).forEach(function (name) {
 | 
			
		||||
      var table = tables[name],
 | 
			
		||||
        relationships,
 | 
			
		||||
        relHandlers = {};
 | 
			
		||||
 | 
			
		||||
      // TODO create a delegates_to directive
 | 
			
		||||
      relHandlers.belongs_to = function (relname) {  
 | 
			
		||||
        // TODO abstract name mutation
 | 
			
		||||
        var relation = tables[relname + 's'],
 | 
			
		||||
          relname_s = relname + '_id';
 | 
			
		||||
 | 
			
		||||
        table.klass.prototype.__defineGetter__(relname, function () {
 | 
			
		||||
          var fid = this[relname_s];
 | 
			
		||||
 | 
			
		||||
          return relation.indexed[fid];
 | 
			
		||||
        });
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      //relationships = table.relationships && table.relationships.belongs_to;
 | 
			
		||||
      //relationships = relationships || [];
 | 
			
		||||
 | 
			
		||||
      relationships = table.relationships || {};
 | 
			
		||||
 | 
			
		||||
      Object.keys(relationships).forEach(function (relType) {
 | 
			
		||||
        if (!relHandlers[relType]) {
 | 
			
		||||
          console.log('relationship type "' + relType + '" is not supported');
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
        relationships[relType].forEach(relHandlers[relType]);
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  function createRelate(tables) {
 | 
			
		||||
    var future = Future()
 | 
			
		||||
      ;
 | 
			
		||||
    
 | 
			
		||||
    createIndexes(tables);
 | 
			
		||||
    createRelationships(tables);
 | 
			
		||||
    //testRelationships(tables);
 | 
			
		||||
    //console.log(Object.keys(data));
 | 
			
		||||
 | 
			
		||||
    future.fulfill(null, tables);
 | 
			
		||||
 | 
			
		||||
    return future.passable();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  var Future = require('future')
 | 
			
		||||
    , Join = require('Join')
 | 
			
		||||
    ;
 | 
			
		||||
 | 
			
		||||
  function createGet(pathname, tables) {
 | 
			
		||||
    var future = Future()
 | 
			
		||||
      , join = Join()
 | 
			
		||||
      , request = require('ahr2')
 | 
			
		||||
      , db = {}
 | 
			
		||||
      , errs = []
 | 
			
		||||
      ;
 | 
			
		||||
 | 
			
		||||
    tables.forEach(function (tablename) {
 | 
			
		||||
      var resource = pathname + '/' + tablename + ".json"
 | 
			
		||||
        , req = request.get(resource)
 | 
			
		||||
        ;
 | 
			
		||||
 | 
			
		||||
      req.when(function (err, xhr, data) {
 | 
			
		||||
        if (err) {
 | 
			
		||||
          console.log('error tables-get');
 | 
			
		||||
          console.log(err);
 | 
			
		||||
          console.log(err.message);
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (global.Buffer && data instanceof global.Buffer) {
 | 
			
		||||
          data = data.toString();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // TODO need to refactor AHR and fix JSON / text handling
 | 
			
		||||
        try {
 | 
			
		||||
          data = JSON.parse(data.toString());
 | 
			
		||||
        } catch (e) {
 | 
			
		||||
          // ignore, it was probably already parsed
 | 
			
		||||
        }
 | 
			
		||||
        // follow convention
 | 
			
		||||
        tablename = tablename.replace('-','_');
 | 
			
		||||
        db[tablename] = data;
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      join.add(req);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    join.when(function () {
 | 
			
		||||
      // TODO add timeout as error
 | 
			
		||||
      if (0 == errs.length) {
 | 
			
		||||
        errs = null;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      future.fulfill(errs, db);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    return future.passable();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  module.exports = {
 | 
			
		||||
      get: createGet
 | 
			
		||||
    , relate: createRelate
 | 
			
		||||
  };
 | 
			
		||||
}());
 | 
			
		||||
@ -1,21 +0,0 @@
 | 
			
		||||
{
 | 
			
		||||
    "author": "AJ ONeal <coolaj86@gmail.com> (http://coolaj86.info)"
 | 
			
		||||
  , "name": "json-tables"
 | 
			
		||||
  , "description": "An abstraction for models to be stored in json-storage"
 | 
			
		||||
  , "keywords": ["ender", "orm", "sql", "model", "json-storage", "localStorage", "sessionStorage", "globalStorage", "Storage"]
 | 
			
		||||
  , "version": "0.7.1"
 | 
			
		||||
  , "repository": {
 | 
			
		||||
        "type": "git"
 | 
			
		||||
      , "url": "git://github.com/coolaj86/json-storage-js.git"
 | 
			
		||||
    }
 | 
			
		||||
  , "engines": {
 | 
			
		||||
        "node": ">= v0.2.0"
 | 
			
		||||
    }
 | 
			
		||||
  , "main": "index"
 | 
			
		||||
  , "dependencies": {
 | 
			
		||||
        "json-storage-model": ">= 0.9.0"
 | 
			
		||||
      , "json-storage": ">= 1.0.0"
 | 
			
		||||
      , "node-uuid": ">= 0.0.0"
 | 
			
		||||
    }
 | 
			
		||||
  , "devDependencies": {}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										146
									
								
								lib/index.js
									
									
									
									
									
								
							
							
						
						
									
										146
									
								
								lib/index.js
									
									
									
									
									
								
							@ -1,146 +0,0 @@
 | 
			
		||||
(function () {
 | 
			
		||||
  "use strict";
 | 
			
		||||
 | 
			
		||||
  var Store
 | 
			
		||||
    , delim = ':'
 | 
			
		||||
    ;
 | 
			
		||||
 | 
			
		||||
  function Stringify(obj) {
 | 
			
		||||
    var str;
 | 
			
		||||
    try {
 | 
			
		||||
      str = JSON.stringify(obj);
 | 
			
		||||
    } catch(e) {
 | 
			
		||||
      str = "";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return str;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function Parse(str) {
 | 
			
		||||
    var obj = null;
 | 
			
		||||
    try {
 | 
			
		||||
      obj = JSON.parse(str);
 | 
			
		||||
    } catch(e) {}
 | 
			
		||||
 | 
			
		||||
    return obj;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function escapeRegExp(str) {
 | 
			
		||||
    return str.replace(/[-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function upgradeStorage(jss, w3cs) {
 | 
			
		||||
    var i
 | 
			
		||||
      , key
 | 
			
		||||
      , val
 | 
			
		||||
      , json = {}
 | 
			
		||||
      ;
 | 
			
		||||
 | 
			
		||||
    if (jss._store.getItem('_json-storage-namespaced_', true)) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // we can't modify the db while were reading or
 | 
			
		||||
    // the keys will shift all over the place
 | 
			
		||||
    for (i = 0; i < w3cs.length; i += 1) {
 | 
			
		||||
      key = w3cs.key(i);
 | 
			
		||||
      val = w3cs.getItem(key);
 | 
			
		||||
      json[key] = val;
 | 
			
		||||
    }
 | 
			
		||||
    w3cs.clear();
 | 
			
		||||
 | 
			
		||||
    Object.keys(json).forEach(function (key) {
 | 
			
		||||
      jss.set(key, json[key]);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    jss._store.setItem('_json-storage-namespaced_', true);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function JsonStorage(w3cStorage, namespace) {
 | 
			
		||||
    // called without new or create
 | 
			
		||||
    // global will be undefined
 | 
			
		||||
    if (!this) {
 | 
			
		||||
      return new JsonStorage(w3cStorage, namespace);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // if we didn't always add at least the delimeter
 | 
			
		||||
    // then if a keyname with the delim, it would be more
 | 
			
		||||
    // complicated to figure it out
 | 
			
		||||
    this._namespace = delim;
 | 
			
		||||
    this._namespace += (namespace || 'jss');
 | 
			
		||||
 | 
			
		||||
    this._store = w3cStorage;
 | 
			
		||||
    this._keysAreDirty = true;
 | 
			
		||||
    if (!this._store.getItem('_json-storage-namespaced_')) {
 | 
			
		||||
      upgradeStorage(this, w3cStorage);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  Store = JsonStorage;
 | 
			
		||||
  
 | 
			
		||||
  Store.prototype.clear = function () {
 | 
			
		||||
    this._keysAreDirty = true;
 | 
			
		||||
    this.keys().forEach(function (key) {
 | 
			
		||||
      this.remove(key);
 | 
			
		||||
    }, this);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  Store.prototype.remove = function (key) {
 | 
			
		||||
    this._keysAreDirty = true;
 | 
			
		||||
    this._store.removeItem(key + this._namespace);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  Store.prototype.get = function (key) {
 | 
			
		||||
    return Parse(this._store.getItem(key + this._namespace));
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  Store.prototype.set = function (key, val) {
 | 
			
		||||
    this._keysAreDirty = true;
 | 
			
		||||
    return this._store.setItem(key + this._namespace, Stringify(val));
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  Store.prototype.keys = function () {
 | 
			
		||||
    var i
 | 
			
		||||
      , key
 | 
			
		||||
      , delimAt
 | 
			
		||||
      ;
 | 
			
		||||
 | 
			
		||||
    if (!this._keysAreDirty) {
 | 
			
		||||
      return this._keys.concat([]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this._keys = [];
 | 
			
		||||
    for (i = 0; i < this._store.length; i += 1) {
 | 
			
		||||
      key = this._store.key(i) || '';
 | 
			
		||||
 | 
			
		||||
      delimAt = key.lastIndexOf(this._namespace);
 | 
			
		||||
      // test if this key belongs to this widget
 | 
			
		||||
      if (-1 !== delimAt) {
 | 
			
		||||
        this._keys.push(key.substr(0, delimAt));
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    this._keysAreDirty = false;
 | 
			
		||||
 | 
			
		||||
    return this._keys.concat([]);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  Store.prototype.size = function () {
 | 
			
		||||
    return this._store.length;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  Store.prototype.toJSON = function () {
 | 
			
		||||
    var json = {}
 | 
			
		||||
      ;
 | 
			
		||||
 | 
			
		||||
    this._keys.forEach(function (key) {
 | 
			
		||||
      json[key] = this.get(key);
 | 
			
		||||
    }, this);
 | 
			
		||||
 | 
			
		||||
    return json;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  Store.create = function (w3cStorage, namespace) {
 | 
			
		||||
    return new JsonStorage(w3cStorage, namespace);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  module.exports = Store;
 | 
			
		||||
}());
 | 
			
		||||
@ -1,18 +0,0 @@
 | 
			
		||||
{
 | 
			
		||||
  "author": "AJ ONeal <coolaj86@gmail.com> (http://coolaj86.info)",
 | 
			
		||||
  "name": "json-storage",
 | 
			
		||||
  "description": "A wrapper for storage engines which use the W3C Storage API",
 | 
			
		||||
  "keywords": ["ender", "localStorage", "sessionStorage", "globalStorage", "Storage"],
 | 
			
		||||
  "version": "1.1.0",
 | 
			
		||||
  "repository": {
 | 
			
		||||
    "type": "git",
 | 
			
		||||
    "url": "git://github.com/coolaj86/json-storage-js.git"
 | 
			
		||||
  },
 | 
			
		||||
  "engines": {
 | 
			
		||||
    "node": ">= v0.2.0"
 | 
			
		||||
  },
 | 
			
		||||
  "main": "index",
 | 
			
		||||
  "browserDependencies": {},
 | 
			
		||||
  "dependencies": {},
 | 
			
		||||
  "devDependencies": {}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										18
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,18 @@
 | 
			
		||||
{
 | 
			
		||||
  "author": "AJ ONeal <coolaj86@gmail.com> (http://coolaj86.com)",
 | 
			
		||||
  "name": "json-storage",
 | 
			
		||||
  "description": "A wrapper for storage engines which use the W3C Storage API",
 | 
			
		||||
  "keywords": ["dom", "storage", "json", "w3c", "localStorage", "sessionStorage", "globalStorage", "Storage"],
 | 
			
		||||
  "version": "2.1.2",
 | 
			
		||||
  "repository": {
 | 
			
		||||
    "type": "git",
 | 
			
		||||
    "url": "git://git.coolaj86.com/coolaj86/json-storage.js.git"
 | 
			
		||||
  },
 | 
			
		||||
  "engines": {
 | 
			
		||||
    "node": ">= v0.2.0"
 | 
			
		||||
  },
 | 
			
		||||
  "main": "json-storage",
 | 
			
		||||
  "browserDependencies": {},
 | 
			
		||||
  "dependencies": {},
 | 
			
		||||
  "devDependencies": {}
 | 
			
		||||
}
 | 
			
		||||
@ -2,8 +2,8 @@
 | 
			
		||||
  "use strict";
 | 
			
		||||
 | 
			
		||||
  var localStorage = require('localStorage')
 | 
			
		||||
    , JsonStorage = require('json-storage')
 | 
			
		||||
    , db = JsonStorage(localStorage)
 | 
			
		||||
    , JsonStorage = require('../lib/').JsonStorage
 | 
			
		||||
    , db = JsonStorage.create(localStorage)
 | 
			
		||||
    , assert = require('assert')
 | 
			
		||||
    ;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -3,8 +3,8 @@
 | 
			
		||||
 | 
			
		||||
  var assert = require('assert')
 | 
			
		||||
    , localStorage = require('localStorage')
 | 
			
		||||
    , JsonStorage = require('json-storage')
 | 
			
		||||
    , db = JsonStorage(localStorage)
 | 
			
		||||
    , JsonStorage = require('../lib/').JsonStorage
 | 
			
		||||
    , db = JsonStorage.create(localStorage)
 | 
			
		||||
    ;
 | 
			
		||||
 | 
			
		||||
  assert.strictEqual(null, db.get('a'));
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user