Merge branch 'feat/inda-383-daily-stat' into 'main'
[ProtonMail-WebClient.git] / packages / encrypted-search / lib / models / esFunctions.ts
blob37d558060f329545cfa983825bba668e9860487c
1 import type { MutableRefObject } from 'react';
3 import type { DecryptedKey } from '@proton/shared/lib/interfaces';
5 import type { CachedItem, ESEvent, ESIndexingState, ESItem, ESItemInfo, ESStatus, ESTimepoint } from './interfaces';
7 /**
8  * Show or update the search results in the UI
9  */
10 export type ESSetResultsList<ESItemMetadata, ESItemContent> = (
11     Elements: ESItem<ESItemMetadata, ESItemContent>[]
12 ) => void;
14 /**
15  * Return the user keys
16  */
17 export type GetUserKeys = () => Promise<DecryptedKey[]>;
19 /**
20  * Extract ID and timepoint from an item, encrypted or otherwise
21  */
22 export type GetItemInfo<ESItemMetadata> = (item: ESItemMetadata) => ESItemInfo;
24 /**
25  * Types of ES functions
26  */
27 export type EncryptedSearch<ESItemMetadata, ESItemContent> = (
28     setResultsList: ESSetResultsList<ESItemMetadata, ESItemContent>,
29     minimumItems?: number
30 ) => Promise<boolean>;
32 export type EncryptedSearchExecution<ESItemMetadata, ESItemContent, ESSearchParameters> = (
33     setResultsList: ESSetResultsList<ESItemMetadata, ESItemContent>,
34     esSearchParams: ESSearchParameters,
35     minimumItems: number | undefined,
36     sendMetricsOnSearch?: boolean
37 ) => Promise<boolean>;
38 export type HighlightString = (content: string, setAutoScroll: boolean) => string;
40 export type HighlightMetadata = (
41     metadata: string,
42     isBold?: boolean,
43     trim?: boolean
44 ) => { numOccurrences: number; resultJSX: JSX.Element };
46 export type EnableContentSearch = (options?: {
47     isRefreshed?: boolean | undefined;
48     isBackgroundIndexing?: boolean;
49     notify?: boolean | undefined;
50 }) => Promise<void>;
52 export type EnableEncryptedSearch = (options?: {
53     isRefreshed?: boolean | undefined;
54     isBackgroundIndexing?: boolean;
55     showErrorNotification?: boolean;
56 }) => Promise<boolean>;
58 /**
59  * Core functionalities of ES to be used in the product
60  */
61 export interface EncryptedSearchFunctions<ESItemMetadata, ESSearchParameters, ESItemContent = void> {
62     /**
63      * Run a new encrypted search or increment an existing one (the difference is handled internally).
64      * @param setResultsList a callback that will be given the items to show, i.e. those found as search
65      * results, and that should handle the UI part of displaying them to the users
66      * @param minimumItems is the optional smallest number of items that the search is expected to produce.
67      * If specified this parameter instructs the search to try finding at least this number of items from disk,
68      * both in case of a new search with limited cache and in case of an incremented search
69      * @returns a boolean indicating the success of the search
70      */
71     encryptedSearch: EncryptedSearch<ESItemMetadata, ESItemContent>;
73     /**
74      * Insert the <mark></mark> highlighting markdown in a string and returns a string containing it,
75      * which then needs to be displayed in the UI. Note that the keywords to highlight are extracted
76      * directly with the getSearchParams callback
77      * @param content the string where to insert the markdown
78      * @param setAutoScroll whether to insert the data-auto-scroll attribute to the first istance of
79      * the inserted mark tags. The UI should automatically scroll, if possible, to said first tag
80      * @returns the string containing the markdown
81      */
82     highlightString: HighlightString;
84     /**
85      * Inserts the <mark></mark> highlighting markdown in a string and returns directly the JSX node
86      * to be used in React
87      * @param metadata the string where to insert the markdown
88      * @param isBold specifies whether the text should also be bolded (e.g. in some headers)
89      * @param trim specifies whether to substitute the initial portion of the string by an ellipsis
90      * if it's too long
91      * @returns an object containing two properties: numOccurrences is the total number of times the
92      * markdown tag has been added to the given string, while resultJSX is the actual React node to be
93      * displayed
94      */
95     highlightMetadata: HighlightMetadata;
97     /**
98      * Start indexing metadata only
99      * @param isRefreshed is only used to be forward to the metrics route for statistical purposes.
100      * Whenever the user manually starts indexing, the latter shouldn't be specified (and defaults to false)
101      */
102     enableEncryptedSearch: EnableEncryptedSearch;
104     /**
105      * Start indexing for the first time or resume it after the user paused it. It optionally accepts
106      * an object with two properties.
107      * @param notify specifies whether any pop-up banner will be displayed to the user indicating success
108      * or failure of the indexing process
109      * @param isRefreshed is only used to be forward to the metrics route for statistical purposes.
110      * Whenever the user manually starts indexing, the latter shouldn't be specified (and defaults to false).
111      * @param isResumed specifies whether to resume previously paused indexing processes. The difference is that
112      * if it's not specified only those processes that were halted and, therefore, have the INDEXING status
113      * saved will be resumed. If it's set to true, instead, also those that were paused, i.e. have the PAUSED
114      * status, are resumed as well
115      */
116     enableContentSearch: EnableContentSearch;
118     /**
119      * Process events (according to the provided callbacks). It should be used in whatever event handling
120      * system the product uses to correctly sync the ES database.
121      * @param event a single event containing a change to the items stored in the ES database
122      */
123     handleEvent: (event: ESEvent<ESItemMetadata> | undefined) => Promise<void>;
125     /**
126      * @param ID the item ID
127      * @returns whether a given item, specified by its ID, is part of the currently shown search results or not.
128      * It returns false if a search is not happening on going
129      */
130     isSearchResult: (ID: string) => boolean;
132     /**
133      * Wipe all local data related to ES, both from IndexedDB and local storage
134      */
135     esDelete: () => Promise<void>;
137     /**
138      * @returns whether some conditions to apply highlighting are met, i.e. whether a search is
139      * on and there are keywords. For example in cases where the user only specifies filters
140      * and not keywords, this function returns false
141      */
142     shouldHighlight: () => boolean;
144     /**
145      * Run some initial checks on the status of ES. This must be the first function that
146      * the EncryptedSearchProvider runs, as it checks for new events, continues indexing in
147      * case a previous one was started, checks whether the index key is still accessible
148      */
149     initializeES: () => Promise<void>;
151     /**
152      * Pause the currently ongoing content indexing process, if any
153      */
154     pauseContentIndexing: () => Promise<void>;
156     /**
157      * Pause the currently ongoing metadata indexing process, if any
158      */
159     pauseMetadataIndexing: () => Promise<void>;
161     /**
162      * Wrapper around `correctDecryptionErrors` es callback, used to correct previous decryption errors after a key recovery
163      */
164     correctDecryptionErrors: () => Promise<number>;
166     /**
167      * Start the caching routine, i.e. fetching and decrypting as many items from the ES
168      * database as possible to be stored in memory for quick access
169      * @returns the reference to the current cache
170      */
171     cacheIndexedDB: () => Promise<void>;
173     /**
174      * Deactivates ES. This does not remove anything, and the database keeps being synced.
175      * It is used to switch ES temporarily off in cases when server side search is available.
176      */
177     toggleEncryptedSearch: () => Promise<void>;
179     /**
180      * Returns the ES cache, a map of indexed items. If the cache is not initialized, the return will be an empty map
181      */
182     getCache: () => Map<string, CachedItem<ESItemMetadata, ESItemContent>>;
184     /**
185      * Reset the cache to its default empty state
186      */
187     resetCache: () => void;
189     /**
190      * An object containing the different variables related to Encrypted Search status
191      */
192     esStatus: ESStatus<ESItemMetadata, ESItemContent, ESSearchParameters>;
194     /**
195      * A reference object to two values related to an IndexedDB operation status.
196      * The first number in the returned list is the current number of items processed while
197      * the second is the total number of items to process. It is useful to show a progress bar.
198      */
199     progressRecorderRef: MutableRefObject<ESTimepoint>;
201     /**
202      * An object containing variables describing the status of the indexing progress
203      */
204     esIndexingProgressState: ESIndexingState;