@univerjs-pro/engine-formula-rust 1.0.0-rc.0 → 1.0.1
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.
- package/lib/cjs/index.cjs +225 -117
- package/lib/es/index.js +227 -117
- package/lib/types/index.d.ts +69 -25
- package/package.json +36 -47
package/lib/es/index.js
CHANGED
|
@@ -80,11 +80,6 @@ function loadSnapshotOnRust(snapshotJson) {
|
|
|
80
80
|
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
81
81
|
return nativeBinding.rustEngineLoadSnapshot(snapshotJson);
|
|
82
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
83
|
function applyMutationOnRust(mutationJson) {
|
|
89
84
|
if (!nativeBinding)
|
|
90
85
|
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
@@ -135,11 +130,6 @@ function syncRustFormulaDependenciesOnRust(inputJson) {
|
|
|
135
130
|
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
136
131
|
return nativeBinding.rustEngineSyncFormulaDependencies(inputJson);
|
|
137
132
|
}
|
|
138
|
-
function inspectRustFormulaDependencyGraphOnRust() {
|
|
139
|
-
if (!nativeBinding)
|
|
140
|
-
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
141
|
-
return nativeBinding.rustEngineInspectFormulaDependencyGraph();
|
|
142
|
-
}
|
|
143
133
|
function markRustFormulaDirtyOnRust(inputJson) {
|
|
144
134
|
if (!nativeBinding)
|
|
145
135
|
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
@@ -155,28 +145,43 @@ function clearRustFormulaDirtyOnRust() {
|
|
|
155
145
|
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
156
146
|
return nativeBinding.rustEngineClearFormulaDirty();
|
|
157
147
|
}
|
|
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
148
|
function materializeWorkbookSnapshotOnRust(workbookJson, unitId, rev, dirtyInputJson) {
|
|
169
149
|
if (!nativeBinding)
|
|
170
150
|
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
171
151
|
return nativeBinding.rustMaterializeWorkbookSnapshot(workbookJson, unitId, rev, dirtyInputJson);
|
|
172
152
|
}
|
|
153
|
+
var RustFormulaEngineSession = class {
|
|
154
|
+
_engine = null;
|
|
155
|
+
_disposed = !1;
|
|
156
|
+
async initialize() {
|
|
157
|
+
if (this._disposed) throw new Error("Rust formula engine session is disposed");
|
|
158
|
+
if (this._engine) return;
|
|
159
|
+
let binding = await loadNativeBinding();
|
|
160
|
+
if (this._disposed) throw new Error("Rust formula engine session is disposed");
|
|
161
|
+
if (!this._engine) {
|
|
162
|
+
if (typeof binding.RustFormulaEngine != "function")
|
|
163
|
+
throw new Error("Native formula binding lacks instance isolation; upgrade engine-formula-rust-binding");
|
|
164
|
+
this._engine = new binding.RustFormulaEngine();
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
get binding() {
|
|
168
|
+
if (this._disposed) throw new Error("Rust formula engine session is disposed");
|
|
169
|
+
if (!this._engine) throw new Error("Rust formula engine session is not initialized");
|
|
170
|
+
return this._engine;
|
|
171
|
+
}
|
|
172
|
+
dispose() {
|
|
173
|
+
this._disposed || (this._disposed = !0, this._engine?.dispose(), this._engine = null);
|
|
174
|
+
}
|
|
175
|
+
};
|
|
173
176
|
|
|
174
177
|
// src/controllers/rust-engine-sync.controller.ts
|
|
175
178
|
import { CommandType, Disposable, ICommandService, setDependencies } from "@univerjs/core";
|
|
176
179
|
|
|
177
180
|
// src/services/rust-formula-projection.service.ts
|
|
178
181
|
import {
|
|
182
|
+
BooleanNumber,
|
|
179
183
|
CellValueType,
|
|
184
|
+
FormulaType,
|
|
180
185
|
ObjectMatrix
|
|
181
186
|
} from "@univerjs/core";
|
|
182
187
|
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_UPSERT_PROJECTION_WORKBOOK_MUTATION_ID = "formula.mutation.upsert-projection-workbook", RUST_SET_SUPER_TABLES_MUTATION_ID = "formula.mutation.set-super-tables", RUST_FORMULA_RELEVANT_MUTATIONS = /* @__PURE__ */ new Set([
|
|
@@ -195,6 +200,11 @@ var XLSX_WORKBOOK_CALCULATION_RESOURCE = "UNIVER_CLI_XLSX_WORKBOOK_CALCULATION_P
|
|
|
195
200
|
"sheet.mutation.set-col-visible",
|
|
196
201
|
"sheet.mutation.set-row-hidden",
|
|
197
202
|
"sheet.mutation.set-row-visible",
|
|
203
|
+
"sheet.mutation.set-table-filter",
|
|
204
|
+
"sheet.mutation.set-filter-range",
|
|
205
|
+
"sheet.mutation.set-filter-criteria",
|
|
206
|
+
"sheet.mutation.remove-filter",
|
|
207
|
+
"sheet.mutation.re-calc-filter",
|
|
198
208
|
"sheet.mutation.set-worksheet-name",
|
|
199
209
|
"sheet.mutation.reorder-range",
|
|
200
210
|
"sheet.mutation.set-worksheet-row-count",
|
|
@@ -268,11 +278,18 @@ function serializeRuntimeWorkbookSnapshots(workbooks) {
|
|
|
268
278
|
}
|
|
269
279
|
function serializeRuntimeWorkbookSnapshot(input) {
|
|
270
280
|
let { snapshot } = input, sheetOrder = snapshot.sheetOrder?.length > 0 ? snapshot.sheetOrder : Object.keys(snapshot.sheets ?? {}), calculation = serializeCalculation(snapshot), precisionAsDisplayed = calculation?.fullPrecision === !1, sheets = sheetOrder.map(
|
|
271
|
-
(sheetId) => serializeSheetSnapshot(
|
|
281
|
+
(sheetId) => serializeSheetSnapshot(
|
|
282
|
+
sheetId,
|
|
283
|
+
snapshot.sheets?.[sheetId],
|
|
284
|
+
snapshot.styles,
|
|
285
|
+
precisionAsDisplayed,
|
|
286
|
+
input.styleResolver
|
|
287
|
+
)
|
|
272
288
|
).filter((sheet) => sheet != null);
|
|
273
289
|
return {
|
|
274
290
|
unitId: input.unitId || snapshot.id,
|
|
275
291
|
name: snapshot.name,
|
|
292
|
+
dateSystem: snapshot.dateSystem,
|
|
276
293
|
sheets,
|
|
277
294
|
...calculation ? { calculation } : {},
|
|
278
295
|
resources: serializeResources(snapshot),
|
|
@@ -340,13 +357,16 @@ function otherFormulaDataToUnitOtherData(otherFormulaData) {
|
|
|
340
357
|
if (!colMap) return;
|
|
341
358
|
let row = Number(rowKey), rowData = {};
|
|
342
359
|
formulaData[row] = rowData, Object.entries(colMap).forEach(([colKey, value]) => {
|
|
343
|
-
rowData[Number(colKey)] =
|
|
360
|
+
rowData[Number(colKey)] = otherFormulaResultFromRustValue(value);
|
|
344
361
|
});
|
|
345
362
|
});
|
|
346
363
|
});
|
|
347
364
|
});
|
|
348
365
|
}), unitOtherData;
|
|
349
366
|
}
|
|
367
|
+
function otherFormulaResultFromRustValue(value) {
|
|
368
|
+
return Array.isArray(value) ? value.map((row) => (Array.isArray(row) ? row : [row]).map((cell) => cellDataFromRustValue(cell))) : [[cellDataFromRustValue(value)]];
|
|
369
|
+
}
|
|
350
370
|
function createFormulaProjectionDesyncSignal(reason, error, mutationId) {
|
|
351
371
|
return {
|
|
352
372
|
reason,
|
|
@@ -355,12 +375,20 @@ function createFormulaProjectionDesyncSignal(reason, error, mutationId) {
|
|
|
355
375
|
};
|
|
356
376
|
}
|
|
357
377
|
var RustFormulaProjectionService = class {
|
|
378
|
+
engine = new RustFormulaEngineSession();
|
|
379
|
+
dispose() {
|
|
380
|
+
this.engine.dispose();
|
|
381
|
+
}
|
|
358
382
|
_nativeLoaded = !1;
|
|
359
383
|
async load(workbooks) {
|
|
360
384
|
await this._ensureNativeLoaded();
|
|
361
385
|
try {
|
|
362
386
|
return {
|
|
363
|
-
stats: JSON.parse(
|
|
387
|
+
stats: JSON.parse(
|
|
388
|
+
this.engine.binding.rustEngineLoadSnapshot(
|
|
389
|
+
JSON.stringify(serializeRuntimeWorkbookSnapshots(workbooks))
|
|
390
|
+
)
|
|
391
|
+
)
|
|
364
392
|
};
|
|
365
393
|
} catch (error) {
|
|
366
394
|
return {
|
|
@@ -373,7 +401,9 @@ var RustFormulaProjectionService = class {
|
|
|
373
401
|
await this._ensureNativeLoaded();
|
|
374
402
|
try {
|
|
375
403
|
return {
|
|
376
|
-
stats: JSON.parse(
|
|
404
|
+
stats: JSON.parse(
|
|
405
|
+
this.engine.binding.rustEngineApplyMutation(JSON.stringify(normalizeRustEngineMutation(mutation)))
|
|
406
|
+
),
|
|
377
407
|
dependencyInvalidated: !isRustIncrementalDependencyMutation(mutation.id)
|
|
378
408
|
};
|
|
379
409
|
} catch (error) {
|
|
@@ -385,16 +415,16 @@ var RustFormulaProjectionService = class {
|
|
|
385
415
|
}
|
|
386
416
|
}
|
|
387
417
|
async syncFormulaDependencies(input) {
|
|
388
|
-
return await this._ensureNativeLoaded(), JSON.parse(
|
|
418
|
+
return await this._ensureNativeLoaded(), JSON.parse(this.engine.binding.rustEngineSyncFormulaDependencies(JSON.stringify(input)));
|
|
389
419
|
}
|
|
390
420
|
async markDirty(input) {
|
|
391
|
-
return await this._ensureNativeLoaded(), JSON.parse(
|
|
421
|
+
return await this._ensureNativeLoaded(), JSON.parse(this.engine.binding.rustEngineMarkFormulaDirty(JSON.stringify(input)));
|
|
392
422
|
}
|
|
393
423
|
async calculateDirty(maxIteration = 1) {
|
|
394
424
|
await this._ensureNativeLoaded();
|
|
395
425
|
try {
|
|
396
426
|
let output = JSON.parse(
|
|
397
|
-
|
|
427
|
+
this.engine.binding.rustEngineExecuteDirtyFormulas(maxIteration, !1, !1, !0)
|
|
398
428
|
);
|
|
399
429
|
return rustExecutionOutputToFormulaCalculationPatch(output);
|
|
400
430
|
} catch (error) {
|
|
@@ -409,7 +439,7 @@ var RustFormulaProjectionService = class {
|
|
|
409
439
|
async reset() {
|
|
410
440
|
await this._ensureNativeLoaded();
|
|
411
441
|
try {
|
|
412
|
-
return
|
|
442
|
+
return this.engine.binding.rustEngineClearFormulaDirty(), this.engine.binding.rustEngineClearFormulaDependencies(
|
|
413
443
|
JSON.stringify({
|
|
414
444
|
unitId: "",
|
|
415
445
|
clearSheetFormulas: !0,
|
|
@@ -417,7 +447,11 @@ var RustFormulaProjectionService = class {
|
|
|
417
447
|
clearOtherFormulas: !0
|
|
418
448
|
})
|
|
419
449
|
), {
|
|
420
|
-
stats: JSON.parse(
|
|
450
|
+
stats: JSON.parse(
|
|
451
|
+
this.engine.binding.rustEngineLoadSnapshot(
|
|
452
|
+
JSON.stringify({ workbooks: [] })
|
|
453
|
+
)
|
|
454
|
+
)
|
|
421
455
|
};
|
|
422
456
|
} catch (error) {
|
|
423
457
|
return {
|
|
@@ -429,7 +463,7 @@ var RustFormulaProjectionService = class {
|
|
|
429
463
|
async disposeWorkbook(unitId) {
|
|
430
464
|
await this._ensureNativeLoaded();
|
|
431
465
|
try {
|
|
432
|
-
return { stats: JSON.parse(
|
|
466
|
+
return { stats: JSON.parse(this.engine.binding.rustEngineDisposeWorkbook(unitId)) };
|
|
433
467
|
} catch (error) {
|
|
434
468
|
return {
|
|
435
469
|
desync: createFormulaProjectionDesyncSignal("workbook-dispose-failed", error),
|
|
@@ -438,7 +472,7 @@ var RustFormulaProjectionService = class {
|
|
|
438
472
|
}
|
|
439
473
|
}
|
|
440
474
|
async _ensureNativeLoaded() {
|
|
441
|
-
this._nativeLoaded || (await
|
|
475
|
+
this._nativeLoaded || (await this.engine.initialize(), this._nativeLoaded = !0);
|
|
442
476
|
}
|
|
443
477
|
};
|
|
444
478
|
function normalizeRustEngineMutation(mutation) {
|
|
@@ -880,19 +914,19 @@ function extractDefinedNames(snapshot) {
|
|
|
880
914
|
}
|
|
881
915
|
return {};
|
|
882
916
|
}
|
|
883
|
-
function serializeSheetSnapshot(sheetId, sheet, styles, precisionAsDisplayed) {
|
|
917
|
+
function serializeSheetSnapshot(sheetId, sheet, styles, precisionAsDisplayed, styleResolver) {
|
|
884
918
|
return sheet ? {
|
|
885
919
|
sheetId: sheet.id ?? sheetId,
|
|
886
920
|
name: sheet.name,
|
|
887
921
|
rowCount: sheet.rowCount ?? 0,
|
|
888
922
|
columnCount: sheet.columnCount ?? 0,
|
|
889
923
|
transitionEvaluation: sheet.transitionEvaluation === !0,
|
|
890
|
-
cellData: serializeCellData(sheet.cellData, styles, precisionAsDisplayed),
|
|
924
|
+
cellData: serializeCellData(sheet.cellData, styles, precisionAsDisplayed, styleResolver),
|
|
891
925
|
rowData: serializeVisibilityData(sheet.rowData),
|
|
892
926
|
columnData: serializeVisibilityData(sheet.columnData)
|
|
893
927
|
} : null;
|
|
894
928
|
}
|
|
895
|
-
function serializeCellData(cellData = {}, styles, precisionAsDisplayed = !1) {
|
|
929
|
+
function serializeCellData(cellData = {}, styles, precisionAsDisplayed = !1, styleResolver) {
|
|
896
930
|
let result = {}, rawCellData = cellData instanceof ObjectMatrix ? cellData.getMatrix() : cellData;
|
|
897
931
|
for (let [rowKey, row] of Object.entries(rawCellData ?? {})) {
|
|
898
932
|
if (!row)
|
|
@@ -901,13 +935,15 @@ function serializeCellData(cellData = {}, styles, precisionAsDisplayed = !1) {
|
|
|
901
935
|
for (let [colKey, cell] of Object.entries(row)) {
|
|
902
936
|
if (!cell || typeof cell != "object")
|
|
903
937
|
continue;
|
|
904
|
-
let cellRecord = cell, value = {};
|
|
905
|
-
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") {
|
|
938
|
+
let cellRecord = cell, resolvedStyle = styleResolver?.getStyleByCell(cell), value = {};
|
|
939
|
+
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.ft == "number" && (value.ft = cellRecord.ft), (cellRecord.fd === BooleanNumber.FALSE || cellRecord.fd === BooleanNumber.TRUE) && (value.fd = cellRecord.fd), typeof cellRecord.si == "string" && (value.si = cellRecord.si), typeof cellRecord.ref == "string") {
|
|
906
940
|
let hasFormula = typeof cellRecord.f == "string" && cellRecord.f.length > 0;
|
|
907
941
|
typeof cellRecord.si == "string" || hasFormula && isLegacyArrayFormulaCell(cellRecord) ? value.ref = cellRecord.ref : hasFormula && (value.dynamicArrayRef = cellRecord.ref);
|
|
908
942
|
}
|
|
909
|
-
|
|
910
|
-
|
|
943
|
+
typeof cellRecord.xf == "string" && (value.xf = cellRecord.xf), "s" in cellRecord && (value.s = cellRecord.s);
|
|
944
|
+
let numberFormat = resolveNumberFormatPattern(cellRecord.s, styles, resolvedStyle);
|
|
945
|
+
if (numberFormat !== void 0 && (value.numberFormat = numberFormat), precisionAsDisplayed && typeof cellRecord.f == "string") {
|
|
946
|
+
let displayPrecision = inferDisplayPrecision(cellRecord.s, styles, resolvedStyle);
|
|
911
947
|
displayPrecision !== void 0 && (value.displayPrecision = displayPrecision);
|
|
912
948
|
}
|
|
913
949
|
Object.keys(value).length > 0 && (serializedRow[Number(colKey)] = value);
|
|
@@ -930,23 +966,19 @@ function serializeCellDataInRanges(cellData, ranges) {
|
|
|
930
966
|
return result;
|
|
931
967
|
}
|
|
932
968
|
function isLegacyArrayFormulaCell(cell) {
|
|
933
|
-
|
|
934
|
-
if (!custom || typeof custom != "object")
|
|
935
|
-
return !1;
|
|
936
|
-
let xlsx = custom._xlsx;
|
|
937
|
-
return xlsx != null && typeof xlsx == "object" && xlsx.legacyArrayFormula === !0;
|
|
969
|
+
return cell.ft === FormulaType.ARRAY && cell.fd !== BooleanNumber.TRUE;
|
|
938
970
|
}
|
|
939
|
-
function inferDisplayPrecision(styleId, styles) {
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
971
|
+
function inferDisplayPrecision(styleId, styles, resolvedStyle) {
|
|
972
|
+
let pattern = resolveNumberFormatPattern(styleId, styles, resolvedStyle);
|
|
973
|
+
return pattern === void 0 ? void 0 : inferFixedNumberFormatPrecision(pattern);
|
|
974
|
+
}
|
|
975
|
+
function resolveNumberFormatPattern(styleRef, styles, resolvedStyle) {
|
|
976
|
+
let style = resolvedStyle ?? (typeof styleRef == "string" && styles && typeof styles == "object" ? styles[styleRef] : styleRef);
|
|
977
|
+
if (!style || typeof style != "object") return;
|
|
945
978
|
let numberFormat = style.n;
|
|
946
|
-
if (!numberFormat || typeof numberFormat != "object")
|
|
947
|
-
return;
|
|
979
|
+
if (!numberFormat || typeof numberFormat != "object") return;
|
|
948
980
|
let pattern = numberFormat.pattern;
|
|
949
|
-
return typeof pattern == "string" ?
|
|
981
|
+
return typeof pattern == "string" ? pattern : void 0;
|
|
950
982
|
}
|
|
951
983
|
function inferFixedNumberFormatPrecision(pattern) {
|
|
952
984
|
let cleaned = (pattern.split(";")[0] ?? pattern).replace(/"[^"]*"/gu, "").replace(/\\./gu, "").replace(/_.|\*./gu, "");
|
|
@@ -974,19 +1006,6 @@ function isRecord(value) {
|
|
|
974
1006
|
}
|
|
975
1007
|
|
|
976
1008
|
// src/controllers/rust-engine-sync.controller.ts
|
|
977
|
-
var rustEngineSyncState = {
|
|
978
|
-
snapshotEpoch: 0,
|
|
979
|
-
dependencyInvalidationEpoch: 0
|
|
980
|
-
};
|
|
981
|
-
function getRustEngineSyncState() {
|
|
982
|
-
return { ...rustEngineSyncState };
|
|
983
|
-
}
|
|
984
|
-
function markRustSnapshotLoaded() {
|
|
985
|
-
rustEngineSyncState.snapshotEpoch += 1, rustEngineSyncState.dependencyInvalidationEpoch += 1;
|
|
986
|
-
}
|
|
987
|
-
function markRustFormulaDependenciesInvalidated() {
|
|
988
|
-
rustEngineSyncState.dependencyInvalidationEpoch += 1;
|
|
989
|
-
}
|
|
990
1009
|
function emitRustEngineSyncDebugEvent(event) {
|
|
991
1010
|
let hook = globalThis.__UNIVER_RUST_FORMULA_DEBUG_HOOK__;
|
|
992
1011
|
typeof hook == "function" && hook(event);
|
|
@@ -1026,6 +1045,17 @@ var RustEngineSyncController = class extends Disposable {
|
|
|
1026
1045
|
this._initialize();
|
|
1027
1046
|
}
|
|
1028
1047
|
_commandService;
|
|
1048
|
+
engine = new RustFormulaEngineSession();
|
|
1049
|
+
_syncState = { snapshotEpoch: 0, dependencyInvalidationEpoch: 0 };
|
|
1050
|
+
getSyncState() {
|
|
1051
|
+
return { ...this._syncState };
|
|
1052
|
+
}
|
|
1053
|
+
_markSnapshotLoaded() {
|
|
1054
|
+
this._syncState.snapshotEpoch += 1, this._syncState.dependencyInvalidationEpoch += 1;
|
|
1055
|
+
}
|
|
1056
|
+
_markDependenciesInvalidated() {
|
|
1057
|
+
this._syncState.dependencyInvalidationEpoch += 1;
|
|
1058
|
+
}
|
|
1029
1059
|
_nativeReady = !1;
|
|
1030
1060
|
_snapshotLoaded = !1;
|
|
1031
1061
|
_projectionLoadPromise = null;
|
|
@@ -1059,7 +1089,7 @@ var RustEngineSyncController = class extends Disposable {
|
|
|
1059
1089
|
this._projectionDeltaBarrier = barrier;
|
|
1060
1090
|
}
|
|
1061
1091
|
async _loadProjection(workbooks) {
|
|
1062
|
-
await
|
|
1092
|
+
await this.engine.initialize(), this._nativeReady = !0;
|
|
1063
1093
|
let serializeStartedAt = performance.now(), snapshot = serializeRuntimeWorkbookSnapshots(workbooks);
|
|
1064
1094
|
this._loadSerializedSnapshot(snapshot, performance.now() - serializeStartedAt);
|
|
1065
1095
|
}
|
|
@@ -1082,20 +1112,17 @@ var RustEngineSyncController = class extends Disposable {
|
|
|
1082
1112
|
disposeProjectionWorkbook(unitId) {
|
|
1083
1113
|
if (!(!this._nativeReady || !this._snapshotLoaded))
|
|
1084
1114
|
try {
|
|
1085
|
-
|
|
1115
|
+
this.engine.binding.rustEngineDisposeWorkbook(unitId), this._markDependenciesInvalidated();
|
|
1086
1116
|
} catch {
|
|
1087
|
-
this.
|
|
1117
|
+
this.markProjectionDesynced();
|
|
1088
1118
|
}
|
|
1089
1119
|
}
|
|
1090
1120
|
dispose() {
|
|
1091
|
-
|
|
1092
|
-
this._snapshotLoaded = !1;
|
|
1093
|
-
return;
|
|
1094
|
-
}
|
|
1121
|
+
super.dispose(), this._pendingMutations.length = 0, this._projectionManagedTableUnits.clear(), this._projectionLoadPromise = null, this._projectionDeltaBarrier = Promise.resolve();
|
|
1095
1122
|
try {
|
|
1096
|
-
|
|
1123
|
+
this.engine.dispose();
|
|
1097
1124
|
} catch {
|
|
1098
|
-
this.
|
|
1125
|
+
this.markProjectionDesynced();
|
|
1099
1126
|
return;
|
|
1100
1127
|
}
|
|
1101
1128
|
this._nativeReady = !1, this._snapshotLoaded = !1;
|
|
@@ -1103,7 +1130,7 @@ var RustEngineSyncController = class extends Disposable {
|
|
|
1103
1130
|
_loadSerializedSnapshot(snapshot, serializeMs) {
|
|
1104
1131
|
let precisionAsDisplayedWorkbookCount = snapshot.workbooks.filter(
|
|
1105
1132
|
(workbook) => workbook.calculation?.fullPrecision === !1
|
|
1106
|
-
).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 ?
|
|
1133
|
+
).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 ? this.engine.binding.rustEngineLoadSnapshotBinary(snapshotBuffer) : this.engine.binding.rustEngineLoadSnapshot(snapshotJson), nativeMs = performance.now() - nativeStartedAt, nativeTimings;
|
|
1107
1134
|
try {
|
|
1108
1135
|
nativeTimings = JSON.parse(nativeOutput).timingsMs;
|
|
1109
1136
|
} catch {
|
|
@@ -1122,7 +1149,7 @@ var RustEngineSyncController = class extends Disposable {
|
|
|
1122
1149
|
transport: snapshotBuffer ? "binary-json" : "string-json",
|
|
1123
1150
|
nativeTimings
|
|
1124
1151
|
}
|
|
1125
|
-
}), this._pendingMutations.splice(0, pendingCountCoveredBySnapshot), this._snapshotLoaded = !0,
|
|
1152
|
+
}), this._pendingMutations.splice(0, pendingCountCoveredBySnapshot), this._snapshotLoaded = !0, this._markSnapshotLoaded(), this._flushPendingMutations();
|
|
1126
1153
|
}
|
|
1127
1154
|
_queueOrSyncMutation(mutation) {
|
|
1128
1155
|
if (!this._nativeReady || !this._snapshotLoaded) {
|
|
@@ -1140,9 +1167,9 @@ var RustEngineSyncController = class extends Disposable {
|
|
|
1140
1167
|
_syncMutation(mutation) {
|
|
1141
1168
|
let totalStartedAt = performance.now(), stringifyStartedAt = performance.now(), payload = JSON.stringify(normalizeRustEngineMutation(mutation)), stringifyMs = performance.now() - stringifyStartedAt, nativeStartedAt = performance.now();
|
|
1142
1169
|
try {
|
|
1143
|
-
|
|
1170
|
+
this.engine.binding.rustEngineApplyMutation(payload), isRustIncrementalDependencyMutation(mutation.id) || this._markDependenciesInvalidated();
|
|
1144
1171
|
} catch {
|
|
1145
|
-
this.
|
|
1172
|
+
this.markProjectionDesynced();
|
|
1146
1173
|
} finally {
|
|
1147
1174
|
emitRustEngineSyncDebugEvent({
|
|
1148
1175
|
type: "applyMutation",
|
|
@@ -1158,7 +1185,11 @@ var RustEngineSyncController = class extends Disposable {
|
|
|
1158
1185
|
});
|
|
1159
1186
|
}
|
|
1160
1187
|
}
|
|
1161
|
-
|
|
1188
|
+
/**
|
|
1189
|
+
* Marks the native projection as out of sync so the next mutation reloads it.
|
|
1190
|
+
* Also used by the projection controller when a background projection load fails.
|
|
1191
|
+
*/
|
|
1192
|
+
markProjectionDesynced() {
|
|
1162
1193
|
this._nativeReady = !1, this._snapshotLoaded = !1;
|
|
1163
1194
|
}
|
|
1164
1195
|
_shouldSyncMutation(command, options) {
|
|
@@ -1224,7 +1255,7 @@ import { ICalculateFormulaService } from "@univerjs/engine-formula";
|
|
|
1224
1255
|
import { UniverProFormulaEnginePlugin } from "@univerjs-pro/engine-formula";
|
|
1225
1256
|
|
|
1226
1257
|
// package.json
|
|
1227
|
-
var name = "@univerjs-pro/engine-formula-rust", version = "1.0.
|
|
1258
|
+
var name = "@univerjs-pro/engine-formula-rust", version = "1.0.1";
|
|
1228
1259
|
|
|
1229
1260
|
// src/controllers/rust-same-runtime-projection.controller.ts
|
|
1230
1261
|
import {
|
|
@@ -1272,13 +1303,16 @@ var RustSameRuntimeProjectionController = class extends Disposable2 {
|
|
|
1272
1303
|
UniverInstanceType.UNIVER_BASE
|
|
1273
1304
|
))
|
|
1274
1305
|
this._rustEngineSyncController.setProjectionManagedTableUnit(base.getUnitId()), this._rememberBaseProjectionStructure(base.getSnapshot());
|
|
1275
|
-
this._initialProjectionLoad = this._loadAllWorkbookProjections()
|
|
1306
|
+
this._initialProjectionLoad = this._loadAllWorkbookProjections().catch(() => {
|
|
1307
|
+
this._rustEngineSyncController.markProjectionDesynced();
|
|
1308
|
+
}), this.disposeWithMe(
|
|
1276
1309
|
toDisposable(
|
|
1277
1310
|
this._univerInstanceService.getTypeOfUnitAdded$(UniverInstanceType.UNIVER_SHEET).subscribe(({ unit }) => {
|
|
1278
1311
|
this._enqueueProjectionDelta(() => {
|
|
1279
1312
|
this._rustEngineSyncController.upsertProjectionWorkbook({
|
|
1280
1313
|
unitId: unit.getUnitId(),
|
|
1281
|
-
snapshot: unit.getSnapshot()
|
|
1314
|
+
snapshot: unit.getSnapshot(),
|
|
1315
|
+
styleResolver: unit.getStyles()
|
|
1282
1316
|
});
|
|
1283
1317
|
});
|
|
1284
1318
|
})
|
|
@@ -1492,7 +1526,8 @@ var RustSameRuntimeProjectionController = class extends Disposable2 {
|
|
|
1492
1526
|
async _loadAllWorkbookProjections() {
|
|
1493
1527
|
let workbooks = this._univerInstanceService.getAllUnitsForType(UniverInstanceType.UNIVER_SHEET).map((workbook) => ({
|
|
1494
1528
|
unitId: workbook.getUnitId(),
|
|
1495
|
-
snapshot: workbook.getSnapshot()
|
|
1529
|
+
snapshot: workbook.getSnapshot(),
|
|
1530
|
+
styleResolver: workbook.getStyles()
|
|
1496
1531
|
})), calculationData = this._formulaDataModel.getCalculateData(), formulaData = this._formulaDataModel.getFormulaData(), baseWorkbooks = this._univerInstanceService.getAllUnitsForType(UniverInstanceType.UNIVER_BASE).map(
|
|
1497
1532
|
(base) => this._createBaseWorkbookProjection(
|
|
1498
1533
|
base.getUnitId(),
|
|
@@ -1778,6 +1813,7 @@ import {
|
|
|
1778
1813
|
FormulaExecuteStageType,
|
|
1779
1814
|
IFeatureCalculationManagerService,
|
|
1780
1815
|
IFormulaCurrentConfigService,
|
|
1816
|
+
IDefinedNamesService,
|
|
1781
1817
|
IFormulaDependencyGenerator,
|
|
1782
1818
|
IFormulaRuntimeService,
|
|
1783
1819
|
IOtherFormulaManagerService,
|
|
@@ -1834,7 +1870,7 @@ function resultBatchSheetCounts(output) {
|
|
|
1834
1870
|
return counts;
|
|
1835
1871
|
}
|
|
1836
1872
|
var RustCalculateFormulaService = class extends Disposable3 {
|
|
1837
|
-
constructor(_configService, _currentConfigService, _runtimeService, _formulaDependencyGenerator, _featureCalculationManagerService, _otherFormulaManagerService, _commandService, _rustEngineSyncController, _formulaDataModel, _formulaReferenceDataService, _excelExternalReferenceModel, _superTableService) {
|
|
1873
|
+
constructor(_configService, _currentConfigService, _runtimeService, _formulaDependencyGenerator, _featureCalculationManagerService, _otherFormulaManagerService, _commandService, _rustEngineSyncController, _formulaDataModel, _formulaReferenceDataService, _excelExternalReferenceModel, _superTableService, _definedNamesService) {
|
|
1838
1874
|
super();
|
|
1839
1875
|
this._configService = _configService;
|
|
1840
1876
|
this._currentConfigService = _currentConfigService;
|
|
@@ -1848,6 +1884,7 @@ var RustCalculateFormulaService = class extends Disposable3 {
|
|
|
1848
1884
|
this._formulaReferenceDataService = _formulaReferenceDataService;
|
|
1849
1885
|
this._excelExternalReferenceModel = _excelExternalReferenceModel;
|
|
1850
1886
|
this._superTableService = _superTableService;
|
|
1887
|
+
this._definedNamesService = _definedNamesService;
|
|
1851
1888
|
this._commandService.hasCommand(SetFormulaCalculationResultMutation2.id) || this.disposeWithMe(this._commandService.registerCommand(SetFormulaCalculationResultMutation2)), this._commandService.hasCommand(SetArrayFormulaDataMutation.id) || this.disposeWithMe(this._commandService.registerCommand(SetArrayFormulaDataMutation));
|
|
1852
1889
|
}
|
|
1853
1890
|
_configService;
|
|
@@ -1862,6 +1899,7 @@ var RustCalculateFormulaService = class extends Disposable3 {
|
|
|
1862
1899
|
_formulaReferenceDataService;
|
|
1863
1900
|
_excelExternalReferenceModel;
|
|
1864
1901
|
_superTableService;
|
|
1902
|
+
_definedNamesService;
|
|
1865
1903
|
_executionInProgressListener$ = new Subject();
|
|
1866
1904
|
executionInProgressListener$ = this._executionInProgressListener$.asObservable();
|
|
1867
1905
|
_executionCompleteListener$ = new Subject();
|
|
@@ -1889,14 +1927,19 @@ var RustCalculateFormulaService = class extends Disposable3 {
|
|
|
1889
1927
|
this._runtimeService.setRuntimeFeatureRange(featureId, featureRange);
|
|
1890
1928
|
}
|
|
1891
1929
|
async execute(formulaDatasetConfig) {
|
|
1892
|
-
this._nativeLoaded || (await
|
|
1930
|
+
this._nativeLoaded || (await this._rustEngineSyncController.engine.initialize(), this._nativeLoaded = !0), await this._rustEngineSyncController.waitForProjectionLoad(), this._externalFormulaDatasetConfig = formulaDatasetConfig, this._currentConfigService.load(formulaDatasetConfig), this._externalRequestGeneration++, this._externalInflight.clear(), this._externalCompleted.clear(), this._runtimeService.setFormulaExecuteStage(FormulaExecuteStageType.START), this._executionInProgressListener$.next(this._runtimeService.getRuntimeState()), this._runtimeService.reset();
|
|
1893
1931
|
let cycleReferenceCount = Math.max(formulaDatasetConfig.maxIteration || 1, 1);
|
|
1894
1932
|
await this._executeLock.acquire("FORMULA_EXECUTION_LOCK", async () => {
|
|
1895
1933
|
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();
|
|
1896
1934
|
});
|
|
1897
1935
|
}
|
|
1898
1936
|
async _executeStep(maxIteration) {
|
|
1899
|
-
let syncedFeatures = this._syncRustFormulaDependencies(void 0, !0), previousFeatureSignatures = this._featureSignatureMap(syncedFeatures), executeStartedAt = performance.now(), outputJson =
|
|
1937
|
+
let syncedFeatures = this._syncRustFormulaDependencies(void 0, !0), previousFeatureSignatures = this._featureSignatureMap(syncedFeatures), executeStartedAt = performance.now(), outputJson = this._rustEngineSyncController.engine.binding.rustEngineExecuteDirtyFormulas(
|
|
1938
|
+
maxIteration,
|
|
1939
|
+
!1,
|
|
1940
|
+
!1,
|
|
1941
|
+
!0
|
|
1942
|
+
), nativeAndSerializeMs = performance.now() - executeStartedAt, parseStartedAt = performance.now(), output = JSON.parse(outputJson), calculatedNodeCount = output.calculatedNodeCount, parseMs = performance.now() - parseStartedAt;
|
|
1900
1943
|
output = await this._resolveExternalReferenceNeeds(output, maxIteration);
|
|
1901
1944
|
let applyStartedAt = performance.now(), applyBreakdown = await this._applyRustDependencyOutput(output), applyMs = performance.now() - applyStartedAt;
|
|
1902
1945
|
if (emitRustFormulaDebugEvent({
|
|
@@ -1932,7 +1975,12 @@ var RustCalculateFormulaService = class extends Disposable3 {
|
|
|
1932
1975
|
this._markRustFormulaDirty(
|
|
1933
1976
|
this._currentConfigService.getDirtyData(),
|
|
1934
1977
|
this._dirtyFeatureMapFor(changedFeatures)
|
|
1935
|
-
), executeStartedAt = performance.now(), outputJson =
|
|
1978
|
+
), executeStartedAt = performance.now(), outputJson = this._rustEngineSyncController.engine.binding.rustEngineExecuteDirtyFormulas(
|
|
1979
|
+
maxIteration,
|
|
1980
|
+
!1,
|
|
1981
|
+
!1,
|
|
1982
|
+
!0
|
|
1983
|
+
), 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({
|
|
1936
1984
|
type: "executeDirtyFormulas",
|
|
1937
1985
|
payload: {
|
|
1938
1986
|
calculatedNodeCount: output.calculatedNodeCount,
|
|
@@ -1977,7 +2025,14 @@ var RustCalculateFormulaService = class extends Disposable3 {
|
|
|
1977
2025
|
loadedRanges,
|
|
1978
2026
|
this._superTableService
|
|
1979
2027
|
) === 0) break;
|
|
1980
|
-
this._syncRustFormulaDependencies(), output = JSON.parse(
|
|
2028
|
+
this._syncRustFormulaDependencies(), output = JSON.parse(
|
|
2029
|
+
this._rustEngineSyncController.engine.binding.rustEngineExecuteDirtyFormulas(
|
|
2030
|
+
maxIteration,
|
|
2031
|
+
!1,
|
|
2032
|
+
!1,
|
|
2033
|
+
!0
|
|
2034
|
+
)
|
|
2035
|
+
);
|
|
1981
2036
|
}
|
|
1982
2037
|
return output;
|
|
1983
2038
|
}
|
|
@@ -2151,7 +2206,7 @@ var RustCalculateFormulaService = class extends Disposable3 {
|
|
|
2151
2206
|
};
|
|
2152
2207
|
}
|
|
2153
2208
|
_syncRustFormulaDependencies(dirtyUnitFeatureMapOverride, includeExternalReferences = !1) {
|
|
2154
|
-
let syncState =
|
|
2209
|
+
let syncState = this._rustEngineSyncController.getSyncState(), externalReferences = includeExternalReferences ? this._externalFormulaDatasetConfig?.externalReferences ?? {} : void 0, externalReferenceSignature = externalReferences ? JSON.stringify(externalReferences) : this._syncedExternalReferenceSignature, shouldSendExternalReferences = includeExternalReferences && (externalReferenceSignature !== "{}" || this._syncedExternalReferenceSignature !== "{}"), rebuildSheetFormulas = this._syncedSnapshotEpoch !== syncState.snapshotEpoch || this._syncedDependencyInvalidationEpoch !== syncState.dependencyInvalidationEpoch || shouldSendExternalReferences, collectStartedAt = performance.now(), state = this._collectRustFormulaDependencySyncState(), collectMs = performance.now() - collectStartedAt;
|
|
2155
2210
|
if (!(shouldSendExternalReferences || rebuildSheetFormulas || state.featureCalculations.length > 0 || state.otherFormulas.length > 0))
|
|
2156
2211
|
return emitRustFormulaDebugEvent({
|
|
2157
2212
|
type: "syncDependencies",
|
|
@@ -2175,7 +2230,7 @@ var RustCalculateFormulaService = class extends Disposable3 {
|
|
|
2175
2230
|
featureCalculations: state.featureCalculations,
|
|
2176
2231
|
otherFormulas: state.otherFormulas,
|
|
2177
2232
|
...shouldSendExternalReferences ? { externalReferences } : {}
|
|
2178
|
-
}), stringifyMs = performance.now() - stringifyStartedAt, nativeStartedAt = performance.now(), outputJson =
|
|
2233
|
+
}), stringifyMs = performance.now() - stringifyStartedAt, nativeStartedAt = performance.now(), outputJson = this._rustEngineSyncController.engine.binding.rustEngineSyncFormulaDependencies(inputJson), nativeMs = performance.now() - nativeStartedAt, parseStartedAt = performance.now(), output = JSON.parse(outputJson), parseMs = performance.now() - parseStartedAt;
|
|
2179
2234
|
return emitRustFormulaDebugEvent({
|
|
2180
2235
|
type: "syncDependencies",
|
|
2181
2236
|
payload: {
|
|
@@ -2197,7 +2252,7 @@ var RustCalculateFormulaService = class extends Disposable3 {
|
|
|
2197
2252
|
}
|
|
2198
2253
|
_syncRustFormulaDependencyDefinitions() {
|
|
2199
2254
|
let state = this._collectRustFormulaDependencySyncState();
|
|
2200
|
-
return
|
|
2255
|
+
return this._rustEngineSyncController.engine.binding.rustEngineSyncFormulaDependencies(
|
|
2201
2256
|
JSON.stringify({
|
|
2202
2257
|
rebuildSheetFormulas: !1,
|
|
2203
2258
|
featureCalculations: state.featureCalculations,
|
|
@@ -2272,7 +2327,7 @@ var RustCalculateFormulaService = class extends Disposable3 {
|
|
|
2272
2327
|
dirtyUnitOtherFormulaMap: dirtyData.dirtyUnitOtherFormulaMap,
|
|
2273
2328
|
dirtyNameMap: dirtyData.dirtyNameMap,
|
|
2274
2329
|
dirtyDefinedNameMap: dirtyData.dirtyDefinedNameMap
|
|
2275
|
-
}, stringifyStartedAt = performance.now(), inputJson = JSON.stringify(payload), stringifyMs = performance.now() - stringifyStartedAt, nativeStartedAt = performance.now(), outputJson =
|
|
2330
|
+
}, stringifyStartedAt = performance.now(), inputJson = JSON.stringify(payload), stringifyMs = performance.now() - stringifyStartedAt, nativeStartedAt = performance.now(), outputJson = this._rustEngineSyncController.engine.binding.rustEngineMarkFormulaDirty(inputJson), nativeMs = performance.now() - nativeStartedAt, rustTimings;
|
|
2276
2331
|
try {
|
|
2277
2332
|
rustTimings = JSON.parse(outputJson).timings;
|
|
2278
2333
|
} catch {
|
|
@@ -2359,16 +2414,23 @@ var RustCalculateFormulaService = class extends Disposable3 {
|
|
|
2359
2414
|
if (!unitData) return result;
|
|
2360
2415
|
for (let [unitId, sheets] of Object.entries(unitData)) {
|
|
2361
2416
|
result[unitId] = {};
|
|
2417
|
+
let styles = this._currentConfigService.getUnitStylesData()[unitId], sheetNames = Object.fromEntries(
|
|
2418
|
+
Object.entries(this._currentConfigService.getSheetNameMap()[unitId] ?? {}).map(([name2, id]) => [
|
|
2419
|
+
id,
|
|
2420
|
+
name2
|
|
2421
|
+
])
|
|
2422
|
+
);
|
|
2362
2423
|
for (let [sheetId, sheet] of Object.entries(sheets))
|
|
2363
2424
|
result[unitId][sheetId] = {
|
|
2364
|
-
|
|
2425
|
+
name: sheetNames[sheetId],
|
|
2426
|
+
cellData: this._serializeCellData(sheet.cellData, styles),
|
|
2365
2427
|
rowCount: sheet.rowCount ?? 0,
|
|
2366
2428
|
columnCount: sheet.columnCount ?? 0
|
|
2367
2429
|
};
|
|
2368
2430
|
}
|
|
2369
2431
|
return result;
|
|
2370
2432
|
}
|
|
2371
|
-
_serializeCellData(cellData) {
|
|
2433
|
+
_serializeCellData(cellData, styles) {
|
|
2372
2434
|
let result = {};
|
|
2373
2435
|
if (!cellData || typeof cellData != "object") return result;
|
|
2374
2436
|
let data = typeof cellData.getMatrix == "function" ? cellData.getMatrix() : cellData;
|
|
@@ -2378,13 +2440,23 @@ var RustCalculateFormulaService = class extends Disposable3 {
|
|
|
2378
2440
|
result[row] = {};
|
|
2379
2441
|
for (let [colStr, cell] of Object.entries(cols)) {
|
|
2380
2442
|
let col = Number(colStr);
|
|
2381
|
-
Number.isFinite(col)
|
|
2443
|
+
if (!Number.isFinite(col))
|
|
2444
|
+
continue;
|
|
2445
|
+
result[row][col] = {
|
|
2382
2446
|
v: cell?.v ?? null,
|
|
2383
2447
|
t: cell?.t ?? void 0,
|
|
2384
2448
|
p: cell?.p ?? void 0,
|
|
2385
2449
|
f: cell?.f ?? void 0,
|
|
2386
2450
|
s: cell?.s ?? void 0
|
|
2387
|
-
}
|
|
2451
|
+
};
|
|
2452
|
+
let style = styles?.getStyleByCell(cell);
|
|
2453
|
+
if (style && typeof style == "object") {
|
|
2454
|
+
let numberFormat = style.n;
|
|
2455
|
+
if (numberFormat && typeof numberFormat == "object") {
|
|
2456
|
+
let pattern = numberFormat.pattern;
|
|
2457
|
+
typeof pattern == "string" && (result[row][col].numberFormat = pattern);
|
|
2458
|
+
}
|
|
2459
|
+
}
|
|
2388
2460
|
}
|
|
2389
2461
|
}
|
|
2390
2462
|
}
|
|
@@ -2393,7 +2465,9 @@ var RustCalculateFormulaService = class extends Disposable3 {
|
|
|
2393
2465
|
_applyRustOutput(_output) {
|
|
2394
2466
|
}
|
|
2395
2467
|
async _applyRustDependencyOutput(output) {
|
|
2396
|
-
let convertStartedAt = performance.now(), patch = rustExecutionOutputToFormulaCalculationPatch(output)
|
|
2468
|
+
let convertStartedAt = performance.now(), patch = rustExecutionOutputToFormulaCalculationPatch(output);
|
|
2469
|
+
this._mergeRuntimeUnitData(patch.unitData);
|
|
2470
|
+
let convertMs = performance.now() - convertStartedAt, commandStartedAt = performance.now();
|
|
2397
2471
|
return (patch.arrayFormulaRange || patch.arrayFormulaCellData) && (this._formulaDataModel.setArrayFormulaRange(patch.arrayFormulaRange ?? {}), this._formulaDataModel.setArrayFormulaCellData(patch.arrayFormulaCellData ?? {}), await this._commandService.executeCommand(
|
|
2398
2472
|
SetArrayFormulaDataMutation.id,
|
|
2399
2473
|
{
|
|
@@ -2420,8 +2494,22 @@ var RustCalculateFormulaService = class extends Disposable3 {
|
|
|
2420
2494
|
commandMs: performance.now() - commandStartedAt
|
|
2421
2495
|
};
|
|
2422
2496
|
}
|
|
2497
|
+
_mergeRuntimeUnitData(unitData) {
|
|
2498
|
+
let runtimeUnitData = this._runtimeService.getUnitData();
|
|
2499
|
+
Object.entries(unitData).forEach(([unitId, sheetMap]) => {
|
|
2500
|
+
if (!sheetMap) return;
|
|
2501
|
+
let runtimeSheetMap = runtimeUnitData[unitId] ??= {};
|
|
2502
|
+
Object.entries(sheetMap).forEach(([sheetId, cellData]) => {
|
|
2503
|
+
if (!cellData) return;
|
|
2504
|
+
let runtimeMatrix = runtimeSheetMap[sheetId] ??= new ObjectMatrix3();
|
|
2505
|
+
new ObjectMatrix3(cellData).forValue((row, column, cell) => {
|
|
2506
|
+
runtimeMatrix.setValue(row, column, cell);
|
|
2507
|
+
});
|
|
2508
|
+
});
|
|
2509
|
+
});
|
|
2510
|
+
}
|
|
2423
2511
|
async calculate(formulaString) {
|
|
2424
|
-
this._nativeLoaded || (await
|
|
2512
|
+
this._nativeLoaded || (await this._rustEngineSyncController.engine.initialize(), this._nativeLoaded = !0);
|
|
2425
2513
|
let unitId = "__rust_formula_calculate__", sheetId = "__sheet__", input = {
|
|
2426
2514
|
config: { maxIteration: 1, intervalCount: DEFAULT_INTERVAL_COUNT },
|
|
2427
2515
|
formulaData: {
|
|
@@ -2446,23 +2534,35 @@ var RustCalculateFormulaService = class extends Disposable3 {
|
|
|
2446
2534
|
return JSON.parse(executeOnRust(JSON.stringify(input))).runtimeData?.[unitId]?.[sheetId]?.[0]?.[0] ?? null;
|
|
2447
2535
|
}
|
|
2448
2536
|
async executeFormulas(formulas, rowData) {
|
|
2449
|
-
this._nativeLoaded || (await
|
|
2450
|
-
let unitData = this._currentConfigService.getUnitData(),
|
|
2537
|
+
this._nativeLoaded || (await this._rustEngineSyncController.engine.initialize(), this._nativeLoaded = !0), this._currentConfigService.loadDataLite(rowData);
|
|
2538
|
+
let unitData = this._currentConfigService.getUnitData(), definedNames = {};
|
|
2539
|
+
for (let [unitId, names] of Object.entries(this._definedNamesService.getAllDefinedNames()))
|
|
2540
|
+
for (let [id, name2] of Object.entries(names))
|
|
2541
|
+
definedNames[JSON.stringify([unitId, id])] = {
|
|
2542
|
+
unitId,
|
|
2543
|
+
localSheetId: name2.localSheetId === "AllDefaultWorkbook" ? void 0 : name2.localSheetId,
|
|
2544
|
+
name: name2.name,
|
|
2545
|
+
formula: name2.formulaOrRefString
|
|
2546
|
+
};
|
|
2547
|
+
let input = {
|
|
2451
2548
|
config: { maxIteration: 1, intervalCount: DEFAULT_INTERVAL_COUNT },
|
|
2452
|
-
formulaData,
|
|
2549
|
+
formulaData: {},
|
|
2550
|
+
queryFormulas: this._formulaStringMapToQueryData(formulas),
|
|
2453
2551
|
unitData: this._serializeUnitData(unitData),
|
|
2454
2552
|
dirtyRanges: [],
|
|
2455
|
-
definedNames
|
|
2553
|
+
definedNames
|
|
2456
2554
|
}, output = JSON.parse(executeOnRust(JSON.stringify(input)));
|
|
2555
|
+
if (!output.queryResults)
|
|
2556
|
+
throw new Error("Native formula binding does not support independent formula queries");
|
|
2457
2557
|
return this._formulaExecutionOutputToResultMap(formulas, output);
|
|
2458
2558
|
}
|
|
2459
2559
|
async getAllDependencyJson(_rowData) {
|
|
2460
|
-
this._nativeLoaded || (await
|
|
2560
|
+
this._nativeLoaded || (await this._rustEngineSyncController.engine.initialize(), this._nativeLoaded = !0), this._syncRustFormulaDependencyDefinitions();
|
|
2461
2561
|
let graph = this._getRustDependencyGraph(), inspect = this._getRustInspectGraph();
|
|
2462
2562
|
return this._rustAllDependencyJson(graph, inspect);
|
|
2463
2563
|
}
|
|
2464
2564
|
async getCellDependencyJson(unitId, sheetId, row, column, _rowData) {
|
|
2465
|
-
this._nativeLoaded || (await
|
|
2565
|
+
this._nativeLoaded || (await this._rustEngineSyncController.engine.initialize(), this._nativeLoaded = !0), this._syncRustFormulaDependencyDefinitions();
|
|
2466
2566
|
let graph = this._getRustDependencyGraph(unitId), all = this._rustGraphDependencyJson(graph), current = all.find(
|
|
2467
2567
|
(item) => item.unitId === unitId && item.subUnitId === sheetId && item.row === row && item.column === column
|
|
2468
2568
|
);
|
|
@@ -2476,16 +2576,18 @@ var RustCalculateFormulaService = class extends Disposable3 {
|
|
|
2476
2576
|
};
|
|
2477
2577
|
}
|
|
2478
2578
|
async getRangeDependents(unitRanges) {
|
|
2479
|
-
this._nativeLoaded || (await
|
|
2579
|
+
this._nativeLoaded || (await this._rustEngineSyncController.engine.initialize(), this._nativeLoaded = !0), this._syncRustFormulaDependencyDefinitions();
|
|
2480
2580
|
let graph = this._getRustDependencyGraph(), graphItems = this._rustGraphDependencyJson(graph), graphByCell = this._rustDependencyJsonByCell(graphItems), dirty = JSON.parse(
|
|
2481
|
-
|
|
2581
|
+
this._rustEngineSyncController.engine.binding.rustEngineGetDirtyDependencies(
|
|
2582
|
+
JSON.stringify(this._serializeUnitRanges(unitRanges))
|
|
2583
|
+
)
|
|
2482
2584
|
);
|
|
2483
2585
|
return this._uniqueDependencyJson(
|
|
2484
2586
|
(dirty.direct ?? dirty.affected ?? []).map((cell) => graphByCell.get(this._cellKey(cell))).filter(Boolean)
|
|
2485
2587
|
);
|
|
2486
2588
|
}
|
|
2487
2589
|
async getInRangeFormulas(unitRanges) {
|
|
2488
|
-
return this._nativeLoaded || (await
|
|
2590
|
+
return this._nativeLoaded || (await this._rustEngineSyncController.engine.initialize(), this._nativeLoaded = !0), this._syncRustFormulaDependencyDefinitions(), this._rustGraphDependencyJson(this._getRustDependencyGraph()).filter(
|
|
2489
2591
|
(item) => this._cellInUnitRanges(item.unitId, item.subUnitId, item.row, item.column, unitRanges)
|
|
2490
2592
|
);
|
|
2491
2593
|
}
|
|
@@ -2496,7 +2598,7 @@ var RustCalculateFormulaService = class extends Disposable3 {
|
|
|
2496
2598
|
]);
|
|
2497
2599
|
return { dependents, inRanges };
|
|
2498
2600
|
}
|
|
2499
|
-
|
|
2601
|
+
_formulaStringMapToQueryData(formulas) {
|
|
2500
2602
|
let formulaData = {};
|
|
2501
2603
|
return Object.entries(formulas).forEach(([unitId, sheetMap]) => {
|
|
2502
2604
|
sheetMap && (formulaData[unitId] = {}, Object.entries(sheetMap).forEach(([sheetId, rowMap]) => {
|
|
@@ -2504,8 +2606,7 @@ var RustCalculateFormulaService = class extends Disposable3 {
|
|
|
2504
2606
|
if (!colMap) return;
|
|
2505
2607
|
let row = Number(rowKey);
|
|
2506
2608
|
formulaData[unitId][sheetId][row] = {}, Object.entries(colMap).forEach(([colKey, formulaList]) => {
|
|
2507
|
-
|
|
2508
|
-
typeof formula == "string" && (formulaData[unitId][sheetId][row][Number(colKey)] = formula);
|
|
2609
|
+
Array.isArray(formulaList) && (formulaData[unitId][sheetId][row][Number(colKey)] = formulaList);
|
|
2509
2610
|
});
|
|
2510
2611
|
}));
|
|
2511
2612
|
}));
|
|
@@ -2519,20 +2620,27 @@ var RustCalculateFormulaService = class extends Disposable3 {
|
|
|
2519
2620
|
if (!colMap) return;
|
|
2520
2621
|
let row = Number(rowKey);
|
|
2521
2622
|
result[unitId][sheetId][row] = {}, Object.entries(colMap).forEach(([colKey, formulaList]) => {
|
|
2522
|
-
let col = Number(colKey), formulasForCell = Array.isArray(formulaList) ? formulaList : []
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2623
|
+
let col = Number(colKey), formulasForCell = Array.isArray(formulaList) ? formulaList : [];
|
|
2624
|
+
result[unitId][sheetId][row][col] = formulasForCell.map((formula, index) => ({
|
|
2625
|
+
formula,
|
|
2626
|
+
value: normalizeFormulaResultValue(
|
|
2627
|
+
output.queryResults?.[unitId]?.[sheetId]?.[row]?.[col]?.[index]?.value
|
|
2628
|
+
)
|
|
2629
|
+
}));
|
|
2526
2630
|
});
|
|
2527
2631
|
}));
|
|
2528
2632
|
}));
|
|
2529
2633
|
}), result;
|
|
2530
2634
|
}
|
|
2531
2635
|
_getRustDependencyGraph(unitId) {
|
|
2532
|
-
return JSON.parse(
|
|
2636
|
+
return JSON.parse(
|
|
2637
|
+
this._rustEngineSyncController.engine.binding.rustEngineBuildDependencyGraph(unitId)
|
|
2638
|
+
);
|
|
2533
2639
|
}
|
|
2534
2640
|
_getRustInspectGraph() {
|
|
2535
|
-
return JSON.parse(
|
|
2641
|
+
return JSON.parse(
|
|
2642
|
+
this._rustEngineSyncController.engine.binding.rustEngineInspectFormulaDependencyGraph()
|
|
2643
|
+
);
|
|
2536
2644
|
}
|
|
2537
2645
|
_rustAllDependencyJson(graph, inspect) {
|
|
2538
2646
|
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));
|
|
@@ -2641,7 +2749,8 @@ setDependencies3(RustCalculateFormulaService, [
|
|
|
2641
2749
|
FormulaDataModel2,
|
|
2642
2750
|
IFormulaReferenceDataService,
|
|
2643
2751
|
ExternalReferenceModel,
|
|
2644
|
-
ISuperTableService2
|
|
2752
|
+
ISuperTableService2,
|
|
2753
|
+
IDefinedNamesService
|
|
2645
2754
|
]);
|
|
2646
2755
|
function createRustProductExternalSyntheticUnitId(hostUnitId, referenceId) {
|
|
2647
2756
|
return `external:product:${encodeURIComponent(hostUnitId)}:${encodeURIComponent(referenceId)}`;
|
|
@@ -2737,6 +2846,7 @@ export {
|
|
|
2737
2846
|
RUST_UPSERT_REFERENCE_DATA_MUTATION_ID,
|
|
2738
2847
|
RustCalculateFormulaService,
|
|
2739
2848
|
RustEngineSyncController,
|
|
2849
|
+
RustFormulaEngineSession,
|
|
2740
2850
|
RustFormulaProjectionService,
|
|
2741
2851
|
UniverRustFormulaEnginePlugin,
|
|
2742
2852
|
analyzeNumberFormatBatch,
|