feat(editor): use store extension manager (#11891)

Closes: BS-3284
This commit is contained in:
Saul-Mirone
2025-04-22 15:51:22 +00:00
parent 99ad4e871e
commit 43966a6c6b
25 changed files with 160 additions and 54 deletions
@@ -5,6 +5,7 @@ import {
NewDocIcon,
} from '@blocksuite/affine-components/icons';
import { toast } from '@blocksuite/affine-components/toast';
import { StoreExtensionManagerIdentifier } from '@blocksuite/affine-ext-loader';
import { insertLinkedNode } from '@blocksuite/affine-inline-reference';
import {
DocModeProvider,
@@ -235,9 +236,13 @@ export function createNewDocMenuGroup(
const onFail = (message: string) => {
toast(editorHost, message);
};
const storeManager = editorHost.std.get(
StoreExtensionManagerIdentifier
);
showImportModal({
collection: doc.workspace,
schema: doc.schema,
extensions: storeManager.get('store'),
onSuccess,
onFail,
});
@@ -8,7 +8,7 @@ import {
} from '@blocksuite/affine-components/icons';
import { openFileOrFiles } from '@blocksuite/affine-shared/utils';
import { WithDisposable } from '@blocksuite/global/lit';
import type { Schema, Workspace } from '@blocksuite/store';
import type { ExtensionType, Schema, Workspace } from '@blocksuite/store';
import { html, LitElement, type PropertyValues } from 'lit';
import { query, state } from 'lit/decorators.js';
@@ -32,6 +32,7 @@ export class ImportDoc extends WithDisposable(LitElement) {
constructor(
private readonly collection: Workspace,
private readonly schema: Schema,
private readonly extensions: ExtensionType[],
private readonly onSuccess?: OnSuccessHandler,
private readonly onFail?: OnFailHandler,
private readonly abortController = new AbortController()
@@ -65,6 +66,7 @@ export class ImportDoc extends WithDisposable(LitElement) {
const pageId = await HtmlTransformer.importHTMLToDoc({
collection: this.collection,
schema: this.schema,
extensions: this.extensions,
html: text,
fileName,
});
@@ -98,6 +100,7 @@ export class ImportDoc extends WithDisposable(LitElement) {
schema: this.schema,
markdown: text,
fileName,
extensions: this.extensions,
});
needLoading && this.abortController.abort();
if (pageId) {
@@ -122,6 +125,7 @@ export class ImportDoc extends WithDisposable(LitElement) {
collection: this.collection,
schema: this.schema,
imported: file,
extensions: this.extensions,
});
needLoading && this.abortController.abort();
if (hasMarkdown) {
@@ -1,4 +1,4 @@
import type { Schema, Workspace } from '@blocksuite/store';
import type { ExtensionType, Schema, Workspace } from '@blocksuite/store';
import {
ImportDoc,
@@ -9,6 +9,7 @@ import {
export function showImportModal({
schema,
collection,
extensions,
onSuccess,
onFail,
container = document.body,
@@ -16,6 +17,7 @@ export function showImportModal({
}: {
schema: Schema;
collection: Workspace;
extensions: ExtensionType[];
onSuccess?: OnSuccessHandler;
onFail?: OnFailHandler;
multiple?: boolean;
@@ -25,6 +27,7 @@ export function showImportModal({
const importDoc = new ImportDoc(
collection,
schema,
extensions,
onSuccess,
onFail,
abortController
@@ -5,10 +5,14 @@ import {
HtmlAdapter,
titleMiddleware,
} from '@blocksuite/affine-shared/adapters';
import { SpecProvider } from '@blocksuite/affine-shared/utils';
import { Container } from '@blocksuite/global/di';
import { sha } from '@blocksuite/global/utils';
import type { Schema, Store, Workspace } from '@blocksuite/store';
import type {
ExtensionType,
Schema,
Store,
Workspace,
} from '@blocksuite/store';
import { extMimeMap, Transformer } from '@blocksuite/store';
import { createAssetsArchive, download, Unzip } from './utils.js';
@@ -18,18 +22,19 @@ type ImportHTMLToDocOptions = {
schema: Schema;
html: string;
fileName?: string;
extensions: ExtensionType[];
};
type ImportHTMLZipOptions = {
collection: Workspace;
schema: Schema;
imported: Blob;
extensions: ExtensionType[];
};
function getProvider() {
function getProvider(extensions: ExtensionType[]) {
const container = new Container();
const exts = SpecProvider._.getSpec('store').value;
exts.forEach(ext => {
extensions.forEach(ext => {
ext.setup(container);
});
return container.provider();
@@ -42,7 +47,7 @@ function getProvider() {
* @returns A Promise that resolves when the export is complete.
*/
async function exportDoc(doc: Store) {
const provider = getProvider();
const provider = doc.provider;
const job = doc.getTransformer([
docLinkBaseURLMiddleware(doc.workspace.id),
titleMiddleware(doc.workspace.meta.docMetas),
@@ -90,8 +95,9 @@ async function importHTMLToDoc({
schema,
html,
fileName,
extensions,
}: ImportHTMLToDocOptions) {
const provider = getProvider();
const provider = getProvider(extensions);
const job = new Transformer({
schema,
blobCRUD: collection.blobSync,
@@ -130,8 +136,9 @@ async function importHTMLZip({
collection,
schema,
imported,
extensions,
}: ImportHTMLZipOptions) {
const provider = getProvider();
const provider = getProvider(extensions);
const unzip = new Unzip();
await unzip.load(imported);
@@ -5,19 +5,22 @@ import {
MarkdownAdapter,
titleMiddleware,
} from '@blocksuite/affine-shared/adapters';
import { SpecProvider } from '@blocksuite/affine-shared/utils';
import { Container } from '@blocksuite/global/di';
import { BlockSuiteError, ErrorCode } from '@blocksuite/global/exceptions';
import { sha } from '@blocksuite/global/utils';
import type { Schema, Store, Workspace } from '@blocksuite/store';
import type {
ExtensionType,
Schema,
Store,
Workspace,
} from '@blocksuite/store';
import { extMimeMap, Transformer } from '@blocksuite/store';
import { createAssetsArchive, download, Unzip } from './utils.js';
function getProvider() {
function getProvider(extensions: ExtensionType[]) {
const container = new Container();
const exts = SpecProvider._.getSpec('store').value;
exts.forEach(ext => {
extensions.forEach(ext => {
ext.setup(container);
});
return container.provider();
@@ -27,6 +30,7 @@ type ImportMarkdownToBlockOptions = {
doc: Store;
markdown: string;
blockId: string;
extensions: ExtensionType[];
};
type ImportMarkdownToDocOptions = {
@@ -34,12 +38,14 @@ type ImportMarkdownToDocOptions = {
schema: Schema;
markdown: string;
fileName?: string;
extensions: ExtensionType[];
};
type ImportMarkdownZipOptions = {
collection: Workspace;
schema: Schema;
imported: Blob;
extensions: ExtensionType[];
};
/**
@@ -48,7 +54,7 @@ type ImportMarkdownZipOptions = {
* @returns A Promise that resolves when the export is complete
*/
async function exportDoc(doc: Store) {
const provider = getProvider();
const provider = doc.provider;
const job = doc.getTransformer([
docLinkBaseURLMiddleware(doc.workspace.id),
titleMiddleware(doc.workspace.meta.docMetas),
@@ -98,8 +104,9 @@ async function importMarkdownToBlock({
doc,
markdown,
blockId,
extensions,
}: ImportMarkdownToBlockOptions) {
const provider = getProvider();
const provider = getProvider(extensions);
const job = doc.getTransformer([
defaultImageProxyMiddleware,
docLinkBaseURLMiddleware(doc.workspace.id),
@@ -142,8 +149,9 @@ async function importMarkdownToDoc({
schema,
markdown,
fileName,
extensions,
}: ImportMarkdownToDocOptions) {
const provider = getProvider();
const provider = getProvider(extensions);
const job = new Transformer({
schema,
blobCRUD: collection.blobSync,
@@ -181,8 +189,9 @@ async function importMarkdownZip({
collection,
schema,
imported,
extensions,
}: ImportMarkdownZipOptions) {
const provider = getProvider();
const provider = getProvider(extensions);
const unzip = new Unzip();
await unzip.load(imported);
@@ -1,9 +1,9 @@
import { defaultImageProxyMiddleware } from '@blocksuite/affine-block-image';
import { NotionHtmlAdapter } from '@blocksuite/affine-shared/adapters';
import { SpecProvider } from '@blocksuite/affine-shared/utils';
import { Container } from '@blocksuite/global/di';
import { sha } from '@blocksuite/global/utils';
import {
type ExtensionType,
extMimeMap,
type Schema,
Transformer,
@@ -16,12 +16,12 @@ type ImportNotionZipOptions = {
collection: Workspace;
schema: Schema;
imported: Blob;
extensions: ExtensionType[];
};
function getProvider() {
function getProvider(extensions: ExtensionType[]) {
const container = new Container();
const exts = SpecProvider._.getSpec('store').value;
exts.forEach(ext => {
extensions.forEach(ext => {
ext.setup(container);
});
return container.provider();
@@ -45,8 +45,9 @@ async function importNotionZip({
collection,
schema,
imported,
extensions,
}: ImportNotionZipOptions) {
const provider = getProvider();
const provider = getProvider(extensions);
const pageIds: string[] = [];
let isWorkspaceFile = false;
let hasMarkdown = false;