UNPKG

angular-cached-resource

Version:

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

146 lines (114 loc) 5.3 kB
DEFAULT_ACTIONS = get: { method: 'GET', } query: { method: 'GET', isArray: yes } save: { method: 'POST', } remove: { method: 'DELETE', } delete: { method: 'DELETE', } readArrayCache = require './read_array_cache' readCache = require './read_cache' writeCache = require './write_cache' module.exports = buildCachedResourceClass = ($resource, $timeout, $q, providerParams, args) -> {$log} = providerParams ResourceCacheEntry = require('./resource_cache_entry')(providerParams) ResourceCacheArrayEntry = require('./resource_cache_array_entry')(providerParams) ResourceWriteQueue = require('./resource_write_queue')(providerParams, $q) Cache = require('./cache')(providerParams) $key = args.shift() url = args.shift() while args.length arg = args.pop() if angular.isObject(arg[Object.keys(arg)[0]]) actions = arg else paramDefaults = arg actions = angular.extend({}, DEFAULT_ACTIONS, actions) paramDefaults ?= {} boundParams = {} for param, paramDefault of paramDefaults when paramDefault[0] is '@' boundParams[paramDefault.substr(1)] = param Resource = $resource.call(null, url, paramDefaults, actions) isPermissibleBoundValue = (value) -> angular.isDate(value) or angular.isNumber(value) or angular.isString(value) class CachedResource $cache: true # right now this is just a flag, eventually it could be useful for cache introspection (see https://github.com/goodeggs/angular-cached-resource/issues/8) constructor: (attrs) -> angular.extend @, attrs toJSON: -> data = angular.extend {}, @ delete data.$promise delete data.$httpPromise data $params: -> params = {} for attribute, param of boundParams when isPermissibleBoundValue @[attribute] params[param] = @[attribute] params $$addToCache: (dirty = false) -> entry = new ResourceCacheEntry($key, @$params()) entry.set @, dirty @ @$clearCache: ({where, exceptFor, clearPendingWrites, isArray, clearChildren} = {}) -> where ?= null exceptFor ?= null clearPendingWrites ?= false isArray ?= false clearChildren ?= false return $log.error "Using where and exceptFor arguments at once in $clearCache() method is forbidden!" if where && exceptFor cacheKeys = [] translateParamsArrayToEntries = (entries) -> entries ||= [] # Translate where and exceptFor objects to array of objects. # f.e. `{where: {id: 2}}` to `{where: [{id: 2}]}` entries = [entries] unless angular.isArray(entries) entries.map (entry) -> new CachedResource(entry).$params() translateEntriesToCacheKeys = (params_objects) -> params_objects.map (params) -> new ResourceCacheEntry($key, params).fullCacheKey() translateParamsArrayToCacheKeys = (entries) -> translateEntriesToCacheKeys translateParamsArrayToEntries entries if exceptFor || where if isArray cacheArrayEntry = new ResourceCacheArrayEntry($key, exceptFor || where).load() cacheKeys.push cacheArrayEntry.fullCacheKey() if cacheArrayEntry.value && ((exceptFor && !clearChildren) || (where && clearChildren)) entries = (params for params in cacheArrayEntry.value) cacheKeys = cacheKeys.concat(translateEntriesToCacheKeys(entries)) if entries else cacheKeys = translateParamsArrayToCacheKeys(where || exceptFor) if !clearPendingWrites && !where {queue, key} = CachedResource.$writes cacheKeys.push key entries = queue.map (resource) -> resource.resourceParams cacheKeys = cacheKeys.concat translateEntriesToCacheKeys(entries) else if clearPendingWrites && where $log.debug "TODO if clearPendingWrites && where" # TODO clear only those writes, which match :where parameter if where Cache.clear {key: $key, where: cacheKeys} else Cache.clear {key: $key, exceptFor: cacheKeys} @$addToCache: (attrs, dirty) -> new CachedResource(attrs).$$addToCache(dirty) @$addArrayToCache: (attrs, instances, dirty = false) -> instances = instances.map (instance) -> new CachedResource(instance) new ResourceCacheArrayEntry($key, attrs).addInstances instances, dirty @$resource: Resource @$key: $key CachedResource.$writes = new ResourceWriteQueue(CachedResource, $timeout) for actionName, actionConfig of actions method = actionConfig.method.toUpperCase() unless actionConfig.cache is false handler = if method is 'GET' and actionConfig.isArray readArrayCache($q, providerParams, actionName, CachedResource, actionConfig) else if method is 'GET' readCache($q, providerParams, actionName, CachedResource, actionConfig) else if method in ['POST', 'PUT', 'DELETE', 'PATCH'] writeCache($q, providerParams, actionName, CachedResource, actionConfig) CachedResource[actionName] = handler CachedResource::["$#{actionName}"] = handler unless method is 'GET' else CachedResource[actionName] = Resource[actionName] CachedResource::["$#{actionName}"] = Resource::["$#{actionName}"] CachedResource