angular-cached-resource
Version:
An AngularJS module to interact with RESTful resources, even when browser is offline
230 lines (215 loc) • 8.06 kB
JavaScript
// Generated by CoffeeScript 1.7.1
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) {
this.CachedResource = CachedResource;
this.$timeout = $timeout;
this.key = "" + this.CachedResource.$key + "/write";
this.queue = Cache.getItem(this.key, []);
resetDeferred(this);
if (this.queue.length === 0) {
resolveDeferred(this);
}
}
ResourceWriteQueue.prototype.enqueue = function(params, resourceData, action, deferred) {
var resourceParams, write, _ref, _ref1;
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, params, write, _i, _len, _ref;
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, newQueue, params, _i, _len, _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 write, _i, _len, _ref, _results;
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 notDone, write, _i, _len, _ref, _results;
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 write, _i, _len, _ref, _results;
_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 (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 cacheEntry, _i, _len, _ref;
_this.removeWrite(write);
for (_i = 0, _len = cacheEntries.length; _i < _len; _i++) {
cacheEntry = cacheEntries[_i];
cacheEntry.setClean();
}
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 + " (" + error.config.method + " to " + error.config.url + ") failed with error " + error.status);
} else {
_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);
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;
})();
};