forked from coolaj86/walnut.js
		
	
		
			
	
	
		
			116 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			116 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 
								 | 
							
								(function (exports) {
							 | 
						||
| 
								 | 
							
								  'use strict';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    var JohnnyCache;
							 | 
						||
| 
								 | 
							
								    var Oauth3 = (exports.OAUTH3 || require('./oauth3'));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /*
							 | 
						||
| 
								 | 
							
								    function batchApiCall(ids, url, handler) {
							 | 
						||
| 
								 | 
							
								      // freshIds, staleIds = ids.filter()
							 | 
						||
| 
								 | 
							
								      // get url but don't cache
							 | 
						||
| 
								 | 
							
								      handler(result, function (id, data) {
							 | 
						||
| 
								 | 
							
								        // put id into result set
							 | 
						||
| 
								 | 
							
								      });
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function create(opts) {
							 | 
						||
| 
								 | 
							
								      var myInstance = {};
							 | 
						||
| 
								 | 
							
								      var conf = {
							 | 
						||
| 
								 | 
							
								        config: opts.config
							 | 
						||
| 
								 | 
							
								      , storage: opts.storage
							 | 
						||
| 
								 | 
							
								      //, caches: {}
							 | 
						||
| 
								 | 
							
								      };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      Object.keys(JohnnyCache.api).forEach(function (key) {
							 | 
						||
| 
								 | 
							
								        myInstance[key] = function () {
							 | 
						||
| 
								 | 
							
								          var args = Array.prototype.slice.call(arguments);
							 | 
						||
| 
								 | 
							
								          args.unshift(conf);
							 | 
						||
| 
								 | 
							
								          return JohnnyCache.api[key].apply(null, args);
							 | 
						||
| 
								 | 
							
								        };
							 | 
						||
| 
								 | 
							
								      });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      return myInstance;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function init(conf) {
							 | 
						||
| 
								 | 
							
								      return conf.storage.get('caches').then(function (result) {
							 | 
						||
| 
								 | 
							
								        conf.caches = result;
							 | 
						||
| 
								 | 
							
								      }, function () {
							 | 
						||
| 
								 | 
							
								        conf.caches = {};
							 | 
						||
| 
								 | 
							
								      });
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function read(conf, id, realFetch, opts) {
							 | 
						||
| 
								 | 
							
								      var refreshWait = conf.config.refreshWait;
							 | 
						||
| 
								 | 
							
								      var uselessWait = conf.config.uselessWait;
							 | 
						||
| 
								 | 
							
								      var fresh;
							 | 
						||
| 
								 | 
							
								      var usable;
							 | 
						||
| 
								 | 
							
								      var now;
							 | 
						||
| 
								 | 
							
								      var promise;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      function fetch() {
							 | 
						||
| 
								 | 
							
								        return realFetch().then(function (result) {
							 | 
						||
| 
								 | 
							
								          if ('string' === typeof result) {
							 | 
						||
| 
								 | 
							
								            // TODO explicit option for strings
							 | 
						||
| 
								 | 
							
								            return Oauth3.PromiseA.reject("expected json, but got a string, which is probably an error");
							 | 
						||
| 
								 | 
							
								          }
							 | 
						||
| 
								 | 
							
								          return fin(result);
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      function fin(value) {
							 | 
						||
| 
								 | 
							
								        promise = null;
							 | 
						||
| 
								 | 
							
								        conf.caches[id] = Date.now();
							 | 
						||
| 
								 | 
							
								        return conf.storage.set(id, value).then(function () {
							 | 
						||
| 
								 | 
							
								          return conf.storage.set('caches', conf.caches).then(function () {
							 | 
						||
| 
								 | 
							
								            return { updated: conf.caches[id], value: value, stale: false };
							 | 
						||
| 
								 | 
							
								          });
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (conf.caches[id] && !(opts && opts.expire)) {
							 | 
						||
| 
								 | 
							
								        now = Date.now();
							 | 
						||
| 
								 | 
							
								        usable = now - conf.caches[id] < uselessWait;
							 | 
						||
| 
								 | 
							
								        fresh = now - conf.caches[id] < refreshWait;
							 | 
						||
| 
								 | 
							
								        if (!fresh) {
							 | 
						||
| 
								 | 
							
								          promise = fetch();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      return conf.storage.get(id).then(function (result) {
							 | 
						||
| 
								 | 
							
								        if ('string' === typeof result) {
							 | 
						||
| 
								 | 
							
								          // TODO explicit option
							 | 
						||
| 
								 | 
							
								          return (promise || fetch());
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (usable) {
							 | 
						||
| 
								 | 
							
								          return Oauth3.PromiseA.resolve({ updated: conf.caches[id], value: result, stale: !fresh });
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								          return (promise || fetch());
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      }, function () {
							 | 
						||
| 
								 | 
							
								        return (promise || fetch());
							 | 
						||
| 
								 | 
							
								      });
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function destroy(conf) {
							 | 
						||
| 
								 | 
							
								      conf.caches = {};
							 | 
						||
| 
								 | 
							
								      return conf.storage.clear();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    JohnnyCache = {
							 | 
						||
| 
								 | 
							
								      create: create
							 | 
						||
| 
								 | 
							
								    , api: {
							 | 
						||
| 
								 | 
							
								        init: init
							 | 
						||
| 
								 | 
							
								      , read: read
							 | 
						||
| 
								 | 
							
								      , destroy: destroy
							 | 
						||
| 
								 | 
							
								      , clear: destroy
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								    exports.JohnnyCache = JohnnyCache.JohnnyCache = JohnnyCache;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if ('undefined' !== typeof module) {
							 | 
						||
| 
								 | 
							
								      module.exports = JohnnyCache;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}('undefined' !== typeof exports ? exports : window));
							 |