Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,11 @@
},
{
"path": "packages/algoliasearch/dist/algoliasearch-lite.umd.js",
"maxSize": "4.6KB"
"maxSize": "4.7KB"
},
{
"path": "packages/recommend/dist/recommend.umd.js",
"maxSize": "4.4KB"
"maxSize": "4.5KB"
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,22 @@ import { Cache, CacheEvents } from '@algolia/cache-common';

import { BrowserLocalStorageCacheItem, BrowserLocalStorageOptions } from '.';

function yieldToMain(): Promise<void> {
// eslint-disable-next-line no-undef
const g: any = typeof globalThis !== 'undefined' ? globalThis : undefined;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do you cast this as any and not Window or something? seems a bit odd to lie to typescript


if (g && g.scheduler && g.scheduler.yield) {
return g.scheduler.yield().catch((error: any) => {
// eslint-disable-next-line no-console
console.error('Failed to yield to main: ', error);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what error can happen?


return new Promise(resolve => setTimeout(resolve, 0));
});
}

return new Promise(resolve => setTimeout(resolve, 0));
}

export function createBrowserLocalStorageCache(options: BrowserLocalStorageOptions): Cache {
const namespaceKey = `algoliasearch-client-js-${options.key}`;

Expand All @@ -23,30 +39,24 @@ export function createBrowserLocalStorageCache(options: BrowserLocalStorageOptio
getStorage().setItem(namespaceKey, JSON.stringify(namespace));
};

const removeOutdatedCacheItems = () => {
const getFilteredNamespace = (): Record<string, BrowserLocalStorageCacheItem> => {
const timeToLive = options.timeToLive ? options.timeToLive * 1000 : null;
const namespace = getNamespace<BrowserLocalStorageCacheItem>();
const currentTime = new Date().getTime();

const filteredNamespaceWithoutOldFormattedCacheItems = Object.fromEntries(
return Object.fromEntries(
Object.entries(namespace).filter(([, cacheItem]) => {
return cacheItem.timestamp !== undefined;
})
);

setNamespace(filteredNamespaceWithoutOldFormattedCacheItems);
if (!cacheItem || cacheItem.timestamp === undefined) {
return false;
}

if (!timeToLive) return;
if (!timeToLive) {
return true;
}

const filteredNamespaceWithoutExpiredItems = Object.fromEntries(
Object.entries(filteredNamespaceWithoutOldFormattedCacheItems).filter(([, cacheItem]) => {
const currentTimestamp = new Date().getTime();
const isExpired = cacheItem.timestamp + timeToLive < currentTimestamp;

return !isExpired;
return cacheItem.timestamp + timeToLive >= currentTime;
})
);

setNamespace(filteredNamespaceWithoutExpiredItems);
};

return {
Expand All @@ -57,25 +67,24 @@ export function createBrowserLocalStorageCache(options: BrowserLocalStorageOptio
miss: () => Promise.resolve(),
}
): Readonly<Promise<TValue>> {
return Promise.resolve()
.then(() => {
removeOutdatedCacheItems();

const keyAsString = JSON.stringify(key);

return getNamespace<Promise<BrowserLocalStorageCacheItem>>()[keyAsString];
})
.then(value => {
return Promise.all([value ? value.value : defaultValue(), value !== undefined]);
})
.then(([value, exists]) => {
return Promise.all([value, exists || events.miss(value)]);
})
.then(([value]) => value);
return yieldToMain().then(() => {
const namespace = getFilteredNamespace();
const keyAsString = JSON.stringify(key);
const cachedItem = namespace[keyAsString];

setNamespace(namespace);

if (cachedItem) {
return cachedItem.value as TValue;
}

// eslint-disable-next-line promise/no-nesting
return defaultValue().then((value: TValue) => events.miss(value).then(() => value));
});
},

set<TValue>(key: object | string, value: TValue): Readonly<Promise<TValue>> {
return Promise.resolve().then(() => {
return yieldToMain().then(() => {
const namespace = getNamespace();

// eslint-disable-next-line functional/immutable-data
Expand All @@ -91,7 +100,7 @@ export function createBrowserLocalStorageCache(options: BrowserLocalStorageOptio
},

delete(key: object | string): Readonly<Promise<void>> {
return Promise.resolve().then(() => {
return yieldToMain().then(() => {
const namespace = getNamespace();

// eslint-disable-next-line functional/immutable-data
Expand Down