feat(editor): merge store and blocks (#9591)
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { SignalWatcher, WithDisposable } from '@blocksuite/global/utils';
|
||||
import { type Blocks, type ExtensionType, Store } from '@blocksuite/store';
|
||||
import type { ExtensionType, Store } from '@blocksuite/store';
|
||||
import { html } from 'lit';
|
||||
import { customElement, property } from 'lit/decorators.js';
|
||||
|
||||
@@ -18,9 +18,8 @@ export class TestEditorContainer extends SignalWatcher(
|
||||
|
||||
override connectedCallback() {
|
||||
super.connectedCallback();
|
||||
const store = new Store({ blocks: this.doc });
|
||||
this._std = new BlockStdScope({
|
||||
store,
|
||||
store: this.doc,
|
||||
extensions: this.specs,
|
||||
});
|
||||
}
|
||||
@@ -32,7 +31,7 @@ export class TestEditorContainer extends SignalWatcher(
|
||||
}
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor doc!: Blocks;
|
||||
accessor doc!: Store;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor specs: ExtensionType[] = [];
|
||||
|
||||
@@ -2,11 +2,11 @@ import type { ServiceProvider } from '@blocksuite/global/di';
|
||||
import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions';
|
||||
import type {
|
||||
BaseAdapter,
|
||||
Blocks,
|
||||
BlockSnapshot,
|
||||
Job,
|
||||
JobMiddleware,
|
||||
Slice,
|
||||
Store,
|
||||
} from '@blocksuite/store';
|
||||
import DOMPurify from 'dompurify';
|
||||
import type { RootContentMap } from 'hast';
|
||||
@@ -110,7 +110,7 @@ export class Clipboard extends LifeCycleWatcher {
|
||||
|
||||
private readonly _getSnapshotByPriority = async (
|
||||
getItem: (type: string) => string | File[],
|
||||
doc: Blocks,
|
||||
doc: Store,
|
||||
parent?: string,
|
||||
index?: number
|
||||
) => {
|
||||
@@ -182,7 +182,7 @@ export class Clipboard extends LifeCycleWatcher {
|
||||
|
||||
duplicateSlice = async (
|
||||
slice: Slice,
|
||||
doc: Blocks,
|
||||
doc: Store,
|
||||
parent?: string,
|
||||
index?: number,
|
||||
type = 'BLOCKSUITE/SNAPSHOT'
|
||||
@@ -201,7 +201,7 @@ export class Clipboard extends LifeCycleWatcher {
|
||||
|
||||
paste = async (
|
||||
event: ClipboardEvent,
|
||||
doc: Blocks,
|
||||
doc: Store,
|
||||
parent?: string,
|
||||
index?: number
|
||||
) => {
|
||||
@@ -238,7 +238,7 @@ export class Clipboard extends LifeCycleWatcher {
|
||||
|
||||
pasteBlockSnapshot = async (
|
||||
snapshot: BlockSnapshot,
|
||||
doc: Blocks,
|
||||
doc: Store,
|
||||
parent?: string,
|
||||
index?: number
|
||||
) => {
|
||||
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
getBoundWithRotation,
|
||||
intersects,
|
||||
} from '@blocksuite/global/utils';
|
||||
import type { BlockModel, Blocks } from '@blocksuite/store';
|
||||
import type { BlockModel, Store } from '@blocksuite/store';
|
||||
|
||||
import { compare } from '../utils/layer.js';
|
||||
import { GfxBlockElementModel } from './model/gfx-block-model.js';
|
||||
@@ -361,7 +361,7 @@ export class GridManager {
|
||||
this.add(element);
|
||||
}
|
||||
|
||||
watch(blocks: { doc?: Blocks; surface?: SurfaceBlockModel | null }) {
|
||||
watch(blocks: { doc?: Store; surface?: SurfaceBlockModel | null }) {
|
||||
const disposables: { dispose: () => void }[] = [];
|
||||
const { doc, surface } = blocks;
|
||||
const isRenderableBlock = (
|
||||
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
last,
|
||||
Slot,
|
||||
} from '@blocksuite/global/utils';
|
||||
import type { Blocks } from '@blocksuite/store';
|
||||
import type { Store } from '@blocksuite/store';
|
||||
import { generateKeyBetween } from 'fractional-indexing';
|
||||
|
||||
import {
|
||||
@@ -100,7 +100,7 @@ export class LayerManager {
|
||||
};
|
||||
|
||||
constructor(
|
||||
private readonly _doc: Blocks,
|
||||
private readonly _doc: Store,
|
||||
private _surface: SurfaceBlockModel | null,
|
||||
options: {
|
||||
watch: boolean;
|
||||
@@ -476,7 +476,7 @@ export class LayerManager {
|
||||
private _reset() {
|
||||
const elements = (
|
||||
this._doc
|
||||
.getBlocks()
|
||||
.getStore()
|
||||
.filter(
|
||||
model =>
|
||||
model instanceof GfxBlockElementModel &&
|
||||
@@ -775,7 +775,7 @@ export class LayerManager {
|
||||
}
|
||||
}
|
||||
|
||||
watch(blocks: { doc?: Blocks; surface: SurfaceBlockModel | null }) {
|
||||
watch(blocks: { doc?: Store; surface: SurfaceBlockModel | null }) {
|
||||
const { doc, surface } = blocks;
|
||||
|
||||
if (doc) {
|
||||
|
||||
@@ -75,7 +75,7 @@ export class BlockStdScope {
|
||||
}
|
||||
|
||||
get doc() {
|
||||
return this.store.blocks;
|
||||
return this.store;
|
||||
}
|
||||
|
||||
get clipboard() {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import type { Blocks } from '@blocksuite/store';
|
||||
import type { Store } from '@blocksuite/store';
|
||||
import { effect } from '@preact/signals-core';
|
||||
|
||||
import { SurfaceBlockModel } from '../gfx/model/surface/surface-model.js';
|
||||
|
||||
export function onSurfaceAdded(
|
||||
doc: Blocks,
|
||||
doc: Store,
|
||||
callback: (model: SurfaceBlockModel | null) => void
|
||||
) {
|
||||
let found = false;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { nToLast } from '@blocksuite/global/utils';
|
||||
import type { Blocks } from '@blocksuite/store';
|
||||
import type { Store } from '@blocksuite/store';
|
||||
|
||||
import type { GfxLocalElementModel } from '../gfx/index.js';
|
||||
import type { Layer } from '../gfx/layer.js';
|
||||
@@ -82,7 +82,7 @@ export function isInRange(edges: [GfxModel, GfxModel], target: GfxModel) {
|
||||
}
|
||||
|
||||
export function renderableInEdgeless(
|
||||
doc: Blocks,
|
||||
doc: Store,
|
||||
surface: SurfaceBlockModel,
|
||||
block: GfxBlockElementModel
|
||||
) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Blocks } from '@blocksuite/store';
|
||||
import type { Store } from '@blocksuite/store';
|
||||
|
||||
import {
|
||||
type GfxCompatibleInterface,
|
||||
@@ -124,16 +124,13 @@ export function isLockedImpl(element: GfxCompatibleInterface): boolean {
|
||||
return isLockedBySelfImpl(element) || isLockedByAncestorImpl(element);
|
||||
}
|
||||
|
||||
export function lockElementImpl(doc: Blocks, element: GfxCompatibleInterface) {
|
||||
export function lockElementImpl(doc: Store, element: GfxCompatibleInterface) {
|
||||
doc.transact(() => {
|
||||
element.lockedBySelf = true;
|
||||
});
|
||||
}
|
||||
|
||||
export function unlockElementImpl(
|
||||
doc: Blocks,
|
||||
element: GfxCompatibleInterface
|
||||
) {
|
||||
export function unlockElementImpl(doc: Store, element: GfxCompatibleInterface) {
|
||||
doc.transact(() => {
|
||||
element.lockedBySelf = false;
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions';
|
||||
import { SignalWatcher, WithDisposable } from '@blocksuite/global/utils';
|
||||
import { type BlockModel, Blocks, type BlockViewType } from '@blocksuite/store';
|
||||
import { type BlockModel, type BlockViewType, Store } from '@blocksuite/store';
|
||||
import { consume, provide } from '@lit/context';
|
||||
import { computed } from '@preact/signals-core';
|
||||
import { nothing, type TemplateResult } from 'lit';
|
||||
@@ -23,7 +23,7 @@ import { ShadowlessElement } from './shadowless-element.js';
|
||||
import type { WidgetComponent } from './widget-component.js';
|
||||
|
||||
@requiredProperties({
|
||||
doc: PropTypes.instanceOf(Blocks),
|
||||
doc: PropTypes.instanceOf(Store),
|
||||
std: PropTypes.object,
|
||||
widgets: PropTypes.recordOf(PropTypes.object),
|
||||
})
|
||||
@@ -307,7 +307,7 @@ export class BlockComponent<
|
||||
private accessor _service: Service | null = null;
|
||||
|
||||
@consume({ context: docContext })
|
||||
accessor doc!: Blocks;
|
||||
accessor doc!: Store;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor viewType: BlockViewType = 'display';
|
||||
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
handleError,
|
||||
} from '@blocksuite/global/exceptions';
|
||||
import { SignalWatcher, Slot, WithDisposable } from '@blocksuite/global/utils';
|
||||
import { type BlockModel, Blocks } from '@blocksuite/store';
|
||||
import { type BlockModel, Store } from '@blocksuite/store';
|
||||
import { createContext, provide } from '@lit/context';
|
||||
import { css, LitElement, nothing, type TemplateResult } from 'lit';
|
||||
import { property } from 'lit/decorators.js';
|
||||
@@ -22,11 +22,11 @@ import type { ViewStore } from '../view-store.js';
|
||||
import { BLOCK_ID_ATTR, WIDGET_ID_ATTR } from './consts.js';
|
||||
import { ShadowlessElement } from './shadowless-element.js';
|
||||
|
||||
export const docContext = createContext<Blocks>('doc');
|
||||
export const docContext = createContext<Store>('doc');
|
||||
export const stdContext = createContext<BlockStdScope>('std');
|
||||
|
||||
@requiredProperties({
|
||||
doc: PropTypes.instanceOf(Blocks),
|
||||
doc: PropTypes.instanceOf(Store),
|
||||
std: PropTypes.object,
|
||||
})
|
||||
export class EditorHost extends SignalWatcher(
|
||||
@@ -189,7 +189,7 @@ export class EditorHost extends SignalWatcher(
|
||||
|
||||
@provide({ context: docContext })
|
||||
@property({ attribute: false })
|
||||
accessor doc!: Blocks;
|
||||
accessor doc!: Store;
|
||||
|
||||
@provide({ context: stdContext })
|
||||
@property({ attribute: false })
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { SignalWatcher, WithDisposable } from '@blocksuite/global/utils';
|
||||
import type { BlockModel, Blocks } from '@blocksuite/store';
|
||||
import type { BlockModel, Store } from '@blocksuite/store';
|
||||
import { consume } from '@lit/context';
|
||||
import { LitElement } from 'lit';
|
||||
|
||||
@@ -94,7 +94,7 @@ export class WidgetComponent<
|
||||
}
|
||||
|
||||
@consume({ context: docContext })
|
||||
private accessor _doc!: Blocks;
|
||||
private accessor _doc!: Store;
|
||||
|
||||
@consume({ context: modelContext })
|
||||
private accessor _model!: Model;
|
||||
|
||||
@@ -4,7 +4,7 @@ import type { Slot } from '@blocksuite/global/utils';
|
||||
import { assert, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import { applyUpdate, type Doc, encodeStateAsUpdate } from 'yjs';
|
||||
|
||||
import type { BlockModel, Blocks, BlockSchemaType, DocMeta } from '../index.js';
|
||||
import type { BlockModel, BlockSchemaType, DocMeta, Store } from '../index.js';
|
||||
import { Schema } from '../index.js';
|
||||
import { Text } from '../reactive/text.js';
|
||||
import { createAutoIncrementIdGenerator } from '../test/index.js';
|
||||
@@ -52,7 +52,7 @@ function waitOnce<T>(slot: Slot<T>) {
|
||||
return new Promise<T>(resolve => slot.once(val => resolve(val)));
|
||||
}
|
||||
|
||||
function createRoot(doc: Blocks) {
|
||||
function createRoot(doc: Store) {
|
||||
doc.addBlock('affine:page');
|
||||
if (!doc.root) throw new Error('root not found');
|
||||
return doc.root;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { BlockSuiteError } from '@blocksuite/global/exceptions';
|
||||
|
||||
import type { Blocks, DraftModel } from '../model/index.js';
|
||||
import type { DraftModel, Store } from '../model/index.js';
|
||||
import type { AssetsManager } from '../transformer/assets.js';
|
||||
import type { Job, Slice } from '../transformer/index.js';
|
||||
import type {
|
||||
@@ -93,7 +93,7 @@ export abstract class BaseAdapter<AdapterTarget = unknown> {
|
||||
| Promise<FromBlockSnapshotResult<AdapterTarget>>
|
||||
| FromBlockSnapshotResult<AdapterTarget>;
|
||||
|
||||
async fromDoc(doc: Blocks) {
|
||||
async fromDoc(doc: Store) {
|
||||
try {
|
||||
const docSnapshot = this.job.docToSnapshot(doc);
|
||||
if (!docSnapshot) return;
|
||||
@@ -138,7 +138,7 @@ export abstract class BaseAdapter<AdapterTarget = unknown> {
|
||||
|
||||
async toBlock(
|
||||
payload: ToBlockSnapshotPayload<AdapterTarget>,
|
||||
doc: Blocks,
|
||||
doc: Store,
|
||||
parent?: string,
|
||||
index?: number
|
||||
) {
|
||||
@@ -175,7 +175,7 @@ export abstract class BaseAdapter<AdapterTarget = unknown> {
|
||||
|
||||
async toSlice(
|
||||
payload: ToSliceSnapshotPayload<AdapterTarget>,
|
||||
doc: Blocks,
|
||||
doc: Store,
|
||||
parent?: string,
|
||||
index?: number
|
||||
) {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { type Container, createIdentifier } from '@blocksuite/global/di';
|
||||
import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions';
|
||||
|
||||
import { StoreIdentifier } from '../store/identifier';
|
||||
import type { Store } from '../store/store';
|
||||
import type { Store } from '../model/store';
|
||||
import { StoreIdentifier } from '../model/store/identifier';
|
||||
import { Extension } from './extension';
|
||||
|
||||
export const StoreExtensionIdentifier =
|
||||
|
||||
@@ -6,7 +6,6 @@ export * from './extension';
|
||||
export * from './model';
|
||||
export * from './reactive';
|
||||
export * from './schema';
|
||||
export * from './store';
|
||||
export * from './transformer';
|
||||
export { type IdGenerator, nanoid, uuidv4 } from './utils/id-generator';
|
||||
export * from './yjs';
|
||||
|
||||
@@ -2,7 +2,7 @@ import { type Disposable, Slot } from '@blocksuite/global/utils';
|
||||
import { computed, type Signal, signal } from '@preact/signals-core';
|
||||
|
||||
import type { Text } from '../../reactive/index.js';
|
||||
import type { Blocks } from '../blocks/blocks.js';
|
||||
import type { Store } from '../store/store.js';
|
||||
import type { YBlock } from './types.js';
|
||||
import type { RoleType } from './zod.js';
|
||||
|
||||
@@ -38,7 +38,7 @@ export class BlockModel<
|
||||
/**
|
||||
* @deprecated use doc instead
|
||||
*/
|
||||
page!: Blocks;
|
||||
page!: Store;
|
||||
|
||||
private readonly _childModels = computed(() => {
|
||||
const value: BlockModel[] = [];
|
||||
@@ -102,7 +102,7 @@ export class BlockModel<
|
||||
return this.page;
|
||||
}
|
||||
|
||||
set doc(doc: Blocks) {
|
||||
set doc(doc: Store) {
|
||||
this.page = doc;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { Schema } from '../../schema/index.js';
|
||||
import type { Blocks } from '../blocks/blocks.js';
|
||||
import type { Store } from '../store/store.js';
|
||||
import { SyncController } from './sync-controller.js';
|
||||
import type { BlockOptions, YBlock } from './types.js';
|
||||
|
||||
@@ -37,7 +37,7 @@ export class Block {
|
||||
constructor(
|
||||
readonly schema: Schema,
|
||||
readonly yBlock: YBlock,
|
||||
readonly doc?: Blocks,
|
||||
readonly doc?: Store,
|
||||
readonly options: BlockOptions = {}
|
||||
) {
|
||||
const onChange = !options.onChange
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
y2Native,
|
||||
} from '../../reactive/index.js';
|
||||
import type { Schema } from '../../schema/schema.js';
|
||||
import type { Blocks } from '../blocks/blocks.js';
|
||||
import type { Store } from '../store/store.js';
|
||||
import { BlockModel } from './block-model.js';
|
||||
import type { YBlock } from './types.js';
|
||||
import { internalPrimitives } from './zod.js';
|
||||
@@ -104,7 +104,7 @@ export class SyncController {
|
||||
constructor(
|
||||
readonly schema: Schema,
|
||||
readonly yBlock: YBlock,
|
||||
readonly doc?: Blocks,
|
||||
readonly doc?: Store,
|
||||
readonly onChange?: (key: string, value: unknown) => void
|
||||
) {
|
||||
const { id, flavour, version, yChildren, props } = this._parseYBlock();
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
export * from './blocks.js';
|
||||
export * from './query.js';
|
||||
@@ -4,15 +4,12 @@ import type * as Y from 'yjs';
|
||||
import type { Schema } from '../schema/schema.js';
|
||||
import type { AwarenessStore } from '../yjs/awareness.js';
|
||||
import type { YBlock } from './block/types.js';
|
||||
import type { Blocks } from './blocks/blocks.js';
|
||||
import type { Query } from './blocks/query.js';
|
||||
import type { Query } from './store/query.js';
|
||||
import type { Store, StoreOptions } from './store/store.js';
|
||||
import type { Workspace } from './workspace.js';
|
||||
import type { DocMeta } from './workspace-meta.js';
|
||||
|
||||
export type GetBlocksOptions = {
|
||||
query?: Query;
|
||||
readonly?: boolean;
|
||||
};
|
||||
export type GetBlocksOptions = Omit<StoreOptions, 'schema' | 'doc'>;
|
||||
export type CreateBlocksOptions = GetBlocksOptions & {
|
||||
id?: string;
|
||||
};
|
||||
@@ -53,7 +50,7 @@ export interface Doc {
|
||||
|
||||
captureSync(): void;
|
||||
clear(): void;
|
||||
getBlocks(options?: GetBlocksOptions): Blocks;
|
||||
getStore(options?: GetBlocksOptions): Store;
|
||||
clearQuery(query: Query, readonly?: boolean): void;
|
||||
|
||||
get loaded(): boolean;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import type { BlockModel } from './block/block-model.js';
|
||||
|
||||
export * from './block/index.js';
|
||||
export * from './blocks/index.js';
|
||||
export * from './doc.js';
|
||||
export * from './store/index.js';
|
||||
export * from './workspace.js';
|
||||
export * from './workspace-meta.js';
|
||||
|
||||
|
||||
3
blocksuite/framework/store/src/model/store/index.ts
Normal file
3
blocksuite/framework/store/src/model/store/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export * from './identifier.js';
|
||||
export * from './query.js';
|
||||
export * from './store.js';
|
||||
@@ -1,7 +1,9 @@
|
||||
import { Container, type ServiceProvider } from '@blocksuite/global/di';
|
||||
import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions';
|
||||
import { type Disposable, Slot } from '@blocksuite/global/utils';
|
||||
import { signal } from '@preact/signals-core';
|
||||
|
||||
import type { ExtensionType } from '../../extension/extension.js';
|
||||
import type { Schema } from '../../schema/index.js';
|
||||
import {
|
||||
Block,
|
||||
@@ -12,17 +14,22 @@ import {
|
||||
} 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';
|
||||
import { syncBlockProps } from './utils.js';
|
||||
|
||||
type DocOptions = {
|
||||
export type StoreOptions = {
|
||||
schema: Schema;
|
||||
blockCollection: Doc;
|
||||
doc: Doc;
|
||||
readonly?: boolean;
|
||||
query?: Query;
|
||||
provider?: ServiceProvider;
|
||||
extensions?: ExtensionType[];
|
||||
};
|
||||
|
||||
export class Blocks {
|
||||
export class Store {
|
||||
private readonly _provider: ServiceProvider;
|
||||
|
||||
private readonly _runQuery = (block: Block) => {
|
||||
runQuery(this._query, block);
|
||||
};
|
||||
@@ -147,6 +154,10 @@ export class Blocks {
|
||||
return this._doc.awarenessStore;
|
||||
}
|
||||
|
||||
get provider() {
|
||||
return this._provider;
|
||||
}
|
||||
|
||||
get blobSync() {
|
||||
return this.workspace.blobSync;
|
||||
}
|
||||
@@ -259,8 +270,24 @@ export class Blocks {
|
||||
return this._doc.withoutTransact.bind(this._doc);
|
||||
}
|
||||
|
||||
constructor({ schema, blockCollection, readonly, query }: DocOptions) {
|
||||
this._doc = blockCollection;
|
||||
constructor({
|
||||
schema,
|
||||
doc,
|
||||
readonly,
|
||||
query,
|
||||
provider,
|
||||
extensions,
|
||||
}: StoreOptions) {
|
||||
const container = new Container();
|
||||
container.addImpl(StoreIdentifier, () => this);
|
||||
|
||||
const userExtensions = extensions ?? [];
|
||||
userExtensions.forEach(extension => {
|
||||
extension.setup(container);
|
||||
});
|
||||
|
||||
this._provider = container.provider(undefined, provider);
|
||||
this._doc = doc;
|
||||
|
||||
this.slots = {
|
||||
ready: new Slot(),
|
||||
@@ -271,7 +298,7 @@ export class Blocks {
|
||||
yBlockUpdated: this._doc.slots.yBlockUpdated,
|
||||
};
|
||||
|
||||
this._crud = new DocCRUD(this._yBlocks, blockCollection.schema);
|
||||
this._crud = new DocCRUD(this._yBlocks, doc.schema);
|
||||
this._schema = schema;
|
||||
this._readonly = readonly;
|
||||
if (query) {
|
||||
@@ -565,7 +592,7 @@ export class Blocks {
|
||||
return (this.getBlock(id)?.model ?? null) as Model | null;
|
||||
}
|
||||
|
||||
getBlocks() {
|
||||
getStore() {
|
||||
return Object.values(this._blocks.peek()).map(block => block.model);
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@ import type * as Y from 'yjs';
|
||||
import type { Schema } from '../schema/schema.js';
|
||||
import type { IdGenerator } from '../utils/id-generator.js';
|
||||
import type { AwarenessStore } from '../yjs/awareness.js';
|
||||
import type { Blocks } from './blocks/blocks.js';
|
||||
import type { CreateBlocksOptions, Doc, GetBlocksOptions } from './doc.js';
|
||||
import type { Store } from './store/store.js';
|
||||
import type { WorkspaceMeta } from './workspace-meta.js';
|
||||
|
||||
export interface Workspace {
|
||||
@@ -26,8 +26,8 @@ export interface Workspace {
|
||||
docRemoved: Slot<string>;
|
||||
};
|
||||
|
||||
createDoc(options?: CreateBlocksOptions): Blocks;
|
||||
getDoc(docId: string, options?: GetBlocksOptions): Blocks | null;
|
||||
createDoc(options?: CreateBlocksOptions): Store;
|
||||
getDoc(docId: string, options?: GetBlocksOptions): Store | null;
|
||||
removeDoc(docId: string): void;
|
||||
|
||||
dispose(): void;
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
export * from './identifier';
|
||||
export * from './store';
|
||||
@@ -1,41 +0,0 @@
|
||||
import { Container, type ServiceProvider } from '@blocksuite/global/di';
|
||||
|
||||
import type { Extension, StoreExtension } from '../extension';
|
||||
import type { Blocks } from '../model';
|
||||
import { StoreIdentifier } from './identifier';
|
||||
|
||||
export interface StoreOptions {
|
||||
blocks: Blocks;
|
||||
provider?: ServiceProvider;
|
||||
extensions?: (typeof Extension | typeof StoreExtension)[];
|
||||
}
|
||||
|
||||
export class Store {
|
||||
private readonly _blocks: Blocks;
|
||||
private readonly _provider: ServiceProvider;
|
||||
|
||||
get blocks() {
|
||||
return this._blocks;
|
||||
}
|
||||
|
||||
get provider() {
|
||||
return this._provider;
|
||||
}
|
||||
|
||||
get awareness() {
|
||||
return this._blocks.awarenessStore;
|
||||
}
|
||||
|
||||
constructor(options: StoreOptions) {
|
||||
this._blocks = options.blocks;
|
||||
const container = new Container();
|
||||
container.addImpl(StoreIdentifier, () => this);
|
||||
|
||||
const userExtensions = options.extensions ?? [];
|
||||
userExtensions.forEach(extension => {
|
||||
extension.setup(container);
|
||||
});
|
||||
|
||||
this._provider = container.provider(undefined, options.provider);
|
||||
}
|
||||
}
|
||||
@@ -3,9 +3,9 @@ import { signal } from '@preact/signals-core';
|
||||
import * as Y from 'yjs';
|
||||
|
||||
import type { YBlock } from '../model/block/types.js';
|
||||
import { Blocks } from '../model/blocks/blocks.js';
|
||||
import type { Query } from '../model/blocks/query.js';
|
||||
import type { Doc, GetBlocksOptions, Workspace } from '../model/index.js';
|
||||
import type { Query } from '../model/store/query.js';
|
||||
import { Store } from '../model/store/store.js';
|
||||
import type { AwarenessStore } from '../yjs/index.js';
|
||||
|
||||
type DocOptions = {
|
||||
@@ -25,9 +25,9 @@ export class TestDoc implements Doc {
|
||||
private readonly _collection: Workspace;
|
||||
|
||||
private readonly _docMap = {
|
||||
undefined: new Map<string, Blocks>(),
|
||||
true: new Map<string, Blocks>(),
|
||||
false: new Map<string, Blocks>(),
|
||||
undefined: new Map<string, Store>(),
|
||||
true: new Map<string, Store>(),
|
||||
false: new Map<string, Store>(),
|
||||
};
|
||||
|
||||
// doc/space container.
|
||||
@@ -279,7 +279,7 @@ export class TestDoc implements Doc {
|
||||
}
|
||||
}
|
||||
|
||||
getBlocks({ readonly, query }: GetBlocksOptions = {}) {
|
||||
getStore({ readonly, query, provider, extensions }: GetBlocksOptions = {}) {
|
||||
const readonlyKey = this._getReadonlyKey(readonly);
|
||||
|
||||
const key = JSON.stringify(query);
|
||||
@@ -288,11 +288,13 @@ export class TestDoc implements Doc {
|
||||
return this._docMap[readonlyKey].get(key)!;
|
||||
}
|
||||
|
||||
const doc = new Blocks({
|
||||
blockCollection: this,
|
||||
const doc = new Store({
|
||||
doc: this,
|
||||
schema: this.workspace.schema,
|
||||
readonly,
|
||||
query,
|
||||
provider,
|
||||
extensions,
|
||||
});
|
||||
|
||||
this._docMap[readonlyKey].set(key, doc);
|
||||
|
||||
@@ -17,9 +17,9 @@ import { Awareness } from 'y-protocols/awareness.js';
|
||||
import * as Y from 'yjs';
|
||||
|
||||
import type {
|
||||
Blocks,
|
||||
CreateBlocksOptions,
|
||||
GetBlocksOptions,
|
||||
Store,
|
||||
Workspace,
|
||||
WorkspaceMeta,
|
||||
} from '../model/index.js';
|
||||
@@ -205,7 +205,7 @@ export class TestWorkspace implements Workspace {
|
||||
tags: [],
|
||||
});
|
||||
this.slots.docCreated.emit(docId);
|
||||
return this.getDoc(docId, { query, readonly }) as Blocks;
|
||||
return this.getDoc(docId, { query, readonly }) as Store;
|
||||
}
|
||||
|
||||
dispose() {
|
||||
@@ -227,9 +227,9 @@ export class TestWorkspace implements Workspace {
|
||||
return space ?? null;
|
||||
}
|
||||
|
||||
getDoc(docId: string, options?: GetBlocksOptions): Blocks | null {
|
||||
getDoc(docId: string, options?: GetBlocksOptions): Store | null {
|
||||
const collection = this.getBlockCollection(docId);
|
||||
return collection?.getBlocks(options) ?? null;
|
||||
return collection?.getStore(options) ?? null;
|
||||
}
|
||||
|
||||
removeDoc(docId: string) {
|
||||
|
||||
@@ -3,9 +3,9 @@ import { nextTick, Slot } from '@blocksuite/global/utils';
|
||||
|
||||
import type {
|
||||
BlockModel,
|
||||
Blocks,
|
||||
BlockSchemaType,
|
||||
DraftModel,
|
||||
Store,
|
||||
} from '../model/index.js';
|
||||
import type { Schema } from '../schema/index.js';
|
||||
import { AssetsManager } from './assets.js';
|
||||
@@ -82,7 +82,7 @@ export class Job {
|
||||
}
|
||||
};
|
||||
|
||||
docToSnapshot = (doc: Blocks): DocSnapshot | undefined => {
|
||||
docToSnapshot = (doc: Store): DocSnapshot | undefined => {
|
||||
try {
|
||||
this._slots.beforeExport.emit({
|
||||
type: 'page',
|
||||
@@ -158,7 +158,7 @@ export class Job {
|
||||
|
||||
snapshotToBlock = async (
|
||||
snapshot: BlockSnapshot,
|
||||
doc: Blocks,
|
||||
doc: Store,
|
||||
parent?: string,
|
||||
index?: number
|
||||
): Promise<BlockModel | undefined> => {
|
||||
@@ -174,9 +174,7 @@ export class Job {
|
||||
}
|
||||
};
|
||||
|
||||
snapshotToDoc = async (
|
||||
snapshot: DocSnapshot
|
||||
): Promise<Blocks | undefined> => {
|
||||
snapshotToDoc = async (snapshot: DocSnapshot): Promise<Store | undefined> => {
|
||||
try {
|
||||
this._slots.beforeImport.emit({
|
||||
type: 'page',
|
||||
@@ -228,7 +226,7 @@ export class Job {
|
||||
|
||||
snapshotToSlice = async (
|
||||
snapshot: SliceSnapshot,
|
||||
doc: Blocks,
|
||||
doc: Store,
|
||||
parent?: string,
|
||||
index?: number
|
||||
): Promise<Slice | undefined> => {
|
||||
@@ -424,7 +422,7 @@ export class Job {
|
||||
}
|
||||
}
|
||||
|
||||
private _exportDocMeta(doc: Blocks): DocSnapshot['meta'] {
|
||||
private _exportDocMeta(doc: Store): DocSnapshot['meta'] {
|
||||
const docMeta = doc.meta;
|
||||
|
||||
if (!docMeta) {
|
||||
@@ -472,7 +470,7 @@ export class Job {
|
||||
|
||||
private async _insertBlockTree(
|
||||
nodes: DraftBlockTreeNode[],
|
||||
doc: Blocks,
|
||||
doc: Store,
|
||||
parentId?: string,
|
||||
startIndex?: number,
|
||||
counter: number = 0
|
||||
@@ -561,7 +559,7 @@ export class Job {
|
||||
|
||||
private async _snapshotToBlock(
|
||||
snapshot: BlockSnapshot,
|
||||
doc: Blocks,
|
||||
doc: Store,
|
||||
parent?: string,
|
||||
index?: number
|
||||
): Promise<BlockModel | null> {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { Slot } from '@blocksuite/global/utils';
|
||||
|
||||
import type { Blocks, DraftModel } from '../model/index.js';
|
||||
import type { DraftModel, Store } from '../model/index.js';
|
||||
import type { AssetsManager } from './assets.js';
|
||||
import type { Slice } from './slice.js';
|
||||
import type {
|
||||
@@ -37,7 +37,7 @@ export type BeforeExportPayload =
|
||||
type: 'block';
|
||||
}
|
||||
| {
|
||||
page: Blocks;
|
||||
page: Store;
|
||||
type: 'page';
|
||||
}
|
||||
| {
|
||||
@@ -59,7 +59,7 @@ export type FinalPayload =
|
||||
| {
|
||||
snapshot: DocSnapshot;
|
||||
type: 'page';
|
||||
page: Blocks;
|
||||
page: Store;
|
||||
}
|
||||
| {
|
||||
snapshot: SliceSnapshot;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Blocks, DraftModel } from '../model/index.js';
|
||||
import type { DraftModel, Store } from '../model/index.js';
|
||||
|
||||
type SliceData = {
|
||||
content: DraftModel[];
|
||||
@@ -21,7 +21,7 @@ export class Slice {
|
||||
|
||||
constructor(readonly data: SliceData) {}
|
||||
|
||||
static fromModels(doc: Blocks, models: DraftModel[]) {
|
||||
static fromModels(doc: Store, models: DraftModel[]) {
|
||||
return new Slice({
|
||||
content: models,
|
||||
workspaceId: doc.workspace.id,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
import type { Blocks } from '../model/blocks/blocks.js';
|
||||
import type { Store } from '../model/store/store.js';
|
||||
import type { DocMeta, DocsPropertiesMeta } from '../model/workspace-meta.js';
|
||||
|
||||
export type BlockSnapshot = {
|
||||
@@ -75,7 +75,7 @@ export interface BlobCRUD {
|
||||
}
|
||||
|
||||
export interface DocCRUD {
|
||||
create: (id: string) => Blocks;
|
||||
get: (id: string) => Blocks | null;
|
||||
create: (id: string) => Store;
|
||||
get: (id: string) => Store | null;
|
||||
delete: (id: string) => void;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user