Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(facade): facade-namespace & global addEvent #4346

Merged
merged 21 commits into from
Jan 2, 2025
Merged
5 changes: 4 additions & 1 deletion packages/core/src/facade/f-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,18 @@
* limitations under the License.
*/

import { Disposable } from '../shared';

/**
* `FBase` is a base class for all facade classes.
* It provides a way to extend classes with static and instance methods.
* The `_initialize` as a special method that will be called after the constructor. You should never call it directly.
*/
export abstract class FBase {
export abstract class FBase extends Disposable {
private static _constructorQueue: Array<() => void> = [];

constructor() {
super();
// eslint-disable-next-line ts/no-this-alias
const self = this;
FBase._constructorQueue.forEach(function (fn) {
Expand Down
46 changes: 46 additions & 0 deletions packages/core/src/facade/f-enum.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/**
* Copyright 2023-present DreamNum Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { UniverInstanceType } from '../common/unit';
import { LifecycleStages } from '../services/lifecycle/lifecycle';
import { DataValidationErrorStyle } from '../types/enum/data-validation-error-style';
import { DataValidationOperator } from '../types/enum/data-validation-operator';
import { DataValidationRenderMode } from '../types/enum/data-validation-render-mode';
import { DataValidationStatus } from '../types/enum/data-validation-status';
import { DataValidationType } from '../types/enum/data-validation-type';
import { FBase } from './f-base';

export class FEnum extends FBase {
static _intance: FEnum | null;
static get() {
if (this._intance) {
return this._intance;
}

const instance = new FEnum();
this._intance = instance;
return instance;
}

readonly UniverInstanceType = UniverInstanceType;
weird94 marked this conversation as resolved.
Show resolved Hide resolved
readonly LifecycleStages = LifecycleStages;

readonly DataValidationType = DataValidationType;
readonly DataValidationErrorStyle = DataValidationErrorStyle;
readonly DataValidationRenderMode = DataValidationRenderMode;
readonly DataValidationOperator = DataValidationOperator;
readonly DataValidationStatus = DataValidationStatus;
}
64 changes: 64 additions & 0 deletions packages/core/src/facade/f-event.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/**
* Copyright 2023-present DreamNum Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import type { UniverInstanceType } from '../common/unit';
import type { LifecycleStages } from '../services/lifecycle/lifecycle';
import type { IWorkbookData } from '../sheets/typedef';
import type { IDocumentData } from '../types/interfaces';
import { FBase } from './f-base';

export interface ISheetCreateParam {
unitId: string;
type: UniverInstanceType.UNIVER_SHEET;
data: IWorkbookData;
}

export interface IDocumentCreateParam {
unitId: string;
type: UniverInstanceType.UNIVER_DOC;
data: IDocumentData;
}

export interface ILifeCycleChangedParam {
stage: LifecycleStages;
}
export interface IEventBase {
cancel?: boolean;
}

export type IUnitCreateEvent = IEventBase & (ISheetCreateParam | IDocumentCreateParam);
export type ILifeCycleChangedEvent = IEventBase & ILifeCycleChangedParam;

export class FEventName extends FBase {
static _intance: FEventName | null;
static get() {
if (this._intance) {
return this._intance;
}

const instance = new FEventName();
this._intance = instance;
return instance;
}

UnitCreated = 'UnitCreated' as const;
weird94 marked this conversation as resolved.
Show resolved Hide resolved
LifeCycleChanged = 'LifeCycleChanged' as const;
}

export interface IEventParamConfig {
// UnitCreated: IUnitCreateEvent;
LifeCycleChanged: ILifeCycleChangedEvent;
}
86 changes: 82 additions & 4 deletions packages/core/src/facade/f-univer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,19 @@
import type { IDisposable } from '../common/di';
import type { CommandListener, IExecutionOptions } from '../services/command/command.service';
import type { LifecycleStages } from '../services/lifecycle/lifecycle';
import type { IEventParamConfig } from './f-event';
import { Inject, Injector } from '../common/di';
import { Registry } from '../common/registry';
import { ICommandService } from '../services/command/command.service';
import { IUniverInstanceService } from '../services/instance/instance.service';
import { LifecycleService } from '../services/lifecycle/lifecycle.service';
import { RedoCommand, UndoCommand } from '../services/undoredo/undoredo.service';
import { Disposable, toDisposable } from '../shared';
import { Univer } from '../univer';
import { FBase } from './f-base';
import { FBlob } from './f-blob';
import { FEnum } from './f-enum';
import { FEventName } from './f-event';
import { FHooks } from './f-hooks';
import { FUserManager } from './f-usermanager';

Expand All @@ -42,14 +47,37 @@ export class FUniver extends FBase {
return injector.createInstance(FUniver);
}

private _eventRegistry: Registry = new Registry<{ event: string; callback: (...args: any[]) => void }>();
private _disposables: [] = [];
weird94 marked this conversation as resolved.
Show resolved Hide resolved

constructor(
@Inject(Injector) protected readonly _injector: Injector,
@ICommandService protected readonly _commandService: ICommandService,
@IUniverInstanceService protected readonly _univerInstanceService: IUniverInstanceService
@IUniverInstanceService protected readonly _univerInstanceService: IUniverInstanceService,
@Inject(LifecycleService) protected readonly _lifecycleService: LifecycleService
) {
super();
}

override _initialize(): void {
const disposeMe = () => {
weird94 marked this conversation as resolved.
Show resolved Hide resolved
this.dispose();
};
class FDisposable extends Disposable {
override dispose() {
super.dispose();
disposeMe();
}
}

this._injector.add([FDisposable]);
this.disposeWithMe(
this._lifecycleService.lifecycle$.subscribe((stage) => {
this.fireEvent(this.Event.LifeCycleChanged, { stage });
})
);
}

/**
* Dispose the UniverSheet by the `unitId`. The UniverSheet would be unload from the application.
*
Expand Down Expand Up @@ -90,7 +118,7 @@ export class FUniver extends FBase {

/**
* Register a callback that will be triggered before invoking a command.
*
* @deprecated use `addEvent(univerAPI.event.BeforeCommandExecute, () => {})` instead.
* @param {CommandListener} callback The callback.
* @returns {IDisposable} The disposable instance.
*/
Expand All @@ -102,7 +130,7 @@ export class FUniver extends FBase {

/**
* Register a callback that will be triggered when a command is invoked.
*
* @deprecated use `addEvent(univerAPI.event.CommandExecuted, () => {})` instead.
* @param {CommandListener} callback The callback.
* @returns {IDisposable} The disposable instance.
*/
Expand Down Expand Up @@ -144,7 +172,7 @@ export class FUniver extends FBase {

/**
* Get hooks.
*
* @deprecated use `addEvent` instead.
* @returns {FHooks} FHooks instance
*/
getHooks(): FHooks {
Expand All @@ -164,7 +192,57 @@ export class FUniver extends FBase {
return this._injector.createInstance(FBlob);
}

get Enum() {
return FEnum.get();
}

get Event() {
return FEventName.get();
}

/**
* add an event listener
weird94 marked this conversation as resolved.
Show resolved Hide resolved
* @param event key of event
* @param callback callback when event triggered
* @returns {Disposable} The Disposable instance, for remove the listener
* @example
* ```ts
* univerAPI.addEvent(univerAPI.event.UnitCreated, (params) => {
* console.log('unit created', params);
* });
* ```
*/
addEvent(event: keyof IEventParamConfig, callback: (params: IEventParamConfig[typeof event]) => void) {
const data = {
event,
callback,
};
this._eventRegistry.add(data);
return toDisposable(() => this._eventRegistry.delete(data));
}

/**
* fire an event, used in internal only.
* @param event {string} key of event
* @param params {any} parmas of event
* @returns {boolean} should cancel
* @example
* ```ts
* this.fireEvent(univerAPI.event.UnitCreated, params);
* ```
*/
protected fireEvent<T extends keyof IEventParamConfig>(event: T, params: IEventParamConfig[T]) {
this._eventRegistry.getData().forEach((item) => {
if (item.event === event) {
item.callback(params);
}
});

return params.cancel;
}

getUserManager(): FUserManager {
return this._injector.createInstance(FUserManager);
}
}

19 changes: 19 additions & 0 deletions packages/core/src/facade/f-util.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* Copyright 2023-present DreamNum Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

export class FUtil {
static Range = Range;
}
2 changes: 2 additions & 0 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ export { FBase } from './facade/f-base';
export { FUniver } from './facade/f-univer';
export { FHooks } from './facade/f-hooks';
export { FBlob, type IFBlobSource } from './facade/f-blob';
export { FEventName, type IEventBase, type IEventParamConfig } from './facade/f-event';
export { FEnum } from './facade/f-enum';
export { isNumeric, isSafeNumeric } from './common/number';
export { Registry, RegistryAsMap } from './common/registry';
export { requestImmediateMacroTask } from './common/request-immediate-macro-task';
Expand Down
54 changes: 54 additions & 0 deletions packages/sheets/src/facade/f-event.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/**
* Copyright 2023-present DreamNum Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import type { IEventBase, IWorksheetData } from '@univerjs/core';
import type { FWorkbook } from './f-workbook';
import type { FWorksheet } from './f-worksheet';
import { FEventName } from '@univerjs/core';

export interface IFSheetEventMixin {
SheetCreated: 'SheetCreated';
BeforeSheetCreate: 'BeforeSheetCreate';
}

export class FSheetEventName extends FEventName implements IFSheetEventMixin {
override readonly SheetCreated = 'SheetCreated' as const;
override readonly BeforeSheetCreate = 'BeforeSheetCreate' as const;
}

export interface IBeforeSheetCreateEventParams extends IEventBase {
workbook: FWorkbook;
index?: number;
sheet?: IWorksheetData;
}

export interface ISheetCreatedEventParams extends IEventBase {
workbook: FWorkbook;
worksheet: FWorksheet;
}

export interface ISheetEventParamConfig {
SheetCreated: ISheetCreatedEventParams;
BeforeSheetCreate: IBeforeSheetCreateEventParams;
}

FEventName.extend(FSheetEventName);
declare module '@univerjs/core' {
// eslint-disable-next-line ts/naming-convention
interface FEventName extends IFSheetEventMixin { }
interface IEventParamConfig extends ISheetEventParamConfig { }
}

Loading
Loading