mindoodb 0.0.24 → 0.0.32
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-server.md +9 -1
- package/README.md +5 -3
- package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.d.ts +1 -1
- package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.d.ts.map +1 -1
- package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.js +24 -5
- package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.js.map +1 -1
- package/dist/appendonlystores/network/HttpTransport.d.ts +14 -2
- package/dist/appendonlystores/network/HttpTransport.d.ts.map +1 -1
- package/dist/appendonlystores/network/HttpTransport.js +124 -27
- package/dist/appendonlystores/network/HttpTransport.js.map +1 -1
- package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.d.ts +159 -4
- package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.d.ts.map +1 -1
- package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.js +334 -25
- package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.js.map +1 -1
- package/dist/browser/appendonlystores/IndexedDBContentAddressedStore.d.ts +9 -0
- package/dist/browser/appendonlystores/IndexedDBContentAddressedStore.d.ts.map +1 -1
- package/dist/browser/appendonlystores/IndexedDBContentAddressedStore.js +77 -5
- package/dist/browser/appendonlystores/IndexedDBContentAddressedStore.js.map +1 -1
- package/dist/browser/index.mjs +103 -0
- package/dist/core/BaseMindooDB.d.ts +662 -4
- package/dist/core/BaseMindooDB.d.ts.map +1 -1
- package/dist/core/BaseMindooDB.js +2769 -144
- package/dist/core/BaseMindooDB.js.map +1 -1
- package/dist/core/BaseMindooTenant.d.ts +192 -1
- package/dist/core/BaseMindooTenant.d.ts.map +1 -1
- package/dist/core/BaseMindooTenant.js +633 -88
- package/dist/core/BaseMindooTenant.js.map +1 -1
- package/dist/core/BaseMindooTenantDirectory.d.ts +770 -10
- package/dist/core/BaseMindooTenantDirectory.d.ts.map +1 -1
- package/dist/core/BaseMindooTenantDirectory.js +2715 -292
- package/dist/core/BaseMindooTenantDirectory.js.map +1 -1
- package/dist/core/BaseMindooTenantFactory.d.ts +2 -0
- package/dist/core/BaseMindooTenantFactory.d.ts.map +1 -1
- package/dist/core/BaseMindooTenantFactory.js +20 -0
- package/dist/core/BaseMindooTenantFactory.js.map +1 -1
- package/dist/core/accesscontrol/AccessDeniedError.d.ts +22 -0
- package/dist/core/accesscontrol/AccessDeniedError.d.ts.map +1 -0
- package/dist/core/accesscontrol/AccessDeniedError.js +28 -0
- package/dist/core/accesscontrol/AccessDeniedError.js.map +1 -0
- package/dist/core/accesscontrol/DirectoryStateNode.d.ts +220 -0
- package/dist/core/accesscontrol/DirectoryStateNode.d.ts.map +1 -0
- package/dist/core/accesscontrol/DirectoryStateNode.js +297 -0
- package/dist/core/accesscontrol/DirectoryStateNode.js.map +1 -0
- package/dist/core/accesscontrol/DirectoryTimeTravelIndex.d.ts +118 -0
- package/dist/core/accesscontrol/DirectoryTimeTravelIndex.d.ts.map +1 -0
- package/dist/core/accesscontrol/DirectoryTimeTravelIndex.js +173 -0
- package/dist/core/accesscontrol/DirectoryTimeTravelIndex.js.map +1 -0
- package/dist/core/accesscontrol/directoryProjection.d.ts +26 -0
- package/dist/core/accesscontrol/directoryProjection.d.ts.map +1 -0
- package/dist/core/accesscontrol/directoryProjection.js +174 -0
- package/dist/core/accesscontrol/directoryProjection.js.map +1 -0
- package/dist/core/accesscontrol/evaluate.d.ts +77 -0
- package/dist/core/accesscontrol/evaluate.d.ts.map +1 -0
- package/dist/core/accesscontrol/evaluate.js +206 -0
- package/dist/core/accesscontrol/evaluate.js.map +1 -0
- package/dist/core/accesscontrol/grantKeys.d.ts +113 -0
- package/dist/core/accesscontrol/grantKeys.d.ts.map +1 -0
- package/dist/core/accesscontrol/grantKeys.js +302 -0
- package/dist/core/accesscontrol/grantKeys.js.map +1 -0
- package/dist/core/accesscontrol/keyBagReconciler.d.ts +22 -0
- package/dist/core/accesscontrol/keyBagReconciler.d.ts.map +1 -0
- package/dist/core/accesscontrol/keyBagReconciler.js +3 -0
- package/dist/core/accesscontrol/keyBagReconciler.js.map +1 -0
- package/dist/core/accesscontrol/materializationGuard.d.ts +89 -0
- package/dist/core/accesscontrol/materializationGuard.d.ts.map +1 -0
- package/dist/core/accesscontrol/materializationGuard.js +69 -0
- package/dist/core/accesscontrol/materializationGuard.js.map +1 -0
- package/dist/core/accesscontrol/quarantine.d.ts +65 -0
- package/dist/core/accesscontrol/quarantine.d.ts.map +1 -0
- package/dist/core/accesscontrol/quarantine.js +79 -0
- package/dist/core/accesscontrol/quarantine.js.map +1 -0
- package/dist/core/accesscontrol/receiptValidation.d.ts +113 -0
- package/dist/core/accesscontrol/receiptValidation.d.ts.map +1 -0
- package/dist/core/accesscontrol/receiptValidation.js +142 -0
- package/dist/core/accesscontrol/receiptValidation.js.map +1 -0
- package/dist/core/accesscontrol/timestamp/Ed25519WitnessProvider.d.ts +31 -0
- package/dist/core/accesscontrol/timestamp/Ed25519WitnessProvider.d.ts.map +1 -0
- package/dist/core/accesscontrol/timestamp/Ed25519WitnessProvider.js +66 -0
- package/dist/core/accesscontrol/timestamp/Ed25519WitnessProvider.js.map +1 -0
- package/dist/core/accesscontrol/timestamp/TimestampProvider.d.ts +79 -0
- package/dist/core/accesscontrol/timestamp/TimestampProvider.d.ts.map +1 -0
- package/dist/core/accesscontrol/timestamp/TimestampProvider.js +22 -0
- package/dist/core/accesscontrol/timestamp/TimestampProvider.js.map +1 -0
- package/dist/core/accesscontrol/types.d.ts +825 -0
- package/dist/core/accesscontrol/types.d.ts.map +1 -0
- package/dist/core/accesscontrol/types.js +534 -0
- package/dist/core/accesscontrol/types.js.map +1 -0
- package/dist/core/appendonlystores/InMemoryContentAddressedStore.d.ts +9 -0
- package/dist/core/appendonlystores/InMemoryContentAddressedStore.d.ts.map +1 -1
- package/dist/core/appendonlystores/InMemoryContentAddressedStore.js +54 -0
- package/dist/core/appendonlystores/InMemoryContentAddressedStore.js.map +1 -1
- package/dist/core/appendonlystores/network/AuthenticationService.d.ts +38 -2
- package/dist/core/appendonlystores/network/AuthenticationService.d.ts.map +1 -1
- package/dist/core/appendonlystores/network/AuthenticationService.js +199 -26
- package/dist/core/appendonlystores/network/AuthenticationService.js.map +1 -1
- package/dist/core/appendonlystores/network/NetworkTransport.d.ts +17 -3
- package/dist/core/appendonlystores/network/NetworkTransport.d.ts.map +1 -1
- package/dist/core/appendonlystores/network/types.d.ts +58 -4
- package/dist/core/appendonlystores/network/types.d.ts.map +1 -1
- package/dist/core/appendonlystores/network/types.js +4 -0
- package/dist/core/appendonlystores/network/types.js.map +1 -1
- package/dist/core/appendonlystores/scanUtils.d.ts +27 -0
- package/dist/core/appendonlystores/scanUtils.d.ts.map +1 -0
- package/dist/core/appendonlystores/scanUtils.js +87 -0
- package/dist/core/appendonlystores/scanUtils.js.map +1 -0
- package/dist/core/appendonlystores/types.d.ts +23 -2
- package/dist/core/appendonlystores/types.d.ts.map +1 -1
- package/dist/core/cache/CacheManager.d.ts +13 -3
- package/dist/core/cache/CacheManager.d.ts.map +1 -1
- package/dist/core/cache/CacheManager.js +7 -4
- package/dist/core/cache/CacheManager.js.map +1 -1
- package/dist/core/crypto/EntrySignature.d.ts +137 -0
- package/dist/core/crypto/EntrySignature.d.ts.map +1 -0
- package/dist/core/crypto/EntrySignature.js +210 -0
- package/dist/core/crypto/EntrySignature.js.map +1 -0
- package/dist/core/crypto/MindooDocSigner.d.ts.map +1 -1
- package/dist/core/crypto/MindooDocSigner.js +6 -2
- package/dist/core/crypto/MindooDocSigner.js.map +1 -1
- package/dist/core/crypto/WitnessReceipt.d.ts +137 -0
- package/dist/core/crypto/WitnessReceipt.d.ts.map +1 -0
- package/dist/core/crypto/WitnessReceipt.js +182 -0
- package/dist/core/crypto/WitnessReceipt.js.map +1 -0
- package/dist/core/crypto/encryptedFields.d.ts +27 -0
- package/dist/core/crypto/encryptedFields.d.ts.map +1 -0
- package/dist/core/crypto/encryptedFields.js +58 -0
- package/dist/core/crypto/encryptedFields.js.map +1 -0
- package/dist/core/crypto/pbkdf2Iterations.d.ts +12 -0
- package/dist/core/crypto/pbkdf2Iterations.d.ts.map +1 -1
- package/dist/core/crypto/pbkdf2Iterations.js +23 -0
- package/dist/core/crypto/pbkdf2Iterations.js.map +1 -1
- package/dist/core/crypto/privateKeyEncryption.d.ts.map +1 -1
- package/dist/core/crypto/privateKeyEncryption.js +3 -1
- package/dist/core/crypto/privateKeyEncryption.js.map +1 -1
- package/dist/core/databaseIdValidation.d.ts +1 -1
- package/dist/core/databaseIdValidation.d.ts.map +1 -1
- package/dist/core/databaseIdValidation.js +4 -4
- package/dist/core/databaseIdValidation.js.map +1 -1
- package/dist/core/errors.d.ts +26 -0
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +42 -1
- package/dist/core/errors.js.map +1 -1
- package/dist/core/expressions/builder.d.ts +102 -0
- package/dist/core/expressions/builder.d.ts.map +1 -0
- package/dist/core/expressions/builder.js +249 -0
- package/dist/core/expressions/builder.js.map +1 -0
- package/dist/core/expressions/evaluateExpression.d.ts +78 -0
- package/dist/core/expressions/evaluateExpression.d.ts.map +1 -0
- package/dist/core/expressions/evaluateExpression.js +386 -0
- package/dist/core/expressions/evaluateExpression.js.map +1 -0
- package/dist/core/expressions/formulaSource.d.ts +24 -0
- package/dist/core/expressions/formulaSource.d.ts.map +1 -0
- package/dist/core/expressions/formulaSource.js +765 -0
- package/dist/core/expressions/formulaSource.js.map +1 -0
- package/dist/core/expressions/index.d.ts +8 -0
- package/dist/core/expressions/index.d.ts.map +1 -0
- package/dist/core/expressions/index.js +46 -0
- package/dist/core/expressions/index.js.map +1 -0
- package/dist/core/expressions/metadata.d.ts +23 -0
- package/dist/core/expressions/metadata.d.ts.map +1 -0
- package/dist/core/expressions/metadata.js +191 -0
- package/dist/core/expressions/metadata.js.map +1 -0
- package/dist/core/expressions/types.d.ts +164 -0
- package/dist/core/expressions/types.d.ts.map +1 -0
- package/dist/core/expressions/types.js +3 -0
- package/dist/core/expressions/types.js.map +1 -0
- package/dist/core/extraction/types.d.ts +47 -0
- package/dist/core/extraction/types.d.ts.map +1 -0
- package/dist/core/extraction/types.js +42 -0
- package/dist/core/extraction/types.js.map +1 -0
- package/dist/core/index.d.ts +13 -3
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +113 -4
- package/dist/core/index.js.map +1 -1
- package/dist/core/indexing/createViewDataProvider.d.ts +84 -0
- package/dist/core/indexing/createViewDataProvider.d.ts.map +1 -0
- package/dist/core/indexing/createViewDataProvider.js +139 -0
- package/dist/core/indexing/createViewDataProvider.js.map +1 -0
- package/dist/core/indexing/fulltext/DocumentFullTextIndex.d.ts +180 -0
- package/dist/core/indexing/fulltext/DocumentFullTextIndex.d.ts.map +1 -0
- package/dist/core/indexing/fulltext/DocumentFullTextIndex.js +548 -0
- package/dist/core/indexing/fulltext/DocumentFullTextIndex.js.map +1 -0
- package/dist/core/indexing/fulltext/SearchEngineAdapter.d.ts +69 -0
- package/dist/core/indexing/fulltext/SearchEngineAdapter.d.ts.map +1 -0
- package/dist/core/indexing/fulltext/SearchEngineAdapter.js +183 -0
- package/dist/core/indexing/fulltext/SearchEngineAdapter.js.map +1 -0
- package/dist/core/indexing/fulltext/extractFulltextText.d.ts +34 -0
- package/dist/core/indexing/fulltext/extractFulltextText.d.ts.map +1 -0
- package/dist/core/indexing/fulltext/extractFulltextText.js +129 -0
- package/dist/core/indexing/fulltext/extractFulltextText.js.map +1 -0
- package/dist/core/indexing/fulltext/index.d.ts +5 -0
- package/dist/core/indexing/fulltext/index.d.ts.map +1 -0
- package/dist/core/indexing/fulltext/index.js +20 -0
- package/dist/core/indexing/fulltext/index.js.map +1 -0
- package/dist/core/indexing/fulltext/types.d.ts +168 -0
- package/dist/core/indexing/fulltext/types.d.ts.map +1 -0
- package/dist/core/indexing/fulltext/types.js +89 -0
- package/dist/core/indexing/fulltext/types.js.map +1 -0
- package/dist/core/indexing/summary/DocumentSummaryStore.d.ts +137 -0
- package/dist/core/indexing/summary/DocumentSummaryStore.d.ts.map +1 -0
- package/dist/core/indexing/summary/DocumentSummaryStore.js +438 -0
- package/dist/core/indexing/summary/DocumentSummaryStore.js.map +1 -0
- package/dist/core/indexing/summary/SummaryVirtualViewDataProvider.d.ts +72 -0
- package/dist/core/indexing/summary/SummaryVirtualViewDataProvider.d.ts.map +1 -0
- package/dist/core/indexing/summary/SummaryVirtualViewDataProvider.js +221 -0
- package/dist/core/indexing/summary/SummaryVirtualViewDataProvider.js.map +1 -0
- package/dist/core/indexing/summary/extractSummaryFields.d.ts +75 -0
- package/dist/core/indexing/summary/extractSummaryFields.d.ts.map +1 -0
- package/dist/core/indexing/summary/extractSummaryFields.js +266 -0
- package/dist/core/indexing/summary/extractSummaryFields.js.map +1 -0
- package/dist/core/indexing/summary/index.d.ts +5 -0
- package/dist/core/indexing/summary/index.d.ts.map +1 -0
- package/dist/core/indexing/summary/index.js +23 -0
- package/dist/core/indexing/summary/index.js.map +1 -0
- package/dist/core/indexing/summary/types.d.ts +119 -0
- package/dist/core/indexing/summary/types.d.ts.map +1 -0
- package/dist/core/indexing/summary/types.js +81 -0
- package/dist/core/indexing/summary/types.js.map +1 -0
- package/dist/core/indexing/virtualviews/IVirtualViewDataProvider.d.ts +47 -1
- package/dist/core/indexing/virtualviews/IVirtualViewDataProvider.d.ts.map +1 -1
- package/dist/core/indexing/virtualviews/MindooDBVirtualViewDataProvider.d.ts +24 -8
- package/dist/core/indexing/virtualviews/MindooDBVirtualViewDataProvider.d.ts.map +1 -1
- package/dist/core/indexing/virtualviews/MindooDBVirtualViewDataProvider.js +96 -41
- package/dist/core/indexing/virtualviews/MindooDBVirtualViewDataProvider.js.map +1 -1
- package/dist/core/indexing/virtualviews/ViewEntrySortKey.d.ts +2 -0
- package/dist/core/indexing/virtualviews/ViewEntrySortKey.d.ts.map +1 -1
- package/dist/core/indexing/virtualviews/ViewEntrySortKey.js +8 -3
- package/dist/core/indexing/virtualviews/ViewEntrySortKey.js.map +1 -1
- package/dist/core/indexing/virtualviews/VirtualView.d.ts +111 -5
- package/dist/core/indexing/virtualviews/VirtualView.d.ts.map +1 -1
- package/dist/core/indexing/virtualviews/VirtualView.js +266 -75
- package/dist/core/indexing/virtualviews/VirtualView.js.map +1 -1
- package/dist/core/indexing/virtualviews/VirtualViewColumn.d.ts +12 -0
- package/dist/core/indexing/virtualviews/VirtualViewColumn.d.ts.map +1 -1
- package/dist/core/indexing/virtualviews/VirtualViewColumn.js +1 -0
- package/dist/core/indexing/virtualviews/VirtualViewColumn.js.map +1 -1
- package/dist/core/indexing/virtualviews/VirtualViewEntryData.d.ts +12 -0
- package/dist/core/indexing/virtualviews/VirtualViewEntryData.d.ts.map +1 -1
- package/dist/core/indexing/virtualviews/VirtualViewEntryData.js +66 -5
- package/dist/core/indexing/virtualviews/VirtualViewEntryData.js.map +1 -1
- package/dist/core/indexing/virtualviews/VirtualViewFactory.d.ts +50 -6
- package/dist/core/indexing/virtualviews/VirtualViewFactory.d.ts.map +1 -1
- package/dist/core/indexing/virtualviews/VirtualViewFactory.js +54 -12
- package/dist/core/indexing/virtualviews/VirtualViewFactory.js.map +1 -1
- package/dist/core/indexing/virtualviews/index.d.ts +3 -3
- package/dist/core/indexing/virtualviews/index.d.ts.map +1 -1
- package/dist/core/indexing/virtualviews/index.js.map +1 -1
- package/dist/core/indexing/virtualviews/types.d.ts +6 -0
- package/dist/core/indexing/virtualviews/types.d.ts.map +1 -1
- package/dist/core/indexing/virtualviews/types.js +11 -3
- package/dist/core/indexing/virtualviews/types.js.map +1 -1
- package/dist/core/keys/KeyBag.d.ts +25 -0
- package/dist/core/keys/KeyBag.d.ts.map +1 -1
- package/dist/core/keys/KeyBag.js +37 -1
- package/dist/core/keys/KeyBag.js.map +1 -1
- package/dist/core/query/executeQuery.d.ts +18 -0
- package/dist/core/query/executeQuery.d.ts.map +1 -0
- package/dist/core/query/executeQuery.js +313 -0
- package/dist/core/query/executeQuery.js.map +1 -0
- package/dist/core/query/index.d.ts +5 -0
- package/dist/core/query/index.d.ts.map +1 -0
- package/dist/core/query/index.js +14 -0
- package/dist/core/query/index.js.map +1 -0
- package/dist/core/query/queryLive.d.ts +27 -0
- package/dist/core/query/queryLive.d.ts.map +1 -0
- package/dist/core/query/queryLive.js +104 -0
- package/dist/core/query/queryLive.js.map +1 -0
- package/dist/core/query/queryView.d.ts +156 -0
- package/dist/core/query/queryView.d.ts.map +1 -0
- package/dist/core/query/queryView.js +266 -0
- package/dist/core/query/queryView.js.map +1 -0
- package/dist/core/query/types.d.ts +121 -0
- package/dist/core/query/types.d.ts.map +1 -0
- package/dist/core/query/types.js +18 -0
- package/dist/core/query/types.js.map +1 -0
- package/dist/core/storeEntryTime.d.ts +57 -0
- package/dist/core/storeEntryTime.d.ts.map +1 -0
- package/dist/core/storeEntryTime.js +72 -0
- package/dist/core/storeEntryTime.js.map +1 -0
- package/dist/core/types.d.ts +1371 -34
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js +13 -1
- package/dist/core/types.js.map +1 -1
- package/dist/core/uri/MindooURI.d.ts +53 -1
- package/dist/core/uri/MindooURI.d.ts.map +1 -1
- package/dist/core/uri/MindooURI.js +135 -0
- package/dist/core/uri/MindooURI.js.map +1 -1
- package/dist/core/utils/urlSafety.d.ts +46 -0
- package/dist/core/utils/urlSafety.d.ts.map +1 -0
- package/dist/core/utils/urlSafety.js +144 -0
- package/dist/core/utils/urlSafety.js.map +1 -0
- package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.d.ts +14 -0
- package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.d.ts.map +1 -1
- package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.js +95 -4
- package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.js.map +1 -1
- package/dist/node/server/CapabilityMatcher.d.ts +10 -0
- package/dist/node/server/CapabilityMatcher.d.ts.map +1 -1
- package/dist/node/server/CapabilityMatcher.js +14 -2
- package/dist/node/server/CapabilityMatcher.js.map +1 -1
- package/dist/node/server/MindooDBServer.d.ts.map +1 -1
- package/dist/node/server/MindooDBServer.js +117 -8
- package/dist/node/server/MindooDBServer.js.map +1 -1
- package/dist/node/server/PurgedDocRegistry.d.ts +32 -0
- package/dist/node/server/PurgedDocRegistry.d.ts.map +1 -0
- package/dist/node/server/PurgedDocRegistry.js +94 -0
- package/dist/node/server/PurgedDocRegistry.js.map +1 -0
- package/dist/node/server/ServerSync.d.ts.map +1 -1
- package/dist/node/server/ServerSync.js +5 -2
- package/dist/node/server/ServerSync.js.map +1 -1
- package/dist/node/server/SystemAdminAuth.d.ts +10 -0
- package/dist/node/server/SystemAdminAuth.d.ts.map +1 -1
- package/dist/node/server/SystemAdminAuth.js +25 -0
- package/dist/node/server/SystemAdminAuth.js.map +1 -1
- package/dist/node/server/TenantManager.d.ts +95 -1
- package/dist/node/server/TenantManager.d.ts.map +1 -1
- package/dist/node/server/TenantManager.js +382 -15
- package/dist/node/server/TenantManager.js.map +1 -1
- package/dist/node/server/config.d.ts.map +1 -1
- package/dist/node/server/config.js +5 -1
- package/dist/node/server/config.js.map +1 -1
- package/dist/node/server/types.d.ts +29 -3
- package/dist/node/server/types.d.ts.map +1 -1
- package/dist/node/server/types.js +12 -0
- package/dist/node/server/types.js.map +1 -1
- package/dist/node/server/validation.d.ts +6 -0
- package/dist/node/server/validation.d.ts.map +1 -1
- package/dist/node/server/validation.js +7 -1
- package/dist/node/server/validation.js.map +1 -1
- package/package.json +4 -3
- package/dist/appendonlystores/BasicOnDiskContentAddressedStoreFactory.d.ts +0 -8
- package/dist/appendonlystores/BasicOnDiskContentAddressedStoreFactory.d.ts.map +0 -1
- package/dist/appendonlystores/BasicOnDiskContentAddressedStoreFactory.js +0 -16
- package/dist/appendonlystores/BasicOnDiskContentAddressedStoreFactory.js.map +0 -1
- package/dist/core/appendonlystores/BasicOnDiskContentAddressedStore.d.ts +0 -68
- package/dist/core/appendonlystores/BasicOnDiskContentAddressedStore.d.ts.map +0 -1
- package/dist/core/appendonlystores/BasicOnDiskContentAddressedStore.js +0 -659
- package/dist/core/appendonlystores/BasicOnDiskContentAddressedStore.js.map +0 -1
- package/dist/node/attachments/writeAttachmentToFile.d.ts +0 -15
- package/dist/node/attachments/writeAttachmentToFile.d.ts.map +0 -1
- package/dist/node/attachments/writeAttachmentToFile.js +0 -73
- package/dist/node/attachments/writeAttachmentToFile.js.map +0 -1
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FULLTEXT_ATTACHMENT_FIELD = exports.DEFAULT_FULLTEXT_MAX_FIELD_BYTES = exports.FULLTEXT_INDEX_FORMAT_VERSION = exports.FULLTEXT_SETUP_FIELD = void 0;
|
|
4
|
+
exports.resolveFulltextConfig = resolveFulltextConfig;
|
|
5
|
+
exports.sanitizeFulltextConfig = sanitizeFulltextConfig;
|
|
6
|
+
exports.computeFulltextConfigFingerprint = computeFulltextConfigFingerprint;
|
|
7
|
+
/**
|
|
8
|
+
* Field of the `dbsetup` document holding the {@link FulltextConfig} used
|
|
9
|
+
* by full-text indexes that were not given an explicit configuration in
|
|
10
|
+
* code. Lives next to `summarySetup` in the same synced setup document
|
|
11
|
+
* (see docs/adhoc-queries.md and docs/fulltext-search.md).
|
|
12
|
+
*/
|
|
13
|
+
exports.FULLTEXT_SETUP_FIELD = "fulltextSetup";
|
|
14
|
+
/**
|
|
15
|
+
* Version of the persisted index format (serialization layout AND the
|
|
16
|
+
* engine/tokenizer behavior). Part of the config fingerprint, so bumping
|
|
17
|
+
* it invalidates persisted indexes and triggers a clean rebuild.
|
|
18
|
+
*/
|
|
19
|
+
exports.FULLTEXT_INDEX_FORMAT_VERSION = 3;
|
|
20
|
+
/**
|
|
21
|
+
* Default per-field cap (approximate bytes, JS string length) for text
|
|
22
|
+
* extracted into the full-text index. Longer values are truncated — not
|
|
23
|
+
* skipped — so a huge e-mail body still contributes its first part.
|
|
24
|
+
*/
|
|
25
|
+
exports.DEFAULT_FULLTEXT_MAX_FIELD_BYTES = 256 * 1024;
|
|
26
|
+
/**
|
|
27
|
+
* Synthetic index field holding text extracted from a document's
|
|
28
|
+
* attachments (via registered {@link AttachmentTextExtractor}s). Hits
|
|
29
|
+
* stay document-scoped (the Notes model): searching matches the document,
|
|
30
|
+
* not an individual attachment.
|
|
31
|
+
*/
|
|
32
|
+
exports.FULLTEXT_ATTACHMENT_FIELD = "_attachments";
|
|
33
|
+
function resolveFulltextConfig(config) {
|
|
34
|
+
return {
|
|
35
|
+
enabled: config?.enabled ?? false,
|
|
36
|
+
include: [...(config?.include ?? [])],
|
|
37
|
+
attachments: config?.attachments ?? false,
|
|
38
|
+
language: config?.language ?? "und",
|
|
39
|
+
maxFieldBytes: Math.max(0, config?.maxFieldBytes ?? exports.DEFAULT_FULLTEXT_MAX_FIELD_BYTES),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Extract a {@link FulltextConfig} from an untyped value (the
|
|
44
|
+
* `fulltextSetup` field of the synced setup document). Unknown properties
|
|
45
|
+
* are dropped and wrongly-typed ones ignored, so a malformed document can
|
|
46
|
+
* never break index maintenance. Returns `undefined` when the value is
|
|
47
|
+
* not an object (missing field, deleted document) — callers fall back to
|
|
48
|
+
* the default (disabled) configuration.
|
|
49
|
+
*/
|
|
50
|
+
function sanitizeFulltextConfig(value) {
|
|
51
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
const raw = value;
|
|
55
|
+
const config = {};
|
|
56
|
+
if (typeof raw.enabled === "boolean") {
|
|
57
|
+
config.enabled = raw.enabled;
|
|
58
|
+
}
|
|
59
|
+
if (Array.isArray(raw.include)) {
|
|
60
|
+
config.include = raw.include.filter((item) => typeof item === "string");
|
|
61
|
+
}
|
|
62
|
+
if (typeof raw.attachments === "boolean") {
|
|
63
|
+
config.attachments = raw.attachments;
|
|
64
|
+
}
|
|
65
|
+
if (typeof raw.language === "string" && raw.language.length > 0 && raw.language.length <= 35) {
|
|
66
|
+
config.language = raw.language;
|
|
67
|
+
}
|
|
68
|
+
if (typeof raw.maxFieldBytes === "number" && Number.isFinite(raw.maxFieldBytes)) {
|
|
69
|
+
config.maxFieldBytes = raw.maxFieldBytes;
|
|
70
|
+
}
|
|
71
|
+
return config;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Deterministic fingerprint of a full-text configuration, including the
|
|
75
|
+
* index format/engine version. Persisted alongside the index; a mismatch
|
|
76
|
+
* on restore (or a config change at runtime) marks the index as
|
|
77
|
+
* `"rebuilding"` and triggers a resumable backfill.
|
|
78
|
+
*/
|
|
79
|
+
function computeFulltextConfigFingerprint(config) {
|
|
80
|
+
return JSON.stringify({
|
|
81
|
+
formatVersion: exports.FULLTEXT_INDEX_FORMAT_VERSION,
|
|
82
|
+
enabled: config.enabled,
|
|
83
|
+
include: [...config.include].sort(),
|
|
84
|
+
attachments: config.attachments,
|
|
85
|
+
language: config.language,
|
|
86
|
+
maxFieldBytes: config.maxFieldBytes,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/core/indexing/fulltext/types.ts"],"names":[],"mappings":";;;AA0FA,sDAQC;AAUD,wDAsBC;AAQD,4EASC;AAjJD;;;;;GAKG;AACU,QAAA,oBAAoB,GAAG,eAAe,CAAC;AAEpD;;;;GAIG;AACU,QAAA,6BAA6B,GAAG,CAAC,CAAC;AAE/C;;;;GAIG;AACU,QAAA,gCAAgC,GAAG,GAAG,GAAG,IAAI,CAAC;AAE3D;;;;;GAKG;AACU,QAAA,yBAAyB,GAAG,cAAc,CAAC;AA4DxD,SAAgB,qBAAqB,CAAC,MAAuB;IAC3D,OAAO;QACL,OAAO,EAAE,MAAM,EAAE,OAAO,IAAI,KAAK;QACjC,OAAO,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC;QACrC,WAAW,EAAE,MAAM,EAAE,WAAW,IAAI,KAAK;QACzC,QAAQ,EAAE,MAAM,EAAE,QAAQ,IAAI,KAAK;QACnC,aAAa,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,aAAa,IAAI,wCAAgC,CAAC;KACtF,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,sBAAsB,CAAC,KAAc;IACnD,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACxE,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,GAAG,GAAG,KAAgC,CAAC;IAC7C,MAAM,MAAM,GAAmB,EAAE,CAAC;IAClC,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QACrC,MAAM,CAAC,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;IAC/B,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QAC/B,MAAM,CAAC,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,EAAkB,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC;IAC1F,CAAC;IACD,IAAI,OAAO,GAAG,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QACzC,MAAM,CAAC,WAAW,GAAG,GAAG,CAAC,WAAW,CAAC;IACvC,CAAC;IACD,IAAI,OAAO,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;QAC7F,MAAM,CAAC,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC;IACjC,CAAC;IACD,IAAI,OAAO,GAAG,CAAC,aAAa,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC;QAChF,MAAM,CAAC,aAAa,GAAG,GAAG,CAAC,aAAa,CAAC;IAC3C,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;GAKG;AACH,SAAgB,gCAAgC,CAAC,MAA8B;IAC7E,OAAO,IAAI,CAAC,SAAS,CAAC;QACpB,aAAa,EAAE,qCAA6B;QAC5C,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,OAAO,EAAE,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE;QACnC,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,aAAa,EAAE,MAAM,CAAC,aAAa;KACpC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import type { MindooDB, ProcessChangesCursor } from "../../types";
|
|
2
|
+
import type { LocalCacheStore } from "../../cache/LocalCacheStore";
|
|
3
|
+
import type { CacheManager, ICacheable } from "../../cache/CacheManager";
|
|
4
|
+
import type { VirtualViewUpdateOptions } from "../virtualviews/IVirtualViewDataProvider";
|
|
5
|
+
import type { DocumentSummaryEntry, ResolvedSummaryConfig, SummaryConfig, SummaryCoverage } from "./types";
|
|
6
|
+
/**
|
|
7
|
+
* The document summary buffer: a changefeed-maintained, per-document map of
|
|
8
|
+
* queryable field values (see docs/adhoc-queries.md).
|
|
9
|
+
*
|
|
10
|
+
* Ad-hoc queries and summary-backed views evaluate exclusively against this
|
|
11
|
+
* store, so they never pay document materialization. The store is kept
|
|
12
|
+
* up to date incrementally via `iterateChangesSince` (deleted/inaccessible
|
|
13
|
+
* documents arrive as lightweight tombstones and are removed), persists in
|
|
14
|
+
* encrypted buckets through the tenant's {@link LocalCacheStore}, and
|
|
15
|
+
* survives configuration changes with a resumable backfill instead of any
|
|
16
|
+
* document rewrite.
|
|
17
|
+
*/
|
|
18
|
+
export declare class DocumentSummaryStore implements ICacheable {
|
|
19
|
+
private readonly db;
|
|
20
|
+
private config;
|
|
21
|
+
private configFingerprint;
|
|
22
|
+
/**
|
|
23
|
+
* `true` when the configuration came from code (constructor arg or
|
|
24
|
+
* `setConfig`). Without an explicit configuration the store follows the
|
|
25
|
+
* `summarySetup` field of the synced {@link DB_SETUP_DOC_ID} document.
|
|
26
|
+
*/
|
|
27
|
+
private hasExplicitConfig;
|
|
28
|
+
/** Whether the setup document was already consulted (once per instance). */
|
|
29
|
+
private setupDocSeeded;
|
|
30
|
+
private entries;
|
|
31
|
+
private cursor;
|
|
32
|
+
private cacheManager;
|
|
33
|
+
private cachePrefix;
|
|
34
|
+
private readonly bucketCount;
|
|
35
|
+
private dirtyBuckets;
|
|
36
|
+
private metaDirty;
|
|
37
|
+
private restorePromise;
|
|
38
|
+
private restored;
|
|
39
|
+
private needsBackfill;
|
|
40
|
+
private backfillCursor;
|
|
41
|
+
private updatePromise;
|
|
42
|
+
constructor(db: MindooDB, config?: SummaryConfig);
|
|
43
|
+
getConfig(): ResolvedSummaryConfig;
|
|
44
|
+
getConfigFingerprint(): string;
|
|
45
|
+
/**
|
|
46
|
+
* Replace the summary configuration. When the fingerprint changes and
|
|
47
|
+
* entries already exist, the store keeps serving the previous state and
|
|
48
|
+
* schedules a resumable backfill that re-extracts all documents with the
|
|
49
|
+
* new configuration on the next `update()` run.
|
|
50
|
+
*
|
|
51
|
+
* Calling this marks the configuration as explicit: the store stops
|
|
52
|
+
* following the {@link DB_SETUP_DOC_ID} document.
|
|
53
|
+
*/
|
|
54
|
+
setConfig(config?: SummaryConfig): void;
|
|
55
|
+
/** Shared config-swap logic for explicit and setup-document paths. */
|
|
56
|
+
private applyConfig;
|
|
57
|
+
private scheduleBackfill;
|
|
58
|
+
/**
|
|
59
|
+
* Adopt the configuration from the synced {@link DB_SETUP_DOC_ID}
|
|
60
|
+
* document (its `summarySetup` field) unless an explicit configuration
|
|
61
|
+
* was provided in code. Runs once per instance, BEFORE the persisted
|
|
62
|
+
* state is restored, so the fingerprint comparison on restore already
|
|
63
|
+
* sees the setup-document configuration (a stale persisted fingerprint
|
|
64
|
+
* then schedules the backfill exactly once).
|
|
65
|
+
*
|
|
66
|
+
* Later changes to the setup document — local edits or sync ingest —
|
|
67
|
+
* arrive through the changefeed and are applied in `applyDocument`.
|
|
68
|
+
*/
|
|
69
|
+
private seedConfigFromSetupDoc;
|
|
70
|
+
/**
|
|
71
|
+
* Make sure the effective configuration is settled: consults the
|
|
72
|
+
* {@link DB_SETUP_DOC_ID} document once (unless the config was provided
|
|
73
|
+
* in code) and returns the resolved configuration. Callers that make
|
|
74
|
+
* decisions based on coverage (e.g. the view data-provider factory)
|
|
75
|
+
* should await this before calling {@link isFieldCovered}.
|
|
76
|
+
*/
|
|
77
|
+
ensureConfigLoaded(): Promise<ResolvedSummaryConfig>;
|
|
78
|
+
/**
|
|
79
|
+
* Whether a field path can be answered from this summary (see
|
|
80
|
+
* {@link isFieldPathCovered}). Coverage is configuration-level; individual
|
|
81
|
+
* documents may still lack a value.
|
|
82
|
+
*/
|
|
83
|
+
isFieldCovered(path: string): boolean;
|
|
84
|
+
/**
|
|
85
|
+
* `"full"` when all entries reflect the current configuration,
|
|
86
|
+
* `"rebuilding"` while a configuration-change backfill is in progress.
|
|
87
|
+
*/
|
|
88
|
+
getCoverage(): SummaryCoverage;
|
|
89
|
+
getEntry(docId: string): DocumentSummaryEntry | undefined;
|
|
90
|
+
getAllEntries(): IterableIterator<DocumentSummaryEntry>;
|
|
91
|
+
getSize(): number;
|
|
92
|
+
getCursor(): ProcessChangesCursor | null;
|
|
93
|
+
/**
|
|
94
|
+
* Bring the summary up to date with the changefeed. Restores persisted
|
|
95
|
+
* state on first use, then consumes `iterateChangesSince` from the saved
|
|
96
|
+
* cursor and finally works down a pending configuration backfill.
|
|
97
|
+
*
|
|
98
|
+
* Accepts the same batching/progress/cancellation options as VirtualView
|
|
99
|
+
* updates; an interrupted run resumes from the saved cursors.
|
|
100
|
+
* Calls are single-flight: concurrent callers share one run.
|
|
101
|
+
*/
|
|
102
|
+
update(options?: VirtualViewUpdateOptions): Promise<void>;
|
|
103
|
+
private runUpdate;
|
|
104
|
+
private applyDocument;
|
|
105
|
+
/**
|
|
106
|
+
* Drop a document's summary entry immediately (called from the DB's purge
|
|
107
|
+
* paths so plaintext field values never outlive key revocation/purges;
|
|
108
|
+
* the changefeed tombstone would remove it anyway, but only on the next
|
|
109
|
+
* update run).
|
|
110
|
+
*/
|
|
111
|
+
removeDocument(docId: string): void;
|
|
112
|
+
/** Drop all entries and cursors (e.g. after the underlying store was cleared). */
|
|
113
|
+
reset(): void;
|
|
114
|
+
/**
|
|
115
|
+
* Attach cache persistence. `cachePrefix` scopes all records of this
|
|
116
|
+
* summary (recommended: `<dbCachePrefix>/summary`). Registers with the
|
|
117
|
+
* CacheManager for periodic flushing; the persisted state is restored
|
|
118
|
+
* lazily on the first `update()` call.
|
|
119
|
+
*/
|
|
120
|
+
attachCache(cacheManager: CacheManager, cachePrefix: string): void;
|
|
121
|
+
getCachePrefix(): string;
|
|
122
|
+
hasDirtyState(): boolean;
|
|
123
|
+
clearDirty(): void;
|
|
124
|
+
private bucketIndexFor;
|
|
125
|
+
private markBucketDirty;
|
|
126
|
+
flushToCache(store: LocalCacheStore, _options?: {
|
|
127
|
+
force?: boolean;
|
|
128
|
+
}): Promise<number>;
|
|
129
|
+
private ensureRestored;
|
|
130
|
+
/**
|
|
131
|
+
* Restore persisted state. A config-fingerprint mismatch keeps the
|
|
132
|
+
* restored entries usable (extracted with the previous configuration)
|
|
133
|
+
* and schedules a backfill instead of discarding them.
|
|
134
|
+
*/
|
|
135
|
+
private restoreFromCache;
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=DocumentSummaryStore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DocumentSummaryStore.d.ts","sourceRoot":"","sources":["../../../../src/core/indexing/summary/DocumentSummaryStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,0CAA0C,CAAC;AACzF,OAAO,KAAK,EACV,oBAAoB,EACpB,qBAAqB,EAErB,aAAa,EACb,eAAe,EAEhB,MAAM,SAAS,CAAC;AAqBjB;;;;;;;;;;;GAWG;AACH,qBAAa,oBAAqB,YAAW,UAAU;IACrD,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAW;IAC9B,OAAO,CAAC,MAAM,CAAwB;IACtC,OAAO,CAAC,iBAAiB,CAAS;IAClC;;;;OAIG;IACH,OAAO,CAAC,iBAAiB,CAAU;IACnC,4EAA4E;IAC5E,OAAO,CAAC,cAAc,CAAkB;IAExC,OAAO,CAAC,OAAO,CAAgD;IAC/D,OAAO,CAAC,MAAM,CAAqC;IAGnD,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAgC;IAC5D,OAAO,CAAC,YAAY,CAA0B;IAC9C,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,cAAc,CAA8B;IACpD,OAAO,CAAC,QAAQ,CAAkB;IAGlC,OAAO,CAAC,aAAa,CAAkB;IACvC,OAAO,CAAC,cAAc,CAAqC;IAG3D,OAAO,CAAC,aAAa,CAA8B;gBAEvC,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,aAAa;IAWhD,SAAS,IAAI,qBAAqB;IAIlC,oBAAoB,IAAI,MAAM;IAI9B;;;;;;;;OAQG;IACH,SAAS,CAAC,MAAM,CAAC,EAAE,aAAa,GAAG,IAAI;IAKvC,sEAAsE;IACtE,OAAO,CAAC,WAAW;IAenB,OAAO,CAAC,gBAAgB;IAKxB;;;;;;;;;;OAUG;YACW,sBAAsB;IAiBpC;;;;;;OAMG;IACG,kBAAkB,IAAI,OAAO,CAAC,qBAAqB,CAAC;IAK1D;;;;OAIG;IACH,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIrC;;;OAGG;IACH,WAAW,IAAI,eAAe;IAQ9B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,oBAAoB,GAAG,SAAS;IAIzD,aAAa,IAAI,gBAAgB,CAAC,oBAAoB,CAAC;IAIvD,OAAO,IAAI,MAAM;IAIjB,SAAS,IAAI,oBAAoB,GAAG,IAAI;IAQxC;;;;;;;;OAQG;IACG,MAAM,CAAC,OAAO,CAAC,EAAE,wBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC;YAUjD,SAAS;IA2EvB,OAAO,CAAC,aAAa;IAuCrB;;;;;OAKG;IACH,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAOnC,kFAAkF;IAClF,KAAK,IAAI,IAAI;IAgBb;;;;;OAKG;IACH,WAAW,CAAC,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI;IAMlE,cAAc,IAAI,MAAM;IAIxB,aAAa,IAAI,OAAO;IAIxB,UAAU,IAAI,IAAI;IAKlB,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,eAAe;IAKjB,YAAY,CAAC,KAAK,EAAE,eAAe,EAAE,QAAQ,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC;YA4C7E,cAAc;IAa5B;;;;OAIG;YACW,gBAAgB;CAwD/B"}
|
|
@@ -0,0 +1,438 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DocumentSummaryStore = void 0;
|
|
4
|
+
const types_1 = require("./types");
|
|
5
|
+
const extractSummaryFields_1 = require("./extractSummaryFields");
|
|
6
|
+
const DEFAULT_BUCKET_COUNT = 64;
|
|
7
|
+
/** Simple deterministic string hash (djb2) used for bucket assignment. */
|
|
8
|
+
function hashDocId(docId) {
|
|
9
|
+
let hash = 5381;
|
|
10
|
+
for (let i = 0; i < docId.length; i++) {
|
|
11
|
+
hash = ((hash << 5) + hash + docId.charCodeAt(i)) | 0;
|
|
12
|
+
}
|
|
13
|
+
return hash >>> 0;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* The document summary buffer: a changefeed-maintained, per-document map of
|
|
17
|
+
* queryable field values (see docs/adhoc-queries.md).
|
|
18
|
+
*
|
|
19
|
+
* Ad-hoc queries and summary-backed views evaluate exclusively against this
|
|
20
|
+
* store, so they never pay document materialization. The store is kept
|
|
21
|
+
* up to date incrementally via `iterateChangesSince` (deleted/inaccessible
|
|
22
|
+
* documents arrive as lightweight tombstones and are removed), persists in
|
|
23
|
+
* encrypted buckets through the tenant's {@link LocalCacheStore}, and
|
|
24
|
+
* survives configuration changes with a resumable backfill instead of any
|
|
25
|
+
* document rewrite.
|
|
26
|
+
*/
|
|
27
|
+
class DocumentSummaryStore {
|
|
28
|
+
constructor(db, config) {
|
|
29
|
+
/** Whether the setup document was already consulted (once per instance). */
|
|
30
|
+
this.setupDocSeeded = false;
|
|
31
|
+
this.entries = new Map();
|
|
32
|
+
this.cursor = null;
|
|
33
|
+
// --- persistence state ---
|
|
34
|
+
this.cacheManager = null;
|
|
35
|
+
this.cachePrefix = null;
|
|
36
|
+
this.bucketCount = DEFAULT_BUCKET_COUNT;
|
|
37
|
+
this.dirtyBuckets = new Set();
|
|
38
|
+
this.metaDirty = false;
|
|
39
|
+
this.restorePromise = null;
|
|
40
|
+
this.restored = false;
|
|
41
|
+
// --- backfill state (config changed while entries already exist) ---
|
|
42
|
+
this.needsBackfill = false;
|
|
43
|
+
this.backfillCursor = null;
|
|
44
|
+
// --- single-flight update ---
|
|
45
|
+
this.updatePromise = null;
|
|
46
|
+
this.db = db;
|
|
47
|
+
this.hasExplicitConfig = config !== undefined;
|
|
48
|
+
this.config = (0, types_1.resolveSummaryConfig)(config);
|
|
49
|
+
this.configFingerprint = (0, types_1.computeSummaryConfigFingerprint)(this.config);
|
|
50
|
+
}
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
// Configuration
|
|
53
|
+
// ---------------------------------------------------------------------------
|
|
54
|
+
getConfig() {
|
|
55
|
+
return this.config;
|
|
56
|
+
}
|
|
57
|
+
getConfigFingerprint() {
|
|
58
|
+
return this.configFingerprint;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Replace the summary configuration. When the fingerprint changes and
|
|
62
|
+
* entries already exist, the store keeps serving the previous state and
|
|
63
|
+
* schedules a resumable backfill that re-extracts all documents with the
|
|
64
|
+
* new configuration on the next `update()` run.
|
|
65
|
+
*
|
|
66
|
+
* Calling this marks the configuration as explicit: the store stops
|
|
67
|
+
* following the {@link DB_SETUP_DOC_ID} document.
|
|
68
|
+
*/
|
|
69
|
+
setConfig(config) {
|
|
70
|
+
this.hasExplicitConfig = true;
|
|
71
|
+
this.applyConfig(config);
|
|
72
|
+
}
|
|
73
|
+
/** Shared config-swap logic for explicit and setup-document paths. */
|
|
74
|
+
applyConfig(config) {
|
|
75
|
+
const resolved = (0, types_1.resolveSummaryConfig)(config);
|
|
76
|
+
const fingerprint = (0, types_1.computeSummaryConfigFingerprint)(resolved);
|
|
77
|
+
if (fingerprint === this.configFingerprint) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
this.config = resolved;
|
|
81
|
+
this.configFingerprint = fingerprint;
|
|
82
|
+
if (this.entries.size > 0 || this.cursor !== null) {
|
|
83
|
+
this.scheduleBackfill();
|
|
84
|
+
}
|
|
85
|
+
this.metaDirty = true;
|
|
86
|
+
this.cacheManager?.markDirty();
|
|
87
|
+
}
|
|
88
|
+
scheduleBackfill() {
|
|
89
|
+
this.needsBackfill = true;
|
|
90
|
+
this.backfillCursor = null;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Adopt the configuration from the synced {@link DB_SETUP_DOC_ID}
|
|
94
|
+
* document (its `summarySetup` field) unless an explicit configuration
|
|
95
|
+
* was provided in code. Runs once per instance, BEFORE the persisted
|
|
96
|
+
* state is restored, so the fingerprint comparison on restore already
|
|
97
|
+
* sees the setup-document configuration (a stale persisted fingerprint
|
|
98
|
+
* then schedules the backfill exactly once).
|
|
99
|
+
*
|
|
100
|
+
* Later changes to the setup document — local edits or sync ingest —
|
|
101
|
+
* arrive through the changefeed and are applied in `applyDocument`.
|
|
102
|
+
*/
|
|
103
|
+
async seedConfigFromSetupDoc() {
|
|
104
|
+
if (this.setupDocSeeded || this.hasExplicitConfig) {
|
|
105
|
+
this.setupDocSeeded = true;
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
this.setupDocSeeded = true;
|
|
109
|
+
try {
|
|
110
|
+
const doc = await this.db.getDocument(types_1.DB_SETUP_DOC_ID);
|
|
111
|
+
const config = (0, types_1.sanitizeSummaryConfig)(doc.getData()[types_1.SUMMARY_SETUP_FIELD]);
|
|
112
|
+
if (config !== undefined) {
|
|
113
|
+
this.applyConfig(config);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
// No setup document (or not readable) → keep the default config.
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Make sure the effective configuration is settled: consults the
|
|
122
|
+
* {@link DB_SETUP_DOC_ID} document once (unless the config was provided
|
|
123
|
+
* in code) and returns the resolved configuration. Callers that make
|
|
124
|
+
* decisions based on coverage (e.g. the view data-provider factory)
|
|
125
|
+
* should await this before calling {@link isFieldCovered}.
|
|
126
|
+
*/
|
|
127
|
+
async ensureConfigLoaded() {
|
|
128
|
+
await this.seedConfigFromSetupDoc();
|
|
129
|
+
return this.config;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Whether a field path can be answered from this summary (see
|
|
133
|
+
* {@link isFieldPathCovered}). Coverage is configuration-level; individual
|
|
134
|
+
* documents may still lack a value.
|
|
135
|
+
*/
|
|
136
|
+
isFieldCovered(path) {
|
|
137
|
+
return (0, extractSummaryFields_1.isFieldPathCovered)(path, this.config);
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* `"full"` when all entries reflect the current configuration,
|
|
141
|
+
* `"rebuilding"` while a configuration-change backfill is in progress.
|
|
142
|
+
*/
|
|
143
|
+
getCoverage() {
|
|
144
|
+
return this.needsBackfill ? "rebuilding" : "full";
|
|
145
|
+
}
|
|
146
|
+
// ---------------------------------------------------------------------------
|
|
147
|
+
// Reads
|
|
148
|
+
// ---------------------------------------------------------------------------
|
|
149
|
+
getEntry(docId) {
|
|
150
|
+
return this.entries.get(docId);
|
|
151
|
+
}
|
|
152
|
+
getAllEntries() {
|
|
153
|
+
return this.entries.values();
|
|
154
|
+
}
|
|
155
|
+
getSize() {
|
|
156
|
+
return this.entries.size;
|
|
157
|
+
}
|
|
158
|
+
getCursor() {
|
|
159
|
+
return this.cursor;
|
|
160
|
+
}
|
|
161
|
+
// ---------------------------------------------------------------------------
|
|
162
|
+
// Incremental update
|
|
163
|
+
// ---------------------------------------------------------------------------
|
|
164
|
+
/**
|
|
165
|
+
* Bring the summary up to date with the changefeed. Restores persisted
|
|
166
|
+
* state on first use, then consumes `iterateChangesSince` from the saved
|
|
167
|
+
* cursor and finally works down a pending configuration backfill.
|
|
168
|
+
*
|
|
169
|
+
* Accepts the same batching/progress/cancellation options as VirtualView
|
|
170
|
+
* updates; an interrupted run resumes from the saved cursors.
|
|
171
|
+
* Calls are single-flight: concurrent callers share one run.
|
|
172
|
+
*/
|
|
173
|
+
async update(options) {
|
|
174
|
+
if (this.updatePromise) {
|
|
175
|
+
return this.updatePromise;
|
|
176
|
+
}
|
|
177
|
+
this.updatePromise = this.runUpdate(options).finally(() => {
|
|
178
|
+
this.updatePromise = null;
|
|
179
|
+
});
|
|
180
|
+
return this.updatePromise;
|
|
181
|
+
}
|
|
182
|
+
async runUpdate(options) {
|
|
183
|
+
await this.seedConfigFromSetupDoc();
|
|
184
|
+
await this.ensureRestored();
|
|
185
|
+
const applyBatchSize = options?.applyBatchSize ?? 100;
|
|
186
|
+
const onProgress = options?.onProgress;
|
|
187
|
+
const signal = options?.signal;
|
|
188
|
+
const countAfter = (cursor) => this.db.countChangesSince?.(cursor) ?? 0;
|
|
189
|
+
const total = onProgress
|
|
190
|
+
? countAfter(this.cursor) + (this.needsBackfill ? countAfter(this.backfillCursor) : 0)
|
|
191
|
+
: 0;
|
|
192
|
+
let processed = 0;
|
|
193
|
+
let processedInBatch = 0;
|
|
194
|
+
// Returns true when the run should stop after the current batch.
|
|
195
|
+
const stopRequested = () => {
|
|
196
|
+
const callbackStop = onProgress?.({ processed, total, origin: "summary" }) === false;
|
|
197
|
+
return callbackStop || signal?.aborted === true;
|
|
198
|
+
};
|
|
199
|
+
if (signal?.aborted) {
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
// Pass 1: incremental changefeed consumption from the main cursor.
|
|
203
|
+
for await (const { doc, cursor } of this.db.iterateChangesSince(this.cursor)) {
|
|
204
|
+
this.applyDocument(doc.getId(), doc, cursor);
|
|
205
|
+
this.cursor = cursor;
|
|
206
|
+
processed++;
|
|
207
|
+
processedInBatch++;
|
|
208
|
+
if (processedInBatch >= applyBatchSize) {
|
|
209
|
+
processedInBatch = 0;
|
|
210
|
+
this.cacheManager?.markDirty();
|
|
211
|
+
if (stopRequested()) {
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
// Pass 2: configuration backfill (re-extract everything with the new
|
|
217
|
+
// config). The feed yields each document's latest state once, so plain
|
|
218
|
+
// overwrites converge; docs changing mid-backfill are re-processed by
|
|
219
|
+
// the next pass 1 anyway.
|
|
220
|
+
if (this.needsBackfill) {
|
|
221
|
+
for await (const { doc, cursor } of this.db.iterateChangesSince(this.backfillCursor)) {
|
|
222
|
+
this.applyDocument(doc.getId(), doc, cursor);
|
|
223
|
+
this.backfillCursor = cursor;
|
|
224
|
+
processed++;
|
|
225
|
+
processedInBatch++;
|
|
226
|
+
if (processedInBatch >= applyBatchSize) {
|
|
227
|
+
processedInBatch = 0;
|
|
228
|
+
this.cacheManager?.markDirty();
|
|
229
|
+
if (stopRequested()) {
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
this.needsBackfill = false;
|
|
235
|
+
this.backfillCursor = null;
|
|
236
|
+
this.metaDirty = true;
|
|
237
|
+
}
|
|
238
|
+
this.cacheManager?.markDirty();
|
|
239
|
+
if (onProgress) {
|
|
240
|
+
onProgress({ processed, total, origin: "summary" });
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
applyDocument(docId, doc, cursor) {
|
|
244
|
+
if (docId === types_1.DB_SETUP_DOC_ID) {
|
|
245
|
+
// The setup document configures the summary instead of appearing in
|
|
246
|
+
// it. Config changes (also arriving via sync) schedule a backfill;
|
|
247
|
+
// a deleted setup document falls back to the default config.
|
|
248
|
+
if (!this.hasExplicitConfig) {
|
|
249
|
+
const config = doc.isDeleted()
|
|
250
|
+
? undefined
|
|
251
|
+
: (0, types_1.sanitizeSummaryConfig)(doc.getData()[types_1.SUMMARY_SETUP_FIELD]);
|
|
252
|
+
this.applyConfig(config);
|
|
253
|
+
}
|
|
254
|
+
// Drop a stale entry left over from before the setup doc was skipped.
|
|
255
|
+
if (this.entries.delete(docId)) {
|
|
256
|
+
this.markBucketDirty(docId);
|
|
257
|
+
}
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
if (doc.isDeleted()) {
|
|
261
|
+
if (this.entries.delete(docId)) {
|
|
262
|
+
this.markBucketDirty(docId);
|
|
263
|
+
}
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
this.entries.set(docId, {
|
|
267
|
+
docId,
|
|
268
|
+
fields: (0, extractSummaryFields_1.extractSummaryFields)(doc.getData(), this.config),
|
|
269
|
+
lastModified: doc.getLastModified(),
|
|
270
|
+
changeSeq: cursor.changeSeq ?? 0,
|
|
271
|
+
decryptionKeyId: doc.getDecryptionKeyId(),
|
|
272
|
+
});
|
|
273
|
+
this.markBucketDirty(docId);
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Drop a document's summary entry immediately (called from the DB's purge
|
|
277
|
+
* paths so plaintext field values never outlive key revocation/purges;
|
|
278
|
+
* the changefeed tombstone would remove it anyway, but only on the next
|
|
279
|
+
* update run).
|
|
280
|
+
*/
|
|
281
|
+
removeDocument(docId) {
|
|
282
|
+
if (this.entries.delete(docId)) {
|
|
283
|
+
this.markBucketDirty(docId);
|
|
284
|
+
this.cacheManager?.markDirty();
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
/** Drop all entries and cursors (e.g. after the underlying store was cleared). */
|
|
288
|
+
reset() {
|
|
289
|
+
this.entries.clear();
|
|
290
|
+
this.cursor = null;
|
|
291
|
+
this.needsBackfill = false;
|
|
292
|
+
this.backfillCursor = null;
|
|
293
|
+
for (let i = 0; i < this.bucketCount; i++) {
|
|
294
|
+
this.dirtyBuckets.add(i);
|
|
295
|
+
}
|
|
296
|
+
this.metaDirty = true;
|
|
297
|
+
this.cacheManager?.markDirty();
|
|
298
|
+
}
|
|
299
|
+
// ---------------------------------------------------------------------------
|
|
300
|
+
// Persistence (ICacheable)
|
|
301
|
+
// ---------------------------------------------------------------------------
|
|
302
|
+
/**
|
|
303
|
+
* Attach cache persistence. `cachePrefix` scopes all records of this
|
|
304
|
+
* summary (recommended: `<dbCachePrefix>/summary`). Registers with the
|
|
305
|
+
* CacheManager for periodic flushing; the persisted state is restored
|
|
306
|
+
* lazily on the first `update()` call.
|
|
307
|
+
*/
|
|
308
|
+
attachCache(cacheManager, cachePrefix) {
|
|
309
|
+
this.cacheManager = cacheManager;
|
|
310
|
+
this.cachePrefix = cachePrefix;
|
|
311
|
+
cacheManager.register(this);
|
|
312
|
+
}
|
|
313
|
+
getCachePrefix() {
|
|
314
|
+
return this.cachePrefix ?? "summary";
|
|
315
|
+
}
|
|
316
|
+
hasDirtyState() {
|
|
317
|
+
return this.dirtyBuckets.size > 0 || this.metaDirty;
|
|
318
|
+
}
|
|
319
|
+
clearDirty() {
|
|
320
|
+
this.dirtyBuckets.clear();
|
|
321
|
+
this.metaDirty = false;
|
|
322
|
+
}
|
|
323
|
+
bucketIndexFor(docId) {
|
|
324
|
+
return hashDocId(docId) % this.bucketCount;
|
|
325
|
+
}
|
|
326
|
+
markBucketDirty(docId) {
|
|
327
|
+
this.dirtyBuckets.add(this.bucketIndexFor(docId));
|
|
328
|
+
this.metaDirty = true;
|
|
329
|
+
}
|
|
330
|
+
async flushToCache(store, _options) {
|
|
331
|
+
const prefix = this.getCachePrefix();
|
|
332
|
+
let written = 0;
|
|
333
|
+
if (this.dirtyBuckets.size > 0) {
|
|
334
|
+
// Group entries by bucket once, then rewrite only dirty buckets.
|
|
335
|
+
const byBucket = new Map();
|
|
336
|
+
for (const entry of this.entries.values()) {
|
|
337
|
+
const bucket = this.bucketIndexFor(entry.docId);
|
|
338
|
+
if (!this.dirtyBuckets.has(bucket)) {
|
|
339
|
+
continue;
|
|
340
|
+
}
|
|
341
|
+
let list = byBucket.get(bucket);
|
|
342
|
+
if (!list) {
|
|
343
|
+
list = [];
|
|
344
|
+
byBucket.set(bucket, list);
|
|
345
|
+
}
|
|
346
|
+
list.push(entry);
|
|
347
|
+
}
|
|
348
|
+
for (const bucket of this.dirtyBuckets) {
|
|
349
|
+
const payload = { entries: byBucket.get(bucket) ?? [] };
|
|
350
|
+
await store.put("summary", `${prefix}/bucket/${bucket}`, new TextEncoder().encode(JSON.stringify(payload)));
|
|
351
|
+
written++;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
const meta = {
|
|
355
|
+
cursor: this.cursor,
|
|
356
|
+
configFingerprint: this.configFingerprint,
|
|
357
|
+
bucketCount: this.bucketCount,
|
|
358
|
+
needsBackfill: this.needsBackfill,
|
|
359
|
+
backfillCursor: this.backfillCursor,
|
|
360
|
+
};
|
|
361
|
+
await store.put("summary", `${prefix}/meta`, new TextEncoder().encode(JSON.stringify(meta)));
|
|
362
|
+
written++;
|
|
363
|
+
return written;
|
|
364
|
+
}
|
|
365
|
+
async ensureRestored() {
|
|
366
|
+
if (this.restored || !this.cacheManager) {
|
|
367
|
+
this.restored = true;
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
if (!this.restorePromise) {
|
|
371
|
+
this.restorePromise = this.restoreFromCache().finally(() => {
|
|
372
|
+
this.restored = true;
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
return this.restorePromise;
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* Restore persisted state. A config-fingerprint mismatch keeps the
|
|
379
|
+
* restored entries usable (extracted with the previous configuration)
|
|
380
|
+
* and schedules a backfill instead of discarding them.
|
|
381
|
+
*/
|
|
382
|
+
async restoreFromCache() {
|
|
383
|
+
const store = this.cacheManager?.getStore();
|
|
384
|
+
if (!store) {
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
const prefix = this.getCachePrefix();
|
|
388
|
+
let meta;
|
|
389
|
+
try {
|
|
390
|
+
const metaBytes = await store.get("summary", `${prefix}/meta`);
|
|
391
|
+
if (!metaBytes) {
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
meta = JSON.parse(new TextDecoder().decode(metaBytes));
|
|
395
|
+
}
|
|
396
|
+
catch {
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
const bucketCount = meta.bucketCount ?? DEFAULT_BUCKET_COUNT;
|
|
400
|
+
const bucketIds = [];
|
|
401
|
+
for (let i = 0; i < bucketCount; i++) {
|
|
402
|
+
bucketIds.push(`${prefix}/bucket/${i}`);
|
|
403
|
+
}
|
|
404
|
+
try {
|
|
405
|
+
const buckets = await store.getMany("summary", bucketIds);
|
|
406
|
+
for (const bytes of buckets) {
|
|
407
|
+
if (!bytes) {
|
|
408
|
+
continue;
|
|
409
|
+
}
|
|
410
|
+
const payload = JSON.parse(new TextDecoder().decode(bytes));
|
|
411
|
+
for (const entry of payload.entries ?? []) {
|
|
412
|
+
this.entries.set(entry.docId, entry);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
catch {
|
|
417
|
+
// A corrupt bucket only loses cached summaries; the changefeed
|
|
418
|
+
// rebuild below restores correctness.
|
|
419
|
+
this.entries.clear();
|
|
420
|
+
this.cursor = null;
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
this.cursor = meta.cursor ?? null;
|
|
424
|
+
if (meta.configFingerprint !== this.configFingerprint) {
|
|
425
|
+
// Entries were extracted with a different configuration: keep them
|
|
426
|
+
// usable, re-extract everything in the background.
|
|
427
|
+
this.scheduleBackfill();
|
|
428
|
+
this.metaDirty = true;
|
|
429
|
+
}
|
|
430
|
+
else if (meta.needsBackfill) {
|
|
431
|
+
// Resume an interrupted backfill where it left off.
|
|
432
|
+
this.needsBackfill = true;
|
|
433
|
+
this.backfillCursor = meta.backfillCursor ?? null;
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
exports.DocumentSummaryStore = DocumentSummaryStore;
|
|
438
|
+
//# sourceMappingURL=DocumentSummaryStore.js.map
|