diff options
| author | Maze Winther <mazewinther@gmail.com> | 2026-02-03 14:00:04 +0100 |
|---|---|---|
| committer | Maze Winther <mazewinther@gmail.com> | 2026-02-03 14:00:04 +0100 |
| commit | 7366cb27e98d9e0b15e0176ac7ca32816c460284 (patch) | |
| tree | 07635628d37c06489519f7daf336c7f3f4fd3a2a /apps/web/src/services/storage/migrations/v1-to-v2.ts | |
| parent | 34daad9df7ed6dac4fbeba8619ca1958bb2dac86 (diff) | |
| download | opencut-7366cb27e98d9e0b15e0176ac7ca32816c460284.tar.gz | |
fix v1 to v2 migration
Diffstat (limited to 'apps/web/src/services/storage/migrations/v1-to-v2.ts')
| -rw-r--r-- | apps/web/src/services/storage/migrations/v1-to-v2.ts | 87 |
1 files changed, 76 insertions, 11 deletions
diff --git a/apps/web/src/services/storage/migrations/v1-to-v2.ts b/apps/web/src/services/storage/migrations/v1-to-v2.ts index a4e1f20b..d593d8a1 100644 --- a/apps/web/src/services/storage/migrations/v1-to-v2.ts +++ b/apps/web/src/services/storage/migrations/v1-to-v2.ts @@ -1,10 +1,14 @@ -/* - * Adds default values for new project properties introduced in v2 - */ - -import { IndexedDBAdapter } from "@/services/storage/indexeddb-adapter"; +import { + IndexedDBAdapter, + deleteDatabase, +} from "@/services/storage/indexeddb-adapter"; +import type { MediaAssetData } from "@/services/storage/types"; import { StorageMigration } from "./base"; -import { getProjectId, transformProjectV1ToV2 } from "./transformers/v1-to-v2"; +import { + getProjectId, + transformProjectV1ToV2, + type TransformV1ToV2Options, +} from "./transformers/v1-to-v2"; export class V1toV2Migration extends StorageMigration { from = 1; @@ -23,20 +27,81 @@ export class V1toV2Migration extends StorageMigration { continue; } - const result = transformProjectV1ToV2({ + const projectId = getProjectId({ project: project as Record<string, unknown>, }); - - if (result.skipped) { + if (!projectId) { continue; } - const projectId = getProjectId({ project: result.project }); - if (!projectId) { + const loadMediaAsset = createMediaAssetLoader({ projectId }); + + const result = await transformProjectV1ToV2({ + project: project as Record<string, unknown>, + options: { loadMediaAsset }, + }); + + if (result.skipped) { continue; } await projectsAdapter.set(projectId, result.project); + + await cleanupLegacyTimelineDBs({ projectId, project: result.project }); + } + } +} + +function createMediaAssetLoader({ + projectId, +}: { + projectId: string; +}): TransformV1ToV2Options["loadMediaAsset"] { + return async ({ mediaId }: { mediaId: string }) => { + const mediaMetadataAdapter = new IndexedDBAdapter<MediaAssetData>( + `video-editor-media-${projectId}`, + "media-metadata", + 1, + ); + + return mediaMetadataAdapter.get(mediaId); + }; +} + +async function cleanupLegacyTimelineDBs({ + projectId, + project, +}: { + projectId: string; + project: Record<string, unknown>; +}): Promise<void> { + const scenes = project.scenes; + if (!Array.isArray(scenes)) { + return; + } + + const dbNamesToDelete: string[] = []; + + for (const scene of scenes) { + if (typeof scene !== "object" || scene === null) { + continue; + } + + const sceneId = scene.id; + if (typeof sceneId === "string") { + const sceneDbName = `video-editor-timelines-${projectId}-${sceneId}`; + dbNamesToDelete.push(sceneDbName); + } + } + + const projectDbName = `video-editor-timelines-${projectId}`; + dbNamesToDelete.push(projectDbName); + + for (const dbName of dbNamesToDelete) { + try { + await deleteDatabase({ dbName }); + } catch { + // ignore errors, DB might not exist or already deleted } } } |
