-
Notifications
You must be signed in to change notification settings - Fork 42
/
Copy pathpromise.cacheable.decorator.js
128 lines (128 loc) · 6.66 KB
/
promise.cacheable.decorator.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
"use strict";
exports.__esModule = true;
var rxjs_1 = require("rxjs");
var common_1 = require("./common");
exports.promiseGlobalCacheBusterNotifier = new rxjs_1.Subject();
var removeCachePair = function (cachePairs, parameters, cacheConfig) {
/**
* if there has been an pending cache pair for these parameters, when it completes or errors, remove it
*/
var _pendingCachePairToRemove = cachePairs.find(function (cp) {
return cacheConfig.cacheResolver(cp.parameters, parameters);
});
cachePairs.splice(cachePairs.indexOf(_pendingCachePairToRemove), 1);
};
function PCacheable(cacheConfig) {
if (cacheConfig === void 0) { cacheConfig = {}; }
return function (_target, _propertyKey, propertyDescriptor) {
var cacheKey = cacheConfig.cacheKey || _target.constructor.name + '#' + _propertyKey;
var oldMethod = propertyDescriptor.value;
if (propertyDescriptor && propertyDescriptor.value) {
var storageStrategy_1 = !cacheConfig.storageStrategy
? new common_1.GlobalCacheConfig.storageStrategy()
: new cacheConfig.storageStrategy();
var pendingCachePairs_1 = [];
/**
* subscribe to the promiseGlobalCacheBusterNotifier
* if a custom cacheBusterObserver is passed, subscribe to it as well
* subscribe to the cacheBusterObserver and upon emission, clear all caches
*/
rxjs_1.merge(exports.promiseGlobalCacheBusterNotifier.asObservable(), cacheConfig.cacheBusterObserver
? cacheConfig.cacheBusterObserver
: rxjs_1.empty()).subscribe(function (_) {
storageStrategy_1.removeAll(cacheKey);
pendingCachePairs_1.length = 0;
});
cacheConfig.cacheResolver = cacheConfig.cacheResolver
? cacheConfig.cacheResolver
: common_1.DEFAULT_CACHE_RESOLVER;
/* use function instead of an arrow function to keep context of invocation */
propertyDescriptor.value = function () {
var _this = this;
var _parameters = [];
for (var _i = 0; _i < arguments.length; _i++) {
_parameters[_i] = arguments[_i];
}
var cachePairs = storageStrategy_1.getAll(cacheKey);
if (!(cachePairs instanceof Promise)) {
cachePairs = Promise.resolve(cachePairs);
}
return cachePairs.then(function (cachePairs) {
var parameters = _parameters.map(function (param) { return param !== undefined ? JSON.parse(JSON.stringify(param)) : param; });
var _foundCachePair = cachePairs.find(function (cp) {
return cacheConfig.cacheResolver(cp.parameters, parameters);
});
var _foundPendingCachePair = pendingCachePairs_1.find(function (cp) {
return cacheConfig.cacheResolver(cp.parameters, parameters);
});
/**
* check if maxAge is passed and cache has actually expired
*/
if (cacheConfig.maxAge && _foundCachePair && _foundCachePair.created) {
if (new Date().getTime() - new Date(_foundCachePair.created).getTime() >
cacheConfig.maxAge) {
/**
* cache duration has expired - remove it from the cachePairs array
*/
storageStrategy_1.removeAtIndex(cachePairs.indexOf(_foundCachePair), cacheKey);
_foundCachePair = null;
}
else if (cacheConfig.slidingExpiration) {
/**
* renew cache duration
*/
_foundCachePair.created = new Date();
storageStrategy_1.updateAtIndex(cachePairs.indexOf(_foundCachePair), _foundCachePair, cacheKey);
}
}
if (_foundCachePair) {
return Promise.resolve(_foundCachePair.response);
}
else if (_foundPendingCachePair) {
return _foundPendingCachePair.response;
}
else {
var response$ = oldMethod.call.apply(oldMethod, [_this].concat(parameters))
.then(function (response) {
removeCachePair(pendingCachePairs_1, parameters, cacheConfig);
/**
* if no maxCacheCount has been passed
* if maxCacheCount has not been passed, just shift the cachePair to make room for the new one
* if maxCacheCount has been passed, respect that and only shift the cachePairs if the new cachePair will make them exceed the count
*/
if (!cacheConfig.shouldCacheDecider ||
cacheConfig.shouldCacheDecider(response)) {
if (!cacheConfig.maxCacheCount ||
cacheConfig.maxCacheCount === 1 ||
(cacheConfig.maxCacheCount &&
cacheConfig.maxCacheCount < cachePairs.length + 1)) {
storageStrategy_1.removeAtIndex(0, cacheKey);
}
storageStrategy_1.add({
parameters: parameters,
response: response,
created: cacheConfig.maxAge ? new Date() : null
}, cacheKey);
}
return response;
})["catch"](function (_) {
removeCachePair(pendingCachePairs_1, parameters, cacheConfig);
});
/**
* cache the stream
*/
pendingCachePairs_1.push({
parameters: parameters,
response: response$,
created: new Date()
});
return response$;
}
});
};
}
return propertyDescriptor;
};
}
exports.PCacheable = PCacheable;
;