refactor(editor): doc as store extension (#12170)

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **New Features**
  - Introduced new exports related to workspace management, making additional workspace features available.

- **Refactor**
  - Updated how document and workspace types are imported and exported, consolidating and reorganizing module structure.
  - Shifted dependency management for document instances to use an internal provider mechanism.
  - Streamlined and centralized type imports across various modules.

- **Bug Fixes**
  - Removed an unused schema definition to improve code clarity.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Saul-Mirone
2025-05-07 09:17:01 +00:00
parent 610565e617
commit eb62d0e853
12 changed files with 38 additions and 29 deletions

View File

@@ -2,3 +2,4 @@ export * from './extension';
export * from './schema';
export * from './selection';
export * from './store-extension';
export * from './workspace';

View File

@@ -1,8 +1,8 @@
import { createIdentifier } from '@blocksuite/global/di';
import type * as Y from 'yjs';
import type { AwarenessStore } from '../yjs/awareness.js';
import type { YBlock } from './block/types.js';
import type { Store, StoreOptions } from './store/store.js';
import type { Store, StoreOptions, YBlock } from '../../model';
import type { AwarenessStore } from '../../yjs';
import type { Workspace } from './workspace.js';
import type { DocMeta } from './workspace-meta.js';
@@ -34,3 +34,5 @@ export interface Doc {
get spaceDoc(): Y.Doc;
get yBlocks(): Y.Map<YBlock>;
}
export const DocIdentifier = createIdentifier<Doc>('store-doc');

View File

@@ -0,0 +1,3 @@
export * from './doc';
export * from './workspace';
export * from './workspace-meta';

View File

@@ -3,7 +3,7 @@ import type { Subject } from 'rxjs';
import type { Awareness } from 'y-protocols/awareness.js';
import type * as Y from 'yjs';
import type { IdGenerator } from '../utils/id-generator.js';
import type { IdGenerator } from '../../utils/id-generator';
import type { Doc } from './doc.js';
import type { WorkspaceMeta } from './workspace-meta.js';

View File

@@ -1,6 +1,3 @@
export * from './block/index.js';
export * from './doc.js';
export * from './store/index.js';
export * from './store-container.js';
export * from './workspace.js';
export * from './workspace-meta.js';

View File

@@ -1,4 +1,10 @@
import type { Doc, GetStoreOptions, RemoveStoreOptions } from './doc';
import type {
Doc,
ExtensionType,
GetStoreOptions,
RemoveStoreOptions,
} from '../extension';
import { DocIdentifier } from '../extension/workspace';
import { type Query, Store } from './store';
export class StoreContainer {
@@ -27,12 +33,18 @@ export class StoreContainer {
return this._storeMap.get(key) as Store;
}
const storeExtension: ExtensionType = {
setup: di => {
di.addImpl(DocIdentifier, () => this.doc);
},
};
const doc = new Store({
doc: this.doc,
readonly,
query,
provider,
extensions,
extensions: [storeExtension].concat(extensions ?? []),
});
this._storeMap.set(key, doc);

View File

@@ -8,9 +8,11 @@ import * as Y from 'yjs';
import type { ExtensionType } from '../../extension/extension.js';
import {
BlockSchemaIdentifier,
type Doc,
StoreExtensionIdentifier,
StoreSelectionExtension,
} from '../../extension/index.js';
import { DocIdentifier } from '../../extension/workspace/doc.js';
import { Schema } from '../../schema/index.js';
import type { TransformerMiddleware } from '../../transformer/middleware.js';
import { Transformer } from '../../transformer/transformer.js';
@@ -21,7 +23,6 @@ import {
type BlockProps,
type YBlock,
} from '../block/index.js';
import type { Doc } from '../doc.js';
import { DocCRUD } from './crud.js';
import { StoreIdentifier } from './identifier.js';
import { type Query, runQuery } from './query.js';
@@ -561,8 +562,7 @@ export class Store {
* In most cases, you don't need to use the constructor directly.
* The store is created by the {@link Doc} instance.
*/
constructor({ doc, readonly, query, provider, extensions }: StoreOptions) {
this._doc = doc;
constructor({ readonly, query, provider, extensions }: StoreOptions) {
this.slots = {
ready: new Subject(),
rootAdded: new Subject(),
@@ -590,6 +590,7 @@ export class Store {
this._provider.getAll(BlockSchemaIdentifier).forEach(schema => {
this._schema.register([schema]);
});
this._doc = this._provider.get(DocIdentifier);
this._crud = new DocCRUD(this._yBlocks, this._schema);
if (readonly !== undefined) {
this._readonly.value = readonly;

View File

@@ -1,12 +1,8 @@
import * as Y from 'yjs';
import type { Doc, GetStoreOptions, Workspace } from '../extension/index.js';
import type { YBlock } from '../model/block/types.js';
import {
type Doc,
type GetStoreOptions,
StoreContainer,
type Workspace,
} from '../model/index.js';
import { StoreContainer } from '../model/index.js';
import type { AwarenessStore } from '../yjs/index.js';
import type { TestWorkspace } from './test-workspace.js';

View File

@@ -5,7 +5,7 @@ import type {
DocMeta,
DocsPropertiesMeta,
WorkspaceMeta,
} from '../model/index.js';
} from '../extension/index.js';
import { createYProxy } from '../reactive/proxy.js';
type DocCollectionMetaState = {

View File

@@ -14,8 +14,12 @@ import { Subject } from 'rxjs';
import { Awareness } from 'y-protocols/awareness.js';
import * as Y from 'yjs';
import type { ExtensionType } from '../extension/extension.js';
import type { Doc, Workspace, WorkspaceMeta } from '../model/index.js';
import type {
Doc,
ExtensionType,
Workspace,
WorkspaceMeta,
} from '../extension/index.js';
import { type IdGenerator, nanoid } from '../utils/id-generator.js';
import { AwarenessStore } from '../yjs/index.js';
import { TestDoc } from './test-doc.js';

View File

@@ -1,7 +1,7 @@
import { z } from 'zod';
import type { DocMeta, DocsPropertiesMeta } from '../extension';
import type { Store } from '../model';
import type { DocMeta, DocsPropertiesMeta } from '../model/workspace-meta';
export type BlockSnapshot = {
type: 'block';
@@ -41,13 +41,6 @@ export type CollectionInfoSnapshot = {
properties: DocsPropertiesMeta;
};
export const CollectionInfoSnapshotSchema: z.ZodType<CollectionInfoSnapshot> =
z.object({
id: z.string(),
type: z.literal('info'),
properties: z.record(z.any()),
});
export type DocSnapshot = {
type: 'page';
meta: DocMeta;