feat(editor): type safe draft model and transformer (#10486)

This commit is contained in:
Saul-Mirone
2025-02-27 09:19:49 +00:00
parent 272d41e32d
commit 4c736bc190
15 changed files with 125 additions and 48 deletions

View File

@@ -4,12 +4,16 @@ type PropsInDraft = 'version' | 'flavour' | 'role' | 'id' | 'keys' | 'text';
type ModelProps<Model> = Model extends BlockModel<infer U> ? U : never;
const draftModelSymbol = Symbol('draftModel');
export type DraftModel<Model extends BlockModel = BlockModel> = Pick<
Model,
PropsInDraft
> & {
children: DraftModel[];
} & ModelProps<Model>;
} & ModelProps<Model> & {
[draftModelSymbol]: true;
};
export function toDraftModel<Model extends BlockModel = BlockModel>(
origin: Model

View File

@@ -16,7 +16,6 @@ import {
type BlockModel,
type BlockOptions,
type BlockProps,
type DraftModel,
} from '../block/index.js';
import type { Doc } from '../doc.js';
import { DocCRUD } from './crud.js';
@@ -100,10 +99,10 @@ export class Store {
};
updateBlock: {
<T extends Partial<BlockProps>>(model: BlockModel, props: T): void;
(model: BlockModel, callback: () => void): void;
<T extends Partial<BlockProps>>(model: BlockModel | string, props: T): void;
(model: BlockModel | string, callback: () => void): void;
} = (
model: BlockModel,
modelOrId: BlockModel | string,
callBackOrProps: (() => void) | Partial<BlockProps>
) => {
if (this.readonly) {
@@ -113,6 +112,17 @@ export class Store {
const isCallback = typeof callBackOrProps === 'function';
const model =
typeof modelOrId === 'string'
? this.getBlock(modelOrId)?.model
: modelOrId;
if (!model) {
throw new BlockSuiteError(
ErrorCode.ModelCRUDError,
`updating block: ${modelOrId} not found`
);
}
if (!isCallback) {
const parent = this.getParent(model);
this.schema.validate(
@@ -549,7 +559,7 @@ export class Store {
}
deleteBlock(
model: DraftModel,
model: BlockModel | string,
options: {
bringChildrenTo?: BlockModel;
deleteChildren?: boolean;
@@ -575,7 +585,10 @@ export class Store {
};
this.transact(() => {
this._crud.deleteBlock(model.id, opts);
this._crud.deleteBlock(
typeof model === 'string' ? model : model.id,
opts
);
});
}