Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

separated from localStorage

  • Loading branch information...
commit 9616ea92b8d97786644ef4562a55505bc3f4de67 1 parent 1e2bf28
@coolaj86 authored
View
16 README.md
@@ -1,7 +1,7 @@
-localStorage
+DOMStorage
===
-An inefficient, but as W3C-compliant as possible using only pure JavaScript, `localStorage` implementation.
+An inefficient, but as W3C-compliant as possible using only pure JavaScript, `DOMStorage` implementation.
Purpose
----
@@ -11,7 +11,9 @@ This is meant for the purpose of being able to run unit-tests and such for brows
Usage
----
- var localStorage = require('localStorage')
+ var Storage = require('dom-storage')
+ , localStorage = new Storage('./db.json') // in-file
+ , sessionStorage = new Storage() // in-memory
, myValue = { foo: 'bar', baz: 'quux' }
;
@@ -48,9 +50,9 @@ Tests
localStorage.clear();
0 === localStorage.length;
-TODO / Bugs
+Notes
---
- * Does not persist.
- * could use `fs.readFileSync` at load and an occasional `fs.writeFile` to write-out localStorage.json
- * Doesn't not emit `Storage` events
+ * db is read in synchronously
+ * No callback when db is saved
+ * Doesn't not emit `Storage` events (not sure how to do)
View
108 lib/index.js
@@ -0,0 +1,108 @@
+/*jshint node:true es5:true laxcomma:true laxbreak:true*/
+// http://www.rajdeepd.com/articles/chrome/localstrg/LocalStorageSample.htm
+
+// NOTE:
+// this varies from actual localStorage in some subtle ways
+
+// also, there is no persistence
+// TODO persist
+(function () {
+ "use strict";
+
+ var fs = require('fs')
+ ;
+
+ function Storage(path) {
+ var db
+ ;
+
+ Object.defineProperty(this, '___priv_bk___', {
+ value: {
+ path: path
+ }
+ , writable: false
+ , enumerable: false
+ });
+
+ try {
+ db = JSON.parse(fs.readFileSync(path));
+ } catch(e) {
+ db = {};
+ }
+
+ Object.keys(db).forEach(function (key) {
+ this[key] = db[key];
+ }, this);
+ }
+
+ Storage.prototype.getItem = function (key) {
+ if (key in this) {
+ return String(this[key]);
+ }
+ return null;
+ };
+
+ Storage.prototype.setItem = function (key, val) {
+ this[key] = String(val);
+ this.___save___();
+ };
+
+ Storage.prototype.removeItem = function (key) {
+ delete this[key];
+ this.___save___();
+ };
+
+ Storage.prototype.clear = function () {
+ var self = this;
+ // filters out prototype keys
+ Object.keys(self).forEach(function (key) {
+ self[key] = undefined;
+ delete self[key];
+ });
+ };
+
+ Storage.prototype.key = function (i) {
+ i = i || 0;
+ return Object.keys(this)[i];
+ };
+
+ Storage.prototype.__defineGetter__('length', function () {
+ return Object.keys(this).length;
+ });
+
+ Storage.prototype.___save___ = function () {
+ var self = this
+ ;
+
+ if (!this.___priv_bk___.path) {
+ return;
+ }
+
+ if (this.___priv_bk___.lock) {
+ this.___priv_bk___.wait = true;
+ return;
+ }
+
+ this.___priv_bk___.lock = true;
+ fs.writeFile(this.___priv_bk___.path, JSON.stringify(this), 'utf8', function (e) {
+ self.___priv_bk___.lock = false;
+ if (e) {
+ return;
+ }
+ if (self.___priv_bk___.wait) {
+ self.___priv_bk___.wait = false;
+ self.___save___();
+ }
+ });
+ };
+
+ Object.defineProperty(Storage, 'create', {
+ value: function (path) {
+ return new Storage(path);
+ }
+ , writable: false
+ , enumerable: false
+ });
+
+ module.exports = Storage;
+}());
View
54 lib/localStorage.js
@@ -1,54 +0,0 @@
-// http://www.rajdeepd.com/articles/chrome/localstrg/LocalStorageSample.htm
-
-// NOTE:
-// this varies from actual localStorage in some subtle ways
-
-// also, there is no persistence
-// TODO persist
-(function () {
- "use strict";
-
- var db;
-
- function LocalStorage() {
- }
- db = LocalStorage;
-
- db.prototype.getItem = function (key) {
- if (key in this) {
- return String(this[key]);
- }
- return null;
- };
-
- db.prototype.setItem = function (key, val) {
- this[key] = String(val);
- };
-
- db.prototype.removeItem = function (key) {
- delete this[key];
- };
-
- db.prototype.clear = function () {
- var self = this;
- Object.keys(self).forEach(function (key) {
- self[key] = undefined;
- delete self[key];
- });
- };
-
- db.prototype.key = function (i) {
- i = i || 0;
- return Object.keys(this)[i];
- };
-
- db.prototype.__defineGetter__('length', function () {
- return Object.keys(this).length;
- });
-
- if (global.localStorage) {
- module.exports = localStorage;
- } else {
- module.exports = new LocalStorage();
- }
-}());
View
10 lib/package.json
@@ -1,16 +1,16 @@
{
"author": "AJ ONeal <coolaj86@gmail.com> (http://coolaj86.info)",
- "name": "localStorage",
- "description": "W3C localStorage for Node.JS",
+ "name": "dom-storage",
+ "description": "W3C DOM Storage (localStorage and sessionStorage) for Node.JS",
"version": "1.0.0",
"repository": {
"type": "git",
- "url": "git://github.com/coolaj86/node-localStorage.git"
+ "url": "git://github.com/coolaj86/node-browser-compat.git"
},
"engines": {
- "node": ">= v0.2.0"
+ "node": "*"
},
- "main": "localStorage.js",
+ "main": "index.js",
"dependencies": {},
"devDependencies": {}
}
View
65 tests/test.js
@@ -1,34 +1,57 @@
+/*jshint node:true es5:true laxcomma:true laxbreak:true*/
(function () {
"use strict";
var assert = require('assert')
- , localStorage = require('localStorage')
+ , fs = require('fs')
+ , Storage = require('dom-storage')
+ , dbPath = './db.json'
;
- // can't make assuptions about key positioning
- localStorage.setItem('a', 1);
- assert.strictEqual(localStorage.key(0), 'a');
+ function runTest(storage) {
+ assert.strictEqual(0, Object.keys(storage).length);
+ assert.strictEqual(0, storage.length);
- localStorage.setItem('b', '2');
- assert.strictEqual(localStorage.getItem('a'), '1');
- assert.strictEqual(localStorage.getItem('b'), '2');
- assert.strictEqual(localStorage.length, 2);
+ // can't make assuptions about key positioning
+ storage.setItem('a', 1);
+ assert.strictEqual(storage.key(0), 'a');
- assert.strictEqual(localStorage['c'], undefined);
- assert.strictEqual(localStorage.getItem('c'), null);
+ storage.setItem('b', '2');
+ assert.strictEqual(storage.getItem('a'), '1');
+ assert.strictEqual(storage.getItem('b'), '2');
+ assert.strictEqual(storage.length, 2);
- localStorage.setItem('c');
- assert.strictEqual(localStorage.getItem('c'), "undefined");
- assert.strictEqual(localStorage.length, 3);
+ assert.strictEqual(storage['c'], undefined);
+ assert.strictEqual(storage.getItem('c'), null);
- localStorage.removeItem('c');
- assert.strictEqual(localStorage.getItem('c'), null);
- assert.strictEqual(localStorage.length, 2);
+ storage.setItem('c');
+ assert.strictEqual(storage.getItem('c'), "undefined");
+ assert.strictEqual(storage.length, 3);
- localStorage.clear();
- assert.strictEqual(localStorage.getItem('a'), null);
- assert.strictEqual(localStorage.getItem('b'), null);
- assert.strictEqual(localStorage.length, 0);
+ storage.removeItem('c');
+ assert.strictEqual(storage.getItem('c'), null);
+ assert.strictEqual(storage.length, 2);
- console.log('All tests passed');
+ storage.clear();
+ assert.strictEqual(storage.getItem('a'), null);
+ assert.strictEqual(storage.getItem('b'), null);
+ assert.strictEqual(storage.length, 0);
+ }
+
+ function runAll() {
+ var localStorage = new Storage(dbPath)
+ , sessionStorage = new Storage()
+ ;
+
+ runTest(sessionStorage);
+ runTest(localStorage);
+
+ localStorage.setItem('a', 1);
+ setTimeout(function () {
+ assert.deepEqual({ a: 1 }, JSON.parse(fs.readFileSync(dbPath)));
+ console.log('All tests passed');
+ }, 100);
+ }
+
+ fs.unlink(dbPath, runAll);
}());
Please sign in to comment.
Something went wrong with that request. Please try again.