internxt-crypto 0.0.10-alpha → 0.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. package/README.md +3 -4
  2. package/dist/asymmetric-crypto-BORmLhnx.js +143 -0
  3. package/dist/asymmetric-crypto-BORmLhnx.js.map +1 -0
  4. package/dist/asymmetric-crypto-CyXsV4XT.mjs +102 -0
  5. package/dist/asymmetric-crypto-CyXsV4XT.mjs.map +1 -0
  6. package/dist/asymmetric-crypto.d.mts +9 -3
  7. package/dist/asymmetric-crypto.d.ts +9 -3
  8. package/dist/asymmetric-crypto.js +8 -92
  9. package/dist/asymmetric-crypto.mjs +2 -84
  10. package/dist/chunk-DWirmd9C.mjs +18 -0
  11. package/dist/chunk-Dt-PWiN7.js +60 -0
  12. package/dist/constants-Ccp21E03.js +208 -0
  13. package/dist/constants-Ccp21E03.js.map +1 -0
  14. package/dist/constants-kTeX-2T0.mjs +34 -0
  15. package/dist/constants-kTeX-2T0.mjs.map +1 -0
  16. package/dist/constants.d.mts +5 -11
  17. package/dist/constants.d.ts +5 -11
  18. package/dist/constants.js +30 -79
  19. package/dist/constants.mjs +2 -41
  20. package/dist/derive-key-Be7hS-cN.mjs +751 -0
  21. package/dist/derive-key-Be7hS-cN.mjs.map +1 -0
  22. package/dist/derive-key-CBf2WxJd.js +2513 -0
  23. package/dist/derive-key-CBf2WxJd.js.map +1 -0
  24. package/dist/derive-key.d.mts +14 -8
  25. package/dist/derive-key.d.ts +14 -8
  26. package/dist/derive-key.js +15 -795
  27. package/dist/derive-key.mjs +5 -783
  28. package/dist/email-crypto-BrT98taw.js +617 -0
  29. package/dist/email-crypto-BrT98taw.js.map +1 -0
  30. package/dist/email-crypto-DJUEjTxA.mjs +534 -0
  31. package/dist/email-crypto-DJUEjTxA.mjs.map +1 -0
  32. package/dist/email-crypto.d.mts +58 -78
  33. package/dist/email-crypto.d.ts +58 -78
  34. package/dist/email-crypto.js +17 -1409
  35. package/dist/email-crypto.mjs +8 -1381
  36. package/dist/email-search.d.mts +39 -32
  37. package/dist/email-search.d.ts +39 -32
  38. package/dist/email-search.js +572 -540
  39. package/dist/email-search.js.map +1 -1
  40. package/dist/email-search.mjs +567 -539
  41. package/dist/email-search.mjs.map +1 -1
  42. package/dist/hash-BoqwNkcd.js +190 -0
  43. package/dist/hash-BoqwNkcd.js.map +1 -0
  44. package/dist/hash-CXeGAwai.mjs +131 -0
  45. package/dist/hash-CXeGAwai.mjs.map +1 -0
  46. package/dist/hash.d.mts +21 -15
  47. package/dist/hash.d.ts +21 -15
  48. package/dist/hash.js +11 -95
  49. package/dist/hash.mjs +2 -84
  50. package/dist/index-CQqgKsbX.d.ts +50 -0
  51. package/dist/index-CintVUbp.d.ts +97 -0
  52. package/dist/index-D5pBU_A5.d.mts +50 -0
  53. package/dist/index-MaOov-ag.d.mts +97 -0
  54. package/dist/index.d.mts +35 -18
  55. package/dist/index.d.ts +35 -18
  56. package/dist/index.js +103 -2685
  57. package/dist/index.mjs +15 -2538
  58. package/dist/keystore-crypto-B4yCVo9l.js +182 -0
  59. package/dist/keystore-crypto-B4yCVo9l.js.map +1 -0
  60. package/dist/keystore-crypto-Bjgriq9h.mjs +159 -0
  61. package/dist/keystore-crypto-Bjgriq9h.mjs.map +1 -0
  62. package/dist/keystore-crypto.d.mts +20 -46
  63. package/dist/keystore-crypto.d.ts +20 -46
  64. package/dist/keystore-crypto.js +11 -530
  65. package/dist/keystore-crypto.mjs +9 -501
  66. package/dist/keystore-service.d.mts +44 -78
  67. package/dist/keystore-service.d.ts +44 -78
  68. package/dist/keystore-service.js +113 -340
  69. package/dist/keystore-service.js.map +1 -1
  70. package/dist/keystore-service.mjs +107 -335
  71. package/dist/keystore-service.mjs.map +1 -1
  72. package/dist/post-quantum-crypto-CAi-cEkV.js +189 -0
  73. package/dist/post-quantum-crypto-CAi-cEkV.js.map +1 -0
  74. package/dist/post-quantum-crypto-Vv34t6gX.mjs +154 -0
  75. package/dist/post-quantum-crypto-Vv34t6gX.mjs.map +1 -0
  76. package/dist/post-quantum-crypto.d.mts +2 -72
  77. package/dist/post-quantum-crypto.d.ts +2 -72
  78. package/dist/post-quantum-crypto.js +13 -92
  79. package/dist/post-quantum-crypto.mjs +2 -89
  80. package/dist/storage-service-BgIK2aYZ.js +82 -0
  81. package/dist/storage-service-BgIK2aYZ.js.map +1 -0
  82. package/dist/storage-service-CubCbhY2.mjs +65 -0
  83. package/dist/storage-service-CubCbhY2.mjs.map +1 -0
  84. package/dist/storage-service.d.mts +2 -53
  85. package/dist/storage-service.d.ts +2 -53
  86. package/dist/storage-service.js +12 -68
  87. package/dist/storage-service.mjs +2 -66
  88. package/dist/symmetric-crypto-CrdS1Che.mjs +197 -0
  89. package/dist/symmetric-crypto-CrdS1Che.mjs.map +1 -0
  90. package/dist/symmetric-crypto-D65zB396.js +244 -0
  91. package/dist/symmetric-crypto-D65zB396.js.map +1 -0
  92. package/dist/symmetric-crypto.d.mts +12 -8
  93. package/dist/symmetric-crypto.d.ts +12 -8
  94. package/dist/symmetric-crypto.js +10 -142
  95. package/dist/symmetric-crypto.mjs +3 -133
  96. package/dist/types-52g887Zi.js +16 -0
  97. package/dist/types-52g887Zi.js.map +1 -0
  98. package/dist/types-BiEoleqw.mjs +10 -0
  99. package/dist/types-BiEoleqw.mjs.map +1 -0
  100. package/dist/types-Ds3ivE9W.d.ts +104 -0
  101. package/dist/types-DwQJtrTx.d.mts +104 -0
  102. package/dist/types.d.mts +2 -102
  103. package/dist/types.d.ts +2 -102
  104. package/dist/types.js +2 -13
  105. package/dist/types.mjs +2 -11
  106. package/dist/utils-CNs3cyDj.js +263 -0
  107. package/dist/utils-CNs3cyDj.js.map +1 -0
  108. package/dist/utils-DS04iUcX.mjs +173 -0
  109. package/dist/utils-DS04iUcX.mjs.map +1 -0
  110. package/dist/utils.d.mts +37 -78
  111. package/dist/utils.d.ts +37 -78
  112. package/dist/utils.js +16 -313
  113. package/dist/utils.mjs +2 -272
  114. package/package.json +15 -90
  115. package/dist/asymmetric-crypto.js.map +0 -1
  116. package/dist/asymmetric-crypto.mjs.map +0 -1
  117. package/dist/constants.js.map +0 -1
  118. package/dist/constants.mjs.map +0 -1
  119. package/dist/derive-key.js.map +0 -1
  120. package/dist/derive-key.mjs.map +0 -1
  121. package/dist/email-crypto.js.map +0 -1
  122. package/dist/email-crypto.mjs.map +0 -1
  123. package/dist/email-service.d.mts +0 -38
  124. package/dist/email-service.d.ts +0 -38
  125. package/dist/email-service.js +0 -154
  126. package/dist/email-service.js.map +0 -1
  127. package/dist/email-service.mjs +0 -147
  128. package/dist/email-service.mjs.map +0 -1
  129. package/dist/hash.js.map +0 -1
  130. package/dist/hash.mjs.map +0 -1
  131. package/dist/index.js.map +0 -1
  132. package/dist/index.mjs.map +0 -1
  133. package/dist/keystore-crypto.js.map +0 -1
  134. package/dist/keystore-crypto.mjs.map +0 -1
  135. package/dist/kyber768-B87rMQ7u.d.mts +0 -30
  136. package/dist/kyber768-B87rMQ7u.d.ts +0 -30
  137. package/dist/post-quantum-crypto.js.map +0 -1
  138. package/dist/post-quantum-crypto.mjs.map +0 -1
  139. package/dist/storage-service.js.map +0 -1
  140. package/dist/storage-service.mjs.map +0 -1
  141. package/dist/symmetric-crypto.js.map +0 -1
  142. package/dist/symmetric-crypto.mjs.map +0 -1
  143. package/dist/types.js.map +0 -1
  144. package/dist/types.mjs.map +0 -1
  145. package/dist/utils-BDaK_d6T.d.ts +0 -114
  146. package/dist/utils-v34IRTIx.d.mts +0 -114
  147. package/dist/utils.js.map +0 -1
  148. package/dist/utils.mjs.map +0 -1
@@ -1,582 +1,609 @@
1
- 'use strict';
1
+ const require_chunk = require('./chunk-Dt-PWiN7.js');
2
+ const require_constants = require('./constants-Ccp21E03.js');
3
+ require('./utils-CNs3cyDj.js');
4
+ require('./hash-BoqwNkcd.js');
5
+ require('./symmetric-crypto-D65zB396.js');
6
+ const require_derive_key = require('./derive-key-CBf2WxJd.js');
7
+ require('./post-quantum-crypto-CAi-cEkV.js');
8
+ const require_email_crypto = require('./email-crypto-BrT98taw.js');
9
+ let idb = require("idb");
10
+ let flexsearch = require("flexsearch");
2
11
 
3
- var idb = require('idb');
4
- var blake3_js = require('@noble/hashes/blake3.js');
5
- var utils_js$1 = require('@noble/hashes/utils.js');
6
- var utils_js = require('@noble/post-quantum/utils.js');
7
- require('uuid');
8
- var flexsearch = require('flexsearch');
9
-
10
- // src/email-search/indexedDB.ts
11
-
12
- // src/constants.ts
13
- var AES_ALGORITHM = "AES-GCM";
14
- var AES_KEY_BIT_LENGTH = 256;
15
- var AUX_LEN = 128;
16
- var IV_LEN_BYTES = 16;
17
- var KEY_FORMAT = "raw";
18
- var CONTEXT_INDEX = "CRYPTO library 2025-07-30 17:20:00 key for protecting current search indices";
19
- var MAX_CACHE_SIZE = 6e8;
20
- var MAX_EMAIL_PER_BATCH = 100;
21
- var DB_LABEL = "email";
22
- var DB_VERSION = 1;
23
- function getBytesFromString(bytes, value) {
24
- return blake3_js.blake3(utils_js$1.utf8ToBytes(value), { dkLen: bytes });
25
- }
26
-
27
- // src/symmetric-crypto/keys.ts
28
- async function importSymmetricCryptoKey(keyData) {
29
- return crypto.subtle.importKey(
30
- KEY_FORMAT,
31
- new Uint8Array(keyData),
32
- {
33
- name: AES_ALGORITHM,
34
- length: AES_KEY_BIT_LENGTH
35
- },
36
- true,
37
- ["encrypt", "decrypt"]
38
- );
39
- }
40
- async function createNISTbasedIV(freeField) {
41
- try {
42
- if (!freeField) {
43
- return utils_js.randomBytes(IV_LEN_BYTES);
44
- }
45
- const iv = new Uint8Array(16);
46
- const randFiled = utils_js.randomBytes(12);
47
- iv.set(randFiled, 0);
48
- const freeFiledFixedLength = await getBytesFromString(4, freeField);
49
- iv.set(freeFiledFixedLength, 12);
50
- return iv;
51
- } catch (error) {
52
- throw new Error("Failed to create IV", { cause: error });
53
- }
54
- }
55
- async function makeAuxFixedLength(aux) {
56
- return getBytesFromString(AUX_LEN / 8, aux);
57
- }
58
- async function encryptMessage(message, encryptionKey, iv, additionalData) {
59
- try {
60
- const encrypted = await crypto.subtle.encrypt(
61
- { name: AES_ALGORITHM, iv, additionalData },
62
- encryptionKey,
63
- message
64
- );
65
- return new Uint8Array(encrypted);
66
- } catch (error) {
67
- throw new Error("Failed to encrypt symmetrically", { cause: error });
68
- }
69
- }
70
- async function decryptMessage(ciphertext, iv, encryptionKey, additionalData) {
71
- try {
72
- const decrypted = await crypto.subtle.decrypt(
73
- { name: AES_ALGORITHM, iv, additionalData },
74
- encryptionKey,
75
- ciphertext
76
- );
77
- return new Uint8Array(decrypted);
78
- } catch (error) {
79
- throw new Error("Failed to decrypt symmetrically", { cause: error });
80
- }
81
- }
82
-
83
- // src/symmetric-crypto/aes.ts
84
- async function encryptSymmetrically(encryptionKey, message, aux, freeField) {
85
- try {
86
- const iv = await createNISTbasedIV(freeField);
87
- const additionalData = await makeAuxFixedLength(aux);
88
- const ciphertext = await encryptMessage(message, encryptionKey, iv, additionalData);
89
- return { ciphertext, iv };
90
- } catch (error) {
91
- throw new Error("Failed to encrypt symmetrically", { cause: error });
92
- }
93
- }
94
- async function decryptSymmetrically(encryptionKey, encryptedMessage, aux) {
95
- try {
96
- const additionalData = await makeAuxFixedLength(aux);
97
- const result = await decryptMessage(
98
- encryptedMessage.ciphertext,
99
- encryptedMessage.iv,
100
- encryptionKey,
101
- additionalData
102
- );
103
- return result;
104
- } catch (error) {
105
- throw new Error("Failed to decrypt symmetrically", { cause: error });
106
- }
107
- }
108
- function UTF8ToUint8(str) {
109
- return new TextEncoder().encode(str);
110
- }
111
- function uint8ToUTF8(array) {
112
- return new TextDecoder().decode(array);
113
- }
114
-
115
- // src/email-crypto/converters.ts
116
- function emailBodyToBinary(body) {
117
- try {
118
- const json = JSON.stringify(body);
119
- return UTF8ToUint8(json);
120
- } catch (error) {
121
- throw new Error("Failed to convert EmailBody to Uint8Array", { cause: error });
122
- }
123
- }
124
- function binaryToEmailBody(array) {
125
- try {
126
- const json = uint8ToUTF8(array);
127
- const email = JSON.parse(json);
128
- return email;
129
- } catch (error) {
130
- throw new Error("Failed to convert Uint8Array to EmailBody", { cause: error });
131
- }
132
- }
133
- function emailToBinary(email) {
134
- try {
135
- const json = JSON.stringify(email);
136
- return UTF8ToUint8(json);
137
- } catch (error) {
138
- throw new Error("Failed to convert EmailBody to Uint8Array", { cause: error });
139
- }
140
- }
141
- function deriveSymmetricKeyFromContext(context, baseKey) {
142
- return blake3_js.blake3(baseKey, { context: UTF8ToUint8(context) });
143
- }
144
- async function deriveSymmetricCryptoKeyFromContext(context, baseKey) {
145
- try {
146
- if (baseKey.length != AES_KEY_BIT_LENGTH / 8) {
147
- throw new Error(`Base key length must be exactly ${AES_KEY_BIT_LENGTH / 8} bytes`);
148
- }
149
- if (!context) ;
150
- const keyBytes = deriveSymmetricKeyFromContext(context, baseKey);
151
- const key = await importSymmetricCryptoKey(keyBytes);
152
- return key;
153
- } catch (error) {
154
- throw new Error("Failed to derive CryptoKey from base key and context", { cause: error });
155
- }
156
- }
157
-
158
- // src/email-crypto/core.ts
159
- async function encryptEmailContentSymmetricallyWithKey(emailBody, encryptionKey, aux, emailID) {
160
- try {
161
- const binaryEmail = emailBodyToBinary(emailBody);
162
- const ciphertext = await encryptSymmetrically(encryptionKey, binaryEmail, aux, emailID);
163
- return ciphertext;
164
- } catch (error) {
165
- throw new Error("Failed to symmetrically encrypt email with the given key", { cause: error });
166
- }
167
- }
168
- async function decryptEmailSymmetrically(emailCiphertext, encryptionKey, aux) {
169
- try {
170
- const binaryEmail = await decryptSymmetrically(encryptionKey, emailCiphertext, aux);
171
- const body = binaryToEmailBody(binaryEmail);
172
- return body;
173
- } catch (error) {
174
- throw new Error("Failed to symmetrically decrypt email", { cause: error });
175
- }
176
- }
177
- function getAux(params) {
178
- try {
179
- const { subject, replyToEmailID, sender, recipients } = params;
180
- const aux = JSON.stringify({ subject, replyToEmailID, sender, recipients });
181
- return aux;
182
- } catch (error) {
183
- throw new Error("Failed to create aux", { cause: error });
184
- }
185
- }
186
-
187
- // src/email-search/indexedDB.ts
188
- var getDatabaseName = (userID) => {
189
- return `ES:${userID}:DB`;
12
+ //#region src/email-search/indexedDB.ts
13
+ /**
14
+ * Returns IndexedDB database name for the given user
15
+ *
16
+ * @param userID - The user ID
17
+ * @returns The database name
18
+ */
19
+ const getDatabaseName = (userID) => {
20
+ return `ES:${userID}:DB`;
190
21
  };
191
- var openDatabase = async (userID) => {
192
- try {
193
- const dbName = getDatabaseName(userID);
194
- return idb.openDB(dbName, DB_VERSION, {
195
- upgrade(db) {
196
- if (!db.objectStoreNames.contains(DB_LABEL)) {
197
- const store = db.createObjectStore(DB_LABEL, { keyPath: "id" });
198
- store.createIndex("byTime", "params.createdAt");
199
- }
200
- }
201
- });
202
- } catch (error) {
203
- throw new Error(`Cannot open a database for the user ${userID}`, { cause: error });
204
- }
22
+ /**
23
+ * Opens IndexedDB database for the given user
24
+ *
25
+ * @param userID - The user ID
26
+ * @returns The database
27
+ */
28
+ const openDatabase = async (userID) => {
29
+ try {
30
+ return (0, idb.openDB)(getDatabaseName(userID), require_constants.DB_VERSION, { upgrade(db) {
31
+ if (!db.objectStoreNames.contains(require_constants.DB_LABEL)) db.createObjectStore(require_constants.DB_LABEL, { keyPath: "id" }).createIndex("byTime", "params.createdAt");
32
+ } });
33
+ } catch (error) {
34
+ throw new Error(`Cannot open a database for the user ${userID}`, { cause: error });
35
+ }
205
36
  };
206
- var closeDatabase = (esDB) => {
207
- return esDB.close();
37
+ /**
38
+ * Closes the IndexedDB database
39
+ *
40
+ * @param esDB - The database
41
+ */
42
+ const closeDatabase = (esDB) => {
43
+ return esDB.close();
208
44
  };
209
- var deleteDatabase = async (userID) => {
210
- const dbName = getDatabaseName(userID);
211
- return idb.deleteDB(dbName);
45
+ /**
46
+ * Deletes IndexedDB database for the given user
47
+ *
48
+ * @param userID - The user ID
49
+ * @returns The database
50
+ */
51
+ const deleteDatabase = async (userID) => {
52
+ return (0, idb.deleteDB)(getDatabaseName(userID));
212
53
  };
213
- var deriveIndexKey = async (baseKey) => {
214
- return deriveSymmetricCryptoKeyFromContext(CONTEXT_INDEX, baseKey);
54
+ /**
55
+ * Derives database encryption key for the given user
56
+ *
57
+ * @param userID - The user ID
58
+ * @returns The symmetric CryptoKey for protecting database
59
+ */
60
+ const deriveIndexKey = async (baseKey) => {
61
+ return require_derive_key.deriveSymmetricCryptoKeyFromContext(require_constants.CONTEXT_INDEX, baseKey);
215
62
  };
216
- var encryptAndStoreEmail = async (newEmailToStore, indexKey, esDB) => {
217
- try {
218
- const aux = getAux(newEmailToStore.params);
219
- const ciphertext = await encryptEmailContentSymmetricallyWithKey(
220
- newEmailToStore.body,
221
- indexKey,
222
- aux,
223
- newEmailToStore.id
224
- );
225
- const encryptedEmail = { content: ciphertext, params: newEmailToStore.params, id: newEmailToStore.id };
226
- await esDB.put(DB_LABEL, encryptedEmail);
227
- } catch (error) {
228
- throw new Error("Cannot encrypt and add the given email to the database", { cause: error });
229
- }
63
+ /**
64
+ * Encrypts the given email and stores it in the IndexedDB database
65
+ *
66
+ * @param newEmailToStore - The email for storing
67
+ * @param indexKey - The symmetric CryptoKey key for protecting database
68
+ * @param esDB - The database
69
+ */
70
+ const encryptAndStoreEmail = async (newEmailToStore, indexKey, esDB) => {
71
+ try {
72
+ const aux = require_email_crypto.getAux(newEmailToStore.params, false);
73
+ const encryptedEmail = {
74
+ enc: await require_email_crypto.encryptEmailContentSymmetricallyWithKey(newEmailToStore.body, indexKey, aux, newEmailToStore.id),
75
+ params: newEmailToStore.params,
76
+ id: newEmailToStore.id
77
+ };
78
+ await esDB.put(require_constants.DB_LABEL, encryptedEmail);
79
+ } catch (error) {
80
+ throw new Error("Cannot encrypt and add the given email to the database", { cause: error });
81
+ }
230
82
  };
231
- var encryptAndStoreManyEmail = async (newEmailsToStore, indexKey, esDB) => {
232
- try {
233
- const encryptedEmails = await Promise.all(
234
- newEmailsToStore.map(async (email) => {
235
- const aux = getAux(email.params);
236
- const ciphertext = await encryptEmailContentSymmetricallyWithKey(email.body, indexKey, aux, email.id);
237
- return { content: ciphertext, params: email.params, id: email.id };
238
- })
239
- );
240
- const tr = esDB.transaction(DB_LABEL, "readwrite");
241
- await Promise.all([...encryptedEmails.map((encEmail) => tr.store.put(encEmail)), tr.done]);
242
- } catch (error) {
243
- throw new Error("Cannot encrypt and add emails to the database", { cause: error });
244
- }
83
+ /**
84
+ * Encrypts the given set of emails and stores it in the IndexedDB database
85
+ *
86
+ * @param newEmailsToStore - The set of emails for storing
87
+ * @param indexKey - The symmetric CryptoKey key for protecting database
88
+ * @param esDB - The database
89
+ */
90
+ const encryptAndStoreManyEmail = async (newEmailsToStore, indexKey, esDB) => {
91
+ try {
92
+ const encryptedEmails = await Promise.all(newEmailsToStore.map(async (email) => {
93
+ const aux = require_email_crypto.getAux(email.params, false);
94
+ return {
95
+ enc: await require_email_crypto.encryptEmailContentSymmetricallyWithKey(email.body, indexKey, aux, email.id),
96
+ params: email.params,
97
+ id: email.id
98
+ };
99
+ }));
100
+ const tr = esDB.transaction(require_constants.DB_LABEL, "readwrite");
101
+ await Promise.all([...encryptedEmails.map((encEmail) => tr.store.put(encEmail)), tr.done]);
102
+ } catch (error) {
103
+ throw new Error("Cannot encrypt and add emails to the database", { cause: error });
104
+ }
245
105
  };
246
- var decryptEmail = async (indexKey, encryptedEmail) => {
247
- try {
248
- const aux = getAux(encryptedEmail.params);
249
- const email = await decryptEmailSymmetrically(encryptedEmail.content, indexKey, aux);
250
- return { body: email, params: encryptedEmail.params, id: encryptedEmail.id };
251
- } catch (error) {
252
- throw new Error("Cannot decrypt the given email", { cause: error });
253
- }
106
+ /**
107
+ * Decrypts the given email
108
+ *
109
+ * @param indexKey - The symmetric CryptoKey key for protecting database
110
+ * @param encryptedEmail - The encrypted email
111
+ * @returns The decrypted email
112
+ */
113
+ const decryptEmail = async (indexKey, encryptedEmail) => {
114
+ try {
115
+ return {
116
+ body: await require_email_crypto.decryptEmailSymmetrically(indexKey, require_email_crypto.getAux(encryptedEmail.params, false), encryptedEmail.enc),
117
+ params: encryptedEmail.params,
118
+ id: encryptedEmail.id
119
+ };
120
+ } catch (error) {
121
+ throw new Error("Cannot decrypt the given email", { cause: error });
122
+ }
254
123
  };
255
- var getAndDecryptEmail = async (emailID, indexKey, esDB) => {
256
- try {
257
- const encryptedEmail = await esDB.get(DB_LABEL, emailID);
258
- if (!encryptedEmail) {
259
- throw new Error(`DB cannot find email with id ${emailID}`);
260
- }
261
- return decryptEmail(indexKey, encryptedEmail);
262
- } catch (error) {
263
- throw new Error(`Cannot fetch the email ${emailID} from the database`, { cause: error });
264
- }
124
+ /**
125
+ * Fetches the email from the database and decrypts it
126
+ *
127
+ * @param emailID - The email identifier
128
+ * @param indexKey - The symmetric CryptoKey key for protecting database
129
+ * @param encryptedEmail - The encrypted email
130
+ * @returns The decrypted email
131
+ */
132
+ const getAndDecryptEmail = async (emailID, indexKey, esDB) => {
133
+ try {
134
+ const encryptedEmail = await esDB.get(require_constants.DB_LABEL, emailID);
135
+ if (!encryptedEmail) throw new Error(`DB cannot find email with id ${emailID}`);
136
+ return decryptEmail(indexKey, encryptedEmail);
137
+ } catch (error) {
138
+ throw new Error(`Cannot fetch the email ${emailID} from the database`, { cause: error });
139
+ }
265
140
  };
266
- var getAndDecryptAllEmails = async (indexKey, esDB) => {
267
- try {
268
- const encryptedEmails = await esDB.getAll(DB_LABEL);
269
- const decryptedEmails = await Promise.all(
270
- encryptedEmails.map(async (encEmail) => {
271
- const aux = getAux(encEmail.params);
272
- const body = await decryptEmailSymmetrically(encEmail.content, indexKey, aux);
273
- return { body, params: encEmail.params, id: encEmail.id };
274
- })
275
- );
276
- return decryptedEmails.filter((email) => email !== null);
277
- } catch (error) {
278
- throw new Error("Cannot fetch and decrypt all emails from the database", { cause: error });
279
- }
141
+ /**
142
+ * Fetches all email from the database and decrypts them
143
+ *
144
+ * @param indexKey - The symmetric CryptoKey key for protecting database
145
+ * @param esDB - The database
146
+ * @returns The decrypted emails
147
+ */
148
+ const getAndDecryptAllEmails = async (indexKey, esDB) => {
149
+ try {
150
+ const encryptedEmails = await esDB.getAll(require_constants.DB_LABEL);
151
+ return (await Promise.all(encryptedEmails.map(async (encEmail) => {
152
+ return {
153
+ body: await require_email_crypto.decryptEmailSymmetrically(indexKey, require_email_crypto.getAux(encEmail.params, false), encEmail.enc),
154
+ params: encEmail.params,
155
+ id: encEmail.id
156
+ };
157
+ }))).filter((email) => email !== null);
158
+ } catch (error) {
159
+ throw new Error("Cannot fetch and decrypt all emails from the database", { cause: error });
160
+ }
280
161
  };
281
- var deleteEmail = async (emailID, esDB) => {
282
- await esDB.delete(DB_LABEL, emailID);
162
+ /**
163
+ * Deletes the email from the database
164
+ *
165
+ * @param emailID - The email identifier
166
+ * @param esDB - The database
167
+ */
168
+ const deleteEmail = async (emailID, esDB) => {
169
+ await esDB.delete(require_constants.DB_LABEL, emailID);
283
170
  };
284
- var getEmailCount = async (esDB) => {
285
- return await esDB.count(DB_LABEL);
171
+ /**
172
+ * Returns the number of stored email
173
+ *
174
+ * @param esDB - The database
175
+ * @returns The number of stored emails
176
+ */
177
+ const getEmailCount = async (esDB) => {
178
+ return await esDB.count(require_constants.DB_LABEL);
286
179
  };
287
- var deleteOldestEmails = async (emailsToDelete, esDB) => {
288
- try {
289
- const tx = esDB.transaction(DB_LABEL, "readwrite");
290
- const index = tx.store.index("byTime");
291
- let cursor = await index.openCursor();
292
- let deletedCount = 0;
293
- while (cursor && deletedCount < emailsToDelete) {
294
- await cursor.delete();
295
- deletedCount++;
296
- cursor = await cursor.continue();
297
- }
298
- await tx.done;
299
- } catch (error) {
300
- throw new Error(`Cannot delete ${emailsToDelete} oldests emails from the database`, { cause: error });
301
- }
180
+ /**
181
+ * Removes the given number of oldests emails from the database
182
+ *
183
+ * @param emailsToDelete - The number of emails to delete
184
+ * @param esDB - The database
185
+ */
186
+ const deleteOldestEmails = async (emailsToDelete, esDB) => {
187
+ try {
188
+ const tx = esDB.transaction(require_constants.DB_LABEL, "readwrite");
189
+ let cursor = await tx.store.index("byTime").openCursor();
190
+ let deletedCount = 0;
191
+ while (cursor && deletedCount < emailsToDelete) {
192
+ await cursor.delete();
193
+ deletedCount++;
194
+ cursor = await cursor.continue();
195
+ }
196
+ await tx.done;
197
+ } catch (error) {
198
+ throw new Error(`Cannot delete ${emailsToDelete} oldests emails from the database`, { cause: error });
199
+ }
302
200
  };
303
- var enforceMaxEmailNumber = async (esDB, max) => {
304
- try {
305
- const currentCount = await getEmailCount(esDB);
306
- if (currentCount <= max) {
307
- return;
308
- }
309
- await deleteOldestEmails(currentCount - max, esDB);
310
- } catch (error) {
311
- throw new Error(`Cannot enforce the maximum of ${max} emails on the database`, { cause: error });
312
- }
201
+ /**
202
+ * Enforces the maximum email number in the database
203
+ *
204
+ * @param esDB - The database
205
+ * @param max - The maximum allowed number of emails
206
+ */
207
+ const enforceMaxEmailNumber = async (esDB, max) => {
208
+ try {
209
+ const currentCount = await getEmailCount(esDB);
210
+ if (currentCount <= max) return;
211
+ await deleteOldestEmails(currentCount - max, esDB);
212
+ } catch (error) {
213
+ throw new Error(`Cannot enforce the maximum of ${max} emails on the database`, { cause: error });
214
+ }
313
215
  };
314
- var fetchEmails = async (esDB, indexKey, direction) => {
315
- try {
316
- const tx = esDB.transaction(DB_LABEL, "readonly");
317
- const index = tx.store.index("byTime");
318
- const encryptedEmails = [];
319
- let cursor = await index.openCursor(null, direction);
320
- while (cursor) {
321
- encryptedEmails.push(cursor.value);
322
- cursor = await cursor.continue();
323
- }
324
- const emails = await Promise.all(encryptedEmails.map((encryptedEmail) => decryptEmail(indexKey, encryptedEmail)));
325
- return emails;
326
- } catch (error) {
327
- throw new Error("Cannot fetch emails from database", { cause: error });
328
- }
216
+ /**
217
+ * Fetches all emails from the database, decrypts them and sortes the results in the specified order
218
+ *
219
+ * @param esDB - The database
220
+ * @param indexKey - The symmetric CryptoKey key for protecting database
221
+ * @param direction - The order of sorting. If 'next' - oldest first, if 'prev' - newest first
222
+ * @returns Decryped emails in the specified order
223
+ */
224
+ const fetchEmails = async (esDB, indexKey, direction) => {
225
+ try {
226
+ const index = esDB.transaction(require_constants.DB_LABEL, "readonly").store.index("byTime");
227
+ const encryptedEmails = [];
228
+ let cursor = await index.openCursor(null, direction);
229
+ while (cursor) {
230
+ encryptedEmails.push(cursor.value);
231
+ cursor = await cursor.continue();
232
+ }
233
+ return await Promise.all(encryptedEmails.map((encryptedEmail) => decryptEmail(indexKey, encryptedEmail)));
234
+ } catch (error) {
235
+ throw new Error("Cannot fetch emails from database", { cause: error });
236
+ }
329
237
  };
330
- var getAllEmailsSortedNewestFirst = async (esDB, indexKey) => {
331
- return fetchEmails(esDB, indexKey, "prev");
238
+ /**
239
+ * Fetches all emails from the database, decrypts them and sortes the results based on the creation time (newest first)
240
+ *
241
+ * @param esDB - The database
242
+ * @param indexKey - The symmetric CryptoKey key for protecting database
243
+ * @returns The number of stored emails
244
+ */
245
+ const getAllEmailsSortedNewestFirst = async (esDB, indexKey) => {
246
+ return fetchEmails(esDB, indexKey, "prev");
332
247
  };
333
- var getAllEmailsSortedOldestFirst = async (esDB, indexKey) => {
334
- return fetchEmails(esDB, indexKey, "next");
248
+ /**
249
+ * Fetches all emails from the database, decrypts them and sortes the results based on the creation time (oldest first)
250
+ *
251
+ * @param esDB - The database
252
+ * @param indexKey - The symmetric CryptoKey key for protecting database
253
+ * @returns The number of stored emails
254
+ */
255
+ const getAllEmailsSortedOldestFirst = async (esDB, indexKey) => {
256
+ return fetchEmails(esDB, indexKey, "next");
335
257
  };
336
- var getEmailBatch = async (esDB, indexKey, batchSize, startCursor) => {
337
- try {
338
- const tx = esDB.transaction(DB_LABEL, "readonly");
339
- const index = tx.store.index("byTime");
340
- const encryptedEmails = [];
341
- let cursor;
342
- if (startCursor) {
343
- const range = IDBKeyRange.upperBound(startCursor, true);
344
- cursor = await index.openCursor(range, "prev");
345
- } else {
346
- cursor = await index.openCursor(null, "prev");
347
- }
348
- let count = 0;
349
- let nextCursor;
350
- while (cursor && count < batchSize) {
351
- encryptedEmails.push(cursor.value);
352
- nextCursor = cursor.key;
353
- count++;
354
- cursor = await cursor.continue();
355
- }
356
- const emails = await Promise.all(encryptedEmails.map((encryptedEmail) => decryptEmail(indexKey, encryptedEmail)));
357
- return {
358
- emails,
359
- nextCursor: count === batchSize ? nextCursor : void 0
360
- };
361
- } catch (error) {
362
- throw new Error(`Cannot fetch email batch of ${batchSize} from the database`, { cause: error });
363
- }
258
+ /**
259
+ * Fetches a batch of emails from the database, decrypts them and sortes the results based on the creation time (newest first)
260
+ *
261
+ * @param esDB - The database
262
+ * @param indexKey - The symmetric CryptoKey key for protecting database
263
+ * @param batchSize - The size of the batch
264
+ * @param startCursor - The starting point (optional). If not given, starts from the beginning
265
+ * @returns The number of stored emails
266
+ */
267
+ const getEmailBatch = async (esDB, indexKey, batchSize, startCursor) => {
268
+ try {
269
+ const index = esDB.transaction(require_constants.DB_LABEL, "readonly").store.index("byTime");
270
+ const encryptedEmails = [];
271
+ let cursor;
272
+ if (startCursor) {
273
+ const range = IDBKeyRange.upperBound(startCursor, true);
274
+ cursor = await index.openCursor(range, "prev");
275
+ } else cursor = await index.openCursor(null, "prev");
276
+ let count = 0;
277
+ let nextCursor;
278
+ while (cursor && count < batchSize) {
279
+ encryptedEmails.push(cursor.value);
280
+ nextCursor = cursor.key;
281
+ count++;
282
+ cursor = await cursor.continue();
283
+ }
284
+ return {
285
+ emails: await Promise.all(encryptedEmails.map((encryptedEmail) => decryptEmail(indexKey, encryptedEmail))),
286
+ nextCursor: count === batchSize ? nextCursor : void 0
287
+ };
288
+ } catch (error) {
289
+ throw new Error(`Cannot fetch email batch of ${batchSize} from the database`, { cause: error });
290
+ }
364
291
  };
365
292
 
366
- // src/email-search/mailCache.ts
293
+ //#endregion
294
+ //#region src/email-search/mailCache.ts
295
+ /**
296
+ * Estimates the email size in the memory
297
+ *
298
+ * @param email - The email
299
+ * @returns The estimation of the email size
300
+ */
367
301
  function sizeOfEmail(email) {
368
- return emailToBinary(email).byteLength;
302
+ return require_email_crypto.emailToBinary(email).byteLength;
369
303
  }
304
+ /**
305
+ * Creates an empty cache variable
306
+ *
307
+ * @returns The empty cache
308
+ */
370
309
  function createEmptyCache() {
371
- return {
372
- esCache: /* @__PURE__ */ new Map(),
373
- cacheSize: 0,
374
- isCacheLimited: false,
375
- isCacheReady: true
376
- };
310
+ return {
311
+ esCache: /* @__PURE__ */ new Map(),
312
+ cacheSize: 0,
313
+ isCacheLimited: false,
314
+ isCacheReady: true
315
+ };
377
316
  }
378
- var createCacheFromDB = async (indexKey, esDB) => {
379
- const esCache = createEmptyCache();
380
- esCache.isCacheReady = false;
381
- try {
382
- const count = await getEmailCount(esDB);
383
- if (!count) {
384
- esCache.isCacheReady = true;
385
- return esCache;
386
- }
387
- if (count <= MAX_EMAIL_PER_BATCH) {
388
- const emails = await getAllEmailsSortedNewestFirst(esDB, indexKey);
389
- addEmailsToCache(emails, esCache);
390
- } else {
391
- let nextCursor = void 0;
392
- let cacheFull = false;
393
- while (!cacheFull) {
394
- const { emails, nextCursor: newCursor } = await getEmailBatch(
395
- esDB,
396
- indexKey,
397
- MAX_EMAIL_PER_BATCH,
398
- nextCursor
399
- );
400
- if (!newCursor || !emails.length) break;
401
- nextCursor = newCursor;
402
- const success = addEmailsToCache(emails, esCache);
403
- if (!success) cacheFull = true;
404
- }
405
- }
406
- return esCache;
407
- } catch (error) {
408
- throw new Error(`Email caching failed: ${error}`);
409
- }
317
+ /**
318
+ * Fetches all emails from the database in batches and cahces them
319
+ *
320
+ * @param indexKey - The symmetric CryptoKey key for protecting database
321
+ * @param esCache - The cache to add emails too
322
+ * @param esDB - The database
323
+ */
324
+ const createCacheFromDB = async (indexKey, esDB) => {
325
+ const esCache = createEmptyCache();
326
+ esCache.isCacheReady = false;
327
+ try {
328
+ const count = await getEmailCount(esDB);
329
+ if (!count) {
330
+ esCache.isCacheReady = true;
331
+ return esCache;
332
+ }
333
+ if (count <= require_constants.MAX_EMAIL_PER_BATCH) addEmailsToCache(await getAllEmailsSortedNewestFirst(esDB, indexKey), esCache);
334
+ else {
335
+ let nextCursor = void 0;
336
+ let cacheFull = false;
337
+ while (!cacheFull) {
338
+ const { emails, nextCursor: newCursor } = await getEmailBatch(esDB, indexKey, require_constants.MAX_EMAIL_PER_BATCH, nextCursor);
339
+ if (!newCursor || !emails.length) break;
340
+ nextCursor = newCursor;
341
+ if (!addEmailsToCache(emails, esCache)) cacheFull = true;
342
+ }
343
+ }
344
+ return esCache;
345
+ } catch (error) {
346
+ throw new Error(`Email caching failed: ${error}`);
347
+ }
410
348
  };
411
- var getEmailFromCache = async (emailID, esCache) => {
412
- const email = esCache.esCache.get(emailID);
413
- if (!email) {
414
- throw new Error(`Email not found in cache for ID: ${emailID}`);
415
- }
416
- return email;
349
+ /**
350
+ * Gets an email from the cache
351
+ *
352
+ * @param emailID - The email identifier
353
+ * @param esCache - The email cache
354
+ * @returns The found email or throws an error
355
+ */
356
+ const getEmailFromCache = async (emailID, esCache) => {
357
+ const email = esCache.esCache.get(emailID);
358
+ if (!email) throw new Error(`Email not found in cache for ID: ${emailID}`);
359
+ return email;
417
360
  };
418
- var deleteEmailFromCache = async (emailID, esCache) => {
419
- try {
420
- const email = await getEmailFromCache(emailID, esCache);
421
- const size = sizeOfEmail(email);
422
- const removed = esCache.esCache.delete(emailID);
423
- if (removed) esCache.cacheSize -= size;
424
- } catch (error) {
425
- throw new Error(`Failed to delete email with ID ${emailID}`, { cause: error });
426
- }
361
+ /**
362
+ * Removes the email from cache
363
+ *
364
+ * @param emailID - The email identifier
365
+ * @param esCache - The email cache
366
+ */
367
+ const deleteEmailFromCache = async (emailID, esCache) => {
368
+ try {
369
+ const size = sizeOfEmail(await getEmailFromCache(emailID, esCache));
370
+ if (esCache.esCache.delete(emailID)) esCache.cacheSize -= size;
371
+ } catch (error) {
372
+ throw new Error(`Failed to delete email with ID ${emailID}`, { cause: error });
373
+ }
427
374
  };
375
+ /**
376
+ * Adds emails to the cache
377
+ *
378
+ * @param emails - The emails to add
379
+ * @param esCache - The email cache
380
+ * @returns TRUE if all emails were added sucessfully, or FALSE and error reason.
381
+ */
428
382
  function addEmailsToCache(emails, esCache) {
429
- try {
430
- for (const email of emails) {
431
- const result = addEmailToCache(email, esCache);
432
- if (!result.success) return result;
433
- }
434
- return { success: true };
435
- } catch (error) {
436
- throw new Error("Failed to add emails to the cache", { cause: error });
437
- }
383
+ try {
384
+ for (const email of emails) {
385
+ const result = addEmailToCache(email, esCache);
386
+ if (!result.success) return result;
387
+ }
388
+ return { success: true };
389
+ } catch (error) {
390
+ throw new Error("Failed to add emails to the cache", { cause: error });
391
+ }
438
392
  }
439
- var addEmailToCache = (email, esCache) => {
440
- try {
441
- if (esCache.esCache.has(email.id)) {
442
- return { success: false, reason: "email already exists in cache" };
443
- }
444
- const emailSize = sizeOfEmail(email);
445
- if (esCache.cacheSize + emailSize > MAX_CACHE_SIZE) {
446
- esCache.isCacheLimited = true;
447
- return { success: false, reason: "hit cache limit" };
448
- }
449
- esCache.esCache.set(email.id, email);
450
- esCache.cacheSize += emailSize;
451
- return { success: true };
452
- } catch (error) {
453
- throw new Error("Failed to add email to the cache", { cause: error });
454
- }
393
+ /**
394
+ * Adds email to the cache
395
+ *
396
+ * @param email - The email to add
397
+ * @param esCache - The email cache
398
+ * @returns TRUE if the email was added sucessfully, or FALSE and error reason.
399
+ */
400
+ const addEmailToCache = (email, esCache) => {
401
+ try {
402
+ if (esCache.esCache.has(email.id)) return {
403
+ success: false,
404
+ reason: "email already exists in cache"
405
+ };
406
+ const emailSize = sizeOfEmail(email);
407
+ if (esCache.cacheSize + emailSize > require_constants.MAX_CACHE_SIZE) {
408
+ esCache.isCacheLimited = true;
409
+ return {
410
+ success: false,
411
+ reason: "hit cache limit"
412
+ };
413
+ }
414
+ esCache.esCache.set(email.id, email);
415
+ esCache.cacheSize += emailSize;
416
+ return { success: true };
417
+ } catch (error) {
418
+ throw new Error("Failed to add email to the cache", { cause: error });
419
+ }
455
420
  };
456
- var SUBJECT_OPTIONS = {
457
- preset: "match",
458
- tokenize: "forward",
459
- resolution: 9,
460
- minlength: 2,
461
- optimize: true,
462
- fastupdate: true,
463
- cache: true
421
+
422
+ //#endregion
423
+ //#region src/email-search/search.ts
424
+ const SUBJECT_OPTIONS = {
425
+ preset: "match",
426
+ tokenize: "forward",
427
+ resolution: 9,
428
+ minlength: 2,
429
+ optimize: true,
430
+ fastupdate: true,
431
+ cache: true
464
432
  };
465
- var BODY_OPTIONS = {
466
- ...SUBJECT_OPTIONS,
467
- minlength: 3,
468
- resolution: 6
433
+ const BODY_OPTIONS = {
434
+ ...SUBJECT_OPTIONS,
435
+ minlength: 3,
436
+ resolution: 6
469
437
  };
470
- var FROM_OPTIONS = {
471
- ...SUBJECT_OPTIONS,
472
- tokenize: "strict",
473
- minlength: 1
438
+ const FROM_OPTIONS = {
439
+ ...SUBJECT_OPTIONS,
440
+ tokenize: "strict",
441
+ minlength: 1
474
442
  };
475
- var TO_OPTIONS = {
476
- ...SUBJECT_OPTIONS,
477
- tokenize: "strict",
478
- minlength: 1
443
+ const TO_OPTIONS = {
444
+ ...SUBJECT_OPTIONS,
445
+ tokenize: "strict",
446
+ minlength: 1
479
447
  };
480
- var createSearchIndex = () => ({
481
- subjectIndex: new flexsearch.Index(SUBJECT_OPTIONS),
482
- bodyIndex: new flexsearch.Index(BODY_OPTIONS),
483
- fromIndex: new flexsearch.Index(FROM_OPTIONS),
484
- toIndex: new flexsearch.Index(TO_OPTIONS),
485
- isReady: false
448
+ /**
449
+ * Creates new email search index
450
+ *
451
+ * @returns The email search index
452
+ */
453
+ const createSearchIndex = () => ({
454
+ subjectIndex: new flexsearch.Index(SUBJECT_OPTIONS),
455
+ bodyIndex: new flexsearch.Index(BODY_OPTIONS),
456
+ fromIndex: new flexsearch.Index(FROM_OPTIONS),
457
+ toIndex: new flexsearch.Index(TO_OPTIONS),
458
+ isReady: false
486
459
  });
487
- var addEmailToSearchIndex = (email, searchIndex) => {
488
- try {
489
- const emailId = email.id;
490
- if (email.params.subject) {
491
- searchIndex.subjectIndex.add(emailId, email.params.subject);
492
- }
493
- if (email.body?.text) {
494
- searchIndex.bodyIndex.add(emailId, email.body.text);
495
- }
496
- if (email.params.sender) {
497
- const senderText = `${email.params.sender.name || ""} ${email.params.sender.email || ""}`.trim();
498
- searchIndex.fromIndex.add(emailId, senderText);
499
- }
500
- const recipientsList = email.params.recipients?.length ? email.params.recipients : [email.params.recipient];
501
- const recipientsText = recipientsList.map((recipient) => `${recipient.name || ""} ${recipient.email || ""}`.trim()).join(" ");
502
- searchIndex.toIndex.add(emailId, recipientsText);
503
- } catch (error) {
504
- throw new Error("Failed to add email to the search index", { cause: error });
505
- }
460
+ /**
461
+ * Adds the given email to the email search index
462
+ *
463
+ * @param email - The email to add
464
+ * @param searchIndex - The email search index
465
+ */
466
+ const addEmailToSearchIndex = (email, searchIndex) => {
467
+ try {
468
+ const emailId = email.id;
469
+ if (email.params.subject) searchIndex.subjectIndex.add(emailId, email.params.subject);
470
+ if (email.body?.text) searchIndex.bodyIndex.add(emailId, email.body.text);
471
+ if (email.params.sender) {
472
+ const senderText = `${email.params.sender.name || ""} ${email.params.sender.email || ""}`.trim();
473
+ searchIndex.fromIndex.add(emailId, senderText);
474
+ }
475
+ const recipientsText = (email.params.recipients?.length ? email.params.recipients : [email.params.recipient]).map((recipient) => `${recipient.name || ""} ${recipient.email || ""}`.trim()).join(" ");
476
+ searchIndex.toIndex.add(emailId, recipientsText);
477
+ } catch (error) {
478
+ throw new Error("Failed to add email to the search index", { cause: error });
479
+ }
506
480
  };
507
- var removeEmailFromSearchIndex = (emailID, searchIndex) => {
508
- try {
509
- searchIndex.subjectIndex.remove(emailID);
510
- searchIndex.bodyIndex.remove(emailID);
511
- searchIndex.fromIndex.remove(emailID);
512
- searchIndex.toIndex.remove(emailID);
513
- } catch (error) {
514
- throw new Error(`Failed to remove email with ID ${emailID} from the search index`, { cause: error });
515
- }
481
+ /**
482
+ * Removes the email from the email search index
483
+ *
484
+ * @param emailID - The email identifier
485
+ * @param searchIndex - The email search index
486
+ */
487
+ const removeEmailFromSearchIndex = (emailID, searchIndex) => {
488
+ try {
489
+ searchIndex.subjectIndex.remove(emailID);
490
+ searchIndex.bodyIndex.remove(emailID);
491
+ searchIndex.fromIndex.remove(emailID);
492
+ searchIndex.toIndex.remove(emailID);
493
+ } catch (error) {
494
+ throw new Error(`Failed to remove email with ID ${emailID} from the search index`, { cause: error });
495
+ }
516
496
  };
517
- var buildSearchIndexFromCache = async (esCache) => {
518
- try {
519
- const searchIndex = createSearchIndex();
520
- searchIndex.isReady = false;
521
- for (const email of esCache.esCache.values()) {
522
- addEmailToSearchIndex(email, searchIndex);
523
- }
524
- searchIndex.isReady = true;
525
- return searchIndex;
526
- } catch (error) {
527
- throw new Error("Failed build an email search index from the cache", { cause: error });
528
- }
497
+ /**
498
+ * Buils the email search index from the email cache
499
+ *
500
+ * @param esCache - The email cache
501
+ * @returns The email search index
502
+ */
503
+ const buildSearchIndexFromCache = async (esCache) => {
504
+ try {
505
+ const searchIndex = createSearchIndex();
506
+ searchIndex.isReady = false;
507
+ for (const email of esCache.esCache.values()) addEmailToSearchIndex(email, searchIndex);
508
+ searchIndex.isReady = true;
509
+ return searchIndex;
510
+ } catch (error) {
511
+ throw new Error("Failed build an email search index from the cache", { cause: error });
512
+ }
529
513
  };
530
- var searchEmails = async (query, esCache, searchIndex, options = {}) => {
531
- try {
532
- if (!searchIndex.isReady || !query.trim()) {
533
- return [];
534
- }
535
- const {
536
- fields = ["subject", "body", "from", "to"],
537
- limit = 50,
538
- boost = { subject: 3, body: 1, from: 2, to: 2 }
539
- } = options;
540
- const results = /* @__PURE__ */ new Map();
541
- const searchPromises = fields.map(async (field) => {
542
- let fieldResults;
543
- switch (field) {
544
- case "subject":
545
- fieldResults = await searchIndex.subjectIndex.searchAsync(query);
546
- break;
547
- case "body":
548
- fieldResults = await searchIndex.bodyIndex.searchAsync(query);
549
- break;
550
- case "from":
551
- fieldResults = await searchIndex.fromIndex.searchAsync(query);
552
- break;
553
- case "to":
554
- fieldResults = await searchIndex.toIndex.searchAsync(query);
555
- break;
556
- default:
557
- return;
558
- }
559
- const fieldBoost = boost[field] || 1;
560
- fieldResults.forEach((emailId) => {
561
- const currentScore = results.get(String(emailId)) || 0;
562
- results.set(String(emailId), currentScore + fieldBoost);
563
- });
564
- });
565
- await Promise.all(searchPromises);
566
- const emailResults = [];
567
- for (const [emailId, score] of results) {
568
- const email = esCache.esCache.get(emailId);
569
- if (email) {
570
- emailResults.push({ email, score });
571
- }
572
- }
573
- emailResults.sort((a, b) => (b.score || 0) - (a.score || 0));
574
- return emailResults.slice(0, limit);
575
- } catch (error) {
576
- throw new Error("Email search failed", { cause: error });
577
- }
514
+ /**
515
+ * Searches in teh
516
+ *
517
+ * @param query - The string to search for
518
+ * @param esCache - The email cache
519
+ * @param searchIndex - The email search index
520
+ * @param opetions - The optional search limitations
521
+ * @returns The result of the email search (emails ans their corresponding result weights)
522
+ */
523
+ const searchEmails = async (query, esCache, searchIndex, options = {}) => {
524
+ try {
525
+ if (!searchIndex.isReady || !query.trim()) return [];
526
+ const { fields = [
527
+ "subject",
528
+ "body",
529
+ "from",
530
+ "to"
531
+ ], limit = 50, boost = {
532
+ subject: 3,
533
+ body: 1,
534
+ from: 2,
535
+ to: 2
536
+ } } = options;
537
+ const results = /* @__PURE__ */ new Map();
538
+ const searchPromises = fields.map(async (field) => {
539
+ let fieldResults;
540
+ switch (field) {
541
+ case "subject":
542
+ fieldResults = await searchIndex.subjectIndex.searchAsync(query);
543
+ break;
544
+ case "body":
545
+ fieldResults = await searchIndex.bodyIndex.searchAsync(query);
546
+ break;
547
+ case "from":
548
+ fieldResults = await searchIndex.fromIndex.searchAsync(query);
549
+ break;
550
+ case "to":
551
+ fieldResults = await searchIndex.toIndex.searchAsync(query);
552
+ break;
553
+ default: return;
554
+ }
555
+ const fieldBoost = boost[field] || 1;
556
+ fieldResults.forEach((emailId) => {
557
+ const currentScore = results.get(String(emailId)) || 0;
558
+ results.set(String(emailId), currentScore + fieldBoost);
559
+ });
560
+ });
561
+ await Promise.all(searchPromises);
562
+ const emailResults = [];
563
+ for (const [emailId, score] of results) {
564
+ const email = esCache.esCache.get(emailId);
565
+ if (email) emailResults.push({
566
+ email,
567
+ score
568
+ });
569
+ }
570
+ emailResults.sort((a, b) => (b.score || 0) - (a.score || 0));
571
+ return emailResults.slice(0, limit);
572
+ } catch (error) {
573
+ throw new Error("Email search failed", { cause: error });
574
+ }
578
575
  };
579
576
 
577
+ //#endregion
578
+ //#region src/email-search/index.ts
579
+ var email_search_exports = /* @__PURE__ */ require_chunk.__exportAll({
580
+ addEmailToCache: () => addEmailToCache,
581
+ addEmailToSearchIndex: () => addEmailToSearchIndex,
582
+ addEmailsToCache: () => addEmailsToCache,
583
+ buildSearchIndexFromCache: () => buildSearchIndexFromCache,
584
+ closeDatabase: () => closeDatabase,
585
+ createCacheFromDB: () => createCacheFromDB,
586
+ deleteDatabase: () => deleteDatabase,
587
+ deleteEmail: () => deleteEmail,
588
+ deleteEmailFromCache: () => deleteEmailFromCache,
589
+ deleteOldestEmails: () => deleteOldestEmails,
590
+ deriveIndexKey: () => deriveIndexKey,
591
+ encryptAndStoreEmail: () => encryptAndStoreEmail,
592
+ encryptAndStoreManyEmail: () => encryptAndStoreManyEmail,
593
+ enforceMaxEmailNumber: () => enforceMaxEmailNumber,
594
+ getAllEmailsSortedNewestFirst: () => getAllEmailsSortedNewestFirst,
595
+ getAllEmailsSortedOldestFirst: () => getAllEmailsSortedOldestFirst,
596
+ getAndDecryptAllEmails: () => getAndDecryptAllEmails,
597
+ getAndDecryptEmail: () => getAndDecryptEmail,
598
+ getEmailBatch: () => getEmailBatch,
599
+ getEmailCount: () => getEmailCount,
600
+ getEmailFromCache: () => getEmailFromCache,
601
+ openDatabase: () => openDatabase,
602
+ removeEmailFromSearchIndex: () => removeEmailFromSearchIndex,
603
+ searchEmails: () => searchEmails
604
+ });
605
+
606
+ //#endregion
580
607
  exports.addEmailToCache = addEmailToCache;
581
608
  exports.addEmailToSearchIndex = addEmailToSearchIndex;
582
609
  exports.addEmailsToCache = addEmailsToCache;
@@ -588,6 +615,12 @@ exports.deleteEmail = deleteEmail;
588
615
  exports.deleteEmailFromCache = deleteEmailFromCache;
589
616
  exports.deleteOldestEmails = deleteOldestEmails;
590
617
  exports.deriveIndexKey = deriveIndexKey;
618
+ Object.defineProperty(exports, 'email_search_exports', {
619
+ enumerable: true,
620
+ get: function () {
621
+ return email_search_exports;
622
+ }
623
+ });
591
624
  exports.encryptAndStoreEmail = encryptAndStoreEmail;
592
625
  exports.encryptAndStoreManyEmail = encryptAndStoreManyEmail;
593
626
  exports.enforceMaxEmailNumber = enforceMaxEmailNumber;
@@ -601,5 +634,4 @@ exports.getEmailFromCache = getEmailFromCache;
601
634
  exports.openDatabase = openDatabase;
602
635
  exports.removeEmailFromSearchIndex = removeEmailFromSearchIndex;
603
636
  exports.searchEmails = searchEmails;
604
- //# sourceMappingURL=email-search.js.map
605
637
  //# sourceMappingURL=email-search.js.map