From 897c7d4284eb87cf6a5fcd81d8f126f5e7cc7870 Mon Sep 17 00:00:00 2001 From: Saul-Mirone Date: Fri, 3 Jan 2025 06:30:27 +0000 Subject: [PATCH] refactor(editor): should not rely on doc collection type (#9501) --- .../block-data-view/src/block-meta/todo.ts | 2 +- .../embed-linked-doc-block.ts | 4 +- .../components/embed-synced-doc-card.ts | 2 +- .../embed-synced-doc-block.ts | 2 +- .../nodes/reference-node/reference-node.ts | 2 +- .../affine/shared/src/adapters/attachment.ts | 1 - .../affine/shared/src/adapters/html/html.ts | 1 - .../affine/shared/src/adapters/image.ts | 1 - .../src/adapters/notion-html/notion-html.ts | 1 - .../src/adapters/plain-text/plain-text.ts | 1 - .../src/services/doc-display-meta-service.ts | 2 +- .../affine/shared/src/utils/model/doc.ts | 4 +- .../blocks/src/_common/adapters/mix-text.ts | 1 - .../blocks/src/_common/transformers/html.ts | 6 +- .../src/_common/transformers/markdown.ts | 6 +- .../src/_common/transformers/notion-html.ts | 13 ++- .../blocks/src/_common/transformers/zip.ts | 6 +- .../linked-doc/import-doc/import-doc.ts | 4 +- .../widgets/linked-doc/import-doc/index.ts | 4 +- .../block-std/src/clipboard/index.ts | 1 - .../src/__tests__/collection.unit.spec.ts | 4 +- .../framework/store/src/store/collection.ts | 21 +++-- .../store/src/store/doc/block-collection.ts | 16 +--- blocksuite/framework/store/src/store/index.ts | 1 + blocksuite/framework/store/src/store/meta.ts | 26 ++---- .../framework/store/src/store/workspace.ts | 86 +++++++++++++++++++ .../framework/store/src/transformer/type.ts | 2 +- .../apps/_common/components/docs-panel.ts | 2 +- .../presets/src/__tests__/utils/misc.ts | 4 +- .../tests-legacy/utils/declare-test-window.ts | 4 +- packages/common/env/src/constant.ts | 6 +- packages/common/env/src/filter.ts | 5 +- .../presets/_common/utils/markdown-utils.ts | 9 -- .../core/src/commands/affine-navigation.tsx | 4 +- .../affine/page-history-modal/data.ts | 11 +-- .../page-history-modal/history-modal.tsx | 9 +- .../affine/reference-link/index.tsx | 4 +- .../block-suite-page-list/utils.tsx | 4 +- .../hooks/affine/use-all-page-list-config.tsx | 4 +- .../hooks/affine/use-reference-link-helper.ts | 4 +- .../hooks/use-all-block-suite-page-meta.ts | 10 +-- .../hooks/use-block-suite-page-meta.ts | 4 +- .../hooks/use-block-suite-workspace-helper.ts | 4 +- .../hooks/use-block-suite-workspace-page.ts | 4 +- .../src/components/page-list/page-group.tsx | 4 +- .../core/src/components/page-list/types.ts | 4 +- .../use-block-suite-workspace-page.ts | 4 +- .../core/src/desktop/dialogs/import/index.tsx | 4 +- .../core/src/modules/tag/stores/tag.ts | 2 +- .../modules/workspace/entities/workspace.ts | 7 +- .../modules/workspace/providers/flavour.ts | 4 +- .../src/modules/workspace/scopes/workspace.ts | 2 - .../src/modules/workspace/services/factory.ts | 4 +- .../frontend/core/src/utils/user-setting.ts | 9 +- tsconfig.json | 2 + 55 files changed, 200 insertions(+), 158 deletions(-) create mode 100644 blocksuite/framework/store/src/store/workspace.ts diff --git a/blocksuite/affine/block-data-view/src/block-meta/todo.ts b/blocksuite/affine/block-data-view/src/block-meta/todo.ts index d384ee3b1b..c76a3df464 100644 --- a/blocksuite/affine/block-data-view/src/block-meta/todo.ts +++ b/blocksuite/affine/block-data-view/src/block-meta/todo.ts @@ -53,7 +53,7 @@ todoMeta.addProperty({ metaConfig: propertyPresets.textPropertyConfig, get: block => block.doc.meta?.title ?? '', updated: (block, callback) => { - return block.doc.collection.meta.docMetaUpdated.on(() => { + return block.doc.collection.slots.docListUpdated.on(() => { callback(); }); }, diff --git a/blocksuite/affine/block-embed/src/embed-linked-doc-block/embed-linked-doc-block.ts b/blocksuite/affine/block-embed/src/embed-linked-doc-block/embed-linked-doc-block.ts index 7847f5b0d8..0ecf25d3e3 100644 --- a/blocksuite/affine/block-embed/src/embed-linked-doc-block/embed-linked-doc-block.ts +++ b/blocksuite/affine/block-embed/src/embed-linked-doc-block/embed-linked-doc-block.ts @@ -295,7 +295,7 @@ export class EmbedLinkedDocBlockComponent extends EmbedBlockComponent { + linkedDoc.collection.slots.docListUpdated.on(() => { this._load().catch(e => { console.error(e); this.isError = true; @@ -328,7 +328,7 @@ export class EmbedLinkedDocBlockComponent extends EmbedBlockComponent { + this.doc.collection.slots.docListUpdated.on(() => { this._setDocUpdatedAt(); }) ); diff --git a/blocksuite/affine/block-embed/src/embed-synced-doc-block/components/embed-synced-doc-card.ts b/blocksuite/affine/block-embed/src/embed-synced-doc-block/components/embed-synced-doc-card.ts index adaf26217a..fee07e4f5e 100644 --- a/blocksuite/affine/block-embed/src/embed-synced-doc-block/components/embed-synced-doc-card.ts +++ b/blocksuite/affine/block-embed/src/embed-synced-doc-block/components/embed-synced-doc-card.ts @@ -100,7 +100,7 @@ export class EmbedSyncedDocCard extends WithDisposable(ShadowlessElement) { } this.disposables.add( - syncedDoc.collection.meta.docMetaUpdated.on(() => { + syncedDoc.collection.slots.docListUpdated.on(() => { renderLinkedDocInCard(this); }) ); diff --git a/blocksuite/affine/block-embed/src/embed-synced-doc-block/embed-synced-doc-block.ts b/blocksuite/affine/block-embed/src/embed-synced-doc-block/embed-synced-doc-block.ts index a54d25c817..7a746017d8 100644 --- a/blocksuite/affine/block-embed/src/embed-synced-doc-block/embed-synced-doc-block.ts +++ b/blocksuite/affine/block-embed/src/embed-synced-doc-block/embed-synced-doc-block.ts @@ -475,7 +475,7 @@ export class EmbedSyncedDocBlockComponent extends EmbedBlockComponent { + this.doc.collection.slots.docListUpdated.on(() => { this._setDocUpdatedAt(); }) ); diff --git a/blocksuite/affine/components/src/rich-text/inline/presets/nodes/reference-node/reference-node.ts b/blocksuite/affine/components/src/rich-text/inline/presets/nodes/reference-node/reference-node.ts index bad4205ffc..3b1f09b926 100644 --- a/blocksuite/affine/components/src/rich-text/inline/presets/nodes/reference-node/reference-node.ts +++ b/blocksuite/affine/components/src/rich-text/inline/presets/nodes/reference-node/reference-node.ts @@ -221,7 +221,7 @@ export class AffineReference extends WithDisposable(ShadowlessElement) { const doc = this.doc; if (doc) { this._disposables.add( - doc.collection.slots.docUpdated.on(() => this._updateRefMeta(doc)) + doc.collection.slots.docListUpdated.on(() => this._updateRefMeta(doc)) ); } diff --git a/blocksuite/affine/shared/src/adapters/attachment.ts b/blocksuite/affine/shared/src/adapters/attachment.ts index b30188dfa9..69eee2e442 100644 --- a/blocksuite/affine/shared/src/adapters/attachment.ts +++ b/blocksuite/affine/shared/src/adapters/attachment.ts @@ -26,7 +26,6 @@ export type Attachment = File[]; type AttachmentToSliceSnapshotPayload = { file: Attachment; assets?: AssetsManager; - blockVersions: Record; workspaceId: string; pageId: string; }; diff --git a/blocksuite/affine/shared/src/adapters/html/html.ts b/blocksuite/affine/shared/src/adapters/html/html.ts index 19060d16d1..edaf350aa5 100644 --- a/blocksuite/affine/shared/src/adapters/html/html.ts +++ b/blocksuite/affine/shared/src/adapters/html/html.ts @@ -46,7 +46,6 @@ export type Html = string; type HtmlToSliceSnapshotPayload = { file: Html; assets?: AssetsManager; - blockVersions: Record; workspaceId: string; pageId: string; }; diff --git a/blocksuite/affine/shared/src/adapters/image.ts b/blocksuite/affine/shared/src/adapters/image.ts index e8eca4a0c2..655b8bb792 100644 --- a/blocksuite/affine/shared/src/adapters/image.ts +++ b/blocksuite/affine/shared/src/adapters/image.ts @@ -26,7 +26,6 @@ export type Image = File[]; type ImageToSliceSnapshotPayload = { file: Image; assets?: AssetsManager; - blockVersions: Record; workspaceId: string; pageId: string; }; diff --git a/blocksuite/affine/shared/src/adapters/notion-html/notion-html.ts b/blocksuite/affine/shared/src/adapters/notion-html/notion-html.ts index 2f0e589e0b..8b74ca2dbc 100644 --- a/blocksuite/affine/shared/src/adapters/notion-html/notion-html.ts +++ b/blocksuite/affine/shared/src/adapters/notion-html/notion-html.ts @@ -41,7 +41,6 @@ export type NotionHtml = string; type NotionHtmlToSliceSnapshotPayload = { file: NotionHtml; assets?: AssetsManager; - blockVersions: Record; workspaceId: string; pageId: string; }; diff --git a/blocksuite/affine/shared/src/adapters/plain-text/plain-text.ts b/blocksuite/affine/shared/src/adapters/plain-text/plain-text.ts index 639ca7867c..57fc7fc08f 100644 --- a/blocksuite/affine/shared/src/adapters/plain-text/plain-text.ts +++ b/blocksuite/affine/shared/src/adapters/plain-text/plain-text.ts @@ -40,7 +40,6 @@ export type PlainText = string; type PlainTextToSliceSnapshotPayload = { file: PlainText; assets?: AssetsManager; - blockVersions: Record; workspaceId: string; pageId: string; }; diff --git a/blocksuite/affine/shared/src/services/doc-display-meta-service.ts b/blocksuite/affine/shared/src/services/doc-display-meta-service.ts index df3bf2751b..2ee920e728 100644 --- a/blocksuite/affine/shared/src/services/doc-display-meta-service.ts +++ b/blocksuite/affine/shared/src/services/doc-display-meta-service.ts @@ -162,7 +162,7 @@ export class DocDisplayMetaService if (!title$) { title$ = signal(doc.meta?.title || 'Untitled'); - const disposable = this.std.collection.meta.docMetaUpdated.on(() => { + const disposable = this.std.collection.slots.docListUpdated.on(() => { title$!.value = doc.meta?.title || 'Untitled'; }); diff --git a/blocksuite/affine/shared/src/utils/model/doc.ts b/blocksuite/affine/shared/src/utils/model/doc.ts index 78f2fb37c0..999b9d33ca 100644 --- a/blocksuite/affine/shared/src/utils/model/doc.ts +++ b/blocksuite/affine/shared/src/utils/model/doc.ts @@ -1,7 +1,7 @@ -import type { DocCollection } from '@blocksuite/store'; +import type { Workspace } from '@blocksuite/store'; export function createDefaultDoc( - collection: DocCollection, + collection: Workspace, options: { id?: string; title?: string } = {} ) { const doc = collection.createDoc({ id: options.id }); diff --git a/blocksuite/blocks/src/_common/adapters/mix-text.ts b/blocksuite/blocks/src/_common/adapters/mix-text.ts index f4a9f7ed1d..23c2cd03f1 100644 --- a/blocksuite/blocks/src/_common/adapters/mix-text.ts +++ b/blocksuite/blocks/src/_common/adapters/mix-text.ts @@ -31,7 +31,6 @@ export type MixText = string; type MixTextToSliceSnapshotPayload = { file: MixText; assets?: AssetsManager; - blockVersions: Record; workspaceId: string; pageId: string; }; diff --git a/blocksuite/blocks/src/_common/transformers/html.ts b/blocksuite/blocks/src/_common/transformers/html.ts index 38ce650d28..a30139bc83 100644 --- a/blocksuite/blocks/src/_common/transformers/html.ts +++ b/blocksuite/blocks/src/_common/transformers/html.ts @@ -1,7 +1,7 @@ import { HtmlAdapter } from '@blocksuite/affine-shared/adapters'; import { Container } from '@blocksuite/global/di'; import { sha } from '@blocksuite/global/utils'; -import type { Doc, DocCollection } from '@blocksuite/store'; +import type { Doc, Workspace } from '@blocksuite/store'; import { extMimeMap, Job } from '@blocksuite/store'; import { defaultBlockHtmlAdapterMatchers } from '../adapters/html/block-matcher.js'; @@ -16,13 +16,13 @@ import { import { createAssetsArchive, download, Unzip } from './utils.js'; type ImportHTMLToDocOptions = { - collection: DocCollection; + collection: Workspace; html: string; fileName?: string; }; type ImportHTMLZipOptions = { - collection: DocCollection; + collection: Workspace; imported: Blob; }; diff --git a/blocksuite/blocks/src/_common/transformers/markdown.ts b/blocksuite/blocks/src/_common/transformers/markdown.ts index 60e8611433..730a4d223a 100644 --- a/blocksuite/blocks/src/_common/transformers/markdown.ts +++ b/blocksuite/blocks/src/_common/transformers/markdown.ts @@ -2,7 +2,7 @@ import { MarkdownAdapter } from '@blocksuite/affine-shared/adapters'; import { Container } from '@blocksuite/global/di'; import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions'; import { assertExists, sha } from '@blocksuite/global/utils'; -import type { Doc, DocCollection } from '@blocksuite/store'; +import type { Doc, Workspace } from '@blocksuite/store'; import { extMimeMap, Job } from '@blocksuite/store'; import { defaultBlockMarkdownAdapterMatchers } from '../adapters/index.js'; @@ -34,13 +34,13 @@ type ImportMarkdownToBlockOptions = { }; type ImportMarkdownToDocOptions = { - collection: DocCollection; + collection: Workspace; markdown: string; fileName?: string; }; type ImportMarkdownZipOptions = { - collection: DocCollection; + collection: Workspace; imported: Blob; }; diff --git a/blocksuite/blocks/src/_common/transformers/notion-html.ts b/blocksuite/blocks/src/_common/transformers/notion-html.ts index fbb5bcd98b..13abf74928 100644 --- a/blocksuite/blocks/src/_common/transformers/notion-html.ts +++ b/blocksuite/blocks/src/_common/transformers/notion-html.ts @@ -1,7 +1,7 @@ import { NotionHtmlAdapter } from '@blocksuite/affine-shared/adapters'; import { Container } from '@blocksuite/global/di'; import { sha } from '@blocksuite/global/utils'; -import { type DocCollection, extMimeMap, Job } from '@blocksuite/store'; +import { extMimeMap, Job, type Workspace } from '@blocksuite/store'; import { defaultBlockNotionHtmlAdapterMatchers } from '../adapters/notion-html/block-matcher.js'; import { notionHtmlInlineToDeltaMatchers } from '../adapters/notion-html/delta-converter/html-inline.js'; @@ -9,7 +9,7 @@ import { defaultImageProxyMiddleware } from './middlewares.js'; import { Unzip } from './utils.js'; type ImportNotionZipOptions = { - collection: DocCollection; + collection: Workspace; imported: Blob; }; @@ -26,12 +26,11 @@ const provider = container.provider(); /** * Imports a Notion zip file into the BlockSuite collection. * - * @param {ImportNotionZipOptions} options - The options for importing. - * @param {DocCollection} options.collection - The BlockSuite document collection. - * @param {Blob} options.imported - The imported zip file as a Blob. + * @param options - The options for importing. + * @param options.collection - The BlockSuite document collection. + * @param options.imported - The imported zip file as a Blob. * - * @returns {Promise<{entryId: string | undefined, pageIds: string[], isWorkspaceFile: boolean, hasMarkdown: boolean}>} - * A promise that resolves to an object containing: + * @returns A promise that resolves to an object containing: * - entryId: The ID of the entry page (if any). * - pageIds: An array of imported page IDs. * - isWorkspaceFile: Whether the imported file is a workspace file. diff --git a/blocksuite/blocks/src/_common/transformers/zip.ts b/blocksuite/blocks/src/_common/transformers/zip.ts index 913548b839..6090642ff4 100644 --- a/blocksuite/blocks/src/_common/transformers/zip.ts +++ b/blocksuite/blocks/src/_common/transformers/zip.ts @@ -1,11 +1,11 @@ import { sha } from '@blocksuite/global/utils'; -import type { Doc, DocCollection, DocSnapshot } from '@blocksuite/store'; +import type { Doc, DocSnapshot, Workspace } from '@blocksuite/store'; import { extMimeMap, getAssetName, Job } from '@blocksuite/store'; import { download, Unzip, Zip } from '../transformers/utils.js'; import { replaceIdMiddleware, titleMiddleware } from './middlewares.js'; -async function exportDocs(collection: DocCollection, docs: Doc[]) { +async function exportDocs(collection: Workspace, docs: Doc[]) { const zip = new Zip(); const job = new Job({ schema: collection.schema, @@ -50,7 +50,7 @@ async function exportDocs(collection: DocCollection, docs: Doc[]) { return download(downloadBlob, `${collection.id}.bs.zip`); } -async function importDocs(collection: DocCollection, imported: Blob) { +async function importDocs(collection: Workspace, imported: Blob) { const unzip = new Unzip(); await unzip.load(imported); diff --git a/blocksuite/blocks/src/root-block/widgets/linked-doc/import-doc/import-doc.ts b/blocksuite/blocks/src/root-block/widgets/linked-doc/import-doc/import-doc.ts index 1825e31054..d5210ab270 100644 --- a/blocksuite/blocks/src/root-block/widgets/linked-doc/import-doc/import-doc.ts +++ b/blocksuite/blocks/src/root-block/widgets/linked-doc/import-doc/import-doc.ts @@ -8,7 +8,7 @@ import { } from '@blocksuite/affine-components/icons'; import { openFileOrFiles } from '@blocksuite/affine-shared/utils'; import { WithDisposable } from '@blocksuite/global/utils'; -import type { DocCollection } from '@blocksuite/store'; +import type { Workspace } from '@blocksuite/store'; import { html, LitElement, type PropertyValues } from 'lit'; import { query, state } from 'lit/decorators.js'; @@ -30,7 +30,7 @@ export class ImportDoc extends WithDisposable(LitElement) { static override styles = styles; constructor( - private readonly collection: DocCollection, + private readonly collection: Workspace, private readonly onSuccess?: OnSuccessHandler, private readonly onFail?: OnFailHandler, private readonly abortController = new AbortController() diff --git a/blocksuite/blocks/src/root-block/widgets/linked-doc/import-doc/index.ts b/blocksuite/blocks/src/root-block/widgets/linked-doc/import-doc/index.ts index 681b6acc71..0de77bcceb 100644 --- a/blocksuite/blocks/src/root-block/widgets/linked-doc/import-doc/index.ts +++ b/blocksuite/blocks/src/root-block/widgets/linked-doc/import-doc/index.ts @@ -1,4 +1,4 @@ -import type { DocCollection } from '@blocksuite/store'; +import type { Workspace } from '@blocksuite/store'; import { ImportDoc, @@ -13,7 +13,7 @@ export function showImportModal({ container = document.body, abortController = new AbortController(), }: { - collection: DocCollection; + collection: Workspace; onSuccess?: OnSuccessHandler; onFail?: OnFailHandler; multiple?: boolean; diff --git a/blocksuite/framework/block-std/src/clipboard/index.ts b/blocksuite/framework/block-std/src/clipboard/index.ts index fefcf3b47e..132060d865 100644 --- a/blocksuite/framework/block-std/src/clipboard/index.ts +++ b/blocksuite/framework/block-std/src/clipboard/index.ts @@ -138,7 +138,6 @@ export class Clipboard extends LifeCycleWatcher { const payload = { file: item, assets: job.assetsManager, - blockVersions: doc.collection.meta.blockVersions, workspaceId: doc.collection.id, pageId: doc.id, }; diff --git a/blocksuite/framework/store/src/__tests__/collection.unit.spec.ts b/blocksuite/framework/store/src/__tests__/collection.unit.spec.ts index 5e76e37d5a..64342ed769 100644 --- a/blocksuite/framework/store/src/__tests__/collection.unit.spec.ts +++ b/blocksuite/framework/store/src/__tests__/collection.unit.spec.ts @@ -7,7 +7,7 @@ import { applyUpdate, encodeStateAsUpdate } from 'yjs'; import { COLLECTION_VERSION, PAGE_VERSION } from '../consts.js'; import type { BlockModel, BlockSchemaType, Doc } from '../index.js'; import { DocCollection, IdGeneratorType, Schema } from '../index.js'; -import type { DocMeta } from '../store/index.js'; +import type { DocMeta } from '../store/workspace.js'; import type { BlockSuiteDoc } from '../yjs/index.js'; import { NoteBlockSchema, @@ -432,7 +432,7 @@ describe('addBlock', () => { ); let called = false; - collection.meta.docMetaUpdated.on(() => { + collection.slots.docListUpdated.on(() => { called = true; }); diff --git a/blocksuite/framework/store/src/store/collection.ts b/blocksuite/framework/store/src/store/collection.ts index 6162f6e14d..f71ca30b27 100644 --- a/blocksuite/framework/store/src/store/collection.ts +++ b/blocksuite/framework/store/src/store/collection.ts @@ -22,11 +22,16 @@ import { BlockSuiteDoc, type RawAwarenessState, } from '../yjs/index.js'; -import { BlockCollection, type GetDocOptions } from './doc/block-collection.js'; -import type { Doc, Query } from './doc/index.js'; +import { BlockCollection } from './doc/block-collection.js'; +import type { Doc } from './doc/index.js'; import type { IdGeneratorType } from './id.js'; import { pickIdGenerator } from './id.js'; import { DocCollectionMeta } from './meta.js'; +import type { + CreateDocOptions, + GetDocOptions, + Workspace, +} from './workspace.js'; export type DocCollectionOptions = { schema: Schema; @@ -69,7 +74,7 @@ export interface StackItem { meta: Map<'cursor-location' | 'selection-state', unknown>; } -export class DocCollection { +export class DocCollection implements Workspace { protected readonly _schema: Schema; readonly awarenessStore: AwarenessStore; @@ -91,7 +96,7 @@ export class DocCollection { meta: DocCollectionMeta; slots = { - docUpdated: new Slot(), + docListUpdated: new Slot(), docRemoved: new Slot(), docCreated: new Slot(), }; @@ -161,7 +166,7 @@ export class DocCollection { this.blockCollections.set(doc.id, doc); }); - this.meta.docMetaUpdated.on(() => this.slots.docUpdated.emit()); + this.meta.docMetaUpdated.on(() => this.slots.docListUpdated.emit()); this.meta.docMetaRemoved.on(id => { const space = this.getBlockCollection(id); @@ -189,8 +194,8 @@ export class DocCollection { * If the `init` parameter is passed, a `surface`, `note`, and `paragraph` block * will be created in the doc simultaneously. */ - createDoc(options: { id?: string; query?: Query } = {}) { - const { id: docId = this.idGenerator(), query } = options; + createDoc(options: CreateDocOptions = {}) { + const { id: docId = this.idGenerator(), query, readonly } = options; if (this._hasDoc(docId)) { throw new BlockSuiteError( ErrorCode.DocCollectionError, @@ -205,7 +210,7 @@ export class DocCollection { tags: [], }); this.slots.docCreated.emit(docId); - return this.getDoc(docId, { query }) as Doc; + return this.getDoc(docId, { query, readonly }) as Doc; } dispose() { diff --git a/blocksuite/framework/store/src/store/doc/block-collection.ts b/blocksuite/framework/store/src/store/doc/block-collection.ts index bc285885d4..57a1c6da6b 100644 --- a/blocksuite/framework/store/src/store/doc/block-collection.ts +++ b/blocksuite/framework/store/src/store/doc/block-collection.ts @@ -7,7 +7,7 @@ import { Text } from '../../reactive/text.js'; import type { BlockModel } from '../../schema/base.js'; import type { IdGenerator } from '../../utils/id-generator.js'; import type { AwarenessStore, BlockSuiteDoc } from '../../yjs/index.js'; -import type { DocCollection } from '../collection.js'; +import type { GetDocOptions, Workspace } from '../workspace.js'; import { Doc } from './doc.js'; import type { YBlock } from './index.js'; import type { Query } from './query.js'; @@ -24,17 +24,12 @@ export type BlockProps = BlockSysProps & Record; type DocOptions = { id: string; - collection: DocCollection; + collection: Workspace; doc: BlockSuiteDoc; awarenessStore: AwarenessStore; idGenerator?: IdGenerator; }; -export type GetDocOptions = { - query?: Query; - readonly?: boolean; -}; - export class BlockCollection { private _awarenessUpdateDisposable: Disposable | null = null; @@ -42,7 +37,7 @@ export class BlockCollection { private readonly _canUndo$ = signal(false); - private readonly _collection: DocCollection; + private readonly _collection: Workspace; private readonly _docMap = { undefined: new Map(), @@ -145,11 +140,6 @@ export class BlockCollection { >(), }; - // So, we apply a listener at the top level for the flat structure of the current - get awarenessSync() { - return this.collection.awarenessSync; - } - get blobSync() { return this.collection.blobSync; } diff --git a/blocksuite/framework/store/src/store/index.ts b/blocksuite/framework/store/src/store/index.ts index ebdadefa26..8024bbd343 100644 --- a/blocksuite/framework/store/src/store/index.ts +++ b/blocksuite/framework/store/src/store/index.ts @@ -4,3 +4,4 @@ export type * from './doc/block-collection.js'; export * from './doc/index.js'; export * from './id.js'; export type * from './meta.js'; +export * from './workspace.js'; diff --git a/blocksuite/framework/store/src/store/meta.ts b/blocksuite/framework/store/src/store/meta.ts index f446893955..33f8e02e76 100644 --- a/blocksuite/framework/store/src/store/meta.ts +++ b/blocksuite/framework/store/src/store/meta.ts @@ -4,26 +4,12 @@ import type * as Y from 'yjs'; import { COLLECTION_VERSION, PAGE_VERSION } from '../consts.js'; import type { BlockSuiteDoc } from '../yjs/index.js'; import type { DocCollection } from './collection.js'; +import type { + DocMeta, + DocsPropertiesMeta, + WorkspaceMeta, +} from './workspace.js'; -// please use `declare module '@blocksuite/store'` to extend this interface -export interface DocMeta { - id: string; - title: string; - tags: string[]; - createDate: number; - updatedDate?: number; -} - -export type Tag = { - id: string; - value: string; - color: string; -}; -export type DocsPropertiesMeta = { - tags?: { - options: Tag[]; - }; -}; export type DocCollectionMetaState = { pages?: unknown[]; properties?: DocsPropertiesMeta; @@ -34,7 +20,7 @@ export type DocCollectionMetaState = { avatar?: string; }; -export class DocCollectionMeta { +export class DocCollectionMeta implements WorkspaceMeta { private readonly _handleDocCollectionMetaEvents = ( events: Y.YEvent | Y.Text | Y.Map>[] ) => { diff --git a/blocksuite/framework/store/src/store/workspace.ts b/blocksuite/framework/store/src/store/workspace.ts new file mode 100644 index 0000000000..a75e775f65 --- /dev/null +++ b/blocksuite/framework/store/src/store/workspace.ts @@ -0,0 +1,86 @@ +import type { Slot } from '@blocksuite/global/utils'; +import type { BlobEngine, DocEngine } from '@blocksuite/sync'; + +import type { Schema } from '../schema/schema.js'; +import type { IdGenerator } from '../utils/id-generator.js'; +import type { AwarenessStore } from '../yjs/awareness.js'; +import type { BlockSuiteDoc } from '../yjs/doc.js'; +import type { Doc } from './doc/doc.js'; +import type { BlockCollection } from './doc/index.js'; +import type { Query } from './doc/query.js'; + +export type Tag = { + id: string; + value: string; + color: string; +}; +export type DocsPropertiesMeta = { + tags?: { + options: Tag[]; + }; +}; +export interface DocMeta { + id: string; + title: string; + tags: string[]; + createDate: number; + updatedDate?: number; + favorite?: boolean; +} + +export type GetDocOptions = { + query?: Query; + readonly?: boolean; +}; +export type CreateDocOptions = GetDocOptions & { + id?: string; +}; + +export interface WorkspaceMeta { + get docMetas(): DocMeta[]; + + getDocMeta(id: string): DocMeta | undefined; + setDocMeta(id: string, props: Partial): void; + removeDocMeta(id: string): void; + + get properties(): DocsPropertiesMeta; + setProperties(meta: DocsPropertiesMeta): void; + + get avatar(): string | undefined; + setAvatar(avatar: string): void; + + get name(): string | undefined; + setName(name: string): void; + + commonFieldsUpdated: Slot; + + hasVersion: boolean; + writeVersion(workspace: Workspace): void; + get docs(): unknown[] | undefined; + initialize(): void; +} + +export interface Workspace { + readonly id: string; + readonly meta: WorkspaceMeta; + readonly idGenerator: IdGenerator; + readonly docSync: DocEngine; + readonly blobSync: BlobEngine; + readonly awarenessStore: AwarenessStore; + + get schema(): Schema; + get doc(): BlockSuiteDoc; + get docs(): Map; + + slots: { + docListUpdated: Slot; + docCreated: Slot; + docRemoved: Slot; + }; + + createDoc(options?: CreateDocOptions): Doc; + getDoc(docId: string, options?: GetDocOptions): Doc | null; + removeDoc(docId: string): void; + + dispose(): void; +} diff --git a/blocksuite/framework/store/src/transformer/type.ts b/blocksuite/framework/store/src/transformer/type.ts index 7ece53061c..e6d48467a3 100644 --- a/blocksuite/framework/store/src/transformer/type.ts +++ b/blocksuite/framework/store/src/transformer/type.ts @@ -1,7 +1,7 @@ import { z } from 'zod'; import type { Doc } from '../store/doc/doc.js'; -import type { DocMeta, DocsPropertiesMeta } from '../store/meta.js'; +import type { DocMeta, DocsPropertiesMeta } from '../store/workspace.js'; export type BlockSnapshot = { type: 'block'; diff --git a/blocksuite/playground/apps/_common/components/docs-panel.ts b/blocksuite/playground/apps/_common/components/docs-panel.ts index d342b1f026..4a9c290e02 100644 --- a/blocksuite/playground/apps/_common/components/docs-panel.ts +++ b/blocksuite/playground/apps/_common/components/docs-panel.ts @@ -110,7 +110,7 @@ export class DocsPanel extends WithDisposable(ShadowlessElement) { }); this.disposables.add( - this.editor.doc.collection.slots.docUpdated.on(() => { + this.editor.doc.collection.slots.docListUpdated.on(() => { this.requestUpdate(); }) ); diff --git a/blocksuite/presets/src/__tests__/utils/misc.ts b/blocksuite/presets/src/__tests__/utils/misc.ts index 49e294d49e..d41731b5d7 100644 --- a/blocksuite/presets/src/__tests__/utils/misc.ts +++ b/blocksuite/presets/src/__tests__/utils/misc.ts @@ -1,8 +1,8 @@ import { replaceIdMiddleware } from '@blocksuite/blocks'; -import { type DocCollection, type DocSnapshot, Job } from '@blocksuite/store'; +import { type DocSnapshot, Job, type Workspace } from '@blocksuite/store'; export async function importFromSnapshot( - collection: DocCollection, + collection: Workspace, snapshot: DocSnapshot ) { const job = new Job({ diff --git a/blocksuite/tests-legacy/utils/declare-test-window.ts b/blocksuite/tests-legacy/utils/declare-test-window.ts index 3f57d33d3d..84e37465ac 100644 --- a/blocksuite/tests-legacy/utils/declare-test-window.ts +++ b/blocksuite/tests-legacy/utils/declare-test-window.ts @@ -6,7 +6,7 @@ import type { } from '@blocksuite/block-std'; import type { AffineEditorContainer } from '@blocksuite/presets'; import type { StarterDebugMenu } from '@playground/apps/_common/components/starter-debug-menu.js'; -import type { BlockModel, Doc, DocCollection, Job } from '@store/index.js'; +import type { BlockModel, Doc, Job, Workspace } from '@store/index.js'; declare global { interface Window { @@ -36,7 +36,7 @@ declare global { mockDocModeService: typeof import('../../packages/playground/apps/_common/mock-services.js').mockDocModeService; }; }; - collection: DocCollection; + collection: Workspace; blockSchema: Record; doc: Doc; debugMenu: StarterDebugMenu; diff --git a/packages/common/env/src/constant.ts b/packages/common/env/src/constant.ts index ee83ac8523..3e907d5d43 100644 --- a/packages/common/env/src/constant.ts +++ b/packages/common/env/src/constant.ts @@ -1,7 +1,7 @@ // This file should has not side effect // oxlint-disable-next-line // @ts-ignore FIXME: typecheck error -import type { DocCollection } from '@blocksuite/affine/store'; +import type { Workspace } from '@blocksuite/affine/store'; declare global { // oxlint-disable-next-line no-var @@ -91,10 +91,10 @@ export const Messages = { }; export class PageNotFoundError extends TypeError { - readonly docCollection: DocCollection; + readonly docCollection: Workspace; readonly pageId: string; - constructor(docCollection: DocCollection, pageId: string) { + constructor(docCollection: Workspace, pageId: string) { super(); this.docCollection = docCollection; this.pageId = pageId; diff --git a/packages/common/env/src/filter.ts b/packages/common/env/src/filter.ts index db2d1a5e24..82e63b1ee6 100644 --- a/packages/common/env/src/filter.ts +++ b/packages/common/env/src/filter.ts @@ -1,4 +1,4 @@ -import type { DocCollection } from '@blocksuite/affine/store'; +import type { DocsPropertiesMeta } from '@blocksuite/affine/store'; import { z } from 'zod'; export const literalValueSchema: z.ZodType = @@ -29,7 +29,6 @@ export type Ref = { name: keyof VariableMap; }; -// eslint-disable-next-line @typescript-eslint/no-empty-interface export interface VariableMap {} export const literalSchema = z.object({ @@ -85,4 +84,4 @@ export const tagSchema = z.object({ }); export type Tag = z.input; -export type PropertiesMeta = DocCollection['meta']['properties']; +export type PropertiesMeta = DocsPropertiesMeta; diff --git a/packages/frontend/core/src/blocksuite/presets/_common/utils/markdown-utils.ts b/packages/frontend/core/src/blocksuite/presets/_common/utils/markdown-utils.ts index 9a7f696a04..bbdae671eb 100644 --- a/packages/frontend/core/src/blocksuite/presets/_common/utils/markdown-utils.ts +++ b/packages/frontend/core/src/blocksuite/presets/_common/utils/markdown-utils.ts @@ -145,18 +145,9 @@ export const markdownToSnapshot = async ( middlewares: [defaultImageProxyMiddleware, pasteMiddleware(host.std)], }); const markdownAdapter = new MixTextAdapter(job, host.std.provider); - const { blockVersions, workspaceVersion, pageVersion } = - host.std.doc.collection.meta; - if (!blockVersions || !workspaceVersion || !pageVersion) - throw new Error( - 'Need blockVersions, workspaceVersion, pageVersion meta information to get slice' - ); const payload = { file: markdown, assets: job.assetsManager, - blockVersions, - pageVersion, - workspaceVersion, workspaceId: host.std.doc.collection.id, pageId: host.std.doc.id, }; diff --git a/packages/frontend/core/src/commands/affine-navigation.tsx b/packages/frontend/core/src/commands/affine-navigation.tsx index de2a3f708d..f96025499a 100644 --- a/packages/frontend/core/src/commands/affine-navigation.tsx +++ b/packages/frontend/core/src/commands/affine-navigation.tsx @@ -1,6 +1,6 @@ import type { useI18n } from '@affine/i18n'; import { track } from '@affine/track'; -import type { DocCollection } from '@blocksuite/affine/store'; +import type { Workspace } from '@blocksuite/affine/store'; import { ArrowRightBigIcon } from '@blocksuite/icons/rc'; import type { createStore } from 'jotai'; @@ -19,7 +19,7 @@ export function registerAffineNavigationCommands({ t: ReturnType; store: ReturnType; navigationHelper: ReturnType; - docCollection: DocCollection; + docCollection: Workspace; globalDialogService: GlobalDialogService; }) { const unsubs: Array<() => void> = []; diff --git a/packages/frontend/core/src/components/affine/page-history-modal/data.ts b/packages/frontend/core/src/components/affine/page-history-modal/data.ts index f847d50de1..d763d4b6b0 100644 --- a/packages/frontend/core/src/components/affine/page-history-modal/data.ts +++ b/packages/frontend/core/src/components/affine/page-history-modal/data.ts @@ -7,7 +7,7 @@ import type { ListHistoryQuery } from '@affine/graphql'; import { listHistoryQuery, recoverDocMutation } from '@affine/graphql'; import { i18nTime } from '@affine/i18n'; import { assertEquals } from '@blocksuite/affine/global/utils'; -import { DocCollection } from '@blocksuite/affine/store'; +import { DocCollection, type Workspace } from '@blocksuite/affine/store'; import { useService } from '@toeverything/infra'; import { useEffect, useMemo } from 'react'; import useSWRImmutable from 'swr/immutable'; @@ -99,7 +99,7 @@ const snapshotFetcher = async ( // so that we do not need to worry about providers etc // TODO(@Peng): fix references to the page (the referenced page will shown as deleted) // if we simply clone the current workspace, it maybe time consuming right? -const docCollectionMap = new Map(); +const docCollectionMap = new Map(); // assume the workspace is a cloud workspace since the history feature is only enabled for cloud workspace const getOrCreateShellWorkspace = ( @@ -147,7 +147,7 @@ export const usePageHistory = ( // workspace id + page id + timestamp + snapshot -> Page (to be used for rendering in blocksuite editor) export const useSnapshotPage = ( - docCollection: DocCollection, + docCollection: Workspace, pageDocId: string, ts?: string ) => { @@ -253,10 +253,7 @@ export function revertUpdate( applyUpdate(doc, revertChangesSinceSnapshotUpdate); } -export const useRestorePage = ( - docCollection: DocCollection, - pageId: string -) => { +export const useRestorePage = (docCollection: Workspace, pageId: string) => { const page = useDocCollectionPage(docCollection, pageId); const mutateQueryResource = useMutateQueryResource(); const { trigger: recover, isMutating } = useMutation({ diff --git a/packages/frontend/core/src/components/affine/page-history-modal/history-modal.tsx b/packages/frontend/core/src/components/affine/page-history-modal/history-modal.tsx index e66774cebe..911eb013e7 100644 --- a/packages/frontend/core/src/components/affine/page-history-modal/history-modal.tsx +++ b/packages/frontend/core/src/components/affine/page-history-modal/history-modal.tsx @@ -11,10 +11,7 @@ import { WorkspaceService } from '@affine/core/modules/workspace'; import { i18nTime, Trans, useI18n } from '@affine/i18n'; import { track } from '@affine/track'; import type { DocMode } from '@blocksuite/affine/blocks'; -import type { - Doc as BlockSuiteDoc, - DocCollection, -} from '@blocksuite/affine/store'; +import type { Doc as BlockSuiteDoc, Workspace } from '@blocksuite/affine/store'; import { CloseIcon, ToggleCollapseIcon } from '@blocksuite/icons/rc'; import * as Collapsible from '@radix-ui/react-collapsible'; import type { DialogContentProps } from '@radix-ui/react-dialog'; @@ -48,7 +45,7 @@ import * as styles from './styles.css'; export interface PageHistoryModalProps { open: boolean; onOpenChange: (open: boolean) => void; - docCollection: DocCollection; + docCollection: Workspace; pageId: string; } @@ -400,7 +397,7 @@ const PageHistoryManager = ({ pageId, onClose, }: { - docCollection: DocCollection; + docCollection: Workspace; pageId: string; onClose: () => void; }) => { diff --git a/packages/frontend/core/src/components/affine/reference-link/index.tsx b/packages/frontend/core/src/components/affine/reference-link/index.tsx index 4b6a7036fd..206bc367a4 100644 --- a/packages/frontend/core/src/components/affine/reference-link/index.tsx +++ b/packages/frontend/core/src/components/affine/reference-link/index.tsx @@ -6,7 +6,7 @@ import { useInsidePeekView } from '@affine/core/modules/peek-view/view/modal-con import { WorkbenchLink } from '@affine/core/modules/workbench'; import { track } from '@affine/track'; import type { DocMode } from '@blocksuite/affine/blocks'; -import type { DocCollection } from '@blocksuite/affine/store'; +import type { Workspace } from '@blocksuite/affine/store'; import { LiveData, useLiveData, useService } from '@toeverything/infra'; import clsx from 'clsx'; import { nanoid } from 'nanoid'; @@ -167,7 +167,7 @@ export function AffineSharedPageReference({ Icon, onClick: userOnClick, }: AffinePageReferenceProps & { - docCollection: DocCollection; + docCollection: Workspace; }) { const journalService = useService(JournalService); const isJournal = !!useLiveData(journalService.journalDate$(pageId)); diff --git a/packages/frontend/core/src/components/blocksuite/block-suite-page-list/utils.tsx b/packages/frontend/core/src/components/blocksuite/block-suite-page-list/utils.tsx index aa3aed7a9b..44559f9b34 100644 --- a/packages/frontend/core/src/components/blocksuite/block-suite-page-list/utils.tsx +++ b/packages/frontend/core/src/components/blocksuite/block-suite-page-list/utils.tsx @@ -5,11 +5,11 @@ import { DocsService } from '@affine/core/modules/doc'; import { EditorSettingService } from '@affine/core/modules/editor-setting'; import { WorkbenchService } from '@affine/core/modules/workbench'; import { type DocMode } from '@blocksuite/affine/blocks'; -import type { DocCollection } from '@blocksuite/affine/store'; +import type { Workspace } from '@blocksuite/affine/store'; import { useServices } from '@toeverything/infra'; import { useCallback, useMemo } from 'react'; -export const usePageHelper = (docCollection: DocCollection) => { +export const usePageHelper = (docCollection: Workspace) => { const { docsService, workbenchService, diff --git a/packages/frontend/core/src/components/hooks/affine/use-all-page-list-config.tsx b/packages/frontend/core/src/components/hooks/affine/use-all-page-list-config.tsx index b924280694..308dde7cd7 100644 --- a/packages/frontend/core/src/components/hooks/affine/use-all-page-list-config.tsx +++ b/packages/frontend/core/src/components/hooks/affine/use-all-page-list-config.tsx @@ -6,13 +6,13 @@ import { ShareDocsListService } from '@affine/core/modules/share-doc'; import { WorkspaceService } from '@affine/core/modules/workspace'; import { PublicPageMode } from '@affine/graphql'; import { useI18n } from '@affine/i18n'; -import type { DocCollection, DocMeta } from '@blocksuite/affine/store'; +import type { DocMeta, Workspace } from '@blocksuite/affine/store'; import { useLiveData, useService } from '@toeverything/infra'; import { type ReactNode, useCallback, useEffect, useMemo } from 'react'; export type AllPageListConfig = { allPages: DocMeta[]; - docCollection: DocCollection; + docCollection: Workspace; /** * Return `undefined` if the page is not public */ diff --git a/packages/frontend/core/src/components/hooks/affine/use-reference-link-helper.ts b/packages/frontend/core/src/components/hooks/affine/use-reference-link-helper.ts index 31285214e2..d696c54a36 100644 --- a/packages/frontend/core/src/components/hooks/affine/use-reference-link-helper.ts +++ b/packages/frontend/core/src/components/hooks/affine/use-reference-link-helper.ts @@ -1,9 +1,9 @@ import type { DeltaInsert } from '@blocksuite/affine/inline'; -import type { DocCollection } from '@blocksuite/affine/store'; +import type { Workspace } from '@blocksuite/affine/store'; import type { AffineTextAttributes } from '@blocksuite/affine-shared/types'; import { useCallback } from 'react'; -export function useReferenceLinkHelper(docCollection: DocCollection) { +export function useReferenceLinkHelper(docCollection: Workspace) { const addReferenceLink = useCallback( (pageId: string, referenceId: string) => { const page = docCollection?.getDoc(pageId); diff --git a/packages/frontend/core/src/components/hooks/use-all-block-suite-page-meta.ts b/packages/frontend/core/src/components/hooks/use-all-block-suite-page-meta.ts index 52ef8099a6..e6b20ea6a0 100644 --- a/packages/frontend/core/src/components/hooks/use-all-block-suite-page-meta.ts +++ b/packages/frontend/core/src/components/hooks/use-all-block-suite-page-meta.ts @@ -1,19 +1,17 @@ -import type { DocCollection, DocMeta } from '@blocksuite/affine/store'; +import type { DocMeta, Workspace } from '@blocksuite/affine/store'; import type { Atom } from 'jotai'; import { atom, useAtomValue } from 'jotai'; -const weakMap = new WeakMap>(); +const weakMap = new WeakMap>(); // this hook is extracted from './use-block-suite-page-meta.ts' to avoid circular dependency -export function useAllBlockSuiteDocMeta( - docCollection: DocCollection -): DocMeta[] { +export function useAllBlockSuiteDocMeta(docCollection: Workspace): DocMeta[] { if (!weakMap.has(docCollection)) { const baseAtom = atom([...docCollection.meta.docMetas]); weakMap.set(docCollection, baseAtom); baseAtom.onMount = set => { set([...docCollection.meta.docMetas]); - const dispose = docCollection.meta.docMetaUpdated.on(() => { + const dispose = docCollection.slots.docListUpdated.on(() => { set([...docCollection.meta.docMetas]); }); return () => { diff --git a/packages/frontend/core/src/components/hooks/use-block-suite-page-meta.ts b/packages/frontend/core/src/components/hooks/use-block-suite-page-meta.ts index 89dde2bdd7..597801161f 100644 --- a/packages/frontend/core/src/components/hooks/use-block-suite-page-meta.ts +++ b/packages/frontend/core/src/components/hooks/use-block-suite-page-meta.ts @@ -1,6 +1,6 @@ import { DocsService } from '@affine/core/modules/doc'; import { WorkspaceService } from '@affine/core/modules/workspace'; -import type { DocCollection, DocMeta } from '@blocksuite/affine/store'; +import type { DocMeta, Workspace } from '@blocksuite/affine/store'; import { useService } from '@toeverything/infra'; import { useCallback, useMemo } from 'react'; @@ -13,7 +13,7 @@ import { useJournalInfoHelper } from './use-journal'; * If you want to get all pageMetas, use `useAllBlockSuitePageMeta` instead * @returns */ -export function useBlockSuiteDocMeta(docCollection: DocCollection) { +export function useBlockSuiteDocMeta(docCollection: Workspace) { const pageMetas = useAllBlockSuiteDocMeta(docCollection); const { isPageJournal } = useJournalInfoHelper(); return useMemo( diff --git a/packages/frontend/core/src/components/hooks/use-block-suite-workspace-helper.ts b/packages/frontend/core/src/components/hooks/use-block-suite-workspace-helper.ts index 72d7521ac2..97bda794d4 100644 --- a/packages/frontend/core/src/components/hooks/use-block-suite-workspace-helper.ts +++ b/packages/frontend/core/src/components/hooks/use-block-suite-workspace-helper.ts @@ -1,7 +1,7 @@ -import type { Doc, DocCollection } from '@blocksuite/affine/store'; +import type { Doc, Workspace } from '@blocksuite/affine/store'; import { useMemo } from 'react'; -export function useDocCollectionHelper(docCollection: DocCollection) { +export function useDocCollectionHelper(docCollection: Workspace) { return useMemo( () => ({ createDoc: (pageId?: string): Doc => { diff --git a/packages/frontend/core/src/components/hooks/use-block-suite-workspace-page.ts b/packages/frontend/core/src/components/hooks/use-block-suite-workspace-page.ts index b833e2d672..7b7b329290 100644 --- a/packages/frontend/core/src/components/hooks/use-block-suite-workspace-page.ts +++ b/packages/frontend/core/src/components/hooks/use-block-suite-workspace-page.ts @@ -1,12 +1,12 @@ import { DebugLogger } from '@affine/debug'; import { DisposableGroup } from '@blocksuite/affine/global/utils'; -import type { Doc, DocCollection } from '@blocksuite/affine/store'; +import type { Doc, Workspace } from '@blocksuite/affine/store'; import { useEffect, useState } from 'react'; const logger = new DebugLogger('use-doc-collection-page'); export function useDocCollectionPage( - docCollection: DocCollection, + docCollection: Workspace, pageId: string | null ): Doc | null { const [page, setPage] = useState( diff --git a/packages/frontend/core/src/components/page-list/page-group.tsx b/packages/frontend/core/src/components/page-list/page-group.tsx index 50cfa84760..1987714618 100644 --- a/packages/frontend/core/src/components/page-list/page-group.tsx +++ b/packages/frontend/core/src/components/page-list/page-group.tsx @@ -2,7 +2,7 @@ import { DocDisplayMetaService } from '@affine/core/modules/doc-display-meta'; import type { Tag } from '@affine/env/filter'; import { useI18n } from '@affine/i18n'; import { assertExists } from '@blocksuite/affine/global/utils'; -import type { DocCollection, DocMeta } from '@blocksuite/affine/store'; +import type { DocMeta, Workspace } from '@blocksuite/affine/store'; import { ToggleCollapseIcon, ViewLayersIcon } from '@blocksuite/icons/rc'; import * as Collapsible from '@radix-ui/react-collapsible'; import { useLiveData, useService } from '@toeverything/infra'; @@ -274,7 +274,7 @@ export const TagListItemRenderer = memo(function TagListItemRenderer( function tagIdToTagOption( tagId: string, - docCollection: DocCollection + docCollection: Workspace ): Tag | undefined { return docCollection.meta.properties.tags?.options.find( opt => opt.id === tagId diff --git a/packages/frontend/core/src/components/page-list/types.ts b/packages/frontend/core/src/components/page-list/types.ts index e48df85de6..320edd8add 100644 --- a/packages/frontend/core/src/components/page-list/types.ts +++ b/packages/frontend/core/src/components/page-list/types.ts @@ -1,5 +1,5 @@ import type { Collection, Tag } from '@affine/env/filter'; -import type { DocCollection, DocMeta } from '@blocksuite/affine/store'; +import type { DocMeta, Workspace } from '@blocksuite/affine/store'; import type { JSX, PropsWithChildren, ReactNode } from 'react'; import type { To } from 'react-router-dom'; @@ -91,7 +91,7 @@ export type PageGroupByType = export interface ListProps { // required data: items: T[]; - docCollection: DocCollection; + docCollection: Workspace; className?: string; hideHeader?: boolean; // whether or not to hide the header. default is false (showing header) groupBy?: ItemGroupDefinition[]; diff --git a/packages/frontend/core/src/components/page-list/use-block-suite-workspace-page.ts b/packages/frontend/core/src/components/page-list/use-block-suite-workspace-page.ts index 9438744a53..5f615d1378 100644 --- a/packages/frontend/core/src/components/page-list/use-block-suite-workspace-page.ts +++ b/packages/frontend/core/src/components/page-list/use-block-suite-workspace-page.ts @@ -1,12 +1,12 @@ import { DebugLogger } from '@affine/debug'; import { DisposableGroup } from '@blocksuite/affine/global/utils'; -import type { Doc, DocCollection } from '@blocksuite/affine/store'; +import type { Doc, Workspace } from '@blocksuite/affine/store'; import { useEffect, useState } from 'react'; const logger = new DebugLogger('useBlockSuiteWorkspacePage'); export function useDocCollectionPage( - docCollection: DocCollection, + docCollection: Workspace, pageId: string | null ): Doc | null { const [page, setPage] = useState( diff --git a/packages/frontend/core/src/desktop/dialogs/import/index.tsx b/packages/frontend/core/src/desktop/dialogs/import/index.tsx index 2c3532a9bf..3e2efb11fd 100644 --- a/packages/frontend/core/src/desktop/dialogs/import/index.tsx +++ b/packages/frontend/core/src/desktop/dialogs/import/index.tsx @@ -16,7 +16,7 @@ import { openFileOrFiles, ZipTransformer, } from '@blocksuite/affine/blocks'; -import type { DocCollection } from '@blocksuite/affine/store'; +import type { Workspace } from '@blocksuite/affine/store'; import { ExportToHtmlIcon, ExportToMarkdownIcon, @@ -51,7 +51,7 @@ type ImportResult = { type ImportConfig = { fileOptions: { acceptType: AcceptType; multiple: boolean }; importFunction: ( - docCollection: DocCollection, + docCollection: Workspace, file: File | File[] ) => Promise; }; diff --git a/packages/frontend/core/src/modules/tag/stores/tag.ts b/packages/frontend/core/src/modules/tag/stores/tag.ts index c122a9fcb6..7a0f3d11c6 100644 --- a/packages/frontend/core/src/modules/tag/stores/tag.ts +++ b/packages/frontend/core/src/modules/tag/stores/tag.ts @@ -23,7 +23,7 @@ export class TagStore extends Store { subscribe(cb: () => void) { const disposable = - this.workspaceService.workspace.docCollection.meta.docMetaUpdated.on(cb); + this.workspaceService.workspace.docCollection.slots.docListUpdated.on(cb); return disposable.dispose; } diff --git a/packages/frontend/core/src/modules/workspace/entities/workspace.ts b/packages/frontend/core/src/modules/workspace/entities/workspace.ts index 12d83e689b..edbc6684c9 100644 --- a/packages/frontend/core/src/modules/workspace/entities/workspace.ts +++ b/packages/frontend/core/src/modules/workspace/entities/workspace.ts @@ -1,4 +1,7 @@ -import { DocCollection } from '@blocksuite/affine/store'; +import { + DocCollection, + type Workspace as BSWorkspace, +} from '@blocksuite/affine/store'; import { Entity, LiveData } from '@toeverything/infra'; import { nanoid } from 'nanoid'; import { Observable } from 'rxjs'; @@ -22,7 +25,7 @@ export class Workspace extends Entity { readonly flavour = this.meta.flavour; - _docCollection: DocCollection | null = null; + _docCollection: BSWorkspace | null = null; get docCollection() { if (!this._docCollection) { diff --git a/packages/frontend/core/src/modules/workspace/providers/flavour.ts b/packages/frontend/core/src/modules/workspace/providers/flavour.ts index c194aaee4a..d7f704a986 100644 --- a/packages/frontend/core/src/modules/workspace/providers/flavour.ts +++ b/packages/frontend/core/src/modules/workspace/providers/flavour.ts @@ -1,4 +1,4 @@ -import type { DocCollection } from '@blocksuite/affine/store'; +import type { Workspace as BSWorkspace } from '@blocksuite/affine/store'; import { type AwarenessConnection, type BlobStorage, @@ -27,7 +27,7 @@ export interface WorkspaceFlavourProvider { createWorkspace( initial: ( - docCollection: DocCollection, + docCollection: BSWorkspace, blobStorage: BlobStorage, docStorage: DocStorage ) => Promise diff --git a/packages/frontend/core/src/modules/workspace/scopes/workspace.ts b/packages/frontend/core/src/modules/workspace/scopes/workspace.ts index 8a8ac82d71..a174e9a277 100644 --- a/packages/frontend/core/src/modules/workspace/scopes/workspace.ts +++ b/packages/frontend/core/src/modules/workspace/scopes/workspace.ts @@ -3,8 +3,6 @@ import { Scope } from '@toeverything/infra'; import type { WorkspaceOpenOptions } from '../open-options'; import type { WorkspaceEngineProvider } from '../providers/flavour'; -export type { DocCollection } from '@blocksuite/affine/store'; - export class WorkspaceScope extends Scope<{ openOptions: WorkspaceOpenOptions; engineProvider: WorkspaceEngineProvider; diff --git a/packages/frontend/core/src/modules/workspace/services/factory.ts b/packages/frontend/core/src/modules/workspace/services/factory.ts index bd64236060..a4f952cbd1 100644 --- a/packages/frontend/core/src/modules/workspace/services/factory.ts +++ b/packages/frontend/core/src/modules/workspace/services/factory.ts @@ -1,4 +1,4 @@ -import type { DocCollection } from '@blocksuite/affine/store'; +import type { Workspace } from '@blocksuite/affine/store'; import { type BlobStorage, type DocStorage, @@ -21,7 +21,7 @@ export class WorkspaceFactoryService extends Service { create = async ( flavour: string, initial: ( - docCollection: DocCollection, + docCollection: Workspace, blobStorage: BlobStorage, docStorage: DocStorage ) => Promise = () => Promise.resolve() diff --git a/packages/frontend/core/src/utils/user-setting.ts b/packages/frontend/core/src/utils/user-setting.ts index 40996fe5aa..bb1b642267 100644 --- a/packages/frontend/core/src/utils/user-setting.ts +++ b/packages/frontend/core/src/utils/user-setting.ts @@ -1,11 +1,11 @@ import type { Collection } from '@affine/env/filter'; -import type { DocCollection } from '@blocksuite/affine/store'; +import type { Workspace } from '@blocksuite/affine/store'; import { nanoid } from 'nanoid'; import type { Map as YMap } from 'yjs'; import { Doc as YDoc } from 'yjs'; export class UserSetting { constructor( - private readonly docCollection: DocCollection, + private readonly docCollection: Workspace, private readonly userId: string ) {} @@ -38,9 +38,6 @@ export class UserSetting { } } -export const getUserSetting = ( - docCollection: DocCollection, - userId: string -) => { +export const getUserSetting = (docCollection: Workspace, userId: string) => { return new UserSetting(docCollection, userId); }; diff --git a/tsconfig.json b/tsconfig.json index 651d1c76f6..1649792eb5 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -44,6 +44,8 @@ // Projects "composite": true, "incremental": true, + // For dev performance + "disableReferencedProjectLoad": true, // Completeness "skipLibCheck": true, // skip all type checks for .d.ts files "paths": {