mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-17 18:16:15 +08:00
feat(editor): feature flag store extension builder (#12235)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Introduced feature flag synchronization for enhanced control over feature availability. - Added new configuration options for store management, allowing initialization and feature flag setup. - **Improvements** - Updated how store extensions are accessed throughout the app for more robust initialization and configuration. - Enhanced workspace entities to support feature flag services, improving flexibility for workspace-specific features. - Centralized configuration of storage implementations for Electron environments. - **Refactor** - Simplified editor module by removing direct feature flag synchronization logic. - Streamlined imports and configuration for storage modules, especially in Electron-based apps. - **Bug Fixes** - Ensured consistent retrieval of store extensions across various modules and platforms. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -252,7 +252,8 @@ export class TextRenderer extends WithDisposable(ShadowlessElement) {
|
||||
} else {
|
||||
const container = new Container();
|
||||
getStoreManager()
|
||||
.get('store')
|
||||
.config.init()
|
||||
.value.get('store')
|
||||
.forEach(ext => {
|
||||
ext.setup(container);
|
||||
});
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ import { markdownToMindmap } from '../mindmap-preview.js';
|
||||
|
||||
const container = new Container();
|
||||
getStoreManager()
|
||||
.get('store')
|
||||
.value.get('store')
|
||||
.forEach(ext => {
|
||||
ext.setup(container);
|
||||
});
|
||||
|
||||
@@ -99,7 +99,7 @@ export const usePageHelper = (docCollection: Workspace) => {
|
||||
showImportModal({
|
||||
collection: docCollection,
|
||||
schema: getAFFiNEWorkspaceSchema(),
|
||||
extensions: getStoreManager().get('store'),
|
||||
extensions: getStoreManager().config.init().value.get('store'),
|
||||
onSuccess,
|
||||
onFail: message => {
|
||||
reject(new Error(message));
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
import {
|
||||
AFFINE_FLAGS,
|
||||
type FeatureFlagService,
|
||||
} from '@affine/core/modules/feature-flag';
|
||||
import { FeatureFlagService as BSFeatureFlagService } from '@blocksuite/affine/shared/services';
|
||||
import { type ExtensionType, StoreExtension } from '@blocksuite/affine/store';
|
||||
|
||||
export function getFeatureFlagSyncer(
|
||||
featureFlagService: FeatureFlagService
|
||||
): ExtensionType {
|
||||
class FeatureFlagSyncer extends StoreExtension {
|
||||
static override key = 'feature-flag-syncer';
|
||||
|
||||
override loaded() {
|
||||
const bsFeatureFlagService = this.store.get(BSFeatureFlagService);
|
||||
Object.entries(AFFINE_FLAGS).forEach(([key, flag]) => {
|
||||
if (flag.category === 'blocksuite') {
|
||||
const value =
|
||||
featureFlagService.flags[key as keyof AFFINE_FLAGS].value;
|
||||
if (value !== undefined) {
|
||||
bsFeatureFlagService.setFlag(flag.bsFlag, value);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return FeatureFlagSyncer;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import { getFeatureFlagSyncer } from '@affine/core/blocksuite/extensions/feature-flag/feature-flag-syncer';
|
||||
import { FeatureFlagService } from '@affine/core/modules/feature-flag';
|
||||
import {
|
||||
type StoreExtensionContext,
|
||||
StoreExtensionProvider,
|
||||
} from '@blocksuite/affine/ext-loader';
|
||||
import { z } from 'zod';
|
||||
|
||||
const optionsSchema = z.object({
|
||||
featureFlagService: z.instanceof(FeatureFlagService).optional(),
|
||||
});
|
||||
|
||||
export class FeatureFlagStoreExtension extends StoreExtensionProvider {
|
||||
override name = 'feature-flag-store-extension';
|
||||
|
||||
override schema = optionsSchema;
|
||||
|
||||
override setup(
|
||||
context: StoreExtensionContext,
|
||||
options?: z.infer<typeof optionsSchema>
|
||||
) {
|
||||
super.setup(context, options);
|
||||
const featureFlagService = options?.featureFlagService;
|
||||
if (!featureFlagService) {
|
||||
return;
|
||||
}
|
||||
context.register(getFeatureFlagSyncer(featureFlagService));
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
import { FeatureFlagStoreExtension } from '@affine/core/blocksuite/extensions/feature-flag';
|
||||
import type { FeatureFlagService } from '@affine/core/modules/feature-flag';
|
||||
import {
|
||||
type StoreExtensionContext,
|
||||
StoreExtensionManager,
|
||||
@@ -18,11 +20,57 @@ class MigratingAffineStoreExtension extends StoreExtensionProvider {
|
||||
}
|
||||
}
|
||||
|
||||
const manager = new StoreExtensionManager([
|
||||
...getInternalStoreExtensions(),
|
||||
MigratingAffineStoreExtension,
|
||||
]);
|
||||
interface Configure {
|
||||
init: () => Configure;
|
||||
featureFlag: (featureFlagService?: FeatureFlagService) => Configure;
|
||||
value: StoreExtensionManager;
|
||||
}
|
||||
|
||||
class StoreProvider {
|
||||
static instance: StoreProvider | null = null;
|
||||
static getInstance() {
|
||||
if (!StoreProvider.instance) {
|
||||
StoreProvider.instance = new StoreProvider();
|
||||
}
|
||||
return StoreProvider.instance;
|
||||
}
|
||||
|
||||
private readonly _manager: StoreExtensionManager;
|
||||
|
||||
constructor() {
|
||||
this._manager = new StoreExtensionManager([
|
||||
...getInternalStoreExtensions(),
|
||||
MigratingAffineStoreExtension,
|
||||
FeatureFlagStoreExtension,
|
||||
]);
|
||||
}
|
||||
|
||||
get config(): Configure {
|
||||
return {
|
||||
init: this._initDefaultConfig,
|
||||
featureFlag: this._configureFeatureFlag,
|
||||
value: this._manager,
|
||||
};
|
||||
}
|
||||
|
||||
get value(): StoreExtensionManager {
|
||||
return this._manager;
|
||||
}
|
||||
|
||||
private readonly _initDefaultConfig = () => {
|
||||
this.config.featureFlag();
|
||||
|
||||
return this.config;
|
||||
};
|
||||
|
||||
private readonly _configureFeatureFlag = (
|
||||
featureFlagService?: FeatureFlagService
|
||||
) => {
|
||||
this._manager.configure(FeatureFlagStoreExtension, { featureFlagService });
|
||||
return this.config;
|
||||
};
|
||||
}
|
||||
|
||||
export function getStoreManager() {
|
||||
return manager;
|
||||
return StoreProvider.getInstance();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user