diff --git a/excalidraw-app/App.tsx b/excalidraw-app/App.tsx index b41bc4e01c..393b163c11 100644 --- a/excalidraw-app/App.tsx +++ b/excalidraw-app/App.tsx @@ -54,7 +54,7 @@ import { restoreElements, } from "@excalidraw/excalidraw/data/restore"; import { - migrateElementsBySchema, + migrateSceneElements, resolveSchemaVersion, SCHEMA_VERSIONS, } from "@excalidraw/excalidraw/data/schema"; @@ -242,15 +242,12 @@ const initializeScene = async (opts: { scrollToContent?: boolean; } = { elements: restoreElements( - migrateElementsBySchema( + migrateSceneElements( localDataState?.elements, - { - schemaVersion: resolveSchemaVersion( - localDataState?.schemaVersion, - SCHEMA_VERSIONS.initial, - ), - scope: "scene", - }, + resolveSchemaVersion( + localDataState?.schemaVersion, + SCHEMA_VERSIONS.initial, + ), ), null, { @@ -281,15 +278,12 @@ const initializeScene = async (opts: { scene = { elements: bumpElementVersions( restoreElements( - migrateElementsBySchema( + migrateSceneElements( imported.elements, - { - schemaVersion: resolveSchemaVersion( - imported.schemaVersion, - SCHEMA_VERSIONS.initial, - ), - scope: "scene", - }, + resolveSchemaVersion( + imported.schemaVersion, + SCHEMA_VERSIONS.initial, + ), ), null, { @@ -580,15 +574,12 @@ const ExcalidrawWrapper = () => { if (isBrowserStorageStateNewer(STORAGE_KEYS.VERSION_DATA_STATE)) { const localDataState = importFromLocalStorage(); const username = importUsernameFromLocalStorage(); - const migratedElements = migrateElementsBySchema( + const migratedElements = migrateSceneElements( localDataState?.elements, - { - schemaVersion: resolveSchemaVersion( - localDataState?.schemaVersion, - SCHEMA_VERSIONS.initial, - ), - scope: "scene", - }, + resolveSchemaVersion( + localDataState?.schemaVersion, + SCHEMA_VERSIONS.initial, + ), ); setLangCode(getPreferredLanguage()); excalidrawAPI.updateScene({ diff --git a/packages/excalidraw/components/App.tsx b/packages/excalidraw/components/App.tsx index 780b6c50c2..4309b23610 100644 --- a/packages/excalidraw/components/App.tsx +++ b/packages/excalidraw/components/App.tsx @@ -356,7 +356,10 @@ import { exportCanvas, loadFromBlob } from "../data"; import Library, { distributeLibraryItemsOnSquareGrid } from "../data/library"; import { restoreAppState, restoreElements } from "../data/restore"; import { - migrateElementsBySchema, + migrateAPIElements, + migrateClipboardElements, + migrateLibraryElements, + migrateSceneElements, resolveSchemaVersion, SCHEMA_VERSIONS, type SchemaMigrationScope, @@ -2819,15 +2822,12 @@ class App extends React.Component { ? SCHEMA_VERSIONS.initial : SCHEMA_VERSIONS.latest; const restoredElements = restoreElements( - migrateElementsBySchema( + migrateSceneElements( initialData?.elements, - { - schemaVersion: resolveSchemaVersion( - initialData?.schemaVersion, - initialDataSchemaFallback, - ), - scope: "scene", - }, + resolveSchemaVersion( + initialData?.schemaVersion, + initialDataSchemaFallback, + ), ), null, { @@ -3754,17 +3754,19 @@ class App extends React.Component { retainSeed?: boolean; fitToContent?: boolean; }) => { + const schemaVersion = resolveSchemaVersion( + opts.schemaVersion, + SCHEMA_VERSIONS.latest, + ); + const migratedElements = + opts.migrationScope === "clipboard" + ? migrateClipboardElements(opts.elements, schemaVersion) + : opts.migrationScope === "library" + ? migrateLibraryElements(opts.elements, schemaVersion) + : migrateAPIElements(opts.elements, schemaVersion); + const elements = restoreElements( - migrateElementsBySchema( - opts.elements, - { - schemaVersion: resolveSchemaVersion( - opts.schemaVersion, - SCHEMA_VERSIONS.latest, - ), - scope: opts.migrationScope, - }, - ), + migratedElements, null, { deleteInvisibleElements: true, diff --git a/packages/excalidraw/data/blob.ts b/packages/excalidraw/data/blob.ts index a936c34436..7c50dabbd6 100644 --- a/packages/excalidraw/data/blob.ts +++ b/packages/excalidraw/data/blob.ts @@ -25,7 +25,7 @@ import { restoreLibraryItems, } from "./restore"; import { - migrateElementsBySchema, + migrateSceneElements, resolveSchemaVersion, SCHEMA_VERSIONS, } from "./schema"; @@ -166,12 +166,9 @@ export const loadSceneOrLibraryFromBlob = async ( data.schemaVersion, SCHEMA_VERSIONS.initial, ); - const migratedElements = migrateElementsBySchema( + const migratedElements = migrateSceneElements( data.elements, - { - schemaVersion, - scope: "scene", - }, + schemaVersion, ); return { type: MIME_TYPES.excalidraw, diff --git a/packages/excalidraw/data/restore.ts b/packages/excalidraw/data/restore.ts index 783ab8d495..365620ca69 100644 --- a/packages/excalidraw/data/restore.ts +++ b/packages/excalidraw/data/restore.ts @@ -81,7 +81,7 @@ import { getNormalizedGridStep, getNormalizedZoom, } from "../scene"; -import { migrateElementsBySchema, SCHEMA_VERSIONS } from "./schema"; +import { migrateLibraryElements, SCHEMA_VERSIONS } from "./schema"; import type { AppState, @@ -962,12 +962,9 @@ const restoreLibraryItem = ( schemaVersion: number, ) => { const elements = restoreElements( - migrateElementsBySchema( + migrateLibraryElements( getNonDeletedElements(libraryItem.elements), - { - schemaVersion, - scope: "library", - }, + schemaVersion, ), null, ); diff --git a/packages/excalidraw/data/schema.test.ts b/packages/excalidraw/data/schema.test.ts index f5428018dc..1a41887ddb 100644 --- a/packages/excalidraw/data/schema.test.ts +++ b/packages/excalidraw/data/schema.test.ts @@ -4,7 +4,10 @@ import { API } from "../tests/helpers/api"; import { ALL_SCOPES, type SchemaMigration, - migrateElementsBySchema, + migrateAPIElements, + migrateClipboardElements, + migrateLibraryElements, + migrateSceneElements, resolveSchemaVersion, SCHEMA_MIGRATIONS, SCHEMA_VERSIONS, @@ -18,10 +21,7 @@ describe("schema migration", () => { backgroundColor: "#ffc9c9", }); - const migrated = migrateElementsBySchema([frame], { - schemaVersion: SCHEMA_VERSIONS.initial, - scope: "scene", - })!; + const migrated = migrateSceneElements([frame], SCHEMA_VERSIONS.initial)!; expect(migrated[0].backgroundColor).toBe( DEFAULT_ELEMENT_PROPS.backgroundColor, @@ -34,10 +34,7 @@ describe("schema migration", () => { backgroundColor: "#ffc9c9", }); - const migrated = migrateElementsBySchema([frame], { - schemaVersion: SCHEMA_VERSIONS.latest, - scope: "scene", - })!; + const migrated = migrateSceneElements([frame], SCHEMA_VERSIONS.latest)!; expect(migrated[0].backgroundColor).toBe("#ffc9c9"); }); @@ -48,11 +45,18 @@ describe("schema migration", () => { backgroundColor: "#a5d8ff", }); + const migrationsByScope = { + scene: migrateSceneElements, + library: migrateLibraryElements, + clipboard: migrateClipboardElements, + api: migrateAPIElements, + } as const; + for (const scope of ALL_SCOPES) { - const migrated = migrateElementsBySchema([frame], { - schemaVersion: SCHEMA_VERSIONS.initial, - scope, - })!; + const migrated = migrationsByScope[scope]( + [frame], + SCHEMA_VERSIONS.initial, + )!; expect(migrated[0].backgroundColor).toBe( DEFAULT_ELEMENT_PROPS.backgroundColor, ); diff --git a/packages/excalidraw/data/schema.ts b/packages/excalidraw/data/schema.ts index 732ec9694d..e1e3b830a4 100644 --- a/packages/excalidraw/data/schema.ts +++ b/packages/excalidraw/data/schema.ts @@ -154,3 +154,39 @@ export const migrateElementsBySchema = ( elements, ); }; + +export const migrateSceneElements = ( + elements: readonly ExcalidrawElement[] | null | undefined, + schemaVersion: number, +) => + migrateElementsBySchema(elements, { + schemaVersion, + scope: "scene", + }); + +export const migrateLibraryElements = ( + elements: readonly ExcalidrawElement[] | null | undefined, + schemaVersion: number, +) => + migrateElementsBySchema(elements, { + schemaVersion, + scope: "library", + }); + +export const migrateClipboardElements = ( + elements: readonly ExcalidrawElement[] | null | undefined, + schemaVersion: number, +) => + migrateElementsBySchema(elements, { + schemaVersion, + scope: "clipboard", + }); + +export const migrateAPIElements = ( + elements: readonly ExcalidrawElement[] | null | undefined, + schemaVersion: number, +) => + migrateElementsBySchema(elements, { + schemaVersion, + scope: "api", + });