refactor(core): move block collection to affine and implement as doc (#9514)
This commit is contained in:
@@ -167,7 +167,7 @@ export class BlockQueryDataSource extends DataSourceBase {
|
|||||||
type ?? propertyPresets.multiSelectPropertyConfig.type
|
type ?? propertyPresets.multiSelectPropertyConfig.type
|
||||||
].create(this.newColumnName());
|
].create(this.newColumnName());
|
||||||
|
|
||||||
const id = doc.generateBlockId();
|
const id = doc.collection.idGenerator();
|
||||||
if (this.block.columns.some(v => v.id === id)) {
|
if (this.block.columns.some(v => v.id === id)) {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ export class DataViewBlockModel extends BlockModel<Props> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
duplicateView(id: string): string {
|
duplicateView(id: string): string {
|
||||||
const newId = this.doc.generateBlockId();
|
const newId = this.doc.collection.idGenerator();
|
||||||
this.doc.transact(() => {
|
this.doc.transact(() => {
|
||||||
const index = this.views.findIndex(v => v.id === id);
|
const index = this.views.findIndex(v => v.id === id);
|
||||||
const view = this.views[index];
|
const view = this.views[index];
|
||||||
|
|||||||
@@ -448,7 +448,7 @@ export const databaseViewInitTemplate = (
|
|||||||
const rowId = model.doc.addBlock(
|
const rowId = model.doc.addBlock(
|
||||||
'affine:paragraph',
|
'affine:paragraph',
|
||||||
{
|
{
|
||||||
text: new model.doc.Text(`Task ${i + 1}`),
|
text: new Text(`Task ${i + 1}`),
|
||||||
},
|
},
|
||||||
model.id
|
model.id
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export function addProperty(
|
|||||||
id?: string;
|
id?: string;
|
||||||
}
|
}
|
||||||
): string {
|
): string {
|
||||||
const id = column.id ?? model.doc.generateBlockId();
|
const id = column.id ?? model.doc.collection.idGenerator();
|
||||||
if (model.columns.some(v => v.id === id)) {
|
if (model.columns.some(v => v.id === id)) {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
@@ -101,7 +101,7 @@ export function deleteView(model: DatabaseBlockModel, id: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function duplicateView(model: DatabaseBlockModel, id: string): string {
|
export function duplicateView(model: DatabaseBlockModel, id: string): string {
|
||||||
const newId = model.doc.generateBlockId();
|
const newId = model.doc.collection.idGenerator();
|
||||||
model.doc.transact(() => {
|
model.doc.transact(() => {
|
||||||
const index = model.views.findIndex(v => v.id === id);
|
const index = model.views.findIndex(v => v.id === id);
|
||||||
const view = model.views[index];
|
const view = model.views[index];
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import {
|
|||||||
type DraftModel,
|
type DraftModel,
|
||||||
type Query,
|
type Query,
|
||||||
Slice,
|
Slice,
|
||||||
|
Text,
|
||||||
} from '@blocksuite/store';
|
} from '@blocksuite/store';
|
||||||
import { render, type TemplateResult } from 'lit';
|
import { render, type TemplateResult } from 'lit';
|
||||||
|
|
||||||
@@ -407,7 +408,7 @@ export function createLinkedDocFromSlice(
|
|||||||
const linkedDoc = doc.collection.createDoc({});
|
const linkedDoc = doc.collection.createDoc({});
|
||||||
linkedDoc.load(() => {
|
linkedDoc.load(() => {
|
||||||
const rootId = linkedDoc.addBlock('affine:page', {
|
const rootId = linkedDoc.addBlock('affine:page', {
|
||||||
title: new doc.Text(docTitle),
|
title: new Text(docTitle),
|
||||||
});
|
});
|
||||||
linkedDoc.addBlock('affine:surface', {}, rootId);
|
linkedDoc.addBlock('affine:surface', {}, rootId);
|
||||||
const noteId = linkedDoc.addBlock('affine:note', {}, rootId);
|
const noteId = linkedDoc.addBlock('affine:note', {}, rootId);
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import {
|
|||||||
referenceToNode,
|
referenceToNode,
|
||||||
} from '@blocksuite/affine-shared/utils';
|
} from '@blocksuite/affine-shared/utils';
|
||||||
import { Bound, throttle } from '@blocksuite/global/utils';
|
import { Bound, throttle } from '@blocksuite/global/utils';
|
||||||
|
import { Text } from '@blocksuite/store';
|
||||||
import { computed } from '@preact/signals-core';
|
import { computed } from '@preact/signals-core';
|
||||||
import { html, nothing } from 'lit';
|
import { html, nothing } from 'lit';
|
||||||
import { property, queryAsync, state } from 'lit/decorators.js';
|
import { property, queryAsync, state } from 'lit/decorators.js';
|
||||||
@@ -171,7 +172,7 @@ export class EmbedLinkedDocBlockComponent extends EmbedBlockComponent<EmbedLinke
|
|||||||
...this.referenceInfo$.peek(),
|
...this.referenceInfo$.peek(),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const text = new doc.Text(yText);
|
const text = new Text(yText);
|
||||||
|
|
||||||
doc.addBlock(
|
doc.addBlock(
|
||||||
'affine:paragraph',
|
'affine:paragraph',
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import {
|
|||||||
BlockViewType,
|
BlockViewType,
|
||||||
type GetDocOptions,
|
type GetDocOptions,
|
||||||
type Query,
|
type Query,
|
||||||
|
Text,
|
||||||
} from '@blocksuite/store';
|
} from '@blocksuite/store';
|
||||||
import { computed } from '@preact/signals-core';
|
import { computed } from '@preact/signals-core';
|
||||||
import { html, type PropertyValues } from 'lit';
|
import { html, type PropertyValues } from 'lit';
|
||||||
@@ -280,7 +281,7 @@ export class EmbedSyncedDocBlockComponent extends EmbedBlockComponent<EmbedSynce
|
|||||||
...this.referenceInfo,
|
...this.referenceInfo,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const text = new doc.Text(yText);
|
const text = new Text(yText);
|
||||||
|
|
||||||
doc.addBlock(
|
doc.addBlock(
|
||||||
'affine:paragraph',
|
'affine:paragraph',
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { focusTextModel } from '@blocksuite/affine-components/rich-text';
|
import { focusTextModel } from '@blocksuite/affine-components/rich-text';
|
||||||
import { getLastNoteBlock } from '@blocksuite/affine-shared/utils';
|
import { getLastNoteBlock } from '@blocksuite/affine-shared/utils';
|
||||||
import type { Command } from '@blocksuite/block-std';
|
import type { Command } from '@blocksuite/block-std';
|
||||||
|
import { Text } from '@blocksuite/store';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Append a paragraph block at the end of the whole page.
|
* Append a paragraph block at the end of the whole page.
|
||||||
@@ -19,11 +20,7 @@ export const appendParagraphCommand: Command<
|
|||||||
if (!noteId) {
|
if (!noteId) {
|
||||||
noteId = doc.addBlock('affine:note', {}, doc.root.id);
|
noteId = doc.addBlock('affine:note', {}, doc.root.id);
|
||||||
}
|
}
|
||||||
const id = doc.addBlock(
|
const id = doc.addBlock('affine:paragraph', { text: new Text(text) }, noteId);
|
||||||
'affine:paragraph',
|
|
||||||
{ text: new doc.Text(text) },
|
|
||||||
noteId
|
|
||||||
);
|
|
||||||
|
|
||||||
focusTextModel(std, id, text.length);
|
focusTextModel(std, id, text.length);
|
||||||
next();
|
next();
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import type { Workspace } from '@blocksuite/store';
|
import type { Workspace } from '@blocksuite/store';
|
||||||
|
import { Text } from '@blocksuite/store';
|
||||||
|
|
||||||
export function createDefaultDoc(
|
export function createDefaultDoc(
|
||||||
collection: Workspace,
|
collection: Workspace,
|
||||||
@@ -9,7 +10,7 @@ export function createDefaultDoc(
|
|||||||
doc.load();
|
doc.load();
|
||||||
const title = options.title ?? '';
|
const title = options.title ?? '';
|
||||||
const rootId = doc.addBlock('affine:page', {
|
const rootId = doc.addBlock('affine:page', {
|
||||||
title: new doc.Text(title),
|
title: new Text(title),
|
||||||
});
|
});
|
||||||
collection.meta.setDocMeta(doc.id, {
|
collection.meta.setDocMeta(doc.id, {
|
||||||
title,
|
title,
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import {
|
|||||||
} from '@blocksuite/affine-model';
|
} from '@blocksuite/affine-model';
|
||||||
import { propertyModelPresets } from '@blocksuite/data-view/property-pure-presets';
|
import { propertyModelPresets } from '@blocksuite/data-view/property-pure-presets';
|
||||||
import type { BlockModel, Blocks } from '@blocksuite/store';
|
import type { BlockModel, Blocks } from '@blocksuite/store';
|
||||||
import { Schema } from '@blocksuite/store';
|
import { Schema, Text } from '@blocksuite/store';
|
||||||
import {
|
import {
|
||||||
createAutoIncrementIdGenerator,
|
createAutoIncrementIdGenerator,
|
||||||
TestWorkspace,
|
TestWorkspace,
|
||||||
@@ -71,7 +71,7 @@ describe('DatabaseManager', () => {
|
|||||||
doc = createTestDoc();
|
doc = createTestDoc();
|
||||||
|
|
||||||
rootId = doc.addBlock('affine:page', {
|
rootId = doc.addBlock('affine:page', {
|
||||||
title: new doc.Text('database test'),
|
title: new Text('database test'),
|
||||||
});
|
});
|
||||||
noteBlockId = doc.addBlock('affine:note', {}, rootId);
|
noteBlockId = doc.addBlock('affine:note', {}, rootId);
|
||||||
|
|
||||||
@@ -114,14 +114,14 @@ describe('DatabaseManager', () => {
|
|||||||
p1 = doc.addBlock(
|
p1 = doc.addBlock(
|
||||||
'affine:paragraph',
|
'affine:paragraph',
|
||||||
{
|
{
|
||||||
text: new doc.Text('text1'),
|
text: new Text('text1'),
|
||||||
},
|
},
|
||||||
databaseBlockId
|
databaseBlockId
|
||||||
);
|
);
|
||||||
p2 = doc.addBlock(
|
p2 = doc.addBlock(
|
||||||
'affine:paragraph',
|
'affine:paragraph',
|
||||||
{
|
{
|
||||||
text: new doc.Text('text2'),
|
text: new Text('text2'),
|
||||||
},
|
},
|
||||||
databaseBlockId
|
databaseBlockId
|
||||||
);
|
);
|
||||||
@@ -173,7 +173,7 @@ describe('DatabaseManager', () => {
|
|||||||
const modelId = doc.addBlock(
|
const modelId = doc.addBlock(
|
||||||
'affine:paragraph',
|
'affine:paragraph',
|
||||||
{
|
{
|
||||||
text: new doc.Text('paragraph'),
|
text: new Text('paragraph'),
|
||||||
},
|
},
|
||||||
noteBlockId
|
noteBlockId
|
||||||
);
|
);
|
||||||
@@ -201,7 +201,7 @@ describe('DatabaseManager', () => {
|
|||||||
const newRowId = doc.addBlock(
|
const newRowId = doc.addBlock(
|
||||||
'affine:paragraph',
|
'affine:paragraph',
|
||||||
{
|
{
|
||||||
text: new doc.Text('text3'),
|
text: new Text('text3'),
|
||||||
},
|
},
|
||||||
databaseBlockId
|
databaseBlockId
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { DocModeProvider } from '@blocksuite/affine-shared/services';
|
|||||||
import { getBlockProps } from '@blocksuite/affine-shared/utils';
|
import { getBlockProps } from '@blocksuite/affine-shared/utils';
|
||||||
import type { EditorHost } from '@blocksuite/block-std';
|
import type { EditorHost } from '@blocksuite/block-std';
|
||||||
import { GfxBlockElementModel } from '@blocksuite/block-std/gfx';
|
import { GfxBlockElementModel } from '@blocksuite/block-std/gfx';
|
||||||
import { type BlockModel, type Blocks } from '@blocksuite/store';
|
import { type BlockModel, type Blocks, Text } from '@blocksuite/store';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getElementProps,
|
getElementProps,
|
||||||
@@ -43,7 +43,7 @@ export function createLinkedDocFromNote(
|
|||||||
const linkedDoc = doc.collection.createDoc({});
|
const linkedDoc = doc.collection.createDoc({});
|
||||||
linkedDoc.load(() => {
|
linkedDoc.load(() => {
|
||||||
const rootId = linkedDoc.addBlock('affine:page', {
|
const rootId = linkedDoc.addBlock('affine:page', {
|
||||||
title: new doc.Text(docTitle),
|
title: new Text(docTitle),
|
||||||
});
|
});
|
||||||
linkedDoc.addBlock('affine:surface', {}, rootId);
|
linkedDoc.addBlock('affine:surface', {}, rootId);
|
||||||
const blockProps = getBlockProps(note);
|
const blockProps = getBlockProps(note);
|
||||||
@@ -74,7 +74,7 @@ export function createLinkedDocFromEdgelessElements(
|
|||||||
const linkedDoc = host.doc.collection.createDoc({});
|
const linkedDoc = host.doc.collection.createDoc({});
|
||||||
linkedDoc.load(() => {
|
linkedDoc.load(() => {
|
||||||
const rootId = linkedDoc.addBlock('affine:page', {
|
const rootId = linkedDoc.addBlock('affine:page', {
|
||||||
title: new host.doc.Text(docTitle),
|
title: new Text(docTitle),
|
||||||
});
|
});
|
||||||
const surfaceId = linkedDoc.addBlock('affine:surface', {}, rootId);
|
const surfaceId = linkedDoc.addBlock('affine:surface', {}, rootId);
|
||||||
const surface = getSurfaceBlock(linkedDoc);
|
const surface = getSurfaceBlock(linkedDoc);
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ import {
|
|||||||
} from '@blocksuite/affine-shared/services';
|
} from '@blocksuite/affine-shared/services';
|
||||||
import { getHostName, referenceToNode } from '@blocksuite/affine-shared/utils';
|
import { getHostName, referenceToNode } from '@blocksuite/affine-shared/utils';
|
||||||
import { type BlockStdScope, WidgetComponent } from '@blocksuite/block-std';
|
import { type BlockStdScope, WidgetComponent } from '@blocksuite/block-std';
|
||||||
import { type BlockModel } from '@blocksuite/store';
|
import { type BlockModel, Text } from '@blocksuite/store';
|
||||||
import { autoUpdate, computePosition, flip, offset } from '@floating-ui/dom';
|
import { autoUpdate, computePosition, flip, offset } from '@floating-ui/dom';
|
||||||
import { html, nothing, type TemplateResult } from 'lit';
|
import { html, nothing, type TemplateResult } from 'lit';
|
||||||
import { query, state } from 'lit/decorators.js';
|
import { query, state } from 'lit/decorators.js';
|
||||||
@@ -619,7 +619,7 @@ export class EmbedCardToolbar extends WidgetComponent<
|
|||||||
const insert = title || caption || url;
|
const insert = title || caption || url;
|
||||||
yText.insert(0, insert);
|
yText.insert(0, insert);
|
||||||
yText.format(0, insert.length, { link: url });
|
yText.format(0, insert.length, { link: url });
|
||||||
const text = new doc.Text(yText);
|
const text = new Text(yText);
|
||||||
doc.addBlock(
|
doc.addBlock(
|
||||||
'affine:paragraph',
|
'affine:paragraph',
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -709,9 +709,7 @@ export const defaultSlashMenuConfig: SlashMenuConfig = {
|
|||||||
model.flavour as never,
|
model.flavour as never,
|
||||||
{
|
{
|
||||||
type: (model as ParagraphBlockModel).type,
|
type: (model as ParagraphBlockModel).type,
|
||||||
text: new rootComponent.doc.Text(
|
text: new Text(model.text.toDelta() as DeltaInsert[]),
|
||||||
model.text.toDelta() as DeltaInsert[]
|
|
||||||
),
|
|
||||||
// @ts-expect-error FIXME: ts error
|
// @ts-expect-error FIXME: ts error
|
||||||
checked: model.checked,
|
checked: model.checked,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { applyUpdate, encodeStateAsUpdate } from 'yjs';
|
|||||||
import { COLLECTION_VERSION, PAGE_VERSION } from '../consts.js';
|
import { COLLECTION_VERSION, PAGE_VERSION } from '../consts.js';
|
||||||
import type { BlockModel, Blocks, BlockSchemaType } from '../index.js';
|
import type { BlockModel, Blocks, BlockSchemaType } from '../index.js';
|
||||||
import { Schema } from '../index.js';
|
import { Schema } from '../index.js';
|
||||||
|
import { Text } from '../reactive/text.js';
|
||||||
import type { DocMeta } from '../store/workspace.js';
|
import type { DocMeta } from '../store/workspace.js';
|
||||||
import { TestWorkspace } from '../test/test-workspace.js';
|
import { TestWorkspace } from '../test/test-workspace.js';
|
||||||
import { createAutoIncrementIdGenerator } from '../utils/id-generator.js';
|
import { createAutoIncrementIdGenerator } from '../utils/id-generator.js';
|
||||||
@@ -166,7 +167,7 @@ describe('basic', () => {
|
|||||||
|
|
||||||
doc.load(() => {
|
doc.load(() => {
|
||||||
const rootId = doc.addBlock('affine:page', {
|
const rootId = doc.addBlock('affine:page', {
|
||||||
title: new doc.Text(),
|
title: new Text(),
|
||||||
});
|
});
|
||||||
expect(rootAddedCallback).toBeCalledTimes(1);
|
expect(rootAddedCallback).toBeCalledTimes(1);
|
||||||
|
|
||||||
@@ -186,7 +187,7 @@ describe('basic', () => {
|
|||||||
});
|
});
|
||||||
doc.load(() => {
|
doc.load(() => {
|
||||||
doc.addBlock('affine:page', {
|
doc.addBlock('affine:page', {
|
||||||
title: new doc.Text(),
|
title: new Text(),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
{
|
{
|
||||||
@@ -245,7 +246,7 @@ describe('addBlock', () => {
|
|||||||
it('can add single model', () => {
|
it('can add single model', () => {
|
||||||
const doc = createTestDoc();
|
const doc = createTestDoc();
|
||||||
doc.addBlock('affine:page', {
|
doc.addBlock('affine:page', {
|
||||||
title: new doc.Text(),
|
title: new Text(),
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.deepEqual(serializCollection(doc.rootDoc).spaces[spaceId].blocks, {
|
assert.deepEqual(serializCollection(doc.rootDoc).spaces[spaceId].blocks, {
|
||||||
@@ -264,7 +265,7 @@ describe('addBlock', () => {
|
|||||||
|
|
||||||
it('can add model with props', () => {
|
it('can add model with props', () => {
|
||||||
const doc = createTestDoc();
|
const doc = createTestDoc();
|
||||||
doc.addBlock('affine:page', { title: new doc.Text('hello') });
|
doc.addBlock('affine:page', { title: new Text('hello') });
|
||||||
|
|
||||||
assert.deepEqual(serializCollection(doc.rootDoc).spaces[spaceId].blocks, {
|
assert.deepEqual(serializCollection(doc.rootDoc).spaces[spaceId].blocks, {
|
||||||
'0': {
|
'0': {
|
||||||
@@ -283,7 +284,7 @@ describe('addBlock', () => {
|
|||||||
it('can add multi models', () => {
|
it('can add multi models', () => {
|
||||||
const doc = createTestDoc();
|
const doc = createTestDoc();
|
||||||
const rootId = doc.addBlock('affine:page', {
|
const rootId = doc.addBlock('affine:page', {
|
||||||
title: new doc.Text(),
|
title: new Text(),
|
||||||
});
|
});
|
||||||
const noteId = doc.addBlock('affine:note', {}, rootId);
|
const noteId = doc.addBlock('affine:note', {}, rootId);
|
||||||
doc.addBlock('affine:paragraph', {}, noteId);
|
doc.addBlock('affine:paragraph', {}, noteId);
|
||||||
@@ -344,7 +345,7 @@ describe('addBlock', () => {
|
|||||||
|
|
||||||
queueMicrotask(() =>
|
queueMicrotask(() =>
|
||||||
doc.addBlock('affine:page', {
|
doc.addBlock('affine:page', {
|
||||||
title: new doc.Text(),
|
title: new Text(),
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
const blockId = await waitOnce(doc.slots.rootAdded);
|
const blockId = await waitOnce(doc.slots.rootAdded);
|
||||||
@@ -389,7 +390,7 @@ describe('addBlock', () => {
|
|||||||
assert.equal(collection.docs.size, 2);
|
assert.equal(collection.docs.size, 2);
|
||||||
|
|
||||||
doc0.addBlock('affine:page', {
|
doc0.addBlock('affine:page', {
|
||||||
title: new doc0.Text(),
|
title: new Text(),
|
||||||
});
|
});
|
||||||
collection.removeDoc(doc0.id);
|
collection.removeDoc(doc0.id);
|
||||||
|
|
||||||
|
|||||||
@@ -5,15 +5,15 @@ import { signal } from '@preact/signals-core';
|
|||||||
import type { BlockModel, Schema } from '../../schema/index.js';
|
import type { BlockModel, Schema } from '../../schema/index.js';
|
||||||
import type { DraftModel } from '../../transformer/index.js';
|
import type { DraftModel } from '../../transformer/index.js';
|
||||||
import { syncBlockProps } from '../../utils/utils.js';
|
import { syncBlockProps } from '../../utils/utils.js';
|
||||||
|
import type { BlockProps, Doc } from '../workspace.js';
|
||||||
import type { BlockOptions } from './block/index.js';
|
import type { BlockOptions } from './block/index.js';
|
||||||
import { Block } from './block/index.js';
|
import { Block } from './block/index.js';
|
||||||
import type { BlockCollection, BlockProps } from './block-collection.js';
|
|
||||||
import { DocCRUD } from './crud.js';
|
import { DocCRUD } from './crud.js';
|
||||||
import { type Query, runQuery } from './query.js';
|
import { type Query, runQuery } from './query.js';
|
||||||
|
|
||||||
type DocOptions = {
|
type DocOptions = {
|
||||||
schema: Schema;
|
schema: Schema;
|
||||||
blockCollection: BlockCollection;
|
blockCollection: Doc;
|
||||||
readonly?: boolean;
|
readonly?: boolean;
|
||||||
query?: Query;
|
query?: Query;
|
||||||
};
|
};
|
||||||
@@ -23,7 +23,7 @@ export class Blocks {
|
|||||||
runQuery(this._query, block);
|
runQuery(this._query, block);
|
||||||
};
|
};
|
||||||
|
|
||||||
protected readonly _blockCollection: BlockCollection;
|
protected readonly _blockCollection: Doc;
|
||||||
|
|
||||||
protected readonly _blocks = signal<Record<string, Block>>({});
|
protected readonly _blocks = signal<Record<string, Block>>({});
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ export class Blocks {
|
|||||||
|
|
||||||
protected readonly _schema: Schema;
|
protected readonly _schema: Schema;
|
||||||
|
|
||||||
readonly slots: BlockCollection['slots'] & {
|
readonly slots: Doc['slots'] & {
|
||||||
/** This is always triggered after `doc.load` is called. */
|
/** This is always triggered after `doc.load` is called. */
|
||||||
ready: Slot;
|
ready: Slot;
|
||||||
/**
|
/**
|
||||||
@@ -179,10 +179,6 @@ export class Blocks {
|
|||||||
return this._blockCollection.collection;
|
return this._blockCollection.collection;
|
||||||
}
|
}
|
||||||
|
|
||||||
get generateBlockId() {
|
|
||||||
return this._blockCollection.generateBlockId.bind(this._blockCollection);
|
|
||||||
}
|
|
||||||
|
|
||||||
get history() {
|
get history() {
|
||||||
return this._blockCollection.history;
|
return this._blockCollection.history;
|
||||||
}
|
}
|
||||||
@@ -250,10 +246,6 @@ export class Blocks {
|
|||||||
return this._blockCollection.spaceDoc;
|
return this._blockCollection.spaceDoc;
|
||||||
}
|
}
|
||||||
|
|
||||||
get Text() {
|
|
||||||
return this._blockCollection.Text;
|
|
||||||
}
|
|
||||||
|
|
||||||
get transact() {
|
get transact() {
|
||||||
return this._blockCollection.transact.bind(this._blockCollection);
|
return this._blockCollection.transact.bind(this._blockCollection);
|
||||||
}
|
}
|
||||||
@@ -432,7 +424,7 @@ export class Blocks {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const id = blockProps.id ?? this._blockCollection.generateBlockId();
|
const id = blockProps.id ?? this._blockCollection.collection.idGenerator();
|
||||||
|
|
||||||
this.transact(() => {
|
this.transact(() => {
|
||||||
this._crud.addBlock(
|
this._crud.addBlock(
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
export * from './block/index.js';
|
export * from './block/index.js';
|
||||||
export * from './block-collection.js';
|
|
||||||
export * from './consts.js';
|
export * from './consts.js';
|
||||||
export * from './doc.js';
|
export * from './doc.js';
|
||||||
export * from './query.js';
|
export * from './query.js';
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
export type * from './doc/block-collection.js';
|
|
||||||
export * from './doc/index.js';
|
export * from './doc/index.js';
|
||||||
export * from './meta.js';
|
export * from './meta.js';
|
||||||
export * from './workspace.js';
|
export * from './workspace.js';
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
import type { Slot } from '@blocksuite/global/utils';
|
import type { Slot } from '@blocksuite/global/utils';
|
||||||
import type { BlobEngine, DocEngine } from '@blocksuite/sync';
|
import type { BlobEngine, DocEngine } from '@blocksuite/sync';
|
||||||
|
import type * as Y from 'yjs';
|
||||||
|
|
||||||
|
import type { BlockModel } from '../schema/base.js';
|
||||||
import type { Schema } from '../schema/schema.js';
|
import type { Schema } from '../schema/schema.js';
|
||||||
import type { IdGenerator } from '../utils/id-generator.js';
|
import type { IdGenerator } from '../utils/id-generator.js';
|
||||||
import type { AwarenessStore } from '../yjs/awareness.js';
|
import type { AwarenessStore } from '../yjs/awareness.js';
|
||||||
import type { BlockSuiteDoc } from '../yjs/doc.js';
|
import type { BlockSuiteDoc } from '../yjs/doc.js';
|
||||||
|
import type { YBlock } from './doc/block/types.js';
|
||||||
import type { Blocks } from './doc/doc.js';
|
import type { Blocks } from './doc/doc.js';
|
||||||
import type { BlockCollection } from './doc/index.js';
|
|
||||||
import type { Query } from './doc/query.js';
|
import type { Query } from './doc/query.js';
|
||||||
|
|
||||||
export type Tag = {
|
export type Tag = {
|
||||||
@@ -70,7 +72,7 @@ export interface Workspace {
|
|||||||
|
|
||||||
get schema(): Schema;
|
get schema(): Schema;
|
||||||
get doc(): BlockSuiteDoc;
|
get doc(): BlockSuiteDoc;
|
||||||
get docs(): Map<string, BlockCollection>;
|
get docs(): Map<string, Doc>;
|
||||||
|
|
||||||
slots: {
|
slots: {
|
||||||
docListUpdated: Slot;
|
docListUpdated: Slot;
|
||||||
@@ -85,6 +87,77 @@ export interface Workspace {
|
|||||||
dispose(): void;
|
dispose(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface Doc {
|
||||||
|
readonly id: string;
|
||||||
|
get meta(): DocMeta | undefined;
|
||||||
|
get schema(): Schema;
|
||||||
|
|
||||||
|
remove(): void;
|
||||||
|
load(initFn?: () => void): void;
|
||||||
|
get ready(): boolean;
|
||||||
|
dispose(): void;
|
||||||
|
|
||||||
|
slots: {
|
||||||
|
historyUpdated: Slot;
|
||||||
|
yBlockUpdated: Slot<
|
||||||
|
| {
|
||||||
|
type: 'add';
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: 'delete';
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
>;
|
||||||
|
};
|
||||||
|
|
||||||
|
get canRedo(): boolean;
|
||||||
|
get canUndo(): boolean;
|
||||||
|
undo(): void;
|
||||||
|
redo(): void;
|
||||||
|
resetHistory(): void;
|
||||||
|
transact(fn: () => void, shouldTransact?: boolean): void;
|
||||||
|
withoutTransact(fn: () => void): void;
|
||||||
|
|
||||||
|
captureSync(): void;
|
||||||
|
clear(): void;
|
||||||
|
getDoc(options?: GetDocOptions): Blocks;
|
||||||
|
clearQuery(query: Query, readonly?: boolean): void;
|
||||||
|
|
||||||
|
get history(): Y.UndoManager;
|
||||||
|
get loaded(): boolean;
|
||||||
|
get readonly(): boolean;
|
||||||
|
get awarenessStore(): AwarenessStore;
|
||||||
|
|
||||||
|
get collection(): Workspace;
|
||||||
|
|
||||||
|
get rootDoc(): BlockSuiteDoc;
|
||||||
|
get spaceDoc(): Y.Doc;
|
||||||
|
get yBlocks(): Y.Map<YBlock>;
|
||||||
|
}
|
||||||
|
|
||||||
export interface StackItem {
|
export interface StackItem {
|
||||||
meta: Map<'selection-state', unknown>;
|
meta: Map<'selection-state', unknown>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type YBlocks = Y.Map<YBlock>;
|
||||||
|
|
||||||
|
/** JSON-serializable properties of a block */
|
||||||
|
export type BlockSysProps = {
|
||||||
|
id: string;
|
||||||
|
flavour: string;
|
||||||
|
children?: BlockModel[];
|
||||||
|
};
|
||||||
|
export type BlockProps = BlockSysProps & Record<string, unknown>;
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
namespace BlockSuite {
|
||||||
|
interface BlockModels {}
|
||||||
|
|
||||||
|
type Flavour = string & keyof BlockModels;
|
||||||
|
|
||||||
|
type ModelProps<Model> = Partial<
|
||||||
|
Model extends BlockModel<infer U> ? U : never
|
||||||
|
>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
export { createAutoIncrementIdGenerator } from '../utils/id-generator.js';
|
export { createAutoIncrementIdGenerator } from '../utils/id-generator.js';
|
||||||
|
export * from './test-doc.js';
|
||||||
export * from './test-workspace.js';
|
export * from './test-workspace.js';
|
||||||
|
|||||||
@@ -1,36 +1,21 @@
|
|||||||
import { type Disposable, Slot } from '@blocksuite/global/utils';
|
import { type Disposable, Slot } from '@blocksuite/global/utils';
|
||||||
import { signal } from '@preact/signals-core';
|
import { signal } from '@preact/signals-core';
|
||||||
import { uuidv4 } from 'lib0/random.js';
|
|
||||||
import * as Y from 'yjs';
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
import { Text } from '../../reactive/text.js';
|
import { Blocks } from '../store/doc/doc.js';
|
||||||
import type { BlockModel } from '../../schema/base.js';
|
import type { YBlock } from '../store/doc/index.js';
|
||||||
import type { IdGenerator } from '../../utils/id-generator.js';
|
import type { Query } from '../store/doc/query.js';
|
||||||
import type { AwarenessStore, BlockSuiteDoc } from '../../yjs/index.js';
|
import type { Doc, GetDocOptions, Workspace } from '../store/workspace.js';
|
||||||
import type { GetDocOptions, Workspace } from '../workspace.js';
|
import type { AwarenessStore, BlockSuiteDoc } from '../yjs/index.js';
|
||||||
import { Blocks } from './doc.js';
|
|
||||||
import type { YBlock } from './index.js';
|
|
||||||
import type { Query } from './query.js';
|
|
||||||
|
|
||||||
export type YBlocks = Y.Map<YBlock>;
|
|
||||||
|
|
||||||
/** JSON-serializable properties of a block */
|
|
||||||
export type BlockSysProps = {
|
|
||||||
id: string;
|
|
||||||
flavour: string;
|
|
||||||
children?: BlockModel[];
|
|
||||||
};
|
|
||||||
export type BlockProps = BlockSysProps & Record<string, unknown>;
|
|
||||||
|
|
||||||
type DocOptions = {
|
type DocOptions = {
|
||||||
id: string;
|
id: string;
|
||||||
collection: Workspace;
|
collection: Workspace;
|
||||||
doc: BlockSuiteDoc;
|
doc: BlockSuiteDoc;
|
||||||
awarenessStore: AwarenessStore;
|
awarenessStore: AwarenessStore;
|
||||||
idGenerator?: IdGenerator;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export class BlockCollection {
|
export class TestDoc implements Doc {
|
||||||
private _awarenessUpdateDisposable: Disposable | null = null;
|
private _awarenessUpdateDisposable: Disposable | null = null;
|
||||||
|
|
||||||
private readonly _canRedo$ = signal(false);
|
private readonly _canRedo$ = signal(false);
|
||||||
@@ -57,8 +42,6 @@ export class BlockCollection {
|
|||||||
this.slots.historyUpdated.emit();
|
this.slots.historyUpdated.emit();
|
||||||
};
|
};
|
||||||
|
|
||||||
private readonly _idGenerator: IdGenerator;
|
|
||||||
|
|
||||||
private readonly _initSubDoc = () => {
|
private readonly _initSubDoc = () => {
|
||||||
let subDoc = this.rootDoc.spaces.get(this.id);
|
let subDoc = this.rootDoc.spaces.get(this.id);
|
||||||
if (!subDoc) {
|
if (!subDoc) {
|
||||||
@@ -184,7 +167,7 @@ export class BlockCollection {
|
|||||||
return this.collection.meta.getDocMeta(this.id);
|
return this.collection.meta.getDocMeta(this.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
get readonly() {
|
get readonly(): boolean {
|
||||||
return this.awarenessStore.isReadonly(this);
|
return this.awarenessStore.isReadonly(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,21 +183,11 @@ export class BlockCollection {
|
|||||||
return this._ySpaceDoc;
|
return this._ySpaceDoc;
|
||||||
}
|
}
|
||||||
|
|
||||||
get Text() {
|
|
||||||
return Text;
|
|
||||||
}
|
|
||||||
|
|
||||||
get yBlocks() {
|
get yBlocks() {
|
||||||
return this._yBlocks;
|
return this._yBlocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor({
|
constructor({ id, collection, doc, awarenessStore }: DocOptions) {
|
||||||
id,
|
|
||||||
collection,
|
|
||||||
doc,
|
|
||||||
awarenessStore,
|
|
||||||
idGenerator = uuidv4,
|
|
||||||
}: DocOptions) {
|
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.rootDoc = doc;
|
this.rootDoc = doc;
|
||||||
this.awarenessStore = awarenessStore;
|
this.awarenessStore = awarenessStore;
|
||||||
@@ -223,7 +196,6 @@ export class BlockCollection {
|
|||||||
|
|
||||||
this._yBlocks = this._ySpaceDoc.getMap('blocks');
|
this._yBlocks = this._ySpaceDoc.getMap('blocks');
|
||||||
this._collection = collection;
|
this._collection = collection;
|
||||||
this._idGenerator = idGenerator;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private _getReadonlyKey(readonly?: boolean): 'true' | 'false' | 'undefined' {
|
private _getReadonlyKey(readonly?: boolean): 'true' | 'false' | 'undefined' {
|
||||||
@@ -295,7 +267,7 @@ export class BlockCollection {
|
|||||||
this._docMap[readonlyKey].delete(JSON.stringify(query));
|
this._docMap[readonlyKey].delete(JSON.stringify(query));
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
private _destroy() {
|
||||||
this._ySpaceDoc.destroy();
|
this._ySpaceDoc.destroy();
|
||||||
this._onLoadSlot.dispose();
|
this._onLoadSlot.dispose();
|
||||||
this._loaded = false;
|
this._loaded = false;
|
||||||
@@ -311,10 +283,6 @@ export class BlockCollection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
generateBlockId() {
|
|
||||||
return this._idGenerator();
|
|
||||||
}
|
|
||||||
|
|
||||||
getDoc({ readonly, query }: GetDocOptions = {}) {
|
getDoc({ readonly, query }: GetDocOptions = {}) {
|
||||||
const readonlyKey = this._getReadonlyKey(readonly);
|
const readonlyKey = this._getReadonlyKey(readonly);
|
||||||
|
|
||||||
@@ -375,8 +343,16 @@ export class BlockCollection {
|
|||||||
this._history.redo();
|
this._history.redo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
undo() {
|
||||||
|
if (this.readonly) {
|
||||||
|
console.error('cannot modify data in readonly mode');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._history.undo();
|
||||||
|
}
|
||||||
|
|
||||||
remove() {
|
remove() {
|
||||||
this.destroy();
|
this._destroy();
|
||||||
this.rootDoc.spaces.delete(this.id);
|
this.rootDoc.spaces.delete(this.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -403,30 +379,9 @@ export class BlockCollection {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle all the events that happen at _any_ level (potentially deep inside the structure).
|
|
||||||
undo() {
|
|
||||||
if (this.readonly) {
|
|
||||||
console.error('cannot modify data in readonly mode');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this._history.undo();
|
|
||||||
}
|
|
||||||
|
|
||||||
withoutTransact(callback: () => void) {
|
withoutTransact(callback: () => void) {
|
||||||
this._shouldTransact = false;
|
this._shouldTransact = false;
|
||||||
callback();
|
callback();
|
||||||
this._shouldTransact = true;
|
this._shouldTransact = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
|
||||||
namespace BlockSuite {
|
|
||||||
interface BlockModels {}
|
|
||||||
|
|
||||||
type Flavour = string & keyof BlockModels;
|
|
||||||
|
|
||||||
type ModelProps<Model> = Partial<
|
|
||||||
Model extends BlockModel<infer U> ? U : never
|
|
||||||
>;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -17,7 +17,6 @@ import { Awareness } from 'y-protocols/awareness.js';
|
|||||||
|
|
||||||
import type { Schema } from '../schema/index.js';
|
import type { Schema } from '../schema/index.js';
|
||||||
import {
|
import {
|
||||||
BlockCollection,
|
|
||||||
type Blocks,
|
type Blocks,
|
||||||
type CreateDocOptions,
|
type CreateDocOptions,
|
||||||
DocCollectionMeta,
|
DocCollectionMeta,
|
||||||
@@ -30,6 +29,7 @@ import {
|
|||||||
BlockSuiteDoc,
|
BlockSuiteDoc,
|
||||||
type RawAwarenessState,
|
type RawAwarenessState,
|
||||||
} from '../yjs/index.js';
|
} from '../yjs/index.js';
|
||||||
|
import { TestDoc } from './test-doc.js';
|
||||||
|
|
||||||
export type DocCollectionOptions = {
|
export type DocCollectionOptions = {
|
||||||
schema: Schema;
|
schema: Schema;
|
||||||
@@ -80,7 +80,7 @@ export class TestWorkspace implements Workspace {
|
|||||||
|
|
||||||
readonly blobSync: BlobEngine;
|
readonly blobSync: BlobEngine;
|
||||||
|
|
||||||
readonly blockCollections = new Map<string, BlockCollection>();
|
readonly blockCollections = new Map<string, TestDoc>();
|
||||||
|
|
||||||
readonly doc: BlockSuiteDoc;
|
readonly doc: BlockSuiteDoc;
|
||||||
|
|
||||||
@@ -154,12 +154,11 @@ export class TestWorkspace implements Workspace {
|
|||||||
|
|
||||||
private _bindDocMetaEvents() {
|
private _bindDocMetaEvents() {
|
||||||
this.meta.docMetaAdded.on(docId => {
|
this.meta.docMetaAdded.on(docId => {
|
||||||
const doc = new BlockCollection({
|
const doc = new TestDoc({
|
||||||
id: docId,
|
id: docId,
|
||||||
collection: this,
|
collection: this,
|
||||||
doc: this.doc,
|
doc: this.doc,
|
||||||
awarenessStore: this.awarenessStore,
|
awarenessStore: this.awarenessStore,
|
||||||
idGenerator: this.idGenerator,
|
|
||||||
});
|
});
|
||||||
this.blockCollections.set(doc.id, doc);
|
this.blockCollections.set(doc.id, doc);
|
||||||
});
|
});
|
||||||
@@ -225,8 +224,8 @@ export class TestWorkspace implements Workspace {
|
|||||||
this.awarenessSync.disconnect();
|
this.awarenessSync.disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
getBlockCollection(docId: string): BlockCollection | null {
|
getBlockCollection(docId: string): TestDoc | null {
|
||||||
const space = this.docs.get(docId) as BlockCollection | undefined;
|
const space = this.docs.get(docId) as TestDoc | undefined;
|
||||||
return space ?? null;
|
return space ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { native2Y } from '../reactive/index.js';
|
|||||||
import type { BlockModel, BlockSchema } from '../schema/base.js';
|
import type { BlockModel, BlockSchema } from '../schema/base.js';
|
||||||
import { internalPrimitives } from '../schema/base.js';
|
import { internalPrimitives } from '../schema/base.js';
|
||||||
import type { YBlock } from '../store/doc/block/index.js';
|
import type { YBlock } from '../store/doc/block/index.js';
|
||||||
import type { BlockProps } from '../store/doc/block-collection.js';
|
import type { BlockProps } from '../store/workspace.js';
|
||||||
|
|
||||||
export function syncBlockProps(
|
export function syncBlockProps(
|
||||||
schema: z.infer<typeof BlockSchema>,
|
schema: z.infer<typeof BlockSchema>,
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import clonedeep from 'lodash.clonedeep';
|
|||||||
import merge from 'lodash.merge';
|
import merge from 'lodash.merge';
|
||||||
import type { Awareness as YAwareness } from 'y-protocols/awareness.js';
|
import type { Awareness as YAwareness } from 'y-protocols/awareness.js';
|
||||||
|
|
||||||
import type { BlockCollection } from '../store/index.js';
|
import type { Doc } from '../store/index.js';
|
||||||
|
|
||||||
export interface UserInfo {
|
export interface UserInfo {
|
||||||
name: string;
|
name: string;
|
||||||
@@ -115,7 +115,7 @@ export class AwarenessStore<Flags extends BlockSuiteFlags = BlockSuiteFlags> {
|
|||||||
return this.awareness.getStates();
|
return this.awareness.getStates();
|
||||||
}
|
}
|
||||||
|
|
||||||
isReadonly(blockCollection: BlockCollection): boolean {
|
isReadonly(blockCollection: Doc): boolean {
|
||||||
const rd = this.getFlag('readonly');
|
const rd = this.getFlag('readonly');
|
||||||
if (rd && typeof rd === 'object') {
|
if (rd && typeof rd === 'object') {
|
||||||
return Boolean((rd as Record<string, boolean>)[blockCollection.id]);
|
return Boolean((rd as Record<string, boolean>)[blockCollection.id]);
|
||||||
@@ -137,7 +137,7 @@ export class AwarenessStore<Flags extends BlockSuiteFlags = BlockSuiteFlags> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
setReadonly(blockCollection: BlockCollection, value: boolean): void {
|
setReadonly(blockCollection: Doc, value: boolean): void {
|
||||||
const flags = this.getFlag('readonly') ?? {};
|
const flags = this.getFlag('readonly') ?? {};
|
||||||
this.setFlag('readonly', {
|
this.setFlag('readonly', {
|
||||||
...flags,
|
...flags,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { effects as blocksEffects } from '@blocksuite/blocks/effects';
|
import { effects as blocksEffects } from '@blocksuite/blocks/effects';
|
||||||
import type { BlockCollection, Blocks, Job } from '@blocksuite/store';
|
import type { Blocks, Job } from '@blocksuite/store';
|
||||||
|
|
||||||
import { effects } from '../../effects.js';
|
import { effects } from '../../effects.js';
|
||||||
|
|
||||||
@@ -57,9 +57,7 @@ function initCollection(collection: TestWorkspace) {
|
|||||||
|
|
||||||
async function createEditor(collection: TestWorkspace, mode: DocMode = 'page') {
|
async function createEditor(collection: TestWorkspace, mode: DocMode = 'page') {
|
||||||
const app = document.createElement('div');
|
const app = document.createElement('div');
|
||||||
const blockCollection = collection.docs.values().next().value as
|
const blockCollection = collection.docs.values().next().value;
|
||||||
| BlockCollection
|
|
||||||
| undefined;
|
|
||||||
assertExists(blockCollection, 'Need to create a doc first');
|
assertExists(blockCollection, 'Need to create a doc first');
|
||||||
const doc = blockCollection.getDoc();
|
const doc = blockCollection.getDoc();
|
||||||
const editor = new AffineEditorContainer();
|
const editor = new AffineEditorContainer();
|
||||||
|
|||||||
@@ -64,11 +64,11 @@ test(scoped`basic init with external text`, async ({ page }) => {
|
|||||||
await page.evaluate(() => {
|
await page.evaluate(() => {
|
||||||
const { doc } = window;
|
const { doc } = window;
|
||||||
const rootId = doc.addBlock('affine:page', {
|
const rootId = doc.addBlock('affine:page', {
|
||||||
title: new doc.Text('hello'),
|
title: new window.$blocksuite.store.Text('hello'),
|
||||||
});
|
});
|
||||||
const note = doc.addBlock('affine:note', {}, rootId);
|
const note = doc.addBlock('affine:note', {}, rootId);
|
||||||
|
|
||||||
const text = new doc.Text('world');
|
const text = new window.$blocksuite.store.Text('world');
|
||||||
doc.addBlock('affine:paragraph', { text }, note);
|
doc.addBlock('affine:paragraph', { text }, note);
|
||||||
|
|
||||||
const delta = [
|
const delta = [
|
||||||
@@ -78,7 +78,7 @@ test(scoped`basic init with external text`, async ({ page }) => {
|
|||||||
doc.addBlock(
|
doc.addBlock(
|
||||||
'affine:paragraph',
|
'affine:paragraph',
|
||||||
{
|
{
|
||||||
text: new doc.Text(delta as DeltaInsert[]),
|
text: new window.$blocksuite.store.Text(delta as DeltaInsert[]),
|
||||||
},
|
},
|
||||||
note
|
note
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -628,7 +628,7 @@ test.fixme(
|
|||||||
const { doc } = window;
|
const { doc } = window;
|
||||||
|
|
||||||
const rootId = doc.addBlock('affine:page', {
|
const rootId = doc.addBlock('affine:page', {
|
||||||
title: new doc.Text(),
|
title: new window.$blocksuite.store.Text(),
|
||||||
});
|
});
|
||||||
doc.addBlock('affine:surface', {}, rootId);
|
doc.addBlock('affine:surface', {}, rootId);
|
||||||
|
|
||||||
@@ -637,7 +637,7 @@ test.fixme(
|
|||||||
doc.addBlock(
|
doc.addBlock(
|
||||||
'affine:paragraph',
|
'affine:paragraph',
|
||||||
{
|
{
|
||||||
text: new doc.Text(text),
|
text: new window.$blocksuite.store.Text(text),
|
||||||
},
|
},
|
||||||
noteId
|
noteId
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -554,7 +554,7 @@ test('press backspace at the start of first line when edgeless text exist', asyn
|
|||||||
await page.evaluate(() => {
|
await page.evaluate(() => {
|
||||||
const { doc } = window;
|
const { doc } = window;
|
||||||
const rootId = doc.addBlock('affine:page', {
|
const rootId = doc.addBlock('affine:page', {
|
||||||
title: new doc.Text(),
|
title: new window.$blocksuite.store.Text(),
|
||||||
});
|
});
|
||||||
doc.addBlock('affine:surface', {}, rootId);
|
doc.addBlock('affine:surface', {}, rootId);
|
||||||
doc.addBlock('affine:note', {}, rootId);
|
doc.addBlock('affine:note', {}, rootId);
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ test.describe('Embed synced doc', () => {
|
|||||||
await page.evaluate(() => {
|
await page.evaluate(() => {
|
||||||
const { doc, collection } = window;
|
const { doc, collection } = window;
|
||||||
const rootId = doc.addBlock('affine:page', {
|
const rootId = doc.addBlock('affine:page', {
|
||||||
title: new doc.Text(),
|
title: new window.$blocksuite.store.Text(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const noteId = doc.addBlock('affine:note', {}, rootId);
|
const noteId = doc.addBlock('affine:note', {}, rootId);
|
||||||
@@ -149,14 +149,14 @@ test.describe('Embed synced doc', () => {
|
|||||||
const doc2 = collection.createDoc({ id: 'doc2' });
|
const doc2 = collection.createDoc({ id: 'doc2' });
|
||||||
doc2.load();
|
doc2.load();
|
||||||
const rootId2 = doc2.addBlock('affine:page', {
|
const rootId2 = doc2.addBlock('affine:page', {
|
||||||
title: new doc.Text('Doc 2'),
|
title: new window.$blocksuite.store.Text('Doc 2'),
|
||||||
});
|
});
|
||||||
|
|
||||||
const noteId2 = doc2.addBlock('affine:note', {}, rootId2);
|
const noteId2 = doc2.addBlock('affine:note', {}, rootId2);
|
||||||
doc2.addBlock(
|
doc2.addBlock(
|
||||||
'affine:paragraph',
|
'affine:paragraph',
|
||||||
{
|
{
|
||||||
text: new doc.Text('Hello from Doc 2'),
|
text: new window.$blocksuite.store.Text('Hello from Doc 2'),
|
||||||
},
|
},
|
||||||
noteId2
|
noteId2
|
||||||
);
|
);
|
||||||
@@ -164,14 +164,14 @@ test.describe('Embed synced doc', () => {
|
|||||||
const doc3 = collection.createDoc({ id: 'doc3' });
|
const doc3 = collection.createDoc({ id: 'doc3' });
|
||||||
doc3.load();
|
doc3.load();
|
||||||
const rootId3 = doc3.addBlock('affine:page', {
|
const rootId3 = doc3.addBlock('affine:page', {
|
||||||
title: new doc.Text('Doc 3'),
|
title: new window.$blocksuite.store.Text('Doc 3'),
|
||||||
});
|
});
|
||||||
|
|
||||||
const noteId3 = doc3.addBlock('affine:note', {}, rootId3);
|
const noteId3 = doc3.addBlock('affine:note', {}, rootId3);
|
||||||
doc3.addBlock(
|
doc3.addBlock(
|
||||||
'affine:paragraph',
|
'affine:paragraph',
|
||||||
{
|
{
|
||||||
text: new doc.Text('Hello from Doc 3'),
|
text: new window.$blocksuite.store.Text('Hello from Doc 3'),
|
||||||
},
|
},
|
||||||
noteId3
|
noteId3
|
||||||
);
|
);
|
||||||
@@ -232,7 +232,7 @@ test.describe('Embed synced doc', () => {
|
|||||||
const databaseId = doc2.addBlock(
|
const databaseId = doc2.addBlock(
|
||||||
'affine:database',
|
'affine:database',
|
||||||
{
|
{
|
||||||
title: new doc2.Text('Database 1'),
|
title: new window.$blocksuite.store.Text('Database 1'),
|
||||||
},
|
},
|
||||||
noteId
|
noteId
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -453,10 +453,10 @@ test('should format quick bar position correct at the start of second line', asy
|
|||||||
await page.evaluate(() => {
|
await page.evaluate(() => {
|
||||||
const { doc } = window;
|
const { doc } = window;
|
||||||
const rootId = doc.addBlock('affine:page', {
|
const rootId = doc.addBlock('affine:page', {
|
||||||
title: new doc.Text(),
|
title: new window.$blocksuite.store.Text(),
|
||||||
});
|
});
|
||||||
const note = doc.addBlock('affine:note', {}, rootId);
|
const note = doc.addBlock('affine:note', {}, rootId);
|
||||||
const text = new doc.Text('a'.repeat(100));
|
const text = new window.$blocksuite.store.Text('a'.repeat(100));
|
||||||
const paragraphId = doc.addBlock('affine:paragraph', { text }, note);
|
const paragraphId = doc.addBlock('affine:paragraph', { text }, note);
|
||||||
return paragraphId;
|
return paragraphId;
|
||||||
});
|
});
|
||||||
@@ -715,7 +715,7 @@ test('should format bar style active correctly', async ({ page }) => {
|
|||||||
await page.evaluate(() => {
|
await page.evaluate(() => {
|
||||||
const { doc } = window;
|
const { doc } = window;
|
||||||
const rootId = doc.addBlock('affine:page', {
|
const rootId = doc.addBlock('affine:page', {
|
||||||
title: new doc.Text(),
|
title: new window.$blocksuite.store.Text(),
|
||||||
});
|
});
|
||||||
const note = doc.addBlock('affine:note', {}, rootId);
|
const note = doc.addBlock('affine:note', {}, rootId);
|
||||||
const delta = [
|
const delta = [
|
||||||
@@ -723,7 +723,7 @@ test('should format bar style active correctly', async ({ page }) => {
|
|||||||
{ insert: '2', attributes: { bold: true, underline: true } },
|
{ insert: '2', attributes: { bold: true, underline: true } },
|
||||||
{ insert: '3', attributes: { bold: true, code: true } },
|
{ insert: '3', attributes: { bold: true, code: true } },
|
||||||
];
|
];
|
||||||
const text = new doc.Text(delta as DeltaInsert[]);
|
const text = new window.$blocksuite.store.Text(delta as DeltaInsert[]);
|
||||||
doc.addBlock('affine:paragraph', { text }, note);
|
doc.addBlock('affine:paragraph', { text }, note);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -869,7 +869,7 @@ test('should update the format quick bar state when there is a change in keyboar
|
|||||||
await page.evaluate(() => {
|
await page.evaluate(() => {
|
||||||
const { doc } = window;
|
const { doc } = window;
|
||||||
const rootId = doc.addBlock('affine:page', {
|
const rootId = doc.addBlock('affine:page', {
|
||||||
title: new doc.Text(),
|
title: new window.$blocksuite.store.Text(),
|
||||||
});
|
});
|
||||||
const note = doc.addBlock('affine:note', {}, rootId);
|
const note = doc.addBlock('affine:note', {}, rootId);
|
||||||
const delta = [
|
const delta = [
|
||||||
@@ -877,7 +877,7 @@ test('should update the format quick bar state when there is a change in keyboar
|
|||||||
{ insert: '2', attributes: { bold: true } },
|
{ insert: '2', attributes: { bold: true } },
|
||||||
{ insert: '3', attributes: { bold: false } },
|
{ insert: '3', attributes: { bold: false } },
|
||||||
];
|
];
|
||||||
const text = new doc.Text(delta as DeltaInsert[]);
|
const text = new window.$blocksuite.store.Text(delta as DeltaInsert[]);
|
||||||
doc.addBlock('affine:paragraph', { text }, note);
|
doc.addBlock('affine:paragraph', { text }, note);
|
||||||
});
|
});
|
||||||
await focusTitle(page);
|
await focusTitle(page);
|
||||||
|
|||||||
@@ -121,11 +121,11 @@ async function createLinkBlock(page: Page, str: string, link: string) {
|
|||||||
([str, link]) => {
|
([str, link]) => {
|
||||||
const { doc } = window;
|
const { doc } = window;
|
||||||
const rootId = doc.addBlock('affine:page', {
|
const rootId = doc.addBlock('affine:page', {
|
||||||
title: new doc.Text('title'),
|
title: new window.$blocksuite.store.Text('title'),
|
||||||
});
|
});
|
||||||
const noteId = doc.addBlock('affine:note', {}, rootId);
|
const noteId = doc.addBlock('affine:note', {}, rootId);
|
||||||
|
|
||||||
const text = new doc.Text([
|
const text = new window.$blocksuite.store.Text([
|
||||||
{ insert: 'Hello' },
|
{ insert: 'Hello' },
|
||||||
{ insert: str, attributes: { link } },
|
{ insert: str, attributes: { link } },
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -825,20 +825,20 @@ test('press arrow down should move caret to the start of line', async ({
|
|||||||
await page.evaluate(() => {
|
await page.evaluate(() => {
|
||||||
const { doc } = window;
|
const { doc } = window;
|
||||||
const rootId = doc.addBlock('affine:page', {
|
const rootId = doc.addBlock('affine:page', {
|
||||||
title: new doc.Text(),
|
title: new window.$blocksuite.store.Text(),
|
||||||
});
|
});
|
||||||
const note = doc.addBlock('affine:note', {}, rootId);
|
const note = doc.addBlock('affine:note', {}, rootId);
|
||||||
doc.addBlock(
|
doc.addBlock(
|
||||||
'affine:paragraph',
|
'affine:paragraph',
|
||||||
{
|
{
|
||||||
text: new doc.Text('0'.repeat(100)),
|
text: new window.$blocksuite.store.Text('0'.repeat(100)),
|
||||||
},
|
},
|
||||||
note
|
note
|
||||||
);
|
);
|
||||||
doc.addBlock(
|
doc.addBlock(
|
||||||
'affine:paragraph',
|
'affine:paragraph',
|
||||||
{
|
{
|
||||||
text: new doc.Text('1'),
|
text: new window.$blocksuite.store.Text('1'),
|
||||||
},
|
},
|
||||||
note
|
note
|
||||||
);
|
);
|
||||||
@@ -860,7 +860,7 @@ test('press arrow up in the second line should move caret to the first line', as
|
|||||||
await page.evaluate(() => {
|
await page.evaluate(() => {
|
||||||
const { doc } = window;
|
const { doc } = window;
|
||||||
const rootId = doc.addBlock('affine:page', {
|
const rootId = doc.addBlock('affine:page', {
|
||||||
title: new doc.Text(),
|
title: new window.$blocksuite.store.Text(),
|
||||||
});
|
});
|
||||||
const note = doc.addBlock('affine:note', {}, rootId);
|
const note = doc.addBlock('affine:note', {}, rootId);
|
||||||
const delta = Array.from({ length: 150 }, (_, i) => {
|
const delta = Array.from({ length: 150 }, (_, i) => {
|
||||||
@@ -868,7 +868,7 @@ test('press arrow up in the second line should move caret to the first line', as
|
|||||||
? { insert: 'i', attributes: { italic: true } }
|
? { insert: 'i', attributes: { italic: true } }
|
||||||
: { insert: 'b', attributes: { bold: true } };
|
: { insert: 'b', attributes: { bold: true } };
|
||||||
}) as DeltaInsert[];
|
}) as DeltaInsert[];
|
||||||
const text = new doc.Text(delta);
|
const text = new window.$blocksuite.store.Text(delta);
|
||||||
doc.addBlock('affine:paragraph', { text }, note);
|
doc.addBlock('affine:paragraph', { text }, note);
|
||||||
doc.addBlock('affine:paragraph', {}, note);
|
doc.addBlock('affine:paragraph', {}, note);
|
||||||
});
|
});
|
||||||
@@ -912,7 +912,7 @@ test('press arrow down in indent line should not move caret to the start of line
|
|||||||
await page.evaluate(() => {
|
await page.evaluate(() => {
|
||||||
const { doc } = window;
|
const { doc } = window;
|
||||||
const rootId = doc.addBlock('affine:page', {
|
const rootId = doc.addBlock('affine:page', {
|
||||||
title: new doc.Text(),
|
title: new window.$blocksuite.store.Text(),
|
||||||
});
|
});
|
||||||
const note = doc.addBlock('affine:note', {}, rootId);
|
const note = doc.addBlock('affine:note', {}, rootId);
|
||||||
const p1 = doc.addBlock('affine:paragraph', {}, note);
|
const p1 = doc.addBlock('affine:paragraph', {}, note);
|
||||||
@@ -921,7 +921,7 @@ test('press arrow down in indent line should not move caret to the start of line
|
|||||||
doc.addBlock(
|
doc.addBlock(
|
||||||
'affine:paragraph',
|
'affine:paragraph',
|
||||||
{
|
{
|
||||||
text: new doc.Text('0'),
|
text: new window.$blocksuite.store.Text('0'),
|
||||||
},
|
},
|
||||||
note
|
note
|
||||||
);
|
);
|
||||||
@@ -1003,20 +1003,22 @@ test.describe('press ArrowDown when cursor is at the last line of a block', () =
|
|||||||
await page.evaluate(() => {
|
await page.evaluate(() => {
|
||||||
const { doc } = window;
|
const { doc } = window;
|
||||||
const rootId = doc.addBlock('affine:page', {
|
const rootId = doc.addBlock('affine:page', {
|
||||||
title: new doc.Text(),
|
title: new window.$blocksuite.store.Text(),
|
||||||
});
|
});
|
||||||
const note = doc.addBlock('affine:note', {}, rootId);
|
const note = doc.addBlock('affine:note', {}, rootId);
|
||||||
doc.addBlock(
|
doc.addBlock(
|
||||||
'affine:paragraph',
|
'affine:paragraph',
|
||||||
{
|
{
|
||||||
text: new doc.Text('This is the 2nd last block.'),
|
text: new window.$blocksuite.store.Text(
|
||||||
|
'This is the 2nd last block.'
|
||||||
|
),
|
||||||
},
|
},
|
||||||
note
|
note
|
||||||
);
|
);
|
||||||
doc.addBlock(
|
doc.addBlock(
|
||||||
'affine:paragraph',
|
'affine:paragraph',
|
||||||
{
|
{
|
||||||
text: new doc.Text('This is the last block.'),
|
text: new window.$blocksuite.store.Text('This is the last block.'),
|
||||||
},
|
},
|
||||||
note
|
note
|
||||||
);
|
);
|
||||||
@@ -1172,7 +1174,7 @@ test('delete at the start of paragraph (multiple notes)', async ({ page }) => {
|
|||||||
const { doc } = window;
|
const { doc } = window;
|
||||||
|
|
||||||
const rootId = doc.addBlock('affine:page', {
|
const rootId = doc.addBlock('affine:page', {
|
||||||
title: new doc.Text(),
|
title: new window.$blocksuite.store.Text(),
|
||||||
});
|
});
|
||||||
doc.addBlock('affine:surface', {}, rootId);
|
doc.addBlock('affine:surface', {}, rootId);
|
||||||
|
|
||||||
@@ -1181,7 +1183,7 @@ test('delete at the start of paragraph (multiple notes)', async ({ page }) => {
|
|||||||
doc.addBlock(
|
doc.addBlock(
|
||||||
'affine:paragraph',
|
'affine:paragraph',
|
||||||
{
|
{
|
||||||
text: new doc.Text(text),
|
text: new window.$blocksuite.store.Text(text),
|
||||||
},
|
},
|
||||||
noteId
|
noteId
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -413,7 +413,7 @@ export async function enterPlaygroundWithList(
|
|||||||
({ contents, type }: { contents: string[]; type: ListType }) => {
|
({ contents, type }: { contents: string[]; type: ListType }) => {
|
||||||
const { doc } = window;
|
const { doc } = window;
|
||||||
const rootId = doc.addBlock('affine:page', {
|
const rootId = doc.addBlock('affine:page', {
|
||||||
title: new doc.Text(),
|
title: new window.$blocksuite.store.Text(),
|
||||||
});
|
});
|
||||||
const noteId = doc.addBlock('affine:note', {}, rootId);
|
const noteId = doc.addBlock('affine:note', {}, rootId);
|
||||||
// eslint-disable-next-line @typescript-eslint/prefer-for-of
|
// eslint-disable-next-line @typescript-eslint/prefer-for-of
|
||||||
@@ -421,7 +421,7 @@ export async function enterPlaygroundWithList(
|
|||||||
doc.addBlock(
|
doc.addBlock(
|
||||||
'affine:list',
|
'affine:list',
|
||||||
contents.length > 0
|
contents.length > 0
|
||||||
? { text: new doc.Text(contents[i]), type }
|
? { text: new window.$blocksuite.store.Text(contents[i]), type }
|
||||||
: { type },
|
: { type },
|
||||||
noteId
|
noteId
|
||||||
);
|
);
|
||||||
@@ -439,7 +439,7 @@ export async function initEmptyParagraphState(page: Page, rootId?: string) {
|
|||||||
doc.captureSync();
|
doc.captureSync();
|
||||||
if (!rootId) {
|
if (!rootId) {
|
||||||
rootId = doc.addBlock('affine:page', {
|
rootId = doc.addBlock('affine:page', {
|
||||||
title: new doc.Text(),
|
title: new window.$blocksuite.store.Text(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -464,7 +464,7 @@ export async function initMultipleNoteWithParagraphState(
|
|||||||
doc.captureSync();
|
doc.captureSync();
|
||||||
if (!rootId) {
|
if (!rootId) {
|
||||||
rootId = doc.addBlock('affine:page', {
|
rootId = doc.addBlock('affine:page', {
|
||||||
title: new doc.Text(),
|
title: new window.$blocksuite.store.Text(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -490,7 +490,7 @@ export async function initEmptyEdgelessState(page: Page) {
|
|||||||
const ids = await page.evaluate(() => {
|
const ids = await page.evaluate(() => {
|
||||||
const { doc } = window;
|
const { doc } = window;
|
||||||
const rootId = doc.addBlock('affine:page', {
|
const rootId = doc.addBlock('affine:page', {
|
||||||
title: new doc.Text(),
|
title: new window.$blocksuite.store.Text(),
|
||||||
});
|
});
|
||||||
doc.addBlock('affine:surface', {}, rootId);
|
doc.addBlock('affine:surface', {}, rootId);
|
||||||
const noteId = doc.addBlock('affine:note', {}, rootId);
|
const noteId = doc.addBlock('affine:note', {}, rootId);
|
||||||
@@ -509,14 +509,14 @@ export async function initEmptyDatabaseState(page: Page, rootId?: string) {
|
|||||||
doc.captureSync();
|
doc.captureSync();
|
||||||
if (!rootId) {
|
if (!rootId) {
|
||||||
rootId = doc.addBlock('affine:page', {
|
rootId = doc.addBlock('affine:page', {
|
||||||
title: new doc.Text(),
|
title: new window.$blocksuite.store.Text(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const noteId = doc.addBlock('affine:note', {}, rootId);
|
const noteId = doc.addBlock('affine:note', {}, rootId);
|
||||||
const databaseId = doc.addBlock(
|
const databaseId = doc.addBlock(
|
||||||
'affine:database',
|
'affine:database',
|
||||||
{
|
{
|
||||||
title: new doc.Text('Database 1'),
|
title: new window.$blocksuite.store.Text('Database 1'),
|
||||||
},
|
},
|
||||||
noteId
|
noteId
|
||||||
);
|
);
|
||||||
@@ -553,14 +553,14 @@ export async function initKanbanViewState(
|
|||||||
doc.captureSync();
|
doc.captureSync();
|
||||||
if (!rootId) {
|
if (!rootId) {
|
||||||
rootId = doc.addBlock('affine:page', {
|
rootId = doc.addBlock('affine:page', {
|
||||||
title: new doc.Text(),
|
title: new window.$blocksuite.store.Text(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const noteId = doc.addBlock('affine:note', {}, rootId);
|
const noteId = doc.addBlock('affine:note', {}, rootId);
|
||||||
const databaseId = doc.addBlock(
|
const databaseId = doc.addBlock(
|
||||||
'affine:database',
|
'affine:database',
|
||||||
{
|
{
|
||||||
title: new doc.Text('Database 1'),
|
title: new window.$blocksuite.store.Text('Database 1'),
|
||||||
},
|
},
|
||||||
noteId
|
noteId
|
||||||
);
|
);
|
||||||
@@ -572,7 +572,7 @@ export async function initKanbanViewState(
|
|||||||
const rowIds = config.rows.map(rowText => {
|
const rowIds = config.rows.map(rowText => {
|
||||||
const rowId = doc.addBlock(
|
const rowId = doc.addBlock(
|
||||||
'affine:paragraph',
|
'affine:paragraph',
|
||||||
{ type: 'text', text: new doc.Text(rowText) },
|
{ type: 'text', text: new window.$blocksuite.store.Text(rowText) },
|
||||||
databaseId
|
databaseId
|
||||||
);
|
);
|
||||||
return rowId;
|
return rowId;
|
||||||
@@ -590,7 +590,7 @@ export async function initKanbanViewState(
|
|||||||
columnId,
|
columnId,
|
||||||
value:
|
value:
|
||||||
column.type === 'rich-text'
|
column.type === 'rich-text'
|
||||||
? new doc.Text(value as string)
|
? new window.$blocksuite.store.Text(value as string)
|
||||||
: value,
|
: value,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -619,14 +619,14 @@ export async function initEmptyDatabaseWithParagraphState(
|
|||||||
doc.captureSync();
|
doc.captureSync();
|
||||||
if (!rootId) {
|
if (!rootId) {
|
||||||
rootId = doc.addBlock('affine:page', {
|
rootId = doc.addBlock('affine:page', {
|
||||||
title: new doc.Text(),
|
title: new window.$blocksuite.store.Text(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const noteId = doc.addBlock('affine:note', {}, rootId);
|
const noteId = doc.addBlock('affine:note', {}, rootId);
|
||||||
const databaseId = doc.addBlock(
|
const databaseId = doc.addBlock(
|
||||||
'affine:database',
|
'affine:database',
|
||||||
{
|
{
|
||||||
title: new doc.Text('Database 1'),
|
title: new window.$blocksuite.store.Text('Database 1'),
|
||||||
},
|
},
|
||||||
noteId
|
noteId
|
||||||
);
|
);
|
||||||
@@ -1326,7 +1326,7 @@ export async function initImageState(page: Page, prependParagraph = false) {
|
|||||||
await page.evaluate(async prepend => {
|
await page.evaluate(async prepend => {
|
||||||
const { doc } = window;
|
const { doc } = window;
|
||||||
const rootId = doc.addBlock('affine:page', {
|
const rootId = doc.addBlock('affine:page', {
|
||||||
title: new doc.Text(),
|
title: new window.$blocksuite.store.Text(),
|
||||||
});
|
});
|
||||||
const noteId = doc.addBlock('affine:note', {}, rootId);
|
const noteId = doc.addBlock('affine:note', {}, rootId);
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import type {
|
|||||||
} from '@blocksuite/block-std';
|
} from '@blocksuite/block-std';
|
||||||
import type { AffineEditorContainer } from '@blocksuite/presets';
|
import type { AffineEditorContainer } from '@blocksuite/presets';
|
||||||
import type { StarterDebugMenu } from '@playground/apps/_common/components/starter-debug-menu.js';
|
import type { StarterDebugMenu } from '@playground/apps/_common/components/starter-debug-menu.js';
|
||||||
import type { BlockModel, Doc, Job, Workspace } from '@store/index.js';
|
import type { BlockModel, Blocks, Job, Workspace } from '@store/index.js';
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
@@ -38,7 +38,7 @@ declare global {
|
|||||||
};
|
};
|
||||||
collection: Workspace;
|
collection: Workspace;
|
||||||
blockSchema: Record<string, typeof BlockModel>;
|
blockSchema: Record<string, typeof BlockModel>;
|
||||||
doc: Doc;
|
doc: Blocks;
|
||||||
debugMenu: StarterDebugMenu;
|
debugMenu: StarterDebugMenu;
|
||||||
editor: AffineEditorContainer;
|
editor: AffineEditorContainer;
|
||||||
host: EditorHost;
|
host: EditorHost;
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ test(
|
|||||||
await page.evaluate(() => {
|
await page.evaluate(() => {
|
||||||
const { doc } = window;
|
const { doc } = window;
|
||||||
const rootId = doc.addBlock('affine:page', {
|
const rootId = doc.addBlock('affine:page', {
|
||||||
title: new doc.Text(),
|
title: new window.$blocksuite.store.Text(),
|
||||||
});
|
});
|
||||||
const note = doc.addBlock('affine:note', {}, rootId);
|
const note = doc.addBlock('affine:note', {}, rootId);
|
||||||
doc.addBlock('affine:code', {}, note);
|
doc.addBlock('affine:code', {}, note);
|
||||||
@@ -71,7 +71,7 @@ test(
|
|||||||
async ({ bookMarkUrl, embedUrl }) => {
|
async ({ bookMarkUrl, embedUrl }) => {
|
||||||
const { doc } = window;
|
const { doc } = window;
|
||||||
const rootId = doc.addBlock('affine:page', {
|
const rootId = doc.addBlock('affine:page', {
|
||||||
title: new doc.Text(),
|
title: new window.$blocksuite.store.Text(),
|
||||||
});
|
});
|
||||||
const note = doc.addBlock('affine:note', {}, rootId);
|
const note = doc.addBlock('affine:note', {}, rootId);
|
||||||
doc.addBlock('affine:code', {}, note);
|
doc.addBlock('affine:code', {}, note);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { DeltaInsert } from '@blocksuite/affine/inline';
|
import type { DeltaInsert } from '@blocksuite/affine/inline';
|
||||||
import type { Workspace } from '@blocksuite/affine/store';
|
import { Text, type Workspace } from '@blocksuite/affine/store';
|
||||||
import type { AffineTextAttributes } from '@blocksuite/affine-shared/types';
|
import type { AffineTextAttributes } from '@blocksuite/affine-shared/types';
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
@@ -10,7 +10,7 @@ export function useReferenceLinkHelper(docCollection: Workspace) {
|
|||||||
if (!page) {
|
if (!page) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const text = new page.Text([
|
const text = new Text([
|
||||||
{
|
{
|
||||||
insert: ' ',
|
insert: ' ',
|
||||||
attributes: {
|
attributes: {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import 'fake-indexeddb/auto';
|
|||||||
|
|
||||||
import { AffineSchemas } from '@blocksuite/affine/blocks/schemas';
|
import { AffineSchemas } from '@blocksuite/affine/blocks/schemas';
|
||||||
import { assertExists } from '@blocksuite/affine/global/utils';
|
import { assertExists } from '@blocksuite/affine/global/utils';
|
||||||
import type { Blocks } from '@blocksuite/affine/store';
|
import { type Blocks, Text } from '@blocksuite/affine/store';
|
||||||
import { Schema } from '@blocksuite/store';
|
import { Schema } from '@blocksuite/store';
|
||||||
import { TestWorkspace } from '@blocksuite/store/test';
|
import { TestWorkspace } from '@blocksuite/store/test';
|
||||||
import { renderHook } from '@testing-library/react';
|
import { renderHook } from '@testing-library/react';
|
||||||
@@ -27,7 +27,7 @@ beforeEach(async () => {
|
|||||||
expect(page).not.toBeNull();
|
expect(page).not.toBeNull();
|
||||||
assertExists(page);
|
assertExists(page);
|
||||||
const pageBlockId = page.addBlock('affine:page', {
|
const pageBlockId = page.addBlock('affine:page', {
|
||||||
title: new page.Text(''),
|
title: new Text(''),
|
||||||
});
|
});
|
||||||
const frameId = page.addBlock('affine:note', {}, pageBlockId);
|
const frameId = page.addBlock('affine:note', {}, pageBlockId);
|
||||||
page.addBlock('affine:paragraph', {}, frameId);
|
page.addBlock('affine:paragraph', {}, frameId);
|
||||||
@@ -41,7 +41,7 @@ describe('useBlockSuitePagePreview', () => {
|
|||||||
const id = page.addBlock(
|
const id = page.addBlock(
|
||||||
'affine:paragraph',
|
'affine:paragraph',
|
||||||
{
|
{
|
||||||
text: new page.Text('Hello, world!'),
|
text: new Text('Hello, world!'),
|
||||||
},
|
},
|
||||||
page.getBlockByFlavour('affine:note')[0].id
|
page.getBlockByFlavour('affine:note')[0].id
|
||||||
);
|
);
|
||||||
@@ -58,7 +58,7 @@ describe('useBlockSuitePagePreview', () => {
|
|||||||
page.addBlock(
|
page.addBlock(
|
||||||
'affine:paragraph',
|
'affine:paragraph',
|
||||||
{
|
{
|
||||||
text: new page.Text('First block!'),
|
text: new Text('First block!'),
|
||||||
},
|
},
|
||||||
page.getBlockByFlavour('affine:note')[0].id,
|
page.getBlockByFlavour('affine:note')[0].id,
|
||||||
0
|
0
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { DebugLogger } from '@affine/debug';
|
|||||||
import { Unreachable } from '@affine/env/constant';
|
import { Unreachable } from '@affine/env/constant';
|
||||||
import type { DocMode } from '@blocksuite/affine/blocks';
|
import type { DocMode } from '@blocksuite/affine/blocks';
|
||||||
import type { DeltaInsert } from '@blocksuite/affine/inline';
|
import type { DeltaInsert } from '@blocksuite/affine/inline';
|
||||||
|
import { Text } from '@blocksuite/affine/store';
|
||||||
import type { AffineTextAttributes } from '@blocksuite/affine-shared/types';
|
import type { AffineTextAttributes } from '@blocksuite/affine-shared/types';
|
||||||
import { LiveData, ObjectPool, Service } from '@toeverything/infra';
|
import { LiveData, ObjectPool, Service } from '@toeverything/infra';
|
||||||
import { omitBy } from 'lodash-es';
|
import { omitBy } from 'lodash-es';
|
||||||
@@ -121,7 +122,7 @@ export class DocsService extends Service {
|
|||||||
const { doc, release } = this.open(targetDocId);
|
const { doc, release } = this.open(targetDocId);
|
||||||
doc.setPriorityLoad(10);
|
doc.setPriorityLoad(10);
|
||||||
await doc.waitForSyncReady();
|
await doc.waitForSyncReady();
|
||||||
const text = new doc.blockSuiteDoc.Text([
|
const text = new Text([
|
||||||
{
|
{
|
||||||
insert: ' ',
|
insert: ' ',
|
||||||
attributes: {
|
attributes: {
|
||||||
|
|||||||
383
packages/frontend/core/src/modules/workspace/impl/doc.ts
Normal file
383
packages/frontend/core/src/modules/workspace/impl/doc.ts
Normal file
@@ -0,0 +1,383 @@
|
|||||||
|
import { type Disposable, Slot } from '@blocksuite/affine/global/utils';
|
||||||
|
import {
|
||||||
|
type AwarenessStore,
|
||||||
|
Blocks,
|
||||||
|
type BlockSuiteDoc,
|
||||||
|
type Doc,
|
||||||
|
type GetDocOptions,
|
||||||
|
type Query,
|
||||||
|
type Workspace,
|
||||||
|
type YBlock,
|
||||||
|
} from '@blocksuite/affine/store';
|
||||||
|
import { signal } from '@preact/signals-core';
|
||||||
|
import * as Y from 'yjs';
|
||||||
|
|
||||||
|
type DocOptions = {
|
||||||
|
id: string;
|
||||||
|
collection: Workspace;
|
||||||
|
doc: BlockSuiteDoc;
|
||||||
|
awarenessStore: AwarenessStore;
|
||||||
|
};
|
||||||
|
|
||||||
|
export class DocImpl implements Doc {
|
||||||
|
private _awarenessUpdateDisposable: Disposable | null = null;
|
||||||
|
|
||||||
|
private readonly _canRedo = signal(false);
|
||||||
|
|
||||||
|
private readonly _canUndo = signal(false);
|
||||||
|
|
||||||
|
private readonly _collection: Workspace;
|
||||||
|
|
||||||
|
private readonly _docMap = {
|
||||||
|
undefined: new Map<string, Blocks>(),
|
||||||
|
true: new Map<string, Blocks>(),
|
||||||
|
false: new Map<string, Blocks>(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// doc/space container.
|
||||||
|
private readonly _handleYEvents = (events: Y.YEvent<YBlock | Y.Text>[]) => {
|
||||||
|
events.forEach(event => this._handleYEvent(event));
|
||||||
|
};
|
||||||
|
|
||||||
|
private _history!: Y.UndoManager;
|
||||||
|
|
||||||
|
private readonly _historyObserver = () => {
|
||||||
|
this._updateCanUndoRedoSignals();
|
||||||
|
this.slots.historyUpdated.emit();
|
||||||
|
};
|
||||||
|
|
||||||
|
private readonly _initSubDoc = () => {
|
||||||
|
let subDoc = this.rootDoc.spaces.get(this.id);
|
||||||
|
if (!subDoc) {
|
||||||
|
subDoc = new Y.Doc({
|
||||||
|
guid: this.id,
|
||||||
|
});
|
||||||
|
this.rootDoc.spaces.set(this.id, subDoc);
|
||||||
|
this._loaded = true;
|
||||||
|
this._onLoadSlot.emit();
|
||||||
|
} else {
|
||||||
|
this._loaded = false;
|
||||||
|
this.rootDoc.on('subdocs', this._onSubdocEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
return subDoc;
|
||||||
|
};
|
||||||
|
|
||||||
|
private _loaded!: boolean;
|
||||||
|
|
||||||
|
private readonly _onLoadSlot = new Slot();
|
||||||
|
|
||||||
|
private readonly _onSubdocEvent = ({
|
||||||
|
loaded,
|
||||||
|
}: {
|
||||||
|
loaded: Set<Y.Doc>;
|
||||||
|
}): void => {
|
||||||
|
const result = Array.from(loaded).find(
|
||||||
|
doc => doc.guid === this._ySpaceDoc.guid
|
||||||
|
);
|
||||||
|
if (!result) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.rootDoc.off('subdocs', this._onSubdocEvent);
|
||||||
|
this._loaded = true;
|
||||||
|
this._onLoadSlot.emit();
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Indicate whether the block tree is ready */
|
||||||
|
private _ready = false;
|
||||||
|
|
||||||
|
private _shouldTransact = true;
|
||||||
|
|
||||||
|
private readonly _updateCanUndoRedoSignals = () => {
|
||||||
|
const canRedo = this.readonly ? false : this._history.canRedo();
|
||||||
|
const canUndo = this.readonly ? false : this._history.canUndo();
|
||||||
|
if (this._canRedo.peek() !== canRedo) {
|
||||||
|
this._canRedo.value = canRedo;
|
||||||
|
}
|
||||||
|
if (this._canUndo.peek() !== canUndo) {
|
||||||
|
this._canUndo.value = canUndo;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
protected readonly _yBlocks: Y.Map<YBlock>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal Used for convenient access to the underlying Yjs map,
|
||||||
|
* can be used interchangeably with ySpace
|
||||||
|
*/
|
||||||
|
protected readonly _ySpaceDoc: Y.Doc;
|
||||||
|
|
||||||
|
readonly awarenessStore: AwarenessStore;
|
||||||
|
|
||||||
|
readonly id: string;
|
||||||
|
|
||||||
|
readonly rootDoc: BlockSuiteDoc;
|
||||||
|
|
||||||
|
readonly slots = {
|
||||||
|
historyUpdated: new Slot(),
|
||||||
|
yBlockUpdated: new Slot<
|
||||||
|
| {
|
||||||
|
type: 'add';
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: 'delete';
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
>(),
|
||||||
|
};
|
||||||
|
|
||||||
|
get blobSync() {
|
||||||
|
return this.collection.blobSync;
|
||||||
|
}
|
||||||
|
|
||||||
|
get canRedo() {
|
||||||
|
return this._canRedo.peek();
|
||||||
|
}
|
||||||
|
|
||||||
|
get canUndo() {
|
||||||
|
return this._canUndo.peek();
|
||||||
|
}
|
||||||
|
|
||||||
|
get collection() {
|
||||||
|
return this._collection;
|
||||||
|
}
|
||||||
|
|
||||||
|
get docSync() {
|
||||||
|
return this.collection.docSync;
|
||||||
|
}
|
||||||
|
|
||||||
|
get history() {
|
||||||
|
return this._history;
|
||||||
|
}
|
||||||
|
|
||||||
|
get isEmpty() {
|
||||||
|
return this._yBlocks.size === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
get loaded() {
|
||||||
|
return this._loaded;
|
||||||
|
}
|
||||||
|
|
||||||
|
get meta() {
|
||||||
|
return this.collection.meta.getDocMeta(this.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
get readonly(): boolean {
|
||||||
|
return this.awarenessStore.isReadonly(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
get ready() {
|
||||||
|
return this._ready;
|
||||||
|
}
|
||||||
|
|
||||||
|
get schema() {
|
||||||
|
return this.collection.schema;
|
||||||
|
}
|
||||||
|
|
||||||
|
get spaceDoc() {
|
||||||
|
return this._ySpaceDoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
get yBlocks() {
|
||||||
|
return this._yBlocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor({ id, collection, doc, awarenessStore }: DocOptions) {
|
||||||
|
this.id = id;
|
||||||
|
this.rootDoc = doc;
|
||||||
|
this.awarenessStore = awarenessStore;
|
||||||
|
|
||||||
|
this._ySpaceDoc = this._initSubDoc();
|
||||||
|
|
||||||
|
this._yBlocks = this._ySpaceDoc.getMap('blocks');
|
||||||
|
this._collection = collection;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _getReadonlyKey(readonly?: boolean): 'true' | 'false' | 'undefined' {
|
||||||
|
return (readonly?.toString() as 'true' | 'false') ?? 'undefined';
|
||||||
|
}
|
||||||
|
|
||||||
|
private _handleVersion() {
|
||||||
|
// Initialization from empty yDoc, indicating that the document is new.
|
||||||
|
if (!this.collection.meta.hasVersion) {
|
||||||
|
this.collection.meta.writeVersion(this.collection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private _handleYBlockAdd(id: string) {
|
||||||
|
this.slots.yBlockUpdated.emit({ type: 'add', id });
|
||||||
|
}
|
||||||
|
|
||||||
|
private _handleYBlockDelete(id: string) {
|
||||||
|
this.slots.yBlockUpdated.emit({ type: 'delete', id });
|
||||||
|
}
|
||||||
|
|
||||||
|
private _handleYEvent(event: Y.YEvent<YBlock | Y.Text | Y.Array<unknown>>) {
|
||||||
|
// event on top-level block store
|
||||||
|
if (event.target !== this._yBlocks) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
event.keys.forEach((value, id) => {
|
||||||
|
try {
|
||||||
|
if (value.action === 'add') {
|
||||||
|
this._handleYBlockAdd(id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (value.action === 'delete') {
|
||||||
|
this._handleYBlockDelete(id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('An error occurred while handling Yjs event:');
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private _initYBlocks() {
|
||||||
|
const { _yBlocks } = this;
|
||||||
|
_yBlocks.observeDeep(this._handleYEvents);
|
||||||
|
this._history = new Y.UndoManager([_yBlocks], {
|
||||||
|
trackedOrigins: new Set([this._ySpaceDoc.clientID]),
|
||||||
|
});
|
||||||
|
|
||||||
|
this._history.on('stack-cleared', this._historyObserver);
|
||||||
|
this._history.on('stack-item-added', this._historyObserver);
|
||||||
|
this._history.on('stack-item-popped', this._historyObserver);
|
||||||
|
this._history.on('stack-item-updated', this._historyObserver);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Capture current operations to undo stack synchronously. */
|
||||||
|
captureSync() {
|
||||||
|
this._history.stopCapturing();
|
||||||
|
}
|
||||||
|
|
||||||
|
clear() {
|
||||||
|
this._yBlocks.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
clearQuery(query: Query, readonly?: boolean) {
|
||||||
|
const readonlyKey = this._getReadonlyKey(readonly);
|
||||||
|
|
||||||
|
this._docMap[readonlyKey].delete(JSON.stringify(query));
|
||||||
|
}
|
||||||
|
|
||||||
|
private _destroy() {
|
||||||
|
this._ySpaceDoc.destroy();
|
||||||
|
this._onLoadSlot.dispose();
|
||||||
|
this._loaded = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
dispose() {
|
||||||
|
this.slots.historyUpdated.dispose();
|
||||||
|
this._awarenessUpdateDisposable?.dispose();
|
||||||
|
|
||||||
|
if (this.ready) {
|
||||||
|
this._yBlocks.unobserveDeep(this._handleYEvents);
|
||||||
|
this._yBlocks.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getDoc({ readonly, query }: GetDocOptions = {}) {
|
||||||
|
const readonlyKey = this._getReadonlyKey(readonly);
|
||||||
|
|
||||||
|
const key = JSON.stringify(query);
|
||||||
|
|
||||||
|
if (this._docMap[readonlyKey].has(key)) {
|
||||||
|
return this._docMap[readonlyKey].get(key) as Blocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
const doc = new Blocks({
|
||||||
|
blockCollection: this,
|
||||||
|
schema: this.collection.schema,
|
||||||
|
readonly,
|
||||||
|
query,
|
||||||
|
});
|
||||||
|
|
||||||
|
this._docMap[readonlyKey].set(key, doc);
|
||||||
|
|
||||||
|
return doc;
|
||||||
|
}
|
||||||
|
|
||||||
|
load(initFn?: () => void): this {
|
||||||
|
if (this.ready) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._ySpaceDoc.load();
|
||||||
|
|
||||||
|
if ((this.collection.meta.docs?.length ?? 0) <= 1) {
|
||||||
|
this._handleVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
this._initYBlocks();
|
||||||
|
|
||||||
|
this._yBlocks.forEach((_, id) => {
|
||||||
|
this._handleYBlockAdd(id);
|
||||||
|
});
|
||||||
|
|
||||||
|
this._awarenessUpdateDisposable = this.awarenessStore.slots.update.on(
|
||||||
|
() => {
|
||||||
|
// change readonly state will affect the undo/redo state
|
||||||
|
this._updateCanUndoRedoSignals();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
initFn?.();
|
||||||
|
|
||||||
|
this._ready = true;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
redo() {
|
||||||
|
if (this.readonly) {
|
||||||
|
console.error('cannot modify data in readonly mode');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._history.redo();
|
||||||
|
}
|
||||||
|
|
||||||
|
undo() {
|
||||||
|
if (this.readonly) {
|
||||||
|
console.error('cannot modify data in readonly mode');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._history.undo();
|
||||||
|
}
|
||||||
|
|
||||||
|
remove() {
|
||||||
|
this._destroy();
|
||||||
|
this.rootDoc.spaces.delete(this.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
resetHistory() {
|
||||||
|
this._history.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If `shouldTransact` is `false`, the transaction will not be push to the history stack.
|
||||||
|
*/
|
||||||
|
transact(fn: () => void, shouldTransact: boolean = this._shouldTransact) {
|
||||||
|
this._ySpaceDoc.transact(
|
||||||
|
() => {
|
||||||
|
try {
|
||||||
|
fn();
|
||||||
|
} catch (e) {
|
||||||
|
console.error(
|
||||||
|
`An error occurred while Y.doc ${this._ySpaceDoc.guid} transacting:`
|
||||||
|
);
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
shouldTransact ? this.rootDoc.clientID : null
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
withoutTransact(callback: () => void) {
|
||||||
|
this._shouldTransact = false;
|
||||||
|
callback();
|
||||||
|
this._shouldTransact = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,10 +6,10 @@ import type { BlockSuiteFlags } from '@blocksuite/affine/global/types';
|
|||||||
import { NoopLogger, Slot } from '@blocksuite/affine/global/utils';
|
import { NoopLogger, Slot } from '@blocksuite/affine/global/utils';
|
||||||
import {
|
import {
|
||||||
AwarenessStore,
|
AwarenessStore,
|
||||||
BlockCollection,
|
|
||||||
type Blocks,
|
type Blocks,
|
||||||
BlockSuiteDoc,
|
BlockSuiteDoc,
|
||||||
type CreateDocOptions,
|
type CreateDocOptions,
|
||||||
|
type Doc,
|
||||||
DocCollectionMeta,
|
DocCollectionMeta,
|
||||||
type GetDocOptions,
|
type GetDocOptions,
|
||||||
type IdGenerator,
|
type IdGenerator,
|
||||||
@@ -27,6 +27,8 @@ import {
|
|||||||
} from '@blocksuite/affine/sync';
|
} from '@blocksuite/affine/sync';
|
||||||
import { Awareness } from 'y-protocols/awareness.js';
|
import { Awareness } from 'y-protocols/awareness.js';
|
||||||
|
|
||||||
|
import { DocImpl } from './doc';
|
||||||
|
|
||||||
type WorkspaceOptions = {
|
type WorkspaceOptions = {
|
||||||
id?: string;
|
id?: string;
|
||||||
schema: Schema;
|
schema: Schema;
|
||||||
@@ -62,7 +64,7 @@ export class WorkspaceImpl implements Workspace {
|
|||||||
|
|
||||||
readonly blobSync: BlobEngine;
|
readonly blobSync: BlobEngine;
|
||||||
|
|
||||||
readonly blockCollections = new Map<string, BlockCollection>();
|
readonly blockCollections = new Map<string, Doc>();
|
||||||
|
|
||||||
readonly doc: BlockSuiteDoc;
|
readonly doc: BlockSuiteDoc;
|
||||||
|
|
||||||
@@ -114,12 +116,11 @@ export class WorkspaceImpl implements Workspace {
|
|||||||
|
|
||||||
private _bindDocMetaEvents() {
|
private _bindDocMetaEvents() {
|
||||||
this.meta.docMetaAdded.on(docId => {
|
this.meta.docMetaAdded.on(docId => {
|
||||||
const doc = new BlockCollection({
|
const doc = new DocImpl({
|
||||||
id: docId,
|
id: docId,
|
||||||
collection: this,
|
collection: this,
|
||||||
doc: this.doc,
|
doc: this.doc,
|
||||||
awarenessStore: this.awarenessStore,
|
awarenessStore: this.awarenessStore,
|
||||||
idGenerator: this.idGenerator,
|
|
||||||
});
|
});
|
||||||
this.blockCollections.set(doc.id, doc);
|
this.blockCollections.set(doc.id, doc);
|
||||||
});
|
});
|
||||||
@@ -185,8 +186,8 @@ export class WorkspaceImpl implements Workspace {
|
|||||||
this.awarenessSync.disconnect();
|
this.awarenessSync.disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
getBlockCollection(docId: string): BlockCollection | null {
|
getBlockCollection(docId: string): Doc | null {
|
||||||
const space = this.docs.get(docId) as BlockCollection | undefined;
|
const space = this.docs.get(docId) as Doc | undefined;
|
||||||
return space ?? null;
|
return space ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user