Skip to content

Commit a291a36

Browse files
fix(javascript): improve caching performance (generated)
algolia/api-clients-automation#6431 Co-authored-by: algolia-bot <accounts+algolia-api-client-bot@algolia.com> Co-authored-by: Eric Zaharia <94015633+eric-zaharia@users.noreply.github.com>
1 parent d4c108c commit a291a36

3 files changed

Lines changed: 42 additions & 33 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
"files": [
2828
{
2929
"path": "packages/algoliasearch/dist/algoliasearch.umd.js",
30-
"maxSize": "14.8KB"
30+
"maxSize": "14.9KB"
3131
},
3232
{
3333
"path": "packages/algoliasearch/dist/lite/builds/browser.umd.js",

packages/client-common/src/__tests__/cache/browser-local-storage-cache.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ describe('browser local storage cache', () => {
103103

104104
expect(missMock.mock.calls.length).toBe(1);
105105

106-
expect(localStorage.getItem(`algolia-client-js-${version}`)).toEqual('{}');
106+
expect(localStorage.getItem(`algolia-client-js-${version}`)).toBeNull();
107107
});
108108

109109
test('do throws localstorage exceptions on access', async () => {

packages/client-common/src/cache/createBrowserLocalStorageCache.ts

Lines changed: 40 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -21,32 +21,40 @@ export function createBrowserLocalStorageCache(options: BrowserLocalStorageOptio
2121
getStorage().setItem(namespaceKey, JSON.stringify(namespace));
2222
}
2323

24-
function removeOutdatedCacheItems(): void {
24+
function yieldToMain(): Promise<void> {
25+
return new Promise((resolve) => setTimeout(resolve, 0));
26+
}
27+
28+
function getFilteredNamespace(): {
29+
namespace: Record<string, BrowserLocalStorageCacheItem>;
30+
changed: boolean;
31+
} {
2532
const timeToLive = options.timeToLive ? options.timeToLive * 1000 : null;
2633
const namespace = getNamespace<BrowserLocalStorageCacheItem>();
34+
const currentTime = new Date().getTime();
35+
let changed = false;
2736

28-
const filteredNamespaceWithoutOldFormattedCacheItems = Object.fromEntries(
37+
const filtered = Object.fromEntries(
2938
Object.entries(namespace).filter(([, cacheItem]) => {
30-
return cacheItem.timestamp !== undefined;
31-
}),
32-
);
33-
34-
setNamespace(filteredNamespaceWithoutOldFormattedCacheItems);
39+
if (!cacheItem || cacheItem.timestamp === undefined) {
40+
changed = true;
41+
return false;
42+
}
3543

36-
if (!timeToLive) {
37-
return;
38-
}
44+
if (!timeToLive) {
45+
return true;
46+
}
3947

40-
const filteredNamespaceWithoutExpiredItems = Object.fromEntries(
41-
Object.entries(filteredNamespaceWithoutOldFormattedCacheItems).filter(([, cacheItem]) => {
42-
const currentTimestamp = new Date().getTime();
43-
const isExpired = cacheItem.timestamp + timeToLive < currentTimestamp;
48+
if (cacheItem.timestamp + timeToLive < currentTime) {
49+
changed = true;
50+
return false;
51+
}
4452

45-
return !isExpired;
53+
return true;
4654
}),
4755
);
4856

49-
setNamespace(filteredNamespaceWithoutExpiredItems);
57+
return { namespace: filtered, changed };
5058
}
5159

5260
return {
@@ -57,23 +65,24 @@ export function createBrowserLocalStorageCache(options: BrowserLocalStorageOptio
5765
miss: () => Promise.resolve(),
5866
},
5967
): Promise<TValue> {
60-
return Promise.resolve()
61-
.then(() => {
62-
removeOutdatedCacheItems();
63-
64-
return getNamespace<Promise<BrowserLocalStorageCacheItem>>()[JSON.stringify(key)];
65-
})
66-
.then((value) => {
67-
return Promise.all([value ? value.value : defaultValue(), value !== undefined]);
68-
})
69-
.then(([value, exists]) => {
70-
return Promise.all([value, exists || events.miss(value)]);
71-
})
72-
.then(([value]) => value);
68+
return yieldToMain().then(() => {
69+
const { namespace, changed } = getFilteredNamespace();
70+
const cachedItem = namespace[JSON.stringify(key)];
71+
72+
if (changed) {
73+
setNamespace(namespace);
74+
}
75+
76+
if (cachedItem) {
77+
return cachedItem.value as TValue;
78+
}
79+
80+
return defaultValue().then((value) => events.miss(value).then(() => value));
81+
});
7382
},
7483

7584
set<TValue>(key: Record<string, any> | string, value: TValue): Promise<TValue> {
76-
return Promise.resolve().then(() => {
85+
return yieldToMain().then(() => {
7786
const namespace = getNamespace();
7887

7988
namespace[JSON.stringify(key)] = {
@@ -88,7 +97,7 @@ export function createBrowserLocalStorageCache(options: BrowserLocalStorageOptio
8897
},
8998

9099
delete(key: Record<string, any> | string): Promise<void> {
91-
return Promise.resolve().then(() => {
100+
return yieldToMain().then(() => {
92101
const namespace = getNamespace();
93102

94103
delete namespace[JSON.stringify(key)];

0 commit comments

Comments
 (0)