feat(editor): schema extension (#10447)

1. **Major Architectural Change: Schema Management**
   - Moved from `workspace.schema` to `store.schema` throughout the codebase
   - Removed schema property from Workspace and Doc interfaces
   - Added `BlockSchemaExtension` pattern across multiple block types

2. **Block Schema Extensions Added**
   - Added new `BlockSchemaExtension` to numerous block types including:
     - DataView, Surface, Attachment, Bookmark, Code
     - Database, Divider, EdgelessText, Embed blocks (Figma, Github, HTML, etc.)
     - Frame, Image, Latex, List, Note, Paragraph
     - Root, Surface Reference, Table blocks

3. **Import/Export System Updates**
   - Updated import functions to accept `schema` parameter:
     - `importHTMLToDoc`
     - `importHTMLZip`
     - `importMarkdownToDoc`
     - `importMarkdownZip`
     - `importNotionZip`
   - Modified export functions to use new schema pattern

4. **Test Infrastructure Updates**
   - Updated test files to use new schema extensions
   - Modified test document creation to include schema extensions
   - Removed direct schema registration in favor of extensions

5. **Service Layer Changes**
   - Updated various services to use `getAFFiNEWorkspaceSchema()`
   - Modified transformer initialization to use document schema
   - Updated collection initialization patterns

6. **Version Management**
   - Removed version-related properties and methods from:
     - `WorkspaceMetaImpl`
     - `TestMeta`
     - `DocImpl`
   - Removed `blockVersions` and `workspaceVersion/pageVersion`

7. **Store and Extension Updates**
   - Added new store extensions and adapters
   - Updated store initialization patterns
   - Added new schema-related functionality in store extension

This PR represents a significant architectural shift in how schemas are managed, moving from a workspace-centric to a store-centric approach, while introducing a more extensible block schema system through `BlockSchemaExtension`. The changes touch multiple layers of the application including core functionality, services, testing infrastructure, and import/export capabilities.
This commit is contained in:
Saul-Mirone
2025-02-26 11:31:28 +00:00
parent 2732b96d00
commit ce87dcf58e
95 changed files with 655 additions and 490 deletions

View File

@@ -2,7 +2,6 @@ import { useDocMetaHelper } from '@affine/core/components/hooks/use-block-suite-
import { useDocCollectionPage } from '@affine/core/components/hooks/use-block-suite-workspace-page';
import { FetchService, GraphQLService } from '@affine/core/modules/cloud';
import {
getAFFiNEWorkspaceSchema,
type WorkspaceFlavourProvider,
WorkspaceService,
WorkspacesService,
@@ -131,7 +130,6 @@ const getOrCreateShellWorkspace = (
return Promise.resolve([]);
},
},
schema: getAFFiNEWorkspaceSchema(),
});
docCollectionMap.set(workspaceId, docCollection);
docCollection.doc.emit('sync', [true, docCollection.doc]);

View File

@@ -4,6 +4,7 @@ import {
resolveGlobalLoadingEventAtom,
} from '@affine/component/global-loading';
import { EditorService } from '@affine/core/modules/editor';
import { getAFFiNEWorkspaceSchema } from '@affine/core/modules/workspace/global-schema';
import { useI18n } from '@affine/i18n';
import { track } from '@affine/track';
import type { BlockStdScope } from '@blocksuite/affine/block-std';
@@ -59,7 +60,7 @@ async function exportDoc(
config: AdapterConfig
) {
const transformer = new Transformer({
schema: doc.workspace.schema,
schema: getAFFiNEWorkspaceSchema(),
blobCRUD: doc.workspace.blobSync,
docCRUD: {
create: (id: string) => doc.workspace.createDoc({ id }),
@@ -148,7 +149,11 @@ async function exportHandler({
await exportToMarkdown(page, editorRoot?.std);
return;
case 'snapshot':
await ZipTransformer.exportDocs(page.workspace, [page]);
await ZipTransformer.exportDocs(
page.workspace,
getAFFiNEWorkspaceSchema(),
[page]
);
return;
case 'pdf':
await printToPdf(editorContainer);

View File

@@ -3,9 +3,9 @@
*/
import 'fake-indexeddb/auto';
import { AffineSchemas } from '@blocksuite/affine/blocks/schemas';
import { StoreExtensions } from '@blocksuite/affine/blocks';
import { assertExists } from '@blocksuite/affine/global/utils';
import { Schema, type Store, Text } from '@blocksuite/affine/store';
import { type Store, Text } from '@blocksuite/affine/store';
import { TestWorkspace } from '@blocksuite/affine/store/test';
import { renderHook } from '@testing-library/react';
import { useAtomValue } from 'jotai';
@@ -14,12 +14,11 @@ import { beforeEach, describe, expect, test, vi } from 'vitest';
import { useBlockSuitePagePreview } from '../use-block-suite-page-preview';
let docCollection: TestWorkspace;
const schema = new Schema();
schema.register(AffineSchemas);
const extensions = StoreExtensions;
beforeEach(async () => {
vi.useFakeTimers({ toFake: ['requestIdleCallback'] });
docCollection = new TestWorkspace({ id: 'test', schema });
docCollection = new TestWorkspace({ id: 'test' });
docCollection.meta.initialize();
const initPage = async (page: Store) => {
page.load();
@@ -31,7 +30,7 @@ beforeEach(async () => {
const frameId = page.addBlock('affine:note', {}, pageBlockId);
page.addBlock('affine:paragraph', {}, frameId);
};
await initPage(docCollection.createDoc({ id: 'page0' }));
await initPage(docCollection.createDoc({ id: 'page0', extensions }));
});
describe('useBlockSuitePagePreview', () => {

View File

@@ -26,7 +26,10 @@ import { EditorSettingService } from '@affine/core/modules/editor-setting';
import { useRegisterNavigationCommands } from '@affine/core/modules/navigation/view/use-register-navigation-commands';
import { QuickSearchContainer } from '@affine/core/modules/quicksearch';
import { WorkbenchService } from '@affine/core/modules/workbench';
import { WorkspaceService } from '@affine/core/modules/workspace';
import {
getAFFiNEWorkspaceSchema,
WorkspaceService,
} from '@affine/core/modules/workspace';
import { useI18n } from '@affine/i18n';
import track from '@affine/track';
import { type DocMode, ZipTransformer } from '@blocksuite/affine/blocks';
@@ -74,6 +77,7 @@ export const WorkspaceSideEffects = () => {
throwIfAborted(abort);
const [doc] = await ZipTransformer.importDocs(
currentWorkspace.docCollection,
getAFFiNEWorkspaceSchema(),
templateBlob
);
if (doc) {