mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-27 02:42:25 +08:00
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:
@@ -5,7 +5,11 @@ import {
|
|||||||
type InsertToPosition,
|
type InsertToPosition,
|
||||||
} from '@blocksuite/affine-shared/utils';
|
} from '@blocksuite/affine-shared/utils';
|
||||||
import type { DataViewDataType } from '@blocksuite/data-view';
|
import type { DataViewDataType } from '@blocksuite/data-view';
|
||||||
import { BlockModel, defineBlockSchema } from '@blocksuite/store';
|
import {
|
||||||
|
BlockModel,
|
||||||
|
BlockSchemaExtension,
|
||||||
|
defineBlockSchema,
|
||||||
|
} from '@blocksuite/store';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
title: string;
|
title: string;
|
||||||
@@ -93,3 +97,6 @@ export const DataViewBlockSchema = defineBlockSchema({
|
|||||||
return new DataViewBlockModel();
|
return new DataViewBlockModel();
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const DataViewBlockSchemaExtension =
|
||||||
|
BlockSchemaExtension(DataViewBlockSchema);
|
||||||
|
|||||||
@@ -374,7 +374,7 @@ export class EdgelessClipboardController extends PageClipboard {
|
|||||||
const elementsRawData = JSON.parse(mayBeSurfaceDataJson);
|
const elementsRawData = JSON.parse(mayBeSurfaceDataJson);
|
||||||
const { snapshot, blobs } = elementsRawData;
|
const { snapshot, blobs } = elementsRawData;
|
||||||
const job = new Transformer({
|
const job = new Transformer({
|
||||||
schema: this.std.workspace.schema,
|
schema: this.std.store.schema,
|
||||||
blobCRUD: this.std.workspace.blobSync,
|
blobCRUD: this.std.workspace.blobSync,
|
||||||
docCRUD: {
|
docCRUD: {
|
||||||
create: (id: string) => this.std.workspace.createDoc({ id }),
|
create: (id: string) => this.std.workspace.createDoc({ id }),
|
||||||
@@ -1378,7 +1378,7 @@ export async function prepareClipboardData(
|
|||||||
std: BlockStdScope
|
std: BlockStdScope
|
||||||
) {
|
) {
|
||||||
const job = new Transformer({
|
const job = new Transformer({
|
||||||
schema: std.workspace.schema,
|
schema: std.store.schema,
|
||||||
blobCRUD: std.workspace.blobSync,
|
blobCRUD: std.workspace.blobSync,
|
||||||
docCRUD: {
|
docCRUD: {
|
||||||
create: (id: string) => std.workspace.createDoc({ id }),
|
create: (id: string) => std.workspace.createDoc({ id }),
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ export class TemplateJob {
|
|||||||
|
|
||||||
constructor({ model, type, middlewares }: TemplateJobConfig) {
|
constructor({ model, type, middlewares }: TemplateJobConfig) {
|
||||||
this.job = new Transformer({
|
this.job = new Transformer({
|
||||||
schema: model.doc.workspace.schema,
|
schema: model.doc.schema,
|
||||||
blobCRUD: model.doc.workspace.blobSync,
|
blobCRUD: model.doc.workspace.blobSync,
|
||||||
docCRUD: {
|
docCRUD: {
|
||||||
create: (id: string) => model.doc.workspace.createDoc({ id }),
|
create: (id: string) => model.doc.workspace.createDoc({ id }),
|
||||||
@@ -320,8 +320,7 @@ export class TemplateJob {
|
|||||||
from: Record<string, Record<string, unknown>>,
|
from: Record<string, Record<string, unknown>>,
|
||||||
to: Y.Map<Y.Map<unknown>>
|
to: Y.Map<Y.Map<unknown>>
|
||||||
) {
|
) {
|
||||||
const schema =
|
const schema = this.model.doc.schema.get('affine:surface');
|
||||||
this.model.doc.workspace.schema.flavourSchemaMap.get('affine:surface');
|
|
||||||
const surfaceTransformer = schema?.transformer?.(
|
const surfaceTransformer = schema?.transformer?.(
|
||||||
new Map()
|
new Map()
|
||||||
) as SurfaceBlockTransformer;
|
) as SurfaceBlockTransformer;
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ export function getSortedCloneElements(elements: GfxModel[]) {
|
|||||||
export function prepareCloneData(elements: GfxModel[], std: BlockStdScope) {
|
export function prepareCloneData(elements: GfxModel[], std: BlockStdScope) {
|
||||||
elements = sortEdgelessElements(elements);
|
elements = sortEdgelessElements(elements);
|
||||||
const job = new Transformer({
|
const job = new Transformer({
|
||||||
schema: std.workspace.schema,
|
schema: std.store.schema,
|
||||||
blobCRUD: std.workspace.blobSync,
|
blobCRUD: std.workspace.blobSync,
|
||||||
docCRUD: {
|
docCRUD: {
|
||||||
create: (id: string) => std.workspace.createDoc({ id }),
|
create: (id: string) => std.workspace.createDoc({ id }),
|
||||||
|
|||||||
@@ -8,19 +8,21 @@ import {
|
|||||||
import { SpecProvider } from '@blocksuite/affine-shared/utils';
|
import { SpecProvider } from '@blocksuite/affine-shared/utils';
|
||||||
import { Container } from '@blocksuite/global/di';
|
import { Container } from '@blocksuite/global/di';
|
||||||
import { sha } from '@blocksuite/global/utils';
|
import { sha } from '@blocksuite/global/utils';
|
||||||
import type { Store, Workspace } from '@blocksuite/store';
|
import type { Schema, Store, Workspace } from '@blocksuite/store';
|
||||||
import { extMimeMap, Transformer } from '@blocksuite/store';
|
import { extMimeMap, Transformer } from '@blocksuite/store';
|
||||||
|
|
||||||
import { createAssetsArchive, download, Unzip } from './utils.js';
|
import { createAssetsArchive, download, Unzip } from './utils.js';
|
||||||
|
|
||||||
type ImportHTMLToDocOptions = {
|
type ImportHTMLToDocOptions = {
|
||||||
collection: Workspace;
|
collection: Workspace;
|
||||||
|
schema: Schema;
|
||||||
html: string;
|
html: string;
|
||||||
fileName?: string;
|
fileName?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type ImportHTMLZipOptions = {
|
type ImportHTMLZipOptions = {
|
||||||
collection: Workspace;
|
collection: Workspace;
|
||||||
|
schema: Schema;
|
||||||
imported: Blob;
|
imported: Blob;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -87,18 +89,20 @@ async function exportDoc(doc: Store) {
|
|||||||
*
|
*
|
||||||
* @param options - The import options.
|
* @param options - The import options.
|
||||||
* @param options.collection - The target doc collection.
|
* @param options.collection - The target doc collection.
|
||||||
|
* @param options.schema - The schema of the target doc collection.
|
||||||
* @param options.html - The HTML content to import.
|
* @param options.html - The HTML content to import.
|
||||||
* @param options.fileName - Optional filename for the imported doc.
|
* @param options.fileName - Optional filename for the imported doc.
|
||||||
* @returns A Promise that resolves to the ID of the newly created doc, or undefined if import fails.
|
* @returns A Promise that resolves to the ID of the newly created doc, or undefined if import fails.
|
||||||
*/
|
*/
|
||||||
async function importHTMLToDoc({
|
async function importHTMLToDoc({
|
||||||
collection,
|
collection,
|
||||||
|
schema,
|
||||||
html,
|
html,
|
||||||
fileName,
|
fileName,
|
||||||
}: ImportHTMLToDocOptions) {
|
}: ImportHTMLToDocOptions) {
|
||||||
const provider = getProvider();
|
const provider = getProvider();
|
||||||
const job = new Transformer({
|
const job = new Transformer({
|
||||||
schema: collection.schema,
|
schema,
|
||||||
blobCRUD: collection.blobSync,
|
blobCRUD: collection.blobSync,
|
||||||
docCRUD: {
|
docCRUD: {
|
||||||
create: (id: string) => collection.createDoc({ id }),
|
create: (id: string) => collection.createDoc({ id }),
|
||||||
@@ -127,10 +131,15 @@ async function importHTMLToDoc({
|
|||||||
*
|
*
|
||||||
* @param options - The import options.
|
* @param options - The import options.
|
||||||
* @param options.collection - The target doc collection.
|
* @param options.collection - The target doc collection.
|
||||||
|
* @param options.schema - The schema of the target doc collection.
|
||||||
* @param options.imported - The zip file as a Blob.
|
* @param options.imported - The zip file as a Blob.
|
||||||
* @returns A Promise that resolves to an array of IDs of the newly created docs.
|
* @returns A Promise that resolves to an array of IDs of the newly created docs.
|
||||||
*/
|
*/
|
||||||
async function importHTMLZip({ collection, imported }: ImportHTMLZipOptions) {
|
async function importHTMLZip({
|
||||||
|
collection,
|
||||||
|
schema,
|
||||||
|
imported,
|
||||||
|
}: ImportHTMLZipOptions) {
|
||||||
const provider = getProvider();
|
const provider = getProvider();
|
||||||
const unzip = new Unzip();
|
const unzip = new Unzip();
|
||||||
await unzip.load(imported);
|
await unzip.load(imported);
|
||||||
@@ -161,7 +170,7 @@ async function importHTMLZip({ collection, imported }: ImportHTMLZipOptions) {
|
|||||||
htmlBlobs.map(async ([fileName, blob]) => {
|
htmlBlobs.map(async ([fileName, blob]) => {
|
||||||
const fileNameWithoutExt = fileName.replace(/\.[^/.]+$/, '');
|
const fileNameWithoutExt = fileName.replace(/\.[^/.]+$/, '');
|
||||||
const job = new Transformer({
|
const job = new Transformer({
|
||||||
schema: collection.schema,
|
schema,
|
||||||
blobCRUD: collection.blobSync,
|
blobCRUD: collection.blobSync,
|
||||||
docCRUD: {
|
docCRUD: {
|
||||||
create: (id: string) => collection.createDoc({ id }),
|
create: (id: string) => collection.createDoc({ id }),
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { SpecProvider } from '@blocksuite/affine-shared/utils';
|
|||||||
import { Container } from '@blocksuite/global/di';
|
import { Container } from '@blocksuite/global/di';
|
||||||
import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions';
|
import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions';
|
||||||
import { assertExists, sha } from '@blocksuite/global/utils';
|
import { assertExists, sha } from '@blocksuite/global/utils';
|
||||||
import type { Store, Workspace } from '@blocksuite/store';
|
import type { Schema, Store, Workspace } from '@blocksuite/store';
|
||||||
import { extMimeMap, Transformer } from '@blocksuite/store';
|
import { extMimeMap, Transformer } from '@blocksuite/store';
|
||||||
|
|
||||||
import { createAssetsArchive, download, Unzip } from './utils.js';
|
import { createAssetsArchive, download, Unzip } from './utils.js';
|
||||||
@@ -31,12 +31,14 @@ type ImportMarkdownToBlockOptions = {
|
|||||||
|
|
||||||
type ImportMarkdownToDocOptions = {
|
type ImportMarkdownToDocOptions = {
|
||||||
collection: Workspace;
|
collection: Workspace;
|
||||||
|
schema: Schema;
|
||||||
markdown: string;
|
markdown: string;
|
||||||
fileName?: string;
|
fileName?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type ImportMarkdownZipOptions = {
|
type ImportMarkdownZipOptions = {
|
||||||
collection: Workspace;
|
collection: Workspace;
|
||||||
|
schema: Schema;
|
||||||
imported: Blob;
|
imported: Blob;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -143,18 +145,20 @@ async function importMarkdownToBlock({
|
|||||||
* Imports Markdown content into a new doc within a collection.
|
* Imports Markdown content into a new doc within a collection.
|
||||||
* @param options Object containing import options
|
* @param options Object containing import options
|
||||||
* @param options.collection The target doc collection
|
* @param options.collection The target doc collection
|
||||||
|
* @param options.schema The schema of the target doc collection
|
||||||
* @param options.markdown The Markdown content to import
|
* @param options.markdown The Markdown content to import
|
||||||
* @param options.fileName Optional filename for the imported doc
|
* @param options.fileName Optional filename for the imported doc
|
||||||
* @returns A Promise that resolves to the ID of the newly created doc, or undefined if import fails
|
* @returns A Promise that resolves to the ID of the newly created doc, or undefined if import fails
|
||||||
*/
|
*/
|
||||||
async function importMarkdownToDoc({
|
async function importMarkdownToDoc({
|
||||||
collection,
|
collection,
|
||||||
|
schema,
|
||||||
markdown,
|
markdown,
|
||||||
fileName,
|
fileName,
|
||||||
}: ImportMarkdownToDocOptions) {
|
}: ImportMarkdownToDocOptions) {
|
||||||
const provider = getProvider();
|
const provider = getProvider();
|
||||||
const job = new Transformer({
|
const job = new Transformer({
|
||||||
schema: collection.schema,
|
schema,
|
||||||
blobCRUD: collection.blobSync,
|
blobCRUD: collection.blobSync,
|
||||||
docCRUD: {
|
docCRUD: {
|
||||||
create: (id: string) => collection.createDoc({ id }),
|
create: (id: string) => collection.createDoc({ id }),
|
||||||
@@ -182,11 +186,13 @@ async function importMarkdownToDoc({
|
|||||||
* Imports a zip file containing Markdown files and assets into a collection.
|
* Imports a zip file containing Markdown files and assets into a collection.
|
||||||
* @param options Object containing import options
|
* @param options Object containing import options
|
||||||
* @param options.collection The target doc collection
|
* @param options.collection The target doc collection
|
||||||
|
* @param options.schema The schema of the target doc collection
|
||||||
* @param options.imported The zip file as a Blob
|
* @param options.imported The zip file as a Blob
|
||||||
* @returns A Promise that resolves to an array of IDs of the newly created docs
|
* @returns A Promise that resolves to an array of IDs of the newly created docs
|
||||||
*/
|
*/
|
||||||
async function importMarkdownZip({
|
async function importMarkdownZip({
|
||||||
collection,
|
collection,
|
||||||
|
schema,
|
||||||
imported,
|
imported,
|
||||||
}: ImportMarkdownZipOptions) {
|
}: ImportMarkdownZipOptions) {
|
||||||
const provider = getProvider();
|
const provider = getProvider();
|
||||||
@@ -219,7 +225,7 @@ async function importMarkdownZip({
|
|||||||
markdownBlobs.map(async ([fileName, blob]) => {
|
markdownBlobs.map(async ([fileName, blob]) => {
|
||||||
const fileNameWithoutExt = fileName.replace(/\.[^/.]+$/, '');
|
const fileNameWithoutExt = fileName.replace(/\.[^/.]+$/, '');
|
||||||
const job = new Transformer({
|
const job = new Transformer({
|
||||||
schema: collection.schema,
|
schema,
|
||||||
blobCRUD: collection.blobSync,
|
blobCRUD: collection.blobSync,
|
||||||
docCRUD: {
|
docCRUD: {
|
||||||
create: (id: string) => collection.createDoc({ id }),
|
create: (id: string) => collection.createDoc({ id }),
|
||||||
|
|||||||
@@ -3,12 +3,18 @@ import { NotionHtmlAdapter } from '@blocksuite/affine-shared/adapters';
|
|||||||
import { SpecProvider } from '@blocksuite/affine-shared/utils';
|
import { SpecProvider } from '@blocksuite/affine-shared/utils';
|
||||||
import { Container } from '@blocksuite/global/di';
|
import { Container } from '@blocksuite/global/di';
|
||||||
import { sha } from '@blocksuite/global/utils';
|
import { sha } from '@blocksuite/global/utils';
|
||||||
import { extMimeMap, Transformer, type Workspace } from '@blocksuite/store';
|
import {
|
||||||
|
extMimeMap,
|
||||||
|
type Schema,
|
||||||
|
Transformer,
|
||||||
|
type Workspace,
|
||||||
|
} from '@blocksuite/store';
|
||||||
|
|
||||||
import { Unzip } from './utils.js';
|
import { Unzip } from './utils.js';
|
||||||
|
|
||||||
type ImportNotionZipOptions = {
|
type ImportNotionZipOptions = {
|
||||||
collection: Workspace;
|
collection: Workspace;
|
||||||
|
schema: Schema;
|
||||||
imported: Blob;
|
imported: Blob;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -26,6 +32,7 @@ function getProvider() {
|
|||||||
*
|
*
|
||||||
* @param options - The options for importing.
|
* @param options - The options for importing.
|
||||||
* @param options.collection - The BlockSuite document collection.
|
* @param options.collection - The BlockSuite document collection.
|
||||||
|
* @param options.schema - The schema of the BlockSuite document collection.
|
||||||
* @param options.imported - The imported zip file as a Blob.
|
* @param options.imported - The imported zip file as a Blob.
|
||||||
*
|
*
|
||||||
* @returns A promise that resolves to an object containing:
|
* @returns A promise that resolves to an object containing:
|
||||||
@@ -36,6 +43,7 @@ function getProvider() {
|
|||||||
*/
|
*/
|
||||||
async function importNotionZip({
|
async function importNotionZip({
|
||||||
collection,
|
collection,
|
||||||
|
schema,
|
||||||
imported,
|
imported,
|
||||||
}: ImportNotionZipOptions) {
|
}: ImportNotionZipOptions) {
|
||||||
const provider = getProvider();
|
const provider = getProvider();
|
||||||
@@ -117,7 +125,7 @@ async function importNotionZip({
|
|||||||
}
|
}
|
||||||
const pagePromises = Array.from(pagePaths).map(async path => {
|
const pagePromises = Array.from(pagePaths).map(async path => {
|
||||||
const job = new Transformer({
|
const job = new Transformer({
|
||||||
schema: collection.schema,
|
schema,
|
||||||
blobCRUD: collection.blobSync,
|
blobCRUD: collection.blobSync,
|
||||||
docCRUD: {
|
docCRUD: {
|
||||||
create: (id: string) => collection.createDoc({ id }),
|
create: (id: string) => collection.createDoc({ id }),
|
||||||
|
|||||||
@@ -3,15 +3,19 @@ import {
|
|||||||
titleMiddleware,
|
titleMiddleware,
|
||||||
} from '@blocksuite/affine-shared/adapters';
|
} from '@blocksuite/affine-shared/adapters';
|
||||||
import { sha } from '@blocksuite/global/utils';
|
import { sha } from '@blocksuite/global/utils';
|
||||||
import type { DocSnapshot, Store, Workspace } from '@blocksuite/store';
|
import type { DocSnapshot, Schema, Store, Workspace } from '@blocksuite/store';
|
||||||
import { extMimeMap, getAssetName, Transformer } from '@blocksuite/store';
|
import { extMimeMap, getAssetName, Transformer } from '@blocksuite/store';
|
||||||
|
|
||||||
import { download, Unzip, Zip } from '../transformers/utils.js';
|
import { download, Unzip, Zip } from '../transformers/utils.js';
|
||||||
|
|
||||||
async function exportDocs(collection: Workspace, docs: Store[]) {
|
async function exportDocs(
|
||||||
|
collection: Workspace,
|
||||||
|
schema: Schema,
|
||||||
|
docs: Store[]
|
||||||
|
) {
|
||||||
const zip = new Zip();
|
const zip = new Zip();
|
||||||
const job = new Transformer({
|
const job = new Transformer({
|
||||||
schema: collection.schema,
|
schema,
|
||||||
blobCRUD: collection.blobSync,
|
blobCRUD: collection.blobSync,
|
||||||
docCRUD: {
|
docCRUD: {
|
||||||
create: (id: string) => collection.createDoc({ id }),
|
create: (id: string) => collection.createDoc({ id }),
|
||||||
@@ -70,7 +74,11 @@ async function exportDocs(collection: Workspace, docs: Store[]) {
|
|||||||
return download(downloadBlob, `${collection.id}.bs.zip`);
|
return download(downloadBlob, `${collection.id}.bs.zip`);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function importDocs(collection: Workspace, imported: Blob) {
|
async function importDocs(
|
||||||
|
collection: Workspace,
|
||||||
|
schema: Schema,
|
||||||
|
imported: Blob
|
||||||
|
) {
|
||||||
const unzip = new Unzip();
|
const unzip = new Unzip();
|
||||||
await unzip.load(imported);
|
await unzip.load(imported);
|
||||||
|
|
||||||
@@ -98,7 +106,7 @@ async function importDocs(collection: Workspace, imported: Blob) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const job = new Transformer({
|
const job = new Transformer({
|
||||||
schema: collection.schema,
|
schema,
|
||||||
blobCRUD: collection.blobSync,
|
blobCRUD: collection.blobSync,
|
||||||
docCRUD: {
|
docCRUD: {
|
||||||
create: (id: string) => collection.createDoc({ id }),
|
create: (id: string) => collection.createDoc({ id }),
|
||||||
|
|||||||
@@ -233,6 +233,7 @@ export function createNewDocMenuGroup(
|
|||||||
};
|
};
|
||||||
showImportModal({
|
showImportModal({
|
||||||
collection: doc.workspace,
|
collection: doc.workspace,
|
||||||
|
schema: doc.schema,
|
||||||
onSuccess,
|
onSuccess,
|
||||||
onFail,
|
onFail,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import {
|
|||||||
} from '@blocksuite/affine-components/icons';
|
} from '@blocksuite/affine-components/icons';
|
||||||
import { openFileOrFiles } from '@blocksuite/affine-shared/utils';
|
import { openFileOrFiles } from '@blocksuite/affine-shared/utils';
|
||||||
import { WithDisposable } from '@blocksuite/global/utils';
|
import { WithDisposable } from '@blocksuite/global/utils';
|
||||||
import type { Workspace } from '@blocksuite/store';
|
import type { Schema, Workspace } from '@blocksuite/store';
|
||||||
import { html, LitElement, type PropertyValues } from 'lit';
|
import { html, LitElement, type PropertyValues } from 'lit';
|
||||||
import { query, state } from 'lit/decorators.js';
|
import { query, state } from 'lit/decorators.js';
|
||||||
|
|
||||||
@@ -31,6 +31,7 @@ export class ImportDoc extends WithDisposable(LitElement) {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly collection: Workspace,
|
private readonly collection: Workspace,
|
||||||
|
private readonly schema: Schema,
|
||||||
private readonly onSuccess?: OnSuccessHandler,
|
private readonly onSuccess?: OnSuccessHandler,
|
||||||
private readonly onFail?: OnFailHandler,
|
private readonly onFail?: OnFailHandler,
|
||||||
private readonly abortController = new AbortController()
|
private readonly abortController = new AbortController()
|
||||||
@@ -63,6 +64,7 @@ export class ImportDoc extends WithDisposable(LitElement) {
|
|||||||
}
|
}
|
||||||
const pageId = await HtmlTransformer.importHTMLToDoc({
|
const pageId = await HtmlTransformer.importHTMLToDoc({
|
||||||
collection: this.collection,
|
collection: this.collection,
|
||||||
|
schema: this.schema,
|
||||||
html: text,
|
html: text,
|
||||||
fileName,
|
fileName,
|
||||||
});
|
});
|
||||||
@@ -93,6 +95,7 @@ export class ImportDoc extends WithDisposable(LitElement) {
|
|||||||
}
|
}
|
||||||
const pageId = await MarkdownTransformer.importMarkdownToDoc({
|
const pageId = await MarkdownTransformer.importMarkdownToDoc({
|
||||||
collection: this.collection,
|
collection: this.collection,
|
||||||
|
schema: this.schema,
|
||||||
markdown: text,
|
markdown: text,
|
||||||
fileName,
|
fileName,
|
||||||
});
|
});
|
||||||
@@ -117,6 +120,7 @@ export class ImportDoc extends WithDisposable(LitElement) {
|
|||||||
const { entryId, pageIds, isWorkspaceFile, hasMarkdown } =
|
const { entryId, pageIds, isWorkspaceFile, hasMarkdown } =
|
||||||
await NotionHtmlTransformer.importNotionZip({
|
await NotionHtmlTransformer.importNotionZip({
|
||||||
collection: this.collection,
|
collection: this.collection,
|
||||||
|
schema: this.schema,
|
||||||
imported: file,
|
imported: file,
|
||||||
});
|
});
|
||||||
needLoading && this.abortController.abort();
|
needLoading && this.abortController.abort();
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { Workspace } from '@blocksuite/store';
|
import type { Schema, Workspace } from '@blocksuite/store';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ImportDoc,
|
ImportDoc,
|
||||||
@@ -7,12 +7,14 @@ import {
|
|||||||
} from './import-doc.js';
|
} from './import-doc.js';
|
||||||
|
|
||||||
export function showImportModal({
|
export function showImportModal({
|
||||||
|
schema,
|
||||||
collection,
|
collection,
|
||||||
onSuccess,
|
onSuccess,
|
||||||
onFail,
|
onFail,
|
||||||
container = document.body,
|
container = document.body,
|
||||||
abortController = new AbortController(),
|
abortController = new AbortController(),
|
||||||
}: {
|
}: {
|
||||||
|
schema: Schema;
|
||||||
collection: Workspace;
|
collection: Workspace;
|
||||||
onSuccess?: OnSuccessHandler;
|
onSuccess?: OnSuccessHandler;
|
||||||
onFail?: OnFailHandler;
|
onFail?: OnFailHandler;
|
||||||
@@ -22,6 +24,7 @@ export function showImportModal({
|
|||||||
}) {
|
}) {
|
||||||
const importDoc = new ImportDoc(
|
const importDoc = new ImportDoc(
|
||||||
collection,
|
collection,
|
||||||
|
schema,
|
||||||
onSuccess,
|
onSuccess,
|
||||||
onFail,
|
onFail,
|
||||||
abortController
|
abortController
|
||||||
|
|||||||
@@ -50,7 +50,11 @@ export {
|
|||||||
} from './adapters/index.js';
|
} from './adapters/index.js';
|
||||||
export type { SurfaceContext } from './surface-block.js';
|
export type { SurfaceContext } from './surface-block.js';
|
||||||
export { SurfaceBlockComponent } from './surface-block.js';
|
export { SurfaceBlockComponent } from './surface-block.js';
|
||||||
export { SurfaceBlockModel, SurfaceBlockSchema } from './surface-model.js';
|
export {
|
||||||
|
SurfaceBlockModel,
|
||||||
|
SurfaceBlockSchema,
|
||||||
|
SurfaceBlockSchemaExtension,
|
||||||
|
} from './surface-model.js';
|
||||||
export type { SurfaceBlockService } from './surface-service.js';
|
export type { SurfaceBlockService } from './surface-service.js';
|
||||||
export {
|
export {
|
||||||
EdgelessSurfaceBlockSpec,
|
EdgelessSurfaceBlockSpec,
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import type {
|
|||||||
import type { SurfaceBlockProps } from '@blocksuite/block-std/gfx';
|
import type { SurfaceBlockProps } from '@blocksuite/block-std/gfx';
|
||||||
import { SurfaceBlockModel as BaseSurfaceModel } from '@blocksuite/block-std/gfx';
|
import { SurfaceBlockModel as BaseSurfaceModel } from '@blocksuite/block-std/gfx';
|
||||||
import { DisposableGroup } from '@blocksuite/global/utils';
|
import { DisposableGroup } from '@blocksuite/global/utils';
|
||||||
import { defineBlockSchema } from '@blocksuite/store';
|
import { BlockSchemaExtension, defineBlockSchema } from '@blocksuite/store';
|
||||||
import * as Y from 'yjs';
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
import { elementsCtorMap } from './element-model/index.js';
|
import { elementsCtorMap } from './element-model/index.js';
|
||||||
@@ -36,6 +36,9 @@ export const SurfaceBlockSchema = defineBlockSchema({
|
|||||||
toModel: () => new SurfaceBlockModel(),
|
toModel: () => new SurfaceBlockModel(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const SurfaceBlockSchemaExtension =
|
||||||
|
BlockSchemaExtension(SurfaceBlockSchema);
|
||||||
|
|
||||||
export type SurfaceMiddleware = (surface: SurfaceBlockModel) => () => void;
|
export type SurfaceMiddleware = (surface: SurfaceBlockModel) => () => void;
|
||||||
|
|
||||||
export class SurfaceBlockModel extends BaseSurfaceModel {
|
export class SurfaceBlockModel extends BaseSurfaceModel {
|
||||||
|
|||||||
@@ -3,7 +3,11 @@ import type {
|
|||||||
GfxElementGeometry,
|
GfxElementGeometry,
|
||||||
} from '@blocksuite/block-std/gfx';
|
} from '@blocksuite/block-std/gfx';
|
||||||
import { GfxCompatible } from '@blocksuite/block-std/gfx';
|
import { GfxCompatible } from '@blocksuite/block-std/gfx';
|
||||||
import { BlockModel, defineBlockSchema } from '@blocksuite/store';
|
import {
|
||||||
|
BlockModel,
|
||||||
|
BlockSchemaExtension,
|
||||||
|
defineBlockSchema,
|
||||||
|
} from '@blocksuite/store';
|
||||||
|
|
||||||
import type { EmbedCardStyle } from '../../utils/index.js';
|
import type { EmbedCardStyle } from '../../utils/index.js';
|
||||||
import { AttachmentBlockTransformer } from './attachment-transformer.js';
|
import { AttachmentBlockTransformer } from './attachment-transformer.js';
|
||||||
@@ -86,6 +90,10 @@ export const AttachmentBlockSchema = defineBlockSchema({
|
|||||||
toModel: () => new AttachmentBlockModel(),
|
toModel: () => new AttachmentBlockModel(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const AttachmentBlockSchemaExtension = BlockSchemaExtension(
|
||||||
|
AttachmentBlockSchema
|
||||||
|
);
|
||||||
|
|
||||||
export class AttachmentBlockModel
|
export class AttachmentBlockModel
|
||||||
extends GfxCompatible<AttachmentBlockProps>(BlockModel)
|
extends GfxCompatible<AttachmentBlockProps>(BlockModel)
|
||||||
implements GfxElementGeometry {}
|
implements GfxElementGeometry {}
|
||||||
|
|||||||
@@ -3,7 +3,11 @@ import type {
|
|||||||
GfxElementGeometry,
|
GfxElementGeometry,
|
||||||
} from '@blocksuite/block-std/gfx';
|
} from '@blocksuite/block-std/gfx';
|
||||||
import { GfxCompatible } from '@blocksuite/block-std/gfx';
|
import { GfxCompatible } from '@blocksuite/block-std/gfx';
|
||||||
import { BlockModel, defineBlockSchema } from '@blocksuite/store';
|
import {
|
||||||
|
BlockModel,
|
||||||
|
BlockSchemaExtension,
|
||||||
|
defineBlockSchema,
|
||||||
|
} from '@blocksuite/store';
|
||||||
|
|
||||||
import type { EmbedCardStyle, LinkPreviewData } from '../../utils/index.js';
|
import type { EmbedCardStyle, LinkPreviewData } from '../../utils/index.js';
|
||||||
|
|
||||||
@@ -54,6 +58,9 @@ export const BookmarkBlockSchema = defineBlockSchema({
|
|||||||
toModel: () => new BookmarkBlockModel(),
|
toModel: () => new BookmarkBlockModel(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const BookmarkBlockSchemaExtension =
|
||||||
|
BlockSchemaExtension(BookmarkBlockSchema);
|
||||||
|
|
||||||
export class BookmarkBlockModel
|
export class BookmarkBlockModel
|
||||||
extends GfxCompatible<BookmarkBlockProps>(BlockModel)
|
extends GfxCompatible<BookmarkBlockProps>(BlockModel)
|
||||||
implements GfxElementGeometry {}
|
implements GfxElementGeometry {}
|
||||||
|
|||||||
@@ -1,4 +1,9 @@
|
|||||||
import { BlockModel, defineBlockSchema, type Text } from '@blocksuite/store';
|
import {
|
||||||
|
BlockModel,
|
||||||
|
BlockSchemaExtension,
|
||||||
|
defineBlockSchema,
|
||||||
|
type Text,
|
||||||
|
} from '@blocksuite/store';
|
||||||
|
|
||||||
interface CodeBlockProps {
|
interface CodeBlockProps {
|
||||||
text: Text;
|
text: Text;
|
||||||
@@ -30,6 +35,8 @@ export const CodeBlockSchema = defineBlockSchema({
|
|||||||
toModel: () => new CodeBlockModel(),
|
toModel: () => new CodeBlockModel(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const CodeBlockSchemaExtension = BlockSchemaExtension(CodeBlockSchema);
|
||||||
|
|
||||||
export class CodeBlockModel extends BlockModel<CodeBlockProps> {
|
export class CodeBlockModel extends BlockModel<CodeBlockProps> {
|
||||||
override text!: Text;
|
override text!: Text;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
import type { Text } from '@blocksuite/store';
|
import type { Text } from '@blocksuite/store';
|
||||||
import { BlockModel, defineBlockSchema } from '@blocksuite/store';
|
import {
|
||||||
|
BlockModel,
|
||||||
|
BlockSchemaExtension,
|
||||||
|
defineBlockSchema,
|
||||||
|
} from '@blocksuite/store';
|
||||||
|
|
||||||
import type { Column, SerializedCells, ViewBasicDataType } from './types.js';
|
import type { Column, SerializedCells, ViewBasicDataType } from './types.js';
|
||||||
|
|
||||||
@@ -28,3 +32,6 @@ export const DatabaseBlockSchema = defineBlockSchema({
|
|||||||
},
|
},
|
||||||
toModel: () => new DatabaseBlockModel(),
|
toModel: () => new DatabaseBlockModel(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const DatabaseBlockSchemaExtension =
|
||||||
|
BlockSchemaExtension(DatabaseBlockSchema);
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
import { BlockModel, defineBlockSchema } from '@blocksuite/store';
|
import {
|
||||||
|
BlockModel,
|
||||||
|
BlockSchemaExtension,
|
||||||
|
defineBlockSchema,
|
||||||
|
} from '@blocksuite/store';
|
||||||
|
|
||||||
export const DividerBlockSchema = defineBlockSchema({
|
export const DividerBlockSchema = defineBlockSchema({
|
||||||
flavour: 'affine:divider',
|
flavour: 'affine:divider',
|
||||||
@@ -15,3 +19,6 @@ type Props = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export class DividerBlockModel extends BlockModel<Props> {}
|
export class DividerBlockModel extends BlockModel<Props> {}
|
||||||
|
|
||||||
|
export const DividerBlockSchemaExtension =
|
||||||
|
BlockSchemaExtension(DividerBlockSchema);
|
||||||
|
|||||||
@@ -3,7 +3,11 @@ import type {
|
|||||||
GfxElementGeometry,
|
GfxElementGeometry,
|
||||||
} from '@blocksuite/block-std/gfx';
|
} from '@blocksuite/block-std/gfx';
|
||||||
import { GfxCompatible } from '@blocksuite/block-std/gfx';
|
import { GfxCompatible } from '@blocksuite/block-std/gfx';
|
||||||
import { BlockModel, defineBlockSchema } from '@blocksuite/store';
|
import {
|
||||||
|
BlockModel,
|
||||||
|
BlockSchemaExtension,
|
||||||
|
defineBlockSchema,
|
||||||
|
} from '@blocksuite/store';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -76,6 +80,10 @@ export const EdgelessTextBlockSchema = defineBlockSchema({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const EdgelessTextBlockSchemaExtension = BlockSchemaExtension(
|
||||||
|
EdgelessTextBlockSchema
|
||||||
|
);
|
||||||
|
|
||||||
export class EdgelessTextBlockModel
|
export class EdgelessTextBlockModel
|
||||||
extends GfxCompatible<EdgelessTextProps>(BlockModel)
|
extends GfxCompatible<EdgelessTextProps>(BlockModel)
|
||||||
implements GfxElementGeometry {}
|
implements GfxElementGeometry {}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { BlockSchemaExtension } from '@blocksuite/store';
|
||||||
|
|
||||||
import { createEmbedBlockSchema } from '../../../utils/index.js';
|
import { createEmbedBlockSchema } from '../../../utils/index.js';
|
||||||
import {
|
import {
|
||||||
type EmbedFigmaBlockProps,
|
type EmbedFigmaBlockProps,
|
||||||
@@ -20,3 +22,7 @@ export const EmbedFigmaBlockSchema = createEmbedBlockSchema({
|
|||||||
toModel: () => new EmbedFigmaModel(),
|
toModel: () => new EmbedFigmaModel(),
|
||||||
props: (): EmbedFigmaBlockProps => defaultEmbedFigmaProps,
|
props: (): EmbedFigmaBlockProps => defaultEmbedFigmaProps,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const EmbedFigmaBlockSchemaExtension = BlockSchemaExtension(
|
||||||
|
EmbedFigmaBlockSchema
|
||||||
|
);
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { BlockSchemaExtension } from '@blocksuite/store';
|
||||||
|
|
||||||
import { createEmbedBlockSchema } from '../../../utils/index.js';
|
import { createEmbedBlockSchema } from '../../../utils/index.js';
|
||||||
import {
|
import {
|
||||||
type EmbedGithubBlockProps,
|
type EmbedGithubBlockProps,
|
||||||
@@ -29,3 +31,7 @@ export const EmbedGithubBlockSchema = createEmbedBlockSchema({
|
|||||||
toModel: () => new EmbedGithubModel(),
|
toModel: () => new EmbedGithubModel(),
|
||||||
props: (): EmbedGithubBlockProps => defaultEmbedGithubProps,
|
props: (): EmbedGithubBlockProps => defaultEmbedGithubProps,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const EmbedGithubBlockSchemaExtension = BlockSchemaExtension(
|
||||||
|
EmbedGithubBlockSchema
|
||||||
|
);
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { BlockSchemaExtension } from '@blocksuite/store';
|
||||||
|
|
||||||
import { createEmbedBlockSchema } from '../../../utils/index.js';
|
import { createEmbedBlockSchema } from '../../../utils/index.js';
|
||||||
import {
|
import {
|
||||||
type EmbedHtmlBlockProps,
|
type EmbedHtmlBlockProps,
|
||||||
@@ -18,3 +20,6 @@ export const EmbedHtmlBlockSchema = createEmbedBlockSchema({
|
|||||||
toModel: () => new EmbedHtmlModel(),
|
toModel: () => new EmbedHtmlModel(),
|
||||||
props: (): EmbedHtmlBlockProps => defaultEmbedHtmlProps,
|
props: (): EmbedHtmlBlockProps => defaultEmbedHtmlProps,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const EmbedHtmlBlockSchemaExtension =
|
||||||
|
BlockSchemaExtension(EmbedHtmlBlockSchema);
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { BlockSchemaExtension } from '@blocksuite/store';
|
||||||
|
|
||||||
import { createEmbedBlockSchema } from '../../../utils/index.js';
|
import { createEmbedBlockSchema } from '../../../utils/index.js';
|
||||||
import {
|
import {
|
||||||
type EmbedLinkedDocBlockProps,
|
type EmbedLinkedDocBlockProps,
|
||||||
@@ -20,3 +22,7 @@ export const EmbedLinkedDocBlockSchema = createEmbedBlockSchema({
|
|||||||
toModel: () => new EmbedLinkedDocModel(),
|
toModel: () => new EmbedLinkedDocModel(),
|
||||||
props: (): EmbedLinkedDocBlockProps => defaultEmbedLinkedDocBlockProps,
|
props: (): EmbedLinkedDocBlockProps => defaultEmbedLinkedDocBlockProps,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const EmbedLinkedDocBlockSchemaExtension = BlockSchemaExtension(
|
||||||
|
EmbedLinkedDocBlockSchema
|
||||||
|
);
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { BlockSchemaExtension } from '@blocksuite/store';
|
||||||
|
|
||||||
import { createEmbedBlockSchema } from '../../../utils/index.js';
|
import { createEmbedBlockSchema } from '../../../utils/index.js';
|
||||||
import {
|
import {
|
||||||
type EmbedLoomBlockProps,
|
type EmbedLoomBlockProps,
|
||||||
@@ -22,3 +24,6 @@ export const EmbedLoomBlockSchema = createEmbedBlockSchema({
|
|||||||
toModel: () => new EmbedLoomModel(),
|
toModel: () => new EmbedLoomModel(),
|
||||||
props: (): EmbedLoomBlockProps => defaultEmbedLoomProps,
|
props: (): EmbedLoomBlockProps => defaultEmbedLoomProps,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const EmbedLoomBlockSchemaExtension =
|
||||||
|
BlockSchemaExtension(EmbedLoomBlockSchema);
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { BlockSchemaExtension } from '@blocksuite/store';
|
||||||
|
|
||||||
import { createEmbedBlockSchema } from '../../../utils/index.js';
|
import { createEmbedBlockSchema } from '../../../utils/index.js';
|
||||||
import {
|
import {
|
||||||
type EmbedSyncedDocBlockProps,
|
type EmbedSyncedDocBlockProps,
|
||||||
@@ -21,3 +23,7 @@ export const EmbedSyncedDocBlockSchema = createEmbedBlockSchema({
|
|||||||
toModel: () => new EmbedSyncedDocModel(),
|
toModel: () => new EmbedSyncedDocModel(),
|
||||||
props: (): EmbedSyncedDocBlockProps => defaultEmbedSyncedDocBlockProps,
|
props: (): EmbedSyncedDocBlockProps => defaultEmbedSyncedDocBlockProps,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const EmbedSyncedDocBlockSchemaExtension = BlockSchemaExtension(
|
||||||
|
EmbedSyncedDocBlockSchema
|
||||||
|
);
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { BlockSchemaExtension } from '@blocksuite/store';
|
||||||
|
|
||||||
import { createEmbedBlockSchema } from '../../../utils/index.js';
|
import { createEmbedBlockSchema } from '../../../utils/index.js';
|
||||||
import {
|
import {
|
||||||
type EmbedYoutubeBlockProps,
|
type EmbedYoutubeBlockProps,
|
||||||
@@ -25,3 +27,7 @@ export const EmbedYoutubeBlockSchema = createEmbedBlockSchema({
|
|||||||
toModel: () => new EmbedYoutubeModel(),
|
toModel: () => new EmbedYoutubeModel(),
|
||||||
props: (): EmbedYoutubeBlockProps => defaultEmbedYoutubeProps,
|
props: (): EmbedYoutubeBlockProps => defaultEmbedYoutubeProps,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const EmbedYoutubeBlockSchemaExtension = BlockSchemaExtension(
|
||||||
|
EmbedYoutubeBlockSchema
|
||||||
|
);
|
||||||
|
|||||||
@@ -15,7 +15,12 @@ import {
|
|||||||
hasDescendantElementImpl,
|
hasDescendantElementImpl,
|
||||||
} from '@blocksuite/block-std/gfx';
|
} from '@blocksuite/block-std/gfx';
|
||||||
import { Bound } from '@blocksuite/global/utils';
|
import { Bound } from '@blocksuite/global/utils';
|
||||||
import { BlockModel, defineBlockSchema, type Text } from '@blocksuite/store';
|
import {
|
||||||
|
BlockModel,
|
||||||
|
BlockSchemaExtension,
|
||||||
|
defineBlockSchema,
|
||||||
|
type Text,
|
||||||
|
} from '@blocksuite/store';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
import { type Color, ColorSchema, DefaultTheme } from '../../themes/index.js';
|
import { type Color, ColorSchema, DefaultTheme } from '../../themes/index.js';
|
||||||
@@ -57,6 +62,8 @@ export const FrameBlockSchema = defineBlockSchema({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const FrameBlockSchemaExtension = BlockSchemaExtension(FrameBlockSchema);
|
||||||
|
|
||||||
export class FrameBlockModel
|
export class FrameBlockModel
|
||||||
extends GfxCompatible<FrameBlockProps>(BlockModel)
|
extends GfxCompatible<FrameBlockProps>(BlockModel)
|
||||||
implements GfxElementGeometry, GfxGroupCompatibleInterface
|
implements GfxElementGeometry, GfxGroupCompatibleInterface
|
||||||
|
|||||||
@@ -3,7 +3,11 @@ import type {
|
|||||||
GfxElementGeometry,
|
GfxElementGeometry,
|
||||||
} from '@blocksuite/block-std/gfx';
|
} from '@blocksuite/block-std/gfx';
|
||||||
import { GfxCompatible } from '@blocksuite/block-std/gfx';
|
import { GfxCompatible } from '@blocksuite/block-std/gfx';
|
||||||
import { BlockModel, defineBlockSchema } from '@blocksuite/store';
|
import {
|
||||||
|
BlockModel,
|
||||||
|
BlockSchemaExtension,
|
||||||
|
defineBlockSchema,
|
||||||
|
} from '@blocksuite/store';
|
||||||
|
|
||||||
import { ImageBlockTransformer } from './image-transformer.js';
|
import { ImageBlockTransformer } from './image-transformer.js';
|
||||||
|
|
||||||
@@ -40,6 +44,8 @@ export const ImageBlockSchema = defineBlockSchema({
|
|||||||
toModel: () => new ImageBlockModel(),
|
toModel: () => new ImageBlockModel(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const ImageBlockSchemaExtension = BlockSchemaExtension(ImageBlockSchema);
|
||||||
|
|
||||||
export class ImageBlockModel
|
export class ImageBlockModel
|
||||||
extends GfxCompatible<ImageBlockProps>(BlockModel)
|
extends GfxCompatible<ImageBlockProps>(BlockModel)
|
||||||
implements GfxElementGeometry {}
|
implements GfxElementGeometry {}
|
||||||
|
|||||||
@@ -3,7 +3,11 @@ import {
|
|||||||
GfxCompatible,
|
GfxCompatible,
|
||||||
type GfxElementGeometry,
|
type GfxElementGeometry,
|
||||||
} from '@blocksuite/block-std/gfx';
|
} from '@blocksuite/block-std/gfx';
|
||||||
import { BlockModel, defineBlockSchema } from '@blocksuite/store';
|
import {
|
||||||
|
BlockModel,
|
||||||
|
BlockSchemaExtension,
|
||||||
|
defineBlockSchema,
|
||||||
|
} from '@blocksuite/store';
|
||||||
|
|
||||||
export type LatexProps = {
|
export type LatexProps = {
|
||||||
latex: string;
|
latex: string;
|
||||||
@@ -34,6 +38,8 @@ export const LatexBlockSchema = defineBlockSchema({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const LatexBlockSchemaExtension = BlockSchemaExtension(LatexBlockSchema);
|
||||||
|
|
||||||
export class LatexBlockModel
|
export class LatexBlockModel
|
||||||
extends GfxCompatible<LatexProps>(BlockModel)
|
extends GfxCompatible<LatexProps>(BlockModel)
|
||||||
implements GfxElementGeometry {}
|
implements GfxElementGeometry {}
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
import type { Text } from '@blocksuite/store';
|
import type { Text } from '@blocksuite/store';
|
||||||
import { BlockModel, defineBlockSchema } from '@blocksuite/store';
|
import {
|
||||||
|
BlockModel,
|
||||||
|
BlockSchemaExtension,
|
||||||
|
defineBlockSchema,
|
||||||
|
} from '@blocksuite/store';
|
||||||
|
|
||||||
// `toggle` type has been deprecated, do not use it
|
// `toggle` type has been deprecated, do not use it
|
||||||
export type ListType = 'bulleted' | 'numbered' | 'todo' | 'toggle';
|
export type ListType = 'bulleted' | 'numbered' | 'todo' | 'toggle';
|
||||||
@@ -38,6 +42,8 @@ export const ListBlockSchema = defineBlockSchema({
|
|||||||
toModel: () => new ListBlockModel(),
|
toModel: () => new ListBlockModel(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const ListBlockSchemaExtension = BlockSchemaExtension(ListBlockSchema);
|
||||||
|
|
||||||
export class ListBlockModel extends BlockModel<ListProps> {
|
export class ListBlockModel extends BlockModel<ListProps> {
|
||||||
override text!: Text;
|
override text!: Text;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,11 @@ import type {
|
|||||||
} from '@blocksuite/block-std/gfx';
|
} from '@blocksuite/block-std/gfx';
|
||||||
import { GfxCompatible } from '@blocksuite/block-std/gfx';
|
import { GfxCompatible } from '@blocksuite/block-std/gfx';
|
||||||
import { Bound } from '@blocksuite/global/utils';
|
import { Bound } from '@blocksuite/global/utils';
|
||||||
import { BlockModel, defineBlockSchema } from '@blocksuite/store';
|
import {
|
||||||
|
BlockModel,
|
||||||
|
BlockSchemaExtension,
|
||||||
|
defineBlockSchema,
|
||||||
|
} from '@blocksuite/store';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -21,6 +25,7 @@ import {
|
|||||||
StrokeStyleSchema,
|
StrokeStyleSchema,
|
||||||
} from '../../consts/note';
|
} from '../../consts/note';
|
||||||
import { type Color, ColorSchema, DefaultTheme } from '../../themes';
|
import { type Color, ColorSchema, DefaultTheme } from '../../themes';
|
||||||
|
import { TableModelFlavour } from '../table';
|
||||||
|
|
||||||
export const NoteZodSchema = z
|
export const NoteZodSchema = z
|
||||||
.object({
|
.object({
|
||||||
@@ -47,7 +52,6 @@ export const NoteZodSchema = z
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
import { TableModelFlavour } from '../table';
|
|
||||||
|
|
||||||
export const NoteBlockSchema = defineBlockSchema({
|
export const NoteBlockSchema = defineBlockSchema({
|
||||||
flavour: 'affine:note',
|
flavour: 'affine:note',
|
||||||
@@ -92,6 +96,7 @@ export const NoteBlockSchema = defineBlockSchema({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const NoteBlockSchemaExtension = BlockSchemaExtension(NoteBlockSchema);
|
||||||
export type NoteProps = {
|
export type NoteProps = {
|
||||||
background: Color;
|
background: Color;
|
||||||
displayMode: NoteDisplayMode;
|
displayMode: NoteDisplayMode;
|
||||||
|
|||||||
@@ -1,4 +1,9 @@
|
|||||||
import { BlockModel, defineBlockSchema, type Text } from '@blocksuite/store';
|
import {
|
||||||
|
BlockModel,
|
||||||
|
BlockSchemaExtension,
|
||||||
|
defineBlockSchema,
|
||||||
|
type Text,
|
||||||
|
} from '@blocksuite/store';
|
||||||
|
|
||||||
export type ParagraphType =
|
export type ParagraphType =
|
||||||
| 'text'
|
| 'text'
|
||||||
@@ -37,6 +42,9 @@ export const ParagraphBlockSchema = defineBlockSchema({
|
|||||||
toModel: () => new ParagraphBlockModel(),
|
toModel: () => new ParagraphBlockModel(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const ParagraphBlockSchemaExtension =
|
||||||
|
BlockSchemaExtension(ParagraphBlockSchema);
|
||||||
|
|
||||||
export class ParagraphBlockModel extends BlockModel<ParagraphProps> {
|
export class ParagraphBlockModel extends BlockModel<ParagraphProps> {
|
||||||
override text!: Text;
|
override text!: Text;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
import type { Text } from '@blocksuite/store';
|
import type { Text } from '@blocksuite/store';
|
||||||
import { BlockModel, defineBlockSchema } from '@blocksuite/store';
|
import {
|
||||||
|
BlockModel,
|
||||||
|
BlockSchemaExtension,
|
||||||
|
defineBlockSchema,
|
||||||
|
} from '@blocksuite/store';
|
||||||
|
|
||||||
export type RootBlockProps = {
|
export type RootBlockProps = {
|
||||||
title: Text;
|
title: Text;
|
||||||
@@ -51,3 +55,5 @@ export const RootBlockSchema = defineBlockSchema({
|
|||||||
},
|
},
|
||||||
toModel: () => new RootBlockModel(),
|
toModel: () => new RootBlockModel(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const RootBlockSchemaExtension = BlockSchemaExtension(RootBlockSchema);
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
import { BlockModel, defineBlockSchema } from '@blocksuite/store';
|
import {
|
||||||
|
BlockModel,
|
||||||
|
BlockSchemaExtension,
|
||||||
|
defineBlockSchema,
|
||||||
|
} from '@blocksuite/store';
|
||||||
|
|
||||||
export type SurfaceRefProps = {
|
export type SurfaceRefProps = {
|
||||||
reference: string;
|
reference: string;
|
||||||
@@ -21,4 +25,8 @@ export const SurfaceRefBlockSchema = defineBlockSchema({
|
|||||||
toModel: () => new SurfaceRefBlockModel(),
|
toModel: () => new SurfaceRefBlockModel(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const SurfaceRefBlockSchemaExtension = BlockSchemaExtension(
|
||||||
|
SurfaceRefBlockSchema
|
||||||
|
);
|
||||||
|
|
||||||
export class SurfaceRefBlockModel extends BlockModel<SurfaceRefProps> {}
|
export class SurfaceRefBlockModel extends BlockModel<SurfaceRefProps> {}
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
import type { DeltaInsert } from '@blocksuite/inline';
|
import type { DeltaInsert } from '@blocksuite/inline';
|
||||||
import type { Text } from '@blocksuite/store';
|
import type { Text } from '@blocksuite/store';
|
||||||
import { BlockModel, defineBlockSchema } from '@blocksuite/store';
|
import {
|
||||||
|
BlockModel,
|
||||||
|
BlockSchemaExtension,
|
||||||
|
defineBlockSchema,
|
||||||
|
} from '@blocksuite/store';
|
||||||
|
|
||||||
export type TableCell = {
|
export type TableCell = {
|
||||||
text: Text;
|
text: Text;
|
||||||
@@ -56,3 +60,5 @@ export const TableBlockSchema = defineBlockSchema({
|
|||||||
},
|
},
|
||||||
toModel: () => new TableBlockModel(),
|
toModel: () => new TableBlockModel(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const TableBlockSchemaExtension = BlockSchemaExtension(TableBlockSchema);
|
||||||
|
|||||||
@@ -4,8 +4,11 @@ import type { SliceSnapshot } from '@blocksuite/store';
|
|||||||
import { describe, expect, test } from 'vitest';
|
import { describe, expect, test } from 'vitest';
|
||||||
|
|
||||||
import { createJob } from '../utils/create-job.js';
|
import { createJob } from '../utils/create-job.js';
|
||||||
|
import { getProvider } from '../utils/get-provider.js';
|
||||||
import { nanoidReplacement } from '../utils/nanoid-replacement.js';
|
import { nanoidReplacement } from '../utils/nanoid-replacement.js';
|
||||||
|
|
||||||
|
getProvider();
|
||||||
|
|
||||||
describe('notion-text to snapshot', () => {
|
describe('notion-text to snapshot', () => {
|
||||||
test('basic', () => {
|
test('basic', () => {
|
||||||
const notionText =
|
const notionText =
|
||||||
|
|||||||
@@ -11,39 +11,37 @@ import {
|
|||||||
type Cell,
|
type Cell,
|
||||||
type Column,
|
type Column,
|
||||||
type DatabaseBlockModel,
|
type DatabaseBlockModel,
|
||||||
DatabaseBlockSchema,
|
DatabaseBlockSchemaExtension,
|
||||||
NoteBlockSchema,
|
NoteBlockSchemaExtension,
|
||||||
ParagraphBlockSchema,
|
ParagraphBlockSchemaExtension,
|
||||||
RootBlockSchema,
|
RootBlockSchemaExtension,
|
||||||
} from '@blocksuite/affine-model';
|
} from '@blocksuite/affine-model';
|
||||||
import { propertyModelPresets } from '@blocksuite/data-view/property-pure-presets';
|
import { propertyModelPresets } from '@blocksuite/data-view/property-pure-presets';
|
||||||
import type { BlockModel, Store } from '@blocksuite/store';
|
import type { BlockModel, Store } from '@blocksuite/store';
|
||||||
import { Schema, Text } from '@blocksuite/store';
|
import { Text } from '@blocksuite/store';
|
||||||
import {
|
import {
|
||||||
createAutoIncrementIdGenerator,
|
createAutoIncrementIdGenerator,
|
||||||
TestWorkspace,
|
TestWorkspace,
|
||||||
} from '@blocksuite/store/test';
|
} from '@blocksuite/store/test';
|
||||||
import { beforeEach, describe, expect, test } from 'vitest';
|
import { beforeEach, describe, expect, test } from 'vitest';
|
||||||
|
|
||||||
const AffineSchemas = [
|
const extensions = [
|
||||||
RootBlockSchema,
|
RootBlockSchemaExtension,
|
||||||
NoteBlockSchema,
|
NoteBlockSchemaExtension,
|
||||||
ParagraphBlockSchema,
|
ParagraphBlockSchemaExtension,
|
||||||
DatabaseBlockSchema,
|
DatabaseBlockSchemaExtension,
|
||||||
];
|
];
|
||||||
|
|
||||||
function createTestOptions() {
|
function createTestOptions() {
|
||||||
const idGenerator = createAutoIncrementIdGenerator();
|
const idGenerator = createAutoIncrementIdGenerator();
|
||||||
const schema = new Schema();
|
return { id: 'test-collection', idGenerator };
|
||||||
schema.register(AffineSchemas);
|
|
||||||
return { id: 'test-collection', idGenerator, schema };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function createTestDoc(docId = 'doc0') {
|
function createTestDoc(docId = 'doc0') {
|
||||||
const options = createTestOptions();
|
const options = createTestOptions();
|
||||||
const collection = new TestWorkspace(options);
|
const collection = new TestWorkspace(options);
|
||||||
collection.meta.initialize();
|
collection.meta.initialize();
|
||||||
const doc = collection.createDoc({ id: docId });
|
const doc = collection.createDoc({ id: docId, extensions });
|
||||||
doc.load();
|
doc.load();
|
||||||
return doc;
|
return doc;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { defaultImageProxyMiddleware } from '@blocksuite/affine-block-image';
|
import { defaultImageProxyMiddleware } from '@blocksuite/affine-block-image';
|
||||||
import { FeatureFlagService } from '@blocksuite/affine-shared/services';
|
import { SpecProvider } from '@blocksuite/affine-shared/utils';
|
||||||
import {
|
import {
|
||||||
Schema,
|
Schema,
|
||||||
Transformer,
|
Transformer,
|
||||||
@@ -26,8 +26,8 @@ export function createJob(middlewares?: TransformerMiddleware[]) {
|
|||||||
const testMiddlewares = middlewares ?? [];
|
const testMiddlewares = middlewares ?? [];
|
||||||
testMiddlewares.push(defaultImageProxyMiddleware);
|
testMiddlewares.push(defaultImageProxyMiddleware);
|
||||||
const schema = new Schema().register(AffineSchemas);
|
const schema = new Schema().register(AffineSchemas);
|
||||||
const docCollection = new TestWorkspace({ schema });
|
const docCollection = new TestWorkspace();
|
||||||
docCollection.storeExtensions = [FeatureFlagService];
|
docCollection.storeExtensions = SpecProvider._.getSpec('store').value;
|
||||||
docCollection.meta.initialize();
|
docCollection.meta.initialize();
|
||||||
return new Transformer({
|
return new Transformer({
|
||||||
schema,
|
schema,
|
||||||
|
|||||||
@@ -2,15 +2,12 @@ import { AttachmentBlockSpec } from '@blocksuite/affine-block-attachment';
|
|||||||
import { BookmarkBlockSpec } from '@blocksuite/affine-block-bookmark';
|
import { BookmarkBlockSpec } from '@blocksuite/affine-block-bookmark';
|
||||||
import { CodeBlockSpec } from '@blocksuite/affine-block-code';
|
import { CodeBlockSpec } from '@blocksuite/affine-block-code';
|
||||||
import { DataViewBlockSpec } from '@blocksuite/affine-block-data-view';
|
import { DataViewBlockSpec } from '@blocksuite/affine-block-data-view';
|
||||||
import {
|
import { DatabaseBlockSpec } from '@blocksuite/affine-block-database';
|
||||||
DatabaseBlockSpec,
|
|
||||||
DatabaseSelectionExtension,
|
|
||||||
} from '@blocksuite/affine-block-database';
|
|
||||||
import { DividerBlockSpec } from '@blocksuite/affine-block-divider';
|
import { DividerBlockSpec } from '@blocksuite/affine-block-divider';
|
||||||
import { EdgelessTextBlockSpec } from '@blocksuite/affine-block-edgeless-text';
|
import { EdgelessTextBlockSpec } from '@blocksuite/affine-block-edgeless-text';
|
||||||
import { EmbedExtensions } from '@blocksuite/affine-block-embed';
|
import { EmbedExtensions } from '@blocksuite/affine-block-embed';
|
||||||
import { FrameBlockSpec } from '@blocksuite/affine-block-frame';
|
import { FrameBlockSpec } from '@blocksuite/affine-block-frame';
|
||||||
import { ImageBlockSpec, ImageStoreSpec } from '@blocksuite/affine-block-image';
|
import { ImageBlockSpec } from '@blocksuite/affine-block-image';
|
||||||
import { LatexBlockSpec } from '@blocksuite/affine-block-latex';
|
import { LatexBlockSpec } from '@blocksuite/affine-block-latex';
|
||||||
import { ListBlockSpec } from '@blocksuite/affine-block-list';
|
import { ListBlockSpec } from '@blocksuite/affine-block-list';
|
||||||
import {
|
import {
|
||||||
@@ -26,43 +23,19 @@ import {
|
|||||||
EdgelessSurfaceRefBlockSpec,
|
EdgelessSurfaceRefBlockSpec,
|
||||||
PageSurfaceRefBlockSpec,
|
PageSurfaceRefBlockSpec,
|
||||||
} from '@blocksuite/affine-block-surface-ref';
|
} from '@blocksuite/affine-block-surface-ref';
|
||||||
import {
|
import { TableBlockSpec } from '@blocksuite/affine-block-table';
|
||||||
TableBlockSpec,
|
|
||||||
TableSelectionExtension,
|
|
||||||
} from '@blocksuite/affine-block-table';
|
|
||||||
import {
|
import {
|
||||||
RefNodeSlotsExtension,
|
RefNodeSlotsExtension,
|
||||||
RichTextExtensions,
|
RichTextExtensions,
|
||||||
} from '@blocksuite/affine-components/rich-text';
|
} from '@blocksuite/affine-components/rich-text';
|
||||||
import {
|
|
||||||
HighlightSelectionExtension,
|
|
||||||
ImageSelectionExtension,
|
|
||||||
} from '@blocksuite/affine-shared/selection';
|
|
||||||
import {
|
import {
|
||||||
DefaultOpenDocExtension,
|
DefaultOpenDocExtension,
|
||||||
DocDisplayMetaService,
|
DocDisplayMetaService,
|
||||||
EditPropsStore,
|
EditPropsStore,
|
||||||
FeatureFlagService,
|
|
||||||
FileSizeLimitService,
|
|
||||||
FontLoaderService,
|
FontLoaderService,
|
||||||
LinkPreviewerService,
|
|
||||||
} from '@blocksuite/affine-shared/services';
|
} from '@blocksuite/affine-shared/services';
|
||||||
import {
|
|
||||||
BlockSelectionExtension,
|
|
||||||
CursorSelectionExtension,
|
|
||||||
SurfaceSelectionExtension,
|
|
||||||
TextSelectionExtension,
|
|
||||||
} from '@blocksuite/block-std';
|
|
||||||
import type { ExtensionType } from '@blocksuite/store';
|
import type { ExtensionType } from '@blocksuite/store';
|
||||||
|
|
||||||
import {
|
|
||||||
AdapterFactoryExtensions,
|
|
||||||
HtmlAdapterExtension,
|
|
||||||
MarkdownAdapterExtension,
|
|
||||||
NotionHtmlAdapterExtension,
|
|
||||||
PlainTextAdapterExtension,
|
|
||||||
} from '../adapters/extension.js';
|
|
||||||
|
|
||||||
export const CommonBlockSpecs: ExtensionType[] = [
|
export const CommonBlockSpecs: ExtensionType[] = [
|
||||||
DocDisplayMetaService,
|
DocDisplayMetaService,
|
||||||
RefNodeSlotsExtension,
|
RefNodeSlotsExtension,
|
||||||
@@ -82,7 +55,6 @@ export const CommonBlockSpecs: ExtensionType[] = [
|
|||||||
ParagraphBlockSpec,
|
ParagraphBlockSpec,
|
||||||
DefaultOpenDocExtension,
|
DefaultOpenDocExtension,
|
||||||
FontLoaderService,
|
FontLoaderService,
|
||||||
AdapterFactoryExtensions,
|
|
||||||
].flat();
|
].flat();
|
||||||
|
|
||||||
export const PageFirstPartyBlockSpecs: ExtensionType[] = [
|
export const PageFirstPartyBlockSpecs: ExtensionType[] = [
|
||||||
@@ -101,24 +73,3 @@ export const EdgelessFirstPartyBlockSpecs: ExtensionType[] = [
|
|||||||
FrameBlockSpec,
|
FrameBlockSpec,
|
||||||
EdgelessTextBlockSpec,
|
EdgelessTextBlockSpec,
|
||||||
].flat();
|
].flat();
|
||||||
|
|
||||||
export const StoreExtensions: ExtensionType[] = [
|
|
||||||
BlockSelectionExtension,
|
|
||||||
TextSelectionExtension,
|
|
||||||
SurfaceSelectionExtension,
|
|
||||||
CursorSelectionExtension,
|
|
||||||
HighlightSelectionExtension,
|
|
||||||
ImageSelectionExtension,
|
|
||||||
DatabaseSelectionExtension,
|
|
||||||
TableSelectionExtension,
|
|
||||||
|
|
||||||
FeatureFlagService,
|
|
||||||
LinkPreviewerService,
|
|
||||||
FileSizeLimitService,
|
|
||||||
ImageStoreSpec,
|
|
||||||
|
|
||||||
HtmlAdapterExtension,
|
|
||||||
MarkdownAdapterExtension,
|
|
||||||
NotionHtmlAdapterExtension,
|
|
||||||
PlainTextAdapterExtension,
|
|
||||||
].flat();
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
export * from './common.js';
|
export * from './common.js';
|
||||||
export * from './editor-specs.js';
|
export * from './editor-specs.js';
|
||||||
export * from './preview-specs.js';
|
export * from './preview-specs.js';
|
||||||
|
export * from './store.js';
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { SpecProvider } from '@blocksuite/affine-shared/utils';
|
import { SpecProvider } from '@blocksuite/affine-shared/utils';
|
||||||
|
|
||||||
import { StoreExtensions } from './common.js';
|
|
||||||
import {
|
import {
|
||||||
EdgelessEditorBlockSpecs,
|
EdgelessEditorBlockSpecs,
|
||||||
PageEditorBlockSpecs,
|
PageEditorBlockSpecs,
|
||||||
@@ -9,6 +8,7 @@ import {
|
|||||||
PreviewEdgelessEditorBlockSpecs,
|
PreviewEdgelessEditorBlockSpecs,
|
||||||
PreviewPageEditorBlockSpecs,
|
PreviewPageEditorBlockSpecs,
|
||||||
} from './preview-specs.js';
|
} from './preview-specs.js';
|
||||||
|
import { StoreExtensions } from './store.js';
|
||||||
|
|
||||||
export function registerSpecs() {
|
export function registerSpecs() {
|
||||||
SpecProvider._.addSpec('store', StoreExtensions);
|
SpecProvider._.addSpec('store', StoreExtensions);
|
||||||
|
|||||||
101
blocksuite/blocks/src/extensions/store.ts
Normal file
101
blocksuite/blocks/src/extensions/store.ts
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
import { DataViewBlockSchemaExtension } from '@blocksuite/affine-block-data-view';
|
||||||
|
import { DatabaseSelectionExtension } from '@blocksuite/affine-block-database';
|
||||||
|
import { ImageStoreSpec } from '@blocksuite/affine-block-image';
|
||||||
|
import { SurfaceBlockSchemaExtension } from '@blocksuite/affine-block-surface';
|
||||||
|
import { TableSelectionExtension } from '@blocksuite/affine-block-table';
|
||||||
|
import {
|
||||||
|
AttachmentBlockSchemaExtension,
|
||||||
|
BookmarkBlockSchemaExtension,
|
||||||
|
CodeBlockSchemaExtension,
|
||||||
|
DatabaseBlockSchemaExtension,
|
||||||
|
DividerBlockSchemaExtension,
|
||||||
|
EdgelessTextBlockSchemaExtension,
|
||||||
|
EmbedFigmaBlockSchemaExtension,
|
||||||
|
EmbedGithubBlockSchemaExtension,
|
||||||
|
EmbedHtmlBlockSchemaExtension,
|
||||||
|
EmbedLinkedDocBlockSchemaExtension,
|
||||||
|
EmbedLoomBlockSchemaExtension,
|
||||||
|
EmbedSyncedDocBlockSchemaExtension,
|
||||||
|
EmbedYoutubeBlockSchemaExtension,
|
||||||
|
FrameBlockSchemaExtension,
|
||||||
|
ImageBlockSchemaExtension,
|
||||||
|
LatexBlockSchemaExtension,
|
||||||
|
ListBlockSchemaExtension,
|
||||||
|
NoteBlockSchemaExtension,
|
||||||
|
ParagraphBlockSchemaExtension,
|
||||||
|
RootBlockSchemaExtension,
|
||||||
|
SurfaceRefBlockSchemaExtension,
|
||||||
|
TableBlockSchemaExtension,
|
||||||
|
} from '@blocksuite/affine-model';
|
||||||
|
import {
|
||||||
|
HighlightSelectionExtension,
|
||||||
|
ImageSelectionExtension,
|
||||||
|
} from '@blocksuite/affine-shared/selection';
|
||||||
|
import {
|
||||||
|
FeatureFlagService,
|
||||||
|
FileSizeLimitService,
|
||||||
|
LinkPreviewerService,
|
||||||
|
} from '@blocksuite/affine-shared/services';
|
||||||
|
import {
|
||||||
|
BlockSelectionExtension,
|
||||||
|
CursorSelectionExtension,
|
||||||
|
SurfaceSelectionExtension,
|
||||||
|
TextSelectionExtension,
|
||||||
|
} from '@blocksuite/block-std';
|
||||||
|
import type { ExtensionType } from '@blocksuite/store';
|
||||||
|
|
||||||
|
import {
|
||||||
|
AdapterFactoryExtensions,
|
||||||
|
HtmlAdapterExtension,
|
||||||
|
MarkdownAdapterExtension,
|
||||||
|
NotionHtmlAdapterExtension,
|
||||||
|
PlainTextAdapterExtension,
|
||||||
|
} from '../adapters/extension.js';
|
||||||
|
|
||||||
|
export const StoreExtensions: ExtensionType[] = [
|
||||||
|
CodeBlockSchemaExtension,
|
||||||
|
ParagraphBlockSchemaExtension,
|
||||||
|
RootBlockSchemaExtension,
|
||||||
|
ListBlockSchemaExtension,
|
||||||
|
NoteBlockSchemaExtension,
|
||||||
|
DividerBlockSchemaExtension,
|
||||||
|
ImageBlockSchemaExtension,
|
||||||
|
SurfaceBlockSchemaExtension,
|
||||||
|
BookmarkBlockSchemaExtension,
|
||||||
|
FrameBlockSchemaExtension,
|
||||||
|
DatabaseBlockSchemaExtension,
|
||||||
|
SurfaceRefBlockSchemaExtension,
|
||||||
|
DataViewBlockSchemaExtension,
|
||||||
|
AttachmentBlockSchemaExtension,
|
||||||
|
EmbedSyncedDocBlockSchemaExtension,
|
||||||
|
EmbedLinkedDocBlockSchemaExtension,
|
||||||
|
EmbedHtmlBlockSchemaExtension,
|
||||||
|
EmbedGithubBlockSchemaExtension,
|
||||||
|
EmbedFigmaBlockSchemaExtension,
|
||||||
|
EmbedLoomBlockSchemaExtension,
|
||||||
|
EmbedYoutubeBlockSchemaExtension,
|
||||||
|
EdgelessTextBlockSchemaExtension,
|
||||||
|
LatexBlockSchemaExtension,
|
||||||
|
TableBlockSchemaExtension,
|
||||||
|
|
||||||
|
BlockSelectionExtension,
|
||||||
|
TextSelectionExtension,
|
||||||
|
SurfaceSelectionExtension,
|
||||||
|
CursorSelectionExtension,
|
||||||
|
HighlightSelectionExtension,
|
||||||
|
ImageSelectionExtension,
|
||||||
|
DatabaseSelectionExtension,
|
||||||
|
TableSelectionExtension,
|
||||||
|
|
||||||
|
FeatureFlagService,
|
||||||
|
LinkPreviewerService,
|
||||||
|
FileSizeLimitService,
|
||||||
|
ImageStoreSpec,
|
||||||
|
|
||||||
|
HtmlAdapterExtension,
|
||||||
|
MarkdownAdapterExtension,
|
||||||
|
NotionHtmlAdapterExtension,
|
||||||
|
PlainTextAdapterExtension,
|
||||||
|
|
||||||
|
AdapterFactoryExtensions,
|
||||||
|
].flat();
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
import { Schema } from '@blocksuite/store';
|
|
||||||
import {
|
import {
|
||||||
createAutoIncrementIdGenerator,
|
createAutoIncrementIdGenerator,
|
||||||
TestWorkspace,
|
TestWorkspace,
|
||||||
@@ -9,19 +8,23 @@ import { effects } from '../effects.js';
|
|||||||
import { TestEditorContainer } from './test-editor.js';
|
import { TestEditorContainer } from './test-editor.js';
|
||||||
import {
|
import {
|
||||||
type HeadingBlockModel,
|
type HeadingBlockModel,
|
||||||
HeadingBlockSchema,
|
HeadingBlockSchemaExtension,
|
||||||
NoteBlockSchema,
|
NoteBlockSchemaExtension,
|
||||||
RootBlockSchema,
|
RootBlockSchemaExtension,
|
||||||
} from './test-schema.js';
|
} from './test-schema.js';
|
||||||
import { testSpecs } from './test-spec.js';
|
import { testSpecs } from './test-spec.js';
|
||||||
|
|
||||||
effects();
|
effects();
|
||||||
|
|
||||||
|
const extensions = [
|
||||||
|
RootBlockSchemaExtension,
|
||||||
|
NoteBlockSchemaExtension,
|
||||||
|
HeadingBlockSchemaExtension,
|
||||||
|
];
|
||||||
|
|
||||||
function createTestOptions() {
|
function createTestOptions() {
|
||||||
const idGenerator = createAutoIncrementIdGenerator();
|
const idGenerator = createAutoIncrementIdGenerator();
|
||||||
const schema = new Schema();
|
return { id: 'test-collection', idGenerator };
|
||||||
schema.register([RootBlockSchema, NoteBlockSchema, HeadingBlockSchema]);
|
|
||||||
return { id: 'test-collection', idGenerator, schema };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function wait(time: number) {
|
function wait(time: number) {
|
||||||
@@ -33,7 +36,7 @@ describe('editor host', () => {
|
|||||||
const collection = new TestWorkspace(createTestOptions());
|
const collection = new TestWorkspace(createTestOptions());
|
||||||
|
|
||||||
collection.meta.initialize();
|
collection.meta.initialize();
|
||||||
const doc = collection.createDoc({ id: 'home' });
|
const doc = collection.createDoc({ id: 'home', extensions });
|
||||||
doc.load();
|
doc.load();
|
||||||
const rootId = doc.addBlock('test:page');
|
const rootId = doc.addBlock('test:page');
|
||||||
const noteId = doc.addBlock('test:note', {}, rootId);
|
const noteId = doc.addBlock('test:note', {}, rootId);
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
import { BlockModel, defineBlockSchema } from '@blocksuite/store';
|
import {
|
||||||
|
BlockModel,
|
||||||
|
BlockSchemaExtension,
|
||||||
|
defineBlockSchema,
|
||||||
|
} from '@blocksuite/store';
|
||||||
|
|
||||||
export const RootBlockSchema = defineBlockSchema({
|
export const RootBlockSchema = defineBlockSchema({
|
||||||
flavour: 'test:page',
|
flavour: 'test:page',
|
||||||
@@ -15,6 +19,8 @@ export const RootBlockSchema = defineBlockSchema({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const RootBlockSchemaExtension = BlockSchemaExtension(RootBlockSchema);
|
||||||
|
|
||||||
export class RootBlockModel extends BlockModel<
|
export class RootBlockModel extends BlockModel<
|
||||||
ReturnType<(typeof RootBlockSchema)['model']['props']>
|
ReturnType<(typeof RootBlockSchema)['model']['props']>
|
||||||
> {}
|
> {}
|
||||||
@@ -30,6 +36,8 @@ export const NoteBlockSchema = defineBlockSchema({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const NoteBlockSchemaExtension = BlockSchemaExtension(NoteBlockSchema);
|
||||||
|
|
||||||
export class NoteBlockModel extends BlockModel<
|
export class NoteBlockModel extends BlockModel<
|
||||||
ReturnType<(typeof NoteBlockSchema)['model']['props']>
|
ReturnType<(typeof NoteBlockSchema)['model']['props']>
|
||||||
> {}
|
> {}
|
||||||
@@ -47,6 +55,9 @@ export const HeadingBlockSchema = defineBlockSchema({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const HeadingBlockSchemaExtension =
|
||||||
|
BlockSchemaExtension(HeadingBlockSchema);
|
||||||
|
|
||||||
export class HeadingBlockModel extends BlockModel<
|
export class HeadingBlockModel extends BlockModel<
|
||||||
ReturnType<(typeof HeadingBlockSchema)['model']['props']>
|
ReturnType<(typeof HeadingBlockSchema)['model']['props']>
|
||||||
> {}
|
> {}
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ export class BlockStdScope {
|
|||||||
|
|
||||||
getTransformer(middlewares: TransformerMiddleware[] = []) {
|
getTransformer(middlewares: TransformerMiddleware[] = []) {
|
||||||
return new Transformer({
|
return new Transformer({
|
||||||
schema: this.workspace.schema,
|
schema: this.store.schema,
|
||||||
blobCRUD: this.workspace.blobSync,
|
blobCRUD: this.workspace.blobSync,
|
||||||
docCRUD: {
|
docCRUD: {
|
||||||
create: (id: string) => this.workspace.createDoc({ id }),
|
create: (id: string) => this.workspace.createDoc({ id }),
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { computed, effect } from '@preact/signals-core';
|
|||||||
import { describe, expect, test, vi } from 'vitest';
|
import { describe, expect, test, vi } from 'vitest';
|
||||||
import * as Y from 'yjs';
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
|
import { BlockSchemaExtension } from '../extension/schema.js';
|
||||||
import {
|
import {
|
||||||
Block,
|
Block,
|
||||||
BlockModel,
|
BlockModel,
|
||||||
@@ -9,7 +10,6 @@ import {
|
|||||||
internalPrimitives,
|
internalPrimitives,
|
||||||
} from '../model/block/index.js';
|
} from '../model/block/index.js';
|
||||||
import type { YBlock } from '../model/block/types.js';
|
import type { YBlock } from '../model/block/types.js';
|
||||||
import { Schema } from '../schema/index.js';
|
|
||||||
import { createAutoIncrementIdGenerator } from '../test/index.js';
|
import { createAutoIncrementIdGenerator } from '../test/index.js';
|
||||||
import { TestWorkspace } from '../test/test-workspace.js';
|
import { TestWorkspace } from '../test/test-workspace.js';
|
||||||
|
|
||||||
@@ -27,6 +27,7 @@ const pageSchema = defineBlockSchema({
|
|||||||
version: 1,
|
version: 1,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
const pageSchemaExtension = BlockSchemaExtension(pageSchema);
|
||||||
|
|
||||||
const tableSchema = defineBlockSchema({
|
const tableSchema = defineBlockSchema({
|
||||||
flavour: 'table',
|
flavour: 'table',
|
||||||
@@ -39,6 +40,7 @@ const tableSchema = defineBlockSchema({
|
|||||||
version: 1,
|
version: 1,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
const tableSchemaExtension = BlockSchemaExtension(tableSchema);
|
||||||
|
|
||||||
const flatTableSchema = defineBlockSchema({
|
const flatTableSchema = defineBlockSchema({
|
||||||
flavour: 'flat-table',
|
flavour: 'flat-table',
|
||||||
@@ -54,6 +56,8 @@ const flatTableSchema = defineBlockSchema({
|
|||||||
isFlatData: true,
|
isFlatData: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
const flatTableSchemaExtension = BlockSchemaExtension(flatTableSchema);
|
||||||
|
|
||||||
class RootModel extends BlockModel<
|
class RootModel extends BlockModel<
|
||||||
ReturnType<(typeof pageSchema)['model']['props']>
|
ReturnType<(typeof pageSchema)['model']['props']>
|
||||||
> {}
|
> {}
|
||||||
@@ -66,9 +70,7 @@ class FlatTableModel extends BlockModel<
|
|||||||
|
|
||||||
function createTestOptions() {
|
function createTestOptions() {
|
||||||
const idGenerator = createAutoIncrementIdGenerator();
|
const idGenerator = createAutoIncrementIdGenerator();
|
||||||
const schema = new Schema();
|
return { id: 'test-collection', idGenerator };
|
||||||
schema.register([pageSchema, tableSchema, flatTableSchema]);
|
|
||||||
return { id: 'test-collection', idGenerator, schema };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultDocId = 'doc:home';
|
const defaultDocId = 'doc:home';
|
||||||
@@ -76,7 +78,14 @@ function createTestDoc(docId = defaultDocId) {
|
|||||||
const options = createTestOptions();
|
const options = createTestOptions();
|
||||||
const collection = new TestWorkspace(options);
|
const collection = new TestWorkspace(options);
|
||||||
collection.meta.initialize();
|
collection.meta.initialize();
|
||||||
const doc = collection.createDoc({ id: docId });
|
const doc = collection.createDoc({
|
||||||
|
id: docId,
|
||||||
|
extensions: [
|
||||||
|
pageSchemaExtension,
|
||||||
|
tableSchemaExtension,
|
||||||
|
flatTableSchemaExtension,
|
||||||
|
],
|
||||||
|
});
|
||||||
doc.load();
|
doc.load();
|
||||||
return doc;
|
return doc;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,29 +4,20 @@ import type { Slot } from '@blocksuite/global/utils';
|
|||||||
import { assert, beforeEach, describe, expect, it, vi } from 'vitest';
|
import { assert, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||||
import { applyUpdate, type Doc, encodeStateAsUpdate } from 'yjs';
|
import { applyUpdate, type Doc, encodeStateAsUpdate } from 'yjs';
|
||||||
|
|
||||||
import type { BlockModel, BlockSchemaType, DocMeta, Store } from '../index.js';
|
import type { BlockModel, DocMeta, Store } from '../index.js';
|
||||||
import { Schema } from '../index.js';
|
|
||||||
import { Text } from '../reactive/text.js';
|
import { Text } from '../reactive/text.js';
|
||||||
import { createAutoIncrementIdGenerator } from '../test/index.js';
|
import { createAutoIncrementIdGenerator } from '../test/index.js';
|
||||||
import { TestWorkspace } from '../test/test-workspace.js';
|
import { TestWorkspace } from '../test/test-workspace.js';
|
||||||
import {
|
import {
|
||||||
NoteBlockSchema,
|
NoteBlockSchemaExtension,
|
||||||
ParagraphBlockSchema,
|
ParagraphBlockSchemaExtension,
|
||||||
RootBlockSchema,
|
RootBlockSchemaExtension,
|
||||||
} from './test-schema.js';
|
} from './test-schema.js';
|
||||||
import { assertExists } from './test-utils-dom.js';
|
import { assertExists } from './test-utils-dom.js';
|
||||||
|
|
||||||
export const BlockSchemas = [
|
|
||||||
ParagraphBlockSchema,
|
|
||||||
RootBlockSchema,
|
|
||||||
NoteBlockSchema,
|
|
||||||
] as BlockSchemaType[];
|
|
||||||
|
|
||||||
function createTestOptions() {
|
function createTestOptions() {
|
||||||
const idGenerator = createAutoIncrementIdGenerator();
|
const idGenerator = createAutoIncrementIdGenerator();
|
||||||
const schema = new Schema();
|
return { id: 'test-collection', idGenerator };
|
||||||
schema.register(BlockSchemas);
|
|
||||||
return { id: 'test-collection', idGenerator, schema };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultDocId = 'doc:home';
|
const defaultDocId = 'doc:home';
|
||||||
@@ -58,11 +49,20 @@ function createRoot(doc: Store) {
|
|||||||
return doc.root;
|
return doc.root;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const extensions = [
|
||||||
|
NoteBlockSchemaExtension,
|
||||||
|
ParagraphBlockSchemaExtension,
|
||||||
|
RootBlockSchemaExtension,
|
||||||
|
];
|
||||||
|
|
||||||
function createTestDoc(docId = defaultDocId) {
|
function createTestDoc(docId = defaultDocId) {
|
||||||
const options = createTestOptions();
|
const options = createTestOptions();
|
||||||
const collection = new TestWorkspace(options);
|
const collection = new TestWorkspace(options);
|
||||||
collection.meta.initialize();
|
collection.meta.initialize();
|
||||||
const doc = collection.createDoc({ id: docId });
|
const doc = collection.createDoc({
|
||||||
|
id: docId,
|
||||||
|
extensions,
|
||||||
|
});
|
||||||
doc.load();
|
doc.load();
|
||||||
return doc;
|
return doc;
|
||||||
}
|
}
|
||||||
@@ -113,13 +113,6 @@ describe('basic', () => {
|
|||||||
tags: [],
|
tags: [],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
workspaceVersion: 2,
|
|
||||||
pageVersion: 2,
|
|
||||||
blockVersions: {
|
|
||||||
'affine:note': 1,
|
|
||||||
'affine:page': 2,
|
|
||||||
'affine:paragraph': 1,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
spaces: {
|
spaces: {
|
||||||
[spaceId]: {
|
[spaceId]: {
|
||||||
@@ -155,6 +148,7 @@ describe('basic', () => {
|
|||||||
collection.meta.initialize();
|
collection.meta.initialize();
|
||||||
const doc = collection.createDoc({
|
const doc = collection.createDoc({
|
||||||
id: 'space:0',
|
id: 'space:0',
|
||||||
|
extensions,
|
||||||
});
|
});
|
||||||
|
|
||||||
const readyCallback = vi.fn();
|
const readyCallback = vi.fn();
|
||||||
@@ -181,6 +175,7 @@ describe('basic', () => {
|
|||||||
const collection2 = new TestWorkspace(options);
|
const collection2 = new TestWorkspace(options);
|
||||||
const doc = collection.createDoc({
|
const doc = collection.createDoc({
|
||||||
id: 'space:0',
|
id: 'space:0',
|
||||||
|
extensions,
|
||||||
});
|
});
|
||||||
doc.load(() => {
|
doc.load(() => {
|
||||||
doc.addBlock('affine:page', {
|
doc.addBlock('affine:page', {
|
||||||
@@ -209,7 +204,9 @@ describe('basic', () => {
|
|||||||
// apply doc update
|
// apply doc update
|
||||||
const update = encodeStateAsUpdate(doc.spaceDoc);
|
const update = encodeStateAsUpdate(doc.spaceDoc);
|
||||||
expect(collection2.docs.size).toBe(1);
|
expect(collection2.docs.size).toBe(1);
|
||||||
const doc2 = collection2.getDoc('space:0');
|
const doc2 = collection2.getDoc('space:0', {
|
||||||
|
extensions,
|
||||||
|
});
|
||||||
assertExists(doc2);
|
assertExists(doc2);
|
||||||
applyUpdate(doc2.spaceDoc, update);
|
applyUpdate(doc2.spaceDoc, update);
|
||||||
expect(serializCollection(collection2.doc)['spaces']).toEqual({
|
expect(serializCollection(collection2.doc)['spaces']).toEqual({
|
||||||
|
|||||||
@@ -2,31 +2,28 @@ import { beforeEach, describe, expect, test, vi } from 'vitest';
|
|||||||
import * as Y from 'yjs';
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
import type { BlockModel, Store } from '../model/index.js';
|
import type { BlockModel, Store } from '../model/index.js';
|
||||||
import { Schema } from '../schema/index.js';
|
|
||||||
import { createAutoIncrementIdGenerator } from '../test/index.js';
|
import { createAutoIncrementIdGenerator } from '../test/index.js';
|
||||||
import { TestWorkspace } from '../test/test-workspace.js';
|
import { TestWorkspace } from '../test/test-workspace.js';
|
||||||
import {
|
import {
|
||||||
DividerBlockSchema,
|
DividerBlockSchemaExtension,
|
||||||
ListBlockSchema,
|
ListBlockSchemaExtension,
|
||||||
NoteBlockSchema,
|
NoteBlockSchemaExtension,
|
||||||
ParagraphBlockSchema,
|
ParagraphBlockSchemaExtension,
|
||||||
type RootBlockModel,
|
type RootBlockModel,
|
||||||
RootBlockSchema,
|
RootBlockSchemaExtension,
|
||||||
} from './test-schema.js';
|
} from './test-schema.js';
|
||||||
|
|
||||||
const BlockSchemas = [
|
const extensions = [
|
||||||
RootBlockSchema,
|
RootBlockSchemaExtension,
|
||||||
ParagraphBlockSchema,
|
ParagraphBlockSchemaExtension,
|
||||||
ListBlockSchema,
|
ListBlockSchemaExtension,
|
||||||
NoteBlockSchema,
|
NoteBlockSchemaExtension,
|
||||||
DividerBlockSchema,
|
DividerBlockSchemaExtension,
|
||||||
];
|
];
|
||||||
|
|
||||||
function createTestOptions() {
|
function createTestOptions() {
|
||||||
const idGenerator = createAutoIncrementIdGenerator();
|
const idGenerator = createAutoIncrementIdGenerator();
|
||||||
const schema = new Schema();
|
return { id: 'test-collection', idGenerator };
|
||||||
schema.register(BlockSchemas);
|
|
||||||
return { id: 'test-collection', idGenerator, schema };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
test('trigger props updated', () => {
|
test('trigger props updated', () => {
|
||||||
@@ -34,7 +31,7 @@ test('trigger props updated', () => {
|
|||||||
const collection = new TestWorkspace(options);
|
const collection = new TestWorkspace(options);
|
||||||
collection.meta.initialize();
|
collection.meta.initialize();
|
||||||
|
|
||||||
const doc = collection.createDoc({ id: 'home' });
|
const doc = collection.createDoc({ id: 'home', extensions });
|
||||||
doc.load();
|
doc.load();
|
||||||
|
|
||||||
doc.addBlock('affine:page');
|
doc.addBlock('affine:page');
|
||||||
@@ -94,7 +91,7 @@ test('stash and pop', () => {
|
|||||||
const collection = new TestWorkspace(options);
|
const collection = new TestWorkspace(options);
|
||||||
collection.meta.initialize();
|
collection.meta.initialize();
|
||||||
|
|
||||||
const doc = collection.createDoc({ id: 'home' });
|
const doc = collection.createDoc({ id: 'home', extensions });
|
||||||
doc.load();
|
doc.load();
|
||||||
|
|
||||||
doc.addBlock('affine:page');
|
doc.addBlock('affine:page');
|
||||||
@@ -164,7 +161,7 @@ test('always get latest value in onChange', () => {
|
|||||||
const collection = new TestWorkspace(options);
|
const collection = new TestWorkspace(options);
|
||||||
collection.meta.initialize();
|
collection.meta.initialize();
|
||||||
|
|
||||||
const doc = collection.createDoc({ id: 'home' });
|
const doc = collection.createDoc({ id: 'home', extensions });
|
||||||
doc.load();
|
doc.load();
|
||||||
|
|
||||||
doc.addBlock('affine:page');
|
doc.addBlock('affine:page');
|
||||||
@@ -210,11 +207,12 @@ test('query', () => {
|
|||||||
const options = createTestOptions();
|
const options = createTestOptions();
|
||||||
const collection = new TestWorkspace(options);
|
const collection = new TestWorkspace(options);
|
||||||
collection.meta.initialize();
|
collection.meta.initialize();
|
||||||
const doc1 = collection.createDoc({ id: 'home' });
|
const doc1 = collection.createDoc({ id: 'home', extensions });
|
||||||
doc1.load();
|
doc1.load();
|
||||||
const doc2 = collection.getDoc('home');
|
const doc2 = collection.getDoc('home', { extensions });
|
||||||
|
|
||||||
const doc3 = collection.getDoc('home', {
|
const doc3 = collection.getDoc('home', {
|
||||||
|
extensions,
|
||||||
query: {
|
query: {
|
||||||
mode: 'loose',
|
mode: 'loose',
|
||||||
match: [
|
match: [
|
||||||
@@ -247,10 +245,10 @@ test('local readonly', () => {
|
|||||||
const options = createTestOptions();
|
const options = createTestOptions();
|
||||||
const collection = new TestWorkspace(options);
|
const collection = new TestWorkspace(options);
|
||||||
collection.meta.initialize();
|
collection.meta.initialize();
|
||||||
const doc1 = collection.createDoc({ id: 'home' });
|
const doc1 = collection.createDoc({ id: 'home', extensions });
|
||||||
doc1.load();
|
doc1.load();
|
||||||
const doc2 = collection.getDoc('home', { readonly: true });
|
const doc2 = collection.getDoc('home', { readonly: true, extensions });
|
||||||
const doc3 = collection.getDoc('home', { readonly: false });
|
const doc3 = collection.getDoc('home', { readonly: false, extensions });
|
||||||
|
|
||||||
expect(doc1.readonly).toBeFalsy();
|
expect(doc1.readonly).toBeFalsy();
|
||||||
expect(doc2?.readonly).toBeTruthy();
|
expect(doc2?.readonly).toBeTruthy();
|
||||||
@@ -276,7 +274,7 @@ describe('move blocks', () => {
|
|||||||
const collection = new TestWorkspace(options);
|
const collection = new TestWorkspace(options);
|
||||||
collection.meta.initialize();
|
collection.meta.initialize();
|
||||||
|
|
||||||
const doc = collection.createDoc({ id: 'home' });
|
const doc = collection.createDoc({ id: 'home', extensions });
|
||||||
doc.load();
|
doc.load();
|
||||||
const pageId = doc.addBlock('affine:page');
|
const pageId = doc.addBlock('affine:page');
|
||||||
const page = doc.getBlock(pageId)!.model;
|
const page = doc.getBlock(pageId)!.model;
|
||||||
|
|||||||
@@ -1,25 +1,23 @@
|
|||||||
import { literal } from 'lit/static-html.js';
|
import { literal } from 'lit/static-html.js';
|
||||||
import { describe, expect, it, vi } from 'vitest';
|
import { describe, expect, it, vi } from 'vitest';
|
||||||
|
|
||||||
|
import { BlockSchemaExtension } from '../extension/schema.js';
|
||||||
import { defineBlockSchema } from '../model/block/zod.js';
|
import { defineBlockSchema } from '../model/block/zod.js';
|
||||||
// import some blocks
|
// import some blocks
|
||||||
import { SchemaValidateError } from '../schema/error.js';
|
import { SchemaValidateError } from '../schema/error.js';
|
||||||
import { Schema } from '../schema/index.js';
|
|
||||||
import { createAutoIncrementIdGenerator } from '../test/index.js';
|
import { createAutoIncrementIdGenerator } from '../test/index.js';
|
||||||
import { TestWorkspace } from '../test/test-workspace.js';
|
import { TestWorkspace } from '../test/test-workspace.js';
|
||||||
import {
|
import {
|
||||||
DividerBlockSchema,
|
DividerBlockSchemaExtension,
|
||||||
ListBlockSchema,
|
ListBlockSchemaExtension,
|
||||||
NoteBlockSchema,
|
NoteBlockSchemaExtension,
|
||||||
ParagraphBlockSchema,
|
ParagraphBlockSchemaExtension,
|
||||||
RootBlockSchema,
|
RootBlockSchemaExtension,
|
||||||
} from './test-schema.js';
|
} from './test-schema.js';
|
||||||
|
|
||||||
function createTestOptions() {
|
function createTestOptions() {
|
||||||
const idGenerator = createAutoIncrementIdGenerator();
|
const idGenerator = createAutoIncrementIdGenerator();
|
||||||
const schema = new Schema();
|
return { id: 'test-collection', idGenerator };
|
||||||
schema.register(BlockSchemas);
|
|
||||||
return { id: 'test-collection', idGenerator, schema };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const TestCustomNoteBlockSchema = defineBlockSchema({
|
const TestCustomNoteBlockSchema = defineBlockSchema({
|
||||||
@@ -35,6 +33,10 @@ const TestCustomNoteBlockSchema = defineBlockSchema({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const TestCustomNoteBlockSchemaExtension = BlockSchemaExtension(
|
||||||
|
TestCustomNoteBlockSchema
|
||||||
|
);
|
||||||
|
|
||||||
const TestInvalidNoteBlockSchema = defineBlockSchema({
|
const TestInvalidNoteBlockSchema = defineBlockSchema({
|
||||||
flavour: 'affine:note-invalid-block-video',
|
flavour: 'affine:note-invalid-block-video',
|
||||||
props: internal => ({
|
props: internal => ({
|
||||||
@@ -48,14 +50,18 @@ const TestInvalidNoteBlockSchema = defineBlockSchema({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const BlockSchemas = [
|
const TestInvalidNoteBlockSchemaExtension = BlockSchemaExtension(
|
||||||
RootBlockSchema,
|
TestInvalidNoteBlockSchema
|
||||||
ParagraphBlockSchema,
|
);
|
||||||
ListBlockSchema,
|
|
||||||
NoteBlockSchema,
|
const extensions = [
|
||||||
DividerBlockSchema,
|
RootBlockSchemaExtension,
|
||||||
TestCustomNoteBlockSchema,
|
ParagraphBlockSchemaExtension,
|
||||||
TestInvalidNoteBlockSchema,
|
ListBlockSchemaExtension,
|
||||||
|
NoteBlockSchemaExtension,
|
||||||
|
DividerBlockSchemaExtension,
|
||||||
|
TestCustomNoteBlockSchemaExtension,
|
||||||
|
TestInvalidNoteBlockSchemaExtension,
|
||||||
];
|
];
|
||||||
|
|
||||||
const defaultDocId = 'doc0';
|
const defaultDocId = 'doc0';
|
||||||
@@ -63,7 +69,7 @@ function createTestDoc(docId = defaultDocId) {
|
|||||||
const options = createTestOptions();
|
const options = createTestOptions();
|
||||||
const collection = new TestWorkspace(options);
|
const collection = new TestWorkspace(options);
|
||||||
collection.meta.initialize();
|
collection.meta.initialize();
|
||||||
const doc = collection.createDoc({ id: docId });
|
const doc = collection.createDoc({ id: docId, extensions });
|
||||||
doc.load();
|
doc.load();
|
||||||
return doc;
|
return doc;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { BlockSchemaExtension } from '../extension/schema.js';
|
||||||
import { BlockModel, defineBlockSchema } from '../model/index.js';
|
import { BlockModel, defineBlockSchema } from '../model/index.js';
|
||||||
|
|
||||||
export const RootBlockSchema = defineBlockSchema({
|
export const RootBlockSchema = defineBlockSchema({
|
||||||
@@ -14,6 +15,8 @@ export const RootBlockSchema = defineBlockSchema({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const RootBlockSchemaExtension = BlockSchemaExtension(RootBlockSchema);
|
||||||
|
|
||||||
export class RootBlockModel extends BlockModel<
|
export class RootBlockModel extends BlockModel<
|
||||||
ReturnType<(typeof RootBlockSchema)['model']['props']>
|
ReturnType<(typeof RootBlockSchema)['model']['props']>
|
||||||
> {}
|
> {}
|
||||||
@@ -42,6 +45,8 @@ export const NoteBlockSchema = defineBlockSchema({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const NoteBlockSchemaExtension = BlockSchemaExtension(NoteBlockSchema);
|
||||||
|
|
||||||
export const ParagraphBlockSchema = defineBlockSchema({
|
export const ParagraphBlockSchema = defineBlockSchema({
|
||||||
flavour: 'affine:paragraph',
|
flavour: 'affine:paragraph',
|
||||||
props: internal => ({
|
props: internal => ({
|
||||||
@@ -60,6 +65,9 @@ export const ParagraphBlockSchema = defineBlockSchema({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const ParagraphBlockSchemaExtension =
|
||||||
|
BlockSchemaExtension(ParagraphBlockSchema);
|
||||||
|
|
||||||
export const ListBlockSchema = defineBlockSchema({
|
export const ListBlockSchema = defineBlockSchema({
|
||||||
flavour: 'affine:list',
|
flavour: 'affine:list',
|
||||||
props: internal => ({
|
props: internal => ({
|
||||||
@@ -80,6 +88,8 @@ export const ListBlockSchema = defineBlockSchema({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const ListBlockSchemaExtension = BlockSchemaExtension(ListBlockSchema);
|
||||||
|
|
||||||
export const DividerBlockSchema = defineBlockSchema({
|
export const DividerBlockSchema = defineBlockSchema({
|
||||||
flavour: 'affine:divider',
|
flavour: 'affine:divider',
|
||||||
metadata: {
|
metadata: {
|
||||||
@@ -88,3 +98,6 @@ export const DividerBlockSchema = defineBlockSchema({
|
|||||||
children: [],
|
children: [],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const DividerBlockSchemaExtension =
|
||||||
|
BlockSchemaExtension(DividerBlockSchema);
|
||||||
|
|||||||
@@ -2,10 +2,10 @@ import { expect, test } from 'vitest';
|
|||||||
import * as Y from 'yjs';
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
import { MemoryBlobCRUD } from '../adapter/index.js';
|
import { MemoryBlobCRUD } from '../adapter/index.js';
|
||||||
|
import { BlockSchemaExtension } from '../extension/schema.js';
|
||||||
import { BlockModel } from '../model/block/block-model.js';
|
import { BlockModel } from '../model/block/block-model.js';
|
||||||
import { defineBlockSchema } from '../model/block/zod.js';
|
import { defineBlockSchema } from '../model/block/zod.js';
|
||||||
import { Text } from '../reactive/index.js';
|
import { Text } from '../reactive/index.js';
|
||||||
import { Schema } from '../schema/index.js';
|
|
||||||
import { createAutoIncrementIdGenerator } from '../test/index.js';
|
import { createAutoIncrementIdGenerator } from '../test/index.js';
|
||||||
import { TestWorkspace } from '../test/test-workspace.js';
|
import { TestWorkspace } from '../test/test-workspace.js';
|
||||||
import { AssetsManager, BaseBlockTransformer } from '../transformer/index.js';
|
import { AssetsManager, BaseBlockTransformer } from '../transformer/index.js';
|
||||||
@@ -39,15 +39,16 @@ const docSchema = defineBlockSchema({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const docSchemaExtension = BlockSchemaExtension(docSchema);
|
||||||
class RootBlockModel extends BlockModel<
|
class RootBlockModel extends BlockModel<
|
||||||
ReturnType<(typeof docSchema)['model']['props']>
|
ReturnType<(typeof docSchema)['model']['props']>
|
||||||
> {}
|
> {}
|
||||||
|
|
||||||
|
const extensions = [docSchemaExtension];
|
||||||
|
|
||||||
function createTestOptions() {
|
function createTestOptions() {
|
||||||
const idGenerator = createAutoIncrementIdGenerator();
|
const idGenerator = createAutoIncrementIdGenerator();
|
||||||
const schema = new Schema();
|
return { id: 'test-collection', idGenerator };
|
||||||
schema.register([docSchema]);
|
|
||||||
return { id: 'test-collection', idGenerator, schema };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const transformer = new BaseBlockTransformer(new Map());
|
const transformer = new BaseBlockTransformer(new Map());
|
||||||
@@ -58,7 +59,7 @@ test('model to snapshot', () => {
|
|||||||
const options = createTestOptions();
|
const options = createTestOptions();
|
||||||
const collection = new TestWorkspace(options);
|
const collection = new TestWorkspace(options);
|
||||||
collection.meta.initialize();
|
collection.meta.initialize();
|
||||||
const doc = collection.createDoc({ id: 'home' });
|
const doc = collection.createDoc({ id: 'home', extensions });
|
||||||
doc.load();
|
doc.load();
|
||||||
doc.addBlock('page');
|
doc.addBlock('page');
|
||||||
const rootModel = doc.root as RootBlockModel;
|
const rootModel = doc.root as RootBlockModel;
|
||||||
@@ -75,7 +76,7 @@ test('snapshot to model', async () => {
|
|||||||
const options = createTestOptions();
|
const options = createTestOptions();
|
||||||
const collection = new TestWorkspace(options);
|
const collection = new TestWorkspace(options);
|
||||||
collection.meta.initialize();
|
collection.meta.initialize();
|
||||||
const doc = collection.createDoc({ id: 'home' });
|
const doc = collection.createDoc({ id: 'home', extensions });
|
||||||
doc.load();
|
doc.load();
|
||||||
doc.addBlock('page');
|
doc.addBlock('page');
|
||||||
const rootModel = doc.root as RootBlockModel;
|
const rootModel = doc.root as RootBlockModel;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
export * from './extension';
|
export * from './extension';
|
||||||
|
export * from './schema';
|
||||||
export * from './selection';
|
export * from './selection';
|
||||||
export * from './store-extension';
|
export * from './store-extension';
|
||||||
|
|||||||
20
blocksuite/framework/store/src/extension/schema.ts
Normal file
20
blocksuite/framework/store/src/extension/schema.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import { createIdentifier } from '@blocksuite/global/di';
|
||||||
|
|
||||||
|
import type { BlockSchemaType } from '../model/block/zod';
|
||||||
|
import type { ExtensionType } from './extension';
|
||||||
|
|
||||||
|
export const BlockSchemaIdentifier =
|
||||||
|
createIdentifier<BlockSchemaType>('BlockSchema');
|
||||||
|
|
||||||
|
export function BlockSchemaExtension(
|
||||||
|
blockSchema: BlockSchemaType
|
||||||
|
): ExtensionType {
|
||||||
|
return {
|
||||||
|
setup: di => {
|
||||||
|
di.addImpl(
|
||||||
|
BlockSchemaIdentifier(blockSchema.model.flavour),
|
||||||
|
() => blockSchema
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
import type { Slot } from '@blocksuite/global/utils';
|
import type { Slot } from '@blocksuite/global/utils';
|
||||||
import type * as Y from 'yjs';
|
import type * as Y from 'yjs';
|
||||||
|
|
||||||
import type { Schema } from '../schema/schema.js';
|
|
||||||
import type { AwarenessStore } from '../yjs/awareness.js';
|
import type { AwarenessStore } from '../yjs/awareness.js';
|
||||||
import type { YBlock } from './block/types.js';
|
import type { YBlock } from './block/types.js';
|
||||||
import type { Query } from './store/query.js';
|
import type { Query } from './store/query.js';
|
||||||
@@ -18,7 +17,6 @@ export type YBlocks = Y.Map<YBlock>;
|
|||||||
export interface Doc {
|
export interface Doc {
|
||||||
readonly id: string;
|
readonly id: string;
|
||||||
get meta(): DocMeta | undefined;
|
get meta(): DocMeta | undefined;
|
||||||
get schema(): Schema;
|
|
||||||
|
|
||||||
remove(): void;
|
remove(): void;
|
||||||
load(initFn?: () => void): void;
|
load(initFn?: () => void): void;
|
||||||
|
|||||||
@@ -4,8 +4,11 @@ import { type Disposable, Slot } from '@blocksuite/global/utils';
|
|||||||
import { computed, signal } from '@preact/signals-core';
|
import { computed, signal } from '@preact/signals-core';
|
||||||
|
|
||||||
import type { ExtensionType } from '../../extension/extension.js';
|
import type { ExtensionType } from '../../extension/extension.js';
|
||||||
import { StoreSelectionExtension } from '../../extension/index.js';
|
import {
|
||||||
import type { Schema } from '../../schema/index.js';
|
BlockSchemaIdentifier,
|
||||||
|
StoreSelectionExtension,
|
||||||
|
} from '../../extension/index.js';
|
||||||
|
import { Schema } from '../../schema/index.js';
|
||||||
import {
|
import {
|
||||||
Block,
|
Block,
|
||||||
type BlockModel,
|
type BlockModel,
|
||||||
@@ -20,7 +23,6 @@ import { type Query, runQuery } from './query.js';
|
|||||||
import { syncBlockProps } from './utils.js';
|
import { syncBlockProps } from './utils.js';
|
||||||
|
|
||||||
export type StoreOptions = {
|
export type StoreOptions = {
|
||||||
schema: Schema;
|
|
||||||
doc: Doc;
|
doc: Doc;
|
||||||
id?: string;
|
id?: string;
|
||||||
readonly?: boolean;
|
readonly?: boolean;
|
||||||
@@ -298,14 +300,7 @@ export class Store {
|
|||||||
return this._doc.withoutTransact.bind(this._doc);
|
return this._doc.withoutTransact.bind(this._doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor({
|
constructor({ doc, readonly, query, provider, extensions }: StoreOptions) {
|
||||||
schema,
|
|
||||||
doc,
|
|
||||||
readonly,
|
|
||||||
query,
|
|
||||||
provider,
|
|
||||||
extensions,
|
|
||||||
}: StoreOptions) {
|
|
||||||
const container = new Container();
|
const container = new Container();
|
||||||
container.addImpl(StoreIdentifier, () => this);
|
container.addImpl(StoreIdentifier, () => this);
|
||||||
|
|
||||||
@@ -331,8 +326,11 @@ export class Store {
|
|||||||
yBlockUpdated: this._doc.slots.yBlockUpdated,
|
yBlockUpdated: this._doc.slots.yBlockUpdated,
|
||||||
};
|
};
|
||||||
|
|
||||||
this._crud = new DocCRUD(this._yBlocks, doc.schema);
|
this._schema = new Schema();
|
||||||
this._schema = schema;
|
this._provider.getAll(BlockSchemaIdentifier).forEach(schema => {
|
||||||
|
this._schema.register([schema]);
|
||||||
|
});
|
||||||
|
this._crud = new DocCRUD(this._yBlocks, this._schema);
|
||||||
if (readonly !== undefined) {
|
if (readonly !== undefined) {
|
||||||
this._readonly.value = readonly;
|
this._readonly.value = readonly;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import type { Slot } from '@blocksuite/global/utils';
|
import type { Slot } from '@blocksuite/global/utils';
|
||||||
|
|
||||||
import type { Workspace } from './workspace.js';
|
|
||||||
|
|
||||||
export type Tag = {
|
export type Tag = {
|
||||||
id: string;
|
id: string;
|
||||||
value: string;
|
value: string;
|
||||||
@@ -38,8 +36,6 @@ export interface WorkspaceMeta {
|
|||||||
get name(): string | undefined;
|
get name(): string | undefined;
|
||||||
setName(name: string): void;
|
setName(name: string): void;
|
||||||
|
|
||||||
hasVersion: boolean;
|
|
||||||
writeVersion(workspace: Workspace): void;
|
|
||||||
get docs(): unknown[] | undefined;
|
get docs(): unknown[] | undefined;
|
||||||
initialize(): void;
|
initialize(): void;
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import type { BlobEngine } from '@blocksuite/sync';
|
|||||||
import type { Awareness } from 'y-protocols/awareness.js';
|
import type { Awareness } from 'y-protocols/awareness.js';
|
||||||
import type * as Y from 'yjs';
|
import type * as Y from 'yjs';
|
||||||
|
|
||||||
import type { Schema } from '../schema/schema.js';
|
|
||||||
import type { IdGenerator } from '../utils/id-generator.js';
|
import type { IdGenerator } from '../utils/id-generator.js';
|
||||||
import type { AwarenessStore } from '../yjs/awareness.js';
|
import type { AwarenessStore } from '../yjs/awareness.js';
|
||||||
import type { CreateBlocksOptions, Doc, GetBlocksOptions } from './doc.js';
|
import type { CreateBlocksOptions, Doc, GetBlocksOptions } from './doc.js';
|
||||||
@@ -19,7 +18,6 @@ export interface Workspace {
|
|||||||
readonly onLoadDoc?: (doc: Y.Doc) => void;
|
readonly onLoadDoc?: (doc: Y.Doc) => void;
|
||||||
readonly onLoadAwareness?: (awareness: Awareness) => void;
|
readonly onLoadAwareness?: (awareness: Awareness) => void;
|
||||||
|
|
||||||
get schema(): Schema;
|
|
||||||
get doc(): Y.Doc;
|
get doc(): Y.Doc;
|
||||||
get docs(): Map<string, Doc>;
|
get docs(): Map<string, Doc>;
|
||||||
|
|
||||||
|
|||||||
@@ -162,10 +162,6 @@ export class TestDoc implements Doc {
|
|||||||
return this._ready;
|
return this._ready;
|
||||||
}
|
}
|
||||||
|
|
||||||
get schema() {
|
|
||||||
return this.workspace.schema;
|
|
||||||
}
|
|
||||||
|
|
||||||
get spaceDoc() {
|
get spaceDoc() {
|
||||||
return this._ySpaceDoc;
|
return this._ySpaceDoc;
|
||||||
}
|
}
|
||||||
@@ -189,13 +185,6 @@ export class TestDoc implements Doc {
|
|||||||
return (readonly?.toString() as 'true' | 'false') ?? 'false';
|
return (readonly?.toString() as 'true' | 'false') ?? 'false';
|
||||||
}
|
}
|
||||||
|
|
||||||
private _handleVersion() {
|
|
||||||
// Initialization from empty yDoc, indicating that the document is new.
|
|
||||||
if (!this.workspace.meta.hasVersion) {
|
|
||||||
this.workspace.meta.writeVersion(this.workspace);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private _handleYBlockAdd(id: string) {
|
private _handleYBlockAdd(id: string) {
|
||||||
this.slots.yBlockUpdated.emit({ type: 'add', id });
|
this.slots.yBlockUpdated.emit({ type: 'add', id });
|
||||||
}
|
}
|
||||||
@@ -306,7 +295,6 @@ export class TestDoc implements Doc {
|
|||||||
|
|
||||||
const doc = new Store({
|
const doc = new Store({
|
||||||
doc: this,
|
doc: this,
|
||||||
schema: this.workspace.schema,
|
|
||||||
readonly,
|
readonly,
|
||||||
query,
|
query,
|
||||||
provider,
|
provider,
|
||||||
@@ -327,10 +315,6 @@ export class TestDoc implements Doc {
|
|||||||
|
|
||||||
this._ySpaceDoc.load();
|
this._ySpaceDoc.load();
|
||||||
|
|
||||||
if ((this.workspace.meta.docs?.length ?? 0) <= 1) {
|
|
||||||
this._handleVersion();
|
|
||||||
}
|
|
||||||
|
|
||||||
this._initYBlocks();
|
this._initYBlocks();
|
||||||
|
|
||||||
this._yBlocks.forEach((_, id) => {
|
this._yBlocks.forEach((_, id) => {
|
||||||
|
|||||||
@@ -4,20 +4,13 @@ import type * as Y from 'yjs';
|
|||||||
import type {
|
import type {
|
||||||
DocMeta,
|
DocMeta,
|
||||||
DocsPropertiesMeta,
|
DocsPropertiesMeta,
|
||||||
Workspace,
|
|
||||||
WorkspaceMeta,
|
WorkspaceMeta,
|
||||||
} from '../model/index.js';
|
} from '../model/index.js';
|
||||||
import { createYProxy } from '../reactive/proxy.js';
|
import { createYProxy } from '../reactive/proxy.js';
|
||||||
|
|
||||||
const COLLECTION_VERSION = 2;
|
|
||||||
const PAGE_VERSION = 2;
|
|
||||||
|
|
||||||
type DocCollectionMetaState = {
|
type DocCollectionMetaState = {
|
||||||
pages?: unknown[];
|
pages?: unknown[];
|
||||||
properties?: DocsPropertiesMeta;
|
properties?: DocsPropertiesMeta;
|
||||||
workspaceVersion?: number;
|
|
||||||
pageVersion?: number;
|
|
||||||
blockVersions?: Record<string, number>;
|
|
||||||
name?: string;
|
name?: string;
|
||||||
avatar?: string;
|
avatar?: string;
|
||||||
};
|
};
|
||||||
@@ -68,10 +61,6 @@ export class TestMeta implements WorkspaceMeta {
|
|||||||
return this._proxy.avatar;
|
return this._proxy.avatar;
|
||||||
}
|
}
|
||||||
|
|
||||||
get blockVersions() {
|
|
||||||
return this._proxy.blockVersions;
|
|
||||||
}
|
|
||||||
|
|
||||||
get docMetas() {
|
get docMetas() {
|
||||||
if (!this._proxy.pages) {
|
if (!this._proxy.pages) {
|
||||||
return [] as DocMeta[];
|
return [] as DocMeta[];
|
||||||
@@ -83,21 +72,10 @@ export class TestMeta implements WorkspaceMeta {
|
|||||||
return this._proxy.pages;
|
return this._proxy.pages;
|
||||||
}
|
}
|
||||||
|
|
||||||
get hasVersion() {
|
|
||||||
if (!this.blockVersions || !this.pageVersion || !this.workspaceVersion) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return Object.keys(this.blockVersions).length > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
get name() {
|
get name() {
|
||||||
return this._proxy.name;
|
return this._proxy.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
get pageVersion() {
|
|
||||||
return this._proxy.pageVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
get properties(): DocsPropertiesMeta {
|
get properties(): DocsPropertiesMeta {
|
||||||
const meta = this._proxy.properties;
|
const meta = this._proxy.properties;
|
||||||
if (!meta) {
|
if (!meta) {
|
||||||
@@ -110,10 +88,6 @@ export class TestMeta implements WorkspaceMeta {
|
|||||||
return meta;
|
return meta;
|
||||||
}
|
}
|
||||||
|
|
||||||
get workspaceVersion() {
|
|
||||||
return this._proxy.workspaceVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
get yDocs() {
|
get yDocs() {
|
||||||
return this._yMap.get('pages') as unknown as Y.Array<unknown>;
|
return this._yMap.get('pages') as unknown as Y.Array<unknown>;
|
||||||
}
|
}
|
||||||
@@ -232,33 +206,4 @@ export class TestMeta implements WorkspaceMeta {
|
|||||||
this._proxy.properties = meta;
|
this._proxy.properties = meta;
|
||||||
this.docMetaUpdated.emit();
|
this.docMetaUpdated.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @internal Only for doc initialization
|
|
||||||
*/
|
|
||||||
writeVersion(collection: Workspace) {
|
|
||||||
const { blockVersions, pageVersion, workspaceVersion } = this._proxy;
|
|
||||||
|
|
||||||
if (!workspaceVersion) {
|
|
||||||
this._proxy.workspaceVersion = COLLECTION_VERSION;
|
|
||||||
} else {
|
|
||||||
console.error('Workspace version is already set');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pageVersion) {
|
|
||||||
this._proxy.pageVersion = PAGE_VERSION;
|
|
||||||
} else {
|
|
||||||
console.error('Doc version is already set');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!blockVersions) {
|
|
||||||
const _versions: Record<string, number> = {};
|
|
||||||
collection.schema.flavourSchemaMap.forEach((schema, flavour) => {
|
|
||||||
_versions[flavour] = schema.version;
|
|
||||||
});
|
|
||||||
this._proxy.blockVersions = _versions;
|
|
||||||
} else {
|
|
||||||
console.error('Block versions is already set');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,14 +21,12 @@ import type {
|
|||||||
Workspace,
|
Workspace,
|
||||||
WorkspaceMeta,
|
WorkspaceMeta,
|
||||||
} from '../model/index.js';
|
} from '../model/index.js';
|
||||||
import type { Schema } from '../schema/index.js';
|
|
||||||
import { type IdGenerator, nanoid } from '../utils/id-generator.js';
|
import { type IdGenerator, nanoid } from '../utils/id-generator.js';
|
||||||
import { AwarenessStore } from '../yjs/index.js';
|
import { AwarenessStore } from '../yjs/index.js';
|
||||||
import { TestDoc } from './test-doc.js';
|
import { TestDoc } from './test-doc.js';
|
||||||
import { TestMeta } from './test-meta.js';
|
import { TestMeta } from './test-meta.js';
|
||||||
|
|
||||||
export type DocCollectionOptions = {
|
export type DocCollectionOptions = {
|
||||||
schema: Schema;
|
|
||||||
id?: string;
|
id?: string;
|
||||||
idGenerator?: IdGenerator;
|
idGenerator?: IdGenerator;
|
||||||
docSources?: {
|
docSources?: {
|
||||||
@@ -47,8 +45,6 @@ export type DocCollectionOptions = {
|
|||||||
* Do not use this in production
|
* Do not use this in production
|
||||||
*/
|
*/
|
||||||
export class TestWorkspace implements Workspace {
|
export class TestWorkspace implements Workspace {
|
||||||
protected readonly _schema: Schema;
|
|
||||||
|
|
||||||
storeExtensions: ExtensionType[] = [];
|
storeExtensions: ExtensionType[] = [];
|
||||||
|
|
||||||
readonly awarenessStore: AwarenessStore;
|
readonly awarenessStore: AwarenessStore;
|
||||||
@@ -79,13 +75,8 @@ export class TestWorkspace implements Workspace {
|
|||||||
return this.blockCollections;
|
return this.blockCollections;
|
||||||
}
|
}
|
||||||
|
|
||||||
get schema() {
|
|
||||||
return this._schema;
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor({
|
constructor({
|
||||||
id,
|
id,
|
||||||
schema,
|
|
||||||
idGenerator,
|
idGenerator,
|
||||||
awarenessSources = [],
|
awarenessSources = [],
|
||||||
docSources = {
|
docSources = {
|
||||||
@@ -94,9 +85,7 @@ export class TestWorkspace implements Workspace {
|
|||||||
blobSources = {
|
blobSources = {
|
||||||
main: new MemoryBlobSource(),
|
main: new MemoryBlobSource(),
|
||||||
},
|
},
|
||||||
}: DocCollectionOptions) {
|
}: DocCollectionOptions = {}) {
|
||||||
this._schema = schema;
|
|
||||||
|
|
||||||
this.id = id || '';
|
this.id = id || '';
|
||||||
this.doc = new Y.Doc({ guid: id });
|
this.doc = new Y.Doc({ guid: id });
|
||||||
this.awarenessStore = new AwarenessStore(new Awareness(this.doc));
|
this.awarenessStore = new AwarenessStore(new Awareness(this.doc));
|
||||||
@@ -165,7 +154,12 @@ export class TestWorkspace implements Workspace {
|
|||||||
* will be created in the doc simultaneously.
|
* will be created in the doc simultaneously.
|
||||||
*/
|
*/
|
||||||
createDoc(options: CreateBlocksOptions = {}) {
|
createDoc(options: CreateBlocksOptions = {}) {
|
||||||
const { id: docId = this.idGenerator(), query, readonly } = options;
|
const {
|
||||||
|
id: docId = this.idGenerator(),
|
||||||
|
query,
|
||||||
|
readonly,
|
||||||
|
extensions,
|
||||||
|
} = options;
|
||||||
if (this._hasDoc(docId)) {
|
if (this._hasDoc(docId)) {
|
||||||
throw new BlockSuiteError(
|
throw new BlockSuiteError(
|
||||||
ErrorCode.DocCollectionError,
|
ErrorCode.DocCollectionError,
|
||||||
@@ -184,6 +178,7 @@ export class TestWorkspace implements Workspace {
|
|||||||
id: docId,
|
id: docId,
|
||||||
query,
|
query,
|
||||||
readonly,
|
readonly,
|
||||||
|
extensions,
|
||||||
}) as Store;
|
}) as Store;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
import { type SurfaceBlockModel, ZipTransformer } from '@blocksuite/blocks';
|
import {
|
||||||
|
AffineSchemas,
|
||||||
|
type SurfaceBlockModel,
|
||||||
|
ZipTransformer,
|
||||||
|
} from '@blocksuite/blocks';
|
||||||
import type { PointLocation } from '@blocksuite/global/utils';
|
import type { PointLocation } from '@blocksuite/global/utils';
|
||||||
|
import { Schema } from '@blocksuite/store';
|
||||||
import { beforeEach, expect, test } from 'vitest';
|
import { beforeEach, expect, test } from 'vitest';
|
||||||
|
|
||||||
import { wait } from '../utils/common.js';
|
import { wait } from '../utils/common.js';
|
||||||
@@ -25,6 +30,8 @@ const skipFields = new Set(['_lastXYWH']);
|
|||||||
|
|
||||||
const snapshotTest = async (snapshotUrl: string, elementsCount: number) => {
|
const snapshotTest = async (snapshotUrl: string, elementsCount: number) => {
|
||||||
const transformer = ZipTransformer;
|
const transformer = ZipTransformer;
|
||||||
|
const schema = new Schema();
|
||||||
|
schema.register(AffineSchemas);
|
||||||
|
|
||||||
const snapshotFile = await fetch(snapshotUrl)
|
const snapshotFile = await fetch(snapshotUrl)
|
||||||
.then(res => res.blob())
|
.then(res => res.blob())
|
||||||
@@ -32,8 +39,10 @@ const snapshotTest = async (snapshotUrl: string, elementsCount: number) => {
|
|||||||
console.error(e);
|
console.error(e);
|
||||||
throw e;
|
throw e;
|
||||||
});
|
});
|
||||||
|
|
||||||
const [newDoc] = await transformer.importDocs(
|
const [newDoc] = await transformer.importDocs(
|
||||||
window.editor.doc.workspace,
|
window.editor.doc.workspace,
|
||||||
|
schema,
|
||||||
snapshotFile
|
snapshotFile
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { replaceIdMiddleware } from '@blocksuite/blocks';
|
import { AffineSchemas, replaceIdMiddleware } from '@blocksuite/blocks';
|
||||||
import {
|
import {
|
||||||
type DocSnapshot,
|
type DocSnapshot,
|
||||||
|
Schema,
|
||||||
Transformer,
|
Transformer,
|
||||||
type Workspace,
|
type Workspace,
|
||||||
} from '@blocksuite/store';
|
} from '@blocksuite/store';
|
||||||
@@ -10,7 +11,7 @@ export async function importFromSnapshot(
|
|||||||
snapshot: DocSnapshot
|
snapshot: DocSnapshot
|
||||||
) {
|
) {
|
||||||
const job = new Transformer({
|
const job = new Transformer({
|
||||||
schema: collection.schema,
|
schema: new Schema().register(AffineSchemas),
|
||||||
blobCRUD: collection.blobSync,
|
blobCRUD: collection.blobSync,
|
||||||
docCRUD: {
|
docCRUD: {
|
||||||
create: (id: string) => collection.createDoc({ id }),
|
create: (id: string) => collection.createDoc({ id }),
|
||||||
|
|||||||
@@ -238,7 +238,7 @@ export class StarterDebugMenu extends ShadowlessElement {
|
|||||||
private async _exportFile(config: AdapterConfig) {
|
private async _exportFile(config: AdapterConfig) {
|
||||||
const doc = this.editor.doc;
|
const doc = this.editor.doc;
|
||||||
const job = new Transformer({
|
const job = new Transformer({
|
||||||
schema: this.collection.schema,
|
schema: doc.schema,
|
||||||
blobCRUD: this.collection.blobSync,
|
blobCRUD: this.collection.blobSync,
|
||||||
docCRUD: {
|
docCRUD: {
|
||||||
create: (id: string) => this.collection.createDoc({ id }),
|
create: (id: string) => this.collection.createDoc({ id }),
|
||||||
@@ -325,6 +325,7 @@ export class StarterDebugMenu extends ShadowlessElement {
|
|||||||
private async _exportSnapshot() {
|
private async _exportSnapshot() {
|
||||||
await ZipTransformer.exportDocs(
|
await ZipTransformer.exportDocs(
|
||||||
this.collection,
|
this.collection,
|
||||||
|
this.editor.doc.schema,
|
||||||
Array.from(this.collection.docs.values()).map(collection =>
|
Array.from(this.collection.docs.values()).map(collection =>
|
||||||
collection.getStore()
|
collection.getStore()
|
||||||
)
|
)
|
||||||
@@ -346,6 +347,7 @@ export class StarterDebugMenu extends ShadowlessElement {
|
|||||||
const fileName = file.name.split('.').slice(0, -1).join('.');
|
const fileName = file.name.split('.').slice(0, -1).join('.');
|
||||||
const pageId = await HtmlTransformer.importHTMLToDoc({
|
const pageId = await HtmlTransformer.importHTMLToDoc({
|
||||||
collection: this.collection,
|
collection: this.collection,
|
||||||
|
schema: this.editor.doc.schema,
|
||||||
html: text,
|
html: text,
|
||||||
fileName,
|
fileName,
|
||||||
});
|
});
|
||||||
@@ -369,6 +371,7 @@ export class StarterDebugMenu extends ShadowlessElement {
|
|||||||
if (!file) return;
|
if (!file) return;
|
||||||
const result = await HtmlTransformer.importHTMLZip({
|
const result = await HtmlTransformer.importHTMLZip({
|
||||||
collection: this.collection,
|
collection: this.collection,
|
||||||
|
schema: this.editor.doc.schema,
|
||||||
imported: file,
|
imported: file,
|
||||||
});
|
});
|
||||||
if (!this.editor.host) return;
|
if (!this.editor.host) return;
|
||||||
@@ -396,6 +399,7 @@ export class StarterDebugMenu extends ShadowlessElement {
|
|||||||
const fileName = file.name.split('.').slice(0, -1).join('.');
|
const fileName = file.name.split('.').slice(0, -1).join('.');
|
||||||
const pageId = await MarkdownTransformer.importMarkdownToDoc({
|
const pageId = await MarkdownTransformer.importMarkdownToDoc({
|
||||||
collection: this.collection,
|
collection: this.collection,
|
||||||
|
schema: this.editor.doc.schema,
|
||||||
markdown: text,
|
markdown: text,
|
||||||
fileName,
|
fileName,
|
||||||
});
|
});
|
||||||
@@ -419,6 +423,7 @@ export class StarterDebugMenu extends ShadowlessElement {
|
|||||||
if (!file) return;
|
if (!file) return;
|
||||||
const result = await MarkdownTransformer.importMarkdownZip({
|
const result = await MarkdownTransformer.importMarkdownZip({
|
||||||
collection: this.collection,
|
collection: this.collection,
|
||||||
|
schema: this.editor.doc.schema,
|
||||||
imported: file,
|
imported: file,
|
||||||
});
|
});
|
||||||
if (!this.editor.host) return;
|
if (!this.editor.host) return;
|
||||||
@@ -438,8 +443,9 @@ export class StarterDebugMenu extends ShadowlessElement {
|
|||||||
multiple: false,
|
multiple: false,
|
||||||
});
|
});
|
||||||
if (!file) return;
|
if (!file) return;
|
||||||
|
const doc = this.editor.doc;
|
||||||
const job = new Transformer({
|
const job = new Transformer({
|
||||||
schema: this.collection.schema,
|
schema: doc.schema,
|
||||||
blobCRUD: this.collection.blobSync,
|
blobCRUD: this.collection.blobSync,
|
||||||
docCRUD: {
|
docCRUD: {
|
||||||
create: (id: string) => this.collection.createDoc({ id }),
|
create: (id: string) => this.collection.createDoc({ id }),
|
||||||
@@ -465,6 +471,7 @@ export class StarterDebugMenu extends ShadowlessElement {
|
|||||||
if (!file) return;
|
if (!file) return;
|
||||||
const result = await NotionHtmlTransformer.importNotionZip({
|
const result = await NotionHtmlTransformer.importNotionZip({
|
||||||
collection: this.collection,
|
collection: this.collection,
|
||||||
|
schema: this.editor.doc.schema,
|
||||||
imported: file,
|
imported: file,
|
||||||
});
|
});
|
||||||
if (!this.editor.host) return;
|
if (!this.editor.host) return;
|
||||||
@@ -488,7 +495,11 @@ export class StarterDebugMenu extends ShadowlessElement {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const docs = await ZipTransformer.importDocs(this.collection, file);
|
const docs = await ZipTransformer.importDocs(
|
||||||
|
this.collection,
|
||||||
|
this.editor.doc.schema,
|
||||||
|
file
|
||||||
|
);
|
||||||
for (const doc of docs) {
|
for (const doc of docs) {
|
||||||
if (doc) {
|
if (doc) {
|
||||||
const noteBlock = window.doc.getBlockByFlavour('affine:note');
|
const noteBlock = window.doc.getBlockByFlavour('affine:note');
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
import { AffineSchemas, SpecProvider } from '@blocksuite/blocks';
|
import { SpecProvider } from '@blocksuite/blocks';
|
||||||
import { Schema } from '@blocksuite/store';
|
|
||||||
import { TestWorkspace } from '@blocksuite/store/test';
|
import { TestWorkspace } from '@blocksuite/store/test';
|
||||||
|
|
||||||
export function createEmptyDoc() {
|
export function createEmptyDoc() {
|
||||||
const schema = new Schema().register(AffineSchemas);
|
const collection = new TestWorkspace();
|
||||||
const collection = new TestWorkspace({ schema });
|
|
||||||
collection.storeExtensions = SpecProvider._.getSpec('store').value;
|
collection.storeExtensions = SpecProvider._.getSpec('store').value;
|
||||||
collection.meta.initialize();
|
collection.meta.initialize();
|
||||||
const doc = collection.createDoc();
|
const doc = collection.createDoc();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { ZipTransformer } from '@blocksuite/blocks';
|
import { AffineSchemas, ZipTransformer } from '@blocksuite/blocks';
|
||||||
import { Text, type Workspace } from '@blocksuite/store';
|
import { Schema, Text, type Workspace } from '@blocksuite/store';
|
||||||
|
|
||||||
export async function affineSnapshot(collection: Workspace, id: string) {
|
export async function affineSnapshot(collection: Workspace, id: string) {
|
||||||
const doc = collection.createDoc({ id });
|
const doc = collection.createDoc({ id });
|
||||||
@@ -13,7 +13,9 @@ export async function affineSnapshot(collection: Workspace, id: string) {
|
|||||||
const path = '/apps/starter/data/snapshots/affine-default.zip';
|
const path = '/apps/starter/data/snapshots/affine-default.zip';
|
||||||
const response = await fetch(path);
|
const response = await fetch(path);
|
||||||
const file = await response.blob();
|
const file = await response.blob();
|
||||||
await ZipTransformer.importDocs(collection, file);
|
const schema = new Schema();
|
||||||
|
schema.register(AffineSchemas);
|
||||||
|
await ZipTransformer.importDocs(collection, schema, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
affineSnapshot.id = 'affine-snapshot';
|
affineSnapshot.id = 'affine-snapshot';
|
||||||
|
|||||||
@@ -49,7 +49,6 @@ export function createStarterDocCollection() {
|
|||||||
|
|
||||||
const options: DocCollectionOptions = {
|
const options: DocCollectionOptions = {
|
||||||
id: collectionId,
|
id: collectionId,
|
||||||
schema,
|
|
||||||
idGenerator,
|
idGenerator,
|
||||||
awarenessSources: [new BroadcastChannelAwarenessSource(id)],
|
awarenessSources: [new BroadcastChannelAwarenessSource(id)],
|
||||||
docSources,
|
docSources,
|
||||||
@@ -63,7 +62,7 @@ export function createStarterDocCollection() {
|
|||||||
window.collection = collection;
|
window.collection = collection;
|
||||||
window.blockSchemas = AffineSchemas;
|
window.blockSchemas = AffineSchemas;
|
||||||
window.job = new Transformer({
|
window.job = new Transformer({
|
||||||
schema: collection.schema,
|
schema,
|
||||||
blobCRUD: collection.blobSync,
|
blobCRUD: collection.blobSync,
|
||||||
docCRUD: {
|
docCRUD: {
|
||||||
create: (id: string) => collection.createDoc({ id }),
|
create: (id: string) => collection.createDoc({ id }),
|
||||||
|
|||||||
@@ -66,33 +66,6 @@ export const defaultStore = {
|
|||||||
tags: [],
|
tags: [],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
blockVersions: {
|
|
||||||
'affine:paragraph': 1,
|
|
||||||
'affine:page': 2,
|
|
||||||
'affine:database': 3,
|
|
||||||
'affine:data-view': 1,
|
|
||||||
'affine:list': 1,
|
|
||||||
'affine:note': 1,
|
|
||||||
'affine:divider': 1,
|
|
||||||
'affine:embed-youtube': 1,
|
|
||||||
'affine:embed-figma': 1,
|
|
||||||
'affine:embed-github': 1,
|
|
||||||
'affine:embed-loom': 1,
|
|
||||||
'affine:embed-html': 1,
|
|
||||||
'affine:embed-linked-doc': 1,
|
|
||||||
'affine:embed-synced-doc': 1,
|
|
||||||
'affine:image': 1,
|
|
||||||
'affine:latex': 1,
|
|
||||||
'affine:frame': 1,
|
|
||||||
'affine:code': 1,
|
|
||||||
'affine:surface': 5,
|
|
||||||
'affine:bookmark': 1,
|
|
||||||
'affine:attachment': 1,
|
|
||||||
'affine:surface-ref': 1,
|
|
||||||
'affine:edgeless-text': 1,
|
|
||||||
},
|
|
||||||
workspaceVersion: 2,
|
|
||||||
pageVersion: 2,
|
|
||||||
},
|
},
|
||||||
spaces: {
|
spaces: {
|
||||||
'doc:home': {
|
'doc:home': {
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ framework.impl(AIButtonProvider, {
|
|||||||
const blockSuiteDoc = doc.blockSuiteDoc;
|
const blockSuiteDoc = doc.blockSuiteDoc;
|
||||||
|
|
||||||
const transformer = new Transformer({
|
const transformer = new Transformer({
|
||||||
schema: blockSuiteDoc.workspace.schema,
|
schema: blockSuiteDoc.schema,
|
||||||
blobCRUD: blockSuiteDoc.workspace.blobSync,
|
blobCRUD: blockSuiteDoc.workspace.blobSync,
|
||||||
docCRUD: {
|
docCRUD: {
|
||||||
create: (id: string) => blockSuiteDoc.workspace.createDoc({ id }),
|
create: (id: string) => blockSuiteDoc.workspace.createDoc({ id }),
|
||||||
|
|||||||
@@ -224,7 +224,7 @@ const frameworkProvider = framework.provider();
|
|||||||
const blockSuiteDoc = doc.blockSuiteDoc;
|
const blockSuiteDoc = doc.blockSuiteDoc;
|
||||||
|
|
||||||
const transformer = new Transformer({
|
const transformer = new Transformer({
|
||||||
schema: blockSuiteDoc.workspace.schema,
|
schema: blockSuiteDoc.schema,
|
||||||
blobCRUD: blockSuiteDoc.workspace.blobSync,
|
blobCRUD: blockSuiteDoc.workspace.blobSync,
|
||||||
docCRUD: {
|
docCRUD: {
|
||||||
create: (id: string) => blockSuiteDoc.workspace.createDoc({ id }),
|
create: (id: string) => blockSuiteDoc.workspace.createDoc({ id }),
|
||||||
|
|||||||
@@ -2,7 +2,11 @@ import {
|
|||||||
type GfxCommonBlockProps,
|
type GfxCommonBlockProps,
|
||||||
GfxCompatible,
|
GfxCompatible,
|
||||||
} from '@blocksuite/affine/block-std/gfx';
|
} from '@blocksuite/affine/block-std/gfx';
|
||||||
import { BlockModel, defineBlockSchema } from '@blocksuite/affine/store';
|
import {
|
||||||
|
BlockModel,
|
||||||
|
BlockSchemaExtension,
|
||||||
|
defineBlockSchema,
|
||||||
|
} from '@blocksuite/affine/store';
|
||||||
|
|
||||||
type AIChatProps = {
|
type AIChatProps = {
|
||||||
messages: string; // JSON string of ChatMessage[]
|
messages: string; // JSON string of ChatMessage[]
|
||||||
@@ -33,4 +37,7 @@ export const AIChatBlockSchema = defineBlockSchema({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const AIChatBlockSchemaExtension =
|
||||||
|
BlockSchemaExtension(AIChatBlockSchema);
|
||||||
|
|
||||||
export class AIChatBlockModel extends GfxCompatible<AIChatProps>(BlockModel) {}
|
export class AIChatBlockModel extends GfxCompatible<AIChatProps>(BlockModel) {}
|
||||||
|
|||||||
@@ -214,7 +214,7 @@ export class TextRenderer extends WithDisposable(ShadowlessElement) {
|
|||||||
if (this._answers.length > 0) {
|
if (this._answers.length > 0) {
|
||||||
const latestAnswer = this._answers.pop();
|
const latestAnswer = this._answers.pop();
|
||||||
this._answers = [];
|
this._answers = [];
|
||||||
const schema = this.schema ?? this.host?.std.store.workspace.schema;
|
const schema = this.schema ?? this.host?.std.store.schema;
|
||||||
let provider: ServiceProvider;
|
let provider: ServiceProvider;
|
||||||
if (this.host) {
|
if (this.host) {
|
||||||
provider = this.host.std.provider;
|
provider = this.host.std.provider;
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { SpecProvider } from '@blocksuite/affine/blocks';
|
||||||
|
|
||||||
import { AIChatBlockComponent } from './blocks/ai-chat-block/ai-chat-block';
|
import { AIChatBlockComponent } from './blocks/ai-chat-block/ai-chat-block';
|
||||||
import { EdgelessAIChatBlockComponent } from './blocks/ai-chat-block/ai-chat-edgeless-block';
|
import { EdgelessAIChatBlockComponent } from './blocks/ai-chat-block/ai-chat-edgeless-block';
|
||||||
import {
|
import {
|
||||||
@@ -10,6 +12,7 @@ import {
|
|||||||
} from './blocks/ai-chat-block/components/chat-images';
|
} from './blocks/ai-chat-block/components/chat-images';
|
||||||
import { ImagePlaceholder } from './blocks/ai-chat-block/components/image-placeholder';
|
import { ImagePlaceholder } from './blocks/ai-chat-block/components/image-placeholder';
|
||||||
import { UserInfo } from './blocks/ai-chat-block/components/user-info';
|
import { UserInfo } from './blocks/ai-chat-block/components/user-info';
|
||||||
|
import { AIChatBlockSchemaExtension } from './blocks/ai-chat-block/model';
|
||||||
import { ChatPanel } from './chat-panel';
|
import { ChatPanel } from './chat-panel';
|
||||||
import { ActionWrapper } from './chat-panel/actions/action-wrapper';
|
import { ActionWrapper } from './chat-panel/actions/action-wrapper';
|
||||||
import { ChatText } from './chat-panel/actions/chat-text';
|
import { ChatText } from './chat-panel/actions/chat-text';
|
||||||
@@ -126,4 +129,6 @@ export function registerAIEffects() {
|
|||||||
'edgeless-copilot-toolbar-entry',
|
'edgeless-copilot-toolbar-entry',
|
||||||
EdgelessCopilotToolbarEntry
|
EdgelessCopilotToolbarEntry
|
||||||
);
|
);
|
||||||
|
|
||||||
|
SpecProvider._.extendSpec('store', [AIChatBlockSchemaExtension]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
import { WorkspaceImpl } from '@affine/core/modules/workspace/impls/workspace';
|
import { WorkspaceImpl } from '@affine/core/modules/workspace/impls/workspace';
|
||||||
import { BlockStdScope, type EditorHost } from '@blocksuite/affine/block-std';
|
import { BlockStdScope, type EditorHost } from '@blocksuite/affine/block-std';
|
||||||
import { SpecProvider } from '@blocksuite/affine/blocks';
|
import { SpecProvider } from '@blocksuite/affine/blocks';
|
||||||
import { AffineSchemas } from '@blocksuite/affine/blocks/schemas';
|
|
||||||
import { WithDisposable } from '@blocksuite/affine/global/utils';
|
import { WithDisposable } from '@blocksuite/affine/global/utils';
|
||||||
import { Schema, type Store } from '@blocksuite/affine/store';
|
import type { Store } from '@blocksuite/affine/store';
|
||||||
import { css, html, LitElement, nothing } from 'lit';
|
import { css, html, LitElement, nothing } from 'lit';
|
||||||
import { property, query } from 'lit/decorators.js';
|
import { property, query } from 'lit/decorators.js';
|
||||||
import { createRef, type Ref, ref } from 'lit/directives/ref.js';
|
import { createRef, type Ref, ref } from 'lit/directives/ref.js';
|
||||||
@@ -216,9 +215,7 @@ export class AISlidesRenderer extends WithDisposable(LitElement) {
|
|||||||
override connectedCallback(): void {
|
override connectedCallback(): void {
|
||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
|
|
||||||
const schema = new Schema().register(AffineSchemas);
|
|
||||||
const collection = new WorkspaceImpl({
|
const collection = new WorkspaceImpl({
|
||||||
schema,
|
|
||||||
id: 'SLIDES_PREVIEW',
|
id: 'SLIDES_PREVIEW',
|
||||||
});
|
});
|
||||||
collection.meta.initialize();
|
collection.meta.initialize();
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import {
|
|||||||
MarkdownInlineToDeltaAdapterExtensions,
|
MarkdownInlineToDeltaAdapterExtensions,
|
||||||
} from '@blocksuite/affine/blocks';
|
} from '@blocksuite/affine/blocks';
|
||||||
import { Container } from '@blocksuite/affine/global/di';
|
import { Container } from '@blocksuite/affine/global/di';
|
||||||
import { Schema } from '@blocksuite/affine/store';
|
|
||||||
import { TestWorkspace } from '@blocksuite/affine/store/test';
|
import { TestWorkspace } from '@blocksuite/affine/store/test';
|
||||||
import { describe, expect, test } from 'vitest';
|
import { describe, expect, test } from 'vitest';
|
||||||
|
|
||||||
@@ -29,7 +28,7 @@ describe('markdownToMindmap: convert markdown list to a mind map tree', () => {
|
|||||||
- Text D
|
- Text D
|
||||||
- Text E
|
- Text E
|
||||||
`;
|
`;
|
||||||
const collection = new TestWorkspace({ schema: new Schema() });
|
const collection = new TestWorkspace();
|
||||||
collection.meta.initialize();
|
collection.meta.initialize();
|
||||||
const doc = collection.createDoc();
|
const doc = collection.createDoc();
|
||||||
const nodes = markdownToMindmap(markdown, doc, provider);
|
const nodes = markdownToMindmap(markdown, doc, provider);
|
||||||
@@ -67,7 +66,7 @@ describe('markdownToMindmap: convert markdown list to a mind map tree', () => {
|
|||||||
- Text D
|
- Text D
|
||||||
- Text E
|
- Text E
|
||||||
`;
|
`;
|
||||||
const collection = new TestWorkspace({ schema: new Schema() });
|
const collection = new TestWorkspace();
|
||||||
collection.meta.initialize();
|
collection.meta.initialize();
|
||||||
const doc = collection.createDoc();
|
const doc = collection.createDoc();
|
||||||
const nodes = markdownToMindmap(markdown, doc, provider);
|
const nodes = markdownToMindmap(markdown, doc, provider);
|
||||||
@@ -99,7 +98,7 @@ describe('markdownToMindmap: convert markdown list to a mind map tree', () => {
|
|||||||
|
|
||||||
test('empty case', () => {
|
test('empty case', () => {
|
||||||
const markdown = '';
|
const markdown = '';
|
||||||
const collection = new TestWorkspace({ schema: new Schema() });
|
const collection = new TestWorkspace();
|
||||||
collection.meta.initialize();
|
collection.meta.initialize();
|
||||||
const doc = collection.createDoc();
|
const doc = collection.createDoc();
|
||||||
const nodes = markdownToMindmap(markdown, doc, provider);
|
const nodes = markdownToMindmap(markdown, doc, provider);
|
||||||
|
|||||||
@@ -99,7 +99,6 @@ export class MiniMindmapPreview extends WithDisposable(LitElement) {
|
|||||||
|
|
||||||
const collection = new WorkspaceImpl({
|
const collection = new WorkspaceImpl({
|
||||||
id: 'MINI_MINDMAP_TEMPORARY',
|
id: 'MINI_MINDMAP_TEMPORARY',
|
||||||
schema,
|
|
||||||
});
|
});
|
||||||
collection.meta.initialize();
|
collection.meta.initialize();
|
||||||
const doc = collection.createDoc({ id: 'doc:home' }).load();
|
const doc = collection.createDoc({ id: 'doc:home' }).load();
|
||||||
@@ -237,7 +236,7 @@ export const markdownToMindmap = (
|
|||||||
) => {
|
) => {
|
||||||
let result: Node | null = null;
|
let result: Node | null = null;
|
||||||
const transformer = new Transformer({
|
const transformer = new Transformer({
|
||||||
schema: doc.workspace.schema,
|
schema: doc.schema,
|
||||||
blobCRUD: doc.workspace.blobSync,
|
blobCRUD: doc.workspace.blobSync,
|
||||||
docCRUD: {
|
docCRUD: {
|
||||||
create: (id: string) => doc.workspace.createDoc({ id }),
|
create: (id: string) => doc.workspace.createDoc({ id }),
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ function getNoteBlockModels(doc: Store) {
|
|||||||
|
|
||||||
async function getTransformer(doc: Store) {
|
async function getTransformer(doc: Store) {
|
||||||
return new Transformer({
|
return new Transformer({
|
||||||
schema: doc.workspace.schema,
|
schema: doc.schema,
|
||||||
blobCRUD: doc.workspace.blobSync,
|
blobCRUD: doc.workspace.blobSync,
|
||||||
docCRUD: {
|
docCRUD: {
|
||||||
create: (id: string) => doc.workspace.createDoc({ id }),
|
create: (id: string) => doc.workspace.createDoc({ id }),
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { AppSidebarService } from '@affine/core/modules/app-sidebar';
|
|||||||
import { DocsService } from '@affine/core/modules/doc';
|
import { DocsService } from '@affine/core/modules/doc';
|
||||||
import { EditorSettingService } from '@affine/core/modules/editor-setting';
|
import { EditorSettingService } from '@affine/core/modules/editor-setting';
|
||||||
import { WorkbenchService } from '@affine/core/modules/workbench';
|
import { WorkbenchService } from '@affine/core/modules/workbench';
|
||||||
|
import { getAFFiNEWorkspaceSchema } from '@affine/core/modules/workspace';
|
||||||
import { type DocMode } from '@blocksuite/affine/blocks';
|
import { type DocMode } from '@blocksuite/affine/blocks';
|
||||||
import type { Workspace } from '@blocksuite/affine/store';
|
import type { Workspace } from '@blocksuite/affine/store';
|
||||||
import { useServices } from '@toeverything/infra';
|
import { useServices } from '@toeverything/infra';
|
||||||
@@ -110,6 +111,7 @@ export const usePageHelper = (docCollection: Workspace) => {
|
|||||||
};
|
};
|
||||||
showImportModal({
|
showImportModal({
|
||||||
collection: docCollection,
|
collection: docCollection,
|
||||||
|
schema: getAFFiNEWorkspaceSchema(),
|
||||||
onSuccess,
|
onSuccess,
|
||||||
onFail: message => {
|
onFail: message => {
|
||||||
reject(new Error(message));
|
reject(new Error(message));
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ export async function getContentFromSlice(
|
|||||||
type: 'markdown' | 'plain-text' = 'markdown'
|
type: 'markdown' | 'plain-text' = 'markdown'
|
||||||
) {
|
) {
|
||||||
const transformer = new Transformer({
|
const transformer = new Transformer({
|
||||||
schema: host.std.store.workspace.schema,
|
schema: host.std.store.schema,
|
||||||
blobCRUD: host.std.store.workspace.blobSync,
|
blobCRUD: host.std.store.workspace.blobSync,
|
||||||
docCRUD: {
|
docCRUD: {
|
||||||
create: (id: string) => host.std.store.workspace.createDoc({ id }),
|
create: (id: string) => host.std.store.workspace.createDoc({ id }),
|
||||||
@@ -114,7 +114,7 @@ export const markdownToSnapshot = async (
|
|||||||
host: EditorHost
|
host: EditorHost
|
||||||
) => {
|
) => {
|
||||||
const transformer = new Transformer({
|
const transformer = new Transformer({
|
||||||
schema: host.std.store.workspace.schema,
|
schema: host.std.store.schema,
|
||||||
blobCRUD: host.std.store.workspace.blobSync,
|
blobCRUD: host.std.store.workspace.blobSync,
|
||||||
docCRUD: {
|
docCRUD: {
|
||||||
create: (id: string) => host.std.store.workspace.createDoc({ id }),
|
create: (id: string) => host.std.store.workspace.createDoc({ id }),
|
||||||
@@ -174,12 +174,10 @@ export async function markDownToDoc(
|
|||||||
middlewares?: TransformerMiddleware[]
|
middlewares?: TransformerMiddleware[]
|
||||||
) {
|
) {
|
||||||
// Should not create a new doc in the original collection
|
// Should not create a new doc in the original collection
|
||||||
const collection = new WorkspaceImpl({
|
const collection = new WorkspaceImpl();
|
||||||
schema,
|
|
||||||
});
|
|
||||||
collection.meta.initialize();
|
collection.meta.initialize();
|
||||||
const transformer = new Transformer({
|
const transformer = new Transformer({
|
||||||
schema: collection.schema,
|
schema,
|
||||||
blobCRUD: collection.blobSync,
|
blobCRUD: collection.blobSync,
|
||||||
docCRUD: {
|
docCRUD: {
|
||||||
create: (id: string) => collection.createDoc({ id }),
|
create: (id: string) => collection.createDoc({ id }),
|
||||||
|
|||||||
@@ -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 { useDocCollectionPage } from '@affine/core/components/hooks/use-block-suite-workspace-page';
|
||||||
import { FetchService, GraphQLService } from '@affine/core/modules/cloud';
|
import { FetchService, GraphQLService } from '@affine/core/modules/cloud';
|
||||||
import {
|
import {
|
||||||
getAFFiNEWorkspaceSchema,
|
|
||||||
type WorkspaceFlavourProvider,
|
type WorkspaceFlavourProvider,
|
||||||
WorkspaceService,
|
WorkspaceService,
|
||||||
WorkspacesService,
|
WorkspacesService,
|
||||||
@@ -131,7 +130,6 @@ const getOrCreateShellWorkspace = (
|
|||||||
return Promise.resolve([]);
|
return Promise.resolve([]);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
schema: getAFFiNEWorkspaceSchema(),
|
|
||||||
});
|
});
|
||||||
docCollectionMap.set(workspaceId, docCollection);
|
docCollectionMap.set(workspaceId, docCollection);
|
||||||
docCollection.doc.emit('sync', [true, docCollection.doc]);
|
docCollection.doc.emit('sync', [true, docCollection.doc]);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import {
|
|||||||
resolveGlobalLoadingEventAtom,
|
resolveGlobalLoadingEventAtom,
|
||||||
} from '@affine/component/global-loading';
|
} from '@affine/component/global-loading';
|
||||||
import { EditorService } from '@affine/core/modules/editor';
|
import { EditorService } from '@affine/core/modules/editor';
|
||||||
|
import { getAFFiNEWorkspaceSchema } from '@affine/core/modules/workspace/global-schema';
|
||||||
import { useI18n } from '@affine/i18n';
|
import { useI18n } from '@affine/i18n';
|
||||||
import { track } from '@affine/track';
|
import { track } from '@affine/track';
|
||||||
import type { BlockStdScope } from '@blocksuite/affine/block-std';
|
import type { BlockStdScope } from '@blocksuite/affine/block-std';
|
||||||
@@ -59,7 +60,7 @@ async function exportDoc(
|
|||||||
config: AdapterConfig
|
config: AdapterConfig
|
||||||
) {
|
) {
|
||||||
const transformer = new Transformer({
|
const transformer = new Transformer({
|
||||||
schema: doc.workspace.schema,
|
schema: getAFFiNEWorkspaceSchema(),
|
||||||
blobCRUD: doc.workspace.blobSync,
|
blobCRUD: doc.workspace.blobSync,
|
||||||
docCRUD: {
|
docCRUD: {
|
||||||
create: (id: string) => doc.workspace.createDoc({ id }),
|
create: (id: string) => doc.workspace.createDoc({ id }),
|
||||||
@@ -148,7 +149,11 @@ async function exportHandler({
|
|||||||
await exportToMarkdown(page, editorRoot?.std);
|
await exportToMarkdown(page, editorRoot?.std);
|
||||||
return;
|
return;
|
||||||
case 'snapshot':
|
case 'snapshot':
|
||||||
await ZipTransformer.exportDocs(page.workspace, [page]);
|
await ZipTransformer.exportDocs(
|
||||||
|
page.workspace,
|
||||||
|
getAFFiNEWorkspaceSchema(),
|
||||||
|
[page]
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
case 'pdf':
|
case 'pdf':
|
||||||
await printToPdf(editorContainer);
|
await printToPdf(editorContainer);
|
||||||
|
|||||||
@@ -3,9 +3,9 @@
|
|||||||
*/
|
*/
|
||||||
import 'fake-indexeddb/auto';
|
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 { 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 { TestWorkspace } from '@blocksuite/affine/store/test';
|
||||||
import { renderHook } from '@testing-library/react';
|
import { renderHook } from '@testing-library/react';
|
||||||
import { useAtomValue } from 'jotai';
|
import { useAtomValue } from 'jotai';
|
||||||
@@ -14,12 +14,11 @@ import { beforeEach, describe, expect, test, vi } from 'vitest';
|
|||||||
import { useBlockSuitePagePreview } from '../use-block-suite-page-preview';
|
import { useBlockSuitePagePreview } from '../use-block-suite-page-preview';
|
||||||
let docCollection: TestWorkspace;
|
let docCollection: TestWorkspace;
|
||||||
|
|
||||||
const schema = new Schema();
|
const extensions = StoreExtensions;
|
||||||
schema.register(AffineSchemas);
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
vi.useFakeTimers({ toFake: ['requestIdleCallback'] });
|
vi.useFakeTimers({ toFake: ['requestIdleCallback'] });
|
||||||
docCollection = new TestWorkspace({ id: 'test', schema });
|
docCollection = new TestWorkspace({ id: 'test' });
|
||||||
docCollection.meta.initialize();
|
docCollection.meta.initialize();
|
||||||
const initPage = async (page: Store) => {
|
const initPage = async (page: Store) => {
|
||||||
page.load();
|
page.load();
|
||||||
@@ -31,7 +30,7 @@ beforeEach(async () => {
|
|||||||
const frameId = page.addBlock('affine:note', {}, pageBlockId);
|
const frameId = page.addBlock('affine:note', {}, pageBlockId);
|
||||||
page.addBlock('affine:paragraph', {}, frameId);
|
page.addBlock('affine:paragraph', {}, frameId);
|
||||||
};
|
};
|
||||||
await initPage(docCollection.createDoc({ id: 'page0' }));
|
await initPage(docCollection.createDoc({ id: 'page0', extensions }));
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('useBlockSuitePagePreview', () => {
|
describe('useBlockSuitePagePreview', () => {
|
||||||
|
|||||||
@@ -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 { useRegisterNavigationCommands } from '@affine/core/modules/navigation/view/use-register-navigation-commands';
|
||||||
import { QuickSearchContainer } from '@affine/core/modules/quicksearch';
|
import { QuickSearchContainer } from '@affine/core/modules/quicksearch';
|
||||||
import { WorkbenchService } from '@affine/core/modules/workbench';
|
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 { useI18n } from '@affine/i18n';
|
||||||
import track from '@affine/track';
|
import track from '@affine/track';
|
||||||
import { type DocMode, ZipTransformer } from '@blocksuite/affine/blocks';
|
import { type DocMode, ZipTransformer } from '@blocksuite/affine/blocks';
|
||||||
@@ -74,6 +77,7 @@ export const WorkspaceSideEffects = () => {
|
|||||||
throwIfAborted(abort);
|
throwIfAborted(abort);
|
||||||
const [doc] = await ZipTransformer.importDocs(
|
const [doc] = await ZipTransformer.importDocs(
|
||||||
currentWorkspace.docCollection,
|
currentWorkspace.docCollection,
|
||||||
|
getAFFiNEWorkspaceSchema(),
|
||||||
templateBlob
|
templateBlob
|
||||||
);
|
);
|
||||||
if (doc) {
|
if (doc) {
|
||||||
|
|||||||
@@ -5,7 +5,10 @@ import type {
|
|||||||
WORKSPACE_DIALOG_SCHEMA,
|
WORKSPACE_DIALOG_SCHEMA,
|
||||||
} from '@affine/core/modules/dialogs';
|
} from '@affine/core/modules/dialogs';
|
||||||
import { UrlService } from '@affine/core/modules/url';
|
import { UrlService } from '@affine/core/modules/url';
|
||||||
import { WorkspaceService } from '@affine/core/modules/workspace';
|
import {
|
||||||
|
getAFFiNEWorkspaceSchema,
|
||||||
|
WorkspaceService,
|
||||||
|
} from '@affine/core/modules/workspace';
|
||||||
import { DebugLogger } from '@affine/debug';
|
import { DebugLogger } from '@affine/debug';
|
||||||
import { useI18n } from '@affine/i18n';
|
import { useI18n } from '@affine/i18n';
|
||||||
import track from '@affine/track';
|
import track from '@affine/track';
|
||||||
@@ -141,6 +144,7 @@ const importConfigs: Record<ImportType, ImportConfig> = {
|
|||||||
const fileName = file.name.split('.').slice(0, -1).join('.');
|
const fileName = file.name.split('.').slice(0, -1).join('.');
|
||||||
const docId = await MarkdownTransformer.importMarkdownToDoc({
|
const docId = await MarkdownTransformer.importMarkdownToDoc({
|
||||||
collection: docCollection,
|
collection: docCollection,
|
||||||
|
schema: getAFFiNEWorkspaceSchema(),
|
||||||
markdown: text,
|
markdown: text,
|
||||||
fileName,
|
fileName,
|
||||||
});
|
});
|
||||||
@@ -159,6 +163,7 @@ const importConfigs: Record<ImportType, ImportConfig> = {
|
|||||||
}
|
}
|
||||||
const docIds = await MarkdownTransformer.importMarkdownZip({
|
const docIds = await MarkdownTransformer.importMarkdownZip({
|
||||||
collection: docCollection,
|
collection: docCollection,
|
||||||
|
schema: getAFFiNEWorkspaceSchema(),
|
||||||
imported: file,
|
imported: file,
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
@@ -178,6 +183,7 @@ const importConfigs: Record<ImportType, ImportConfig> = {
|
|||||||
const fileName = file.name.split('.').slice(0, -1).join('.');
|
const fileName = file.name.split('.').slice(0, -1).join('.');
|
||||||
const docId = await HtmlTransformer.importHTMLToDoc({
|
const docId = await HtmlTransformer.importHTMLToDoc({
|
||||||
collection: docCollection,
|
collection: docCollection,
|
||||||
|
schema: getAFFiNEWorkspaceSchema(),
|
||||||
html: text,
|
html: text,
|
||||||
fileName,
|
fileName,
|
||||||
});
|
});
|
||||||
@@ -197,6 +203,7 @@ const importConfigs: Record<ImportType, ImportConfig> = {
|
|||||||
const { entryId, pageIds, isWorkspaceFile } =
|
const { entryId, pageIds, isWorkspaceFile } =
|
||||||
await NotionHtmlTransformer.importNotionZip({
|
await NotionHtmlTransformer.importNotionZip({
|
||||||
collection: docCollection,
|
collection: docCollection,
|
||||||
|
schema: getAFFiNEWorkspaceSchema(),
|
||||||
imported: file,
|
imported: file,
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
@@ -212,7 +219,13 @@ const importConfigs: Record<ImportType, ImportConfig> = {
|
|||||||
if (Array.isArray(file)) {
|
if (Array.isArray(file)) {
|
||||||
throw new Error('Expected a single zip file for snapshot import');
|
throw new Error('Expected a single zip file for snapshot import');
|
||||||
}
|
}
|
||||||
const docIds = (await ZipTransformer.importDocs(docCollection, file))
|
const docIds = (
|
||||||
|
await ZipTransformer.importDocs(
|
||||||
|
docCollection,
|
||||||
|
getAFFiNEWorkspaceSchema(),
|
||||||
|
file
|
||||||
|
)
|
||||||
|
)
|
||||||
.filter(doc => doc !== undefined)
|
.filter(doc => doc !== undefined)
|
||||||
.map(doc => doc.id);
|
.map(doc => doc.id);
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
import { getAFFiNEWorkspaceSchema } from '@affine/core/modules/workspace';
|
||||||
import { WorkspaceImpl } from '@affine/core/modules/workspace/impls/workspace';
|
import { WorkspaceImpl } from '@affine/core/modules/workspace/impls/workspace';
|
||||||
import { AffineSchemas } from '@blocksuite/affine/blocks';
|
|
||||||
import type { DocSnapshot, Store } from '@blocksuite/affine/store';
|
import type { DocSnapshot, Store } from '@blocksuite/affine/store';
|
||||||
import { Schema, Transformer } from '@blocksuite/affine/store';
|
import { Transformer } from '@blocksuite/affine/store';
|
||||||
|
|
||||||
const getCollection = (() => {
|
const getCollection = (() => {
|
||||||
let collection: WorkspaceImpl | null = null;
|
let collection: WorkspaceImpl | null = null;
|
||||||
@@ -9,9 +9,7 @@ const getCollection = (() => {
|
|||||||
if (collection) {
|
if (collection) {
|
||||||
return collection;
|
return collection;
|
||||||
}
|
}
|
||||||
const schema = new Schema();
|
collection = new WorkspaceImpl({});
|
||||||
schema.register(AffineSchemas);
|
|
||||||
collection = new WorkspaceImpl({ schema });
|
|
||||||
collection.meta.initialize();
|
collection.meta.initialize();
|
||||||
return collection;
|
return collection;
|
||||||
};
|
};
|
||||||
@@ -86,7 +84,7 @@ async function initDoc(name: DocName) {
|
|||||||
const snapshot = (await loaders[name]()) as DocSnapshot;
|
const snapshot = (await loaders[name]()) as DocSnapshot;
|
||||||
const collection = await getCollection();
|
const collection = await getCollection();
|
||||||
const transformer = new Transformer({
|
const transformer = new Transformer({
|
||||||
schema: collection.schema,
|
schema: getAFFiNEWorkspaceSchema(),
|
||||||
blobCRUD: collection.blobSync,
|
blobCRUD: collection.blobSync,
|
||||||
docCRUD: {
|
docCRUD: {
|
||||||
create: (id: string) => collection.createDoc({ id }),
|
create: (id: string) => collection.createDoc({ id }),
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import { DndService } from '@affine/core/modules/dnd/services';
|
|||||||
import { GlobalContextService } from '@affine/core/modules/global-context';
|
import { GlobalContextService } from '@affine/core/modules/global-context';
|
||||||
import { OpenInAppGuard } from '@affine/core/modules/open-in-app';
|
import { OpenInAppGuard } from '@affine/core/modules/open-in-app';
|
||||||
import {
|
import {
|
||||||
|
getAFFiNEWorkspaceSchema,
|
||||||
type Workspace,
|
type Workspace,
|
||||||
type WorkspaceMetadata,
|
type WorkspaceMetadata,
|
||||||
WorkspacesService,
|
WorkspacesService,
|
||||||
@@ -279,6 +280,7 @@ const WorkspacePage = ({ meta }: { meta: WorkspaceMetadata }) => {
|
|||||||
window.exportWorkspaceSnapshot = async (docs?: string[]) => {
|
window.exportWorkspaceSnapshot = async (docs?: string[]) => {
|
||||||
await ZipTransformer.exportDocs(
|
await ZipTransformer.exportDocs(
|
||||||
workspace.docCollection,
|
workspace.docCollection,
|
||||||
|
getAFFiNEWorkspaceSchema(),
|
||||||
Array.from(workspace.docCollection.docs.values())
|
Array.from(workspace.docCollection.docs.values())
|
||||||
.filter(doc => (docs ? docs.includes(doc.id) : true))
|
.filter(doc => (docs ? docs.includes(doc.id) : true))
|
||||||
.map(doc => doc.getStore())
|
.map(doc => doc.getStore())
|
||||||
@@ -294,6 +296,7 @@ const WorkspacePage = ({ meta }: { meta: WorkspaceMetadata }) => {
|
|||||||
const blob = new Blob([file], { type: 'application/zip' });
|
const blob = new Blob([file], { type: 'application/zip' });
|
||||||
const newDocs = await ZipTransformer.importDocs(
|
const newDocs = await ZipTransformer.importDocs(
|
||||||
workspace.docCollection,
|
workspace.docCollection,
|
||||||
|
getAFFiNEWorkspaceSchema(),
|
||||||
blob
|
blob
|
||||||
);
|
);
|
||||||
console.log(
|
console.log(
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import {
|
|||||||
initDocFromProps,
|
initDocFromProps,
|
||||||
} from '../../../blocksuite/initialization';
|
} from '../../../blocksuite/initialization';
|
||||||
import type { DocProperties } from '../../db';
|
import type { DocProperties } from '../../db';
|
||||||
|
import { getAFFiNEWorkspaceSchema } from '../../workspace';
|
||||||
import type { Doc } from '../entities/doc';
|
import type { Doc } from '../entities/doc';
|
||||||
import { DocPropertyList } from '../entities/property-list';
|
import { DocPropertyList } from '../entities/property-list';
|
||||||
import { DocRecordList } from '../entities/record-list';
|
import { DocRecordList } from '../entities/record-list';
|
||||||
@@ -202,7 +203,7 @@ export class DocsService extends Service {
|
|||||||
|
|
||||||
const collection = this.store.getBlocksuiteCollection();
|
const collection = this.store.getBlocksuiteCollection();
|
||||||
const transformer = new Transformer({
|
const transformer = new Transformer({
|
||||||
schema: collection.schema,
|
schema: getAFFiNEWorkspaceSchema(),
|
||||||
blobCRUD: collection.blobSync,
|
blobCRUD: collection.blobSync,
|
||||||
docCRUD: {
|
docCRUD: {
|
||||||
create: (id: string) => collection.createDoc({ id }),
|
create: (id: string) => collection.createDoc({ id }),
|
||||||
|
|||||||
@@ -116,7 +116,6 @@ const bookmarkFlavours = new Set([
|
|||||||
|
|
||||||
const markdownPreviewDocCollection = new WorkspaceImpl({
|
const markdownPreviewDocCollection = new WorkspaceImpl({
|
||||||
id: 'indexer',
|
id: 'indexer',
|
||||||
schema: blocksuiteSchema,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function generateMarkdownPreviewBuilder(
|
function generateMarkdownPreviewBuilder(
|
||||||
@@ -190,7 +189,7 @@ function generateMarkdownPreviewBuilder(
|
|||||||
const provider = container.provider();
|
const provider = container.provider();
|
||||||
const markdownAdapter = new MarkdownAdapter(
|
const markdownAdapter = new MarkdownAdapter(
|
||||||
new Transformer({
|
new Transformer({
|
||||||
schema: markdownPreviewDocCollection.schema,
|
schema: getAFFiNEWorkspaceSchema(),
|
||||||
blobCRUD: markdownPreviewDocCollection.blobSync,
|
blobCRUD: markdownPreviewDocCollection.blobSync,
|
||||||
docCRUD: {
|
docCRUD: {
|
||||||
create: (id: string) => markdownPreviewDocCollection.createDoc({ id }),
|
create: (id: string) => markdownPreviewDocCollection.createDoc({ id }),
|
||||||
|
|||||||
@@ -2,7 +2,11 @@ import { type DocMode, ZipTransformer } from '@blocksuite/affine/blocks';
|
|||||||
import { Service } from '@toeverything/infra';
|
import { Service } from '@toeverything/infra';
|
||||||
|
|
||||||
import { DocsService } from '../../doc';
|
import { DocsService } from '../../doc';
|
||||||
import type { WorkspaceMetadata, WorkspacesService } from '../../workspace';
|
import {
|
||||||
|
getAFFiNEWorkspaceSchema,
|
||||||
|
type WorkspaceMetadata,
|
||||||
|
type WorkspacesService,
|
||||||
|
} from '../../workspace';
|
||||||
|
|
||||||
export class ImportTemplateService extends Service {
|
export class ImportTemplateService extends Service {
|
||||||
constructor(private readonly workspacesService: WorkspacesService) {
|
constructor(private readonly workspacesService: WorkspacesService) {
|
||||||
@@ -21,6 +25,7 @@ export class ImportTemplateService extends Service {
|
|||||||
await workspace.engine.doc.waitForDocReady(workspace.id); // wait for root doc ready
|
await workspace.engine.doc.waitForDocReady(workspace.id); // wait for root doc ready
|
||||||
const [importedDoc] = await ZipTransformer.importDocs(
|
const [importedDoc] = await ZipTransformer.importDocs(
|
||||||
workspace.docCollection,
|
workspace.docCollection,
|
||||||
|
getAFFiNEWorkspaceSchema(),
|
||||||
new Blob([docBinary], {
|
new Blob([docBinary], {
|
||||||
type: 'application/zip',
|
type: 'application/zip',
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -53,13 +53,12 @@ import {
|
|||||||
WorkspaceServerService,
|
WorkspaceServerService,
|
||||||
} from '../../cloud';
|
} from '../../cloud';
|
||||||
import type { GlobalState } from '../../storage';
|
import type { GlobalState } from '../../storage';
|
||||||
import {
|
import type {
|
||||||
getAFFiNEWorkspaceSchema,
|
Workspace,
|
||||||
type Workspace,
|
WorkspaceFlavourProvider,
|
||||||
type WorkspaceFlavourProvider,
|
WorkspaceFlavoursProvider,
|
||||||
type WorkspaceFlavoursProvider,
|
WorkspaceMetadata,
|
||||||
type WorkspaceMetadata,
|
WorkspaceProfileInfo,
|
||||||
type WorkspaceProfileInfo,
|
|
||||||
} from '../../workspace';
|
} from '../../workspace';
|
||||||
import { WorkspaceImpl } from '../../workspace/impls/workspace';
|
import { WorkspaceImpl } from '../../workspace/impls/workspace';
|
||||||
import { getWorkspaceProfileWorker } from './out-worker';
|
import { getWorkspaceProfileWorker } from './out-worker';
|
||||||
@@ -163,7 +162,6 @@ class CloudWorkspaceFlavourProvider implements WorkspaceFlavourProvider {
|
|||||||
|
|
||||||
const docCollection = new WorkspaceImpl({
|
const docCollection = new WorkspaceImpl({
|
||||||
id: workspaceId,
|
id: workspaceId,
|
||||||
schema: getAFFiNEWorkspaceSchema(),
|
|
||||||
blobSource: {
|
blobSource: {
|
||||||
get: async key => {
|
get: async key => {
|
||||||
const record = await blobStorage.get(key);
|
const record = await blobStorage.get(key);
|
||||||
|
|||||||
@@ -32,12 +32,11 @@ import { Observable } from 'rxjs';
|
|||||||
import { type Doc as YDoc, encodeStateAsUpdate } from 'yjs';
|
import { type Doc as YDoc, encodeStateAsUpdate } from 'yjs';
|
||||||
|
|
||||||
import { DesktopApiService } from '../../desktop-api';
|
import { DesktopApiService } from '../../desktop-api';
|
||||||
import {
|
import type {
|
||||||
getAFFiNEWorkspaceSchema,
|
WorkspaceFlavourProvider,
|
||||||
type WorkspaceFlavourProvider,
|
WorkspaceFlavoursProvider,
|
||||||
type WorkspaceFlavoursProvider,
|
WorkspaceMetadata,
|
||||||
type WorkspaceMetadata,
|
WorkspaceProfileInfo,
|
||||||
type WorkspaceProfileInfo,
|
|
||||||
} from '../../workspace';
|
} from '../../workspace';
|
||||||
import { WorkspaceImpl } from '../../workspace/impls/workspace';
|
import { WorkspaceImpl } from '../../workspace/impls/workspace';
|
||||||
import { getWorkspaceProfileWorker } from './out-worker';
|
import { getWorkspaceProfileWorker } from './out-worker';
|
||||||
@@ -145,7 +144,6 @@ class LocalWorkspaceFlavourProvider implements WorkspaceFlavourProvider {
|
|||||||
|
|
||||||
const docCollection = new WorkspaceImpl({
|
const docCollection = new WorkspaceImpl({
|
||||||
id: id,
|
id: id,
|
||||||
schema: getAFFiNEWorkspaceSchema(),
|
|
||||||
blobSource: {
|
blobSource: {
|
||||||
get: async key => {
|
get: async key => {
|
||||||
const record = await blobStorage.get(key);
|
const record = await blobStorage.get(key);
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import { Entity, LiveData } from '@toeverything/infra';
|
|||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import type { Awareness } from 'y-protocols/awareness.js';
|
import type { Awareness } from 'y-protocols/awareness.js';
|
||||||
|
|
||||||
import { getAFFiNEWorkspaceSchema } from '../global-schema';
|
|
||||||
import { WorkspaceImpl } from '../impls/workspace';
|
import { WorkspaceImpl } from '../impls/workspace';
|
||||||
import type { WorkspaceScope } from '../scopes/workspace';
|
import type { WorkspaceScope } from '../scopes/workspace';
|
||||||
import { WorkspaceEngineService } from '../services/engine';
|
import { WorkspaceEngineService } from '../services/engine';
|
||||||
@@ -51,7 +50,6 @@ export class Workspace extends Entity {
|
|||||||
name: 'blob',
|
name: 'blob',
|
||||||
readonly: false,
|
readonly: false,
|
||||||
},
|
},
|
||||||
schema: getAFFiNEWorkspaceSchema(),
|
|
||||||
onLoadDoc: doc => this.engine.doc.connectDoc(doc),
|
onLoadDoc: doc => this.engine.doc.connectDoc(doc),
|
||||||
onLoadAwareness: awareness =>
|
onLoadAwareness: awareness =>
|
||||||
this.engine.awareness.connectAwareness(awareness),
|
this.engine.awareness.connectAwareness(awareness),
|
||||||
|
|||||||
@@ -147,10 +147,6 @@ export class DocImpl implements Doc {
|
|||||||
return this._ready;
|
return this._ready;
|
||||||
}
|
}
|
||||||
|
|
||||||
get schema() {
|
|
||||||
return this.workspace.schema;
|
|
||||||
}
|
|
||||||
|
|
||||||
get spaceDoc() {
|
get spaceDoc() {
|
||||||
return this._ySpaceDoc;
|
return this._ySpaceDoc;
|
||||||
}
|
}
|
||||||
@@ -174,13 +170,6 @@ export class DocImpl implements Doc {
|
|||||||
return (readonly?.toString() as 'true' | 'false') ?? 'false';
|
return (readonly?.toString() as 'true' | 'false') ?? 'false';
|
||||||
}
|
}
|
||||||
|
|
||||||
private _handleVersion() {
|
|
||||||
// Initialization from empty yDoc, indicating that the document is new.
|
|
||||||
if (!this.workspace.meta.hasVersion) {
|
|
||||||
this.workspace.meta.writeVersion(this.workspace);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private _handleYBlockAdd(id: string) {
|
private _handleYBlockAdd(id: string) {
|
||||||
this.slots.yBlockUpdated.emit({ type: 'add', id });
|
this.slots.yBlockUpdated.emit({ type: 'add', id });
|
||||||
}
|
}
|
||||||
@@ -296,7 +285,6 @@ export class DocImpl implements Doc {
|
|||||||
|
|
||||||
const doc = new Store({
|
const doc = new Store({
|
||||||
doc: this,
|
doc: this,
|
||||||
schema: this.workspace.schema,
|
|
||||||
readonly,
|
readonly,
|
||||||
query,
|
query,
|
||||||
provider,
|
provider,
|
||||||
@@ -316,10 +304,6 @@ export class DocImpl implements Doc {
|
|||||||
this.spaceDoc.load();
|
this.spaceDoc.load();
|
||||||
this.workspace.onLoadDoc?.(this.spaceDoc);
|
this.workspace.onLoadDoc?.(this.spaceDoc);
|
||||||
|
|
||||||
if ((this.workspace.meta.docs?.length ?? 0) <= 1) {
|
|
||||||
this._handleVersion();
|
|
||||||
}
|
|
||||||
|
|
||||||
this._initYBlocks();
|
this._initYBlocks();
|
||||||
|
|
||||||
this._yBlocks.forEach((_, id) => {
|
this._yBlocks.forEach((_, id) => {
|
||||||
|
|||||||
@@ -3,20 +3,13 @@ import {
|
|||||||
createYProxy,
|
createYProxy,
|
||||||
type DocMeta,
|
type DocMeta,
|
||||||
type DocsPropertiesMeta,
|
type DocsPropertiesMeta,
|
||||||
type Workspace,
|
|
||||||
type WorkspaceMeta,
|
type WorkspaceMeta,
|
||||||
} from '@blocksuite/affine/store';
|
} from '@blocksuite/affine/store';
|
||||||
import type * as Y from 'yjs';
|
import type * as Y from 'yjs';
|
||||||
|
|
||||||
const COLLECTION_VERSION = 2;
|
|
||||||
const PAGE_VERSION = 2;
|
|
||||||
|
|
||||||
type MetaState = {
|
type MetaState = {
|
||||||
pages?: unknown[];
|
pages?: unknown[];
|
||||||
properties?: DocsPropertiesMeta;
|
properties?: DocsPropertiesMeta;
|
||||||
workspaceVersion?: number;
|
|
||||||
pageVersion?: number;
|
|
||||||
blockVersions?: Record<string, number>;
|
|
||||||
name?: string;
|
name?: string;
|
||||||
avatar?: string;
|
avatar?: string;
|
||||||
};
|
};
|
||||||
@@ -102,25 +95,6 @@ export class WorkspaceMetaImpl implements WorkspaceMeta {
|
|||||||
return this._proxy.pages;
|
return this._proxy.pages;
|
||||||
}
|
}
|
||||||
|
|
||||||
get hasVersion() {
|
|
||||||
if (!this._blockVersions || !this._pageVersion || !this._workspaceVersion) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return Object.keys(this._blockVersions).length > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private get _blockVersions() {
|
|
||||||
return this._proxy.blockVersions;
|
|
||||||
}
|
|
||||||
|
|
||||||
private get _pageVersion() {
|
|
||||||
return this._proxy.pageVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
private get _workspaceVersion() {
|
|
||||||
return this._proxy.workspaceVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
get yDocs() {
|
get yDocs() {
|
||||||
return this._yMap.get('pages') as unknown as Y.Array<unknown>;
|
return this._yMap.get('pages') as unknown as Y.Array<unknown>;
|
||||||
}
|
}
|
||||||
@@ -220,33 +194,4 @@ export class WorkspaceMetaImpl implements WorkspaceMeta {
|
|||||||
});
|
});
|
||||||
}, this._doc.clientID);
|
}, this._doc.clientID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @internal Only for doc initialization
|
|
||||||
*/
|
|
||||||
writeVersion(collection: Workspace) {
|
|
||||||
const { blockVersions, pageVersion, workspaceVersion } = this._proxy;
|
|
||||||
|
|
||||||
if (!workspaceVersion) {
|
|
||||||
this._proxy.workspaceVersion = COLLECTION_VERSION;
|
|
||||||
} else {
|
|
||||||
console.error('Workspace version is already set');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pageVersion) {
|
|
||||||
this._proxy.pageVersion = PAGE_VERSION;
|
|
||||||
} else {
|
|
||||||
console.error('Doc version is already set');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!blockVersions) {
|
|
||||||
const _versions: Record<string, number> = {};
|
|
||||||
collection.schema.flavourSchemaMap.forEach((schema, flavour) => {
|
|
||||||
_versions[flavour] = schema.version;
|
|
||||||
});
|
|
||||||
this._proxy.blockVersions = _versions;
|
|
||||||
} else {
|
|
||||||
console.error('Block versions is already set');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import {
|
|||||||
type GetBlocksOptions,
|
type GetBlocksOptions,
|
||||||
type IdGenerator,
|
type IdGenerator,
|
||||||
nanoid,
|
nanoid,
|
||||||
type Schema,
|
|
||||||
type Store,
|
type Store,
|
||||||
type Workspace,
|
type Workspace,
|
||||||
type WorkspaceMeta,
|
type WorkspaceMeta,
|
||||||
@@ -28,15 +27,12 @@ import { WorkspaceMetaImpl } from './meta';
|
|||||||
|
|
||||||
type WorkspaceOptions = {
|
type WorkspaceOptions = {
|
||||||
id?: string;
|
id?: string;
|
||||||
schema: Schema;
|
|
||||||
blobSource?: BlobSource;
|
blobSource?: BlobSource;
|
||||||
onLoadDoc?: (doc: Y.Doc) => void;
|
onLoadDoc?: (doc: Y.Doc) => void;
|
||||||
onLoadAwareness?: (awareness: Awareness) => void;
|
onLoadAwareness?: (awareness: Awareness) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export class WorkspaceImpl implements Workspace {
|
export class WorkspaceImpl implements Workspace {
|
||||||
protected readonly _schema: Schema;
|
|
||||||
|
|
||||||
readonly awarenessStore: AwarenessStore;
|
readonly awarenessStore: AwarenessStore;
|
||||||
|
|
||||||
readonly blobSync: BlobEngine;
|
readonly blobSync: BlobEngine;
|
||||||
@@ -61,22 +57,15 @@ export class WorkspaceImpl implements Workspace {
|
|||||||
return this.blockCollections;
|
return this.blockCollections;
|
||||||
}
|
}
|
||||||
|
|
||||||
get schema() {
|
|
||||||
return this._schema;
|
|
||||||
}
|
|
||||||
|
|
||||||
readonly onLoadDoc?: (doc: Y.Doc) => void;
|
readonly onLoadDoc?: (doc: Y.Doc) => void;
|
||||||
readonly onLoadAwareness?: (awareness: Awareness) => void;
|
readonly onLoadAwareness?: (awareness: Awareness) => void;
|
||||||
|
|
||||||
constructor({
|
constructor({
|
||||||
id,
|
id,
|
||||||
schema,
|
|
||||||
blobSource,
|
blobSource,
|
||||||
onLoadDoc,
|
onLoadDoc,
|
||||||
onLoadAwareness,
|
onLoadAwareness,
|
||||||
}: WorkspaceOptions) {
|
}: WorkspaceOptions = {}) {
|
||||||
this._schema = schema;
|
|
||||||
|
|
||||||
this.id = id || '';
|
this.id = id || '';
|
||||||
this.doc = new Y.Doc({ guid: id });
|
this.doc = new Y.Doc({ guid: id });
|
||||||
this.awarenessStore = new AwarenessStore(new Awareness(this.doc));
|
this.awarenessStore = new AwarenessStore(new Awareness(this.doc));
|
||||||
|
|||||||
@@ -7,7 +7,10 @@ import onboardingUrl from '@affine/templates/onboarding.zip';
|
|||||||
import { ZipTransformer } from '@blocksuite/affine/blocks';
|
import { ZipTransformer } from '@blocksuite/affine/blocks';
|
||||||
|
|
||||||
import { DocsService } from '../modules/doc';
|
import { DocsService } from '../modules/doc';
|
||||||
import type { WorkspacesService } from '../modules/workspace';
|
import {
|
||||||
|
getAFFiNEWorkspaceSchema,
|
||||||
|
type WorkspacesService,
|
||||||
|
} from '../modules/workspace';
|
||||||
|
|
||||||
export async function buildShowcaseWorkspace(
|
export async function buildShowcaseWorkspace(
|
||||||
workspacesService: WorkspacesService,
|
workspacesService: WorkspacesService,
|
||||||
@@ -19,7 +22,11 @@ export async function buildShowcaseWorkspace(
|
|||||||
docCollection.meta.setName(workspaceName);
|
docCollection.meta.setName(workspaceName);
|
||||||
const blob = await (await fetch(onboardingUrl)).blob();
|
const blob = await (await fetch(onboardingUrl)).blob();
|
||||||
|
|
||||||
await ZipTransformer.importDocs(docCollection, blob);
|
await ZipTransformer.importDocs(
|
||||||
|
docCollection,
|
||||||
|
getAFFiNEWorkspaceSchema(),
|
||||||
|
blob
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
const { workspace, dispose } = workspacesService.open({ metadata: meta });
|
const { workspace, dispose } = workspacesService.open({ metadata: meta });
|
||||||
|
|||||||
Reference in New Issue
Block a user