@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.
- package/README.md +88 -0
- package/apps/admin/audit-log/index.tsx +35 -8
- package/apps/admin/data-requests/index.tsx +480 -485
- package/apps/admin/distribution-lists/[uid].tsx +19 -1
- package/apps/admin/escrow-scopes/[uid].tsx +348 -237
- package/apps/admin/escrow-scopes/new/index.tsx +8 -2
- package/apps/admin/index.tsx +19 -1
- package/apps/admin/ingest-queue/index.tsx +44 -5
- package/apps/admin/mailboxes/[uid].tsx +211 -184
- package/apps/admin/quarantine/index.tsx +46 -14
- package/apps/admin/transport-rules/[uid].tsx +30 -1
- package/apps/admin/transport-rules/_transportRuleConfig.tsx +38 -2
- package/apps/admin/transport-rules/index.tsx +24 -6
- package/apps/admin/transport-rules/new/index.tsx +30 -1
- package/apps/escrow/_layout.tsx +2 -3
- package/apps/escrow/audit-log/index.tsx +196 -168
- package/apps/escrow/matters/[uid].tsx +621 -521
- package/apps/shared/components/admin/escrowScopes/EscrowScopeKeyAndHoldersFields.tsx +22 -1
- package/apps/shared/components/admin/layout/AdminShell.tsx +28 -9
- package/apps/shared/components/admin/mailboxes/EscrowScopeCard.tsx +152 -0
- package/apps/shared/components/admin/mailboxes/ResourceSettingsCard.tsx +3 -3
- package/apps/shared/components/admin/mailboxes/ShareAccessCard.tsx +55 -11
- package/apps/shared/components/admin/settings/BrandingForm.tsx +15 -4
- package/apps/shared/components/admin/settings/DomainDnsSetup.tsx +18 -7
- package/apps/shared/components/admin/settings/EncryptionPolicyForm.tsx +10 -2
- package/apps/shared/components/admin/settings/MailboxCreateForm.tsx +6 -0
- package/apps/shared/components/admin/settings/MailboxPolicyForm.tsx +45 -12
- package/apps/shared/components/admin/settings/PluginsManager.tsx +1235 -595
- package/apps/shared/components/admin/settings/RetentionPolicyForm.tsx +174 -98
- package/apps/shared/components/admin/setup/EscrowSetupStep.tsx +49 -13
- package/apps/shared/components/admin/setup/SetupWizard.tsx +150 -34
- package/apps/shared/components/admin/signOut.ts +79 -0
- package/apps/shared/components/admin/usePagedList.tsx +129 -0
- package/apps/shared/components/calendar/EventModal.tsx +717 -549
- package/apps/shared/components/calendar/MonthView.tsx +173 -139
- package/apps/shared/components/calendar/RecurrenceEditor.tsx +222 -180
- package/apps/shared/components/calendar/SplitDayView.tsx +143 -137
- package/apps/shared/components/calendar/TimeGridView.tsx +244 -198
- package/apps/shared/components/calendar/allDay.ts +124 -0
- package/apps/shared/components/calendar/layout/CalendarShell.tsx +194 -192
- package/apps/shared/components/contacts/ContactDetailPane.tsx +100 -21
- package/apps/shared/components/contacts/ContactForm.tsx +377 -348
- package/apps/shared/components/contacts/ContactsSidebar.tsx +6 -2
- package/apps/shared/components/contacts/KeyChangeReview.tsx +192 -0
- package/apps/shared/components/contacts/contactKeys.ts +78 -0
- package/apps/shared/components/contacts/layout/ContactsShell.tsx +199 -197
- package/apps/shared/components/escrow/layout/EscrowShell.tsx +148 -134
- package/apps/shared/components/layout/AppShell.tsx +123 -33
- package/apps/shared/components/layout/BrandingChrome.tsx +48 -10
- package/apps/shared/components/layout/KeyEnrollmentGate.tsx +389 -298
- package/apps/shared/components/layout/MailboxProvisioning.tsx +19 -3
- package/apps/shared/components/layout/RecoveryCodeUnlock.tsx +350 -0
- package/apps/shared/components/layout/UnlockPromptProvider.tsx +257 -128
- package/apps/shared/components/mail/ConversationThreadPane.tsx +216 -181
- package/apps/shared/components/mail/MessageDetailPane.tsx +1318 -630
- package/apps/shared/components/mail/compose/ComposeContext.tsx +20 -15
- package/apps/shared/components/mail/compose/ComposeWindow.tsx +854 -132
- package/apps/shared/components/mail/compose/composeFlushRegistry.ts +60 -0
- package/apps/shared/components/mail/layout/MailShell.tsx +420 -408
- package/apps/shared/components/mail/pinnedSigners.ts +124 -0
- package/apps/shared/components/mail/verificationSeals.ts +125 -0
- package/apps/shared/components/mail/writableMailboxes.ts +101 -0
- package/apps/shared/components/rules/RuleBuilder.tsx +311 -276
- package/apps/shared/components/settings/layout/SettingsShell.tsx +23 -9
- package/apps/shared/components/tasks/layout/TasksShell.tsx +201 -199
- package/apps/shared/mail/listAllPages.ts +39 -0
- package/apps/shared/plugins/pluginNav.ts +73 -0
- package/apps/shared/search/LocalIndexLifecycle.tsx +64 -55
- package/apps/shared/search/localIndexBuilder.ts +481 -179
- package/apps/shared/search/localIndexRpcClient.ts +231 -29
- package/apps/shared/search/localIndexSchema.ts +15 -6
- package/apps/shared/search/localIndexStorage.ts +98 -0
- package/apps/shared/search/localIndexVFS.ts +32 -1
- package/apps/shared/search/localIndexWorker.ts +648 -186
- package/apps/www/calendar/index.tsx +438 -417
- package/apps/www/contacts/[uid].tsx +21 -2
- package/apps/www/contacts/index.tsx +116 -12
- package/apps/www/index.tsx +1314 -1041
- package/apps/www/messages/[uid].tsx +18 -6
- package/apps/www/settings/auto-reply/index.tsx +134 -129
- package/apps/www/settings/encryption/index.tsx +739 -216
- package/apps/www/settings/filters/[uid].tsx +171 -155
- package/apps/www/settings/filters/new/index.tsx +8 -1
- package/apps/www/settings/focused-inbox/index.tsx +150 -148
- package/apps/www/settings/privacy/index.tsx +494 -436
- package/apps/www/settings/read-receipts/index.tsx +148 -125
- package/apps/www/settings/sharing/index.tsx +17 -14
- package/apps/www/tasks/index.tsx +638 -579
- package/dist/apps/admin/_404.d.ts +2 -0
- package/dist/apps/admin/_500.d.ts +2 -0
- package/dist/apps/admin/_layout.d.ts +8 -0
- package/dist/apps/admin/audit-log/index.d.ts +11 -0
- package/dist/apps/admin/audit-log/index.js +38 -8
- package/dist/apps/admin/branding/index.d.ts +3 -0
- package/dist/apps/admin/data-requests/index.d.ts +3 -0
- package/dist/apps/admin/data-requests/index.js +52 -72
- package/dist/apps/admin/distribution-lists/[uid].d.ts +7 -0
- package/dist/apps/admin/distribution-lists/[uid].js +1 -1
- package/dist/apps/admin/distribution-lists/index.d.ts +3 -0
- package/dist/apps/admin/distribution-lists/new/index.d.ts +3 -0
- package/dist/apps/admin/domains/[uid].d.ts +7 -0
- package/dist/apps/admin/domains/index.d.ts +3 -0
- package/dist/apps/admin/domains/new/index.d.ts +3 -0
- package/dist/apps/admin/encryption-policy/index.d.ts +3 -0
- package/dist/apps/admin/escrow-scopes/[uid].d.ts +21 -0
- package/dist/apps/admin/escrow-scopes/[uid].js +91 -12
- package/dist/apps/admin/escrow-scopes/index.d.ts +3 -0
- package/dist/apps/admin/escrow-scopes/new/index.d.ts +3 -0
- package/dist/apps/admin/escrow-scopes/new/index.js +8 -3
- package/dist/apps/admin/index.d.ts +3 -0
- package/dist/apps/admin/index.js +4 -1
- package/dist/apps/admin/ingest-queue/index.d.ts +4 -0
- package/dist/apps/admin/ingest-queue/index.js +24 -6
- package/dist/apps/admin/mailbox-policy/index.d.ts +3 -0
- package/dist/apps/admin/mailboxes/[uid].d.ts +7 -0
- package/dist/apps/admin/mailboxes/[uid].js +20 -4
- package/dist/apps/admin/mailboxes/new/index.d.ts +3 -0
- package/dist/apps/admin/plugins/index.d.ts +3 -0
- package/dist/apps/admin/quarantine/index.d.ts +6 -0
- package/dist/apps/admin/quarantine/index.js +20 -11
- package/dist/apps/admin/retention-policy/index.d.ts +3 -0
- package/dist/apps/admin/setup/index.d.ts +3 -0
- package/dist/apps/admin/transport-rules/[uid].d.ts +7 -0
- package/dist/apps/admin/transport-rules/[uid].js +18 -2
- package/dist/apps/admin/transport-rules/_transportRuleConfig.d.ts +21 -0
- package/dist/apps/admin/transport-rules/_transportRuleConfig.js +19 -0
- package/dist/apps/admin/transport-rules/index.d.ts +3 -0
- package/dist/apps/admin/transport-rules/index.js +22 -6
- package/dist/apps/admin/transport-rules/new/index.d.ts +3 -0
- package/dist/apps/admin/transport-rules/new/index.js +18 -2
- package/dist/apps/escrow/_layout.d.ts +10 -0
- package/dist/apps/escrow/_layout.js +3 -3
- package/dist/apps/escrow/audit-log/index.d.ts +9 -0
- package/dist/apps/escrow/audit-log/index.js +26 -1
- package/dist/apps/escrow/index.d.ts +3 -0
- package/dist/apps/escrow/matters/[uid].d.ts +7 -0
- package/dist/apps/escrow/matters/[uid].js +77 -42
- package/dist/apps/escrow/matters/new/index.d.ts +3 -0
- package/dist/apps/shared/components/admin/distributionLists/MemberListCard.d.ts +17 -0
- package/dist/apps/shared/components/admin/escrowScopes/EscrowScopeKeyAndHoldersFields.d.ts +32 -0
- package/dist/apps/shared/components/admin/escrowScopes/EscrowScopeKeyAndHoldersFields.js +11 -2
- package/dist/apps/shared/components/admin/layout/AdminShell.d.ts +32 -0
- package/dist/apps/shared/components/admin/layout/AdminShell.js +15 -6
- package/dist/apps/shared/components/admin/mailboxes/EscrowScopeCard.d.ts +12 -0
- package/dist/apps/shared/components/admin/mailboxes/EscrowScopeCard.js +72 -0
- package/dist/apps/shared/components/admin/mailboxes/MailboxTable.d.ts +6 -0
- package/dist/apps/shared/components/admin/mailboxes/ResourceSettingsCard.d.ts +19 -0
- package/dist/apps/shared/components/admin/mailboxes/ResourceSettingsCard.js +3 -3
- package/dist/apps/shared/components/admin/mailboxes/ShareAccessCard.d.ts +12 -0
- package/dist/apps/shared/components/admin/mailboxes/ShareAccessCard.js +22 -4
- package/dist/apps/shared/components/admin/settings/BrandingForm.d.ts +9 -0
- package/dist/apps/shared/components/admin/settings/BrandingForm.js +15 -4
- package/dist/apps/shared/components/admin/settings/DomainDnsSetup.d.ts +12 -0
- package/dist/apps/shared/components/admin/settings/DomainDnsSetup.js +13 -7
- package/dist/apps/shared/components/admin/settings/EncryptionPolicyForm.d.ts +12 -0
- package/dist/apps/shared/components/admin/settings/EncryptionPolicyForm.js +7 -2
- package/dist/apps/shared/components/admin/settings/LoadedSettingsForm.d.ts +9 -0
- package/dist/apps/shared/components/admin/settings/MailboxCreateForm.d.ts +19 -0
- package/dist/apps/shared/components/admin/settings/MailboxCreateForm.js +6 -0
- package/dist/apps/shared/components/admin/settings/MailboxPolicyForm.d.ts +10 -0
- package/dist/apps/shared/components/admin/settings/MailboxPolicyForm.js +34 -12
- package/dist/apps/shared/components/admin/settings/PluginsManager.d.ts +4 -0
- package/dist/apps/shared/components/admin/settings/PluginsManager.js +390 -78
- package/dist/apps/shared/components/admin/settings/RetentionPolicyForm.d.ts +9 -0
- package/dist/apps/shared/components/admin/settings/RetentionPolicyForm.js +40 -11
- package/dist/apps/shared/components/admin/setup/EscrowSetupStep.d.ts +14 -0
- package/dist/apps/shared/components/admin/setup/EscrowSetupStep.js +29 -13
- package/dist/apps/shared/components/admin/setup/SetupWizard.d.ts +36 -0
- package/dist/apps/shared/components/admin/setup/SetupWizard.js +87 -21
- package/dist/apps/shared/components/admin/signOut.d.ts +23 -0
- package/dist/apps/shared/components/admin/signOut.js +75 -0
- package/dist/apps/shared/components/admin/usePagedList.d.ts +39 -0
- package/dist/apps/shared/components/admin/usePagedList.js +99 -0
- package/dist/apps/shared/components/calendar/CalendarListSidebar.d.ts +26 -0
- package/dist/apps/shared/components/calendar/EventModal.d.ts +46 -0
- package/dist/apps/shared/components/calendar/EventModal.js +142 -21
- package/dist/apps/shared/components/calendar/MonthView.d.ts +15 -0
- package/dist/apps/shared/components/calendar/MonthView.js +12 -5
- package/dist/apps/shared/components/calendar/RecurrenceEditor.d.ts +20 -0
- package/dist/apps/shared/components/calendar/RecurrenceEditor.js +40 -5
- package/dist/apps/shared/components/calendar/ResourcePicker.d.ts +19 -0
- package/dist/apps/shared/components/calendar/SplitDayView.d.ts +28 -0
- package/dist/apps/shared/components/calendar/SplitDayView.js +10 -4
- package/dist/apps/shared/components/calendar/TimeGridView.d.ts +17 -0
- package/dist/apps/shared/components/calendar/TimeGridView.js +23 -7
- package/dist/apps/shared/components/calendar/allDay.d.ts +51 -0
- package/dist/apps/shared/components/calendar/allDay.js +111 -0
- package/dist/apps/shared/components/calendar/layout/CalendarShell.d.ts +40 -0
- package/dist/apps/shared/components/calendar/layout/CalendarShell.js +3 -3
- package/dist/apps/shared/components/contacts/ContactDetailPane.d.ts +23 -0
- package/dist/apps/shared/components/contacts/ContactDetailPane.js +43 -5
- package/dist/apps/shared/components/contacts/ContactForm.d.ts +20 -0
- package/dist/apps/shared/components/contacts/ContactForm.js +32 -10
- package/dist/apps/shared/components/contacts/ContactsSidebar.d.ts +40 -0
- package/dist/apps/shared/components/contacts/ContactsSidebar.js +2 -2
- package/dist/apps/shared/components/contacts/ContactsToolbar.d.ts +25 -0
- package/dist/apps/shared/components/contacts/KeyChangeReview.d.ts +40 -0
- package/dist/apps/shared/components/contacts/KeyChangeReview.js +63 -0
- package/dist/apps/shared/components/contacts/contactKeys.d.ts +29 -0
- package/dist/apps/shared/components/contacts/contactKeys.js +64 -0
- package/dist/apps/shared/components/contacts/layout/ContactsShell.d.ts +21 -0
- package/dist/apps/shared/components/contacts/layout/ContactsShell.js +2 -2
- package/dist/apps/shared/components/escrow/layout/EscrowShell.d.ts +25 -0
- package/dist/apps/shared/components/escrow/layout/EscrowShell.js +24 -5
- package/dist/apps/shared/components/forms/StringListField.d.ts +22 -0
- package/dist/apps/shared/components/layout/AppShell.d.ts +49 -0
- package/dist/apps/shared/components/layout/AppShell.js +97 -26
- package/dist/apps/shared/components/layout/BrandingChrome.d.ts +18 -0
- package/dist/apps/shared/components/layout/BrandingChrome.js +45 -10
- package/dist/apps/shared/components/layout/KeyEnrollmentGate.d.ts +51 -0
- package/dist/apps/shared/components/layout/KeyEnrollmentGate.js +49 -12
- package/dist/apps/shared/components/layout/MailboxProvisioning.d.ts +13 -0
- package/dist/apps/shared/components/layout/MailboxProvisioning.js +10 -2
- package/dist/apps/shared/components/layout/RecoveryCodeUnlock.d.ts +66 -0
- package/dist/apps/shared/components/layout/RecoveryCodeUnlock.js +174 -0
- package/dist/apps/shared/components/layout/UnlockPromptProvider.d.ts +45 -0
- package/dist/apps/shared/components/layout/UnlockPromptProvider.js +73 -14
- package/dist/apps/shared/components/layout/UserMenu.d.ts +23 -0
- package/dist/apps/shared/components/mail/ConversationList.d.ts +11 -0
- package/dist/apps/shared/components/mail/ConversationThreadPane.d.ts +23 -0
- package/dist/apps/shared/components/mail/ConversationThreadPane.js +50 -12
- package/dist/apps/shared/components/mail/MessageDetailPane.d.ts +93 -0
- package/dist/apps/shared/components/mail/MessageDetailPane.js +441 -36
- package/dist/apps/shared/components/mail/compose/ComposeContext.d.ts +58 -0
- package/dist/apps/shared/components/mail/compose/ComposeContext.js +9 -6
- package/dist/apps/shared/components/mail/compose/ComposeToolbar.d.ts +15 -0
- package/dist/apps/shared/components/mail/compose/ComposeWindow.d.ts +37 -0
- package/dist/apps/shared/components/mail/compose/ComposeWindow.js +699 -128
- package/dist/apps/shared/components/mail/compose/EmojiPicker.d.ts +14 -0
- package/dist/apps/shared/components/mail/compose/GifPicker.d.ts +13 -0
- package/dist/apps/shared/components/mail/compose/RichTextEditor.d.ts +34 -0
- package/dist/apps/shared/components/mail/compose/ScheduleSendPicker.d.ts +16 -0
- package/dist/apps/shared/components/mail/compose/composeFlushRegistry.d.ts +27 -0
- package/dist/apps/shared/components/mail/compose/composeFlushRegistry.js +50 -0
- package/dist/apps/shared/components/mail/layout/MailShell.d.ts +57 -0
- package/dist/apps/shared/components/mail/layout/MailShell.js +13 -4
- package/dist/apps/shared/components/mail/pinnedSigners.d.ts +33 -0
- package/dist/apps/shared/components/mail/pinnedSigners.js +98 -0
- package/dist/apps/shared/components/mail/verificationSeals.d.ts +22 -0
- package/dist/apps/shared/components/mail/verificationSeals.js +112 -0
- package/dist/apps/shared/components/mail/writableMailboxes.d.ts +15 -0
- package/dist/apps/shared/components/mail/writableMailboxes.js +87 -0
- package/dist/apps/shared/components/rules/RuleBuilder.d.ts +70 -0
- package/dist/apps/shared/components/rules/RuleBuilder.js +34 -6
- package/dist/apps/shared/components/settings/layout/SettingsShell.d.ts +41 -0
- package/dist/apps/shared/components/settings/layout/SettingsShell.js +19 -9
- package/dist/apps/shared/components/tasks/TasksSidebar.d.ts +41 -0
- package/dist/apps/shared/components/tasks/TasksToolbar.d.ts +14 -0
- package/dist/apps/shared/components/tasks/layout/TasksShell.d.ts +24 -0
- package/dist/apps/shared/components/tasks/layout/TasksShell.js +2 -2
- package/dist/apps/shared/mail/findWellKnownFolderUid.d.ts +5 -0
- package/dist/apps/shared/mail/listAllPages.d.ts +17 -0
- package/dist/apps/shared/mail/listAllPages.js +25 -0
- package/dist/apps/shared/plugins/pluginNav.d.ts +39 -0
- package/dist/apps/shared/plugins/pluginNav.js +33 -0
- package/dist/apps/shared/search/LocalIndexLifecycle.d.ts +13 -0
- package/dist/apps/shared/search/LocalIndexLifecycle.js +58 -54
- package/dist/apps/shared/search/localIndexBlockCipher.d.ts +36 -0
- package/dist/apps/shared/search/localIndexBuilder.d.ts +85 -0
- package/dist/apps/shared/search/localIndexBuilder.js +292 -37
- package/dist/apps/shared/search/localIndexKey.d.ts +4 -0
- package/dist/apps/shared/search/localIndexRpcClient.d.ts +71 -0
- package/dist/apps/shared/search/localIndexRpcClient.js +191 -26
- package/dist/apps/shared/search/localIndexSchema.d.ts +111 -0
- package/dist/apps/shared/search/localIndexSchema.js +12 -6
- package/dist/apps/shared/search/localIndexSizePreference.d.ts +27 -0
- package/dist/apps/shared/search/localIndexStorage.d.ts +28 -0
- package/dist/apps/shared/search/localIndexStorage.js +86 -0
- package/dist/apps/shared/search/localIndexVFS.d.ts +101 -0
- package/dist/apps/shared/search/localIndexVFS.js +68 -40
- package/dist/apps/shared/search/localIndexWorker.d.ts +145 -0
- package/dist/apps/shared/search/localIndexWorker.js +519 -173
- package/dist/apps/shared/search/searchTier2.d.ts +30 -0
- package/dist/apps/www/_404.d.ts +2 -0
- package/dist/apps/www/_500.d.ts +2 -0
- package/dist/apps/www/_layout.d.ts +14 -0
- package/dist/apps/www/calendar/index.d.ts +3 -0
- package/dist/apps/www/calendar/index.js +28 -10
- package/dist/apps/www/contacts/[uid].d.ts +13 -0
- package/dist/apps/www/contacts/[uid].js +13 -2
- package/dist/apps/www/contacts/index.d.ts +3 -0
- package/dist/apps/www/contacts/index.js +80 -10
- package/dist/apps/www/index.d.ts +3 -0
- package/dist/apps/www/index.js +339 -108
- package/dist/apps/www/messages/[uid].d.ts +11 -0
- package/dist/apps/www/messages/[uid].js +18 -6
- package/dist/apps/www/settings/auto-reply/index.d.ts +4 -0
- package/dist/apps/www/settings/auto-reply/index.js +9 -4
- package/dist/apps/www/settings/encryption/index.d.ts +7 -0
- package/dist/apps/www/settings/encryption/index.js +514 -97
- package/dist/apps/www/settings/filters/[uid].d.ts +8 -0
- package/dist/apps/www/settings/filters/[uid].js +22 -7
- package/dist/apps/www/settings/filters/_mailFilterRuleConfig.d.ts +11 -0
- package/dist/apps/www/settings/filters/index.d.ts +4 -0
- package/dist/apps/www/settings/filters/new/index.d.ts +4 -0
- package/dist/apps/www/settings/filters/new/index.js +8 -2
- package/dist/apps/www/settings/focused-inbox/index.d.ts +4 -0
- package/dist/apps/www/settings/focused-inbox/index.js +3 -1
- package/dist/apps/www/settings/labels/index.d.ts +4 -0
- package/dist/apps/www/settings/privacy/index.d.ts +4 -0
- package/dist/apps/www/settings/privacy/index.js +57 -22
- package/dist/apps/www/settings/read-receipts/index.d.ts +4 -0
- package/dist/apps/www/settings/read-receipts/index.js +10 -3
- package/dist/apps/www/settings/sharing/index.d.ts +4 -0
- package/dist/apps/www/settings/sharing/index.js +7 -11
- package/dist/apps/www/settings/signatures/[uid].d.ts +8 -0
- package/dist/apps/www/settings/signatures/index.d.ts +4 -0
- package/dist/apps/www/settings/signatures/new/index.d.ts +4 -0
- package/dist/apps/www/settings/signatures/signatureDefaults.d.ts +10 -0
- package/dist/apps/www/tasks/index.d.ts +3 -0
- package/dist/apps/www/tasks/index.js +50 -10
- package/package.json +3 -3
- package/apps/shared/components/booking/AvailabilityEditor.tsx +0 -118
- package/apps/www/settings/booking-types/[uid].tsx +0 -300
- package/apps/www/settings/booking-types/index.tsx +0 -98
- package/apps/www/settings/booking-types/new/index.tsx +0 -212
- package/dist/apps/shared/components/booking/AvailabilityEditor.js +0 -45
- package/dist/apps/www/settings/booking-types/[uid].js +0 -129
- package/dist/apps/www/settings/booking-types/index.js +0 -29
- 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
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
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
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
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>;
|