[DRVWEB-4373] Add Suggestion Mode spotlight onboarding modal for docs on drive
[ProtonMail-WebClient.git] / packages / encrypted-search / lib / constants.ts
blobe6741d209966d50d62457b083ed3efad51c23c1c
1 import noop from '@proton/utils/noop';
3 import type { ESIndexingState, ESProgress, EncryptedSearchFunctions, OptionalESCallbacks } from './models';
5 /**
6  * Number of items to add to the search results list during
7  * a partial search. It corresponds to one page of results in mail
8  */
9 export const ES_EXTRA_RESULTS_LIMIT = 50;
11 /**
12  * Size of a batch of items during indexing and syncing.
13  * It corresponds to the maximum number of items' metadata returned
14  * by mail API
15  */
16 export const ES_MAX_PARALLEL_ITEMS = 150;
18 /**
19  * Number of items to fetch and process concurrently during indexing. Some
20  * browsers internally set the maximum concurrent requests to handle to 100,
21  * therefore we impose a slightly more stringent limit to allow some room for
22  * other requests the app might send. Note that this should not be used for backgound
23  * indexing, in which case ES_BACKGROUND_CONCURRENT should be used instead
24  */
25 export const ES_MAX_CONCURRENT = 20;
27 /**
28  * Number of items to fetch and process concurrently when the indexing is started in background mode
29  */
30 export const ES_BACKGROUND_CONCURRENT = 1;
32 /**
33  * Number of characters to retain from an item's metadata when highlighting it
34  */
35 export const ES_MAX_INITIAL_CHARS = 20;
37 /**
38  * Maximum size of cached items expressed in MB. It is heuristically determined
39  * so to cover most users (it should be enough for ~50k emails, and more than 95% of
40  * paid users have less than that, based on an extrapolation made in 2021) yet not
41  * to be too heavy on their devices' memory. The target size is 500 MB, however the
42  * number is larger due to our size estimation function being more conservative
43  * than the actual memory occupation
44  */
45 export const ES_MAX_CACHE = 600000000; // 600 MB
47 /**
48  * Maximum number of metadata "pages" per batch during metadata indexing
49  */
50 export const ES_MAX_METADATA_BATCH = 20;
51 export const ES_BACKGROUND_METADATA_BATCH = 1;
53 /**
54  * Upper bound of number of items queried from IndexedDB at once
55  */
56 export const ES_MAX_ITEMS_PER_BATCH = 1000;
58 /**
59  * Current version of the most up-to-date ES IndexedDB
60  */
61 export const INDEXEDDB_VERSION = 2;
63 /**
64  * Maximum number of times an API call to fetch an item
65  * content will be retried before being stored locally
66  * for a later attempt
67  */
68 export const ES_MAX_RETRIES = 10;
70 /**
71  * Error codes that are deemed temporary and therefore will trigger a retry
72  * during API calls that the ES library does
73  */
74 export const ES_TEMPORARY_ERRORS = [408, 429, 502, 503];
76 /**
77  * Regular expression used to find and/or remove diacritics for the purpose of
78  * searching and highlighting text. It matches all combining characters
79  */
80 export const DIACRITICS_REGEXP = /\p{Mark}/gu;
82 /**
83  * Regular expression used to turn all fancy quotes into normal ones
84  */
85 export const QUOTES_REGEXP =
86     /\u00ab|\u00bb|\u201e|\u201c|\u201f|\u201d|\u275d|\u275e|\u276e|\u276f|\u2e42|\u301d|\u301e|\u301f|\uff02/gu;
88 /**
89  * Regular expression used to turn all fancy apostrophes into normal ones
90  */
91 export const APOSTROPHES_REGEXP = /\u2018|\u2019|\u02bc/gu;
93 /**
94  * Configuration of the Web Crypto API to symmetrically encrypt items in IndexedDB
95  */
96 export const AesKeyGenParams: AesKeyGenParams = { name: 'AES-GCM', length: 128 };
97 export const KeyUsages: KeyUsage[] = ['encrypt', `decrypt`];
99 /**
100  * ENUMS
101  */
102 export enum INDEXING_STATUS {
103     INACTIVE,
104     INDEXING,
105     PAUSED,
106     ACTIVE,
109 export enum TIMESTAMP_TYPE {
110     STOP,
111     START,
112     STEP,
115 export enum ES_SYNC_ACTIONS {
116     DELETE,
117     CREATE,
118     UPDATE_CONTENT,
119     UPDATE_METADATA,
122 export enum STORING_OUTCOME {
123     FAILURE,
124     SUCCESS,
125     QUOTA,
129  * DEFAULTS
130  */
131 export const defaultESStatus = {
132     permanentResults: [],
133     setResultsList: () => {},
134     lastTimePoint: undefined,
135     previousESSearchParams: undefined,
136     cachedIndexKey: undefined,
137     dbExists: false,
138     isEnablingContentSearch: false,
139     isDBLimited: false,
140     esEnabled: false,
141     esSupported: true,
142     isRefreshing: false,
143     isSearchPartial: false,
144     isSearching: false,
145     isFirstSearch: true,
146     isEnablingEncryptedSearch: false,
147     isContentIndexingPaused: false,
148     isMetadataIndexingPaused: false,
149     contentIndexingDone: false,
150     isConfigFromESDBLoaded: false,
151     getCacheStatus: () => ({ isCacheReady: false, isCacheLimited: false }),
154 export const defaultESCache = {
155     esCache: new Map(),
156     cacheSize: 0,
157     isCacheLimited: false,
158     isCacheReady: false,
161 export const defaultESIndexingState: ESIndexingState = {
162     esProgress: 0,
163     estimatedMinutes: 0,
164     totalIndexingItems: 0,
165     currentProgressValue: 0,
168 export const defaultESContext: EncryptedSearchFunctions<any, any, any> = {
169     encryptedSearch: async () => false,
170     highlightString: () => '',
171     highlightMetadata: () => ({ numOccurrences: 0, resultJSX: null as any }),
172     enableEncryptedSearch: async () => false,
173     enableContentSearch: async () => {},
174     handleEvent: async () => {},
175     isSearchResult: () => false,
176     esDelete: async () => {},
177     shouldHighlight: () => false,
178     initializeES: async () => {},
179     pauseContentIndexing: async () => {},
180     pauseMetadataIndexing: async () => {},
181     cacheIndexedDB: async () => {},
182     toggleEncryptedSearch: async () => {},
183     getCache: () => new Map(),
184     resetCache: () => {},
185     correctDecryptionErrors: async () => 0,
186     esStatus: defaultESStatus,
187     progressRecorderRef: { current: [0, 0] },
188     esIndexingProgressState: defaultESIndexingState,
191 export const defaultESCallbacks: OptionalESCallbacks<any, any, any> = {
192     checkIsReverse: () => true,
193     shouldOnlySortResults: () => false,
194     resetSort: noop,
195     getSearchInterval: () => ({ begin: undefined, end: undefined }),
196     applyFilters: () => true,
197     onContentDeletion: async () => {},
198     correctDecryptionErrors: async () => 0,
201 export const defaultESProgress: ESProgress = {
202     totalItems: 0,
203     numPauses: 0,
204     isRefreshed: false,
205     timestamps: [],
206     originalEstimate: 0,
207     recoveryPoint: undefined,
208     status: INDEXING_STATUS.INACTIVE,