diff --git a/lib/ops/holder-store-ops.js b/lib/ops/holder-store-ops.js new file mode 100644 --- /dev/null +++ b/lib/ops/holder-store-ops.js @@ -0,0 +1,87 @@ +// @flow + +import { type BaseStoreOpsHandlers } from './base-ops.js'; +import type { + HolderStore, + HolderItem, + ClientDBHolderItem, + StoredHolders, +} from '../types/holder-types.js'; +import { assertHolderStatus } from '../types/holder-types.js'; + +export type RemoveHoldersOperation = { + +type: 'remove_holders', + +payload: { +hashes: $ReadOnlyArray }, +}; + +export type ReplaceHoldersOperation = { + +type: 'replace_holders', + +payload: { +items: $ReadOnlyArray }, +}; + +export type HolderStoreOperation = + | RemoveHoldersOperation + | ReplaceHoldersOperation; + +export type ReplaceClientDBHoldersOperation = { + +type: 'replace_holders', + +payload: { +items: $ReadOnlyArray }, +}; + +export type ClientDBHolderStoreOperation = + | RemoveHoldersOperation + | ReplaceClientDBHoldersOperation; + +export const holderStoreOpsHandlers: BaseStoreOpsHandlers< + HolderStore, + HolderStoreOperation, + ClientDBHolderStoreOperation, + StoredHolders, + ClientDBHolderItem, +> = { + processStoreOperations( + store: HolderStore, + ops: $ReadOnlyArray, + ): HolderStore { + if (ops.length === 0) { + return store; + } + const processedHolders = { ...store.storedHolders }; + for (const operation of ops) { + if (operation.type === 'replace_holders') { + const { items } = operation.payload; + for (const holderItem of items) { + processedHolders[holderItem.hash] = { + holder: holderItem.holder, + status: holderItem.status, + }; + } + } else if (operation.type === 'remove_holders') { + for (const hash of operation.payload.hashes) { + delete processedHolders[hash]; + } + } + } + return { ...store, storedHolders: processedHolders }; + }, + + convertOpsToClientDBOps( + ops: ?$ReadOnlyArray, + ): $ReadOnlyArray { + return ops ?? []; + }, + + translateClientDBData( + data: $ReadOnlyArray, + ): StoredHolders { + return Object.fromEntries( + data.map((holderItem: ClientDBHolderItem) => [ + holderItem.hash, + { + holder: holderItem.holder, + status: assertHolderStatus(holderItem.status), + }, + ]), + ); + }, +}; 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 @@ -299,6 +299,7 @@ threadActivityStore: {}, entries: {}, messageStoreLocalMessageInfos: {}, + holders: {}, }, }, { diff --git a/lib/shared/redux/client-db-utils.js b/lib/shared/redux/client-db-utils.js --- a/lib/shared/redux/client-db-utils.js +++ b/lib/shared/redux/client-db-utils.js @@ -7,6 +7,7 @@ import { createReplaceThreadOperation } from '../../ops/create-replace-thread-operation.js'; import { convertDMOperationOpsToClientDBOps } from '../../ops/dm-operations-store-ops.js'; import { entryStoreOpsHandlers } from '../../ops/entries-store-ops.js'; +import { holderStoreOpsHandlers } from '../../ops/holder-store-ops.js'; import { integrityStoreOpsHandlers } from '../../ops/integrity-store-ops.js'; import { keyserverStoreOpsHandlers } from '../../ops/keyserver-store-ops.js'; import { messageStoreOpsHandlers } from '../../ops/message-store-ops.js'; @@ -73,6 +74,7 @@ entryStoreOperations, messageSearchStoreOperations, dmOperationStoreOperations, + holderStoreOperations, } = storeOperations; const convertedThreadStoreOperations = @@ -103,6 +105,8 @@ entryStoreOpsHandlers.convertOpsToClientDBOps(entryStoreOperations); const convertedDMOperationStoreOperations = convertDMOperationOpsToClientDBOps(dmOperationStoreOperations); + const convertedHolderStoreOperations = + holderStoreOpsHandlers.convertOpsToClientDBOps(holderStoreOperations); return { draftStoreOperations: draftStoreOperations, @@ -120,6 +124,7 @@ entryStoreOperations: convertedEntryStoreOperations, messageSearchStoreOperations, dmOperationStoreOperations: convertedDMOperationStoreOperations, + holderStoreOperations: convertedHolderStoreOperations, }; } diff --git a/lib/types/holder-types.js b/lib/types/holder-types.js --- a/lib/types/holder-types.js +++ b/lib/types/holder-types.js @@ -28,10 +28,12 @@ +status: HolderStatus, }; +export type StoredHolders = { + +[blobHash: string]: HolderInfo, +}; + export type HolderStore = { - +storedHolders: { - +[blobHash: string]: HolderInfo, - }, + +storedHolders: StoredHolders, }; export type BlobOperation = { @@ -44,6 +46,12 @@ +holder: string, }; +export type HolderItem = { + +hash: string, + +holder: string, + +status: HolderStatus, +}; + export type ClientDBHolderItem = { +hash: string, +holder: string, 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 @@ -8,6 +8,7 @@ ClientDBDraftInfo, } from './draft-types.js'; import type { RawEntryInfos } from './entry-types.js'; +import type { ClientDBHolderItem, StoredHolders } from './holder-types.js'; import type { ThreadHashes } from './integrity-types.js'; import type { KeyserverInfos } from './keyserver-types.js'; import type { @@ -46,6 +47,10 @@ EntryStoreOperation, ClientDBEntryStoreOperation, } from '../ops/entries-store-ops.js'; +import type { + HolderStoreOperation, + ClientDBHolderStoreOperation, +} from '../ops/holder-store-ops.js'; import type { ClientDBIntegrityThreadHash, ClientDBIntegrityStoreOperation, @@ -100,6 +105,7 @@ +entryStoreOperations?: $ReadOnlyArray, +messageSearchStoreOperations?: $ReadOnlyArray, +dmOperationStoreOperations?: $ReadOnlyArray, + +holderStoreOperations?: $ReadOnlyArray, }; export type ClientDBStoreOperations = { @@ -118,6 +124,7 @@ +entryStoreOperations?: $ReadOnlyArray, +messageSearchStoreOperations?: $ReadOnlyArray, +dmOperationStoreOperations?: $ReadOnlyArray, + +holderStoreOperations?: $ReadOnlyArray, }; export type ClientDBStore = { @@ -136,6 +143,7 @@ +entries: $ReadOnlyArray, +messageStoreLocalMessageInfos: $ReadOnlyArray, +dmOperations: $ReadOnlyArray, + +holders: $ReadOnlyArray, }; export type ClientStore = { @@ -154,4 +162,5 @@ +threadActivityStore: ?ThreadActivityStore, +entries: ?RawEntryInfos, +messageStoreLocalMessageInfos: ?MessageStoreLocalMessageInfos, + +holders: ?StoredHolders, }; diff --git a/native/database/store.js b/native/database/store.js --- a/native/database/store.js +++ b/native/database/store.js @@ -3,6 +3,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 { holderStoreOpsHandlers } from 'lib/ops/holder-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'; @@ -35,6 +36,7 @@ threadActivityEntries, entries, messageStoreLocalMessageInfos, + holders, } = await commCoreModule.getClientDBStore(dbID); const threadInfosFromDB = threadStoreOpsHandlers.translateClientDBData(threads); @@ -57,6 +59,7 @@ const localMessageInfosFromDB = translateClientDBLocalMessageInfos( messageStoreLocalMessageInfos, ); + const holdersFromDB = holderStoreOpsHandlers.translateClientDBData(holders); return { drafts, @@ -74,6 +77,7 @@ threadActivityStore: threadActivityStoreFromDB, entries: entriesFromDB, messageStoreLocalMessageInfos: localMessageInfosFromDB, + holders: holdersFromDB, }; } diff --git a/web/database/store.js b/web/database/store.js --- a/web/database/store.js +++ b/web/database/store.js @@ -3,6 +3,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 { holderStoreOpsHandlers } from 'lib/ops/holder-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'; @@ -39,6 +40,7 @@ threadActivityStore: null, entries: null, messageStoreLocalMessageInfos: null, + holders: null, }; const data = await sharedWorker.schedule({ type: workerRequestMessageTypes.GET_CLIENT_STORE, @@ -157,6 +159,14 @@ ), }; } + + if (data?.store?.holders && data.store.holders.length > 0) { + result = { + ...result, + holders: holderStoreOpsHandlers.translateClientDBData(data.store.holders), + }; + } + return result; } 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 @@ -701,6 +701,7 @@ messageStoreLocalMessageInfos: sqliteQueryExecutor.getAllMessageStoreLocalMessageInfos(), dmOperations: sqliteQueryExecutor.getAllDMOperations(), + holders: sqliteQueryExecutor.getHolders(), }; }