store.js
* Generic Key-Value, Namespace-based Store
* @author Hermann Mayer <hermann.mayer92@gmail.com>
* @param {Array} namespaces - Namespaces to register
var Store = function(namespaces)
if (namespaces && util.isArray(namespaces)) {
namespaces.forEach(function(namespace) {
self.namespaces[namespace] = {};
* Return the value of a given key and its given namespace.
* @param {String} [namespace] - Namespace or the default-namespace
* @param {String} key - Key to get
Store.prototype.get = function()
throw new Error('Arguments are not correctly set');
var escapeRegExp = function(string) {
return string.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
// Check for wildcards and globstars
if (/\.\*$|\.\*\*$|\.\*\.|\.\*\*\./.test(key)) {
var searchKey = escapeRegExp(key);
// Check for wildcard on path end
searchKey = searchKey.replace(/\\\.\\\*$/, '\\.[^.]+$');
// Check for globstars on path end
searchKey = searchKey.replace(/\\\.\\\*\\\*$/, '\\..*');
// Check for wildcard on path inner
searchKey = searchKey.replace(/\\\.\\\*\\\./, '\\.[^.]+\\.');
// Check for globstars on path inner
searchKey = searchKey.replace(/\\\.\\\*\\\*\\\./, '\\..*\\.');
// Assemble the regular expression
var searchRegExp = new RegExp(searchKey);
// Prepare prefix stripping to
var prefix = key.replace(/([^*]+)\.\*(.*)/, '$1.');
matches = this.list(namespace).filter(function(path) {
return searchRegExp.test(path);
map = matches.reduce(function(base, key) {
var strippedKey = key.replace(prefix, '');
var parts = strippedKey.split('.');
// Assemble the map - we can handle flat
// mappings as well as deep mappings
for (var i = 0; i < parts.length; i++) {
this.namespaces[namespace][key]
* Set the value of a given key and its given namespace.
* @param {String} [namespace] - Namespace or the default-namespace
* @param {String} key - Key to write to
* @param {String} value - Value to set upon the key
Store.prototype.set = function()
throw new Error('Arguments are not correctly set');
if (!this.namespaces[namespace]) {
throw new Error('Namespace "' + namespace + '" was not registered');
this.namespaces[namespace][key] = value;
* List all keys in a given namespace.
* @param {String} [namespace] - Namespace or the default-namespace
Store.prototype.list = function(namespace)
namespace = namespace || 'default';
if (!this.namespaces[namespace]) {
throw new Error('Namespace "' + namespace + '" was not registered');