Cleanup - unused files / unused exports / duplicate exports
[ProtonMail-WebClient.git] / packages / components / hooks / useGetCanonicalEmailsMap.ts
blob8d6e5a91a1eb5ef6a1aa52599e438e2662b94805
1 import { useCallback } from 'react';
3 import { getCanonicalAddresses } from '@proton/shared/lib/api/addresses';
4 import { API_CODES, GET_CANONICAL_EMAILS_API_LIMIT } from '@proton/shared/lib/constants';
5 import type { GetCanonicalAddressesApiResponse } from '@proton/shared/lib/interfaces/calendar';
6 import type { GetCanonicalEmailsMap } from '@proton/shared/lib/interfaces/hooks/GetCanonicalEmailsMap';
7 import type { SimpleMap } from '@proton/shared/lib/interfaces/utils';
8 import chunk from '@proton/utils/chunk';
10 import useApi from './useApi';
11 import useCache from './useCache';
12 import { getIsRecordInvalid, getPromiseValue } from './useCachedModelResult';
14 const CACHE_KEY = 'CANONICAL_EMAILS';
16 export const useGetCanonicalEmailsMap = () => {
17     const api = useApi();
18     const cache = useCache();
20     const getCanonicalEmailsMap = useCallback(
21         async (emails: string[]): Promise<SimpleMap<string>> => {
22             if (!emails.length) {
23                 return Promise.resolve({});
24             }
25             const encodedEmails = emails.map((email) => encodeURIComponent(email));
26             const batchedEmails = chunk(encodedEmails, GET_CANONICAL_EMAILS_API_LIMIT);
28             const maps = await Promise.all(
29                 batchedEmails.map(async (batch) => {
30                     const { Responses, Code } = await api<GetCanonicalAddressesApiResponse>(
31                         getCanonicalAddresses(batch)
32                     );
33                     if (Code !== API_CODES.GLOBAL_SUCCESS) {
34                         throw new Error('Canonicalize operation failed');
35                     }
36                     return Responses.reduce<SimpleMap<string>>((acc, { Email, Response: { CanonicalEmail } }) => {
37                         acc[Email] = CanonicalEmail;
38                         return acc;
39                     }, {});
40                 })
41             );
42             return maps.reduce<SimpleMap<string>>((acc, curr) => ({ ...acc, ...curr }), {});
43         },
44         [api, cache]
45     );
47     return useCallback<GetCanonicalEmailsMap>(
48         (emails: string[]) => {
49             if (!cache.has(CACHE_KEY)) {
50                 cache.set(CACHE_KEY, new Map());
51             }
52             const subCache = cache.get(CACHE_KEY);
53             const missing = emails.filter((email) => {
54                 return getIsRecordInvalid(subCache.get(email));
55             });
56             const promise = getCanonicalEmailsMap(missing);
57             const miss = async (tzid: string) => {
58                 const map = await promise;
59                 return map[tzid];
60             };
61             return Promise.all(
62                 emails.map(async (email) => {
63                     const result = await getPromiseValue(subCache, email, miss);
64                     return {
65                         email,
66                         result: result as string,
67                     };
68                 })
69             ).then((result) => {
70                 return result.reduce<SimpleMap<string>>((acc, { email, result }) => {
71                     acc[email] = result;
72                     return acc;
73                 }, {});
74             });
75         },
76         [cache, getCanonicalEmailsMap]
77     );