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 | 
							
								
								
									
										87
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										87
									
								
								README.md
									
									
									
									
									
								
							| @ -1,27 +1,34 @@ | ||||
| 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). | ||||
| 
 | ||||
| ```javascript | ||||
| var localStorage = require('localStorage') | ||||
|       , JsonStorage = require('json-storage') | ||||
|       , store = JsonStorage.create(localStorage, 'my-widget-namespace') | ||||
|   , JsonStorage = require('json-storage').JsonStorage | ||||
|   , store = JsonStorage.create(localStorage, 'my-widget-namespace', { stringify: true }) | ||||
|   , myValue = { | ||||
|         foo: "bar" | ||||
|       , baz: "quux" | ||||
| @ -30,32 +37,35 @@ Made fo for Node.JS and Ender.JS (browser-side). | ||||
| 
 | ||||
| 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`. | ||||
| 
 | ||||
| ```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