1 | DEFAULT_ACTIONS =
|
2 | get: { method: 'GET', }
|
3 | query: { method: 'GET', isArray: yes }
|
4 | save: { method: 'POST', }
|
5 | remove: { method: 'DELETE', }
|
6 | delete: { method: 'DELETE', }
|
7 |
|
8 | readArrayCache = require './read_array_cache'
|
9 | readCache = require './read_cache'
|
10 | writeCache = require './write_cache'
|
11 |
|
12 | module.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
|
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 |
|
77 |
|
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 |
|
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
|