diff --git a/lib/reducers/message-reducer.test.js b/lib/reducers/message-reducer.test.js --- a/lib/reducers/message-reducer.test.js +++ b/lib/reducers/message-reducer.test.js @@ -297,6 +297,7 @@ syncedMetadata: {}, auxUserInfos: {}, threadActivityStore: {}, + entries: {}, }, }, { diff --git a/lib/types/store-ops-types.js b/lib/types/store-ops-types.js --- a/lib/types/store-ops-types.js +++ b/lib/types/store-ops-types.js @@ -7,6 +7,7 @@ ClientDBDraftStoreOperation, ClientDBDraftInfo, } from './draft-types.js'; +import type { RawEntryInfos } from './entry-types.js'; import type { ThreadHashes } from './integrity-types.js'; import type { KeyserverInfos } from './keyserver-types.js'; import type { @@ -29,6 +30,11 @@ ClientDBCommunityStoreOperation, CommunityStoreOperation, } from '../ops/community-store-ops.js'; +import type { + ClientDBEntryInfo, + EntryStoreOperation, + ClientDBEntryStoreOperation, +} from '../ops/entries-store-ops.js'; import type { ClientDBIntegrityThreadHash, ClientDBIntegrityStoreOperation, @@ -80,6 +86,7 @@ +auxUserStoreOperations?: $ReadOnlyArray, +threadActivityStoreOperations?: $ReadOnlyArray, +outboundP2PMessages?: $ReadOnlyArray, + +entryStoreOperations?: $ReadOnlyArray, }; export type ClientDBStoreOperations = { @@ -95,6 +102,7 @@ +auxUserStoreOperations?: $ReadOnlyArray, +threadActivityStoreOperations?: $ReadOnlyArray, +outboundP2PMessages?: $ReadOnlyArray, + +entryStoreOperations?: $ReadOnlyArray, }; export type ClientDBStore = { @@ -110,6 +118,7 @@ +syncedMetadata: $ReadOnlyArray, +auxUserInfos: $ReadOnlyArray, +threadActivityEntries: $ReadOnlyArray, + +entries: $ReadOnlyArray, }; export type ClientStore = { @@ -126,4 +135,5 @@ +syncedMetadata: ?SyncedMetadata, +auxUserInfos: ?AuxUserInfos, +threadActivityStore: ?ThreadActivityStore, + +entries: ?RawEntryInfos, }; diff --git a/native/data/sqlite-data-handler.js b/native/data/sqlite-data-handler.js --- a/native/data/sqlite-data-handler.js +++ b/native/data/sqlite-data-handler.js @@ -10,6 +10,7 @@ import { useKeyserverRecoveryLogIn } from 'lib/keyserver-conn/recovery-utils.js'; import { auxUserStoreOpsHandlers } from 'lib/ops/aux-user-store-ops.js'; import { communityStoreOpsHandlers } from 'lib/ops/community-store-ops.js'; +import { entryStoreOpsHandlers } from 'lib/ops/entries-store-ops.js'; import { integrityStoreOpsHandlers } from 'lib/ops/integrity-store-ops.js'; import { keyserverStoreOpsHandlers } from 'lib/ops/keyserver-store-ops.js'; import { reportStoreOpsHandlers } from 'lib/ops/report-store-ops.js'; @@ -242,6 +243,7 @@ syncedMetadata, auxUserInfos, threadActivityEntries, + entries, } = await commCoreModule.getClientDBStore(); const threadInfosFromDB = threadStoreOpsHandlers.translateClientDBData(threads); @@ -264,6 +266,8 @@ threadActivityStoreOpsHandlers.translateClientDBData( threadActivityEntries, ); + const entriesFromDB = + entryStoreOpsHandlers.translateClientDBData(entries); dispatch({ type: setClientDBStoreActionType, payload: { @@ -280,6 +284,7 @@ syncedMetadata: syncedMetadataFromDB, auxUserInfos: auxUserInfosFromDB, threadActivityStore: threadActivityStoreFromDB, + entries: entriesFromDB, }, }); } catch (setStoreException) { diff --git a/native/redux/redux-utils.js b/native/redux/redux-utils.js --- a/native/redux/redux-utils.js +++ b/native/redux/redux-utils.js @@ -4,6 +4,7 @@ import { auxUserStoreOpsHandlers } from 'lib/ops/aux-user-store-ops.js'; import { communityStoreOpsHandlers } from 'lib/ops/community-store-ops.js'; +import { entryStoreOpsHandlers } from 'lib/ops/entries-store-ops.js'; import { integrityStoreOpsHandlers } from 'lib/ops/integrity-store-ops.js'; import { keyserverStoreOpsHandlers, @@ -45,6 +46,7 @@ auxUserStoreOperations, threadActivityStoreOperations, outboundP2PMessages, + entryStoreOperations, } = storeOperations; const convertedThreadStoreOperations = @@ -73,6 +75,8 @@ threadActivityStoreOpsHandlers.convertOpsToClientDBOps( threadActivityStoreOperations, ); + const convertedEntryStoreOperations = + entryStoreOpsHandlers.convertOpsToClientDBOps(entryStoreOperations); try { const promises = []; @@ -97,6 +101,7 @@ auxUserStoreOperations: convertedAuxUserStoreOperations, threadActivityStoreOperations: convertedThreadActivityStoreOperations, outboundP2PMessages, + entryStoreOperations: convertedEntryStoreOperations, }; if (values(dbOps).some(ops => ops && ops.length > 0)) { promises.push(commCoreModule.processDBStoreOperations(dbOps)); diff --git a/web/shared-worker/utils/store.js b/web/shared-worker/utils/store.js --- a/web/shared-worker/utils/store.js +++ b/web/shared-worker/utils/store.js @@ -2,6 +2,7 @@ import { auxUserStoreOpsHandlers } from 'lib/ops/aux-user-store-ops.js'; import { communityStoreOpsHandlers } from 'lib/ops/community-store-ops.js'; +import { entryStoreOpsHandlers } from 'lib/ops/entries-store-ops.js'; import { integrityStoreOpsHandlers } from 'lib/ops/integrity-store-ops.js'; import { keyserverStoreOpsHandlers } from 'lib/ops/keyserver-store-ops.js'; import { messageStoreOpsHandlers } from 'lib/ops/message-store-ops.js'; @@ -37,6 +38,7 @@ syncedMetadata: null, auxUserInfos: null, threadActivityStore: null, + entries: null, }; const data = await sharedWorker.schedule({ type: workerRequestMessageTypes.GET_CLIENT_STORE, @@ -135,6 +137,13 @@ ), }; } + + if (data?.store?.entries && data.store.entries.length > 0) { + result = { + ...result, + entries: entryStoreOpsHandlers.translateClientDBData(data.store.entries), + }; + } return result; } @@ -155,6 +164,7 @@ messageStoreOperations, threadActivityStoreOperations, outboundP2PMessages, + entryStoreOperations, } = storeOperations; const canUseDatabase = canUseDatabaseOnWeb(userID); @@ -184,6 +194,8 @@ threadActivityStoreOpsHandlers.convertOpsToClientDBOps( threadActivityStoreOperations, ); + const convertedEntryStoreOperations = + entryStoreOpsHandlers.convertOpsToClientDBOps(entryStoreOperations); if ( convertedThreadStoreOperations.length === 0 && @@ -196,7 +208,8 @@ convertedAuxUserStoreOperations.length === 0 && convertedUserStoreOperations.length === 0 && convertedMessageStoreOperations.length === 0 && - convertedThreadActivityStoreOperations.length === 0 + convertedThreadActivityStoreOperations.length === 0 && + convertedEntryStoreOperations.length === 0 ) { return; } @@ -222,6 +235,7 @@ messageStoreOperations: convertedMessageStoreOperations, threadActivityStoreOperations: convertedThreadActivityStoreOperations, outboundP2PMessages, + entryStoreOperations: convertedEntryStoreOperations, }, }); } catch (e) { diff --git a/web/shared-worker/worker/process-operations.js b/web/shared-worker/worker/process-operations.js --- a/web/shared-worker/worker/process-operations.js +++ b/web/shared-worker/worker/process-operations.js @@ -2,6 +2,7 @@ import type { ClientDBAuxUserStoreOperation } from 'lib/ops/aux-user-store-ops.js'; import type { ClientDBCommunityStoreOperation } from 'lib/ops/community-store-ops.js'; +import type { ClientDBEntryStoreOperation } from 'lib/ops/entries-store-ops.js'; import type { ClientDBIntegrityStoreOperation } from 'lib/ops/integrity-store-ops.js'; import type { ClientDBKeyserverStoreOperation } from 'lib/ops/keyserver-store-ops.js'; import type { ClientDBMessageStoreOperation } from 'lib/ops/message-store-ops.js'; @@ -363,6 +364,7 @@ messageStoreOperations, threadActivityStoreOperations, outboundP2PMessages, + entryStoreOperations, } = storeOperations; try { @@ -453,6 +455,13 @@ if (outboundP2PMessages && outboundP2PMessages.length > 0) { sqliteQueryExecutor.addOutboundP2PMessages(outboundP2PMessages); } + if (entryStoreOperations && entryStoreOperations.length > 0) { + processEntryStoreOperations( + sqliteQueryExecutor, + entryStoreOperations, + module, + ); + } sqliteQueryExecutor.commitTransaction(); } catch (e) { sqliteQueryExecutor.rollbackTransaction(); @@ -526,6 +535,37 @@ } } +function processEntryStoreOperations( + sqliteQueryExecutor: SQLiteQueryExecutor, + operations: $ReadOnlyArray, + module: EmscriptenModule, +) { + for (const operation: ClientDBEntryStoreOperation of operations) { + try { + if (operation.type === 'remove_all_entries') { + sqliteQueryExecutor.removeAllEntries(); + } else if (operation.type === 'remove_entries') { + const { ids } = operation.payload; + sqliteQueryExecutor.removeEntries(ids); + } else if (operation.type === 'replace_entry') { + const { id, entry } = operation.payload; + sqliteQueryExecutor.replaceEntry({ id, entry }); + } else { + throw new Error('Unsupported thread activity operation'); + } + } catch (e) { + throw new Error( + `Error while processing ${ + operation.type + } entry store operation: ${getProcessingStoreOpsExceptionMessage( + e, + module, + )}`, + ); + } + } +} + function getClientStoreFromQueryExecutor( sqliteQueryExecutor: SQLiteQueryExecutor, ): ClientDBStore { @@ -551,6 +591,7 @@ syncedMetadata: sqliteQueryExecutor.getAllSyncedMetadata(), auxUserInfos: sqliteQueryExecutor.getAllAuxUserInfos(), threadActivityEntries: sqliteQueryExecutor.getAllThreadActivityEntries(), + entries: sqliteQueryExecutor.getAllEntries(), }; }