Closes: [BS-2566](https://linear.app/affine-design/issue/BS-2566/remove-global-types-in-service)
202 lines
4.5 KiB
TypeScript
202 lines
4.5 KiB
TypeScript
import { Container, type ServiceProvider } from '@blocksuite/global/di';
|
|
import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions';
|
|
import {
|
|
type ExtensionType,
|
|
type Store,
|
|
StoreSelectionExtension,
|
|
Transformer,
|
|
type TransformerMiddleware,
|
|
} from '@blocksuite/store';
|
|
|
|
import { Clipboard } from '../clipboard/index.js';
|
|
import { CommandManager } from '../command/index.js';
|
|
import { UIEventDispatcher } from '../event/index.js';
|
|
import { DndController } from '../extension/dnd/index.js';
|
|
import { GfxController } from '../gfx/controller.js';
|
|
import { GfxSelectionManager } from '../gfx/selection.js';
|
|
import { SurfaceMiddlewareExtension } from '../gfx/surface-middleware.js';
|
|
import { ViewManager } from '../gfx/view/view-manager.js';
|
|
import {
|
|
BlockViewIdentifier,
|
|
ConfigIdentifier,
|
|
LifeCycleWatcherIdentifier,
|
|
StdIdentifier,
|
|
} from '../identifier.js';
|
|
import { RangeManager } from '../range/index.js';
|
|
import { ServiceManager } from '../service/index.js';
|
|
import { EditorHost } from '../view/element/index.js';
|
|
import { ViewStore } from '../view/view-store.js';
|
|
|
|
export interface BlockStdOptions {
|
|
store: Store;
|
|
extensions: ExtensionType[];
|
|
}
|
|
|
|
const internalExtensions = [
|
|
ServiceManager,
|
|
CommandManager,
|
|
UIEventDispatcher,
|
|
RangeManager,
|
|
ViewStore,
|
|
Clipboard,
|
|
GfxController,
|
|
GfxSelectionManager,
|
|
SurfaceMiddlewareExtension,
|
|
ViewManager,
|
|
DndController,
|
|
];
|
|
|
|
export class BlockStdScope {
|
|
static internalExtensions = internalExtensions;
|
|
|
|
readonly container: Container;
|
|
|
|
readonly store: Store;
|
|
|
|
readonly provider: ServiceProvider;
|
|
|
|
readonly userExtensions: ExtensionType[];
|
|
|
|
private get _lifeCycleWatchers() {
|
|
return this.provider.getAll(LifeCycleWatcherIdentifier);
|
|
}
|
|
|
|
private _host!: EditorHost;
|
|
|
|
get dnd() {
|
|
return this.get(DndController);
|
|
}
|
|
|
|
get clipboard() {
|
|
return this.get(Clipboard);
|
|
}
|
|
|
|
get workspace() {
|
|
return this.store.workspace;
|
|
}
|
|
|
|
get command() {
|
|
return this.get(CommandManager);
|
|
}
|
|
|
|
get event() {
|
|
return this.get(UIEventDispatcher);
|
|
}
|
|
|
|
get get() {
|
|
return this.provider.get.bind(this.provider);
|
|
}
|
|
|
|
get getOptional() {
|
|
return this.provider.getOptional.bind(this.provider);
|
|
}
|
|
|
|
get host() {
|
|
if (!this._host) {
|
|
throw new BlockSuiteError(
|
|
ErrorCode.ValueNotExists,
|
|
'Host is not ready to use, the `render` method should be called first'
|
|
);
|
|
}
|
|
|
|
return this._host;
|
|
}
|
|
|
|
get range() {
|
|
return this.get(RangeManager);
|
|
}
|
|
|
|
get selection() {
|
|
return this.get(StoreSelectionExtension);
|
|
}
|
|
|
|
get view() {
|
|
return this.get(ViewStore);
|
|
}
|
|
|
|
constructor(options: BlockStdOptions) {
|
|
this.store = options.store;
|
|
this.userExtensions = options.extensions;
|
|
this.container = new Container();
|
|
this.container.addImpl(StdIdentifier, () => this);
|
|
|
|
internalExtensions.forEach(ext => {
|
|
const container = this.container;
|
|
ext.setup(container);
|
|
});
|
|
|
|
this.userExtensions.forEach(ext => {
|
|
const container = this.container;
|
|
ext.setup(container);
|
|
});
|
|
|
|
this.provider = this.container.provider(undefined, this.store.provider);
|
|
|
|
this._lifeCycleWatchers.forEach(watcher => {
|
|
watcher.created();
|
|
});
|
|
}
|
|
|
|
getConfig<Key extends BlockSuite.ConfigKeys>(
|
|
flavour: Key
|
|
): BlockSuite.BlockConfigs[Key] | null;
|
|
|
|
getConfig(flavour: string) {
|
|
const config = this.provider.getOptional(ConfigIdentifier(flavour));
|
|
if (!config) {
|
|
return null;
|
|
}
|
|
|
|
return config;
|
|
}
|
|
|
|
getView(flavour: string) {
|
|
return this.getOptional(BlockViewIdentifier(flavour));
|
|
}
|
|
|
|
getTransformer(middlewares: TransformerMiddleware[] = []) {
|
|
return new Transformer({
|
|
schema: this.workspace.schema,
|
|
blobCRUD: this.workspace.blobSync,
|
|
docCRUD: {
|
|
create: (id: string) => this.workspace.createDoc({ id }),
|
|
get: (id: string) => this.workspace.getDoc(id),
|
|
delete: (id: string) => this.workspace.removeDoc(id),
|
|
},
|
|
middlewares,
|
|
});
|
|
}
|
|
|
|
mount() {
|
|
this._lifeCycleWatchers.forEach(watcher => {
|
|
watcher.mounted();
|
|
});
|
|
}
|
|
|
|
render() {
|
|
const element = new EditorHost();
|
|
element.std = this;
|
|
element.doc = this.store;
|
|
this._host = element;
|
|
this._lifeCycleWatchers.forEach(watcher => {
|
|
watcher.rendered();
|
|
});
|
|
|
|
return element;
|
|
}
|
|
|
|
unmount() {
|
|
this._lifeCycleWatchers.forEach(watcher => {
|
|
watcher.unmounted();
|
|
});
|
|
}
|
|
}
|
|
|
|
declare global {
|
|
namespace BlockSuite {
|
|
interface BlockConfigs {}
|
|
|
|
type ConfigKeys = string & keyof BlockConfigs;
|
|
}
|
|
}
|