@univerjs-pro/engine-formula-rust 1.0.0-insiders.20260725-1b9c8d8

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 (39) hide show
  1. package/README.md +56 -0
  2. package/lib/index.js +2114 -0
  3. package/lib/types/adapters/rust-projection-remote-instance.service.d.ts +28 -0
  4. package/lib/types/binding.d.ts +105 -0
  5. package/lib/types/controllers/rust-engine-sync.controller.d.ts +40 -0
  6. package/lib/types/controllers/rust-same-runtime-projection.controller.d.ts +27 -0
  7. package/lib/types/index.d.ts +10 -0
  8. package/lib/types/numfmt.d.ts +145 -0
  9. package/lib/types/plugin.d.ts +35 -0
  10. package/lib/types/regression/formula-array-followers.d.ts +14 -0
  11. package/lib/types/regression/formula-value-normalization.d.ts +2 -0
  12. package/lib/types/regression/formula-volatile-dependencies.d.ts +7 -0
  13. package/lib/types/regression/real-univer-stage-timeouts.d.ts +7 -0
  14. package/lib/types/regression/rust-only-artifact-cache.d.ts +41 -0
  15. package/lib/types/regression/rust-only-discovery.d.ts +17 -0
  16. package/lib/types/regression/rust-only-excel-com-oracle.d.ts +57 -0
  17. package/lib/types/regression/rust-only-excel-process-cleanup.d.ts +3 -0
  18. package/lib/types/regression/rust-only-exchange-binary.d.ts +15 -0
  19. package/lib/types/regression/rust-only-failure-report.d.ts +13 -0
  20. package/lib/types/regression/rust-only-feature-extraction.d.ts +19 -0
  21. package/lib/types/regression/rust-only-formula-comparison.d.ts +43 -0
  22. package/lib/types/regression/rust-only-ooxml-diff.d.ts +23 -0
  23. package/lib/types/regression/rust-only-ooxml-feature-extraction.d.ts +7 -0
  24. package/lib/types/regression/rust-only-partial-artifacts.d.ts +7 -0
  25. package/lib/types/regression/rust-only-pipeline.d.ts +55 -0
  26. package/lib/types/regression/rust-only-process.d.ts +9 -0
  27. package/lib/types/regression/rust-only-real-runner.d.ts +103 -0
  28. package/lib/types/regression/rust-only-report.d.ts +131 -0
  29. package/lib/types/regression/rust-only-sequential-runner.d.ts +24 -0
  30. package/lib/types/regression/rust-only-timeout.d.ts +63 -0
  31. package/lib/types/regression/rust-only-view-host.d.ts +171 -0
  32. package/lib/types/regression/rust-only-workbook-json-formula-values.d.ts +2 -0
  33. package/lib/types/regression/rust-only-xlsx-formula-values.d.ts +8 -0
  34. package/lib/types/regression/xlsx-sample-compatibility.d.ts +56 -0
  35. package/lib/types/services/calculate-formula.service.d.ts +106 -0
  36. package/lib/types/services/rust-formula-projection.service.d.ts +70 -0
  37. package/lib/types/services/workbook-snapshot-materializer.d.ts +20 -0
  38. package/lib/types/types.d.ts +398 -0
  39. package/package.json +47 -0
package/lib/index.js ADDED
@@ -0,0 +1,2114 @@
1
+ // src/binding.ts
2
+ import { createRequire } from "node:module";
3
+ import process from "node:process";
4
+ var nativeBinding = null, nativeBindingSource = null, nodeRequire = createRequire(import.meta.url);
5
+ function getNativeBindingSource() {
6
+ return nativeBindingSource;
7
+ }
8
+ function formatBindingLoadError(error) {
9
+ return error instanceof Error ? error.message : String(error);
10
+ }
11
+ function createBindingLoadFailure(errors) {
12
+ return new Error(
13
+ [
14
+ "Failed to load native formula engine binding.",
15
+ `platform=${process.platform}`,
16
+ `arch=${process.arch}`,
17
+ "expected npm package=@univerjs-pro/engine-formula-rust-binding",
18
+ "attempted paths:",
19
+ ...errors.map((item) => `- ${item}`)
20
+ ].join(`
21
+ `)
22
+ );
23
+ }
24
+ async function loadNativeBinding() {
25
+ if (nativeBinding)
26
+ return nativeBinding;
27
+ if (typeof process < "u" && process.versions?.node) {
28
+ let errors = [];
29
+ try {
30
+ return nativeBinding = nodeRequire("@univerjs-pro/engine-formula-rust-binding"), nativeBindingSource = "@univerjs-pro/engine-formula-rust-binding", nativeBinding;
31
+ } catch (error) {
32
+ errors.push(`@univerjs-pro/engine-formula-rust-binding: ${formatBindingLoadError(error)}`);
33
+ }
34
+ throw createBindingLoadFailure(errors);
35
+ } else
36
+ throw new Error("WASM binding not yet implemented");
37
+ }
38
+ function executeOnRust(inputJson) {
39
+ if (!nativeBinding)
40
+ throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
41
+ return nativeBinding.formulaEngineExecute(inputJson);
42
+ }
43
+ function buildLexerTreeOnRust(formula, transformSuffix = !0) {
44
+ if (!nativeBinding)
45
+ throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
46
+ return nativeBinding.formulaLexerTreeBuild(formula, transformSuffix);
47
+ }
48
+ function buildSequenceNodesOnRust(formula) {
49
+ if (!nativeBinding)
50
+ throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
51
+ return nativeBinding.formulaSequenceNodesBuild(formula);
52
+ }
53
+ function checkIfAddBracketOnRust(formula) {
54
+ if (!nativeBinding)
55
+ throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
56
+ return nativeBinding.formulaCheckIfAddBracket(formula);
57
+ }
58
+ function formatNumberBatchOnRust(inputJson) {
59
+ if (!nativeBinding)
60
+ throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
61
+ return nativeBinding.rustNumfmtFormatBatch(inputJson);
62
+ }
63
+ function parseNumberFormatInputBatchOnRust(inputJson) {
64
+ if (!nativeBinding)
65
+ throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
66
+ return nativeBinding.rustNumfmtParseBatch(inputJson);
67
+ }
68
+ function parseNumberFormatMatrixBatchOnRust(inputJson) {
69
+ if (!nativeBinding)
70
+ throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
71
+ return nativeBinding.rustNumfmtParseMatrixBatch(inputJson);
72
+ }
73
+ function analyzeNumberFormatBatchOnRust(inputJson) {
74
+ if (!nativeBinding)
75
+ throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
76
+ return nativeBinding.rustNumfmtAnalyzeBatch(inputJson);
77
+ }
78
+ function loadSnapshotOnRust(snapshotJson) {
79
+ if (!nativeBinding)
80
+ throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
81
+ return nativeBinding.rustEngineLoadSnapshot(snapshotJson);
82
+ }
83
+ function loadSnapshotBinaryOnRust(snapshotBytes) {
84
+ if (!nativeBinding)
85
+ throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
86
+ return nativeBinding.rustEngineLoadSnapshotBinary(snapshotBytes);
87
+ }
88
+ function applyMutationOnRust(mutationJson) {
89
+ if (!nativeBinding)
90
+ throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
91
+ return nativeBinding.rustEngineApplyMutation(mutationJson);
92
+ }
93
+ function disposeWorkbookOnRust(unitId) {
94
+ if (!nativeBinding)
95
+ throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
96
+ return nativeBinding.rustEngineDisposeWorkbook(unitId);
97
+ }
98
+ function disposeAllWorkbooksOnRust() {
99
+ if (!nativeBinding)
100
+ throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
101
+ return nativeBinding.rustEngineDisposeAllWorkbooks();
102
+ }
103
+ function getRustModelStats() {
104
+ if (!nativeBinding)
105
+ throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
106
+ return nativeBinding.rustEngineGetModelStats();
107
+ }
108
+ function getRustCellOnRust(unitId, sheetId, row, col) {
109
+ if (!nativeBinding)
110
+ throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
111
+ return nativeBinding.rustEngineGetCell(unitId, sheetId, row, col);
112
+ }
113
+ function getRustSheetStateOnRust(unitId, sheetId) {
114
+ if (!nativeBinding)
115
+ throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
116
+ return nativeBinding.rustEngineGetSheetState(unitId, sheetId);
117
+ }
118
+ function getRustFormulaDataOnRust(unitId) {
119
+ if (!nativeBinding)
120
+ throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
121
+ return nativeBinding.rustEngineGetFormulaData(unitId);
122
+ }
123
+ function buildRustDependencyGraphOnRust(unitId) {
124
+ if (!nativeBinding)
125
+ throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
126
+ return nativeBinding.rustEngineBuildDependencyGraph(unitId);
127
+ }
128
+ function getRustDirtyDependenciesOnRust(dirtyRangesJson, unitId) {
129
+ if (!nativeBinding)
130
+ throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
131
+ return nativeBinding.rustEngineGetDirtyDependencies(dirtyRangesJson, unitId);
132
+ }
133
+ function syncRustFormulaDependenciesOnRust(inputJson) {
134
+ if (!nativeBinding)
135
+ throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
136
+ return nativeBinding.rustEngineSyncFormulaDependencies(inputJson);
137
+ }
138
+ function inspectRustFormulaDependencyGraphOnRust() {
139
+ if (!nativeBinding)
140
+ throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
141
+ return nativeBinding.rustEngineInspectFormulaDependencyGraph();
142
+ }
143
+ function markRustFormulaDirtyOnRust(inputJson) {
144
+ if (!nativeBinding)
145
+ throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
146
+ return nativeBinding.rustEngineMarkFormulaDirty(inputJson);
147
+ }
148
+ function clearRustFormulaDependenciesOnRust(inputJson) {
149
+ if (!nativeBinding)
150
+ throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
151
+ return nativeBinding.rustEngineClearFormulaDependencies(inputJson);
152
+ }
153
+ function clearRustFormulaDirtyOnRust() {
154
+ if (!nativeBinding)
155
+ throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
156
+ return nativeBinding.rustEngineClearFormulaDirty();
157
+ }
158
+ function executeDirtyFormulasOnRust(maxIteration, includeCalculatedNodes, includeRuntimeData, includeResultBatches) {
159
+ if (!nativeBinding)
160
+ throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
161
+ return nativeBinding.rustEngineExecuteDirtyFormulas(
162
+ maxIteration,
163
+ includeCalculatedNodes,
164
+ includeRuntimeData,
165
+ includeResultBatches
166
+ );
167
+ }
168
+ function materializeWorkbookSnapshotOnRust(workbookJson, unitId, rev, dirtyInputJson) {
169
+ if (!nativeBinding)
170
+ throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
171
+ return nativeBinding.rustMaterializeWorkbookSnapshot(workbookJson, unitId, rev, dirtyInputJson);
172
+ }
173
+
174
+ // src/controllers/rust-engine-sync.controller.ts
175
+ import { CommandType, Disposable, ICommandService, setDependencies } from "@univerjs/core";
176
+
177
+ // src/services/rust-formula-projection.service.ts
178
+ import { CellValueType, ObjectMatrix } from "@univerjs/core";
179
+ var XLSX_WORKBOOK_CALCULATION_RESOURCE = "UNIVER_CLI_XLSX_WORKBOOK_CALCULATION_PLUGIN", EXTERNAL_DATA_RESOURCE = "SHEET_EXTERNAL_DATA_PLUGIN", EXTERNAL_DATA_SIGNATURE = "external_data", RUST_UPSERT_REFERENCE_DATA_MUTATION_ID = "formula.mutation.upsert-reference-data", RUST_FORMULA_RELEVANT_MUTATIONS = /* @__PURE__ */ new Set([
180
+ "sheet.mutation.set-range-values",
181
+ "sheet.mutation.insert-row",
182
+ "sheet.mutation.insert-col",
183
+ "sheet.mutation.insert-sheet",
184
+ "sheet.mutation.move-range",
185
+ "sheet.mutation.move-rows",
186
+ "sheet.mutation.move-columns",
187
+ "sheet.mutation.move-cols",
188
+ "sheet.mutation.remove-col",
189
+ "sheet.mutation.remove-rows",
190
+ "sheet.mutation.remove-sheet",
191
+ "sheet.mutation.set-col-hidden",
192
+ "sheet.mutation.set-col-visible",
193
+ "sheet.mutation.set-row-hidden",
194
+ "sheet.mutation.set-row-visible",
195
+ "sheet.mutation.set-worksheet-name",
196
+ "sheet.mutation.reorder-range",
197
+ "sheet.mutation.set-worksheet-row-count",
198
+ "sheet.mutation.set-worksheet-column-count",
199
+ "formula.mutation.set-array-formula-data",
200
+ "formula.mutation.set-defined-name",
201
+ "formula.mutation.set-feature-calculation",
202
+ "formula.mutation.set-formula-data",
203
+ "formula.mutation.set-image-formula-data",
204
+ "formula.mutation.set-other-formula",
205
+ "formula.mutation.set-super-table",
206
+ "formula.mutation.set-super-table-option",
207
+ "formula.mutation.remove-defined-name",
208
+ "formula.mutation.remove-feature-calculation",
209
+ "formula.mutation.remove-other-formula",
210
+ "formula.mutation.remove-super-table"
211
+ ]), RUST_INCREMENTAL_DEPENDENCY_MUTATIONS = /* @__PURE__ */ new Set(["sheet.mutation.set-range-values"]);
212
+ function isRustFormulaRelevantMutation(id) {
213
+ return RUST_FORMULA_RELEVANT_MUTATIONS.has(id);
214
+ }
215
+ function isRustIncrementalDependencyMutation(id) {
216
+ return RUST_INCREMENTAL_DEPENDENCY_MUTATIONS.has(id);
217
+ }
218
+ function createReferenceDataUpsertMutations(config, needs) {
219
+ let unitNameMap = config.unitNameMap, grouped = /* @__PURE__ */ new Map();
220
+ for (let need of needs) {
221
+ let key = `${need.unitId}\0${need.sheetId}`, group = grouped.get(key) ?? [];
222
+ group.push(need), grouped.set(key, group);
223
+ }
224
+ return Array.from(grouped.values()).flatMap((group) => {
225
+ let first = group[0], unitData = config.allUnitData?.[first.unitId], sheetNameMap = config.unitSheetNameMap?.[first.unitId] ?? {}, resolvedSheetId = unitData?.[first.sheetId] ? first.sheetId : sheetNameMap[first.sheetId] ?? first.sheetId, sheet = unitData?.[resolvedSheetId];
226
+ if (!sheet)
227
+ return [];
228
+ let sheetName = Object.entries(sheetNameMap).find(([, sheetId]) => sheetId === resolvedSheetId)?.[0] ?? first.sheetId, ranges = group.map(({ range }) => range);
229
+ return [
230
+ {
231
+ id: RUST_UPSERT_REFERENCE_DATA_MUTATION_ID,
232
+ params: {
233
+ unitId: first.unitId,
234
+ name: unitNameMap?.[first.unitId]?.name,
235
+ sheet: {
236
+ name: sheetName,
237
+ sheetId: resolvedSheetId,
238
+ rowCount: sheet.rowCount,
239
+ columnCount: sheet.columnCount,
240
+ coverage: ranges,
241
+ cellData: serializeCellDataInRanges(sheet.cellData, ranges)
242
+ }
243
+ },
244
+ dirtyRanges: ranges.map((range) => ({
245
+ unitId: first.unitId,
246
+ sheetId: resolvedSheetId,
247
+ range
248
+ }))
249
+ }
250
+ ];
251
+ });
252
+ }
253
+ function serializeRuntimeWorkbookSnapshots(workbooks) {
254
+ return {
255
+ workbooks: workbooks.map((workbook) => serializeRuntimeWorkbookSnapshot(workbook))
256
+ };
257
+ }
258
+ function serializeRuntimeWorkbookSnapshot(input) {
259
+ let { snapshot } = input, sheetOrder = snapshot.sheetOrder?.length > 0 ? snapshot.sheetOrder : Object.keys(snapshot.sheets ?? {}), calculation = serializeCalculation(snapshot), precisionAsDisplayed = calculation?.fullPrecision === !1, sheets = sheetOrder.map(
260
+ (sheetId) => serializeSheetSnapshot(sheetId, snapshot.sheets?.[sheetId], snapshot.styles, precisionAsDisplayed)
261
+ ).filter((sheet) => sheet != null);
262
+ return {
263
+ unitId: input.unitId || snapshot.id,
264
+ name: snapshot.name,
265
+ sheets,
266
+ ...calculation ? { calculation } : {},
267
+ resources: serializeResources(snapshot),
268
+ definedNames: serializeDefinedNames(input.definedNames, snapshot),
269
+ externalLinks: serializeExternalLinks(snapshot),
270
+ tables: serializeTables(snapshot)
271
+ };
272
+ }
273
+ function rustExecutionOutputToFormulaCalculationPatch(output) {
274
+ let arrayFormulaOutput = output;
275
+ return {
276
+ unitData: output.resultBatches?.length ? resultBatchesToUnitData(output.resultBatches) : runtimeDataToUnitData(output.runtimeData),
277
+ unitOtherData: otherFormulaDataToUnitOtherData(output.otherFormulaData),
278
+ ...arrayFormulaOutput.arrayFormulaRange ? { arrayFormulaRange: arrayFormulaOutput.arrayFormulaRange } : {},
279
+ ...arrayFormulaOutput.arrayFormulaCellData ? { arrayFormulaCellData: arrayFormulaOutput.arrayFormulaCellData } : {},
280
+ errors: output.errors?.map((error) => ({
281
+ code: "RUST_FORMULA_CALCULATION_ERROR",
282
+ unitId: error.unitId,
283
+ sheetId: error.sheetId,
284
+ row: error.row,
285
+ column: error.column,
286
+ message: error.message
287
+ }))
288
+ };
289
+ }
290
+ function otherFormulaDataToUnitOtherData(otherFormulaData) {
291
+ let unitOtherData = {};
292
+ return Object.entries(otherFormulaData ?? {}).forEach(([unitId, sheetMap]) => {
293
+ if (!sheetMap) return;
294
+ let unitSheetData = {};
295
+ unitOtherData[unitId] = unitSheetData, Object.entries(sheetMap).forEach(([sheetId, formulaMap]) => {
296
+ if (!formulaMap) return;
297
+ let sheetData = {};
298
+ unitSheetData[sheetId] = sheetData, Object.entries(formulaMap).forEach(([formulaId, rowMap]) => {
299
+ if (!rowMap) return;
300
+ let formulaData = {};
301
+ sheetData[formulaId] = formulaData, Object.entries(rowMap).forEach(([rowKey, colMap]) => {
302
+ if (!colMap) return;
303
+ let row = Number(rowKey), rowData = {};
304
+ formulaData[row] = rowData, Object.entries(colMap).forEach(([colKey, value]) => {
305
+ rowData[Number(colKey)] = [[cellDataFromRustValue(value)]];
306
+ });
307
+ });
308
+ });
309
+ });
310
+ }), unitOtherData;
311
+ }
312
+ function createFormulaProjectionDesyncSignal(reason, error, mutationId) {
313
+ return {
314
+ reason,
315
+ mutationId,
316
+ message: error instanceof Error ? error.message : String(error)
317
+ };
318
+ }
319
+ var RustFormulaProjectionService = class {
320
+ _nativeLoaded = !1;
321
+ async load(workbooks) {
322
+ await this._ensureNativeLoaded();
323
+ try {
324
+ return {
325
+ stats: JSON.parse(loadSnapshotOnRust(JSON.stringify(serializeRuntimeWorkbookSnapshots(workbooks))))
326
+ };
327
+ } catch (error) {
328
+ return {
329
+ desync: createFormulaProjectionDesyncSignal("snapshot-load-failed", error),
330
+ errors: [errorToFormulaCalculationError("RUST_FORMULA_LOAD_ERROR", error)]
331
+ };
332
+ }
333
+ }
334
+ async applyMutation(mutation) {
335
+ await this._ensureNativeLoaded();
336
+ try {
337
+ return {
338
+ stats: JSON.parse(applyMutationOnRust(JSON.stringify(normalizeRustEngineMutation(mutation)))),
339
+ dependencyInvalidated: !isRustIncrementalDependencyMutation(mutation.id)
340
+ };
341
+ } catch (error) {
342
+ return {
343
+ dependencyInvalidated: !0,
344
+ desync: createFormulaProjectionDesyncSignal("mutation-apply-failed", error, mutation.id),
345
+ errors: [errorToFormulaCalculationError("RUST_FORMULA_MUTATION_ERROR", error)]
346
+ };
347
+ }
348
+ }
349
+ async syncFormulaDependencies(input) {
350
+ return await this._ensureNativeLoaded(), JSON.parse(syncRustFormulaDependenciesOnRust(JSON.stringify(input)));
351
+ }
352
+ async markDirty(input) {
353
+ return await this._ensureNativeLoaded(), JSON.parse(markRustFormulaDirtyOnRust(JSON.stringify(input)));
354
+ }
355
+ async calculateDirty(maxIteration = 1) {
356
+ await this._ensureNativeLoaded();
357
+ try {
358
+ let output = JSON.parse(
359
+ executeDirtyFormulasOnRust(maxIteration, !1, !1, !0)
360
+ );
361
+ return rustExecutionOutputToFormulaCalculationPatch(output);
362
+ } catch (error) {
363
+ return {
364
+ unitData: {},
365
+ unitOtherData: {},
366
+ desync: createFormulaProjectionDesyncSignal("dirty-calculation-failed", error),
367
+ errors: [errorToFormulaCalculationError("RUST_FORMULA_CALCULATION_ERROR", error)]
368
+ };
369
+ }
370
+ }
371
+ async reset() {
372
+ await this._ensureNativeLoaded();
373
+ try {
374
+ return clearRustFormulaDirtyOnRust(), clearRustFormulaDependenciesOnRust(
375
+ JSON.stringify({
376
+ unitId: "",
377
+ clearSheetFormulas: !0,
378
+ clearFeatureFormulas: !0,
379
+ clearOtherFormulas: !0
380
+ })
381
+ ), {
382
+ stats: JSON.parse(loadSnapshotOnRust(JSON.stringify({ workbooks: [] })))
383
+ };
384
+ } catch (error) {
385
+ return {
386
+ desync: createFormulaProjectionDesyncSignal("projection-reset-failed", error),
387
+ errors: [errorToFormulaCalculationError("RUST_FORMULA_RESET_ERROR", error)]
388
+ };
389
+ }
390
+ }
391
+ async disposeWorkbook(unitId) {
392
+ await this._ensureNativeLoaded();
393
+ try {
394
+ return { stats: JSON.parse(disposeWorkbookOnRust(unitId)) };
395
+ } catch (error) {
396
+ return {
397
+ desync: createFormulaProjectionDesyncSignal("workbook-dispose-failed", error),
398
+ errors: [errorToFormulaCalculationError("RUST_FORMULA_DISPOSE_ERROR", error)]
399
+ };
400
+ }
401
+ }
402
+ async _ensureNativeLoaded() {
403
+ this._nativeLoaded || (await loadNativeBinding(), this._nativeLoaded = !0);
404
+ }
405
+ };
406
+ function normalizeRustEngineMutation(mutation) {
407
+ return {
408
+ id: mutation.id,
409
+ params: mutation.params ?? {},
410
+ dirtyRanges: Array.isArray(mutation.dirtyRanges) ? mutation.dirtyRanges : []
411
+ };
412
+ }
413
+ function resultBatchesToUnitData(resultBatches) {
414
+ let unitData = {};
415
+ for (let batch of resultBatches) {
416
+ let unitSheetData = unitData[batch.unitId] ?? {};
417
+ unitData[batch.unitId] = unitSheetData;
418
+ let sheetData = unitSheetData[batch.sheetId] ?? {};
419
+ unitSheetData[batch.sheetId] = sheetData;
420
+ for (let index = 0; index < batch.values.length; index++) {
421
+ let row = batch.rows[index], col = batch.cols[index], value = batch.values[index], rowData = sheetData[row] ?? {};
422
+ sheetData[row] = rowData, rowData[col] = cellDataFromRustValue(value);
423
+ }
424
+ }
425
+ return unitData;
426
+ }
427
+ function runtimeDataToUnitData(runtimeData) {
428
+ let unitData = {};
429
+ return Object.entries(runtimeData ?? {}).forEach(([unitId, sheetMap]) => {
430
+ if (!sheetMap) return;
431
+ let unitSheetData = {};
432
+ unitData[unitId] = unitSheetData, Object.entries(sheetMap).forEach(([sheetId, rowMap]) => {
433
+ if (!rowMap) return;
434
+ let sheetData = {};
435
+ unitSheetData[sheetId] = sheetData, Object.entries(rowMap).forEach(([rowKey, colMap]) => {
436
+ if (!colMap) return;
437
+ let row = Number(rowKey), rowData = {};
438
+ sheetData[row] = rowData, Object.entries(colMap).forEach(([colKey, value]) => {
439
+ rowData[Number(colKey)] = cellDataFromRustValue(value);
440
+ });
441
+ });
442
+ });
443
+ }), unitData;
444
+ }
445
+ function cellDataFromRustValue(value) {
446
+ if (value == null)
447
+ return null;
448
+ if (typeof value == "number")
449
+ return { t: CellValueType.NUMBER, v: value };
450
+ if (typeof value == "boolean")
451
+ return { t: CellValueType.BOOLEAN, v: value };
452
+ if (typeof value == "string")
453
+ return { t: CellValueType.STRING, v: value };
454
+ if (isRecord(value)) {
455
+ let cell = sanitizeCoreCellData(value);
456
+ if (Object.keys(cell).length > 0)
457
+ return cell;
458
+ }
459
+ return { v: value };
460
+ }
461
+ function sanitizeCoreCellData(value) {
462
+ let cell = {};
463
+ for (let key of ["v", "t", "p", "s", "f", "si", "ref", "xf", "custom"])
464
+ key in value && (cell[key] = value[key]);
465
+ return cell;
466
+ }
467
+ function serializeResources(snapshot) {
468
+ let resources = snapshot.resources;
469
+ if (!resources || typeof resources != "object")
470
+ return;
471
+ let serialized = {};
472
+ for (let [id, resource] of Object.entries(resources))
473
+ typeof resource?.name == "string" && (serialized[id] = {
474
+ name: resource.name,
475
+ data: resource.data
476
+ });
477
+ return Object.keys(serialized).length > 0 ? serialized : void 0;
478
+ }
479
+ function serializeCalculation(snapshot) {
480
+ for (let resource of Object.values(
481
+ snapshot.resources ?? {}
482
+ )) {
483
+ if (resource?.name !== XLSX_WORKBOOK_CALCULATION_RESOURCE)
484
+ continue;
485
+ let data = parseResourceData(resource.data);
486
+ if (!data || typeof data != "object")
487
+ return;
488
+ let fullPrecision = data.fullPrecision;
489
+ return typeof fullPrecision == "boolean" ? { fullPrecision } : void 0;
490
+ }
491
+ }
492
+ function serializeTables(snapshot) {
493
+ for (let resource of Object.values(
494
+ snapshot.resources ?? {}
495
+ )) {
496
+ if (resource?.name !== "SHEET_TABLE_PLUGIN")
497
+ continue;
498
+ let data = parseResourceData(resource.data);
499
+ if (!data || typeof data != "object")
500
+ return;
501
+ let tables = {};
502
+ for (let [sheetId, sheetTables] of Object.entries(data)) {
503
+ let tableList = sheetTables?.tables;
504
+ if (Array.isArray(tableList))
505
+ for (let table of tableList) {
506
+ let serialized = serializeTableSnapshot(sheetId, table, snapshot);
507
+ serialized && (tables[serialized.name] = serialized.table);
508
+ }
509
+ }
510
+ return Object.keys(tables).length > 0 ? tables : void 0;
511
+ }
512
+ }
513
+ function serializeTableSnapshot(sheetId, table, snapshot) {
514
+ if (!table || typeof table != "object")
515
+ return null;
516
+ let record = table, name2 = typeof record.name == "string" ? record.name : void 0, range = record.range;
517
+ if (!name2 || !range || typeof range.startRow != "number" || typeof range.endRow != "number" || typeof range.startColumn != "number" || typeof range.endColumn != "number")
518
+ return null;
519
+ let columns = Array.isArray(record.columns) ? record.columns.map((column) => {
520
+ let displayName = column?.displayName;
521
+ return typeof displayName == "string" ? { displayName } : null;
522
+ }).filter((column) => column != null) : [], showHeader = record.options?.showHeader !== !1, showFooter = typeof record.options?.showFooter == "boolean" ? record.options.showFooter : inferTableFooter(snapshot, sheetId, range.startRow, range.endRow, range.startColumn, range.endColumn);
523
+ return {
524
+ name: name2,
525
+ table: {
526
+ sheetId,
527
+ range: {
528
+ startRow: range.startRow,
529
+ endRow: range.endRow,
530
+ startColumn: range.startColumn,
531
+ endColumn: range.endColumn
532
+ },
533
+ columns,
534
+ showHeader,
535
+ showFooter
536
+ }
537
+ };
538
+ }
539
+ function parseResourceData(data) {
540
+ if (typeof data != "string")
541
+ return data;
542
+ try {
543
+ return JSON.parse(data || "{}");
544
+ } catch {
545
+ return;
546
+ }
547
+ }
548
+ function inferTableFooter(snapshot, sheetId, startRow, endRow, startColumn, endColumn) {
549
+ let row = snapshot.sheets?.[sheetId]?.cellData?.[endRow];
550
+ if (!row)
551
+ return !1;
552
+ for (let col = startColumn; col <= endColumn; col++) {
553
+ let cell = row[col];
554
+ if (cell && (typeof cell.f == "string" && /\bSUBTOTAL\s*\(/iu.test(cell.f) || col === startColumn && typeof cell.v == "string" && cell.v.trim().toLowerCase() === "total"))
555
+ return !0;
556
+ }
557
+ return !1;
558
+ }
559
+ function serializeExternalLinks(snapshot) {
560
+ let externalLinks = snapshot.externalLinks, serializedLinks = Array.isArray(externalLinks) ? externalLinks.map((link) => serializeExternalLink(link)).filter((link) => link != null) : [];
561
+ return serializedLinks.push(...serializeExternalLinksFromResource(snapshot)), serializedLinks.length > 0 ? serializedLinks : void 0;
562
+ }
563
+ function serializeExternalLinksFromResource(snapshot) {
564
+ let links = [];
565
+ for (let resource of Object.values(
566
+ snapshot.resources ?? {}
567
+ )) {
568
+ if (resource?.name !== EXTERNAL_DATA_RESOURCE)
569
+ continue;
570
+ let data = parseResourceData(resource.data);
571
+ if (isRecord(data)) {
572
+ if (data.schemaVersion === 1 && Array.isArray(data.links)) {
573
+ links.push(
574
+ ...data.links.map((link) => serializeVersionedExternalLink(link)).filter((link) => link != null)
575
+ );
576
+ continue;
577
+ }
578
+ if (!(data.signature !== EXTERNAL_DATA_SIGNATURE || !isRecord(data.units)))
579
+ for (let [unitId, unit] of Object.entries(data.units)) {
580
+ let link = serializeExternalDataUnit(unitId, unit);
581
+ link && links.push(link);
582
+ }
583
+ }
584
+ }
585
+ return links;
586
+ }
587
+ function serializeVersionedExternalLink(link) {
588
+ if (!isRecord(link) || !Number.isInteger(link.slot) || Number(link.slot) <= 0 || !isRecord(link.target))
589
+ return null;
590
+ let target = link.target, cache = isRecord(link.cache) ? link.cache : void 0, cachedSheets = Array.isArray(cache?.sheets) ? cache.sheets.map((sheet) => serializeVersionedExternalSheet(sheet)).filter((sheet) => sheet != null) : [], cachedNames = new Set(cachedSheets.map((sheet) => sheet.name.toLocaleLowerCase())), uncachedSheets = Array.isArray(link.sheetNames) ? link.sheetNames.flatMap((item) => {
591
+ if (!isRecord(item)) return [];
592
+ let { name: name2 } = item;
593
+ return typeof name2 != "string" || cachedNames.has(name2.toLocaleLowerCase()) ? [] : [
594
+ {
595
+ name: name2,
596
+ rowCount: 1048576,
597
+ columnCount: 16384,
598
+ cellData: {},
599
+ coverage: []
600
+ }
601
+ ];
602
+ }) : [], sheets = [...cachedSheets, ...uncachedSheets], definedNames = serializeVersionedExternalDefinedNames(link.definedNames), tables = serializeVersionedExternalTables(link.tables), aliases = [link.name, target.name, target.uri].filter(
603
+ (alias) => typeof alias == "string" && alias.length > 0
604
+ );
605
+ return {
606
+ ...aliases.length > 0 ? { aliases: [...new Set(aliases)] } : {},
607
+ ...definedNames ? { definedNames } : {},
608
+ sheets,
609
+ ...tables ? { tables } : {},
610
+ ...typeof target.uri == "string" ? { target: target.uri } : typeof target.name == "string" ? { target: target.name } : typeof link.name == "string" ? { target: link.name } : {},
611
+ unitId: String(link.slot)
612
+ };
613
+ }
614
+ function serializeVersionedExternalDefinedNames(value) {
615
+ if (!Array.isArray(value))
616
+ return;
617
+ let result = {};
618
+ for (let item of value)
619
+ !isRecord(item) || typeof item.name != "string" || (result[item.name] = {
620
+ name: item.name,
621
+ ...typeof item.formulaOrRefString == "string" ? { formulaOrRefString: item.formulaOrRefString } : {}
622
+ });
623
+ return Object.keys(result).length > 0 ? result : void 0;
624
+ }
625
+ function serializeVersionedExternalTables(value) {
626
+ if (!Array.isArray(value))
627
+ return;
628
+ let result = {};
629
+ for (let item of value) {
630
+ if (!isRecord(item) || typeof item.name != "string" || typeof item.sheetName != "string" || !isRange(item.range)) continue;
631
+ let columns = Array.isArray(item.columns) ? item.columns.flatMap((column) => {
632
+ if (!isRecord(column)) return [];
633
+ let { name: name2 } = column;
634
+ return typeof name2 == "string" ? [{ displayName: name2 }] : [];
635
+ }) : [];
636
+ result[item.name] = {
637
+ sheetId: item.sheetName,
638
+ range: item.range,
639
+ columns,
640
+ showHeader: item.showHeader !== !1
641
+ };
642
+ }
643
+ return Object.keys(result).length > 0 ? result : void 0;
644
+ }
645
+ function serializeVersionedExternalSheet(sheet) {
646
+ if (!isRecord(sheet) || typeof sheet.name != "string") return null;
647
+ let cellData = {};
648
+ if (Array.isArray(sheet.cells))
649
+ for (let cell of sheet.cells) {
650
+ if (!isExternalCell(cell)) continue;
651
+ let { row, column } = cell;
652
+ (cellData[row] ??= {})[column] = {
653
+ v: cell.value,
654
+ ...typeof cell.valueType == "number" ? { t: cell.valueType } : {}
655
+ };
656
+ }
657
+ return {
658
+ name: sheet.name,
659
+ ...typeof sheet.sheetId == "string" ? { sheetId: sheet.sheetId } : {},
660
+ rowCount: typeof sheet.rowCount == "number" ? sheet.rowCount : 0,
661
+ columnCount: typeof sheet.columnCount == "number" ? sheet.columnCount : 0,
662
+ cellData,
663
+ coverage: Array.isArray(sheet.coverage) ? sheet.coverage.filter(isRange) : []
664
+ };
665
+ }
666
+ function isRange(value) {
667
+ return value != null && typeof value == "object" && "startRow" in value && typeof value.startRow == "number" && "endRow" in value && typeof value.endRow == "number" && "startColumn" in value && typeof value.startColumn == "number" && "endColumn" in value && typeof value.endColumn == "number";
668
+ }
669
+ function isRustTableSnapshot(value) {
670
+ return value != null && typeof value == "object" && "sheetId" in value && typeof value.sheetId == "string" && "range" in value && isRange(value.range) && "columns" in value && Array.isArray(value.columns);
671
+ }
672
+ function isExternalCell(value) {
673
+ return isRecord(value) && Number.isInteger(value.row) && Number.isInteger(value.column);
674
+ }
675
+ function serializeExternalDataUnit(unitId, unit) {
676
+ if (!unit || typeof unit != "object")
677
+ return null;
678
+ let record = unit;
679
+ if (!record.sheets || typeof record.sheets != "object")
680
+ return null;
681
+ let sheets = Object.values(record.sheets).map((sheet) => serializeExternalSheet(sheet)).filter((sheet) => sheet != null);
682
+ if (sheets.length === 0)
683
+ return null;
684
+ let definedNames = serializeExternalDefinedNames(record.definedNames);
685
+ return {
686
+ ...definedNames === void 0 ? {} : { definedNames },
687
+ sheets,
688
+ ...typeof record.target == "string" ? { target: record.target } : {},
689
+ unitId
690
+ };
691
+ }
692
+ function serializeExternalLink(link) {
693
+ if (!isRecord(link))
694
+ return null;
695
+ let record = link;
696
+ if (!Array.isArray(record.sheets))
697
+ return null;
698
+ let sheets = record.sheets.map((sheet) => serializeExternalSheet(sheet)).filter((sheet) => sheet != null);
699
+ if (sheets.length === 0)
700
+ return null;
701
+ let definedNames = serializeExternalDefinedNames(record.definedNames), tables = serializeExternalTables(record.tables);
702
+ return {
703
+ ...definedNames === void 0 ? {} : { definedNames },
704
+ sheets,
705
+ ...tables === void 0 ? {} : { tables },
706
+ ...typeof record.target == "string" ? { target: record.target } : {},
707
+ ...typeof record.unitId == "string" ? { unitId: record.unitId } : {}
708
+ };
709
+ }
710
+ function serializeExternalTables(value) {
711
+ if (!isRecord(value)) return;
712
+ let result = {};
713
+ for (let [name2, table] of Object.entries(value))
714
+ !table || typeof table != "object" || isRustTableSnapshot(table) && (result[name2] = table);
715
+ return Object.keys(result).length > 0 ? result : void 0;
716
+ }
717
+ function serializeExternalDefinedNames(value) {
718
+ if (!isRecord(value))
719
+ return;
720
+ let definedNames = {};
721
+ for (let [key, item] of Object.entries(value)) {
722
+ if (!isRecord(item))
723
+ continue;
724
+ let record = item, name2 = typeof record.name == "string" ? record.name : key;
725
+ definedNames[key] = {
726
+ ...typeof record.id == "string" ? { id: record.id } : {},
727
+ name: name2,
728
+ ...typeof record.formulaOrRefString == "string" ? { formulaOrRefString: record.formulaOrRefString } : {},
729
+ ...typeof record.localSheetId == "string" ? { localSheetId: record.localSheetId } : {}
730
+ };
731
+ }
732
+ return Object.keys(definedNames).length > 0 ? definedNames : void 0;
733
+ }
734
+ function serializeExternalSheet(sheet) {
735
+ if (!sheet || typeof sheet != "object")
736
+ return null;
737
+ let record = sheet;
738
+ return typeof record.name != "string" ? null : {
739
+ name: record.name,
740
+ ...typeof record.sheetId == "string" ? { sheetId: record.sheetId } : {},
741
+ rowCount: typeof record.rowCount == "number" ? record.rowCount : 0,
742
+ columnCount: typeof record.columnCount == "number" ? record.columnCount : 0,
743
+ cellData: serializeCellData(record.cellData)
744
+ };
745
+ }
746
+ function serializeDefinedNames(definedNames, snapshot) {
747
+ let direct = definedNames && Object.keys(definedNames).length > 0 ? definedNames : extractDefinedNames(snapshot), sheetIds = new Set(Object.keys(snapshot.sheets ?? {})), sheetNameToId = new Map(
748
+ Object.entries(snapshot.sheets ?? {}).map(([sheetId, sheet]) => [sheet.name, sheetId])
749
+ );
750
+ return Object.fromEntries(
751
+ Object.entries(direct).map(([id, definedName]) => [
752
+ id,
753
+ {
754
+ id: definedName.id,
755
+ name: definedName.name,
756
+ formulaOrRefString: definedName.formulaOrRefString,
757
+ localSheetId: normalizeDefinedNameLocalSheetId(
758
+ definedName.localSheetId,
759
+ definedName.formulaOrRefString,
760
+ sheetIds,
761
+ sheetNameToId
762
+ )
763
+ }
764
+ ])
765
+ );
766
+ }
767
+ function normalizeDefinedNameLocalSheetId(localSheetId, formulaOrRefString, sheetIds, sheetNameToId) {
768
+ if (!localSheetId || localSheetId === "AllDefaultWorkbook")
769
+ return localSheetId;
770
+ let sheetName = extractLeadingSheetName(formulaOrRefString), sheetIdFromFormula = sheetName ? sheetNameToId.get(sheetName) : void 0;
771
+ return sheetIdFromFormula && sheetIdFromFormula !== localSheetId ? sheetIdFromFormula : sheetIds.has(localSheetId) || !sheetName ? localSheetId : sheetIdFromFormula ?? localSheetId;
772
+ }
773
+ function extractLeadingSheetName(formulaOrRefString) {
774
+ if (!formulaOrRefString)
775
+ return;
776
+ let quotedMatch = /^'((?:[^']|'')+)'!/.exec(formulaOrRefString);
777
+ return quotedMatch ? quotedMatch[1].replace(/''/g, "'") : /^([^=!]+)!/.exec(formulaOrRefString)?.[1];
778
+ }
779
+ function extractDefinedNames(snapshot) {
780
+ let direct = snapshot.definedNames;
781
+ if (direct && Object.keys(direct).length > 0)
782
+ return direct;
783
+ for (let resource of Object.values(
784
+ snapshot.resources ?? {}
785
+ )) {
786
+ if (resource?.name !== "SHEET_DEFINED_NAME_PLUGIN")
787
+ continue;
788
+ let data = parseResourceData(resource.data);
789
+ return data && typeof data == "object" ? data : {};
790
+ }
791
+ return {};
792
+ }
793
+ function serializeSheetSnapshot(sheetId, sheet, styles, precisionAsDisplayed) {
794
+ return sheet ? {
795
+ sheetId: sheet.id ?? sheetId,
796
+ name: sheet.name,
797
+ rowCount: sheet.rowCount ?? 0,
798
+ columnCount: sheet.columnCount ?? 0,
799
+ transitionEvaluation: sheet.transitionEvaluation === !0,
800
+ cellData: serializeCellData(sheet.cellData, styles, precisionAsDisplayed),
801
+ rowData: serializeVisibilityData(sheet.rowData),
802
+ columnData: serializeVisibilityData(sheet.columnData)
803
+ } : null;
804
+ }
805
+ function serializeCellData(cellData = {}, styles, precisionAsDisplayed = !1) {
806
+ let result = {}, rawCellData = cellData instanceof ObjectMatrix ? cellData.getData() : cellData;
807
+ for (let [rowKey, row] of Object.entries(rawCellData ?? {})) {
808
+ if (!row)
809
+ continue;
810
+ let serializedRow = {};
811
+ for (let [colKey, cell] of Object.entries(row)) {
812
+ if (!cell || typeof cell != "object")
813
+ continue;
814
+ let cellRecord = cell, value = {};
815
+ if ("v" in cellRecord && (value.v = cellRecord.v), typeof cellRecord.t == "number" && (value.t = cellRecord.t), "p" in cellRecord && (value.p = cellRecord.p), typeof cellRecord.f == "string" && (value.f = cellRecord.f), typeof cellRecord.si == "string" && (value.si = cellRecord.si), typeof cellRecord.ref == "string" && (value.ref = cellRecord.ref), typeof cellRecord.xf == "string" && (value.xf = cellRecord.xf), "s" in cellRecord && (value.s = cellRecord.s), precisionAsDisplayed && typeof cellRecord.f == "string") {
816
+ let displayPrecision = inferDisplayPrecision(cellRecord.s, styles);
817
+ displayPrecision !== void 0 && (value.displayPrecision = displayPrecision);
818
+ }
819
+ Object.keys(value).length > 0 && (serializedRow[Number(colKey)] = value);
820
+ }
821
+ Object.keys(serializedRow).length > 0 && (result[Number(rowKey)] = serializedRow);
822
+ }
823
+ return result;
824
+ }
825
+ function serializeCellDataInRanges(cellData, ranges) {
826
+ let serialized = serializeCellData(cellData), result = {};
827
+ for (let [rowKey, row] of Object.entries(serialized)) {
828
+ let rowIndex = Number(rowKey);
829
+ for (let [columnKey, value] of Object.entries(row)) {
830
+ let columnIndex = Number(columnKey);
831
+ ranges.some(
832
+ (range) => rowIndex >= range.startRow && rowIndex <= range.endRow && columnIndex >= range.startColumn && columnIndex <= range.endColumn
833
+ ) && ((result[rowIndex] ??= {})[columnIndex] = value);
834
+ }
835
+ }
836
+ return result;
837
+ }
838
+ function inferDisplayPrecision(styleId, styles) {
839
+ if (typeof styleId != "string" || !styles || typeof styles != "object")
840
+ return;
841
+ let style = styles[styleId];
842
+ if (!style || typeof style != "object")
843
+ return;
844
+ let numberFormat = style.n;
845
+ if (!numberFormat || typeof numberFormat != "object")
846
+ return;
847
+ let pattern = numberFormat.pattern;
848
+ return typeof pattern == "string" ? inferFixedNumberFormatPrecision(pattern) : void 0;
849
+ }
850
+ function inferFixedNumberFormatPrecision(pattern) {
851
+ let cleaned = (pattern.split(";")[0] ?? pattern).replace(/"[^"]*"/gu, "").replace(/\\./gu, "").replace(/_.|\*./gu, "");
852
+ if (!/[0#?]/u.test(cleaned) || /[%Ee]|[ymdhsa]/iu.test(cleaned))
853
+ return;
854
+ let decimalMatch = cleaned.match(/\.([0#?]+)/u);
855
+ return decimalMatch?.[1] ? decimalMatch[1].length : 0;
856
+ }
857
+ function serializeVisibilityData(data = {}) {
858
+ let result = {};
859
+ for (let [indexKey, metadata] of Object.entries(data))
860
+ !metadata || typeof metadata != "object" || !("hd" in metadata) || (result[Number(indexKey)] = {
861
+ hd: metadata.hd
862
+ });
863
+ return result;
864
+ }
865
+ function errorToFormulaCalculationError(code, error) {
866
+ return {
867
+ code,
868
+ message: error instanceof Error ? error.message : String(error)
869
+ };
870
+ }
871
+ function isRecord(value) {
872
+ return typeof value == "object" && value !== null && !Array.isArray(value);
873
+ }
874
+
875
+ // src/controllers/rust-engine-sync.controller.ts
876
+ var rustEngineSyncState = {
877
+ snapshotEpoch: 0,
878
+ dependencyInvalidationEpoch: 0
879
+ };
880
+ function getRustEngineSyncState() {
881
+ return { ...rustEngineSyncState };
882
+ }
883
+ function markRustSnapshotLoaded() {
884
+ rustEngineSyncState.snapshotEpoch += 1, rustEngineSyncState.dependencyInvalidationEpoch += 1;
885
+ }
886
+ function markRustFormulaDependenciesInvalidated() {
887
+ rustEngineSyncState.dependencyInvalidationEpoch += 1;
888
+ }
889
+ function emitRustEngineSyncDebugEvent(event) {
890
+ let hook = globalThis.__UNIVER_RUST_FORMULA_DEBUG_HOOK__;
891
+ typeof hook == "function" && hook(event);
892
+ }
893
+ function summarizeObjectMatrixPayload(value) {
894
+ if (!value || typeof value != "object")
895
+ return {};
896
+ let cellValueCells = 0;
897
+ for (let row of Object.values(value))
898
+ !row || typeof row != "object" || (cellValueCells += Object.keys(row).length);
899
+ return {
900
+ cellValueRows: Object.keys(value).length,
901
+ cellValueCells
902
+ };
903
+ }
904
+ function hasObjectMatrixValues(value) {
905
+ return !value || typeof value != "object" ? !1 : Object.values(value).some(
906
+ (row) => row != null && typeof row == "object" && Object.keys(row).length > 0
907
+ );
908
+ }
909
+ function hasRecordEntries(value) {
910
+ return value != null && typeof value == "object" && Object.keys(value).length > 0;
911
+ }
912
+ function countDisplayPrecisionCells(snapshot) {
913
+ let count = 0;
914
+ for (let workbook of snapshot.workbooks)
915
+ for (let sheet of workbook.sheets)
916
+ for (let row of Object.values(sheet.cellData))
917
+ for (let cell of Object.values(row))
918
+ typeof cell.displayPrecision == "number" && (count += 1);
919
+ return count;
920
+ }
921
+ var RustEngineSyncController = class extends Disposable {
922
+ constructor(_commandService) {
923
+ super();
924
+ this._commandService = _commandService;
925
+ this._initialize();
926
+ }
927
+ _commandService;
928
+ _nativeReady = !1;
929
+ _snapshotLoaded = !1;
930
+ _projectionLoadPromise = null;
931
+ _pendingMutations = [];
932
+ _initialize() {
933
+ this.disposeWithMe(
934
+ this._commandService.onCommandExecuted((command, options) => {
935
+ this._shouldSyncMutation(command, options) && this._queueOrSyncMutation(this._serializeMutation(command, options));
936
+ })
937
+ );
938
+ }
939
+ async loadProjection(workbooks) {
940
+ let loadPromise = this._loadProjection(workbooks);
941
+ this._projectionLoadPromise = loadPromise;
942
+ try {
943
+ await loadPromise;
944
+ } finally {
945
+ this._projectionLoadPromise === loadPromise && (this._projectionLoadPromise = null);
946
+ }
947
+ }
948
+ async waitForProjectionLoad() {
949
+ await this._projectionLoadPromise;
950
+ }
951
+ async _loadProjection(workbooks) {
952
+ await loadNativeBinding(), this._nativeReady = !0;
953
+ let serializeStartedAt = performance.now(), snapshot = serializeRuntimeWorkbookSnapshots(workbooks);
954
+ this._loadSerializedSnapshot(snapshot, performance.now() - serializeStartedAt);
955
+ }
956
+ applyProjectionMutation(mutation) {
957
+ this._queueOrSyncMutation(mutation);
958
+ }
959
+ upsertReferenceData(config, needs) {
960
+ let mutations = createReferenceDataUpsertMutations(config, needs);
961
+ return mutations.forEach((mutation) => this._queueOrSyncMutation(mutation)), mutations.length;
962
+ }
963
+ disposeProjectionWorkbook(unitId) {
964
+ if (!(!this._nativeReady || !this._snapshotLoaded))
965
+ try {
966
+ disposeWorkbookOnRust(unitId), markRustFormulaDependenciesInvalidated();
967
+ } catch {
968
+ this._markProjectionDesynced();
969
+ }
970
+ }
971
+ dispose() {
972
+ if (super.dispose(), this._pendingMutations.length = 0, this._projectionLoadPromise = null, !this._nativeReady) {
973
+ this._snapshotLoaded = !1;
974
+ return;
975
+ }
976
+ try {
977
+ disposeAllWorkbooksOnRust();
978
+ } catch {
979
+ this._markProjectionDesynced();
980
+ return;
981
+ }
982
+ this._nativeReady = !1, this._snapshotLoaded = !1;
983
+ }
984
+ _loadSerializedSnapshot(snapshot, serializeMs) {
985
+ let precisionAsDisplayedWorkbookCount = snapshot.workbooks.filter(
986
+ (workbook) => workbook.calculation?.fullPrecision === !1
987
+ ).length, displayPrecisionCellCount = countDisplayPrecisionCells(snapshot), pendingCountCoveredBySnapshot = this._pendingMutations.length, stringifyStartedAt = performance.now(), snapshotJson = JSON.stringify(snapshot), stringifyMs = performance.now() - stringifyStartedAt, snapshotBuffer = globalThis.Buffer?.from(snapshotJson), nativeStartedAt = performance.now(), nativeOutput = snapshotBuffer ? loadSnapshotBinaryOnRust(snapshotBuffer) : loadSnapshotOnRust(snapshotJson), nativeMs = performance.now() - nativeStartedAt, nativeTimings;
988
+ try {
989
+ nativeTimings = JSON.parse(nativeOutput).timingsMs;
990
+ } catch {
991
+ nativeTimings = void 0;
992
+ }
993
+ emitRustEngineSyncDebugEvent({
994
+ type: "loadSnapshot",
995
+ payload: {
996
+ workbookCount: snapshot.workbooks.length,
997
+ serializeMs,
998
+ stringifyMs,
999
+ nativeMs,
1000
+ precisionAsDisplayedWorkbookCount,
1001
+ displayPrecisionCellCount,
1002
+ snapshotBytes: snapshotBuffer?.byteLength ?? snapshotJson.length,
1003
+ transport: snapshotBuffer ? "binary-json" : "string-json",
1004
+ nativeTimings
1005
+ }
1006
+ }), this._pendingMutations.splice(0, pendingCountCoveredBySnapshot), this._snapshotLoaded = !0, markRustSnapshotLoaded(), this._flushPendingMutations();
1007
+ }
1008
+ _queueOrSyncMutation(mutation) {
1009
+ if (!this._nativeReady || !this._snapshotLoaded) {
1010
+ this._pendingMutations.push(mutation);
1011
+ return;
1012
+ }
1013
+ this._syncMutation(mutation);
1014
+ }
1015
+ _flushPendingMutations() {
1016
+ for (; this._pendingMutations.length > 0; ) {
1017
+ let mutation = this._pendingMutations.shift();
1018
+ mutation && this._syncMutation(mutation);
1019
+ }
1020
+ }
1021
+ _syncMutation(mutation) {
1022
+ let totalStartedAt = performance.now(), stringifyStartedAt = performance.now(), payload = JSON.stringify(mutation), stringifyMs = performance.now() - stringifyStartedAt, nativeStartedAt = performance.now();
1023
+ try {
1024
+ applyMutationOnRust(payload), isRustIncrementalDependencyMutation(mutation.id) || markRustFormulaDependenciesInvalidated();
1025
+ } catch {
1026
+ this._markProjectionDesynced();
1027
+ } finally {
1028
+ emitRustEngineSyncDebugEvent({
1029
+ type: "applyMutation",
1030
+ payload: {
1031
+ id: mutation.id,
1032
+ stringifyMs,
1033
+ nativeMs: performance.now() - nativeStartedAt,
1034
+ totalMs: performance.now() - totalStartedAt,
1035
+ ...summarizeObjectMatrixPayload(
1036
+ mutation.params?.cellValue
1037
+ )
1038
+ }
1039
+ });
1040
+ }
1041
+ }
1042
+ _markProjectionDesynced() {
1043
+ this._nativeReady = !1, this._snapshotLoaded = !1;
1044
+ }
1045
+ _shouldSyncMutation(command, options) {
1046
+ if (command.type !== CommandType.MUTATION || !isRustFormulaRelevantMutation(command.id))
1047
+ return !1;
1048
+ let syncOptions = options;
1049
+ if (syncOptions?.fromRustFormulaEngine === !0 || syncOptions?.applyFormulaCalculationResult === !0 || command.id === "sheet.mutation.set-range-values" && !hasObjectMatrixValues(command.params?.cellValue))
1050
+ return !1;
1051
+ if (command.id === "formula.mutation.set-formula-calculation-result") {
1052
+ let params = command.params;
1053
+ if (!hasRecordEntries(params?.unitData) && !hasRecordEntries(params?.unitOtherData))
1054
+ return !1;
1055
+ }
1056
+ if (command.id === "formula.mutation.set-array-formula-data") {
1057
+ let params = command.params;
1058
+ if (!hasRecordEntries(params?.arrayFormulaRange) && !hasRecordEntries(params?.arrayFormulaCellData) && !hasRecordEntries(params?.arrayFormulaEmbedded))
1059
+ return !1;
1060
+ }
1061
+ return !0;
1062
+ }
1063
+ _serializeMutation(command, options) {
1064
+ let dirtyRanges = options?.dirtyRanges;
1065
+ return {
1066
+ id: command.id,
1067
+ params: command.params ?? {},
1068
+ dirtyRanges: Array.isArray(dirtyRanges) ? dirtyRanges : []
1069
+ };
1070
+ }
1071
+ };
1072
+ setDependencies(RustEngineSyncController, [ICommandService]);
1073
+
1074
+ // src/numfmt.ts
1075
+ var nativeBindingReady = null;
1076
+ function ensureNativeBinding() {
1077
+ return nativeBindingReady ??= loadNativeBinding().catch((error) => {
1078
+ throw nativeBindingReady = null, error;
1079
+ }), nativeBindingReady;
1080
+ }
1081
+ function parseJsonOutput(output) {
1082
+ return JSON.parse(output);
1083
+ }
1084
+ async function formatNumberBatch(input) {
1085
+ return await ensureNativeBinding(), parseJsonOutput(formatNumberBatchOnRust(JSON.stringify(input)));
1086
+ }
1087
+ async function parseNumberFormatBatch(input) {
1088
+ return await ensureNativeBinding(), parseJsonOutput(parseNumberFormatInputBatchOnRust(JSON.stringify(input)));
1089
+ }
1090
+ async function parseNumberFormatMatrixBatch(input) {
1091
+ return await ensureNativeBinding(), parseJsonOutput(
1092
+ parseNumberFormatMatrixBatchOnRust(JSON.stringify(input))
1093
+ );
1094
+ }
1095
+ async function analyzeNumberFormatBatch(input) {
1096
+ return await ensureNativeBinding(), parseJsonOutput(analyzeNumberFormatBatchOnRust(JSON.stringify(input)));
1097
+ }
1098
+
1099
+ // src/plugin.ts
1100
+ import { IConfigService as IConfigService2, Injector, setDependencies as setDependencies4, touchDependencies } from "@univerjs/core";
1101
+ import { ICalculateFormulaService } from "@univerjs/engine-formula";
1102
+ import { UniverProFormulaEnginePlugin } from "@univerjs-pro/engine-formula";
1103
+
1104
+ // package.json
1105
+ var name = "@univerjs-pro/engine-formula-rust", version = "1.0.0-insiders.20260725-1b9c8d8";
1106
+
1107
+ // src/controllers/rust-same-runtime-projection.controller.ts
1108
+ import {
1109
+ Disposable as Disposable2,
1110
+ CommandType as CommandType2,
1111
+ ICommandService as ICommandService2,
1112
+ IUniverInstanceService,
1113
+ LocaleType,
1114
+ setDependencies as setDependencies2,
1115
+ toDisposable,
1116
+ UniverInstanceType
1117
+ } from "@univerjs/core";
1118
+ import { FormulaDataModel, ISuperTableService, SetFormulaCalculationResultMutation } from "@univerjs/engine-formula";
1119
+ var RustSameRuntimeProjectionController = class extends Disposable2 {
1120
+ constructor(_univerInstanceService, _rustEngineSyncController, _formulaDataModel, _superTableService, _commandService) {
1121
+ super();
1122
+ this._univerInstanceService = _univerInstanceService;
1123
+ this._rustEngineSyncController = _rustEngineSyncController;
1124
+ this._formulaDataModel = _formulaDataModel;
1125
+ this._superTableService = _superTableService;
1126
+ this._commandService = _commandService;
1127
+ this._initialize();
1128
+ }
1129
+ _univerInstanceService;
1130
+ _rustEngineSyncController;
1131
+ _formulaDataModel;
1132
+ _superTableService;
1133
+ _commandService;
1134
+ _projectionReload = null;
1135
+ _projectionReloadRequested = !1;
1136
+ _initialize() {
1137
+ this._scheduleProjectionReload(), this.disposeWithMe(
1138
+ toDisposable(
1139
+ this._univerInstanceService.getTypeOfUnitAdded$(UniverInstanceType.UNIVER_SHEET).subscribe(() => {
1140
+ this._scheduleProjectionReload();
1141
+ })
1142
+ )
1143
+ ), this.disposeWithMe(
1144
+ toDisposable(
1145
+ this._univerInstanceService.getTypeOfUnitAdded$(UniverInstanceType.UNIVER_BASE).subscribe(() => {
1146
+ this._scheduleProjectionReload();
1147
+ })
1148
+ )
1149
+ ), this.disposeWithMe(
1150
+ this._commandService.onCommandExecuted((command) => {
1151
+ command.type !== CommandType2.MUTATION || !hasUnitId(command.params) || this._univerInstanceService.getUnit(command.params.unitId, UniverInstanceType.UNIVER_BASE) && (hasTrigger(command.params) && command.params.trigger === SetFormulaCalculationResultMutation.id || this._scheduleProjectionReload());
1152
+ })
1153
+ ), this.disposeWithMe(
1154
+ toDisposable(
1155
+ this._univerInstanceService.getTypeOfUnitDisposed$(UniverInstanceType.UNIVER_BASE).subscribe((base) => {
1156
+ this._rustEngineSyncController.disposeProjectionWorkbook(base.getUnitId());
1157
+ })
1158
+ )
1159
+ ), this.disposeWithMe(
1160
+ toDisposable(
1161
+ this._univerInstanceService.getTypeOfUnitDisposed$(UniverInstanceType.UNIVER_SHEET).subscribe((workbook) => {
1162
+ this._rustEngineSyncController.disposeProjectionWorkbook(workbook.getUnitId());
1163
+ })
1164
+ )
1165
+ );
1166
+ }
1167
+ _scheduleProjectionReload() {
1168
+ this._projectionReloadRequested = !0, !this._projectionReload && (this._projectionReload = this._drainProjectionReloads().finally(() => {
1169
+ this._projectionReload = null, this._projectionReloadRequested && this._scheduleProjectionReload();
1170
+ }));
1171
+ }
1172
+ async _drainProjectionReloads() {
1173
+ for (; this._projectionReloadRequested; )
1174
+ this._projectionReloadRequested = !1, await this._loadAllWorkbookProjections();
1175
+ }
1176
+ async _loadAllWorkbookProjections() {
1177
+ let workbooks = this._univerInstanceService.getAllUnitsForType(UniverInstanceType.UNIVER_SHEET).map((workbook) => ({
1178
+ unitId: workbook.getUnitId(),
1179
+ snapshot: workbook.getSnapshot()
1180
+ })), calculationData = this._formulaDataModel.getCalculateData(), formulaData = this._formulaDataModel.getFormulaData(), baseWorkbooks = this._univerInstanceService.getAllUnitsForType(UniverInstanceType.UNIVER_BASE).map(
1181
+ (base) => this._createBaseWorkbookProjection(
1182
+ base.getUnitId(),
1183
+ calculationData.allUnitData,
1184
+ calculationData.unitSheetNameMap,
1185
+ calculationData.unitNameMap ?? {},
1186
+ formulaData
1187
+ )
1188
+ ).filter((workbook) => workbook != null);
1189
+ workbooks.push(...baseWorkbooks), await this._rustEngineSyncController.loadProjection(workbooks);
1190
+ }
1191
+ _createBaseWorkbookProjection(unitId, allUnitData, unitSheetNameMap, unitNameMap, formulaData) {
1192
+ let unitData = allUnitData[unitId];
1193
+ if (!unitData) return null;
1194
+ let sheetNameMap = unitSheetNameMap[unitId] ?? {}, sheetOrder = Object.keys(unitData), resources = this._createBaseTableResource(unitId), sheets = {};
1195
+ for (let sheetId of sheetOrder) {
1196
+ let sheet = unitData[sheetId];
1197
+ if (!sheet) continue;
1198
+ let cellData = this._rawCellData(sheet.cellData);
1199
+ for (let [rowKey, row] of Object.entries(formulaData[unitId]?.[sheetId] ?? {}))
1200
+ for (let [columnKey, formula] of Object.entries(row ?? {})) {
1201
+ if (!formula) continue;
1202
+ let rowIndex = Number(rowKey), columnIndex = Number(columnKey), current = cellData[rowIndex]?.[columnIndex] ?? {};
1203
+ (cellData[rowIndex] ??= {})[columnIndex] = { ...current, ...formula };
1204
+ }
1205
+ sheets[sheetId] = {
1206
+ id: sheetId,
1207
+ name: Object.entries(sheetNameMap).find(([, currentSheetId]) => currentSheetId === sheetId)?.[0] ?? sheetId,
1208
+ rowCount: sheet.rowCount,
1209
+ columnCount: sheet.columnCount,
1210
+ cellData,
1211
+ rowData: sheet.rowData,
1212
+ columnData: sheet.columnData
1213
+ };
1214
+ }
1215
+ return {
1216
+ unitId,
1217
+ snapshot: {
1218
+ id: unitId,
1219
+ name: unitNameMap[unitId]?.name ?? unitId,
1220
+ appVersion: "",
1221
+ locale: LocaleType.EN_US,
1222
+ styles: {},
1223
+ sheetOrder,
1224
+ sheets,
1225
+ resources
1226
+ }
1227
+ };
1228
+ }
1229
+ _createBaseTableResource(unitId) {
1230
+ let tableMap = this._superTableService.getTableMap(unitId);
1231
+ if (!tableMap) return [];
1232
+ let data = {};
1233
+ for (let [name2, table] of tableMap) {
1234
+ let columns = Array.from(table.titleMap.entries()).toSorted((left, right) => left[1] - right[1]).map(([displayName]) => ({ displayName }));
1235
+ (data[table.sheetId] ??= { tables: [] }).tables.push({
1236
+ name: name2,
1237
+ range: table.range,
1238
+ columns,
1239
+ options: { showHeader: table.showHeader !== !1 }
1240
+ });
1241
+ }
1242
+ return [
1243
+ {
1244
+ name: "SHEET_TABLE_PLUGIN",
1245
+ data: JSON.stringify(data)
1246
+ }
1247
+ ];
1248
+ }
1249
+ _rawCellData(cellData) {
1250
+ let raw = cellData.getData(), result = {};
1251
+ for (let [row, values] of Object.entries(raw ?? {})) {
1252
+ let rowData = {};
1253
+ for (let [column, value] of Object.entries(values ?? {}))
1254
+ value && (rowData[Number(column)] = { ...value });
1255
+ result[Number(row)] = rowData;
1256
+ }
1257
+ return result;
1258
+ }
1259
+ };
1260
+ function hasUnitId(value) {
1261
+ return value != null && typeof value == "object" && "unitId" in value && typeof value.unitId == "string";
1262
+ }
1263
+ function hasTrigger(value) {
1264
+ return "trigger" in value && typeof value.trigger == "string";
1265
+ }
1266
+ setDependencies2(RustSameRuntimeProjectionController, [
1267
+ IUniverInstanceService,
1268
+ RustEngineSyncController,
1269
+ FormulaDataModel,
1270
+ ISuperTableService,
1271
+ ICommandService2
1272
+ ]);
1273
+
1274
+ // src/services/calculate-formula.service.ts
1275
+ import {
1276
+ AsyncLock,
1277
+ createIdentifier,
1278
+ Disposable as Disposable3,
1279
+ ICommandService as ICommandService3,
1280
+ IConfigService,
1281
+ setDependencies as setDependencies3
1282
+ } from "@univerjs/core";
1283
+ import {
1284
+ ENGINE_FORMULA_PLUGIN_CONFIG_KEY,
1285
+ FormulaExecuteStageType,
1286
+ IFeatureCalculationManagerService,
1287
+ IFormulaCurrentConfigService,
1288
+ IFormulaDependencyGenerator,
1289
+ IFormulaRuntimeService,
1290
+ IOtherFormulaManagerService,
1291
+ SetFormulaCalculationResultMutation as SetFormulaCalculationResultMutation2
1292
+ } from "@univerjs/engine-formula";
1293
+ import { ExternalReferencePrefetchPlanner, ExternalReferencePrefetchService } from "@univerjs-pro/engine-formula";
1294
+ import { Subject } from "rxjs";
1295
+ var IRustCalculateFormulaService = createIdentifier(
1296
+ "engine-formula-rust.calculate-formula.service"
1297
+ ), DEFAULT_INTERVAL_COUNT = 500, MAX_FEATURE_CALCULATION_PASSES = 8, MAX_EXTERNAL_REFERENCE_PASSES = 8, FORMULA_TREE_TYPE_NORMAL = 0, FORMULA_TREE_TYPE_OTHER = 1, FORMULA_TREE_TYPE_FEATURE = 2;
1298
+ function emitRustFormulaDebugEvent(event) {
1299
+ let hook = globalThis.__UNIVER_RUST_FORMULA_DEBUG_HOOK__;
1300
+ typeof hook == "function" && hook(event);
1301
+ }
1302
+ function firstResultBatchValue(output) {
1303
+ return output.resultBatches?.find((batch) => batch.values.length > 0)?.values[0];
1304
+ }
1305
+ function resultBatchSheetCounts(output) {
1306
+ let counts = {};
1307
+ for (let batch of output.resultBatches ?? []) {
1308
+ let key = `${batch.unitId}/${batch.sheetId}`;
1309
+ counts[key] = (counts[key] ?? 0) + batch.values.length;
1310
+ }
1311
+ return counts;
1312
+ }
1313
+ function rustExecutionOutputToCalculationResult(output) {
1314
+ let patch = rustExecutionOutputToFormulaCalculationPatch(output);
1315
+ return {
1316
+ unitData: patch.unitData,
1317
+ unitOtherData: patch.unitOtherData
1318
+ };
1319
+ }
1320
+ var RustCalculateFormulaService = class extends Disposable3 {
1321
+ constructor(_configService, _currentConfigService, _runtimeService, _formulaDependencyGenerator, _featureCalculationManagerService, _otherFormulaManagerService, _commandService, _rustEngineSyncController, _externalPrefetchPlanner, _externalPrefetchService) {
1322
+ super();
1323
+ this._configService = _configService;
1324
+ this._currentConfigService = _currentConfigService;
1325
+ this._runtimeService = _runtimeService;
1326
+ this._formulaDependencyGenerator = _formulaDependencyGenerator;
1327
+ this._featureCalculationManagerService = _featureCalculationManagerService;
1328
+ this._otherFormulaManagerService = _otherFormulaManagerService;
1329
+ this._commandService = _commandService;
1330
+ this._rustEngineSyncController = _rustEngineSyncController;
1331
+ this._externalPrefetchPlanner = _externalPrefetchPlanner;
1332
+ this._externalPrefetchService = _externalPrefetchService;
1333
+ this._commandService.hasCommand(SetFormulaCalculationResultMutation2.id) || this.disposeWithMe(this._commandService.registerCommand(SetFormulaCalculationResultMutation2));
1334
+ }
1335
+ _configService;
1336
+ _currentConfigService;
1337
+ _runtimeService;
1338
+ _formulaDependencyGenerator;
1339
+ _featureCalculationManagerService;
1340
+ _otherFormulaManagerService;
1341
+ _commandService;
1342
+ _rustEngineSyncController;
1343
+ _externalPrefetchPlanner;
1344
+ _externalPrefetchService;
1345
+ _executionInProgressListener$ = new Subject();
1346
+ executionInProgressListener$ = this._executionInProgressListener$.asObservable();
1347
+ _executionCompleteListener$ = new Subject();
1348
+ executionCompleteListener$ = this._executionCompleteListener$.asObservable();
1349
+ _executeLock = new AsyncLock();
1350
+ _nativeLoaded = !1;
1351
+ _syncedSnapshotEpoch = -1;
1352
+ _syncedDependencyInvalidationEpoch = -1;
1353
+ _externalFormulaDatasetConfig;
1354
+ dispose() {
1355
+ super.dispose(), this._executionInProgressListener$.complete(), this._executionCompleteListener$.complete();
1356
+ }
1357
+ stopFormulaExecution() {
1358
+ this._runtimeService.stopExecution();
1359
+ }
1360
+ setRuntimeFeatureCellData(featureId, featureData) {
1361
+ this._runtimeService.setRuntimeFeatureCellData(featureId, featureData);
1362
+ }
1363
+ setRuntimeFeatureRange(featureId, featureRange) {
1364
+ this._runtimeService.setRuntimeFeatureRange(featureId, featureRange);
1365
+ }
1366
+ async execute(formulaDatasetConfig) {
1367
+ this._nativeLoaded || (await loadNativeBinding(), this._nativeLoaded = !0), await this._rustEngineSyncController.waitForProjectionLoad(), this._externalFormulaDatasetConfig = formulaDatasetConfig, await this._prefetchStaticExternalReferences(formulaDatasetConfig), this._runtimeService.setFormulaExecuteStage(FormulaExecuteStageType.START), this._executionInProgressListener$.next(this._runtimeService.getRuntimeState()), this._currentConfigService.load(formulaDatasetConfig), this._runtimeService.reset();
1368
+ let cycleReferenceCount = Math.max(formulaDatasetConfig.maxIteration || 1, 1);
1369
+ await this._executeLock.acquire("FORMULA_EXECUTION_LOCK", async () => {
1370
+ this._runtimeService.setFormulaCycleIndex(0), await this._executeStep(cycleReferenceCount) > 0 ? this._runtimeService.markedAsSuccessfullyExecuted() : this._runtimeService.markedAsNoFunctionsExecuted(), this._runtimeService.setFormulaExecuteStage(FormulaExecuteStageType.CALCULATION_COMPLETED), this._executionInProgressListener$.next(this._runtimeService.getRuntimeState()), this._executionCompleteListener$.next(this._runtimeService.getAllRuntimeData()), this._runtimeService.reset();
1371
+ });
1372
+ }
1373
+ async _executeStep(maxIteration) {
1374
+ let syncedFeatures = this._syncRustFormulaDependencies(), previousFeatureSignatures = this._featureSignatureMap(syncedFeatures), executeStartedAt = performance.now(), outputJson = executeDirtyFormulasOnRust(maxIteration, !1, !1, !0), nativeAndSerializeMs = performance.now() - executeStartedAt, parseStartedAt = performance.now(), output = JSON.parse(outputJson), calculatedNodeCount = output.calculatedNodeCount, parseMs = performance.now() - parseStartedAt;
1375
+ output = await this._resolveExternalReferenceNeeds(output, maxIteration);
1376
+ let applyStartedAt = performance.now(), applyBreakdown = await this._applyRustDependencyOutput(output), applyMs = performance.now() - applyStartedAt;
1377
+ if (emitRustFormulaDebugEvent({
1378
+ type: "executeDirtyFormulas",
1379
+ payload: {
1380
+ calculatedNodeCount: output.calculatedNodeCount,
1381
+ hasCycle: output.hasCycle,
1382
+ cycleIterationCount: output.cycleIterationCount,
1383
+ parallelBatchCount: output.parallelBatchCount,
1384
+ parallelNodeCount: output.parallelNodeCount,
1385
+ errorCount: output.errors.length,
1386
+ resultBatchCount: output.resultBatches?.length ?? 0,
1387
+ firstResultBatchValue: firstResultBatchValue(output),
1388
+ resultBatchSheetCounts: resultBatchSheetCounts(output),
1389
+ timings: output.timings,
1390
+ functionProfile: output.functionProfile,
1391
+ bridgeTimings: {
1392
+ nativeAndSerializeMs,
1393
+ outputBytes: outputJson.length,
1394
+ parseMs,
1395
+ applyMs,
1396
+ applyConvertMs: applyBreakdown.convertMs,
1397
+ applyCommandMs: applyBreakdown.commandMs
1398
+ }
1399
+ }
1400
+ }), syncedFeatures.length > 0)
1401
+ for (let pass = 0; pass < MAX_FEATURE_CALCULATION_PASSES; pass++) {
1402
+ let refreshedFeatures = this._syncRustFormulaDependencyDefinitions(), changedFeatures = refreshedFeatures.filter(
1403
+ (feature) => previousFeatureSignatures.get(this._featureKey(feature)) !== feature.signature
1404
+ );
1405
+ if (changedFeatures.length === 0)
1406
+ break;
1407
+ this._markRustFormulaDirty(
1408
+ this._currentConfigService.getDirtyData(),
1409
+ this._dirtyFeatureMapFor(changedFeatures)
1410
+ ), executeStartedAt = performance.now(), outputJson = executeDirtyFormulasOnRust(maxIteration, !1, !1, !0), nativeAndSerializeMs = performance.now() - executeStartedAt, parseStartedAt = performance.now(), output = JSON.parse(outputJson), calculatedNodeCount += output.calculatedNodeCount, parseMs = performance.now() - parseStartedAt, output = await this._resolveExternalReferenceNeeds(output, maxIteration), applyStartedAt = performance.now(), applyBreakdown = await this._applyRustDependencyOutput(output), applyMs = performance.now() - applyStartedAt, emitRustFormulaDebugEvent({
1411
+ type: "executeDirtyFormulas",
1412
+ payload: {
1413
+ calculatedNodeCount: output.calculatedNodeCount,
1414
+ hasCycle: output.hasCycle,
1415
+ cycleIterationCount: output.cycleIterationCount,
1416
+ parallelBatchCount: output.parallelBatchCount,
1417
+ parallelNodeCount: output.parallelNodeCount,
1418
+ errorCount: output.errors.length,
1419
+ resultBatchCount: output.resultBatches?.length ?? 0,
1420
+ firstResultBatchValue: firstResultBatchValue(output),
1421
+ resultBatchSheetCounts: resultBatchSheetCounts(output),
1422
+ timings: output.timings,
1423
+ functionProfile: output.functionProfile,
1424
+ bridgeTimings: {
1425
+ nativeAndSerializeMs,
1426
+ outputBytes: outputJson.length,
1427
+ parseMs,
1428
+ applyMs,
1429
+ applyConvertMs: applyBreakdown.convertMs,
1430
+ applyCommandMs: applyBreakdown.commandMs
1431
+ }
1432
+ }
1433
+ }), previousFeatureSignatures = this._featureSignatureMap(refreshedFeatures);
1434
+ }
1435
+ return calculatedNodeCount;
1436
+ }
1437
+ async _prefetchStaticExternalReferences(config) {
1438
+ let requests = this._externalPrefetchPlanner.plan(config);
1439
+ if (requests.length === 0) return;
1440
+ let result = await this._externalPrefetchService.prefetch(requests, config);
1441
+ result.dirtyRanges.length > 0 && this._rustEngineSyncController.upsertReferenceData(config, result.dirtyRanges);
1442
+ }
1443
+ async _resolveExternalReferenceNeeds(initialOutput, maxIteration) {
1444
+ let config = this._externalFormulaDatasetConfig;
1445
+ if (!config) return initialOutput;
1446
+ let output = initialOutput;
1447
+ for (let pass = 0; pass < MAX_EXTERNAL_REFERENCE_PASSES; pass++) {
1448
+ let needs = output.needsData ?? [];
1449
+ if (needs.length === 0) break;
1450
+ let requests = /* @__PURE__ */ new Map();
1451
+ for (let [hostUnitId, references] of this._groupExternalReferenceNeeds(config, needs))
1452
+ for (let request of this._externalPrefetchPlanner.planDynamic(hostUnitId, references))
1453
+ requests.set(`${request.hostUnitId}\0${request.bindingSlot}`, request);
1454
+ if (requests.size === 0) break;
1455
+ let result = await this._externalPrefetchService.prefetch(Array.from(requests.values()), config), upsertCount = this._rustEngineSyncController.upsertReferenceData(config, needs);
1456
+ if (result.dirtyRanges.length === 0 || upsertCount === 0) break;
1457
+ output = JSON.parse(executeDirtyFormulasOnRust(maxIteration, !1, !1, !0));
1458
+ }
1459
+ return output;
1460
+ }
1461
+ _groupExternalReferenceNeeds(config, needs) {
1462
+ let grouped = /* @__PURE__ */ new Map();
1463
+ for (let need of needs) {
1464
+ let hostUnitId = this._hostUnitIdFromSynthetic(need.unitId);
1465
+ if (!hostUnitId) continue;
1466
+ let sheetNameMap = config.unitSheetNameMap?.[need.unitId] ?? {}, sheetName = Object.entries(sheetNameMap).find(([, sheetId]) => sheetId === need.sheetId)?.[0] ?? need.sheetId, references = grouped.get(hostUnitId) ?? [];
1467
+ references.push({ unitId: need.unitId, sheetName, range: need.range }), grouped.set(hostUnitId, references);
1468
+ }
1469
+ return grouped;
1470
+ }
1471
+ _hostUnitIdFromSynthetic(unitId) {
1472
+ if (!unitId.startsWith("external:")) return;
1473
+ let separator = unitId.lastIndexOf(":");
1474
+ if (!(separator <= 9 || !/^\d+$/.test(unitId.slice(separator + 1))))
1475
+ try {
1476
+ return decodeURIComponent(unitId.slice(9, separator));
1477
+ } catch {
1478
+ return;
1479
+ }
1480
+ }
1481
+ _buildRustInput() {
1482
+ let unitData = this._currentConfigService.getUnitData(), formulaData = this._currentConfigService.getFormulaData(), dirtyRanges = this._currentConfigService.getDirtyRanges(), config = this._configService.getConfig(ENGINE_FORMULA_PLUGIN_CONFIG_KEY);
1483
+ return {
1484
+ config: {
1485
+ maxIteration: config?.maxIteration ?? 1,
1486
+ intervalCount: config?.intervalCount ?? DEFAULT_INTERVAL_COUNT
1487
+ },
1488
+ formulaData: this._serializeFormulaData(formulaData),
1489
+ unitData: this._serializeUnitData(unitData),
1490
+ dirtyRanges: dirtyRanges || [],
1491
+ definedNames: {}
1492
+ };
1493
+ }
1494
+ _syncRustFormulaDependencies(dirtyUnitFeatureMapOverride) {
1495
+ let syncState = getRustEngineSyncState(), rebuildSheetFormulas = this._syncedSnapshotEpoch !== syncState.snapshotEpoch || this._syncedDependencyInvalidationEpoch !== syncState.dependencyInvalidationEpoch, collectStartedAt = performance.now(), state = this._collectRustFormulaDependencySyncState(), collectMs = performance.now() - collectStartedAt;
1496
+ if (!(rebuildSheetFormulas || state.featureCalculations.length > 0 || state.otherFormulas.length > 0))
1497
+ return emitRustFormulaDebugEvent({
1498
+ type: "syncDependencies",
1499
+ payload: {
1500
+ rebuildSheetFormulas,
1501
+ skipped: !0,
1502
+ featureCalculationCount: 0,
1503
+ otherFormulaCount: 0,
1504
+ syncedFeatureCount: 0,
1505
+ timings: {
1506
+ collectMs,
1507
+ stringifyMs: 0,
1508
+ nativeMs: 0,
1509
+ parseMs: 0,
1510
+ totalMs: collectMs
1511
+ }
1512
+ }
1513
+ }), this._markRustFormulaDirty(state.dirtyData, dirtyUnitFeatureMapOverride, rebuildSheetFormulas), state.syncedFeatures;
1514
+ let stringifyStartedAt = performance.now(), inputJson = JSON.stringify({
1515
+ rebuildSheetFormulas,
1516
+ featureCalculations: state.featureCalculations,
1517
+ otherFormulas: state.otherFormulas
1518
+ }), stringifyMs = performance.now() - stringifyStartedAt, nativeStartedAt = performance.now(), outputJson = syncRustFormulaDependenciesOnRust(inputJson), nativeMs = performance.now() - nativeStartedAt, parseStartedAt = performance.now(), output = JSON.parse(outputJson), parseMs = performance.now() - parseStartedAt;
1519
+ return emitRustFormulaDebugEvent({
1520
+ type: "syncDependencies",
1521
+ payload: {
1522
+ rebuildSheetFormulas,
1523
+ skipped: !1,
1524
+ featureCalculationCount: state.featureCalculations.length,
1525
+ otherFormulaCount: state.otherFormulas.length,
1526
+ syncedFeatureCount: state.syncedFeatures.length,
1527
+ timings: {
1528
+ collectMs,
1529
+ stringifyMs,
1530
+ nativeMs,
1531
+ parseMs,
1532
+ totalMs: collectMs + stringifyMs + nativeMs + parseMs,
1533
+ rust: output.timings
1534
+ }
1535
+ }
1536
+ }), rebuildSheetFormulas && (this._syncedSnapshotEpoch = syncState.snapshotEpoch, this._syncedDependencyInvalidationEpoch = syncState.dependencyInvalidationEpoch), this._markRustFormulaDirty(state.dirtyData, dirtyUnitFeatureMapOverride, rebuildSheetFormulas), state.syncedFeatures;
1537
+ }
1538
+ _syncRustFormulaDependencyDefinitions() {
1539
+ let state = this._collectRustFormulaDependencySyncState();
1540
+ return syncRustFormulaDependenciesOnRust(
1541
+ JSON.stringify({
1542
+ rebuildSheetFormulas: !1,
1543
+ featureCalculations: state.featureCalculations,
1544
+ otherFormulas: state.otherFormulas
1545
+ })
1546
+ ), state.syncedFeatures;
1547
+ }
1548
+ _collectRustFormulaDependencySyncState() {
1549
+ let featureCalculations = [], syncedFeatures = [], dirtyData = this._currentConfigService.getDirtyData(), runtimeData = this._runtimeService.getAllRuntimeData();
1550
+ this._featureCalculationManagerService.getReferenceExecutorMap().forEach((sheetMap) => {
1551
+ sheetMap.forEach((featureMap) => {
1552
+ featureMap.forEach((params, featureId) => {
1553
+ let { runtimeCellData, dirtyRanges: featureDirtyRanges } = params.getDirtyData(
1554
+ dirtyData,
1555
+ runtimeData
1556
+ ), serializedDirtyRanges = this._serializeFeatureDirtyRanges(featureDirtyRanges), serializedRuntimeCellData = this._serializeRuntimeFeatureCellData(runtimeCellData);
1557
+ this._runtimeService.setRuntimeFeatureCellData(featureId, runtimeCellData), this._runtimeService.setRuntimeFeatureRange(featureId, featureDirtyRanges), featureCalculations.push({
1558
+ unitId: params.unitId,
1559
+ sheetId: params.subUnitId,
1560
+ featureId,
1561
+ dependencyRanges: params.dependencyRanges.map((range) => ({
1562
+ unitId: range.unitId,
1563
+ sheetId: range.sheetId,
1564
+ startRow: range.range.startRow,
1565
+ endRow: range.range.endRow,
1566
+ startColumn: range.range.startColumn,
1567
+ endColumn: range.range.endColumn
1568
+ })),
1569
+ dirtyRanges: serializedDirtyRanges,
1570
+ runtimeCellData: serializedRuntimeCellData
1571
+ }), syncedFeatures.push({
1572
+ unitId: params.unitId,
1573
+ sheetId: params.subUnitId,
1574
+ featureId,
1575
+ signature: JSON.stringify({
1576
+ dirtyRanges: serializedDirtyRanges,
1577
+ runtimeCellData: serializedRuntimeCellData
1578
+ })
1579
+ });
1580
+ });
1581
+ });
1582
+ });
1583
+ let otherFormulas = [], otherFormulaData = this._otherFormulaManagerService.getOtherFormulaData();
1584
+ return Object.entries(otherFormulaData).forEach(([unitId, sheetMap]) => {
1585
+ sheetMap && Object.entries(sheetMap).forEach(([sheetId, formulaMap]) => {
1586
+ formulaMap && Object.entries(formulaMap).forEach(([formulaId, item]) => {
1587
+ item && otherFormulas.push({
1588
+ unitId,
1589
+ sheetId,
1590
+ formulaId,
1591
+ formula: item.f,
1592
+ ranges: item.ranges
1593
+ });
1594
+ });
1595
+ });
1596
+ }), { dirtyData, featureCalculations, otherFormulas, syncedFeatures };
1597
+ }
1598
+ _markRustFormulaDirty(dirtyData, dirtyUnitFeatureMapOverride, forceCalculationOverride = !1) {
1599
+ let payload = {
1600
+ forceCalculation: forceCalculationOverride || dirtyData.forceCalculation,
1601
+ includeDirtyNodes: !1,
1602
+ includeCalculationOrder: !1,
1603
+ dirtyRanges: (dirtyData.dirtyRanges ?? []).map((range) => ({
1604
+ unitId: range.unitId,
1605
+ sheetId: range.sheetId,
1606
+ startRow: range.range.startRow,
1607
+ endRow: range.range.endRow,
1608
+ startColumn: range.range.startColumn,
1609
+ endColumn: range.range.endColumn
1610
+ })),
1611
+ dirtyUnitFeatureMap: dirtyUnitFeatureMapOverride ?? dirtyData.dirtyUnitFeatureMap,
1612
+ dirtyUnitOtherFormulaMap: dirtyData.dirtyUnitOtherFormulaMap,
1613
+ dirtyNameMap: dirtyData.dirtyNameMap,
1614
+ dirtyDefinedNameMap: dirtyData.dirtyDefinedNameMap
1615
+ }, stringifyStartedAt = performance.now(), inputJson = JSON.stringify(payload), stringifyMs = performance.now() - stringifyStartedAt, nativeStartedAt = performance.now(), outputJson = markRustFormulaDirtyOnRust(inputJson), nativeMs = performance.now() - nativeStartedAt, rustTimings;
1616
+ try {
1617
+ rustTimings = JSON.parse(outputJson).timings;
1618
+ } catch {
1619
+ rustTimings = void 0;
1620
+ }
1621
+ emitRustFormulaDebugEvent({
1622
+ type: "markDirty",
1623
+ payload: {
1624
+ ...payload,
1625
+ timings: {
1626
+ stringifyMs,
1627
+ nativeMs,
1628
+ totalMs: stringifyMs + nativeMs
1629
+ },
1630
+ rustTimings
1631
+ }
1632
+ });
1633
+ }
1634
+ _dirtyFeatureMapFor(features) {
1635
+ let dirtyMap = {};
1636
+ return features.forEach(({ unitId, sheetId, featureId }) => {
1637
+ dirtyMap[unitId] = dirtyMap[unitId] ?? {}, dirtyMap[unitId][sheetId] = dirtyMap[unitId][sheetId] ?? {}, dirtyMap[unitId][sheetId][featureId] = !0;
1638
+ }), dirtyMap;
1639
+ }
1640
+ _featureKey(feature) {
1641
+ return `${feature.unitId}\0${feature.sheetId}\0${feature.featureId}`;
1642
+ }
1643
+ _featureSignatureMap(features) {
1644
+ return new Map(features.map((feature) => [this._featureKey(feature), feature.signature]));
1645
+ }
1646
+ _serializeFeatureDirtyRanges(dirtyRanges) {
1647
+ let serialized = [];
1648
+ return Object.entries(dirtyRanges).forEach(([unitId, sheetMap]) => {
1649
+ sheetMap && Object.entries(sheetMap).forEach(([sheetId, ranges]) => {
1650
+ ranges && ranges.forEach((range) => {
1651
+ serialized.push({
1652
+ unitId,
1653
+ sheetId,
1654
+ startRow: range.startRow,
1655
+ endRow: range.endRow,
1656
+ startColumn: range.startColumn,
1657
+ endColumn: range.endColumn
1658
+ });
1659
+ });
1660
+ });
1661
+ }), serialized;
1662
+ }
1663
+ _serializeRuntimeFeatureCellData(runtimeCellData) {
1664
+ let result = {};
1665
+ return Object.entries(runtimeCellData ?? {}).forEach(([unitId, sheetMap]) => {
1666
+ if (!sheetMap) return;
1667
+ let unitData = {};
1668
+ result[unitId] = unitData, Object.entries(sheetMap).forEach(([sheetId, matrix]) => {
1669
+ if (!matrix) return;
1670
+ let sheetData = {};
1671
+ unitData[sheetId] = sheetData, matrix.forValue((row, column, cell) => {
1672
+ let rowData = sheetData[row] ??= {};
1673
+ rowData[column] = cell == null ? null : {
1674
+ v: cell.v,
1675
+ ...typeof cell.t == "number" ? { t: cell.t } : {},
1676
+ ...cell.p != null ? { p: cell.p } : {},
1677
+ ...typeof cell.f == "string" ? { f: cell.f } : {},
1678
+ ...typeof cell.si == "string" ? { si: cell.si } : {},
1679
+ ...typeof cell.ref == "string" ? { ref: cell.ref } : {},
1680
+ ...typeof cell.xf == "string" ? { xf: cell.xf } : {},
1681
+ ...cell.s != null ? { s: cell.s } : {}
1682
+ };
1683
+ });
1684
+ });
1685
+ }), result;
1686
+ }
1687
+ _serializeFormulaData(formulaData) {
1688
+ let result = {};
1689
+ if (!formulaData || typeof formulaData != "object") return result;
1690
+ for (let [unitId, sheets] of Object.entries(formulaData))
1691
+ if (!(!sheets || typeof sheets != "object")) {
1692
+ result[unitId] = {};
1693
+ for (let [sheetId, rows] of Object.entries(sheets))
1694
+ if (!(!rows || typeof rows != "object")) {
1695
+ result[unitId][sheetId] = {};
1696
+ for (let [rowStr, cols] of Object.entries(rows)) {
1697
+ if (!cols || typeof cols != "object")
1698
+ continue;
1699
+ let row = Number(rowStr);
1700
+ result[unitId][sheetId][row] = {};
1701
+ for (let [colStr, item] of Object.entries(cols)) {
1702
+ let col = Number(colStr);
1703
+ if (typeof item == "string")
1704
+ result[unitId][sheetId][row][col] = item;
1705
+ else if (item && typeof item == "object" && typeof item.f == "string") {
1706
+ let formulaItem = item;
1707
+ result[unitId][sheetId][row][col] = {
1708
+ f: formulaItem.f,
1709
+ si: typeof formulaItem.si == "string" ? formulaItem.si : void 0,
1710
+ ref: typeof formulaItem.ref == "string" ? formulaItem.ref : void 0,
1711
+ x: typeof formulaItem.x == "number" ? formulaItem.x : void 0,
1712
+ y: typeof formulaItem.y == "number" ? formulaItem.y : void 0
1713
+ };
1714
+ }
1715
+ }
1716
+ }
1717
+ }
1718
+ }
1719
+ return result;
1720
+ }
1721
+ _serializeUnitData(unitData) {
1722
+ let result = {};
1723
+ if (!unitData) return result;
1724
+ for (let [unitId, sheets] of Object.entries(unitData)) {
1725
+ result[unitId] = {};
1726
+ for (let [sheetId, sheet] of Object.entries(sheets))
1727
+ result[unitId][sheetId] = {
1728
+ cellData: this._serializeCellData(sheet.cellData),
1729
+ rowCount: sheet.rowCount ?? 0,
1730
+ columnCount: sheet.columnCount ?? 0
1731
+ };
1732
+ }
1733
+ return result;
1734
+ }
1735
+ _serializeCellData(cellData) {
1736
+ let result = {};
1737
+ if (!cellData || typeof cellData != "object") return result;
1738
+ let data = typeof cellData.getMatrix == "function" ? cellData.getMatrix() : cellData;
1739
+ for (let [rowStr, cols] of Object.entries(data)) {
1740
+ let row = Number(rowStr);
1741
+ if (Number.isFinite(row)) {
1742
+ result[row] = {};
1743
+ for (let [colStr, cell] of Object.entries(cols)) {
1744
+ let col = Number(colStr);
1745
+ Number.isFinite(col) && (result[row][col] = {
1746
+ v: cell?.v ?? null,
1747
+ t: cell?.t ?? void 0,
1748
+ p: cell?.p ?? void 0,
1749
+ f: cell?.f ?? void 0,
1750
+ s: cell?.s ?? void 0
1751
+ });
1752
+ }
1753
+ }
1754
+ }
1755
+ return result;
1756
+ }
1757
+ _applyRustOutput(_output) {
1758
+ }
1759
+ async _applyRustDependencyOutput(output) {
1760
+ let convertStartedAt = performance.now(), result = rustExecutionOutputToCalculationResult(output), convertMs = performance.now() - convertStartedAt, commandStartedAt = performance.now();
1761
+ return await this._commandService.executeCommand(SetFormulaCalculationResultMutation2.id, result, {
1762
+ onlyLocal: !0,
1763
+ fromRustFormulaEngine: !0
1764
+ }), {
1765
+ convertMs,
1766
+ commandMs: performance.now() - commandStartedAt
1767
+ };
1768
+ }
1769
+ async calculate(formulaString) {
1770
+ this._nativeLoaded || (await loadNativeBinding(), this._nativeLoaded = !0);
1771
+ let unitId = "__rust_formula_calculate__", sheetId = "__sheet__", input = {
1772
+ config: { maxIteration: 1, intervalCount: DEFAULT_INTERVAL_COUNT },
1773
+ formulaData: {
1774
+ [unitId]: {
1775
+ [sheetId]: {
1776
+ 0: { 0: formulaString }
1777
+ }
1778
+ }
1779
+ },
1780
+ unitData: {
1781
+ [unitId]: {
1782
+ [sheetId]: {
1783
+ rowCount: 1,
1784
+ columnCount: 1,
1785
+ cellData: {}
1786
+ }
1787
+ }
1788
+ },
1789
+ dirtyRanges: [],
1790
+ definedNames: {}
1791
+ };
1792
+ return JSON.parse(executeOnRust(JSON.stringify(input))).runtimeData?.[unitId]?.[sheetId]?.[0]?.[0] ?? null;
1793
+ }
1794
+ async executeFormulas(formulas, rowData) {
1795
+ this._nativeLoaded || (await loadNativeBinding(), this._nativeLoaded = !0), this._currentConfigService.loadDataLite(rowData);
1796
+ let unitData = this._currentConfigService.getUnitData(), formulaData = this._formulaStringMapToFormulaData(formulas), input = {
1797
+ config: { maxIteration: 1, intervalCount: DEFAULT_INTERVAL_COUNT },
1798
+ formulaData,
1799
+ unitData: this._serializeUnitData(unitData),
1800
+ dirtyRanges: [],
1801
+ definedNames: {}
1802
+ }, output = JSON.parse(executeOnRust(JSON.stringify(input)));
1803
+ return this._formulaExecutionOutputToResultMap(formulas, output);
1804
+ }
1805
+ async getAllDependencyJson(_rowData) {
1806
+ this._nativeLoaded || (await loadNativeBinding(), this._nativeLoaded = !0), this._syncRustFormulaDependencyDefinitions();
1807
+ let graph = this._getRustDependencyGraph(), inspect = this._getRustInspectGraph();
1808
+ return this._rustAllDependencyJson(graph, inspect);
1809
+ }
1810
+ async getCellDependencyJson(unitId, sheetId, row, column, _rowData) {
1811
+ this._nativeLoaded || (await loadNativeBinding(), this._nativeLoaded = !0), this._syncRustFormulaDependencyDefinitions();
1812
+ let graph = this._getRustDependencyGraph(unitId), all = this._rustGraphDependencyJson(graph), current = all.find(
1813
+ (item) => item.unitId === unitId && item.subUnitId === sheetId && item.row === row && item.column === column
1814
+ );
1815
+ if (!current)
1816
+ return;
1817
+ let byId = new Map(all.map((item) => [item.treeId, item]));
1818
+ return {
1819
+ ...current,
1820
+ children: current.children.map((id) => byId.get(id)).filter(isFormulaDependencyTreeJson),
1821
+ parents: current.parents.map((id) => byId.get(id)).filter(isFormulaDependencyTreeJson)
1822
+ };
1823
+ }
1824
+ async getRangeDependents(unitRanges) {
1825
+ this._nativeLoaded || (await loadNativeBinding(), this._nativeLoaded = !0), this._syncRustFormulaDependencyDefinitions();
1826
+ let graph = this._getRustDependencyGraph(), graphItems = this._rustGraphDependencyJson(graph), graphByCell = this._rustDependencyJsonByCell(graphItems), dirty = JSON.parse(
1827
+ getRustDirtyDependenciesOnRust(JSON.stringify(this._serializeUnitRanges(unitRanges)))
1828
+ );
1829
+ return this._uniqueDependencyJson(
1830
+ (dirty.direct ?? dirty.affected ?? []).map((cell) => graphByCell.get(this._cellKey(cell))).filter(Boolean)
1831
+ );
1832
+ }
1833
+ async getInRangeFormulas(unitRanges) {
1834
+ return this._nativeLoaded || (await loadNativeBinding(), this._nativeLoaded = !0), this._syncRustFormulaDependencyDefinitions(), this._rustGraphDependencyJson(this._getRustDependencyGraph()).filter(
1835
+ (item) => this._cellInUnitRanges(item.unitId, item.subUnitId, item.row, item.column, unitRanges)
1836
+ );
1837
+ }
1838
+ async getDependentsAndInRangeFormulas(unitRanges) {
1839
+ let [dependents, inRanges] = await Promise.all([
1840
+ this.getRangeDependents(unitRanges),
1841
+ this.getInRangeFormulas(unitRanges)
1842
+ ]);
1843
+ return { dependents, inRanges };
1844
+ }
1845
+ _formulaStringMapToFormulaData(formulas) {
1846
+ let formulaData = {};
1847
+ return Object.entries(formulas).forEach(([unitId, sheetMap]) => {
1848
+ sheetMap && (formulaData[unitId] = {}, Object.entries(sheetMap).forEach(([sheetId, rowMap]) => {
1849
+ rowMap && (formulaData[unitId][sheetId] = {}, Object.entries(rowMap).forEach(([rowKey, colMap]) => {
1850
+ if (!colMap) return;
1851
+ let row = Number(rowKey);
1852
+ formulaData[unitId][sheetId][row] = {}, Object.entries(colMap).forEach(([colKey, formulaList]) => {
1853
+ let formula = Array.isArray(formulaList) ? formulaList[0] : void 0;
1854
+ typeof formula == "string" && (formulaData[unitId][sheetId][row][Number(colKey)] = formula);
1855
+ });
1856
+ }));
1857
+ }));
1858
+ }), formulaData;
1859
+ }
1860
+ _formulaExecutionOutputToResultMap(formulas, output) {
1861
+ let result = {};
1862
+ return Object.entries(formulas).forEach(([unitId, sheetMap]) => {
1863
+ sheetMap && (result[unitId] = {}, Object.entries(sheetMap).forEach(([sheetId, rowMap]) => {
1864
+ rowMap && (result[unitId][sheetId] = {}, Object.entries(rowMap).forEach(([rowKey, colMap]) => {
1865
+ if (!colMap) return;
1866
+ let row = Number(rowKey);
1867
+ result[unitId][sheetId][row] = {}, Object.entries(colMap).forEach(([colKey, formulaList]) => {
1868
+ let col = Number(colKey), formulasForCell = Array.isArray(formulaList) ? formulaList : [], value = normalizeFormulaResultValue(
1869
+ output.runtimeData?.[unitId]?.[sheetId]?.[row]?.[col]
1870
+ );
1871
+ result[unitId][sheetId][row][col] = formulasForCell.map((formula) => ({ formula, value }));
1872
+ });
1873
+ }));
1874
+ }));
1875
+ }), result;
1876
+ }
1877
+ _getRustDependencyGraph(unitId) {
1878
+ return JSON.parse(buildRustDependencyGraphOnRust(unitId));
1879
+ }
1880
+ _getRustInspectGraph() {
1881
+ return JSON.parse(inspectRustFormulaDependencyGraphOnRust());
1882
+ }
1883
+ _rustAllDependencyJson(graph, inspect) {
1884
+ let cellItems = this._rustGraphDependencyJson(graph), seen = new Set(cellItems.map((item) => item.treeId)), nonCellItems = (inspect.nodes ?? []).filter((item) => item.node.nodeType !== "cellFormula" && !seen.has(item.index)).map((item) => this._rustFormulaNodeToDependencyJson(item.index, item.node));
1885
+ return this._uniqueDependencyJson([...cellItems, ...nonCellItems]);
1886
+ }
1887
+ _rustGraphDependencyJson(graph) {
1888
+ return (graph.nodes ?? []).map((node) => this._rustDependencyNodeToJson(node));
1889
+ }
1890
+ _rustDependencyNodeToJson(node) {
1891
+ return {
1892
+ children: node.children ?? [],
1893
+ parents: node.parents ?? [],
1894
+ treeId: node.id,
1895
+ formula: node.formula,
1896
+ row: node.row,
1897
+ column: node.column,
1898
+ unitId: node.unitId,
1899
+ subUnitId: node.sheetId,
1900
+ refOffsetX: node.offsetX ?? 0,
1901
+ refOffsetY: node.offsetY ?? 0,
1902
+ rangeList: (node.precedentRanges ?? []).map((range) => this._rustRangeToUnitRange(range)),
1903
+ refTreeId: void 0,
1904
+ formulaId: node.formulaId ?? null,
1905
+ featureId: null,
1906
+ type: FORMULA_TREE_TYPE_NORMAL
1907
+ };
1908
+ }
1909
+ _rustFormulaNodeToDependencyJson(index, node) {
1910
+ return {
1911
+ children: [],
1912
+ parents: [],
1913
+ treeId: index,
1914
+ formula: "",
1915
+ row: node.row ?? -1,
1916
+ column: node.column ?? -1,
1917
+ unitId: node.unitId ?? "",
1918
+ subUnitId: node.sheetId ?? "",
1919
+ refOffsetX: node.refOffsetX ?? 0,
1920
+ refOffsetY: node.refOffsetY ?? 0,
1921
+ rangeList: [],
1922
+ refTreeId: void 0,
1923
+ formulaId: node.formulaId ?? null,
1924
+ featureId: node.featureId ?? null,
1925
+ type: node.nodeType === "featureCalculation" ? FORMULA_TREE_TYPE_FEATURE : FORMULA_TREE_TYPE_OTHER
1926
+ };
1927
+ }
1928
+ _rustRangeToUnitRange(range) {
1929
+ return {
1930
+ unitId: range.unitId,
1931
+ sheetId: range.sheetId,
1932
+ range: {
1933
+ startRow: range.startRow,
1934
+ endRow: range.endRow,
1935
+ startColumn: range.startColumn,
1936
+ endColumn: range.endColumn
1937
+ }
1938
+ };
1939
+ }
1940
+ _serializeUnitRanges(unitRanges) {
1941
+ return unitRanges.map((unitRange) => ({
1942
+ unitId: unitRange.unitId,
1943
+ sheetId: unitRange.sheetId,
1944
+ startRow: unitRange.range.startRow,
1945
+ endRow: unitRange.range.endRow,
1946
+ startColumn: unitRange.range.startColumn,
1947
+ endColumn: unitRange.range.endColumn
1948
+ }));
1949
+ }
1950
+ _rustDependencyJsonByCell(items) {
1951
+ return new Map(
1952
+ items.map((item) => [
1953
+ this._cellKey({
1954
+ unitId: item.unitId,
1955
+ sheetId: item.subUnitId,
1956
+ row: item.row,
1957
+ column: item.column
1958
+ }),
1959
+ item
1960
+ ])
1961
+ );
1962
+ }
1963
+ _cellKey(cell) {
1964
+ return `${cell.unitId}\0${cell.sheetId}\0${cell.row}\0${cell.column}`;
1965
+ }
1966
+ _cellInUnitRanges(unitId, sheetId, row, column, unitRanges) {
1967
+ return unitRanges.some(
1968
+ (unitRange) => unitRange.unitId === unitId && unitRange.sheetId === sheetId && row >= unitRange.range.startRow && row <= unitRange.range.endRow && column >= unitRange.range.startColumn && column <= unitRange.range.endColumn
1969
+ );
1970
+ }
1971
+ _uniqueDependencyJson(items) {
1972
+ let seen = /* @__PURE__ */ new Set(), result = [];
1973
+ return items.forEach((item) => {
1974
+ !item || seen.has(item.treeId) || (seen.add(item.treeId), result.push(item));
1975
+ }), result;
1976
+ }
1977
+ };
1978
+ setDependencies3(RustCalculateFormulaService, [
1979
+ IConfigService,
1980
+ IFormulaCurrentConfigService,
1981
+ IFormulaRuntimeService,
1982
+ IFormulaDependencyGenerator,
1983
+ IFeatureCalculationManagerService,
1984
+ IOtherFormulaManagerService,
1985
+ ICommandService3,
1986
+ RustEngineSyncController,
1987
+ ExternalReferencePrefetchPlanner,
1988
+ ExternalReferencePrefetchService
1989
+ ]);
1990
+ function isFormulaDependencyTreeJson(value) {
1991
+ return value !== void 0;
1992
+ }
1993
+ function normalizeFormulaResultValue(value) {
1994
+ return value == null || typeof value == "number" || typeof value == "string" || typeof value == "boolean" || Array.isArray(value) && value.every(isFormulaResultRow) ? value : null;
1995
+ }
1996
+ function isFormulaResultRow(value) {
1997
+ return Array.isArray(value) && value.every(
1998
+ (item) => item == null || typeof item == "number" || typeof item == "string" || typeof item == "boolean"
1999
+ );
2000
+ }
2001
+
2002
+ // src/plugin.ts
2003
+ var DEFAULT_RUST_FORMULA_PLUGIN_CONFIG = {}, UniverRustFormulaEnginePlugin = class extends UniverProFormulaEnginePlugin {
2004
+ constructor(_config = DEFAULT_RUST_FORMULA_PLUGIN_CONFIG, _injector, _configService) {
2005
+ super(_config, _injector, _configService);
2006
+ this._config = _config;
2007
+ this._injector = _injector;
2008
+ this._configService = _configService;
2009
+ }
2010
+ _config;
2011
+ _injector;
2012
+ _configService;
2013
+ static packageName = name;
2014
+ static version = version;
2015
+ onReady() {
2016
+ super.onReady(), !this._config?.notExecuteFormula && this._config?.useRustEngine !== !1 && touchDependencies(this._injector, [[RustEngineSyncController], [RustSameRuntimeProjectionController]]);
2017
+ }
2018
+ /**
2019
+ * UniverProFormulaEnginePlugin invokes this hook before its single DI
2020
+ * registration pass.
2021
+ */
2022
+ _extendFormulaExecutionDependencies(dependencies) {
2023
+ if (this._config?.useRustEngine !== !1 && !this._config?.notExecuteFormula) {
2024
+ let calculateServiceIndex = dependencies.findIndex(
2025
+ (dependency) => Array.isArray(dependency) && dependency[0] === ICalculateFormulaService
2026
+ ), rustDependencies = [
2027
+ [RustEngineSyncController],
2028
+ [RustSameRuntimeProjectionController],
2029
+ [IRustCalculateFormulaService, { useClass: RustCalculateFormulaService }],
2030
+ // eslint-disable-next-line react/no-unnecessary-use-prefix
2031
+ [ICalculateFormulaService, { useFactory: () => this._injector.get(IRustCalculateFormulaService) }]
2032
+ ];
2033
+ calculateServiceIndex >= 0 && dependencies.splice(calculateServiceIndex, 1), dependencies.push(...rustDependencies);
2034
+ }
2035
+ }
2036
+ };
2037
+ setDependencies4(UniverRustFormulaEnginePlugin, [Injector, IConfigService2], 1);
2038
+
2039
+ // src/services/workbook-snapshot-materializer.ts
2040
+ import { Buffer } from "node:buffer";
2041
+ async function materializeWorkbookSnapshot(workbook, unitID, rev, dirtyInput) {
2042
+ await loadNativeBinding();
2043
+ let result = await materializeWorkbookSnapshotOnRust(
2044
+ Buffer.from(JSON.stringify(workbook)),
2045
+ unitID,
2046
+ rev,
2047
+ dirtyInput == null ? void 0 : JSON.stringify(dirtyInput)
2048
+ ), draft = JSON.parse(result.snapshotDraftJson.toString("utf8")), encoder = new TextEncoder(), sheets = Object.fromEntries(
2049
+ Object.entries(draft.workbook.sheets).map(([sheetID, sheet]) => {
2050
+ let { originalMetaJson: originalMetaJson2, ...meta } = sheet;
2051
+ return [sheetID, { ...meta, originalMeta: encoder.encode(originalMetaJson2) }];
2052
+ })
2053
+ ), { originalMetaJson, ...workbookMeta } = draft.workbook;
2054
+ return {
2055
+ snapshot: {
2056
+ unitID: draft.unitID,
2057
+ type: draft.type,
2058
+ rev: draft.rev,
2059
+ workbook: {
2060
+ ...workbookMeta,
2061
+ sheets,
2062
+ originalMeta: encoder.encode(originalMetaJson)
2063
+ },
2064
+ doc: void 0,
2065
+ slide: void 0,
2066
+ board: void 0
2067
+ },
2068
+ sheetBlocks: Object.fromEntries(result.sheetBlocks.map(({ sheetId, blocks }) => [sheetId, blocks])),
2069
+ warnings: JSON.parse(result.warningsJson.toString("utf8")),
2070
+ calculationStats: JSON.parse(result.calculationStatsJson.toString("utf8"))
2071
+ };
2072
+ }
2073
+ export {
2074
+ IRustCalculateFormulaService,
2075
+ RUST_FORMULA_RELEVANT_MUTATIONS,
2076
+ RUST_INCREMENTAL_DEPENDENCY_MUTATIONS,
2077
+ RUST_UPSERT_REFERENCE_DATA_MUTATION_ID,
2078
+ RustCalculateFormulaService,
2079
+ RustEngineSyncController,
2080
+ RustFormulaProjectionService,
2081
+ UniverRustFormulaEnginePlugin,
2082
+ analyzeNumberFormatBatch,
2083
+ applyMutationOnRust,
2084
+ buildLexerTreeOnRust,
2085
+ buildRustDependencyGraphOnRust,
2086
+ buildSequenceNodesOnRust,
2087
+ checkIfAddBracketOnRust,
2088
+ clearRustFormulaDependenciesOnRust,
2089
+ clearRustFormulaDirtyOnRust,
2090
+ createFormulaProjectionDesyncSignal,
2091
+ disposeAllWorkbooksOnRust,
2092
+ disposeWorkbookOnRust,
2093
+ executeOnRust,
2094
+ formatNumberBatch,
2095
+ getNativeBindingSource,
2096
+ getRustCellOnRust,
2097
+ getRustDirtyDependenciesOnRust,
2098
+ getRustFormulaDataOnRust,
2099
+ getRustModelStats,
2100
+ getRustSheetStateOnRust,
2101
+ isRustFormulaRelevantMutation,
2102
+ isRustIncrementalDependencyMutation,
2103
+ loadNativeBinding,
2104
+ loadSnapshotOnRust,
2105
+ markRustFormulaDirtyOnRust,
2106
+ materializeWorkbookSnapshot,
2107
+ materializeWorkbookSnapshotOnRust,
2108
+ parseNumberFormatBatch,
2109
+ parseNumberFormatMatrixBatch,
2110
+ rustExecutionOutputToFormulaCalculationPatch,
2111
+ serializeRuntimeWorkbookSnapshot,
2112
+ serializeRuntimeWorkbookSnapshots,
2113
+ syncRustFormulaDependenciesOnRust
2114
+ };