diff --git a/lib/shared/redux/client-db-utils.js b/lib/shared/redux/client-db-utils.js index 8a4ca3e17..2b389746b 100644 --- a/lib/shared/redux/client-db-utils.js +++ b/lib/shared/redux/client-db-utils.js @@ -1,57 +1,101 @@ // @flow import _keyBy from 'lodash/fp/keyBy.js'; import { threadStoreOpsHandlers, type ClientDBThreadStoreOperation, type ReplaceThreadOperation, type ThreadStoreOperation, } from '../../ops/thread-store-ops.js'; -import type { RawThreadInfos, ThreadStore } from '../../types/thread-types.js'; -import { entries } from '../../utils/objects.js'; +import type { + RawThreadInfos, + ThreadStore, + ClientDBThreadInfo, +} from '../../types/thread-types.js'; +import { entries, values } from '../../utils/objects.js'; +import { + convertClientDBThreadInfoToRawThreadInfo, + convertRawThreadInfoToClientDBThreadInfo, +} from '../../utils/thread-ops-utils.js'; function updateThreadStoreThreadInfos( threadStore: ThreadStore, migrationFunc: RawThreadInfos => RawThreadInfos, ): { +newThreadStore: ThreadStore, +dbOperations: $ReadOnlyArray, } { const rawThreadInfos = threadStore.threadInfos; // 1. Convert `RawThreadInfo`s to a map of `threadID` => `threadInfo`. const keyedRawThreadInfos = _keyBy('id')(rawThreadInfos); // 2. Apply `migrationFunc` to `ThreadInfo`s. const updatedKeyedRawThreadInfos = migrationFunc(keyedRawThreadInfos); // 3. Construct `replace` `ThreadStoreOperation`s. const replaceOps: $ReadOnlyArray = entries( updatedKeyedRawThreadInfos, ).map(([id, threadInfo]) => ({ type: 'replace', payload: { id, threadInfo }, })); // 4. Prepend `replaceOps` with `remove_all` ops const operations: $ReadOnlyArray = [ { type: 'remove_all' }, ...replaceOps, ]; // 5. Process `ThreadStoreOperation`s to get new `ThreadStore`. const newThreadStore: ThreadStore = threadStoreOpsHandlers.processStoreOperations(threadStore, operations); // 6. Convert `ThreadStoreOperation`s to `ClientDBThreadStoreOperation`s. const dbOperations: $ReadOnlyArray = threadStoreOpsHandlers.convertOpsToClientDBOps(operations); return { newThreadStore, dbOperations, }; } -export { updateThreadStoreThreadInfos }; +function createUpdateDBOpsForThreadStoreThreadInfos( + clientDBThreadInfos: $ReadOnlyArray, + migrationFunc: RawThreadInfos => RawThreadInfos, +): $ReadOnlyArray { + // 1. Translate `ClientDBThreadInfo`s to `RawThreadInfo`s. + const rawThreadInfos = clientDBThreadInfos.map( + convertClientDBThreadInfoToRawThreadInfo, + ); + + // 2. Convert `RawThreadInfo`s to a map of `threadID` => `threadInfo`. + const keyedRawThreadInfos = _keyBy('id')(rawThreadInfos); + + // 3. Apply `migrationFunc` to `ThreadInfo`s. + const updatedKeyedRawThreadInfos = migrationFunc(keyedRawThreadInfos); + + // 4. Convert the updated `RawThreadInfos` back into an array. + const updatedKeyedRawThreadInfosArray = values(updatedKeyedRawThreadInfos); + + // 5. Translate `RawThreadInfo`s back to `ClientDBThreadInfo`s. + const updatedClientDBThreadInfos = updatedKeyedRawThreadInfosArray.map( + convertRawThreadInfoToClientDBThreadInfo, + ); + + // 6. Construct `replace` `ClientDBThreadStoreOperation`s. + const replaceThreadOperations = updatedClientDBThreadInfos.map(thread => ({ + type: 'replace', + payload: thread, + })); + + // 7. Prepend `replaceThreadOperations` with `remove_all` op and return. + return [{ type: 'remove_all' }, ...replaceThreadOperations]; +} + +export { + updateThreadStoreThreadInfos, + createUpdateDBOpsForThreadStoreThreadInfos, +}; diff --git a/native/redux/client-db-utils.js b/native/redux/client-db-utils.js index 2368fd3c2..45c3fee80 100644 --- a/native/redux/client-db-utils.js +++ b/native/redux/client-db-utils.js @@ -1,146 +1,104 @@ // @flow -import _keyBy from 'lodash/fp/keyBy.js'; - import type { ClientDBMessageStoreOperation } from 'lib/ops/message-store-ops.js'; -import type { ClientDBThreadStoreOperation } from 'lib/ops/thread-store-ops.js'; +import { createUpdateDBOpsForThreadStoreThreadInfos } from 'lib/shared/redux/client-db-utils.js'; import type { RawMessageInfo, ClientDBMessageInfo, ClientDBThreadMessageInfo, } from 'lib/types/message-types.js'; -import type { - ClientDBThreadInfo, - RawThreadInfos, -} from 'lib/types/thread-types.js'; +import type { RawThreadInfos } from 'lib/types/thread-types.js'; import { translateClientDBMessageInfoToRawMessageInfo, translateRawMessageInfoToClientDBMessageInfo, translateClientDBThreadMessageInfos, translateThreadMessageInfoToClientDBThreadMessageInfo, type TranslatedThreadMessageInfos, } from 'lib/utils/message-ops-utils.js'; -import { entries, values } from 'lib/utils/objects.js'; -import { - convertClientDBThreadInfoToRawThreadInfo, - convertRawThreadInfoToClientDBThreadInfo, -} from 'lib/utils/thread-ops-utils.js'; +import { entries } from 'lib/utils/objects.js'; import type { AppState } from './state-types.js'; import { commCoreModule } from '../native-modules.js'; function updateClientDBThreadStoreThreadInfos( state: AppState, migrationFunc: RawThreadInfos => RawThreadInfos, handleMigrationFailure?: AppState => AppState, ): AppState { const clientDBThreadInfos = commCoreModule.getAllThreadsSync(); const operations = createUpdateDBOpsForThreadStoreThreadInfos( clientDBThreadInfos, migrationFunc, ); try { commCoreModule.processThreadStoreOperationsSync(operations); } catch (exception) { console.log(exception); if (handleMigrationFailure) { return handleMigrationFailure(state); } return ({ ...state, cookie: null }: any); } return state; } -function createUpdateDBOpsForThreadStoreThreadInfos( - clientDBThreadInfos: $ReadOnlyArray, - migrationFunc: RawThreadInfos => RawThreadInfos, -): $ReadOnlyArray { - // 1. Translate `ClientDBThreadInfo`s to `RawThreadInfo`s. - const rawThreadInfos = clientDBThreadInfos.map( - convertClientDBThreadInfoToRawThreadInfo, - ); - - // 2. Convert `RawThreadInfo`s to a map of `threadID` => `threadInfo`. - const keyedRawThreadInfos = _keyBy('id')(rawThreadInfos); - - // 3. Apply `migrationFunc` to `ThreadInfo`s. - const updatedKeyedRawThreadInfos = migrationFunc(keyedRawThreadInfos); - - // 4. Convert the updated `RawThreadInfos` back into an array. - const updatedKeyedRawThreadInfosArray = values(updatedKeyedRawThreadInfos); - - // 5. Translate `RawThreadInfo`s back to `ClientDBThreadInfo`s. - const updatedClientDBThreadInfos = updatedKeyedRawThreadInfosArray.map( - convertRawThreadInfoToClientDBThreadInfo, - ); - - // 6. Construct `replace` `ClientDBThreadStoreOperation`s. - const replaceThreadOperations = updatedClientDBThreadInfos.map(thread => ({ - type: 'replace', - payload: thread, - })); - - // 7. Prepend `replaceThreadOperations` with `remove_all` op and return. - return [{ type: 'remove_all' }, ...replaceThreadOperations]; -} - function createUpdateDBOpsForMessageStoreMessages( clientDBMessageInfos: $ReadOnlyArray, migrationFunc: ( $ReadOnlyArray, ) => $ReadOnlyArray, ): $ReadOnlyArray { const rawMessageInfos = clientDBMessageInfos.map( translateClientDBMessageInfoToRawMessageInfo, ); const convertedRawMessageInfos = migrationFunc(rawMessageInfos); const replaceMessagesOperations: $ReadOnlyArray = convertedRawMessageInfos.map(messageInfo => ({ type: 'replace', payload: translateRawMessageInfoToClientDBMessageInfo(messageInfo), })); return [ { type: 'remove_all', }, ...replaceMessagesOperations, ]; } function createUpdateDBOpsForMessageStoreThreads( messageStoreThreads: $ReadOnlyArray, migrationFunc: TranslatedThreadMessageInfos => TranslatedThreadMessageInfos, ): $ReadOnlyArray { const translatedMessageStoreThreads = translateClientDBThreadMessageInfos(messageStoreThreads); const convertedTranslatedMessageStoreThreads = migrationFunc( translatedMessageStoreThreads, ); return [ { type: 'remove_all_threads', }, { type: 'replace_threads', payload: { threads: entries(convertedTranslatedMessageStoreThreads).map( ([id, thread]) => translateThreadMessageInfoToClientDBThreadMessageInfo(id, thread), ), }, }, ]; } export { updateClientDBThreadStoreThreadInfos, createUpdateDBOpsForThreadStoreThreadInfos, createUpdateDBOpsForMessageStoreMessages, createUpdateDBOpsForMessageStoreThreads, };