-
Notifications
You must be signed in to change notification settings - Fork 2.6k
/
depTrackingCache.ts
70 lines (60 loc) · 1.83 KB
/
depTrackingCache.ts
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
import { NormalizedCache, NormalizedCacheObject, StoreObject } from './types';
import { wrap, OptimisticWrapperFunction } from 'optimism';
const hasOwn = Object.prototype.hasOwnProperty;
export class DepTrackingCache implements NormalizedCache {
// Wrapper function produced by the optimism library, used to depend on
// dataId strings, for easy invalidation of specific IDs.
private depend: OptimisticWrapperFunction<[string], StoreObject | undefined>;
constructor(private data: NormalizedCacheObject = Object.create(null)) {
this.depend = wrap((dataId: string) => this.data[dataId], {
disposable: true,
makeCacheKey(dataId: string) {
return dataId;
},
});
}
public toObject(): NormalizedCacheObject {
return this.data;
}
public get(dataId: string): StoreObject {
this.depend(dataId);
return this.data[dataId]!;
}
public set(dataId: string, value?: StoreObject) {
const oldValue = this.data[dataId];
if (value !== oldValue) {
this.data[dataId] = value;
this.depend.dirty(dataId);
}
}
public delete(dataId: string): void {
if (hasOwn.call(this.data, dataId)) {
delete this.data[dataId];
this.depend.dirty(dataId);
}
}
public clear(): void {
this.replace(null);
}
public replace(newData: NormalizedCacheObject | null): void {
if (newData) {
Object.keys(newData).forEach(dataId => {
this.set(dataId, newData[dataId]);
});
Object.keys(this.data).forEach(dataId => {
if (!hasOwn.call(newData, dataId)) {
this.delete(dataId);
}
});
} else {
Object.keys(this.data).forEach(dataId => {
this.delete(dataId);
});
}
}
}
export function defaultNormalizedCacheFactory(
seed?: NormalizedCacheObject,
): NormalizedCache {
return new DepTrackingCache(seed);
}