From 00e7cf9a060bff7ac06eda5e8891d3cafec28a0c Mon Sep 17 00:00:00 2001 From: Alex Yang Date: Wed, 30 Aug 2023 00:04:16 -0500 Subject: [PATCH] fix(core): incorrect blocksuite data format (#4039) --- apps/core/src/layouts/workspace-layout.tsx | 20 +++++++++++++++++++- apps/core/src/pages/index.tsx | 1 + apps/electron/src/helper/db/migration.ts | 8 +++++--- packages/infra/src/blocksuite/index.ts | 19 +++++++++++++++---- 4 files changed, 40 insertions(+), 8 deletions(-) diff --git a/apps/core/src/layouts/workspace-layout.tsx b/apps/core/src/layouts/workspace-layout.tsx index 6aae895130..368e4e0ab5 100644 --- a/apps/core/src/layouts/workspace-layout.tsx +++ b/apps/core/src/layouts/workspace-layout.tsx @@ -33,8 +33,9 @@ import { usePassiveWorkspaceEffect } from '@toeverything/infra/__internal__/reac import { currentWorkspaceIdAtom } from '@toeverything/infra/atom'; import { useAtom, useAtomValue, useSetAtom } from 'jotai'; import type { PropsWithChildren, ReactElement } from 'react'; -import { lazy, Suspense, useCallback } from 'react'; +import { lazy, Suspense, useCallback, useEffect } from 'react'; import { useLocation, useParams } from 'react-router-dom'; +import { Map as YMap } from 'yjs'; import { openQuickSearchModalAtom, @@ -134,6 +135,23 @@ export const WorkspaceLayoutInner = ({ children }: PropsWithChildren) => { const [currentWorkspace] = useCurrentWorkspace(); const { openPage } = useNavigateHelper(); + useEffect(() => { + // hotfix for blockVersions + // this is a mistake in the + // 0.8.0 ~ 0.8.1 + // 0.8.0-beta.0 ~ 0.8.0-beta.3 + // 0.9.0-canary.0 ~ 0.9.0-canary.3 + const meta = currentWorkspace.blockSuiteWorkspace.doc.getMap('meta'); + const blockVersions = meta.get('blockVersions'); + if (!(blockVersions instanceof YMap)) { + console.log('fixing blockVersions'); + meta.set( + 'blockVersions', + new YMap(Object.entries(blockVersions as Record)) + ); + } + }, [currentWorkspace.blockSuiteWorkspace.doc]); + usePassiveWorkspaceEffect(currentWorkspace.blockSuiteWorkspace); const [, setOpenWorkspacesModal] = useAtom(openWorkspacesModalAtom); diff --git a/apps/core/src/pages/index.tsx b/apps/core/src/pages/index.tsx index 29840142ac..3c9ccf5deb 100644 --- a/apps/core/src/pages/index.tsx +++ b/apps/core/src/pages/index.tsx @@ -23,6 +23,7 @@ export const loader: LoaderFunction = async () => { const target = (lastId && meta.find(({ id }) => id === lastId)) || meta.at(0); if (target) { const targetWorkspace = getWorkspace(target.id); + const nonTrashPages = targetWorkspace.meta.pageMetas.filter( ({ trash }) => !trash ); diff --git a/apps/electron/src/helper/db/migration.ts b/apps/electron/src/helper/db/migration.ts index add0b85d74..d33da9b9dd 100644 --- a/apps/electron/src/helper/db/migration.ts +++ b/apps/electron/src/helper/db/migration.ts @@ -50,9 +50,11 @@ export const migrateToLatestDatabase = async (path: string) => { const update = ( await connection.getUpdates(isRoot ? undefined : doc.guid) ).map(update => update.data); - // Buffer[] -> Uint8Array - const data = new Uint8Array(Buffer.concat(update).buffer); - applyUpdate(doc, data); + // Buffer[] -> Uint8Array[] + const data = update.map(update => new Uint8Array(update)); + data.forEach(data => { + applyUpdate(doc, data); + }); // trigger data manually if (isRoot) { doc.getMap('meta'); diff --git a/packages/infra/src/blocksuite/index.ts b/packages/infra/src/blocksuite/index.ts index f493739431..8c6eb91cad 100644 --- a/packages/infra/src/blocksuite/index.ts +++ b/packages/infra/src/blocksuite/index.ts @@ -1,6 +1,7 @@ import type { PageMeta, Workspace } from '@blocksuite/store'; import { createIndexeddbStorage } from '@blocksuite/store'; import type { createStore, WritableAtom } from 'jotai/vanilla'; +import { Array as YArray, Doc as YDoc, Map as YMap } from 'yjs'; export async function buildShowcaseWorkspace( workspace: Workspace, @@ -27,7 +28,9 @@ export async function buildShowcaseWorkspace( 'affine:bookmark': 1, 'affine:database': 2, }; - workspace.doc.getMap('meta').set('blockVersions', showcaseWorkspaceVersions); + workspace.doc + .getMap('meta') + .set('blockVersions', new YMap(Object.entries(showcaseWorkspaceVersions))); const prototypes = { tags: { options: [ @@ -201,7 +204,6 @@ import { applyUpdate, encodeStateAsUpdate } from 'yjs'; const migrationOrigin = 'affine-migration'; import type { Schema } from '@blocksuite/store'; -import { Array as YArray, Doc as YDoc, Map as YMap } from 'yjs'; type XYWH = [number, number, number, number]; @@ -495,7 +497,11 @@ const upgradeV2ToV3 = async (options: UpgradeOptions): Promise => { const spaces = rootDoc.getMap('spaces') as YMap; const meta = rootDoc.getMap('meta') as YMap; const versions = meta.get('blockVersions') as YMap; - if (versions.get('affine:database') === 3) { + if ('affine:database' in versions) { + if (versions['affine:database'] === 3) { + return false; + } + } else if (versions.get('affine:database') === 3) { return false; } const schema = options.getSchema(); @@ -516,7 +522,12 @@ const upgradeV2ToV3 = async (options: UpgradeOptions): Promise => { space ); }); - versions.set('affine:database', 3); + if ('affine:database' in versions) { + versions['affine:database'] = 3; + meta.set('blockVersions', new YMap(Object.entries(versions))); + } else { + versions.set('affine:database', 3); + } return true; };