@univerjs/engine-formula 0.12.4 → 0.13.0-insiders.20251216-1519cb7

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,5 @@
1
- import { IDisposable, ICommandService, IConfigService, Injector } from '@univerjs/core';
2
- import { FormulaExecutedStateType, IExecutionInProgressParams, ISequenceNode, LexerTreeBuilder } from '@univerjs/engine-formula';
1
+ import { IDisposable, IUnitRange, ICommandService, IConfigService, Injector } from '@univerjs/core';
2
+ import { FormulaExecutedStateType, IExecutionInProgressParams, IExprTreeNode, IFormulaDependencyTreeFullJson, IFormulaDependencyTreeJson, IFormulaExecuteResultMap, IFormulaStringMap, ISequenceNode, ISetFormulaCalculationResultMutation, IDefinedNamesService, IFunctionService, ISuperTableService, LexerTreeBuilder } from '@univerjs/engine-formula';
3
3
  import { FBase } from '@univerjs/core/facade';
4
4
  /**
5
5
  * This interface class provides methods to modify the behavior of the operation formula.
@@ -10,7 +10,10 @@ export declare class FFormula extends FBase {
10
10
  protected readonly _injector: Injector;
11
11
  private _lexerTreeBuilder;
12
12
  protected readonly _configService: IConfigService;
13
- constructor(_commandService: ICommandService, _injector: Injector, _lexerTreeBuilder: LexerTreeBuilder, _configService: IConfigService);
13
+ private readonly _functionService;
14
+ private readonly _definedNamesService;
15
+ private readonly _superTableService;
16
+ constructor(_commandService: ICommandService, _injector: Injector, _lexerTreeBuilder: LexerTreeBuilder, _configService: IConfigService, _functionService: IFunctionService, _definedNamesService: IDefinedNamesService, _superTableService: ISuperTableService);
14
17
  /**
15
18
  * @ignore
16
19
  */
@@ -146,4 +149,370 @@ export declare class FFormula extends FBase {
146
149
  * ```
147
150
  */
148
151
  setMaxIteration(maxIteration: number): void;
152
+ /**
153
+ * Listens for the moment when formula-calculation results are applied.
154
+ *
155
+ * This event fires after the engine completes a calculation cycle and
156
+ * dispatches a `SetFormulaCalculationResultMutation`.
157
+ * The callback is invoked during an idle frame to avoid blocking UI updates.
158
+ *
159
+ * @param {Function} callback - A function called with the calculation result payload
160
+ * once the result-application mutation is emitted.
161
+ * @returns {IDisposable} A disposable used to unsubscribe from the event.
162
+ *
163
+ * @example
164
+ * ```ts
165
+ * const formulaEngine = univerAPI.getFormula();
166
+ *
167
+ * const dispose = formulaEngine.calculationResultApplied((result) => {
168
+ * console.log('Calculation results applied:', result);
169
+ * });
170
+ *
171
+ * // Later…
172
+ * dispose.dispose();
173
+ * ```
174
+ */
175
+ calculationResultApplied(callback: (result: ISetFormulaCalculationResultMutation) => void): IDisposable;
176
+ /**
177
+ * Waits for formula-calculation results to be applied.
178
+ *
179
+ * This method resolves under three conditions:
180
+ * 1. A real calculation runs and the engine emits a "calculation started" signal,
181
+ * followed by a "calculation result applied" signal.
182
+ * 2. No calculation actually starts within 500 ms — the method assumes there is
183
+ * nothing to wait for and resolves automatically.
184
+ * 3. A global 30 s timeout triggers, in which case the promise rejects.
185
+ *
186
+ * The API internally listens to both “calculation in progress” events and
187
+ * “calculation result applied” events, ensuring it behaves correctly whether
188
+ * formulas are recalculated or skipped due to cache/state.
189
+ *
190
+ * @returns {Promise<void>} A promise that resolves when calculation results are applied
191
+ * or when no calculation occurs within the start-detection window.
192
+ *
193
+ * @example
194
+ * ```ts
195
+ * const formulaEngine = univerAPI.getFormula();
196
+ *
197
+ * // Wait for formula updates to apply before reading values.
198
+ * await formulaEngine.onCalculationResultApplied();
199
+ *
200
+ * const value = sheet.getRange("C24").getValue();
201
+ * console.log("Updated value:", value);
202
+ * ```
203
+ */
204
+ onCalculationResultApplied(): Promise<void>;
205
+ /**
206
+ * Execute a batch of formulas asynchronously and receive computed results.
207
+ *
208
+ * Each formula cell is represented as a string array:
209
+ * [fullFormula, ...subFormulas]
210
+ *
211
+ * Where:
212
+ * - fullFormula (index 0) is the complete formula expression written in the cell.
213
+ * Example: "=SUM(A1:A10) + SQRT(D7)".
214
+ *
215
+ * - subFormulas (index 1+) are **optional decomposed expressions** extracted from
216
+ * the full formula. Each of them can be independently computed by the formula engine.
217
+ *
218
+ * These sub-expressions can include:
219
+ * - Single-cell references: "A2", "B2", "C5"
220
+ * - Range references: "A1:A10"
221
+ * - Function calls: "SQRT(D7)", "ABS(A2-B2)"
222
+ * - Any sub-formula that was parsed out of the original formula and can be
223
+ * evaluated on its own.
224
+ *
225
+ * The batch execution engine may use these sub-formulas for dependency resolution,
226
+ * incremental computation, or performance optimizations.
227
+ *
228
+ * @param {IFormulaStringMap} formulas
229
+ * Nested structure (unit → sheet → row → column) describing formulas and
230
+ * their decomposed sub-expressions.
231
+ *
232
+ * @param {number} [timeout]
233
+ * Optional timeout in milliseconds. If no result is received within this
234
+ * period, the promise will be rejected.
235
+ *
236
+ * @returns {Promise<IFormulaExecuteResultMap>}
237
+ * A promise that resolves with the computed value map mirroring
238
+ * the input structure.
239
+ *
240
+ * @example
241
+ * ```ts
242
+ * const formulaEngine = univerAPI.getFormula();
243
+ * const formulas = {
244
+ * Book1: {
245
+ * Sheet1: {
246
+ * 2: {
247
+ * 3: [
248
+ * // Full formula:
249
+ * "=SUM(A1:A10) + SQRT(D7)",
250
+ *
251
+ * // Decomposed sub-formulas (each one can be evaluated independently):
252
+ * "SUM(A1:A10)", // sub-formula 1
253
+ * "SQRT(D7)", // sub-formula 2
254
+ * "A1:A10", // range reference
255
+ * "D7", // single-cell reference
256
+ * ],
257
+ * },
258
+ * 4: {
259
+ * 5: [
260
+ * "=A2 + B2 + SQRT(C5)",
261
+ * "A2",
262
+ * "B2",
263
+ * "SQRT(C5)",
264
+ * ],
265
+ * }
266
+ * },
267
+ * },
268
+ * };
269
+ *
270
+ * const result = await formulaEngine.executeFormulas(formulas);
271
+ * console.log(result);
272
+ * ```
273
+ */
274
+ executeFormulas(formulas: IFormulaStringMap, timeout?: number): Promise<IFormulaExecuteResultMap>;
275
+ /**
276
+ * Retrieve all formula dependency trees that were produced during the latest
277
+ * dependency-analysis run. This triggers a local dependency-calculation command
278
+ * and returns the complete set of dependency trees once the calculation finishes.
279
+ *
280
+ * @param {number} [timeout]
281
+ * Optional timeout in milliseconds. If no result is received within this
282
+ * period, the promise will be rejected.
283
+ *
284
+ * @returns {Promise<IFormulaDependencyTreeJson[]>}
285
+ * A promise that resolves with the array of dependency trees.
286
+ *
287
+ * @example
288
+ * ```ts
289
+ * const formulaEngine = univerAPI.getFormula();
290
+ *
291
+ * // Fetch all dependency trees generated for the current workbook.
292
+ * const trees = await formulaEngine.getAllDependencyTrees();
293
+ * console.log('All dependency trees:', trees);
294
+ * ```
295
+ */
296
+ getAllDependencyTrees(timeout?: number): Promise<IFormulaDependencyTreeJson[]>;
297
+ /**
298
+ * Retrieve the dependency tree of a specific cell. This triggers a local
299
+ * dependency-calculation command for the given unit, sheet, and cell location,
300
+ * and returns the computed dependency tree when the calculation is completed.
301
+ *
302
+ * @param param The target cell location:
303
+ * - `unitId` The workbook ID.
304
+ * - `sheetId` The sheet ID.
305
+ * - `row` The zero-based row index.
306
+ * - `column` The zero-based column index.
307
+ *
308
+ * @param {number} [timeout]
309
+ * Optional timeout in milliseconds. If no result is received within this
310
+ * period, the promise will be rejected.
311
+ *
312
+ * @returns {Promise<IFormulaDependencyTreeFullJson | undefined>}
313
+ * A promise that resolves with the dependency tree or `undefined`
314
+ * if no tree exists for that cell.
315
+ *
316
+ * @example
317
+ * ```ts
318
+ * const formulaEngine = univerAPI.getFormula();
319
+ *
320
+ * // Query the dependency tree for cell B2 in a specific sheet.
321
+ * const tree = await formulaEngine.getCellDependencyTree({
322
+ * unitId: 'workbook1',
323
+ * sheetId: 'sheet1',
324
+ * row: 1,
325
+ * column: 1,
326
+ * });
327
+ *
328
+ * console.log('Cell dependency tree:', tree);
329
+ * ```
330
+ */
331
+ getCellDependencyTree(param: {
332
+ unitId: string;
333
+ sheetId: string;
334
+ row: number;
335
+ column: number;
336
+ }, timeout?: number): Promise<IFormulaDependencyTreeFullJson | undefined>;
337
+ /**
338
+ * Retrieve the full dependency trees for all formulas that *depend on* the
339
+ * specified ranges. This triggers a local dependency-calculation command and
340
+ * resolves once the calculation completes.
341
+ *
342
+ * @param unitRanges An array of workbook/sheet ranges to query. Each range
343
+ * includes:
344
+ * - `unitId` The workbook ID.
345
+ * - `sheetId` The sheet ID.
346
+ * - `range` The row/column boundaries.
347
+ *
348
+ * @param {number} [timeout]
349
+ * Optional timeout in milliseconds. If no result is received within this
350
+ * period, the promise will be rejected.
351
+ *
352
+ * @returns {Promise<IFormulaDependencyTreeJson[]>}
353
+ * A promise that resolves with an array of `IFormulaDependencyTreeJson`
354
+ * representing formulas and their relationships within the dependency graph.
355
+ *
356
+ * @example
357
+ * ```ts
358
+ * const formulaEngine = univerAPI.getFormula();
359
+ *
360
+ * // Query all formulas that depend on A1:B10 in Sheet1.
361
+ * const dependents = await formulaEngine.getRangeDependents([
362
+ * { unitId: 'workbook1', sheetId: 'sheet1', range: { startRow: 0, endRow: 9, startColumn: 0, endColumn: 1 } }
363
+ * ]);
364
+ *
365
+ * console.log('Dependent formulas:', dependents);
366
+ * ```
367
+ */
368
+ getRangeDependents(unitRanges: IUnitRange[], timeout?: number): Promise<IFormulaDependencyTreeJson[]>;
369
+ /**
370
+ * Retrieve the dependency trees of all formulas *inside* the specified ranges.
371
+ * Unlike `getRangeDependents`, this API only returns formulas whose definitions
372
+ * physically reside within the queried ranges.
373
+ *
374
+ * Internally this triggers the same dependency-calculation command but with
375
+ * `isInRange = true`, and the promise resolves when the results are ready.
376
+ *
377
+ * @param unitRanges An array of workbook/sheet ranges defining the lookup
378
+ * boundaries:
379
+ * - `unitId` The workbook ID.
380
+ * - `sheetId` The sheet ID.
381
+ * - `range` The zero-based grid range.
382
+ *
383
+ * @param {number} [timeout]
384
+ * Optional timeout in milliseconds. If no result is received within this
385
+ * period, the promise will be rejected.
386
+ *
387
+ * @returns {Promise<IFormulaDependencyTreeJson[]>}
388
+ * A promise that resolves with an array of `IFormulaDependencyTreeJson`
389
+ * describing every formula found in the provided ranges along with
390
+ * their parent/child relationships.
391
+ *
392
+ * @example
393
+ * ```ts
394
+ * const formulaEngine = univerAPI.getFormula();
395
+ *
396
+ * // Query all formulas that lie within A1:D20 in Sheet1.
397
+ * const formulasInRange = await formulaEngine.getInRangeFormulas([
398
+ * { unitId: 'workbook1', sheetId: 'sheet1', range: { startRow: 0, endRow: 19, startColumn: 0, endColumn: 3 } }
399
+ * ]);
400
+ *
401
+ * console.log('Formulas inside range:', formulasInRange);
402
+ * ```
403
+ */
404
+ getInRangeFormulas(unitRanges: IUnitRange[], timeout?: number): Promise<IFormulaDependencyTreeJson[]>;
405
+ /**
406
+ * Enable or disable emitting formula dependency trees after each formula calculation.
407
+ *
408
+ * When enabled, the formula engine will emit the dependency trees produced by
409
+ * each completed formula calculation through the internal command system.
410
+ * Consumers can obtain the result by listening for the corresponding
411
+ * calculation-result command.
412
+ *
413
+ * When disabled, dependency trees will not be emitted.
414
+ *
415
+ * This option only controls whether dependency trees are exposed.
416
+ * It does not affect formula calculation behavior.
417
+ *
418
+ * @param {boolean} value
419
+ * Whether to emit formula dependency trees after calculation.
420
+ * - `true`: Emit dependency trees after each calculation.
421
+ * - `false`: Do not emit dependency trees (default behavior).
422
+ *
423
+ * @example
424
+ * ```ts
425
+ * const formulaEngine = univerAPI.getFormula();
426
+ *
427
+ * // Enable dependency tree emission
428
+ * formulaEngine.setFormulaReturnDependencyTree(true);
429
+ *
430
+ * // Listen for dependency trees produced by formula calculation
431
+ * const trees = await new Promise<IFormulaDependencyTreeJson[]>((resolve, reject) => {
432
+ * const timer = setTimeout(() => {
433
+ * disposable.dispose();
434
+ * reject(new Error('Timeout waiting for formula dependency trees'));
435
+ * }, 30_000);
436
+ *
437
+ * const disposable = commandService.onCommandExecuted((command) => {
438
+ * if (command.id !== SetFormulaDependencyCalculationResultMutation.id) {
439
+ * return;
440
+ * }
441
+ *
442
+ * clearTimeout(timer);
443
+ * disposable.dispose();
444
+ *
445
+ * const params = command.params as ISetFormulaDependencyCalculationResultMutation;
446
+ * resolve(params.result ?? []);
447
+ * });
448
+ * });
449
+ *
450
+ * console.log('Dependency trees:', trees);
451
+ * ```
452
+ */
453
+ setFormulaReturnDependencyTree(value: boolean): void;
454
+ /**
455
+ * Parse a formula string and return its **formula expression tree**.
456
+ *
457
+ * This API analyzes the syntactic structure of a formula and builds an
458
+ * expression tree that reflects how the formula is composed (functions,
459
+ * operators, ranges, and nested expressions), without performing calculation
460
+ * or dependency evaluation.
461
+ *
462
+ * The returned tree is suitable for:
463
+ * - Formula structure visualization
464
+ * - Explaining complex formulas (e.g. LET / LAMBDA)
465
+ * - Debugging or inspecting formula composition
466
+ * - Building advanced formula tooling
467
+ *
468
+ * ---
469
+ *
470
+ * @example
471
+ * ```ts
472
+ * const formulaEngine = univerAPI.getFormula();
473
+ *
474
+ * const formula = '=LET(x,SUM(A1,B1,A1:B10),y,OFFSET(A1:B10,0,1),SUM(x,y)+x)+1';
475
+ *
476
+ * const exprTree = formulaEngine.getFormulaExpressTree(formula);
477
+ *
478
+ * console.log(exprTree);
479
+ * ```
480
+ *
481
+ * Example output (simplified):
482
+ *
483
+ * ```json
484
+ * {
485
+ * "value": "let(x,sum(A1,B1,A1:B10),y,offset(A1:B10,0,1),sum(x,y)+x)+1",
486
+ * "children": [
487
+ * {
488
+ * "value": "let(x,sum(A1,B1,A1:B10),y,offset(A1:B10,0,1),sum(x,y)+x)",
489
+ * "children": [
490
+ * {
491
+ * "value": "sum(A1,B1,A1:B10)",
492
+ * "children": [
493
+ * {
494
+ * "value": "A1:B10",
495
+ * "children": []
496
+ * }
497
+ * ]
498
+ * },
499
+ * {
500
+ * "value": "offset(A1:B10,0,1)",
501
+ * "children": [
502
+ * {
503
+ * "value": "A1:B10",
504
+ * "children": []
505
+ * }
506
+ * ]
507
+ * }
508
+ * ]
509
+ * }
510
+ * ]
511
+ * }
512
+ * ```
513
+ *
514
+ * @param formulaString The formula string to parse (with or without leading `=`)
515
+ * @returns A formula expression tree describing the hierarchical structure of the formula
516
+ */
517
+ getFormulaExpressTree(formulaString: string, unitId: string): IExprTreeNode | null;
149
518
  }
@@ -13,10 +13,10 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- export type { IArrayFormulaEmbeddedMap, IArrayFormulaRangeType, IArrayFormulaUnitCellType, IDirtyUnitFeatureMap, IDirtyUnitOtherFormulaMap, IDirtyUnitSheetDefinedNameMap, IDirtyUnitSheetNameMap, IFeatureDirtyRangeType, IFormulaData, IFormulaDataItem, IFormulaDatasetConfig, IRuntimeImageFormulaDataType, IRuntimeUnitDataType, ISheetData, IUnitData, IUnitImageFormulaDataType, IUnitSheetNameMap, } from './basics/common';
16
+ export type { IArrayFormulaEmbeddedMap, IArrayFormulaRangeType, IArrayFormulaUnitCellType, IDirtyUnitFeatureMap, IDirtyUnitOtherFormulaMap, IDirtyUnitSheetDefinedNameMap, IDirtyUnitSheetNameMap, IFeatureDirtyRangeType, IFormulaData, IFormulaDataItem, IFormulaDatasetConfig, IFormulaExecuteResultMap, IFormulaStringMap, IRuntimeImageFormulaDataType, IRuntimeUnitDataType, ISheetData, IUnitData, IUnitImageFormulaDataType, IUnitSheetNameMap, } from './basics/common';
17
17
  export { BooleanValue } from './basics/common';
18
18
  export { type IOtherFormulaData } from './basics/common';
19
- export { type IUnitRowData } from './basics/common';
19
+ export type { IExprTreeNode, ISuperTable, IUnitRowData } from './basics/common';
20
20
  export { isInDirtyRange } from './basics/dirty';
21
21
  export { ERROR_TYPE_SET, ErrorType } from './basics/error-type';
22
22
  export { type ISheetFormulaError } from './basics/error-type';
@@ -33,14 +33,14 @@ export { type ISetArrayFormulaDataMutationParams, SetArrayFormulaDataMutation }
33
33
  export { type ISetDefinedNameMutationParam, type ISetDefinedNameMutationSearchParam, RemoveDefinedNameMutation, SetDefinedNameMutation } from './commands/mutations/set-defined-name.mutation';
34
34
  export { SetDefinedNameMutationFactory } from './commands/mutations/set-defined-name.mutation';
35
35
  export { RemoveFeatureCalculationMutation, SetFeatureCalculationMutation } from './commands/mutations/set-feature-calculation.mutation';
36
- export { type ISetFormulaCalculationNotificationMutation, type ISetFormulaCalculationResultMutation, type ISetFormulaCalculationStartMutation, SetFormulaCalculationNotificationMutation, SetFormulaCalculationResultMutation, SetFormulaCalculationStartMutation, SetFormulaCalculationStopMutation, } from './commands/mutations/set-formula-calculation.mutation';
36
+ export { type ISetCellFormulaDependencyCalculationResultMutation, type ISetFormulaCalculationNotificationMutation, type ISetFormulaCalculationResultMutation, type ISetFormulaCalculationStartMutation, type ISetFormulaDependencyCalculationMutation, type ISetFormulaDependencyCalculationResultMutation, type ISetFormulaStringBatchCalculationResultMutation, type ISetQueryFormulaDependencyResultMutation, SetCellFormulaDependencyCalculationMutation, SetCellFormulaDependencyCalculationResultMutation, SetFormulaCalculationNotificationMutation, SetFormulaCalculationResultMutation, SetFormulaCalculationStartMutation, SetFormulaCalculationStopMutation, SetFormulaDependencyCalculationMutation, SetFormulaDependencyCalculationResultMutation, SetFormulaStringBatchCalculationMutation, SetFormulaStringBatchCalculationResultMutation, SetQueryFormulaDependencyMutation, SetQueryFormulaDependencyResultMutation, } from './commands/mutations/set-formula-calculation.mutation';
37
37
  export { type ISetFormulaDataMutationParams, SetFormulaDataMutation } from './commands/mutations/set-formula-data.mutation';
38
38
  export { type ISetImageFormulaDataMutationParams, SetImageFormulaDataMutation } from './commands/mutations/set-image-formula-data.mutation';
39
39
  export { type IRemoveOtherFormulaMutationParams, type ISetOtherFormulaMutationParams, RemoveOtherFormulaMutation, SetOtherFormulaMutation } from './commands/mutations/set-other-formula.mutation';
40
40
  export { RemoveSuperTableMutation, SetSuperTableMutation, SetSuperTableOptionMutation } from './commands/mutations/set-super-table.mutation';
41
41
  export type { ISetSuperTableMutationParam, ISetSuperTableMutationSearchParam } from './commands/mutations/set-super-table.mutation';
42
42
  export { CalculateController } from './controller/calculate.controller';
43
- export { ENGINE_FORMULA_CYCLE_REFERENCE_COUNT, ENGINE_FORMULA_PLUGIN_CONFIG_KEY, type IUniverEngineFormulaConfig } from './controller/config.schema';
43
+ export { ENGINE_FORMULA_CYCLE_REFERENCE_COUNT, ENGINE_FORMULA_PLUGIN_CONFIG_KEY, ENGINE_FORMULA_RETURN_DEPENDENCY_TREE, type IUniverEngineFormulaConfig } from './controller/config.schema';
44
44
  export { Lexer } from './engine/analysis/lexer';
45
45
  export { LexerNode } from './engine/analysis/lexer-node';
46
46
  export { LexerTreeBuilder } from './engine/analysis/lexer-tree-builder';
@@ -56,7 +56,7 @@ export { ReferenceNodeFactory } from './engine/ast-node/reference-node';
56
56
  export { SuffixNodeFactory } from './engine/ast-node/suffix-node';
57
57
  export { UnionNodeFactory } from './engine/ast-node/union-node';
58
58
  export { ValueNodeFactory } from './engine/ast-node/value-node';
59
- export { FormulaDependencyTree, type IFormulaDependencyTree } from './engine/dependency/dependency-tree';
59
+ export { FormulaDependencyTree, FormulaDependencyTreeModel, type IFormulaDependencyTree, type IFormulaDependencyTreeFullJson, type IFormulaDependencyTreeJson } from './engine/dependency/dependency-tree';
60
60
  export { FormulaDependencyTreeType } from './engine/dependency/dependency-tree';
61
61
  export { FormulaDependencyTreeVirtual } from './engine/dependency/dependency-tree';
62
62
  export { FormulaDependencyGenerator, IFormulaDependencyGenerator } from './engine/dependency/formula-dependency';
@@ -71,7 +71,7 @@ export { generateAstNode } from './engine/utils/generate-ast-node';
71
71
  export { strip, stripErrorMargin } from './engine/utils/math-kit';
72
72
  export { handleNumfmtInCell } from './engine/utils/numfmt-kit';
73
73
  export { deserializeRangeForR1C1 } from './engine/utils/r1c1-reference';
74
- export { deserializeRangeWithSheet, getAbsoluteRefTypeWithSingleString, getAbsoluteRefTypeWitString, getRangeWithRefsString, type IAbsoluteRefTypeForRange, isReferenceStrings, isReferenceStringWithEffectiveColumn, needsQuoting, quoteSheetName, serializeRange, serializeRangeToRefString, serializeRangeWithSheet, serializeRangeWithSpreadsheet, singleReferenceToGrid, unquoteSheetName, } from './engine/utils/reference';
74
+ export { deserializeRangeWithSheet, getAbsoluteRefTypeWithSingleString, getAbsoluteRefTypeWitString, getRangeWithRefsString, type IAbsoluteRefTypeForRange, isReferenceStrings, isReferenceStringWithEffectiveColumn, needsQuoting, quoteSheetName, serializeRange, serializeRangeToRefString, serializeRangeWithSheet, serializeRangeWithSpreadsheet, singleReferenceToGrid, splitTableStructuredRef, unquoteSheetName, } from './engine/utils/reference';
75
75
  export { handleRefStringInfo } from './engine/utils/reference';
76
76
  export { deserializeRangeWithSheetWithCache } from './engine/utils/reference-cache';
77
77
  export { generateStringWithSequence, type ISequenceNode, sequenceNodeType } from './engine/utils/sequence';
@@ -1,10 +1,11 @@
1
+ import { IUnitRange, Disposable, IConfigService } from '@univerjs/core';
1
2
  import { Observable, Subject } from 'rxjs';
2
- import { IFeatureDirtyRangeType, IFormulaDatasetConfig, IRuntimeUnitDataType } from '../basics/common';
3
+ import { IFeatureDirtyRangeType, IFormulaDatasetConfig, IFormulaExecuteResultMap, IFormulaStringMap, IRuntimeUnitDataType, IUnitRowData } from '../basics/common';
4
+ import { IFormulaDependencyTreeFullJson, IFormulaDependencyTreeJson } from '../engine/dependency/dependency-tree';
5
+ import { FunctionVariantType } from '../engine/reference-object/base-reference-object';
3
6
  import { IAllRuntimeData, IExecutionInProgressParams, IFormulaRuntimeService } from './runtime.service';
4
- import { Disposable, IConfigService } from '@univerjs/core';
5
7
  import { Lexer } from '../engine/analysis/lexer';
6
8
  import { AstTreeBuilder } from '../engine/analysis/parser';
7
- import { ErrorNode } from '../engine/ast-node/base-ast-node';
8
9
  import { IFormulaDependencyGenerator } from '../engine/dependency/formula-dependency';
9
10
  import { Interpreter } from '../engine/interpreter/interpreter';
10
11
  import { IFormulaCurrentConfigService } from './current-data.service';
@@ -19,6 +20,11 @@ export interface ICalculateFormulaService {
19
20
  execute(formulaDatasetConfig: IFormulaDatasetConfig): Promise<void>;
20
21
  stopFormulaExecution(): void;
21
22
  calculate(formulaString: string, transformSuffix?: boolean): void;
23
+ executeFormulas(formulas: IFormulaStringMap, rowData?: IUnitRowData): Promise<IFormulaExecuteResultMap>;
24
+ getAllDependencyJson(rowData?: IUnitRowData): Promise<IFormulaDependencyTreeJson[]>;
25
+ getCellDependencyJson(unitId: string, sheetId: string, row: number, column: number, rowData?: IUnitRowData): Promise<IFormulaDependencyTreeFullJson | undefined>;
26
+ getRangeDependents(unitRanges: IUnitRange[]): Promise<IFormulaDependencyTreeJson[]>;
27
+ getInRangeFormulas(unitRanges: IUnitRange[]): Promise<IFormulaDependencyTreeJson[]>;
22
28
  }
23
29
  export declare const ICalculateFormulaService: import('@wendellhu/redi').IdentifierDecorator<ICalculateFormulaService>;
24
30
  export declare class CalculateFormulaService extends Disposable implements ICalculateFormulaService {
@@ -34,6 +40,7 @@ export declare class CalculateFormulaService extends Disposable implements ICalc
34
40
  protected readonly _executionCompleteListener$: Subject<IAllRuntimeData>;
35
41
  readonly executionCompleteListener$: Observable<IAllRuntimeData>;
36
42
  private _executeLock;
43
+ protected _isCalculateTreeModel: boolean;
37
44
  constructor(_configService: IConfigService, _lexer: Lexer, _currentConfigService: IFormulaCurrentConfigService, _runtimeService: IFormulaRuntimeService, _formulaDependencyGenerator: IFormulaDependencyGenerator, _interpreter: Interpreter, _astTreeBuilder: AstTreeBuilder);
38
45
  dispose(): void;
39
46
  /**
@@ -53,5 +60,10 @@ export declare class CalculateFormulaService extends Disposable implements ICalc
53
60
  private _executeStep;
54
61
  private _getArrayFormulaDirtyRangeAndExcludedRange;
55
62
  protected _apply(isArrayFormulaState?: boolean): Promise<IAllRuntimeData | undefined>;
56
- calculate(formulaString: string, transformSuffix?: boolean): ErrorNode | undefined;
63
+ executeFormulas(formulas: IFormulaStringMap, rowData?: IUnitRowData): Promise<IFormulaExecuteResultMap>;
64
+ calculate(formulaString: string): Promise<FunctionVariantType | undefined>;
65
+ getAllDependencyJson(): Promise<IFormulaDependencyTreeJson[]>;
66
+ getCellDependencyJson(unitId: string, sheetId: string, row: number, column: number): Promise<IFormulaDependencyTreeFullJson | undefined>;
67
+ getRangeDependents(unitRanges: IUnitRange[]): Promise<IFormulaDependencyTreeJson[]>;
68
+ getInRangeFormulas(unitRanges: IUnitRange[]): Promise<IFormulaDependencyTreeJson[]>;
57
69
  }
@@ -11,6 +11,7 @@ export interface IFormulaDirtyData {
11
11
  dirtyUnitOtherFormulaMap: IDirtyUnitOtherFormulaMap;
12
12
  clearDependencyTreeCache: IDirtyUnitSheetNameMap;
13
13
  maxIteration?: number;
14
+ isCalculateTreeModel?: boolean;
14
15
  rowData?: IUnitRowData;
15
16
  }
16
17
  export interface IFormulaCurrentConfigService {
@@ -55,6 +56,7 @@ export interface IFormulaCurrentConfigService {
55
56
  };
56
57
  getFilteredOutRows(unitId: string, sheetId: string, startRow: number, endRow: number): number[];
57
58
  setSheetNameMap(sheetIdToNameMap: IUnitSheetIdToNameMap): void;
59
+ loadDataLite(rowData?: IUnitRowData): void;
58
60
  }
59
61
  export declare class FormulaCurrentConfigService extends Disposable implements IFormulaCurrentConfigService {
60
62
  private readonly _univerInstanceService;
@@ -113,6 +115,7 @@ export declare class FormulaCurrentConfigService extends Disposable implements I
113
115
  };
114
116
  getFilteredOutRows(unitId: string, sheetId: string, startRow: number, endRow: number): number[];
115
117
  load(config: IFormulaDatasetConfig): void;
118
+ loadDataLite(rowData?: IUnitRowData): void;
116
119
  getDirtyData(): IFormulaDirtyData;
117
120
  loadDirtyRangesAndExcludedCell(dirtyRanges: IUnitRange[], excludedCell?: IUnitExcludedCell): void;
118
121
  registerUnitData(unitData: IUnitData): void;
@@ -64,6 +64,7 @@ export declare class DefinedNamesService extends Disposable implements IDefinedN
64
64
  getValueById(unitId: string, id: string): IDefinedNamesServiceParam;
65
65
  hasDefinedName(unitId: string): boolean;
66
66
  getAllDefinedNames(): IDefinedNameMap;
67
+ getDefinedNameByRefString(unitId: string, formulaOrRefString: string): IDefinedNamesServiceParam | undefined;
67
68
  private _update;
68
69
  private _updateCache;
69
70
  }
@@ -1,6 +1,7 @@
1
1
  import { Nullable, Disposable } from '@univerjs/core';
2
2
  import { IArrayFormulaEmbeddedMap, IArrayFormulaRangeType, IFeatureDirtyRangeType, IRuntimeImageFormulaDataType, IRuntimeOtherUnitDataType, IRuntimeUnitDataType } from '../basics/common';
3
3
  import { BaseAstNode } from '../engine/ast-node/base-ast-node';
4
+ import { IFormulaDependencyTreeJson } from '../engine/dependency/dependency-tree';
4
5
  import { FunctionVariantType } from '../engine/reference-object/base-reference-object';
5
6
  import { IFormulaCurrentConfigService } from './current-data.service';
6
7
  import { IHyperlinkEngineFormulaService } from './hyperlink-engine-formula.service';
@@ -40,6 +41,7 @@ export interface IAllRuntimeData {
40
41
  runtimeFeatureCellData: {
41
42
  [featureId: string]: IRuntimeUnitDataType;
42
43
  };
44
+ dependencyTreeModelData: IFormulaDependencyTreeJson[];
43
45
  }
44
46
  export interface IExecutionInProgressParams {
45
47
  totalFormulasToCalculate: number;
@@ -100,6 +102,8 @@ export interface IFormulaRuntimeService {
100
102
  setUnitArrayFormulaEmbeddedMap(): void;
101
103
  clearArrayObjectCache(): void;
102
104
  getRuntimeImageFormulaData(): IRuntimeImageFormulaDataType[];
105
+ setDependencyTreeModelData(data: IFormulaDependencyTreeJson[]): void;
106
+ getDependencyTreeModelData(): IFormulaDependencyTreeJson[];
103
107
  }
104
108
  export declare class FormulaRuntimeService extends Disposable implements IFormulaRuntimeService {
105
109
  private readonly _currentConfigService;
@@ -129,6 +133,7 @@ export declare class FormulaRuntimeService extends Disposable implements IFormul
129
133
  private _completedArrayFormulasCount;
130
134
  private _formulaCycleIndex;
131
135
  private _isCycleDependency;
136
+ private _dependencyTreeModelData;
132
137
  constructor(_currentConfigService: IFormulaCurrentConfigService, _hyperlinkEngineFormulaService: IHyperlinkEngineFormulaService);
133
138
  get currentRow(): number;
134
139
  get currentColumn(): number;
@@ -182,6 +187,8 @@ export declare class FormulaRuntimeService extends Disposable implements IFormul
182
187
  [featureId: string]: IRuntimeUnitDataType;
183
188
  };
184
189
  setRuntimeFeatureCellData(featureId: string, featureData: IRuntimeUnitDataType): void;
190
+ setDependencyTreeModelData(data: IFormulaDependencyTreeJson[]): void;
191
+ getDependencyTreeModelData(): IFormulaDependencyTreeJson[];
185
192
  getRuntimeImageFormulaData(): IRuntimeImageFormulaDataType[];
186
193
  getAllRuntimeData(): IAllRuntimeData;
187
194
  getRuntimeState(): IExecutionInProgressParams;
@@ -12,6 +12,7 @@ export interface ISuperTableService {
12
12
  registerTableOptionMap(tableOption: string, tableOptionType: TableOptionType): void;
13
13
  remove(unitId: string, tableName: string): void;
14
14
  update$: Observable<unknown>;
15
+ getTable(unitId: string, tableName: string): Nullable<ISuperTable>;
15
16
  }
16
17
  export declare class SuperTableService extends Disposable implements ISuperTableService {
17
18
  private _tableMap;
@@ -25,6 +26,7 @@ export declare class SuperTableService extends Disposable implements ISuperTable
25
26
  getTableOptionMap(): Map<string, TableOptionType>;
26
27
  registerTable(unitId: string, tableName: string, reference: ISuperTable): void;
27
28
  registerTableOptionMap(tableOption: string, tableOptionType: TableOptionType): void;
29
+ getTable(unitId: string, tableName: string): Nullable<ISuperTable>;
28
30
  private _update;
29
31
  }
30
32
  export declare const ISuperTableService: import('@wendellhu/redi').IdentifierDecorator<ISuperTableService>;
package/lib/umd/facade.js CHANGED
@@ -1 +1 @@
1
- (function(r,o){typeof exports=="object"&&typeof module<"u"?o(exports,require("@univerjs/core/facade"),require("@univerjs/core"),require("@univerjs/engine-formula"),require("rxjs")):typeof define=="function"&&define.amd?define(["exports","@univerjs/core/facade","@univerjs/core","@univerjs/engine-formula","rxjs"],o):(r=typeof globalThis<"u"?globalThis:r||self,o(r.UniverEngineFormulaFacade={},r.UniverCoreFacade,r.UniverCore,r.UniverEngineFormula,r.rxjs))})(this,(function(r,o,u,a,s){"use strict";var f=Object.getOwnPropertyDescriptor,v=(c,e,t,i)=>{for(var n=i>1?void 0:i?f(e,t):e,d=c.length-1,m;d>=0;d--)(m=c[d])&&(n=m(n)||n);return n},l=(c,e)=>(t,i)=>e(t,i,c);r.FFormula=class extends o.FBase{constructor(e,t,i,n){super(),this._commandService=e,this._injector=t,this._lexerTreeBuilder=i,this._configService=n,this._initialize()}_initialize(){}get lexerTreeBuilder(){return this._lexerTreeBuilder}moveFormulaRefOffset(e,t,i,n){return this._lexerTreeBuilder.moveFormulaRefOffset(e,t,i,n)}sequenceNodesBuilder(e){return this._lexerTreeBuilder.sequenceNodesBuilder(e)||[]}executeCalculation(){this._commandService.executeCommand(a.SetFormulaCalculationStartMutation.id,{commands:[],forceCalculation:!0},{onlyLocal:!0})}stopCalculation(){this._commandService.executeCommand(a.SetFormulaCalculationStopMutation.id,{})}calculationStart(e){return this._commandService.onCommandExecuted(t=>{if(t.id===a.SetFormulaCalculationStartMutation.id){const i=t.params;e(i.forceCalculation)}})}calculationEnd(e){return this._commandService.onCommandExecuted(t=>{if(t.id!==a.SetFormulaCalculationNotificationMutation.id)return;const i=t.params;i.functionsExecutedState!==void 0&&e(i.functionsExecutedState)})}whenComputingCompleteAsync(e){const t=this._injector.get(a.GlobalComputingStatusService);return t.computingStatus?Promise.resolve(!0):s.firstValueFrom(s.race(t.computingStatus$.pipe(s.filter(i=>i)),s.timer(e!=null?e:3e4).pipe(s.map(()=>!1))))}onCalculationEnd(){return new Promise((e,t)=>{const i=setTimeout(()=>{t(new Error("Calculation end timeout"))},3e4),n=this.calculationEnd(()=>{clearTimeout(i),n.dispose(),e()})})}calculationProcessing(e){return this._commandService.onCommandExecuted(t=>{if(t.id!==a.SetFormulaCalculationNotificationMutation.id)return;const i=t.params;i.stageInfo!==void 0&&e(i.stageInfo)})}setMaxIteration(e){this._configService.setConfig(a.ENGINE_FORMULA_CYCLE_REFERENCE_COUNT,e)}},r.FFormula=v([l(0,u.Inject(u.ICommandService)),l(1,u.Inject(u.Injector)),l(2,u.Inject(a.LexerTreeBuilder)),l(3,u.IConfigService)],r.FFormula);class C extends o.FUniver{getFormula(){return this._injector.createInstance(r.FFormula)}}o.FUniver.extend(C),Object.defineProperty(r,Symbol.toStringTag,{value:"Module"})}));
1
+ (function(u,l){typeof exports=="object"&&typeof module<"u"?l(exports,require("@univerjs/core/facade"),require("@univerjs/core"),require("@univerjs/engine-formula"),require("rxjs")):typeof define=="function"&&define.amd?define(["exports","@univerjs/core/facade","@univerjs/core","@univerjs/engine-formula","rxjs"],l):(u=typeof globalThis<"u"?globalThis:u||self,l(u.UniverEngineFormulaFacade={},u.UniverCoreFacade,u.UniverCore,u.UniverEngineFormula,u.rxjs))})(this,(function(u,l,m,n,f){"use strict";var v=Object.getOwnPropertyDescriptor,C=(p,e,t,i)=>{for(var r=i>1?void 0:i?v(e,t):e,o=p.length-1,a;o>=0;o--)(a=p[o])&&(r=a(r)||r);return r},d=(p,e)=>(t,i)=>e(t,i,p);u.FFormula=class extends l.FBase{constructor(e,t,i,r,o,a,s){super(),this._commandService=e,this._injector=t,this._lexerTreeBuilder=i,this._configService=r,this._functionService=o,this._definedNamesService=a,this._superTableService=s,this._initialize()}_initialize(){}get lexerTreeBuilder(){return this._lexerTreeBuilder}moveFormulaRefOffset(e,t,i,r){return this._lexerTreeBuilder.moveFormulaRefOffset(e,t,i,r)}sequenceNodesBuilder(e){return this._lexerTreeBuilder.sequenceNodesBuilder(e)||[]}executeCalculation(){this._commandService.executeCommand(n.SetFormulaCalculationStartMutation.id,{commands:[],forceCalculation:!0},{onlyLocal:!0})}stopCalculation(){this._commandService.executeCommand(n.SetFormulaCalculationStopMutation.id,{})}calculationStart(e){return this._commandService.onCommandExecuted(t=>{if(t.id===n.SetFormulaCalculationStartMutation.id){const i=t.params;e(i.forceCalculation)}})}calculationEnd(e){return this._commandService.onCommandExecuted(t=>{if(t.id!==n.SetFormulaCalculationNotificationMutation.id)return;const i=t.params;i.functionsExecutedState!==void 0&&e(i.functionsExecutedState)})}whenComputingCompleteAsync(e){const t=this._injector.get(n.GlobalComputingStatusService);return t.computingStatus?Promise.resolve(!0):f.firstValueFrom(f.race(t.computingStatus$.pipe(f.filter(i=>i)),f.timer(e!=null?e:3e4).pipe(f.map(()=>!1))))}onCalculationEnd(){return new Promise((e,t)=>{const i=setTimeout(()=>{t(new Error("Calculation end timeout"))},3e4),r=this.calculationEnd(()=>{clearTimeout(i),r.dispose(),e()})})}calculationProcessing(e){return this._commandService.onCommandExecuted(t=>{if(t.id!==n.SetFormulaCalculationNotificationMutation.id)return;const i=t.params;i.stageInfo!==void 0&&e(i.stageInfo)})}setMaxIteration(e){this._configService.setConfig(n.ENGINE_FORMULA_CYCLE_REFERENCE_COUNT,e)}calculationResultApplied(e){return this._commandService.onCommandExecuted(t=>{if(t.id!==n.SetFormulaCalculationResultMutation.id)return;const i=t.params;i!==void 0&&requestIdleCallback(()=>{e(i)})})}onCalculationResultApplied(){return new Promise((e,t)=>{let i=!1,r=!1;const o=setTimeout(()=>{S(),t(new Error("Calculation end timeout"))},3e4),a=setTimeout(()=>{i||(S(),e())},500),s=this.calculationProcessing(()=>{i||(i=!0,clearTimeout(a))}),c=this.calculationResultApplied(()=>{r||(r=!0,S(),e())});function S(){clearTimeout(o),clearTimeout(a),s.dispose(),c.dispose()}})}executeFormulas(e,t=3e4){return new Promise((i,r)=>{const o=this._commandService.onCommandExecuted(s=>{if(s.id!==n.SetFormulaStringBatchCalculationResultMutation.id)return;const c=s.params;clearTimeout(a),o.dispose(),c.result!=null?i(c.result):r(new Error("Formula batch calculation returned no result"))}),a=setTimeout(()=>{o.dispose(),r(new Error("Formula batch calculation timeout"))},t);this._commandService.executeCommand(n.SetFormulaStringBatchCalculationMutation.id,{formulas:e},{onlyLocal:!0})})}getAllDependencyTrees(e=3e4){return new Promise((t,i)=>{const r=this._commandService.onCommandExecuted(a=>{if(a.id!==n.SetFormulaDependencyCalculationResultMutation.id)return;const s=a.params;clearTimeout(o),r.dispose(),s.result!=null?t(s.result):t([])}),o=setTimeout(()=>{r.dispose(),i(new Error("Formula dependency calculation timeout"))},e);this._commandService.executeCommand(n.SetFormulaDependencyCalculationMutation.id,void 0,{onlyLocal:!0})})}getCellDependencyTree(e,t=3e4){return new Promise((i,r)=>{const o=this._commandService.onCommandExecuted(s=>{if(s.id!==n.SetCellFormulaDependencyCalculationResultMutation.id)return;const c=s.params;clearTimeout(a),o.dispose(),i(c.result)}),a=setTimeout(()=>{o.dispose(),r(new Error("Cell dependency calculation timeout"))},t);this._commandService.executeCommand(n.SetCellFormulaDependencyCalculationMutation.id,e,{onlyLocal:!0})})}getRangeDependents(e,t=3e4){return new Promise((i,r)=>{const o=this._commandService.onCommandExecuted(s=>{if(s.id!==n.SetQueryFormulaDependencyResultMutation.id)return;const c=s.params;clearTimeout(a),o.dispose(),c.result!=null?i(c.result):i([])}),a=setTimeout(()=>{o.dispose(),r(new Error("Range dependents calculation timeout"))},t);this._commandService.executeCommand(n.SetQueryFormulaDependencyMutation.id,{unitRanges:e},{onlyLocal:!0})})}getInRangeFormulas(e,t=3e4){return new Promise((i,r)=>{const o=this._commandService.onCommandExecuted(s=>{if(s.id!==n.SetQueryFormulaDependencyResultMutation.id)return;const c=s.params;clearTimeout(a),o.dispose(),c.result!=null?i(c.result):i([])}),a=setTimeout(()=>{o.dispose(),r(new Error("In-range formulas calculation timeout"))},t);this._commandService.executeCommand(n.SetQueryFormulaDependencyMutation.id,{unitRanges:e,isInRange:!0},{onlyLocal:!0})})}setFormulaReturnDependencyTree(e){this._configService.setConfig(n.ENGINE_FORMULA_RETURN_DEPENDENCY_TREE,e)}getFormulaExpressTree(e,t){return this._lexerTreeBuilder.getFormulaExprTree(e,t,this._functionService.hasExecutor.bind(this._functionService),this._definedNamesService.getValueByName.bind(this._definedNamesService),this._superTableService.getTable.bind(this._superTableService))}},u.FFormula=C([d(0,m.Inject(m.ICommandService)),d(1,m.Inject(m.Injector)),d(2,m.Inject(n.LexerTreeBuilder)),d(3,m.IConfigService),d(4,n.IFunctionService),d(5,n.IDefinedNamesService),d(6,n.ISuperTableService)],u.FFormula);class h extends l.FUniver{getFormula(){return this._injector.createInstance(u.FFormula)}}l.FUniver.extend(h),Object.defineProperty(u,Symbol.toStringTag,{value:"Module"})}));