/**
 * Superstore synchronous library
 *
 * @author Matt Andrews <matthew.andrews@ft.com>
 * @copyright The Financial Times [All Rights Reserved]
 */

var escapeRegex = require('escape-regexp-component');

var keys = {};
var store = {};
var persist = true;

// Watch for changes from other tabs
window.addEventListener("storage", function(e) {
  if (keys[e.key]) {
    keys[e.key] = true;
    store[e.key] = JSON.parse(e.newValue);
  }
});

/**
 * get localstorage value for key falling back to in memory for iOS private browsing bug
 * <http://stackoverflow.com/questions/9077101/iphone-localstorage-quota-exceeded-err-issue>
 * @param {String} key
 * @return {*} data for supplied key
 *
 */
exports.get = function(key) {
  if (arguments.length !== 1) {
    throw Error("get expects 1 argument, " + arguments.length + " given; " + key);
  }
  if (!keys[key] && persist) {
    var data;
    try {
      data = localStorage[key];
    } catch(e) {
      persist = false; // Safari 8 with Cookies set to 'Never' throws on every read
    }

    // Slightly weird hack because JSON.parse of an undefined value throws
    // a weird exception "SyntaxError: Unexpected token u"
    if (data) data = JSON.parse(data);
    store[key] = data;
    keys[key] = true;
  }
  return store[key];
};

/**
 * set localstorage key,value falling back to in memory for iOS private browsing bug
 * <http://stackoverflow.com/questions/9077101/iphone-localstorage-quota-exceeded-err-issue>
 * @param {String} key
 * @param {*} value which will be passed via JSON.stringify
 * @return {*} value
 *
 */
exports.set = function(key, value) {
  if (arguments.length !== 2) {
    throw Error("set expects 2 arguments, " + arguments.length + " given; " + key);
  }
  if (persist) {
    try {
      localStorage[key] = JSON.stringify(value);
    } catch(err) {

      // Known iOS Private Browsing Bug - fall back to non-persistent storage
      if (err.code === 22) {
        persist = false;
      } else {
        throw err;
      }
    }
  }

  store[key] = value;
  keys[key] = true;
  return value;
};


/**
 * unset value in store for key
 * @param {String} key
 */
exports.unset = function(key) {
  delete store[key];
  delete keys[key];
  localStorage.removeItem(key);
};

/**
 * clear localstorage
 * @param clearPrefix will clear keys starting with `clearPrefix`
 * #clear(true) and #clear() clear cache and persistent layer, #clear(false) only clears cache
 *
 */
exports.clear = function(clearPrefix) {
  if (!clearPrefix) {
    if (persist) {
      localStorage.clear();
    }
    store = {};
    keys = {};
    return;
  }

  clearPrefix = escapeRegex(clearPrefix);
  var clearKeyRegex = new RegExp("^" + clearPrefix);
  for (var key in keys) {
    if (key.match(clearKeyRegex)) {
      this.unset(key);
    }
  }
};

@@ -166,43 +166,93 @@
 x = 
-require('escape-regexp-component
+function(str)%7B%0A  return String(str).replace(/(%5B.*+?=%5E!:$%7B%7D()%7C%5B%5C%5D%5C/%5C%5C%5D)/g, '%5C%5C$1
 ');
+%0A%7D;
 %0A%0Ava
@@ -484,16 +484,77 @@
  %7D%0A%7D);%0A%0A
+function Superstore(type) %7B%0A%09this.storage = window%5Btype%5D;%0A%7D%0A%0A
 /**%0A * g
@@ -798,23 +798,36 @@
 %0A *%0A */%0A
-exports
+Superstore.prototype
 .get = f
@@ -1028,22 +1028,22 @@
  data = 
-localS
+this.s
 torage%5Bk
@@ -1695,23 +1695,36 @@
 %0A *%0A */%0A
-exports
+Superstore.prototype
 .set = f
@@ -1894,30 +1894,30 @@
 try %7B%0A      
-localS
+this.s
 torage%5Bkey%5D 
@@ -2272,23 +2272,36 @@
 key%0A */%0A
-exports
+Superstore.prototype
 .unset =
@@ -2360,22 +2360,22 @@
 key%5D;%0A  
-localS
+this.s
 torage.r
@@ -2592,15 +2592,28 @@
  */%0A
-exports
+Superstore.prototype
 .cle
@@ -2692,14 +2692,14 @@
     
-localS
+this.s
 tora
@@ -2954,11 +2954,126 @@
   %7D%0A  %7D%0A
-
 %7D;%0A
+%0Amodule.exports.local = new Superstore('localStorage');%0Amodule.exports.session = new Superstore('sessionStorage');%0A

Refactor lib to be agnostic of storage type