Changeset View
Standalone View
web/redux/create-async-migrate.js
// @flow | // @flow | ||||
import { getStoredState, purgeStoredState } from 'redux-persist'; | |||||
import { DEFAULT_VERSION } from 'redux-persist/es/constants.js'; | 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 type { PersistState } from 'redux-persist/es/types.js'; | ||||
import { databaseModule } from '../database/database-module-provider.js'; | |||||
type MigrationManifest = { | type MigrationManifest = { | ||||
[number | string]: (PersistedState) => Promise<PersistedState>, | [number | string]: (PersistedState) => Promise<PersistedState>, | ||||
}; | }; | ||||
type PersistedState = { | type PersistedState = { | ||||
_persist: PersistState, | _persist: PersistState, | ||||
... | ... | ||||
} | void; | } | void; | ||||
function creatAsyncMigrate( | function creatAsyncMigrate( | ||||
migrations: MigrationManifest, | migrations: MigrationManifest, | ||||
config: { debug: boolean }, | config: { debug: boolean }, | ||||
): (state: PersistedState, currentVersion: number) => Promise<PersistedState> { | ): (state: PersistedState, currentVersion: number) => Promise<PersistedState> { | ||||
const debug = !!config?.debug; | const debug = !!config?.debug; | ||||
return async function ( | return async function ( | ||||
state: PersistedState, | state: PersistedState, | ||||
currentVersion: number, | currentVersion: number, | ||||
): Promise<PersistedState> { | ): Promise<PersistedState> { | ||||
if (!state) { | if (!state) { | ||||
const isSupported = await databaseModule.isDatabaseSupported(); | |||||
if (!isSupported) { | |||||
if (process.env.NODE_ENV !== 'production' && debug) { | if (process.env.NODE_ENV !== 'production' && debug) { | ||||
console.log('redux-persist: no inbound state, skipping migration'); | console.log('redux-persist: no inbound state, skipping migration'); | ||||
} | } | ||||
return undefined; | return undefined; | ||||
} | } | ||||
const oldStorage = await getStoredState({ storage, key: 'root' }); | |||||
if (!oldStorage) { | |||||
return undefined; | |||||
} | |||||
state = oldStorage; | |||||
purgeStoredState({ storage, key: 'root' }); | |||||
if (process.env.NODE_ENV !== 'production' && debug) { | |||||
console.log('redux-persist: migrating state to SQLite storage'); | |||||
} | |||||
} | |||||
tomek: Is it a standard way of doing this? Wondering if checking this during each migration makes… | |||||
kamilAuthorUnsubmitted Done Inline Actions
I didn't find any suggestion of how to do it properly, there is one issue on GitHub and my solution is similar to the comments there (link).
We not checking in each migration, we check once, one app start, and rehydrated state is empty.
Yes, this code will migrate storage engines without any new migrations. I can explain two alternative solutions but I don't think they're better:
According to this comment: https://phab.comm.dev/D7658?id=25832#inline-50059. Run through migrations and if the undefined state was an argument, return undefined, and then introduce the next migration which will be responsible for taking a look into the old storage engine.
This callback is called after rehydration and migrations, we can look into the old store but it's tough to propagate data to a new one. Let me know what do you think. kamil: > Is it a standard way of doing this?
I didn't find any suggestion of how to do it properly… | |||||
const inboundVersion: number = | const inboundVersion: number = | ||||
state._persist && state._persist.version !== undefined | state._persist && state._persist.version !== undefined | ||||
? state._persist.version | ? state._persist.version | ||||
: DEFAULT_VERSION; | : DEFAULT_VERSION; | ||||
if (inboundVersion === currentVersion) { | if (inboundVersion === currentVersion) { | ||||
if (process.env.NODE_ENV !== 'production' && debug) { | if (process.env.NODE_ENV !== 'production' && debug) { | ||||
console.log('redux-persist: versions match, noop migration'); | console.log('redux-persist: versions match, noop migration'); | ||||
Show All 37 Lines |
Is it a standard way of doing this? Wondering if checking this during each migration makes sense. Is it possible that we would want to move from one store to the other without any new migration introduced?