diff --git a/lib/backup/persist-shared-migrations.js b/lib/backup/persist-shared-migrations.js --- a/lib/backup/persist-shared-migrations.js +++ b/lib/backup/persist-shared-migrations.js @@ -1,7 +1,9 @@ // @flow import type { DatabaseIdentifier } from '../types/database-identifier-types.js'; +import type { RawThreadInfo } from '../types/minimally-encoded-thread-permissions-types.js'; import type { StoreOperations } from '../types/store-ops-types.js'; +import { getConfig } from '../utils/config.js'; export type SharedMigrationFunction = ( databaseIdentifier: DatabaseIdentifier, @@ -10,6 +12,37 @@ export type SharedMigrationsManifest = { +[number | string]: SharedMigrationFunction, }; -const sharedMigrations: SharedMigrationsManifest = {}; +const sharedMigrations: SharedMigrationsManifest = { + [93]: (async (databaseIdentifier: DatabaseIdentifier) => { + const { sqliteAPI } = getConfig(); + + const clientStoreToMigrate = + await sqliteAPI.getClientDBStore(databaseIdentifier); + + if (!clientStoreToMigrate?.threadStore?.threadInfos) { + return {}; + } + + const threadInfos: Array = Object.values( + clientStoreToMigrate.threadStore.threadInfos, + ); + + const threadStoreOperations = threadInfos + .map(rawThreadInfo => ({ + ...rawThreadInfo, + color: 'FFFFFF', + description: 'BACKUP_MIGRATION', + })) + .map(thread => ({ + type: 'replace', + payload: { + id: thread.id, + threadInfo: thread, + }, + })); + + return { threadStoreOperations }; + }: SharedMigrationFunction), +}; export { sharedMigrations }; diff --git a/native/redux/persist-constants.js b/native/redux/persist-constants.js --- a/native/redux/persist-constants.js +++ b/native/redux/persist-constants.js @@ -5,6 +5,6 @@ // NOTE: renaming this constant requires updating // `native/native_rust_library/build.rs` to correctly // scrap Redux state version from this file. -const storeVersion = 92; +const storeVersion = 93; export { rootKey, storeVersion }; diff --git a/native/redux/persist.js b/native/redux/persist.js --- a/native/redux/persist.js +++ b/native/redux/persist.js @@ -16,6 +16,7 @@ convertCalendarFilterToNewIDSchema, convertConnectionInfoToNewIDSchema, } from 'lib/_generated/migration-utils.js'; +import { sharedMigrations } from 'lib/backup/persist-shared-migrations.js'; import { extractKeyserverIDFromID } from 'lib/keyserver-conn/keyserver-call-utils.js'; import type { ClientDBEntryStoreOperation, @@ -82,6 +83,7 @@ defaultAlertInfos, alertTypes, } from 'lib/types/alert-types.js'; +import { databaseIdentifier } from 'lib/types/database-identifier-types.js'; import { dmOperationTypes } from 'lib/types/dm-ops.js'; import { defaultEnabledApps } from 'lib/types/enabled-apps.js'; import { defaultCalendarQuery } from 'lib/types/entry-types.js'; @@ -1617,6 +1619,27 @@ ops: {}, }; }: MigrationFunction), + [93]: (async (state: AppState) => { + // First we need to execute migration using database logic + const ops = await sharedMigrations[93](databaseIdentifier.MAIN); + + // We still can to make changes in the state but making sure database + // migrations logic will be executed on backup database + const { processStoreOperations: processMessageStoreOperations } = + messageStoreOpsHandlers; + const processedMessageStore = processMessageStoreOperations( + state.messageStore, + ops.messageStoreOperations ?? [], + ); + + return { + state: { + ...state, + messageStore: processedMessageStore, + }, + ops, + }; + }: MigrationFunction), }); const persistConfig = { diff --git a/web/redux/persist-constants.js b/web/redux/persist-constants.js --- a/web/redux/persist-constants.js +++ b/web/redux/persist-constants.js @@ -3,6 +3,6 @@ const rootKey = 'root'; const rootKeyPrefix = 'persist:'; const completeRootKey = `${rootKeyPrefix}${rootKey}`; -const storeVersion = 92; +const storeVersion = 93; export { rootKey, rootKeyPrefix, completeRootKey, storeVersion }; diff --git a/web/redux/persist.js b/web/redux/persist.js --- a/web/redux/persist.js +++ b/web/redux/persist.js @@ -6,6 +6,7 @@ import storage from 'redux-persist/es/storage/index.js'; import type { PersistConfig } from 'redux-persist/src/types.js'; +import { sharedMigrations } from 'lib/backup/persist-shared-migrations.js'; import { type ClientDBKeyserverStoreOperation, keyserverStoreOpsHandlers, @@ -29,6 +30,7 @@ import { messageStoreMessagesBlocklistTransform } from 'lib/shared/transforms/message-store-transform.js'; import { unshimDMOperations } from 'lib/shared/unshim-utils.js'; import { defaultAlertInfos } from 'lib/types/alert-types.js'; +import { databaseIdentifier } from 'lib/types/database-identifier-types.js'; import { dmOperationTypes } from 'lib/types/dm-ops.js'; import { defaultCalendarQuery } from 'lib/types/entry-types.js'; import type { KeyserverInfo } from 'lib/types/keyserver-types.js'; @@ -841,6 +843,27 @@ state, ops: {}, }): MigrationFunction), + [93]: (async (state: AppState) => { + // First we need to execute migration using database logic + const ops = await sharedMigrations[93](databaseIdentifier.MAIN); + + // We still can to make changes in the state but making sure database + // migrations logic will be executed on backup database + const { processStoreOperations: processMessageStoreOperations } = + messageStoreOpsHandlers; + const processedMessageStore = processMessageStoreOperations( + state.messageStore, + ops.messageStoreOperations ?? [], + ); + + return { + state: { + ...state, + messageStore: processedMessageStore, + }, + ops, + }; + }: MigrationFunction), }; const persistConfig: PersistConfig = {