Update selected item color in Pass menu
[ProtonMail-WebClient.git] / packages / pass / lib / logger / store.ts
blobb75f3185f660d79b2f58d5fe80aa34c7a41ad6c2
1 import { AVERAGE_BYTES_PER_LOG_LINE, MAX_LOG_STORAGE_LINES, MAX_LOG_STORAGE_RATIO } from '@proton/pass/constants';
2 import type { AnyStorage } from '@proton/pass/types';
3 import { getLocalStorageQuota } from '@proton/pass/utils/dom/storage';
4 import debounce from '@proton/utils/debounce';
6 export type LogStorageData = { logs: string };
8 export const createLogStore = <T extends LogStorageData>(storage: AnyStorage<T>) => {
9     const buffer: string[] = [];
11     /** Reads the logs from storage. If parsing the
12      * logs fails, clears the log storage key */
13     const read = async (): Promise<string[]> => {
14         try {
15             const logs = await storage.getItem('logs');
16             return typeof logs === 'string' ? [...buffer, ...JSON.parse(logs)] : buffer;
17         } catch {
18             void storage.removeItem('logs');
19             return buffer;
20         }
21     };
23     /** Debounces the write operation to occur once every 5 seconds
24      * to prevent excessive concurrent writes to the storage */
25     const write = debounce(async () => {
26         const maxLogSize = MAX_LOG_STORAGE_RATIO * (await getLocalStorageQuota());
27         const maxLogLinesLength = maxLogSize / AVERAGE_BYTES_PER_LOG_LINE;
28         const max = Math.min(maxLogLinesLength, MAX_LOG_STORAGE_LINES);
30         const logs = (await read()).slice(0, max);
31         void storage.setItem('logs', JSON.stringify(logs));
32         buffer.length = 0;
33     }, 5_000);
35     const push = (...logs: string[]) => {
36         buffer.unshift(`${new Date().toLocaleString()} ${logs.join(' ')}`);
37         void write();
38         return true;
39     };
41     return { push, read, flush: write.flush };
44 export type LogStore = ReturnType<typeof createLogStore>;