diff --git a/lib/package.json b/lib/package.json --- a/lib/package.json +++ b/lib/package.json @@ -48,6 +48,7 @@ "react": "18.1.0", "react-icomoon": "^2.5.7", "react-redux": "^7.1.1", + "redux-persist": "^6.0.0", "reselect": "^4.0.0", "reselect-map": "^1.0.5", "simple-markdown": "^0.7.2", diff --git a/web/redux/create-async-migrate.js b/lib/shared/create-async-migrate.js rename from web/redux/create-async-migrate.js rename to lib/shared/create-async-migrate.js --- a/web/redux/create-async-migrate.js +++ b/lib/shared/create-async-migrate.js @@ -1,12 +1,8 @@ // @flow -import { getStoredState, purgeStoredState } from 'redux-persist'; import { DEFAULT_VERSION } from 'redux-persist/es/constants.js'; -import storage from 'redux-persist/es/storage/index.js'; import type { PersistState } from 'redux-persist/es/types.js'; -import { databaseModule } from '../database/database-module-provider.js'; - type MigrationManifest = { +[number | string]: (PersistedState) => Promise, }; @@ -18,34 +14,30 @@ +debug: boolean, }; +export type StorageMigrationFunction = ( + debug: boolean, +) => Promise; + function createAsyncMigrate( migrations: MigrationManifest, config: ConfigType, + storageMigration: ?StorageMigrationFunction, ): (state: PersistedState, currentVersion: number) => Promise { const debug = process.env.NODE_ENV !== 'production' && !!config?.debug; return async function ( - state: PersistedState, + state: ?PersistedState, currentVersion: number, ): Promise { if (!state) { - const isSupported = await databaseModule.isDatabaseSupported(); - if (!isSupported) { + if (storageMigration) { + state = await storageMigration(debug); + } + if (!state) { if (debug) { console.log('redux-persist: no inbound state, skipping migration'); } return undefined; } - - const oldStorage = await getStoredState({ storage, key: 'root' }); - if (!oldStorage) { - return undefined; - } - - state = oldStorage; - purgeStoredState({ storage, key: 'root' }); - if (debug) { - console.log('redux-persist: migrating state to SQLite storage'); - } } const inboundVersion: number = state?._persist?.version ?? DEFAULT_VERSION; diff --git a/web/redux/persist.js b/web/redux/persist.js --- a/web/redux/persist.js +++ b/web/redux/persist.js @@ -1,11 +1,16 @@ // @flow +import { getStoredState, purgeStoredState } from 'redux-persist'; +import storage from 'redux-persist/es/storage/index.js'; import type { PersistConfig } from 'redux-persist/src/types.js'; +import { + createAsyncMigrate, + type StorageMigrationFunction, +} from 'lib/shared/create-async-migrate.js'; import { isDev } from 'lib/utils/dev-utils.js'; import commReduxStorageEngine from './comm-redux-storage-engine.js'; -import { createAsyncMigrate } from './create-async-migrate.js'; import type { AppState } from './redux-setup.js'; import { databaseModule } from '../database/database-module-provider.js'; import { isSQLiteSupported } from '../database/utils/db-utils.js'; @@ -67,13 +72,36 @@ 'lastCommunicatedPlatformDetails', ]; +const migrateStorageToSQLite: StorageMigrationFunction = async debug => { + const isSupported = await databaseModule.isDatabaseSupported(); + if (!isSupported) { + return undefined; + } + + const oldStorage = await getStoredState({ storage, key: 'root' }); + if (!oldStorage) { + return undefined; + } + + purgeStoredState({ storage, key: 'root' }); + if (debug) { + console.log('redux-persist: migrating state to SQLite storage'); + } + + return oldStorage; +}; + const persistConfig: PersistConfig = { key: 'root', storage: commReduxStorageEngine, whitelist: isDatabaseSupported ? persistWhitelist : [...persistWhitelist, 'draftStore'], - migrate: (createAsyncMigrate(migrations, { debug: isDev }): any), + migrate: (createAsyncMigrate( + migrations, + { debug: isDev }, + migrateStorageToSQLite, + ): any), version: 2, };