Skip to content

Commit

Permalink
0.9.6: Full Web Storage API implementation
Browse files Browse the repository at this point in the history
Refactored code to make it able to also support accessing and mutating stored values through index operators:
var value = store['my-key'];
store['my-key'] = 'some-value';
Also removed the options object, the keys variable and made id a private field
  • Loading branch information
Download committed Sep 2, 2015
1 parent 286e0b3 commit d2b1047
Show file tree
Hide file tree
Showing 13 changed files with 157 additions and 145 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
# memorystorage <sub><sup>v0.9.5</sup></sub>
# memorystorage <sub><sup>v0.9.6</sup></sub>
Memory-backed storage that implements the [Web Storage API](http://www.w3.org/TR/webstorage/), making it a drop-in replacement for `localStorage` and `sessionStorage` in environments where these are not available.
[Project website](http://download.github.io/memorystorage)

## Download
* [memorystorage.js](https://cdn.rawgit.com/download/memorystorage/0.9.5/src/memorystorage.js) (~3kB, commented)
* [memorystorage.min.js](https://cdn.rawgit.com/download/memorystorage/0.9.5/dist/memorystorage.min.js) (~2kB, minified)
* [memorystorage.min.js.map](https://cdn.rawgit.com/download/memorystorage/0.9.5/dist/memorystorage.min.js.map) (~2kB, debug map file)
* [memorystorage.js](https://cdn.rawgit.com/download/memorystorage/0.9.6/src/memorystorage.js) (~3kB, commented)
* [memorystorage.min.js](https://cdn.rawgit.com/download/memorystorage/0.9.6/dist/memorystorage.min.js) (~2kB, minified)
* [memorystorage.min.js.map](https://cdn.rawgit.com/download/memorystorage/0.9.6/dist/memorystorage.min.js.map) (~2kB, debug map file)

## Include on your page
`memorystorage` can be used directly from CDN, or from a local script file.

### CDN
```xml
<script src="https://cdn.rawgit.com/download/memorystorage/0.9.5/dist/memorystorage.min.js"></script>
<script src="https://cdn.rawgit.com/download/memorystorage/0.9.6/dist/memorystorage.min.js"></script>
```

### Local script file
Expand Down
4 changes: 2 additions & 2 deletions dist/memorystorage.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/memorystorage.min.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion doc/classes.list.html
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ <h3 class="subsection-title">Classes</h3>

<span class="jsdoc-message">
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.3.2</a>
on Tue Sep 1st 2015 using the <a
on Wed Sep 2nd 2015 using the <a
href="https://github.com/terryweiss/docstrap">DocStrap template</a>.
</span>
</footer>
Expand Down
2 changes: 1 addition & 1 deletion doc/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ <h1 class="page-title">Index</h1>

<span class="jsdoc-message">
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.3.2</a>
on Tue Sep 1st 2015 using the <a
on Wed Sep 2nd 2015 using the <a
href="https://github.com/terryweiss/docstrap">DocStrap template</a>.
</span>
</footer>
Expand Down
73 changes: 41 additions & 32 deletions doc/memorystorage.js.html
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,14 @@ <h1 class="page-title">Source: memorystorage.js</h1>
else {u[m] = d();}
}(this, 'MemoryStorage', function(){
'use strict';


var API = {'clear':1, 'getItem':1, 'key':1, 'length':1, 'removeItem':1, 'setItem':1},
API_LENGTH = Object.keys(API).length,
CLOAK = '__memorystorage_cloaked_items__';

// Used to store all data
var storage = {};

/** @module memorystorage */

/**
Expand All @@ -83,58 +90,60 @@ <h1 class="page-title">Source: memorystorage.js</h1>
* storage object will only show up in other memory storage objects that have been created with
* the same id. This data will not show up in the &lt;code>global&lt;/code> memory space. As such it
* is recommended to always construct a memory storage object with a unique string id as argument.&lt;/p>
*
* &lt;p>An options object may be passed as the second argument. At the moment only one option is available:&lt;/p>
*
* &lt;table>
* &lt;tr>&lt;th>Name&lt;/th>&lt;th>Type&lt;/th>&lt;th>Default&lt;/th>&lt;tr>
* &lt;tr>&lt;td>idKey&lt;/td>&lt;td>String&lt;/td>&lt;td>'memId'&lt;/td>&lt;tr>
* &lt;/table>
*
* @param id Optional string argument used to isolate this memory storage object from others.
* @param options Optional options object.
*
* @alias module:memorystorage.MemoryStorage
* @class
*/
function MemoryStorage(id, options) {
var idKey = options &amp;&amp; options.idKey || 'memId';
this[idKey] = id || 'global';
if (!storage[this[idKey]]) {storage[this[idKey]] = {};}
var keys = Object.keys(storage[this[idKey]]);
function MemoryStorage(id) {
id = id || 'global';
var result = storage[id];
if (result) {return result;}

result = storage[id] = this;
// create a space to store 'cloaked' key/values: items that have a key
// that collides with Web Storage API method names.
var cloaked = {};
Object.defineProperty(this, CLOAK, {
enumerable: false,
get: function(){return cloaked;}
});
Object.defineProperty(this, 'length', {
enumerable: true,
get: function(){return keys.length;}
});
get: function(){
return Object.keys(this).length + Object.keys(this[CLOAK]).length - API_LENGTH;
}
});
this.getItem = function MemoryStorage_getItem(key) {
return storage[this[idKey]][key];
return key in API ? this[CLOAK][key] : this[key];
};
this.setItem = function MemoryStorage_setItem(key, val) {
if (! (key in storage[this[idKey]])) {
keys.push(key);
}
storage[this[idKey]][key] = val;
if (key in API) {this[CLOAK][key] = val;}
else {this[key] = val;}
};
this.removeItem = function MemoryStorage_removeItem(key) {
if (key in storage[this[idKey]]) {
keys.splice(keys.indexOf(key), 1);
delete storage[this[idKey]][key];
}
if (key in API) {delete this[CLOAK][key];}
else {delete this[key];}
};
this.key = function MemoryStorage_key(idx) {
var keys = Object.keys(this).concat(Object.keys(this[CLOAK]));
keys = keys.filter(function(x){return !(x in API);});
return idx >= 0 &amp;&amp; idx &lt; keys.length ? keys[idx] : null;
};
this.clear = function MemoryStorage_clear() {
for (var i=0; i&lt;keys.length; i++) {
delete storage[this[idKey]][keys[i]];
var keys = Object.keys(this).filter(function(x){return !(x in API);});
for (var i=0,key; key=keys[i]; i++) {
if (! (key in API)) {delete this[key];}
}
keys = Object.keys(this[CLOAK]);
for (var i=0,key; key=keys[i]; i++) {
delete this[CLOAK][key];
}
keys.splice(0, keys.length);
};
return result;
}

// Used to store all data
var storage = {};

// EXPOSE
return MemoryStorage;
}));
Expand Down Expand Up @@ -167,7 +176,7 @@ <h1 class="page-title">Source: memorystorage.js</h1>

<span class="jsdoc-message">
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.3.2</a>
on Tue Sep 1st 2015 using the <a
on Wed Sep 2nd 2015 using the <a
href="https://github.com/terryweiss/docstrap">DocStrap template</a>.
</span>
</footer>
Expand Down
33 changes: 4 additions & 29 deletions doc/module-memorystorage.MemoryStorage.html
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ <h2>


<dt>
<h4 class="name" id="MemoryStorage"><span class="type-signature"></span>new MemoryStorage<span class="signature">(id, options)</span><span class="type-signature"></span></h4>
<h4 class="name" id="MemoryStorage"><span class="type-signature"></span>new MemoryStorage<span class="signature">(id)</span><span class="type-signature"></span></h4>


</dt>
Expand All @@ -88,14 +88,7 @@ <h4 class="name" id="MemoryStorage"><span class="type-signature"></span>new Memo
will read from and write to it's own segment of memory. Any data written to such a memory
storage object will only show up in other memory storage objects that have been created with
the same id. This data will not show up in the <code>global</code> memory space. As such it
is recommended to always construct a memory storage object with a unique string id as argument.</p>

<p>An options object may be passed as the second argument. At the moment only one option is available:</p>

<table>
<tr><th>Name</th><th>Type</th><th>Default</th><tr>
<tr><td>idKey</td><td>String</td><td>'memId'</td><tr>
</table>
is recommended to always construct a memory storage object with a unique string id as argument.</p>
</div>


Expand Down Expand Up @@ -145,24 +138,6 @@ <h5>Parameters:</h5>
</tr>



<tr>

<td class="name"><code>options</code></td>


<td class="type">

</td>





<td class="description last"><p>Optional options object.</p></td>
</tr>


</tbody>
</table>

Expand Down Expand Up @@ -204,7 +179,7 @@ <h5>Parameters:</h5>
<ul class="dummy">
<li>
<a href="memorystorage.js.html">memorystorage.js</a>,
<a href="memorystorage.js.html#sunlight-1-line-39">line 39</a>
<a href="memorystorage.js.html#sunlight-1-line-38">line 38</a>
</li>
</ul>
</dd>
Expand Down Expand Up @@ -285,7 +260,7 @@ <h5>Parameters:</h5>

<span class="jsdoc-message">
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.3.2</a>
on Tue Sep 1st 2015 using the <a
on Wed Sep 2nd 2015 using the <a
href="https://github.com/terryweiss/docstrap">DocStrap template</a>.
</span>
</footer>
Expand Down
4 changes: 2 additions & 2 deletions doc/module-memorystorage.html
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ <h1 class="page-title">Module: memorystorage</h1>
<ul class="dummy">
<li>
<a href="memorystorage.js.html">memorystorage.js</a>,
<a href="memorystorage.js.html#sunlight-1-line-14">line 14</a>
<a href="memorystorage.js.html#sunlight-1-line-21">line 21</a>
</li>
</ul>
</dd>
Expand Down Expand Up @@ -177,7 +177,7 @@ <h3 class="subsection-title">Classes</h3>

<span class="jsdoc-message">
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.3.2</a>
on Tue Sep 1st 2015 using the <a
on Wed Sep 2nd 2015 using the <a
href="https://github.com/terryweiss/docstrap">DocStrap template</a>.
</span>
</footer>
Expand Down
2 changes: 1 addition & 1 deletion doc/modules.list.html
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ <h3 class="subsection-title">Classes</h3>

<span class="jsdoc-message">
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.3.2</a>
on Tue Sep 1st 2015 using the <a
on Wed Sep 2nd 2015 using the <a
href="https://github.com/terryweiss/docstrap">DocStrap template</a>.
</span>
</footer>
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "memorystorage",
"version": "0.9.5",
"version": "0.9.6",
"description": "Memory-backed implementation of the Web Storage API",
"main": "src/memorystorage.js",
"dist": {
Expand Down
71 changes: 40 additions & 31 deletions src/memorystorage.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,14 @@
else {u[m] = d();}
}(this, 'MemoryStorage', function(){
'use strict';


var API = {'clear':1, 'getItem':1, 'key':1, 'length':1, 'removeItem':1, 'setItem':1},
API_LENGTH = Object.keys(API).length,
CLOAK = '__memorystorage_cloaked_items__';

// Used to store all data
var storage = {};

/** @module memorystorage */

/**
Expand All @@ -22,58 +29,60 @@
* storage object will only show up in other memory storage objects that have been created with
* the same id. This data will not show up in the <code>global</code> memory space. As such it
* is recommended to always construct a memory storage object with a unique string id as argument.</p>
*
* <p>An options object may be passed as the second argument. At the moment only one option is available:</p>
*
* <table>
* <tr><th>Name</th><th>Type</th><th>Default</th><tr>
* <tr><td>idKey</td><td>String</td><td>'memId'</td><tr>
* </table>
*
* @param id Optional string argument used to isolate this memory storage object from others.
* @param options Optional options object.
*
* @alias module:memorystorage.MemoryStorage
* @class
*/
function MemoryStorage(id, options) {
var idKey = options && options.idKey || 'memId';
this[idKey] = id || 'global';
if (!storage[this[idKey]]) {storage[this[idKey]] = {};}
var keys = Object.keys(storage[this[idKey]]);
function MemoryStorage(id) {
id = id || 'global';
var result = storage[id];
if (result) {return result;}

result = storage[id] = this;
// create a space to store 'cloaked' key/values: items that have a key
// that collides with Web Storage API method names.
var cloaked = {};
Object.defineProperty(this, CLOAK, {
enumerable: false,
get: function(){return cloaked;}
});
Object.defineProperty(this, 'length', {
enumerable: true,
get: function(){return keys.length;}
});
get: function(){
return Object.keys(this).length + Object.keys(this[CLOAK]).length - API_LENGTH;
}
});
this.getItem = function MemoryStorage_getItem(key) {
return storage[this[idKey]][key];
return key in API ? this[CLOAK][key] : this[key];
};
this.setItem = function MemoryStorage_setItem(key, val) {
if (! (key in storage[this[idKey]])) {
keys.push(key);
}
storage[this[idKey]][key] = val;
if (key in API) {this[CLOAK][key] = val;}
else {this[key] = val;}
};
this.removeItem = function MemoryStorage_removeItem(key) {
if (key in storage[this[idKey]]) {
keys.splice(keys.indexOf(key), 1);
delete storage[this[idKey]][key];
}
if (key in API) {delete this[CLOAK][key];}
else {delete this[key];}
};
this.key = function MemoryStorage_key(idx) {
var keys = Object.keys(this).concat(Object.keys(this[CLOAK]));
keys = keys.filter(function(x){return !(x in API);});
return idx >= 0 && idx < keys.length ? keys[idx] : null;
};
this.clear = function MemoryStorage_clear() {
for (var i=0; i<keys.length; i++) {
delete storage[this[idKey]][keys[i]];
var keys = Object.keys(this).filter(function(x){return !(x in API);});
for (var i=0,key; key=keys[i]; i++) {
if (! (key in API)) {delete this[key];}
}
keys = Object.keys(this[CLOAK]);
for (var i=0,key; key=keys[i]; i++) {
delete this[CLOAK][key];
}
keys.splice(0, keys.length);
};
return result;
}

// Used to store all data
var storage = {};

// EXPOSE
return MemoryStorage;
}));
5 changes: 3 additions & 2 deletions tests/index.html
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
<!DOCTYPE html>
<html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>MemoryStorage Tests</title>
<script src="../dist/memorystorage.min.js"></script>
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-1.14.0.css">
<body>
<a style="font-size:xx-large;" href="test-memorystorage.html">Restart</a>
<h1>Test MemoryStorage</h1>
<h3>MemoryStorage as separate module</h3>
<h1>MemoryStorage Tests</h1>
<h3>W3C Web Storage API Compliance Test</h3>
<a href="test.js">Test code</a>
<script src="http://code.jquery.com/qunit/qunit-1.14.0.js"></script>
<script src="test.js"></script>
Expand Down
Loading

0 comments on commit d2b1047

Please sign in to comment.