refactor(editor): rename model.doc to store (#12172)

This commit is contained in:
Saul-Mirone
2025-05-07 09:17:01 +00:00
parent eb62d0e853
commit 95b9e4b3d0
95 changed files with 264 additions and 246 deletions
+1 -1
View File
@@ -104,7 +104,7 @@ const createHelmCommand = ({ isDryRun }) => {
`--set web.resources.requests.cpu="${cpu.web}"`, `--set web.resources.requests.cpu="${cpu.web}"`,
`--set graphql.resources.requests.cpu="${cpu.graphql}"`, `--set graphql.resources.requests.cpu="${cpu.graphql}"`,
`--set sync.resources.requests.cpu="${cpu.sync}"`, `--set sync.resources.requests.cpu="${cpu.sync}"`,
`--set doc.resources.requests.cpu="${cpu.doc}"`, `--set doc.resources.requests.cpu="${cpu.store}"`,
] ]
: []; : [];
@@ -42,7 +42,7 @@ import { downloadAttachmentBlob, refreshData } from './utils';
@Peekable({ @Peekable({
enableOn: ({ model }: AttachmentBlockComponent) => { enableOn: ({ model }: AttachmentBlockComponent) => {
return !model.doc.readonly && model.props.type.endsWith('pdf'); return !model.store.readonly && model.props.type.endsWith('pdf');
}, },
}) })
export class AttachmentBlockComponent extends CaptionedBlockComponent<AttachmentBlockModel> { export class AttachmentBlockComponent extends CaptionedBlockComponent<AttachmentBlockModel> {
@@ -41,7 +41,7 @@ export const RenameModal = ({
toast(editorHost, 'File name cannot be empty'); toast(editorHost, 'File name cannot be empty');
return; return;
} }
model.doc.updateBlock(model, { model.store.updateBlock(model, {
name: newFileName, name: newFileName,
}); });
abort(); abort();
@@ -18,7 +18,7 @@ export const attachmentSlashMenuConfig: SlashMenuConfig = {
searchAlias: ['file'], searchAlias: ['file'],
group: '4_Content & Media@3', group: '4_Content & Media@3',
when: ({ model }) => when: ({ model }) =>
model.doc.schema.flavourSchemaMap.has('affine:attachment'), model.store.schema.flavourSchemaMap.has('affine:attachment'),
action: ({ std, model }) => { action: ({ std, model }) => {
(async () => { (async () => {
const file = await openFileOrFiles(); const file = await openFileOrFiles();
@@ -41,7 +41,7 @@ export const attachmentSlashMenuConfig: SlashMenuConfig = {
}, },
group: '4_Content & Media@4', group: '4_Content & Media@4',
when: ({ model }) => when: ({ model }) =>
model.doc.schema.flavourSchemaMap.has('affine:attachment'), model.store.schema.flavourSchemaMap.has('affine:attachment'),
action: ({ std, model }) => { action: ({ std, model }) => {
(async () => { (async () => {
const file = await openFileOrFiles(); const file = await openFileOrFiles();
@@ -98,7 +98,7 @@ export class AttachmentEmbedService extends Extension {
convertTo(model: AttachmentBlockModel, maxFileSize = this._maxFileSize) { convertTo(model: AttachmentBlockModel, maxFileSize = this._maxFileSize) {
const config = this.values.find(config => config.check(model, maxFileSize)); const config = this.values.find(config => config.check(model, maxFileSize));
if (!config?.action) { if (!config?.action) {
model.doc.updateBlock(model, { embed: true }); model.store.updateBlock(model, { embed: true });
return; return;
} }
config.action(model, this.std)?.catch(console.error); config.action(model, this.std)?.catch(console.error);
@@ -129,7 +129,7 @@ const embedConfig: AttachmentEmbedConfig[] = [
{ {
name: 'image', name: 'image',
check: model => check: model =>
model.doc.schema.flavourSchemaMap.has('affine:image') && model.store.schema.flavourSchemaMap.has('affine:image') &&
model.props.type.startsWith('image/'), model.props.type.startsWith('image/'),
async action(model, std) { async action(model, std) {
const component = std.view.getBlock(model.id); const component = std.view.getBlock(model.id);
@@ -189,7 +189,7 @@ const embedConfig: AttachmentEmbedConfig[] = [
* Turn the attachment block into an image block. * Turn the attachment block into an image block.
*/ */
async function turnIntoImageBlock(model: AttachmentBlockModel) { async function turnIntoImageBlock(model: AttachmentBlockModel) {
if (!model.doc.schema.flavourSchemaMap.has('affine:image')) { if (!model.store.schema.flavourSchemaMap.has('affine:image')) {
console.error('The image flavour is not supported!'); console.error('The image flavour is not supported!');
return; return;
} }
@@ -27,7 +27,7 @@ export async function getAttachmentBlob(model: AttachmentBlockModel) {
const type = type$.peek(); const type = type$.peek();
if (!sourceId) return null; if (!sourceId) return null;
const doc = model.doc; const doc = model.store;
const blob = await doc.blobSync.get(sourceId); const blob = await doc.blobSync.get(sourceId);
if (!blob) return null; if (!blob) return null;
@@ -23,7 +23,7 @@ const bookmarkSlashMenuConfig: SlashMenuConfig = {
}, },
group: '4_Content & Media@2', group: '4_Content & Media@2',
when: ({ model }) => when: ({ model }) =>
model.doc.schema.flavourSchemaMap.has('affine:bookmark'), model.store.schema.flavourSchemaMap.has('affine:bookmark'),
action: ({ std, model }) => { action: ({ std, model }) => {
const { host } = std; const { host } = std;
const parentModel = host.doc.getParent(model); const parentModel = host.doc.getParent(model);
@@ -45,7 +45,7 @@ const bookmarkSlashMenuConfig: SlashMenuConfig = {
) )
.then(() => { .then(() => {
if (model.text?.length === 0) { if (model.text?.length === 0) {
model.doc.deleteBlock(model); model.store.deleteBlock(model);
} }
}) })
.catch(console.error); .catch(console.error);
@@ -33,19 +33,24 @@ export const calloutSlashMenuConfig: SlashMenuConfig = {
when: ({ std, model }) => { when: ({ std, model }) => {
return ( return (
std.get(FeatureFlagService).getFlag('enable_callout') && std.get(FeatureFlagService).getFlag('enable_callout') &&
!isInsideBlockByFlavour(model.doc, model, 'affine:edgeless-text') !isInsideBlockByFlavour(model.store, model, 'affine:edgeless-text')
); );
}, },
action: ({ model, std }) => { action: ({ model, std }) => {
const { doc } = model; const { store } = model;
const parent = doc.getParent(model); const parent = store.getParent(model);
if (!parent) return; if (!parent) return;
const index = parent.children.indexOf(model); const index = parent.children.indexOf(model);
if (index === -1) return; if (index === -1) return;
const calloutId = doc.addBlock('affine:callout', {}, parent, index + 1); const calloutId = store.addBlock(
'affine:callout',
{},
parent,
index + 1
);
if (!calloutId) return; if (!calloutId) return;
const paragraphId = doc.addBlock('affine:paragraph', {}, calloutId); const paragraphId = store.addBlock('affine:paragraph', {}, calloutId);
if (!paragraphId) return; if (!paragraphId) return;
std.host.updateComplete std.host.updateComplete
.then(() => { .then(() => {
@@ -363,7 +363,7 @@ export class CodeBlockComponent extends CaptionedBlockComponent<CodeBlockModel>
copyCode() { copyCode() {
const model = this.model; const model = this.model;
const slice = Slice.fromModels(model.doc, [model]); const slice = Slice.fromModels(model.store, [model]);
this.std.clipboard this.std.clipboard
.copySlice(slice) .copySlice(slice)
.then(() => { .then(() => {
@@ -12,5 +12,5 @@ export const duplicateCodeBlock = (model: CodeBlockModel) => {
...duplicateProps, ...duplicateProps,
}; };
return model.doc.addSiblingBlocks(model, [newProps])[0]; return model.store.addSiblingBlocks(model, [newProps])[0];
}; };
@@ -21,7 +21,7 @@ export const dataViewSlashMenuConfig: SlashMenuConfig = {
}, },
group: '7_Database@1', group: '7_Database@1',
when: ({ model, std }) => when: ({ model, std }) =>
!isInsideBlockByFlavour(model.doc, model, 'affine:edgeless-text') && !isInsideBlockByFlavour(model.store, model, 'affine:edgeless-text') &&
!!std.get(FeatureFlagService).getFlag('enable_block_query'), !!std.get(FeatureFlagService).getFlag('enable_block_query'),
action: ({ model, std }) => { action: ({ model, std }) => {
@@ -43,7 +43,7 @@ export const dataViewSlashMenuConfig: SlashMenuConfig = {
dataView?.dataSource.viewManager.viewAdd('table'); dataView?.dataSource.viewManager.viewAdd('table');
if (model.text?.length === 0) { if (model.text?.length === 0) {
model.doc.deleteBlock(model); model.store.deleteBlock(model);
} }
}, },
}, },
@@ -169,7 +169,7 @@ export class BlockQueryDataSource extends DataSourceBase {
insertToPosition: InsertToPosition, insertToPosition: InsertToPosition,
type: string | undefined type: string | undefined
): string { ): string {
const doc = this.block.doc; const doc = this.block.store;
doc.captureSync(); doc.captureSync();
const column = DatabaseBlockDataSource.propertiesMap.value[ const column = DatabaseBlockDataSource.propertiesMap.value[
type ?? propertyPresets.multiSelectPropertyConfig.type type ?? propertyPresets.multiSelectPropertyConfig.type
@@ -292,7 +292,7 @@ export class BlockQueryDataSource extends DataSourceBase {
].config.propertyData.default(), ].config.propertyData.default(),
cells: currentCells.map(() => undefined), cells: currentCells.map(() => undefined),
}; };
this.block.doc.captureSync(); this.block.store.captureSync();
viewColumn.type = toType; viewColumn.type = toType;
viewColumn.data = result.property; viewColumn.data = result.property;
currentCells.forEach((value, i) => { currentCells.forEach((value, i) => {
@@ -24,21 +24,21 @@ export class DataViewBlockModel extends BlockModel<Props> {
} }
applyViewsUpdate() { applyViewsUpdate() {
this.doc.updateBlock(this, { this.store.updateBlock(this, {
views: this.props.views, views: this.props.views,
}); });
} }
deleteView(id: string) { deleteView(id: string) {
this.doc.captureSync(); this.store.captureSync();
this.doc.transact(() => { this.store.transact(() => {
this.props.views = this.props.views.filter(v => v.id !== id); this.props.views = this.props.views.filter(v => v.id !== id);
}); });
} }
duplicateView(id: string): string { duplicateView(id: string): string {
const newId = this.doc.workspace.idGenerator(); const newId = this.store.workspace.idGenerator();
this.doc.transact(() => { this.store.transact(() => {
const index = this.props.views.findIndex(v => v.id === id); const index = this.props.views.findIndex(v => v.id === id);
const view = this.props.views[index]; const view = this.props.views[index];
if (view) { if (view) {
@@ -53,7 +53,7 @@ export class DataViewBlockModel extends BlockModel<Props> {
} }
moveViewTo(id: string, position: InsertToPosition) { moveViewTo(id: string, position: InsertToPosition) {
this.doc.transact(() => { this.store.transact(() => {
this.props.views = arrayMove( this.props.views = arrayMove(
this.props.views, this.props.views,
v => v.id === id, v => v.id === id,
@@ -67,7 +67,7 @@ export class DataViewBlockModel extends BlockModel<Props> {
id: string, id: string,
update: (data: DataViewDataType) => Partial<DataViewDataType> update: (data: DataViewDataType) => Partial<DataViewDataType>
) { ) {
this.doc.transact(() => { this.store.transact(() => {
this.props.views = this.props.views.map(v => { this.props.views = this.props.views.map(v => {
if (v.id !== id) { if (v.id !== id) {
return v; return v;
@@ -25,7 +25,7 @@ export const databaseSlashMenuConfig: SlashMenuConfig = {
}, },
group: '7_Database@0', group: '7_Database@0',
when: ({ model }) => when: ({ model }) =>
!isInsideBlockByFlavour(model.doc, model, 'affine:edgeless-text'), !isInsideBlockByFlavour(model.store, model, 'affine:edgeless-text'),
action: ({ std }) => { action: ({ std }) => {
std.command std.command
.chain() .chain()
@@ -58,7 +58,7 @@ export const databaseSlashMenuConfig: SlashMenuConfig = {
}, },
group: '7_Database@2', group: '7_Database@2',
when: ({ model }) => when: ({ model }) =>
!isInsideBlockByFlavour(model.doc, model, 'affine:edgeless-text'), !isInsideBlockByFlavour(model.store, model, 'affine:edgeless-text'),
action: ({ std }) => { action: ({ std }) => {
std.command std.command
.chain() .chain()
@@ -99,7 +99,7 @@ export class DatabaseBlockDataSource extends DataSourceBase {
readonly$: ReadonlySignal<boolean> = computed(() => { readonly$: ReadonlySignal<boolean> = computed(() => {
return ( return (
this._model.doc.readonly || this._model.store.readonly ||
// TODO(@L-Sun): use block level readonly // TODO(@L-Sun): use block level readonly
IS_MOBILE IS_MOBILE
); );
@@ -120,7 +120,7 @@ export class DatabaseBlockDataSource extends DataSourceBase {
viewMetas = databaseBlockViews; viewMetas = databaseBlockViews;
get doc() { get doc() {
return this._model.doc; return this._model.store;
} }
allPropertyMetas$ = computed<PropertyMetaConfig<any, any, any, any>[]>(() => { allPropertyMetas$ = computed<PropertyMetaConfig<any, any, any, any>[]>(() => {
@@ -302,7 +302,7 @@ export class DatabaseBlockDataSource extends DataSourceBase {
return; return;
} }
const { column: prevColumn, index } = result; const { column: prevColumn, index } = result;
this._model.doc.transact(() => { this._model.store.transact(() => {
if (index >= 0) { if (index >= 0) {
const result = updater(prevColumn); const result = updater(prevColumn);
this._model.props.columns[index] = { ...prevColumn, ...result }; this._model.props.columns[index] = { ...prevColumn, ...result };
@@ -500,15 +500,15 @@ export class DatabaseBlockDataSource extends DataSourceBase {
} }
viewDataAdd(viewData: DataViewDataType): string { viewDataAdd(viewData: DataViewDataType): string {
this._model.doc.captureSync(); this._model.store.captureSync();
this._model.doc.transact(() => { this._model.store.transact(() => {
this._model.props.views = [...this._model.props.views, viewData]; this._model.props.views = [...this._model.props.views, viewData];
}); });
return viewData.id; return viewData.id;
} }
viewDataDelete(viewId: string): void { viewDataDelete(viewId: string): void {
this._model.doc.captureSync(); this._model.store.captureSync();
deleteView(this._model, viewId); deleteView(this._model, viewId);
} }
@@ -434,13 +434,13 @@ export class DatabaseBlockComponent extends CaptionedBlockComponent<DatabaseBloc
return peekViewService.peek({ return peekViewService.peek({
docId, docId,
databaseId: this.blockId, databaseId: this.blockId,
databaseDocId: this.model.doc.id, databaseDocId: this.model.store.id,
databaseRowId: data.rowId, databaseRowId: data.rowId,
target: this, target: this,
}); });
}; };
const doc = getSingleDocIdFromText( const doc = getSingleDocIdFromText(
this.model.doc.getBlock(data.rowId)?.model?.text this.model.store.getBlock(data.rowId)?.model?.text
); );
if (doc) { if (doc) {
return openDoc(doc); return openDoc(doc);
@@ -36,7 +36,7 @@ export class NoteRenderer
accessor rowId!: string; accessor rowId!: string;
rowText$ = computed(() => { rowText$ = computed(() => {
return this.databaseBlock.doc.getBlock(this.rowId)?.model?.text; return this.databaseBlock.store.getBlock(this.rowId)?.model?.text;
}); });
allowCreateDoc$ = computed(() => { allowCreateDoc$ = computed(() => {
@@ -19,11 +19,11 @@ export function addProperty(
id?: string; id?: string;
} }
): string { ): string {
const id = column.id ?? model.doc.workspace.idGenerator(); const id = column.id ?? model.store.workspace.idGenerator();
if (model.props.columns.some(v => v.id === id)) { if (model.props.columns.some(v => v.id === id)) {
return id; return id;
} }
model.doc.transact(() => { model.store.transact(() => {
const col: ColumnDataType = { const col: ColumnDataType = {
...column, ...column,
id, id,
@@ -42,7 +42,7 @@ export function copyCellsByProperty(
fromId: ColumnDataType['id'], fromId: ColumnDataType['id'],
toId: ColumnDataType['id'] toId: ColumnDataType['id']
) { ) {
model.doc.transact(() => { model.store.transact(() => {
Object.keys(model.props.cells).forEach(rowId => { Object.keys(model.props.cells).forEach(rowId => {
const cell = model.props.cells[rowId]?.[fromId]; const cell = model.props.cells[rowId]?.[fromId];
if (cell && model.props.cells[rowId]) { if (cell && model.props.cells[rowId]) {
@@ -62,13 +62,13 @@ export function deleteColumn(
const index = model.props.columns.findIndex(v => v.id === columnId); const index = model.props.columns.findIndex(v => v.id === columnId);
if (index < 0) return; if (index < 0) return;
model.doc.transact(() => { model.store.transact(() => {
model.props.columns.splice(index, 1); model.props.columns.splice(index, 1);
}); });
} }
export function deleteRows(model: DatabaseBlockModel, rowIds: string[]) { export function deleteRows(model: DatabaseBlockModel, rowIds: string[]) {
model.doc.transact(() => { model.store.transact(() => {
for (const rowId of rowIds) { for (const rowId of rowIds) {
delete model.props.cells[rowId]; delete model.props.cells[rowId];
} }
@@ -76,15 +76,15 @@ export function deleteRows(model: DatabaseBlockModel, rowIds: string[]) {
} }
export function deleteView(model: DatabaseBlockModel, id: string) { export function deleteView(model: DatabaseBlockModel, id: string) {
model.doc.captureSync(); model.store.captureSync();
model.doc.transact(() => { model.store.transact(() => {
model.props.views = model.props.views.filter(v => v.id !== id); model.props.views = model.props.views.filter(v => v.id !== id);
}); });
} }
export function duplicateView(model: DatabaseBlockModel, id: string): string { export function duplicateView(model: DatabaseBlockModel, id: string): string {
const newId = model.doc.workspace.idGenerator(); const newId = model.store.workspace.idGenerator();
model.doc.transact(() => { model.store.transact(() => {
const index = model.props.views.findIndex(v => v.id === id); const index = model.props.views.findIndex(v => v.id === id);
const view = model.props.views[index]; const view = model.props.views[index];
if (view) { if (view) {
@@ -131,7 +131,7 @@ export function moveViewTo(
id: string, id: string,
position: InsertToPosition position: InsertToPosition
) { ) {
model.doc.transact(() => { model.store.transact(() => {
model.props.views = arrayMove( model.props.views = arrayMove(
model.props.views, model.props.views,
v => v.id === id, v => v.id === id,
@@ -145,7 +145,7 @@ export function updateCell(
rowId: string, rowId: string,
cell: CellDataType cell: CellDataType
) { ) {
model.doc.transact(() => { model.store.transact(() => {
const columnId = cell.columnId; const columnId = cell.columnId;
if ( if (
rowId === '__proto__' || rowId === '__proto__' ||
@@ -180,7 +180,7 @@ export function updateCells(
columnId: string, columnId: string,
cells: Record<string, unknown> cells: Record<string, unknown>
) { ) {
model.doc.transact(() => { model.store.transact(() => {
Object.entries(cells).forEach(([rowId, value]) => { Object.entries(cells).forEach(([rowId, value]) => {
if ( if (
rowId === '__proto__' || rowId === '__proto__' ||
@@ -212,7 +212,7 @@ export function updateProperty(
if (index == null) { if (index == null) {
return; return;
} }
model.doc.transact(() => { model.store.transact(() => {
const column = model.props.columns[index]; const column = model.props.columns[index];
if (!column) { if (!column) {
return; return;
@@ -228,7 +228,7 @@ export const updateView = <ViewData extends ViewBasicDataType>(
id: string, id: string,
update: (data: ViewData) => Partial<ViewData> update: (data: ViewData) => Partial<ViewData>
) => { ) => {
model.doc.transact(() => { model.store.transact(() => {
model.props.views = model.props.views.map(v => { model.props.views = model.props.views.map(v => {
if (v.id !== id) { if (v.id !== id) {
return v; return v;
@@ -23,7 +23,7 @@ const linkedDocSlashMenuConfig: SlashMenuConfig = {
}, },
group: '3_Page@0', group: '3_Page@0',
when: ({ model }) => when: ({ model }) =>
model.doc.schema.flavourSchemaMap.has('affine:embed-linked-doc'), model.store.schema.flavourSchemaMap.has('affine:embed-linked-doc'),
action: ({ std, model }) => { action: ({ std, model }) => {
const newDoc = createDefaultDoc(std.host.doc.workspace); const newDoc = createDefaultDoc(std.host.doc.workspace);
insertContent(std, model, REFERENCE_NODE, { insertContent(std, model, REFERENCE_NODE, {
@@ -45,7 +45,7 @@ const linkedDocSlashMenuConfig: SlashMenuConfig = {
searchAlias: ['dual link'], searchAlias: ['dual link'],
group: '3_Page@1', group: '3_Page@1',
when: ({ std, model }) => { when: ({ std, model }) => {
const root = model.doc.root; const root = model.store.root;
if (!root) return false; if (!root) return false;
const linkedDocWidget = std.view.getWidget( const linkedDocWidget = std.view.getWidget(
'affine-linked-doc-widget', 'affine-linked-doc-widget',
@@ -53,10 +53,12 @@ const linkedDocSlashMenuConfig: SlashMenuConfig = {
); );
if (!linkedDocWidget) return false; if (!linkedDocWidget) return false;
return model.doc.schema.flavourSchemaMap.has('affine:embed-linked-doc'); return model.store.schema.flavourSchemaMap.has(
'affine:embed-linked-doc'
);
}, },
action: ({ model, std }) => { action: ({ model, std }) => {
const root = model.doc.root; const root = model.store.root;
if (!root) return; if (!root) return;
const linkedDocWidget = std.view.getWidget( const linkedDocWidget = std.view.getWidget(
'affine-linked-doc-widget', 'affine-linked-doc-widget',
@@ -21,7 +21,7 @@ export class EmbedEdgelessLinkedDocBlockComponent extends toEdgelessEmbedBlock(
) { ) {
override convertToEmbed = () => { override convertToEmbed = () => {
const { caption, xywh } = this.model.props; const { caption, xywh } = this.model.props;
const { doc, id } = this.model; const { store, id } = this.model;
const style = 'syncedDoc'; const style = 'syncedDoc';
const bound = Bound.deserialize(xywh); const bound = Bound.deserialize(xywh);
@@ -50,7 +50,7 @@ export class EmbedEdgelessLinkedDocBlockComponent extends toEdgelessEmbedBlock(
elements: [newId], elements: [newId],
}); });
doc.deleteBlock(this.model); store.deleteBlock(this.model);
}; };
protected override _handleClick = (evt: MouseEvent): void => { protected override _handleClick = (evt: MouseEvent): void => {
@@ -137,10 +137,10 @@ export class EmbedLinkedDocBlockComponent extends EmbedBlockComponent<EmbedLinke
if (this._referenceToNode) return; if (this._referenceToNode) return;
const { caption } = this.model.props; const { caption } = this.model.props;
const { parent, doc } = this.model; const { parent, store } = this.model;
const index = parent?.children.indexOf(this.model); const index = parent?.children.indexOf(this.model);
const blockId = doc.addBlock( const blockId = store.addBlock(
'affine:embed-synced-doc', 'affine:embed-synced-doc',
{ {
caption, caption,
@@ -150,7 +150,7 @@ export class EmbedLinkedDocBlockComponent extends EmbedBlockComponent<EmbedLinke
index index
); );
doc.deleteBlock(this.model); store.deleteBlock(this.model);
this.std.selection.setGroup('note', [ this.std.selection.setGroup('note', [
this.std.selection.create(BlockSelection, { blockId }), this.std.selection.create(BlockSelection, { blockId }),
@@ -158,8 +158,8 @@ export class EmbedLinkedDocBlockComponent extends EmbedBlockComponent<EmbedLinke
}; };
convertToInline = () => { convertToInline = () => {
const { doc } = this.model; const { store } = this.model;
const parent = doc.getParent(this.model); const parent = store.getParent(this.model);
if (!parent) { if (!parent) {
return; return;
} }
@@ -175,7 +175,7 @@ export class EmbedLinkedDocBlockComponent extends EmbedBlockComponent<EmbedLinke
}); });
const text = new Text(yText); const text = new Text(yText);
doc.addBlock( store.addBlock(
'affine:paragraph', 'affine:paragraph',
{ {
text, text,
@@ -184,7 +184,7 @@ export class EmbedLinkedDocBlockComponent extends EmbedBlockComponent<EmbedLinke
index index
); );
doc.deleteBlock(this.model); store.deleteBlock(this.model);
}; };
referenceInfo$ = computed(() => { referenceInfo$ = computed(() => {
@@ -145,7 +145,7 @@ export class EmbedEdgelessSyncedDocBlockComponent extends toEdgelessEmbedBlock(
}; };
override convertToCard = (aliasInfo?: AliasInfo) => { override convertToCard = (aliasInfo?: AliasInfo) => {
const { id, doc, xywh } = this.model; const { id, store, xywh } = this.model;
const { caption } = this.model.props; const { caption } = this.model.props;
const style = 'vertical'; const style = 'vertical';
@@ -176,7 +176,7 @@ export class EmbedEdgelessSyncedDocBlockComponent extends toEdgelessEmbedBlock(
editing: false, editing: false,
elements: [newId], elements: [newId],
}); });
doc.deleteBlock(this.model); store.deleteBlock(this.model);
}; };
override renderGfxBlock() { override renderGfxBlock() {
@@ -276,10 +276,10 @@ export class EmbedSyncedDocBlockComponent extends EmbedBlockComponent<EmbedSynce
}); });
convertToCard = (aliasInfo?: AliasInfo) => { convertToCard = (aliasInfo?: AliasInfo) => {
const { doc } = this.model; const { store } = this.model;
const { caption } = this.model.props; const { caption } = this.model.props;
const parent = doc.getParent(this.model); const parent = store.getParent(this.model);
if (!parent) { if (!parent) {
console.error( console.error(
`Trying to convert synced doc to card, but the parent is not found.` `Trying to convert synced doc to card, but the parent is not found.`
@@ -288,14 +288,14 @@ export class EmbedSyncedDocBlockComponent extends EmbedBlockComponent<EmbedSynce
} }
const index = parent.children.indexOf(this.model); const index = parent.children.indexOf(this.model);
const blockId = doc.addBlock( const blockId = store.addBlock(
'affine:embed-linked-doc', 'affine:embed-linked-doc',
{ caption, ...this.referenceInfo, ...aliasInfo }, { caption, ...this.referenceInfo, ...aliasInfo },
parent, parent,
index index
); );
doc.deleteBlock(this.model); store.deleteBlock(this.model);
this.std.selection.setGroup('note', [ this.std.selection.setGroup('note', [
this.std.selection.create(BlockSelection, { blockId }), this.std.selection.create(BlockSelection, { blockId }),
@@ -303,8 +303,8 @@ export class EmbedSyncedDocBlockComponent extends EmbedBlockComponent<EmbedSynce
}; };
convertToInline = () => { convertToInline = () => {
const { doc } = this.model; const { store } = this.model;
const parent = doc.getParent(this.model); const parent = store.getParent(this.model);
if (!parent) { if (!parent) {
console.error( console.error(
`Trying to convert synced doc to inline, but the parent is not found.` `Trying to convert synced doc to inline, but the parent is not found.`
@@ -323,7 +323,7 @@ export class EmbedSyncedDocBlockComponent extends EmbedBlockComponent<EmbedSynce
}); });
const text = new Text(yText); const text = new Text(yText);
doc.addBlock( store.addBlock(
'affine:paragraph', 'affine:paragraph',
{ {
text, text,
@@ -332,7 +332,7 @@ export class EmbedSyncedDocBlockComponent extends EmbedBlockComponent<EmbedSynce
index index
); );
doc.deleteBlock(this.model); store.deleteBlock(this.model);
}; };
protected override embedContainerStyle: StyleInfo = { protected override embedContainerStyle: StyleInfo = {
@@ -18,7 +18,7 @@ export const embedFigmaSlashMenuConfig: SlashMenuConfig = {
}, },
group: '4_Content & Media@8', group: '4_Content & Media@8',
when: ({ model }) => when: ({ model }) =>
model.doc.schema.flavourSchemaMap.has('affine:embed-figma'), model.store.schema.flavourSchemaMap.has('affine:embed-figma'),
action: ({ std, model }) => { action: ({ std, model }) => {
(async () => { (async () => {
const { host } = std; const { host } = std;
@@ -18,7 +18,7 @@ export const embedGithubSlashMenuConfig: SlashMenuConfig = {
}, },
group: '4_Content & Media@7', group: '4_Content & Media@7',
when: ({ model }) => when: ({ model }) =>
model.doc.schema.flavourSchemaMap.has('affine:embed-github'), model.store.schema.flavourSchemaMap.has('affine:embed-github'),
action: ({ std, model }) => { action: ({ std, model }) => {
(async () => { (async () => {
const { host } = std; const { host } = std;
@@ -282,7 +282,7 @@ export class EmbedIframeErrorCard extends WithDisposable(LitElement) {
} }
get readonly() { get readonly() {
return this.model.doc.readonly; return this.model.store.readonly;
} }
get telemetryService() { get telemetryService() {
@@ -133,7 +133,7 @@ export class EmbedIframeLinkInputBase extends WithDisposable(LitElement) {
} }
get store() { get store() {
return this.model.doc; return this.model.store;
} }
get notificationService() { get notificationService() {
@@ -17,7 +17,7 @@ export const embedIframeSlashMenuConfig: SlashMenuConfig = {
}, },
group: '4_Content & Media@5', group: '4_Content & Media@5',
when: ({ model }) => { when: ({ model }) => {
return model.doc.schema.flavourSchemaMap.has('affine:embed-iframe'); return model.store.schema.flavourSchemaMap.has('affine:embed-iframe');
}, },
action: ({ std }) => { action: ({ std }) => {
std.command std.command
@@ -18,7 +18,7 @@ export const embedLoomSlashMenuConfig: SlashMenuConfig = {
}, },
group: '4_Content & Media@9', group: '4_Content & Media@9',
when: ({ model }) => when: ({ model }) =>
model.doc.schema.flavourSchemaMap.has('affine:embed-loom'), model.store.schema.flavourSchemaMap.has('affine:embed-loom'),
action: ({ std, model }) => { action: ({ std, model }) => {
(async () => { (async () => {
const { host } = std; const { host } = std;
@@ -18,7 +18,7 @@ export const embedYoutubeSlashMenuConfig: SlashMenuConfig = {
}, },
group: '4_Content & Media@6', group: '4_Content & Media@6',
when: ({ model }) => when: ({ model }) =>
model.doc.schema.flavourSchemaMap.has('affine:embed-youtube'), model.store.schema.flavourSchemaMap.has('affine:embed-youtube'),
action: ({ std, model }) => { action: ({ std, model }) => {
(async () => { (async () => {
const { host } = std; const { host } = std;
@@ -17,7 +17,7 @@ export const imageSlashMenuConfig: SlashMenuConfig = {
}, },
group: '4_Content & Media@1', group: '4_Content & Media@1',
when: ({ model }) => when: ({ model }) =>
model.doc.schema.flavourSchemaMap.has('affine:image'), model.store.schema.flavourSchemaMap.has('affine:image'),
action: ({ std }) => { action: ({ std }) => {
const [success, ctx] = std.command const [success, ctx] = std.command
.chain() .chain()
@@ -23,9 +23,9 @@ export class ImageResizeManager {
} }
const dragModel = getModelByElement(this._activeComponent); const dragModel = getModelByElement(this._activeComponent);
dragModel?.doc.captureSync(); dragModel?.store.captureSync();
const { width, height } = this._imageContainer.getBoundingClientRect(); const { width, height } = this._imageContainer.getBoundingClientRect();
dragModel?.doc.updateBlock(dragModel, { dragModel?.store.updateBlock(dragModel, {
width: width / this._zoom, width: width / this._zoom,
height: height / this._zoom, height: height / this._zoom,
}); });
@@ -13,7 +13,7 @@ const flavour = ImageBlockSchema.model.flavour;
export const ImageBlockSpec: ExtensionType[] = [ export const ImageBlockSpec: ExtensionType[] = [
FlavourExtension(flavour), FlavourExtension(flavour),
BlockViewExtension(flavour, model => { BlockViewExtension(flavour, model => {
const parent = model.doc.getParent(model.id); const parent = model.store.getParent(model.id);
if (parent?.flavour === 'affine:surface') { if (parent?.flavour === 'affine:surface') {
return literal`affine-edgeless-image`; return literal`affine-edgeless-image`;
+4 -4
View File
@@ -36,7 +36,7 @@ async function getImageBlob(model: ImageBlockModel) {
const sourceId = model.props.sourceId$.peek(); const sourceId = model.props.sourceId$.peek();
if (!sourceId) return null; if (!sourceId) return null;
const doc = model.doc; const doc = model.store;
let blob = await doc.blobSync.get(sourceId); let blob = await doc.blobSync.get(sourceId);
if (!blob) return null; if (!blob) return null;
@@ -419,15 +419,15 @@ export function duplicate(block: ImageBlockComponent) {
...duplicateProps ...duplicateProps
} = blockProps; } = blockProps;
const { doc } = model; const { store } = model;
const parent = doc.getParent(model); const parent = store.getParent(model);
if (!parent) { if (!parent) {
console.error(`Parent not found for block(${model.flavour}) ${model.id}`); console.error(`Parent not found for block(${model.flavour}) ${model.id}`);
return; return;
} }
const index = parent?.children.indexOf(model); const index = parent?.children.indexOf(model);
const duplicateId = doc.addBlock( const duplicateId = store.addBlock(
model.flavour, model.flavour,
duplicateProps, duplicateProps,
parent, parent,
@@ -15,10 +15,10 @@ import { getNumberPrefix } from './get-number-prefix.js';
const getListDeep = (model: ListBlockModel): number => { const getListDeep = (model: ListBlockModel): number => {
let deep = 0; let deep = 0;
let parent = model.doc.getParent(model); let parent = model.store.getParent(model);
while (parent?.flavour === model.flavour) { while (parent?.flavour === model.flavour) {
deep++; deep++;
parent = model.doc.getParent(parent); parent = model.store.getParent(parent);
} }
return deep; return deep;
}; };
@@ -56,7 +56,7 @@ export function getListIcon(
case 'todo': case 'todo':
return html`<div return html`<div
contenteditable="false" contenteditable="false"
class=${`affine-list-block__prefix affine-list-block__todo-prefix ${model.doc.readonly ? 'readonly' : ''}`} class=${`affine-list-block__prefix affine-list-block__todo-prefix ${model.store.readonly ? 'readonly' : ''}`}
@click=${onClick} @click=${onClick}
> >
${model.props.checked ${model.props.checked
@@ -45,8 +45,12 @@ const noteSlashMenuConfig: SlashMenuConfig = {
({ ({
...createConversionItem(config, `0_Basic@${basicIndex++}`), ...createConversionItem(config, `0_Basic@${basicIndex++}`),
when: ({ model }) => when: ({ model }) =>
model.doc.schema.flavourSchemaMap.has(config.flavour) && model.store.schema.flavourSchemaMap.has(config.flavour) &&
!isInsideBlockByFlavour(model.doc, model, 'affine:edgeless-text'), !isInsideBlockByFlavour(
model.store,
model,
'affine:edgeless-text'
),
}) satisfies SlashMenuActionItem }) satisfies SlashMenuActionItem
), ),
@@ -75,7 +79,7 @@ function createConversionItem(
description, description,
icon, icon,
tooltip: tooltips[name], tooltip: tooltips[name],
when: ({ model }) => model.doc.schema.flavourSchemaMap.has(flavour), when: ({ model }) => model.store.schema.flavourSchemaMap.has(flavour),
action: ({ std }) => { action: ({ std }) => {
std.command.exec(updateBlockType, { std.command.exec(updateBlockType, {
flavour, flavour,
@@ -130,14 +130,14 @@ export class EdgelessNoteBlockComponent extends toGfxBlockComponent(
const { collapse, collapsedHeight } = this.model.props.edgeless; const { collapse, collapsedHeight } = this.model.props.edgeless;
if (collapse) { if (collapse) {
this.model.doc.updateBlock(this.model, () => { this.model.store.updateBlock(this.model, () => {
this.model.props.edgeless.collapse = false; this.model.props.edgeless.collapse = false;
}); });
} else if (collapsedHeight) { } else if (collapsedHeight) {
const { xywh, edgeless } = this.model.props; const { xywh, edgeless } = this.model.props;
const bound = Bound.deserialize(xywh); const bound = Bound.deserialize(xywh);
bound.h = collapsedHeight * (edgeless.scale ?? 1); bound.h = collapsedHeight * (edgeless.scale ?? 1);
this.model.doc.updateBlock(this.model, () => { this.model.store.updateBlock(this.model, () => {
this.model.props.edgeless.collapse = true; this.model.props.edgeless.collapse = true;
this.model.props.xywh = bound.serialize(); this.model.props.xywh = bound.serialize();
}); });
@@ -41,7 +41,7 @@ import type { BlockModel, Text } from '@blocksuite/store';
* - line3 * - line3
*/ */
export function mergeWithPrev(editorHost: EditorHost, model: BlockModel) { export function mergeWithPrev(editorHost: EditorHost, model: BlockModel) {
const doc = model.doc; const doc = model.store;
const parent = doc.getParent(model); const parent = doc.getParent(model);
if (!parent) return false; if (!parent) return false;
@@ -118,7 +118,7 @@ export function mergeWithPrev(editorHost: EditorHost, model: BlockModel) {
} }
function handleNoPreviousSibling(editorHost: EditorHost, model: ExtendedModel) { function handleNoPreviousSibling(editorHost: EditorHost, model: ExtendedModel) {
const doc = model.doc; const doc = model.store;
const text = model.text; const text = model.text;
const parent = doc.getParent(model); const parent = doc.getParent(model);
if (!parent) return false; if (!parent) return false;
@@ -137,7 +137,7 @@ function handleNoPreviousSibling(editorHost: EditorHost, model: ExtendedModel) {
return false; return false;
} }
const rootModel = model.doc.root as RootBlockModel; const rootModel = model.store.root as RootBlockModel;
const title = rootModel.props.title; const title = rootModel.props.title;
doc.captureSync(); doc.captureSync();
@@ -43,7 +43,7 @@ export class SurfaceRefNotePortal extends WithDisposable(ShadowlessElement) {
let parent: BlockModel | null = this.model; let parent: BlockModel | null = this.model;
while (parent) { while (parent) {
this.ancestors.add(parent.id); this.ancestors.add(parent.id);
parent = this.model.doc.getParent(parent.id); parent = this.model.store.getParent(parent.id);
} }
const query: Query = { const query: Query = {
mode: 'include', mode: 'include',
@@ -54,7 +54,7 @@ export class SurfaceRefNotePortal extends WithDisposable(ShadowlessElement) {
}; };
this.query = query; this.query = query;
const doc = this.model.doc; const doc = this.model.store;
this._disposables.add(() => { this._disposables.add(() => {
doc.doc.removeStore({ query, readonly: true }); doc.doc.removeStore({ query, readonly: true });
}); });
@@ -118,7 +118,7 @@ export class SurfaceRefNotePortal extends WithDisposable(ShadowlessElement) {
console.error('Query is not set before rendering note preview'); console.error('Query is not set before rendering note preview');
return nothing; return nothing;
} }
const doc = this.model.doc.doc.getStore({ const doc = this.model.store.doc.getStore({
query: this.query, query: this.query,
readonly: true, readonly: true,
}); });
@@ -402,7 +402,7 @@ export class SurfaceRefBlockComponent extends BlockComponent<SurfaceRefBlockMode
openMode?: OpenDocMode; openMode?: OpenDocMode;
event?: MouseEvent; event?: MouseEvent;
} = {}) => { } = {}) => {
const pageId = this.referenceModel?.surface?.doc.id; const pageId = this.referenceModel?.surface?.store.id;
if (!pageId) return; if (!pageId) return;
this.std.getOptional(RefNodeSlotsProvider)?.docLinkClicked.next({ this.std.getOptional(RefNodeSlotsProvider)?.docLinkClicked.next({
@@ -438,7 +438,7 @@ export class ExportManager {
if (matchModels(block, [ImageBlockModel])) { if (matchModels(block, [ImageBlockModel])) {
if (!block.props.sourceId) return; if (!block.props.sourceId) return;
const blob = await block.doc.blobSync.get(block.props.sourceId); const blob = await block.store.blobSync.get(block.props.sourceId);
if (!blob) return; if (!blob) return;
const blobToImage = (blob: Blob) => const blobToImage = (blob: Blob) =>
@@ -44,7 +44,7 @@ export class SurfaceBlockModel extends BaseSurfaceModel {
override _init() { override _init() {
this._extendElement(elementsCtorMap); this._extendElement(elementsCtorMap);
super._init(); super._init();
this.doc.provider this.store.provider
.getAll(surfaceMiddlewareIdentifier) .getAll(surfaceMiddlewareIdentifier)
.forEach(({ middleware }) => { .forEach(({ middleware }) => {
this._disposables.add(middleware(this)); this._disposables.add(middleware(this));
@@ -51,7 +51,7 @@ export function updateXYWH(
bound.w = clamp(bound.w, NOTE_MIN_WIDTH * scale, Infinity); bound.w = clamp(bound.w, NOTE_MIN_WIDTH * scale, Infinity);
bound.h = clamp(bound.h, NOTE_MIN_HEIGHT * scale, Infinity); bound.h = clamp(bound.h, NOTE_MIN_HEIGHT * scale, Infinity);
if (bound.h >= NOTE_MIN_HEIGHT * scale) { if (bound.h >= NOTE_MIN_HEIGHT * scale) {
updateBlock.call(ele.doc, ele, () => { updateBlock.call(ele.store, ele, () => {
ele.props.edgeless.collapse = true; ele.props.edgeless.collapse = true;
ele.props.edgeless.collapsedHeight = bound.h / scale; ele.props.edgeless.collapsedHeight = bound.h / scale;
}); });
@@ -20,7 +20,7 @@ export const tableSlashMenuConfig: SlashMenuConfig = {
}, },
group: '4_Content & Media@0', group: '4_Content & Media@0',
when: ({ model }) => when: ({ model }) =>
!isInsideBlockByFlavour(model.doc, model, 'affine:edgeless-text'), !isInsideBlockByFlavour(model.store, model, 'affine:edgeless-text'),
action: ({ std }) => { action: ({ std }) => {
std.command std.command
.chain() .chain()
@@ -8,7 +8,7 @@ import type { TableAreaSelection } from './selection-schema';
export class TableDataManager { export class TableDataManager {
constructor(private readonly model: TableBlockModel) {} constructor(private readonly model: TableBlockModel) {}
readonly readonly$: ReadonlySignal<boolean> = computed(() => { readonly readonly$: ReadonlySignal<boolean> = computed(() => {
return this.model.doc.readonly; return this.model.store.readonly;
}); });
readonly ui = { readonly ui = {
columnIndicatorIndex$: signal<number>(), columnIndicatorIndex$: signal<number>(),
@@ -83,7 +83,7 @@ export class TableDataManager {
addRow(after?: number) { addRow(after?: number) {
const order = this.getOrder(this.rows$.value, after); const order = this.getOrder(this.rows$.value, after);
const rowId = nanoid(); const rowId = nanoid();
this.model.doc.transact(() => { this.model.store.transact(() => {
this.model.props.rows[rowId] = { this.model.props.rows[rowId] = {
rowId, rowId,
order, order,
@@ -102,7 +102,7 @@ export class TableDataManager {
return; return;
} }
if (count > 0) { if (count > 0) {
this.model.doc.transact(() => { this.model.store.transact(() => {
for (let i = 0; i < count; i++) { for (let i = 0; i < count; i++) {
this.addRow(this.rows$.value.length - 1); this.addRow(this.rows$.value.length - 1);
} }
@@ -110,7 +110,7 @@ export class TableDataManager {
} else { } else {
const rows = this.rows$.value; const rows = this.rows$.value;
const rowCount = rows.length; const rowCount = rows.length;
this.model.doc.transact(() => { this.model.store.transact(() => {
rows.slice(rowCount + count, rowCount).forEach(row => { rows.slice(rowCount + count, rowCount).forEach(row => {
this.deleteRow(row.rowId); this.deleteRow(row.rowId);
}); });
@@ -123,7 +123,7 @@ export class TableDataManager {
return; return;
} }
if (count > 0) { if (count > 0) {
this.model.doc.transact(() => { this.model.store.transact(() => {
for (let i = 0; i < count; i++) { for (let i = 0; i < count; i++) {
this.addColumn(this.columns$.value.length - 1); this.addColumn(this.columns$.value.length - 1);
} }
@@ -131,7 +131,7 @@ export class TableDataManager {
} else { } else {
const columns = this.columns$.value; const columns = this.columns$.value;
const columnCount = columns.length; const columnCount = columns.length;
this.model.doc.transact(() => { this.model.store.transact(() => {
columns.slice(columnCount + count, columnCount).forEach(column => { columns.slice(columnCount + count, columnCount).forEach(column => {
this.deleteColumn(column.columnId); this.deleteColumn(column.columnId);
}); });
@@ -153,7 +153,7 @@ export class TableDataManager {
addColumn(after?: number) { addColumn(after?: number) {
const order = this.getOrder(this.columns$.value, after); const order = this.getOrder(this.columns$.value, after);
const columnId = nanoid(); const columnId = nanoid();
this.model.doc.transact(() => { this.model.store.transact(() => {
this.model.props.columns[columnId] = { this.model.props.columns[columnId] = {
columnId, columnId,
order, order,
@@ -168,7 +168,7 @@ export class TableDataManager {
} }
deleteRow(rowId: string) { deleteRow(rowId: string) {
this.model.doc.transact(() => { this.model.store.transact(() => {
Object.keys(this.model.props.rows).forEach(id => { Object.keys(this.model.props.rows).forEach(id => {
if (id === rowId) { if (id === rowId) {
delete this.model.props.rows[id]; delete this.model.props.rows[id];
@@ -183,7 +183,7 @@ export class TableDataManager {
} }
deleteColumn(columnId: string) { deleteColumn(columnId: string) {
this.model.doc.transact(() => { this.model.store.transact(() => {
Object.keys(this.model.props.columns).forEach(id => { Object.keys(this.model.props.columns).forEach(id => {
if (id === columnId) { if (id === columnId) {
delete this.model.props.columns[id]; delete this.model.props.columns[id];
@@ -198,7 +198,7 @@ export class TableDataManager {
} }
updateRowOrder(rowId: string, newOrder: string) { updateRowOrder(rowId: string, newOrder: string) {
this.model.doc.transact(() => { this.model.store.transact(() => {
if (this.model.props.rows[rowId]) { if (this.model.props.rows[rowId]) {
this.model.props.rows[rowId].order = newOrder; this.model.props.rows[rowId].order = newOrder;
} }
@@ -206,7 +206,7 @@ export class TableDataManager {
} }
updateColumnOrder(columnId: string, newOrder: string) { updateColumnOrder(columnId: string, newOrder: string) {
this.model.doc.transact(() => { this.model.store.transact(() => {
if (this.model.props.columns[columnId]) { if (this.model.props.columns[columnId]) {
this.model.props.columns[columnId].order = newOrder; this.model.props.columns[columnId].order = newOrder;
} }
@@ -214,7 +214,7 @@ export class TableDataManager {
} }
setRowBackgroundColor(rowId: string, color?: string) { setRowBackgroundColor(rowId: string, color?: string) {
this.model.doc.transact(() => { this.model.store.transact(() => {
if (this.model.props.rows[rowId]) { if (this.model.props.rows[rowId]) {
this.model.props.rows[rowId].backgroundColor = color; this.model.props.rows[rowId].backgroundColor = color;
} }
@@ -222,7 +222,7 @@ export class TableDataManager {
} }
setColumnBackgroundColor(columnId: string, color?: string) { setColumnBackgroundColor(columnId: string, color?: string) {
this.model.doc.transact(() => { this.model.store.transact(() => {
if (this.model.props.columns[columnId]) { if (this.model.props.columns[columnId]) {
this.model.props.columns[columnId].backgroundColor = color; this.model.props.columns[columnId].backgroundColor = color;
} }
@@ -230,7 +230,7 @@ export class TableDataManager {
} }
setColumnWidth(columnId: string, width: number) { setColumnWidth(columnId: string, width: number) {
this.model.doc.transact(() => { this.model.store.transact(() => {
if (this.model.props.columns[columnId]) { if (this.model.props.columns[columnId]) {
this.model.props.columns[columnId].width = width; this.model.props.columns[columnId].width = width;
} }
@@ -238,7 +238,7 @@ export class TableDataManager {
} }
clearRow(rowId: string) { clearRow(rowId: string) {
this.model.doc.transact(() => { this.model.store.transact(() => {
Object.keys(this.model.props.cells).forEach(id => { Object.keys(this.model.props.cells).forEach(id => {
if (id.startsWith(rowId)) { if (id.startsWith(rowId)) {
this.model.props.cells[id]?.text.replace( this.model.props.cells[id]?.text.replace(
@@ -252,7 +252,7 @@ export class TableDataManager {
} }
clearColumn(columnId: string) { clearColumn(columnId: string) {
this.model.doc.transact(() => { this.model.store.transact(() => {
Object.keys(this.model.props.cells).forEach(id => { Object.keys(this.model.props.cells).forEach(id => {
if (id.endsWith(`:${columnId}`)) { if (id.endsWith(`:${columnId}`)) {
this.model.props.cells[id]?.text.replace( this.model.props.cells[id]?.text.replace(
@@ -290,7 +290,7 @@ export class TableDataManager {
} }
clearCells(cells: { rowId: string; columnId: string }[]) { clearCells(cells: { rowId: string; columnId: string }[]) {
this.model.doc.transact(() => { this.model.store.transact(() => {
cells.forEach(({ rowId, columnId }) => { cells.forEach(({ rowId, columnId }) => {
const text = this.model.props.cells[`${rowId}:${columnId}`]?.text; const text = this.model.props.cells[`${rowId}:${columnId}`]?.text;
if (text) { if (text) {
@@ -313,7 +313,7 @@ export class TableDataManager {
const column = columns[from]; const column = columns[from];
if (!column) return; if (!column) return;
const order = this.getOrder(columns, after); const order = this.getOrder(columns, after);
this.model.doc.transact(() => { this.model.store.transact(() => {
const realColumn = this.model.props.columns[column.columnId]; const realColumn = this.model.props.columns[column.columnId];
if (realColumn) { if (realColumn) {
realColumn.order = order; realColumn.order = order;
@@ -326,7 +326,7 @@ export class TableDataManager {
const row = rows[from]; const row = rows[from];
if (!row) return; if (!row) return;
const order = this.getOrder(rows, after); const order = this.getOrder(rows, after);
this.model.doc.transact(() => { this.model.store.transact(() => {
const realRow = this.model.props.rows[row.rowId]; const realRow = this.model.props.rows[row.rowId];
if (realRow) { if (realRow) {
realRow.order = order; realRow.order = order;
@@ -339,7 +339,7 @@ export class TableDataManager {
if (!oldColumn) return; if (!oldColumn) return;
const order = this.getOrder(this.columns$.value, index); const order = this.getOrder(this.columns$.value, index);
const newColumnId = nanoid(); const newColumnId = nanoid();
this.model.doc.transact(() => { this.model.store.transact(() => {
this.model.props.columns[newColumnId] = { this.model.props.columns[newColumnId] = {
...oldColumn, ...oldColumn,
columnId: newColumnId, columnId: newColumnId,
@@ -362,7 +362,7 @@ export class TableDataManager {
if (!oldRow) return; if (!oldRow) return;
const order = this.getOrder(this.rows$.value, index); const order = this.getOrder(this.rows$.value, index);
const newRowId = nanoid(); const newRowId = nanoid();
this.model.doc.transact(() => { this.model.store.transact(() => {
this.model.props.rows[newRowId] = { this.model.props.rows[newRowId] = {
...oldRow, ...oldRow,
rowId: newRowId, rowId: newRowId,
@@ -163,7 +163,10 @@ export class EmbedCardEditModal extends SignalWatcher(
const std = blockComponent.std; const std = blockComponent.std;
this.model.doc.updateBlock(this.model, { title: null, description: null }); this.model.store.updateBlock(this.model, {
title: null,
description: null,
});
this.onReset?.(std, blockComponent); this.onReset?.(std, blockComponent);
@@ -312,7 +312,7 @@ export class FramePanelBody extends SignalWatcher(
const after = frames[insertIndex]?.props.presentationIndex || null; const after = frames[insertIndex]?.props.presentationIndex || null;
selectedFrames.forEach(frame => { selectedFrames.forEach(frame => {
const newIndex = generateKeyBetweenV2(before, after); const newIndex = generateKeyBetweenV2(before, after);
frame.doc.updateBlock(frame, { frame.store.updateBlock(frame, {
presentationIndex: newIndex, presentationIndex: newIndex,
}); });
before = newIndex; before = newIndex;
@@ -112,7 +112,7 @@ export class FramePreview extends WithDisposable(ShadowlessElement) {
}; };
get _originalDoc() { get _originalDoc() {
return this.frame.doc; return this.frame.store;
} }
private _initPreviewDoc() { private _initPreviewDoc() {
@@ -52,7 +52,7 @@ export class OutlineBlockPreview extends SignalWatcher(
if (delta.attributes?.reference) { if (delta.attributes?.reference) {
// If linked doc, render linked doc icon and the doc title. // If linked doc, render linked doc icon and the doc title.
const refAttribute = delta.attributes.reference; const refAttribute = delta.attributes.reference;
const refMeta = block.doc.workspace.meta.docMetas.find( const refMeta = block.store.workspace.meta.docMetas.find(
doc => doc.id === refAttribute.pageId doc => doc.id === refAttribute.pageId
); );
const unavailable = !refMeta; const unavailable = !refMeta;
@@ -12,9 +12,9 @@ export const connectorWatcher: SurfaceMiddleware = (
surface: SurfaceBlockModel surface: SurfaceBlockModel
) => { ) => {
const hasElementById = (id: string) => const hasElementById = (id: string) =>
surface.hasElementById(id) || surface.doc.hasBlock(id); surface.hasElementById(id) || surface.store.hasBlock(id);
const elementGetter = (id: string) => const elementGetter = (id: string) =>
surface.getElementById(id) ?? (surface.doc.getModelById(id) as GfxModel); surface.getElementById(id) ?? (surface.store.getModelById(id) as GfxModel);
const updateConnectorPath = (connector: ConnectorElementModel) => { const updateConnectorPath = (connector: ConnectorElementModel) => {
if ( if (
((connector.source?.id && hasElementById(connector.source.id)) || ((connector.source?.id && hasElementById(connector.source.id)) ||
@@ -70,7 +70,7 @@ export const connectorWatcher: SurfaceMiddleware = (
addToUpdateList(element as ConnectorElementModel); addToUpdateList(element as ConnectorElementModel);
} }
}), }),
surface.doc.slots.blockUpdated.subscribe(payload => { surface.store.slots.blockUpdated.subscribe(payload => {
if ( if (
payload.type === 'add' || payload.type === 'add' ||
(payload.type === 'update' && payload.props.key === 'xywh') (payload.type === 'update' && payload.props.key === 'xywh')
@@ -34,7 +34,7 @@ export const mindmap: ElementRenderer<MindmapElementModel> = (
const { connector, outdated } = result; const { connector, outdated } = result;
const elementGetter = (id: string) => const elementGetter = (id: string) =>
model.surface.getElementById(id) ?? model.surface.getElementById(id) ??
(model.surface.doc.getModelById(id) as GfxModel); (model.surface.store.getModelById(id) as GfxModel);
if (outdated) { if (outdated) {
ConnectorPathGenerator.updatePath(connector, null, elementGetter); ConnectorPathGenerator.updatePath(connector, null, elementGetter);
@@ -116,7 +116,7 @@ function moveNodePosition(
) )
: (node.detail.index ?? undefined); : (node.detail.index ?? undefined);
mindmap.surface.doc.transact(() => { mindmap.surface.store.transact(() => {
const val: NodeDetail = { const val: NodeDetail = {
...node.detail, ...node.detail,
index, index,
@@ -139,7 +139,7 @@ export function applyStyle(
mindmap: MindmapElementModel, mindmap: MindmapElementModel,
shouldFitContent: boolean = false shouldFitContent: boolean = false
) { ) {
mindmap.surface.doc.transact(() => { mindmap.surface.store.transact(() => {
const style = mindmap.styleGetter; const style = mindmap.styleGetter;
if (!style) return; if (!style) return;
@@ -208,7 +208,7 @@ export function addNode(
) )
: node.detail.index; : node.detail.index;
mindmap.surface.doc.transact(() => { mindmap.surface.store.transact(() => {
mindmap.children.set(node.id, { mindmap.children.set(node.id, {
...node.detail, ...node.detail,
index, index,
@@ -281,7 +281,7 @@ export function addTree(
if (!('text' in tree)) { if (!('text' in tree)) {
// Modify the children ymap directly hence need transaction // Modify the children ymap directly hence need transaction
mindmap.surface.doc.transact(() => { mindmap.surface.store.transact(() => {
traverse(tree, parent, sibling); traverse(tree, parent, sibling);
}); });
@@ -328,7 +328,7 @@ export function detachMindmap(
subtree.children.forEach(child => traverse(child)); subtree.children.forEach(child => traverse(child));
}; };
mindmap.surface.doc.transact(() => { mindmap.surface.store.transact(() => {
traverse(subtree); traverse(subtree);
}); });
@@ -351,7 +351,7 @@ export function handleLayout(
applyStyle(mindmap, true); applyStyle(mindmap, true);
} }
mindmap.surface.doc.transact(() => { mindmap.surface.store.transact(() => {
const path = mindmap.getPath(tree.id); const path = mindmap.getPath(tree.id);
layout(tree, mindmap, layoutType ?? mindmap.getLayoutDir(tree.id), path); layout(tree, mindmap, layoutType ?? mindmap.getLayoutDir(tree.id), path);
}); });
@@ -68,7 +68,7 @@ export function drawGeneralShape(
const { blur, offsetX, offsetY, color } = shapeModel.shadow; const { blur, offsetX, offsetY, color } = shapeModel.shadow;
const scale = ctx.getTransform().a; const scale = ctx.getTransform().a;
const enableShadowBlur = shapeModel.surface.doc const enableShadowBlur = shapeModel.surface.store
.get(FeatureFlagService) .get(FeatureFlagService)
.getFlag('enable_shape_shadow_blur'); .getFlag('enable_shape_shadow_blur');
@@ -21,7 +21,7 @@ export const replaceIdMiddleware = (job: TemplateJob) => {
const { blockJson } = data; const { blockJson } = data;
const newId = regeneratedIdMap.has(blockJson.id) const newId = regeneratedIdMap.has(blockJson.id)
? regeneratedIdMap.get(blockJson.id)! ? regeneratedIdMap.get(blockJson.id)!
: job.model.doc.workspace.idGenerator(); : job.model.store.workspace.idGenerator();
if (!regeneratedIdMap.has(blockJson.id)) { if (!regeneratedIdMap.has(blockJson.id)) {
regeneratedIdMap.set(blockJson.id, newId); regeneratedIdMap.set(blockJson.id, newId);
@@ -63,7 +63,7 @@ export const replaceIdMiddleware = (job: TemplateJob) => {
}); });
blockJson.children.forEach(block => { blockJson.children.forEach(block => {
regeneratedIdMap.set(block.id, job.model.doc.workspace.idGenerator()); regeneratedIdMap.set(block.id, job.model.store.workspace.idGenerator());
}); });
defered.forEach(id => { defered.forEach(id => {
@@ -97,7 +97,7 @@ export class TemplateJob {
type: TemplateType; type: TemplateType;
constructor({ model, type, middlewares }: TemplateJobConfig) { constructor({ model, type, middlewares }: TemplateJobConfig) {
this.job = model.doc.getTransformer(); this.job = model.store.getTransformer();
this.model = model; this.model = model;
this.type = TEMPLATE_TYPES.includes(type as TemplateType) this.type = TEMPLATE_TYPES.includes(type as TemplateType)
? (type as TemplateType) ? (type as TemplateType)
@@ -118,7 +118,7 @@ export class TemplateJob {
private _getMergeBlockId(modelData: BlockSnapshot) { private _getMergeBlockId(modelData: BlockSnapshot) {
switch (modelData.flavour as MergeBlockFlavour) { switch (modelData.flavour as MergeBlockFlavour) {
case 'affine:page': case 'affine:page':
return this.model.doc.root!.id; return this.model.store.root!.id;
case 'affine:surface': case 'affine:surface':
return this.model.id; return this.model.id;
} }
@@ -174,7 +174,7 @@ export class TemplateJob {
index?: number; index?: number;
}[] }[]
) { ) {
const doc = this.model.doc; const doc = this.model.store;
const mergeIdMapping = new Map<string, string>(); const mergeIdMapping = new Map<string, string>();
const deferInserting: typeof modelDataList = []; const deferInserting: typeof modelDataList = [];
@@ -199,7 +199,7 @@ export class TemplateJob {
if (isMergeBlock) { if (isMergeBlock) {
this._mergeProps( this._mergeProps(
json, json,
this.model.doc.getModelById( this.model.store.getModelById(
this._getMergeBlockId(json) this._getMergeBlockId(json)
) as BlockModel ) as BlockModel
); );
@@ -320,12 +320,12 @@ export class TemplateJob {
from: Record<string, Record<string, unknown>>, from: Record<string, Record<string, unknown>>,
to: Y.Map<Y.Map<unknown>> to: Y.Map<Y.Map<unknown>>
) { ) {
const schema = this.model.doc.schema.get('affine:surface'); const schema = this.model.store.schema.get('affine:surface');
const surfaceTransformer = schema?.transformer?.( const surfaceTransformer = schema?.transformer?.(
new Map() new Map()
) as SurfaceBlockTransformer; ) as SurfaceBlockTransformer;
this.model.doc.transact(() => { this.model.store.transact(() => {
const defered: [string, Record<string, unknown>][] = []; const defered: [string, Record<string, unknown>][] = [];
Object.entries(from).forEach(([id, val]) => { Object.entries(from).forEach(([id, val]) => {
@@ -78,7 +78,7 @@ export class FrameBlockModel
for (const key of this.childIds) { for (const key of this.childIds) {
const element = const element =
this.surface.getElementById(key) || this.surface.getElementById(key) ||
(this.surface.doc.getModelById(key) as GfxBlockElementModel); (this.surface.store.getModelById(key) as GfxBlockElementModel);
element && elements.push(element); element && elements.push(element);
} }
@@ -99,7 +99,7 @@ export class FrameBlockModel
addChild(element: GfxModel) { addChild(element: GfxModel) {
if (!canSafeAddToContainer(this, element)) return; if (!canSafeAddToContainer(this, element)) return;
this.doc.transact(() => { this.store.transact(() => {
this.props.childElementIds = { this.props.childElementIds = {
...this.props.childElementIds, ...this.props.childElementIds,
[element.id]: true, [element.id]: true,
@@ -118,7 +118,7 @@ export class FrameBlockModel
newChildren[id] = true; newChildren[id] = true;
} }
this.doc.transact(() => { this.store.transact(() => {
this.props.childElementIds = { this.props.childElementIds = {
...this.props.childElementIds, ...this.props.childElementIds,
...newChildren, ...newChildren,
@@ -153,7 +153,7 @@ export class FrameBlockModel
} }
removeChild(element: GfxModel): void { removeChild(element: GfxModel): void {
this.doc.transact(() => { this.store.transact(() => {
this.props.childElementIds && this.props.childElementIds &&
delete this.props.childElementIds[element.id]; delete this.props.childElementIds[element.id];
}); });
@@ -14,15 +14,17 @@ export class RootBlockModel extends BlockModel<RootBlockProps> {
super(); super();
const createdSubscription = this.created.subscribe(() => { const createdSubscription = this.created.subscribe(() => {
createdSubscription.unsubscribe(); createdSubscription.unsubscribe();
this.doc.slots.rootAdded.subscribe(id => { this.store.slots.rootAdded.subscribe(id => {
const model = this.doc.getModelById(id); const model = this.store.getModelById(id);
if (model instanceof RootBlockModel) { if (model instanceof RootBlockModel) {
const newDocMeta = this.doc.workspace.meta.getDocMeta(model.doc.id); const newDocMeta = this.store.workspace.meta.getDocMeta(
model.store.id
);
if ( if (
!newDocMeta || !newDocMeta ||
newDocMeta.title !== model.props.title.toString() newDocMeta.title !== model.props.title.toString()
) { ) {
this.doc.workspace.meta.setDocMeta(model.doc.id, { this.store.workspace.meta.setDocMeta(model.store.id, {
title: model.props.title.toString(), title: model.props.title.toString(),
}); });
} }
@@ -58,7 +58,7 @@ export class GroupElementModel extends GfxGroupLikeElementModel<GroupElementProp
return; return;
} }
this.surface.doc.transact(() => { this.surface.store.transact(() => {
this.children.set(element.id, true); this.children.set(element.id, true);
}); });
} }
@@ -79,7 +79,7 @@ export class GroupElementModel extends GfxGroupLikeElementModel<GroupElementProp
if (!this.children) { if (!this.children) {
return; return;
} }
this.surface.doc.transact(() => { this.surface.store.transact(() => {
this.children.delete(element.id); this.children.delete(element.id);
}); });
} }
@@ -118,7 +118,7 @@ function watchLayoutType(
return; return;
} }
instance.surface.doc.transact(() => { instance.surface.store.transact(() => {
instance['_tree']?.children.forEach(child => { instance['_tree']?.children.forEach(child => {
if (!instance.children.has(child.id)) { if (!instance.children.has(child.id)) {
return; return;
@@ -285,7 +285,7 @@ export class MindmapElementModel extends GfxGroupLikeElementModel<MindmapElement
const type = (props.type as string) ?? 'shape'; const type = (props.type as string) ?? 'shape';
let id: string; let id: string;
this.surface.doc.transact(() => { this.surface.store.transact(() => {
const parentNode = parent ? this._nodeMap.get(parent)! : null; const parentNode = parent ? this._nodeMap.get(parent)! : null;
if (parentNode) { if (parentNode) {
@@ -433,7 +433,7 @@ export class MindmapElementModel extends GfxGroupLikeElementModel<MindmapElement
const loops = findInfiniteLoop(rootNode, mindmapNodeMap); const loops = findInfiniteLoop(rootNode, mindmapNodeMap);
if (loops.length) { if (loops.length) {
this.surface.doc.withoutTransact(() => { this.surface.store.withoutTransact(() => {
loops.forEach(loop => { loops.forEach(loop => {
if (loop.detached) { if (loop.detached) {
loop.chain.forEach(node => { loop.chain.forEach(node => {
@@ -745,7 +745,7 @@ export class MindmapElementModel extends GfxGroupLikeElementModel<MindmapElement
const offsetX = targetPos[0] - x; const offsetX = targetPos[0] - x;
const offsetY = targetPos[1] - y; const offsetY = targetPos[1] - y;
this.surface.doc.transact(() => { this.surface.store.transact(() => {
this.childElements.forEach(el => { this.childElements.forEach(el => {
const deserializedXYWH = deserializeXYWH(el.xywh); const deserializedXYWH = deserializeXYWH(el.xywh);
@@ -775,7 +775,7 @@ export class MindmapElementModel extends GfxGroupLikeElementModel<MindmapElement
removedDescendants.push(node.id); removedDescendants.push(node.id);
}; };
surface.doc.transact(() => { surface.store.transact(() => {
remove(this._nodeMap.get(element.id)!); remove(this._nodeMap.get(element.id)!);
}); });
@@ -877,7 +877,7 @@ export class MindmapElementModel extends GfxGroupLikeElementModel<MindmapElement
}; };
node.children.forEach(changeNodesVisibility); node.children.forEach(changeNodesVisibility);
this.surface.doc.transact(() => { this.surface.store.transact(() => {
this.children.set(node.id, { this.children.set(node.id, {
...node.detail, ...node.detail,
collapsed, collapsed,
@@ -921,7 +921,7 @@ export class MindmapElementModel extends GfxGroupLikeElementModel<MindmapElement
const map: Y.Map<NodeDetail> = new Y.Map(); const map: Y.Map<NodeDetail> = new Y.Map();
const surface = instance.surface; const surface = instance.surface;
const doc = surface.doc; const doc = surface.store;
const recursive = ( const recursive = (
node: NodeType, node: NodeType,
parent: string | null = null, parent: string | null = null,
@@ -18,7 +18,7 @@ export function toCode(
return; return;
} }
const doc = model.doc; const doc = model.store;
const parent = doc.getParent(model); const parent = doc.getParent(model);
if (!parent) { if (!parent) {
return; return;
@@ -80,7 +80,7 @@ export const replaceIdMiddleware =
model.props.reference = idMap.get(original)!; model.props.reference = idMap.get(original)!;
} else if ( } else if (
model.props.refFlavour === 'affine:frame' && model.props.refFlavour === 'affine:frame' &&
!model.doc.hasBlock(original) !model.store.hasBlock(original)
) { ) {
const newId = idGenerator(); const newId = idGenerator();
idMap.set(original, newId); idMap.set(original, newId);
@@ -45,7 +45,7 @@ export function calcDropTarget(
*/ */
allowSublist: boolean = true allowSublist: boolean = true
): DropTarget | null { ): DropTarget | null {
const schema = model.doc.schema.get('affine:database'); const schema = model.store.schema.get('affine:database');
const children = schema?.model.children ?? []; const children = schema?.model.children ?? [];
let shouldAppendToDatabase = true; let shouldAppendToDatabase = true;
@@ -26,7 +26,7 @@ export function getPrevContentBlock(
model: BlockModel model: BlockModel
): BlockModel | null { ): BlockModel | null {
const getPrev = (model: BlockModel) => { const getPrev = (model: BlockModel) => {
const parent = model.doc.getParent(model); const parent = model.store.getParent(model);
if (!parent) return null; if (!parent) return null;
const index = parent.children.indexOf(model); const index = parent.children.indexOf(model);
@@ -113,7 +113,7 @@ export function getNextContentBlock(
} }
map[model.id] = true; map[model.id] = true;
const doc = model.doc; const doc = model.store;
if (model.children.length) { if (model.children.length) {
return model.children[0]; return model.children[0];
} }
@@ -5,7 +5,7 @@ export function mergeToCodeModel(models: BlockModel[]) {
if (models.length === 0) { if (models.length === 0) {
return null; return null;
} }
const doc = models[0].doc; const doc = models[0].store;
const parent = doc.getParent(models[0]); const parent = doc.getParent(models[0]);
if (!parent) { if (!parent) {
@@ -5,7 +5,7 @@ export function transformModel(
flavour: string, flavour: string,
props?: Parameters<Store['addBlock']>[1] props?: Parameters<Store['addBlock']>[1]
) { ) {
const doc = model.doc; const doc = model.store;
const parent = doc.getParent(model); const parent = doc.getParent(model);
if (!parent) { if (!parent) {
return null; return null;
@@ -88,7 +88,7 @@ export class PreviewHelper {
setup(di) { setup(di) {
di.override(BlockViewIdentifier('affine:image'), () => { di.override(BlockViewIdentifier('affine:image'), () => {
return (model: BlockModel) => { return (model: BlockModel) => {
const parent = model.doc.getParent(model.id); const parent = model.store.getParent(model.id);
if (parent?.flavour === 'affine:surface') { if (parent?.flavour === 'affine:surface') {
return literal`affine-edgeless-placeholder-preview-image`; return literal`affine-edgeless-placeholder-preview-image`;
@@ -75,7 +75,7 @@ export class AffineFrameTitle extends SignalWatcher(
} }
get doc() { get doc() {
return this.model.doc; return this.model.store;
} }
get gfx() { get gfx() {
@@ -164,7 +164,7 @@ export class GfxBlockElementModel<
} }
get surface(): SurfaceBlockModel | null { get surface(): SurfaceBlockModel | null {
const result = this.doc.getBlocksByFlavour('affine:surface'); const result = this.store.getBlocksByFlavour('affine:surface');
if (result.length === 0) return null; if (result.length === 0) return null;
return result[0].model as SurfaceBlockModel; return result[0].model as SurfaceBlockModel;
} }
@@ -257,11 +257,11 @@ export class GfxBlockElementModel<
} }
lock() { lock() {
lockElementImpl(this.doc, this); lockElementImpl(this.store, this);
} }
unlock() { unlock() {
unlockElementImpl(this.doc, this); unlockElementImpl(this.store, this);
} }
} }
@@ -38,7 +38,7 @@ export function field<V, T extends GfxPrimitiveElementModel>(fallback?: V) {
if (this.yMap) { if (this.yMap) {
if (this.yMap.doc) { if (this.yMap.doc) {
this.surface.doc.transact(() => { this.surface.store.transact(() => {
this.yMap.set(prop as string, v); this.yMap.set(prop as string, v);
}); });
} else { } else {
@@ -69,7 +69,7 @@ export function field<V, T extends GfxPrimitiveElementModel>(fallback?: V) {
: convertProps(prop, originalVal, this); : convertProps(prop, originalVal, this);
if (this.yMap.doc) { if (this.yMap.doc) {
this.surface.doc.transact(() => { this.surface.store.transact(() => {
this.yMap.set(prop as string, val); this.yMap.set(prop as string, val);
}); });
} else { } else {
@@ -256,7 +256,7 @@ export abstract class GfxPrimitiveElementModel<
} }
lock() { lock() {
lockElementImpl(this.surface.doc, this); lockElementImpl(this.surface.store, this);
} }
onCreated() {} onCreated() {}
@@ -278,7 +278,7 @@ export abstract class GfxPrimitiveElementModel<
if (getFieldPropsSet(this).has(prop as string)) { if (getFieldPropsSet(this).has(prop as string)) {
if (!isEqual(value, this.yMap.get(prop as string))) { if (!isEqual(value, this.yMap.get(prop as string))) {
this.surface.doc.transact(() => { this.surface.store.transact(() => {
this.yMap.set(prop as string, value); this.yMap.set(prop as string, value);
}); });
} }
@@ -339,7 +339,7 @@ export abstract class GfxPrimitiveElementModel<
} }
unlock() { unlock() {
unlockElementImpl(this.surface.doc, this); unlockElementImpl(this.surface.store, this);
} }
@local() @local()
@@ -396,7 +396,7 @@ export abstract class GfxGroupLikeElementModel<
for (const key of this.childIds) { for (const key of this.childIds) {
const element = const element =
this.surface.getElementById(key) || this.surface.getElementById(key) ||
(this.surface.doc.getModelById(key) as GfxBlockElementModel); (this.surface.store.getModelById(key) as GfxBlockElementModel);
element && elements.push(element); element && elements.push(element);
} }
@@ -368,7 +368,7 @@ export class SurfaceBlockModel extends BlockModel<SurfaceBlockProps> {
mount(); mount();
}); });
Object.values(this.doc.blocks.peek()).forEach(block => { Object.values(this.store.blocks.peek()).forEach(block => {
if (isGfxGroupCompatibleModel(block.model)) { if (isGfxGroupCompatibleModel(block.model)) {
this._groupLikeModels.set(block.id, block.model); this._groupLikeModels.set(block.id, block.model);
} }
@@ -376,7 +376,7 @@ export class SurfaceBlockModel extends BlockModel<SurfaceBlockProps> {
elementsYMap.observe(onElementsMapChange); elementsYMap.observe(onElementsMapChange);
const subscription = this.doc.slots.blockUpdated.subscribe(payload => { const subscription = this.store.slots.blockUpdated.subscribe(payload => {
switch (payload.type) { switch (payload.type) {
case 'add': case 'add':
if (isGfxGroupCompatibleModel(payload.model)) { if (isGfxGroupCompatibleModel(payload.model)) {
@@ -468,7 +468,7 @@ export class SurfaceBlockModel extends BlockModel<SurfaceBlockProps> {
const disposables = new DisposableGroup(); const disposables = new DisposableGroup();
disposables.add(this.elementAdded.subscribe(updateIsEmpty)); disposables.add(this.elementAdded.subscribe(updateIsEmpty));
disposables.add(this.elementRemoved.subscribe(updateIsEmpty)); disposables.add(this.elementRemoved.subscribe(updateIsEmpty));
this.doc.slots.blockUpdated.subscribe(payload => { this.store.slots.blockUpdated.subscribe(payload => {
if (['add', 'delete'].includes(payload.type)) { if (['add', 'delete'].includes(payload.type)) {
updateIsEmpty(); updateIsEmpty();
} }
@@ -503,7 +503,7 @@ export class SurfaceBlockModel extends BlockModel<SurfaceBlockProps> {
addElement<T extends object = Record<string, unknown>>( addElement<T extends object = Record<string, unknown>>(
props: Partial<T> & { type: string } props: Partial<T> & { type: string }
) { ) {
if (this.doc.readonly) { if (this.store.readonly) {
throw new Error('Cannot add element in readonly mode'); throw new Error('Cannot add element in readonly mode');
} }
@@ -535,7 +535,7 @@ export class SurfaceBlockModel extends BlockModel<SurfaceBlockProps> {
this._elementModels.set(id, elementModel); this._elementModels.set(id, elementModel);
this.doc.transact(() => { this.store.transact(() => {
this.elements.getValue()!.set(id, elementModel.model.yMap); this.elements.getValue()!.set(id, elementModel.model.yMap);
}); });
@@ -552,7 +552,7 @@ export class SurfaceBlockModel extends BlockModel<SurfaceBlockProps> {
} }
deleteElement(id: string) { deleteElement(id: string) {
if (this.doc.readonly) { if (this.store.readonly) {
throw new Error('Cannot remove element in readonly mode'); throw new Error('Cannot remove element in readonly mode');
} }
@@ -560,7 +560,7 @@ export class SurfaceBlockModel extends BlockModel<SurfaceBlockProps> {
return; return;
} }
this.doc.transact(() => { this.store.transact(() => {
const element = this.getElementById(id)!; const element = this.getElementById(id)!;
const group = this.getGroup(id); const group = this.getGroup(id);
@@ -568,8 +568,8 @@ export class SurfaceBlockModel extends BlockModel<SurfaceBlockProps> {
element.childIds.forEach(childId => { element.childIds.forEach(childId => {
if (this.hasElementById(childId)) { if (this.hasElementById(childId)) {
this.deleteElement(childId); this.deleteElement(childId);
} else if (this.doc.hasBlock(childId)) { } else if (this.store.hasBlock(childId)) {
this.doc.deleteBlock(this.doc.getBlock(childId)!.model); this.store.deleteBlock(this.store.getBlock(childId)!.model);
} }
}); });
} }
@@ -610,7 +610,7 @@ export class SurfaceBlockModel extends BlockModel<SurfaceBlockProps> {
elem = elem =
typeof elem === 'string' typeof elem === 'string'
? ((this.getElementById(elem) ?? ? ((this.getElementById(elem) ??
this.doc.getBlock(elem)?.model) as GfxModel) this.store.getBlock(elem)?.model) as GfxModel)
: elem; : elem;
if (!elem) return null; if (!elem) return null;
@@ -655,7 +655,7 @@ export class SurfaceBlockModel extends BlockModel<SurfaceBlockProps> {
const el = this.getElementById(element); const el = this.getElementById(element);
if (el) return isGfxGroupCompatibleModel(el); if (el) return isGfxGroupCompatibleModel(el);
const blockModel = this.doc.getBlock(element)?.model; const blockModel = this.store.getBlock(element)?.model;
if (blockModel) return isGfxGroupCompatibleModel(blockModel); if (blockModel) return isGfxGroupCompatibleModel(blockModel);
return false; return false;
@@ -668,7 +668,7 @@ export class SurfaceBlockModel extends BlockModel<SurfaceBlockProps> {
id: string, id: string,
props: Partial<T> props: Partial<T>
) { ) {
if (this.doc.readonly) { if (this.store.readonly) {
throw new Error('Cannot update element in readonly mode'); throw new Error('Cannot update element in readonly mode');
} }
@@ -678,7 +678,7 @@ export class SurfaceBlockModel extends BlockModel<SurfaceBlockProps> {
throw new Error(`Element ${id} is not found`); throw new Error(`Element ${id} is not found`);
} }
this.doc.transact(() => { this.store.transact(() => {
props = this._propsToY( props = this._propsToY(
elementModel.type, elementModel.type,
props as Record<string, unknown> props as Record<string, unknown>
@@ -97,16 +97,16 @@ export class BlockModel<Props extends object = object> {
return this._childModels.value; return this._childModels.value;
} }
get doc() { get store() {
return this._store; return this._store;
} }
set doc(doc: Store) { set store(doc: Store) {
this._store = doc; this._store = doc;
} }
get parent() { get parent() {
return this.doc.getParent(this); return this.store.getParent(this);
} }
get role() { get role() {
@@ -63,7 +63,7 @@ export class FlatSyncController {
model.stash = this.stash; model.stash = this.stash;
model.pop = this.pop; model.pop = this.pop;
if (this.doc) { if (this.doc) {
model.doc = this.doc; model.store = this.doc;
} }
const defaultProps = schema.model.props?.(internalPrimitives); const defaultProps = schema.model.props?.(internalPrimitives);
@@ -168,7 +168,7 @@ export class SyncController {
model.stash = this.stash; model.stash = this.stash;
model.pop = this.pop; model.pop = this.pop;
if (this.doc) { if (this.doc) {
model.doc = this.doc; model.store = this.doc;
} }
const proxy = new Proxy(signalWithProps, { const proxy = new Proxy(signalWithProps, {
@@ -70,7 +70,7 @@ function getBlockViewType(query: Query, block: Block): BlockViewType {
} }
function setAncestorsToDisplayIfHidden(mode: QueryMode, block: Block) { function setAncestorsToDisplayIfHidden(mode: QueryMode, block: Block) {
const doc = block.model.doc; const doc = block.model.store;
let parent = doc.getParent(block.model); let parent = doc.getParent(block.model);
while (parent) { while (parent) {
const parentBlock = doc.getBlock(parent.id); const parentBlock = doc.getBlock(parent.id);
@@ -82,7 +82,7 @@ describe('group', () => {
}); });
const group = model.getElementById(groupId) as GroupElementModel; const group = model.getElementById(groupId) as GroupElementModel;
model.doc.transact(() => { model.store.transact(() => {
group.children.delete(id); group.children.delete(id);
group.children.delete(id2); group.children.delete(id2);
}); });
@@ -141,7 +141,7 @@ export function cleanup() {
delete (window as any).editor; delete (window as any).editor;
delete (window as any).doc; delete (window as any).store;
} }
declare global { declare global {
@@ -182,7 +182,7 @@ export class AttachmentViewerPanel extends SignalWatcher(
console.debug('connected'); console.debug('connected');
this.#state.value = State.Connected; this.#state.value = State.Connected;
const blob = await model.doc.blobSync.get(model.props.sourceId!); const blob = await model.store.blobSync.get(model.props.sourceId!);
if (!blob) return; if (!blob) return;
const buffer = await blob.arrayBuffer(); const buffer = await blob.arrayBuffer();
@@ -387,7 +387,7 @@ export function responseToExpandMindmap(host: EditorHost, ctx: AIContext) {
if (!subtree) return; if (!subtree) return;
surface.doc.transact(() => { surface.store.transact(() => {
const updateNodeSize = (node: typeof subtree) => { const updateNodeSize = (node: typeof subtree) => {
fitContent(node.element as ShapeElementModel); fitContent(node.element as ShapeElementModel);
@@ -4,7 +4,7 @@ import { literal } from 'lit/static-html.js';
export const AIChatBlockSpec: ExtensionType[] = [ export const AIChatBlockSpec: ExtensionType[] = [
BlockViewExtension('affine:embed-ai-chat', model => { BlockViewExtension('affine:embed-ai-chat', model => {
const parent = model.doc.getParent(model.id); const parent = model.store.getParent(model.id);
if (parent?.flavour === 'affine:surface') { if (parent?.flavour === 'affine:surface') {
return literal`affine-edgeless-ai-chat`; return literal`affine-edgeless-ai-chat`;
@@ -42,7 +42,7 @@ export class MindmapSurfaceBlock extends BlockComponent<SurfaceBlockModel> {
} }
private _adjustNodeWidth() { private _adjustNodeWidth() {
this.model.doc.transact(() => { this.model.store.transact(() => {
this.model.elementModels.forEach(element => { this.model.elementModels.forEach(element => {
if (element.type === 'shape') { if (element.type === 'shape') {
fitContent(element as ShapeElementModel); fitContent(element as ShapeElementModel);
@@ -74,7 +74,7 @@ export function PDFViewerEmbedded({ model }: AttachmentViewerProps) {
const canvasRef = useRef<HTMLCanvasElement>(null); const canvasRef = useRef<HTMLCanvasElement>(null);
const peek = useCallback(() => { const peek = useCallback(() => {
const target = model.doc.getBlock(model.id); const target = model.store.getBlock(model.id);
if (!target) return; if (!target) return;
peekView.open({ element: target }).catch(console.error); peekView.open({ element: target }).catch(console.error);
}, [peekView, model]); }, [peekView, model]);
@@ -10,7 +10,7 @@ export async function getAttachmentBlob(model: AttachmentBlockModel) {
return null; return null;
} }
const doc = model.doc; const doc = model.store;
let blob = await doc.blobSync.get(sourceId); let blob = await doc.blobSync.get(sourceId);
if (blob) { if (blob) {
@@ -16,7 +16,7 @@ export function patchForPDFEmbedView(reactToLit: ReactToLit): ExtensionType {
const bound = Bound.deserialize(model.props.xywh); const bound = Bound.deserialize(model.props.xywh);
bound.w = 537 + 24 + 2; bound.w = 537 + 24 + 2;
bound.h = 759 + 46 + 24 + 2; bound.h = 759 + 46 + 24 + 2;
model.doc.updateBlock(model, { model.store.updateBlock(model, {
embed: true, embed: true,
style: 'pdf', style: 'pdf',
xywh: bound.serialize(), xywh: bound.serialize(),
@@ -54,7 +54,7 @@ const ToggleButton = ({ model }: { model: EmbedSyncedDocModel }) => {
}, [model.props.preFoldHeight$, model.xywh$]); }, [model.props.preFoldHeight$, model.xywh$]);
const toggle = useCallback(() => { const toggle = useCallback(() => {
model.doc.captureSync(); model.store.captureSync();
batch(() => { batch(() => {
const { x, y, w, h } = model.elementBound; const { x, y, w, h } = model.elementBound;
@@ -55,7 +55,7 @@ const EdgelessNoteToggleButton = ({ note }: { note: NoteBlockModel }) => {
const dispose = selection.slots.updated.subscribe(() => { const dispose = selection.slots.updated.subscribe(() => {
if (selection.has(note.id) && selection.editing) { if (selection.has(note.id) && selection.editing) {
note.doc.transact(() => { note.store.transact(() => {
note.props.edgeless.collapse = false; note.props.edgeless.collapse = false;
}); });
} }
@@ -68,7 +68,7 @@ const EdgelessNoteToggleButton = ({ note }: { note: NoteBlockModel }) => {
track.edgeless.pageBlock.headerToolbar.toggle({ track.edgeless.pageBlock.headerToolbar.toggle({
type: collapsed ? 'expand' : 'collapse', type: collapsed ? 'expand' : 'collapse',
}); });
note.doc.transact(() => { note.store.transact(() => {
if (collapsed) { if (collapsed) {
note.props.edgeless.collapse = false; note.props.edgeless.collapse = false;
} else { } else {
@@ -134,7 +134,7 @@ const PageBlockInfoButton = ({ note }: { note: NoteBlockModel }) => {
return ( return (
<DocInfoButton <DocInfoButton
docId={note.doc.id} docId={note.store.id}
trackFn={trackFn} trackFn={trackFn}
data-testid="edgeless-note-info-button" data-testid="edgeless-note-info-button"
/> />
@@ -148,7 +148,7 @@ const NoteCopyLinkButton = ({ note }: { note: NoteBlockModel }) => {
return ( return (
<CopyLinkButton <CopyLinkButton
pageId={note.doc.id} pageId={note.store.id}
blockId={note.id} blockId={note.id}
mode="edgeless" mode="edgeless"
trackFn={trackFn} trackFn={trackFn}
@@ -26,11 +26,13 @@ export function patchForEdgelessNoteConfig(
reactToLit(<EdgelessNoteHeader note={note} />), reactToLit(<EdgelessNoteHeader note={note} />),
pageBlockTitle: ({ note }) => { pageBlockTitle: ({ note }) => {
const journalService = framework.get(JournalService); const journalService = framework.get(JournalService);
const isJournal = !!journalService.journalDate$(note.doc.id).value; const isJournal = !!journalService.journalDate$(note.store.id).value;
if (isJournal) { if (isJournal) {
return reactToLit(<BlocksuiteEditorJournalDocTitle page={note.doc} />); return reactToLit(
<BlocksuiteEditorJournalDocTitle page={note.store} />
);
} else { } else {
return html`<doc-title .doc=${note.doc}></doc-title>`; return html`<doc-title .doc=${note.store}></doc-title>`;
} }
}, },
pageBlockViewportFitAnimation: insidePeekView pageBlockViewportFitAnimation: insidePeekView
@@ -42,7 +42,7 @@ function createCopyLinkToBlockMenuItem(
}, },
select: () => { select: () => {
const serverService = framework.get(ServerService); const serverService = framework.get(ServerService);
const pageId = model.doc.id; const pageId = model.store.id;
const { editor } = framework.get(EditorService); const { editor } = framework.get(EditorService);
const mode = editor.mode$.value; const mode = editor.mode$.value;
@@ -66,7 +66,7 @@ export class AudioAttachmentBlock extends Entity<AttachmentBlockModel> {
computed(() => { computed(() => {
// find the last transcription block // find the last transcription block
for (const key of [...this.props.childMap.value.keys()].reverse()) { for (const key of [...this.props.childMap.value.keys()].reverse()) {
const block = this.props.doc.getBlock$(key); const block = this.props.store.getBlock$(key);
if (block?.flavour === TranscriptionBlockFlavour) { if (block?.flavour === TranscriptionBlockFlavour) {
return block.model as unknown as TranscriptionBlockModel; return block.model as unknown as TranscriptionBlockModel;
} }
@@ -113,7 +113,7 @@ export class AudioAttachmentBlock extends Entity<AttachmentBlockModel> {
if (!transcriptionBlockProps) { if (!transcriptionBlockProps) {
// transcription block is not created yet, we need to create it // transcription block is not created yet, we need to create it
this.props.doc.addBlock( this.props.store.addBlock(
'affine:transcription', 'affine:transcription',
{ {
transcription: {}, transcription: {},
@@ -179,14 +179,14 @@ export class AudioAttachmentBlock extends Entity<AttachmentBlockModel> {
title: string, title: string,
collapsed: boolean = false collapsed: boolean = false
) => { ) => {
const calloutId = this.props.doc.addBlock( const calloutId = this.props.store.addBlock(
'affine:callout', 'affine:callout',
{ {
emoji, emoji,
}, },
this.transcriptionBlock$.value?.id this.transcriptionBlock$.value?.id
); );
this.props.doc.addBlock( this.props.store.addBlock(
'affine:paragraph', 'affine:paragraph',
{ {
type: 'h6', type: 'h6',
@@ -223,7 +223,7 @@ export class AudioAttachmentBlock extends Entity<AttachmentBlockModel> {
insert: ': ' + sanitizeText(segment.transcription), insert: ': ' + sanitizeText(segment.transcription),
}, },
]; ];
this.props.doc.addBlock( this.props.store.addBlock(
'affine:paragraph', 'affine:paragraph',
{ {
text: new Text(deltaInserts), text: new Text(deltaInserts),
@@ -238,7 +238,7 @@ export class AudioAttachmentBlock extends Entity<AttachmentBlockModel> {
await insertFromMarkdown( await insertFromMarkdown(
undefined, undefined,
summary, summary,
this.props.doc, this.props.store,
calloutId, calloutId,
1 1
); );
@@ -252,7 +252,7 @@ export class AudioAttachmentBlock extends Entity<AttachmentBlockModel> {
await insertFromMarkdown( await insertFromMarkdown(
undefined, undefined,
actions ?? '', actions ?? '',
this.props.doc, this.props.store,
calloutId, calloutId,
1 1
); );
@@ -28,8 +28,8 @@ export class AudioAttachmentService extends Service {
const key = attachmentBlockAudioMediaKey({ const key = attachmentBlockAudioMediaKey({
blobId: model.props.sourceId, blobId: model.props.sourceId,
blockId: model.id, blockId: model.id,
docId: model.doc.id, docId: model.store.id,
workspaceId: model.doc.rootDoc.guid, workspaceId: model.store.rootDoc.guid,
}); });
let exists = this.pool.get(key); let exists = this.pool.get(key);
if (!exists) { if (!exists) {
@@ -308,8 +308,8 @@ export class AudioMediaManagerService extends Service {
key: attachmentBlockAudioMediaKey({ key: attachmentBlockAudioMediaKey({
blobId: input.props.sourceId, blobId: input.props.sourceId,
blockId: input.id, blockId: input.id,
docId: input.doc.id, docId: input.store.id,
workspaceId: input.doc.rootDoc.guid, workspaceId: input.store.rootDoc.guid,
}), }),
name: input.props.name, name: input.props.name,
size: input.props.size, size: input.props.size,
@@ -60,7 +60,7 @@ export async function downloadBlobToBuffer(model: AttachmentBlockModel) {
throw new Error('Attachment not found'); throw new Error('Attachment not found');
} }
const blob = await model.doc.blobSync.get(sourceId); const blob = await model.store.blobSync.get(sourceId);
if (!blob) { if (!blob) {
throw new Error('Attachment not found'); throw new Error('Attachment not found');
} }
@@ -165,7 +165,7 @@ function resolvePeekInfoFromPeekTarget(
// refModel can be null if the reference is invalid // refModel can be null if the reference is invalid
if (refModel) { if (refModel) {
const docId = const docId =
'doc' in refModel ? refModel.doc.id : refModel.surface.doc.id; 'store' in refModel ? refModel.store.id : refModel.surface.store.id;
return { return {
type: 'doc', type: 'doc',
docRef: { docRef: {
@@ -179,7 +179,7 @@ function resolvePeekInfoFromPeekTarget(
return { return {
type: 'attachment', type: 'attachment',
docRef: { docRef: {
docId: blockModel.doc.id, docId: blockModel.store.id,
blockIds: [blockModel.id], blockIds: [blockModel.id],
filetype: blockModel.props.type, filetype: blockModel.props.type,
}, },
@@ -188,7 +188,7 @@ function resolvePeekInfoFromPeekTarget(
return { return {
type: 'image', type: 'image',
docRef: { docRef: {
docId: blockModel.doc.id, docId: blockModel.store.id,
blockIds: [blockModel.id], blockIds: [blockModel.id],
}, },
}; };
@@ -196,7 +196,7 @@ function resolvePeekInfoFromPeekTarget(
return { return {
type: 'ai-chat-block', type: 'ai-chat-block',
docRef: { docRef: {
docId: blockModel.doc.id, docId: blockModel.store.id,
blockIds: [blockModel.id], blockIds: [blockModel.id],
}, },
model: blockModel, model: blockModel,
@@ -362,7 +362,7 @@ const ImagePreviewModalImpl = ({
index, index,
url: blobUrl, url: blobUrl,
caption: blockModel.props.caption, caption: blockModel.props.caption,
onDelete: !blockModel.doc.readonly onDelete: !blockModel.store.readonly
? () => { ? () => {
handleDelete(); handleDelete();
} }
+2 -2
View File
@@ -440,7 +440,7 @@ export async function assertParentBlockId(
if (!model) { if (!model) {
throw new Error(`Block with id ${blockId} not found`); throw new Error(`Block with id ${blockId} not found`);
} }
return model.doc.getParent(model)?.id; return model.store.getParent(model)?.id;
}, },
{ blockId } { blockId }
); );
@@ -458,7 +458,7 @@ export async function assertParentBlockFlavour(
if (!model) { if (!model) {
throw new Error(`Block with id ${blockId} not found`); throw new Error(`Block with id ${blockId} not found`);
} }
return model.doc.getParent(model)?.flavour; return model.store.getParent(model)?.flavour;
}, },
{ blockId } { blockId }
); );