@kovalenko/http-request-cache 1.0.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/README.md +73 -0
- package/esm2020/lib/http-cache-options.mjs +1 -1
- package/esm2020/lib/http-request-cache.decorator.mjs +39 -4
- package/esm2020/lib/request-times.mjs +15 -0
- package/fesm2015/kovalenko-http-request-cache.mjs +55 -5
- package/fesm2015/kovalenko-http-request-cache.mjs.map +1 -1
- package/fesm2020/kovalenko-http-request-cache.mjs +52 -3
- package/fesm2020/kovalenko-http-request-cache.mjs.map +1 -1
- package/{kovalenko-http-request-cache.d.ts → index.d.ts} +0 -0
- package/lib/http-cache-options.d.ts +2 -0
- package/lib/request-times.d.ts +8 -0
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
## [1.2.1](https://github.com/menelai/http-request-cache/compare/v1.2.0...v1.2.1) (2022-06-28)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* remove items from store ([#25](https://github.com/menelai/http-request-cache/issues/25)) ([c4dc8e8](https://github.com/menelai/http-request-cache/commit/c4dc8e8eeb67c003355940a0991dac74a93d6da1))
|
|
7
|
+
|
|
8
|
+
# [1.2.0](https://github.com/menelai/http-request-cache/compare/v1.1.0...v1.2.0) (2022-06-27)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* TTL option for cache ([#25](https://github.com/menelai/http-request-cache/issues/25)) ([7163fc9](https://github.com/menelai/http-request-cache/commit/7163fc9da90ba3c2d07d675330adca959884e08c))
|
|
14
|
+
|
|
15
|
+
# [1.1.0](https://github.com/menelai/http-request-cache/compare/v1.0.0...v1.1.0) (2022-06-27)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Features
|
|
19
|
+
|
|
20
|
+
* windowTime option ([#24](https://github.com/menelai/http-request-cache/issues/24)) ([31f4a6b](https://github.com/menelai/http-request-cache/commit/31f4a6bd9684e777ac40249604f50b6bfde74b82))
|
|
21
|
+
|
|
1
22
|
# [1.0.0](https://github.com/menelai/http-request-cache/compare/v0.1.11...v1.0.0) (2022-06-02)
|
|
2
23
|
|
|
3
24
|
|
package/README.md
CHANGED
|
@@ -20,6 +20,9 @@ npm install @kovalenko/http-request-cache
|
|
|
20
20
|
|
|
21
21
|
```typescript
|
|
22
22
|
interface HttpCacheOptions {
|
|
23
|
+
refCount?: boolean; // If `refCount` is true, the source will be unsubscribed from once the reference count drops to zero
|
|
24
|
+
windowTime?: number; // Maximum time length of the replay buffer in milliseconds
|
|
25
|
+
ttl?: number; // cache time to live before it will be refreshed. Unlike refreshOn: interval(1000), ttl will not refresh automatically
|
|
23
26
|
storage?: HttpCacheStorage; // if none specified, the default cache object will be used
|
|
24
27
|
refreshOn?: Observable<unknown> | Subject<unknown> | BehaviorSubject<unknown>; // refresh trigger
|
|
25
28
|
}
|
|
@@ -103,6 +106,76 @@ export class DataService {
|
|
|
103
106
|
}
|
|
104
107
|
```
|
|
105
108
|
|
|
109
|
+
### TTL
|
|
110
|
+
|
|
111
|
+
When someone subscribes list() method after TTL period, every subscription is being refreshed
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
@Injectable()
|
|
115
|
+
export class DataService {
|
|
116
|
+
constructor(private http: HttpClient) { }
|
|
117
|
+
|
|
118
|
+
@HttpRequestCache(() => ({
|
|
119
|
+
ttl: 5000
|
|
120
|
+
}))
|
|
121
|
+
list(): Observable<any> {
|
|
122
|
+
return this.http.get('assets/angular.json');
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
@Component({
|
|
128
|
+
selector: 'app-root',
|
|
129
|
+
templateUrl: './app.component.html',
|
|
130
|
+
styleUrls: ['./app.component.scss'],
|
|
131
|
+
})
|
|
132
|
+
export class AppComponent implements OnInit {
|
|
133
|
+
|
|
134
|
+
constructor(
|
|
135
|
+
private http: HttpClient,
|
|
136
|
+
private dataService: DataService
|
|
137
|
+
) { }
|
|
138
|
+
|
|
139
|
+
ngOnInit(): void {
|
|
140
|
+
this.dataService.list().subscribe(g => {
|
|
141
|
+
console.log('1', g);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
// outputs:
|
|
145
|
+
// 1 {...}
|
|
146
|
+
|
|
147
|
+
setTimeout(() => {
|
|
148
|
+
this.dataService.list().subscribe(g => {
|
|
149
|
+
console.log('2', g);
|
|
150
|
+
});
|
|
151
|
+
}, 1000);
|
|
152
|
+
|
|
153
|
+
// outputs:
|
|
154
|
+
// 2 {...}
|
|
155
|
+
|
|
156
|
+
setTimeout(() => {
|
|
157
|
+
this.dataService.list().subscribe(g => {
|
|
158
|
+
console.log('3', g);
|
|
159
|
+
});
|
|
160
|
+
}, 6000);
|
|
161
|
+
|
|
162
|
+
// outputs:
|
|
163
|
+
// 1 {...}
|
|
164
|
+
// 2 {...}
|
|
165
|
+
// 3 {...}
|
|
166
|
+
|
|
167
|
+
setTimeout(() => {
|
|
168
|
+
this.dataService.list().subscribe(g => {
|
|
169
|
+
console.log('4', g);
|
|
170
|
+
});
|
|
171
|
+
}, 8000);
|
|
172
|
+
|
|
173
|
+
// outputs:
|
|
174
|
+
// 4 {...}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
106
179
|
### If cache invalidation is not necessary
|
|
107
180
|
```typescript
|
|
108
181
|
@Injectable()
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export {};
|
|
2
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHR0cC1jYWNoZS1vcHRpb25zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvaHR0cC1yZXF1ZXN0LWNhY2hlL3NyYy9saWIvaHR0cC1jYWNoZS1vcHRpb25zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0JlaGF2aW9yU3ViamVjdCwgT2JzZXJ2YWJsZSwgU3ViamVjdH0gZnJvbSAncnhqcyc7XG5pbXBvcnQge0h0dHBDYWNoZVN0b3JhZ2V9IGZyb20gJy4vaHR0cC1jYWNoZS1zdG9yYWdlJztcblxuZXhwb3J0IGludGVyZmFjZSBIdHRwQ2FjaGVPcHRpb25zIHtcbiAgcmVmQ291bnQ/
|
|
2
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHR0cC1jYWNoZS1vcHRpb25zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvaHR0cC1yZXF1ZXN0LWNhY2hlL3NyYy9saWIvaHR0cC1jYWNoZS1vcHRpb25zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0JlaGF2aW9yU3ViamVjdCwgT2JzZXJ2YWJsZSwgU3ViamVjdH0gZnJvbSAncnhqcyc7XG5pbXBvcnQge0h0dHBDYWNoZVN0b3JhZ2V9IGZyb20gJy4vaHR0cC1jYWNoZS1zdG9yYWdlJztcblxuZXhwb3J0IGludGVyZmFjZSBIdHRwQ2FjaGVPcHRpb25zIHtcbiAgcmVmQ291bnQ/OiBib29sZWFuO1xuICB3aW5kb3dUaW1lPzogbnVtYmVyO1xuICB0dGw/OiBudW1iZXI7XG4gIHN0b3JhZ2U/OiBIdHRwQ2FjaGVTdG9yYWdlO1xuICByZWZyZXNoT24/OiBPYnNlcnZhYmxlPHVua25vd24+IHwgU3ViamVjdDx1bmtub3duPiB8IEJlaGF2aW9yU3ViamVjdDx1bmtub3duPjtcbn1cbiJdfQ==
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { NEVER } from 'rxjs';
|
|
1
|
+
import { filter, finalize, merge, NEVER, Subject, tap } from 'rxjs';
|
|
2
2
|
import { shareReplay, startWith, switchMap } from 'rxjs/operators';
|
|
3
3
|
import { DefaultStorage } from './default-storage';
|
|
4
|
+
import { RequestTimes } from './request-times';
|
|
4
5
|
export const HttpRequestCache = (optionsHandler) => {
|
|
5
6
|
return (target, methodName, descriptor) => {
|
|
6
7
|
if (!(descriptor?.value instanceof Function)) {
|
|
@@ -8,25 +9,59 @@ export const HttpRequestCache = (optionsHandler) => {
|
|
|
8
9
|
}
|
|
9
10
|
const cacheKeyPrefix = `${target.constructor.name}_${methodName}`;
|
|
10
11
|
const originalMethod = descriptor.value;
|
|
12
|
+
const working = {};
|
|
13
|
+
let subscribers = 0;
|
|
11
14
|
descriptor.value = function (...args) {
|
|
12
15
|
const options = optionsHandler?.call(this, this, ...args);
|
|
13
16
|
if (!options?.storage && !target._____storage_____) {
|
|
14
17
|
target._____storage_____ = new DefaultStorage();
|
|
15
18
|
}
|
|
19
|
+
if (options?.ttl && !target._____ttl_storage_____) {
|
|
20
|
+
target._____ttl_storage_____ = new RequestTimes();
|
|
21
|
+
}
|
|
16
22
|
const storage = options?.storage ?? target._____storage_____;
|
|
17
|
-
const refreshOn = options?.refreshOn ?? NEVER;
|
|
18
23
|
const key = `${cacheKeyPrefix}_${JSON.stringify(args)}`;
|
|
24
|
+
let ttl = undefined;
|
|
25
|
+
if (options?.ttl) {
|
|
26
|
+
ttl = target._____ttl_storage_____.getItem(key);
|
|
27
|
+
if (!ttl) {
|
|
28
|
+
ttl = {
|
|
29
|
+
requestTime: Date.now(),
|
|
30
|
+
subject: new Subject(),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
else if (ttl.requestTime + options.ttl <= Date.now()) {
|
|
34
|
+
working[key] = true;
|
|
35
|
+
ttl.requestTime = Date.now();
|
|
36
|
+
ttl.subject.next();
|
|
37
|
+
}
|
|
38
|
+
target._____ttl_storage_____.setItem(key, ttl);
|
|
39
|
+
}
|
|
40
|
+
const refreshOn = merge(options?.refreshOn ?? NEVER, ttl?.subject ?? NEVER);
|
|
19
41
|
let observable = storage.getItem(key);
|
|
20
42
|
if (!observable) {
|
|
21
|
-
observable = refreshOn.pipe(startWith(true), switchMap(() => originalMethod.apply(this, [...args])),
|
|
43
|
+
observable = refreshOn.pipe(startWith(true), switchMap(() => originalMethod.apply(this, [...args])), tap(() => {
|
|
44
|
+
console.log(working);
|
|
45
|
+
delete working[key];
|
|
46
|
+
}), shareReplay({
|
|
22
47
|
bufferSize: 1,
|
|
23
48
|
refCount: options?.refCount ?? false,
|
|
49
|
+
windowTime: options?.windowTime ?? Infinity,
|
|
50
|
+
}), filter(() => {
|
|
51
|
+
return !working[key];
|
|
52
|
+
}), finalize(() => {
|
|
53
|
+
subscribers--;
|
|
54
|
+
if (subscribers === 0 && options?.refCount) {
|
|
55
|
+
storage.deleteItem(key);
|
|
56
|
+
target._____ttl_storage_____?.deleteItem(key);
|
|
57
|
+
}
|
|
24
58
|
}));
|
|
25
59
|
storage.setItem(key, observable);
|
|
26
60
|
}
|
|
61
|
+
subscribers++;
|
|
27
62
|
return observable;
|
|
28
63
|
};
|
|
29
64
|
return descriptor;
|
|
30
65
|
};
|
|
31
66
|
};
|
|
32
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
67
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHR0cC1yZXF1ZXN0LWNhY2hlLmRlY29yYXRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL2h0dHAtcmVxdWVzdC1jYWNoZS9zcmMvbGliL2h0dHAtcmVxdWVzdC1jYWNoZS5kZWNvcmF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBYyxPQUFPLEVBQUUsR0FBRyxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBQzlFLE9BQU8sRUFBQyxXQUFXLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBQ2pFLE9BQU8sRUFBQyxjQUFjLEVBQUMsTUFBTSxtQkFBbUIsQ0FBQztBQUNqRCxPQUFPLEVBQUMsWUFBWSxFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFJN0MsTUFBTSxDQUFDLE1BQU0sZ0JBQWdCLEdBQUcsQ0FBZ0MsY0FBNkQsRUFBRSxFQUFFO0lBQy9ILE9BQU8sQ0FBQyxNQUFTLEVBQUUsVUFBa0IsRUFBRSxVQUEyRCxFQUFtRCxFQUFFO1FBQ3JKLElBQUksQ0FBQyxDQUFDLFVBQVUsRUFBRSxLQUFLLFlBQVksUUFBUSxDQUFDLEVBQUU7WUFDNUMsTUFBTSxLQUFLLENBQUMseUZBQXlGLENBQUMsQ0FBQztTQUN4RztRQUVELE1BQU0sY0FBYyxHQUFHLEdBQUcsTUFBTSxDQUFDLFdBQVcsQ0FBQyxJQUFJLElBQUksVUFBVSxFQUFFLENBQUM7UUFDbEUsTUFBTSxjQUFjLEdBQUcsVUFBVSxDQUFDLEtBQUssQ0FBQztRQUN4QyxNQUFNLE9BQU8sR0FBNEIsRUFBRSxDQUFDO1FBQzVDLElBQUksV0FBVyxHQUFHLENBQUMsQ0FBQztRQUVwQixVQUFVLENBQUMsS0FBSyxHQUFHLFVBQVMsR0FBRyxJQUFXO1lBQ3hDLE1BQU0sT0FBTyxHQUFHLGNBQWMsRUFBRSxJQUFJLENBQUMsSUFBUyxFQUFF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QkFDeEQ7Z0JBQ0gsQ0FBQyxDQUFDLENBQ0gsQ0FBQztnQkFDRixPQUFPLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxVQUFVLENBQUMsQ0FBQzthQUNsQztZQUVELFdBQVcsRUFBRSxDQUFDO1lBRWQsT0FBTyxVQUFVLENBQUM7UUFDcEIsQ0FBQyxDQUFDO1FBRUYsT0FBTyxVQUFVLENBQUM7SUFDcEIsQ0FBQyxDQUFBO0FBQ0gsQ0FBQyxDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtIdHRwQ2FjaGVPcHRpb25zfSBmcm9tICcuL2h0dHAtY2FjaGUtb3B0aW9ucyc7XG5pbXBvcnQge2ZpbHRlciwgZmluYWxpemUsIG1lcmdlLCBORVZFUiwgT2JzZXJ2YWJsZSwgU3ViamVjdCwgdGFwfSBmcm9tICdyeGpzJztcbmltcG9ydCB7c2hhcmVSZXBsYXksIHN0YXJ0V2l0aCwgc3dpdGNoTWFwfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQge0RlZmF1bHRTdG9yYWdlfSBmcm9tICcuL2RlZmF1bHQtc3RvcmFnZSc7XG5pbXBvcnQge1JlcXVlc3RUaW1lc30gZnJvbSAnLi9yZXF1ZXN0LXRpbWVzJztcblxudHlwZSBIdHRwUmVxdWVzdENhY2hlTWV0aG9kID0gKC4uLmFyZ3M6IGFueVtdKSA9PiBPYnNlcnZhYmxlPGFueT47XG5cbmV4cG9ydCBjb25zdCBIdHRwUmVxdWVzdENhY2hlID0gPFQgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBhbnk+PihvcHRpb25zSGFuZGxlcj86IChvYmo6IFQsIC4uLmFyZ3M6IGFueVtdKSA9PiBIdHRwQ2FjaGVPcHRpb25zKSA9PiB7XG4gIHJldHVybiAodGFyZ2V0OiBULCBtZXRob2ROYW1lOiBzdHJpbmcsIGRlc2NyaXB0b3I6IFR5cGVkUHJvcGVydHlEZXNjcmlwdG9yPEh0dHBSZXF1ZXN0Q2FjaGVNZXRob2Q+KTogVHlwZWRQcm9wZXJ0eURlc2NyaXB0b3I8SHR0cFJlcXVlc3RDYWNoZU1ldGhvZD4gPT4ge1xuICAgIGlmICghKGRlc2NyaXB0b3I/LnZhbHVlIGluc3RhbmNlb2YgRnVuY3Rpb24pKSB7XG4gICAgICB0aHJvdyBFcnJvcihgJ0BIdHRwUmVxdWVzdENhY2hlJyBjYW4gYmUgYXBwbGllZCBvbmx5IHRvIHRoZSBjbGFzcyBtZXRob2Qgd2hpY2ggcmV0dXJucyBhbiBPYnNlcnZhYmxlYCk7XG4gICAgfVxuXG4gICAgY29uc3QgY2FjaGVLZXlQcmVmaXggPSBgJHt0YXJnZXQuY29uc3RydWN0b3IubmFtZX1fJHttZXRob2ROYW1lfWA7XG4gICAgY29uc3Qgb3JpZ2luYWxNZXRob2QgPSBkZXNjcmlwdG9yLnZhbHVlO1xuICAgIGNvbnN0IHdvcmtpbmc6IFJlY29yZDxzdHJpbmcsIGJvb2xlYW4+ID0ge307XG4gICAgbGV0IHN1YnNjcmliZXJzID0gMDtcblxuICAgIGRlc2NyaXB0b3IudmFsdWUgPSBmdW5jdGlvbiguLi5hcmdzOiBhbnlbXSk6IE9ic2VydmFibGU8YW55PiB7XG4gICAgICBjb25zdCBvcHRpb25zID0gb3B0aW9uc0hhbmRsZXI/LmNhbGwodGhpcyBhcyBULCB0aGlzIGFzIFQsIC4uLmFyZ3MpO1xuXG4gICAgICBpZiAoIW9wdGlvbnM/LnN0b3JhZ2UgJiYgISh0YXJnZXQgYXMgYW55KS5fX19fX3N0b3JhZ2VfX19fXykge1xuICAgICAgICAodGFyZ2V0IGFzIGFueSkuX19fX19zdG9yYWdlX19fX18gPSBuZXcgRGVmYXVsdFN0b3JhZ2UoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKG9wdGlvbnM/LnR0bCAmJiAhKHRhcmdldCBhcyBhbnkpLl9fX19fdHRsX3N0b3JhZ2VfX19fXykge1xuICAgICAgICAodGFyZ2V0IGFzIGFueSkuX19fX190dGxfc3RvcmFnZV9fX19fID0gbmV3IFJlcXVlc3RUaW1lcygpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBzdG9yYWdlID0gb3B0aW9ucz8uc3RvcmFnZSA/PyAodGFyZ2V0IGFzIGFueSkuX19fX19zdG9yYWdlX19fX187XG5cbiAgICAgIGNvbnN0IGtleSA9IGAke2NhY2hlS2V5UHJlZml4fV8ke0pTT04uc3RyaW5naWZ5KGFyZ3MpfWA7XG5cbiAgICAgIGxldCB0dGw6IHtyZXF1ZXN0VGltZTogbnVtYmVyLCBzdWJqZWN0OiBTdWJqZWN0PHZvaWQ+fSA9IHVuZGVmaW5lZCBhcyBhbnk7XG5cbiAgICAgIGlmIChvcHRpb25zPy50dGwpIHtcbiAgICAgICAgdHRsID0gKHRhcmdldCBhcyBhbnkpLl9fX19fdHRsX3N0b3JhZ2VfX19fXy5nZXRJdGVtKGtleSk7XG5cbiAgICAgICAgaWYgKCF0dGwpIHtcbiAgICAgICAgICB0dGwgPSB7XG4gICAgICAgICAgICByZXF1ZXN0VGltZTogRGF0ZS5ub3coKSxcbiAgICAgICAgICAgIHN1YmplY3Q6IG5ldyBTdWJqZWN0KCksXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIGlmICh0dGwucmVxdWVzdFRpbWUgKyBvcHRpb25zLnR0bCA8PSBEYXRlLm5vdygpKSB7XG4gICAgICAgICAgd29ya2luZ1trZXldID0gdHJ1ZTtcbiAgICAgICAgICB0dGwucmVxdWVzdFRpbWUgPSBEYXRlLm5vdygpO1xuICAgICAgICAgIHR0bC5zdWJqZWN0Lm5leHQoKTtcbiAgICAgICAgfVxuXG4gICAgICAgICh0YXJnZXQgYXMgYW55KS5fX19fX3R0bF9zdG9yYWdlX19fX18uc2V0SXRlbShrZXksIHR0bCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJlZnJlc2hPbiA9IG1lcmdlKFxuICAgICAgICBvcHRpb25zPy5yZWZyZXNoT24gPz8gTkVWRVIgYXMgT2JzZXJ2YWJsZTx1bmtub3duPixcbiAgICAgICAgIHR0bD8uc3ViamVjdCA/PyBORVZFUixcbiAgICAgICk7XG5cbiAgICAgIGxldCBvYnNlcnZhYmxlID0gc3RvcmFnZS5nZXRJdGVtKGtleSk7XG5cbiAgICAgIGlmICghb2JzZXJ2YWJsZSkge1xuICAgICAgICBvYnNlcnZhYmxlID0gcmVmcmVzaE9uLnBpcGUoXG4gICAgICAgICAgc3RhcnRXaXRoKHRydWUpLFxuICAgICAgICAgIHN3aXRjaE1hcCgoKSA9PiBvcmlnaW5hbE1ldGhvZC5hcHBseSh0aGlzLCBbLi4uYXJnc10pKSxcbiAgICAgICAgICB0YXAoKCkgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5sb2cod29ya2luZyk7XG4gICAgICAgICAgICBkZWxldGUgd29ya2luZ1trZXldO1xuICAgICAgICAgIH0pLFxuICAgICAgICAgIHNoYXJlUmVwbGF5KHtcbiAgICAgICAgICAgIGJ1ZmZlclNpemU6IDEsXG4gICAgICAgICAgICByZWZDb3VudDogb3B0aW9ucz8ucmVmQ291bnQgPz8gZmFsc2UsXG4gICAgICAgICAgICB3aW5kb3dUaW1lOiBvcHRpb25zPy53aW5kb3dUaW1lID8/IEluZmluaXR5LFxuICAgICAgICAgIH0pLFxuICAgICAgICAgIGZpbHRlcigoKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gIXdvcmtpbmdba2V5XTtcbiAgICAgICAgICB9KSxcbiAgICAgICAgICBmaW5hbGl6ZSgoKSA9PiB7XG4gICAgICAgICAgICBzdWJzY3JpYmVycy0tO1xuICAgICAgICAgICAgaWYgKHN1YnNjcmliZXJzID09PSAwICYmIG9wdGlvbnM/LnJlZkNvdW50KSB7XG4gICAgICAgICAgICAgIHN0b3JhZ2UuZGVsZXRlSXRlbShrZXkpO1xuICAgICAgICAgICAgICAodGFyZ2V0IGFzIGFueSkuX19fX190dGxfc3RvcmFnZV9fX19fPy5kZWxldGVJdGVtKGtleSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgICAgc3RvcmFnZS5zZXRJdGVtKGtleSwgb2JzZXJ2YWJsZSk7XG4gICAgICB9XG5cbiAgICAgIHN1YnNjcmliZXJzKys7XG5cbiAgICAgIHJldHVybiBvYnNlcnZhYmxlO1xuICAgIH07XG5cbiAgICByZXR1cm4gZGVzY3JpcHRvcjtcbiAgfVxufVxuXG4iXX0=
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export class RequestTimes {
|
|
2
|
+
constructor() {
|
|
3
|
+
this.storage = new Map();
|
|
4
|
+
}
|
|
5
|
+
getItem(key) {
|
|
6
|
+
return this.storage.get(key);
|
|
7
|
+
}
|
|
8
|
+
setItem(key, item) {
|
|
9
|
+
this.storage.set(key, item);
|
|
10
|
+
}
|
|
11
|
+
deleteItem(key) {
|
|
12
|
+
this.storage.delete(key);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVxdWVzdC10aW1lcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL2h0dHAtcmVxdWVzdC1jYWNoZS9zcmMvbGliL3JlcXVlc3QtdGltZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBR0EsTUFBTSxPQUFPLFlBQVk7SUFBekI7UUFDVSxZQUFPLEdBQUcsSUFBSSxHQUFHLEVBQTJCLENBQUM7SUFhdkQsQ0FBQztJQVhDLE9BQU8sQ0FBQyxHQUFXO1FBQ2pCLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDL0IsQ0FBQztJQUVELE9BQU8sQ0FBQyxHQUFXLEVBQUUsSUFBcUI7UUFDeEMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQzlCLENBQUM7SUFFRCxVQUFVLENBQUMsR0FBVztRQUNwQixJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUMzQixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0h0dHBDYWNoZVN0b3JhZ2V9IGZyb20gJy4vaHR0cC1jYWNoZS1zdG9yYWdlJztcbmltcG9ydCB7T2JzZXJ2YWJsZX0gZnJvbSAncnhqcyc7XG5cbmV4cG9ydCBjbGFzcyBSZXF1ZXN0VGltZXMgaW1wbGVtZW50cyBIdHRwQ2FjaGVTdG9yYWdlIHtcbiAgcHJpdmF0ZSBzdG9yYWdlID0gbmV3IE1hcDxzdHJpbmcsIE9ic2VydmFibGU8YW55Pj4oKTtcblxuICBnZXRJdGVtKGtleTogc3RyaW5nKTogT2JzZXJ2YWJsZTxhbnk+IHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5zdG9yYWdlLmdldChrZXkpO1xuICB9XG5cbiAgc2V0SXRlbShrZXk6IHN0cmluZywgaXRlbTogT2JzZXJ2YWJsZTxhbnk+KTogdm9pZCB7XG4gICAgdGhpcy5zdG9yYWdlLnNldChrZXksIGl0ZW0pO1xuICB9XG5cbiAgZGVsZXRlSXRlbShrZXk6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuc3RvcmFnZS5kZWxldGUoa2V5KTtcbiAgfVxufVxuIl19
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { NEVER } from 'rxjs';
|
|
1
|
+
import { Subject, merge, NEVER, tap, filter, finalize } from 'rxjs';
|
|
2
2
|
import { startWith, switchMap, shareReplay } from 'rxjs/operators';
|
|
3
3
|
|
|
4
4
|
class DefaultStorage {
|
|
@@ -16,6 +16,21 @@ class DefaultStorage {
|
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
class RequestTimes {
|
|
20
|
+
constructor() {
|
|
21
|
+
this.storage = new Map();
|
|
22
|
+
}
|
|
23
|
+
getItem(key) {
|
|
24
|
+
return this.storage.get(key);
|
|
25
|
+
}
|
|
26
|
+
setItem(key, item) {
|
|
27
|
+
this.storage.set(key, item);
|
|
28
|
+
}
|
|
29
|
+
deleteItem(key) {
|
|
30
|
+
this.storage.delete(key);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
19
34
|
const HttpRequestCache = (optionsHandler) => {
|
|
20
35
|
return (target, methodName, descriptor) => {
|
|
21
36
|
if (!((descriptor === null || descriptor === void 0 ? void 0 : descriptor.value) instanceof Function)) {
|
|
@@ -23,23 +38,58 @@ const HttpRequestCache = (optionsHandler) => {
|
|
|
23
38
|
}
|
|
24
39
|
const cacheKeyPrefix = `${target.constructor.name}_${methodName}`;
|
|
25
40
|
const originalMethod = descriptor.value;
|
|
41
|
+
const working = {};
|
|
42
|
+
let subscribers = 0;
|
|
26
43
|
descriptor.value = function (...args) {
|
|
27
|
-
var _a, _b, _c;
|
|
44
|
+
var _a, _b, _c, _d, _e;
|
|
28
45
|
const options = optionsHandler === null || optionsHandler === void 0 ? void 0 : optionsHandler.call(this, this, ...args);
|
|
29
46
|
if (!(options === null || options === void 0 ? void 0 : options.storage) && !target._____storage_____) {
|
|
30
47
|
target._____storage_____ = new DefaultStorage();
|
|
31
48
|
}
|
|
49
|
+
if ((options === null || options === void 0 ? void 0 : options.ttl) && !target._____ttl_storage_____) {
|
|
50
|
+
target._____ttl_storage_____ = new RequestTimes();
|
|
51
|
+
}
|
|
32
52
|
const storage = (_a = options === null || options === void 0 ? void 0 : options.storage) !== null && _a !== void 0 ? _a : target._____storage_____;
|
|
33
|
-
const refreshOn = (_b = options === null || options === void 0 ? void 0 : options.refreshOn) !== null && _b !== void 0 ? _b : NEVER;
|
|
34
53
|
const key = `${cacheKeyPrefix}_${JSON.stringify(args)}`;
|
|
54
|
+
let ttl = undefined;
|
|
55
|
+
if (options === null || options === void 0 ? void 0 : options.ttl) {
|
|
56
|
+
ttl = target._____ttl_storage_____.getItem(key);
|
|
57
|
+
if (!ttl) {
|
|
58
|
+
ttl = {
|
|
59
|
+
requestTime: Date.now(),
|
|
60
|
+
subject: new Subject(),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
else if (ttl.requestTime + options.ttl <= Date.now()) {
|
|
64
|
+
working[key] = true;
|
|
65
|
+
ttl.requestTime = Date.now();
|
|
66
|
+
ttl.subject.next();
|
|
67
|
+
}
|
|
68
|
+
target._____ttl_storage_____.setItem(key, ttl);
|
|
69
|
+
}
|
|
70
|
+
const refreshOn = merge((_b = options === null || options === void 0 ? void 0 : options.refreshOn) !== null && _b !== void 0 ? _b : NEVER, (_c = ttl === null || ttl === void 0 ? void 0 : ttl.subject) !== null && _c !== void 0 ? _c : NEVER);
|
|
35
71
|
let observable = storage.getItem(key);
|
|
36
72
|
if (!observable) {
|
|
37
|
-
observable = refreshOn.pipe(startWith(true), switchMap(() => originalMethod.apply(this, [...args])),
|
|
73
|
+
observable = refreshOn.pipe(startWith(true), switchMap(() => originalMethod.apply(this, [...args])), tap(() => {
|
|
74
|
+
console.log(working);
|
|
75
|
+
delete working[key];
|
|
76
|
+
}), shareReplay({
|
|
38
77
|
bufferSize: 1,
|
|
39
|
-
refCount: (
|
|
78
|
+
refCount: (_d = options === null || options === void 0 ? void 0 : options.refCount) !== null && _d !== void 0 ? _d : false,
|
|
79
|
+
windowTime: (_e = options === null || options === void 0 ? void 0 : options.windowTime) !== null && _e !== void 0 ? _e : Infinity,
|
|
80
|
+
}), filter(() => {
|
|
81
|
+
return !working[key];
|
|
82
|
+
}), finalize(() => {
|
|
83
|
+
var _a;
|
|
84
|
+
subscribers--;
|
|
85
|
+
if (subscribers === 0 && (options === null || options === void 0 ? void 0 : options.refCount)) {
|
|
86
|
+
storage.deleteItem(key);
|
|
87
|
+
(_a = target._____ttl_storage_____) === null || _a === void 0 ? void 0 : _a.deleteItem(key);
|
|
88
|
+
}
|
|
40
89
|
}));
|
|
41
90
|
storage.setItem(key, observable);
|
|
42
91
|
}
|
|
92
|
+
subscribers++;
|
|
43
93
|
return observable;
|
|
44
94
|
};
|
|
45
95
|
return descriptor;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kovalenko-http-request-cache.mjs","sources":["../../../projects/http-request-cache/src/lib/default-storage.ts","../../../projects/http-request-cache/src/lib/http-request-cache.decorator.ts","../../../projects/http-request-cache/src/public-api.ts","../../../projects/http-request-cache/src/kovalenko-http-request-cache.ts"],"sourcesContent":["import {HttpCacheStorage} from './http-cache-storage';\nimport {Observable} from 'rxjs';\n\nexport class DefaultStorage implements HttpCacheStorage {\n private storage = new Map<string, Observable<any>>();\n\n getItem(key: string): Observable<any> | undefined {\n return this.storage.get(key);\n }\n\n setItem(key: string, item: Observable<any>): void {\n this.storage.set(key, item);\n }\n\n deleteItem(key: string): void {\n this.storage.delete(key);\n }\n}\n","import {HttpCacheOptions} from './http-cache-options';\nimport {NEVER, Observable} from 'rxjs';\nimport {shareReplay, startWith, switchMap} from 'rxjs/operators';\nimport {DefaultStorage} from './default-storage';\n\ntype HttpRequestCacheMethod = (...args: any[]) => Observable<any>;\n\nexport const HttpRequestCache = <T extends Record<string, any>>(optionsHandler?: (obj: T, ...args: any[]) => HttpCacheOptions) => {\n return (target: T, methodName: string, descriptor: TypedPropertyDescriptor<HttpRequestCacheMethod>): TypedPropertyDescriptor<HttpRequestCacheMethod> => {\n if (!(descriptor?.value instanceof Function)) {\n throw Error(`'@HttpRequestCache' can be applied only to the class method which returns an Observable`);\n }\n\n const cacheKeyPrefix = `${target.constructor.name}_${methodName}`;\n const originalMethod = descriptor.value;\n\n descriptor.value = function(...args: any[]): Observable<any> {\n const options = optionsHandler?.call(this as T, this as T, ...args);\n\n if (!options?.storage && !(target as any)._____storage_____) {\n (target as any)._____storage_____ = new DefaultStorage();\n }\n\n
|
|
1
|
+
{"version":3,"file":"kovalenko-http-request-cache.mjs","sources":["../../../projects/http-request-cache/src/lib/default-storage.ts","../../../projects/http-request-cache/src/lib/request-times.ts","../../../projects/http-request-cache/src/lib/http-request-cache.decorator.ts","../../../projects/http-request-cache/src/public-api.ts","../../../projects/http-request-cache/src/kovalenko-http-request-cache.ts"],"sourcesContent":["import {HttpCacheStorage} from './http-cache-storage';\nimport {Observable} from 'rxjs';\n\nexport class DefaultStorage implements HttpCacheStorage {\n private storage = new Map<string, Observable<any>>();\n\n getItem(key: string): Observable<any> | undefined {\n return this.storage.get(key);\n }\n\n setItem(key: string, item: Observable<any>): void {\n this.storage.set(key, item);\n }\n\n deleteItem(key: string): void {\n this.storage.delete(key);\n }\n}\n","import {HttpCacheStorage} from './http-cache-storage';\nimport {Observable} from 'rxjs';\n\nexport class RequestTimes implements HttpCacheStorage {\n private storage = new Map<string, Observable<any>>();\n\n getItem(key: string): Observable<any> | undefined {\n return this.storage.get(key);\n }\n\n setItem(key: string, item: Observable<any>): void {\n this.storage.set(key, item);\n }\n\n deleteItem(key: string): void {\n this.storage.delete(key);\n }\n}\n","import {HttpCacheOptions} from './http-cache-options';\nimport {filter, finalize, merge, NEVER, Observable, Subject, tap} from 'rxjs';\nimport {shareReplay, startWith, switchMap} from 'rxjs/operators';\nimport {DefaultStorage} from './default-storage';\nimport {RequestTimes} from './request-times';\n\ntype HttpRequestCacheMethod = (...args: any[]) => Observable<any>;\n\nexport const HttpRequestCache = <T extends Record<string, any>>(optionsHandler?: (obj: T, ...args: any[]) => HttpCacheOptions) => {\n return (target: T, methodName: string, descriptor: TypedPropertyDescriptor<HttpRequestCacheMethod>): TypedPropertyDescriptor<HttpRequestCacheMethod> => {\n if (!(descriptor?.value instanceof Function)) {\n throw Error(`'@HttpRequestCache' can be applied only to the class method which returns an Observable`);\n }\n\n const cacheKeyPrefix = `${target.constructor.name}_${methodName}`;\n const originalMethod = descriptor.value;\n const working: Record<string, boolean> = {};\n let subscribers = 0;\n\n descriptor.value = function(...args: any[]): Observable<any> {\n const options = optionsHandler?.call(this as T, this as T, ...args);\n\n if (!options?.storage && !(target as any)._____storage_____) {\n (target as any)._____storage_____ = new DefaultStorage();\n }\n\n if (options?.ttl && !(target as any)._____ttl_storage_____) {\n (target as any)._____ttl_storage_____ = new RequestTimes();\n }\n\n const storage = options?.storage ?? (target as any)._____storage_____;\n\n const key = `${cacheKeyPrefix}_${JSON.stringify(args)}`;\n\n let ttl: {requestTime: number, subject: Subject<void>} = undefined as any;\n\n if (options?.ttl) {\n ttl = (target as any)._____ttl_storage_____.getItem(key);\n\n if (!ttl) {\n ttl = {\n requestTime: Date.now(),\n subject: new Subject(),\n };\n } else if (ttl.requestTime + options.ttl <= Date.now()) {\n working[key] = true;\n ttl.requestTime = Date.now();\n ttl.subject.next();\n }\n\n (target as any)._____ttl_storage_____.setItem(key, ttl);\n }\n\n const refreshOn = merge(\n options?.refreshOn ?? NEVER as Observable<unknown>,\n ttl?.subject ?? NEVER,\n );\n\n let observable = storage.getItem(key);\n\n if (!observable) {\n observable = refreshOn.pipe(\n startWith(true),\n switchMap(() => originalMethod.apply(this, [...args])),\n tap(() => {\n console.log(working);\n delete working[key];\n }),\n shareReplay({\n bufferSize: 1,\n refCount: options?.refCount ?? false,\n windowTime: options?.windowTime ?? Infinity,\n }),\n filter(() => {\n return !working[key];\n }),\n finalize(() => {\n subscribers--;\n if (subscribers === 0 && options?.refCount) {\n storage.deleteItem(key);\n (target as any)._____ttl_storage_____?.deleteItem(key);\n }\n })\n );\n storage.setItem(key, observable);\n }\n\n subscribers++;\n\n return observable;\n };\n\n return descriptor;\n }\n}\n\n","/*\n * Public API Surface of http-request-cache\n */\n\nexport * from './lib/http-request-cache.decorator';\nexport * from './lib/http-cache-storage';\nexport * from './lib/http-cache-options';\nexport * from './lib/default-storage';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { NEVER } from 'rxjs';
|
|
1
|
+
import { Subject, merge, NEVER, tap, filter, finalize } from 'rxjs';
|
|
2
2
|
import { startWith, switchMap, shareReplay } from 'rxjs/operators';
|
|
3
3
|
|
|
4
4
|
class DefaultStorage {
|
|
@@ -16,6 +16,21 @@ class DefaultStorage {
|
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
class RequestTimes {
|
|
20
|
+
constructor() {
|
|
21
|
+
this.storage = new Map();
|
|
22
|
+
}
|
|
23
|
+
getItem(key) {
|
|
24
|
+
return this.storage.get(key);
|
|
25
|
+
}
|
|
26
|
+
setItem(key, item) {
|
|
27
|
+
this.storage.set(key, item);
|
|
28
|
+
}
|
|
29
|
+
deleteItem(key) {
|
|
30
|
+
this.storage.delete(key);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
19
34
|
const HttpRequestCache = (optionsHandler) => {
|
|
20
35
|
return (target, methodName, descriptor) => {
|
|
21
36
|
if (!(descriptor?.value instanceof Function)) {
|
|
@@ -23,22 +38,56 @@ const HttpRequestCache = (optionsHandler) => {
|
|
|
23
38
|
}
|
|
24
39
|
const cacheKeyPrefix = `${target.constructor.name}_${methodName}`;
|
|
25
40
|
const originalMethod = descriptor.value;
|
|
41
|
+
const working = {};
|
|
42
|
+
let subscribers = 0;
|
|
26
43
|
descriptor.value = function (...args) {
|
|
27
44
|
const options = optionsHandler?.call(this, this, ...args);
|
|
28
45
|
if (!options?.storage && !target._____storage_____) {
|
|
29
46
|
target._____storage_____ = new DefaultStorage();
|
|
30
47
|
}
|
|
48
|
+
if (options?.ttl && !target._____ttl_storage_____) {
|
|
49
|
+
target._____ttl_storage_____ = new RequestTimes();
|
|
50
|
+
}
|
|
31
51
|
const storage = options?.storage ?? target._____storage_____;
|
|
32
|
-
const refreshOn = options?.refreshOn ?? NEVER;
|
|
33
52
|
const key = `${cacheKeyPrefix}_${JSON.stringify(args)}`;
|
|
53
|
+
let ttl = undefined;
|
|
54
|
+
if (options?.ttl) {
|
|
55
|
+
ttl = target._____ttl_storage_____.getItem(key);
|
|
56
|
+
if (!ttl) {
|
|
57
|
+
ttl = {
|
|
58
|
+
requestTime: Date.now(),
|
|
59
|
+
subject: new Subject(),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
else if (ttl.requestTime + options.ttl <= Date.now()) {
|
|
63
|
+
working[key] = true;
|
|
64
|
+
ttl.requestTime = Date.now();
|
|
65
|
+
ttl.subject.next();
|
|
66
|
+
}
|
|
67
|
+
target._____ttl_storage_____.setItem(key, ttl);
|
|
68
|
+
}
|
|
69
|
+
const refreshOn = merge(options?.refreshOn ?? NEVER, ttl?.subject ?? NEVER);
|
|
34
70
|
let observable = storage.getItem(key);
|
|
35
71
|
if (!observable) {
|
|
36
|
-
observable = refreshOn.pipe(startWith(true), switchMap(() => originalMethod.apply(this, [...args])),
|
|
72
|
+
observable = refreshOn.pipe(startWith(true), switchMap(() => originalMethod.apply(this, [...args])), tap(() => {
|
|
73
|
+
console.log(working);
|
|
74
|
+
delete working[key];
|
|
75
|
+
}), shareReplay({
|
|
37
76
|
bufferSize: 1,
|
|
38
77
|
refCount: options?.refCount ?? false,
|
|
78
|
+
windowTime: options?.windowTime ?? Infinity,
|
|
79
|
+
}), filter(() => {
|
|
80
|
+
return !working[key];
|
|
81
|
+
}), finalize(() => {
|
|
82
|
+
subscribers--;
|
|
83
|
+
if (subscribers === 0 && options?.refCount) {
|
|
84
|
+
storage.deleteItem(key);
|
|
85
|
+
target._____ttl_storage_____?.deleteItem(key);
|
|
86
|
+
}
|
|
39
87
|
}));
|
|
40
88
|
storage.setItem(key, observable);
|
|
41
89
|
}
|
|
90
|
+
subscribers++;
|
|
42
91
|
return observable;
|
|
43
92
|
};
|
|
44
93
|
return descriptor;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kovalenko-http-request-cache.mjs","sources":["../../../projects/http-request-cache/src/lib/default-storage.ts","../../../projects/http-request-cache/src/lib/http-request-cache.decorator.ts","../../../projects/http-request-cache/src/public-api.ts","../../../projects/http-request-cache/src/kovalenko-http-request-cache.ts"],"sourcesContent":["import {HttpCacheStorage} from './http-cache-storage';\nimport {Observable} from 'rxjs';\n\nexport class DefaultStorage implements HttpCacheStorage {\n private storage = new Map<string, Observable<any>>();\n\n getItem(key: string): Observable<any> | undefined {\n return this.storage.get(key);\n }\n\n setItem(key: string, item: Observable<any>): void {\n this.storage.set(key, item);\n }\n\n deleteItem(key: string): void {\n this.storage.delete(key);\n }\n}\n","import {HttpCacheOptions} from './http-cache-options';\nimport {NEVER, Observable} from 'rxjs';\nimport {shareReplay, startWith, switchMap} from 'rxjs/operators';\nimport {DefaultStorage} from './default-storage';\n\ntype HttpRequestCacheMethod = (...args: any[]) => Observable<any>;\n\nexport const HttpRequestCache = <T extends Record<string, any>>(optionsHandler?: (obj: T, ...args: any[]) => HttpCacheOptions) => {\n return (target: T, methodName: string, descriptor: TypedPropertyDescriptor<HttpRequestCacheMethod>): TypedPropertyDescriptor<HttpRequestCacheMethod> => {\n if (!(descriptor?.value instanceof Function)) {\n throw Error(`'@HttpRequestCache' can be applied only to the class method which returns an Observable`);\n }\n\n const cacheKeyPrefix = `${target.constructor.name}_${methodName}`;\n const originalMethod = descriptor.value;\n\n descriptor.value = function(...args: any[]): Observable<any> {\n const options = optionsHandler?.call(this as T, this as T, ...args);\n\n if (!options?.storage && !(target as any)._____storage_____) {\n (target as any)._____storage_____ = new DefaultStorage();\n }\n\n
|
|
1
|
+
{"version":3,"file":"kovalenko-http-request-cache.mjs","sources":["../../../projects/http-request-cache/src/lib/default-storage.ts","../../../projects/http-request-cache/src/lib/request-times.ts","../../../projects/http-request-cache/src/lib/http-request-cache.decorator.ts","../../../projects/http-request-cache/src/public-api.ts","../../../projects/http-request-cache/src/kovalenko-http-request-cache.ts"],"sourcesContent":["import {HttpCacheStorage} from './http-cache-storage';\nimport {Observable} from 'rxjs';\n\nexport class DefaultStorage implements HttpCacheStorage {\n private storage = new Map<string, Observable<any>>();\n\n getItem(key: string): Observable<any> | undefined {\n return this.storage.get(key);\n }\n\n setItem(key: string, item: Observable<any>): void {\n this.storage.set(key, item);\n }\n\n deleteItem(key: string): void {\n this.storage.delete(key);\n }\n}\n","import {HttpCacheStorage} from './http-cache-storage';\nimport {Observable} from 'rxjs';\n\nexport class RequestTimes implements HttpCacheStorage {\n private storage = new Map<string, Observable<any>>();\n\n getItem(key: string): Observable<any> | undefined {\n return this.storage.get(key);\n }\n\n setItem(key: string, item: Observable<any>): void {\n this.storage.set(key, item);\n }\n\n deleteItem(key: string): void {\n this.storage.delete(key);\n }\n}\n","import {HttpCacheOptions} from './http-cache-options';\nimport {filter, finalize, merge, NEVER, Observable, Subject, tap} from 'rxjs';\nimport {shareReplay, startWith, switchMap} from 'rxjs/operators';\nimport {DefaultStorage} from './default-storage';\nimport {RequestTimes} from './request-times';\n\ntype HttpRequestCacheMethod = (...args: any[]) => Observable<any>;\n\nexport const HttpRequestCache = <T extends Record<string, any>>(optionsHandler?: (obj: T, ...args: any[]) => HttpCacheOptions) => {\n return (target: T, methodName: string, descriptor: TypedPropertyDescriptor<HttpRequestCacheMethod>): TypedPropertyDescriptor<HttpRequestCacheMethod> => {\n if (!(descriptor?.value instanceof Function)) {\n throw Error(`'@HttpRequestCache' can be applied only to the class method which returns an Observable`);\n }\n\n const cacheKeyPrefix = `${target.constructor.name}_${methodName}`;\n const originalMethod = descriptor.value;\n const working: Record<string, boolean> = {};\n let subscribers = 0;\n\n descriptor.value = function(...args: any[]): Observable<any> {\n const options = optionsHandler?.call(this as T, this as T, ...args);\n\n if (!options?.storage && !(target as any)._____storage_____) {\n (target as any)._____storage_____ = new DefaultStorage();\n }\n\n if (options?.ttl && !(target as any)._____ttl_storage_____) {\n (target as any)._____ttl_storage_____ = new RequestTimes();\n }\n\n const storage = options?.storage ?? (target as any)._____storage_____;\n\n const key = `${cacheKeyPrefix}_${JSON.stringify(args)}`;\n\n let ttl: {requestTime: number, subject: Subject<void>} = undefined as any;\n\n if (options?.ttl) {\n ttl = (target as any)._____ttl_storage_____.getItem(key);\n\n if (!ttl) {\n ttl = {\n requestTime: Date.now(),\n subject: new Subject(),\n };\n } else if (ttl.requestTime + options.ttl <= Date.now()) {\n working[key] = true;\n ttl.requestTime = Date.now();\n ttl.subject.next();\n }\n\n (target as any)._____ttl_storage_____.setItem(key, ttl);\n }\n\n const refreshOn = merge(\n options?.refreshOn ?? NEVER as Observable<unknown>,\n ttl?.subject ?? NEVER,\n );\n\n let observable = storage.getItem(key);\n\n if (!observable) {\n observable = refreshOn.pipe(\n startWith(true),\n switchMap(() => originalMethod.apply(this, [...args])),\n tap(() => {\n console.log(working);\n delete working[key];\n }),\n shareReplay({\n bufferSize: 1,\n refCount: options?.refCount ?? false,\n windowTime: options?.windowTime ?? Infinity,\n }),\n filter(() => {\n return !working[key];\n }),\n finalize(() => {\n subscribers--;\n if (subscribers === 0 && options?.refCount) {\n storage.deleteItem(key);\n (target as any)._____ttl_storage_____?.deleteItem(key);\n }\n })\n );\n storage.setItem(key, observable);\n }\n\n subscribers++;\n\n return observable;\n };\n\n return descriptor;\n }\n}\n\n","/*\n * Public API Surface of http-request-cache\n */\n\nexport * from './lib/http-request-cache.decorator';\nexport * from './lib/http-cache-storage';\nexport * from './lib/http-cache-options';\nexport * from './lib/default-storage';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
File without changes
|
|
@@ -2,6 +2,8 @@ import { BehaviorSubject, Observable, Subject } from 'rxjs';
|
|
|
2
2
|
import { HttpCacheStorage } from './http-cache-storage';
|
|
3
3
|
export interface HttpCacheOptions {
|
|
4
4
|
refCount?: boolean;
|
|
5
|
+
windowTime?: number;
|
|
6
|
+
ttl?: number;
|
|
5
7
|
storage?: HttpCacheStorage;
|
|
6
8
|
refreshOn?: Observable<unknown> | Subject<unknown> | BehaviorSubject<unknown>;
|
|
7
9
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { HttpCacheStorage } from './http-cache-storage';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
export declare class RequestTimes implements HttpCacheStorage {
|
|
4
|
+
private storage;
|
|
5
|
+
getItem(key: string): Observable<any> | undefined;
|
|
6
|
+
setItem(key: string, item: Observable<any>): void;
|
|
7
|
+
deleteItem(key: string): void;
|
|
8
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kovalenko/http-request-cache",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"peerDependencies": {
|
|
5
5
|
"rxjs": ">=7"
|
|
6
6
|
},
|
|
@@ -27,13 +27,13 @@
|
|
|
27
27
|
"esm2020": "esm2020/kovalenko-http-request-cache.mjs",
|
|
28
28
|
"fesm2020": "fesm2020/kovalenko-http-request-cache.mjs",
|
|
29
29
|
"fesm2015": "fesm2015/kovalenko-http-request-cache.mjs",
|
|
30
|
-
"typings": "
|
|
30
|
+
"typings": "index.d.ts",
|
|
31
31
|
"exports": {
|
|
32
32
|
"./package.json": {
|
|
33
33
|
"default": "./package.json"
|
|
34
34
|
},
|
|
35
35
|
".": {
|
|
36
|
-
"types": "./
|
|
36
|
+
"types": "./index.d.ts",
|
|
37
37
|
"esm2020": "./esm2020/kovalenko-http-request-cache.mjs",
|
|
38
38
|
"es2020": "./fesm2020/kovalenko-http-request-cache.mjs",
|
|
39
39
|
"es2015": "./fesm2015/kovalenko-http-request-cache.mjs",
|