refactor(editor): should not rely on doc collection type (#9501)

This commit is contained in:
Saul-Mirone
2025-01-03 06:30:27 +00:00
parent cb5d7eaabc
commit 897c7d4284
55 changed files with 200 additions and 158 deletions
@@ -53,7 +53,7 @@ todoMeta.addProperty({
metaConfig: propertyPresets.textPropertyConfig, metaConfig: propertyPresets.textPropertyConfig,
get: block => block.doc.meta?.title ?? '', get: block => block.doc.meta?.title ?? '',
updated: (block, callback) => { updated: (block, callback) => {
return block.doc.collection.meta.docMetaUpdated.on(() => { return block.doc.collection.slots.docListUpdated.on(() => {
callback(); callback();
}); });
}, },
@@ -295,7 +295,7 @@ export class EmbedLinkedDocBlockComponent extends EmbedBlockComponent<EmbedLinke
const linkedDoc = this.linkedDoc; const linkedDoc = this.linkedDoc;
if (linkedDoc) { if (linkedDoc) {
this.disposables.add( this.disposables.add(
linkedDoc.collection.meta.docMetaUpdated.on(() => { linkedDoc.collection.slots.docListUpdated.on(() => {
this._load().catch(e => { this._load().catch(e => {
console.error(e); console.error(e);
this.isError = true; this.isError = true;
@@ -328,7 +328,7 @@ export class EmbedLinkedDocBlockComponent extends EmbedBlockComponent<EmbedLinke
this._setDocUpdatedAt(); this._setDocUpdatedAt();
this.disposables.add( this.disposables.add(
this.doc.collection.meta.docMetaUpdated.on(() => { this.doc.collection.slots.docListUpdated.on(() => {
this._setDocUpdatedAt(); this._setDocUpdatedAt();
}) })
); );
@@ -100,7 +100,7 @@ export class EmbedSyncedDocCard extends WithDisposable(ShadowlessElement) {
} }
this.disposables.add( this.disposables.add(
syncedDoc.collection.meta.docMetaUpdated.on(() => { syncedDoc.collection.slots.docListUpdated.on(() => {
renderLinkedDocInCard(this); renderLinkedDocInCard(this);
}) })
); );
@@ -475,7 +475,7 @@ export class EmbedSyncedDocBlockComponent extends EmbedBlockComponent<EmbedSynce
this._setDocUpdatedAt(); this._setDocUpdatedAt();
this.disposables.add( this.disposables.add(
this.doc.collection.meta.docMetaUpdated.on(() => { this.doc.collection.slots.docListUpdated.on(() => {
this._setDocUpdatedAt(); this._setDocUpdatedAt();
}) })
); );
@@ -221,7 +221,7 @@ export class AffineReference extends WithDisposable(ShadowlessElement) {
const doc = this.doc; const doc = this.doc;
if (doc) { if (doc) {
this._disposables.add( this._disposables.add(
doc.collection.slots.docUpdated.on(() => this._updateRefMeta(doc)) doc.collection.slots.docListUpdated.on(() => this._updateRefMeta(doc))
); );
} }
@@ -26,7 +26,6 @@ export type Attachment = File[];
type AttachmentToSliceSnapshotPayload = { type AttachmentToSliceSnapshotPayload = {
file: Attachment; file: Attachment;
assets?: AssetsManager; assets?: AssetsManager;
blockVersions: Record<string, number>;
workspaceId: string; workspaceId: string;
pageId: string; pageId: string;
}; };
@@ -46,7 +46,6 @@ export type Html = string;
type HtmlToSliceSnapshotPayload = { type HtmlToSliceSnapshotPayload = {
file: Html; file: Html;
assets?: AssetsManager; assets?: AssetsManager;
blockVersions: Record<string, number>;
workspaceId: string; workspaceId: string;
pageId: string; pageId: string;
}; };
@@ -26,7 +26,6 @@ export type Image = File[];
type ImageToSliceSnapshotPayload = { type ImageToSliceSnapshotPayload = {
file: Image; file: Image;
assets?: AssetsManager; assets?: AssetsManager;
blockVersions: Record<string, number>;
workspaceId: string; workspaceId: string;
pageId: string; pageId: string;
}; };
@@ -41,7 +41,6 @@ export type NotionHtml = string;
type NotionHtmlToSliceSnapshotPayload = { type NotionHtmlToSliceSnapshotPayload = {
file: NotionHtml; file: NotionHtml;
assets?: AssetsManager; assets?: AssetsManager;
blockVersions: Record<string, number>;
workspaceId: string; workspaceId: string;
pageId: string; pageId: string;
}; };
@@ -40,7 +40,6 @@ export type PlainText = string;
type PlainTextToSliceSnapshotPayload = { type PlainTextToSliceSnapshotPayload = {
file: PlainText; file: PlainText;
assets?: AssetsManager; assets?: AssetsManager;
blockVersions: Record<string, number>;
workspaceId: string; workspaceId: string;
pageId: string; pageId: string;
}; };
@@ -162,7 +162,7 @@ export class DocDisplayMetaService
if (!title$) { if (!title$) {
title$ = signal(doc.meta?.title || 'Untitled'); title$ = signal(doc.meta?.title || 'Untitled');
const disposable = this.std.collection.meta.docMetaUpdated.on(() => { const disposable = this.std.collection.slots.docListUpdated.on(() => {
title$!.value = doc.meta?.title || 'Untitled'; title$!.value = doc.meta?.title || 'Untitled';
}); });
@@ -1,7 +1,7 @@
import type { DocCollection } from '@blocksuite/store'; import type { Workspace } from '@blocksuite/store';
export function createDefaultDoc( export function createDefaultDoc(
collection: DocCollection, collection: Workspace,
options: { id?: string; title?: string } = {} options: { id?: string; title?: string } = {}
) { ) {
const doc = collection.createDoc({ id: options.id }); const doc = collection.createDoc({ id: options.id });
@@ -31,7 +31,6 @@ export type MixText = string;
type MixTextToSliceSnapshotPayload = { type MixTextToSliceSnapshotPayload = {
file: MixText; file: MixText;
assets?: AssetsManager; assets?: AssetsManager;
blockVersions: Record<string, number>;
workspaceId: string; workspaceId: string;
pageId: string; pageId: string;
}; };
@@ -1,7 +1,7 @@
import { HtmlAdapter } from '@blocksuite/affine-shared/adapters'; import { HtmlAdapter } from '@blocksuite/affine-shared/adapters';
import { Container } from '@blocksuite/global/di'; import { Container } from '@blocksuite/global/di';
import { sha } from '@blocksuite/global/utils'; import { sha } from '@blocksuite/global/utils';
import type { Doc, DocCollection } from '@blocksuite/store'; import type { Doc, Workspace } from '@blocksuite/store';
import { extMimeMap, Job } from '@blocksuite/store'; import { extMimeMap, Job } from '@blocksuite/store';
import { defaultBlockHtmlAdapterMatchers } from '../adapters/html/block-matcher.js'; import { defaultBlockHtmlAdapterMatchers } from '../adapters/html/block-matcher.js';
@@ -16,13 +16,13 @@ import {
import { createAssetsArchive, download, Unzip } from './utils.js'; import { createAssetsArchive, download, Unzip } from './utils.js';
type ImportHTMLToDocOptions = { type ImportHTMLToDocOptions = {
collection: DocCollection; collection: Workspace;
html: string; html: string;
fileName?: string; fileName?: string;
}; };
type ImportHTMLZipOptions = { type ImportHTMLZipOptions = {
collection: DocCollection; collection: Workspace;
imported: Blob; imported: Blob;
}; };
@@ -2,7 +2,7 @@ import { MarkdownAdapter } from '@blocksuite/affine-shared/adapters';
import { Container } from '@blocksuite/global/di'; import { Container } from '@blocksuite/global/di';
import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions'; import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions';
import { assertExists, sha } from '@blocksuite/global/utils'; import { assertExists, sha } from '@blocksuite/global/utils';
import type { Doc, DocCollection } from '@blocksuite/store'; import type { Doc, Workspace } from '@blocksuite/store';
import { extMimeMap, Job } from '@blocksuite/store'; import { extMimeMap, Job } from '@blocksuite/store';
import { defaultBlockMarkdownAdapterMatchers } from '../adapters/index.js'; import { defaultBlockMarkdownAdapterMatchers } from '../adapters/index.js';
@@ -34,13 +34,13 @@ type ImportMarkdownToBlockOptions = {
}; };
type ImportMarkdownToDocOptions = { type ImportMarkdownToDocOptions = {
collection: DocCollection; collection: Workspace;
markdown: string; markdown: string;
fileName?: string; fileName?: string;
}; };
type ImportMarkdownZipOptions = { type ImportMarkdownZipOptions = {
collection: DocCollection; collection: Workspace;
imported: Blob; imported: Blob;
}; };
@@ -1,7 +1,7 @@
import { NotionHtmlAdapter } from '@blocksuite/affine-shared/adapters'; import { NotionHtmlAdapter } from '@blocksuite/affine-shared/adapters';
import { Container } from '@blocksuite/global/di'; import { Container } from '@blocksuite/global/di';
import { sha } from '@blocksuite/global/utils'; import { sha } from '@blocksuite/global/utils';
import { type DocCollection, extMimeMap, Job } from '@blocksuite/store'; import { extMimeMap, Job, type Workspace } from '@blocksuite/store';
import { defaultBlockNotionHtmlAdapterMatchers } from '../adapters/notion-html/block-matcher.js'; import { defaultBlockNotionHtmlAdapterMatchers } from '../adapters/notion-html/block-matcher.js';
import { notionHtmlInlineToDeltaMatchers } from '../adapters/notion-html/delta-converter/html-inline.js'; import { notionHtmlInlineToDeltaMatchers } from '../adapters/notion-html/delta-converter/html-inline.js';
@@ -9,7 +9,7 @@ import { defaultImageProxyMiddleware } from './middlewares.js';
import { Unzip } from './utils.js'; import { Unzip } from './utils.js';
type ImportNotionZipOptions = { type ImportNotionZipOptions = {
collection: DocCollection; collection: Workspace;
imported: Blob; imported: Blob;
}; };
@@ -26,12 +26,11 @@ const provider = container.provider();
/** /**
* Imports a Notion zip file into the BlockSuite collection. * Imports a Notion zip file into the BlockSuite collection.
* *
* @param {ImportNotionZipOptions} options - The options for importing. * @param options - The options for importing.
* @param {DocCollection} options.collection - The BlockSuite document collection. * @param options.collection - The BlockSuite document collection.
* @param {Blob} options.imported - The imported zip file as a Blob. * @param options.imported - The imported zip file as a Blob.
* *
* @returns {Promise<{entryId: string | undefined, pageIds: string[], isWorkspaceFile: boolean, hasMarkdown: boolean}>} * @returns A promise that resolves to an object containing:
* A promise that resolves to an object containing:
* - entryId: The ID of the entry page (if any). * - entryId: The ID of the entry page (if any).
* - pageIds: An array of imported page IDs. * - pageIds: An array of imported page IDs.
* - isWorkspaceFile: Whether the imported file is a workspace file. * - isWorkspaceFile: Whether the imported file is a workspace file.
@@ -1,11 +1,11 @@
import { sha } from '@blocksuite/global/utils'; import { sha } from '@blocksuite/global/utils';
import type { Doc, DocCollection, DocSnapshot } from '@blocksuite/store'; import type { Doc, DocSnapshot, Workspace } from '@blocksuite/store';
import { extMimeMap, getAssetName, Job } from '@blocksuite/store'; import { extMimeMap, getAssetName, Job } from '@blocksuite/store';
import { download, Unzip, Zip } from '../transformers/utils.js'; import { download, Unzip, Zip } from '../transformers/utils.js';
import { replaceIdMiddleware, titleMiddleware } from './middlewares.js'; import { replaceIdMiddleware, titleMiddleware } from './middlewares.js';
async function exportDocs(collection: DocCollection, docs: Doc[]) { async function exportDocs(collection: Workspace, docs: Doc[]) {
const zip = new Zip(); const zip = new Zip();
const job = new Job({ const job = new Job({
schema: collection.schema, schema: collection.schema,
@@ -50,7 +50,7 @@ async function exportDocs(collection: DocCollection, docs: Doc[]) {
return download(downloadBlob, `${collection.id}.bs.zip`); return download(downloadBlob, `${collection.id}.bs.zip`);
} }
async function importDocs(collection: DocCollection, imported: Blob) { async function importDocs(collection: Workspace, imported: Blob) {
const unzip = new Unzip(); const unzip = new Unzip();
await unzip.load(imported); await unzip.load(imported);
@@ -8,7 +8,7 @@ import {
} from '@blocksuite/affine-components/icons'; } from '@blocksuite/affine-components/icons';
import { openFileOrFiles } from '@blocksuite/affine-shared/utils'; import { openFileOrFiles } from '@blocksuite/affine-shared/utils';
import { WithDisposable } from '@blocksuite/global/utils'; import { WithDisposable } from '@blocksuite/global/utils';
import type { DocCollection } from '@blocksuite/store'; import type { Workspace } from '@blocksuite/store';
import { html, LitElement, type PropertyValues } from 'lit'; import { html, LitElement, type PropertyValues } from 'lit';
import { query, state } from 'lit/decorators.js'; import { query, state } from 'lit/decorators.js';
@@ -30,7 +30,7 @@ export class ImportDoc extends WithDisposable(LitElement) {
static override styles = styles; static override styles = styles;
constructor( constructor(
private readonly collection: DocCollection, private readonly collection: Workspace,
private readonly onSuccess?: OnSuccessHandler, private readonly onSuccess?: OnSuccessHandler,
private readonly onFail?: OnFailHandler, private readonly onFail?: OnFailHandler,
private readonly abortController = new AbortController() private readonly abortController = new AbortController()
@@ -1,4 +1,4 @@
import type { DocCollection } from '@blocksuite/store'; import type { Workspace } from '@blocksuite/store';
import { import {
ImportDoc, ImportDoc,
@@ -13,7 +13,7 @@ export function showImportModal({
container = document.body, container = document.body,
abortController = new AbortController(), abortController = new AbortController(),
}: { }: {
collection: DocCollection; collection: Workspace;
onSuccess?: OnSuccessHandler; onSuccess?: OnSuccessHandler;
onFail?: OnFailHandler; onFail?: OnFailHandler;
multiple?: boolean; multiple?: boolean;
@@ -138,7 +138,6 @@ export class Clipboard extends LifeCycleWatcher {
const payload = { const payload = {
file: item, file: item,
assets: job.assetsManager, assets: job.assetsManager,
blockVersions: doc.collection.meta.blockVersions,
workspaceId: doc.collection.id, workspaceId: doc.collection.id,
pageId: doc.id, pageId: doc.id,
}; };
@@ -7,7 +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, BlockSchemaType, Doc } from '../index.js'; import type { BlockModel, BlockSchemaType, Doc } from '../index.js';
import { DocCollection, IdGeneratorType, Schema } from '../index.js'; import { DocCollection, IdGeneratorType, Schema } from '../index.js';
import type { DocMeta } from '../store/index.js'; import type { DocMeta } from '../store/workspace.js';
import type { BlockSuiteDoc } from '../yjs/index.js'; import type { BlockSuiteDoc } from '../yjs/index.js';
import { import {
NoteBlockSchema, NoteBlockSchema,
@@ -432,7 +432,7 @@ describe('addBlock', () => {
); );
let called = false; let called = false;
collection.meta.docMetaUpdated.on(() => { collection.slots.docListUpdated.on(() => {
called = true; called = true;
}); });
@@ -22,11 +22,16 @@ import {
BlockSuiteDoc, BlockSuiteDoc,
type RawAwarenessState, type RawAwarenessState,
} from '../yjs/index.js'; } from '../yjs/index.js';
import { BlockCollection, type GetDocOptions } from './doc/block-collection.js'; import { BlockCollection } from './doc/block-collection.js';
import type { Doc, Query } from './doc/index.js'; import type { Doc } from './doc/index.js';
import type { IdGeneratorType } from './id.js'; import type { IdGeneratorType } from './id.js';
import { pickIdGenerator } from './id.js'; import { pickIdGenerator } from './id.js';
import { DocCollectionMeta } from './meta.js'; import { DocCollectionMeta } from './meta.js';
import type {
CreateDocOptions,
GetDocOptions,
Workspace,
} from './workspace.js';
export type DocCollectionOptions = { export type DocCollectionOptions = {
schema: Schema; schema: Schema;
@@ -69,7 +74,7 @@ export interface StackItem {
meta: Map<'cursor-location' | 'selection-state', unknown>; meta: Map<'cursor-location' | 'selection-state', unknown>;
} }
export class DocCollection { export class DocCollection implements Workspace {
protected readonly _schema: Schema; protected readonly _schema: Schema;
readonly awarenessStore: AwarenessStore; readonly awarenessStore: AwarenessStore;
@@ -91,7 +96,7 @@ export class DocCollection {
meta: DocCollectionMeta; meta: DocCollectionMeta;
slots = { slots = {
docUpdated: new Slot(), docListUpdated: new Slot(),
docRemoved: new Slot<string>(), docRemoved: new Slot<string>(),
docCreated: new Slot<string>(), docCreated: new Slot<string>(),
}; };
@@ -161,7 +166,7 @@ export class DocCollection {
this.blockCollections.set(doc.id, doc); this.blockCollections.set(doc.id, doc);
}); });
this.meta.docMetaUpdated.on(() => this.slots.docUpdated.emit()); this.meta.docMetaUpdated.on(() => this.slots.docListUpdated.emit());
this.meta.docMetaRemoved.on(id => { this.meta.docMetaRemoved.on(id => {
const space = this.getBlockCollection(id); const space = this.getBlockCollection(id);
@@ -189,8 +194,8 @@ export class DocCollection {
* If the `init` parameter is passed, a `surface`, `note`, and `paragraph` block * If the `init` parameter is passed, a `surface`, `note`, and `paragraph` block
* will be created in the doc simultaneously. * will be created in the doc simultaneously.
*/ */
createDoc(options: { id?: string; query?: Query } = {}) { createDoc(options: CreateDocOptions = {}) {
const { id: docId = this.idGenerator(), query } = options; const { id: docId = this.idGenerator(), query, readonly } = options;
if (this._hasDoc(docId)) { if (this._hasDoc(docId)) {
throw new BlockSuiteError( throw new BlockSuiteError(
ErrorCode.DocCollectionError, ErrorCode.DocCollectionError,
@@ -205,7 +210,7 @@ export class DocCollection {
tags: [], tags: [],
}); });
this.slots.docCreated.emit(docId); this.slots.docCreated.emit(docId);
return this.getDoc(docId, { query }) as Doc; return this.getDoc(docId, { query, readonly }) as Doc;
} }
dispose() { dispose() {
@@ -7,7 +7,7 @@ import { Text } from '../../reactive/text.js';
import type { BlockModel } from '../../schema/base.js'; import type { BlockModel } from '../../schema/base.js';
import type { IdGenerator } from '../../utils/id-generator.js'; import type { IdGenerator } from '../../utils/id-generator.js';
import type { AwarenessStore, BlockSuiteDoc } from '../../yjs/index.js'; import type { AwarenessStore, BlockSuiteDoc } from '../../yjs/index.js';
import type { DocCollection } from '../collection.js'; import type { GetDocOptions, Workspace } from '../workspace.js';
import { Doc } from './doc.js'; import { Doc } from './doc.js';
import type { YBlock } from './index.js'; import type { YBlock } from './index.js';
import type { Query } from './query.js'; import type { Query } from './query.js';
@@ -24,17 +24,12 @@ export type BlockProps = BlockSysProps & Record<string, unknown>;
type DocOptions = { type DocOptions = {
id: string; id: string;
collection: DocCollection; collection: Workspace;
doc: BlockSuiteDoc; doc: BlockSuiteDoc;
awarenessStore: AwarenessStore; awarenessStore: AwarenessStore;
idGenerator?: IdGenerator; idGenerator?: IdGenerator;
}; };
export type GetDocOptions = {
query?: Query;
readonly?: boolean;
};
export class BlockCollection { export class BlockCollection {
private _awarenessUpdateDisposable: Disposable | null = null; private _awarenessUpdateDisposable: Disposable | null = null;
@@ -42,7 +37,7 @@ export class BlockCollection {
private readonly _canUndo$ = signal(false); private readonly _canUndo$ = signal(false);
private readonly _collection: DocCollection; private readonly _collection: Workspace;
private readonly _docMap = { private readonly _docMap = {
undefined: new Map<string, Doc>(), undefined: new Map<string, Doc>(),
@@ -145,11 +140,6 @@ export class BlockCollection {
>(), >(),
}; };
// So, we apply a listener at the top level for the flat structure of the current
get awarenessSync() {
return this.collection.awarenessSync;
}
get blobSync() { get blobSync() {
return this.collection.blobSync; return this.collection.blobSync;
} }
@@ -4,3 +4,4 @@ export type * from './doc/block-collection.js';
export * from './doc/index.js'; export * from './doc/index.js';
export * from './id.js'; export * from './id.js';
export type * from './meta.js'; export type * from './meta.js';
export * from './workspace.js';
+6 -20
View File
@@ -4,26 +4,12 @@ import type * as Y from 'yjs';
import { COLLECTION_VERSION, PAGE_VERSION } from '../consts.js'; import { COLLECTION_VERSION, PAGE_VERSION } from '../consts.js';
import type { BlockSuiteDoc } from '../yjs/index.js'; import type { BlockSuiteDoc } from '../yjs/index.js';
import type { DocCollection } from './collection.js'; import type { DocCollection } from './collection.js';
import type {
DocMeta,
DocsPropertiesMeta,
WorkspaceMeta,
} from './workspace.js';
// please use `declare module '@blocksuite/store'` to extend this interface
export interface DocMeta {
id: string;
title: string;
tags: string[];
createDate: number;
updatedDate?: number;
}
export type Tag = {
id: string;
value: string;
color: string;
};
export type DocsPropertiesMeta = {
tags?: {
options: Tag[];
};
};
export type DocCollectionMetaState = { export type DocCollectionMetaState = {
pages?: unknown[]; pages?: unknown[];
properties?: DocsPropertiesMeta; properties?: DocsPropertiesMeta;
@@ -34,7 +20,7 @@ export type DocCollectionMetaState = {
avatar?: string; avatar?: string;
}; };
export class DocCollectionMeta { export class DocCollectionMeta implements WorkspaceMeta {
private readonly _handleDocCollectionMetaEvents = ( private readonly _handleDocCollectionMetaEvents = (
events: Y.YEvent<Y.Array<unknown> | Y.Text | Y.Map<unknown>>[] events: Y.YEvent<Y.Array<unknown> | Y.Text | Y.Map<unknown>>[]
) => { ) => {
@@ -0,0 +1,86 @@
import type { Slot } from '@blocksuite/global/utils';
import type { BlobEngine, DocEngine } from '@blocksuite/sync';
import type { Schema } from '../schema/schema.js';
import type { IdGenerator } from '../utils/id-generator.js';
import type { AwarenessStore } from '../yjs/awareness.js';
import type { BlockSuiteDoc } from '../yjs/doc.js';
import type { Doc } from './doc/doc.js';
import type { BlockCollection } from './doc/index.js';
import type { Query } from './doc/query.js';
export type Tag = {
id: string;
value: string;
color: string;
};
export type DocsPropertiesMeta = {
tags?: {
options: Tag[];
};
};
export interface DocMeta {
id: string;
title: string;
tags: string[];
createDate: number;
updatedDate?: number;
favorite?: boolean;
}
export type GetDocOptions = {
query?: Query;
readonly?: boolean;
};
export type CreateDocOptions = GetDocOptions & {
id?: string;
};
export interface WorkspaceMeta {
get docMetas(): DocMeta[];
getDocMeta(id: string): DocMeta | undefined;
setDocMeta(id: string, props: Partial<DocMeta>): void;
removeDocMeta(id: string): void;
get properties(): DocsPropertiesMeta;
setProperties(meta: DocsPropertiesMeta): void;
get avatar(): string | undefined;
setAvatar(avatar: string): void;
get name(): string | undefined;
setName(name: string): void;
commonFieldsUpdated: Slot;
hasVersion: boolean;
writeVersion(workspace: Workspace): void;
get docs(): unknown[] | undefined;
initialize(): void;
}
export interface Workspace {
readonly id: string;
readonly meta: WorkspaceMeta;
readonly idGenerator: IdGenerator;
readonly docSync: DocEngine;
readonly blobSync: BlobEngine;
readonly awarenessStore: AwarenessStore;
get schema(): Schema;
get doc(): BlockSuiteDoc;
get docs(): Map<string, BlockCollection>;
slots: {
docListUpdated: Slot;
docCreated: Slot<string>;
docRemoved: Slot<string>;
};
createDoc(options?: CreateDocOptions): Doc;
getDoc(docId: string, options?: GetDocOptions): Doc | null;
removeDoc(docId: string): void;
dispose(): void;
}
@@ -1,7 +1,7 @@
import { z } from 'zod'; import { z } from 'zod';
import type { Doc } from '../store/doc/doc.js'; import type { Doc } from '../store/doc/doc.js';
import type { DocMeta, DocsPropertiesMeta } from '../store/meta.js'; import type { DocMeta, DocsPropertiesMeta } from '../store/workspace.js';
export type BlockSnapshot = { export type BlockSnapshot = {
type: 'block'; type: 'block';
@@ -110,7 +110,7 @@ export class DocsPanel extends WithDisposable(ShadowlessElement) {
}); });
this.disposables.add( this.disposables.add(
this.editor.doc.collection.slots.docUpdated.on(() => { this.editor.doc.collection.slots.docListUpdated.on(() => {
this.requestUpdate(); this.requestUpdate();
}) })
); );
@@ -1,8 +1,8 @@
import { replaceIdMiddleware } from '@blocksuite/blocks'; import { replaceIdMiddleware } from '@blocksuite/blocks';
import { type DocCollection, type DocSnapshot, Job } from '@blocksuite/store'; import { type DocSnapshot, Job, type Workspace } from '@blocksuite/store';
export async function importFromSnapshot( export async function importFromSnapshot(
collection: DocCollection, collection: Workspace,
snapshot: DocSnapshot snapshot: DocSnapshot
) { ) {
const job = new Job({ const job = new Job({
@@ -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, DocCollection, Job } from '@store/index.js'; import type { BlockModel, Doc, Job, Workspace } from '@store/index.js';
declare global { declare global {
interface Window { interface Window {
@@ -36,7 +36,7 @@ declare global {
mockDocModeService: typeof import('../../packages/playground/apps/_common/mock-services.js').mockDocModeService; mockDocModeService: typeof import('../../packages/playground/apps/_common/mock-services.js').mockDocModeService;
}; };
}; };
collection: DocCollection; collection: Workspace;
blockSchema: Record<string, typeof BlockModel>; blockSchema: Record<string, typeof BlockModel>;
doc: Doc; doc: Doc;
debugMenu: StarterDebugMenu; debugMenu: StarterDebugMenu;
+3 -3
View File
@@ -1,7 +1,7 @@
// This file should has not side effect // This file should has not side effect
// oxlint-disable-next-line // oxlint-disable-next-line
// @ts-ignore FIXME: typecheck error // @ts-ignore FIXME: typecheck error
import type { DocCollection } from '@blocksuite/affine/store'; import type { Workspace } from '@blocksuite/affine/store';
declare global { declare global {
// oxlint-disable-next-line no-var // oxlint-disable-next-line no-var
@@ -91,10 +91,10 @@ export const Messages = {
}; };
export class PageNotFoundError extends TypeError { export class PageNotFoundError extends TypeError {
readonly docCollection: DocCollection; readonly docCollection: Workspace;
readonly pageId: string; readonly pageId: string;
constructor(docCollection: DocCollection, pageId: string) { constructor(docCollection: Workspace, pageId: string) {
super(); super();
this.docCollection = docCollection; this.docCollection = docCollection;
this.pageId = pageId; this.pageId = pageId;
+2 -3
View File
@@ -1,4 +1,4 @@
import type { DocCollection } from '@blocksuite/affine/store'; import type { DocsPropertiesMeta } from '@blocksuite/affine/store';
import { z } from 'zod'; import { z } from 'zod';
export const literalValueSchema: z.ZodType<LiteralValue, z.ZodTypeDef> = export const literalValueSchema: z.ZodType<LiteralValue, z.ZodTypeDef> =
@@ -29,7 +29,6 @@ export type Ref = {
name: keyof VariableMap; name: keyof VariableMap;
}; };
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface VariableMap {} export interface VariableMap {}
export const literalSchema = z.object({ export const literalSchema = z.object({
@@ -85,4 +84,4 @@ export const tagSchema = z.object({
}); });
export type Tag = z.input<typeof tagSchema>; export type Tag = z.input<typeof tagSchema>;
export type PropertiesMeta = DocCollection['meta']['properties']; export type PropertiesMeta = DocsPropertiesMeta;
@@ -145,18 +145,9 @@ export const markdownToSnapshot = async (
middlewares: [defaultImageProxyMiddleware, pasteMiddleware(host.std)], middlewares: [defaultImageProxyMiddleware, pasteMiddleware(host.std)],
}); });
const markdownAdapter = new MixTextAdapter(job, host.std.provider); const markdownAdapter = new MixTextAdapter(job, host.std.provider);
const { blockVersions, workspaceVersion, pageVersion } =
host.std.doc.collection.meta;
if (!blockVersions || !workspaceVersion || !pageVersion)
throw new Error(
'Need blockVersions, workspaceVersion, pageVersion meta information to get slice'
);
const payload = { const payload = {
file: markdown, file: markdown,
assets: job.assetsManager, assets: job.assetsManager,
blockVersions,
pageVersion,
workspaceVersion,
workspaceId: host.std.doc.collection.id, workspaceId: host.std.doc.collection.id,
pageId: host.std.doc.id, pageId: host.std.doc.id,
}; };
@@ -1,6 +1,6 @@
import type { useI18n } from '@affine/i18n'; import type { useI18n } from '@affine/i18n';
import { track } from '@affine/track'; import { track } from '@affine/track';
import type { DocCollection } from '@blocksuite/affine/store'; import type { Workspace } from '@blocksuite/affine/store';
import { ArrowRightBigIcon } from '@blocksuite/icons/rc'; import { ArrowRightBigIcon } from '@blocksuite/icons/rc';
import type { createStore } from 'jotai'; import type { createStore } from 'jotai';
@@ -19,7 +19,7 @@ export function registerAffineNavigationCommands({
t: ReturnType<typeof useI18n>; t: ReturnType<typeof useI18n>;
store: ReturnType<typeof createStore>; store: ReturnType<typeof createStore>;
navigationHelper: ReturnType<typeof useNavigateHelper>; navigationHelper: ReturnType<typeof useNavigateHelper>;
docCollection: DocCollection; docCollection: Workspace;
globalDialogService: GlobalDialogService; globalDialogService: GlobalDialogService;
}) { }) {
const unsubs: Array<() => void> = []; const unsubs: Array<() => void> = [];
@@ -7,7 +7,7 @@ import type { ListHistoryQuery } from '@affine/graphql';
import { listHistoryQuery, recoverDocMutation } from '@affine/graphql'; import { listHistoryQuery, recoverDocMutation } from '@affine/graphql';
import { i18nTime } from '@affine/i18n'; import { i18nTime } from '@affine/i18n';
import { assertEquals } from '@blocksuite/affine/global/utils'; import { assertEquals } from '@blocksuite/affine/global/utils';
import { DocCollection } from '@blocksuite/affine/store'; import { DocCollection, type Workspace } from '@blocksuite/affine/store';
import { useService } from '@toeverything/infra'; import { useService } from '@toeverything/infra';
import { useEffect, useMemo } from 'react'; import { useEffect, useMemo } from 'react';
import useSWRImmutable from 'swr/immutable'; import useSWRImmutable from 'swr/immutable';
@@ -99,7 +99,7 @@ const snapshotFetcher = async (
// so that we do not need to worry about providers etc // so that we do not need to worry about providers etc
// TODO(@Peng): fix references to the page (the referenced page will shown as deleted) // TODO(@Peng): fix references to the page (the referenced page will shown as deleted)
// if we simply clone the current workspace, it maybe time consuming right? // if we simply clone the current workspace, it maybe time consuming right?
const docCollectionMap = new Map<string, DocCollection>(); const docCollectionMap = new Map<string, Workspace>();
// assume the workspace is a cloud workspace since the history feature is only enabled for cloud workspace // assume the workspace is a cloud workspace since the history feature is only enabled for cloud workspace
const getOrCreateShellWorkspace = ( const getOrCreateShellWorkspace = (
@@ -147,7 +147,7 @@ export const usePageHistory = (
// workspace id + page id + timestamp + snapshot -> Page (to be used for rendering in blocksuite editor) // workspace id + page id + timestamp + snapshot -> Page (to be used for rendering in blocksuite editor)
export const useSnapshotPage = ( export const useSnapshotPage = (
docCollection: DocCollection, docCollection: Workspace,
pageDocId: string, pageDocId: string,
ts?: string ts?: string
) => { ) => {
@@ -253,10 +253,7 @@ export function revertUpdate(
applyUpdate(doc, revertChangesSinceSnapshotUpdate); applyUpdate(doc, revertChangesSinceSnapshotUpdate);
} }
export const useRestorePage = ( export const useRestorePage = (docCollection: Workspace, pageId: string) => {
docCollection: DocCollection,
pageId: string
) => {
const page = useDocCollectionPage(docCollection, pageId); const page = useDocCollectionPage(docCollection, pageId);
const mutateQueryResource = useMutateQueryResource(); const mutateQueryResource = useMutateQueryResource();
const { trigger: recover, isMutating } = useMutation({ const { trigger: recover, isMutating } = useMutation({
@@ -11,10 +11,7 @@ import { WorkspaceService } from '@affine/core/modules/workspace';
import { i18nTime, Trans, useI18n } from '@affine/i18n'; import { i18nTime, Trans, useI18n } from '@affine/i18n';
import { track } from '@affine/track'; import { track } from '@affine/track';
import type { DocMode } from '@blocksuite/affine/blocks'; import type { DocMode } from '@blocksuite/affine/blocks';
import type { import type { Doc as BlockSuiteDoc, Workspace } from '@blocksuite/affine/store';
Doc as BlockSuiteDoc,
DocCollection,
} from '@blocksuite/affine/store';
import { CloseIcon, ToggleCollapseIcon } from '@blocksuite/icons/rc'; import { CloseIcon, ToggleCollapseIcon } from '@blocksuite/icons/rc';
import * as Collapsible from '@radix-ui/react-collapsible'; import * as Collapsible from '@radix-ui/react-collapsible';
import type { DialogContentProps } from '@radix-ui/react-dialog'; import type { DialogContentProps } from '@radix-ui/react-dialog';
@@ -48,7 +45,7 @@ import * as styles from './styles.css';
export interface PageHistoryModalProps { export interface PageHistoryModalProps {
open: boolean; open: boolean;
onOpenChange: (open: boolean) => void; onOpenChange: (open: boolean) => void;
docCollection: DocCollection; docCollection: Workspace;
pageId: string; pageId: string;
} }
@@ -400,7 +397,7 @@ const PageHistoryManager = ({
pageId, pageId,
onClose, onClose,
}: { }: {
docCollection: DocCollection; docCollection: Workspace;
pageId: string; pageId: string;
onClose: () => void; onClose: () => void;
}) => { }) => {
@@ -6,7 +6,7 @@ import { useInsidePeekView } from '@affine/core/modules/peek-view/view/modal-con
import { WorkbenchLink } from '@affine/core/modules/workbench'; import { WorkbenchLink } from '@affine/core/modules/workbench';
import { track } from '@affine/track'; import { track } from '@affine/track';
import type { DocMode } from '@blocksuite/affine/blocks'; import type { DocMode } from '@blocksuite/affine/blocks';
import type { DocCollection } from '@blocksuite/affine/store'; import type { Workspace } from '@blocksuite/affine/store';
import { LiveData, useLiveData, useService } from '@toeverything/infra'; import { LiveData, useLiveData, useService } from '@toeverything/infra';
import clsx from 'clsx'; import clsx from 'clsx';
import { nanoid } from 'nanoid'; import { nanoid } from 'nanoid';
@@ -167,7 +167,7 @@ export function AffineSharedPageReference({
Icon, Icon,
onClick: userOnClick, onClick: userOnClick,
}: AffinePageReferenceProps & { }: AffinePageReferenceProps & {
docCollection: DocCollection; docCollection: Workspace;
}) { }) {
const journalService = useService(JournalService); const journalService = useService(JournalService);
const isJournal = !!useLiveData(journalService.journalDate$(pageId)); const isJournal = !!useLiveData(journalService.journalDate$(pageId));
@@ -5,11 +5,11 @@ import { DocsService } from '@affine/core/modules/doc';
import { EditorSettingService } from '@affine/core/modules/editor-setting'; import { EditorSettingService } from '@affine/core/modules/editor-setting';
import { WorkbenchService } from '@affine/core/modules/workbench'; import { WorkbenchService } from '@affine/core/modules/workbench';
import { type DocMode } from '@blocksuite/affine/blocks'; import { type DocMode } from '@blocksuite/affine/blocks';
import type { DocCollection } from '@blocksuite/affine/store'; import type { Workspace } from '@blocksuite/affine/store';
import { useServices } from '@toeverything/infra'; import { useServices } from '@toeverything/infra';
import { useCallback, useMemo } from 'react'; import { useCallback, useMemo } from 'react';
export const usePageHelper = (docCollection: DocCollection) => { export const usePageHelper = (docCollection: Workspace) => {
const { const {
docsService, docsService,
workbenchService, workbenchService,
@@ -6,13 +6,13 @@ import { ShareDocsListService } from '@affine/core/modules/share-doc';
import { WorkspaceService } from '@affine/core/modules/workspace'; import { WorkspaceService } from '@affine/core/modules/workspace';
import { PublicPageMode } from '@affine/graphql'; import { PublicPageMode } from '@affine/graphql';
import { useI18n } from '@affine/i18n'; import { useI18n } from '@affine/i18n';
import type { DocCollection, DocMeta } from '@blocksuite/affine/store'; import type { DocMeta, Workspace } from '@blocksuite/affine/store';
import { useLiveData, useService } from '@toeverything/infra'; import { useLiveData, useService } from '@toeverything/infra';
import { type ReactNode, useCallback, useEffect, useMemo } from 'react'; import { type ReactNode, useCallback, useEffect, useMemo } from 'react';
export type AllPageListConfig = { export type AllPageListConfig = {
allPages: DocMeta[]; allPages: DocMeta[];
docCollection: DocCollection; docCollection: Workspace;
/** /**
* Return `undefined` if the page is not public * Return `undefined` if the page is not public
*/ */
@@ -1,9 +1,9 @@
import type { DeltaInsert } from '@blocksuite/affine/inline'; import type { DeltaInsert } from '@blocksuite/affine/inline';
import type { DocCollection } from '@blocksuite/affine/store'; import 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';
export function useReferenceLinkHelper(docCollection: DocCollection) { export function useReferenceLinkHelper(docCollection: Workspace) {
const addReferenceLink = useCallback( const addReferenceLink = useCallback(
(pageId: string, referenceId: string) => { (pageId: string, referenceId: string) => {
const page = docCollection?.getDoc(pageId); const page = docCollection?.getDoc(pageId);
@@ -1,19 +1,17 @@
import type { DocCollection, DocMeta } from '@blocksuite/affine/store'; import type { DocMeta, Workspace } from '@blocksuite/affine/store';
import type { Atom } from 'jotai'; import type { Atom } from 'jotai';
import { atom, useAtomValue } from 'jotai'; import { atom, useAtomValue } from 'jotai';
const weakMap = new WeakMap<DocCollection, Atom<DocMeta[]>>(); const weakMap = new WeakMap<Workspace, Atom<DocMeta[]>>();
// this hook is extracted from './use-block-suite-page-meta.ts' to avoid circular dependency // this hook is extracted from './use-block-suite-page-meta.ts' to avoid circular dependency
export function useAllBlockSuiteDocMeta( export function useAllBlockSuiteDocMeta(docCollection: Workspace): DocMeta[] {
docCollection: DocCollection
): DocMeta[] {
if (!weakMap.has(docCollection)) { if (!weakMap.has(docCollection)) {
const baseAtom = atom<DocMeta[]>([...docCollection.meta.docMetas]); const baseAtom = atom<DocMeta[]>([...docCollection.meta.docMetas]);
weakMap.set(docCollection, baseAtom); weakMap.set(docCollection, baseAtom);
baseAtom.onMount = set => { baseAtom.onMount = set => {
set([...docCollection.meta.docMetas]); set([...docCollection.meta.docMetas]);
const dispose = docCollection.meta.docMetaUpdated.on(() => { const dispose = docCollection.slots.docListUpdated.on(() => {
set([...docCollection.meta.docMetas]); set([...docCollection.meta.docMetas]);
}); });
return () => { return () => {
@@ -1,6 +1,6 @@
import { DocsService } from '@affine/core/modules/doc'; import { DocsService } from '@affine/core/modules/doc';
import { WorkspaceService } from '@affine/core/modules/workspace'; import { WorkspaceService } from '@affine/core/modules/workspace';
import type { DocCollection, DocMeta } from '@blocksuite/affine/store'; import type { DocMeta, Workspace } from '@blocksuite/affine/store';
import { useService } from '@toeverything/infra'; import { useService } from '@toeverything/infra';
import { useCallback, useMemo } from 'react'; import { useCallback, useMemo } from 'react';
@@ -13,7 +13,7 @@ import { useJournalInfoHelper } from './use-journal';
* If you want to get all pageMetas, use `useAllBlockSuitePageMeta` instead * If you want to get all pageMetas, use `useAllBlockSuitePageMeta` instead
* @returns * @returns
*/ */
export function useBlockSuiteDocMeta(docCollection: DocCollection) { export function useBlockSuiteDocMeta(docCollection: Workspace) {
const pageMetas = useAllBlockSuiteDocMeta(docCollection); const pageMetas = useAllBlockSuiteDocMeta(docCollection);
const { isPageJournal } = useJournalInfoHelper(); const { isPageJournal } = useJournalInfoHelper();
return useMemo( return useMemo(
@@ -1,7 +1,7 @@
import type { Doc, DocCollection } from '@blocksuite/affine/store'; import type { Doc, Workspace } from '@blocksuite/affine/store';
import { useMemo } from 'react'; import { useMemo } from 'react';
export function useDocCollectionHelper(docCollection: DocCollection) { export function useDocCollectionHelper(docCollection: Workspace) {
return useMemo( return useMemo(
() => ({ () => ({
createDoc: (pageId?: string): Doc => { createDoc: (pageId?: string): Doc => {
@@ -1,12 +1,12 @@
import { DebugLogger } from '@affine/debug'; import { DebugLogger } from '@affine/debug';
import { DisposableGroup } from '@blocksuite/affine/global/utils'; import { DisposableGroup } from '@blocksuite/affine/global/utils';
import type { Doc, DocCollection } from '@blocksuite/affine/store'; import type { Doc, Workspace } from '@blocksuite/affine/store';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
const logger = new DebugLogger('use-doc-collection-page'); const logger = new DebugLogger('use-doc-collection-page');
export function useDocCollectionPage( export function useDocCollectionPage(
docCollection: DocCollection, docCollection: Workspace,
pageId: string | null pageId: string | null
): Doc | null { ): Doc | null {
const [page, setPage] = useState( const [page, setPage] = useState(
@@ -2,7 +2,7 @@ import { DocDisplayMetaService } from '@affine/core/modules/doc-display-meta';
import type { Tag } from '@affine/env/filter'; import type { Tag } from '@affine/env/filter';
import { useI18n } from '@affine/i18n'; import { useI18n } from '@affine/i18n';
import { assertExists } from '@blocksuite/affine/global/utils'; import { assertExists } from '@blocksuite/affine/global/utils';
import type { DocCollection, DocMeta } from '@blocksuite/affine/store'; import type { DocMeta, Workspace } from '@blocksuite/affine/store';
import { ToggleCollapseIcon, ViewLayersIcon } from '@blocksuite/icons/rc'; import { ToggleCollapseIcon, ViewLayersIcon } from '@blocksuite/icons/rc';
import * as Collapsible from '@radix-ui/react-collapsible'; import * as Collapsible from '@radix-ui/react-collapsible';
import { useLiveData, useService } from '@toeverything/infra'; import { useLiveData, useService } from '@toeverything/infra';
@@ -274,7 +274,7 @@ export const TagListItemRenderer = memo(function TagListItemRenderer(
function tagIdToTagOption( function tagIdToTagOption(
tagId: string, tagId: string,
docCollection: DocCollection docCollection: Workspace
): Tag | undefined { ): Tag | undefined {
return docCollection.meta.properties.tags?.options.find( return docCollection.meta.properties.tags?.options.find(
opt => opt.id === tagId opt => opt.id === tagId
@@ -1,5 +1,5 @@
import type { Collection, Tag } from '@affine/env/filter'; import type { Collection, Tag } from '@affine/env/filter';
import type { DocCollection, DocMeta } from '@blocksuite/affine/store'; import type { DocMeta, Workspace } from '@blocksuite/affine/store';
import type { JSX, PropsWithChildren, ReactNode } from 'react'; import type { JSX, PropsWithChildren, ReactNode } from 'react';
import type { To } from 'react-router-dom'; import type { To } from 'react-router-dom';
@@ -91,7 +91,7 @@ export type PageGroupByType =
export interface ListProps<T> { export interface ListProps<T> {
// required data: // required data:
items: T[]; items: T[];
docCollection: DocCollection; docCollection: Workspace;
className?: string; className?: string;
hideHeader?: boolean; // whether or not to hide the header. default is false (showing header) hideHeader?: boolean; // whether or not to hide the header. default is false (showing header)
groupBy?: ItemGroupDefinition<T>[]; groupBy?: ItemGroupDefinition<T>[];
@@ -1,12 +1,12 @@
import { DebugLogger } from '@affine/debug'; import { DebugLogger } from '@affine/debug';
import { DisposableGroup } from '@blocksuite/affine/global/utils'; import { DisposableGroup } from '@blocksuite/affine/global/utils';
import type { Doc, DocCollection } from '@blocksuite/affine/store'; import type { Doc, Workspace } from '@blocksuite/affine/store';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
const logger = new DebugLogger('useBlockSuiteWorkspacePage'); const logger = new DebugLogger('useBlockSuiteWorkspacePage');
export function useDocCollectionPage( export function useDocCollectionPage(
docCollection: DocCollection, docCollection: Workspace,
pageId: string | null pageId: string | null
): Doc | null { ): Doc | null {
const [page, setPage] = useState( const [page, setPage] = useState(
@@ -16,7 +16,7 @@ import {
openFileOrFiles, openFileOrFiles,
ZipTransformer, ZipTransformer,
} from '@blocksuite/affine/blocks'; } from '@blocksuite/affine/blocks';
import type { DocCollection } from '@blocksuite/affine/store'; import type { Workspace } from '@blocksuite/affine/store';
import { import {
ExportToHtmlIcon, ExportToHtmlIcon,
ExportToMarkdownIcon, ExportToMarkdownIcon,
@@ -51,7 +51,7 @@ type ImportResult = {
type ImportConfig = { type ImportConfig = {
fileOptions: { acceptType: AcceptType; multiple: boolean }; fileOptions: { acceptType: AcceptType; multiple: boolean };
importFunction: ( importFunction: (
docCollection: DocCollection, docCollection: Workspace,
file: File | File[] file: File | File[]
) => Promise<ImportResult>; ) => Promise<ImportResult>;
}; };
@@ -23,7 +23,7 @@ export class TagStore extends Store {
subscribe(cb: () => void) { subscribe(cb: () => void) {
const disposable = const disposable =
this.workspaceService.workspace.docCollection.meta.docMetaUpdated.on(cb); this.workspaceService.workspace.docCollection.slots.docListUpdated.on(cb);
return disposable.dispose; return disposable.dispose;
} }
@@ -1,4 +1,7 @@
import { DocCollection } from '@blocksuite/affine/store'; import {
DocCollection,
type Workspace as BSWorkspace,
} from '@blocksuite/affine/store';
import { Entity, LiveData } from '@toeverything/infra'; import { Entity, LiveData } from '@toeverything/infra';
import { nanoid } from 'nanoid'; import { nanoid } from 'nanoid';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
@@ -22,7 +25,7 @@ export class Workspace extends Entity {
readonly flavour = this.meta.flavour; readonly flavour = this.meta.flavour;
_docCollection: DocCollection | null = null; _docCollection: BSWorkspace | null = null;
get docCollection() { get docCollection() {
if (!this._docCollection) { if (!this._docCollection) {
@@ -1,4 +1,4 @@
import type { DocCollection } from '@blocksuite/affine/store'; import type { Workspace as BSWorkspace } from '@blocksuite/affine/store';
import { import {
type AwarenessConnection, type AwarenessConnection,
type BlobStorage, type BlobStorage,
@@ -27,7 +27,7 @@ export interface WorkspaceFlavourProvider {
createWorkspace( createWorkspace(
initial: ( initial: (
docCollection: DocCollection, docCollection: BSWorkspace,
blobStorage: BlobStorage, blobStorage: BlobStorage,
docStorage: DocStorage docStorage: DocStorage
) => Promise<void> ) => Promise<void>
@@ -3,8 +3,6 @@ import { Scope } from '@toeverything/infra';
import type { WorkspaceOpenOptions } from '../open-options'; import type { WorkspaceOpenOptions } from '../open-options';
import type { WorkspaceEngineProvider } from '../providers/flavour'; import type { WorkspaceEngineProvider } from '../providers/flavour';
export type { DocCollection } from '@blocksuite/affine/store';
export class WorkspaceScope extends Scope<{ export class WorkspaceScope extends Scope<{
openOptions: WorkspaceOpenOptions; openOptions: WorkspaceOpenOptions;
engineProvider: WorkspaceEngineProvider; engineProvider: WorkspaceEngineProvider;
@@ -1,4 +1,4 @@
import type { DocCollection } from '@blocksuite/affine/store'; import type { Workspace } from '@blocksuite/affine/store';
import { import {
type BlobStorage, type BlobStorage,
type DocStorage, type DocStorage,
@@ -21,7 +21,7 @@ export class WorkspaceFactoryService extends Service {
create = async ( create = async (
flavour: string, flavour: string,
initial: ( initial: (
docCollection: DocCollection, docCollection: Workspace,
blobStorage: BlobStorage, blobStorage: BlobStorage,
docStorage: DocStorage docStorage: DocStorage
) => Promise<void> = () => Promise.resolve() ) => Promise<void> = () => Promise.resolve()
@@ -1,11 +1,11 @@
import type { Collection } from '@affine/env/filter'; import type { Collection } from '@affine/env/filter';
import type { DocCollection } from '@blocksuite/affine/store'; import type { Workspace } from '@blocksuite/affine/store';
import { nanoid } from 'nanoid'; import { nanoid } from 'nanoid';
import type { Map as YMap } from 'yjs'; import type { Map as YMap } from 'yjs';
import { Doc as YDoc } from 'yjs'; import { Doc as YDoc } from 'yjs';
export class UserSetting { export class UserSetting {
constructor( constructor(
private readonly docCollection: DocCollection, private readonly docCollection: Workspace,
private readonly userId: string private readonly userId: string
) {} ) {}
@@ -38,9 +38,6 @@ export class UserSetting {
} }
} }
export const getUserSetting = ( export const getUserSetting = (docCollection: Workspace, userId: string) => {
docCollection: DocCollection,
userId: string
) => {
return new UserSetting(docCollection, userId); return new UserSetting(docCollection, userId);
}; };
+2
View File
@@ -44,6 +44,8 @@
// Projects // Projects
"composite": true, "composite": true,
"incremental": true, "incremental": true,
// For dev performance
"disableReferencedProjectLoad": true,
// Completeness // Completeness
"skipLibCheck": true, // skip all type checks for .d.ts files "skipLibCheck": true, // skip all type checks for .d.ts files
"paths": { "paths": {