<commit_before>dom-module#maki-datastore
  script(src="/js/json-patch-duplex.min.js")
  script.
    Polymer({
      is: 'maki-datastore',
      properties: {
        name: { 
          type: String
        },
        store: {
          type: Object
        },
        private: {
          type: Boolean
        },
        resources: {
          type: Object,
          value: {}
        }
      },
      listeners: {
        'datastore:miss':   '_handleMiss',
        'datastore:change': '_handleChange'
      },
      _populate: function(obj, stack) {
        var self = this;
        for (var property in obj) {
          if (obj.hasOwnProperty(property)) {
            if (typeof obj[property] === 'object') {
              return self._populate(obj[property], stack);
            } else {
              
            }
          }
        }
      },
      _store: function(key, val, cb) {
        var self = this;
        console.log('[MAKI:DATASTORE]', '_store', typeof val, key, val);
        if (val instanceof Array && val.length === 0) return cb('Empty array not allowed.');
        self.store.put(key, val, function(err) {
          if (err) console.error(err);
          self.fire('datastore:change', {
            key: key,
            val: val
          });
          return cb(err);
        });
      },
      _retrieve: function(key, cb) {
        var self = this;
        console.log('[MAKI:DATASTORE]', '_retrieve looking for:', key);
        self.store.get(key, {
          asBuffer: false
        }, function(err, val) {
          if (err) console.error(err);
          if (val) return cb(null, val);
          self.fire('datastore:miss', key);
          return cb('datastore:miss');
        });
      },
      _patch: function(key, ops, cb) {
        var self = this;
        console.log('[MAKI:DATASTORE]', 'datastore:patch:', key, ops);
        self._retrieve(key, function(err, obj) {
          if (err) console.error(err);
          console.log('[MAKI:DATASTORE]', 'applying to:', obj);
          jsonpatch.apply(obj, ops);
          console.log('[MAKI:DATASTORE]', 'obj now:', obj);
          self._store(key, obj, function(err) {
            if (err) console.error(err);
          });
        });
      },
      _handleMiss: function(e, detail) {
        var self = this;
        var key = e.detail;

        console.log('[MAKI:DATASTORE]', '_handleMiss', e, detail);
        console.log('private:', self.private);
        if (self.private) return;

        $.getJSON(key, function(data) {
          console.log('[MAKI:DATASTORE]', 'retrieved (from remote)', data);
          if (!data) return;
          self._store(key, data, function(err) {
            if (err) console.error('[MAKI:DATASTORE]', '_handeMiss error:', err);
          });
        });
      },
      _handleChange: function(e, detail) {
        var self = this;
        var key = detail.key;
        var val = detail.val;
        <commit_msg>Always fall back to server.<commit_after>dom-module#maki-datastore
  script(src="/js/json-patch-duplex.min.js")
  script.
    Polymer({
      is: 'maki-datastore',
      properties: {
        name: { 
          type: String
        },
        store: {
          type: Object
        },
        private: {
          type: Boolean
        },
        resources: {
          type: Object,
          value: {}
        }
      },
      listeners: {
        'datastore:miss':   '_handleMiss',
        'datastore:change': '_handleChange'
      },
      _populate: function(obj, stack) {
        var self = this;
        for (var property in obj) {
          if (obj.hasOwnProperty(property)) {
            if (typeof obj[property] === 'object') {
              return self._populate(obj[property], stack);
            } else {
              
            }
          }
        }
      },
      _store: function(key, val, cb) {
        var self = this;
        console.log('[MAKI:DATASTORE]', '_store', typeof val, key, val);
        if (val instanceof Array && val.length === 0) return cb('Empty array not allowed.');
        self.store.put(key, val, function(err) {
          if (err) console.error(err);
          self.fire('datastore:change', {
            key: key,
            val: val
          });
          return cb(err);
        });
      },
      _retrieve: function(key, cb) {
        var self = this;
        console.log('[MAKI:DATASTORE]', '_retrieve looking for:', key);
        self.store.get(key, {
          asBuffer: false
        }, function(err, val) {
          if (err) console.error(err);
          if (val) return cb(null, val) && self.fire('datastore:miss', key);
          self.fire('datastore:miss', key);
          return cb('datastore:miss');
        });
      },
      _patch: function(key, ops, cb) {
        var self = this;
        console.log('[MAKI:DATASTORE]', 'datastore:patch:', key, ops);
        self._retrieve(key, function(err, obj) {
          if (err) console.error(err);
          console.log('[MAKI:DATASTORE]', 'applying to:', obj);
          jsonpatch.apply(obj, ops);
          console.log('[MAKI:DATASTORE]', 'obj now:', obj);
          self._store(key, obj, function(err) {
            if (err) console.error(err);
          });
        });
      },
      _handleMiss: function(e, detail) {
        var self = this;
        var key = e.detail;
        console.log('[MAKI:DATASTORE]', '_handleMiss', e, detail);
        if (self.private) return;
        
        // TODO: query network instead of server
        $.getJSON(key, function(data) {
          console.log('[MAKI:DATASTORE]', 'retrieved (from remote)', data);
          if (!data) return;
          self._store(key, data, function(err) {
            if (err) console.error('[MAKI:DATASTORE]', '_handeMiss error:', err);
          });
        });
      },
      _handleChange: function(e, detail) {
        var self = this;
        var key = detail.key;
        var val = detail.val;
        
{'fraction_non_alphanumeric': 0.15016028344862495, 'fraction_numerical': 0.0003374388392103931, 'mean_word_length': 1.7118023787740164, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2327497', 'n_tokens_mistral': 1826, 'n_tokens_neox': 1806, 'n_words': 396}