mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-12 12:28:42 +00:00
chore(editor): move legacy doc collection to test workspace (#9507)
This commit is contained in:
@@ -1,4 +1,8 @@
|
||||
import { DocCollection, IdGeneratorType, Schema } from '@blocksuite/store';
|
||||
import { Schema } from '@blocksuite/store';
|
||||
import {
|
||||
createAutoIncrementIdGenerator,
|
||||
TestWorkspace,
|
||||
} from '@blocksuite/store/test';
|
||||
import { describe, expect, test } from 'vitest';
|
||||
|
||||
import { effects } from '../effects.js';
|
||||
@@ -14,7 +18,7 @@ import { testSpecs } from './test-spec.js';
|
||||
effects();
|
||||
|
||||
function createTestOptions() {
|
||||
const idGenerator = IdGeneratorType.AutoIncrement;
|
||||
const idGenerator = createAutoIncrementIdGenerator();
|
||||
const schema = new Schema();
|
||||
schema.register([RootBlockSchema, NoteBlockSchema, HeadingBlockSchema]);
|
||||
return { id: 'test-collection', idGenerator, schema };
|
||||
@@ -26,7 +30,7 @@ function wait(time: number) {
|
||||
|
||||
describe('editor host', () => {
|
||||
test('editor host should rerender model when view changes', async () => {
|
||||
const collection = new DocCollection(createTestOptions());
|
||||
const collection = new TestWorkspace(createTestOptions());
|
||||
|
||||
collection.meta.initialize();
|
||||
const doc = collection.createDoc({ id: 'home' });
|
||||
|
||||
@@ -35,7 +35,8 @@
|
||||
"@types/lodash.merge": "^4.6.9"
|
||||
},
|
||||
"exports": {
|
||||
".": "./src/index.ts"
|
||||
".": "./src/index.ts",
|
||||
"./test": "./src/test/index.ts"
|
||||
},
|
||||
"files": [
|
||||
"src",
|
||||
|
||||
@@ -9,7 +9,8 @@ import {
|
||||
type SchemaToModel,
|
||||
} from '../schema/index.js';
|
||||
import { Block, type YBlock } from '../store/doc/block/index.js';
|
||||
import { DocCollection, IdGeneratorType } from '../store/index.js';
|
||||
import { TestWorkspace } from '../test/test-workspace.js';
|
||||
import { createAutoIncrementIdGenerator } from '../utils/id-generator.js';
|
||||
|
||||
const pageSchema = defineBlockSchema({
|
||||
flavour: 'page',
|
||||
@@ -28,7 +29,7 @@ const pageSchema = defineBlockSchema({
|
||||
type RootModel = SchemaToModel<typeof pageSchema>;
|
||||
|
||||
function createTestOptions() {
|
||||
const idGenerator = IdGeneratorType.AutoIncrement;
|
||||
const idGenerator = createAutoIncrementIdGenerator();
|
||||
const schema = new Schema();
|
||||
schema.register([pageSchema]);
|
||||
return { id: 'test-collection', idGenerator, schema };
|
||||
@@ -37,7 +38,7 @@ function createTestOptions() {
|
||||
const defaultDocId = 'doc:home';
|
||||
function createTestDoc(docId = defaultDocId) {
|
||||
const options = createTestOptions();
|
||||
const collection = new DocCollection(options);
|
||||
const collection = new TestWorkspace(options);
|
||||
collection.meta.initialize();
|
||||
const doc = collection.createDoc({ id: docId });
|
||||
doc.load();
|
||||
|
||||
@@ -6,8 +6,10 @@ import { applyUpdate, encodeStateAsUpdate } from 'yjs';
|
||||
|
||||
import { COLLECTION_VERSION, PAGE_VERSION } from '../consts.js';
|
||||
import type { BlockModel, BlockSchemaType, Doc } from '../index.js';
|
||||
import { DocCollection, IdGeneratorType, Schema } from '../index.js';
|
||||
import { Schema } from '../index.js';
|
||||
import type { DocMeta } from '../store/workspace.js';
|
||||
import { TestWorkspace } from '../test/test-workspace.js';
|
||||
import { createAutoIncrementIdGenerator } from '../utils/id-generator.js';
|
||||
import type { BlockSuiteDoc } from '../yjs/index.js';
|
||||
import {
|
||||
NoteBlockSchema,
|
||||
@@ -23,7 +25,7 @@ export const BlockSchemas = [
|
||||
] as BlockSchemaType[];
|
||||
|
||||
function createTestOptions() {
|
||||
const idGenerator = IdGeneratorType.AutoIncrement;
|
||||
const idGenerator = createAutoIncrementIdGenerator();
|
||||
const schema = new Schema();
|
||||
schema.register(BlockSchemas);
|
||||
return { id: 'test-collection', idGenerator, schema };
|
||||
@@ -60,7 +62,7 @@ function createRoot(doc: Doc) {
|
||||
|
||||
function createTestDoc(docId = defaultDocId) {
|
||||
const options = createTestOptions();
|
||||
const collection = new DocCollection(options);
|
||||
const collection = new TestWorkspace(options);
|
||||
collection.meta.initialize();
|
||||
const doc = collection.createDoc({ id: docId });
|
||||
doc.load();
|
||||
@@ -92,7 +94,7 @@ beforeEach(() => {
|
||||
describe('basic', () => {
|
||||
it('can init collection', () => {
|
||||
const options = createTestOptions();
|
||||
const collection = new DocCollection(options);
|
||||
const collection = new TestWorkspace(options);
|
||||
collection.meta.initialize();
|
||||
|
||||
const doc = collection.createDoc({ id: 'doc:home' });
|
||||
@@ -132,7 +134,7 @@ describe('basic', () => {
|
||||
it('init collection with custom id generator', () => {
|
||||
const options = createTestOptions();
|
||||
let id = 100;
|
||||
const collection = new DocCollection({
|
||||
const collection = new TestWorkspace({
|
||||
...options,
|
||||
idGenerator: () => {
|
||||
return String(id++);
|
||||
@@ -151,7 +153,7 @@ describe('basic', () => {
|
||||
|
||||
it('doc ready lifecycle', () => {
|
||||
const options = createTestOptions();
|
||||
const collection = new DocCollection(options);
|
||||
const collection = new TestWorkspace(options);
|
||||
collection.meta.initialize();
|
||||
const doc = collection.createDoc({
|
||||
id: 'space:0',
|
||||
@@ -176,9 +178,9 @@ describe('basic', () => {
|
||||
|
||||
it('collection docs with yjs applyUpdate', () => {
|
||||
const options = createTestOptions();
|
||||
const collection = new DocCollection(options);
|
||||
const collection = new TestWorkspace(options);
|
||||
collection.meta.initialize();
|
||||
const collection2 = new DocCollection(options);
|
||||
const collection2 = new TestWorkspace(options);
|
||||
const doc = collection.createDoc({
|
||||
id: 'space:0',
|
||||
});
|
||||
@@ -378,7 +380,7 @@ describe('addBlock', () => {
|
||||
|
||||
it('can add and remove multi docs', async () => {
|
||||
const options = createTestOptions();
|
||||
const collection = new DocCollection(options);
|
||||
const collection = new TestWorkspace(options);
|
||||
collection.meta.initialize();
|
||||
|
||||
const doc0 = collection.createDoc({ id: 'doc:home' });
|
||||
@@ -403,7 +405,7 @@ describe('addBlock', () => {
|
||||
|
||||
it('can remove doc that has not been loaded', () => {
|
||||
const options = createTestOptions();
|
||||
const collection = new DocCollection(options);
|
||||
const collection = new TestWorkspace(options);
|
||||
collection.meta.initialize();
|
||||
|
||||
const doc0 = collection.createDoc({ id: 'doc:home' });
|
||||
@@ -414,7 +416,7 @@ describe('addBlock', () => {
|
||||
|
||||
it('can set doc state', () => {
|
||||
const options = createTestOptions();
|
||||
const collection = new DocCollection(options);
|
||||
const collection = new TestWorkspace(options);
|
||||
collection.meta.initialize();
|
||||
collection.createDoc({ id: 'doc:home' });
|
||||
|
||||
@@ -456,7 +458,7 @@ describe('addBlock', () => {
|
||||
|
||||
it('can set collection common meta fields', async () => {
|
||||
const options = createTestOptions();
|
||||
const collection = new DocCollection(options);
|
||||
const collection = new TestWorkspace(options);
|
||||
|
||||
queueMicrotask(() => collection.meta.setName('hello'));
|
||||
await waitOnce(collection.meta.commonFieldsUpdated);
|
||||
@@ -863,7 +865,7 @@ describe('getBlock', () => {
|
||||
describe('flags', () => {
|
||||
it('update flags', () => {
|
||||
const options = createTestOptions();
|
||||
const collection = new DocCollection(options);
|
||||
const collection = new TestWorkspace(options);
|
||||
collection.meta.initialize();
|
||||
|
||||
const awareness = collection.awarenessStore;
|
||||
|
||||
@@ -2,11 +2,9 @@ import { expect, test, vi } from 'vitest';
|
||||
import * as Y from 'yjs';
|
||||
|
||||
import { Schema } from '../schema/index.js';
|
||||
import {
|
||||
BlockViewType,
|
||||
DocCollection,
|
||||
IdGeneratorType,
|
||||
} from '../store/index.js';
|
||||
import { BlockViewType } from '../store/index.js';
|
||||
import { TestWorkspace } from '../test/test-workspace.js';
|
||||
import { createAutoIncrementIdGenerator } from '../utils/id-generator.js';
|
||||
import {
|
||||
DividerBlockSchema,
|
||||
ListBlockSchema,
|
||||
@@ -25,7 +23,7 @@ const BlockSchemas = [
|
||||
];
|
||||
|
||||
function createTestOptions() {
|
||||
const idGenerator = IdGeneratorType.AutoIncrement;
|
||||
const idGenerator = createAutoIncrementIdGenerator();
|
||||
const schema = new Schema();
|
||||
schema.register(BlockSchemas);
|
||||
return { id: 'test-collection', idGenerator, schema };
|
||||
@@ -33,7 +31,7 @@ function createTestOptions() {
|
||||
|
||||
test('trigger props updated', () => {
|
||||
const options = createTestOptions();
|
||||
const collection = new DocCollection(options);
|
||||
const collection = new TestWorkspace(options);
|
||||
collection.meta.initialize();
|
||||
|
||||
const doc = collection.createDoc({ id: 'home' });
|
||||
@@ -93,7 +91,7 @@ test('trigger props updated', () => {
|
||||
|
||||
test('stash and pop', () => {
|
||||
const options = createTestOptions();
|
||||
const collection = new DocCollection(options);
|
||||
const collection = new TestWorkspace(options);
|
||||
collection.meta.initialize();
|
||||
|
||||
const doc = collection.createDoc({ id: 'home' });
|
||||
@@ -163,7 +161,7 @@ test('stash and pop', () => {
|
||||
|
||||
test('always get latest value in onChange', () => {
|
||||
const options = createTestOptions();
|
||||
const collection = new DocCollection(options);
|
||||
const collection = new TestWorkspace(options);
|
||||
collection.meta.initialize();
|
||||
|
||||
const doc = collection.createDoc({ id: 'home' });
|
||||
@@ -210,7 +208,7 @@ test('always get latest value in onChange', () => {
|
||||
|
||||
test('query', () => {
|
||||
const options = createTestOptions();
|
||||
const collection = new DocCollection(options);
|
||||
const collection = new TestWorkspace(options);
|
||||
collection.meta.initialize();
|
||||
const doc1 = collection.createDoc({ id: 'home' });
|
||||
doc1.load();
|
||||
@@ -247,7 +245,7 @@ test('query', () => {
|
||||
|
||||
test('local readonly', () => {
|
||||
const options = createTestOptions();
|
||||
const collection = new DocCollection(options);
|
||||
const collection = new TestWorkspace(options);
|
||||
collection.meta.initialize();
|
||||
const doc1 = collection.createDoc({ id: 'home' });
|
||||
doc1.load();
|
||||
|
||||
@@ -5,7 +5,8 @@ import { describe, expect, it, vi } from 'vitest';
|
||||
import { type BlockModel, defineBlockSchema } from '../schema/base.js';
|
||||
import { SchemaValidateError } from '../schema/error.js';
|
||||
import { Schema } from '../schema/index.js';
|
||||
import { DocCollection, IdGeneratorType } from '../store/index.js';
|
||||
import { TestWorkspace } from '../test/test-workspace.js';
|
||||
import { createAutoIncrementIdGenerator } from '../utils/id-generator.js';
|
||||
import {
|
||||
DividerBlockSchema,
|
||||
ListBlockSchema,
|
||||
@@ -15,7 +16,7 @@ import {
|
||||
} from './test-schema.js';
|
||||
|
||||
function createTestOptions() {
|
||||
const idGenerator = IdGeneratorType.AutoIncrement;
|
||||
const idGenerator = createAutoIncrementIdGenerator();
|
||||
const schema = new Schema();
|
||||
schema.register(BlockSchemas);
|
||||
return { id: 'test-collection', idGenerator, schema };
|
||||
@@ -60,7 +61,7 @@ const BlockSchemas = [
|
||||
const defaultDocId = 'doc0';
|
||||
function createTestDoc(docId = defaultDocId) {
|
||||
const options = createTestOptions();
|
||||
const collection = new DocCollection(options);
|
||||
const collection = new TestWorkspace(options);
|
||||
collection.meta.initialize();
|
||||
const doc = collection.createDoc({ id: docId });
|
||||
doc.load();
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import type { DocCollection } from '../store/index.js';
|
||||
import type { TestWorkspace } from '../test';
|
||||
|
||||
declare global {
|
||||
interface WindowEventMap {
|
||||
'test-result': CustomEvent<TestResult>;
|
||||
}
|
||||
interface Window {
|
||||
collection: DocCollection;
|
||||
collection: TestWorkspace;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,8 +9,9 @@ import {
|
||||
Schema,
|
||||
type SchemaToModel,
|
||||
} from '../schema/index.js';
|
||||
import { DocCollection, IdGeneratorType } from '../store/index.js';
|
||||
import { TestWorkspace } from '../test/test-workspace.js';
|
||||
import { AssetsManager, BaseBlockTransformer } from '../transformer/index.js';
|
||||
import { createAutoIncrementIdGenerator } from '../utils/id-generator.js';
|
||||
|
||||
const docSchema = defineBlockSchema({
|
||||
flavour: 'page',
|
||||
@@ -44,7 +45,7 @@ const docSchema = defineBlockSchema({
|
||||
type RootBlockModel = SchemaToModel<typeof docSchema>;
|
||||
|
||||
function createTestOptions() {
|
||||
const idGenerator = IdGeneratorType.AutoIncrement;
|
||||
const idGenerator = createAutoIncrementIdGenerator();
|
||||
const schema = new Schema();
|
||||
schema.register([docSchema]);
|
||||
return { id: 'test-collection', idGenerator, schema };
|
||||
@@ -56,7 +57,7 @@ const assets = new AssetsManager({ blob: blobCRUD });
|
||||
|
||||
test('model to snapshot', () => {
|
||||
const options = createTestOptions();
|
||||
const collection = new DocCollection(options);
|
||||
const collection = new TestWorkspace(options);
|
||||
collection.meta.initialize();
|
||||
const doc = collection.createDoc({ id: 'home' });
|
||||
doc.load();
|
||||
@@ -73,7 +74,7 @@ test('model to snapshot', () => {
|
||||
|
||||
test('snapshot to model', async () => {
|
||||
const options = createTestOptions();
|
||||
const collection = new DocCollection(options);
|
||||
const collection = new TestWorkspace(options);
|
||||
collection.meta.initialize();
|
||||
const doc = collection.createDoc({ id: 'home' });
|
||||
doc.load();
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
import {
|
||||
createAutoIncrementIdGenerator,
|
||||
createAutoIncrementIdGeneratorByClientId,
|
||||
type IdGenerator,
|
||||
nanoid,
|
||||
uuidv4,
|
||||
} from '../utils/id-generator.js';
|
||||
|
||||
export enum IdGeneratorType {
|
||||
/**
|
||||
* **Warning**: This generator mode will crash the collaborative feature
|
||||
* if multiple clients are adding new blocks.
|
||||
* Use this mode only if you know what you're doing.
|
||||
*/
|
||||
AutoIncrement = 'autoIncrement',
|
||||
|
||||
/**
|
||||
* This generator is trying to fix the real-time collaboration on debug mode.
|
||||
* This will make generator predictable and won't make conflict
|
||||
* @link https://docs.yjs.dev/api/faq#i-get-a-new-clientid-for-every-session-is-there-a-way-to-make-it-static-for-a-peer-accessing-the-doc
|
||||
*/
|
||||
AutoIncrementByClientId = 'autoIncrementByClientId',
|
||||
|
||||
/**
|
||||
* Default mode, generator for the unpredictable id
|
||||
*/
|
||||
NanoID = 'nanoID',
|
||||
UUIDv4 = 'uuidV4',
|
||||
}
|
||||
|
||||
export function pickIdGenerator(
|
||||
idGenerator: IdGeneratorType | IdGenerator | undefined,
|
||||
clientId: number
|
||||
) {
|
||||
if (typeof idGenerator === 'function') {
|
||||
return idGenerator;
|
||||
}
|
||||
|
||||
switch (idGenerator) {
|
||||
case IdGeneratorType.AutoIncrement: {
|
||||
return createAutoIncrementIdGenerator();
|
||||
}
|
||||
case IdGeneratorType.AutoIncrementByClientId: {
|
||||
return createAutoIncrementIdGeneratorByClientId(clientId);
|
||||
}
|
||||
case IdGeneratorType.UUIDv4: {
|
||||
return uuidv4;
|
||||
}
|
||||
case IdGeneratorType.NanoID:
|
||||
default: {
|
||||
return nanoid;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,4 @@
|
||||
export type * from './collection.js';
|
||||
export { DocCollection } from './collection.js';
|
||||
export type * from './doc/block-collection.js';
|
||||
export * from './doc/index.js';
|
||||
export * from './id.js';
|
||||
export * from './meta.js';
|
||||
export * from './workspace.js';
|
||||
|
||||
@@ -3,10 +3,10 @@ import type * as Y from 'yjs';
|
||||
|
||||
import { COLLECTION_VERSION, PAGE_VERSION } from '../consts.js';
|
||||
import type { BlockSuiteDoc } from '../yjs/index.js';
|
||||
import type { DocCollection } from './collection.js';
|
||||
import type {
|
||||
DocMeta,
|
||||
DocsPropertiesMeta,
|
||||
Workspace,
|
||||
WorkspaceMeta,
|
||||
} from './workspace.js';
|
||||
|
||||
@@ -231,7 +231,7 @@ export class DocCollectionMeta implements WorkspaceMeta {
|
||||
/**
|
||||
* @internal Only for doc initialization
|
||||
*/
|
||||
writeVersion(collection: DocCollection) {
|
||||
writeVersion(collection: Workspace) {
|
||||
const { blockVersions, pageVersion, workspaceVersion } = this._proxy;
|
||||
|
||||
if (!workspaceVersion) {
|
||||
|
||||
@@ -86,5 +86,5 @@ export interface Workspace {
|
||||
}
|
||||
|
||||
export interface StackItem {
|
||||
meta: Map<'cursor-location' | 'selection-state', unknown>;
|
||||
meta: Map<'selection-state', unknown>;
|
||||
}
|
||||
|
||||
2
blocksuite/framework/store/src/test/index.ts
Normal file
2
blocksuite/framework/store/src/test/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export { createAutoIncrementIdGenerator } from '../utils/id-generator.js';
|
||||
export * from './test-workspace.js';
|
||||
@@ -1,6 +1,6 @@
|
||||
import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions';
|
||||
import type { BlockSuiteFlags } from '@blocksuite/global/types';
|
||||
import { type Logger, NoopLogger, Slot } from '@blocksuite/global/utils';
|
||||
import { NoopLogger, Slot } from '@blocksuite/global/utils';
|
||||
import {
|
||||
AwarenessEngine,
|
||||
type AwarenessSource,
|
||||
@@ -16,29 +16,26 @@ import merge from 'lodash.merge';
|
||||
import { Awareness } from 'y-protocols/awareness.js';
|
||||
|
||||
import type { Schema } from '../schema/index.js';
|
||||
import type { IdGenerator } from '../utils/id-generator.js';
|
||||
import {
|
||||
BlockCollection,
|
||||
type CreateDocOptions,
|
||||
type Doc,
|
||||
DocCollectionMeta,
|
||||
type GetDocOptions,
|
||||
type Workspace,
|
||||
} from '../store/index.js';
|
||||
import { type IdGenerator, nanoid } from '../utils/id-generator.js';
|
||||
import {
|
||||
AwarenessStore,
|
||||
BlockSuiteDoc,
|
||||
type RawAwarenessState,
|
||||
} from '../yjs/index.js';
|
||||
import { BlockCollection } from './doc/block-collection.js';
|
||||
import type { Doc } from './doc/index.js';
|
||||
import type { IdGeneratorType } from './id.js';
|
||||
import { pickIdGenerator } from './id.js';
|
||||
import { DocCollectionMeta } from './meta.js';
|
||||
import type {
|
||||
CreateDocOptions,
|
||||
GetDocOptions,
|
||||
Workspace,
|
||||
} from './workspace.js';
|
||||
|
||||
export type DocCollectionOptions = {
|
||||
schema: Schema;
|
||||
id?: string;
|
||||
idGenerator?: IdGeneratorType | IdGenerator;
|
||||
idGenerator?: IdGenerator;
|
||||
defaultFlags?: Partial<BlockSuiteFlags>;
|
||||
logger?: Logger;
|
||||
docSources?: {
|
||||
main: DocSource;
|
||||
shadows?: DocSource[];
|
||||
@@ -70,7 +67,11 @@ const FLAGS_PRESET = {
|
||||
readonly: {},
|
||||
} satisfies BlockSuiteFlags;
|
||||
|
||||
export class DocCollection implements Workspace {
|
||||
/**
|
||||
* Test only
|
||||
* Do not use this in production
|
||||
*/
|
||||
export class TestWorkspace implements Workspace {
|
||||
protected readonly _schema: Schema;
|
||||
|
||||
readonly awarenessStore: AwarenessStore;
|
||||
@@ -117,7 +118,6 @@ export class DocCollection implements Workspace {
|
||||
blobSources = {
|
||||
main: new MemoryBlobSource(),
|
||||
},
|
||||
logger = new NoopLogger(),
|
||||
}: DocCollectionOptions) {
|
||||
this._schema = schema;
|
||||
|
||||
@@ -128,6 +128,8 @@ export class DocCollection implements Workspace {
|
||||
merge(clonedeep(FLAGS_PRESET), defaultFlags)
|
||||
);
|
||||
|
||||
const logger = new NoopLogger();
|
||||
|
||||
this.awarenessSync = new AwarenessEngine(
|
||||
this.awarenessStore.awareness,
|
||||
awarenessSources
|
||||
@@ -144,7 +146,7 @@ export class DocCollection implements Workspace {
|
||||
logger
|
||||
);
|
||||
|
||||
this.idGenerator = pickIdGenerator(idGenerator, this.doc.clientID);
|
||||
this.idGenerator = idGenerator ?? nanoid;
|
||||
|
||||
this.meta = new DocCollectionMeta(this.doc);
|
||||
this._bindDocMetaEvents();
|
||||
@@ -8,13 +8,6 @@ export function createAutoIncrementIdGenerator(): IdGenerator {
|
||||
return () => (i++).toString();
|
||||
}
|
||||
|
||||
export function createAutoIncrementIdGeneratorByClientId(
|
||||
clientId: number
|
||||
): IdGenerator {
|
||||
let i = 0;
|
||||
return () => `${clientId}:${i++}`;
|
||||
}
|
||||
|
||||
export const uuidv4: IdGenerator = () => {
|
||||
return uuidv4IdGenerator();
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user