mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-12 20:38:52 +00:00
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Introduced a new store management system for handling document stores, improving efficiency and flexibility when working with document data. - **Refactor** - Updated internal store handling to use a centralized store container, simplifying store retrieval and removal across various components. - Renamed and updated several store-related method signatures for consistency and clarity. - Replaced editor extension loading logic with a new local implementation for better modularity. - **Chores** - Improved and streamlined the export of store-related modules for better maintainability. - Removed obsolete and redundant code related to previous store management approaches. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
187 lines
3.5 KiB
TypeScript
187 lines
3.5 KiB
TypeScript
import * as Y from 'yjs';
|
|
|
|
import type { YBlock } from '../model/block/types.js';
|
|
import {
|
|
type Doc,
|
|
type GetStoreOptions,
|
|
StoreContainer,
|
|
type Workspace,
|
|
} from '../model/index.js';
|
|
import type { AwarenessStore } from '../yjs/index.js';
|
|
import type { TestWorkspace } from './test-workspace.js';
|
|
|
|
type DocOptions = {
|
|
id: string;
|
|
collection: Workspace;
|
|
doc: Y.Doc;
|
|
awarenessStore: AwarenessStore;
|
|
};
|
|
|
|
export class TestDoc implements Doc {
|
|
private readonly _collection: Workspace;
|
|
|
|
private readonly _storeContainer: StoreContainer;
|
|
|
|
private readonly _initSubDoc = () => {
|
|
let subDoc = this.rootDoc.getMap('spaces').get(this.id);
|
|
if (!subDoc) {
|
|
subDoc = new Y.Doc({
|
|
guid: this.id,
|
|
});
|
|
this.rootDoc.getMap('spaces').set(this.id, subDoc);
|
|
this._loaded = true;
|
|
} else {
|
|
this._loaded = false;
|
|
this.rootDoc.on('subdocs', this._onSubdocEvent);
|
|
}
|
|
|
|
return subDoc;
|
|
};
|
|
|
|
private _loaded!: boolean;
|
|
|
|
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;
|
|
};
|
|
|
|
/** Indicate whether the block tree is ready */
|
|
private _ready = false;
|
|
|
|
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: Y.Doc;
|
|
|
|
get blobSync() {
|
|
return this.workspace.blobSync;
|
|
}
|
|
|
|
get workspace() {
|
|
return this._collection;
|
|
}
|
|
|
|
get isEmpty() {
|
|
return this._yBlocks.size === 0;
|
|
}
|
|
|
|
get loaded() {
|
|
return this._loaded;
|
|
}
|
|
|
|
get meta() {
|
|
return this.workspace.meta.getDocMeta(this.id);
|
|
}
|
|
|
|
get ready() {
|
|
return this._ready;
|
|
}
|
|
|
|
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() as Y.Doc;
|
|
|
|
this._yBlocks = this._ySpaceDoc.getMap('blocks');
|
|
this._collection = collection;
|
|
this._storeContainer = new StoreContainer(this);
|
|
}
|
|
|
|
clear() {
|
|
this._yBlocks.clear();
|
|
}
|
|
|
|
get removeStore() {
|
|
return this._storeContainer.removeStore;
|
|
}
|
|
|
|
private _destroy() {
|
|
this._ySpaceDoc.destroy();
|
|
this._loaded = false;
|
|
}
|
|
|
|
dispose() {
|
|
if (this.ready) {
|
|
this._yBlocks.clear();
|
|
}
|
|
}
|
|
|
|
getStore({
|
|
readonly,
|
|
query,
|
|
provider,
|
|
extensions,
|
|
id,
|
|
}: GetStoreOptions = {}) {
|
|
const storeExtensions = (
|
|
this.workspace as TestWorkspace
|
|
).storeExtensions.concat(extensions ?? []);
|
|
|
|
let storeId: string | undefined;
|
|
|
|
if (id) {
|
|
storeId = id;
|
|
} else if (readonly !== undefined || query) {
|
|
storeId = id;
|
|
} else {
|
|
storeId = this.spaceDoc.guid;
|
|
}
|
|
|
|
return this._storeContainer.getStore({
|
|
id: storeId,
|
|
readonly,
|
|
query,
|
|
provider,
|
|
extensions: storeExtensions,
|
|
});
|
|
}
|
|
|
|
load(initFn?: () => void): this {
|
|
if (this.ready) {
|
|
return this;
|
|
}
|
|
|
|
this._ySpaceDoc.load();
|
|
|
|
initFn?.();
|
|
|
|
this._ready = true;
|
|
|
|
return this;
|
|
}
|
|
|
|
remove() {
|
|
this._destroy();
|
|
this.rootDoc.getMap('spaces').delete(this.id);
|
|
}
|
|
}
|