Skip to content

Commit

Permalink
Fixed #1: Storages have no existing elements when they are instantiat…
Browse files Browse the repository at this point in the history
…ed the first time
  • Loading branch information
jherax committed Nov 17, 2016
1 parent c4600f6 commit f395391
Show file tree
Hide file tree
Showing 7 changed files with 245 additions and 189 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# 1.0.1

### Fixes

1. Fixed [#1](https://github.com/jherax/proxy-storage/issues/1): Storages have no existing elements when they are instantiated the first time

# 1.0.0

### Features
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ const data = {
platform: 'Linux x86_64',
};
const options = {
path: '/profile',
path: '/jherax',
expires: { hours: 6 }
};

Expand Down
216 changes: 122 additions & 94 deletions dist/proxy-storage.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ return /******/ (function(modules) { // webpackBootstrap
value: true
});

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
Expand All @@ -85,6 +87,25 @@ return /******/ (function(modules) { // webpackBootstrap
// If you want to support all ES6 features, uncomment the next line
// import 'babel-polyfill';

/**
* @private
*
* Proxy for the default cookie storage associated with the current document.
*
* @Reference
* https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie
*
* @type {object}
*/
var $cookie = {
get: function get() {
return document.cookie;
},
set: function set(value) {
document.cookie = value;
}
};

/**
* @private
*
Expand All @@ -99,10 +120,53 @@ return /******/ (function(modules) { // webpackBootstrap
var _proxy = {
localStorage: window.localStorage,
sessionStorage: window.sessionStorage,
cookieStorage: cookieStorage(),
memoryStorage: memoryStorage()
cookieStorage: initApi(cookieStorage()),
memoryStorage: initApi(memoryStorage())
};

/**
* @private
*
* Adds the current elements in the storage object
*
* @param {object} api: the API to initialize
* @return {object}
*/
function initApi(api) {
// sets read-only and non-enumerable properties
for (var prop in api) {
// eslint-disable-line
if (prop !== 'initialize') setProperty(api, prop);
}
api.initialize();
// this method is removed after being invoked
// because is not part of the Web Storage interface
delete api.initialize;
return api;
}

/**
* @private
*
* Creates a non-enumerable read-only property.
*
* @param {object} obj: the object to add the property
* @param {string} name: the name of the property
* @param {any} value: the value of the property
* @return {void}
*/
function setProperty(obj, name, value) {
var descriptor = {
configurable: false,
enumerable: false,
writable: false
};
if (typeof value !== 'undefined') {
descriptor.value = value;
}
Object.defineProperty(obj, name, descriptor);
}

/**
* @private
*
Expand All @@ -118,6 +182,8 @@ return /******/ (function(modules) { // webpackBootstrap
};

/**
* @private
*
* Executes the interceptors of a WebStorage method
*
* @param {string} command: name of the method to intercept
Expand Down Expand Up @@ -147,25 +213,6 @@ return /******/ (function(modules) { // webpackBootstrap
}
}

/**
* @private
*
* Creates a non-enumerable read-only property.
*
* @param {object} obj: the object to add the property
* @param {string} name: the name of the property
* @param {any} value: the value of the property
* @return {void}
*/
function setProperty(obj, name, value) {
Object.defineProperty(obj, name, {
configurable: false,
enumerable: false,
writable: false,
value: value
});
}

/**
* @public
*
Expand All @@ -187,12 +234,23 @@ return /******/ (function(modules) { // webpackBootstrap
* @memberOf WebStorage
*/
function WebStorage(storageType) {
var _this = this;

_classCallCheck(this, WebStorage);

if (!_proxy.hasOwnProperty(storageType)) {
throw new Error('Storage type "' + storageType + '" is not valid');
}
setProperty(this, '__storage', _proxy[storageType]);
setProperty(this, '__storage__', storageType);
// copies all existing elements in the storage
Object.keys(_proxy[storageType]).forEach(function (key) {
var value = _proxy[storageType][key];
try {
_this[key] = JSON.parse(value);
} catch (e) {
_this[key] = value;
}
});
}
/**
* Stores a value given a key name.
Expand All @@ -213,7 +271,7 @@ return /******/ (function(modules) { // webpackBootstrap
this[key] = value;
executeInterceptors('setItem', key, value, options);
value = JSON.stringify(value);
this.__storage.setItem(key, value, options);
_proxy[this.__storage__].setItem(key, value, options);
}
/**
* Retrieves a value by its key name.
Expand All @@ -229,8 +287,8 @@ return /******/ (function(modules) { // webpackBootstrap
value: function getItem(key) {
checkEmpty(key);
executeInterceptors('getItem', key);
var value = JSON.parse(this.__storage.getItem(key));
return value;
var value = _proxy[this.__storage__].getItem(key);
return JSON.parse(value);
}
/**
* Deletes a key from the storage.
Expand All @@ -247,7 +305,7 @@ return /******/ (function(modules) { // webpackBootstrap
checkEmpty(key);
delete this[key];
executeInterceptors('removeItem', key);
this.__storage.removeItem(key);
_proxy[this.__storage__].removeItem(key);
}
/**
* Removes all keys from the storage.
Expand All @@ -260,13 +318,13 @@ return /******/ (function(modules) { // webpackBootstrap
}, {
key: 'clear',
value: function clear() {
var _this = this;
var _this2 = this;

executeInterceptors('clear');
Object.keys(this).forEach(function (key) {
return delete _this[key];
return delete _this2[key];
});
this.__storage.clear();
_proxy[this.__storage__].clear();
}
/**
* Gets the number of data items stored in the Storage object.
Expand Down Expand Up @@ -325,14 +383,6 @@ return /******/ (function(modules) { // webpackBootstrap
*/
var storage = null;

/**
* @private
*
* Current storage type
* @type {string}
*/
var _currentStorageName = null;

/**
* @public
*
Expand All @@ -341,7 +391,7 @@ return /******/ (function(modules) { // webpackBootstrap
*/
var configStorage = {
get: function get() {
return _currentStorageName;
return storage.__storage__;
},


Expand All @@ -355,7 +405,6 @@ return /******/ (function(modules) { // webpackBootstrap
throw new Error('Storage type "' + storageType + '" is not valid');
}
exports.default = storage = new WebStorage(storageType);
_currentStorageName = storageType;
}
};

Expand Down Expand Up @@ -411,21 +460,15 @@ return /******/ (function(modules) { // webpackBootstrap
/**
* @private
*
* Alias for the default cookie storage associated with the current document.
*
* @Reference
* https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie
*
* @type {object}
* Callback that finds an element in the array.
* @param {string} cookie: key=value
* @return {boolean}
*/
var $cookie = {
get: function get() {
return document.cookie;
},
set: function set(value) {
document.cookie = value;
}
};
function findCookie(cookie) {
var nameEQ = this.toString();
// prevent leading spaces before the key
return cookie.trim().indexOf(nameEQ) === 0;
}

/**
* @private
Expand All @@ -448,7 +491,7 @@ return /******/ (function(modules) { // webpackBootstrap
$cookie.set(cookie);
},
getItem: function getItem(key) {
var value = null;
var value = void 0;
var nameEQ = key + '=';
var cookie = $cookie.get().split(';').find(findCookie, nameEQ);
if (cookie) {
Expand All @@ -473,36 +516,19 @@ return /******/ (function(modules) { // webpackBootstrap
api.removeItem(key.trim());
}
});
},
initialize: function initialize() {
$cookie.get().split(';').forEach(function (cookie) {
var index = cookie.indexOf('=');
var key = cookie.substring(0, index).trim();
var value = cookie.substring(index + 1).trim();
api[key] = decodeURIComponent(value);
});
}
};
return api;
}

/**
* @private
*
* Callback that finds an element in the array.
* @param {string} cookie: key=value
* @return {boolean}
*/
function findCookie(cookie) {
var nameEQ = this.toString();
// prevent leading spaces before the key
return cookie.trim().indexOf(nameEQ) === 0;
}

/**
* @private
*
* Callback that finds an element in the array.
* @param {object} item: {key, value}
* @return {boolean}
*/
function findItem(item) {
var key = this.toString();
return item.key === key;
}

/**
* @private
*
Expand All @@ -516,23 +542,24 @@ return /******/ (function(modules) { // webpackBootstrap
var hashtable = getStoreFromWindow();
var api = {
setItem: function setItem(key, value) {
var item = hashtable.find(findItem, key);
if (item) item.value = value;else hashtable.push({ key: key, value: value });
hashtable[key] = value;
setStoreToWindow(hashtable);
},
getItem: function getItem(key) {
var item = hashtable.find(findItem, key);
if (item) return item.value;
return null;
return hashtable[key];
},
removeItem: function removeItem(key) {
var index = hashtable.findIndex(findItem, key);
if (index > -1) hashtable.splice(index, 1);
delete hashtable[key];
setStoreToWindow(hashtable);
},
clear: function clear() {
hashtable.length = 0;
Object.keys(hashtable).forEach(function (key) {
return delete hashtable[key];
});
setStoreToWindow(hashtable);
},
initialize: function initialize() {
Object.assign(api, hashtable);
}
};
return api;
Expand All @@ -541,22 +568,23 @@ return /******/ (function(modules) { // webpackBootstrap
/**
* @private
*
* Gets the hashtable store from the current window.
* @return {array}
* Gets the hashtable-store from the current window.
* @return {object}
*/
function getStoreFromWindow() {
try {
var store = JSON.parse(window.self.name);
if (store instanceof Array) return store;
} catch (e) {} // eslint-disable-line
return []; /* {key,value} */
if (store && (typeof store === 'undefined' ? 'undefined' : _typeof(store)) === 'object') return store;
} catch (e) {
return {};
}
}

/**
* @private
*
* Saves the hashtable store in the current window.
* @param {array} hashtable: list of objects stored in memoryStorage
* Saves the hashtable-store in the current window.
* @param {object} hashtable: {key,value} pairs stored in memoryStorage
* @return {void}
*/
function setStoreToWindow(hashtable) {
Expand Down
Loading

0 comments on commit f395391

Please sign in to comment.