Compare commits
	
		
			20 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 2e4745b189 | |||
| 21098984f1 | |||
| b2fdf0aba2 | |||
| 7b459f1f87 | |||
| 3a2ada1ce0 | |||
| a881915cfe | |||
| 5e9e9d8a41 | |||
| 780b7583a1 | |||
| c4efbba4da | |||
| 6f7b83ea15 | |||
| 1a9a10c24e | |||
| 9cdcdf98d9 | |||
| a430f94fce | |||
| 699f673b79 | |||
| 4e61155c7e | |||
| a704e4ad02 | |||
| 16fb1c730e | |||
| 6dba7f09f8 | |||
| dfe7ca8752 | |||
| 3ddf2be63d | 
							
								
								
									
										94
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										94
									
								
								README.md
									
									
									
									
									
								
							| @ -1,48 +1,71 @@ | |||||||
| jsonStorage | JsonStorage | ||||||
| ==== | ==== | ||||||
| 
 | 
 | ||||||
| A light abstraction for DOMStorage (such as localStorage). | A light, sensible abstraction for DOMStorage (such as localStorage). | ||||||
| 
 | 
 | ||||||
| Installation | 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) | Node.JS (Server) | ||||||
| 
 | 
 | ||||||
|     npm install localStorage json-storage | ```bash | ||||||
|  | npm install -S localStorage json-storage | ||||||
|  | ``` | ||||||
| 
 | 
 | ||||||
| Usage | Usage | ||||||
| === | === | ||||||
| 
 | 
 | ||||||
| Made fo for Node.JS and Ender.JS (browser-side). | Made for Node.js and Bower (browser-side). | ||||||
| 
 | 
 | ||||||
|     var localStorage = require('localStorage') | ```javascript | ||||||
|       , JsonStorage = require('json-storage') | var localStorage = require('localStorage') | ||||||
|       , db = JsonStorage(localStorage, 'my-app-prefix') |   , JsonStorage = require('json-storage').JsonStorage | ||||||
|  |   , store = JsonStorage.create(localStorage, 'my-widget-namespace', { stringify: true }) | ||||||
|   , myValue = { |   , myValue = { | ||||||
|         foo: "bar" |         foo: "bar" | ||||||
|       , baz: "quux" |       , baz: "quux" | ||||||
|     } |     } | ||||||
|   ; |   ; | ||||||
| 
 | 
 | ||||||
|     db.set('myKey', myValue);  | store.set('myKey', myValue); | ||||||
|     myValue = db.get('myKey'); | 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 | API | ||||||
| === | === | ||||||
| 
 | 
 | ||||||
|   * JsonStorage(DOMStorage, 'application-prefix') // optional prefix |   * `JsonStorage.create(DOMStorage, namespace, opts)` | ||||||
|   * get(key) |     * `DOMStorage` should be globalStorage, sessionStorage, or localStorage. Defaults to window.localStorage if set to `null`. | ||||||
|   * set(key, value) |     * `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: | ||||||
|   * remove(key) |       * `Gizmos.create(JsonStorage.create(null, 'my-gizmos'))` | ||||||
|   * clear() |       * `Gadgets.create(JsonStorage.create(null, 'my-gadgets'))` | ||||||
|   * keys() |       * Namespacing can be turned off by explicitly setting `false` | ||||||
|   * size() |         * `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)` | ||||||
| 
 | 
 | ||||||
| null vs undefined in JSON | **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 })` | ||||||
|  | 
 | ||||||
|  | JSON / DOMStorage Conversion Gotchas | ||||||
| === | === | ||||||
| 
 | 
 | ||||||
| These notes do not reflect a bugs or defects in this library, | These notes do not reflect a bugs or defects in this library, | ||||||
| @ -52,22 +75,45 @@ 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. | If they do, you're probably doing something wrong in the first place. | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| It is not valid to set `undefined` in JSON. So setting a key to `undefined` will remove it from the db. | ### `undefined` vs `null` | ||||||
| 
 | 
 | ||||||
| This means that `db.set('x')` is the same as `db.remove('x')`. | 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')`. | ||||||
| 
 | 
 | ||||||
| To save `undefined`, use `null` instead. | 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`. | Note that both values that exist as `null` and values that don't exist at all will return `null`. | ||||||
| 
 | 
 | ||||||
|     db.set('existing-key', null); | ```javascript | ||||||
|     null === db.get('existing-key'); | store.set('existing-key', null); | ||||||
|     null === db.get('non-existant-key'); | null === store.get('existing-key'); | ||||||
|  | null === store.get('non-existant-key'); | ||||||
|  | ``` | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | ### `null` vs `"null"` | ||||||
|  | 
 | ||||||
| The special case of `null` as `"null"`, aka `"\"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\""`). | `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. | 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": {} |  | ||||||
| } |  | ||||||
							
								
								
									
										79
									
								
								lib/index.js
									
									
									
									
									
								
							
							
						
						
									
										79
									
								
								lib/index.js
									
									
									
									
									
								
							| @ -1,79 +0,0 @@ | |||||||
| (function () { |  | ||||||
|   "use strict"; |  | ||||||
| 
 |  | ||||||
|   var db; |  | ||||||
| 
 |  | ||||||
|   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) { |  | ||||||
|     this.db = w3cStorage; |  | ||||||
|     this.keysAreDirty = true; |  | ||||||
|   } |  | ||||||
|   db = JsonStorage; |  | ||||||
|    |  | ||||||
|   db.prototype.clear = function () { |  | ||||||
|     this.keysAreDirty = true; |  | ||||||
|     this.keys().forEach(function (uuid) { |  | ||||||
|       this.remove(uuid); |  | ||||||
|     }, this); |  | ||||||
|   }; |  | ||||||
| 
 |  | ||||||
|   db.prototype.remove = function (uuid) { |  | ||||||
|     this.keysAreDirty = true; |  | ||||||
|     this.db.removeItem(uuid); |  | ||||||
|   }; |  | ||||||
| 
 |  | ||||||
|   db.prototype.get = function (uuid) { |  | ||||||
|     return Parse(this.db.getItem(uuid)); |  | ||||||
|   }; |  | ||||||
| 
 |  | ||||||
|   db.prototype.set = function (uuid, val) { |  | ||||||
|     this.keysAreDirty = true; |  | ||||||
|     return this.db.setItem(uuid, Stringify(val)); |  | ||||||
|   }; |  | ||||||
| 
 |  | ||||||
|   db.prototype.keys = function () { |  | ||||||
|     var i |  | ||||||
|       ; |  | ||||||
| 
 |  | ||||||
|     if (!this.keysAreDirty) { |  | ||||||
|       return this.__keys.concat([]); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     this.__keys = []; |  | ||||||
|     for (i = 0; i < this.db.length; i += 1) { |  | ||||||
|       this.__keys.push(this.db.key(i)); |  | ||||||
|     } |  | ||||||
|     this.keysAreDirty = false; |  | ||||||
| 
 |  | ||||||
|     return this.__keys.concat([]); |  | ||||||
|   }; |  | ||||||
| 
 |  | ||||||
|   db.prototype.size = function () { |  | ||||||
|     return this.db.length; |  | ||||||
|   }; |  | ||||||
| 
 |  | ||||||
|   function create(w3cStorage) { |  | ||||||
|     return new JsonStorage(w3cStorage); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   module.exports = create; |  | ||||||
| }()); |  | ||||||
| @ -1,17 +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.0.1", |  | ||||||
|   "repository": { |  | ||||||
|     "type": "git", |  | ||||||
|     "url": "git://github.com/coolaj86/json-storage-js.git" |  | ||||||
|   }, |  | ||||||
|   "engines": { |  | ||||||
|     "node": ">= v0.2.0" |  | ||||||
|   }, |  | ||||||
|   "main": "index", |  | ||||||
|   "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": {} | ||||||
|  | } | ||||||
							
								
								
									
										10
									
								
								test/test.js
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								test/test.js
									
									
									
									
									
								
							| @ -2,13 +2,13 @@ | |||||||
|   "use strict"; |   "use strict"; | ||||||
| 
 | 
 | ||||||
|   var localStorage = require('localStorage') |   var localStorage = require('localStorage') | ||||||
|     , JsonStorage = require('json-storage') |     , JsonStorage = require('../lib/').JsonStorage | ||||||
|     , db = JsonStorage(localStorage) |     , db = JsonStorage.create(localStorage) | ||||||
|     , assert = require('assert') |     , assert = require('assert') | ||||||
|     ; |     ; | ||||||
| 
 | 
 | ||||||
|   assert.equal(null, db.get('x')); |   assert.equal(null, db.get('x')); | ||||||
|   assert.deepEqual([], db.keys()); |   assert.deepEqual([], db.keys(), 'found keys in empty db: ' + JSON.stringify(db.keys())); | ||||||
|   db.clear(); |   db.clear(); | ||||||
|   assert.equal(null, db.get('x')); |   assert.equal(null, db.get('x')); | ||||||
| 
 | 
 | ||||||
| @ -23,5 +23,9 @@ | |||||||
|   db.clear(); |   db.clear(); | ||||||
|   assert.deepEqual([], db.keys()); |   assert.deepEqual([], db.keys()); | ||||||
| 
 | 
 | ||||||
|  |   db.set('a', 'b'); | ||||||
|  |   assert.deepEqual(['a'], db.keys()); | ||||||
|  |   assert.deepEqual({ 'a': 'b' }, db.toJSON()); | ||||||
|  | 
 | ||||||
|   console.log("Done! All tests pass."); |   console.log("Done! All tests pass."); | ||||||
| }()); | }()); | ||||||
|  | |||||||
| @ -3,8 +3,8 @@ | |||||||
| 
 | 
 | ||||||
|   var assert = require('assert') |   var assert = require('assert') | ||||||
|     , localStorage = require('localStorage') |     , localStorage = require('localStorage') | ||||||
|     , JsonStorage = require('json-storage') |     , JsonStorage = require('../lib/').JsonStorage | ||||||
|     , db = JsonStorage(localStorage) |     , db = JsonStorage.create(localStorage) | ||||||
|     ; |     ; | ||||||
| 
 | 
 | ||||||
|   assert.strictEqual(null, db.get('a')); |   assert.strictEqual(null, db.get('a')); | ||||||
|  | |||||||
							
								
								
									
										28
									
								
								test/two-stores-can-have-same-keys.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								test/two-stores-can-have-same-keys.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,28 @@ | |||||||
|  | (function () { | ||||||
|  |   "use strict"; | ||||||
|  | 
 | ||||||
|  |   var localStorage = require('localStorage') | ||||||
|  |     , jsonStorage = require('../lib/') | ||||||
|  |     , assert = require('assert') | ||||||
|  |     , store0 = jsonStorage.create(localStorage, '0') | ||||||
|  |     , store1 = jsonStorage.create(localStorage, '1') | ||||||
|  |     ; | ||||||
|  | 
 | ||||||
|  |   store0.set('foo', 'bar'); | ||||||
|  |   store1.set('foo', 'baz'); | ||||||
|  | 
 | ||||||
|  |   assert.strictEqual('bar', store0.get('foo')); | ||||||
|  |   assert.strictEqual('baz', store1.get('foo')); | ||||||
|  | 
 | ||||||
|  |   store0.remove('foo'); | ||||||
|  | 
 | ||||||
|  |   assert.strictEqual(null, store0.get('foo')); | ||||||
|  |   assert.strictEqual('baz', store1.get('foo'), 'after removing a value from store1, store0 lost it as well'); | ||||||
|  | 
 | ||||||
|  |   store0.clear(); | ||||||
|  | 
 | ||||||
|  |   assert.strictEqual(null, store0.get('foo')); | ||||||
|  |   assert.strictEqual('baz', store1.get('foo'), 'after clearing store0, store1 lost values'); | ||||||
|  | 
 | ||||||
|  |   console.log('[PASS] no assertions failed'); | ||||||
|  | }()); | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user