@univerjs-pro/engine-formula-rust 1.0.0-beta.2
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 +2796 -0
- package/lib/es/index.js +2775 -0
- package/lib/types/index.d.ts +926 -0
- package/package.json +49 -0
|
@@ -0,0 +1,2796 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf, __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name2 in all)
|
|
9
|
+
__defProp(target, name2, { get: all[name2], enumerable: !0 });
|
|
10
|
+
}, __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from == "object" || typeof from == "function")
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
!__hasOwnProp.call(to, key) && key !== except && __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
return to;
|
|
15
|
+
};
|
|
16
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
17
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
18
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
19
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
20
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
21
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: !0 }) : target,
|
|
22
|
+
mod
|
|
23
|
+
)), __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: !0 }), mod);
|
|
24
|
+
|
|
25
|
+
// src/index.ts
|
|
26
|
+
var index_exports = {};
|
|
27
|
+
__export(index_exports, {
|
|
28
|
+
IRustCalculateFormulaService: () => IRustCalculateFormulaService,
|
|
29
|
+
RUST_FORMULA_RELEVANT_MUTATIONS: () => RUST_FORMULA_RELEVANT_MUTATIONS,
|
|
30
|
+
RUST_INCREMENTAL_DEPENDENCY_MUTATIONS: () => RUST_INCREMENTAL_DEPENDENCY_MUTATIONS,
|
|
31
|
+
RUST_UPSERT_PROJECTION_WORKBOOK_MUTATION_ID: () => RUST_UPSERT_PROJECTION_WORKBOOK_MUTATION_ID,
|
|
32
|
+
RUST_UPSERT_REFERENCE_DATA_MUTATION_ID: () => RUST_UPSERT_REFERENCE_DATA_MUTATION_ID,
|
|
33
|
+
RustCalculateFormulaService: () => RustCalculateFormulaService,
|
|
34
|
+
RustEngineSyncController: () => RustEngineSyncController,
|
|
35
|
+
RustFormulaProjectionService: () => RustFormulaProjectionService,
|
|
36
|
+
UniverRustFormulaEnginePlugin: () => UniverRustFormulaEnginePlugin,
|
|
37
|
+
analyzeNumberFormatBatch: () => analyzeNumberFormatBatch,
|
|
38
|
+
applyMutationOnRust: () => applyMutationOnRust,
|
|
39
|
+
buildLexerTreeOnRust: () => buildLexerTreeOnRust,
|
|
40
|
+
buildRustDependencyGraphOnRust: () => buildRustDependencyGraphOnRust,
|
|
41
|
+
buildSequenceNodesOnRust: () => buildSequenceNodesOnRust,
|
|
42
|
+
checkIfAddBracketOnRust: () => checkIfAddBracketOnRust,
|
|
43
|
+
clearRustFormulaDependenciesOnRust: () => clearRustFormulaDependenciesOnRust,
|
|
44
|
+
clearRustFormulaDirtyOnRust: () => clearRustFormulaDirtyOnRust,
|
|
45
|
+
createFormulaProjectionDesyncSignal: () => createFormulaProjectionDesyncSignal,
|
|
46
|
+
createProjectionWorkbookUpsertMutation: () => createProjectionWorkbookUpsertMutation,
|
|
47
|
+
disposeAllWorkbooksOnRust: () => disposeAllWorkbooksOnRust,
|
|
48
|
+
disposeWorkbookOnRust: () => disposeWorkbookOnRust,
|
|
49
|
+
executeOnRust: () => executeOnRust,
|
|
50
|
+
formatNumberBatch: () => formatNumberBatch,
|
|
51
|
+
getNativeBindingSource: () => getNativeBindingSource,
|
|
52
|
+
getRustCellOnRust: () => getRustCellOnRust,
|
|
53
|
+
getRustDirtyDependenciesOnRust: () => getRustDirtyDependenciesOnRust,
|
|
54
|
+
getRustFormulaDataOnRust: () => getRustFormulaDataOnRust,
|
|
55
|
+
getRustModelStats: () => getRustModelStats,
|
|
56
|
+
getRustSheetStateOnRust: () => getRustSheetStateOnRust,
|
|
57
|
+
isRustFormulaRelevantMutation: () => isRustFormulaRelevantMutation,
|
|
58
|
+
isRustIncrementalDependencyMutation: () => isRustIncrementalDependencyMutation,
|
|
59
|
+
loadNativeBinding: () => loadNativeBinding,
|
|
60
|
+
loadSnapshotOnRust: () => loadSnapshotOnRust,
|
|
61
|
+
markRustFormulaDirtyOnRust: () => markRustFormulaDirtyOnRust,
|
|
62
|
+
materializeWorkbookSnapshot: () => materializeWorkbookSnapshot,
|
|
63
|
+
materializeWorkbookSnapshotOnRust: () => materializeWorkbookSnapshotOnRust,
|
|
64
|
+
parseNumberFormatBatch: () => parseNumberFormatBatch,
|
|
65
|
+
parseNumberFormatMatrixBatch: () => parseNumberFormatMatrixBatch,
|
|
66
|
+
rustExecutionOutputToFormulaCalculationPatch: () => rustExecutionOutputToFormulaCalculationPatch,
|
|
67
|
+
serializeRuntimeWorkbookSnapshot: () => serializeRuntimeWorkbookSnapshot,
|
|
68
|
+
serializeRuntimeWorkbookSnapshots: () => serializeRuntimeWorkbookSnapshots,
|
|
69
|
+
syncRustFormulaDependenciesOnRust: () => syncRustFormulaDependenciesOnRust
|
|
70
|
+
});
|
|
71
|
+
module.exports = __toCommonJS(index_exports);
|
|
72
|
+
|
|
73
|
+
// src/binding.ts
|
|
74
|
+
var import_node_module = require("node:module"), import_node_process = __toESM(require("node:process"), 1), nativeBinding = null, nativeBindingSource = null, nodeRequire = (0, import_node_module.createRequire)(__filename);
|
|
75
|
+
function getNativeBindingSource() {
|
|
76
|
+
return nativeBindingSource;
|
|
77
|
+
}
|
|
78
|
+
function formatBindingLoadError(error) {
|
|
79
|
+
return error instanceof Error ? error.message : String(error);
|
|
80
|
+
}
|
|
81
|
+
function createBindingLoadFailure(errors) {
|
|
82
|
+
return new Error(
|
|
83
|
+
[
|
|
84
|
+
"Failed to load native formula engine binding.",
|
|
85
|
+
`platform=${import_node_process.default.platform}`,
|
|
86
|
+
`arch=${import_node_process.default.arch}`,
|
|
87
|
+
"expected npm package=@univerjs-pro/engine-formula-rust-binding",
|
|
88
|
+
"attempted paths:",
|
|
89
|
+
...errors.map((item) => `- ${item}`)
|
|
90
|
+
].join(`
|
|
91
|
+
`)
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
async function loadNativeBinding() {
|
|
95
|
+
if (nativeBinding)
|
|
96
|
+
return nativeBinding;
|
|
97
|
+
if (typeof import_node_process.default < "u" && import_node_process.default.versions?.node) {
|
|
98
|
+
let errors = [];
|
|
99
|
+
try {
|
|
100
|
+
return nativeBinding = nodeRequire("@univerjs-pro/engine-formula-rust-binding"), nativeBindingSource = "@univerjs-pro/engine-formula-rust-binding", nativeBinding;
|
|
101
|
+
} catch (error) {
|
|
102
|
+
errors.push(`@univerjs-pro/engine-formula-rust-binding: ${formatBindingLoadError(error)}`);
|
|
103
|
+
}
|
|
104
|
+
throw createBindingLoadFailure(errors);
|
|
105
|
+
} else
|
|
106
|
+
throw new Error("WASM binding not yet implemented");
|
|
107
|
+
}
|
|
108
|
+
function executeOnRust(inputJson) {
|
|
109
|
+
if (!nativeBinding)
|
|
110
|
+
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
111
|
+
return nativeBinding.formulaEngineExecute(inputJson);
|
|
112
|
+
}
|
|
113
|
+
function buildLexerTreeOnRust(formula, transformSuffix = !0) {
|
|
114
|
+
if (!nativeBinding)
|
|
115
|
+
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
116
|
+
return nativeBinding.formulaLexerTreeBuild(formula, transformSuffix);
|
|
117
|
+
}
|
|
118
|
+
function buildSequenceNodesOnRust(formula) {
|
|
119
|
+
if (!nativeBinding)
|
|
120
|
+
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
121
|
+
return nativeBinding.formulaSequenceNodesBuild(formula);
|
|
122
|
+
}
|
|
123
|
+
function checkIfAddBracketOnRust(formula) {
|
|
124
|
+
if (!nativeBinding)
|
|
125
|
+
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
126
|
+
return nativeBinding.formulaCheckIfAddBracket(formula);
|
|
127
|
+
}
|
|
128
|
+
function formatNumberBatchOnRust(inputJson) {
|
|
129
|
+
if (!nativeBinding)
|
|
130
|
+
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
131
|
+
return nativeBinding.rustNumfmtFormatBatch(inputJson);
|
|
132
|
+
}
|
|
133
|
+
function parseNumberFormatInputBatchOnRust(inputJson) {
|
|
134
|
+
if (!nativeBinding)
|
|
135
|
+
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
136
|
+
return nativeBinding.rustNumfmtParseBatch(inputJson);
|
|
137
|
+
}
|
|
138
|
+
function parseNumberFormatMatrixBatchOnRust(inputJson) {
|
|
139
|
+
if (!nativeBinding)
|
|
140
|
+
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
141
|
+
return nativeBinding.rustNumfmtParseMatrixBatch(inputJson);
|
|
142
|
+
}
|
|
143
|
+
function analyzeNumberFormatBatchOnRust(inputJson) {
|
|
144
|
+
if (!nativeBinding)
|
|
145
|
+
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
146
|
+
return nativeBinding.rustNumfmtAnalyzeBatch(inputJson);
|
|
147
|
+
}
|
|
148
|
+
function loadSnapshotOnRust(snapshotJson) {
|
|
149
|
+
if (!nativeBinding)
|
|
150
|
+
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
151
|
+
return nativeBinding.rustEngineLoadSnapshot(snapshotJson);
|
|
152
|
+
}
|
|
153
|
+
function loadSnapshotBinaryOnRust(snapshotBytes) {
|
|
154
|
+
if (!nativeBinding)
|
|
155
|
+
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
156
|
+
return nativeBinding.rustEngineLoadSnapshotBinary(snapshotBytes);
|
|
157
|
+
}
|
|
158
|
+
function applyMutationOnRust(mutationJson) {
|
|
159
|
+
if (!nativeBinding)
|
|
160
|
+
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
161
|
+
return nativeBinding.rustEngineApplyMutation(mutationJson);
|
|
162
|
+
}
|
|
163
|
+
function disposeWorkbookOnRust(unitId) {
|
|
164
|
+
if (!nativeBinding)
|
|
165
|
+
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
166
|
+
return nativeBinding.rustEngineDisposeWorkbook(unitId);
|
|
167
|
+
}
|
|
168
|
+
function disposeAllWorkbooksOnRust() {
|
|
169
|
+
if (!nativeBinding)
|
|
170
|
+
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
171
|
+
return nativeBinding.rustEngineDisposeAllWorkbooks();
|
|
172
|
+
}
|
|
173
|
+
function getRustModelStats() {
|
|
174
|
+
if (!nativeBinding)
|
|
175
|
+
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
176
|
+
return nativeBinding.rustEngineGetModelStats();
|
|
177
|
+
}
|
|
178
|
+
function getRustCellOnRust(unitId, sheetId, row, col) {
|
|
179
|
+
if (!nativeBinding)
|
|
180
|
+
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
181
|
+
return nativeBinding.rustEngineGetCell(unitId, sheetId, row, col);
|
|
182
|
+
}
|
|
183
|
+
function getRustSheetStateOnRust(unitId, sheetId) {
|
|
184
|
+
if (!nativeBinding)
|
|
185
|
+
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
186
|
+
return nativeBinding.rustEngineGetSheetState(unitId, sheetId);
|
|
187
|
+
}
|
|
188
|
+
function getRustFormulaDataOnRust(unitId) {
|
|
189
|
+
if (!nativeBinding)
|
|
190
|
+
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
191
|
+
return nativeBinding.rustEngineGetFormulaData(unitId);
|
|
192
|
+
}
|
|
193
|
+
function buildRustDependencyGraphOnRust(unitId) {
|
|
194
|
+
if (!nativeBinding)
|
|
195
|
+
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
196
|
+
return nativeBinding.rustEngineBuildDependencyGraph(unitId);
|
|
197
|
+
}
|
|
198
|
+
function getRustDirtyDependenciesOnRust(dirtyRangesJson, unitId) {
|
|
199
|
+
if (!nativeBinding)
|
|
200
|
+
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
201
|
+
return nativeBinding.rustEngineGetDirtyDependencies(dirtyRangesJson, unitId);
|
|
202
|
+
}
|
|
203
|
+
function syncRustFormulaDependenciesOnRust(inputJson) {
|
|
204
|
+
if (!nativeBinding)
|
|
205
|
+
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
206
|
+
return nativeBinding.rustEngineSyncFormulaDependencies(inputJson);
|
|
207
|
+
}
|
|
208
|
+
function inspectRustFormulaDependencyGraphOnRust() {
|
|
209
|
+
if (!nativeBinding)
|
|
210
|
+
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
211
|
+
return nativeBinding.rustEngineInspectFormulaDependencyGraph();
|
|
212
|
+
}
|
|
213
|
+
function markRustFormulaDirtyOnRust(inputJson) {
|
|
214
|
+
if (!nativeBinding)
|
|
215
|
+
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
216
|
+
return nativeBinding.rustEngineMarkFormulaDirty(inputJson);
|
|
217
|
+
}
|
|
218
|
+
function clearRustFormulaDependenciesOnRust(inputJson) {
|
|
219
|
+
if (!nativeBinding)
|
|
220
|
+
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
221
|
+
return nativeBinding.rustEngineClearFormulaDependencies(inputJson);
|
|
222
|
+
}
|
|
223
|
+
function clearRustFormulaDirtyOnRust() {
|
|
224
|
+
if (!nativeBinding)
|
|
225
|
+
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
226
|
+
return nativeBinding.rustEngineClearFormulaDirty();
|
|
227
|
+
}
|
|
228
|
+
function executeDirtyFormulasOnRust(maxIteration, includeCalculatedNodes, includeRuntimeData, includeResultBatches) {
|
|
229
|
+
if (!nativeBinding)
|
|
230
|
+
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
231
|
+
return nativeBinding.rustEngineExecuteDirtyFormulas(
|
|
232
|
+
maxIteration,
|
|
233
|
+
includeCalculatedNodes,
|
|
234
|
+
includeRuntimeData,
|
|
235
|
+
includeResultBatches
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
function materializeWorkbookSnapshotOnRust(workbookJson, unitId, rev, dirtyInputJson) {
|
|
239
|
+
if (!nativeBinding)
|
|
240
|
+
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
241
|
+
return nativeBinding.rustMaterializeWorkbookSnapshot(workbookJson, unitId, rev, dirtyInputJson);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// src/controllers/rust-engine-sync.controller.ts
|
|
245
|
+
var import_core2 = require("@univerjs/core");
|
|
246
|
+
|
|
247
|
+
// src/services/rust-formula-projection.service.ts
|
|
248
|
+
var import_core = require("@univerjs/core");
|
|
249
|
+
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([
|
|
250
|
+
"sheet.mutation.set-range-values",
|
|
251
|
+
"sheet.mutation.insert-row",
|
|
252
|
+
"sheet.mutation.insert-col",
|
|
253
|
+
"sheet.mutation.insert-sheet",
|
|
254
|
+
"sheet.mutation.move-range",
|
|
255
|
+
"sheet.mutation.move-rows",
|
|
256
|
+
"sheet.mutation.move-columns",
|
|
257
|
+
"sheet.mutation.move-cols",
|
|
258
|
+
"sheet.mutation.remove-col",
|
|
259
|
+
"sheet.mutation.remove-rows",
|
|
260
|
+
"sheet.mutation.remove-sheet",
|
|
261
|
+
"sheet.mutation.set-col-hidden",
|
|
262
|
+
"sheet.mutation.set-col-visible",
|
|
263
|
+
"sheet.mutation.set-row-hidden",
|
|
264
|
+
"sheet.mutation.set-row-visible",
|
|
265
|
+
"sheet.mutation.set-worksheet-name",
|
|
266
|
+
"sheet.mutation.reorder-range",
|
|
267
|
+
"sheet.mutation.set-worksheet-row-count",
|
|
268
|
+
"sheet.mutation.set-worksheet-column-count",
|
|
269
|
+
"formula.mutation.set-array-formula-data",
|
|
270
|
+
"formula.mutation.set-defined-name",
|
|
271
|
+
"formula.mutation.set-feature-calculation",
|
|
272
|
+
"formula.mutation.set-formula-data",
|
|
273
|
+
"formula.mutation.set-image-formula-data",
|
|
274
|
+
"formula.mutation.set-other-formula",
|
|
275
|
+
"formula.mutation.set-super-table",
|
|
276
|
+
RUST_SET_SUPER_TABLES_MUTATION_ID,
|
|
277
|
+
"formula.mutation.set-super-table-option",
|
|
278
|
+
"formula.mutation.remove-defined-name",
|
|
279
|
+
"formula.mutation.remove-feature-calculation",
|
|
280
|
+
"formula.mutation.remove-other-formula",
|
|
281
|
+
"formula.mutation.remove-super-table",
|
|
282
|
+
RUST_UPSERT_PROJECTION_WORKBOOK_MUTATION_ID
|
|
283
|
+
]), RUST_INCREMENTAL_DEPENDENCY_MUTATIONS = /* @__PURE__ */ new Set(["sheet.mutation.set-range-values"]);
|
|
284
|
+
function isRustFormulaRelevantMutation(id) {
|
|
285
|
+
return RUST_FORMULA_RELEVANT_MUTATIONS.has(id);
|
|
286
|
+
}
|
|
287
|
+
function isRustIncrementalDependencyMutation(id) {
|
|
288
|
+
return RUST_INCREMENTAL_DEPENDENCY_MUTATIONS.has(id);
|
|
289
|
+
}
|
|
290
|
+
function createReferenceDataUpsertMutations(config, needs, tableService) {
|
|
291
|
+
let unitNameMap = config.unitNameMap, grouped = /* @__PURE__ */ new Map();
|
|
292
|
+
for (let need of needs) {
|
|
293
|
+
let key = `${need.unitId}\0${need.sheetId}`, group = grouped.get(key) ?? [];
|
|
294
|
+
group.push(need), grouped.set(key, group);
|
|
295
|
+
}
|
|
296
|
+
return Array.from(grouped.values()).flatMap((group) => {
|
|
297
|
+
let first = group[0], dataUnitId = first.dataUnitId ?? first.unitId, unitData = config.allUnitData?.[dataUnitId], sheetNameMap = config.unitSheetNameMap?.[dataUnitId] ?? {}, resolvedSheetId = unitData?.[first.sheetId] ? first.sheetId : sheetNameMap[first.sheetId] ?? first.sheetId, sheet = unitData?.[resolvedSheetId];
|
|
298
|
+
if (!sheet)
|
|
299
|
+
return [];
|
|
300
|
+
let sheetName = Object.entries(sheetNameMap).find(([, sheetId]) => sheetId === resolvedSheetId)?.[0] ?? first.sheetId, ranges = group.map(({ range }) => range), tables = Object.fromEntries(
|
|
301
|
+
group.flatMap(({ tableName }) => tableName ? [tableName] : []).filter((tableName, index, names) => names.indexOf(tableName) === index).flatMap((tableName) => {
|
|
302
|
+
let table = tableService?.getTable(dataUnitId, tableName), serialized = isRecord(table) ? serializeRuntimeSuperTable(table) : null;
|
|
303
|
+
return serialized ? [[tableName, serialized]] : [];
|
|
304
|
+
})
|
|
305
|
+
);
|
|
306
|
+
return [
|
|
307
|
+
{
|
|
308
|
+
id: RUST_UPSERT_REFERENCE_DATA_MUTATION_ID,
|
|
309
|
+
params: {
|
|
310
|
+
unitId: first.unitId,
|
|
311
|
+
name: unitNameMap?.[dataUnitId]?.name,
|
|
312
|
+
sheet: {
|
|
313
|
+
name: sheetName,
|
|
314
|
+
sheetId: resolvedSheetId,
|
|
315
|
+
rowCount: sheet.rowCount,
|
|
316
|
+
columnCount: sheet.columnCount,
|
|
317
|
+
coverage: ranges,
|
|
318
|
+
cellData: serializeCellDataInRanges(sheet.cellData, ranges)
|
|
319
|
+
},
|
|
320
|
+
...Object.keys(tables).length > 0 ? { tables } : {}
|
|
321
|
+
},
|
|
322
|
+
dirtyRanges: ranges.map((range) => ({
|
|
323
|
+
unitId: first.unitId,
|
|
324
|
+
sheetId: resolvedSheetId,
|
|
325
|
+
range
|
|
326
|
+
}))
|
|
327
|
+
}
|
|
328
|
+
];
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
function serializeRuntimeWorkbookSnapshots(workbooks) {
|
|
332
|
+
return {
|
|
333
|
+
workbooks: workbooks.map((workbook) => serializeRuntimeWorkbookSnapshot(workbook))
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
function serializeRuntimeWorkbookSnapshot(input) {
|
|
337
|
+
let { snapshot } = input, sheetOrder = snapshot.sheetOrder?.length > 0 ? snapshot.sheetOrder : Object.keys(snapshot.sheets ?? {}), calculation = serializeCalculation(snapshot), precisionAsDisplayed = calculation?.fullPrecision === !1, sheets = sheetOrder.map(
|
|
338
|
+
(sheetId) => serializeSheetSnapshot(sheetId, snapshot.sheets?.[sheetId], snapshot.styles, precisionAsDisplayed)
|
|
339
|
+
).filter((sheet) => sheet != null);
|
|
340
|
+
return {
|
|
341
|
+
unitId: input.unitId || snapshot.id,
|
|
342
|
+
name: snapshot.name,
|
|
343
|
+
sheets,
|
|
344
|
+
...calculation ? { calculation } : {},
|
|
345
|
+
resources: serializeResources(snapshot),
|
|
346
|
+
definedNames: serializeDefinedNames(input.definedNames, snapshot),
|
|
347
|
+
externalLinks: serializeExternalLinks(snapshot),
|
|
348
|
+
tables: serializeTables(snapshot)
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
function createProjectionWorkbookUpsertMutation(input) {
|
|
352
|
+
return {
|
|
353
|
+
id: RUST_UPSERT_PROJECTION_WORKBOOK_MUTATION_ID,
|
|
354
|
+
params: {
|
|
355
|
+
workbook: serializeRuntimeWorkbookSnapshot(input)
|
|
356
|
+
},
|
|
357
|
+
dirtyRanges: []
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
function rustExecutionOutputToFormulaCalculationPatch(output) {
|
|
361
|
+
let arrayFormulaOutput = output;
|
|
362
|
+
return {
|
|
363
|
+
unitData: output.resultBatches?.length ? resultBatchesToUnitData(output.resultBatches) : runtimeDataToUnitData(output.runtimeData),
|
|
364
|
+
unitOtherData: otherFormulaDataToUnitOtherData(output.otherFormulaData),
|
|
365
|
+
...arrayFormulaOutput.arrayFormulaRange ? { arrayFormulaRange: arrayFormulaOutput.arrayFormulaRange } : {},
|
|
366
|
+
...arrayFormulaOutput.arrayFormulaCellData ? { arrayFormulaCellData: arrayFormulaCellDataToUnitData(arrayFormulaOutput.arrayFormulaCellData) } : {},
|
|
367
|
+
errors: output.errors?.map((error) => ({
|
|
368
|
+
code: "RUST_FORMULA_CALCULATION_ERROR",
|
|
369
|
+
unitId: error.unitId,
|
|
370
|
+
sheetId: error.sheetId,
|
|
371
|
+
row: error.row,
|
|
372
|
+
column: error.column,
|
|
373
|
+
message: error.message
|
|
374
|
+
}))
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
function arrayFormulaCellDataToUnitData(input) {
|
|
378
|
+
let result = {};
|
|
379
|
+
for (let [unitId, sheetMap] of Object.entries(input)) {
|
|
380
|
+
let unitData = {};
|
|
381
|
+
result[unitId] = unitData;
|
|
382
|
+
for (let [sheetId, rowMap] of Object.entries(sheetMap)) {
|
|
383
|
+
let sheetData = {};
|
|
384
|
+
unitData[sheetId] = sheetData;
|
|
385
|
+
for (let [rowKey, colMap] of Object.entries(rowMap)) {
|
|
386
|
+
let rowData = {};
|
|
387
|
+
sheetData[Number(rowKey)] = rowData;
|
|
388
|
+
for (let [colKey, value] of Object.entries(colMap))
|
|
389
|
+
rowData[Number(colKey)] = cellDataFromRustValue(value);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
return result;
|
|
394
|
+
}
|
|
395
|
+
function otherFormulaDataToUnitOtherData(otherFormulaData) {
|
|
396
|
+
let unitOtherData = {};
|
|
397
|
+
return Object.entries(otherFormulaData ?? {}).forEach(([unitId, sheetMap]) => {
|
|
398
|
+
if (!sheetMap) return;
|
|
399
|
+
let unitSheetData = {};
|
|
400
|
+
unitOtherData[unitId] = unitSheetData, Object.entries(sheetMap).forEach(([sheetId, formulaMap]) => {
|
|
401
|
+
if (!formulaMap) return;
|
|
402
|
+
let sheetData = {};
|
|
403
|
+
unitSheetData[sheetId] = sheetData, Object.entries(formulaMap).forEach(([formulaId, rowMap]) => {
|
|
404
|
+
if (!rowMap) return;
|
|
405
|
+
let formulaData = {};
|
|
406
|
+
sheetData[formulaId] = formulaData, Object.entries(rowMap).forEach(([rowKey, colMap]) => {
|
|
407
|
+
if (!colMap) return;
|
|
408
|
+
let row = Number(rowKey), rowData = {};
|
|
409
|
+
formulaData[row] = rowData, Object.entries(colMap).forEach(([colKey, value]) => {
|
|
410
|
+
rowData[Number(colKey)] = [[cellDataFromRustValue(value)]];
|
|
411
|
+
});
|
|
412
|
+
});
|
|
413
|
+
});
|
|
414
|
+
});
|
|
415
|
+
}), unitOtherData;
|
|
416
|
+
}
|
|
417
|
+
function createFormulaProjectionDesyncSignal(reason, error, mutationId) {
|
|
418
|
+
return {
|
|
419
|
+
reason,
|
|
420
|
+
mutationId,
|
|
421
|
+
message: error instanceof Error ? error.message : String(error)
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
var RustFormulaProjectionService = class {
|
|
425
|
+
_nativeLoaded = !1;
|
|
426
|
+
async load(workbooks) {
|
|
427
|
+
await this._ensureNativeLoaded();
|
|
428
|
+
try {
|
|
429
|
+
return {
|
|
430
|
+
stats: JSON.parse(loadSnapshotOnRust(JSON.stringify(serializeRuntimeWorkbookSnapshots(workbooks))))
|
|
431
|
+
};
|
|
432
|
+
} catch (error) {
|
|
433
|
+
return {
|
|
434
|
+
desync: createFormulaProjectionDesyncSignal("snapshot-load-failed", error),
|
|
435
|
+
errors: [errorToFormulaCalculationError("RUST_FORMULA_LOAD_ERROR", error)]
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
async applyMutation(mutation) {
|
|
440
|
+
await this._ensureNativeLoaded();
|
|
441
|
+
try {
|
|
442
|
+
return {
|
|
443
|
+
stats: JSON.parse(applyMutationOnRust(JSON.stringify(normalizeRustEngineMutation(mutation)))),
|
|
444
|
+
dependencyInvalidated: !isRustIncrementalDependencyMutation(mutation.id)
|
|
445
|
+
};
|
|
446
|
+
} catch (error) {
|
|
447
|
+
return {
|
|
448
|
+
dependencyInvalidated: !0,
|
|
449
|
+
desync: createFormulaProjectionDesyncSignal("mutation-apply-failed", error, mutation.id),
|
|
450
|
+
errors: [errorToFormulaCalculationError("RUST_FORMULA_MUTATION_ERROR", error)]
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
async syncFormulaDependencies(input) {
|
|
455
|
+
return await this._ensureNativeLoaded(), JSON.parse(syncRustFormulaDependenciesOnRust(JSON.stringify(input)));
|
|
456
|
+
}
|
|
457
|
+
async markDirty(input) {
|
|
458
|
+
return await this._ensureNativeLoaded(), JSON.parse(markRustFormulaDirtyOnRust(JSON.stringify(input)));
|
|
459
|
+
}
|
|
460
|
+
async calculateDirty(maxIteration = 1) {
|
|
461
|
+
await this._ensureNativeLoaded();
|
|
462
|
+
try {
|
|
463
|
+
let output = JSON.parse(
|
|
464
|
+
executeDirtyFormulasOnRust(maxIteration, !1, !1, !0)
|
|
465
|
+
);
|
|
466
|
+
return rustExecutionOutputToFormulaCalculationPatch(output);
|
|
467
|
+
} catch (error) {
|
|
468
|
+
return {
|
|
469
|
+
unitData: {},
|
|
470
|
+
unitOtherData: {},
|
|
471
|
+
desync: createFormulaProjectionDesyncSignal("dirty-calculation-failed", error),
|
|
472
|
+
errors: [errorToFormulaCalculationError("RUST_FORMULA_CALCULATION_ERROR", error)]
|
|
473
|
+
};
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
async reset() {
|
|
477
|
+
await this._ensureNativeLoaded();
|
|
478
|
+
try {
|
|
479
|
+
return clearRustFormulaDirtyOnRust(), clearRustFormulaDependenciesOnRust(
|
|
480
|
+
JSON.stringify({
|
|
481
|
+
unitId: "",
|
|
482
|
+
clearSheetFormulas: !0,
|
|
483
|
+
clearFeatureFormulas: !0,
|
|
484
|
+
clearOtherFormulas: !0
|
|
485
|
+
})
|
|
486
|
+
), {
|
|
487
|
+
stats: JSON.parse(loadSnapshotOnRust(JSON.stringify({ workbooks: [] })))
|
|
488
|
+
};
|
|
489
|
+
} catch (error) {
|
|
490
|
+
return {
|
|
491
|
+
desync: createFormulaProjectionDesyncSignal("projection-reset-failed", error),
|
|
492
|
+
errors: [errorToFormulaCalculationError("RUST_FORMULA_RESET_ERROR", error)]
|
|
493
|
+
};
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
async disposeWorkbook(unitId) {
|
|
497
|
+
await this._ensureNativeLoaded();
|
|
498
|
+
try {
|
|
499
|
+
return { stats: JSON.parse(disposeWorkbookOnRust(unitId)) };
|
|
500
|
+
} catch (error) {
|
|
501
|
+
return {
|
|
502
|
+
desync: createFormulaProjectionDesyncSignal("workbook-dispose-failed", error),
|
|
503
|
+
errors: [errorToFormulaCalculationError("RUST_FORMULA_DISPOSE_ERROR", error)]
|
|
504
|
+
};
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
async _ensureNativeLoaded() {
|
|
508
|
+
this._nativeLoaded || (await loadNativeBinding(), this._nativeLoaded = !0);
|
|
509
|
+
}
|
|
510
|
+
};
|
|
511
|
+
function normalizeRustEngineMutation(mutation) {
|
|
512
|
+
let params = mutation.id === "formula.mutation.set-super-table" ? normalizeSetSuperTableMutationParams(mutation.params) : mutation.id === RUST_SET_SUPER_TABLES_MUTATION_ID ? normalizeSetSuperTablesMutationParams(mutation.params) : mutation.params ?? {};
|
|
513
|
+
return {
|
|
514
|
+
id: mutation.id,
|
|
515
|
+
params,
|
|
516
|
+
dirtyRanges: Array.isArray(mutation.dirtyRanges) ? mutation.dirtyRanges : []
|
|
517
|
+
};
|
|
518
|
+
}
|
|
519
|
+
function normalizeSetSuperTablesMutationParams(params) {
|
|
520
|
+
return !isRecord(params) || typeof params.unitId != "string" || !Array.isArray(params.tables) ? params ?? {} : {
|
|
521
|
+
...params,
|
|
522
|
+
tables: params.tables.map((entry) => {
|
|
523
|
+
let normalized = normalizeSetSuperTableMutationParams(
|
|
524
|
+
isRecord(entry) ? { ...entry, unitId: params.unitId } : entry
|
|
525
|
+
);
|
|
526
|
+
if (!isRecord(normalized)) return normalized;
|
|
527
|
+
let { unitId: _unitId, ...table } = normalized;
|
|
528
|
+
return table;
|
|
529
|
+
})
|
|
530
|
+
};
|
|
531
|
+
}
|
|
532
|
+
function normalizeSetSuperTableMutationParams(params) {
|
|
533
|
+
if (!isRecord(params) || !isRecord(params.reference))
|
|
534
|
+
return params ?? {};
|
|
535
|
+
let reference = params.reference, table = serializeRuntimeSuperTable(reference);
|
|
536
|
+
return table ? {
|
|
537
|
+
...params,
|
|
538
|
+
reference: normalizeRuntimeValue(reference),
|
|
539
|
+
table
|
|
540
|
+
} : {
|
|
541
|
+
...params,
|
|
542
|
+
reference: normalizeRuntimeValue(reference)
|
|
543
|
+
};
|
|
544
|
+
}
|
|
545
|
+
function serializeRuntimeSuperTable(reference) {
|
|
546
|
+
let sheetId = reference.sheetId, range = reference.range;
|
|
547
|
+
if (typeof sheetId != "string" || !isRecord(range) || typeof range.startRow != "number" || typeof range.endRow != "number" || typeof range.startColumn != "number" || typeof range.endColumn != "number")
|
|
548
|
+
return null;
|
|
549
|
+
let columns = (reference.titleMap instanceof Map ? Array.from(reference.titleMap.entries()) : isRecord(reference.titleMap) ? Object.entries(reference.titleMap) : []).filter((entry) => typeof entry[0] == "string" && typeof entry[1] == "number").toSorted((left, right) => left[1] - right[1]).map(([displayName]) => ({ displayName }));
|
|
550
|
+
return {
|
|
551
|
+
sheetId,
|
|
552
|
+
range: {
|
|
553
|
+
startRow: range.startRow,
|
|
554
|
+
endRow: range.endRow,
|
|
555
|
+
startColumn: range.startColumn,
|
|
556
|
+
endColumn: range.endColumn
|
|
557
|
+
},
|
|
558
|
+
columns,
|
|
559
|
+
showHeader: reference.showHeader !== !1,
|
|
560
|
+
showFooter: reference.showFooter === !0
|
|
561
|
+
};
|
|
562
|
+
}
|
|
563
|
+
function normalizeRuntimeValue(value) {
|
|
564
|
+
return value instanceof Map ? Object.fromEntries(
|
|
565
|
+
Array.from(value.entries(), ([key, entryValue]) => [String(key), normalizeRuntimeValue(entryValue)])
|
|
566
|
+
) : Array.isArray(value) ? value.map(normalizeRuntimeValue) : isRecord(value) ? Object.fromEntries(
|
|
567
|
+
Object.entries(value).map(([key, entryValue]) => [key, normalizeRuntimeValue(entryValue)])
|
|
568
|
+
) : value;
|
|
569
|
+
}
|
|
570
|
+
function resultBatchesToUnitData(resultBatches) {
|
|
571
|
+
let unitData = {};
|
|
572
|
+
for (let batch of resultBatches) {
|
|
573
|
+
let unitSheetData = unitData[batch.unitId] ?? {};
|
|
574
|
+
unitData[batch.unitId] = unitSheetData;
|
|
575
|
+
let sheetData = unitSheetData[batch.sheetId] ?? {};
|
|
576
|
+
unitSheetData[batch.sheetId] = sheetData;
|
|
577
|
+
for (let index = 0; index < batch.values.length; index++) {
|
|
578
|
+
let row = batch.rows[index], col = batch.cols[index], value = batch.values[index], rowData = sheetData[row] ?? {};
|
|
579
|
+
sheetData[row] = rowData, rowData[col] = cellDataFromRustValue(value);
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
return unitData;
|
|
583
|
+
}
|
|
584
|
+
function runtimeDataToUnitData(runtimeData) {
|
|
585
|
+
let unitData = {};
|
|
586
|
+
return Object.entries(runtimeData ?? {}).forEach(([unitId, sheetMap]) => {
|
|
587
|
+
if (!sheetMap) return;
|
|
588
|
+
let unitSheetData = {};
|
|
589
|
+
unitData[unitId] = unitSheetData, Object.entries(sheetMap).forEach(([sheetId, rowMap]) => {
|
|
590
|
+
if (!rowMap) return;
|
|
591
|
+
let sheetData = {};
|
|
592
|
+
unitSheetData[sheetId] = sheetData, Object.entries(rowMap).forEach(([rowKey, colMap]) => {
|
|
593
|
+
if (!colMap) return;
|
|
594
|
+
let row = Number(rowKey), rowData = {};
|
|
595
|
+
sheetData[row] = rowData, Object.entries(colMap).forEach(([colKey, value]) => {
|
|
596
|
+
rowData[Number(colKey)] = cellDataFromRustValue(value);
|
|
597
|
+
});
|
|
598
|
+
});
|
|
599
|
+
});
|
|
600
|
+
}), unitData;
|
|
601
|
+
}
|
|
602
|
+
function cellDataFromRustValue(value) {
|
|
603
|
+
if (value == null)
|
|
604
|
+
return null;
|
|
605
|
+
if (typeof value == "number")
|
|
606
|
+
return { t: import_core.CellValueType.NUMBER, v: value };
|
|
607
|
+
if (typeof value == "boolean")
|
|
608
|
+
return { t: import_core.CellValueType.BOOLEAN, v: value };
|
|
609
|
+
if (typeof value == "string")
|
|
610
|
+
return { t: import_core.CellValueType.STRING, v: value };
|
|
611
|
+
if (isRecord(value)) {
|
|
612
|
+
let cell = sanitizeCoreCellData(value);
|
|
613
|
+
if (Object.keys(cell).length > 0)
|
|
614
|
+
return cell;
|
|
615
|
+
}
|
|
616
|
+
return { v: value };
|
|
617
|
+
}
|
|
618
|
+
function sanitizeCoreCellData(value) {
|
|
619
|
+
let cell = {};
|
|
620
|
+
for (let key of ["v", "t", "p", "s", "f", "si", "ref", "xf", "custom"])
|
|
621
|
+
key in value && (cell[key] = value[key]);
|
|
622
|
+
return cell;
|
|
623
|
+
}
|
|
624
|
+
function serializeResources(snapshot) {
|
|
625
|
+
let resources = snapshot.resources;
|
|
626
|
+
if (!resources || typeof resources != "object")
|
|
627
|
+
return;
|
|
628
|
+
let serialized = {};
|
|
629
|
+
for (let [id, resource] of Object.entries(resources))
|
|
630
|
+
typeof resource?.name == "string" && (serialized[id] = {
|
|
631
|
+
name: resource.name,
|
|
632
|
+
data: resource.data
|
|
633
|
+
});
|
|
634
|
+
return Object.keys(serialized).length > 0 ? serialized : void 0;
|
|
635
|
+
}
|
|
636
|
+
function serializeCalculation(snapshot) {
|
|
637
|
+
for (let resource of Object.values(
|
|
638
|
+
snapshot.resources ?? {}
|
|
639
|
+
)) {
|
|
640
|
+
if (resource?.name !== XLSX_WORKBOOK_CALCULATION_RESOURCE)
|
|
641
|
+
continue;
|
|
642
|
+
let data = parseResourceData(resource.data);
|
|
643
|
+
if (!data || typeof data != "object")
|
|
644
|
+
return;
|
|
645
|
+
let fullPrecision = data.fullPrecision;
|
|
646
|
+
return typeof fullPrecision == "boolean" ? { fullPrecision } : void 0;
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
function serializeTables(snapshot) {
|
|
650
|
+
for (let resource of Object.values(
|
|
651
|
+
snapshot.resources ?? {}
|
|
652
|
+
)) {
|
|
653
|
+
if (resource?.name !== "SHEET_TABLE_PLUGIN")
|
|
654
|
+
continue;
|
|
655
|
+
let data = parseResourceData(resource.data);
|
|
656
|
+
if (!data || typeof data != "object")
|
|
657
|
+
return;
|
|
658
|
+
let tables = {};
|
|
659
|
+
for (let [sheetId, sheetTables] of Object.entries(data)) {
|
|
660
|
+
let tableList = sheetTables?.tables;
|
|
661
|
+
if (Array.isArray(tableList))
|
|
662
|
+
for (let table of tableList) {
|
|
663
|
+
let serialized = serializeTableSnapshot(sheetId, table, snapshot);
|
|
664
|
+
serialized && (tables[serialized.name] = serialized.table);
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
return Object.keys(tables).length > 0 ? tables : void 0;
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
function serializeTableSnapshot(sheetId, table, snapshot) {
|
|
671
|
+
if (!table || typeof table != "object")
|
|
672
|
+
return null;
|
|
673
|
+
let record = table, name2 = typeof record.name == "string" ? record.name : void 0, range = record.range;
|
|
674
|
+
if (!name2 || !range || typeof range.startRow != "number" || typeof range.endRow != "number" || typeof range.startColumn != "number" || typeof range.endColumn != "number")
|
|
675
|
+
return null;
|
|
676
|
+
let columns = Array.isArray(record.columns) ? record.columns.map((column) => {
|
|
677
|
+
let displayName = column?.displayName;
|
|
678
|
+
return typeof displayName == "string" ? { displayName } : null;
|
|
679
|
+
}).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);
|
|
680
|
+
return {
|
|
681
|
+
name: name2,
|
|
682
|
+
table: {
|
|
683
|
+
sheetId,
|
|
684
|
+
range: {
|
|
685
|
+
startRow: range.startRow,
|
|
686
|
+
endRow: range.endRow,
|
|
687
|
+
startColumn: range.startColumn,
|
|
688
|
+
endColumn: range.endColumn
|
|
689
|
+
},
|
|
690
|
+
columns,
|
|
691
|
+
showHeader,
|
|
692
|
+
showFooter
|
|
693
|
+
}
|
|
694
|
+
};
|
|
695
|
+
}
|
|
696
|
+
function parseResourceData(data) {
|
|
697
|
+
if (typeof data != "string")
|
|
698
|
+
return data;
|
|
699
|
+
try {
|
|
700
|
+
return JSON.parse(data || "{}");
|
|
701
|
+
} catch {
|
|
702
|
+
return;
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
function inferTableFooter(snapshot, sheetId, startRow, endRow, startColumn, endColumn) {
|
|
706
|
+
let row = snapshot.sheets?.[sheetId]?.cellData?.[endRow];
|
|
707
|
+
if (!row)
|
|
708
|
+
return !1;
|
|
709
|
+
for (let col = startColumn; col <= endColumn; col++) {
|
|
710
|
+
let cell = row[col];
|
|
711
|
+
if (cell && (typeof cell.f == "string" && /\bSUBTOTAL\s*\(/iu.test(cell.f) || col === startColumn && typeof cell.v == "string" && cell.v.trim().toLowerCase() === "total"))
|
|
712
|
+
return !0;
|
|
713
|
+
}
|
|
714
|
+
return !1;
|
|
715
|
+
}
|
|
716
|
+
function serializeExternalLinks(snapshot) {
|
|
717
|
+
let externalLinks = snapshot.externalLinks, serializedLinks = Array.isArray(externalLinks) ? externalLinks.map((link) => serializeExternalLink(link)).filter((link) => link != null) : [];
|
|
718
|
+
return serializedLinks.push(...serializeExternalLinksFromResource(snapshot)), serializedLinks.length > 0 ? serializedLinks : void 0;
|
|
719
|
+
}
|
|
720
|
+
function serializeExternalLinksFromResource(snapshot) {
|
|
721
|
+
let links = [];
|
|
722
|
+
for (let resource of Object.values(
|
|
723
|
+
snapshot.resources ?? {}
|
|
724
|
+
)) {
|
|
725
|
+
if (resource?.name !== EXTERNAL_DATA_RESOURCE)
|
|
726
|
+
continue;
|
|
727
|
+
let data = parseResourceData(resource.data);
|
|
728
|
+
if (isRecord(data)) {
|
|
729
|
+
if (data.schemaVersion === 1 && Array.isArray(data.links)) {
|
|
730
|
+
links.push(
|
|
731
|
+
...data.links.map((link) => serializeVersionedExternalLink(link)).filter((link) => link != null)
|
|
732
|
+
);
|
|
733
|
+
continue;
|
|
734
|
+
}
|
|
735
|
+
if (!(data.signature !== EXTERNAL_DATA_SIGNATURE || !isRecord(data.units)))
|
|
736
|
+
for (let [unitId, unit] of Object.entries(data.units)) {
|
|
737
|
+
let link = serializeExternalDataUnit(unitId, unit);
|
|
738
|
+
link && links.push(link);
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
return links;
|
|
743
|
+
}
|
|
744
|
+
function serializeVersionedExternalLink(link) {
|
|
745
|
+
if (!isRecord(link) || !Number.isInteger(link.slot) || Number(link.slot) <= 0 || !isRecord(link.target))
|
|
746
|
+
return null;
|
|
747
|
+
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) => {
|
|
748
|
+
if (!isRecord(item)) return [];
|
|
749
|
+
let { name: name2 } = item;
|
|
750
|
+
return typeof name2 != "string" || cachedNames.has(name2.toLocaleLowerCase()) ? [] : [
|
|
751
|
+
{
|
|
752
|
+
name: name2,
|
|
753
|
+
rowCount: 1048576,
|
|
754
|
+
columnCount: 16384,
|
|
755
|
+
cellData: {},
|
|
756
|
+
coverage: []
|
|
757
|
+
}
|
|
758
|
+
];
|
|
759
|
+
}) : [], sheets = [...cachedSheets, ...uncachedSheets], definedNames = serializeVersionedExternalDefinedNames(link.definedNames), tables = serializeVersionedExternalTables(link.tables), aliases = [link.name, target.name, target.uri].filter(
|
|
760
|
+
(alias) => typeof alias == "string" && alias.length > 0
|
|
761
|
+
);
|
|
762
|
+
return {
|
|
763
|
+
...aliases.length > 0 ? { aliases: [...new Set(aliases)] } : {},
|
|
764
|
+
...definedNames ? { definedNames } : {},
|
|
765
|
+
sheets,
|
|
766
|
+
...tables ? { tables } : {},
|
|
767
|
+
...typeof target.uri == "string" ? { target: target.uri } : typeof target.name == "string" ? { target: target.name } : typeof link.name == "string" ? { target: link.name } : {},
|
|
768
|
+
unitId: String(link.slot)
|
|
769
|
+
};
|
|
770
|
+
}
|
|
771
|
+
function serializeVersionedExternalDefinedNames(value) {
|
|
772
|
+
if (!Array.isArray(value))
|
|
773
|
+
return;
|
|
774
|
+
let result = {};
|
|
775
|
+
for (let item of value)
|
|
776
|
+
!isRecord(item) || typeof item.name != "string" || (result[item.name] = {
|
|
777
|
+
name: item.name,
|
|
778
|
+
...typeof item.formulaOrRefString == "string" ? { formulaOrRefString: item.formulaOrRefString } : {}
|
|
779
|
+
});
|
|
780
|
+
return Object.keys(result).length > 0 ? result : void 0;
|
|
781
|
+
}
|
|
782
|
+
function serializeVersionedExternalTables(value) {
|
|
783
|
+
if (!Array.isArray(value))
|
|
784
|
+
return;
|
|
785
|
+
let result = {};
|
|
786
|
+
for (let item of value) {
|
|
787
|
+
if (!isRecord(item) || typeof item.name != "string" || typeof item.sheetName != "string" || !isRange(item.range)) continue;
|
|
788
|
+
let columns = Array.isArray(item.columns) ? item.columns.flatMap((column) => {
|
|
789
|
+
if (!isRecord(column)) return [];
|
|
790
|
+
let { name: name2 } = column;
|
|
791
|
+
return typeof name2 == "string" ? [{ displayName: name2 }] : [];
|
|
792
|
+
}) : [];
|
|
793
|
+
result[item.name] = {
|
|
794
|
+
sheetId: item.sheetName,
|
|
795
|
+
range: item.range,
|
|
796
|
+
columns,
|
|
797
|
+
showHeader: item.showHeader !== !1
|
|
798
|
+
};
|
|
799
|
+
}
|
|
800
|
+
return Object.keys(result).length > 0 ? result : void 0;
|
|
801
|
+
}
|
|
802
|
+
function serializeVersionedExternalSheet(sheet) {
|
|
803
|
+
if (!isRecord(sheet) || typeof sheet.name != "string") return null;
|
|
804
|
+
let cellData = {};
|
|
805
|
+
if (Array.isArray(sheet.cells))
|
|
806
|
+
for (let cell of sheet.cells) {
|
|
807
|
+
if (!isExternalCell(cell)) continue;
|
|
808
|
+
let { row, column } = cell;
|
|
809
|
+
(cellData[row] ??= {})[column] = {
|
|
810
|
+
v: cell.value,
|
|
811
|
+
...typeof cell.valueType == "number" ? { t: cell.valueType } : {}
|
|
812
|
+
};
|
|
813
|
+
}
|
|
814
|
+
return {
|
|
815
|
+
name: sheet.name,
|
|
816
|
+
...typeof sheet.sheetId == "string" ? { sheetId: sheet.sheetId } : {},
|
|
817
|
+
rowCount: typeof sheet.rowCount == "number" ? sheet.rowCount : 0,
|
|
818
|
+
columnCount: typeof sheet.columnCount == "number" ? sheet.columnCount : 0,
|
|
819
|
+
cellData,
|
|
820
|
+
coverage: Array.isArray(sheet.coverage) ? sheet.coverage.filter(isRange) : []
|
|
821
|
+
};
|
|
822
|
+
}
|
|
823
|
+
function isRange(value) {
|
|
824
|
+
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";
|
|
825
|
+
}
|
|
826
|
+
function isRustTableSnapshot(value) {
|
|
827
|
+
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);
|
|
828
|
+
}
|
|
829
|
+
function isExternalCell(value) {
|
|
830
|
+
return isRecord(value) && Number.isInteger(value.row) && Number.isInteger(value.column);
|
|
831
|
+
}
|
|
832
|
+
function serializeExternalDataUnit(unitId, unit) {
|
|
833
|
+
if (!unit || typeof unit != "object")
|
|
834
|
+
return null;
|
|
835
|
+
let record = unit;
|
|
836
|
+
if (!record.sheets || typeof record.sheets != "object")
|
|
837
|
+
return null;
|
|
838
|
+
let sheets = Object.values(record.sheets).map((sheet) => serializeExternalSheet(sheet)).filter((sheet) => sheet != null);
|
|
839
|
+
if (sheets.length === 0)
|
|
840
|
+
return null;
|
|
841
|
+
let definedNames = serializeExternalDefinedNames(record.definedNames);
|
|
842
|
+
return {
|
|
843
|
+
...definedNames === void 0 ? {} : { definedNames },
|
|
844
|
+
sheets,
|
|
845
|
+
...typeof record.target == "string" ? { target: record.target } : {},
|
|
846
|
+
unitId
|
|
847
|
+
};
|
|
848
|
+
}
|
|
849
|
+
function serializeExternalLink(link) {
|
|
850
|
+
if (!isRecord(link))
|
|
851
|
+
return null;
|
|
852
|
+
let record = link;
|
|
853
|
+
if (!Array.isArray(record.sheets))
|
|
854
|
+
return null;
|
|
855
|
+
let sheets = record.sheets.map((sheet) => serializeExternalSheet(sheet)).filter((sheet) => sheet != null);
|
|
856
|
+
if (sheets.length === 0)
|
|
857
|
+
return null;
|
|
858
|
+
let definedNames = serializeExternalDefinedNames(record.definedNames), tables = serializeExternalTables(record.tables);
|
|
859
|
+
return {
|
|
860
|
+
...definedNames === void 0 ? {} : { definedNames },
|
|
861
|
+
sheets,
|
|
862
|
+
...tables === void 0 ? {} : { tables },
|
|
863
|
+
...typeof record.target == "string" ? { target: record.target } : {},
|
|
864
|
+
...typeof record.unitId == "string" ? { unitId: record.unitId } : {}
|
|
865
|
+
};
|
|
866
|
+
}
|
|
867
|
+
function serializeExternalTables(value) {
|
|
868
|
+
if (!isRecord(value)) return;
|
|
869
|
+
let result = {};
|
|
870
|
+
for (let [name2, table] of Object.entries(value))
|
|
871
|
+
!table || typeof table != "object" || isRustTableSnapshot(table) && (result[name2] = table);
|
|
872
|
+
return Object.keys(result).length > 0 ? result : void 0;
|
|
873
|
+
}
|
|
874
|
+
function serializeExternalDefinedNames(value) {
|
|
875
|
+
if (!isRecord(value))
|
|
876
|
+
return;
|
|
877
|
+
let definedNames = {};
|
|
878
|
+
for (let [key, item] of Object.entries(value)) {
|
|
879
|
+
if (!isRecord(item))
|
|
880
|
+
continue;
|
|
881
|
+
let record = item, name2 = typeof record.name == "string" ? record.name : key;
|
|
882
|
+
definedNames[key] = {
|
|
883
|
+
...typeof record.id == "string" ? { id: record.id } : {},
|
|
884
|
+
name: name2,
|
|
885
|
+
...typeof record.formulaOrRefString == "string" ? { formulaOrRefString: record.formulaOrRefString } : {},
|
|
886
|
+
...typeof record.localSheetId == "string" ? { localSheetId: record.localSheetId } : {}
|
|
887
|
+
};
|
|
888
|
+
}
|
|
889
|
+
return Object.keys(definedNames).length > 0 ? definedNames : void 0;
|
|
890
|
+
}
|
|
891
|
+
function serializeExternalSheet(sheet) {
|
|
892
|
+
if (!sheet || typeof sheet != "object")
|
|
893
|
+
return null;
|
|
894
|
+
let record = sheet;
|
|
895
|
+
return typeof record.name != "string" ? null : {
|
|
896
|
+
name: record.name,
|
|
897
|
+
...typeof record.sheetId == "string" ? { sheetId: record.sheetId } : {},
|
|
898
|
+
rowCount: typeof record.rowCount == "number" ? record.rowCount : 0,
|
|
899
|
+
columnCount: typeof record.columnCount == "number" ? record.columnCount : 0,
|
|
900
|
+
cellData: serializeCellData(record.cellData)
|
|
901
|
+
};
|
|
902
|
+
}
|
|
903
|
+
function serializeDefinedNames(definedNames, snapshot) {
|
|
904
|
+
let direct = definedNames && Object.keys(definedNames).length > 0 ? definedNames : extractDefinedNames(snapshot), sheetIds = new Set(Object.keys(snapshot.sheets ?? {})), sheetNameToId = new Map(
|
|
905
|
+
Object.entries(snapshot.sheets ?? {}).map(([sheetId, sheet]) => [sheet.name, sheetId])
|
|
906
|
+
);
|
|
907
|
+
return Object.fromEntries(
|
|
908
|
+
Object.entries(direct).map(([id, definedName]) => [
|
|
909
|
+
id,
|
|
910
|
+
{
|
|
911
|
+
id: definedName.id,
|
|
912
|
+
name: definedName.name,
|
|
913
|
+
formulaOrRefString: definedName.formulaOrRefString,
|
|
914
|
+
localSheetId: normalizeDefinedNameLocalSheetId(
|
|
915
|
+
definedName.localSheetId,
|
|
916
|
+
definedName.formulaOrRefString,
|
|
917
|
+
sheetIds,
|
|
918
|
+
sheetNameToId
|
|
919
|
+
)
|
|
920
|
+
}
|
|
921
|
+
])
|
|
922
|
+
);
|
|
923
|
+
}
|
|
924
|
+
function normalizeDefinedNameLocalSheetId(localSheetId, formulaOrRefString, sheetIds, sheetNameToId) {
|
|
925
|
+
if (!localSheetId || localSheetId === "AllDefaultWorkbook")
|
|
926
|
+
return localSheetId;
|
|
927
|
+
let sheetName = extractLeadingSheetName(formulaOrRefString), sheetIdFromFormula = sheetName ? sheetNameToId.get(sheetName) : void 0;
|
|
928
|
+
return sheetIdFromFormula && sheetIdFromFormula !== localSheetId ? sheetIdFromFormula : sheetIds.has(localSheetId) || !sheetName ? localSheetId : sheetIdFromFormula ?? localSheetId;
|
|
929
|
+
}
|
|
930
|
+
function extractLeadingSheetName(formulaOrRefString) {
|
|
931
|
+
if (!formulaOrRefString)
|
|
932
|
+
return;
|
|
933
|
+
let quotedMatch = /^'((?:[^']|'')+)'!/.exec(formulaOrRefString);
|
|
934
|
+
return quotedMatch ? quotedMatch[1].replace(/''/g, "'") : /^([^=!]+)!/.exec(formulaOrRefString)?.[1];
|
|
935
|
+
}
|
|
936
|
+
function extractDefinedNames(snapshot) {
|
|
937
|
+
let direct = snapshot.definedNames;
|
|
938
|
+
if (direct && Object.keys(direct).length > 0)
|
|
939
|
+
return direct;
|
|
940
|
+
for (let resource of Object.values(
|
|
941
|
+
snapshot.resources ?? {}
|
|
942
|
+
)) {
|
|
943
|
+
if (resource?.name !== "SHEET_DEFINED_NAME_PLUGIN")
|
|
944
|
+
continue;
|
|
945
|
+
let data = parseResourceData(resource.data);
|
|
946
|
+
return data && typeof data == "object" ? data : {};
|
|
947
|
+
}
|
|
948
|
+
return {};
|
|
949
|
+
}
|
|
950
|
+
function serializeSheetSnapshot(sheetId, sheet, styles, precisionAsDisplayed) {
|
|
951
|
+
return sheet ? {
|
|
952
|
+
sheetId: sheet.id ?? sheetId,
|
|
953
|
+
name: sheet.name,
|
|
954
|
+
rowCount: sheet.rowCount ?? 0,
|
|
955
|
+
columnCount: sheet.columnCount ?? 0,
|
|
956
|
+
transitionEvaluation: sheet.transitionEvaluation === !0,
|
|
957
|
+
cellData: serializeCellData(sheet.cellData, styles, precisionAsDisplayed),
|
|
958
|
+
rowData: serializeVisibilityData(sheet.rowData),
|
|
959
|
+
columnData: serializeVisibilityData(sheet.columnData)
|
|
960
|
+
} : null;
|
|
961
|
+
}
|
|
962
|
+
function serializeCellData(cellData = {}, styles, precisionAsDisplayed = !1) {
|
|
963
|
+
let result = {}, rawCellData = cellData instanceof import_core.ObjectMatrix ? cellData.getMatrix() : cellData;
|
|
964
|
+
for (let [rowKey, row] of Object.entries(rawCellData ?? {})) {
|
|
965
|
+
if (!row)
|
|
966
|
+
continue;
|
|
967
|
+
let serializedRow = {};
|
|
968
|
+
for (let [colKey, cell] of Object.entries(row)) {
|
|
969
|
+
if (!cell || typeof cell != "object")
|
|
970
|
+
continue;
|
|
971
|
+
let cellRecord = cell, value = {};
|
|
972
|
+
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") {
|
|
973
|
+
let hasFormula = typeof cellRecord.f == "string" && cellRecord.f.length > 0;
|
|
974
|
+
typeof cellRecord.si == "string" || hasFormula && isLegacyArrayFormulaCell(cellRecord) ? value.ref = cellRecord.ref : hasFormula && (value.dynamicArrayRef = cellRecord.ref);
|
|
975
|
+
}
|
|
976
|
+
if (typeof cellRecord.xf == "string" && (value.xf = cellRecord.xf), "s" in cellRecord && (value.s = cellRecord.s), precisionAsDisplayed && typeof cellRecord.f == "string") {
|
|
977
|
+
let displayPrecision = inferDisplayPrecision(cellRecord.s, styles);
|
|
978
|
+
displayPrecision !== void 0 && (value.displayPrecision = displayPrecision);
|
|
979
|
+
}
|
|
980
|
+
Object.keys(value).length > 0 && (serializedRow[Number(colKey)] = value);
|
|
981
|
+
}
|
|
982
|
+
Object.keys(serializedRow).length > 0 && (result[Number(rowKey)] = serializedRow);
|
|
983
|
+
}
|
|
984
|
+
return result;
|
|
985
|
+
}
|
|
986
|
+
function serializeCellDataInRanges(cellData, ranges) {
|
|
987
|
+
let serialized = serializeCellData(cellData), result = {};
|
|
988
|
+
for (let [rowKey, row] of Object.entries(serialized)) {
|
|
989
|
+
let rowIndex = Number(rowKey);
|
|
990
|
+
for (let [columnKey, value] of Object.entries(row)) {
|
|
991
|
+
let columnIndex = Number(columnKey);
|
|
992
|
+
ranges.some(
|
|
993
|
+
(range) => rowIndex >= range.startRow && rowIndex <= range.endRow && columnIndex >= range.startColumn && columnIndex <= range.endColumn
|
|
994
|
+
) && ((result[rowIndex] ??= {})[columnIndex] = value);
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
return result;
|
|
998
|
+
}
|
|
999
|
+
function isLegacyArrayFormulaCell(cell) {
|
|
1000
|
+
let custom = cell.custom;
|
|
1001
|
+
if (!custom || typeof custom != "object")
|
|
1002
|
+
return !1;
|
|
1003
|
+
let xlsx = custom._xlsx;
|
|
1004
|
+
return xlsx != null && typeof xlsx == "object" && xlsx.legacyArrayFormula === !0;
|
|
1005
|
+
}
|
|
1006
|
+
function inferDisplayPrecision(styleId, styles) {
|
|
1007
|
+
if (typeof styleId != "string" || !styles || typeof styles != "object")
|
|
1008
|
+
return;
|
|
1009
|
+
let style = styles[styleId];
|
|
1010
|
+
if (!style || typeof style != "object")
|
|
1011
|
+
return;
|
|
1012
|
+
let numberFormat = style.n;
|
|
1013
|
+
if (!numberFormat || typeof numberFormat != "object")
|
|
1014
|
+
return;
|
|
1015
|
+
let pattern = numberFormat.pattern;
|
|
1016
|
+
return typeof pattern == "string" ? inferFixedNumberFormatPrecision(pattern) : void 0;
|
|
1017
|
+
}
|
|
1018
|
+
function inferFixedNumberFormatPrecision(pattern) {
|
|
1019
|
+
let cleaned = (pattern.split(";")[0] ?? pattern).replace(/"[^"]*"/gu, "").replace(/\\./gu, "").replace(/_.|\*./gu, "");
|
|
1020
|
+
if (!/[0#?]/u.test(cleaned) || /[%Ee]|[ymdhsa]/iu.test(cleaned))
|
|
1021
|
+
return;
|
|
1022
|
+
let decimalMatch = cleaned.match(/\.([0#?]+)/u);
|
|
1023
|
+
return decimalMatch?.[1] ? decimalMatch[1].length : 0;
|
|
1024
|
+
}
|
|
1025
|
+
function serializeVisibilityData(data = {}) {
|
|
1026
|
+
let result = {};
|
|
1027
|
+
for (let [indexKey, metadata] of Object.entries(data))
|
|
1028
|
+
!metadata || typeof metadata != "object" || !("hd" in metadata) || (result[Number(indexKey)] = {
|
|
1029
|
+
hd: metadata.hd
|
|
1030
|
+
});
|
|
1031
|
+
return result;
|
|
1032
|
+
}
|
|
1033
|
+
function errorToFormulaCalculationError(code, error) {
|
|
1034
|
+
return {
|
|
1035
|
+
code,
|
|
1036
|
+
message: error instanceof Error ? error.message : String(error)
|
|
1037
|
+
};
|
|
1038
|
+
}
|
|
1039
|
+
function isRecord(value) {
|
|
1040
|
+
return typeof value == "object" && value !== null && !Array.isArray(value);
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
// src/controllers/rust-engine-sync.controller.ts
|
|
1044
|
+
var rustEngineSyncState = {
|
|
1045
|
+
snapshotEpoch: 0,
|
|
1046
|
+
dependencyInvalidationEpoch: 0
|
|
1047
|
+
};
|
|
1048
|
+
function getRustEngineSyncState() {
|
|
1049
|
+
return { ...rustEngineSyncState };
|
|
1050
|
+
}
|
|
1051
|
+
function markRustSnapshotLoaded() {
|
|
1052
|
+
rustEngineSyncState.snapshotEpoch += 1, rustEngineSyncState.dependencyInvalidationEpoch += 1;
|
|
1053
|
+
}
|
|
1054
|
+
function markRustFormulaDependenciesInvalidated() {
|
|
1055
|
+
rustEngineSyncState.dependencyInvalidationEpoch += 1;
|
|
1056
|
+
}
|
|
1057
|
+
function emitRustEngineSyncDebugEvent(event) {
|
|
1058
|
+
let hook = globalThis.__UNIVER_RUST_FORMULA_DEBUG_HOOK__;
|
|
1059
|
+
typeof hook == "function" && hook(event);
|
|
1060
|
+
}
|
|
1061
|
+
function summarizeObjectMatrixPayload(value) {
|
|
1062
|
+
if (!value || typeof value != "object")
|
|
1063
|
+
return {};
|
|
1064
|
+
let cellValueCells = 0;
|
|
1065
|
+
for (let row of Object.values(value))
|
|
1066
|
+
!row || typeof row != "object" || (cellValueCells += Object.keys(row).length);
|
|
1067
|
+
return {
|
|
1068
|
+
cellValueRows: Object.keys(value).length,
|
|
1069
|
+
cellValueCells
|
|
1070
|
+
};
|
|
1071
|
+
}
|
|
1072
|
+
function hasObjectMatrixValues(value) {
|
|
1073
|
+
return !value || typeof value != "object" ? !1 : Object.values(value).some(
|
|
1074
|
+
(row) => row != null && typeof row == "object" && Object.keys(row).length > 0
|
|
1075
|
+
);
|
|
1076
|
+
}
|
|
1077
|
+
function hasRecordEntries(value) {
|
|
1078
|
+
return value != null && typeof value == "object" && Object.keys(value).length > 0;
|
|
1079
|
+
}
|
|
1080
|
+
function countDisplayPrecisionCells(snapshot) {
|
|
1081
|
+
let count = 0;
|
|
1082
|
+
for (let workbook of snapshot.workbooks)
|
|
1083
|
+
for (let sheet of workbook.sheets)
|
|
1084
|
+
for (let row of Object.values(sheet.cellData))
|
|
1085
|
+
for (let cell of Object.values(row))
|
|
1086
|
+
typeof cell.displayPrecision == "number" && (count += 1);
|
|
1087
|
+
return count;
|
|
1088
|
+
}
|
|
1089
|
+
var RustEngineSyncController = class extends import_core2.Disposable {
|
|
1090
|
+
constructor(_commandService) {
|
|
1091
|
+
super();
|
|
1092
|
+
this._commandService = _commandService;
|
|
1093
|
+
this._initialize();
|
|
1094
|
+
}
|
|
1095
|
+
_commandService;
|
|
1096
|
+
_nativeReady = !1;
|
|
1097
|
+
_snapshotLoaded = !1;
|
|
1098
|
+
_projectionLoadPromise = null;
|
|
1099
|
+
_projectionDeltaBarrier = Promise.resolve();
|
|
1100
|
+
_pendingMutations = [];
|
|
1101
|
+
_projectionManagedTableUnits = /* @__PURE__ */ new Set();
|
|
1102
|
+
_initialize() {
|
|
1103
|
+
this.disposeWithMe(
|
|
1104
|
+
this._commandService.onCommandExecuted((command, options) => {
|
|
1105
|
+
this._shouldSyncMutation(command, options) && this._queueOrSyncMutation(this._serializeMutation(command, options));
|
|
1106
|
+
})
|
|
1107
|
+
);
|
|
1108
|
+
}
|
|
1109
|
+
async loadProjection(workbooks) {
|
|
1110
|
+
let loadPromise = this._loadProjection(workbooks);
|
|
1111
|
+
this._projectionLoadPromise = loadPromise;
|
|
1112
|
+
try {
|
|
1113
|
+
await loadPromise;
|
|
1114
|
+
} finally {
|
|
1115
|
+
this._projectionLoadPromise === loadPromise && (this._projectionLoadPromise = null);
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
async waitForProjectionLoad() {
|
|
1119
|
+
await this._projectionLoadPromise;
|
|
1120
|
+
let barrier;
|
|
1121
|
+
do
|
|
1122
|
+
barrier = this._projectionDeltaBarrier, await barrier;
|
|
1123
|
+
while (barrier !== this._projectionDeltaBarrier);
|
|
1124
|
+
}
|
|
1125
|
+
setProjectionDeltaBarrier(barrier) {
|
|
1126
|
+
this._projectionDeltaBarrier = barrier;
|
|
1127
|
+
}
|
|
1128
|
+
async _loadProjection(workbooks) {
|
|
1129
|
+
await loadNativeBinding(), this._nativeReady = !0;
|
|
1130
|
+
let serializeStartedAt = performance.now(), snapshot = serializeRuntimeWorkbookSnapshots(workbooks);
|
|
1131
|
+
this._loadSerializedSnapshot(snapshot, performance.now() - serializeStartedAt);
|
|
1132
|
+
}
|
|
1133
|
+
applyProjectionMutation(mutation) {
|
|
1134
|
+
this._queueOrSyncMutation(mutation);
|
|
1135
|
+
}
|
|
1136
|
+
upsertProjectionWorkbook(workbook) {
|
|
1137
|
+
this._queueOrSyncMutation(createProjectionWorkbookUpsertMutation(workbook));
|
|
1138
|
+
}
|
|
1139
|
+
setProjectionManagedTableUnit(unitId) {
|
|
1140
|
+
this._projectionManagedTableUnits.add(unitId);
|
|
1141
|
+
}
|
|
1142
|
+
unsetProjectionManagedTableUnit(unitId) {
|
|
1143
|
+
this._projectionManagedTableUnits.delete(unitId);
|
|
1144
|
+
}
|
|
1145
|
+
upsertReferenceData(config, needs, tableService) {
|
|
1146
|
+
let mutations = createReferenceDataUpsertMutations(config, needs, tableService);
|
|
1147
|
+
return mutations.forEach((mutation) => this._queueOrSyncMutation(mutation)), mutations.length;
|
|
1148
|
+
}
|
|
1149
|
+
disposeProjectionWorkbook(unitId) {
|
|
1150
|
+
if (!(!this._nativeReady || !this._snapshotLoaded))
|
|
1151
|
+
try {
|
|
1152
|
+
disposeWorkbookOnRust(unitId), markRustFormulaDependenciesInvalidated();
|
|
1153
|
+
} catch {
|
|
1154
|
+
this._markProjectionDesynced();
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
dispose() {
|
|
1158
|
+
if (super.dispose(), this._pendingMutations.length = 0, this._projectionManagedTableUnits.clear(), this._projectionLoadPromise = null, this._projectionDeltaBarrier = Promise.resolve(), !this._nativeReady) {
|
|
1159
|
+
this._snapshotLoaded = !1;
|
|
1160
|
+
return;
|
|
1161
|
+
}
|
|
1162
|
+
try {
|
|
1163
|
+
disposeAllWorkbooksOnRust();
|
|
1164
|
+
} catch {
|
|
1165
|
+
this._markProjectionDesynced();
|
|
1166
|
+
return;
|
|
1167
|
+
}
|
|
1168
|
+
this._nativeReady = !1, this._snapshotLoaded = !1;
|
|
1169
|
+
}
|
|
1170
|
+
_loadSerializedSnapshot(snapshot, serializeMs) {
|
|
1171
|
+
let precisionAsDisplayedWorkbookCount = snapshot.workbooks.filter(
|
|
1172
|
+
(workbook) => workbook.calculation?.fullPrecision === !1
|
|
1173
|
+
).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;
|
|
1174
|
+
try {
|
|
1175
|
+
nativeTimings = JSON.parse(nativeOutput).timingsMs;
|
|
1176
|
+
} catch {
|
|
1177
|
+
nativeTimings = void 0;
|
|
1178
|
+
}
|
|
1179
|
+
emitRustEngineSyncDebugEvent({
|
|
1180
|
+
type: "loadSnapshot",
|
|
1181
|
+
payload: {
|
|
1182
|
+
workbookCount: snapshot.workbooks.length,
|
|
1183
|
+
serializeMs,
|
|
1184
|
+
stringifyMs,
|
|
1185
|
+
nativeMs,
|
|
1186
|
+
precisionAsDisplayedWorkbookCount,
|
|
1187
|
+
displayPrecisionCellCount,
|
|
1188
|
+
snapshotBytes: snapshotBuffer?.byteLength ?? snapshotJson.length,
|
|
1189
|
+
transport: snapshotBuffer ? "binary-json" : "string-json",
|
|
1190
|
+
nativeTimings
|
|
1191
|
+
}
|
|
1192
|
+
}), this._pendingMutations.splice(0, pendingCountCoveredBySnapshot), this._snapshotLoaded = !0, markRustSnapshotLoaded(), this._flushPendingMutations();
|
|
1193
|
+
}
|
|
1194
|
+
_queueOrSyncMutation(mutation) {
|
|
1195
|
+
if (!this._nativeReady || !this._snapshotLoaded) {
|
|
1196
|
+
this._pendingMutations.push(mutation);
|
|
1197
|
+
return;
|
|
1198
|
+
}
|
|
1199
|
+
this._syncMutation(mutation);
|
|
1200
|
+
}
|
|
1201
|
+
_flushPendingMutations() {
|
|
1202
|
+
for (; this._pendingMutations.length > 0; ) {
|
|
1203
|
+
let mutation = this._pendingMutations.shift();
|
|
1204
|
+
mutation && this._syncMutation(mutation);
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
_syncMutation(mutation) {
|
|
1208
|
+
let totalStartedAt = performance.now(), stringifyStartedAt = performance.now(), payload = JSON.stringify(normalizeRustEngineMutation(mutation)), stringifyMs = performance.now() - stringifyStartedAt, nativeStartedAt = performance.now();
|
|
1209
|
+
try {
|
|
1210
|
+
applyMutationOnRust(payload), isRustIncrementalDependencyMutation(mutation.id) || markRustFormulaDependenciesInvalidated();
|
|
1211
|
+
} catch {
|
|
1212
|
+
this._markProjectionDesynced();
|
|
1213
|
+
} finally {
|
|
1214
|
+
emitRustEngineSyncDebugEvent({
|
|
1215
|
+
type: "applyMutation",
|
|
1216
|
+
payload: {
|
|
1217
|
+
id: mutation.id,
|
|
1218
|
+
stringifyMs,
|
|
1219
|
+
nativeMs: performance.now() - nativeStartedAt,
|
|
1220
|
+
totalMs: performance.now() - totalStartedAt,
|
|
1221
|
+
...summarizeObjectMatrixPayload(
|
|
1222
|
+
mutation.params?.cellValue
|
|
1223
|
+
)
|
|
1224
|
+
}
|
|
1225
|
+
});
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
_markProjectionDesynced() {
|
|
1229
|
+
this._nativeReady = !1, this._snapshotLoaded = !1;
|
|
1230
|
+
}
|
|
1231
|
+
_shouldSyncMutation(command, options) {
|
|
1232
|
+
if (command.type !== import_core2.CommandType.MUTATION || !isRustFormulaRelevantMutation(command.id) || (command.id === "formula.mutation.set-super-table" || command.id === "formula.mutation.remove-super-table") && hasUnitId(command.params) && this._projectionManagedTableUnits.has(command.params.unitId))
|
|
1233
|
+
return !1;
|
|
1234
|
+
let syncOptions = options;
|
|
1235
|
+
if (syncOptions?.fromRustFormulaEngine === !0 || syncOptions?.applyFormulaCalculationResult === !0 || command.id === "sheet.mutation.set-range-values" && !hasObjectMatrixValues(command.params?.cellValue))
|
|
1236
|
+
return !1;
|
|
1237
|
+
if (command.id === "formula.mutation.set-formula-calculation-result") {
|
|
1238
|
+
let params = command.params;
|
|
1239
|
+
if (!hasRecordEntries(params?.unitData) && !hasRecordEntries(params?.unitOtherData))
|
|
1240
|
+
return !1;
|
|
1241
|
+
}
|
|
1242
|
+
if (command.id === "formula.mutation.set-array-formula-data") {
|
|
1243
|
+
let params = command.params;
|
|
1244
|
+
if (!hasRecordEntries(params?.arrayFormulaRange) && !hasRecordEntries(params?.arrayFormulaCellData) && !hasRecordEntries(params?.arrayFormulaEmbedded))
|
|
1245
|
+
return !1;
|
|
1246
|
+
}
|
|
1247
|
+
return !0;
|
|
1248
|
+
}
|
|
1249
|
+
_serializeMutation(command, options) {
|
|
1250
|
+
let dirtyRanges = options?.dirtyRanges;
|
|
1251
|
+
return {
|
|
1252
|
+
id: command.id,
|
|
1253
|
+
params: command.params ?? {},
|
|
1254
|
+
dirtyRanges: Array.isArray(dirtyRanges) ? dirtyRanges : []
|
|
1255
|
+
};
|
|
1256
|
+
}
|
|
1257
|
+
};
|
|
1258
|
+
function hasUnitId(value) {
|
|
1259
|
+
return value != null && typeof value == "object" && "unitId" in value && typeof value.unitId == "string";
|
|
1260
|
+
}
|
|
1261
|
+
(0, import_core2.setDependencies)(RustEngineSyncController, [import_core2.ICommandService]);
|
|
1262
|
+
|
|
1263
|
+
// src/numfmt.ts
|
|
1264
|
+
var nativeBindingReady = null;
|
|
1265
|
+
function ensureNativeBinding() {
|
|
1266
|
+
return nativeBindingReady ??= loadNativeBinding().catch((error) => {
|
|
1267
|
+
throw nativeBindingReady = null, error;
|
|
1268
|
+
}), nativeBindingReady;
|
|
1269
|
+
}
|
|
1270
|
+
function parseJsonOutput(output) {
|
|
1271
|
+
return JSON.parse(output);
|
|
1272
|
+
}
|
|
1273
|
+
async function formatNumberBatch(input) {
|
|
1274
|
+
return await ensureNativeBinding(), parseJsonOutput(formatNumberBatchOnRust(JSON.stringify(input)));
|
|
1275
|
+
}
|
|
1276
|
+
async function parseNumberFormatBatch(input) {
|
|
1277
|
+
return await ensureNativeBinding(), parseJsonOutput(parseNumberFormatInputBatchOnRust(JSON.stringify(input)));
|
|
1278
|
+
}
|
|
1279
|
+
async function parseNumberFormatMatrixBatch(input) {
|
|
1280
|
+
return await ensureNativeBinding(), parseJsonOutput(
|
|
1281
|
+
parseNumberFormatMatrixBatchOnRust(JSON.stringify(input))
|
|
1282
|
+
);
|
|
1283
|
+
}
|
|
1284
|
+
async function analyzeNumberFormatBatch(input) {
|
|
1285
|
+
return await ensureNativeBinding(), parseJsonOutput(analyzeNumberFormatBatchOnRust(JSON.stringify(input)));
|
|
1286
|
+
}
|
|
1287
|
+
|
|
1288
|
+
// src/plugin.ts
|
|
1289
|
+
var import_core5 = require("@univerjs/core"), import_engine_formula4 = require("@univerjs/engine-formula"), import_engine_formula5 = require("@univerjs-pro/engine-formula");
|
|
1290
|
+
|
|
1291
|
+
// package.json
|
|
1292
|
+
var name = "@univerjs-pro/engine-formula-rust", version = "1.0.0-beta.2";
|
|
1293
|
+
|
|
1294
|
+
// src/controllers/rust-same-runtime-projection.controller.ts
|
|
1295
|
+
var import_core3 = require("@univerjs/core"), import_engine_formula = require("@univerjs/engine-formula");
|
|
1296
|
+
var RustSameRuntimeProjectionController = class extends import_core3.Disposable {
|
|
1297
|
+
constructor(_univerInstanceService, _rustEngineSyncController, _formulaDataModel, _superTableService, _commandService, _activeDirtyManagerService) {
|
|
1298
|
+
super();
|
|
1299
|
+
this._univerInstanceService = _univerInstanceService;
|
|
1300
|
+
this._rustEngineSyncController = _rustEngineSyncController;
|
|
1301
|
+
this._formulaDataModel = _formulaDataModel;
|
|
1302
|
+
this._superTableService = _superTableService;
|
|
1303
|
+
this._commandService = _commandService;
|
|
1304
|
+
this._activeDirtyManagerService = _activeDirtyManagerService;
|
|
1305
|
+
this._initialize();
|
|
1306
|
+
}
|
|
1307
|
+
_univerInstanceService;
|
|
1308
|
+
_rustEngineSyncController;
|
|
1309
|
+
_formulaDataModel;
|
|
1310
|
+
_superTableService;
|
|
1311
|
+
_commandService;
|
|
1312
|
+
_activeDirtyManagerService;
|
|
1313
|
+
_initialProjectionLoad = Promise.resolve();
|
|
1314
|
+
_projectionDeltaQueue = Promise.resolve();
|
|
1315
|
+
_baseProjectionStructures = /* @__PURE__ */ new Map();
|
|
1316
|
+
_initialize() {
|
|
1317
|
+
for (let base of this._univerInstanceService.getAllUnitsForType(
|
|
1318
|
+
import_core3.UniverInstanceType.UNIVER_BASE
|
|
1319
|
+
))
|
|
1320
|
+
this._rustEngineSyncController.setProjectionManagedTableUnit(base.getUnitId()), this._rememberBaseProjectionStructure(base.getSnapshot());
|
|
1321
|
+
this._initialProjectionLoad = this._loadAllWorkbookProjections(), this.disposeWithMe(
|
|
1322
|
+
(0, import_core3.toDisposable)(
|
|
1323
|
+
this._univerInstanceService.getTypeOfUnitAdded$(import_core3.UniverInstanceType.UNIVER_SHEET).subscribe(({ unit }) => {
|
|
1324
|
+
this._enqueueProjectionDelta(() => {
|
|
1325
|
+
this._rustEngineSyncController.upsertProjectionWorkbook({
|
|
1326
|
+
unitId: unit.getUnitId(),
|
|
1327
|
+
snapshot: unit.getSnapshot()
|
|
1328
|
+
});
|
|
1329
|
+
});
|
|
1330
|
+
})
|
|
1331
|
+
)
|
|
1332
|
+
), this.disposeWithMe(
|
|
1333
|
+
(0, import_core3.toDisposable)(
|
|
1334
|
+
this._univerInstanceService.getTypeOfUnitAdded$(import_core3.UniverInstanceType.UNIVER_BASE).subscribe(({ unit }) => {
|
|
1335
|
+
this._rustEngineSyncController.setProjectionManagedTableUnit(unit.getUnitId()), this._rememberBaseProjectionStructure(unit.getSnapshot()), this._enqueueProjectionDelta(() => this._upsertBaseProjection(unit.getUnitId()));
|
|
1336
|
+
})
|
|
1337
|
+
)
|
|
1338
|
+
), this.disposeWithMe(
|
|
1339
|
+
this._commandService.onCommandExecuted((command) => {
|
|
1340
|
+
command.type !== import_core3.CommandType.MUTATION || !hasUnitId2(command.params) || this._univerInstanceService.getUnit(command.params.unitId, import_core3.UniverInstanceType.UNIVER_BASE) && (hasTrigger(command.params) && command.params.trigger === import_engine_formula.SetFormulaCalculationResultMutation.id || isRustFormulaRelevantMutation(command.id) || this._enqueueProjectionDelta(() => this._syncBaseMutation(command)));
|
|
1341
|
+
})
|
|
1342
|
+
), this.disposeWithMe(
|
|
1343
|
+
(0, import_core3.toDisposable)(
|
|
1344
|
+
this._univerInstanceService.getTypeOfUnitDisposed$(import_core3.UniverInstanceType.UNIVER_BASE).subscribe((base) => {
|
|
1345
|
+
this._baseProjectionStructures.delete(base.getUnitId()), this._rustEngineSyncController.unsetProjectionManagedTableUnit(base.getUnitId()), this._enqueueProjectionDelta(
|
|
1346
|
+
() => this._rustEngineSyncController.disposeProjectionWorkbook(base.getUnitId())
|
|
1347
|
+
);
|
|
1348
|
+
})
|
|
1349
|
+
)
|
|
1350
|
+
), this.disposeWithMe(
|
|
1351
|
+
(0, import_core3.toDisposable)(
|
|
1352
|
+
this._univerInstanceService.getTypeOfUnitDisposed$(import_core3.UniverInstanceType.UNIVER_SHEET).subscribe((workbook) => {
|
|
1353
|
+
this._enqueueProjectionDelta(
|
|
1354
|
+
() => this._rustEngineSyncController.disposeProjectionWorkbook(workbook.getUnitId())
|
|
1355
|
+
);
|
|
1356
|
+
})
|
|
1357
|
+
)
|
|
1358
|
+
), this.disposeWithMe(
|
|
1359
|
+
(0, import_core3.toDisposable)(() => {
|
|
1360
|
+
this._projectionDeltaQueue = Promise.resolve();
|
|
1361
|
+
})
|
|
1362
|
+
);
|
|
1363
|
+
}
|
|
1364
|
+
_enqueueProjectionDelta(task) {
|
|
1365
|
+
this._projectionDeltaQueue = this._projectionDeltaQueue.then(() => this._initialProjectionLoad).then(() => {
|
|
1366
|
+
if (!this._disposed)
|
|
1367
|
+
return task();
|
|
1368
|
+
}).catch(() => {
|
|
1369
|
+
}), this._rustEngineSyncController.setProjectionDeltaBarrier(this._projectionDeltaQueue);
|
|
1370
|
+
}
|
|
1371
|
+
async _syncBaseMutation(command) {
|
|
1372
|
+
if (!hasUnitId2(command.params)) return;
|
|
1373
|
+
let unitId = command.params.unitId, dirtyData = this._activeDirtyManagerService.get(command.id)?.getDirtyData(command), dirtyRanges = (dirtyData?.dirtyRanges ?? []).filter((dirtyRange) => dirtyRange.unitId === unitId), hasStructureInvalidation = !!dirtyData?.clearDependencyTreeCache?.[unitId] || !!(dirtyData?.forceCalculation && dirtyRanges.length === 0);
|
|
1374
|
+
if (dirtyRanges.length > 0 && !hasStructureInvalidation) {
|
|
1375
|
+
this._applyBaseDirtyRanges(unitId, dirtyRanges);
|
|
1376
|
+
return;
|
|
1377
|
+
}
|
|
1378
|
+
hasStructureInvalidation && this._isBaseProjectionStructureUnchanged(unitId) || hasStructureInvalidation && this._applyBaseFieldInsertion(unitId, dirtyRanges) || await this._upsertBaseProjection(unitId);
|
|
1379
|
+
}
|
|
1380
|
+
_applyBaseFieldInsertion(unitId, dirtyRanges) {
|
|
1381
|
+
let base = this._univerInstanceService.getUnit(unitId, import_core3.UniverInstanceType.UNIVER_BASE), previous = this._baseProjectionStructures.get(unitId);
|
|
1382
|
+
if (!base || !previous) return !1;
|
|
1383
|
+
let snapshot = base.getSnapshot(), insertion = findSingleBaseFieldInsertion(previous, snapshot);
|
|
1384
|
+
if (!insertion) return !1;
|
|
1385
|
+
let projectionData = this._getBaseProjectionData(unitId), sheet = projectionData?.calculationData.allUnitData[unitId]?.[insertion.tableId];
|
|
1386
|
+
if (!projectionData || !sheet) return !1;
|
|
1387
|
+
let formulaData = projectionData.formulaData[unitId]?.[insertion.tableId], cellValue = {};
|
|
1388
|
+
for (let row = 0; row < sheet.rowCount; row++) {
|
|
1389
|
+
let value = sheet.cellData.getValue(row, insertion.column), formula = formulaData?.[row]?.[insertion.column];
|
|
1390
|
+
cellValue[row] = {
|
|
1391
|
+
[insertion.column]: formula ? { ...value, ...formula } : value ?? null
|
|
1392
|
+
};
|
|
1393
|
+
}
|
|
1394
|
+
let insertedRange = {
|
|
1395
|
+
startRow: 0,
|
|
1396
|
+
endRow: Math.max(0, sheet.rowCount - 1),
|
|
1397
|
+
startColumn: insertion.column,
|
|
1398
|
+
endColumn: insertion.column
|
|
1399
|
+
};
|
|
1400
|
+
return this._rustEngineSyncController.applyProjectionMutation({
|
|
1401
|
+
id: "sheet.mutation.insert-col",
|
|
1402
|
+
params: {
|
|
1403
|
+
unitId,
|
|
1404
|
+
subUnitId: insertion.tableId,
|
|
1405
|
+
range: insertedRange
|
|
1406
|
+
},
|
|
1407
|
+
dirtyRanges: []
|
|
1408
|
+
}), this._rustEngineSyncController.applyProjectionMutation({
|
|
1409
|
+
id: "sheet.mutation.set-range-values",
|
|
1410
|
+
params: {
|
|
1411
|
+
unitId,
|
|
1412
|
+
subUnitId: insertion.tableId,
|
|
1413
|
+
cellValue
|
|
1414
|
+
},
|
|
1415
|
+
dirtyRanges: [
|
|
1416
|
+
{
|
|
1417
|
+
unitId,
|
|
1418
|
+
sheetId: insertion.tableId,
|
|
1419
|
+
range: insertedRange
|
|
1420
|
+
}
|
|
1421
|
+
]
|
|
1422
|
+
}), this._rustEngineSyncController.applyProjectionMutation({
|
|
1423
|
+
id: RUST_SET_SUPER_TABLES_MUTATION_ID,
|
|
1424
|
+
params: {
|
|
1425
|
+
unitId,
|
|
1426
|
+
tables: this._getBaseTableEntries(
|
|
1427
|
+
insertion.tableId,
|
|
1428
|
+
snapshot,
|
|
1429
|
+
(0, import_core3.createBaseFormulaTableNameMap)(snapshot)
|
|
1430
|
+
).map(([tableName, reference]) => ({
|
|
1431
|
+
tableName,
|
|
1432
|
+
reference
|
|
1433
|
+
}))
|
|
1434
|
+
},
|
|
1435
|
+
dirtyRanges: []
|
|
1436
|
+
}), dirtyRanges.length > 0 && this._applyBaseDirtyRanges(unitId, dirtyRanges), this._rememberBaseProjectionStructure(snapshot), !0;
|
|
1437
|
+
}
|
|
1438
|
+
_applyBaseDirtyRanges(unitId, dirtyRanges) {
|
|
1439
|
+
let projectionData = this._getBaseProjectionData(unitId);
|
|
1440
|
+
if (!projectionData) return;
|
|
1441
|
+
let { calculationData, formulaData } = projectionData, rangesBySheet = /* @__PURE__ */ new Map();
|
|
1442
|
+
for (let dirtyRange of dirtyRanges) {
|
|
1443
|
+
let ranges = rangesBySheet.get(dirtyRange.sheetId) ?? [];
|
|
1444
|
+
ranges.push(dirtyRange), rangesBySheet.set(dirtyRange.sheetId, ranges);
|
|
1445
|
+
}
|
|
1446
|
+
for (let [sheetId, ranges] of rangesBySheet) {
|
|
1447
|
+
let sheet = calculationData.allUnitData[unitId]?.[sheetId];
|
|
1448
|
+
if (!sheet) continue;
|
|
1449
|
+
let cellValue = {};
|
|
1450
|
+
for (let { range } of ranges)
|
|
1451
|
+
for (let row = range.startRow; row <= range.endRow; row++)
|
|
1452
|
+
for (let column = range.startColumn; column <= range.endColumn; column++) {
|
|
1453
|
+
let value = sheet.cellData.getValue(row, column), formula = formulaData[unitId]?.[sheetId]?.[row]?.[column];
|
|
1454
|
+
(cellValue[row] ??= {})[column] = formula ? { ...value, ...formula } : value ?? null;
|
|
1455
|
+
}
|
|
1456
|
+
this._rustEngineSyncController.applyProjectionMutation({
|
|
1457
|
+
id: "sheet.mutation.set-range-values",
|
|
1458
|
+
params: {
|
|
1459
|
+
unitId,
|
|
1460
|
+
subUnitId: sheetId,
|
|
1461
|
+
cellValue
|
|
1462
|
+
},
|
|
1463
|
+
dirtyRanges: ranges
|
|
1464
|
+
});
|
|
1465
|
+
}
|
|
1466
|
+
}
|
|
1467
|
+
async _upsertBaseProjection(unitId) {
|
|
1468
|
+
let projectionData = this._getBaseProjectionData(unitId);
|
|
1469
|
+
if (!projectionData) return;
|
|
1470
|
+
let { calculationData, formulaData } = projectionData, workbook = this._createBaseWorkbookProjection(
|
|
1471
|
+
unitId,
|
|
1472
|
+
calculationData.allUnitData,
|
|
1473
|
+
calculationData.unitSheetNameMap,
|
|
1474
|
+
calculationData.unitNameMap,
|
|
1475
|
+
formulaData
|
|
1476
|
+
);
|
|
1477
|
+
workbook && this._rustEngineSyncController.upsertProjectionWorkbook(workbook);
|
|
1478
|
+
let base = this._univerInstanceService.getUnit(unitId, import_core3.UniverInstanceType.UNIVER_BASE);
|
|
1479
|
+
base && this._rememberBaseProjectionStructure(base.getSnapshot());
|
|
1480
|
+
}
|
|
1481
|
+
_rememberBaseProjectionStructure(snapshot) {
|
|
1482
|
+
this._baseProjectionStructures.set(snapshot.id, createBaseProjectionStructure(snapshot));
|
|
1483
|
+
}
|
|
1484
|
+
_isBaseProjectionStructureUnchanged(unitId) {
|
|
1485
|
+
let base = this._univerInstanceService.getUnit(unitId, import_core3.UniverInstanceType.UNIVER_BASE), previous = this._baseProjectionStructures.get(unitId);
|
|
1486
|
+
return !!(base && previous && isSameBaseProjectionStructure(previous, createBaseProjectionStructure(base.getSnapshot())));
|
|
1487
|
+
}
|
|
1488
|
+
_getBaseProjectionData(unitId) {
|
|
1489
|
+
let base = this._univerInstanceService.getUnit(unitId, import_core3.UniverInstanceType.UNIVER_BASE);
|
|
1490
|
+
if (!base) return null;
|
|
1491
|
+
let snapshot = base.getSnapshot(), allUnitData = { [unitId]: {} }, unitSheetNameMap = { [unitId]: {} }, unitNameMap = {
|
|
1492
|
+
[unitId]: {
|
|
1493
|
+
name: snapshot.name,
|
|
1494
|
+
unitType: import_core3.UniverInstanceType.UNIVER_BASE
|
|
1495
|
+
}
|
|
1496
|
+
}, formulaData = { [unitId]: {} }, formulaTableNames = (0, import_core3.createBaseFormulaTableNameMap)(snapshot), normalizeFormulaTableReferences = (0, import_core3.createBaseFormulaTableReferenceNormalizer)(snapshot, formulaTableNames);
|
|
1497
|
+
for (let table of Object.values(snapshot.tables)) {
|
|
1498
|
+
let fieldOrder = table.fieldOrder;
|
|
1499
|
+
allUnitData[unitId][table.id] = {
|
|
1500
|
+
cellData: new import_core3.ObjectMatrix(
|
|
1501
|
+
buildBaseRuntimeCellData(table)
|
|
1502
|
+
),
|
|
1503
|
+
rowCount: baseRecordOrder(table).length,
|
|
1504
|
+
columnCount: fieldOrder.length,
|
|
1505
|
+
rowData: {},
|
|
1506
|
+
columnData: {}
|
|
1507
|
+
}, unitSheetNameMap[unitId][formulaTableNames.get(table.id)] = table.id;
|
|
1508
|
+
let tableFormulaData = {}, normalizedFormulaByFieldId = /* @__PURE__ */ new Map(), recordOrder = baseRecordOrder(table);
|
|
1509
|
+
for (let row = 0; row < recordOrder.length; row++)
|
|
1510
|
+
if (table.records[recordOrder[row]])
|
|
1511
|
+
for (let column = 0; column < fieldOrder.length; column++) {
|
|
1512
|
+
let field = table.fields[fieldOrder[column]];
|
|
1513
|
+
if (!field || field.type !== "formula") continue;
|
|
1514
|
+
let formula = String(field.config?.formula ?? "").trim();
|
|
1515
|
+
if (!formula) continue;
|
|
1516
|
+
let normalizedFormula = normalizedFormulaByFieldId.get(field.id);
|
|
1517
|
+
normalizedFormula == null && (normalizedFormula = normalizeBaseFormulaForEngine(
|
|
1518
|
+
formula,
|
|
1519
|
+
table,
|
|
1520
|
+
formulaTableNames,
|
|
1521
|
+
normalizeFormulaTableReferences
|
|
1522
|
+
), normalizedFormulaByFieldId.set(field.id, normalizedFormula)), (tableFormulaData[row] ??= {})[column] = {
|
|
1523
|
+
f: normalizedFormula,
|
|
1524
|
+
si: field.id
|
|
1525
|
+
};
|
|
1526
|
+
}
|
|
1527
|
+
formulaData[unitId][table.id] = tableFormulaData;
|
|
1528
|
+
}
|
|
1529
|
+
return {
|
|
1530
|
+
calculationData: {
|
|
1531
|
+
allUnitData,
|
|
1532
|
+
unitSheetNameMap,
|
|
1533
|
+
unitNameMap
|
|
1534
|
+
},
|
|
1535
|
+
formulaData
|
|
1536
|
+
};
|
|
1537
|
+
}
|
|
1538
|
+
async _loadAllWorkbookProjections() {
|
|
1539
|
+
let workbooks = this._univerInstanceService.getAllUnitsForType(import_core3.UniverInstanceType.UNIVER_SHEET).map((workbook) => ({
|
|
1540
|
+
unitId: workbook.getUnitId(),
|
|
1541
|
+
snapshot: workbook.getSnapshot()
|
|
1542
|
+
})), calculationData = this._formulaDataModel.getCalculateData(), formulaData = this._formulaDataModel.getFormulaData(), baseWorkbooks = this._univerInstanceService.getAllUnitsForType(import_core3.UniverInstanceType.UNIVER_BASE).map(
|
|
1543
|
+
(base) => this._createBaseWorkbookProjection(
|
|
1544
|
+
base.getUnitId(),
|
|
1545
|
+
calculationData.allUnitData,
|
|
1546
|
+
calculationData.unitSheetNameMap,
|
|
1547
|
+
calculationData.unitNameMap ?? {},
|
|
1548
|
+
formulaData
|
|
1549
|
+
)
|
|
1550
|
+
).filter((workbook) => workbook != null);
|
|
1551
|
+
workbooks.push(...baseWorkbooks), await this._rustEngineSyncController.loadProjection(workbooks);
|
|
1552
|
+
}
|
|
1553
|
+
_createBaseWorkbookProjection(unitId, allUnitData, unitSheetNameMap, unitNameMap, formulaData) {
|
|
1554
|
+
let unitData = allUnitData[unitId];
|
|
1555
|
+
if (!unitData) return null;
|
|
1556
|
+
let sheetNameMap = unitSheetNameMap[unitId] ?? {}, sheetOrder = Object.keys(unitData), resources = this._createBaseTableResource(unitId), sheets = {};
|
|
1557
|
+
for (let sheetId of sheetOrder) {
|
|
1558
|
+
let sheet = unitData[sheetId];
|
|
1559
|
+
if (!sheet) continue;
|
|
1560
|
+
let cellData = this._rawCellData(sheet.cellData);
|
|
1561
|
+
for (let [rowKey, row] of Object.entries(formulaData[unitId]?.[sheetId] ?? {}))
|
|
1562
|
+
for (let [columnKey, formula] of Object.entries(row ?? {})) {
|
|
1563
|
+
if (!formula) continue;
|
|
1564
|
+
let rowIndex = Number(rowKey), columnIndex = Number(columnKey), current = cellData[rowIndex]?.[columnIndex] ?? {};
|
|
1565
|
+
(cellData[rowIndex] ??= {})[columnIndex] = { ...current, ...formula };
|
|
1566
|
+
}
|
|
1567
|
+
sheets[sheetId] = {
|
|
1568
|
+
id: sheetId,
|
|
1569
|
+
name: Object.entries(sheetNameMap).find(([, currentSheetId]) => currentSheetId === sheetId)?.[0] ?? sheetId,
|
|
1570
|
+
rowCount: sheet.rowCount,
|
|
1571
|
+
columnCount: sheet.columnCount,
|
|
1572
|
+
cellData,
|
|
1573
|
+
rowData: sheet.rowData,
|
|
1574
|
+
columnData: sheet.columnData
|
|
1575
|
+
};
|
|
1576
|
+
}
|
|
1577
|
+
return {
|
|
1578
|
+
unitId,
|
|
1579
|
+
snapshot: {
|
|
1580
|
+
id: unitId,
|
|
1581
|
+
name: unitNameMap[unitId]?.name ?? unitId,
|
|
1582
|
+
appVersion: "",
|
|
1583
|
+
locale: import_core3.LocaleType.EN_US,
|
|
1584
|
+
styles: {},
|
|
1585
|
+
sheetOrder,
|
|
1586
|
+
sheets,
|
|
1587
|
+
resources
|
|
1588
|
+
}
|
|
1589
|
+
};
|
|
1590
|
+
}
|
|
1591
|
+
_createBaseTableResource(unitId) {
|
|
1592
|
+
let base = this._univerInstanceService.getUnit(unitId, import_core3.UniverInstanceType.UNIVER_BASE);
|
|
1593
|
+
if (base) {
|
|
1594
|
+
let snapshot = base.getSnapshot(), tables = Object.values(snapshot.tables), formulaTableNames = (0, import_core3.createBaseFormulaTableNameMap)(snapshot), data2 = {};
|
|
1595
|
+
for (let table of tables)
|
|
1596
|
+
for (let [name2, reference] of this._getBaseTableEntries(table.id, snapshot, formulaTableNames)) {
|
|
1597
|
+
let columns = Array.from(reference.titleMap.entries()).toSorted((left, right) => left[1] - right[1]).map(([displayName]) => ({ displayName }));
|
|
1598
|
+
(data2[table.id] ??= { tables: [] }).tables.push({
|
|
1599
|
+
name: name2,
|
|
1600
|
+
range: reference.range,
|
|
1601
|
+
columns,
|
|
1602
|
+
options: { showHeader: reference.showHeader !== !1 }
|
|
1603
|
+
});
|
|
1604
|
+
}
|
|
1605
|
+
return [
|
|
1606
|
+
{
|
|
1607
|
+
name: "SHEET_TABLE_PLUGIN",
|
|
1608
|
+
data: JSON.stringify(data2)
|
|
1609
|
+
}
|
|
1610
|
+
];
|
|
1611
|
+
}
|
|
1612
|
+
let tableMap = this._superTableService.getTableMap(unitId);
|
|
1613
|
+
if (!tableMap) return [];
|
|
1614
|
+
let data = {};
|
|
1615
|
+
for (let [name2, table] of tableMap) {
|
|
1616
|
+
let columns = Array.from(table.titleMap.entries()).toSorted((left, right) => left[1] - right[1]).map(([displayName]) => ({ displayName }));
|
|
1617
|
+
(data[table.sheetId] ??= { tables: [] }).tables.push({
|
|
1618
|
+
name: name2,
|
|
1619
|
+
range: table.range,
|
|
1620
|
+
columns,
|
|
1621
|
+
options: { showHeader: table.showHeader !== !1 }
|
|
1622
|
+
});
|
|
1623
|
+
}
|
|
1624
|
+
return [
|
|
1625
|
+
{
|
|
1626
|
+
name: "SHEET_TABLE_PLUGIN",
|
|
1627
|
+
data: JSON.stringify(data)
|
|
1628
|
+
}
|
|
1629
|
+
];
|
|
1630
|
+
}
|
|
1631
|
+
_getBaseTableEntries(tableId, snapshot, formulaTableNames) {
|
|
1632
|
+
let table = snapshot.tables[tableId];
|
|
1633
|
+
if (!table) return [];
|
|
1634
|
+
let recordCount = baseRecordOrder(table).length, fieldOrder = table.fieldOrder, reference = {
|
|
1635
|
+
sheetId: table.id,
|
|
1636
|
+
range: {
|
|
1637
|
+
startRow: 0,
|
|
1638
|
+
endRow: Math.max(0, recordCount - 1),
|
|
1639
|
+
startColumn: 0,
|
|
1640
|
+
endColumn: Math.max(0, fieldOrder.length - 1)
|
|
1641
|
+
},
|
|
1642
|
+
titleMap: new Map(fieldOrder.map((fieldId, index) => [table.fields[fieldId]?.name ?? fieldId, index])),
|
|
1643
|
+
showHeader: !1
|
|
1644
|
+
};
|
|
1645
|
+
return [[formulaTableNames.get(table.id), reference]];
|
|
1646
|
+
}
|
|
1647
|
+
_rawCellData(cellData) {
|
|
1648
|
+
let raw = cellData.getMatrix(), result = {};
|
|
1649
|
+
for (let [row, values] of Object.entries(raw ?? {})) {
|
|
1650
|
+
let rowData = {};
|
|
1651
|
+
for (let [column, value] of Object.entries(values ?? {}))
|
|
1652
|
+
value && (rowData[Number(column)] = { ...value });
|
|
1653
|
+
result[Number(row)] = rowData;
|
|
1654
|
+
}
|
|
1655
|
+
return result;
|
|
1656
|
+
}
|
|
1657
|
+
};
|
|
1658
|
+
function createBaseProjectionStructure(snapshot) {
|
|
1659
|
+
let formulaTableNames = (0, import_core3.createBaseFormulaTableNameMap)(snapshot);
|
|
1660
|
+
return {
|
|
1661
|
+
unitName: snapshot.name,
|
|
1662
|
+
tables: Object.fromEntries(
|
|
1663
|
+
Object.values(snapshot.tables).map((table) => [
|
|
1664
|
+
table.id,
|
|
1665
|
+
{
|
|
1666
|
+
formulaName: formulaTableNames.get(table.id),
|
|
1667
|
+
fieldOrder: [...table.fieldOrder],
|
|
1668
|
+
recordOrder: baseRecordOrder(table),
|
|
1669
|
+
fieldSignatures: Object.fromEntries(
|
|
1670
|
+
Object.entries(table.fields).map(([fieldId, field]) => [fieldId, JSON.stringify(field)])
|
|
1671
|
+
)
|
|
1672
|
+
}
|
|
1673
|
+
])
|
|
1674
|
+
)
|
|
1675
|
+
};
|
|
1676
|
+
}
|
|
1677
|
+
function isSameBaseProjectionStructure(left, right) {
|
|
1678
|
+
return JSON.stringify(left) === JSON.stringify(right);
|
|
1679
|
+
}
|
|
1680
|
+
function findSingleBaseFieldInsertion(previous, snapshot) {
|
|
1681
|
+
let current = createBaseProjectionStructure(snapshot), previousTableIds = Object.keys(previous.tables).toSorted(), currentTableIds = Object.keys(current.tables).toSorted();
|
|
1682
|
+
if (JSON.stringify(previousTableIds) !== JSON.stringify(currentTableIds)) return null;
|
|
1683
|
+
let insertion = null;
|
|
1684
|
+
for (let tableId of currentTableIds) {
|
|
1685
|
+
let before = previous.tables[tableId], after = current.tables[tableId];
|
|
1686
|
+
if (!before || !after || before.formulaName !== after.formulaName || JSON.stringify(before.recordOrder) !== JSON.stringify(after.recordOrder)) return null;
|
|
1687
|
+
for (let fieldId of before.fieldOrder)
|
|
1688
|
+
if (before.fieldSignatures[fieldId] !== after.fieldSignatures[fieldId]) return null;
|
|
1689
|
+
if (JSON.stringify(before.fieldOrder) === JSON.stringify(after.fieldOrder)) continue;
|
|
1690
|
+
if (insertion || after.fieldOrder.length !== before.fieldOrder.length + 1) return null;
|
|
1691
|
+
let column = after.fieldOrder.findIndex((fieldId, index) => fieldId !== before.fieldOrder[index]);
|
|
1692
|
+
if (column < 0) return null;
|
|
1693
|
+
let withoutInserted = after.fieldOrder.filter((_, index) => index !== column);
|
|
1694
|
+
if (JSON.stringify(withoutInserted) !== JSON.stringify(before.fieldOrder)) return null;
|
|
1695
|
+
insertion = { tableId, column };
|
|
1696
|
+
}
|
|
1697
|
+
return insertion;
|
|
1698
|
+
}
|
|
1699
|
+
var BASE_LEGACY_FIELD_REF_PATTERN = /\{([^}]+)\}/g, BASE_TABLE_REFERENCE_PREFIX = /\b[A-Z_][\w.]*\[/gi, BASE_SCOPED_FIELD_REF_PATTERN = /(^|[^\w[])\[\[\s*#(This Row|Data)\s*\],\s*\[([^\]]+)\]\]/gi, BASE_CURRENT_ROW_FIELD_REF_PATTERN = /(^|[^\w[])\[@\[([^\]]+)\]\](?!\])/g, BASE_BRACKET_FIELD_REF_PATTERN = /(^|[^A-Za-z0-9_[\]])\[([^\]]+)\]/g, BASE_EXTERNAL_A1_REF_PATTERN = /(?:'\[[^\]]+\](?:[^']|'')+'|\[[^\]]+\][^\s'!]+)!\$?[A-Z]{1,3}\$?\d+(?::\$?[A-Z]{1,3}\$?\d+)?/gi, BASE_EXTERNAL_STRUCTURED_REFERENCE_PREFIX = /(?:'((?:[^']|'')+)'|\[[^\]]+\]|[A-Za-z0-9_.-]+)![^\s![\]]+\[/g;
|
|
1700
|
+
function normalizeBaseFormulaForEngine(formula, currentTable, formulaTableNames, normalizeFormulaTableReferences) {
|
|
1701
|
+
let canonicalFormula = normalizeFormulaTableReferences(formula), references = [], hold = (reference) => `__BASE_FORMULA_REF_${references.push(reference) - 1}__`;
|
|
1702
|
+
return protectBaseTableReferences(protectBaseExternalReferences(canonicalFormula, hold), hold).replace(
|
|
1703
|
+
BASE_LEGACY_FIELD_REF_PATTERN,
|
|
1704
|
+
(_match, fieldName) => hold(createEngineThisRowRef(currentTable, fieldName, formulaTableNames))
|
|
1705
|
+
).replace(BASE_SCOPED_FIELD_REF_PATTERN, (_match, prefix, scope, fieldName) => {
|
|
1706
|
+
let tableName = formulaTableNames.get(currentTable.id) ?? currentTable.name;
|
|
1707
|
+
return `${prefix}${hold(`${tableName}[[#${scope}],[${fieldName}]]`)}`;
|
|
1708
|
+
}).replace(BASE_CURRENT_ROW_FIELD_REF_PATTERN, (_match, prefix, fieldName) => `${prefix}${hold(createEngineThisRowRef(currentTable, fieldName, formulaTableNames))}`).replace(BASE_BRACKET_FIELD_REF_PATTERN, (_match, prefix, fieldName) => `${prefix}${hold(createEngineThisRowRef(currentTable, fieldName, formulaTableNames))}`).replace(
|
|
1709
|
+
/__BASE_FORMULA_REF_(\d+)__/g,
|
|
1710
|
+
(_match, index) => references[Number(index)] ?? ""
|
|
1711
|
+
);
|
|
1712
|
+
}
|
|
1713
|
+
function protectBaseTableReferences(formula, replace) {
|
|
1714
|
+
return protectBaseStructuredReferences(formula, BASE_TABLE_REFERENCE_PREFIX, replace);
|
|
1715
|
+
}
|
|
1716
|
+
function protectBaseExternalReferences(formula, replace) {
|
|
1717
|
+
let withProtectedA1 = formula.replace(
|
|
1718
|
+
BASE_EXTERNAL_A1_REF_PATTERN,
|
|
1719
|
+
(reference, offset) => isInsideBaseFormulaString(formula, offset) ? reference : replace(reference)
|
|
1720
|
+
);
|
|
1721
|
+
return protectBaseExternalStructuredReferences(withProtectedA1, replace);
|
|
1722
|
+
}
|
|
1723
|
+
function protectBaseExternalStructuredReferences(formula, replace) {
|
|
1724
|
+
return protectBaseStructuredReferences(formula, BASE_EXTERNAL_STRUCTURED_REFERENCE_PREFIX, replace);
|
|
1725
|
+
}
|
|
1726
|
+
function protectBaseStructuredReferences(formula, prefixPattern, replace) {
|
|
1727
|
+
let spans = [];
|
|
1728
|
+
prefixPattern.lastIndex = 0;
|
|
1729
|
+
let match;
|
|
1730
|
+
for (; (match = prefixPattern.exec(formula)) != null; ) {
|
|
1731
|
+
if (isInsideBaseFormulaString(formula, match.index)) continue;
|
|
1732
|
+
let openBracket = prefixPattern.lastIndex - 1, depth = 0;
|
|
1733
|
+
for (let index = openBracket; index < formula.length; index++)
|
|
1734
|
+
if (formula[index] === "[" && depth++, formula[index] === "]" && (depth--, depth === 0)) {
|
|
1735
|
+
spans.push({ start: match.index, end: index + 1 }), prefixPattern.lastIndex = index + 1;
|
|
1736
|
+
break;
|
|
1737
|
+
}
|
|
1738
|
+
}
|
|
1739
|
+
if (spans.length === 0) return formula;
|
|
1740
|
+
let result = "", offset = 0;
|
|
1741
|
+
for (let span of spans)
|
|
1742
|
+
result += formula.slice(offset, span.start), result += replace(formula.slice(span.start, span.end)), offset = span.end;
|
|
1743
|
+
return result + formula.slice(offset);
|
|
1744
|
+
}
|
|
1745
|
+
function isInsideBaseFormulaString(formula, position) {
|
|
1746
|
+
let inString = !1;
|
|
1747
|
+
for (let index = 0; index < position; index++)
|
|
1748
|
+
if (formula[index] === '"') {
|
|
1749
|
+
if (inString && formula[index + 1] === '"') {
|
|
1750
|
+
index++;
|
|
1751
|
+
continue;
|
|
1752
|
+
}
|
|
1753
|
+
inString = !inString;
|
|
1754
|
+
}
|
|
1755
|
+
return inString;
|
|
1756
|
+
}
|
|
1757
|
+
function createEngineThisRowRef(table, fieldName, formulaTableNames) {
|
|
1758
|
+
return `${formulaTableNames.get(table.id) ?? table.name}[[#This Row],[${fieldName}]]`;
|
|
1759
|
+
}
|
|
1760
|
+
function baseRecordOrder(table) {
|
|
1761
|
+
return table.recordOrder ? table.recordOrder.filter((recordId) => table.records[recordId] != null) : Object.values(table.records ?? {}).toSorted((left, right) => left.orderKey.localeCompare(right.orderKey)).map((record) => record.id);
|
|
1762
|
+
}
|
|
1763
|
+
function buildBaseRuntimeCellData(table) {
|
|
1764
|
+
let cellData = { ...table.cellData }, fieldOrder = table.fieldOrder, recordOrder = baseRecordOrder(table);
|
|
1765
|
+
for (let row = 0; row < recordOrder.length; row++) {
|
|
1766
|
+
let record = table.records[recordOrder[row]];
|
|
1767
|
+
if (record) {
|
|
1768
|
+
cellData[row] = { ...cellData[row] };
|
|
1769
|
+
for (let column = 0; column < fieldOrder.length; column++) {
|
|
1770
|
+
let fieldId = fieldOrder[column];
|
|
1771
|
+
table.fields[fieldId] && Object.prototype.hasOwnProperty.call(record.values ?? {}, fieldId) && (cellData[row][column] = toBaseRuntimeCellData(record.values[fieldId], table.fields[fieldId]));
|
|
1772
|
+
}
|
|
1773
|
+
}
|
|
1774
|
+
}
|
|
1775
|
+
return cellData;
|
|
1776
|
+
}
|
|
1777
|
+
function toBaseRuntimeCellData(value, field) {
|
|
1778
|
+
if (isBaseCellData(value))
|
|
1779
|
+
return { ...value, t: inferBaseRuntimeCellType(value.v ?? null) };
|
|
1780
|
+
if (field?.type === "attachment")
|
|
1781
|
+
return { v: "", t: import_core3.CellValueType.STRING };
|
|
1782
|
+
if (Array.isArray(value))
|
|
1783
|
+
return { v: value.join(", "), t: import_core3.CellValueType.STRING };
|
|
1784
|
+
if (field?.type === "link" && value && typeof value == "object") {
|
|
1785
|
+
let link = value;
|
|
1786
|
+
return { v: String(link.text ?? link.url ?? ""), t: import_core3.CellValueType.STRING };
|
|
1787
|
+
}
|
|
1788
|
+
return value === null || typeof value == "string" || typeof value == "number" || typeof value == "boolean" ? { v: value, t: inferBaseRuntimeCellType(value) } : { v: null, t: null };
|
|
1789
|
+
}
|
|
1790
|
+
function inferBaseRuntimeCellType(value) {
|
|
1791
|
+
return typeof value == "number" ? import_core3.CellValueType.NUMBER : typeof value == "boolean" ? import_core3.CellValueType.BOOLEAN : typeof value == "string" ? import_core3.CellValueType.STRING : null;
|
|
1792
|
+
}
|
|
1793
|
+
function isBaseCellData(value) {
|
|
1794
|
+
return value != null && typeof value == "object" && ["v", "t", "p", "f", "si"].some((key) => Object.prototype.hasOwnProperty.call(value, key));
|
|
1795
|
+
}
|
|
1796
|
+
function hasUnitId2(value) {
|
|
1797
|
+
return value != null && typeof value == "object" && "unitId" in value && typeof value.unitId == "string";
|
|
1798
|
+
}
|
|
1799
|
+
function hasTrigger(value) {
|
|
1800
|
+
return "trigger" in value && typeof value.trigger == "string";
|
|
1801
|
+
}
|
|
1802
|
+
(0, import_core3.setDependencies)(RustSameRuntimeProjectionController, [
|
|
1803
|
+
import_core3.IUniverInstanceService,
|
|
1804
|
+
RustEngineSyncController,
|
|
1805
|
+
import_engine_formula.FormulaDataModel,
|
|
1806
|
+
import_engine_formula.ISuperTableService,
|
|
1807
|
+
import_core3.ICommandService,
|
|
1808
|
+
import_engine_formula.IActiveDirtyManagerService
|
|
1809
|
+
]);
|
|
1810
|
+
|
|
1811
|
+
// src/services/calculate-formula.service.ts
|
|
1812
|
+
var import_core4 = require("@univerjs/core"), import_engine_formula2 = require("@univerjs/engine-formula"), import_engine_formula3 = require("@univerjs-pro/engine-formula"), import_rxjs = require("rxjs");
|
|
1813
|
+
var IRustCalculateFormulaService = (0, import_core4.createIdentifier)(
|
|
1814
|
+
"engine-formula-rust.calculate-formula.service"
|
|
1815
|
+
), 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;
|
|
1816
|
+
function serializeRuntimeFeatureCellData(runtimeCellData) {
|
|
1817
|
+
let result = {};
|
|
1818
|
+
return Object.entries(runtimeCellData ?? {}).forEach(([unitId, sheetMap]) => {
|
|
1819
|
+
if (!sheetMap) return;
|
|
1820
|
+
let unitData = {};
|
|
1821
|
+
result[unitId] = unitData, Object.entries(sheetMap).forEach(([sheetId, matrix]) => {
|
|
1822
|
+
if (!matrix) return;
|
|
1823
|
+
let sheetData = {};
|
|
1824
|
+
unitData[sheetId] = sheetData, matrix.forValue((row, column, cell) => {
|
|
1825
|
+
if (cell == null) return;
|
|
1826
|
+
let rowData = sheetData[row] ??= {};
|
|
1827
|
+
rowData[column] = {
|
|
1828
|
+
v: cell.v,
|
|
1829
|
+
...typeof cell.t == "number" ? { t: cell.t } : {},
|
|
1830
|
+
...cell.p != null ? { p: cell.p } : {},
|
|
1831
|
+
...typeof cell.f == "string" ? { f: cell.f } : {},
|
|
1832
|
+
...typeof cell.si == "string" ? { si: cell.si } : {},
|
|
1833
|
+
...typeof cell.ref == "string" ? { ref: cell.ref } : {},
|
|
1834
|
+
...typeof cell.xf == "string" ? { xf: cell.xf } : {},
|
|
1835
|
+
...cell.s != null ? { s: cell.s } : {}
|
|
1836
|
+
};
|
|
1837
|
+
});
|
|
1838
|
+
});
|
|
1839
|
+
}), result;
|
|
1840
|
+
}
|
|
1841
|
+
function emitRustFormulaDebugEvent(event) {
|
|
1842
|
+
let hook = globalThis.__UNIVER_RUST_FORMULA_DEBUG_HOOK__;
|
|
1843
|
+
typeof hook == "function" && hook(event);
|
|
1844
|
+
}
|
|
1845
|
+
function firstResultBatchValue(output) {
|
|
1846
|
+
return output.resultBatches?.find((batch) => batch.values.length > 0)?.values[0];
|
|
1847
|
+
}
|
|
1848
|
+
function resultBatchSheetCounts(output) {
|
|
1849
|
+
let counts = {};
|
|
1850
|
+
for (let batch of output.resultBatches ?? []) {
|
|
1851
|
+
let key = `${batch.unitId}/${batch.sheetId}`;
|
|
1852
|
+
counts[key] = (counts[key] ?? 0) + batch.values.length;
|
|
1853
|
+
}
|
|
1854
|
+
return counts;
|
|
1855
|
+
}
|
|
1856
|
+
var RustCalculateFormulaService = class extends import_core4.Disposable {
|
|
1857
|
+
constructor(_configService, _currentConfigService, _runtimeService, _formulaDependencyGenerator, _featureCalculationManagerService, _otherFormulaManagerService, _commandService, _rustEngineSyncController, _formulaDataModel, _formulaReferenceDataService, _excelExternalReferenceModel, _superTableService) {
|
|
1858
|
+
super();
|
|
1859
|
+
this._configService = _configService;
|
|
1860
|
+
this._currentConfigService = _currentConfigService;
|
|
1861
|
+
this._runtimeService = _runtimeService;
|
|
1862
|
+
this._formulaDependencyGenerator = _formulaDependencyGenerator;
|
|
1863
|
+
this._featureCalculationManagerService = _featureCalculationManagerService;
|
|
1864
|
+
this._otherFormulaManagerService = _otherFormulaManagerService;
|
|
1865
|
+
this._commandService = _commandService;
|
|
1866
|
+
this._rustEngineSyncController = _rustEngineSyncController;
|
|
1867
|
+
this._formulaDataModel = _formulaDataModel;
|
|
1868
|
+
this._formulaReferenceDataService = _formulaReferenceDataService;
|
|
1869
|
+
this._excelExternalReferenceModel = _excelExternalReferenceModel;
|
|
1870
|
+
this._superTableService = _superTableService;
|
|
1871
|
+
this._commandService.hasCommand(import_engine_formula2.SetFormulaCalculationResultMutation.id) || this.disposeWithMe(this._commandService.registerCommand(import_engine_formula2.SetFormulaCalculationResultMutation)), this._commandService.hasCommand(import_engine_formula2.SetArrayFormulaDataMutation.id) || this.disposeWithMe(this._commandService.registerCommand(import_engine_formula2.SetArrayFormulaDataMutation));
|
|
1872
|
+
}
|
|
1873
|
+
_configService;
|
|
1874
|
+
_currentConfigService;
|
|
1875
|
+
_runtimeService;
|
|
1876
|
+
_formulaDependencyGenerator;
|
|
1877
|
+
_featureCalculationManagerService;
|
|
1878
|
+
_otherFormulaManagerService;
|
|
1879
|
+
_commandService;
|
|
1880
|
+
_rustEngineSyncController;
|
|
1881
|
+
_formulaDataModel;
|
|
1882
|
+
_formulaReferenceDataService;
|
|
1883
|
+
_excelExternalReferenceModel;
|
|
1884
|
+
_superTableService;
|
|
1885
|
+
_executionInProgressListener$ = new import_rxjs.Subject();
|
|
1886
|
+
executionInProgressListener$ = this._executionInProgressListener$.asObservable();
|
|
1887
|
+
_executionCompleteListener$ = new import_rxjs.Subject();
|
|
1888
|
+
executionCompleteListener$ = this._executionCompleteListener$.asObservable();
|
|
1889
|
+
_executeLock = new import_core4.AsyncLock();
|
|
1890
|
+
_nativeLoaded = !1;
|
|
1891
|
+
_syncedSnapshotEpoch = -1;
|
|
1892
|
+
_syncedDependencyInvalidationEpoch = -1;
|
|
1893
|
+
_syncedExternalReferenceSignature = "{}";
|
|
1894
|
+
_externalFormulaDatasetConfig;
|
|
1895
|
+
_externalRequestCounter = 0;
|
|
1896
|
+
_externalRequestGeneration = -1;
|
|
1897
|
+
_externalInflight = /* @__PURE__ */ new Map();
|
|
1898
|
+
_externalCompleted = /* @__PURE__ */ new Map();
|
|
1899
|
+
dispose() {
|
|
1900
|
+
super.dispose(), this._executionInProgressListener$.complete(), this._executionCompleteListener$.complete();
|
|
1901
|
+
}
|
|
1902
|
+
stopFormulaExecution() {
|
|
1903
|
+
this._runtimeService.stopExecution();
|
|
1904
|
+
}
|
|
1905
|
+
setRuntimeFeatureCellData(featureId, featureData) {
|
|
1906
|
+
this._runtimeService.setRuntimeFeatureCellData(featureId, featureData);
|
|
1907
|
+
}
|
|
1908
|
+
setRuntimeFeatureRange(featureId, featureRange) {
|
|
1909
|
+
this._runtimeService.setRuntimeFeatureRange(featureId, featureRange);
|
|
1910
|
+
}
|
|
1911
|
+
async execute(formulaDatasetConfig) {
|
|
1912
|
+
this._nativeLoaded || (await loadNativeBinding(), 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(import_engine_formula2.FormulaExecuteStageType.START), this._executionInProgressListener$.next(this._runtimeService.getRuntimeState()), this._runtimeService.reset();
|
|
1913
|
+
let cycleReferenceCount = Math.max(formulaDatasetConfig.maxIteration || 1, 1);
|
|
1914
|
+
await this._executeLock.acquire("FORMULA_EXECUTION_LOCK", async () => {
|
|
1915
|
+
this._runtimeService.setFormulaCycleIndex(0), await this._executeStep(cycleReferenceCount) > 0 ? this._runtimeService.markedAsSuccessfullyExecuted() : this._runtimeService.markedAsNoFunctionsExecuted(), this._runtimeService.setFormulaExecuteStage(import_engine_formula2.FormulaExecuteStageType.CALCULATION_COMPLETED), this._executionInProgressListener$.next(this._runtimeService.getRuntimeState()), this._executionCompleteListener$.next(this._runtimeService.getAllRuntimeData()), this._runtimeService.reset();
|
|
1916
|
+
});
|
|
1917
|
+
}
|
|
1918
|
+
async _executeStep(maxIteration) {
|
|
1919
|
+
let syncedFeatures = this._syncRustFormulaDependencies(void 0, !0), 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;
|
|
1920
|
+
output = await this._resolveExternalReferenceNeeds(output, maxIteration);
|
|
1921
|
+
let applyStartedAt = performance.now(), applyBreakdown = await this._applyRustDependencyOutput(output), applyMs = performance.now() - applyStartedAt;
|
|
1922
|
+
if (emitRustFormulaDebugEvent({
|
|
1923
|
+
type: "executeDirtyFormulas",
|
|
1924
|
+
payload: {
|
|
1925
|
+
calculatedNodeCount: output.calculatedNodeCount,
|
|
1926
|
+
hasCycle: output.hasCycle,
|
|
1927
|
+
cycleIterationCount: output.cycleIterationCount,
|
|
1928
|
+
parallelBatchCount: output.parallelBatchCount,
|
|
1929
|
+
parallelNodeCount: output.parallelNodeCount,
|
|
1930
|
+
errorCount: output.errors.length,
|
|
1931
|
+
resultBatchCount: output.resultBatches?.length ?? 0,
|
|
1932
|
+
firstResultBatchValue: firstResultBatchValue(output),
|
|
1933
|
+
resultBatchSheetCounts: resultBatchSheetCounts(output),
|
|
1934
|
+
timings: output.timings,
|
|
1935
|
+
functionProfile: output.functionProfile,
|
|
1936
|
+
bridgeTimings: {
|
|
1937
|
+
nativeAndSerializeMs,
|
|
1938
|
+
outputBytes: outputJson.length,
|
|
1939
|
+
parseMs,
|
|
1940
|
+
applyMs,
|
|
1941
|
+
applyConvertMs: applyBreakdown.convertMs,
|
|
1942
|
+
applyCommandMs: applyBreakdown.commandMs
|
|
1943
|
+
}
|
|
1944
|
+
}
|
|
1945
|
+
}), syncedFeatures.length > 0)
|
|
1946
|
+
for (let pass = 0; pass < MAX_FEATURE_CALCULATION_PASSES; pass++) {
|
|
1947
|
+
let refreshedFeatures = this._syncRustFormulaDependencyDefinitions(), changedFeatures = refreshedFeatures.filter(
|
|
1948
|
+
(feature) => previousFeatureSignatures.get(this._featureKey(feature)) !== feature.signature
|
|
1949
|
+
);
|
|
1950
|
+
if (changedFeatures.length === 0)
|
|
1951
|
+
break;
|
|
1952
|
+
this._markRustFormulaDirty(
|
|
1953
|
+
this._currentConfigService.getDirtyData(),
|
|
1954
|
+
this._dirtyFeatureMapFor(changedFeatures)
|
|
1955
|
+
), 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({
|
|
1956
|
+
type: "executeDirtyFormulas",
|
|
1957
|
+
payload: {
|
|
1958
|
+
calculatedNodeCount: output.calculatedNodeCount,
|
|
1959
|
+
hasCycle: output.hasCycle,
|
|
1960
|
+
cycleIterationCount: output.cycleIterationCount,
|
|
1961
|
+
parallelBatchCount: output.parallelBatchCount,
|
|
1962
|
+
parallelNodeCount: output.parallelNodeCount,
|
|
1963
|
+
errorCount: output.errors.length,
|
|
1964
|
+
resultBatchCount: output.resultBatches?.length ?? 0,
|
|
1965
|
+
firstResultBatchValue: firstResultBatchValue(output),
|
|
1966
|
+
resultBatchSheetCounts: resultBatchSheetCounts(output),
|
|
1967
|
+
timings: output.timings,
|
|
1968
|
+
functionProfile: output.functionProfile,
|
|
1969
|
+
bridgeTimings: {
|
|
1970
|
+
nativeAndSerializeMs,
|
|
1971
|
+
outputBytes: outputJson.length,
|
|
1972
|
+
parseMs,
|
|
1973
|
+
applyMs,
|
|
1974
|
+
applyConvertMs: applyBreakdown.convertMs,
|
|
1975
|
+
applyCommandMs: applyBreakdown.commandMs
|
|
1976
|
+
}
|
|
1977
|
+
}
|
|
1978
|
+
}), previousFeatureSignatures = this._featureSignatureMap(refreshedFeatures);
|
|
1979
|
+
}
|
|
1980
|
+
return calculatedNodeCount;
|
|
1981
|
+
}
|
|
1982
|
+
async _resolveExternalReferenceNeeds(initialOutput, maxIteration) {
|
|
1983
|
+
let config = this._externalFormulaDatasetConfig;
|
|
1984
|
+
if (!config) return initialOutput;
|
|
1985
|
+
let output = initialOutput;
|
|
1986
|
+
for (let pass = 0; pass < MAX_EXTERNAL_REFERENCE_PASSES; pass++) {
|
|
1987
|
+
let rangeNeeds = output.needsData ?? [], tableNeeds = output.tableNeedsData ?? [];
|
|
1988
|
+
if (rangeNeeds.length === 0 && tableNeeds.length === 0) break;
|
|
1989
|
+
let loadedRanges = await this._loadExternalReferenceNeeds(config, output, rangeNeeds, tableNeeds);
|
|
1990
|
+
if (loadedRanges.length === 0 || this._rustEngineSyncController.upsertReferenceData(
|
|
1991
|
+
{
|
|
1992
|
+
...config,
|
|
1993
|
+
allUnitData: this._currentConfigService.getUnitData(),
|
|
1994
|
+
unitSheetNameMap: this._currentConfigService.getSheetNameMap(),
|
|
1995
|
+
unitNameMap: this._currentConfigService.getUnitNameMap()
|
|
1996
|
+
},
|
|
1997
|
+
loadedRanges,
|
|
1998
|
+
this._superTableService
|
|
1999
|
+
) === 0) break;
|
|
2000
|
+
this._syncRustFormulaDependencies(), output = JSON.parse(executeDirtyFormulasOnRust(maxIteration, !1, !1, !0));
|
|
2001
|
+
}
|
|
2002
|
+
return output;
|
|
2003
|
+
}
|
|
2004
|
+
async _loadExternalReferenceNeeds(config, output, rangeNeeds, tableNeeds) {
|
|
2005
|
+
let loaded = [];
|
|
2006
|
+
for (let need of rangeNeeds) {
|
|
2007
|
+
let binding = this._resolveRustExternalBinding(config, need.unitId);
|
|
2008
|
+
!binding || await this._loadRustExternalReference(binding, {
|
|
2009
|
+
sheetName: need.sheetId,
|
|
2010
|
+
range: need.range
|
|
2011
|
+
}) !== !0 || loaded.push({
|
|
2012
|
+
...need,
|
|
2013
|
+
...binding.dataUnitId !== need.unitId ? { dataUnitId: binding.dataUnitId } : {}
|
|
2014
|
+
});
|
|
2015
|
+
}
|
|
2016
|
+
for (let need of tableNeeds) {
|
|
2017
|
+
let binding = this._resolveRustExternalBinding(config, need.unitId);
|
|
2018
|
+
if (!binding) continue;
|
|
2019
|
+
let loadedReference = await this._loadRustExternalReference(binding, {
|
|
2020
|
+
tableName: need.tableName
|
|
2021
|
+
});
|
|
2022
|
+
if (loadedReference !== !0) {
|
|
2023
|
+
this._applyTableReferenceLoadError(output, need, loadedReference);
|
|
2024
|
+
continue;
|
|
2025
|
+
}
|
|
2026
|
+
let table = this._superTableService.getTable(binding.dataUnitId, need.tableName);
|
|
2027
|
+
table && loaded.push({
|
|
2028
|
+
unitId: need.unitId,
|
|
2029
|
+
dataUnitId: binding.dataUnitId,
|
|
2030
|
+
tableName: need.tableName,
|
|
2031
|
+
sheetId: table.sheetId,
|
|
2032
|
+
range: table.range
|
|
2033
|
+
});
|
|
2034
|
+
}
|
|
2035
|
+
return loaded;
|
|
2036
|
+
}
|
|
2037
|
+
_applyTableReferenceLoadError(output, need, error) {
|
|
2038
|
+
if (need.formulaId) {
|
|
2039
|
+
let unit = output.otherFormulaData ??= {}, sheet = unit[need.ownerUnitId] ??= {}, formulas = sheet[need.ownerSheetId] ??= {}, rows = formulas[need.formulaId] ??= {}, columns = rows[need.row] ??= {};
|
|
2040
|
+
columns[need.column] = error;
|
|
2041
|
+
return;
|
|
2042
|
+
}
|
|
2043
|
+
let batch = output.resultBatches.find(
|
|
2044
|
+
(candidate) => candidate.unitId === need.ownerUnitId && candidate.sheetId === need.ownerSheetId
|
|
2045
|
+
) ?? {
|
|
2046
|
+
unitId: need.ownerUnitId,
|
|
2047
|
+
sheetId: need.ownerSheetId,
|
|
2048
|
+
rows: [],
|
|
2049
|
+
cols: [],
|
|
2050
|
+
values: []
|
|
2051
|
+
};
|
|
2052
|
+
output.resultBatches.includes(batch) || output.resultBatches.push(batch);
|
|
2053
|
+
let index = batch.rows.findIndex((row, index2) => row === need.row && batch.cols[index2] === need.column);
|
|
2054
|
+
index >= 0 ? batch.values[index] = error : (batch.rows.push(need.row), batch.cols.push(need.column), batch.values.push(error));
|
|
2055
|
+
}
|
|
2056
|
+
async _loadRustExternalReference(binding, range) {
|
|
2057
|
+
let generation = this._externalRequestGeneration, calculationId = `rust-formula-calculation-${generation}`, request = {
|
|
2058
|
+
requestId: `rust-external-request-${++this._externalRequestCounter}`,
|
|
2059
|
+
calculationId,
|
|
2060
|
+
hostUnitId: binding.hostUnitId,
|
|
2061
|
+
...binding.referenceId ? { referenceId: binding.referenceId } : {},
|
|
2062
|
+
...binding.bindingSlot ? { bindingSlot: binding.bindingSlot } : {},
|
|
2063
|
+
syntheticUnitId: binding.dataUnitId,
|
|
2064
|
+
target: binding.target,
|
|
2065
|
+
ranges: [range],
|
|
2066
|
+
requireFresh: !0
|
|
2067
|
+
}, key = [
|
|
2068
|
+
generation,
|
|
2069
|
+
binding.hostUnitId,
|
|
2070
|
+
binding.dataUnitId,
|
|
2071
|
+
range.sheetName,
|
|
2072
|
+
range.sheetId,
|
|
2073
|
+
range.tableName,
|
|
2074
|
+
range.range?.startRow,
|
|
2075
|
+
range.range?.endRow,
|
|
2076
|
+
range.range?.startColumn,
|
|
2077
|
+
range.range?.endColumn
|
|
2078
|
+
].join("\0"), completed = this._externalCompleted.get(key);
|
|
2079
|
+
if (completed != null)
|
|
2080
|
+
return completed;
|
|
2081
|
+
let pending = this._externalInflight.get(key);
|
|
2082
|
+
pending || (pending = this._formulaReferenceDataService.readData(
|
|
2083
|
+
request
|
|
2084
|
+
), this._externalInflight.set(key, pending));
|
|
2085
|
+
let response;
|
|
2086
|
+
try {
|
|
2087
|
+
response = await pending;
|
|
2088
|
+
} finally {
|
|
2089
|
+
this._externalInflight.get(key) === pending && this._externalInflight.delete(key);
|
|
2090
|
+
}
|
|
2091
|
+
return generation !== this._externalRequestGeneration || response.calculationId !== calculationId ? "#N/A" : response.error ? (this._externalCompleted.set(key, response.error), response.error) : response.sheets.length === 0 ? (this._externalCompleted.set(key, "#N/A"), "#N/A") : (this._materializeRustExternalReference(response, binding), this._externalCompleted.set(key, !0), !0);
|
|
2092
|
+
}
|
|
2093
|
+
_materializeRustExternalReference(response, binding) {
|
|
2094
|
+
let unitData = this._currentConfigService.getUnitData(), sheetNameMap = this._currentConfigService.getSheetNameMap(), unitNameMap = this._currentConfigService.getUnitNameMap(), sheets = unitData[binding.dataUnitId] ?? {}, names = sheetNameMap[binding.dataUnitId] ?? {};
|
|
2095
|
+
for (let responseSheet of response.sheets) {
|
|
2096
|
+
let current = sheets[responseSheet.sheetId], cellData = current?.cellData ?? new import_core4.ObjectMatrix();
|
|
2097
|
+
for (let { row, column, cell } of responseSheet.cells)
|
|
2098
|
+
cellData.setValue(row, column, cell);
|
|
2099
|
+
sheets[responseSheet.sheetId] = {
|
|
2100
|
+
cellData,
|
|
2101
|
+
rowCount: Math.max(current?.rowCount ?? 0, responseSheet.rowCount),
|
|
2102
|
+
columnCount: Math.max(current?.columnCount ?? 0, responseSheet.columnCount),
|
|
2103
|
+
rowData: current?.rowData ?? {},
|
|
2104
|
+
columnData: current?.columnData ?? {}
|
|
2105
|
+
}, names[responseSheet.name] = responseSheet.sheetId;
|
|
2106
|
+
}
|
|
2107
|
+
unitData[binding.dataUnitId] = sheets, sheetNameMap[binding.dataUnitId] = names, unitNameMap[binding.dataUnitId] = {
|
|
2108
|
+
name: unitNameMap[binding.dataUnitId]?.name ?? binding.qualifier,
|
|
2109
|
+
unitType: binding.target.unitType
|
|
2110
|
+
}, this._currentConfigService.registerUnitData(unitData), this._currentConfigService.registerSheetNameMap(sheetNameMap), this._currentConfigService.registerUnitNameMap(unitNameMap);
|
|
2111
|
+
for (let table of response.tables ?? [])
|
|
2112
|
+
this._superTableService.registerTable(binding.dataUnitId, table.name, {
|
|
2113
|
+
sheetId: table.sheetId,
|
|
2114
|
+
range: table.range,
|
|
2115
|
+
titleMap: new Map(table.columns.map((column, index) => [column, index])),
|
|
2116
|
+
showHeader: table.showHeader
|
|
2117
|
+
});
|
|
2118
|
+
}
|
|
2119
|
+
_resolveRustExternalBinding(config, unitId) {
|
|
2120
|
+
let externalReferences = config.externalReferences ?? {};
|
|
2121
|
+
for (let [hostUnitId, resource] of Object.entries(externalReferences))
|
|
2122
|
+
for (let [referenceId, reference] of Object.entries(resource.references))
|
|
2123
|
+
if (createRustProductExternalSyntheticUnitId(hostUnitId, referenceId) === unitId)
|
|
2124
|
+
return {
|
|
2125
|
+
hostUnitId,
|
|
2126
|
+
dataUnitId: reference.sourceUnitId,
|
|
2127
|
+
qualifier: reference.qualifier,
|
|
2128
|
+
referenceId,
|
|
2129
|
+
target: {
|
|
2130
|
+
name: reference.qualifier,
|
|
2131
|
+
unitType: reference.sourceUnitType,
|
|
2132
|
+
sourceUnitId: reference.sourceUnitId
|
|
2133
|
+
}
|
|
2134
|
+
};
|
|
2135
|
+
let ooxml = this._parseOoxmlExternalSyntheticUnitId(unitId);
|
|
2136
|
+
if (!ooxml) return;
|
|
2137
|
+
let binding = this._excelExternalReferenceModel.resolveBinding(ooxml.hostUnitId, String(ooxml.slot));
|
|
2138
|
+
if (binding.status === "resolved")
|
|
2139
|
+
return {
|
|
2140
|
+
hostUnitId: ooxml.hostUnitId,
|
|
2141
|
+
dataUnitId: unitId,
|
|
2142
|
+
qualifier: String(ooxml.slot),
|
|
2143
|
+
bindingSlot: ooxml.slot,
|
|
2144
|
+
target: binding.link.target
|
|
2145
|
+
};
|
|
2146
|
+
}
|
|
2147
|
+
_parseOoxmlExternalSyntheticUnitId(unitId) {
|
|
2148
|
+
if (!unitId.startsWith("external:") || unitId.startsWith("external:product:")) return;
|
|
2149
|
+
let separator = unitId.lastIndexOf(":");
|
|
2150
|
+
if (!(separator <= 9 || !/^\d+$/.test(unitId.slice(separator + 1))))
|
|
2151
|
+
try {
|
|
2152
|
+
return {
|
|
2153
|
+
hostUnitId: decodeURIComponent(unitId.slice(9, separator)),
|
|
2154
|
+
slot: Number(unitId.slice(separator + 1))
|
|
2155
|
+
};
|
|
2156
|
+
} catch {
|
|
2157
|
+
return;
|
|
2158
|
+
}
|
|
2159
|
+
}
|
|
2160
|
+
_buildRustInput() {
|
|
2161
|
+
let unitData = this._currentConfigService.getUnitData(), formulaData = this._currentConfigService.getFormulaData(), dirtyRanges = this._currentConfigService.getDirtyRanges(), config = this._configService.getConfig(import_engine_formula2.ENGINE_FORMULA_PLUGIN_CONFIG_KEY);
|
|
2162
|
+
return {
|
|
2163
|
+
config: {
|
|
2164
|
+
maxIteration: config?.maxIteration ?? 1,
|
|
2165
|
+
intervalCount: config?.intervalCount ?? DEFAULT_INTERVAL_COUNT
|
|
2166
|
+
},
|
|
2167
|
+
formulaData: this._serializeFormulaData(formulaData),
|
|
2168
|
+
unitData: this._serializeUnitData(unitData),
|
|
2169
|
+
dirtyRanges: dirtyRanges || [],
|
|
2170
|
+
definedNames: {}
|
|
2171
|
+
};
|
|
2172
|
+
}
|
|
2173
|
+
_syncRustFormulaDependencies(dirtyUnitFeatureMapOverride, includeExternalReferences = !1) {
|
|
2174
|
+
let syncState = getRustEngineSyncState(), 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;
|
|
2175
|
+
if (!(shouldSendExternalReferences || rebuildSheetFormulas || state.featureCalculations.length > 0 || state.otherFormulas.length > 0))
|
|
2176
|
+
return emitRustFormulaDebugEvent({
|
|
2177
|
+
type: "syncDependencies",
|
|
2178
|
+
payload: {
|
|
2179
|
+
rebuildSheetFormulas,
|
|
2180
|
+
skipped: !0,
|
|
2181
|
+
featureCalculationCount: 0,
|
|
2182
|
+
otherFormulaCount: 0,
|
|
2183
|
+
syncedFeatureCount: 0,
|
|
2184
|
+
timings: {
|
|
2185
|
+
collectMs,
|
|
2186
|
+
stringifyMs: 0,
|
|
2187
|
+
nativeMs: 0,
|
|
2188
|
+
parseMs: 0,
|
|
2189
|
+
totalMs: collectMs
|
|
2190
|
+
}
|
|
2191
|
+
}
|
|
2192
|
+
}), this._markRustFormulaDirty(state.dirtyData, dirtyUnitFeatureMapOverride, rebuildSheetFormulas), state.syncedFeatures;
|
|
2193
|
+
let stringifyStartedAt = performance.now(), inputJson = JSON.stringify({
|
|
2194
|
+
rebuildSheetFormulas,
|
|
2195
|
+
featureCalculations: state.featureCalculations,
|
|
2196
|
+
otherFormulas: state.otherFormulas,
|
|
2197
|
+
...shouldSendExternalReferences ? { externalReferences } : {}
|
|
2198
|
+
}), 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;
|
|
2199
|
+
return emitRustFormulaDebugEvent({
|
|
2200
|
+
type: "syncDependencies",
|
|
2201
|
+
payload: {
|
|
2202
|
+
rebuildSheetFormulas,
|
|
2203
|
+
skipped: !1,
|
|
2204
|
+
featureCalculationCount: state.featureCalculations.length,
|
|
2205
|
+
otherFormulaCount: state.otherFormulas.length,
|
|
2206
|
+
syncedFeatureCount: state.syncedFeatures.length,
|
|
2207
|
+
timings: {
|
|
2208
|
+
collectMs,
|
|
2209
|
+
stringifyMs,
|
|
2210
|
+
nativeMs,
|
|
2211
|
+
parseMs,
|
|
2212
|
+
totalMs: collectMs + stringifyMs + nativeMs + parseMs,
|
|
2213
|
+
rust: output.timings
|
|
2214
|
+
}
|
|
2215
|
+
}
|
|
2216
|
+
}), rebuildSheetFormulas && (this._syncedSnapshotEpoch = syncState.snapshotEpoch, this._syncedDependencyInvalidationEpoch = syncState.dependencyInvalidationEpoch), includeExternalReferences && (this._syncedExternalReferenceSignature = externalReferenceSignature), this._markRustFormulaDirty(state.dirtyData, dirtyUnitFeatureMapOverride, rebuildSheetFormulas), state.syncedFeatures;
|
|
2217
|
+
}
|
|
2218
|
+
_syncRustFormulaDependencyDefinitions() {
|
|
2219
|
+
let state = this._collectRustFormulaDependencySyncState();
|
|
2220
|
+
return syncRustFormulaDependenciesOnRust(
|
|
2221
|
+
JSON.stringify({
|
|
2222
|
+
rebuildSheetFormulas: !1,
|
|
2223
|
+
featureCalculations: state.featureCalculations,
|
|
2224
|
+
otherFormulas: state.otherFormulas
|
|
2225
|
+
})
|
|
2226
|
+
), state.syncedFeatures;
|
|
2227
|
+
}
|
|
2228
|
+
_collectRustFormulaDependencySyncState() {
|
|
2229
|
+
let featureCalculations = [], syncedFeatures = [], dirtyData = this._currentConfigService.getDirtyData(), runtimeData = this._runtimeService.getAllRuntimeData();
|
|
2230
|
+
this._featureCalculationManagerService.getReferenceExecutorMap().forEach((sheetMap) => {
|
|
2231
|
+
sheetMap.forEach((featureMap) => {
|
|
2232
|
+
featureMap.forEach((params, featureId) => {
|
|
2233
|
+
let { runtimeCellData, dirtyRanges: featureDirtyRanges } = params.getDirtyData(
|
|
2234
|
+
dirtyData,
|
|
2235
|
+
runtimeData
|
|
2236
|
+
), serializedDirtyRanges = this._serializeFeatureDirtyRanges(featureDirtyRanges), serializedRuntimeCellData = serializeRuntimeFeatureCellData(runtimeCellData);
|
|
2237
|
+
this._runtimeService.setRuntimeFeatureCellData(featureId, runtimeCellData), this._runtimeService.setRuntimeFeatureRange(featureId, featureDirtyRanges), featureCalculations.push({
|
|
2238
|
+
unitId: params.unitId,
|
|
2239
|
+
sheetId: params.subUnitId,
|
|
2240
|
+
featureId,
|
|
2241
|
+
dependencyRanges: params.dependencyRanges.map((range) => ({
|
|
2242
|
+
unitId: range.unitId,
|
|
2243
|
+
sheetId: range.sheetId,
|
|
2244
|
+
startRow: range.range.startRow,
|
|
2245
|
+
endRow: range.range.endRow,
|
|
2246
|
+
startColumn: range.range.startColumn,
|
|
2247
|
+
endColumn: range.range.endColumn
|
|
2248
|
+
})),
|
|
2249
|
+
dirtyRanges: serializedDirtyRanges,
|
|
2250
|
+
runtimeCellData: serializedRuntimeCellData
|
|
2251
|
+
}), syncedFeatures.push({
|
|
2252
|
+
unitId: params.unitId,
|
|
2253
|
+
sheetId: params.subUnitId,
|
|
2254
|
+
featureId,
|
|
2255
|
+
signature: JSON.stringify({
|
|
2256
|
+
dirtyRanges: serializedDirtyRanges,
|
|
2257
|
+
runtimeCellData: serializedRuntimeCellData
|
|
2258
|
+
})
|
|
2259
|
+
});
|
|
2260
|
+
});
|
|
2261
|
+
});
|
|
2262
|
+
});
|
|
2263
|
+
let otherFormulas = [], otherFormulaData = this._otherFormulaManagerService.getOtherFormulaData();
|
|
2264
|
+
return Object.entries(otherFormulaData).forEach(([unitId, sheetMap]) => {
|
|
2265
|
+
sheetMap && Object.entries(sheetMap).forEach(([sheetId, formulaMap]) => {
|
|
2266
|
+
formulaMap && Object.entries(formulaMap).forEach(([formulaId, item]) => {
|
|
2267
|
+
item && otherFormulas.push({
|
|
2268
|
+
unitId,
|
|
2269
|
+
sheetId,
|
|
2270
|
+
formulaId,
|
|
2271
|
+
formula: item.f,
|
|
2272
|
+
ranges: item.ranges
|
|
2273
|
+
});
|
|
2274
|
+
});
|
|
2275
|
+
});
|
|
2276
|
+
}), { dirtyData, featureCalculations, otherFormulas, syncedFeatures };
|
|
2277
|
+
}
|
|
2278
|
+
_markRustFormulaDirty(dirtyData, dirtyUnitFeatureMapOverride, forceCalculationOverride = !1) {
|
|
2279
|
+
let payload = {
|
|
2280
|
+
forceCalculation: forceCalculationOverride || dirtyData.forceCalculation,
|
|
2281
|
+
includeDirtyNodes: !1,
|
|
2282
|
+
includeCalculationOrder: !1,
|
|
2283
|
+
dirtyRanges: (dirtyData.dirtyRanges ?? []).map((range) => ({
|
|
2284
|
+
unitId: range.unitId,
|
|
2285
|
+
sheetId: range.sheetId,
|
|
2286
|
+
startRow: range.range.startRow,
|
|
2287
|
+
endRow: range.range.endRow,
|
|
2288
|
+
startColumn: range.range.startColumn,
|
|
2289
|
+
endColumn: range.range.endColumn
|
|
2290
|
+
})),
|
|
2291
|
+
dirtyUnitFeatureMap: dirtyUnitFeatureMapOverride ?? dirtyData.dirtyUnitFeatureMap,
|
|
2292
|
+
dirtyUnitOtherFormulaMap: dirtyData.dirtyUnitOtherFormulaMap,
|
|
2293
|
+
dirtyNameMap: dirtyData.dirtyNameMap,
|
|
2294
|
+
dirtyDefinedNameMap: dirtyData.dirtyDefinedNameMap
|
|
2295
|
+
}, stringifyStartedAt = performance.now(), inputJson = JSON.stringify(payload), stringifyMs = performance.now() - stringifyStartedAt, nativeStartedAt = performance.now(), outputJson = markRustFormulaDirtyOnRust(inputJson), nativeMs = performance.now() - nativeStartedAt, rustTimings;
|
|
2296
|
+
try {
|
|
2297
|
+
rustTimings = JSON.parse(outputJson).timings;
|
|
2298
|
+
} catch {
|
|
2299
|
+
rustTimings = void 0;
|
|
2300
|
+
}
|
|
2301
|
+
emitRustFormulaDebugEvent({
|
|
2302
|
+
type: "markDirty",
|
|
2303
|
+
payload: {
|
|
2304
|
+
...payload,
|
|
2305
|
+
timings: {
|
|
2306
|
+
stringifyMs,
|
|
2307
|
+
nativeMs,
|
|
2308
|
+
totalMs: stringifyMs + nativeMs
|
|
2309
|
+
},
|
|
2310
|
+
rustTimings
|
|
2311
|
+
}
|
|
2312
|
+
});
|
|
2313
|
+
}
|
|
2314
|
+
_dirtyFeatureMapFor(features) {
|
|
2315
|
+
let dirtyMap = {};
|
|
2316
|
+
return features.forEach(({ unitId, sheetId, featureId }) => {
|
|
2317
|
+
dirtyMap[unitId] = dirtyMap[unitId] ?? {}, dirtyMap[unitId][sheetId] = dirtyMap[unitId][sheetId] ?? {}, dirtyMap[unitId][sheetId][featureId] = !0;
|
|
2318
|
+
}), dirtyMap;
|
|
2319
|
+
}
|
|
2320
|
+
_featureKey(feature) {
|
|
2321
|
+
return `${feature.unitId}\0${feature.sheetId}\0${feature.featureId}`;
|
|
2322
|
+
}
|
|
2323
|
+
_featureSignatureMap(features) {
|
|
2324
|
+
return new Map(features.map((feature) => [this._featureKey(feature), feature.signature]));
|
|
2325
|
+
}
|
|
2326
|
+
_serializeFeatureDirtyRanges(dirtyRanges) {
|
|
2327
|
+
let serialized = [];
|
|
2328
|
+
return Object.entries(dirtyRanges).forEach(([unitId, sheetMap]) => {
|
|
2329
|
+
sheetMap && Object.entries(sheetMap).forEach(([sheetId, ranges]) => {
|
|
2330
|
+
ranges && ranges.forEach((range) => {
|
|
2331
|
+
serialized.push({
|
|
2332
|
+
unitId,
|
|
2333
|
+
sheetId,
|
|
2334
|
+
startRow: range.startRow,
|
|
2335
|
+
endRow: range.endRow,
|
|
2336
|
+
startColumn: range.startColumn,
|
|
2337
|
+
endColumn: range.endColumn
|
|
2338
|
+
});
|
|
2339
|
+
});
|
|
2340
|
+
});
|
|
2341
|
+
}), serialized;
|
|
2342
|
+
}
|
|
2343
|
+
_serializeFormulaData(formulaData) {
|
|
2344
|
+
let result = {};
|
|
2345
|
+
if (!formulaData || typeof formulaData != "object") return result;
|
|
2346
|
+
for (let [unitId, sheets] of Object.entries(formulaData))
|
|
2347
|
+
if (!(!sheets || typeof sheets != "object")) {
|
|
2348
|
+
result[unitId] = {};
|
|
2349
|
+
for (let [sheetId, rows] of Object.entries(sheets))
|
|
2350
|
+
if (!(!rows || typeof rows != "object")) {
|
|
2351
|
+
result[unitId][sheetId] = {};
|
|
2352
|
+
for (let [rowStr, cols] of Object.entries(rows)) {
|
|
2353
|
+
if (!cols || typeof cols != "object")
|
|
2354
|
+
continue;
|
|
2355
|
+
let row = Number(rowStr);
|
|
2356
|
+
result[unitId][sheetId][row] = {};
|
|
2357
|
+
for (let [colStr, item] of Object.entries(cols)) {
|
|
2358
|
+
let col = Number(colStr);
|
|
2359
|
+
if (typeof item == "string")
|
|
2360
|
+
result[unitId][sheetId][row][col] = item;
|
|
2361
|
+
else if (item && typeof item == "object" && typeof item.f == "string") {
|
|
2362
|
+
let formulaItem = item;
|
|
2363
|
+
result[unitId][sheetId][row][col] = {
|
|
2364
|
+
f: formulaItem.f,
|
|
2365
|
+
si: typeof formulaItem.si == "string" ? formulaItem.si : void 0,
|
|
2366
|
+
ref: typeof formulaItem.ref == "string" ? formulaItem.ref : void 0,
|
|
2367
|
+
x: typeof formulaItem.x == "number" ? formulaItem.x : void 0,
|
|
2368
|
+
y: typeof formulaItem.y == "number" ? formulaItem.y : void 0
|
|
2369
|
+
};
|
|
2370
|
+
}
|
|
2371
|
+
}
|
|
2372
|
+
}
|
|
2373
|
+
}
|
|
2374
|
+
}
|
|
2375
|
+
return result;
|
|
2376
|
+
}
|
|
2377
|
+
_serializeUnitData(unitData) {
|
|
2378
|
+
let result = {};
|
|
2379
|
+
if (!unitData) return result;
|
|
2380
|
+
for (let [unitId, sheets] of Object.entries(unitData)) {
|
|
2381
|
+
result[unitId] = {};
|
|
2382
|
+
for (let [sheetId, sheet] of Object.entries(sheets))
|
|
2383
|
+
result[unitId][sheetId] = {
|
|
2384
|
+
cellData: this._serializeCellData(sheet.cellData),
|
|
2385
|
+
rowCount: sheet.rowCount ?? 0,
|
|
2386
|
+
columnCount: sheet.columnCount ?? 0
|
|
2387
|
+
};
|
|
2388
|
+
}
|
|
2389
|
+
return result;
|
|
2390
|
+
}
|
|
2391
|
+
_serializeCellData(cellData) {
|
|
2392
|
+
let result = {};
|
|
2393
|
+
if (!cellData || typeof cellData != "object") return result;
|
|
2394
|
+
let data = typeof cellData.getMatrix == "function" ? cellData.getMatrix() : cellData;
|
|
2395
|
+
for (let [rowStr, cols] of Object.entries(data)) {
|
|
2396
|
+
let row = Number(rowStr);
|
|
2397
|
+
if (Number.isFinite(row)) {
|
|
2398
|
+
result[row] = {};
|
|
2399
|
+
for (let [colStr, cell] of Object.entries(cols)) {
|
|
2400
|
+
let col = Number(colStr);
|
|
2401
|
+
Number.isFinite(col) && (result[row][col] = {
|
|
2402
|
+
v: cell?.v ?? null,
|
|
2403
|
+
t: cell?.t ?? void 0,
|
|
2404
|
+
p: cell?.p ?? void 0,
|
|
2405
|
+
f: cell?.f ?? void 0,
|
|
2406
|
+
s: cell?.s ?? void 0
|
|
2407
|
+
});
|
|
2408
|
+
}
|
|
2409
|
+
}
|
|
2410
|
+
}
|
|
2411
|
+
return result;
|
|
2412
|
+
}
|
|
2413
|
+
_applyRustOutput(_output) {
|
|
2414
|
+
}
|
|
2415
|
+
async _applyRustDependencyOutput(output) {
|
|
2416
|
+
let convertStartedAt = performance.now(), patch = rustExecutionOutputToFormulaCalculationPatch(output), convertMs = performance.now() - convertStartedAt, commandStartedAt = performance.now();
|
|
2417
|
+
return (patch.arrayFormulaRange || patch.arrayFormulaCellData) && (this._formulaDataModel.setArrayFormulaRange(patch.arrayFormulaRange ?? {}), this._formulaDataModel.setArrayFormulaCellData(patch.arrayFormulaCellData ?? {}), await this._commandService.executeCommand(
|
|
2418
|
+
import_engine_formula2.SetArrayFormulaDataMutation.id,
|
|
2419
|
+
{
|
|
2420
|
+
arrayFormulaRange: this._formulaDataModel.getArrayFormulaRange(),
|
|
2421
|
+
arrayFormulaCellData: this._formulaDataModel.getArrayFormulaCellData(),
|
|
2422
|
+
arrayFormulaEmbedded: {}
|
|
2423
|
+
},
|
|
2424
|
+
{
|
|
2425
|
+
onlyLocal: !0,
|
|
2426
|
+
fromRustFormulaEngine: !0
|
|
2427
|
+
}
|
|
2428
|
+
)), await this._commandService.executeCommand(
|
|
2429
|
+
import_engine_formula2.SetFormulaCalculationResultMutation.id,
|
|
2430
|
+
{
|
|
2431
|
+
unitData: patch.unitData,
|
|
2432
|
+
unitOtherData: patch.unitOtherData
|
|
2433
|
+
},
|
|
2434
|
+
{
|
|
2435
|
+
onlyLocal: !0,
|
|
2436
|
+
fromRustFormulaEngine: !0
|
|
2437
|
+
}
|
|
2438
|
+
), {
|
|
2439
|
+
convertMs,
|
|
2440
|
+
commandMs: performance.now() - commandStartedAt
|
|
2441
|
+
};
|
|
2442
|
+
}
|
|
2443
|
+
async calculate(formulaString) {
|
|
2444
|
+
this._nativeLoaded || (await loadNativeBinding(), this._nativeLoaded = !0);
|
|
2445
|
+
let unitId = "__rust_formula_calculate__", sheetId = "__sheet__", input = {
|
|
2446
|
+
config: { maxIteration: 1, intervalCount: DEFAULT_INTERVAL_COUNT },
|
|
2447
|
+
formulaData: {
|
|
2448
|
+
[unitId]: {
|
|
2449
|
+
[sheetId]: {
|
|
2450
|
+
0: { 0: formulaString }
|
|
2451
|
+
}
|
|
2452
|
+
}
|
|
2453
|
+
},
|
|
2454
|
+
unitData: {
|
|
2455
|
+
[unitId]: {
|
|
2456
|
+
[sheetId]: {
|
|
2457
|
+
rowCount: 1,
|
|
2458
|
+
columnCount: 1,
|
|
2459
|
+
cellData: {}
|
|
2460
|
+
}
|
|
2461
|
+
}
|
|
2462
|
+
},
|
|
2463
|
+
dirtyRanges: [],
|
|
2464
|
+
definedNames: {}
|
|
2465
|
+
};
|
|
2466
|
+
return JSON.parse(executeOnRust(JSON.stringify(input))).runtimeData?.[unitId]?.[sheetId]?.[0]?.[0] ?? null;
|
|
2467
|
+
}
|
|
2468
|
+
async executeFormulas(formulas, rowData) {
|
|
2469
|
+
this._nativeLoaded || (await loadNativeBinding(), this._nativeLoaded = !0), this._currentConfigService.loadDataLite(rowData);
|
|
2470
|
+
let unitData = this._currentConfigService.getUnitData(), formulaData = this._formulaStringMapToFormulaData(formulas), input = {
|
|
2471
|
+
config: { maxIteration: 1, intervalCount: DEFAULT_INTERVAL_COUNT },
|
|
2472
|
+
formulaData,
|
|
2473
|
+
unitData: this._serializeUnitData(unitData),
|
|
2474
|
+
dirtyRanges: [],
|
|
2475
|
+
definedNames: {}
|
|
2476
|
+
}, output = JSON.parse(executeOnRust(JSON.stringify(input)));
|
|
2477
|
+
return this._formulaExecutionOutputToResultMap(formulas, output);
|
|
2478
|
+
}
|
|
2479
|
+
async getAllDependencyJson(_rowData) {
|
|
2480
|
+
this._nativeLoaded || (await loadNativeBinding(), this._nativeLoaded = !0), this._syncRustFormulaDependencyDefinitions();
|
|
2481
|
+
let graph = this._getRustDependencyGraph(), inspect = this._getRustInspectGraph();
|
|
2482
|
+
return this._rustAllDependencyJson(graph, inspect);
|
|
2483
|
+
}
|
|
2484
|
+
async getCellDependencyJson(unitId, sheetId, row, column, _rowData) {
|
|
2485
|
+
this._nativeLoaded || (await loadNativeBinding(), this._nativeLoaded = !0), this._syncRustFormulaDependencyDefinitions();
|
|
2486
|
+
let graph = this._getRustDependencyGraph(unitId), all = this._rustGraphDependencyJson(graph), current = all.find(
|
|
2487
|
+
(item) => item.unitId === unitId && item.subUnitId === sheetId && item.row === row && item.column === column
|
|
2488
|
+
);
|
|
2489
|
+
if (!current)
|
|
2490
|
+
return;
|
|
2491
|
+
let byId = new Map(all.map((item) => [item.treeId, item]));
|
|
2492
|
+
return {
|
|
2493
|
+
...current,
|
|
2494
|
+
children: current.children.map((id) => byId.get(id)).filter(isFormulaDependencyTreeJson),
|
|
2495
|
+
parents: current.parents.map((id) => byId.get(id)).filter(isFormulaDependencyTreeJson)
|
|
2496
|
+
};
|
|
2497
|
+
}
|
|
2498
|
+
async getRangeDependents(unitRanges) {
|
|
2499
|
+
this._nativeLoaded || (await loadNativeBinding(), this._nativeLoaded = !0), this._syncRustFormulaDependencyDefinitions();
|
|
2500
|
+
let graph = this._getRustDependencyGraph(), graphItems = this._rustGraphDependencyJson(graph), graphByCell = this._rustDependencyJsonByCell(graphItems), dirty = JSON.parse(
|
|
2501
|
+
getRustDirtyDependenciesOnRust(JSON.stringify(this._serializeUnitRanges(unitRanges)))
|
|
2502
|
+
);
|
|
2503
|
+
return this._uniqueDependencyJson(
|
|
2504
|
+
(dirty.direct ?? dirty.affected ?? []).map((cell) => graphByCell.get(this._cellKey(cell))).filter(Boolean)
|
|
2505
|
+
);
|
|
2506
|
+
}
|
|
2507
|
+
async getInRangeFormulas(unitRanges) {
|
|
2508
|
+
return this._nativeLoaded || (await loadNativeBinding(), this._nativeLoaded = !0), this._syncRustFormulaDependencyDefinitions(), this._rustGraphDependencyJson(this._getRustDependencyGraph()).filter(
|
|
2509
|
+
(item) => this._cellInUnitRanges(item.unitId, item.subUnitId, item.row, item.column, unitRanges)
|
|
2510
|
+
);
|
|
2511
|
+
}
|
|
2512
|
+
async getDependentsAndInRangeFormulas(unitRanges) {
|
|
2513
|
+
let [dependents, inRanges] = await Promise.all([
|
|
2514
|
+
this.getRangeDependents(unitRanges),
|
|
2515
|
+
this.getInRangeFormulas(unitRanges)
|
|
2516
|
+
]);
|
|
2517
|
+
return { dependents, inRanges };
|
|
2518
|
+
}
|
|
2519
|
+
_formulaStringMapToFormulaData(formulas) {
|
|
2520
|
+
let formulaData = {};
|
|
2521
|
+
return Object.entries(formulas).forEach(([unitId, sheetMap]) => {
|
|
2522
|
+
sheetMap && (formulaData[unitId] = {}, Object.entries(sheetMap).forEach(([sheetId, rowMap]) => {
|
|
2523
|
+
rowMap && (formulaData[unitId][sheetId] = {}, Object.entries(rowMap).forEach(([rowKey, colMap]) => {
|
|
2524
|
+
if (!colMap) return;
|
|
2525
|
+
let row = Number(rowKey);
|
|
2526
|
+
formulaData[unitId][sheetId][row] = {}, Object.entries(colMap).forEach(([colKey, formulaList]) => {
|
|
2527
|
+
let formula = Array.isArray(formulaList) ? formulaList[0] : void 0;
|
|
2528
|
+
typeof formula == "string" && (formulaData[unitId][sheetId][row][Number(colKey)] = formula);
|
|
2529
|
+
});
|
|
2530
|
+
}));
|
|
2531
|
+
}));
|
|
2532
|
+
}), formulaData;
|
|
2533
|
+
}
|
|
2534
|
+
_formulaExecutionOutputToResultMap(formulas, output) {
|
|
2535
|
+
let result = {};
|
|
2536
|
+
return Object.entries(formulas).forEach(([unitId, sheetMap]) => {
|
|
2537
|
+
sheetMap && (result[unitId] = {}, Object.entries(sheetMap).forEach(([sheetId, rowMap]) => {
|
|
2538
|
+
rowMap && (result[unitId][sheetId] = {}, Object.entries(rowMap).forEach(([rowKey, colMap]) => {
|
|
2539
|
+
if (!colMap) return;
|
|
2540
|
+
let row = Number(rowKey);
|
|
2541
|
+
result[unitId][sheetId][row] = {}, Object.entries(colMap).forEach(([colKey, formulaList]) => {
|
|
2542
|
+
let col = Number(colKey), formulasForCell = Array.isArray(formulaList) ? formulaList : [], value = normalizeFormulaResultValue(
|
|
2543
|
+
output.runtimeData?.[unitId]?.[sheetId]?.[row]?.[col]
|
|
2544
|
+
);
|
|
2545
|
+
result[unitId][sheetId][row][col] = formulasForCell.map((formula) => ({ formula, value }));
|
|
2546
|
+
});
|
|
2547
|
+
}));
|
|
2548
|
+
}));
|
|
2549
|
+
}), result;
|
|
2550
|
+
}
|
|
2551
|
+
_getRustDependencyGraph(unitId) {
|
|
2552
|
+
return JSON.parse(buildRustDependencyGraphOnRust(unitId));
|
|
2553
|
+
}
|
|
2554
|
+
_getRustInspectGraph() {
|
|
2555
|
+
return JSON.parse(inspectRustFormulaDependencyGraphOnRust());
|
|
2556
|
+
}
|
|
2557
|
+
_rustAllDependencyJson(graph, inspect) {
|
|
2558
|
+
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));
|
|
2559
|
+
return this._uniqueDependencyJson([...cellItems, ...nonCellItems]);
|
|
2560
|
+
}
|
|
2561
|
+
_rustGraphDependencyJson(graph) {
|
|
2562
|
+
return (graph.nodes ?? []).map((node) => this._rustDependencyNodeToJson(node));
|
|
2563
|
+
}
|
|
2564
|
+
_rustDependencyNodeToJson(node) {
|
|
2565
|
+
return {
|
|
2566
|
+
children: node.children ?? [],
|
|
2567
|
+
parents: node.parents ?? [],
|
|
2568
|
+
treeId: node.id,
|
|
2569
|
+
formula: node.formula,
|
|
2570
|
+
row: node.row,
|
|
2571
|
+
column: node.column,
|
|
2572
|
+
unitId: node.unitId,
|
|
2573
|
+
subUnitId: node.sheetId,
|
|
2574
|
+
refOffsetX: node.offsetX ?? 0,
|
|
2575
|
+
refOffsetY: node.offsetY ?? 0,
|
|
2576
|
+
rangeList: (node.precedentRanges ?? []).map((range) => this._rustRangeToUnitRange(range)),
|
|
2577
|
+
refTreeId: void 0,
|
|
2578
|
+
formulaId: node.formulaId ?? null,
|
|
2579
|
+
featureId: null,
|
|
2580
|
+
type: FORMULA_TREE_TYPE_NORMAL
|
|
2581
|
+
};
|
|
2582
|
+
}
|
|
2583
|
+
_rustFormulaNodeToDependencyJson(index, node) {
|
|
2584
|
+
return {
|
|
2585
|
+
children: [],
|
|
2586
|
+
parents: [],
|
|
2587
|
+
treeId: index,
|
|
2588
|
+
formula: "",
|
|
2589
|
+
row: node.row ?? -1,
|
|
2590
|
+
column: node.column ?? -1,
|
|
2591
|
+
unitId: node.unitId ?? "",
|
|
2592
|
+
subUnitId: node.sheetId ?? "",
|
|
2593
|
+
refOffsetX: node.refOffsetX ?? 0,
|
|
2594
|
+
refOffsetY: node.refOffsetY ?? 0,
|
|
2595
|
+
rangeList: [],
|
|
2596
|
+
refTreeId: void 0,
|
|
2597
|
+
formulaId: node.formulaId ?? null,
|
|
2598
|
+
featureId: node.featureId ?? null,
|
|
2599
|
+
type: node.nodeType === "featureCalculation" ? FORMULA_TREE_TYPE_FEATURE : FORMULA_TREE_TYPE_OTHER
|
|
2600
|
+
};
|
|
2601
|
+
}
|
|
2602
|
+
_rustRangeToUnitRange(range) {
|
|
2603
|
+
return {
|
|
2604
|
+
unitId: range.unitId,
|
|
2605
|
+
sheetId: range.sheetId,
|
|
2606
|
+
range: {
|
|
2607
|
+
startRow: range.startRow,
|
|
2608
|
+
endRow: range.endRow,
|
|
2609
|
+
startColumn: range.startColumn,
|
|
2610
|
+
endColumn: range.endColumn
|
|
2611
|
+
}
|
|
2612
|
+
};
|
|
2613
|
+
}
|
|
2614
|
+
_serializeUnitRanges(unitRanges) {
|
|
2615
|
+
return unitRanges.map((unitRange) => ({
|
|
2616
|
+
unitId: unitRange.unitId,
|
|
2617
|
+
sheetId: unitRange.sheetId,
|
|
2618
|
+
startRow: unitRange.range.startRow,
|
|
2619
|
+
endRow: unitRange.range.endRow,
|
|
2620
|
+
startColumn: unitRange.range.startColumn,
|
|
2621
|
+
endColumn: unitRange.range.endColumn
|
|
2622
|
+
}));
|
|
2623
|
+
}
|
|
2624
|
+
_rustDependencyJsonByCell(items) {
|
|
2625
|
+
return new Map(
|
|
2626
|
+
items.map((item) => [
|
|
2627
|
+
this._cellKey({
|
|
2628
|
+
unitId: item.unitId,
|
|
2629
|
+
sheetId: item.subUnitId,
|
|
2630
|
+
row: item.row,
|
|
2631
|
+
column: item.column
|
|
2632
|
+
}),
|
|
2633
|
+
item
|
|
2634
|
+
])
|
|
2635
|
+
);
|
|
2636
|
+
}
|
|
2637
|
+
_cellKey(cell) {
|
|
2638
|
+
return `${cell.unitId}\0${cell.sheetId}\0${cell.row}\0${cell.column}`;
|
|
2639
|
+
}
|
|
2640
|
+
_cellInUnitRanges(unitId, sheetId, row, column, unitRanges) {
|
|
2641
|
+
return unitRanges.some(
|
|
2642
|
+
(unitRange) => unitRange.unitId === unitId && unitRange.sheetId === sheetId && row >= unitRange.range.startRow && row <= unitRange.range.endRow && column >= unitRange.range.startColumn && column <= unitRange.range.endColumn
|
|
2643
|
+
);
|
|
2644
|
+
}
|
|
2645
|
+
_uniqueDependencyJson(items) {
|
|
2646
|
+
let seen = /* @__PURE__ */ new Set(), result = [];
|
|
2647
|
+
return items.forEach((item) => {
|
|
2648
|
+
!item || seen.has(item.treeId) || (seen.add(item.treeId), result.push(item));
|
|
2649
|
+
}), result;
|
|
2650
|
+
}
|
|
2651
|
+
};
|
|
2652
|
+
(0, import_core4.setDependencies)(RustCalculateFormulaService, [
|
|
2653
|
+
import_core4.IConfigService,
|
|
2654
|
+
import_engine_formula2.IFormulaCurrentConfigService,
|
|
2655
|
+
import_engine_formula2.IFormulaRuntimeService,
|
|
2656
|
+
import_engine_formula2.IFormulaDependencyGenerator,
|
|
2657
|
+
import_engine_formula2.IFeatureCalculationManagerService,
|
|
2658
|
+
import_engine_formula2.IOtherFormulaManagerService,
|
|
2659
|
+
import_core4.ICommandService,
|
|
2660
|
+
RustEngineSyncController,
|
|
2661
|
+
import_engine_formula2.FormulaDataModel,
|
|
2662
|
+
import_engine_formula3.IFormulaReferenceDataService,
|
|
2663
|
+
import_engine_formula3.ExternalReferenceModel,
|
|
2664
|
+
import_engine_formula2.ISuperTableService
|
|
2665
|
+
]);
|
|
2666
|
+
function createRustProductExternalSyntheticUnitId(hostUnitId, referenceId) {
|
|
2667
|
+
return `external:product:${encodeURIComponent(hostUnitId)}:${encodeURIComponent(referenceId)}`;
|
|
2668
|
+
}
|
|
2669
|
+
function isFormulaDependencyTreeJson(value) {
|
|
2670
|
+
return value !== void 0;
|
|
2671
|
+
}
|
|
2672
|
+
function normalizeFormulaResultValue(value) {
|
|
2673
|
+
return value == null || typeof value == "number" || typeof value == "string" || typeof value == "boolean" || Array.isArray(value) && value.every(isFormulaResultRow) ? value : null;
|
|
2674
|
+
}
|
|
2675
|
+
function isFormulaResultRow(value) {
|
|
2676
|
+
return Array.isArray(value) && value.every(
|
|
2677
|
+
(item) => item == null || typeof item == "number" || typeof item == "string" || typeof item == "boolean"
|
|
2678
|
+
);
|
|
2679
|
+
}
|
|
2680
|
+
|
|
2681
|
+
// src/plugin.ts
|
|
2682
|
+
var DEFAULT_RUST_FORMULA_PLUGIN_CONFIG = {}, UniverRustFormulaEnginePlugin = class extends import_engine_formula5.UniverProFormulaEnginePlugin {
|
|
2683
|
+
constructor(_config = DEFAULT_RUST_FORMULA_PLUGIN_CONFIG, _injector, _configService) {
|
|
2684
|
+
super(_config, _injector, _configService);
|
|
2685
|
+
this._config = _config;
|
|
2686
|
+
this._injector = _injector;
|
|
2687
|
+
this._configService = _configService;
|
|
2688
|
+
}
|
|
2689
|
+
_config;
|
|
2690
|
+
_injector;
|
|
2691
|
+
_configService;
|
|
2692
|
+
static packageName = name;
|
|
2693
|
+
static version = version;
|
|
2694
|
+
onReady() {
|
|
2695
|
+
super.onReady(), !this._config?.notExecuteFormula && this._config?.useRustEngine !== !1 && (0, import_core5.touchDependencies)(this._injector, [[RustEngineSyncController], [RustSameRuntimeProjectionController]]);
|
|
2696
|
+
}
|
|
2697
|
+
/**
|
|
2698
|
+
* UniverProFormulaEnginePlugin invokes this hook before its single DI
|
|
2699
|
+
* registration pass.
|
|
2700
|
+
*/
|
|
2701
|
+
_extendFormulaExecutionDependencies(dependencies) {
|
|
2702
|
+
if (this._config?.useRustEngine !== !1 && !this._config?.notExecuteFormula) {
|
|
2703
|
+
let calculateServiceIndex = dependencies.findIndex(
|
|
2704
|
+
(dependency) => Array.isArray(dependency) && dependency[0] === import_engine_formula4.ICalculateFormulaService
|
|
2705
|
+
), rustDependencies = [
|
|
2706
|
+
[RustEngineSyncController],
|
|
2707
|
+
[RustSameRuntimeProjectionController],
|
|
2708
|
+
[IRustCalculateFormulaService, { useClass: RustCalculateFormulaService }],
|
|
2709
|
+
// eslint-disable-next-line react/no-unnecessary-use-prefix
|
|
2710
|
+
[import_engine_formula4.ICalculateFormulaService, { useFactory: () => this._injector.get(IRustCalculateFormulaService) }]
|
|
2711
|
+
];
|
|
2712
|
+
calculateServiceIndex >= 0 && dependencies.splice(calculateServiceIndex, 1), dependencies.push(...rustDependencies);
|
|
2713
|
+
}
|
|
2714
|
+
}
|
|
2715
|
+
};
|
|
2716
|
+
(0, import_core5.setDependencies)(UniverRustFormulaEnginePlugin, [import_core5.Injector, import_core5.IConfigService], 1);
|
|
2717
|
+
|
|
2718
|
+
// src/services/workbook-snapshot-materializer.ts
|
|
2719
|
+
var import_node_buffer = require("node:buffer");
|
|
2720
|
+
async function materializeWorkbookSnapshot(workbook, unitID, rev, dirtyInput) {
|
|
2721
|
+
await loadNativeBinding();
|
|
2722
|
+
let result = await materializeWorkbookSnapshotOnRust(
|
|
2723
|
+
import_node_buffer.Buffer.from(JSON.stringify(workbook)),
|
|
2724
|
+
unitID,
|
|
2725
|
+
rev,
|
|
2726
|
+
dirtyInput == null ? void 0 : JSON.stringify(dirtyInput)
|
|
2727
|
+
), draft = JSON.parse(result.snapshotDraftJson.toString("utf8")), encoder = new TextEncoder(), sheets = Object.fromEntries(
|
|
2728
|
+
Object.entries(draft.workbook.sheets).map(([sheetID, sheet]) => {
|
|
2729
|
+
let { originalMetaJson: originalMetaJson2, ...meta } = sheet;
|
|
2730
|
+
return [sheetID, { ...meta, originalMeta: encoder.encode(originalMetaJson2) }];
|
|
2731
|
+
})
|
|
2732
|
+
), { originalMetaJson, ...workbookMeta } = draft.workbook;
|
|
2733
|
+
return {
|
|
2734
|
+
snapshot: {
|
|
2735
|
+
unitID: draft.unitID,
|
|
2736
|
+
type: draft.type,
|
|
2737
|
+
rev: draft.rev,
|
|
2738
|
+
workbook: {
|
|
2739
|
+
...workbookMeta,
|
|
2740
|
+
sheets,
|
|
2741
|
+
originalMeta: encoder.encode(originalMetaJson)
|
|
2742
|
+
},
|
|
2743
|
+
doc: void 0,
|
|
2744
|
+
slide: void 0,
|
|
2745
|
+
board: void 0
|
|
2746
|
+
},
|
|
2747
|
+
sheetBlocks: Object.fromEntries(result.sheetBlocks.map(({ sheetId, blocks }) => [sheetId, blocks])),
|
|
2748
|
+
warnings: JSON.parse(result.warningsJson.toString("utf8")),
|
|
2749
|
+
calculationStats: JSON.parse(result.calculationStatsJson.toString("utf8"))
|
|
2750
|
+
};
|
|
2751
|
+
}
|
|
2752
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
2753
|
+
0 && (module.exports = {
|
|
2754
|
+
IRustCalculateFormulaService,
|
|
2755
|
+
RUST_FORMULA_RELEVANT_MUTATIONS,
|
|
2756
|
+
RUST_INCREMENTAL_DEPENDENCY_MUTATIONS,
|
|
2757
|
+
RUST_UPSERT_PROJECTION_WORKBOOK_MUTATION_ID,
|
|
2758
|
+
RUST_UPSERT_REFERENCE_DATA_MUTATION_ID,
|
|
2759
|
+
RustCalculateFormulaService,
|
|
2760
|
+
RustEngineSyncController,
|
|
2761
|
+
RustFormulaProjectionService,
|
|
2762
|
+
UniverRustFormulaEnginePlugin,
|
|
2763
|
+
analyzeNumberFormatBatch,
|
|
2764
|
+
applyMutationOnRust,
|
|
2765
|
+
buildLexerTreeOnRust,
|
|
2766
|
+
buildRustDependencyGraphOnRust,
|
|
2767
|
+
buildSequenceNodesOnRust,
|
|
2768
|
+
checkIfAddBracketOnRust,
|
|
2769
|
+
clearRustFormulaDependenciesOnRust,
|
|
2770
|
+
clearRustFormulaDirtyOnRust,
|
|
2771
|
+
createFormulaProjectionDesyncSignal,
|
|
2772
|
+
createProjectionWorkbookUpsertMutation,
|
|
2773
|
+
disposeAllWorkbooksOnRust,
|
|
2774
|
+
disposeWorkbookOnRust,
|
|
2775
|
+
executeOnRust,
|
|
2776
|
+
formatNumberBatch,
|
|
2777
|
+
getNativeBindingSource,
|
|
2778
|
+
getRustCellOnRust,
|
|
2779
|
+
getRustDirtyDependenciesOnRust,
|
|
2780
|
+
getRustFormulaDataOnRust,
|
|
2781
|
+
getRustModelStats,
|
|
2782
|
+
getRustSheetStateOnRust,
|
|
2783
|
+
isRustFormulaRelevantMutation,
|
|
2784
|
+
isRustIncrementalDependencyMutation,
|
|
2785
|
+
loadNativeBinding,
|
|
2786
|
+
loadSnapshotOnRust,
|
|
2787
|
+
markRustFormulaDirtyOnRust,
|
|
2788
|
+
materializeWorkbookSnapshot,
|
|
2789
|
+
materializeWorkbookSnapshotOnRust,
|
|
2790
|
+
parseNumberFormatBatch,
|
|
2791
|
+
parseNumberFormatMatrixBatch,
|
|
2792
|
+
rustExecutionOutputToFormulaCalculationPatch,
|
|
2793
|
+
serializeRuntimeWorkbookSnapshot,
|
|
2794
|
+
serializeRuntimeWorkbookSnapshots,
|
|
2795
|
+
syncRustFormulaDependenciesOnRust
|
|
2796
|
+
});
|