mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-09-07 09:21:24 +08:00
refactor(editor): should not rely on doc collection type (#9501)
This commit is contained in:
@@ -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();
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|||||||
+1
-1
@@ -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();
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|||||||
+1
-1
@@ -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';
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Vendored
+3
-3
@@ -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;
|
||||||
|
|||||||
Vendored
+2
-3
@@ -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);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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": {
|
||||||
|
|||||||
Reference in New Issue
Block a user