const Observable = require('zen-observable');

let data = {};
let handlers = [];

const escapeRegexp = require('escape-regex');

const keyRegex = str => {
  str = str.split('*').map(s => escapeRegexp(s)).join('*');
  return new RegExp('^' + str.replace('*', '.*'));
};

const observable = new Observable(observer => {
  handlers.push(data => observer.next(data));
  let index = handlers.length;
  return () => {
    handlers = [...handlers.slice(0, index), ...handlers.slice(index)];
  };
});

function get(key, options) {
  const value = data[key] || { views: [] };
  return Promise.resolve({
    views: value.views.filter(view => {
      if (options && options.before && view.time > options.before) return false;
      if (options && options.after && view.time < options.after) return false;
      return true;
    }),
  });
}

function keys() {
  return Promise.resolve(Object.keys(data));
}

function put(key, value) {
  data[key] = value;
  handlers.forEach(handler => {
    handler({ key, value });
  });

  return Promise.resolve();
}

async function getAll(options) {
  const value = {};
  const _keys = (await keys()).filter(
    key =>
      options.ignoreWildcard
        ? key.startsWith(options.pathname)
        : key.match(keyRegex(options.pathname))
  );

  for (let key of _keys) {
    value[key] = await get(key, {
      before: options.before,
      after: options.after,
    });
  }

  return Promise.resolve(value);
}

function has(key) {
  return Promise.resolve({}.hasOwnProperty.call(data, key));
}

function clear() {
  data = {};
}

function subscribe(listener) {
  return observable.subscribe(listener);
}

module.exports = { get, put, getAll, has, keys, clear, subscribe };

@@ -3,269 +3,160 @@
 nst 
-Observable = require('zen-observable');%0A%0Alet data = %7B%7D;%0Alet handlers = %5B%5D
+%7B filterViews, filterPaths %7D = require('micro-analytics-adapter-utils')
 ;%0A
-%0A
 const 
-escapeRegexp = require('escape-regex');%0A%0Aconst keyRegex = str
+Observable = require('zen-observable');%0A%0Alet data
  =
-%3E
  %7B
-%0A  str = str.split('*').map(s =%3E escapeRegexp(s)).join('*');%0A  return new RegExp('%5E' + str.replace('*', '.*'));%0A%7D
+%7D;%0Alet handlers = %5B%5D
 ;%0A%0Ac
@@ -481,20 +481,16 @@
 ve(%7B
-%0A   
  views: 
 valu
@@ -489,225 +489,41 @@
 ws: 
-value.views.
 filter
-(view =%3E %7B%0A      if (options && options.before && view.time %3E options.before) return false;%0A      if (options && options.after && view.time %3C options.after) return false;%0A      return true;%0A    %7D),%0A 
+Views(value.views, options)
  %7D);
@@ -812,164 +812,41 @@
 s = 
-(await keys()).filter(%0A    key =%3E%0A      options.ignoreWildcard%0A        ? key.startsWith(options.pathname)%0A        : key.match(keyRegex(options.pathname))%0A  
+filterPaths(await keys(), options
 );%0A%0A

Use adapter-utils filtering in memory adapter