feat(editor): add embed option config extension (#10540)

This PR implements a significant refactoring of the embed block services across multiple components (Figma, GitHub, Loom, and YouTube) in the BlockSuite codebase. Here are the key changes:

1. **Architecture Change**:
   - Moves from a dynamic registration pattern to a more declarative configuration approach
   - Replaces `EmbedOptionProvider.registerEmbedBlockOptions()` calls with a new `EmbedOptionConfig` factory function

2. **Service Refactoring**:
   - For each embed block type (Figma, GitHub, Loom, YouTube):
     - Separates configuration from service logic
     - Creates new `EmbedBlockOptionConfig` constants using the new `EmbedOptionConfig` factory
     - Removes the `mounted()` lifecycle hook from services where it was only used for registration

3. **Core Changes**:
   - In `embed-option-service.ts`:
     - Introduces new `EmbedOptionConfigIdentifier` for dependency injection
     - Adds `EmbedOptionConfig` factory function for creating embed configurations
     - Updates `EmbedOptionService` constructor to automatically register configurations
     - Modifies DI setup to include `StdIdentifier` dependency

4. **Spec Updates**:
   - Updates all block specs to include the new configuration objects
   - Maintains existing functionality while using the new pattern

The main benefit of this refactoring is:
- More declarative configuration approach
- Better separation of concerns
- Reduced runtime registration code
- More predictable initialization of embed options
This commit is contained in:
Saul-Mirone
2025-03-01 16:40:18 +00:00
parent 7527d36547
commit 6353e72078
10 changed files with 72 additions and 64 deletions

View File

@@ -1,7 +1,8 @@
import type { EmbedCardStyle } from '@blocksuite/affine-model';
import { type BlockStdScope, StdIdentifier } from '@blocksuite/block-std';
import type { Container } from '@blocksuite/global/di';
import { createIdentifier } from '@blocksuite/global/di';
import { Extension } from '@blocksuite/store';
import { Extension, type ExtensionType } from '@blocksuite/store';
export type EmbedOptions = {
flavour: string;
@@ -19,12 +20,32 @@ export const EmbedOptionProvider = createIdentifier<EmbedOptionProvider>(
'AffineEmbedOptionProvider'
);
export const EmbedOptionConfigIdentifier = createIdentifier<EmbedOptions>(
'AffineEmbedOptionConfig'
);
export const EmbedOptionConfig = (options: EmbedOptions): ExtensionType => {
return {
setup: di => {
di.addImpl(EmbedOptionConfigIdentifier(options.flavour), options);
},
};
};
export class EmbedOptionService
extends Extension
implements EmbedOptionProvider
{
private readonly _embedBlockRegistry = new Set<EmbedOptions>();
constructor(readonly std: BlockStdScope) {
super();
const configs = this.std.provider.getAll(EmbedOptionConfigIdentifier);
configs.forEach(value => {
this.registerEmbedBlockOptions(value);
});
}
getEmbedBlockOptions = (url: string): EmbedOptions | null => {
const entries = this._embedBlockRegistry.entries();
for (const [options] of entries) {
@@ -39,6 +60,6 @@ export class EmbedOptionService
};
static override setup(di: Container) {
di.addImpl(EmbedOptionProvider, EmbedOptionService);
di.addImpl(EmbedOptionProvider, EmbedOptionService, [StdIdentifier]);
}
}