@rapidmx/web-client 0.4.0 → 0.6.0

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 (320) hide show
  1. package/README.md +88 -0
  2. package/apps/admin/audit-log/index.tsx +35 -8
  3. package/apps/admin/data-requests/index.tsx +480 -485
  4. package/apps/admin/distribution-lists/[uid].tsx +19 -1
  5. package/apps/admin/escrow-scopes/[uid].tsx +348 -237
  6. package/apps/admin/escrow-scopes/new/index.tsx +8 -2
  7. package/apps/admin/index.tsx +19 -1
  8. package/apps/admin/ingest-queue/index.tsx +44 -5
  9. package/apps/admin/mailboxes/[uid].tsx +211 -184
  10. package/apps/admin/quarantine/index.tsx +46 -14
  11. package/apps/admin/transport-rules/[uid].tsx +30 -1
  12. package/apps/admin/transport-rules/_transportRuleConfig.tsx +38 -2
  13. package/apps/admin/transport-rules/index.tsx +24 -6
  14. package/apps/admin/transport-rules/new/index.tsx +30 -1
  15. package/apps/escrow/_layout.tsx +2 -3
  16. package/apps/escrow/audit-log/index.tsx +196 -168
  17. package/apps/escrow/matters/[uid].tsx +621 -521
  18. package/apps/shared/components/admin/escrowScopes/EscrowScopeKeyAndHoldersFields.tsx +22 -1
  19. package/apps/shared/components/admin/layout/AdminShell.tsx +28 -9
  20. package/apps/shared/components/admin/mailboxes/EscrowScopeCard.tsx +152 -0
  21. package/apps/shared/components/admin/mailboxes/ResourceSettingsCard.tsx +3 -3
  22. package/apps/shared/components/admin/mailboxes/ShareAccessCard.tsx +55 -11
  23. package/apps/shared/components/admin/settings/BrandingForm.tsx +15 -4
  24. package/apps/shared/components/admin/settings/DomainDnsSetup.tsx +18 -7
  25. package/apps/shared/components/admin/settings/EncryptionPolicyForm.tsx +10 -2
  26. package/apps/shared/components/admin/settings/MailboxCreateForm.tsx +6 -0
  27. package/apps/shared/components/admin/settings/MailboxPolicyForm.tsx +45 -12
  28. package/apps/shared/components/admin/settings/PluginsManager.tsx +1235 -595
  29. package/apps/shared/components/admin/settings/RetentionPolicyForm.tsx +174 -98
  30. package/apps/shared/components/admin/setup/EscrowSetupStep.tsx +49 -13
  31. package/apps/shared/components/admin/setup/SetupWizard.tsx +150 -34
  32. package/apps/shared/components/admin/signOut.ts +79 -0
  33. package/apps/shared/components/admin/usePagedList.tsx +129 -0
  34. package/apps/shared/components/calendar/EventModal.tsx +717 -549
  35. package/apps/shared/components/calendar/MonthView.tsx +173 -139
  36. package/apps/shared/components/calendar/RecurrenceEditor.tsx +222 -180
  37. package/apps/shared/components/calendar/SplitDayView.tsx +143 -137
  38. package/apps/shared/components/calendar/TimeGridView.tsx +244 -198
  39. package/apps/shared/components/calendar/allDay.ts +124 -0
  40. package/apps/shared/components/calendar/layout/CalendarShell.tsx +194 -192
  41. package/apps/shared/components/contacts/ContactDetailPane.tsx +100 -21
  42. package/apps/shared/components/contacts/ContactForm.tsx +377 -348
  43. package/apps/shared/components/contacts/ContactsSidebar.tsx +6 -2
  44. package/apps/shared/components/contacts/KeyChangeReview.tsx +192 -0
  45. package/apps/shared/components/contacts/contactKeys.ts +78 -0
  46. package/apps/shared/components/contacts/layout/ContactsShell.tsx +199 -197
  47. package/apps/shared/components/escrow/layout/EscrowShell.tsx +148 -134
  48. package/apps/shared/components/layout/AppShell.tsx +123 -33
  49. package/apps/shared/components/layout/BrandingChrome.tsx +48 -10
  50. package/apps/shared/components/layout/KeyEnrollmentGate.tsx +389 -298
  51. package/apps/shared/components/layout/MailboxProvisioning.tsx +19 -3
  52. package/apps/shared/components/layout/RecoveryCodeUnlock.tsx +350 -0
  53. package/apps/shared/components/layout/UnlockPromptProvider.tsx +257 -128
  54. package/apps/shared/components/mail/ConversationThreadPane.tsx +216 -181
  55. package/apps/shared/components/mail/MessageDetailPane.tsx +1318 -630
  56. package/apps/shared/components/mail/compose/ComposeContext.tsx +20 -15
  57. package/apps/shared/components/mail/compose/ComposeWindow.tsx +854 -132
  58. package/apps/shared/components/mail/compose/composeFlushRegistry.ts +60 -0
  59. package/apps/shared/components/mail/layout/MailShell.tsx +420 -408
  60. package/apps/shared/components/mail/pinnedSigners.ts +124 -0
  61. package/apps/shared/components/mail/verificationSeals.ts +125 -0
  62. package/apps/shared/components/mail/writableMailboxes.ts +101 -0
  63. package/apps/shared/components/rules/RuleBuilder.tsx +311 -276
  64. package/apps/shared/components/settings/layout/SettingsShell.tsx +23 -9
  65. package/apps/shared/components/tasks/layout/TasksShell.tsx +201 -199
  66. package/apps/shared/mail/listAllPages.ts +39 -0
  67. package/apps/shared/plugins/pluginNav.ts +73 -0
  68. package/apps/shared/search/LocalIndexLifecycle.tsx +64 -55
  69. package/apps/shared/search/localIndexBuilder.ts +481 -179
  70. package/apps/shared/search/localIndexRpcClient.ts +231 -29
  71. package/apps/shared/search/localIndexSchema.ts +15 -6
  72. package/apps/shared/search/localIndexStorage.ts +98 -0
  73. package/apps/shared/search/localIndexVFS.ts +32 -1
  74. package/apps/shared/search/localIndexWorker.ts +648 -186
  75. package/apps/www/calendar/index.tsx +438 -417
  76. package/apps/www/contacts/[uid].tsx +21 -2
  77. package/apps/www/contacts/index.tsx +116 -12
  78. package/apps/www/index.tsx +1314 -1041
  79. package/apps/www/messages/[uid].tsx +18 -6
  80. package/apps/www/settings/auto-reply/index.tsx +134 -129
  81. package/apps/www/settings/encryption/index.tsx +739 -216
  82. package/apps/www/settings/filters/[uid].tsx +171 -155
  83. package/apps/www/settings/filters/new/index.tsx +8 -1
  84. package/apps/www/settings/focused-inbox/index.tsx +150 -148
  85. package/apps/www/settings/privacy/index.tsx +494 -436
  86. package/apps/www/settings/read-receipts/index.tsx +148 -125
  87. package/apps/www/settings/sharing/index.tsx +17 -14
  88. package/apps/www/tasks/index.tsx +638 -579
  89. package/dist/apps/admin/_404.d.ts +2 -0
  90. package/dist/apps/admin/_500.d.ts +2 -0
  91. package/dist/apps/admin/_layout.d.ts +8 -0
  92. package/dist/apps/admin/audit-log/index.d.ts +11 -0
  93. package/dist/apps/admin/audit-log/index.js +38 -8
  94. package/dist/apps/admin/branding/index.d.ts +3 -0
  95. package/dist/apps/admin/data-requests/index.d.ts +3 -0
  96. package/dist/apps/admin/data-requests/index.js +52 -72
  97. package/dist/apps/admin/distribution-lists/[uid].d.ts +7 -0
  98. package/dist/apps/admin/distribution-lists/[uid].js +1 -1
  99. package/dist/apps/admin/distribution-lists/index.d.ts +3 -0
  100. package/dist/apps/admin/distribution-lists/new/index.d.ts +3 -0
  101. package/dist/apps/admin/domains/[uid].d.ts +7 -0
  102. package/dist/apps/admin/domains/index.d.ts +3 -0
  103. package/dist/apps/admin/domains/new/index.d.ts +3 -0
  104. package/dist/apps/admin/encryption-policy/index.d.ts +3 -0
  105. package/dist/apps/admin/escrow-scopes/[uid].d.ts +21 -0
  106. package/dist/apps/admin/escrow-scopes/[uid].js +91 -12
  107. package/dist/apps/admin/escrow-scopes/index.d.ts +3 -0
  108. package/dist/apps/admin/escrow-scopes/new/index.d.ts +3 -0
  109. package/dist/apps/admin/escrow-scopes/new/index.js +8 -3
  110. package/dist/apps/admin/index.d.ts +3 -0
  111. package/dist/apps/admin/index.js +4 -1
  112. package/dist/apps/admin/ingest-queue/index.d.ts +4 -0
  113. package/dist/apps/admin/ingest-queue/index.js +24 -6
  114. package/dist/apps/admin/mailbox-policy/index.d.ts +3 -0
  115. package/dist/apps/admin/mailboxes/[uid].d.ts +7 -0
  116. package/dist/apps/admin/mailboxes/[uid].js +20 -4
  117. package/dist/apps/admin/mailboxes/new/index.d.ts +3 -0
  118. package/dist/apps/admin/plugins/index.d.ts +3 -0
  119. package/dist/apps/admin/quarantine/index.d.ts +6 -0
  120. package/dist/apps/admin/quarantine/index.js +20 -11
  121. package/dist/apps/admin/retention-policy/index.d.ts +3 -0
  122. package/dist/apps/admin/setup/index.d.ts +3 -0
  123. package/dist/apps/admin/transport-rules/[uid].d.ts +7 -0
  124. package/dist/apps/admin/transport-rules/[uid].js +18 -2
  125. package/dist/apps/admin/transport-rules/_transportRuleConfig.d.ts +21 -0
  126. package/dist/apps/admin/transport-rules/_transportRuleConfig.js +19 -0
  127. package/dist/apps/admin/transport-rules/index.d.ts +3 -0
  128. package/dist/apps/admin/transport-rules/index.js +22 -6
  129. package/dist/apps/admin/transport-rules/new/index.d.ts +3 -0
  130. package/dist/apps/admin/transport-rules/new/index.js +18 -2
  131. package/dist/apps/escrow/_layout.d.ts +10 -0
  132. package/dist/apps/escrow/_layout.js +3 -3
  133. package/dist/apps/escrow/audit-log/index.d.ts +9 -0
  134. package/dist/apps/escrow/audit-log/index.js +26 -1
  135. package/dist/apps/escrow/index.d.ts +3 -0
  136. package/dist/apps/escrow/matters/[uid].d.ts +7 -0
  137. package/dist/apps/escrow/matters/[uid].js +77 -42
  138. package/dist/apps/escrow/matters/new/index.d.ts +3 -0
  139. package/dist/apps/shared/components/admin/distributionLists/MemberListCard.d.ts +17 -0
  140. package/dist/apps/shared/components/admin/escrowScopes/EscrowScopeKeyAndHoldersFields.d.ts +32 -0
  141. package/dist/apps/shared/components/admin/escrowScopes/EscrowScopeKeyAndHoldersFields.js +11 -2
  142. package/dist/apps/shared/components/admin/layout/AdminShell.d.ts +32 -0
  143. package/dist/apps/shared/components/admin/layout/AdminShell.js +15 -6
  144. package/dist/apps/shared/components/admin/mailboxes/EscrowScopeCard.d.ts +12 -0
  145. package/dist/apps/shared/components/admin/mailboxes/EscrowScopeCard.js +72 -0
  146. package/dist/apps/shared/components/admin/mailboxes/MailboxTable.d.ts +6 -0
  147. package/dist/apps/shared/components/admin/mailboxes/ResourceSettingsCard.d.ts +19 -0
  148. package/dist/apps/shared/components/admin/mailboxes/ResourceSettingsCard.js +3 -3
  149. package/dist/apps/shared/components/admin/mailboxes/ShareAccessCard.d.ts +12 -0
  150. package/dist/apps/shared/components/admin/mailboxes/ShareAccessCard.js +22 -4
  151. package/dist/apps/shared/components/admin/settings/BrandingForm.d.ts +9 -0
  152. package/dist/apps/shared/components/admin/settings/BrandingForm.js +15 -4
  153. package/dist/apps/shared/components/admin/settings/DomainDnsSetup.d.ts +12 -0
  154. package/dist/apps/shared/components/admin/settings/DomainDnsSetup.js +13 -7
  155. package/dist/apps/shared/components/admin/settings/EncryptionPolicyForm.d.ts +12 -0
  156. package/dist/apps/shared/components/admin/settings/EncryptionPolicyForm.js +7 -2
  157. package/dist/apps/shared/components/admin/settings/LoadedSettingsForm.d.ts +9 -0
  158. package/dist/apps/shared/components/admin/settings/MailboxCreateForm.d.ts +19 -0
  159. package/dist/apps/shared/components/admin/settings/MailboxCreateForm.js +6 -0
  160. package/dist/apps/shared/components/admin/settings/MailboxPolicyForm.d.ts +10 -0
  161. package/dist/apps/shared/components/admin/settings/MailboxPolicyForm.js +34 -12
  162. package/dist/apps/shared/components/admin/settings/PluginsManager.d.ts +4 -0
  163. package/dist/apps/shared/components/admin/settings/PluginsManager.js +390 -78
  164. package/dist/apps/shared/components/admin/settings/RetentionPolicyForm.d.ts +9 -0
  165. package/dist/apps/shared/components/admin/settings/RetentionPolicyForm.js +40 -11
  166. package/dist/apps/shared/components/admin/setup/EscrowSetupStep.d.ts +14 -0
  167. package/dist/apps/shared/components/admin/setup/EscrowSetupStep.js +29 -13
  168. package/dist/apps/shared/components/admin/setup/SetupWizard.d.ts +36 -0
  169. package/dist/apps/shared/components/admin/setup/SetupWizard.js +87 -21
  170. package/dist/apps/shared/components/admin/signOut.d.ts +23 -0
  171. package/dist/apps/shared/components/admin/signOut.js +75 -0
  172. package/dist/apps/shared/components/admin/usePagedList.d.ts +39 -0
  173. package/dist/apps/shared/components/admin/usePagedList.js +99 -0
  174. package/dist/apps/shared/components/calendar/CalendarListSidebar.d.ts +26 -0
  175. package/dist/apps/shared/components/calendar/EventModal.d.ts +46 -0
  176. package/dist/apps/shared/components/calendar/EventModal.js +142 -21
  177. package/dist/apps/shared/components/calendar/MonthView.d.ts +15 -0
  178. package/dist/apps/shared/components/calendar/MonthView.js +12 -5
  179. package/dist/apps/shared/components/calendar/RecurrenceEditor.d.ts +20 -0
  180. package/dist/apps/shared/components/calendar/RecurrenceEditor.js +40 -5
  181. package/dist/apps/shared/components/calendar/ResourcePicker.d.ts +19 -0
  182. package/dist/apps/shared/components/calendar/SplitDayView.d.ts +28 -0
  183. package/dist/apps/shared/components/calendar/SplitDayView.js +10 -4
  184. package/dist/apps/shared/components/calendar/TimeGridView.d.ts +17 -0
  185. package/dist/apps/shared/components/calendar/TimeGridView.js +23 -7
  186. package/dist/apps/shared/components/calendar/allDay.d.ts +51 -0
  187. package/dist/apps/shared/components/calendar/allDay.js +111 -0
  188. package/dist/apps/shared/components/calendar/layout/CalendarShell.d.ts +40 -0
  189. package/dist/apps/shared/components/calendar/layout/CalendarShell.js +3 -3
  190. package/dist/apps/shared/components/contacts/ContactDetailPane.d.ts +23 -0
  191. package/dist/apps/shared/components/contacts/ContactDetailPane.js +43 -5
  192. package/dist/apps/shared/components/contacts/ContactForm.d.ts +20 -0
  193. package/dist/apps/shared/components/contacts/ContactForm.js +32 -10
  194. package/dist/apps/shared/components/contacts/ContactsSidebar.d.ts +40 -0
  195. package/dist/apps/shared/components/contacts/ContactsSidebar.js +2 -2
  196. package/dist/apps/shared/components/contacts/ContactsToolbar.d.ts +25 -0
  197. package/dist/apps/shared/components/contacts/KeyChangeReview.d.ts +40 -0
  198. package/dist/apps/shared/components/contacts/KeyChangeReview.js +63 -0
  199. package/dist/apps/shared/components/contacts/contactKeys.d.ts +29 -0
  200. package/dist/apps/shared/components/contacts/contactKeys.js +64 -0
  201. package/dist/apps/shared/components/contacts/layout/ContactsShell.d.ts +21 -0
  202. package/dist/apps/shared/components/contacts/layout/ContactsShell.js +2 -2
  203. package/dist/apps/shared/components/escrow/layout/EscrowShell.d.ts +25 -0
  204. package/dist/apps/shared/components/escrow/layout/EscrowShell.js +24 -5
  205. package/dist/apps/shared/components/forms/StringListField.d.ts +22 -0
  206. package/dist/apps/shared/components/layout/AppShell.d.ts +49 -0
  207. package/dist/apps/shared/components/layout/AppShell.js +97 -26
  208. package/dist/apps/shared/components/layout/BrandingChrome.d.ts +18 -0
  209. package/dist/apps/shared/components/layout/BrandingChrome.js +45 -10
  210. package/dist/apps/shared/components/layout/KeyEnrollmentGate.d.ts +51 -0
  211. package/dist/apps/shared/components/layout/KeyEnrollmentGate.js +49 -12
  212. package/dist/apps/shared/components/layout/MailboxProvisioning.d.ts +13 -0
  213. package/dist/apps/shared/components/layout/MailboxProvisioning.js +10 -2
  214. package/dist/apps/shared/components/layout/RecoveryCodeUnlock.d.ts +66 -0
  215. package/dist/apps/shared/components/layout/RecoveryCodeUnlock.js +174 -0
  216. package/dist/apps/shared/components/layout/UnlockPromptProvider.d.ts +45 -0
  217. package/dist/apps/shared/components/layout/UnlockPromptProvider.js +73 -14
  218. package/dist/apps/shared/components/layout/UserMenu.d.ts +23 -0
  219. package/dist/apps/shared/components/mail/ConversationList.d.ts +11 -0
  220. package/dist/apps/shared/components/mail/ConversationThreadPane.d.ts +23 -0
  221. package/dist/apps/shared/components/mail/ConversationThreadPane.js +50 -12
  222. package/dist/apps/shared/components/mail/MessageDetailPane.d.ts +93 -0
  223. package/dist/apps/shared/components/mail/MessageDetailPane.js +441 -36
  224. package/dist/apps/shared/components/mail/compose/ComposeContext.d.ts +58 -0
  225. package/dist/apps/shared/components/mail/compose/ComposeContext.js +9 -6
  226. package/dist/apps/shared/components/mail/compose/ComposeToolbar.d.ts +15 -0
  227. package/dist/apps/shared/components/mail/compose/ComposeWindow.d.ts +37 -0
  228. package/dist/apps/shared/components/mail/compose/ComposeWindow.js +699 -128
  229. package/dist/apps/shared/components/mail/compose/EmojiPicker.d.ts +14 -0
  230. package/dist/apps/shared/components/mail/compose/GifPicker.d.ts +13 -0
  231. package/dist/apps/shared/components/mail/compose/RichTextEditor.d.ts +34 -0
  232. package/dist/apps/shared/components/mail/compose/ScheduleSendPicker.d.ts +16 -0
  233. package/dist/apps/shared/components/mail/compose/composeFlushRegistry.d.ts +27 -0
  234. package/dist/apps/shared/components/mail/compose/composeFlushRegistry.js +50 -0
  235. package/dist/apps/shared/components/mail/layout/MailShell.d.ts +57 -0
  236. package/dist/apps/shared/components/mail/layout/MailShell.js +13 -4
  237. package/dist/apps/shared/components/mail/pinnedSigners.d.ts +33 -0
  238. package/dist/apps/shared/components/mail/pinnedSigners.js +98 -0
  239. package/dist/apps/shared/components/mail/verificationSeals.d.ts +22 -0
  240. package/dist/apps/shared/components/mail/verificationSeals.js +112 -0
  241. package/dist/apps/shared/components/mail/writableMailboxes.d.ts +15 -0
  242. package/dist/apps/shared/components/mail/writableMailboxes.js +87 -0
  243. package/dist/apps/shared/components/rules/RuleBuilder.d.ts +70 -0
  244. package/dist/apps/shared/components/rules/RuleBuilder.js +34 -6
  245. package/dist/apps/shared/components/settings/layout/SettingsShell.d.ts +41 -0
  246. package/dist/apps/shared/components/settings/layout/SettingsShell.js +19 -9
  247. package/dist/apps/shared/components/tasks/TasksSidebar.d.ts +41 -0
  248. package/dist/apps/shared/components/tasks/TasksToolbar.d.ts +14 -0
  249. package/dist/apps/shared/components/tasks/layout/TasksShell.d.ts +24 -0
  250. package/dist/apps/shared/components/tasks/layout/TasksShell.js +2 -2
  251. package/dist/apps/shared/mail/findWellKnownFolderUid.d.ts +5 -0
  252. package/dist/apps/shared/mail/listAllPages.d.ts +17 -0
  253. package/dist/apps/shared/mail/listAllPages.js +25 -0
  254. package/dist/apps/shared/plugins/pluginNav.d.ts +39 -0
  255. package/dist/apps/shared/plugins/pluginNav.js +33 -0
  256. package/dist/apps/shared/search/LocalIndexLifecycle.d.ts +13 -0
  257. package/dist/apps/shared/search/LocalIndexLifecycle.js +58 -54
  258. package/dist/apps/shared/search/localIndexBlockCipher.d.ts +36 -0
  259. package/dist/apps/shared/search/localIndexBuilder.d.ts +85 -0
  260. package/dist/apps/shared/search/localIndexBuilder.js +292 -37
  261. package/dist/apps/shared/search/localIndexKey.d.ts +4 -0
  262. package/dist/apps/shared/search/localIndexRpcClient.d.ts +71 -0
  263. package/dist/apps/shared/search/localIndexRpcClient.js +191 -26
  264. package/dist/apps/shared/search/localIndexSchema.d.ts +111 -0
  265. package/dist/apps/shared/search/localIndexSchema.js +12 -6
  266. package/dist/apps/shared/search/localIndexSizePreference.d.ts +27 -0
  267. package/dist/apps/shared/search/localIndexStorage.d.ts +28 -0
  268. package/dist/apps/shared/search/localIndexStorage.js +86 -0
  269. package/dist/apps/shared/search/localIndexVFS.d.ts +101 -0
  270. package/dist/apps/shared/search/localIndexVFS.js +68 -40
  271. package/dist/apps/shared/search/localIndexWorker.d.ts +145 -0
  272. package/dist/apps/shared/search/localIndexWorker.js +519 -173
  273. package/dist/apps/shared/search/searchTier2.d.ts +30 -0
  274. package/dist/apps/www/_404.d.ts +2 -0
  275. package/dist/apps/www/_500.d.ts +2 -0
  276. package/dist/apps/www/_layout.d.ts +14 -0
  277. package/dist/apps/www/calendar/index.d.ts +3 -0
  278. package/dist/apps/www/calendar/index.js +28 -10
  279. package/dist/apps/www/contacts/[uid].d.ts +13 -0
  280. package/dist/apps/www/contacts/[uid].js +13 -2
  281. package/dist/apps/www/contacts/index.d.ts +3 -0
  282. package/dist/apps/www/contacts/index.js +80 -10
  283. package/dist/apps/www/index.d.ts +3 -0
  284. package/dist/apps/www/index.js +339 -108
  285. package/dist/apps/www/messages/[uid].d.ts +11 -0
  286. package/dist/apps/www/messages/[uid].js +18 -6
  287. package/dist/apps/www/settings/auto-reply/index.d.ts +4 -0
  288. package/dist/apps/www/settings/auto-reply/index.js +9 -4
  289. package/dist/apps/www/settings/encryption/index.d.ts +7 -0
  290. package/dist/apps/www/settings/encryption/index.js +514 -97
  291. package/dist/apps/www/settings/filters/[uid].d.ts +8 -0
  292. package/dist/apps/www/settings/filters/[uid].js +22 -7
  293. package/dist/apps/www/settings/filters/_mailFilterRuleConfig.d.ts +11 -0
  294. package/dist/apps/www/settings/filters/index.d.ts +4 -0
  295. package/dist/apps/www/settings/filters/new/index.d.ts +4 -0
  296. package/dist/apps/www/settings/filters/new/index.js +8 -2
  297. package/dist/apps/www/settings/focused-inbox/index.d.ts +4 -0
  298. package/dist/apps/www/settings/focused-inbox/index.js +3 -1
  299. package/dist/apps/www/settings/labels/index.d.ts +4 -0
  300. package/dist/apps/www/settings/privacy/index.d.ts +4 -0
  301. package/dist/apps/www/settings/privacy/index.js +57 -22
  302. package/dist/apps/www/settings/read-receipts/index.d.ts +4 -0
  303. package/dist/apps/www/settings/read-receipts/index.js +10 -3
  304. package/dist/apps/www/settings/sharing/index.d.ts +4 -0
  305. package/dist/apps/www/settings/sharing/index.js +7 -11
  306. package/dist/apps/www/settings/signatures/[uid].d.ts +8 -0
  307. package/dist/apps/www/settings/signatures/index.d.ts +4 -0
  308. package/dist/apps/www/settings/signatures/new/index.d.ts +4 -0
  309. package/dist/apps/www/settings/signatures/signatureDefaults.d.ts +10 -0
  310. package/dist/apps/www/tasks/index.d.ts +3 -0
  311. package/dist/apps/www/tasks/index.js +50 -10
  312. package/package.json +3 -3
  313. package/apps/shared/components/booking/AvailabilityEditor.tsx +0 -118
  314. package/apps/www/settings/booking-types/[uid].tsx +0 -300
  315. package/apps/www/settings/booking-types/index.tsx +0 -98
  316. package/apps/www/settings/booking-types/new/index.tsx +0 -212
  317. package/dist/apps/shared/components/booking/AvailabilityEditor.js +0 -45
  318. package/dist/apps/www/settings/booking-types/[uid].js +0 -129
  319. package/dist/apps/www/settings/booking-types/index.js +0 -29
  320. package/dist/apps/www/settings/booking-types/new/index.js +0 -86
@@ -0,0 +1,101 @@
1
+ /**
2
+ * `EncryptingVFS` - the Tier 2 local index's at-rest encryption layer (`specs/search.md` §11
3
+ * "Persistence and protection", §13 "Encryption at Rest": "no official SQLCipher WASM build exists...
4
+ * encryption at rest requires a custom VFS that encrypts pages before they reach OPFS").
5
+ *
6
+ * Wraps (composes, does not subclass - `AccessHandlePoolVFS`'s own file-table state is private `#`
7
+ * fields) an `AccessHandlePoolVFS` instance and delegates every `FacadeVFS` method straight through
8
+ * except `jRead`/`jWrite`, which it intercepts to decrypt/encrypt pages.
9
+ *
10
+ * ## Page layout
11
+ *
12
+ * SQLite is opened with a fixed 4096-byte page size (`PRAGMA page_size=4096` - set by
13
+ * `localIndexWorker.ts` before the first write, since SQLite fixes a database's page size on creation).
14
+ * Each *logical* 4096-byte page is stored *physically* as `nonce(12) || AES-256-GCM(ciphertext(4096) ||
15
+ * tag(16))` = 4124 bytes, at a remapped offset (`physicalOffset(page) = page * 4124`). This block size
16
+ * is this class's own fixed constant, independent of whatever byte range a given `jRead`/`jWrite` call
17
+ * actually requests - reads/writes are handled generically over whichever physical blocks the requested
18
+ * logical range overlaps (including a read-modify-write for a sub-block write), not by assuming SQLite
19
+ * only ever issues page-aligned, page-sized I/O. That assumption holds for the *main database file* once
20
+ * its page size is fixed, but handling the general case costs little and removes the need to rely on it.
21
+ *
22
+ * **A fresh random nonce is generated on every write, never reused or derived from a counter** - the
23
+ * simplest way to make an AES-GCM (key, nonce) pair never repeat across different plaintexts, which is
24
+ * the one hard requirement GCM has. The nonce travels with its block, so decryption never needs any
25
+ * external state (a lost/corrupted counter, a persisted salt) to reconstruct it.
26
+ *
27
+ * **AAD binds each block to its logical filename and page index** (not just its own ciphertext) - GCM
28
+ * authenticates a block's own content but not its *position*; without this, an attacker able to write
29
+ * directly into this origin's OPFS storage (outside this codebase's own threat model per spec §4, which
30
+ * excludes a compromised client, but cheap to close off anyway) could silently swap two blocks and each
31
+ * would still decrypt "successfully" on its own, corrupting data instead of failing loudly. Binding to
32
+ * position turns a swap into a caught decryption failure - see `PageCorruptedError` below - the same
33
+ * "invalidate and rebuild" path a schema-version mismatch already takes (spec §11 "Invalidation").
34
+ *
35
+ * **No WAL, no rollback journal.** `localIndexWorker.ts` opens the database with `journal_mode=OFF`. A
36
+ * page cipher for the main database file is one encryption surface; WAL frames (their own header +
37
+ * checksum format) and rollback-journal records (their own, different record format) would each be a
38
+ * *second* one. This index has no durability requirement to justify that cost - spec §11 already
39
+ * requires discarding and rebuilding it on corruption, schema change, key rotation, or platform storage
40
+ * eviction, and eviction "MUST NOT block search" - so an interrupted write in the worst case is just
41
+ * caught by the same GCM-auth-failure -> rebuild path as any other corruption, never partial/torn state
42
+ * silently trusted.
43
+ *
44
+ * Every `jRead`/`jWrite` here is `async` (declared `async` specifically so `FacadeVFS.hasAsyncMethod()`
45
+ * detects it via `instanceof AsyncFunction` and awaits it) because `crypto.subtle.encrypt`/`decrypt` has
46
+ * no synchronous form in a browser - this is *why* `localIndexWorker.ts` boots the Asyncify SQLite build
47
+ * (`dist/wa-sqlite-async.mjs`), not the plain synchronous one `AccessHandlePoolVFS`'s own doc comment
48
+ * says it's designed for: that claim is about `AccessHandlePoolVFS`'s *own* methods (real synchronous
49
+ * OPFS access-handle calls), which stay synchronous and work fine wrapped underneath an async outer VFS
50
+ * on an Asyncify build - the build choice is driven by this class's needs, not the inner VFS's.
51
+ */
52
+ import { FacadeVFS } from "@journeyapps/wa-sqlite/src/FacadeVFS.js";
53
+ export { PageCorruptedError } from "./localIndexBlockCipher.js";
54
+ export declare class EncryptingVFS extends FacadeVFS {
55
+ #private;
56
+ private constructor();
57
+ /** `rawKey` MUST be exactly 32 bytes (AES-256) - see `localIndexKey.ts`'s `deriveLocalIndexKey()`,
58
+ * the only intended source of this value. */
59
+ static create(name: string, module: unknown, rawKey: Uint8Array): Promise<EncryptingVFS>;
60
+ /**
61
+ * Releases every pooled OPFS sync access handle `AccessHandlePoolVFS` opened and holds open for its
62
+ * entire lifetime (not per SQLite-file-open/close - `jOpen`/`jClose` above only associate/disassociate
63
+ * a SQLite fileId with an already-open handle, they never open or close the handles themselves). MUST
64
+ * be called before creating another VFS instance against the same OPFS pool `name` - confirmed by
65
+ * direct reproduction: skipping this and calling `create()` again with the same `name` throws
66
+ * "Access Handles cannot be created if there is another open Access Handle," since the previous
67
+ * instance's handles are still live. `localIndexWorker.ts` calls this alongside `sqlite3.close(db)`
68
+ * (which closes the SQLite *connection*, a separate, shorter-lived thing from the VFS itself) whenever
69
+ * it tears down a mailbox's connection - on `destroy()` and in `selfTest()`'s own close/reopen check.
70
+ */
71
+ close(): void | Promise<void>;
72
+ jOpen(filename: string | null, pFile: number, flags: number, pOutFlags: DataView): number | Promise<number>;
73
+ jClose(pFile: number): number | Promise<number>;
74
+ jDelete(filename: string, syncDir: number): number | Promise<number>;
75
+ jAccess(filename: string, flags: number, pResOut: DataView): number | Promise<number>;
76
+ jFullPathname(filename: string, zOut: Uint8Array): number | Promise<number>;
77
+ jSync(pFile: number, flags: number): number | Promise<number>;
78
+ jSectorSize(pFile: number): number;
79
+ jDeviceCharacteristics(pFile: number): number;
80
+ /** Logical file size = physical size scaled back down to the logical block size - the inner VFS's
81
+ * own `jFileSize` reports the *physical* (post-remap) byte count, which is always an exact multiple
82
+ * of `PHYSICAL_BLOCK_SIZE` since every write here always fills whole physical blocks. */
83
+ jFileSize(pFile: number, pSize64: DataView): Promise<number>;
84
+ /** `iSize` is a logical byte size - truncates to the smallest whole number of *physical* blocks that
85
+ * still covers it, so a partially-truncated trailing block is never left half-written. */
86
+ jTruncate(pFile: number, iSize: number): Promise<number>;
87
+ /** Set once any block has failed to decrypt/authenticate (or the inner VFS failed a read/write outright)
88
+ * - `localIndexWorker.ts` checks this after a failed SQLite call to tell real corruption (discard and
89
+ * rebuild, spec §11 "Invalidation") apart from an ordinary error such as a malformed FTS5 query. */
90
+ corruptionDetected: boolean;
91
+ /**
92
+ * `jRead`/`jWrite` MUST NOT throw: with the Asyncify build, an exception escaping an async VFS method
93
+ * never reaches the awaiting `sqlite3.*` call - it surfaces only as an unhandled rejection and the
94
+ * SQLite call hangs forever (confirmed by direct reproduction in node against the real wa-sqlite build).
95
+ * A thrown `PageCorruptedError` therefore used to wedge the whole connection instead of triggering a
96
+ * rebuild. Errors are converted to an I/O error return code here, which SQLite does propagate as a
97
+ * normal `SQLiteError`, and recorded on `corruptionDetected`.
98
+ */
99
+ jRead(pFile: number, pData: Uint8Array, iOffset: number): Promise<number>;
100
+ jWrite(pFile: number, pData: Uint8Array, iOffset: number): Promise<number>;
101
+ }
@@ -9,7 +9,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
9
9
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
10
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
11
  };
12
- var _EncryptingVFS_instances, _EncryptingVFS_inner, _EncryptingVFS_key, _EncryptingVFS_filenamesByFileId, _EncryptingVFS_readBlock, _EncryptingVFS_writeBlock;
12
+ var _EncryptingVFS_instances, _EncryptingVFS_inner, _EncryptingVFS_key, _EncryptingVFS_filenamesByFileId, _EncryptingVFS_readBlock, _EncryptingVFS_writeBlock, _EncryptingVFS_jReadBlocks, _EncryptingVFS_jWriteBlocks;
13
13
  ///////////////////////////////////////////////////////////////////////////////
14
14
  // Copyright (C) 2026 Jean-Philippe Steinmetz
15
15
  // SPDX-License-Identifier: MPL-2.0
@@ -80,6 +80,10 @@ export class EncryptingVFS extends FacadeVFS {
80
80
  * open handle, never persisted - this map lets `jRead`/`jWrite` recover the stable filename an AAD
81
81
  * needs to bind to, from the ephemeral fileId SQLite actually passes them. */
82
82
  _EncryptingVFS_filenamesByFileId.set(this, new Map());
83
+ /** Set once any block has failed to decrypt/authenticate (or the inner VFS failed a read/write outright)
84
+ * - `localIndexWorker.ts` checks this after a failed SQLite call to tell real corruption (discard and
85
+ * rebuild, spec §11 "Invalidation") apart from an ordinary error such as a malformed FTS5 query. */
86
+ this.corruptionDetected = false;
83
87
  __classPrivateFieldSet(this, _EncryptingVFS_inner, inner, "f");
84
88
  }
85
89
  /** `rawKey` MUST be exactly 32 bytes (AES-256) - see `localIndexKey.ts`'s `deriveLocalIndexKey()`,
@@ -152,50 +156,31 @@ export class EncryptingVFS extends FacadeVFS {
152
156
  const blocks = Math.ceil(iSize / LOGICAL_BLOCK_SIZE);
153
157
  return __classPrivateFieldGet(this, _EncryptingVFS_inner, "f").jTruncate(pFile, blocks * PHYSICAL_BLOCK_SIZE);
154
158
  }
159
+ /**
160
+ * `jRead`/`jWrite` MUST NOT throw: with the Asyncify build, an exception escaping an async VFS method
161
+ * never reaches the awaiting `sqlite3.*` call - it surfaces only as an unhandled rejection and the
162
+ * SQLite call hangs forever (confirmed by direct reproduction in node against the real wa-sqlite build).
163
+ * A thrown `PageCorruptedError` therefore used to wedge the whole connection instead of triggering a
164
+ * rebuild. Errors are converted to an I/O error return code here, which SQLite does propagate as a
165
+ * normal `SQLiteError`, and recorded on `corruptionDetected`.
166
+ */
155
167
  async jRead(pFile, pData, iOffset) {
156
- const filename = __classPrivateFieldGet(this, _EncryptingVFS_filenamesByFileId, "f").get(pFile) ?? `(unknown:${pFile})`;
157
- const startBlock = Math.floor(iOffset / LOGICAL_BLOCK_SIZE);
158
- const endBlock = Math.floor((iOffset + pData.length - 1) / LOGICAL_BLOCK_SIZE);
159
- let anyAbsent = false;
160
- for (let block = startBlock; block <= endBlock; block++) {
161
- const { plaintext, absent } = await __classPrivateFieldGet(this, _EncryptingVFS_instances, "m", _EncryptingVFS_readBlock).call(this, pFile, filename, block);
162
- const blockStart = block * LOGICAL_BLOCK_SIZE;
163
- const copyStart = Math.max(iOffset, blockStart);
164
- const copyEnd = Math.min(iOffset + pData.length, blockStart + LOGICAL_BLOCK_SIZE);
165
- pData.set(plaintext.subarray(copyStart - blockStart, copyEnd - blockStart), copyStart - iOffset);
166
- // SQLITE_IOERR_SHORT_READ is how SQLite distinguishes "nothing here yet" from "here is real
167
- // (possibly zero-filled) data," e.g. when probing whether a file exists at all - see
168
- // #readBlock's own doc comment on why this is tracked explicitly, not inferred from content.
169
- if (absent) {
170
- anyAbsent = true;
171
- }
168
+ try {
169
+ return await __classPrivateFieldGet(this, _EncryptingVFS_instances, "m", _EncryptingVFS_jReadBlocks).call(this, pFile, pData, iOffset);
170
+ }
171
+ catch {
172
+ this.corruptionDetected = true;
173
+ return VFS.SQLITE_IOERR_READ;
172
174
  }
173
- return anyAbsent ? VFS.SQLITE_IOERR_SHORT_READ : VFS.SQLITE_OK;
174
175
  }
175
176
  async jWrite(pFile, pData, iOffset) {
176
- const filename = __classPrivateFieldGet(this, _EncryptingVFS_filenamesByFileId, "f").get(pFile) ?? `(unknown:${pFile})`;
177
- const startBlock = Math.floor(iOffset / LOGICAL_BLOCK_SIZE);
178
- const endBlock = Math.floor((iOffset + pData.length - 1) / LOGICAL_BLOCK_SIZE);
179
- for (let block = startBlock; block <= endBlock; block++) {
180
- const blockStart = block * LOGICAL_BLOCK_SIZE;
181
- const writeStart = Math.max(iOffset, blockStart);
182
- const writeEnd = Math.min(iOffset + pData.length, blockStart + LOGICAL_BLOCK_SIZE);
183
- // Whole-block write (the common case once SQLite's page size is fixed): no need to read the
184
- // old block first. Anything narrower (a sub-page write, or this block only partially
185
- // overlaps the requested range) needs the existing content as a base - a real
186
- // read-modify-write - since the physical block is re-encrypted as a single AEAD unit.
187
- const plaintext = writeStart === blockStart && writeEnd === blockStart + LOGICAL_BLOCK_SIZE
188
- ? pData.subarray(writeStart - iOffset, writeEnd - iOffset)
189
- : await __classPrivateFieldGet(this, _EncryptingVFS_instances, "m", _EncryptingVFS_readBlock).call(this, pFile, filename, block).then(({ plaintext: existing }) => {
190
- const merged = existing.slice();
191
- merged.set(pData.subarray(writeStart - iOffset, writeEnd - iOffset), writeStart - blockStart);
192
- return merged;
193
- });
194
- const rc = await __classPrivateFieldGet(this, _EncryptingVFS_instances, "m", _EncryptingVFS_writeBlock).call(this, pFile, filename, block, plaintext);
195
- if (rc !== VFS.SQLITE_OK)
196
- return rc;
177
+ try {
178
+ return await __classPrivateFieldGet(this, _EncryptingVFS_instances, "m", _EncryptingVFS_jWriteBlocks).call(this, pFile, pData, iOffset);
179
+ }
180
+ catch {
181
+ this.corruptionDetected = true;
182
+ return VFS.SQLITE_IOERR_WRITE;
197
183
  }
198
- return VFS.SQLITE_OK;
199
184
  }
200
185
  }
201
186
  _EncryptingVFS_inner = new WeakMap(), _EncryptingVFS_key = new WeakMap(), _EncryptingVFS_filenamesByFileId = new WeakMap(), _EncryptingVFS_instances = new WeakSet(), _EncryptingVFS_readBlock =
@@ -227,4 +212,47 @@ async function _EncryptingVFS_readBlock(pFile, filename, blockIndex) {
227
212
  }, _EncryptingVFS_writeBlock = async function _EncryptingVFS_writeBlock(pFile, filename, blockIndex, plaintext) {
228
213
  const physical = await encryptBlock(__classPrivateFieldGet(this, _EncryptingVFS_key, "f"), filename, blockIndex, plaintext);
229
214
  return __classPrivateFieldGet(this, _EncryptingVFS_inner, "f").jWrite(pFile, physical, blockIndex * PHYSICAL_BLOCK_SIZE);
215
+ }, _EncryptingVFS_jReadBlocks = async function _EncryptingVFS_jReadBlocks(pFile, pData, iOffset) {
216
+ const filename = __classPrivateFieldGet(this, _EncryptingVFS_filenamesByFileId, "f").get(pFile) ?? `(unknown:${pFile})`;
217
+ const startBlock = Math.floor(iOffset / LOGICAL_BLOCK_SIZE);
218
+ const endBlock = Math.floor((iOffset + pData.length - 1) / LOGICAL_BLOCK_SIZE);
219
+ let anyAbsent = false;
220
+ for (let block = startBlock; block <= endBlock; block++) {
221
+ const { plaintext, absent } = await __classPrivateFieldGet(this, _EncryptingVFS_instances, "m", _EncryptingVFS_readBlock).call(this, pFile, filename, block);
222
+ const blockStart = block * LOGICAL_BLOCK_SIZE;
223
+ const copyStart = Math.max(iOffset, blockStart);
224
+ const copyEnd = Math.min(iOffset + pData.length, blockStart + LOGICAL_BLOCK_SIZE);
225
+ pData.set(plaintext.subarray(copyStart - blockStart, copyEnd - blockStart), copyStart - iOffset);
226
+ // SQLITE_IOERR_SHORT_READ is how SQLite distinguishes "nothing here yet" from "here is real
227
+ // (possibly zero-filled) data," e.g. when probing whether a file exists at all - see
228
+ // #readBlock's own doc comment on why this is tracked explicitly, not inferred from content.
229
+ if (absent) {
230
+ anyAbsent = true;
231
+ }
232
+ }
233
+ return anyAbsent ? VFS.SQLITE_IOERR_SHORT_READ : VFS.SQLITE_OK;
234
+ }, _EncryptingVFS_jWriteBlocks = async function _EncryptingVFS_jWriteBlocks(pFile, pData, iOffset) {
235
+ const filename = __classPrivateFieldGet(this, _EncryptingVFS_filenamesByFileId, "f").get(pFile) ?? `(unknown:${pFile})`;
236
+ const startBlock = Math.floor(iOffset / LOGICAL_BLOCK_SIZE);
237
+ const endBlock = Math.floor((iOffset + pData.length - 1) / LOGICAL_BLOCK_SIZE);
238
+ for (let block = startBlock; block <= endBlock; block++) {
239
+ const blockStart = block * LOGICAL_BLOCK_SIZE;
240
+ const writeStart = Math.max(iOffset, blockStart);
241
+ const writeEnd = Math.min(iOffset + pData.length, blockStart + LOGICAL_BLOCK_SIZE);
242
+ // Whole-block write (the common case once SQLite's page size is fixed): no need to read the
243
+ // old block first. Anything narrower (a sub-page write, or this block only partially
244
+ // overlaps the requested range) needs the existing content as a base - a real
245
+ // read-modify-write - since the physical block is re-encrypted as a single AEAD unit.
246
+ const plaintext = writeStart === blockStart && writeEnd === blockStart + LOGICAL_BLOCK_SIZE
247
+ ? pData.subarray(writeStart - iOffset, writeEnd - iOffset)
248
+ : await __classPrivateFieldGet(this, _EncryptingVFS_instances, "m", _EncryptingVFS_readBlock).call(this, pFile, filename, block).then(({ plaintext: existing }) => {
249
+ const merged = existing.slice();
250
+ merged.set(pData.subarray(writeStart - iOffset, writeEnd - iOffset), writeStart - blockStart);
251
+ return merged;
252
+ });
253
+ const rc = await __classPrivateFieldGet(this, _EncryptingVFS_instances, "m", _EncryptingVFS_writeBlock).call(this, pFile, filename, block, plaintext);
254
+ if (rc !== VFS.SQLITE_OK)
255
+ return rc;
256
+ }
257
+ return VFS.SQLITE_OK;
230
258
  };
@@ -0,0 +1,145 @@
1
+ import type { ParsedSearchQuery } from "@rapidmx/react-shared/search/queryGrammar.js";
2
+ import { LocalIndexEntity } from "./localIndexSchema.js";
3
+ /** One request sent from the main thread. `id` correlates the eventual response - `postMessage` has no
4
+ * native request/response pairing, so every RPC call carries its own id (see `localIndexRpcClient.ts`,
5
+ * the main-thread counterpart that generates/awaits these). */
6
+ export interface LocalIndexRequest {
7
+ id: number;
8
+ method: "init" | "indexEntities" | "removeEntity" | "moveEntity" | "indexedVersions" | "pruneEntities" | "search" | "coverage" | "setWindow" | "setBuilding" | "destroy" | "destroyAll" | "selfTest" | "ping";
9
+ params?: unknown;
10
+ }
11
+ export type LocalIndexResponse = {
12
+ id: number;
13
+ ok: true;
14
+ result: unknown;
15
+ } | {
16
+ id: number;
17
+ ok: false;
18
+ error: string;
19
+ };
20
+ /**
21
+ * Carried by every call a build pass makes (`init`, `setWindow`, `setBuilding`, `indexEntities`,
22
+ * `pruneEntities`). Generations come from one monotonic counter on the main thread
23
+ * (`localIndexRpcClient.ts`), shared with `destroy`/`destroyAll`: a call whose generation is older than the
24
+ * last destroy of its mailbox is rejected (`StaleGenerationError`), so a build started before a lock/sign-out
25
+ * can't recreate the index with its captured keys or write into a rebuild that started after it. Calls
26
+ * without a generation (search, coverage, in-session moves) are never rejected.
27
+ */
28
+ export interface GenerationParams {
29
+ generation?: number;
30
+ }
31
+ export interface InitParams extends GenerationParams {
32
+ mailboxUid: string;
33
+ /** The mailbox's already-derived local-index key (`localIndexKey.ts`'s `deriveLocalIndexKey()`) -
34
+ * this Worker never touches the master key itself, only this one purpose-derived value, matching
35
+ * every other MK-derived-key boundary already established elsewhere in this codebase. */
36
+ indexKey: Uint8Array;
37
+ }
38
+ export interface IndexEntitiesParams extends GenerationParams {
39
+ mailboxUid: string;
40
+ entities: LocalIndexEntity[];
41
+ }
42
+ export interface IndexEntitiesResult {
43
+ /** `true` when this call's eviction pass had to delete anything to get back under the byte budget. */
44
+ budgetReached: boolean;
45
+ /** The eviction watermark after this call - see `WindowState.evictedBefore`. */
46
+ evictedBefore?: string;
47
+ }
48
+ export interface WindowState {
49
+ /** Set once the byte budget has forced an eviction: messages dated strictly before this were evicted (or
50
+ * would be, on insert), so a build pass neither re-fetches them nor walks past them. Cleared by
51
+ * `setWindow` once the index has comfortably shrunk back under budget (or the budget was raised). */
52
+ evictedBefore?: string;
53
+ }
54
+ export interface DestroyParams extends GenerationParams {
55
+ mailboxUid: string;
56
+ }
57
+ export interface RemoveEntityParams {
58
+ mailboxUid: string;
59
+ entityUid: string;
60
+ }
61
+ export interface MoveEntityParams {
62
+ mailboxUid: string;
63
+ entityUid: string;
64
+ folderUid: string;
65
+ }
66
+ export interface IndexedVersionsParams {
67
+ mailboxUid: string;
68
+ entityUids: string[];
69
+ }
70
+ export interface PruneEntitiesParams extends GenerationParams {
71
+ mailboxUid: string;
72
+ /** Every entity uid a build pass saw on the server. */
73
+ keepEntityUids: string[];
74
+ /** Only rows at or after this `date_for_sort` are candidates (the walk's own time floor - anything
75
+ * older was never re-listed, so its absence proves nothing). `undefined` means no floor. */
76
+ since?: string;
77
+ /** Only rows currently filed in one of these folders are candidates - folders whose listing was reliable
78
+ * for the whole walk. `undefined` means every folder. */
79
+ folderUids?: string[];
80
+ }
81
+ export interface SearchParams {
82
+ mailboxUid: string;
83
+ parsed: ParsedSearchQuery;
84
+ limit: number;
85
+ /** How many matches to skip before returning `limit` more - §8's composite pagination cursor's own
86
+ * "the local index position consumed so far" component, threaded straight through to SQL `OFFSET`.
87
+ * Defaults to `0` for a first page. */
88
+ offset?: number;
89
+ }
90
+ export interface LocalSearchHit {
91
+ entityUid: string;
92
+ /** Raw `bm25()` score - more negative is a better match, per SQLite's own convention. Normalized by
93
+ * `searchTier2.ts` (main thread) before merging (spec §7). */
94
+ score: number;
95
+ snippet?: string;
96
+ }
97
+ export interface LocalSearchPage {
98
+ hits: LocalSearchHit[];
99
+ /** `true` when at least one more match exists beyond this page - detected by fetching `limit + 1`
100
+ * rows and trimming the extra one, rather than a separate `COUNT(*)` query. */
101
+ hasMore: boolean;
102
+ }
103
+ export interface Coverage {
104
+ /** The oldest date the index is known to cover. While `complete`, every indexable message at least
105
+ * this recent is present; otherwise it is only the oldest row that happens to be present. `undefined`
106
+ * for an empty index. */
107
+ indexedFrom?: string;
108
+ indexedCount: number;
109
+ building: boolean;
110
+ /** `true` only once a build pass *in this connection's lifetime* has walked every mail folder all the
111
+ * way back to its time floor with no errors and no budget cut-off - reset whenever the index is opened,
112
+ * so a completion persisted by an earlier session never counts. Callers MUST NOT treat `indexedFrom` as
113
+ * a coverage guarantee (e.g. to narrow Tier 3) unless this is `true` and `building` is `false`. */
114
+ complete: boolean;
115
+ /** Only set while `complete`: the guarantee ends here. Nothing indexes mail that arrives after a pass
116
+ * started, so everything dated after this (ISO) is NOT covered and must still be searched elsewhere. */
117
+ indexedUntil?: string;
118
+ }
119
+ export interface SetWindowParams extends GenerationParams {
120
+ mailboxUid: string;
121
+ timeFloorMonths: number;
122
+ byteBudgetBytes: number;
123
+ }
124
+ export interface SetBuildingParams extends GenerationParams {
125
+ mailboxUid: string;
126
+ building: boolean;
127
+ /** Only meaningful with `building: false` - whether the pass that just ended walked everything. */
128
+ complete?: boolean;
129
+ /** Only meaningful with `complete: true` - the pass's time floor (ISO), or `undefined` for none. */
130
+ coveredFrom?: string;
131
+ /** Only meaningful with `complete: true` - when the pass started (ISO, minus a clock-skew margin). */
132
+ coveredUntil?: string;
133
+ }
134
+ /** Runs `task` after every previously queued task for `mailboxUid` has settled. Exported for tests. */
135
+ export declare function runExclusive<T>(mailboxUid: string, task: () => Promise<T>): Promise<T>;
136
+ /** Rejects a build-pass call issued before its mailbox's index was last destroyed. */
137
+ export declare class StaleGenerationError extends Error {
138
+ constructor(mailboxUid: string);
139
+ }
140
+ /** Thrown by `init` when another tab already holds this mailbox's index open. */
141
+ export declare class LocalIndexBusyError extends Error {
142
+ constructor(mailboxUid: string);
143
+ }
144
+ /** Routes one request to its handler, inside the owning mailbox's serial queue. Exported for tests. */
145
+ export declare function handleRequest(method: LocalIndexRequest["method"], params: unknown): Promise<unknown>;