UNPKG

5.3 kBtext/coffeescriptView Raw
1DEFAULT_ACTIONS =
2 get: { method: 'GET', }
3 query: { method: 'GET', isArray: yes }
4 save: { method: 'POST', }
5 remove: { method: 'DELETE', }
6 delete: { method: 'DELETE', }
7
8readArrayCache = require './read_array_cache'
9readCache = require './read_cache'
10writeCache = require './write_cache'
11
12module.exports = buildCachedResourceClass = ($resource, $timeout, $q, providerParams, args) ->
13 {$log} = providerParams
14 ResourceCacheEntry = require('./resource_cache_entry')(providerParams)
15 ResourceCacheArrayEntry = require('./resource_cache_array_entry')(providerParams)
16 ResourceWriteQueue = require('./resource_write_queue')(providerParams, $q)
17 Cache = require('./cache')(providerParams)
18
19 $key = args.shift()
20 url = args.shift()
21 while args.length
22 arg = args.pop()
23 if angular.isObject(arg[Object.keys(arg)[0]])
24 actions = arg
25 else
26 paramDefaults = arg
27 actions = angular.extend({}, DEFAULT_ACTIONS, actions)
28 paramDefaults ?= {}
29
30 boundParams = {}
31 for param, paramDefault of paramDefaults when paramDefault[0] is '@'
32 boundParams[paramDefault.substr(1)] = param
33
34 Resource = $resource.call(null, url, paramDefaults, actions)
35
36 isPermissibleBoundValue = (value) ->
37 angular.isDate(value) or angular.isNumber(value) or angular.isString(value)
38
39 class CachedResource
40 $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)
41
42 constructor: (attrs) ->
43 angular.extend @, attrs
44
45 toJSON: ->
46 data = angular.extend {}, @
47 delete data.$promise
48 delete data.$httpPromise
49 data
50
51 $params: ->
52 params = {}
53 for attribute, param of boundParams when isPermissibleBoundValue @[attribute]
54 params[param] = @[attribute]
55 params
56
57 $$addToCache: (dirty = false) ->
58 entry = new ResourceCacheEntry($key, @$params())
59 entry.set @, dirty
60 @
61
62 @$clearCache: ({where, exceptFor, clearPendingWrites, isArray, clearChildren} = {}) ->
63 where ?= null
64 exceptFor ?= null
65 clearPendingWrites ?= false
66 isArray ?= false
67 clearChildren ?= false
68
69 return $log.error "Using where and exceptFor arguments at once in $clearCache() method is forbidden!" if where && exceptFor
70
71 cacheKeys = []
72
73 translateParamsArrayToEntries = (entries) ->
74 entries ||= []
75
76 # Translate where and exceptFor objects to array of objects.
77 # f.e. `{where: {id: 2}}` to `{where: [{id: 2}]}`
78 entries = [entries] unless angular.isArray(entries)
79
80 entries.map (entry) ->
81 new CachedResource(entry).$params()
82
83 translateEntriesToCacheKeys = (params_objects) ->
84 params_objects.map (params) ->
85 new ResourceCacheEntry($key, params).fullCacheKey()
86
87 translateParamsArrayToCacheKeys = (entries) ->
88 translateEntriesToCacheKeys translateParamsArrayToEntries entries
89
90 if exceptFor || where
91 if isArray
92 cacheArrayEntry = new ResourceCacheArrayEntry($key, exceptFor || where).load()
93 cacheKeys.push cacheArrayEntry.fullCacheKey()
94
95 if cacheArrayEntry.value && ((exceptFor && !clearChildren) || (where && clearChildren))
96 entries = (params for params in cacheArrayEntry.value)
97 cacheKeys = cacheKeys.concat(translateEntriesToCacheKeys(entries)) if entries
98 else
99 cacheKeys = translateParamsArrayToCacheKeys(where || exceptFor)
100
101 if !clearPendingWrites && !where
102 {queue, key} = CachedResource.$writes
103 cacheKeys.push key
104 entries = queue.map (resource) -> resource.resourceParams
105 cacheKeys = cacheKeys.concat translateEntriesToCacheKeys(entries)
106 else if clearPendingWrites && where
107 $log.debug "TODO if clearPendingWrites && where"
108 # TODO clear only those writes, which match :where parameter
109
110 if where
111 Cache.clear {key: $key, where: cacheKeys}
112 else
113 Cache.clear {key: $key, exceptFor: cacheKeys}
114
115
116 @$addToCache: (attrs, dirty) ->
117 new CachedResource(attrs).$$addToCache(dirty)
118
119 @$addArrayToCache: (attrs, instances, dirty = false) ->
120 instances = instances.map (instance) ->
121 new CachedResource(instance)
122 new ResourceCacheArrayEntry($key, attrs).addInstances instances, dirty
123
124 @$resource: Resource
125 @$key: $key
126
127 CachedResource.$writes = new ResourceWriteQueue(CachedResource, $timeout)
128
129 for actionName, actionConfig of actions
130 method = actionConfig.method.toUpperCase()
131 unless actionConfig.cache is false
132 handler = if method is 'GET' and actionConfig.isArray
133 readArrayCache($q, providerParams, actionName, CachedResource, actionConfig)
134 else if method is 'GET'
135 readCache($q, providerParams, actionName, CachedResource, actionConfig)
136 else if method in ['POST', 'PUT', 'DELETE', 'PATCH']
137 writeCache($q, providerParams, actionName, CachedResource, actionConfig)
138
139 CachedResource[actionName] = handler
140 CachedResource::["$#{actionName}"] = handler unless method is 'GET'
141 else
142 CachedResource[actionName] = Resource[actionName]
143 CachedResource::["$#{actionName}"] = Resource::["$#{actionName}"]
144
145 CachedResource