mirror of
https://github.com/dream-num/univer.git
synced 2026-09-24 15:32:18 +08:00
fix: fix univer plugin lifecycle not triggered (#2023)
* fix: fix univer plugin lifecycle not triggered * feat: add start API on Univer
This commit is contained in:
@@ -85,6 +85,9 @@ univer.registerPlugin(UniverDataValidationPlugin);
|
||||
univer.registerPlugin(UniverSheetsDataValidationPlugin);
|
||||
univer.registerPlugin(UniverSheetsFindReplacePlugin);
|
||||
|
||||
// sheet condition formatting
|
||||
univer.registerPlugin(UniverSheetsConditionalFormattingUIPlugin);
|
||||
|
||||
// create univer sheet instance
|
||||
univer.createUniverSheet(DEFAULT_WORKBOOK_DATA_DEMO);
|
||||
|
||||
@@ -93,9 +96,6 @@ univer.createUniverSheet(DEFAULT_WORKBOOK_DATA_DEMO);
|
||||
// univer.__getInjector().get(IUniverInstanceService).disposeUnit(DEFAULT_WORKBOOK_DATA_DEMO.id);
|
||||
// }, 5000);
|
||||
|
||||
// sheet condition formatting
|
||||
univer.registerPlugin(UniverSheetsConditionalFormattingUIPlugin);
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
univer?: Univer;
|
||||
|
||||
@@ -26,12 +26,14 @@ import { type Plugin, type PluginCtor, PluginRegistry, PluginStore } from './plu
|
||||
|
||||
export class PluginHolder extends Disposable {
|
||||
protected _started: boolean = false;
|
||||
get started(): boolean { return this._started; }
|
||||
|
||||
protected readonly _pluginRegistered = new Set<string>();
|
||||
protected readonly _pluginStore = new PluginStore();
|
||||
protected readonly _pluginRegistry = new PluginRegistry();
|
||||
|
||||
constructor(
|
||||
private readonly _immediateStart: boolean,
|
||||
@ILogService protected readonly _logService: ILogService,
|
||||
@Inject(Injector) protected readonly _injector: Injector,
|
||||
@Inject(LifecycleService) protected readonly _lifecycleService: LifecycleService,
|
||||
@@ -48,7 +50,7 @@ export class PluginHolder extends Disposable {
|
||||
this._pluginRegistry.removePlugins();
|
||||
}
|
||||
|
||||
protected _registerPlugin<T extends PluginCtor<Plugin>>(pluginCtor: T, config?: ConstructorParameters<T>[0]): void {
|
||||
registerPlugin<T extends PluginCtor<Plugin>>(pluginCtor: T, config?: ConstructorParameters<T>[0]): void {
|
||||
const { pluginName } = pluginCtor;
|
||||
if (this._pluginRegistered.has(pluginName)) {
|
||||
this._logService.warn('[PluginService]', `plugin ${pluginName} has already been registered. This registration will be ignored.`);
|
||||
@@ -58,21 +60,24 @@ export class PluginHolder extends Disposable {
|
||||
this._pluginRegistry.registerPlugin(pluginCtor, config);
|
||||
}
|
||||
|
||||
_start(): void {
|
||||
start(): void {
|
||||
if (this._started) return;
|
||||
this._started = true;
|
||||
|
||||
this._flush();
|
||||
this.flush();
|
||||
}
|
||||
|
||||
_flush(): void {
|
||||
flush(): void {
|
||||
if (!this._started) return;
|
||||
|
||||
const plugins = this._pluginRegistry.getRegisterPlugins().map(({ plugin, options }) => this._initPlugin(plugin, options));
|
||||
this._pluginRegistry.removePlugins();
|
||||
|
||||
this.disposeWithMe(this._lifecycleService.subscribeWithPrevious().subscribe((stage) => {
|
||||
const lifecycleSubscription = this.disposeWithMe(this._lifecycleService.subscribeWithPrevious().subscribe((stage) => {
|
||||
this._pluginsRunLifecycle(plugins, stage);
|
||||
if (stage === LifecycleStages.Steady) {
|
||||
lifecycleSubscription.dispose();
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
@@ -14,11 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import type { IDisposable } from '@wendellhu/redi';
|
||||
import { Inject, Injector } from '@wendellhu/redi';
|
||||
import type { UniverType } from '@univerjs/protocol';
|
||||
import { type UnitType, UniverInstanceType } from '../../common/unit';
|
||||
import { LifecycleInitializerService, LifecycleService } from '../lifecycle/lifecycle.service';
|
||||
import { LifecycleStages } from '../lifecycle/lifecycle';
|
||||
import { ILogService } from '../log/log.service';
|
||||
import { PluginHolder } from './plugin-holder';
|
||||
import type { Plugin, PluginCtor } from './plugin';
|
||||
|
||||
@@ -27,42 +26,61 @@ const INIT_LAZY_PLUGINS_TIMEOUT = 200;
|
||||
/**
|
||||
* This service manages plugin registration.
|
||||
*/
|
||||
export class PluginService extends PluginHolder {
|
||||
private _pluginHoldersForTypes = new Map<UnitType, PluginHolder>();
|
||||
export class PluginService implements IDisposable {
|
||||
private readonly _pluginHolderForUniver: PluginHolder;
|
||||
private readonly _pluginHoldersForTypes = new Map<UnitType, PluginHolder>();
|
||||
|
||||
constructor(
|
||||
@ILogService _logService: ILogService,
|
||||
@Inject(Injector) _injector: Injector,
|
||||
@Inject(LifecycleService) _lifecycleService: LifecycleService,
|
||||
@Inject(LifecycleInitializerService) _lifecycleInitializerService: LifecycleInitializerService
|
||||
@Inject(Injector) private readonly _injector: Injector
|
||||
) {
|
||||
super(_logService, _injector, _lifecycleService, _lifecycleInitializerService);
|
||||
this._pluginHolderForUniver = this._injector.createInstance(PluginHolder, true);
|
||||
}
|
||||
|
||||
override dispose(): void {
|
||||
dispose(): void {
|
||||
this._clearFlushLazyPluginsTimer();
|
||||
|
||||
// Dispose all plugin holders including self.
|
||||
super.dispose();
|
||||
for (const holder of this._pluginHoldersForTypes.values()) {
|
||||
holder.dispose();
|
||||
}
|
||||
|
||||
this._pluginHolderForUniver.dispose();
|
||||
}
|
||||
|
||||
/** Register a plugin into univer. */
|
||||
registerPlugin<T extends PluginCtor<Plugin>>(plugin: T, config?: ConstructorParameters<T>[0]): void {
|
||||
this._assertPluginValid(plugin);
|
||||
|
||||
const { type } = plugin;
|
||||
if (type === UniverInstanceType.UNIVER) {
|
||||
return this._registerPlugin(plugin, config);
|
||||
if (this._pluginHolderForUniver.started) {
|
||||
this._scheduleInitPluginAfterStarted();
|
||||
}
|
||||
|
||||
// If it's type is for specific document, we should run them at specific time.
|
||||
const holder = this._ensurePluginHolderForType(type);
|
||||
const { type } = plugin;
|
||||
if (type === UniverInstanceType.UNIVER) {
|
||||
this._pluginHolderForUniver.registerPlugin(plugin, config);
|
||||
} else {
|
||||
// If it's type is for specific document, we should run them at specific time.
|
||||
const holder = this._ensurePluginHolderForType(type);
|
||||
holder.registerPlugin(plugin, config);
|
||||
}
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
holder._registerPlugin(plugin, config);
|
||||
start(): void {
|
||||
this._pluginHolderForUniver.start();
|
||||
}
|
||||
|
||||
startPluginForType(type: UniverType): void {
|
||||
const holder = this._ensurePluginHolderForType(type);
|
||||
holder.start();
|
||||
}
|
||||
|
||||
_ensurePluginHolderForType(type: UnitType): PluginHolder {
|
||||
if (!this._pluginHoldersForTypes.has(type)) {
|
||||
const pluginHolder = this._injector.createInstance(PluginHolder, false);
|
||||
this._pluginHoldersForTypes.set(type, pluginHolder);
|
||||
return pluginHolder;
|
||||
}
|
||||
|
||||
return this._pluginHoldersForTypes.get(type)!;
|
||||
}
|
||||
|
||||
private _assertPluginValid(plugin: PluginCtor<Plugin>): void {
|
||||
@@ -77,44 +95,14 @@ export class PluginService extends PluginHolder {
|
||||
}
|
||||
}
|
||||
|
||||
protected override _registerPlugin<T extends PluginCtor<Plugin>>(pluginCtor: T, options?: ConstructorParameters<T>[0]): void {
|
||||
const { pluginName } = pluginCtor;
|
||||
if (this._pluginRegistered.has(pluginName)) {
|
||||
this._logService.warn('[PluginService]', `plugin ${pluginName} has already been registered. This registration will be ignored.`);
|
||||
return;
|
||||
}
|
||||
|
||||
this._pluginRegistered.add(pluginName);
|
||||
|
||||
if (this._started) {
|
||||
this._pluginRegistry.registerPlugin(pluginCtor, options);
|
||||
|
||||
// If Univer has already started, we should manually call onStarting for the plugin.
|
||||
// We do that in an asynchronous way, because user may lazy load several plugins at the same time.
|
||||
return this._scheduleInitPluginAfterStarted();
|
||||
} else {
|
||||
// For plugins at Univer level. Plugins would be initialized immediately so they can register dependencies.
|
||||
const pluginInstance: Plugin = this._injector.createInstance(pluginCtor, options);
|
||||
this._pluginStore.addPlugin(pluginInstance);
|
||||
this._pluginsRunLifecycle([pluginInstance], LifecycleStages.Starting);
|
||||
}
|
||||
}
|
||||
|
||||
_ensurePluginHolderForType(type: UnitType): PluginHolder {
|
||||
if (!this._pluginHoldersForTypes.has(type)) {
|
||||
const pluginHolder = this._injector.createInstance(PluginHolder);
|
||||
this._pluginHoldersForTypes.set(type, pluginHolder);
|
||||
return pluginHolder;
|
||||
}
|
||||
|
||||
return this._pluginHoldersForTypes.get(type)!;
|
||||
}
|
||||
|
||||
private _initLazyPluginsTimer?: number;
|
||||
private _scheduleInitPluginAfterStarted() {
|
||||
if (this._initLazyPluginsTimer === undefined) {
|
||||
this._initLazyPluginsTimer = setTimeout(
|
||||
() => this._flushLazyPlugins(),
|
||||
() => {
|
||||
this._flushLazyPlugins();
|
||||
this._clearFlushLazyPluginsTimer();
|
||||
},
|
||||
INIT_LAZY_PLUGINS_TIMEOUT
|
||||
) as unknown as number;
|
||||
}
|
||||
@@ -128,10 +116,11 @@ export class PluginService extends PluginHolder {
|
||||
}
|
||||
|
||||
private _flushLazyPlugins() {
|
||||
this._flush();
|
||||
|
||||
this._pluginHolderForUniver.flush();
|
||||
for (const [_, holder] of this._pluginHoldersForTypes) {
|
||||
holder._flush();
|
||||
if (holder.started) {
|
||||
holder.flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,6 +111,10 @@ export class Univer {
|
||||
return this._univerInstanceService.createUnit<ISlideData, SlideDataModel>(UniverInstanceType.SLIDE, data);
|
||||
}
|
||||
|
||||
start(): void {
|
||||
this._tryProgressToStart();
|
||||
}
|
||||
|
||||
private _init(injector: Injector): void {
|
||||
this._univerInstanceService.registerCtorForType(UniverInstanceType.SHEET, Workbook);
|
||||
this._univerInstanceService.registerCtorForType(UniverInstanceType.DOC, DocumentDataModel);
|
||||
@@ -122,11 +126,9 @@ export class Univer {
|
||||
this._tryProgressToStart();
|
||||
|
||||
if (!this._startedTypes.has(type)) {
|
||||
this._pluginService.startPluginForType(type);
|
||||
this._startedTypes.add(type);
|
||||
|
||||
const pluginHolder = this._pluginService._ensurePluginHolderForType(type);
|
||||
pluginHolder._start();
|
||||
|
||||
const model = injector.createInstance(ctor, data);
|
||||
univerInstanceService.__addUnit(model);
|
||||
|
||||
@@ -143,7 +145,7 @@ export class Univer {
|
||||
}
|
||||
|
||||
private _tryProgressToStart(): void {
|
||||
this._pluginService._start();
|
||||
this._pluginService.start();
|
||||
}
|
||||
|
||||
private _tryProgressToReady(): void {
|
||||
|
||||
Reference in New Issue
Block a user