diff --git a/examples/src/mobile-s/main.ts b/examples/src/mobile-s/main.ts index c281ec561b..803d22b39f 100644 --- a/examples/src/mobile-s/main.ts +++ b/examples/src/mobile-s/main.ts @@ -15,7 +15,6 @@ */ import type { FUniver } from '@univerjs/core'; -import type { IUniverRPCMainThreadConfig } from '@univerjs/rpc'; import { LocaleType, LogLevel, Univer, UniverInstanceType, UserManagerService } from '@univerjs/core'; import { defaultTheme } from '@univerjs/design'; import { UniverDocsPlugin } from '@univerjs/docs'; @@ -56,9 +55,10 @@ univer.registerPlugin(UniverMobileUIPlugin, { container: 'app', contextMenu: true, }); -univer.registerPlugin(UniverRPCMainThreadPlugin, { - workerURL: new Worker(new URL('./worker.js', import.meta.url), { type: 'module' }), -} as IUniverRPCMainThreadConfig); + +const worker = new Worker(new URL('./worker.js', import.meta.url), { type: 'module' }); +univer.registerPlugin(UniverRPCMainThreadPlugin, { workerURL: worker }); +univer.onDispose(() => worker.terminate()); univer.registerPlugin(UniverDocsUIPlugin); univer.registerPlugin(UniverSheetsPlugin); diff --git a/examples/src/sheets/main.ts b/examples/src/sheets/main.ts index 6d0a5fe257..d1f8b8f99c 100644 --- a/examples/src/sheets/main.ts +++ b/examples/src/sheets/main.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -import type { IUniverRPCMainThreadConfig } from '@univerjs/rpc'; import { FUniver, LocaleType, LogLevel, Univer, UniverInstanceType, UserManagerService } from '@univerjs/core'; import { UniverDebuggerPlugin } from '@univerjs/debugger'; import { defaultTheme } from '@univerjs/design'; @@ -88,9 +87,8 @@ const univer = new Univer({ logLevel: LogLevel.VERBOSE, }); -univer.registerPlugin(UniverRPCMainThreadPlugin, { - workerURL: new Worker(new URL('./worker.js', import.meta.url), { type: 'module' }), -} as IUniverRPCMainThreadConfig); +const worker = new Worker(new URL('./worker.js', import.meta.url), { type: 'module' }); +univer.registerPlugin(UniverRPCMainThreadPlugin, { workerURL: worker }); univer.registerPlugin(UniverDocsPlugin); univer.registerPlugin(UniverRenderEnginePlugin); @@ -144,6 +142,12 @@ setTimeout(() => { }); }, LOAD_VERY_LAZY_PLUGINS_TIMEOUT); +univer.onDispose(() => { + worker.terminate(); + window.univer = undefined; + window.univerAPI = undefined; +}); + window.univer = univer; window.univerAPI = FUniver.newAPI(univer); diff --git a/examples/src/uni/main.ts b/examples/src/uni/main.ts index d7ce102e2a..a93dc86507 100644 --- a/examples/src/uni/main.ts +++ b/examples/src/uni/main.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -import type { IUniverRPCMainThreadConfig } from '@univerjs/rpc'; import { FUniver, Injector, LocaleType, LogLevel, Univer, UniverInstanceType } from '@univerjs/core'; import { UniverDebuggerPlugin } from '@univerjs/debugger'; import { defaultTheme } from '@univerjs/design'; @@ -114,9 +113,10 @@ function registerBasicPlugins(univer: Univer) { ], }); - univer.registerPlugin(UniverRPCMainThreadPlugin, { - workerURL: new Worker(new URL('./worker.js', import.meta.url), { type: 'module' }), - } as IUniverRPCMainThreadConfig); + const worker = new Worker(new URL('./worker.js', import.meta.url), { type: 'module' }); + univer.registerPlugin(UniverRPCMainThreadPlugin, { workerURL: worker }); + univer.onDispose(() => worker.terminate()); + univer.registerPlugin(UniverThreadCommentUIPlugin); univer.registerPlugin(UniverDocsDrawingUIPlugin); diff --git a/packages/core/src/shared/lifecycle.ts b/packages/core/src/shared/lifecycle.ts index a53d76a2f0..36accc2d57 100644 --- a/packages/core/src/shared/lifecycle.ts +++ b/packages/core/src/shared/lifecycle.ts @@ -68,13 +68,16 @@ export function fromObservable(subscription: Subscription) { export class DisposableCollection implements IDisposable { private readonly _disposables = new Set(); - add(disposable: DisposableLike): IDisposable { + add(disposable: DisposableLike): { dispose: (notDisposeSelf?: boolean) => void } { const d = toDisposable(disposable); this._disposables.add(d); return { - dispose: () => { - d.dispose(); + dispose: (notDisposeSelf: boolean = false) => { + if (!notDisposeSelf) { + d.dispose(); + } + this._disposables.delete(d); }, }; diff --git a/packages/core/src/univer.ts b/packages/core/src/univer.ts index aca4a00044..54ebb97a5f 100644 --- a/packages/core/src/univer.ts +++ b/packages/core/src/univer.ts @@ -14,14 +14,12 @@ * limitations under the License. */ -import type { Dependency } from './common/di'; +import type { Dependency, IDisposable } from './common/di'; import type { UnitModel, UnitType } from './common/unit'; - import type { LogLevel } from './services/log/log.service'; import type { Plugin, PluginCtor } from './services/plugin/plugin'; import type { DependencyOverride } from './services/plugin/plugin-override'; import type { IStyleSheet } from './services/theme/theme.service'; -import type { ILocales } from './shared'; import type { IWorkbookData } from './sheets/typedef'; import type { LocaleType } from './types/enum/locale-type'; import type { IDocumentData, ISlideData } from './types/interfaces'; @@ -30,7 +28,6 @@ import { UniverInstanceType } from './common/unit'; import { DocumentDataModel } from './docs/data-model/document-data-model'; import { AuthzIoLocalService } from './services/authz-io/authz-io-local.service'; import { IAuthzIoService } from './services/authz-io/type'; - import { CommandService, ICommandService } from './services/command/command.service'; import { ConfigService, IConfigService } from './services/config/config.service'; import { ContextService, IContextService } from './services/context/context.service'; @@ -44,8 +41,8 @@ import { MentionIOLocalService } from './services/mention-io/mention-io-local.se import { IMentionIOService } from './services/mention-io/type'; import { PermissionService } from './services/permission/permission.service'; import { IPermissionService } from './services/permission/type'; -import { PluginService } from './services/plugin/plugin.service'; import { mergeOverrideWithDependencies } from './services/plugin/plugin-override'; +import { PluginService } from './services/plugin/plugin.service'; import { ResourceLoaderService } from './services/resource-loader/resource-loader.service'; import { IResourceLoaderService } from './services/resource-loader/type'; import { ResourceManagerService } from './services/resource-manager/resource-manager.service'; @@ -53,6 +50,7 @@ import { IResourceManagerService } from './services/resource-manager/type'; import { ThemeService } from './services/theme/theme.service'; import { IUndoRedoService, LocalUndoRedoService } from './services/undoredo/undoredo.service'; import { UserManagerService } from './services/user-manager/user-manager.service'; +import { DisposableCollection, type ILocales, toDisposable } from './shared'; import { Workbook } from './sheets/workbook'; import { SlideDataModel } from './slides/slide-model'; @@ -65,7 +63,7 @@ export interface IUniverConfig { override?: DependencyOverride; } -export class Univer { +export class Univer implements IDisposable { private _startedTypes = new Set(); private _injector: Injector; @@ -77,6 +75,8 @@ export class Univer { return this._injector.get(PluginService); } + private _disposingCallbacks = new DisposableCollection(); + /** * Create a Univer instance. * @param config Configuration data for Univer @@ -98,7 +98,21 @@ export class Univer { return this._injector; } + /** + * Register a callback function which will be called when this Univer instance is disposing. + * + * @ignore + * + * @param callback The callback function. + * @returns To remove this callback function from this Univer instance's on disposing list. + */ + onDispose(callback: () => void): IDisposable { + const d = this._disposingCallbacks.add(toDisposable(callback)); + return toDisposable(() => d.dispose(true)); + } + dispose(): void { + this._disposingCallbacks.dispose(); this._injector.dispose(); }