Skip to content

Commit

Permalink
target pending invalidations for those that actually use the state (#865
Browse files Browse the repository at this point in the history
)
  • Loading branch information
agubler authored Dec 1, 2020
1 parent 86011f5 commit 272a7ef
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 2 deletions.
9 changes: 9 additions & 0 deletions src/core/middleware/icache.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* tslint:disable:interface-name */
import Map from '../../shim/Map';
import Set from '../../shim/Set';
import { create, invalidator, destroy } from '../vdom';

const factory = create({ invalidator, destroy });
Expand Down Expand Up @@ -56,6 +57,7 @@ export interface ICacheResult<S = void> {
const icacheFactory = factory(
({ middleware: { invalidator, destroy } }): ICacheResult<any> => {
const cacheMap = new Map<string, CacheWrapper>();
const pendingKeys = new Set<string>();
destroy(() => {
cacheMap.clear();
});
Expand All @@ -75,10 +77,14 @@ const icacheFactory = factory(
if (typeof value === 'function') {
value = value(current);
if (value && typeof value.then === 'function') {
const currentStatus = cacheMap.get(key);
cacheMap.set(key, {
status: 'pending',
value
});
if (pendingKeys.has(key) && (!currentStatus || currentStatus.status !== 'pending')) {
invalidate && invalidator();
}
value.then((result: any) => {
const cachedValue = cacheMap.get(key);
if (cachedValue && cachedValue.value === value) {
Expand All @@ -104,10 +110,12 @@ const icacheFactory = factory(
};
api.delete = (key: any, invalidate: boolean = true) => {
cacheMap.delete(key);
pendingKeys.delete(key);
invalidate && invalidator();
};
api.clear = (invalidate: boolean = true): void => {
cacheMap.clear();
pendingKeys.clear();
invalidate && invalidator();
};
api.getOrSet = (key: any, value: any, invalidate: boolean = true): any | undefined => {
Expand All @@ -122,6 +130,7 @@ const icacheFactory = factory(
return cachedValue.value;
};
api.pending = (key: any): boolean => {
pendingKeys.add(key);
let cachedValue = cacheMap.get(key);
return Boolean(cachedValue && cachedValue.status === 'pending');
};
Expand Down
5 changes: 3 additions & 2 deletions tests/core/unit/middleware/icache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,14 +124,15 @@ describe('icache middleware', () => {
const promiseOne = new Promise<string>((resolve) => {
resolverOne = resolve;
});
assert.isFalse(icache.pending('test'));
icache.set('test', () => promiseOne);
assert.isUndefined(icache.get('test'));
assert.isTrue(icache.pending('test'));
assert.isTrue(invalidatorStub.notCalled);
assert.isTrue(invalidatorStub.calledOnce);
resolverOne('value');
await promiseOne;

assert.isTrue(invalidatorStub.calledOnce);
assert.isTrue(invalidatorStub.calledTwice);
assert.isFalse(icache.pending('test'));
assert.strictEqual(icache.get('test'), 'value');
});
Expand Down

0 comments on commit 272a7ef

Please sign in to comment.