@univerjs/engine-formula 1.0.3 → 1.1.0

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.
Files changed (31) hide show
  1. package/lib/cjs/{en-US-DrAfIiBE.js → en-US-BYMYuEpp.js} +15 -15
  2. package/lib/cjs/facade.js +3 -18
  3. package/lib/cjs/index.js +479 -165
  4. package/lib/cjs/locale/en-US.js +1 -1
  5. package/lib/cjs/locale/fa-IR.js +1 -1
  6. package/lib/cjs/locale/zh-HK.js +1 -1
  7. package/lib/cjs/locale/zh-TW.js +1 -1
  8. package/lib/cjs/{zh-TW-CvMudVQy.js → zh-TW-B5pYt-NJ.js} +15 -15
  9. package/lib/es/facade.js +3 -18
  10. package/lib/es/index.js +453 -139
  11. package/lib/facade.js +3 -18
  12. package/lib/index.js +453 -139
  13. package/lib/types/basics/common.d.ts +8 -2
  14. package/lib/types/commands/mutations/set-formula-calculation.mutation.d.ts +4 -2
  15. package/lib/types/config/config.d.ts +0 -2
  16. package/lib/types/engine/dependency/dependency-groups.d.ts +21 -0
  17. package/lib/types/engine/dependency/dependency-tree.d.ts +1 -0
  18. package/lib/types/engine/dependency/formula-dependency.d.ts +1 -1
  19. package/lib/types/facade/f-formula.d.ts +0 -13
  20. package/lib/types/functions/lookup/xlookup/index.d.ts +2 -4
  21. package/lib/types/index.d.ts +4 -2
  22. package/lib/types/models/formula-data.model.d.ts +5 -0
  23. package/lib/types/services/active-dirty-manager.service.d.ts +1 -0
  24. package/lib/types/services/calculate-formula.service.d.ts +34 -2
  25. package/lib/types/services/current-data.service.d.ts +4 -2
  26. package/lib/types/services/formula-calculation-trigger.service.d.ts +5 -0
  27. package/lib/types/services/formula-changeset-calculation.service.d.ts +34 -0
  28. package/lib/types/services/runtime.service.d.ts +40 -3
  29. package/lib/umd/facade.js +1 -1
  30. package/lib/umd/index.js +4 -4
  31. package/package.json +5 -5
package/lib/cjs/index.js CHANGED
@@ -358,7 +358,7 @@ function getSearchModeValue(searchModeValue) {
358
358
  }
359
359
 
360
360
  //#endregion
361
- //#region \0@oxc-project+runtime@0.149.0/helpers/esm/typeof.js
361
+ //#region \0@oxc-project+runtime@0.153.0/helpers/esm/typeof.js
362
362
  function _typeof(o) {
363
363
  "@babel/helpers - typeof";
364
364
  return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
@@ -369,7 +369,7 @@ function _typeof(o) {
369
369
  }
370
370
 
371
371
  //#endregion
372
- //#region \0@oxc-project+runtime@0.149.0/helpers/esm/toPrimitive.js
372
+ //#region \0@oxc-project+runtime@0.153.0/helpers/esm/toPrimitive.js
373
373
  function toPrimitive(t, r) {
374
374
  if ("object" != _typeof(t) || !t) return t;
375
375
  var e = t[Symbol.toPrimitive];
@@ -382,14 +382,14 @@ function toPrimitive(t, r) {
382
382
  }
383
383
 
384
384
  //#endregion
385
- //#region \0@oxc-project+runtime@0.149.0/helpers/esm/toPropertyKey.js
385
+ //#region \0@oxc-project+runtime@0.153.0/helpers/esm/toPropertyKey.js
386
386
  function toPropertyKey(t) {
387
387
  var i = toPrimitive(t, "string");
388
388
  return "symbol" == _typeof(i) ? i : i + "";
389
389
  }
390
390
 
391
391
  //#endregion
392
- //#region \0@oxc-project+runtime@0.149.0/helpers/esm/defineProperty.js
392
+ //#region \0@oxc-project+runtime@0.153.0/helpers/esm/defineProperty.js
393
393
  function _defineProperty(e, r, t) {
394
394
  return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
395
395
  value: t,
@@ -1216,7 +1216,7 @@ function splitTableStructuredRef(ref) {
1216
1216
  }
1217
1217
 
1218
1218
  //#endregion
1219
- //#region \0@oxc-project+runtime@0.149.0/helpers/esm/decorateParam.js
1219
+ //#region \0@oxc-project+runtime@0.153.0/helpers/esm/decorateParam.js
1220
1220
  function __decorateParam(paramIndex, decorator) {
1221
1221
  return function(target, key) {
1222
1222
  decorator(target, key, paramIndex);
@@ -1224,7 +1224,7 @@ function __decorateParam(paramIndex, decorator) {
1224
1224
  }
1225
1225
 
1226
1226
  //#endregion
1227
- //#region \0@oxc-project+runtime@0.149.0/helpers/esm/decorate.js
1227
+ //#region \0@oxc-project+runtime@0.153.0/helpers/esm/decorate.js
1228
1228
  function __decorate(decorators, target, key, desc) {
1229
1229
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1230
1230
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -1702,8 +1702,6 @@ const SetSuperTableOptionMutation = {
1702
1702
  //#endregion
1703
1703
  //#region src/config/config.ts
1704
1704
  const ENGINE_FORMULA_PLUGIN_CONFIG_KEY = "engine-formula.config";
1705
- const DEFAULT_CYCLE_REFERENCE_COUNT = 1;
1706
- const ENGINE_FORMULA_CYCLE_REFERENCE_COUNT = "CYCLE_REFERENCE_COUNT";
1707
1705
  const ENGINE_FORMULA_RETURN_DEPENDENCY_TREE = "RETURN_DEPENDENCY_TREE";
1708
1706
  const configSymbol = Symbol(ENGINE_FORMULA_PLUGIN_CONFIG_KEY);
1709
1707
  const defaultPluginConfig = {};
@@ -3124,9 +3122,8 @@ var LexerTreeBuilder = class extends _univerjs_core.Disposable {
3124
3122
  const isCacheable = !/\b(?:LET|LAMBDA)\s*\(/iu.test(formulaString);
3125
3123
  const cacheKey = injectDefinedNameParam == null ? formulaString : `${injectDefinedNameParam.unitId ?? ""}\0${injectDefinedNameParam.sheetId ?? ""}\0${injectDefinedNameParam.refOffsetX}\0${injectDefinedNameParam.refOffsetY}\0${formulaString}`;
3126
3124
  if (transformSuffix === true && isCacheable) {
3127
- var _this$_simpleCheckDef;
3128
3125
  const lexerNode = FormulaLexerNodeCache.get(cacheKey);
3129
- const simpleCheckDefinedNameResult = injectDefinedNameParam && ((_this$_simpleCheckDef = this._simpleCheckDefinedName) === null || _this$_simpleCheckDef === void 0 ? void 0 : _this$_simpleCheckDef.call(this, formulaString, injectDefinedNameParam));
3126
+ const simpleCheckDefinedNameResult = injectDefinedNameParam && this._simpleCheckDefinedName(formulaString, injectDefinedNameParam, lexerNode);
3130
3127
  if (lexerNode && !simpleCheckDefinedNameResult) return lexerNode;
3131
3128
  }
3132
3129
  this._resetCurrentLexerNode();
@@ -3193,13 +3190,13 @@ var LexerTreeBuilder = class extends _univerjs_core.Disposable {
3193
3190
  const definedNameToken = token.trim();
3194
3191
  const definedContent = getValueByName(unitId, definedNameToken, sheetId);
3195
3192
  if (definedContent) {
3193
+ definedNames.push(definedContent.name);
3196
3194
  const refOffsetX = definedContent.localSheetId === "AllDefaultWorkbook" ? param.refOffsetX - 1 : param.refOffsetX;
3197
3195
  const refString = definedContent.formulaOrRefString.startsWith("=") ? definedContent.formulaOrRefString : this._moveDefinedNameRefOffset(definedContent.formulaOrRefString, refOffsetX, param.refOffsetY);
3198
3196
  const nestedDefinedNameParam = this._handleNestedDefinedName(refString, param);
3199
3197
  if (nestedDefinedNameParam == null || typeof nestedDefinedNameParam !== "object") {
3200
3198
  sequenceString += nestedDefinedNameParam || "#NAME?";
3201
3199
  hasDefinedName = true;
3202
- definedNames.push(definedNameToken);
3203
3200
  } else if (typeof nestedDefinedNameParam === "object") {
3204
3201
  const { sequenceString: nestedSequenceString, definedNames: nestedDefinedNames } = nestedDefinedNameParam;
3205
3202
  sequenceString += nestedSequenceString;
@@ -3264,7 +3261,7 @@ var LexerTreeBuilder = class extends _univerjs_core.Disposable {
3264
3261
  if (state === "#VALUE!" || sequenceArray.length === 0) return state;
3265
3262
  return this._handleDefinedName(sequenceArray, param);
3266
3263
  }
3267
- _simpleCheckDefinedName(formulaString, injectDefinedNameParam) {
3264
+ _simpleCheckDefinedName(formulaString, injectDefinedNameParam, lexerNode) {
3268
3265
  const { getDirtyDefinedNameMap, unitId } = injectDefinedNameParam;
3269
3266
  const definedNameMap = getDirtyDefinedNameMap();
3270
3267
  const executeUnitId = unitId;
@@ -3272,7 +3269,7 @@ var LexerTreeBuilder = class extends _univerjs_core.Disposable {
3272
3269
  const names = Object.keys(definedNameMap[executeUnitId]);
3273
3270
  for (let i = 0, len = names.length; i < len; i++) {
3274
3271
  const name = names[i];
3275
- if (formulaString.indexOf(name) > -1) return true;
3272
+ if (formulaString.indexOf(name) > -1 || (lexerNode === null || lexerNode === void 0 ? void 0 : lexerNode.getDefinedNames().includes(name))) return true;
3276
3273
  }
3277
3274
  }
3278
3275
  return false;
@@ -4331,18 +4328,43 @@ let FormulaDataModel = class FormulaDataModel extends _univerjs_core.Disposable
4331
4328
  super();
4332
4329
  this._univerInstanceService = _univerInstanceService;
4333
4330
  this._lexerTreeBuilder = _lexerTreeBuilder;
4331
+ _defineProperty(this, "_circularReferences", /* @__PURE__ */ new Map());
4334
4332
  _defineProperty(this, "_formulaIdMapData", Object.create(null));
4335
4333
  _defineProperty(this, "_arrayFormulaRange", Object.create(null));
4336
4334
  _defineProperty(this, "_arrayFormulaCellData", Object.create(null));
4337
4335
  _defineProperty(this, "_unitImageFormulaData", Object.create(null));
4336
+ this.disposeWithMe(this._univerInstanceService.getTypeOfUnitDisposed$(_univerjs_core.UniverInstanceType.UNIVER_SHEET).subscribe((workbook) => {
4337
+ for (const [key, cell] of this._circularReferences) if (cell.unitId === workbook.getUnitId()) this._circularReferences.delete(key);
4338
+ }));
4338
4339
  }
4339
4340
  dispose() {
4340
4341
  super.dispose();
4342
+ this._circularReferences.clear();
4341
4343
  this._formulaIdMapData = Object.create(null);
4342
4344
  this._arrayFormulaRange = Object.create(null);
4343
4345
  this._arrayFormulaCellData = Object.create(null);
4344
4346
  this._unitImageFormulaData = Object.create(null);
4345
4347
  }
4348
+ setCircularReferences(cells) {
4349
+ this._circularReferences.clear();
4350
+ for (const cell of cells) this._circularReferences.set(JSON.stringify([
4351
+ cell.unitId,
4352
+ cell.sheetId,
4353
+ cell.row,
4354
+ cell.column
4355
+ ]), { ...cell });
4356
+ }
4357
+ getCircularReferences(unitId) {
4358
+ return Array.from(this._circularReferences.values()).filter((cell) => cell.unitId === unitId).map((cell) => ({ ...cell }));
4359
+ }
4360
+ isCircularReference(unitId, sheetId, row, column) {
4361
+ return this._circularReferences.has(JSON.stringify([
4362
+ unitId,
4363
+ sheetId,
4364
+ row,
4365
+ column
4366
+ ]));
4367
+ }
4346
4368
  clearPreviousArrayFormulaCellData(clearArrayFormulaCellData) {
4347
4369
  Object.keys(clearArrayFormulaCellData).forEach((unitId) => {
4348
4370
  const clearSheetData = clearArrayFormulaCellData[unitId];
@@ -5181,6 +5203,7 @@ let FormulaCurrentConfigService = class FormulaCurrentConfigService extends _uni
5181
5203
  this._localeService = _localeService;
5182
5204
  this._formulaDataModel = _formulaDataModel;
5183
5205
  this._sheetRowFilteredService = _sheetRowFilteredService;
5206
+ _defineProperty(this, "_dirtyIterationUnits", []);
5184
5207
  _defineProperty(this, "_unitData", Object.create(null));
5185
5208
  _defineProperty(this, "_unitStylesData", Object.create(null));
5186
5209
  _defineProperty(this, "_arrayFormulaCellData", Object.create(null));
@@ -5361,6 +5384,7 @@ let FormulaCurrentConfigService = class FormulaCurrentConfigService extends _uni
5361
5384
  }
5362
5385
  if (config.rowData) this._applyUnitRowData(config.rowData);
5363
5386
  this._formulaData = config.formulaData;
5387
+ this._dirtyIterationUnits = config.dirtyIterationUnits ?? [];
5364
5388
  this._arrayFormulaCellData = convertUnitDataToRuntime(config.arrayFormulaCellData);
5365
5389
  this._arrayFormulaRange = config.arrayFormulaRange;
5366
5390
  this._forceCalculate = config.forceCalculate;
@@ -5388,6 +5412,7 @@ let FormulaCurrentConfigService = class FormulaCurrentConfigService extends _uni
5388
5412
  }
5389
5413
  getDirtyData() {
5390
5414
  return {
5415
+ dirtyIterationUnits: this._dirtyIterationUnits,
5391
5416
  forceCalculation: this._forceCalculate,
5392
5417
  dirtyRanges: this._dirtyRanges,
5393
5418
  dirtyNameMap: this._dirtyNameMap,
@@ -5400,6 +5425,7 @@ let FormulaCurrentConfigService = class FormulaCurrentConfigService extends _uni
5400
5425
  };
5401
5426
  }
5402
5427
  loadDirtyRangesAndExcludedCell(dirtyRanges, excludedCell) {
5428
+ this._dirtyIterationUnits = [];
5403
5429
  this._dirtyRanges = dirtyRanges;
5404
5430
  this._excludedCell = excludedCell;
5405
5431
  /**
@@ -10059,11 +10085,14 @@ let FormulaExecutedStateType = /* @__PURE__ */ function(FormulaExecutedStateType
10059
10085
  return FormulaExecutedStateType;
10060
10086
  }({});
10061
10087
  let FormulaRuntimeService = class FormulaRuntimeService extends _univerjs_core.Disposable {
10062
- constructor(_currentConfigService, _hyperlinkEngineFormulaService) {
10088
+ constructor(_currentConfigService, _hyperlinkEngineFormulaService, _univerInstanceService) {
10063
10089
  super();
10064
10090
  this._currentConfigService = _currentConfigService;
10065
10091
  this._hyperlinkEngineFormulaService = _hyperlinkEngineFormulaService;
10092
+ this._univerInstanceService = _univerInstanceService;
10066
10093
  _defineProperty(this, "_formulaExecuteStage", 0);
10094
+ _defineProperty(this, "_circularReferences", /* @__PURE__ */ new Map());
10095
+ _defineProperty(this, "_pendingCircularReferences", /* @__PURE__ */ new Map());
10067
10096
  _defineProperty(this, "_stopState", false);
10068
10097
  _defineProperty(this, "_externalReferenceUnavailable", false);
10069
10098
  _defineProperty(this, "_currentRow", -1);
@@ -10074,6 +10103,8 @@ let FormulaRuntimeService = class FormulaRuntimeService extends _univerjs_core.D
10074
10103
  _defineProperty(this, "_currentSubUnitId", "");
10075
10104
  _defineProperty(this, "_currentUnitId", "");
10076
10105
  _defineProperty(this, "_runtimeData", Object.create(null));
10106
+ _defineProperty(this, "_sourceFormulaData", Object.create(null));
10107
+ _defineProperty(this, "_currentSourceFormula", void 0);
10077
10108
  _defineProperty(this, "_runtimeOtherData", Object.create(null));
10078
10109
  _defineProperty(this, "_unitArrayFormulaRange", Object.create(null));
10079
10110
  _defineProperty(this, "_unitArrayFormulaEmbeddedMap", Object.create(null));
@@ -10091,6 +10122,9 @@ let FormulaRuntimeService = class FormulaRuntimeService extends _univerjs_core.D
10091
10122
  _defineProperty(this, "_formulaCycleIndex", 0);
10092
10123
  _defineProperty(this, "_isCycleDependency", false);
10093
10124
  _defineProperty(this, "_dependencyTreeModelData", []);
10125
+ this.disposeWithMe(this._univerInstanceService.getTypeOfUnitDisposed$(_univerjs_core.UniverInstanceType.UNIVER_SHEET).subscribe((workbook) => {
10126
+ for (const references of [this._circularReferences, this._pendingCircularReferences]) for (const [key, cell] of references) if (cell.unitId === workbook.getUnitId()) references.delete(key);
10127
+ }));
10094
10128
  }
10095
10129
  get currentRow() {
10096
10130
  return this._currentRow;
@@ -10115,6 +10149,8 @@ let FormulaRuntimeService = class FormulaRuntimeService extends _univerjs_core.D
10115
10149
  dispose() {
10116
10150
  super.dispose();
10117
10151
  this.reset();
10152
+ this._circularReferences.clear();
10153
+ this._pendingCircularReferences.clear();
10118
10154
  this._runtimeFeatureCellData = Object.create(null);
10119
10155
  this._runtimeFeatureRange = Object.create(null);
10120
10156
  this.clearReferenceAndNumberformatCache();
@@ -10186,6 +10222,8 @@ let FormulaRuntimeService = class FormulaRuntimeService extends _univerjs_core.D
10186
10222
  reset() {
10187
10223
  this._formulaExecuteStage = 0;
10188
10224
  this._runtimeData = Object.create(null);
10225
+ this._sourceFormulaData = Object.create(null);
10226
+ this._currentSourceFormula = void 0;
10189
10227
  this._runtimeOtherData = Object.create(null);
10190
10228
  this._unitArrayFormulaRange = Object.create(null);
10191
10229
  this._unitArrayFormulaEmbeddedMap = Object.create(null);
@@ -10206,7 +10244,60 @@ let FormulaRuntimeService = class FormulaRuntimeService extends _univerjs_core.D
10206
10244
  clearStringToNumberPatternCache();
10207
10245
  clearReferenceToRangeCache();
10208
10246
  }
10247
+ beginCircularReferences() {
10248
+ this._pendingCircularReferences = new Map(this._circularReferences);
10249
+ const formulaData = this._currentConfigService.getFormulaData();
10250
+ for (const [key, cell] of this._pendingCircularReferences) {
10251
+ var _formulaData$cell$uni;
10252
+ if (!((_formulaData$cell$uni = formulaData[cell.unitId]) === null || _formulaData$cell$uni === void 0 || (_formulaData$cell$uni = _formulaData$cell$uni[cell.sheetId]) === null || _formulaData$cell$uni === void 0 || (_formulaData$cell$uni = _formulaData$cell$uni[cell.row]) === null || _formulaData$cell$uni === void 0 ? void 0 : _formulaData$cell$uni[cell.column])) this._pendingCircularReferences.delete(key);
10253
+ }
10254
+ }
10255
+ clearCircularReferenceCells(cells) {
10256
+ if (this._pendingCircularReferences.size === 0) return;
10257
+ for (const cell of cells) {
10258
+ this._pendingCircularReferences.delete(JSON.stringify([
10259
+ cell.unitId,
10260
+ cell.subUnitId,
10261
+ cell.row,
10262
+ cell.column
10263
+ ]));
10264
+ if (this._pendingCircularReferences.size === 0) return;
10265
+ }
10266
+ }
10267
+ recordCircularReferences(cells) {
10268
+ for (const cell of cells) {
10269
+ if (cell.row < 0 || cell.column < 0) continue;
10270
+ this._pendingCircularReferences.set(JSON.stringify([
10271
+ cell.unitId,
10272
+ cell.sheetId,
10273
+ cell.row,
10274
+ cell.column
10275
+ ]), { ...cell });
10276
+ }
10277
+ }
10278
+ completeCircularReferences() {
10279
+ if (!this.isStopExecution()) this._circularReferences = new Map(this._pendingCircularReferences);
10280
+ }
10281
+ preserveCurrentCellData() {
10282
+ var _this$_currentConfigS;
10283
+ const unitId = this.currentUnitId;
10284
+ const sheetId = this.currentSubUnitId;
10285
+ const cell = (_this$_currentConfigS = this._currentConfigService.getUnitData()[unitId]) === null || _this$_currentConfigS === void 0 || (_this$_currentConfigS = _this$_currentConfigS[sheetId]) === null || _this$_currentConfigS === void 0 ? void 0 : _this$_currentConfigS.cellData.getValue(this.currentRow, this.currentColumn);
10286
+ if ((cell === null || cell === void 0 ? void 0 : cell.v) != null) return;
10287
+ const sheets = this._runtimeData[unitId] ??= {};
10288
+ (sheets[sheetId] ??= new _univerjs_core.ObjectMatrix()).setValue(this.currentRow, this.currentColumn, {
10289
+ v: (cell === null || cell === void 0 ? void 0 : cell.v) ?? 0,
10290
+ t: (cell === null || cell === void 0 ? void 0 : cell.v) == null ? _univerjs_core.CellValueType.NUMBER : cell.t
10291
+ });
10292
+ if (this._currentSourceFormula) {
10293
+ const formulas = this._sourceFormulaData[unitId] ??= {};
10294
+ const sheet = formulas[sheetId] ??= {};
10295
+ const row = sheet[this.currentRow] ??= {};
10296
+ row[this.currentColumn] = { ...this._currentSourceFormula };
10297
+ }
10298
+ }
10209
10299
  setCurrent(row, column, rowCount, columnCount, sheetId, unitId) {
10300
+ var _this$_currentConfigS2, _this$_currentConfigS3;
10210
10301
  this._externalReferenceUnavailable = false;
10211
10302
  this._currentRow = row;
10212
10303
  this._currentColumn = column;
@@ -10214,6 +10305,18 @@ let FormulaRuntimeService = class FormulaRuntimeService extends _univerjs_core.D
10214
10305
  this._currentColumnCount = columnCount;
10215
10306
  this._currentSubUnitId = sheetId;
10216
10307
  this._currentUnitId = unitId;
10308
+ const cell = (_this$_currentConfigS2 = this._currentConfigService.getUnitData()[unitId]) === null || _this$_currentConfigS2 === void 0 || (_this$_currentConfigS2 = _this$_currentConfigS2[sheetId]) === null || _this$_currentConfigS2 === void 0 ? void 0 : _this$_currentConfigS2.cellData.getValue(row, column);
10309
+ const formula = (_this$_currentConfigS3 = this._currentConfigService.getFormulaData()[unitId]) === null || _this$_currentConfigS3 === void 0 || (_this$_currentConfigS3 = _this$_currentConfigS3[sheetId]) === null || _this$_currentConfigS3 === void 0 || (_this$_currentConfigS3 = _this$_currentConfigS3[row]) === null || _this$_currentConfigS3 === void 0 ? void 0 : _this$_currentConfigS3[column];
10310
+ if (formula) {
10311
+ const isSharedFollower = (formula.x ?? 0) !== 0 || (formula.y ?? 0) !== 0;
10312
+ this._currentSourceFormula = {
10313
+ f: isSharedFollower ? "" : formula.f,
10314
+ si: formula.si
10315
+ };
10316
+ } else this._currentSourceFormula = (cell === null || cell === void 0 ? void 0 : cell.f) || (cell === null || cell === void 0 ? void 0 : cell.si) ? {
10317
+ f: cell.f ?? "",
10318
+ si: cell.si ?? void 0
10319
+ } : void 0;
10217
10320
  }
10218
10321
  setFunctionRefInfoOverride(rowCount, columnCount) {
10219
10322
  this._functionRefInfoOverrideStack.push({
@@ -10264,9 +10367,9 @@ let FormulaRuntimeService = class FormulaRuntimeService extends _univerjs_core.D
10264
10367
  }
10265
10368
  setRuntimeData(functionVariant) {
10266
10369
  if (this._externalReferenceUnavailable) {
10267
- var _this$_currentConfigS, _this$_currentConfigS2;
10268
- const cell = (_this$_currentConfigS = this._currentConfigService.getUnitData()[this._currentUnitId]) === null || _this$_currentConfigS === void 0 || (_this$_currentConfigS = _this$_currentConfigS[this._currentSubUnitId]) === null || _this$_currentConfigS === void 0 ? void 0 : _this$_currentConfigS.cellData.getValue(this._currentRow, this._currentColumn);
10269
- const formula = (_this$_currentConfigS2 = this._currentConfigService.getFormulaData()[this._currentUnitId]) === null || _this$_currentConfigS2 === void 0 || (_this$_currentConfigS2 = _this$_currentConfigS2[this._currentSubUnitId]) === null || _this$_currentConfigS2 === void 0 || (_this$_currentConfigS2 = _this$_currentConfigS2[this._currentRow]) === null || _this$_currentConfigS2 === void 0 || (_this$_currentConfigS2 = _this$_currentConfigS2[this._currentColumn]) === null || _this$_currentConfigS2 === void 0 ? void 0 : _this$_currentConfigS2.f;
10370
+ var _this$_currentConfigS4, _this$_currentConfigS5;
10371
+ const cell = (_this$_currentConfigS4 = this._currentConfigService.getUnitData()[this._currentUnitId]) === null || _this$_currentConfigS4 === void 0 || (_this$_currentConfigS4 = _this$_currentConfigS4[this._currentSubUnitId]) === null || _this$_currentConfigS4 === void 0 ? void 0 : _this$_currentConfigS4.cellData.getValue(this._currentRow, this._currentColumn);
10372
+ const formula = (_this$_currentConfigS5 = this._currentConfigService.getFormulaData()[this._currentUnitId]) === null || _this$_currentConfigS5 === void 0 || (_this$_currentConfigS5 = _this$_currentConfigS5[this._currentSubUnitId]) === null || _this$_currentConfigS5 === void 0 || (_this$_currentConfigS5 = _this$_currentConfigS5[this._currentRow]) === null || _this$_currentConfigS5 === void 0 || (_this$_currentConfigS5 = _this$_currentConfigS5[this._currentColumn]) === null || _this$_currentConfigS5 === void 0 ? void 0 : _this$_currentConfigS5.f;
10270
10373
  if ((cell === null || cell === void 0 ? void 0 : cell.f) && cell.v != null && (formula == null || formula === cell.f)) return;
10271
10374
  }
10272
10375
  const row = this._currentRow;
@@ -10325,7 +10428,7 @@ let FormulaRuntimeService = class FormulaRuntimeService extends _univerjs_core.D
10325
10428
  const hasDataInArrayFormulaRange = this._checkIfArrayFormulaRangeHasData(unitId, sheetId, row, column, arrayRange);
10326
10429
  const isArrayFormulaExceeded = this._checkIfArrayFormulaExceeded(rowCount, columnCount, arrayRange);
10327
10430
  if (hasDataInArrayFormulaRange || isArrayFormulaExceeded) {
10328
- var _this$_currentConfigS3;
10431
+ var _this$_currentConfigS6;
10329
10432
  const errorObject = this._getValueObjectOfRuntimeData(ErrorValueObject.create("#SPILL!"));
10330
10433
  sheetData.setValue(row, column, errorObject);
10331
10434
  clearArrayUnitData.setValue(row, column, errorObject);
@@ -10336,7 +10439,7 @@ let FormulaRuntimeService = class FormulaRuntimeService extends _univerjs_core.D
10336
10439
  */
10337
10440
  const unitData = this._currentConfigService.getUnitData();
10338
10441
  const arrayData = this._currentConfigService.getArrayFormulaCellData();
10339
- const previousArrayFormulaRange = (_this$_currentConfigS3 = this._currentConfigService.getArrayFormulaRange()[unitId]) === null || _this$_currentConfigS3 === void 0 || (_this$_currentConfigS3 = _this$_currentConfigS3[sheetId]) === null || _this$_currentConfigS3 === void 0 || (_this$_currentConfigS3 = _this$_currentConfigS3[row]) === null || _this$_currentConfigS3 === void 0 ? void 0 : _this$_currentConfigS3[column];
10442
+ const previousArrayFormulaRange = (_this$_currentConfigS6 = this._currentConfigService.getArrayFormulaRange()[unitId]) === null || _this$_currentConfigS6 === void 0 || (_this$_currentConfigS6 = _this$_currentConfigS6[sheetId]) === null || _this$_currentConfigS6 === void 0 || (_this$_currentConfigS6 = _this$_currentConfigS6[row]) === null || _this$_currentConfigS6 === void 0 ? void 0 : _this$_currentConfigS6[column];
10340
10443
  objectValueRefOrArray.iterator((_, rowIndex, columnIndex) => {
10341
10444
  var _unitData$unitId, _arrayData$unitId;
10342
10445
  const currentRow = rowIndex - startRow + row;
@@ -10376,6 +10479,12 @@ let FormulaRuntimeService = class FormulaRuntimeService extends _univerjs_core.D
10376
10479
  } else {
10377
10480
  const valueObject = this._getValueObjectOfRuntimeData(functionVariant);
10378
10481
  sheetData.setValue(row, column, valueObject);
10482
+ if (this._currentSourceFormula != null) {
10483
+ const unitFormulas = this._sourceFormulaData[unitId] ??= {};
10484
+ const sheetFormulas = unitFormulas[sheetId] ??= {};
10485
+ const rowFormulas = sheetFormulas[row] ??= {};
10486
+ rowFormulas[column] = { ...this._currentSourceFormula };
10487
+ }
10379
10488
  if (functionVariant.isString() && functionVariant.isImage()) {
10380
10489
  const imageInfo = functionVariant.getImageInfo();
10381
10490
  if (imageInfo) this._runtimeImageFormulaData.push({
@@ -10447,6 +10556,8 @@ let FormulaRuntimeService = class FormulaRuntimeService extends _univerjs_core.D
10447
10556
  getAllRuntimeData() {
10448
10557
  return {
10449
10558
  unitData: this.getUnitData(),
10559
+ circularReferences: Array.from(this._circularReferences.values(), (cell) => ({ ...cell })),
10560
+ sourceFormulaData: this._sourceFormulaData,
10450
10561
  arrayFormulaRange: this.getUnitArrayFormula(),
10451
10562
  arrayFormulaEmbedded: this.getUnitArrayFormulaEmbeddedMap(),
10452
10563
  unitOtherData: this.getRuntimeOtherData(),
@@ -10466,6 +10577,7 @@ let FormulaRuntimeService = class FormulaRuntimeService extends _univerjs_core.D
10466
10577
  totalArrayFormulasToCalculate: this.getTotalArrayFormulasToCalculate(),
10467
10578
  completedArrayFormulasCount: this.getCompletedArrayFormulasCount(),
10468
10579
  stage: this.getFormulaExecuteStage(),
10580
+ circularReferences: Array.from(this._circularReferences.values(), (cell) => ({ ...cell })),
10469
10581
  formulaCycleIndex: this.getFormulaCycleIndex()
10470
10582
  };
10471
10583
  }
@@ -10473,11 +10585,11 @@ let FormulaRuntimeService = class FormulaRuntimeService extends _univerjs_core.D
10473
10585
  FORMULA_REF_TO_ARRAY_CACHE.clear();
10474
10586
  }
10475
10587
  _checkIfArrayFormulaRangeHasData(formulaUnitId, formulaSheetId, formulaRow, formulaColumn, arrayRange) {
10476
- var _this$_currentConfigS4;
10588
+ var _this$_currentConfigS7;
10477
10589
  const { startRow, startColumn, endRow, endColumn } = arrayRange;
10478
10590
  const unitData = this._currentConfigService.getUnitData();
10479
10591
  const arrayData = this._currentConfigService.getArrayFormulaCellData();
10480
- const previousArrayFormulaRange = (_this$_currentConfigS4 = this._currentConfigService.getArrayFormulaRange()[formulaUnitId]) === null || _this$_currentConfigS4 === void 0 || (_this$_currentConfigS4 = _this$_currentConfigS4[formulaSheetId]) === null || _this$_currentConfigS4 === void 0 || (_this$_currentConfigS4 = _this$_currentConfigS4[formulaRow]) === null || _this$_currentConfigS4 === void 0 ? void 0 : _this$_currentConfigS4[formulaColumn];
10592
+ const previousArrayFormulaRange = (_this$_currentConfigS7 = this._currentConfigService.getArrayFormulaRange()[formulaUnitId]) === null || _this$_currentConfigS7 === void 0 || (_this$_currentConfigS7 = _this$_currentConfigS7[formulaSheetId]) === null || _this$_currentConfigS7 === void 0 || (_this$_currentConfigS7 = _this$_currentConfigS7[formulaRow]) === null || _this$_currentConfigS7 === void 0 ? void 0 : _this$_currentConfigS7[formulaColumn];
10481
10593
  for (let r = startRow; r <= endRow; r++) for (let c = startColumn; c <= endColumn; c++) {
10482
10594
  var _this$_runtimeData, _arrayData$formulaUni, _unitData$formulaUnit;
10483
10595
  if (r === formulaRow && formulaColumn === c) continue;
@@ -10513,8 +10625,8 @@ let FormulaRuntimeService = class FormulaRuntimeService extends _univerjs_core.D
10513
10625
  * @returns
10514
10626
  */
10515
10627
  _isInOtherArrayFormulaRange(formulaUnitId, formulaSheetId, formulaRow, formulaColumn, r, c) {
10516
- var _this$_currentConfigS5;
10517
- const arrayFormulaRange = (_this$_currentConfigS5 = this._currentConfigService.getArrayFormulaRange()[formulaUnitId]) === null || _this$_currentConfigS5 === void 0 ? void 0 : _this$_currentConfigS5[formulaSheetId];
10628
+ var _this$_currentConfigS8;
10629
+ const arrayFormulaRange = (_this$_currentConfigS8 = this._currentConfigService.getArrayFormulaRange()[formulaUnitId]) === null || _this$_currentConfigS8 === void 0 ? void 0 : _this$_currentConfigS8[formulaSheetId];
10518
10630
  if (arrayFormulaRange == null) return false;
10519
10631
  let isCellOverlapping = false;
10520
10632
  new _univerjs_core.ObjectMatrix(arrayFormulaRange).forValue((rangeRow, rangeCol, range) => {
@@ -10527,8 +10639,8 @@ let FormulaRuntimeService = class FormulaRuntimeService extends _univerjs_core.D
10527
10639
  return isCellOverlapping;
10528
10640
  }
10529
10641
  _isCurrentSingleCellArrayFormulaRange(unitId, sheetId, row, column) {
10530
- var _this$_currentConfigS6;
10531
- const range = (_this$_currentConfigS6 = this._currentConfigService.getArrayFormulaRange()[unitId]) === null || _this$_currentConfigS6 === void 0 || (_this$_currentConfigS6 = _this$_currentConfigS6[sheetId]) === null || _this$_currentConfigS6 === void 0 || (_this$_currentConfigS6 = _this$_currentConfigS6[row]) === null || _this$_currentConfigS6 === void 0 ? void 0 : _this$_currentConfigS6[column];
10642
+ var _this$_currentConfigS9;
10643
+ const range = (_this$_currentConfigS9 = this._currentConfigService.getArrayFormulaRange()[unitId]) === null || _this$_currentConfigS9 === void 0 || (_this$_currentConfigS9 = _this$_currentConfigS9[sheetId]) === null || _this$_currentConfigS9 === void 0 || (_this$_currentConfigS9 = _this$_currentConfigS9[row]) === null || _this$_currentConfigS9 === void 0 ? void 0 : _this$_currentConfigS9[column];
10532
10644
  return range != null && range.startRow === range.endRow && range.startColumn === range.endColumn;
10533
10645
  }
10534
10646
  _isInArrayFormulaRange(range, r, c) {
@@ -10552,7 +10664,11 @@ let FormulaRuntimeService = class FormulaRuntimeService extends _univerjs_core.D
10552
10664
  return isInDirtyRange(dirtyRanges, unitId, sheetId, row, column);
10553
10665
  }
10554
10666
  };
10555
- FormulaRuntimeService = __decorate([__decorateParam(0, IFormulaCurrentConfigService), __decorateParam(1, IHyperlinkEngineFormulaService)], FormulaRuntimeService);
10667
+ FormulaRuntimeService = __decorate([
10668
+ __decorateParam(0, IFormulaCurrentConfigService),
10669
+ __decorateParam(1, IHyperlinkEngineFormulaService),
10670
+ __decorateParam(2, _univerjs_core.IUniverInstanceService)
10671
+ ], FormulaRuntimeService);
10556
10672
  const IFormulaRuntimeService = (0, _univerjs_core.createIdentifier)("univer.formula.runtime.service");
10557
10673
 
10558
10674
  //#endregion
@@ -13556,6 +13672,90 @@ var OtherFormulaManagerService = class extends _univerjs_core.Disposable {
13556
13672
  };
13557
13673
  const IOtherFormulaManagerService = (0, _univerjs_core.createIdentifier)("univer.formula.other-formula-manager.service");
13558
13674
 
13675
+ //#endregion
13676
+ //#region src/engine/dependency/dependency-groups.ts
13677
+ /**
13678
+ * Copyright 2023-present DreamNum Co., Ltd.
13679
+ *
13680
+ * Licensed under the Apache License, Version 2.0 (the "License");
13681
+ * you may not use this file except in compliance with the License.
13682
+ * You may obtain a copy of the License at
13683
+ *
13684
+ * http://www.apache.org/licenses/LICENSE-2.0
13685
+ *
13686
+ * Unless required by applicable law or agreed to in writing, software
13687
+ * distributed under the License is distributed on an "AS IS" BASIS,
13688
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13689
+ * See the License for the specific language governing permissions and
13690
+ * limitations under the License.
13691
+ */
13692
+ /**
13693
+ * Returns strongly connected components in dependency order: precedents before their dependents.
13694
+ * Mutually dependent nodes stay together so only their group needs iterative calculation.
13695
+ * Uses iterative Kosaraju traversal to avoid overflowing the call stack on large dependency graphs.
13696
+ */
13697
+ function getDependencyGroups(nodes, getId, getDependents) {
13698
+ const byId = new Map(nodes.map((node) => [getId(node), node]));
13699
+ const edges = /* @__PURE__ */ new Map();
13700
+ const reverse = /* @__PURE__ */ new Map();
13701
+ for (const node of nodes) {
13702
+ const id = getId(node);
13703
+ const dependents = Array.from(getDependents(node)).filter((dependent) => byId.has(dependent));
13704
+ edges.set(id, dependents);
13705
+ for (const dependent of dependents) {
13706
+ const incoming = reverse.get(dependent) ?? [];
13707
+ incoming.push(id);
13708
+ reverse.set(dependent, incoming);
13709
+ }
13710
+ }
13711
+ const visited = /* @__PURE__ */ new Set();
13712
+ const order = [];
13713
+ for (const id of byId.keys()) {
13714
+ if (visited.has(id)) continue;
13715
+ visited.add(id);
13716
+ const stack = [{
13717
+ id,
13718
+ next: 0
13719
+ }];
13720
+ while (stack.length) {
13721
+ const frame = stack[stack.length - 1];
13722
+ const children = edges.get(frame.id);
13723
+ if (frame.next === children.length) {
13724
+ order.push(frame.id);
13725
+ stack.pop();
13726
+ continue;
13727
+ }
13728
+ const child = children[frame.next++];
13729
+ if (!visited.has(child)) {
13730
+ visited.add(child);
13731
+ stack.push({
13732
+ id: child,
13733
+ next: 0
13734
+ });
13735
+ }
13736
+ }
13737
+ }
13738
+ visited.clear();
13739
+ const groups = [];
13740
+ for (let i = order.length - 1; i >= 0; i--) {
13741
+ const id = order[i];
13742
+ if (visited.has(id)) continue;
13743
+ const group = [];
13744
+ const stack = [id];
13745
+ visited.add(id);
13746
+ while (stack.length) {
13747
+ const current = stack.pop();
13748
+ group.push(byId.get(current));
13749
+ for (const parent of reverse.get(current) ?? []) if (!visited.has(parent)) {
13750
+ visited.add(parent);
13751
+ stack.push(parent);
13752
+ }
13753
+ }
13754
+ groups.push(group);
13755
+ }
13756
+ return groups;
13757
+ }
13758
+
13559
13759
  //#endregion
13560
13760
  //#region src/engine/dependency/dependency-tree.ts
13561
13761
  let FormulaDependencyTreeType = /* @__PURE__ */ function(FormulaDependencyTreeType) {
@@ -13568,6 +13768,7 @@ var FormulaDependencyTreeCalculator = class {
13568
13768
  constructor() {
13569
13769
  _defineProperty(this, "_state", 0);
13570
13770
  _defineProperty(this, "type", 0);
13771
+ _defineProperty(this, "cycleGroup", void 0);
13571
13772
  _defineProperty(this, "treeId", void 0);
13572
13773
  _defineProperty(this, "children", /* @__PURE__ */ new Set());
13573
13774
  _defineProperty(this, "parents", /* @__PURE__ */ new Set());
@@ -13989,7 +14190,28 @@ let FormulaDependencyGenerator = class FormulaDependencyGenerator extends _unive
13989
14190
  await this._generateTreeList(formulaData, otherFormulaData, unitData);
13990
14191
  this._dependencyManagerService.openKdTree();
13991
14192
  const updateTreeList = this._getUpdateTreeListAndMakeDependency();
13992
- const finalTreeList = this._calculateRunList(updateTreeList);
14193
+ const runList = this._calculateRunList(updateTreeList);
14194
+ const selfReferences = /* @__PURE__ */ new Set();
14195
+ const groups = getDependencyGroups(runList, (tree) => tree.treeId, (tree) => {
14196
+ const dependents = this._dependencyManagerService.searchDependency(tree.toRTreeItem());
14197
+ const addressDependents = this._dependencyRTreeCacheForAddressFunction.bulkSearch(tree.toRTreeItem());
14198
+ for (const dependent of addressDependents) dependents.add(dependent);
14199
+ if (dependents.has(tree.treeId)) selfReferences.add(tree.treeId);
14200
+ return dependents;
14201
+ });
14202
+ this._runtimeService.clearCircularReferenceCells(runList);
14203
+ for (const group of groups) {
14204
+ const cyclic = group.length > 1 || selfReferences.has(group[0].treeId);
14205
+ const groupId = cyclic ? group.map((tree) => tree.treeId).sort((a, b) => a - b).join(",") : void 0;
14206
+ for (const tree of group) {
14207
+ tree.cycleGroup = groupId;
14208
+ if (cyclic) {
14209
+ var _this$_runtimeService;
14210
+ (_this$_runtimeService = this._runtimeService.getUnitData()[tree.unitId]) === null || _this$_runtimeService === void 0 || (_this$_runtimeService = _this$_runtimeService[tree.subUnitId]) === null || _this$_runtimeService === void 0 || _this$_runtimeService.realDeleteValue(tree.row, tree.column);
14211
+ }
14212
+ }
14213
+ }
14214
+ const finalTreeList = groups.flat().reverse();
13993
14215
  if (this._checkIsCycleDependency(finalTreeList)) this._runtimeService.enableCycleDependency();
13994
14216
  if (isCalculateTreeModel) this._runtimeService.setDependencyTreeModelData(this._getAllDependencyJson(Array.from(this._dependencyTreeCache.values())));
13995
14217
  this._dependencyTreeCache.clear();
@@ -13998,41 +14220,8 @@ let FormulaDependencyGenerator = class FormulaDependencyGenerator extends _unive
13998
14220
  this._runtimeService.clearArrayObjectCache();
13999
14221
  return Promise.resolve(finalTreeList);
14000
14222
  }
14001
- _isCyclicUtilMap(treeId, colorMap) {
14002
- const WHITE = 0;
14003
- const GRAY = 1;
14004
- const BLACK = 2;
14005
- const stack = [treeId];
14006
- while (stack.length > 0) {
14007
- const currentTreeId = stack[stack.length - 1];
14008
- if ((colorMap.get(currentTreeId) || WHITE) === WHITE) {
14009
- colorMap.set(currentTreeId, GRAY);
14010
- const node = this._dependencyTreeCache.get(currentTreeId);
14011
- if (node == null) {
14012
- colorMap.set(currentTreeId, BLACK);
14013
- stack.pop();
14014
- continue;
14015
- }
14016
- const parents = this._dependencyManagerService.searchDependency(node.toRTreeItem());
14017
- for (const parentTreeId of parents) {
14018
- const parentColor = colorMap.get(parentTreeId) || WHITE;
14019
- if (parentColor === GRAY) return true;
14020
- else if (parentColor === WHITE) stack.push(parentTreeId);
14021
- }
14022
- } else {
14023
- colorMap.set(currentTreeId, BLACK);
14024
- stack.pop();
14025
- }
14026
- }
14027
- return false;
14028
- }
14029
14223
  _checkIsCycleDependency(treeList) {
14030
- const colorMap = /* @__PURE__ */ new Map();
14031
- for (const tree of treeList) if (!colorMap.has(tree.treeId)) {
14032
- if (this._isCyclicUtilMap(tree.treeId, colorMap)) return true;
14033
- }
14034
- colorMap.clear();
14035
- return false;
14224
+ return treeList.some((tree) => tree.cycleGroup != null);
14036
14225
  }
14037
14226
  _getFeatureFormulaTree(featureId, treeId, params) {
14038
14227
  const { unitId, subUnitId, dependencyRanges, getDirtyData } = params;
@@ -14416,11 +14605,17 @@ let FormulaDependencyGenerator = class FormulaDependencyGenerator extends _unive
14416
14605
  if (node.nodeType === 12 && node.getToken() === "#") return true;
14417
14606
  return false;
14418
14607
  }
14608
+ _isStaticReference(node) {
14609
+ return node.nodeType === 1 || node.nodeType === 10 && node.getChildren().every((child) => this._isStaticReference(child));
14610
+ }
14419
14611
  _nodeTraversalRef(node, result) {
14420
14612
  const children = node.getChildren();
14421
14613
  const childrenCount = children.length;
14614
+ const token = node.getToken();
14615
+ const readsReferenceMetadata = node.nodeType === 4 && (token === "ROW" || token === "ROWS" || token === "COLUMN" || token === "COLUMNS");
14422
14616
  for (let i = 0; i < childrenCount; i++) {
14423
14617
  const item = children[i];
14618
+ if (readsReferenceMetadata && this._isStaticReference(item)) continue;
14424
14619
  if (this._isPreCalculateNode(item)) {
14425
14620
  result.push(item);
14426
14621
  if (item.nodeType === 10) {
@@ -14664,9 +14859,10 @@ let FormulaDependencyGenerator = class FormulaDependencyGenerator extends _unive
14664
14859
  * @param tree
14665
14860
  */
14666
14861
  _includeTree(tree, node) {
14667
- var _this$_currentConfigS, _this$_currentConfigS2;
14862
+ var _this$_currentConfigS, _this$_currentConfigS2, _this$_currentConfigS3;
14668
14863
  const unitId = tree.unitId;
14669
14864
  const subUnitId = tree.subUnitId;
14865
+ if ((_this$_currentConfigS = this._currentConfigService.getDirtyData().dirtyIterationUnits) === null || _this$_currentConfigS === void 0 ? void 0 : _this$_currentConfigS.includes(unitId)) return true;
14670
14866
  /**
14671
14867
  * RAND, RANDBETWEEN, NOW, TODAY are volatile functions that are marked dirty and recalculated every time a calculation occurs.
14672
14868
  */
@@ -14674,13 +14870,13 @@ let FormulaDependencyGenerator = class FormulaDependencyGenerator extends _unive
14674
14870
  if (this._includeTreeFeature(tree) === true) return true;
14675
14871
  if (this._includeOtherFormula(tree) === true) return true;
14676
14872
  if (includeDefinedName(tree, node, this._currentConfigService) === true) return true;
14677
- const excludedCell = (_this$_currentConfigS = this._currentConfigService.getExcludedRange()) === null || _this$_currentConfigS === void 0 || (_this$_currentConfigS = _this$_currentConfigS[unitId]) === null || _this$_currentConfigS === void 0 ? void 0 : _this$_currentConfigS[subUnitId];
14873
+ const excludedCell = (_this$_currentConfigS2 = this._currentConfigService.getExcludedRange()) === null || _this$_currentConfigS2 === void 0 || (_this$_currentConfigS2 = _this$_currentConfigS2[unitId]) === null || _this$_currentConfigS2 === void 0 ? void 0 : _this$_currentConfigS2[subUnitId];
14678
14874
  if ((excludedCell === null || excludedCell === void 0 ? void 0 : excludedCell.getValue(tree.row, tree.column)) != null) return false;
14679
14875
  /**
14680
14876
  * When a worksheet is inserted or deleted,
14681
14877
  * the formulas within it need to be calculated.
14682
14878
  */
14683
- if (((_this$_currentConfigS2 = this._currentConfigService.getDirtyNameMap()[unitId]) === null || _this$_currentConfigS2 === void 0 ? void 0 : _this$_currentConfigS2[subUnitId]) != null) return true;
14879
+ if (((_this$_currentConfigS3 = this._currentConfigService.getDirtyNameMap()[unitId]) === null || _this$_currentConfigS3 === void 0 ? void 0 : _this$_currentConfigS3[subUnitId]) != null) return true;
14684
14880
  if (!this._updateRangeFlattenCache.has(unitId)) return false;
14685
14881
  const sheetRangeMap = this._updateRangeFlattenCache.get(unitId);
14686
14882
  if (!sheetRangeMap.has(subUnitId)) return false;
@@ -14843,6 +15039,105 @@ FormulaDependencyGenerator = __decorate([
14843
15039
  const DEFAULT_INTERVAL_COUNT = 500;
14844
15040
  const ICalculateFormulaService = (0, _univerjs_core.createIdentifier)("engine-formula.calculate-formula.service");
14845
15041
  let CalculateFormulaService = class CalculateFormulaService extends _univerjs_core.Disposable {
15042
+ _loadCalculationSettings(settings) {
15043
+ this._workbookCalculationSettings = settings ?? {};
15044
+ this._normalizedCalculationSettings.clear();
15045
+ }
15046
+ _getCalculationSettings(unitId) {
15047
+ let settings = this._normalizedCalculationSettings.get(unitId);
15048
+ if (settings == null) {
15049
+ settings = (0, _univerjs_core.normalizeWorkbookCalculationSettings)(this._workbookCalculationSettings[unitId]);
15050
+ this._normalizedCalculationSettings.set(unitId, settings);
15051
+ }
15052
+ return settings;
15053
+ }
15054
+ _getIterationCell(tree) {
15055
+ var _this$_runtimeService, _this$_currentConfigS;
15056
+ const cell = ((_this$_runtimeService = this._runtimeService.getUnitData()[tree.unitId]) === null || _this$_runtimeService === void 0 || (_this$_runtimeService = _this$_runtimeService[tree.subUnitId]) === null || _this$_runtimeService === void 0 ? void 0 : _this$_runtimeService.getValue(tree.row, tree.column)) ?? ((_this$_currentConfigS = this._currentConfigService.getUnitData()[tree.unitId]) === null || _this$_currentConfigS === void 0 || (_this$_currentConfigS = _this$_currentConfigS[tree.subUnitId]) === null || _this$_currentConfigS === void 0 ? void 0 : _this$_currentConfigS.cellData.getValue(tree.row, tree.column)) ?? { v: 0 };
15057
+ return cell.v == null ? {
15058
+ v: 0,
15059
+ t: _univerjs_core.CellValueType.NUMBER
15060
+ } : cell;
15061
+ }
15062
+ async *_iterateCalculationGroup(group, groupId) {
15063
+ const settings = group.map((item) => this._getCalculationSettings(item.unitId));
15064
+ if (group.every((item, i) => {
15065
+ var _this$_currentConfigS2;
15066
+ const cell = (_this$_currentConfigS2 = this._currentConfigService.getUnitData()[item.unitId]) === null || _this$_currentConfigS2 === void 0 || (_this$_currentConfigS2 = _this$_currentConfigS2[item.subUnitId]) === null || _this$_currentConfigS2 === void 0 ? void 0 : _this$_currentConfigS2.cellData.getValue(item.row, item.column);
15067
+ const formula = (item.formula ?? (cell === null || cell === void 0 ? void 0 : cell.f) ?? "").toUpperCase();
15068
+ const requiresRecalculation = formula.includes(`${"INDEX"}(`) && !(formula.includes(`${"LOOKUP"}(`) && !formula.includes(`${"XLOOKUP"}(`));
15069
+ return settings[i].iterativeCalculation && this._preserveCircularUnits.has(item.unitId) && (cell === null || cell === void 0 ? void 0 : cell.v) != null && !requiresRecalculation;
15070
+ })) {
15071
+ for (const tree of group) yield {
15072
+ tree,
15073
+ preserve: true,
15074
+ iteration: 0
15075
+ };
15076
+ this._runtimeService.recordCircularReferences(group.map((item) => ({
15077
+ unitId: item.unitId,
15078
+ sheetId: item.subUnitId,
15079
+ row: item.row,
15080
+ column: item.column,
15081
+ groupId,
15082
+ iterations: 0
15083
+ })));
15084
+ return;
15085
+ }
15086
+ const limit = settings.reduce((limit, setting) => Math.max(limit, setting.iterativeCalculation ? setting.maxIterations : 0), 1);
15087
+ let converged = false;
15088
+ let iterations = 0;
15089
+ const beforeValues = [];
15090
+ const beforeTypes = [];
15091
+ for (let iteration = 0; iteration < limit; iteration++) {
15092
+ for (let i = 0; i < group.length; i++) if (settings[i].iterativeCalculation) {
15093
+ const before = this._getIterationCell(group[i]);
15094
+ beforeValues[i] = before.v;
15095
+ beforeTypes[i] = before.t;
15096
+ }
15097
+ for (let i = 0; i < group.length; i++) if (iteration < (settings[i].iterativeCalculation ? settings[i].maxIterations : 1)) {
15098
+ FORMULA_REF_TO_ARRAY_CACHE.clear();
15099
+ yield {
15100
+ tree: group[i],
15101
+ preserve: !settings[i].iterativeCalculation,
15102
+ iteration
15103
+ };
15104
+ }
15105
+ iterations = iteration + 1;
15106
+ converged = group.every((item, i) => {
15107
+ if (!settings[i].iterativeCalculation) return true;
15108
+ const after = this._getIterationCell(item);
15109
+ const previousValue = beforeValues[i];
15110
+ return typeof after.v === "number" && typeof previousValue === "number" && (after.t == null || after.t === _univerjs_core.CellValueType.NUMBER) && (beforeTypes[i] == null || beforeTypes[i] === _univerjs_core.CellValueType.NUMBER) ? Number.isFinite(after.v) && Math.abs(after.v - previousValue) <= settings[i].maxChange : after.t === beforeTypes[i] && after.v === previousValue;
15111
+ });
15112
+ if (converged) break;
15113
+ }
15114
+ FORMULA_REF_TO_ARRAY_CACHE.clear();
15115
+ this._runtimeService.recordCircularReferences(group.map((item, i) => ({
15116
+ unitId: item.unitId,
15117
+ sheetId: item.subUnitId,
15118
+ row: item.row,
15119
+ column: item.column,
15120
+ groupId,
15121
+ iterations: settings[i].iterativeCalculation ? Math.min(iterations, settings[i].maxIterations) : 0,
15122
+ converged: settings[i].iterativeCalculation ? converged : void 0
15123
+ })));
15124
+ }
15125
+ async *_getCalculationSteps(trees) {
15126
+ while (trees.length) {
15127
+ const tree = trees.pop();
15128
+ if (tree.cycleGroup == null) {
15129
+ yield {
15130
+ tree,
15131
+ preserve: false,
15132
+ iteration: 0
15133
+ };
15134
+ continue;
15135
+ }
15136
+ const group = [tree];
15137
+ while (trees.length && trees[trees.length - 1].cycleGroup === tree.cycleGroup) group.push(trees.pop());
15138
+ yield* this._iterateCalculationGroup(group, tree.cycleGroup);
15139
+ }
15140
+ }
14846
15141
  constructor(_configService, _lexer, _currentConfigService, _runtimeService, _formulaDependencyGenerator, _interpreter, _astTreeBuilder) {
14847
15142
  super();
14848
15143
  this._configService = _configService;
@@ -14858,6 +15153,9 @@ let CalculateFormulaService = class CalculateFormulaService extends _univerjs_co
14858
15153
  _defineProperty(this, "executionCompleteListener$", this._executionCompleteListener$.asObservable());
14859
15154
  _defineProperty(this, "_executeLock", new _univerjs_core.AsyncLock());
14860
15155
  _defineProperty(this, "_isCalculateTreeModel", false);
15156
+ _defineProperty(this, "_workbookCalculationSettings", {});
15157
+ _defineProperty(this, "_preserveCircularUnits", /* @__PURE__ */ new Set());
15158
+ _defineProperty(this, "_normalizedCalculationSettings", /* @__PURE__ */ new Map());
14861
15159
  }
14862
15160
  dispose() {
14863
15161
  super.dispose();
@@ -14888,20 +15186,17 @@ let CalculateFormulaService = class CalculateFormulaService extends _univerjs_co
14888
15186
  this._runtimeService.setRuntimeFeatureRange(featureId, featureRange);
14889
15187
  }
14890
15188
  async execute(formulaDatasetConfig) {
14891
- this._runtimeService.setFormulaExecuteStage(1);
14892
- this._executionInProgressListener$.next(this._runtimeService.getRuntimeState());
14893
- this._currentConfigService.load(formulaDatasetConfig);
14894
- this._runtimeService.reset();
14895
- const cycleReferenceCount = formulaDatasetConfig.maxIteration || 1;
14896
- this._isCalculateTreeModel = formulaDatasetConfig.isCalculateTreeModel || false;
14897
- this._executeLock.acquire("FORMULA_EXECUTION_LOCK", async () => {
14898
- for (let i = 0; i < cycleReferenceCount; i++) {
14899
- this._runtimeService.setFormulaCycleIndex(i);
14900
- const executed = await this._executeStep();
14901
- FORMULA_REF_TO_ARRAY_CACHE.clear();
14902
- const isCycleDependency = this._runtimeService.isCycleDependency();
14903
- if (!executed || !isCycleDependency) break;
14904
- }
15189
+ return this._executeLock.acquire("FORMULA_EXECUTION_LOCK", async () => {
15190
+ this._runtimeService.setFormulaExecuteStage(1);
15191
+ this._executionInProgressListener$.next(this._runtimeService.getRuntimeState());
15192
+ this._currentConfigService.load(formulaDatasetConfig);
15193
+ this._runtimeService.reset();
15194
+ this._loadCalculationSettings(formulaDatasetConfig.calculationSettings);
15195
+ this._preserveCircularUnits = new Set(formulaDatasetConfig.preserveCircularUnits);
15196
+ this._runtimeService.beginCircularReferences();
15197
+ this._isCalculateTreeModel = formulaDatasetConfig.isCalculateTreeModel || false;
15198
+ await this._executeStep();
15199
+ this._runtimeService.completeCircularReferences();
14905
15200
  this._runtimeService.setFormulaExecuteStage(8);
14906
15201
  this._executionInProgressListener$.next(this._runtimeService.getRuntimeState());
14907
15202
  this._executionCompleteListener$.next(this._runtimeService.getAllRuntimeData());
@@ -14982,15 +15277,9 @@ let CalculateFormulaService = class CalculateFormulaService extends _univerjs_co
14982
15277
  const intervalCount = (config === null || config === void 0 ? void 0 : config.intervalCount) || 500;
14983
15278
  let i = 0;
14984
15279
  const treeCount = treeList.length;
14985
- while (treeList.length > 0) {
14986
- const tree = treeList.pop();
15280
+ for await (const { tree, preserve, iteration } of this._getCalculationSteps(treeList)) {
15281
+ this._runtimeService.setFormulaCycleIndex(iteration);
14987
15282
  this._runtimeService.setCurrent(tree.row, tree.column, tree.rowCount, tree.columnCount, tree.subUnitId, tree.unitId);
14988
- const node = generateAstNode(tree.unitId, tree.formula, this._lexer, this._astTreeBuilder, this._currentConfigService, tree.subUnitId, tree.column, tree.row);
14989
- const nodeData = {
14990
- node,
14991
- refOffsetX: tree.refOffsetX,
14992
- refOffsetY: tree.refOffsetY
14993
- };
14994
15283
  const getDirtyData = tree.getDirtyData;
14995
15284
  if (i % intervalCount === 0) {
14996
15285
  /**
@@ -15008,12 +15297,23 @@ let CalculateFormulaService = class CalculateFormulaService extends _univerjs_co
15008
15297
  this._runtimeService.setCompletedFormulasCount(i + 1);
15009
15298
  }
15010
15299
  this._executionInProgressListener$.next(this._runtimeService.getRuntimeState());
15011
- if (this._runtimeService.isStopExecution() || nodeData == null && getDirtyData == null) {
15300
+ if (this._runtimeService.isStopExecution()) {
15012
15301
  this._runtimeService.setFormulaExecuteStage(0);
15013
15302
  this._runtimeService.markedAsStopFunctionsExecuted();
15014
15303
  return;
15015
15304
  }
15016
15305
  }
15306
+ if (preserve) {
15307
+ this._runtimeService.preserveCurrentCellData();
15308
+ i++;
15309
+ continue;
15310
+ }
15311
+ const node = generateAstNode(tree.unitId, tree.formula, this._lexer, this._astTreeBuilder, this._currentConfigService, tree.subUnitId, tree.column, tree.row);
15312
+ const nodeData = {
15313
+ node,
15314
+ refOffsetX: tree.refOffsetX,
15315
+ refOffsetY: tree.refOffsetY
15316
+ };
15017
15317
  let value;
15018
15318
  if (getDirtyData != null && tree.featureId != null) {
15019
15319
  /**
@@ -15189,11 +15489,12 @@ let CalculateController = class CalculateController extends _univerjs_core.Dispo
15189
15489
  }));
15190
15490
  }
15191
15491
  async _calculate(formulaDirtyData) {
15192
- const { forceCalculation: forceCalculate = false, dirtyRanges = [], dirtyNameMap = {}, dirtyDefinedNameMap = {}, dirtySuperTableMap = {}, dirtyUnitFeatureMap = {}, dirtyUnitOtherFormulaMap = {}, clearDependencyTreeCache = {}, maxIteration = 1, rowData, externalReferences, isCalculateTreeModel = false } = formulaDirtyData;
15492
+ const { dirtyIterationUnits, forceCalculation: forceCalculate = false, dirtyRanges = [], dirtyNameMap = {}, dirtyDefinedNameMap = {}, dirtySuperTableMap = {}, dirtyUnitFeatureMap = {}, dirtyUnitOtherFormulaMap = {}, clearDependencyTreeCache = {}, calculationSettings, rowData, externalReferences, isCalculateTreeModel = false } = formulaDirtyData;
15193
15493
  const formulaData = this._formulaDataModel.getFormulaData();
15194
15494
  const arrayFormulaCellData = this._formulaDataModel.getArrayFormulaCellData();
15195
15495
  const arrayFormulaRange = this._formulaDataModel.getArrayFormulaRange();
15196
15496
  this._calculateFormulaService.execute({
15497
+ dirtyIterationUnits,
15197
15498
  formulaData,
15198
15499
  arrayFormulaCellData,
15199
15500
  arrayFormulaRange,
@@ -15205,7 +15506,7 @@ let CalculateController = class CalculateController extends _univerjs_core.Dispo
15205
15506
  dirtyUnitFeatureMap,
15206
15507
  dirtyUnitOtherFormulaMap,
15207
15508
  clearDependencyTreeCache,
15208
- maxIteration,
15509
+ calculationSettings,
15209
15510
  isCalculateTreeModel,
15210
15511
  rowData,
15211
15512
  externalReferences
@@ -15253,7 +15554,10 @@ let CalculateController = class CalculateController extends _univerjs_core.Dispo
15253
15554
  break;
15254
15555
  case 0:
15255
15556
  }
15256
- this._commandService.executeCommand(SetFormulaCalculationNotificationMutation.id, { functionsExecutedState }, { onlyLocal: true });
15557
+ this._commandService.executeCommand(SetFormulaCalculationNotificationMutation.id, {
15558
+ functionsExecutedState,
15559
+ circularReferences: data.circularReferences
15560
+ }, { onlyLocal: true });
15257
15561
  });
15258
15562
  /**
15259
15563
  * Assignment operation after formula calculation.
@@ -15267,7 +15571,7 @@ let CalculateController = class CalculateController extends _univerjs_core.Dispo
15267
15571
  if (dependencyTreeModelData.length > 0) this._commandService.executeCommand(SetFormulaDependencyCalculationResultMutation.id, { result: dependencyTreeModelData }, { onlyLocal: true });
15268
15572
  }
15269
15573
  async _applyResult(data) {
15270
- const { unitData, unitOtherData, arrayFormulaRange, arrayFormulaCellData, clearArrayFormulaCellData, arrayFormulaEmbedded, imageFormulaData } = data;
15574
+ const { unitData, sourceFormulaData, unitOtherData, arrayFormulaRange, arrayFormulaCellData, clearArrayFormulaCellData, arrayFormulaEmbedded, imageFormulaData } = data;
15271
15575
  if (!unitData) {
15272
15576
  this._applyTreeResult(data);
15273
15577
  console.error("No sheetData from Formula Engine!");
@@ -15287,6 +15591,7 @@ let CalculateController = class CalculateController extends _univerjs_core.Dispo
15287
15591
  this._applyTreeResult(data);
15288
15592
  this._commandService.executeCommand(SetFormulaCalculationResultMutation.id, {
15289
15593
  unitData: convertRuntimeToUnitData(unitData),
15594
+ sourceFormulaData,
15290
15595
  unitOtherData
15291
15596
  }, { onlyLocal: true });
15292
15597
  }
@@ -21330,13 +21635,13 @@ const weekendNumberMap = {
21330
21635
  17: [6]
21331
21636
  };
21332
21637
  function isValidWeekend(weekend) {
21333
- if (typeof weekend === "string" && /^[0|1]{7}/.test(weekend)) return true;
21638
+ if (typeof weekend === "string") return weekend.length === 7 && /^[01]{7}$/.test(weekend);
21334
21639
  if (weekendNumberMap[Number(weekend)]) return true;
21335
21640
  return false;
21336
21641
  }
21337
21642
  function getWeekendArray(weekend) {
21338
21643
  if (!isValidWeekend(weekend)) return [];
21339
- if (typeof weekend === "string" && /^[0|1]{7}/.test(weekend)) {
21644
+ if (typeof weekend === "string") {
21340
21645
  const result = [];
21341
21646
  for (let i = 1; i <= weekend.length; i++) if (`${weekend[i - 1]}` === "1") {
21342
21647
  if (i === weekend.length) result.push(0);
@@ -32711,7 +33016,7 @@ var Sort = class extends BaseFunction {
32711
33016
  _getResult(array, sortIndexValue, sortOrderValue, byColValue, arrayRowCount, arrayColumnCount) {
32712
33017
  if (!byColValue) {
32713
33018
  if (sortIndexValue > arrayColumnCount) return ErrorValueObject.create("#VALUE!");
32714
- const arrayValue = array.getArrayValue();
33019
+ const arrayValue = array.getArrayValue().slice();
32715
33020
  arrayValue.sort(this._sort(sortIndexValue - 1, sortOrderValue));
32716
33021
  return ArrayValueObject.create({
32717
33022
  calculateValueList: arrayValue,
@@ -33643,30 +33948,18 @@ var Xlookup = class extends BaseFunction {
33643
33948
  else resultArray = returnArray.slice(void 0, [0, 1]);
33644
33949
  if (resultArray == null) return ErrorValueObject.create("#N/A");
33645
33950
  return lookupValue.map((value) => {
33646
- const checkErrorCombination = this._checkErrorCombination(matchModeValue, searchModeValue);
33647
- if (checkErrorCombination) return checkErrorCombination;
33648
- const result = this._handleSingleObject(value, lookupArray, resultArray, matchModeValue, searchModeValue);
33649
- if (result.isError()) return ifNotFound;
33650
- return this._blankResultAsZero(result);
33951
+ return this._getLookupResult(value, lookupArray, resultArray, ifNotFound, matchModeValue, searchModeValue);
33651
33952
  });
33652
33953
  }
33653
33954
  const _lookupValue = lookupValue.isArray() ? lookupValue.get(0, 0) : lookupValue;
33654
- if (columnCountLookup === columnCountReturn && rowCountLookup === rowCountReturn) {
33655
- const checkErrorCombination = this._checkErrorCombination(matchModeValue, searchModeValue);
33656
- if (checkErrorCombination) return checkErrorCombination;
33657
- const result = this._handleSingleObject(_lookupValue, lookupArray, returnArray, matchModeValue, searchModeValue);
33658
- if (result.isError()) return ifNotFound;
33659
- return this._blankResultAsZero(result);
33660
- }
33955
+ if (columnCountLookup === columnCountReturn && rowCountLookup === rowCountReturn) return this._getLookupResult(_lookupValue, lookupArray, returnArray, ifNotFound, matchModeValue, searchModeValue);
33661
33956
  let axis = 0;
33662
33957
  /**
33663
33958
  * 0 for rows
33664
33959
  * 1 for columns
33665
33960
  */
33666
33961
  if (columnCountLookup === columnCountReturn) axis = 1;
33667
- const resultArray = this._handleExpandObject(_lookupValue, lookupArray, returnArray, matchModeValue, searchModeValue, axis);
33668
- if (resultArray == null) return ErrorValueObject.create("#N/A");
33669
- return resultArray;
33962
+ return this._getLookupResult(_lookupValue, lookupArray, returnArray, ifNotFound, matchModeValue, searchModeValue, axis);
33670
33963
  }
33671
33964
  _legacyImplicitLookupValue(lookupValue) {
33672
33965
  if (!lookupValue.isArray()) return lookupValue;
@@ -33694,35 +33987,37 @@ var Xlookup = class extends BaseFunction {
33694
33987
  if (rowIndex < 0 || rowIndex >= rowCount || columnIndex < 0 || columnIndex >= columnCount) return ErrorValueObject.create("#VALUE!");
33695
33988
  return array.get(rowIndex, columnIndex) || ErrorValueObject.create("#VALUE!");
33696
33989
  }
33697
- _handleExpandObject(value, searchArray, resultArray, matchModeValue, searchModeValue, axis = 0) {
33990
+ _getLookupResult(value, searchArray, resultArray, ifNotFound, matchModeValue, searchModeValue, axis) {
33991
+ if (value.isError()) return value;
33992
+ const checkErrorCombination = this._checkErrorCombination(matchModeValue, searchModeValue);
33993
+ if (checkErrorCombination) return checkErrorCombination;
33994
+ const position = this._findPosition(value, searchArray, matchModeValue, searchModeValue);
33995
+ if (position == null) return ifNotFound;
33996
+ if (axis === 0) return resultArray.slice([position.row, position.row + 1]) ?? ErrorValueObject.create("#N/A");
33997
+ if (axis === 1) return resultArray.slice(void 0, [position.column, position.column + 1]) ?? ErrorValueObject.create("#N/A");
33998
+ const result = resultArray.get(position.row, position.column) ?? NullValueObject.create();
33999
+ return this._blankResultAsZero(result);
34000
+ }
34001
+ _findPosition(value, searchArray, matchModeValue, searchModeValue) {
33698
34002
  if ((searchModeValue === 2 || searchModeValue === -2) && matchModeValue !== 2) {
33699
34003
  const searchType = getSearchModeValue(searchModeValue);
33700
34004
  const matchType = getMatchModeValue(matchModeValue);
33701
- return this.binarySearchExpand(value, searchArray, resultArray, axis, searchType, matchType);
34005
+ const rowOrColumn = searchArray.binarySearch(value, searchType, matchType);
34006
+ if (rowOrColumn == null) return null;
34007
+ return searchArray.getRowCount() === 1 ? {
34008
+ row: 0,
34009
+ column: rowOrColumn
34010
+ } : {
34011
+ row: rowOrColumn,
34012
+ column: 0
34013
+ };
33702
34014
  }
33703
- if (matchModeValue === 2) return this.fuzzySearchExpand(value, searchArray, resultArray, searchModeValue !== -1, axis);
33704
- if (matchModeValue === -1 || matchModeValue === 1) return this.orderSearchExpand(value, searchArray, resultArray, matchModeValue === 1 ? 2 : 1, searchModeValue === -1, axis, true);
33705
- return this._exactSearchExpand(value, searchArray, resultArray, searchModeValue !== -1, axis);
33706
- }
33707
- _handleSingleObject(value, searchArray, resultArray, matchModeValue, searchModeValue) {
33708
- if ((searchModeValue === 2 || searchModeValue === -2) && matchModeValue !== 2) {
33709
- const searchType = getSearchModeValue(searchModeValue);
33710
- const matchType = getMatchModeValue(matchModeValue);
33711
- return this.binarySearch(value, searchArray, resultArray, searchType, matchType);
34015
+ if (matchModeValue === 2) {
34016
+ const matches = searchArray.compare(value, "=");
34017
+ return searchModeValue === -1 ? matches.getLastTruePosition() : matches.getFirstTruePosition();
33712
34018
  }
33713
- if (matchModeValue === 2) return this.fuzzySearch(value, searchArray, resultArray, searchModeValue !== -1);
33714
- if (matchModeValue === -1 || matchModeValue === 1) return this.orderSearch(value, searchArray, resultArray, matchModeValue === 1 ? 2 : 1, searchModeValue === -1, true);
33715
- return this._exactSearch(value, searchArray, resultArray, searchModeValue !== -1);
33716
- }
33717
- _exactSearch(value, searchArray, resultArray, isFirst) {
33718
- const position = this._findExactPosition(value, searchArray, isFirst);
33719
- if (position == null) return ErrorValueObject.create("#N/A");
33720
- return resultArray.get(position.row, position.column) ?? ErrorValueObject.create("#N/A");
33721
- }
33722
- _exactSearchExpand(value, searchArray, resultArray, isFirst, axis) {
33723
- const position = this._findExactPosition(value, searchArray, isFirst);
33724
- if (position == null) return ErrorValueObject.create("#N/A");
33725
- return axis === 0 ? resultArray.slice([position.row, position.row + 1]) ?? ErrorValueObject.create("#N/A") : resultArray.slice(void 0, [position.column, position.column + 1]) ?? ErrorValueObject.create("#N/A");
34019
+ if (matchModeValue === -1 || matchModeValue === 1) return searchArray.orderSearch(value, matchModeValue === 1 ? 2 : 1, searchModeValue === -1, false, true);
34020
+ return this._findExactPosition(value, searchArray, searchModeValue !== -1);
33726
34021
  }
33727
34022
  _findExactPosition(value, searchArray, isFirst) {
33728
34023
  let position;
@@ -43749,7 +44044,7 @@ function getObjectValue(result, isUseStrip = false) {
43749
44044
  //#endregion
43750
44045
  //#region package.json
43751
44046
  var name = "@univerjs/engine-formula";
43752
- var version = "1.0.3";
44047
+ var version = "1.1.0";
43753
44048
 
43754
44049
  //#endregion
43755
44050
  //#region src/services/global-computing-status.service.ts
@@ -43835,6 +44130,7 @@ let FormulaCalculationTriggerService = class FormulaCalculationTriggerService ex
43835
44130
  _defineProperty(this, "_executionInProgress", false);
43836
44131
  _defineProperty(this, "_hasPendingCalculation", false);
43837
44132
  _defineProperty(this, "_stopRequested", false);
44133
+ _defineProperty(this, "_suppressed", false);
43838
44134
  this._registerGenericDirtyConversions();
43839
44135
  this._initialize();
43840
44136
  }
@@ -43843,6 +44139,16 @@ let FormulaCalculationTriggerService = class FormulaCalculationTriggerService ex
43843
44139
  this._started = true;
43844
44140
  this._scheduleFlush();
43845
44141
  }
44142
+ /** Snapshot reconstruction calculates these synchronous mutations in its isolated runtime. */
44143
+ runWithoutTriggering(operation) {
44144
+ const previous = this._suppressed;
44145
+ this._suppressed = true;
44146
+ try {
44147
+ return operation();
44148
+ } finally {
44149
+ this._suppressed = previous;
44150
+ }
44151
+ }
43846
44152
  dispose() {
43847
44153
  clearTimeout(this._timer);
43848
44154
  this._waitingCommandQueue = [];
@@ -43862,7 +44168,7 @@ let FormulaCalculationTriggerService = class FormulaCalculationTriggerService ex
43862
44168
  return;
43863
44169
  }
43864
44170
  const conversion = this._activeDirtyManagerService.get(command.id);
43865
- if (!conversion) return;
44171
+ if (!conversion || this._suppressed) return;
43866
44172
  if (((_conversion$shouldTri = conversion.shouldTrigger) === null || _conversion$shouldTri === void 0 ? void 0 : _conversion$shouldTri.call(conversion, command, options)) === false) return;
43867
44173
  this._waitingCommandQueue.push(command);
43868
44174
  this._scheduleFlush();
@@ -43951,6 +44257,8 @@ function mergeDirtyData(left, right) {
43951
44257
  return result;
43952
44258
  }
43953
44259
  function appendDirtyData(target, source, rangeKeys) {
44260
+ var _source$dirtyIteratio;
44261
+ if ((_source$dirtyIteratio = source.dirtyIterationUnits) === null || _source$dirtyIteratio === void 0 ? void 0 : _source$dirtyIteratio.length) target.dirtyIterationUnits = Array.from(/* @__PURE__ */ new Set([...target.dirtyIterationUnits ?? [], ...source.dirtyIterationUnits]));
43954
44262
  mergeDirtyRanges(target.dirtyRanges, source.dirtyRanges ?? [], rangeKeys);
43955
44263
  mergeDirtyUnitStringMap(target.dirtyNameMap, source.dirtyNameMap);
43956
44264
  mergeDirtyUnitStringMap(target.dirtyDefinedNameMap, source.dirtyDefinedNameMap);
@@ -43994,7 +44302,8 @@ function mergeDirtyUnitNestedMap(target, right) {
43994
44302
  });
43995
44303
  }
43996
44304
  function hasDirtyData(dirtyData) {
43997
- return dirtyData.forceCalculation || dirtyData.dirtyRanges.length > 0 || hasNestedValue(dirtyData.dirtyNameMap) || hasNestedValue(dirtyData.dirtyDefinedNameMap) || hasNestedValue(dirtyData.dirtySuperTableMap) || hasNestedValue(dirtyData.dirtyUnitFeatureMap) || hasNestedValue(dirtyData.dirtyUnitOtherFormulaMap) || hasNestedValue(dirtyData.clearDependencyTreeCache);
44305
+ var _dirtyData$dirtyItera;
44306
+ return dirtyData.forceCalculation || Boolean((_dirtyData$dirtyItera = dirtyData.dirtyIterationUnits) === null || _dirtyData$dirtyItera === void 0 ? void 0 : _dirtyData$dirtyItera.length) || dirtyData.dirtyRanges.length > 0 || hasNestedValue(dirtyData.dirtyNameMap) || hasNestedValue(dirtyData.dirtyDefinedNameMap) || hasNestedValue(dirtyData.dirtySuperTableMap) || hasNestedValue(dirtyData.dirtyUnitFeatureMap) || hasNestedValue(dirtyData.dirtyUnitOtherFormulaMap) || hasNestedValue(dirtyData.clearDependencyTreeCache);
43998
44307
  }
43999
44308
  function hasNestedValue(value) {
44000
44309
  if (value == null) return false;
@@ -44002,7 +44311,8 @@ function hasNestedValue(value) {
44002
44311
  return Object.values(value).some(hasNestedValue);
44003
44312
  }
44004
44313
  function dirtyDataIntersects(left, right) {
44005
- if (left.forceCalculation || right.forceCalculation) return true;
44314
+ var _left$dirtyIterationU, _right$dirtyIteration;
44315
+ if (left.forceCalculation || right.forceCalculation || ((_left$dirtyIterationU = left.dirtyIterationUnits) === null || _left$dirtyIterationU === void 0 ? void 0 : _left$dirtyIterationU.length) || ((_right$dirtyIteration = right.dirtyIterationUnits) === null || _right$dirtyIteration === void 0 ? void 0 : _right$dirtyIteration.length)) return true;
44006
44316
  if (left.dirtyRanges.some((leftRange) => right.dirtyRanges.some((rightRange) => leftRange.unitId === rightRange.unitId && leftRange.sheetId === rightRange.sheetId && _univerjs_core.Rectangle.intersects(leftRange.range, rightRange.range))) || clearedSheetIntersects(left, right) || clearedSheetIntersects(right, left)) return true;
44007
44317
  return [
44008
44318
  [left.dirtyNameMap, right.dirtyNameMap],
@@ -57450,13 +57760,17 @@ _defineProperty(UniverFormulaEnginePlugin, "packageName", name);
57450
57760
  _defineProperty(UniverFormulaEnginePlugin, "version", version);
57451
57761
  UniverFormulaEnginePlugin = __decorate([__decorateParam(1, (0, _univerjs_core.Inject)(_univerjs_core.Injector)), __decorateParam(2, _univerjs_core.IConfigService)], UniverFormulaEnginePlugin);
57452
57762
 
57763
+ //#endregion
57764
+ //#region src/services/formula-changeset-calculation.service.ts
57765
+ const IFormulaChangesetCalculationService = (0, _univerjs_core.createIdentifier)("engine-formula.changeset-calculation.service");
57766
+
57453
57767
  //#endregion
57454
57768
  exports.ALL_IMPLEMENTED_FUNCTIONS = ALL_IMPLEMENTED_FUNCTIONS;
57455
57769
  exports.ALL_IMPLEMENTED_FUNCTIONS_SET = ALL_IMPLEMENTED_FUNCTIONS_SET;
57456
57770
  exports.ActiveDirtyManagerService = ActiveDirtyManagerService;
57457
57771
  exports.ArrayValueObject = ArrayValueObject;
57458
57772
  exports.AstRootNodeFactory = AstRootNodeFactory;
57459
- Object.defineProperty(exports, 'AstTreeBuilder', {
57773
+ Object.defineProperty(exports, "AstTreeBuilder", {
57460
57774
  enumerable: true,
57461
57775
  get: function () {
57462
57776
  return AstTreeBuilder;
@@ -57471,27 +57785,26 @@ exports.BaseValueObject = BaseValueObject;
57471
57785
  exports.BooleanValue = BooleanValue;
57472
57786
  exports.BooleanValueObject = BooleanValueObject;
57473
57787
  exports.CELL_INVERTED_INDEX_CACHE = CELL_INVERTED_INDEX_CACHE;
57474
- Object.defineProperty(exports, 'CalculateController', {
57788
+ Object.defineProperty(exports, "CalculateController", {
57475
57789
  enumerable: true,
57476
57790
  get: function () {
57477
57791
  return CalculateController;
57478
57792
  }
57479
57793
  });
57480
- Object.defineProperty(exports, 'CalculateFormulaService', {
57794
+ Object.defineProperty(exports, "CalculateFormulaService", {
57481
57795
  enumerable: true,
57482
57796
  get: function () {
57483
57797
  return CalculateFormulaService;
57484
57798
  }
57485
57799
  });
57486
57800
  exports.CustomFunction = CustomFunction;
57487
- exports.DEFAULT_CYCLE_REFERENCE_COUNT = DEFAULT_CYCLE_REFERENCE_COUNT;
57488
57801
  exports.DEFAULT_INTERVAL_COUNT = DEFAULT_INTERVAL_COUNT;
57489
57802
  exports.DEFAULT_TOKEN_LAMBDA_FUNCTION_NAME = DEFAULT_TOKEN_LAMBDA_FUNCTION_NAME;
57490
57803
  exports.DEFAULT_TOKEN_LET_FUNCTION_NAME = DEFAULT_TOKEN_LET_FUNCTION_NAME;
57491
57804
  exports.DEFAULT_TOKEN_TYPE_LAMBDA_PARAMETER = DEFAULT_TOKEN_TYPE_LAMBDA_PARAMETER;
57492
57805
  exports.DEFAULT_TOKEN_TYPE_PARAMETER = DEFAULT_TOKEN_TYPE_PARAMETER;
57493
57806
  exports.DEFAULT_TOKEN_TYPE_ROOT = DEFAULT_TOKEN_TYPE_ROOT;
57494
- Object.defineProperty(exports, 'DefinedNamesService', {
57807
+ Object.defineProperty(exports, "DefinedNamesService", {
57495
57808
  enumerable: true,
57496
57809
  get: function () {
57497
57810
  return DefinedNamesService;
@@ -57499,13 +57812,12 @@ Object.defineProperty(exports, 'DefinedNamesService', {
57499
57812
  });
57500
57813
  exports.DependencyManagerBaseService = DependencyManagerBaseService;
57501
57814
  exports.DependencyManagerService = DependencyManagerService;
57502
- Object.defineProperty(exports, 'DescriptionService', {
57815
+ Object.defineProperty(exports, "DescriptionService", {
57503
57816
  enumerable: true,
57504
57817
  get: function () {
57505
57818
  return DescriptionService;
57506
57819
  }
57507
57820
  });
57508
- exports.ENGINE_FORMULA_CYCLE_REFERENCE_COUNT = ENGINE_FORMULA_CYCLE_REFERENCE_COUNT;
57509
57821
  exports.ENGINE_FORMULA_PLUGIN_CONFIG_KEY = ENGINE_FORMULA_PLUGIN_CONFIG_KEY;
57510
57822
  exports.ENGINE_FORMULA_RETURN_DEPENDENCY_TREE = ENGINE_FORMULA_RETURN_DEPENDENCY_TREE;
57511
57823
  exports.ERROR_TYPE_SET = ERROR_TYPE_SET;
@@ -57544,32 +57856,32 @@ exports.FUNCTION_NAMES_TEXT = FUNCTION_NAMES_TEXT;
57544
57856
  exports.FUNCTION_NAMES_UNIVER = FUNCTION_NAMES_UNIVER;
57545
57857
  exports.FUNCTION_NAMES_WEB = FUNCTION_NAMES_WEB;
57546
57858
  exports.FeatureCalculationManagerService = FeatureCalculationManagerService;
57547
- Object.defineProperty(exports, 'FormulaCalculationSessionController', {
57859
+ Object.defineProperty(exports, "FormulaCalculationSessionController", {
57548
57860
  enumerable: true,
57549
57861
  get: function () {
57550
57862
  return FormulaCalculationSessionController;
57551
57863
  }
57552
57864
  });
57553
57865
  exports.FormulaCalculationSessionService = FormulaCalculationSessionService;
57554
- Object.defineProperty(exports, 'FormulaCalculationTriggerService', {
57866
+ Object.defineProperty(exports, "FormulaCalculationTriggerService", {
57555
57867
  enumerable: true,
57556
57868
  get: function () {
57557
57869
  return FormulaCalculationTriggerService;
57558
57870
  }
57559
57871
  });
57560
- Object.defineProperty(exports, 'FormulaCurrentConfigService', {
57872
+ Object.defineProperty(exports, "FormulaCurrentConfigService", {
57561
57873
  enumerable: true,
57562
57874
  get: function () {
57563
57875
  return FormulaCurrentConfigService;
57564
57876
  }
57565
57877
  });
57566
- Object.defineProperty(exports, 'FormulaDataModel', {
57878
+ Object.defineProperty(exports, "FormulaDataModel", {
57567
57879
  enumerable: true,
57568
57880
  get: function () {
57569
57881
  return FormulaDataModel;
57570
57882
  }
57571
57883
  });
57572
- Object.defineProperty(exports, 'FormulaDependencyGenerator', {
57884
+ Object.defineProperty(exports, "FormulaDependencyGenerator", {
57573
57885
  enumerable: true,
57574
57886
  get: function () {
57575
57887
  return FormulaDependencyGenerator;
@@ -57583,19 +57895,19 @@ exports.FormulaExecuteStageType = FormulaExecuteStageType;
57583
57895
  exports.FormulaExecutedStateType = FormulaExecutedStateType;
57584
57896
  exports.FormulaResultApplicationType = FormulaResultApplicationType;
57585
57897
  exports.FormulaResultStatus = FormulaResultStatus;
57586
- Object.defineProperty(exports, 'FormulaRuntimeService', {
57898
+ Object.defineProperty(exports, "FormulaRuntimeService", {
57587
57899
  enumerable: true,
57588
57900
  get: function () {
57589
57901
  return FormulaRuntimeService;
57590
57902
  }
57591
57903
  });
57592
- Object.defineProperty(exports, 'FormulaUnitReferenceResolver', {
57904
+ Object.defineProperty(exports, "FormulaUnitReferenceResolver", {
57593
57905
  enumerable: true,
57594
57906
  get: function () {
57595
57907
  return FormulaUnitReferenceResolver;
57596
57908
  }
57597
57909
  });
57598
- Object.defineProperty(exports, 'FunctionNodeFactory', {
57910
+ Object.defineProperty(exports, "FunctionNodeFactory", {
57599
57911
  enumerable: true,
57600
57912
  get: function () {
57601
57913
  return FunctionNodeFactory;
@@ -57604,7 +57916,7 @@ Object.defineProperty(exports, 'FunctionNodeFactory', {
57604
57916
  exports.FunctionService = FunctionService;
57605
57917
  exports.FunctionType = FunctionType;
57606
57918
  exports.GlobalComputingStatusService = GlobalComputingStatusService;
57607
- Object.defineProperty(exports, 'HyperlinkEngineFormulaService', {
57919
+ Object.defineProperty(exports, "HyperlinkEngineFormulaService", {
57608
57920
  enumerable: true,
57609
57921
  get: function () {
57610
57922
  return HyperlinkEngineFormulaService;
@@ -57616,6 +57928,7 @@ exports.IDefinedNamesService = IDefinedNamesService;
57616
57928
  exports.IDependencyManagerService = IDependencyManagerService;
57617
57929
  exports.IDescriptionService = IDescriptionService;
57618
57930
  exports.IFeatureCalculationManagerService = IFeatureCalculationManagerService;
57931
+ exports.IFormulaChangesetCalculationService = IFormulaChangesetCalculationService;
57619
57932
  exports.IFormulaCurrentConfigService = IFormulaCurrentConfigService;
57620
57933
  exports.IFormulaDependencyGenerator = IFormulaDependencyGenerator;
57621
57934
  exports.IFormulaExternalReferenceDataLoader = IFormulaExternalReferenceDataLoader;
@@ -57627,13 +57940,13 @@ exports.IOtherFormulaManagerService = IOtherFormulaManagerService;
57627
57940
  exports.IRegisterFunctionService = IRegisterFunctionService;
57628
57941
  exports.ISheetRowFilteredService = ISheetRowFilteredService;
57629
57942
  exports.ISuperTableService = ISuperTableService;
57630
- Object.defineProperty(exports, 'Interpreter', {
57943
+ Object.defineProperty(exports, "Interpreter", {
57631
57944
  enumerable: true,
57632
57945
  get: function () {
57633
57946
  return Interpreter;
57634
57947
  }
57635
57948
  });
57636
- Object.defineProperty(exports, 'LambdaNodeFactory', {
57949
+ Object.defineProperty(exports, "LambdaNodeFactory", {
57637
57950
  enumerable: true,
57638
57951
  get: function () {
57639
57952
  return LambdaNodeFactory;
@@ -57641,7 +57954,7 @@ Object.defineProperty(exports, 'LambdaNodeFactory', {
57641
57954
  });
57642
57955
  exports.LambdaParameterNodeFactory = LambdaParameterNodeFactory;
57643
57956
  exports.LambdaValueObjectObject = LambdaValueObjectObject;
57644
- Object.defineProperty(exports, 'Lexer', {
57957
+ Object.defineProperty(exports, "Lexer", {
57645
57958
  enumerable: true,
57646
57959
  get: function () {
57647
57960
  return Lexer;
@@ -57654,7 +57967,7 @@ exports.NoopFormulaExternalReferenceDataLoader = NoopFormulaExternalReferenceDat
57654
57967
  exports.NullValueObject = NullValueObject;
57655
57968
  exports.NumberValueObject = NumberValueObject;
57656
57969
  exports.OPERATOR_TOKEN_SET = OPERATOR_TOKEN_SET;
57657
- Object.defineProperty(exports, 'OperatorNodeFactory', {
57970
+ Object.defineProperty(exports, "OperatorNodeFactory", {
57658
57971
  enumerable: true,
57659
57972
  get: function () {
57660
57973
  return OperatorNodeFactory;
@@ -57663,27 +57976,27 @@ Object.defineProperty(exports, 'OperatorNodeFactory', {
57663
57976
  exports.OtherFormulaBizType = OtherFormulaBizType;
57664
57977
  exports.OtherFormulaManagerService = OtherFormulaManagerService;
57665
57978
  exports.OtherFormulaMarkDirty = OtherFormulaMarkDirty;
57666
- Object.defineProperty(exports, 'PrefixNodeFactory', {
57979
+ Object.defineProperty(exports, "PrefixNodeFactory", {
57667
57980
  enumerable: true,
57668
57981
  get: function () {
57669
57982
  return PrefixNodeFactory;
57670
57983
  }
57671
57984
  });
57672
57985
  exports.RangeReferenceObject = RangeReferenceObject;
57673
- Object.defineProperty(exports, 'ReferenceNodeFactory', {
57986
+ Object.defineProperty(exports, "ReferenceNodeFactory", {
57674
57987
  enumerable: true,
57675
57988
  get: function () {
57676
57989
  return ReferenceNodeFactory;
57677
57990
  }
57678
57991
  });
57679
57992
  exports.RegisterFunctionMutation = RegisterFunctionMutation;
57680
- Object.defineProperty(exports, 'RegisterFunctionService', {
57993
+ Object.defineProperty(exports, "RegisterFunctionService", {
57681
57994
  enumerable: true,
57682
57995
  get: function () {
57683
57996
  return RegisterFunctionService;
57684
57997
  }
57685
57998
  });
57686
- Object.defineProperty(exports, 'RegisterOtherFormulaService', {
57999
+ Object.defineProperty(exports, "RegisterOtherFormulaService", {
57687
58000
  enumerable: true,
57688
58001
  get: function () {
57689
58002
  return RegisterOtherFormulaService;
@@ -57720,26 +58033,26 @@ exports.SetSuperTableOptionMutation = SetSuperTableOptionMutation;
57720
58033
  exports.SetTriggerFormulaCalculationStartMutation = SetTriggerFormulaCalculationStartMutation;
57721
58034
  exports.SheetRowFilteredService = SheetRowFilteredService;
57722
58035
  exports.StringValueObject = StringValueObject;
57723
- Object.defineProperty(exports, 'SuffixNodeFactory', {
58036
+ Object.defineProperty(exports, "SuffixNodeFactory", {
57724
58037
  enumerable: true,
57725
58038
  get: function () {
57726
58039
  return SuffixNodeFactory;
57727
58040
  }
57728
58041
  });
57729
- Object.defineProperty(exports, 'SuperTableActiveDirtyController', {
58042
+ Object.defineProperty(exports, "SuperTableActiveDirtyController", {
57730
58043
  enumerable: true,
57731
58044
  get: function () {
57732
58045
  return SuperTableActiveDirtyController;
57733
58046
  }
57734
58047
  });
57735
58048
  exports.SuperTableService = SuperTableService;
57736
- Object.defineProperty(exports, 'UnionNodeFactory', {
58049
+ Object.defineProperty(exports, "UnionNodeFactory", {
57737
58050
  enumerable: true,
57738
58051
  get: function () {
57739
58052
  return UnionNodeFactory;
57740
58053
  }
57741
58054
  });
57742
- Object.defineProperty(exports, 'UniverFormulaEnginePlugin', {
58055
+ Object.defineProperty(exports, "UniverFormulaEnginePlugin", {
57743
58056
  enumerable: true,
57744
58057
  get: function () {
57745
58058
  return UniverFormulaEnginePlugin;
@@ -57798,6 +58111,7 @@ exports.isReferenceStringWithEffectiveColumn = isReferenceStringWithEffectiveCol
57798
58111
  exports.isReferenceStrings = isReferenceStrings;
57799
58112
  exports.matchRefDrawToken = matchRefDrawToken;
57800
58113
  exports.matchToken = matchToken;
58114
+ exports.mergeDirtyData = mergeDirtyData;
57801
58115
  exports.needsQuoting = needsQuoting;
57802
58116
  exports.normalizeFormulaUnitName = normalizeFormulaUnitName;
57803
58117
  exports.normalizeSheetName = normalizeSheetName;