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 @@ -192,7 +192,7 @@ threadPermissions.MANAGE_INVITE_LINKS, ]; -type LegacyMigrationManifest> = { +export type LegacyMigrationManifest> = { +[number | string]: (T) => Promise, }; type PersistedState> = T | void; @@ -204,10 +204,11 @@ debug: boolean, ) => Promise>; -type MigrationManifest> = { +export type MigrationManifest> = { +[number | string]: (PersistedState) => Promise<{ +state: T, +ops: StoreOperations, + +changesSchema?: boolean, }>, }; @@ -251,7 +252,7 @@ return state; } - return await runMigrations( + const { state: newState } = await runMigrations( legacyMigrations, migrations, state, @@ -260,6 +261,8 @@ debug, handleException, ); + + return newState; }; } @@ -270,8 +273,11 @@ inboundVersion: number, currentVersion: number, debug: boolean, - handleException: (error: Error, state: T) => T, -): Promise> { + handleException?: (error: Error, state: T) => T, +): Promise<{ + +state: PersistedState, + +schemaChanged: boolean, +}> { const migrationKeys = [ ...Object.keys(legacyMigrations), ...Object.keys(migrations), @@ -285,6 +291,7 @@ } let migratedState = state; + let schemaChanged = false; for (const versionKey of sortedMigrationKeys) { if (debug) { console.log( @@ -296,36 +303,45 @@ if (!versionKey) { continue; } - - if (legacyMigrations[versionKey]) { - migratedState = await legacyMigrations[versionKey](migratedState); - } else { - const { state: newState, ops } = - await migrations[versionKey](migratedState); - migratedState = newState; - const versionUpdateOp = { - type: 'replace_synced_metadata_entry', - payload: { - name: syncedMetadataNames.DB_VERSION, - data: versionKey.toString(), - }, - }; - const dbOps = { - ...ops, - syncedMetadataStoreOperations: [ - ...(ops.syncedMetadataStoreOperations ?? []), - versionUpdateOp, - ], - }; - try { + try { + if (legacyMigrations[versionKey]) { + migratedState = await legacyMigrations[versionKey](migratedState); + } else { + const { + state: newState, + ops, + changesSchema, + } = await migrations[versionKey](migratedState); + schemaChanged ||= !!changesSchema; + migratedState = newState; + const versionUpdateOp = { + type: 'replace_synced_metadata_entry', + payload: { + name: syncedMetadataNames.DB_VERSION, + data: versionKey.toString(), + }, + }; + const dbOps = { + ...ops, + syncedMetadataStoreOperations: [ + ...(ops.syncedMetadataStoreOperations ?? []), + versionUpdateOp, + ], + }; await getConfig().sqliteAPI.processDBStoreOperations(dbOps); - } catch (exception) { - return handleException(exception, state); } + } catch (exception) { + if (handleException) { + return { + state: handleException(exception, state), + schemaChanged, + }; + } + throw exception; } } - return migratedState; + return { state: migratedState, schemaChanged }; } export {