From d0b4b1a5fc439d68371d8cfa677348250afec88b Mon Sep 17 00:00:00 2001 From: Maze Winther Date: Thu, 5 Feb 2026 14:28:16 +0100 Subject: [PATCH] fix migration dialog --- apps/web/src/core/managers/project-manager.ts | 9 +++- .../src/services/storage/migrations/index.ts | 1 + .../src/services/storage/migrations/runner.ts | 53 ++++++++++++++++--- .../migrations/transformers/v1-to-v2.ts | 6 --- .../services/storage/migrations/v0-to-v1.ts | 6 --- .../services/storage/migrations/v2-to-v3.ts | 4 -- 6 files changed, 55 insertions(+), 24 deletions(-) diff --git a/apps/web/src/core/managers/project-manager.ts b/apps/web/src/core/managers/project-manager.ts index 94576879..c7497ef0 100644 --- a/apps/web/src/core/managers/project-manager.ts +++ b/apps/web/src/core/managers/project-manager.ts @@ -24,6 +24,7 @@ import { CURRENT_PROJECT_VERSION, migrations, runStorageMigrations, + type MigrationProgress, } from "@/services/storage/migrations"; import { DEFAULT_TIMELINE_VIEW_STATE } from "@/constants/timeline-constants"; @@ -58,7 +59,13 @@ export class ProjectManager { } this.storageMigrationPromise = (async () => { - await runStorageMigrations({ migrations }); + await runStorageMigrations({ + migrations, + onProgress: (progress: MigrationProgress) => { + this.migrationState = progress; + this.notify(); + }, + }); })(); await this.storageMigrationPromise; diff --git a/apps/web/src/services/storage/migrations/index.ts b/apps/web/src/services/storage/migrations/index.ts index 285dda0c..df0b8007 100644 --- a/apps/web/src/services/storage/migrations/index.ts +++ b/apps/web/src/services/storage/migrations/index.ts @@ -3,6 +3,7 @@ import { V0toV1Migration } from "./v0-to-v1"; import { V1toV2Migration } from "./v1-to-v2"; import { V2toV3Migration } from "./v2-to-v3"; export { runStorageMigrations } from "./runner"; +export type { MigrationProgress } from "./runner"; export const CURRENT_PROJECT_VERSION = 3; diff --git a/apps/web/src/services/storage/migrations/runner.ts b/apps/web/src/services/storage/migrations/runner.ts index 83e7edae..bd34c661 100644 --- a/apps/web/src/services/storage/migrations/runner.ts +++ b/apps/web/src/services/storage/migrations/runner.ts @@ -4,18 +4,27 @@ import { } from "@/services/storage/indexeddb-adapter"; import type { StorageMigration } from "./base"; import type { ProjectRecord } from "./transformers/types"; -import { getProjectId } from "./transformers/utils"; +import { getProjectId, isRecord } from "./transformers/utils"; export interface StorageMigrationResult { migratedCount: number; } +export interface MigrationProgress { + isMigrating: boolean; + fromVersion: number | null; + toVersion: number | null; + projectName: string | null; +} + let hasCleanedUpMetaDb = false; export async function runStorageMigrations({ migrations, + onProgress, }: { migrations: StorageMigration[]; + onProgress?: (progress: MigrationProgress) => void; }): Promise { // One-time cleanup: delete the old global version database if (!hasCleanedUpMetaDb) { @@ -44,8 +53,20 @@ export async function runStorageMigrations({ let projectRecord = project as ProjectRecord; let currentVersion = getProjectVersion({ project: projectRecord }); + const targetVersion = orderedMigrations.at(-1)?.to ?? currentVersion; + + if (currentVersion >= targetVersion) { + continue; + } + + const projectName = getProjectName({ project: projectRecord }); + onProgress?.({ + isMigrating: true, + fromVersion: currentVersion, + toVersion: targetVersion, + projectName, + }); - // Apply migrations sequentially until project is up to date for (const migration of orderedMigrations) { if (migration.from !== currentVersion) { continue; @@ -54,24 +75,28 @@ export async function runStorageMigrations({ const result = await migration.transform(projectRecord); if (result.skipped) { - break; // Project is already at this version or higher + break; } - // Update project with migrated version const projectId = getProjectId({ project: result.project }); if (!projectId) { - break; // Can't save without ID + break; } await projectsAdapter.set(projectId, result.project); migratedCount++; currentVersion = migration.to; - - // Use migrated project for next iteration projectRecord = result.project; } } + onProgress?.({ + isMigrating: false, + fromVersion: null, + toVersion: null, + projectName: null, + }); + return { migratedCount }; } @@ -92,3 +117,17 @@ function getProjectVersion({ project }: { project: ProjectRecord }): number { // v0 - no scenes return 0; } + +function getProjectName({ project }: { project: ProjectRecord }): string | null { + const metadata = project.metadata; + if (isRecord(metadata) && typeof metadata.name === "string") { + return metadata.name; + } + + // v0 had name directly on project + if (typeof project.name === "string") { + return project.name; + } + + return null; +} diff --git a/apps/web/src/services/storage/migrations/transformers/v1-to-v2.ts b/apps/web/src/services/storage/migrations/transformers/v1-to-v2.ts index 0e5ffbf7..6242f8c3 100644 --- a/apps/web/src/services/storage/migrations/transformers/v1-to-v2.ts +++ b/apps/web/src/services/storage/migrations/transformers/v1-to-v2.ts @@ -148,7 +148,6 @@ async function migrateProject({ const transformedTracks = await transformTracks({ tracks, - projectId, loadMediaAsset, }); @@ -252,11 +251,9 @@ async function loadTracksFromLegacyDB({ async function transformTracks({ tracks, - projectId, loadMediaAsset, }: { tracks: unknown[]; - projectId: string; loadMediaAsset?: ({ mediaId, }: { @@ -279,7 +276,6 @@ async function transformTracks({ if (trackType === "media") { const videoTrack = await transformMediaTrack({ track: track as LegacyMediaTrack, - projectId, loadMediaAsset, isMain: !isFirstVideoTrackFound, }); @@ -306,12 +302,10 @@ async function transformTracks({ async function transformMediaTrack({ track, - projectId, loadMediaAsset, isMain, }: { track: LegacyMediaTrack; - projectId: string; loadMediaAsset?: ({ mediaId, }: { diff --git a/apps/web/src/services/storage/migrations/v0-to-v1.ts b/apps/web/src/services/storage/migrations/v0-to-v1.ts index a2225c76..8868e3f2 100644 --- a/apps/web/src/services/storage/migrations/v0-to-v1.ts +++ b/apps/web/src/services/storage/migrations/v0-to-v1.ts @@ -1,9 +1,3 @@ -/* - * Ensures every project has at least one scene - * Adds a default "Main scene" if none exist - * Sets currentSceneId to the new scene's id - */ - import { StorageMigration } from "./base"; import type { ProjectRecord } from "./transformers/types"; import { transformProjectV0ToV1 } from "./transformers/v0-to-v1"; diff --git a/apps/web/src/services/storage/migrations/v2-to-v3.ts b/apps/web/src/services/storage/migrations/v2-to-v3.ts index 7b9c7fda..70eb9aad 100644 --- a/apps/web/src/services/storage/migrations/v2-to-v3.ts +++ b/apps/web/src/services/storage/migrations/v2-to-v3.ts @@ -1,7 +1,3 @@ -/* - * Adds a "duration" field to each project's metadata - */ - import { StorageMigration } from "./base"; import type { ProjectRecord } from "./transformers/types"; import { transformProjectV2ToV3 } from "./transformers/v2-to-v3";