UNPKG

angular-cached-resource

Version:

An AngularJS module to interact with RESTful resources, even when browser is offline

254 lines (239 loc) 8.79 kB
// Generated by CoffeeScript 1.10.0 var CACHE_RETRY_TIMEOUT; CACHE_RETRY_TIMEOUT = 60000; module.exports = function(providerParams, $q) { var $log, Cache, ResourceCacheEntry, ResourceWriteQueue, flushQueueDeferreds, resetDeferred, resolveDeferred; $log = providerParams.$log; ResourceCacheEntry = require('./resource_cache_entry')(providerParams); Cache = require('./cache')(providerParams); flushQueueDeferreds = {}; resetDeferred = function(queue) { var deferred; deferred = $q.defer(); flushQueueDeferreds[queue.key] = deferred; queue.promise = deferred.promise; return deferred; }; resolveDeferred = function(queue) { return flushQueueDeferreds[queue.key].resolve(); }; return ResourceWriteQueue = (function() { ResourceWriteQueue.prototype.logStatusOfRequest = function(status, action, params, data) { return $log.debug(action + " for " + this.key + " " + (angular.toJson(params)) + " " + status + " (queue length: " + this.queue.length + ")", data); }; function ResourceWriteQueue(CachedResource, $timeout) { var i, len, ref, write; this.CachedResource = CachedResource; this.$timeout = $timeout; this.key = this.CachedResource.$key + "/write"; this.queue = Cache.getItem(this.key, []); ref = this.queue; for (i = 0, len = ref.length; i < len; i++) { write = ref[i]; write.busy = false; } resetDeferred(this); if (this.queue.length === 0) { resolveDeferred(this); } } ResourceWriteQueue.prototype.enqueue = function(params, resourceData, action, deferred) { var ref, ref1, resourceParams, write; if (this.queue.length === 0) { resetDeferred(this); } resourceParams = angular.isArray(resourceData) ? resourceData.map(function(resource) { return resource.$params(); }) : resourceData.$params(); write = this.findWrite({ params: params, action: action }); if (write == null) { this.queue.push({ params: params, resourceParams: resourceParams, action: action, deferred: deferred }); this._update(); } else { if ((ref = write.deferred) != null) { ref.promise.then(function(response) { return deferred.resolve(response); }); } if ((ref1 = write.deferred) != null) { ref1.promise["catch"](function(error) { return deferred.reject(error); }); } } return this.logStatusOfRequest('enqueued', action, params, resourceData); }; ResourceWriteQueue.prototype.findWrite = function(arg) { var action, i, len, params, ref, write; action = arg.action, params = arg.params; ref = this.queue; for (i = 0, len = ref.length; i < len; i++) { write = ref[i]; if (action === write.action && angular.equals(params, write.params)) { return write; } } }; ResourceWriteQueue.prototype.removeWrite = function(arg) { var action, entry, i, len, newQueue, params, ref; action = arg.action, params = arg.params; newQueue = []; ref = this.queue; for (i = 0, len = ref.length; i < len; i++) { entry = ref[i]; if (!(action === entry.action && angular.equals(params, entry.params))) { newQueue.push(entry); } } this.queue = newQueue; if (this.queue.length === 0 && this.timeoutPromise) { this.$timeout.cancel(this.timeoutPromise); delete this.timeoutPromise; } this._update(); if (this.queue.length === 0) { return resolveDeferred(this); } }; ResourceWriteQueue.prototype.flush = function(done) { var i, len, ref, results, write; if (angular.isFunction(done)) { this.promise.then(done); } this._setFlushTimeout(); ref = this.queue; results = []; for (i = 0, len = ref.length; i < len; i++) { write = ref[i]; results.push(this._processWrite(write)); } return results; }; ResourceWriteQueue.prototype.processResource = function(params, done) { var i, len, notDone, ref, results, write; notDone = true; ref = this._writesForResource(params); results = []; for (i = 0, len = ref.length; i < len; i++) { write = ref[i]; results.push(this._processWrite(write, (function(_this) { return function() { if (notDone && _this._writesForResource(params).length === 0) { notDone = false; return done(); } }; })(this))); } return results; }; ResourceWriteQueue.prototype._writesForResource = function(params) { var i, len, ref, results, write; ref = this.queue; results = []; for (i = 0, len = ref.length; i < len; i++) { write = ref[i]; if (angular.equals(params, write.params)) { results.push(write); } } return results; }; ResourceWriteQueue.prototype._processWrite = function(write, done) { var cacheEntries, onFailure, onSuccess, writeData; if (write.busy) { return; } write.busy = true; if (angular.isArray(write.resourceParams)) { cacheEntries = write.resourceParams.map((function(_this) { return function(resourceParams) { return new ResourceCacheEntry(_this.CachedResource.$key, resourceParams).load(); }; })(this)); writeData = cacheEntries.map(function(cacheEntry) { return cacheEntry.value; }); } else { cacheEntries = [new ResourceCacheEntry(this.CachedResource.$key, write.resourceParams).load()]; writeData = cacheEntries[0].value; } onSuccess = (function(_this) { return function(value) { var ref; _this.removeWrite(write); if ((ref = write.deferred) != null) { ref.resolve(value); } _this.logStatusOfRequest('succeeded', write.action, write.resourceParams, writeData); if (angular.isFunction(done)) { return done(); } }; })(this); onFailure = (function(_this) { return function(error) { var ref; if (error && error.status >= 400 && error.status < 500) { _this.removeWrite(write); $log.error(write.action + " to " + _this.CachedResource.$key + " failed with error " + error.status, { method: error.config.method, url: error.config.url, writeData: writeData }); } else { write.busy = false; _this.logStatusOfRequest("failed with error " + (angular.toJson(error)) + "; still in queue", write.action, write.resourceParams, writeData); } return (ref = write.deferred) != null ? ref.reject(error) : void 0; }; })(this); this.CachedResource.$resource[write.action](write.params, writeData, onSuccess, onFailure).$promise.then((function(_this) { return function(savedResources) { var cacheEntry, i, len, resource, resourceInstance, results; savedResources = angular.isArray(savedResources) ? savedResources : [savedResources]; results = []; for (i = 0, len = savedResources.length; i < len; i++) { resource = savedResources[i]; resourceInstance = new _this.CachedResource(resource); cacheEntry = new ResourceCacheEntry(_this.CachedResource.$key, resourceInstance.$params()).load(); results.push(cacheEntry.set(resource, false)); } return results; }; })(this)); return this.logStatusOfRequest('processed', write.action, write.resourceParams, writeData); }; ResourceWriteQueue.prototype._setFlushTimeout = function() { if (this.queue.length > 0 && !this.timeoutPromise) { this.timeoutPromise = this.$timeout(angular.bind(this, this.flush), CACHE_RETRY_TIMEOUT); return this.timeoutPromise.then((function(_this) { return function() { delete _this.timeoutPromise; return _this._setFlushTimeout(); }; })(this)); } }; ResourceWriteQueue.prototype._update = function() { var savableQueue; savableQueue = this.queue.map(function(write) { return { params: write.params, resourceParams: write.resourceParams, action: write.action }; }); return Cache.setItem(this.key, savableQueue); }; return ResourceWriteQueue; })(); };