@univerjs/sheets-formula 0.5.2 → 0.5.3

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,168 @@ export interface IFFormulaSheetsMixin {
7
8
  * @returns
8
9
  */
9
10
  setInitialFormulaComputing(calculationMode: CalculationMode): void;
11
+ /**
12
+ * Register a custom synchronous formula function.
13
+ *
14
+ * @param name - The name of the function to register. This will be used in formulas (e.g., =MYFUNC())
15
+ * @param func - The implementation of the function
16
+ * @param description - A string describing the function's purpose and usage
17
+ * @returns A disposable object that will unregister the function when disposed
18
+ * @example
19
+ * ```js
20
+ * univerAPI.getFormula().registerFunction('HELLO', (name) => `Hello, ${name}!`, 'A simple greeting function');
21
+ *
22
+ * // Use the function in a cell
23
+ * univerAPI.getActiveWorkbook().getActiveSheet().getRange('A1').setValue('World');
24
+ * univerAPI.getActiveWorkbook().getActiveSheet().getRange('A2').setValue({ f: '=HELLO(A1)' });
25
+ * // A2 will display: "Hello, World!"
26
+ * ```
27
+ * @example
28
+ * ```js
29
+ * univerAPI.getFormula().registerFunction(
30
+ * 'DISCOUNT',
31
+ * (price, discountPercent) => price * (1 - discountPercent / 100),
32
+ * 'Calculates final price after discount'
33
+ * );
34
+ *
35
+ * // Use in cell
36
+ * univerAPI.getActiveWorkbook().getActiveSheet().getRange('A1').setValue(100);
37
+ * univerAPI.getActiveWorkbook().getActiveSheet().getRange('A2').setValue({ f: '=DISCOUNT(A1, 20)' });
38
+ * // A2 will display: 80
39
+ * ```
40
+ */
41
+ registerFunction(name: string, func: IRegisterFunction, description?: string): IDisposable;
42
+ /**
43
+ * Register a custom synchronous formula function with localization support.
44
+ *
45
+ * @param name - The name of the function to register. This will be used in formulas (e.g., =MYFUNC())
46
+ * @param func - The implementation of the function
47
+ * @param options - Object containing locales and description
48
+ * @returns A disposable object that will unregister the function when disposed
49
+ *
50
+ * @example
51
+ * ```js
52
+ * univerAPI.getFormula().registerFunction('HELLO',
53
+ * (name) => {
54
+ * return `Hello, ${name}!`;
55
+ * },
56
+ * {
57
+ * description: 'customFunction.HELLO.description',
58
+ * locales: {
59
+ * 'zhCN': {
60
+ * 'customFunction' : {
61
+ * 'HELLO' : {
62
+ * 'description': '一个简单的问候函数'
63
+ * }
64
+ * }
65
+ * },
66
+ * 'enUS': {
67
+ * 'customFunction' : {
68
+ * 'HELLO' : {
69
+ * 'description': 'A simple greeting function'
70
+ * }
71
+ * }
72
+ * }
73
+ * }
74
+ * }
75
+ * );
76
+ *
77
+ * // Use in cell
78
+ * univerAPI.getActiveWorkbook().getActiveSheet().getRange('A1').setValue({ f: '=HELLO("John")' });
79
+ * // A1 will display: "Hello, John!"
80
+ * ```
81
+ */
82
+ registerFunction(name: string, func: IRegisterFunction, { locales, description }: {
83
+ locales?: ILocales;
84
+ description?: string | IFunctionInfo;
85
+ }): IDisposable;
86
+ /**
87
+ * Register a custom asynchronous formula function.
88
+ *
89
+ * @param name - The name of the function to register. This will be used in formulas (e.g., =ASYNCFUNC())
90
+ * @param func - The async implementation of the function
91
+ * @returns A disposable object that will unregister the function when disposed
92
+ *
93
+ * @example
94
+ * ```js
95
+ * univerAPI.getFormula().registerAsyncFunction('RANDOM_DELAYED',
96
+ * async () => {
97
+ * await new Promise(resolve => setTimeout(resolve, 500));
98
+ * return Math.random();
99
+ * },
100
+ * 'Mock a random number generation function'
101
+ * );
102
+ *
103
+ * // Use in cell
104
+ * univerAPI.getActiveWorkbook().getActiveSheet().getRange('A1').setValue({ f: '=RANDOM_DELAYED()' });
105
+ * // After 0.5 second, A1 will display a random number
106
+ * ```
107
+ */
108
+ registerAsyncFunction(name: string, func: IRegisterAsyncFunction, description?: string): IDisposable;
109
+ /**
110
+ * Register a custom asynchronous formula function with description.
111
+ *
112
+ * @param name - The name of the function to register. This will be used in formulas (e.g., =ASYNCFUNC())
113
+ * @param func - The async implementation of the function
114
+ * @param description - A string describing the function's purpose and usage
115
+ * @returns A disposable object that will unregister the function when disposed
116
+ *
117
+ * @example
118
+ * ```js
119
+ * // Mock a user score fetching function
120
+ * univerAPI.getFormula().registerAsyncFunction('FETCH_USER_SCORE',
121
+ * async (userId) => {
122
+ * await new Promise(resolve => setTimeout(resolve, 1000));
123
+ * // Mock fetching user score from database
124
+ * return userId * 10 + Math.floor(Math.random() * 20);
125
+ * },
126
+ * {
127
+ * description: 'customFunction.description.FETCH_USER_SCORE',
128
+ * locales: {
129
+ * 'zhCN': {
130
+ * 'customFunction': {
131
+ * 'description': {
132
+ * 'FETCH_USER_SCORE': '从数据库中获取用户分数'
133
+ * }
134
+ * }
135
+ * },
136
+ * 'enUS': {
137
+ * 'customFunction': {
138
+ * 'description': {
139
+ * 'FETCH_USER_SCORE': 'Mock fetching user score from database'
140
+ * }
141
+ * }
142
+ * }
143
+ * }
144
+ * }
145
+ * );
146
+ *
147
+ * // Use in cell
148
+ * univerAPI.getActiveWorkbook().getActiveSheet().getRange('A1').setValue({ f: '=FETCH_USER_SCORE(42)' });
149
+ * // After 1 second, A1 will display a score
150
+ * ```
151
+ */
152
+ registerAsyncFunction(name: string, func: IRegisterAsyncFunction, { locales, description }: {
153
+ locales?: ILocales;
154
+ description?: string | IFunctionInfo;
155
+ }): IDisposable;
10
156
  }
11
157
  export declare class FFormulaSheetsMixin extends FFormula implements IFFormulaSheetsMixin {
158
+ /**
159
+ * registerFunction may be executed multiple times, triggering multiple formula forced refreshes
160
+ */
161
+ private _debouncedFormulaCalculation;
162
+ /**
163
+ * Initialize the FUniver instance.
164
+ *
165
+ * @private
166
+ */
167
+ _initialize(): void;
12
168
  setInitialFormulaComputing(calculationMode: CalculationMode): void;
169
+ registerFunction(name: string, func: IRegisterFunction): IDisposable;
170
+ registerFunction(name: string, func: IRegisterFunction, description: string): IDisposable;
171
+ registerAsyncFunction(name: string, func: IRegisterAsyncFunction): IDisposable;
172
+ registerAsyncFunction(name: string, func: IRegisterAsyncFunction, description: string): IDisposable;
13
173
  }
14
174
  declare module '@univerjs/engine-formula' {
15
175
  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
  */
@@ -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)});