summaryrefslogtreecommitdiff
path: root/apps/web/src/services/storage/migrations
diff options
context:
space:
mode:
authorMaze Winther <mazewinther@gmail.com>2026-04-07 04:41:27 +0200
committerMaze Winther <mazewinther@gmail.com>2026-04-07 04:41:27 +0200
commitcbd1b8212370c67b34a70dccd21bd82de72fead2 (patch)
treed97cbee2aae22c22b59c59a50e9f8a6af0ae8ccf /apps/web/src/services/storage/migrations
parent4f7d401a974047d37673ee8e3840dceaaddc295c (diff)
downloadopencut-cbd1b8212370c67b34a70dccd21bd82de72fead2.tar.gz
refactor: structured track layout per scene
Diffstat (limited to 'apps/web/src/services/storage/migrations')
-rw-r--r--apps/web/src/services/storage/migrations/index.ts4
-rw-r--r--apps/web/src/services/storage/migrations/transformers/v23-to-v24.ts113
-rw-r--r--apps/web/src/services/storage/migrations/v23-to-v24.ts16
3 files changed, 132 insertions, 1 deletions
diff --git a/apps/web/src/services/storage/migrations/index.ts b/apps/web/src/services/storage/migrations/index.ts
index 9f0f3e0d..b7ee37f5 100644
--- a/apps/web/src/services/storage/migrations/index.ts
+++ b/apps/web/src/services/storage/migrations/index.ts
@@ -22,10 +22,11 @@ import { V19toV20Migration } from "./v19-to-v20";
import { V20toV21Migration } from "./v20-to-v21";
import { V21toV22Migration } from "./v21-to-v22";
import { V22toV23Migration } from "./v22-to-v23";
+import { V23toV24Migration } from "./v23-to-v24";
export { runStorageMigrations } from "./runner";
export type { MigrationProgress } from "./runner";
-export const CURRENT_PROJECT_VERSION = 23;
+export const CURRENT_PROJECT_VERSION = 24;
export const migrations = [
new V0toV1Migration(),
@@ -51,4 +52,5 @@ export const migrations = [
new V20toV21Migration(),
new V21toV22Migration(),
new V22toV23Migration(),
+ new V23toV24Migration(),
];
diff --git a/apps/web/src/services/storage/migrations/transformers/v23-to-v24.ts b/apps/web/src/services/storage/migrations/transformers/v23-to-v24.ts
new file mode 100644
index 00000000..710d4dc1
--- /dev/null
+++ b/apps/web/src/services/storage/migrations/transformers/v23-to-v24.ts
@@ -0,0 +1,113 @@
+import type { MigrationResult, ProjectRecord } from "./types";
+import { getProjectId, isRecord } from "./utils";
+
+export function transformProjectV23ToV24({
+ project,
+}: {
+ project: ProjectRecord;
+}): MigrationResult<ProjectRecord> {
+ if (!getProjectId({ project })) {
+ return { project, skipped: true, reason: "no project id" };
+ }
+
+ const version = project.version;
+ if (typeof version !== "number") {
+ return { project, skipped: true, reason: "invalid version" };
+ }
+ if (version >= 24) {
+ return { project, skipped: true, reason: "already v24" };
+ }
+ if (version !== 23) {
+ return { project, skipped: true, reason: "not v23" };
+ }
+
+ return {
+ project: {
+ ...migrateProject({ project }),
+ version: 24,
+ },
+ skipped: false,
+ };
+}
+
+function migrateProject({
+ project,
+}: {
+ project: ProjectRecord;
+}): ProjectRecord {
+ if (!Array.isArray(project.scenes)) {
+ return project;
+ }
+
+ return {
+ ...project,
+ scenes: project.scenes.map((scene) => migrateScene({ scene })),
+ };
+}
+
+function migrateScene({ scene }: { scene: unknown }): unknown {
+ if (!isRecord(scene) || !Array.isArray(scene.tracks)) {
+ return scene;
+ }
+
+ const mainTrack = findMainTrack({ tracks: scene.tracks });
+ if (!mainTrack) {
+ return scene;
+ }
+
+ return {
+ ...scene,
+ tracks: {
+ overlay: scene.tracks
+ .filter((track) => track !== mainTrack)
+ .map((track) => migrateTrack({ track }))
+ .filter(
+ (track): track is ProjectRecord =>
+ isRecord(track) && track.type !== "audio",
+ ),
+ main: migrateTrack({ track: mainTrack }),
+ audio: scene.tracks
+ .map((track) => migrateTrack({ track }))
+ .filter(
+ (track): track is ProjectRecord =>
+ isRecord(track) && track.type === "audio",
+ ),
+ },
+ };
+}
+
+function findMainTrack({
+ tracks,
+}: {
+ tracks: unknown[];
+}): ProjectRecord | null {
+ for (const track of tracks) {
+ if (!isRecord(track)) {
+ continue;
+ }
+ if (track.type === "video" && track.isMain === true) {
+ return track;
+ }
+ }
+
+ for (const track of tracks) {
+ if (!isRecord(track)) {
+ continue;
+ }
+ if (track.type === "video") {
+ return track;
+ }
+ }
+
+ return null;
+}
+
+function migrateTrack({ track }: { track: unknown }): unknown {
+ if (!isRecord(track)) {
+ return track;
+ }
+
+ const nextTrack = { ...track };
+ delete nextTrack.isMain;
+ return nextTrack;
+}
diff --git a/apps/web/src/services/storage/migrations/v23-to-v24.ts b/apps/web/src/services/storage/migrations/v23-to-v24.ts
new file mode 100644
index 00000000..fe952bb1
--- /dev/null
+++ b/apps/web/src/services/storage/migrations/v23-to-v24.ts
@@ -0,0 +1,16 @@
+import { StorageMigration } from "./base";
+import type { ProjectRecord } from "./transformers/types";
+import { transformProjectV23ToV24 } from "./transformers/v23-to-v24";
+
+export class V23toV24Migration extends StorageMigration {
+ from = 23;
+ to = 24;
+
+ async transform(project: ProjectRecord): Promise<{
+ project: ProjectRecord;
+ skipped: boolean;
+ reason?: string;
+ }> {
+ return transformProjectV23ToV24({ project });
+ }
+}