@univerjs/sheets-formula 0.5.2 → 0.5.3-experimental.20250106-e3b7a39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,6 @@
1
- import { CalculationMode } from '@univerjs/sheets-formula';
2
- import { FFormula } from '@univerjs/engine-formula';
1
+ import { IDisposable, ILocales } from '@univerjs/core';
2
+ import { IFunctionInfo, FFormula } from '@univerjs/engine-formula';
3
+ import { CalculationMode, IRegisterAsyncFunction, IRegisterFunction } from '@univerjs/sheets-formula';
3
4
  export interface IFFormulaSheetsMixin {
4
5
  /**
5
6
  * Update the calculation mode of the formula.
@@ -7,9 +8,160 @@ export interface IFFormulaSheetsMixin {
7
8
  * @returns
8
9
  */
9
10
  setInitialFormulaComputing(calculationMode: CalculationMode): void;
11
+ /**
12
+ * Register a custom synchronous formula function.
13
+ * @param name - The name of the function to register. This will be used in formulas (e.g., =MYFUNC())
14
+ * @param func - The implementation of the function
15
+ * @param description - A string describing the function's purpose and usage
16
+ * @returns A disposable object that will unregister the function when disposed
17
+ * @example
18
+ * ```js
19
+ * univerAPI.getFormula().registerFunction('HELLO', (name) => `Hello, ${name}!`, 'A simple greeting function');
20
+ *
21
+ * // Use the function in a cell
22
+ * univerAPI.getActiveWorkbook().getActiveSheet().getRange('A1').setValue('World');
23
+ * univerAPI.getActiveWorkbook().getActiveSheet().getRange('A2').setValue({ f: '=HELLO(A1)' });
24
+ * // A2 will display: "Hello, World!"
25
+ * ```
26
+ * @example
27
+ * ```js
28
+ * univerAPI.getFormula().registerFunction(
29
+ * 'DISCOUNT',
30
+ * (price, discountPercent) => price * (1 - discountPercent / 100),
31
+ * 'Calculates final price after discount'
32
+ * );
33
+ *
34
+ * // Use in cell
35
+ * univerAPI.getActiveWorkbook().getActiveSheet().getRange('A1').setValue(100);
36
+ * univerAPI.getActiveWorkbook().getActiveSheet().getRange('A2').setValue({ f: '=DISCOUNT(A1, 20)' });
37
+ * // A2 will display: 80
38
+ * ```
39
+ */
40
+ registerFunction(name: string, func: IRegisterFunction, description?: string): IDisposable;
41
+ /**
42
+ * Register a custom synchronous formula function with localization support.
43
+ * @param name - The name of the function to register. This will be used in formulas (e.g., =MYFUNC())
44
+ * @param func - The implementation of the function
45
+ * @param options - Object containing locales and description
46
+ * @returns A disposable object that will unregister the function when disposed
47
+ * @example
48
+ * ```js
49
+ * univerAPI.getFormula().registerFunction('HELLO',
50
+ * (name) => {
51
+ * return `Hello, ${name}!`;
52
+ * },
53
+ * {
54
+ * description: 'customFunction.HELLO.description',
55
+ * locales: {
56
+ * 'zhCN': {
57
+ * 'customFunction' : {
58
+ * 'HELLO' : {
59
+ * 'description': '一个简单的问候函数'
60
+ * }
61
+ * }
62
+ * },
63
+ * 'enUS': {
64
+ * 'customFunction' : {
65
+ * 'HELLO' : {
66
+ * 'description': 'A simple greeting function'
67
+ * }
68
+ * }
69
+ * }
70
+ * }
71
+ * }
72
+ * );
73
+ *
74
+ * // Use in cell
75
+ * univerAPI.getActiveWorkbook().getActiveSheet().getRange('A1').setValue({ f: '=HELLO("John")' });
76
+ * // A1 will display: "Hello, John!"
77
+ * ```
78
+ */
79
+ registerFunction(name: string, func: IRegisterFunction, { locales, description }: {
80
+ locales?: ILocales;
81
+ description?: string | IFunctionInfo;
82
+ }): IDisposable;
83
+ /**
84
+ * Register a custom asynchronous formula function.
85
+ * @param name - The name of the function to register. This will be used in formulas (e.g., =ASYNCFUNC())
86
+ * @param func - The async implementation of the function
87
+ * @returns A disposable object that will unregister the function when disposed
88
+ * @example
89
+ * ```js
90
+ * univerAPI.getFormula().registerAsyncFunction('RANDOM_DELAYED',
91
+ * async () => {
92
+ * await new Promise(resolve => setTimeout(resolve, 500));
93
+ * return Math.random();
94
+ * },
95
+ * 'Mock a random number generation function'
96
+ * );
97
+ *
98
+ * // Use in cell
99
+ * univerAPI.getActiveWorkbook().getActiveSheet().getRange('A1').setValue({ f: '=RANDOM_DELAYED()' });
100
+ * // After 0.5 second, A1 will display a random number
101
+ * ```
102
+ */
103
+ registerAsyncFunction(name: string, func: IRegisterAsyncFunction, description?: string): IDisposable;
104
+ /**
105
+ * Register a custom asynchronous formula function with description.
106
+ * @param name - The name of the function to register. This will be used in formulas (e.g., =ASYNCFUNC())
107
+ * @param func - The async implementation of the function
108
+ * @param description - A string describing the function's purpose and usage
109
+ * @returns A disposable object that will unregister the function when disposed
110
+ * @example
111
+ * ```js
112
+ * // Mock a user score fetching function
113
+ * univerAPI.getFormula().registerAsyncFunction('FETCH_USER_SCORE',
114
+ * async (userId) => {
115
+ * await new Promise(resolve => setTimeout(resolve, 1000));
116
+ * // Mock fetching user score from database
117
+ * return userId * 10 + Math.floor(Math.random() * 20);
118
+ * },
119
+ * {
120
+ * description: 'customFunction.description.FETCH_USER_SCORE',
121
+ * locales: {
122
+ * 'zhCN': {
123
+ * 'customFunction': {
124
+ * 'description': {
125
+ * 'FETCH_USER_SCORE': '从数据库中获取用户分数'
126
+ * }
127
+ * }
128
+ * },
129
+ * 'enUS': {
130
+ * 'customFunction': {
131
+ * 'description': {
132
+ * 'FETCH_USER_SCORE': 'Mock fetching user score from database'
133
+ * }
134
+ * }
135
+ * }
136
+ * }
137
+ * }
138
+ * );
139
+ *
140
+ * // Use in cell
141
+ * univerAPI.getActiveWorkbook().getActiveSheet().getRange('A1').setValue({ f: '=FETCH_USER_SCORE(42)' });
142
+ * // After 1 second, A1 will display a score
143
+ * ```
144
+ */
145
+ registerAsyncFunction(name: string, func: IRegisterAsyncFunction, { locales, description }: {
146
+ locales?: ILocales;
147
+ description?: string | IFunctionInfo;
148
+ }): IDisposable;
10
149
  }
11
150
  export declare class FFormulaSheetsMixin extends FFormula implements IFFormulaSheetsMixin {
151
+ /**
152
+ * RegisterFunction may be executed multiple times, triggering multiple formula forced refreshes.
153
+ */
154
+ private _debouncedFormulaCalculation;
155
+ /**
156
+ * Initialize the FUniver instance.
157
+ * @private
158
+ */
159
+ _initialize(): void;
12
160
  setInitialFormulaComputing(calculationMode: CalculationMode): void;
161
+ registerFunction(name: string, func: IRegisterFunction): IDisposable;
162
+ registerFunction(name: string, func: IRegisterFunction, description: string): IDisposable;
163
+ registerAsyncFunction(name: string, func: IRegisterAsyncFunction): IDisposable;
164
+ registerAsyncFunction(name: string, func: IRegisterAsyncFunction, description: string): IDisposable;
13
165
  }
14
166
  declare module '@univerjs/engine-formula' {
15
167
  interface FFormula extends IFFormulaSheetsMixin {
@@ -3,7 +3,7 @@ import { IRegisterFunctionParams } from '@univerjs/sheets-formula';
3
3
  export interface IFUniverSheetsFormulaMixin {
4
4
  /**
5
5
  * Register a function to the spreadsheet.
6
- *
6
+ * @deprecated Use `univerAPI.getFormula().registerFunction` instead.
7
7
  * @param {IRegisterFunctionParams} config The configuration of the function.
8
8
  * @returns {IDisposable} The disposable instance.
9
9
  */
@@ -11,12 +11,11 @@ export interface IFUniverSheetsFormulaMixin {
11
11
  }
12
12
  export declare class FUniverSheetsFormulaMixin extends FUniver implements IFUniverSheetsFormulaMixin {
13
13
  /**
14
- * registerFunction may be executed multiple times, triggering multiple formula forced refreshes
14
+ * RegisterFunction may be executed multiple times, triggering multiple formula forced refreshes.
15
15
  */
16
16
  private _debouncedFormulaCalculation;
17
17
  /**
18
18
  * Initialize the FUniver instance.
19
- *
20
19
  * @private
21
20
  */
22
21
  _initialize(): void;
@@ -18,6 +18,7 @@ export { OtherFormulaMarkDirty } from './commands/mutations/formula.mutation';
18
18
  export { UpdateDefinedNameController } from './controllers/update-defined-name.controller';
19
19
  export { TriggerCalculationController } from './controllers/trigger-calculation.controller';
20
20
  export { CalculationMode, type IUniverSheetsFormulaBaseConfig, PLUGIN_CONFIG_KEY_BASE } from './controllers/config.schema';
21
+ export type { IRegisterAsyncFunction, IRegisterFunction, ISingleFunctionRegisterParams } from './services/register-function.service';
21
22
  export { UpdateFormulaController } from './controllers/update-formula.controller';
22
23
  export { DescriptionService, IDescriptionService, type ISearchItem } from './services/description.service';
23
24
  export type { IFormulaInfo, IOtherFormulaResult } from './services/formula-common';
@@ -1,8 +1,9 @@
1
1
  import { IDisposable, ILocales, Disposable, LocaleService } from '@univerjs/core';
2
- import { IFunctionInfo, PrimitiveValueType, IFunctionService } from '@univerjs/engine-formula';
2
+ import { FormulaFunctionValueType, IFunctionInfo, IFunctionService } from '@univerjs/engine-formula';
3
3
  import { IDescriptionService } from './description.service';
4
4
  import { IRemoteRegisterFunctionService } from './remote/remote-register-function.service';
5
- export type IRegisterFunction = (...arg: Array<PrimitiveValueType | PrimitiveValueType[][]>) => PrimitiveValueType | PrimitiveValueType[][];
5
+ export type IRegisterFunction = (...arg: Array<FormulaFunctionValueType>) => FormulaFunctionValueType;
6
+ export type IRegisterAsyncFunction = (...arg: Array<FormulaFunctionValueType>) => Promise<FormulaFunctionValueType>;
6
7
  export type IRegisterFunctionList = [[IRegisterFunction, string, string?]];
7
8
  export interface IFormulaCustomFunctionService {
8
9
  /**
@@ -50,15 +51,50 @@ export interface IRegisterFunctionService {
50
51
  * @param params
51
52
  */
52
53
  registerFunctions(params: IRegisterFunctionParams): IDisposable;
54
+ /**
55
+ * register a single function
56
+ * @param params
57
+ */
58
+ registerFunction(params: ISingleFunctionRegisterParams): IDisposable;
59
+ /**
60
+ * register a single async function
61
+ * @param params
62
+ */
63
+ registerAsyncFunction(params: ISingleFunctionRegisterParams): IDisposable;
53
64
  }
54
65
  export declare const IRegisterFunctionService: import('@wendellhu/redi').IdentifierDecorator<IRegisterFunctionService>;
66
+ export interface ISingleFunctionRegisterParams {
67
+ /**
68
+ * function name
69
+ */
70
+ name: string;
71
+ /**
72
+ * function calculation
73
+ */
74
+ func: IRegisterFunction | IRegisterAsyncFunction;
75
+ /**
76
+ * function description
77
+ */
78
+ description: string | IFunctionInfo;
79
+ /**
80
+ * function locales
81
+ */
82
+ locales?: ILocales;
83
+ /**
84
+ * function async
85
+ */
86
+ async?: boolean;
87
+ }
55
88
  export declare class RegisterFunctionService extends Disposable implements IRegisterFunctionService {
56
89
  private readonly _localeService;
57
90
  private readonly _descriptionService;
58
91
  private readonly _functionService;
59
92
  private readonly _remoteRegisterFunctionService?;
60
93
  constructor(_localeService: LocaleService, _descriptionService: IDescriptionService, _functionService: IFunctionService, _remoteRegisterFunctionService?: IRemoteRegisterFunctionService | undefined);
94
+ registerFunction(params: ISingleFunctionRegisterParams): IDisposable;
95
+ registerAsyncFunction(params: ISingleFunctionRegisterParams): IDisposable;
61
96
  registerFunctions(params: IRegisterFunctionParams): IDisposable;
97
+ private _registerSingleFunction;
62
98
  private _registerLocalExecutors;
63
99
  private _registerRemoteExecutors;
64
100
  }
@@ -1,6 +1,7 @@
1
1
  import { IFunctionService } from '@univerjs/engine-formula';
2
2
  export interface IRemoteRegisterFunctionService {
3
3
  registerFunctions(serializedFuncs: Array<[string, string]>): Promise<void>;
4
+ registerAsyncFunctions(serializedFuncs: Array<[string, string]>): Promise<void>;
4
5
  unregisterFunctions(names: string[]): Promise<void>;
5
6
  }
6
7
  export declare const RemoteRegisterFunctionServiceName = "sheets-formula.remote-register-function.service";
@@ -12,5 +13,6 @@ export declare class RemoteRegisterFunctionService implements IRemoteRegisterFun
12
13
  private readonly _functionService;
13
14
  constructor(_functionService: IFunctionService);
14
15
  registerFunctions(serializedFuncs: Array<[string, string]>): Promise<void>;
16
+ registerAsyncFunctions(serializedFuncs: Array<[string, string]>): Promise<void>;
15
17
  unregisterFunctions(names: string[]): Promise<void>;
16
18
  }
package/lib/umd/facade.js CHANGED
@@ -1 +1 @@
1
- (function(e,i){typeof exports=="object"&&typeof module<"u"?i(require("@univerjs/core"),require("@univerjs/engine-formula"),require("@univerjs/sheets-formula")):typeof define=="function"&&define.amd?define(["@univerjs/core","@univerjs/engine-formula","@univerjs/sheets-formula"],i):(e=typeof globalThis<"u"?globalThis:e||self,i(e.UniverCore,e.UniverEngineFormula,e.UniverSheetsFormula))})(this,function(e,i,t){"use strict";class s extends e.FUniver{_initialize(){this._debouncedFormulaCalculation=e.debounce(()=>{this._commandService.executeCommand(i.SetFormulaCalculationStartMutation.id,{commands:[],forceCalculation:!0},{onlyLocal:!0})},10)}registerFunction(r){let n=this._injector.get(t.IRegisterFunctionService);n||(this._injector.add([t.IRegisterFunctionService,{useClass:t.RegisterFunctionService}]),n=this._injector.get(t.IRegisterFunctionService));const c=n.registerFunctions(r);return this._debouncedFormulaCalculation(),c}}e.FUniver.extend(s);class u extends i.FFormula{setInitialFormulaComputing(r){const c=this._injector.get(e.LifecycleService).stage,a=this._injector.get(e.ILogService),f=this._injector.get(e.IConfigService);c>e.LifecycleStages.Starting&&a.warn("[FFormula]","CalculationMode is called after the Starting lifecycle and will take effect the next time the Univer Sheet is constructed. If you want it to take effect when the Univer Sheet is initialized this time, consider calling it before the Ready lifecycle or using configuration.");const o=f.getConfig(t.PLUGIN_CONFIG_KEY_BASE);o&&(o.initialFormulaComputing=r)}}i.FFormula.extend(u)});
1
+ (function(i,c){typeof exports=="object"&&typeof module<"u"?c(require("@univerjs/core"),require("@univerjs/engine-formula"),require("@univerjs/sheets-formula")):typeof define=="function"&&define.amd?define(["@univerjs/core","@univerjs/engine-formula","@univerjs/sheets-formula"],c):(i=typeof globalThis<"u"?globalThis:i||self,c(i.UniverCore,i.UniverEngineFormula,i.UniverSheetsFormula))})(this,function(i,c,t){"use strict";class l extends i.FUniver{_initialize(){this._debouncedFormulaCalculation=i.debounce(()=>{this._commandService.executeCommand(c.SetFormulaCalculationStartMutation.id,{commands:[],forceCalculation:!0},{onlyLocal:!0})},10)}registerFunction(o){let r=this._injector.get(t.IRegisterFunctionService);r||(this._injector.add([t.IRegisterFunctionService,{useClass:t.RegisterFunctionService}]),r=this._injector.get(t.IRegisterFunctionService));const e=r.registerFunctions(o);return this._debouncedFormulaCalculation(),e}}i.FUniver.extend(l);class d extends c.FFormula{_initialize(){this._debouncedFormulaCalculation=i.debounce(()=>{this._commandService.executeCommand(c.SetFormulaCalculationStartMutation.id,{commands:[],forceCalculation:!0},{onlyLocal:!0})},10)}setInitialFormulaComputing(o){const e=this._injector.get(i.LifecycleService).stage,n=this._injector.get(i.ILogService),s=this._injector.get(i.IConfigService);e>i.LifecycleStages.Starting&&n.warn("[FFormula]","CalculationMode is called after the Starting lifecycle and will take effect the next time the Univer Sheet is constructed. If you want it to take effect when the Univer Sheet is initialized this time, consider calling it before the Ready lifecycle or using configuration.");const u=s.getConfig(t.PLUGIN_CONFIG_KEY_BASE);u&&(u.initialFormulaComputing=o)}registerFunction(o,r,e){var a;let n=this._injector.get(t.IRegisterFunctionService);n||(this._injector.add([t.IRegisterFunctionService,{useClass:t.RegisterFunctionService}]),n=this._injector.get(t.IRegisterFunctionService));const s={name:o,func:r,description:typeof e=="string"?e:(a=e==null?void 0:e.description)!=null?a:"",locales:typeof e=="object"?e.locales:void 0},u=n.registerFunction(s);return this._debouncedFormulaCalculation(),u}registerAsyncFunction(o,r,e){var a;let n=this._injector.get(t.IRegisterFunctionService);n||(this._injector.add([t.IRegisterFunctionService,{useClass:t.RegisterFunctionService}]),n=this._injector.get(t.IRegisterFunctionService));const s={name:o,func:r,description:typeof e=="string"?e:(a=e==null?void 0:e.description)!=null?a:"",locales:typeof e=="object"?e.locales:void 0},u=n.registerAsyncFunction(s);return this._debouncedFormulaCalculation(),u}}c.FFormula.extend(d)});