diff --git a/lib/utils/migration-utils.js b/lib/utils/migration-utils.js --- a/lib/utils/migration-utils.js +++ b/lib/utils/migration-utils.js @@ -186,14 +186,16 @@ debug: boolean, ) => Promise>; -export type MigrationFunction< - N: BaseNavInfo, - T: BaseAppState, -> = T => Promise<{ +export type MigrationResult = { +state: T, +ops: StoreOperations, +changesSchema?: boolean, -}>; +}; + +export type MigrationFunction< + N: BaseNavInfo, + T: BaseAppState, +> = T => Promise>; export type MigrationsManifest> = { +[number | string]: MigrationFunction, diff --git a/native/redux/persist.js b/native/redux/persist.js --- a/native/redux/persist.js +++ b/native/redux/persist.js @@ -150,7 +150,7 @@ import { persistMigrationForManagePinsThreadPermission } from './manage-pins-permission-migration.js'; import { persistMigrationToRemoveSelectRolePermissions } from './remove-select-role-permissions.js'; import type { AppState } from './state-types.js'; -import { unshimClientDB } from './unshim-utils.js'; +import { unshimClientDB, legacyUnshimClientDB } from './unshim-utils.js'; import { authoritativeKeyserverID } from '../authoritative-keyserver.js'; import { commCoreModule } from '../native-modules.js'; import type { NavInfo } from '../navigation/default-state.js'; @@ -515,13 +515,16 @@ } return state; }, - [32]: (state: AppState) => unshimClientDB(state, [messageTypes.MULTIMEDIA]), - [33]: (state: AppState) => unshimClientDB(state, [messageTypes.REACTION]), + [32]: (state: AppState) => + legacyUnshimClientDB(state, [messageTypes.MULTIMEDIA]), + [33]: (state: AppState) => + legacyUnshimClientDB(state, [messageTypes.REACTION]), [34]: (state: any) => { const { threadIDsToNotifIDs, ...stateSansThreadIDsToNotifIDs } = state; return stateSansThreadIDsToNotifIDs; }, - [35]: (state: AppState) => unshimClientDB(state, [messageTypes.MULTIMEDIA]), + [35]: (state: AppState) => + legacyUnshimClientDB(state, [messageTypes.MULTIMEDIA]), [36]: (state: AppState) => { // 1. Get threads and messages from SQLite `threads` and `messages` tables. const clientDBThreadInfos = commCoreModule.getAllThreadsSync(); @@ -653,7 +656,8 @@ state, legacyUpdateRolesAndPermissions, ), - [39]: (state: AppState) => unshimClientDB(state, [messageTypes.EDIT_MESSAGE]), + [39]: (state: AppState) => + legacyUnshimClientDB(state, [messageTypes.EDIT_MESSAGE]), [40]: (state: AppState) => deprecatedUpdateClientDBThreadStoreThreadInfos( state, @@ -1305,7 +1309,7 @@ }; }, [74]: (state: AppState) => - unshimClientDB( + legacyUnshimClientDB( state, [messageTypes.UPDATE_RELATIONSHIP], handleReduxMigrationFailure, @@ -1496,6 +1500,12 @@ state, ops: {}, }): MigrationFunction), + [85]: (async (state: AppState) => + unshimClientDB( + state, + [messageTypes.MULTIMEDIA], + handleReduxMigrationFailure, + ): MigrationFunction), }); // NOTE: renaming this object, and especially the `version` property @@ -1506,7 +1516,7 @@ storage: AsyncStorage, blacklist: persistBlacklist, debug: __DEV__, - version: 84, + version: 85, transforms: [ messageStoreMessagesBlocklistTransform, reportStoreTransform, diff --git a/native/redux/unshim-utils.js b/native/redux/unshim-utils.js --- a/native/redux/unshim-utils.js +++ b/native/redux/unshim-utils.js @@ -9,6 +9,7 @@ import { type MessageType } from 'lib/types/message-types-enum.js'; import type { RawMessageInfo } from 'lib/types/message-types.js'; import { translateClientDBMessageInfoToRawMessageInfo } from 'lib/utils/message-ops-utils.js'; +import type { MigrationResult } from 'lib/utils/migration-utils.js'; import type { AppState } from './state-types.js'; import { commCoreModule } from '../native-modules.js'; @@ -22,7 +23,7 @@ state: AppState, unshimTypes: $ReadOnlyArray, handleMigrationFailure?: AppState => AppState, -): AppState { +): MigrationResult { // 1. Get messages from SQLite `messages` table. const clientDBMessageInfos = commCoreModule.getInitialMessagesSync(); @@ -51,26 +52,52 @@ // 5. Try processing `ClientDBMessageStoreOperation`s and log out if // `processMessageStoreOperationsSync(...)` throws an exception. try { - const convertedMessageStoreOperations = - convertMessageOpsToClientDBOps(operations); - commCoreModule.processMessageStoreOperationsSync( - convertedMessageStoreOperations, - ); const processedMessageStore = processMessageStoreOperations( state.messageStore, operations, ); return { - ...state, - messageStore: processedMessageStore, + state: { + ...state, + messageStore: processedMessageStore, + }, + ops: { + messageStoreOperations: operations, + }, }; } catch (exception) { console.log(exception); if (handleMigrationFailure) { - return handleMigrationFailure(state); + const newState = handleMigrationFailure(state); + return { state: newState, ops: {} }; } - return ({ ...state, cookie: null }: any); + return { + state: ({ ...state, cookie: null }: any), + ops: {}, + }; + } +} + +function legacyUnshimClientDB( + prevState: AppState, + unshimTypes: $ReadOnlyArray, + handleMigrationFailure?: AppState => AppState, +): AppState { + const { state, ops } = unshimClientDB( + prevState, + unshimTypes, + handleMigrationFailure, + ); + const { messageStoreOperations } = ops; + if (messageStoreOperations) { + const convertedMessageStoreOperations = convertMessageOpsToClientDBOps( + messageStoreOperations, + ); + commCoreModule.processMessageStoreOperationsSync( + convertedMessageStoreOperations, + ); } + return state; } -export { unshimClientDB }; +export { unshimClientDB, legacyUnshimClientDB }; 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 = 84; +const storeVersion = 85; 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 @@ -65,7 +65,7 @@ } from './handle-redux-migration-failure.js'; import { rootKey, rootKeyPrefix, storeVersion } from './persist-constants.js'; import type { AppState } from './redux-setup.js'; -import { unshimClientDB } from './unshim-utils.js'; +import { legacyUnshimClientDB } from './unshim-utils.js'; import { authoritativeKeyserverID } from '../authoritative-keyserver.js'; import { getCommSharedWorker } from '../shared-worker/shared-worker-provider.js'; import { getOlmWasmPath } from '../shared-worker/utils/constants.js'; @@ -486,7 +486,7 @@ return state; }, [18]: (state: AppState) => - unshimClientDB(state, [messageTypes.UPDATE_RELATIONSHIP]), + legacyUnshimClientDB(state, [messageTypes.UPDATE_RELATIONSHIP]), }; const migrateStorageToSQLite: StorageMigrationFunction< @@ -718,6 +718,10 @@ }; return { state, ops: operations }; }: MigrationFunction), + [85]: (async (state: AppState) => ({ + state, + ops: {}, + }): MigrationFunction), }; const persistConfig: PersistConfig = { diff --git a/web/redux/unshim-utils.js b/web/redux/unshim-utils.js --- a/web/redux/unshim-utils.js +++ b/web/redux/unshim-utils.js @@ -12,8 +12,8 @@ ClientDBMessageInfo, } from 'lib/types/message-types.js'; import { translateClientDBMessageInfoToRawMessageInfo } from 'lib/utils/message-ops-utils.js'; +import type { MigrationResult } from 'lib/utils/migration-utils.js'; -import { handleReduxMigrationFailure } from './handle-redux-migration-failure.js'; import type { AppState } from './redux-setup.js'; import { getCommSharedWorker } from '../shared-worker/shared-worker-provider.js'; import { workerRequestMessageTypes } from '../types/worker-types.js'; @@ -26,13 +26,16 @@ async function unshimClientDB( state: AppState, unshimTypes: $ReadOnlyArray, -): Promise { +): Promise> { // 1. Check if `databaseModule` is supported and early-exit if not. const sharedWorker = await getCommSharedWorker(); const isDatabaseSupported = await sharedWorker.isSupported(); if (!isDatabaseSupported) { - return state; + return { + state, + ops: {}, + }; } // 2. Get existing `stores` from SQLite. @@ -44,7 +47,10 @@ stores?.store?.messages; if (messages === null || messages === undefined || messages.length === 0) { - return state; + return { + state, + ops: {}, + }; } // 3. Translate `ClientDBMessageInfo`s to `RawMessageInfo`s. @@ -71,26 +77,46 @@ // 6. Process the constructed `messageStoreOperations`. try { - const convertedMessageStoreOperations = - convertMessageOpsToClientDBOps(operations); - await sharedWorker.schedule({ - type: workerRequestMessageTypes.PROCESS_STORE_OPERATIONS, - storeOperations: { - messageStoreOperations: convertedMessageStoreOperations, - }, - }); const processedMessageStore = processMessageStoreOperations( state.messageStore, operations, ); return { - ...state, - messageStore: processedMessageStore, + state: { + ...state, + messageStore: processedMessageStore, + }, + ops: { + messageStoreOperations: operations, + }, }; } catch (e) { console.log(e); - return handleReduxMigrationFailure(state); + throw e; + } +} + +async function legacyUnshimClientDB( + prevState: AppState, + unshimTypes: $ReadOnlyArray, +): Promise { + const [sharedWorker, { state, ops }] = await Promise.all([ + getCommSharedWorker(), + unshimClientDB(prevState, unshimTypes), + ]); + const { messageStoreOperations } = ops; + if (messageStoreOperations) { + const convertedMessageStoreOperations = convertMessageOpsToClientDBOps( + messageStoreOperations, + ); + await sharedWorker.schedule({ + type: workerRequestMessageTypes.PROCESS_STORE_OPERATIONS, + storeOperations: { + messageStoreOperations: convertedMessageStoreOperations, + }, + }); } + return state; } -export { unshimClientDB }; +export { unshimClientDB, legacyUnshimClientDB };