@univerjs-pro/engine-formula-rust 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/index.cjs +118 -75
- package/lib/es/index.js +117 -75
- package/lib/types/index.d.ts +48 -21
- package/package.json +6 -6
package/lib/cjs/index.cjs
CHANGED
|
@@ -32,6 +32,7 @@ __export(index_exports, {
|
|
|
32
32
|
RUST_UPSERT_REFERENCE_DATA_MUTATION_ID: () => RUST_UPSERT_REFERENCE_DATA_MUTATION_ID,
|
|
33
33
|
RustCalculateFormulaService: () => RustCalculateFormulaService,
|
|
34
34
|
RustEngineSyncController: () => RustEngineSyncController,
|
|
35
|
+
RustFormulaEngineSession: () => RustFormulaEngineSession,
|
|
35
36
|
RustFormulaProjectionService: () => RustFormulaProjectionService,
|
|
36
37
|
UniverRustFormulaEnginePlugin: () => UniverRustFormulaEnginePlugin,
|
|
37
38
|
analyzeNumberFormatBatch: () => analyzeNumberFormatBatch,
|
|
@@ -150,11 +151,6 @@ function loadSnapshotOnRust(snapshotJson) {
|
|
|
150
151
|
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
151
152
|
return nativeBinding.rustEngineLoadSnapshot(snapshotJson);
|
|
152
153
|
}
|
|
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
154
|
function applyMutationOnRust(mutationJson) {
|
|
159
155
|
if (!nativeBinding)
|
|
160
156
|
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
@@ -205,11 +201,6 @@ function syncRustFormulaDependenciesOnRust(inputJson) {
|
|
|
205
201
|
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
206
202
|
return nativeBinding.rustEngineSyncFormulaDependencies(inputJson);
|
|
207
203
|
}
|
|
208
|
-
function inspectRustFormulaDependencyGraphOnRust() {
|
|
209
|
-
if (!nativeBinding)
|
|
210
|
-
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
211
|
-
return nativeBinding.rustEngineInspectFormulaDependencyGraph();
|
|
212
|
-
}
|
|
213
204
|
function markRustFormulaDirtyOnRust(inputJson) {
|
|
214
205
|
if (!nativeBinding)
|
|
215
206
|
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
@@ -225,21 +216,34 @@ function clearRustFormulaDirtyOnRust() {
|
|
|
225
216
|
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
226
217
|
return nativeBinding.rustEngineClearFormulaDirty();
|
|
227
218
|
}
|
|
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
219
|
function materializeWorkbookSnapshotOnRust(workbookJson, unitId, rev, dirtyInputJson) {
|
|
239
220
|
if (!nativeBinding)
|
|
240
221
|
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
241
222
|
return nativeBinding.rustMaterializeWorkbookSnapshot(workbookJson, unitId, rev, dirtyInputJson);
|
|
242
223
|
}
|
|
224
|
+
var RustFormulaEngineSession = class {
|
|
225
|
+
_engine = null;
|
|
226
|
+
_disposed = !1;
|
|
227
|
+
async initialize() {
|
|
228
|
+
if (this._disposed) throw new Error("Rust formula engine session is disposed");
|
|
229
|
+
if (this._engine) return;
|
|
230
|
+
let binding = await loadNativeBinding();
|
|
231
|
+
if (this._disposed) throw new Error("Rust formula engine session is disposed");
|
|
232
|
+
if (!this._engine) {
|
|
233
|
+
if (typeof binding.RustFormulaEngine != "function")
|
|
234
|
+
throw new Error("Native formula binding lacks instance isolation; upgrade engine-formula-rust-binding");
|
|
235
|
+
this._engine = new binding.RustFormulaEngine();
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
get binding() {
|
|
239
|
+
if (this._disposed) throw new Error("Rust formula engine session is disposed");
|
|
240
|
+
if (!this._engine) throw new Error("Rust formula engine session is not initialized");
|
|
241
|
+
return this._engine;
|
|
242
|
+
}
|
|
243
|
+
dispose() {
|
|
244
|
+
this._disposed || (this._disposed = !0, this._engine?.dispose(), this._engine = null);
|
|
245
|
+
}
|
|
246
|
+
};
|
|
243
247
|
|
|
244
248
|
// src/controllers/rust-engine-sync.controller.ts
|
|
245
249
|
var import_core2 = require("@univerjs/core");
|
|
@@ -437,12 +441,20 @@ function createFormulaProjectionDesyncSignal(reason, error, mutationId) {
|
|
|
437
441
|
};
|
|
438
442
|
}
|
|
439
443
|
var RustFormulaProjectionService = class {
|
|
444
|
+
engine = new RustFormulaEngineSession();
|
|
445
|
+
dispose() {
|
|
446
|
+
this.engine.dispose();
|
|
447
|
+
}
|
|
440
448
|
_nativeLoaded = !1;
|
|
441
449
|
async load(workbooks) {
|
|
442
450
|
await this._ensureNativeLoaded();
|
|
443
451
|
try {
|
|
444
452
|
return {
|
|
445
|
-
stats: JSON.parse(
|
|
453
|
+
stats: JSON.parse(
|
|
454
|
+
this.engine.binding.rustEngineLoadSnapshot(
|
|
455
|
+
JSON.stringify(serializeRuntimeWorkbookSnapshots(workbooks))
|
|
456
|
+
)
|
|
457
|
+
)
|
|
446
458
|
};
|
|
447
459
|
} catch (error) {
|
|
448
460
|
return {
|
|
@@ -455,7 +467,9 @@ var RustFormulaProjectionService = class {
|
|
|
455
467
|
await this._ensureNativeLoaded();
|
|
456
468
|
try {
|
|
457
469
|
return {
|
|
458
|
-
stats: JSON.parse(
|
|
470
|
+
stats: JSON.parse(
|
|
471
|
+
this.engine.binding.rustEngineApplyMutation(JSON.stringify(normalizeRustEngineMutation(mutation)))
|
|
472
|
+
),
|
|
459
473
|
dependencyInvalidated: !isRustIncrementalDependencyMutation(mutation.id)
|
|
460
474
|
};
|
|
461
475
|
} catch (error) {
|
|
@@ -467,16 +481,16 @@ var RustFormulaProjectionService = class {
|
|
|
467
481
|
}
|
|
468
482
|
}
|
|
469
483
|
async syncFormulaDependencies(input) {
|
|
470
|
-
return await this._ensureNativeLoaded(), JSON.parse(
|
|
484
|
+
return await this._ensureNativeLoaded(), JSON.parse(this.engine.binding.rustEngineSyncFormulaDependencies(JSON.stringify(input)));
|
|
471
485
|
}
|
|
472
486
|
async markDirty(input) {
|
|
473
|
-
return await this._ensureNativeLoaded(), JSON.parse(
|
|
487
|
+
return await this._ensureNativeLoaded(), JSON.parse(this.engine.binding.rustEngineMarkFormulaDirty(JSON.stringify(input)));
|
|
474
488
|
}
|
|
475
489
|
async calculateDirty(maxIteration = 1) {
|
|
476
490
|
await this._ensureNativeLoaded();
|
|
477
491
|
try {
|
|
478
492
|
let output = JSON.parse(
|
|
479
|
-
|
|
493
|
+
this.engine.binding.rustEngineExecuteDirtyFormulas(maxIteration, !1, !1, !0)
|
|
480
494
|
);
|
|
481
495
|
return rustExecutionOutputToFormulaCalculationPatch(output);
|
|
482
496
|
} catch (error) {
|
|
@@ -491,7 +505,7 @@ var RustFormulaProjectionService = class {
|
|
|
491
505
|
async reset() {
|
|
492
506
|
await this._ensureNativeLoaded();
|
|
493
507
|
try {
|
|
494
|
-
return
|
|
508
|
+
return this.engine.binding.rustEngineClearFormulaDirty(), this.engine.binding.rustEngineClearFormulaDependencies(
|
|
495
509
|
JSON.stringify({
|
|
496
510
|
unitId: "",
|
|
497
511
|
clearSheetFormulas: !0,
|
|
@@ -499,7 +513,11 @@ var RustFormulaProjectionService = class {
|
|
|
499
513
|
clearOtherFormulas: !0
|
|
500
514
|
})
|
|
501
515
|
), {
|
|
502
|
-
stats: JSON.parse(
|
|
516
|
+
stats: JSON.parse(
|
|
517
|
+
this.engine.binding.rustEngineLoadSnapshot(
|
|
518
|
+
JSON.stringify({ workbooks: [] })
|
|
519
|
+
)
|
|
520
|
+
)
|
|
503
521
|
};
|
|
504
522
|
} catch (error) {
|
|
505
523
|
return {
|
|
@@ -511,7 +529,7 @@ var RustFormulaProjectionService = class {
|
|
|
511
529
|
async disposeWorkbook(unitId) {
|
|
512
530
|
await this._ensureNativeLoaded();
|
|
513
531
|
try {
|
|
514
|
-
return { stats: JSON.parse(
|
|
532
|
+
return { stats: JSON.parse(this.engine.binding.rustEngineDisposeWorkbook(unitId)) };
|
|
515
533
|
} catch (error) {
|
|
516
534
|
return {
|
|
517
535
|
desync: createFormulaProjectionDesyncSignal("workbook-dispose-failed", error),
|
|
@@ -520,7 +538,7 @@ var RustFormulaProjectionService = class {
|
|
|
520
538
|
}
|
|
521
539
|
}
|
|
522
540
|
async _ensureNativeLoaded() {
|
|
523
|
-
this._nativeLoaded || (await
|
|
541
|
+
this._nativeLoaded || (await this.engine.initialize(), this._nativeLoaded = !0);
|
|
524
542
|
}
|
|
525
543
|
};
|
|
526
544
|
function normalizeRustEngineMutation(mutation) {
|
|
@@ -1054,19 +1072,6 @@ function isRecord(value) {
|
|
|
1054
1072
|
}
|
|
1055
1073
|
|
|
1056
1074
|
// src/controllers/rust-engine-sync.controller.ts
|
|
1057
|
-
var rustEngineSyncState = {
|
|
1058
|
-
snapshotEpoch: 0,
|
|
1059
|
-
dependencyInvalidationEpoch: 0
|
|
1060
|
-
};
|
|
1061
|
-
function getRustEngineSyncState() {
|
|
1062
|
-
return { ...rustEngineSyncState };
|
|
1063
|
-
}
|
|
1064
|
-
function markRustSnapshotLoaded() {
|
|
1065
|
-
rustEngineSyncState.snapshotEpoch += 1, rustEngineSyncState.dependencyInvalidationEpoch += 1;
|
|
1066
|
-
}
|
|
1067
|
-
function markRustFormulaDependenciesInvalidated() {
|
|
1068
|
-
rustEngineSyncState.dependencyInvalidationEpoch += 1;
|
|
1069
|
-
}
|
|
1070
1075
|
function emitRustEngineSyncDebugEvent(event) {
|
|
1071
1076
|
let hook = globalThis.__UNIVER_RUST_FORMULA_DEBUG_HOOK__;
|
|
1072
1077
|
typeof hook == "function" && hook(event);
|
|
@@ -1106,6 +1111,17 @@ var RustEngineSyncController = class extends import_core2.Disposable {
|
|
|
1106
1111
|
this._initialize();
|
|
1107
1112
|
}
|
|
1108
1113
|
_commandService;
|
|
1114
|
+
engine = new RustFormulaEngineSession();
|
|
1115
|
+
_syncState = { snapshotEpoch: 0, dependencyInvalidationEpoch: 0 };
|
|
1116
|
+
getSyncState() {
|
|
1117
|
+
return { ...this._syncState };
|
|
1118
|
+
}
|
|
1119
|
+
_markSnapshotLoaded() {
|
|
1120
|
+
this._syncState.snapshotEpoch += 1, this._syncState.dependencyInvalidationEpoch += 1;
|
|
1121
|
+
}
|
|
1122
|
+
_markDependenciesInvalidated() {
|
|
1123
|
+
this._syncState.dependencyInvalidationEpoch += 1;
|
|
1124
|
+
}
|
|
1109
1125
|
_nativeReady = !1;
|
|
1110
1126
|
_snapshotLoaded = !1;
|
|
1111
1127
|
_projectionLoadPromise = null;
|
|
@@ -1139,7 +1155,7 @@ var RustEngineSyncController = class extends import_core2.Disposable {
|
|
|
1139
1155
|
this._projectionDeltaBarrier = barrier;
|
|
1140
1156
|
}
|
|
1141
1157
|
async _loadProjection(workbooks) {
|
|
1142
|
-
await
|
|
1158
|
+
await this.engine.initialize(), this._nativeReady = !0;
|
|
1143
1159
|
let serializeStartedAt = performance.now(), snapshot = serializeRuntimeWorkbookSnapshots(workbooks);
|
|
1144
1160
|
this._loadSerializedSnapshot(snapshot, performance.now() - serializeStartedAt);
|
|
1145
1161
|
}
|
|
@@ -1162,20 +1178,17 @@ var RustEngineSyncController = class extends import_core2.Disposable {
|
|
|
1162
1178
|
disposeProjectionWorkbook(unitId) {
|
|
1163
1179
|
if (!(!this._nativeReady || !this._snapshotLoaded))
|
|
1164
1180
|
try {
|
|
1165
|
-
|
|
1181
|
+
this.engine.binding.rustEngineDisposeWorkbook(unitId), this._markDependenciesInvalidated();
|
|
1166
1182
|
} catch {
|
|
1167
|
-
this.
|
|
1183
|
+
this.markProjectionDesynced();
|
|
1168
1184
|
}
|
|
1169
1185
|
}
|
|
1170
1186
|
dispose() {
|
|
1171
|
-
|
|
1172
|
-
this._snapshotLoaded = !1;
|
|
1173
|
-
return;
|
|
1174
|
-
}
|
|
1187
|
+
super.dispose(), this._pendingMutations.length = 0, this._projectionManagedTableUnits.clear(), this._projectionLoadPromise = null, this._projectionDeltaBarrier = Promise.resolve();
|
|
1175
1188
|
try {
|
|
1176
|
-
|
|
1189
|
+
this.engine.dispose();
|
|
1177
1190
|
} catch {
|
|
1178
|
-
this.
|
|
1191
|
+
this.markProjectionDesynced();
|
|
1179
1192
|
return;
|
|
1180
1193
|
}
|
|
1181
1194
|
this._nativeReady = !1, this._snapshotLoaded = !1;
|
|
@@ -1183,7 +1196,7 @@ var RustEngineSyncController = class extends import_core2.Disposable {
|
|
|
1183
1196
|
_loadSerializedSnapshot(snapshot, serializeMs) {
|
|
1184
1197
|
let precisionAsDisplayedWorkbookCount = snapshot.workbooks.filter(
|
|
1185
1198
|
(workbook) => workbook.calculation?.fullPrecision === !1
|
|
1186
|
-
).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 ?
|
|
1199
|
+
).length, displayPrecisionCellCount = countDisplayPrecisionCells(snapshot), pendingCountCoveredBySnapshot = this._pendingMutations.length, stringifyStartedAt = performance.now(), snapshotJson = JSON.stringify(snapshot), stringifyMs = performance.now() - stringifyStartedAt, snapshotBuffer = globalThis.Buffer?.from(snapshotJson), nativeStartedAt = performance.now(), nativeOutput = snapshotBuffer ? this.engine.binding.rustEngineLoadSnapshotBinary(snapshotBuffer) : this.engine.binding.rustEngineLoadSnapshot(snapshotJson), nativeMs = performance.now() - nativeStartedAt, nativeTimings;
|
|
1187
1200
|
try {
|
|
1188
1201
|
nativeTimings = JSON.parse(nativeOutput).timingsMs;
|
|
1189
1202
|
} catch {
|
|
@@ -1202,7 +1215,7 @@ var RustEngineSyncController = class extends import_core2.Disposable {
|
|
|
1202
1215
|
transport: snapshotBuffer ? "binary-json" : "string-json",
|
|
1203
1216
|
nativeTimings
|
|
1204
1217
|
}
|
|
1205
|
-
}), this._pendingMutations.splice(0, pendingCountCoveredBySnapshot), this._snapshotLoaded = !0,
|
|
1218
|
+
}), this._pendingMutations.splice(0, pendingCountCoveredBySnapshot), this._snapshotLoaded = !0, this._markSnapshotLoaded(), this._flushPendingMutations();
|
|
1206
1219
|
}
|
|
1207
1220
|
_queueOrSyncMutation(mutation) {
|
|
1208
1221
|
if (!this._nativeReady || !this._snapshotLoaded) {
|
|
@@ -1220,9 +1233,9 @@ var RustEngineSyncController = class extends import_core2.Disposable {
|
|
|
1220
1233
|
_syncMutation(mutation) {
|
|
1221
1234
|
let totalStartedAt = performance.now(), stringifyStartedAt = performance.now(), payload = JSON.stringify(normalizeRustEngineMutation(mutation)), stringifyMs = performance.now() - stringifyStartedAt, nativeStartedAt = performance.now();
|
|
1222
1235
|
try {
|
|
1223
|
-
|
|
1236
|
+
this.engine.binding.rustEngineApplyMutation(payload), isRustIncrementalDependencyMutation(mutation.id) || this._markDependenciesInvalidated();
|
|
1224
1237
|
} catch {
|
|
1225
|
-
this.
|
|
1238
|
+
this.markProjectionDesynced();
|
|
1226
1239
|
} finally {
|
|
1227
1240
|
emitRustEngineSyncDebugEvent({
|
|
1228
1241
|
type: "applyMutation",
|
|
@@ -1238,7 +1251,11 @@ var RustEngineSyncController = class extends import_core2.Disposable {
|
|
|
1238
1251
|
});
|
|
1239
1252
|
}
|
|
1240
1253
|
}
|
|
1241
|
-
|
|
1254
|
+
/**
|
|
1255
|
+
* Marks the native projection as out of sync so the next mutation reloads it.
|
|
1256
|
+
* Also used by the projection controller when a background projection load fails.
|
|
1257
|
+
*/
|
|
1258
|
+
markProjectionDesynced() {
|
|
1242
1259
|
this._nativeReady = !1, this._snapshotLoaded = !1;
|
|
1243
1260
|
}
|
|
1244
1261
|
_shouldSyncMutation(command, options) {
|
|
@@ -1302,7 +1319,7 @@ async function analyzeNumberFormatBatch(input) {
|
|
|
1302
1319
|
var import_core5 = require("@univerjs/core"), import_engine_formula4 = require("@univerjs/engine-formula"), import_engine_formula5 = require("@univerjs-pro/engine-formula");
|
|
1303
1320
|
|
|
1304
1321
|
// package.json
|
|
1305
|
-
var name = "@univerjs-pro/engine-formula-rust", version = "1.0.
|
|
1322
|
+
var name = "@univerjs-pro/engine-formula-rust", version = "1.0.1";
|
|
1306
1323
|
|
|
1307
1324
|
// src/controllers/rust-same-runtime-projection.controller.ts
|
|
1308
1325
|
var import_core3 = require("@univerjs/core"), import_engine_formula = require("@univerjs/engine-formula");
|
|
@@ -1331,7 +1348,9 @@ var RustSameRuntimeProjectionController = class extends import_core3.Disposable
|
|
|
1331
1348
|
import_core3.UniverInstanceType.UNIVER_BASE
|
|
1332
1349
|
))
|
|
1333
1350
|
this._rustEngineSyncController.setProjectionManagedTableUnit(base.getUnitId()), this._rememberBaseProjectionStructure(base.getSnapshot());
|
|
1334
|
-
this._initialProjectionLoad = this._loadAllWorkbookProjections()
|
|
1351
|
+
this._initialProjectionLoad = this._loadAllWorkbookProjections().catch(() => {
|
|
1352
|
+
this._rustEngineSyncController.markProjectionDesynced();
|
|
1353
|
+
}), this.disposeWithMe(
|
|
1335
1354
|
(0, import_core3.toDisposable)(
|
|
1336
1355
|
this._univerInstanceService.getTypeOfUnitAdded$(import_core3.UniverInstanceType.UNIVER_SHEET).subscribe(({ unit }) => {
|
|
1337
1356
|
this._enqueueProjectionDelta(() => {
|
|
@@ -1926,14 +1945,19 @@ var RustCalculateFormulaService = class extends import_core4.Disposable {
|
|
|
1926
1945
|
this._runtimeService.setRuntimeFeatureRange(featureId, featureRange);
|
|
1927
1946
|
}
|
|
1928
1947
|
async execute(formulaDatasetConfig) {
|
|
1929
|
-
this._nativeLoaded || (await
|
|
1948
|
+
this._nativeLoaded || (await this._rustEngineSyncController.engine.initialize(), this._nativeLoaded = !0), await this._rustEngineSyncController.waitForProjectionLoad(), this._externalFormulaDatasetConfig = formulaDatasetConfig, this._currentConfigService.load(formulaDatasetConfig), this._externalRequestGeneration++, this._externalInflight.clear(), this._externalCompleted.clear(), this._runtimeService.setFormulaExecuteStage(import_engine_formula2.FormulaExecuteStageType.START), this._executionInProgressListener$.next(this._runtimeService.getRuntimeState()), this._runtimeService.reset();
|
|
1930
1949
|
let cycleReferenceCount = Math.max(formulaDatasetConfig.maxIteration || 1, 1);
|
|
1931
1950
|
await this._executeLock.acquire("FORMULA_EXECUTION_LOCK", async () => {
|
|
1932
1951
|
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();
|
|
1933
1952
|
});
|
|
1934
1953
|
}
|
|
1935
1954
|
async _executeStep(maxIteration) {
|
|
1936
|
-
let syncedFeatures = this._syncRustFormulaDependencies(void 0, !0), previousFeatureSignatures = this._featureSignatureMap(syncedFeatures), executeStartedAt = performance.now(), outputJson =
|
|
1955
|
+
let syncedFeatures = this._syncRustFormulaDependencies(void 0, !0), previousFeatureSignatures = this._featureSignatureMap(syncedFeatures), executeStartedAt = performance.now(), outputJson = this._rustEngineSyncController.engine.binding.rustEngineExecuteDirtyFormulas(
|
|
1956
|
+
maxIteration,
|
|
1957
|
+
!1,
|
|
1958
|
+
!1,
|
|
1959
|
+
!0
|
|
1960
|
+
), nativeAndSerializeMs = performance.now() - executeStartedAt, parseStartedAt = performance.now(), output = JSON.parse(outputJson), calculatedNodeCount = output.calculatedNodeCount, parseMs = performance.now() - parseStartedAt;
|
|
1937
1961
|
output = await this._resolveExternalReferenceNeeds(output, maxIteration);
|
|
1938
1962
|
let applyStartedAt = performance.now(), applyBreakdown = await this._applyRustDependencyOutput(output), applyMs = performance.now() - applyStartedAt;
|
|
1939
1963
|
if (emitRustFormulaDebugEvent({
|
|
@@ -1969,7 +1993,12 @@ var RustCalculateFormulaService = class extends import_core4.Disposable {
|
|
|
1969
1993
|
this._markRustFormulaDirty(
|
|
1970
1994
|
this._currentConfigService.getDirtyData(),
|
|
1971
1995
|
this._dirtyFeatureMapFor(changedFeatures)
|
|
1972
|
-
), executeStartedAt = performance.now(), outputJson =
|
|
1996
|
+
), executeStartedAt = performance.now(), outputJson = this._rustEngineSyncController.engine.binding.rustEngineExecuteDirtyFormulas(
|
|
1997
|
+
maxIteration,
|
|
1998
|
+
!1,
|
|
1999
|
+
!1,
|
|
2000
|
+
!0
|
|
2001
|
+
), 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({
|
|
1973
2002
|
type: "executeDirtyFormulas",
|
|
1974
2003
|
payload: {
|
|
1975
2004
|
calculatedNodeCount: output.calculatedNodeCount,
|
|
@@ -2014,7 +2043,14 @@ var RustCalculateFormulaService = class extends import_core4.Disposable {
|
|
|
2014
2043
|
loadedRanges,
|
|
2015
2044
|
this._superTableService
|
|
2016
2045
|
) === 0) break;
|
|
2017
|
-
this._syncRustFormulaDependencies(), output = JSON.parse(
|
|
2046
|
+
this._syncRustFormulaDependencies(), output = JSON.parse(
|
|
2047
|
+
this._rustEngineSyncController.engine.binding.rustEngineExecuteDirtyFormulas(
|
|
2048
|
+
maxIteration,
|
|
2049
|
+
!1,
|
|
2050
|
+
!1,
|
|
2051
|
+
!0
|
|
2052
|
+
)
|
|
2053
|
+
);
|
|
2018
2054
|
}
|
|
2019
2055
|
return output;
|
|
2020
2056
|
}
|
|
@@ -2188,7 +2224,7 @@ var RustCalculateFormulaService = class extends import_core4.Disposable {
|
|
|
2188
2224
|
};
|
|
2189
2225
|
}
|
|
2190
2226
|
_syncRustFormulaDependencies(dirtyUnitFeatureMapOverride, includeExternalReferences = !1) {
|
|
2191
|
-
let syncState =
|
|
2227
|
+
let syncState = this._rustEngineSyncController.getSyncState(), externalReferences = includeExternalReferences ? this._externalFormulaDatasetConfig?.externalReferences ?? {} : void 0, externalReferenceSignature = externalReferences ? JSON.stringify(externalReferences) : this._syncedExternalReferenceSignature, shouldSendExternalReferences = includeExternalReferences && (externalReferenceSignature !== "{}" || this._syncedExternalReferenceSignature !== "{}"), rebuildSheetFormulas = this._syncedSnapshotEpoch !== syncState.snapshotEpoch || this._syncedDependencyInvalidationEpoch !== syncState.dependencyInvalidationEpoch || shouldSendExternalReferences, collectStartedAt = performance.now(), state = this._collectRustFormulaDependencySyncState(), collectMs = performance.now() - collectStartedAt;
|
|
2192
2228
|
if (!(shouldSendExternalReferences || rebuildSheetFormulas || state.featureCalculations.length > 0 || state.otherFormulas.length > 0))
|
|
2193
2229
|
return emitRustFormulaDebugEvent({
|
|
2194
2230
|
type: "syncDependencies",
|
|
@@ -2212,7 +2248,7 @@ var RustCalculateFormulaService = class extends import_core4.Disposable {
|
|
|
2212
2248
|
featureCalculations: state.featureCalculations,
|
|
2213
2249
|
otherFormulas: state.otherFormulas,
|
|
2214
2250
|
...shouldSendExternalReferences ? { externalReferences } : {}
|
|
2215
|
-
}), stringifyMs = performance.now() - stringifyStartedAt, nativeStartedAt = performance.now(), outputJson =
|
|
2251
|
+
}), stringifyMs = performance.now() - stringifyStartedAt, nativeStartedAt = performance.now(), outputJson = this._rustEngineSyncController.engine.binding.rustEngineSyncFormulaDependencies(inputJson), nativeMs = performance.now() - nativeStartedAt, parseStartedAt = performance.now(), output = JSON.parse(outputJson), parseMs = performance.now() - parseStartedAt;
|
|
2216
2252
|
return emitRustFormulaDebugEvent({
|
|
2217
2253
|
type: "syncDependencies",
|
|
2218
2254
|
payload: {
|
|
@@ -2234,7 +2270,7 @@ var RustCalculateFormulaService = class extends import_core4.Disposable {
|
|
|
2234
2270
|
}
|
|
2235
2271
|
_syncRustFormulaDependencyDefinitions() {
|
|
2236
2272
|
let state = this._collectRustFormulaDependencySyncState();
|
|
2237
|
-
return
|
|
2273
|
+
return this._rustEngineSyncController.engine.binding.rustEngineSyncFormulaDependencies(
|
|
2238
2274
|
JSON.stringify({
|
|
2239
2275
|
rebuildSheetFormulas: !1,
|
|
2240
2276
|
featureCalculations: state.featureCalculations,
|
|
@@ -2309,7 +2345,7 @@ var RustCalculateFormulaService = class extends import_core4.Disposable {
|
|
|
2309
2345
|
dirtyUnitOtherFormulaMap: dirtyData.dirtyUnitOtherFormulaMap,
|
|
2310
2346
|
dirtyNameMap: dirtyData.dirtyNameMap,
|
|
2311
2347
|
dirtyDefinedNameMap: dirtyData.dirtyDefinedNameMap
|
|
2312
|
-
}, stringifyStartedAt = performance.now(), inputJson = JSON.stringify(payload), stringifyMs = performance.now() - stringifyStartedAt, nativeStartedAt = performance.now(), outputJson =
|
|
2348
|
+
}, stringifyStartedAt = performance.now(), inputJson = JSON.stringify(payload), stringifyMs = performance.now() - stringifyStartedAt, nativeStartedAt = performance.now(), outputJson = this._rustEngineSyncController.engine.binding.rustEngineMarkFormulaDirty(inputJson), nativeMs = performance.now() - nativeStartedAt, rustTimings;
|
|
2313
2349
|
try {
|
|
2314
2350
|
rustTimings = JSON.parse(outputJson).timings;
|
|
2315
2351
|
} catch {
|
|
@@ -2491,7 +2527,7 @@ var RustCalculateFormulaService = class extends import_core4.Disposable {
|
|
|
2491
2527
|
});
|
|
2492
2528
|
}
|
|
2493
2529
|
async calculate(formulaString) {
|
|
2494
|
-
this._nativeLoaded || (await
|
|
2530
|
+
this._nativeLoaded || (await this._rustEngineSyncController.engine.initialize(), this._nativeLoaded = !0);
|
|
2495
2531
|
let unitId = "__rust_formula_calculate__", sheetId = "__sheet__", input = {
|
|
2496
2532
|
config: { maxIteration: 1, intervalCount: DEFAULT_INTERVAL_COUNT },
|
|
2497
2533
|
formulaData: {
|
|
@@ -2516,7 +2552,7 @@ var RustCalculateFormulaService = class extends import_core4.Disposable {
|
|
|
2516
2552
|
return JSON.parse(executeOnRust(JSON.stringify(input))).runtimeData?.[unitId]?.[sheetId]?.[0]?.[0] ?? null;
|
|
2517
2553
|
}
|
|
2518
2554
|
async executeFormulas(formulas, rowData) {
|
|
2519
|
-
this._nativeLoaded || (await
|
|
2555
|
+
this._nativeLoaded || (await this._rustEngineSyncController.engine.initialize(), this._nativeLoaded = !0), this._currentConfigService.loadDataLite(rowData);
|
|
2520
2556
|
let unitData = this._currentConfigService.getUnitData(), definedNames = {};
|
|
2521
2557
|
for (let [unitId, names] of Object.entries(this._definedNamesService.getAllDefinedNames()))
|
|
2522
2558
|
for (let [id, name2] of Object.entries(names))
|
|
@@ -2539,12 +2575,12 @@ var RustCalculateFormulaService = class extends import_core4.Disposable {
|
|
|
2539
2575
|
return this._formulaExecutionOutputToResultMap(formulas, output);
|
|
2540
2576
|
}
|
|
2541
2577
|
async getAllDependencyJson(_rowData) {
|
|
2542
|
-
this._nativeLoaded || (await
|
|
2578
|
+
this._nativeLoaded || (await this._rustEngineSyncController.engine.initialize(), this._nativeLoaded = !0), this._syncRustFormulaDependencyDefinitions();
|
|
2543
2579
|
let graph = this._getRustDependencyGraph(), inspect = this._getRustInspectGraph();
|
|
2544
2580
|
return this._rustAllDependencyJson(graph, inspect);
|
|
2545
2581
|
}
|
|
2546
2582
|
async getCellDependencyJson(unitId, sheetId, row, column, _rowData) {
|
|
2547
|
-
this._nativeLoaded || (await
|
|
2583
|
+
this._nativeLoaded || (await this._rustEngineSyncController.engine.initialize(), this._nativeLoaded = !0), this._syncRustFormulaDependencyDefinitions();
|
|
2548
2584
|
let graph = this._getRustDependencyGraph(unitId), all = this._rustGraphDependencyJson(graph), current = all.find(
|
|
2549
2585
|
(item) => item.unitId === unitId && item.subUnitId === sheetId && item.row === row && item.column === column
|
|
2550
2586
|
);
|
|
@@ -2558,16 +2594,18 @@ var RustCalculateFormulaService = class extends import_core4.Disposable {
|
|
|
2558
2594
|
};
|
|
2559
2595
|
}
|
|
2560
2596
|
async getRangeDependents(unitRanges) {
|
|
2561
|
-
this._nativeLoaded || (await
|
|
2597
|
+
this._nativeLoaded || (await this._rustEngineSyncController.engine.initialize(), this._nativeLoaded = !0), this._syncRustFormulaDependencyDefinitions();
|
|
2562
2598
|
let graph = this._getRustDependencyGraph(), graphItems = this._rustGraphDependencyJson(graph), graphByCell = this._rustDependencyJsonByCell(graphItems), dirty = JSON.parse(
|
|
2563
|
-
|
|
2599
|
+
this._rustEngineSyncController.engine.binding.rustEngineGetDirtyDependencies(
|
|
2600
|
+
JSON.stringify(this._serializeUnitRanges(unitRanges))
|
|
2601
|
+
)
|
|
2564
2602
|
);
|
|
2565
2603
|
return this._uniqueDependencyJson(
|
|
2566
2604
|
(dirty.direct ?? dirty.affected ?? []).map((cell) => graphByCell.get(this._cellKey(cell))).filter(Boolean)
|
|
2567
2605
|
);
|
|
2568
2606
|
}
|
|
2569
2607
|
async getInRangeFormulas(unitRanges) {
|
|
2570
|
-
return this._nativeLoaded || (await
|
|
2608
|
+
return this._nativeLoaded || (await this._rustEngineSyncController.engine.initialize(), this._nativeLoaded = !0), this._syncRustFormulaDependencyDefinitions(), this._rustGraphDependencyJson(this._getRustDependencyGraph()).filter(
|
|
2571
2609
|
(item) => this._cellInUnitRanges(item.unitId, item.subUnitId, item.row, item.column, unitRanges)
|
|
2572
2610
|
);
|
|
2573
2611
|
}
|
|
@@ -2613,10 +2651,14 @@ var RustCalculateFormulaService = class extends import_core4.Disposable {
|
|
|
2613
2651
|
}), result;
|
|
2614
2652
|
}
|
|
2615
2653
|
_getRustDependencyGraph(unitId) {
|
|
2616
|
-
return JSON.parse(
|
|
2654
|
+
return JSON.parse(
|
|
2655
|
+
this._rustEngineSyncController.engine.binding.rustEngineBuildDependencyGraph(unitId)
|
|
2656
|
+
);
|
|
2617
2657
|
}
|
|
2618
2658
|
_getRustInspectGraph() {
|
|
2619
|
-
return JSON.parse(
|
|
2659
|
+
return JSON.parse(
|
|
2660
|
+
this._rustEngineSyncController.engine.binding.rustEngineInspectFormulaDependencyGraph()
|
|
2661
|
+
);
|
|
2620
2662
|
}
|
|
2621
2663
|
_rustAllDependencyJson(graph, inspect) {
|
|
2622
2664
|
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));
|
|
@@ -2823,6 +2865,7 @@ async function materializeWorkbookSnapshot(workbook, unitID, rev, dirtyInput) {
|
|
|
2823
2865
|
RUST_UPSERT_REFERENCE_DATA_MUTATION_ID,
|
|
2824
2866
|
RustCalculateFormulaService,
|
|
2825
2867
|
RustEngineSyncController,
|
|
2868
|
+
RustFormulaEngineSession,
|
|
2826
2869
|
RustFormulaProjectionService,
|
|
2827
2870
|
UniverRustFormulaEnginePlugin,
|
|
2828
2871
|
analyzeNumberFormatBatch,
|
package/lib/es/index.js
CHANGED
|
@@ -80,11 +80,6 @@ function loadSnapshotOnRust(snapshotJson) {
|
|
|
80
80
|
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
81
81
|
return nativeBinding.rustEngineLoadSnapshot(snapshotJson);
|
|
82
82
|
}
|
|
83
|
-
function loadSnapshotBinaryOnRust(snapshotBytes) {
|
|
84
|
-
if (!nativeBinding)
|
|
85
|
-
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
86
|
-
return nativeBinding.rustEngineLoadSnapshotBinary(snapshotBytes);
|
|
87
|
-
}
|
|
88
83
|
function applyMutationOnRust(mutationJson) {
|
|
89
84
|
if (!nativeBinding)
|
|
90
85
|
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
@@ -135,11 +130,6 @@ function syncRustFormulaDependenciesOnRust(inputJson) {
|
|
|
135
130
|
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
136
131
|
return nativeBinding.rustEngineSyncFormulaDependencies(inputJson);
|
|
137
132
|
}
|
|
138
|
-
function inspectRustFormulaDependencyGraphOnRust() {
|
|
139
|
-
if (!nativeBinding)
|
|
140
|
-
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
141
|
-
return nativeBinding.rustEngineInspectFormulaDependencyGraph();
|
|
142
|
-
}
|
|
143
133
|
function markRustFormulaDirtyOnRust(inputJson) {
|
|
144
134
|
if (!nativeBinding)
|
|
145
135
|
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
@@ -155,21 +145,34 @@ function clearRustFormulaDirtyOnRust() {
|
|
|
155
145
|
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
156
146
|
return nativeBinding.rustEngineClearFormulaDirty();
|
|
157
147
|
}
|
|
158
|
-
function executeDirtyFormulasOnRust(maxIteration, includeCalculatedNodes, includeRuntimeData, includeResultBatches) {
|
|
159
|
-
if (!nativeBinding)
|
|
160
|
-
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
161
|
-
return nativeBinding.rustEngineExecuteDirtyFormulas(
|
|
162
|
-
maxIteration,
|
|
163
|
-
includeCalculatedNodes,
|
|
164
|
-
includeRuntimeData,
|
|
165
|
-
includeResultBatches
|
|
166
|
-
);
|
|
167
|
-
}
|
|
168
148
|
function materializeWorkbookSnapshotOnRust(workbookJson, unitId, rev, dirtyInputJson) {
|
|
169
149
|
if (!nativeBinding)
|
|
170
150
|
throw new Error("Native binding not loaded. Call loadNativeBinding() first.");
|
|
171
151
|
return nativeBinding.rustMaterializeWorkbookSnapshot(workbookJson, unitId, rev, dirtyInputJson);
|
|
172
152
|
}
|
|
153
|
+
var RustFormulaEngineSession = class {
|
|
154
|
+
_engine = null;
|
|
155
|
+
_disposed = !1;
|
|
156
|
+
async initialize() {
|
|
157
|
+
if (this._disposed) throw new Error("Rust formula engine session is disposed");
|
|
158
|
+
if (this._engine) return;
|
|
159
|
+
let binding = await loadNativeBinding();
|
|
160
|
+
if (this._disposed) throw new Error("Rust formula engine session is disposed");
|
|
161
|
+
if (!this._engine) {
|
|
162
|
+
if (typeof binding.RustFormulaEngine != "function")
|
|
163
|
+
throw new Error("Native formula binding lacks instance isolation; upgrade engine-formula-rust-binding");
|
|
164
|
+
this._engine = new binding.RustFormulaEngine();
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
get binding() {
|
|
168
|
+
if (this._disposed) throw new Error("Rust formula engine session is disposed");
|
|
169
|
+
if (!this._engine) throw new Error("Rust formula engine session is not initialized");
|
|
170
|
+
return this._engine;
|
|
171
|
+
}
|
|
172
|
+
dispose() {
|
|
173
|
+
this._disposed || (this._disposed = !0, this._engine?.dispose(), this._engine = null);
|
|
174
|
+
}
|
|
175
|
+
};
|
|
173
176
|
|
|
174
177
|
// src/controllers/rust-engine-sync.controller.ts
|
|
175
178
|
import { CommandType, Disposable, ICommandService, setDependencies } from "@univerjs/core";
|
|
@@ -372,12 +375,20 @@ function createFormulaProjectionDesyncSignal(reason, error, mutationId) {
|
|
|
372
375
|
};
|
|
373
376
|
}
|
|
374
377
|
var RustFormulaProjectionService = class {
|
|
378
|
+
engine = new RustFormulaEngineSession();
|
|
379
|
+
dispose() {
|
|
380
|
+
this.engine.dispose();
|
|
381
|
+
}
|
|
375
382
|
_nativeLoaded = !1;
|
|
376
383
|
async load(workbooks) {
|
|
377
384
|
await this._ensureNativeLoaded();
|
|
378
385
|
try {
|
|
379
386
|
return {
|
|
380
|
-
stats: JSON.parse(
|
|
387
|
+
stats: JSON.parse(
|
|
388
|
+
this.engine.binding.rustEngineLoadSnapshot(
|
|
389
|
+
JSON.stringify(serializeRuntimeWorkbookSnapshots(workbooks))
|
|
390
|
+
)
|
|
391
|
+
)
|
|
381
392
|
};
|
|
382
393
|
} catch (error) {
|
|
383
394
|
return {
|
|
@@ -390,7 +401,9 @@ var RustFormulaProjectionService = class {
|
|
|
390
401
|
await this._ensureNativeLoaded();
|
|
391
402
|
try {
|
|
392
403
|
return {
|
|
393
|
-
stats: JSON.parse(
|
|
404
|
+
stats: JSON.parse(
|
|
405
|
+
this.engine.binding.rustEngineApplyMutation(JSON.stringify(normalizeRustEngineMutation(mutation)))
|
|
406
|
+
),
|
|
394
407
|
dependencyInvalidated: !isRustIncrementalDependencyMutation(mutation.id)
|
|
395
408
|
};
|
|
396
409
|
} catch (error) {
|
|
@@ -402,16 +415,16 @@ var RustFormulaProjectionService = class {
|
|
|
402
415
|
}
|
|
403
416
|
}
|
|
404
417
|
async syncFormulaDependencies(input) {
|
|
405
|
-
return await this._ensureNativeLoaded(), JSON.parse(
|
|
418
|
+
return await this._ensureNativeLoaded(), JSON.parse(this.engine.binding.rustEngineSyncFormulaDependencies(JSON.stringify(input)));
|
|
406
419
|
}
|
|
407
420
|
async markDirty(input) {
|
|
408
|
-
return await this._ensureNativeLoaded(), JSON.parse(
|
|
421
|
+
return await this._ensureNativeLoaded(), JSON.parse(this.engine.binding.rustEngineMarkFormulaDirty(JSON.stringify(input)));
|
|
409
422
|
}
|
|
410
423
|
async calculateDirty(maxIteration = 1) {
|
|
411
424
|
await this._ensureNativeLoaded();
|
|
412
425
|
try {
|
|
413
426
|
let output = JSON.parse(
|
|
414
|
-
|
|
427
|
+
this.engine.binding.rustEngineExecuteDirtyFormulas(maxIteration, !1, !1, !0)
|
|
415
428
|
);
|
|
416
429
|
return rustExecutionOutputToFormulaCalculationPatch(output);
|
|
417
430
|
} catch (error) {
|
|
@@ -426,7 +439,7 @@ var RustFormulaProjectionService = class {
|
|
|
426
439
|
async reset() {
|
|
427
440
|
await this._ensureNativeLoaded();
|
|
428
441
|
try {
|
|
429
|
-
return
|
|
442
|
+
return this.engine.binding.rustEngineClearFormulaDirty(), this.engine.binding.rustEngineClearFormulaDependencies(
|
|
430
443
|
JSON.stringify({
|
|
431
444
|
unitId: "",
|
|
432
445
|
clearSheetFormulas: !0,
|
|
@@ -434,7 +447,11 @@ var RustFormulaProjectionService = class {
|
|
|
434
447
|
clearOtherFormulas: !0
|
|
435
448
|
})
|
|
436
449
|
), {
|
|
437
|
-
stats: JSON.parse(
|
|
450
|
+
stats: JSON.parse(
|
|
451
|
+
this.engine.binding.rustEngineLoadSnapshot(
|
|
452
|
+
JSON.stringify({ workbooks: [] })
|
|
453
|
+
)
|
|
454
|
+
)
|
|
438
455
|
};
|
|
439
456
|
} catch (error) {
|
|
440
457
|
return {
|
|
@@ -446,7 +463,7 @@ var RustFormulaProjectionService = class {
|
|
|
446
463
|
async disposeWorkbook(unitId) {
|
|
447
464
|
await this._ensureNativeLoaded();
|
|
448
465
|
try {
|
|
449
|
-
return { stats: JSON.parse(
|
|
466
|
+
return { stats: JSON.parse(this.engine.binding.rustEngineDisposeWorkbook(unitId)) };
|
|
450
467
|
} catch (error) {
|
|
451
468
|
return {
|
|
452
469
|
desync: createFormulaProjectionDesyncSignal("workbook-dispose-failed", error),
|
|
@@ -455,7 +472,7 @@ var RustFormulaProjectionService = class {
|
|
|
455
472
|
}
|
|
456
473
|
}
|
|
457
474
|
async _ensureNativeLoaded() {
|
|
458
|
-
this._nativeLoaded || (await
|
|
475
|
+
this._nativeLoaded || (await this.engine.initialize(), this._nativeLoaded = !0);
|
|
459
476
|
}
|
|
460
477
|
};
|
|
461
478
|
function normalizeRustEngineMutation(mutation) {
|
|
@@ -989,19 +1006,6 @@ function isRecord(value) {
|
|
|
989
1006
|
}
|
|
990
1007
|
|
|
991
1008
|
// src/controllers/rust-engine-sync.controller.ts
|
|
992
|
-
var rustEngineSyncState = {
|
|
993
|
-
snapshotEpoch: 0,
|
|
994
|
-
dependencyInvalidationEpoch: 0
|
|
995
|
-
};
|
|
996
|
-
function getRustEngineSyncState() {
|
|
997
|
-
return { ...rustEngineSyncState };
|
|
998
|
-
}
|
|
999
|
-
function markRustSnapshotLoaded() {
|
|
1000
|
-
rustEngineSyncState.snapshotEpoch += 1, rustEngineSyncState.dependencyInvalidationEpoch += 1;
|
|
1001
|
-
}
|
|
1002
|
-
function markRustFormulaDependenciesInvalidated() {
|
|
1003
|
-
rustEngineSyncState.dependencyInvalidationEpoch += 1;
|
|
1004
|
-
}
|
|
1005
1009
|
function emitRustEngineSyncDebugEvent(event) {
|
|
1006
1010
|
let hook = globalThis.__UNIVER_RUST_FORMULA_DEBUG_HOOK__;
|
|
1007
1011
|
typeof hook == "function" && hook(event);
|
|
@@ -1041,6 +1045,17 @@ var RustEngineSyncController = class extends Disposable {
|
|
|
1041
1045
|
this._initialize();
|
|
1042
1046
|
}
|
|
1043
1047
|
_commandService;
|
|
1048
|
+
engine = new RustFormulaEngineSession();
|
|
1049
|
+
_syncState = { snapshotEpoch: 0, dependencyInvalidationEpoch: 0 };
|
|
1050
|
+
getSyncState() {
|
|
1051
|
+
return { ...this._syncState };
|
|
1052
|
+
}
|
|
1053
|
+
_markSnapshotLoaded() {
|
|
1054
|
+
this._syncState.snapshotEpoch += 1, this._syncState.dependencyInvalidationEpoch += 1;
|
|
1055
|
+
}
|
|
1056
|
+
_markDependenciesInvalidated() {
|
|
1057
|
+
this._syncState.dependencyInvalidationEpoch += 1;
|
|
1058
|
+
}
|
|
1044
1059
|
_nativeReady = !1;
|
|
1045
1060
|
_snapshotLoaded = !1;
|
|
1046
1061
|
_projectionLoadPromise = null;
|
|
@@ -1074,7 +1089,7 @@ var RustEngineSyncController = class extends Disposable {
|
|
|
1074
1089
|
this._projectionDeltaBarrier = barrier;
|
|
1075
1090
|
}
|
|
1076
1091
|
async _loadProjection(workbooks) {
|
|
1077
|
-
await
|
|
1092
|
+
await this.engine.initialize(), this._nativeReady = !0;
|
|
1078
1093
|
let serializeStartedAt = performance.now(), snapshot = serializeRuntimeWorkbookSnapshots(workbooks);
|
|
1079
1094
|
this._loadSerializedSnapshot(snapshot, performance.now() - serializeStartedAt);
|
|
1080
1095
|
}
|
|
@@ -1097,20 +1112,17 @@ var RustEngineSyncController = class extends Disposable {
|
|
|
1097
1112
|
disposeProjectionWorkbook(unitId) {
|
|
1098
1113
|
if (!(!this._nativeReady || !this._snapshotLoaded))
|
|
1099
1114
|
try {
|
|
1100
|
-
|
|
1115
|
+
this.engine.binding.rustEngineDisposeWorkbook(unitId), this._markDependenciesInvalidated();
|
|
1101
1116
|
} catch {
|
|
1102
|
-
this.
|
|
1117
|
+
this.markProjectionDesynced();
|
|
1103
1118
|
}
|
|
1104
1119
|
}
|
|
1105
1120
|
dispose() {
|
|
1106
|
-
|
|
1107
|
-
this._snapshotLoaded = !1;
|
|
1108
|
-
return;
|
|
1109
|
-
}
|
|
1121
|
+
super.dispose(), this._pendingMutations.length = 0, this._projectionManagedTableUnits.clear(), this._projectionLoadPromise = null, this._projectionDeltaBarrier = Promise.resolve();
|
|
1110
1122
|
try {
|
|
1111
|
-
|
|
1123
|
+
this.engine.dispose();
|
|
1112
1124
|
} catch {
|
|
1113
|
-
this.
|
|
1125
|
+
this.markProjectionDesynced();
|
|
1114
1126
|
return;
|
|
1115
1127
|
}
|
|
1116
1128
|
this._nativeReady = !1, this._snapshotLoaded = !1;
|
|
@@ -1118,7 +1130,7 @@ var RustEngineSyncController = class extends Disposable {
|
|
|
1118
1130
|
_loadSerializedSnapshot(snapshot, serializeMs) {
|
|
1119
1131
|
let precisionAsDisplayedWorkbookCount = snapshot.workbooks.filter(
|
|
1120
1132
|
(workbook) => workbook.calculation?.fullPrecision === !1
|
|
1121
|
-
).length, displayPrecisionCellCount = countDisplayPrecisionCells(snapshot), pendingCountCoveredBySnapshot = this._pendingMutations.length, stringifyStartedAt = performance.now(), snapshotJson = JSON.stringify(snapshot), stringifyMs = performance.now() - stringifyStartedAt, snapshotBuffer = globalThis.Buffer?.from(snapshotJson), nativeStartedAt = performance.now(), nativeOutput = snapshotBuffer ?
|
|
1133
|
+
).length, displayPrecisionCellCount = countDisplayPrecisionCells(snapshot), pendingCountCoveredBySnapshot = this._pendingMutations.length, stringifyStartedAt = performance.now(), snapshotJson = JSON.stringify(snapshot), stringifyMs = performance.now() - stringifyStartedAt, snapshotBuffer = globalThis.Buffer?.from(snapshotJson), nativeStartedAt = performance.now(), nativeOutput = snapshotBuffer ? this.engine.binding.rustEngineLoadSnapshotBinary(snapshotBuffer) : this.engine.binding.rustEngineLoadSnapshot(snapshotJson), nativeMs = performance.now() - nativeStartedAt, nativeTimings;
|
|
1122
1134
|
try {
|
|
1123
1135
|
nativeTimings = JSON.parse(nativeOutput).timingsMs;
|
|
1124
1136
|
} catch {
|
|
@@ -1137,7 +1149,7 @@ var RustEngineSyncController = class extends Disposable {
|
|
|
1137
1149
|
transport: snapshotBuffer ? "binary-json" : "string-json",
|
|
1138
1150
|
nativeTimings
|
|
1139
1151
|
}
|
|
1140
|
-
}), this._pendingMutations.splice(0, pendingCountCoveredBySnapshot), this._snapshotLoaded = !0,
|
|
1152
|
+
}), this._pendingMutations.splice(0, pendingCountCoveredBySnapshot), this._snapshotLoaded = !0, this._markSnapshotLoaded(), this._flushPendingMutations();
|
|
1141
1153
|
}
|
|
1142
1154
|
_queueOrSyncMutation(mutation) {
|
|
1143
1155
|
if (!this._nativeReady || !this._snapshotLoaded) {
|
|
@@ -1155,9 +1167,9 @@ var RustEngineSyncController = class extends Disposable {
|
|
|
1155
1167
|
_syncMutation(mutation) {
|
|
1156
1168
|
let totalStartedAt = performance.now(), stringifyStartedAt = performance.now(), payload = JSON.stringify(normalizeRustEngineMutation(mutation)), stringifyMs = performance.now() - stringifyStartedAt, nativeStartedAt = performance.now();
|
|
1157
1169
|
try {
|
|
1158
|
-
|
|
1170
|
+
this.engine.binding.rustEngineApplyMutation(payload), isRustIncrementalDependencyMutation(mutation.id) || this._markDependenciesInvalidated();
|
|
1159
1171
|
} catch {
|
|
1160
|
-
this.
|
|
1172
|
+
this.markProjectionDesynced();
|
|
1161
1173
|
} finally {
|
|
1162
1174
|
emitRustEngineSyncDebugEvent({
|
|
1163
1175
|
type: "applyMutation",
|
|
@@ -1173,7 +1185,11 @@ var RustEngineSyncController = class extends Disposable {
|
|
|
1173
1185
|
});
|
|
1174
1186
|
}
|
|
1175
1187
|
}
|
|
1176
|
-
|
|
1188
|
+
/**
|
|
1189
|
+
* Marks the native projection as out of sync so the next mutation reloads it.
|
|
1190
|
+
* Also used by the projection controller when a background projection load fails.
|
|
1191
|
+
*/
|
|
1192
|
+
markProjectionDesynced() {
|
|
1177
1193
|
this._nativeReady = !1, this._snapshotLoaded = !1;
|
|
1178
1194
|
}
|
|
1179
1195
|
_shouldSyncMutation(command, options) {
|
|
@@ -1239,7 +1255,7 @@ import { ICalculateFormulaService } from "@univerjs/engine-formula";
|
|
|
1239
1255
|
import { UniverProFormulaEnginePlugin } from "@univerjs-pro/engine-formula";
|
|
1240
1256
|
|
|
1241
1257
|
// package.json
|
|
1242
|
-
var name = "@univerjs-pro/engine-formula-rust", version = "1.0.
|
|
1258
|
+
var name = "@univerjs-pro/engine-formula-rust", version = "1.0.1";
|
|
1243
1259
|
|
|
1244
1260
|
// src/controllers/rust-same-runtime-projection.controller.ts
|
|
1245
1261
|
import {
|
|
@@ -1287,7 +1303,9 @@ var RustSameRuntimeProjectionController = class extends Disposable2 {
|
|
|
1287
1303
|
UniverInstanceType.UNIVER_BASE
|
|
1288
1304
|
))
|
|
1289
1305
|
this._rustEngineSyncController.setProjectionManagedTableUnit(base.getUnitId()), this._rememberBaseProjectionStructure(base.getSnapshot());
|
|
1290
|
-
this._initialProjectionLoad = this._loadAllWorkbookProjections()
|
|
1306
|
+
this._initialProjectionLoad = this._loadAllWorkbookProjections().catch(() => {
|
|
1307
|
+
this._rustEngineSyncController.markProjectionDesynced();
|
|
1308
|
+
}), this.disposeWithMe(
|
|
1291
1309
|
toDisposable(
|
|
1292
1310
|
this._univerInstanceService.getTypeOfUnitAdded$(UniverInstanceType.UNIVER_SHEET).subscribe(({ unit }) => {
|
|
1293
1311
|
this._enqueueProjectionDelta(() => {
|
|
@@ -1909,14 +1927,19 @@ var RustCalculateFormulaService = class extends Disposable3 {
|
|
|
1909
1927
|
this._runtimeService.setRuntimeFeatureRange(featureId, featureRange);
|
|
1910
1928
|
}
|
|
1911
1929
|
async execute(formulaDatasetConfig) {
|
|
1912
|
-
this._nativeLoaded || (await
|
|
1930
|
+
this._nativeLoaded || (await this._rustEngineSyncController.engine.initialize(), this._nativeLoaded = !0), await this._rustEngineSyncController.waitForProjectionLoad(), this._externalFormulaDatasetConfig = formulaDatasetConfig, this._currentConfigService.load(formulaDatasetConfig), this._externalRequestGeneration++, this._externalInflight.clear(), this._externalCompleted.clear(), this._runtimeService.setFormulaExecuteStage(FormulaExecuteStageType.START), this._executionInProgressListener$.next(this._runtimeService.getRuntimeState()), this._runtimeService.reset();
|
|
1913
1931
|
let cycleReferenceCount = Math.max(formulaDatasetConfig.maxIteration || 1, 1);
|
|
1914
1932
|
await this._executeLock.acquire("FORMULA_EXECUTION_LOCK", async () => {
|
|
1915
1933
|
this._runtimeService.setFormulaCycleIndex(0), await this._executeStep(cycleReferenceCount) > 0 ? this._runtimeService.markedAsSuccessfullyExecuted() : this._runtimeService.markedAsNoFunctionsExecuted(), this._runtimeService.setFormulaExecuteStage(FormulaExecuteStageType.CALCULATION_COMPLETED), this._executionInProgressListener$.next(this._runtimeService.getRuntimeState()), this._executionCompleteListener$.next(this._runtimeService.getAllRuntimeData()), this._runtimeService.reset();
|
|
1916
1934
|
});
|
|
1917
1935
|
}
|
|
1918
1936
|
async _executeStep(maxIteration) {
|
|
1919
|
-
let syncedFeatures = this._syncRustFormulaDependencies(void 0, !0), previousFeatureSignatures = this._featureSignatureMap(syncedFeatures), executeStartedAt = performance.now(), outputJson =
|
|
1937
|
+
let syncedFeatures = this._syncRustFormulaDependencies(void 0, !0), previousFeatureSignatures = this._featureSignatureMap(syncedFeatures), executeStartedAt = performance.now(), outputJson = this._rustEngineSyncController.engine.binding.rustEngineExecuteDirtyFormulas(
|
|
1938
|
+
maxIteration,
|
|
1939
|
+
!1,
|
|
1940
|
+
!1,
|
|
1941
|
+
!0
|
|
1942
|
+
), nativeAndSerializeMs = performance.now() - executeStartedAt, parseStartedAt = performance.now(), output = JSON.parse(outputJson), calculatedNodeCount = output.calculatedNodeCount, parseMs = performance.now() - parseStartedAt;
|
|
1920
1943
|
output = await this._resolveExternalReferenceNeeds(output, maxIteration);
|
|
1921
1944
|
let applyStartedAt = performance.now(), applyBreakdown = await this._applyRustDependencyOutput(output), applyMs = performance.now() - applyStartedAt;
|
|
1922
1945
|
if (emitRustFormulaDebugEvent({
|
|
@@ -1952,7 +1975,12 @@ var RustCalculateFormulaService = class extends Disposable3 {
|
|
|
1952
1975
|
this._markRustFormulaDirty(
|
|
1953
1976
|
this._currentConfigService.getDirtyData(),
|
|
1954
1977
|
this._dirtyFeatureMapFor(changedFeatures)
|
|
1955
|
-
), executeStartedAt = performance.now(), outputJson =
|
|
1978
|
+
), executeStartedAt = performance.now(), outputJson = this._rustEngineSyncController.engine.binding.rustEngineExecuteDirtyFormulas(
|
|
1979
|
+
maxIteration,
|
|
1980
|
+
!1,
|
|
1981
|
+
!1,
|
|
1982
|
+
!0
|
|
1983
|
+
), nativeAndSerializeMs = performance.now() - executeStartedAt, parseStartedAt = performance.now(), output = JSON.parse(outputJson), calculatedNodeCount += output.calculatedNodeCount, parseMs = performance.now() - parseStartedAt, output = await this._resolveExternalReferenceNeeds(output, maxIteration), applyStartedAt = performance.now(), applyBreakdown = await this._applyRustDependencyOutput(output), applyMs = performance.now() - applyStartedAt, emitRustFormulaDebugEvent({
|
|
1956
1984
|
type: "executeDirtyFormulas",
|
|
1957
1985
|
payload: {
|
|
1958
1986
|
calculatedNodeCount: output.calculatedNodeCount,
|
|
@@ -1997,7 +2025,14 @@ var RustCalculateFormulaService = class extends Disposable3 {
|
|
|
1997
2025
|
loadedRanges,
|
|
1998
2026
|
this._superTableService
|
|
1999
2027
|
) === 0) break;
|
|
2000
|
-
this._syncRustFormulaDependencies(), output = JSON.parse(
|
|
2028
|
+
this._syncRustFormulaDependencies(), output = JSON.parse(
|
|
2029
|
+
this._rustEngineSyncController.engine.binding.rustEngineExecuteDirtyFormulas(
|
|
2030
|
+
maxIteration,
|
|
2031
|
+
!1,
|
|
2032
|
+
!1,
|
|
2033
|
+
!0
|
|
2034
|
+
)
|
|
2035
|
+
);
|
|
2001
2036
|
}
|
|
2002
2037
|
return output;
|
|
2003
2038
|
}
|
|
@@ -2171,7 +2206,7 @@ var RustCalculateFormulaService = class extends Disposable3 {
|
|
|
2171
2206
|
};
|
|
2172
2207
|
}
|
|
2173
2208
|
_syncRustFormulaDependencies(dirtyUnitFeatureMapOverride, includeExternalReferences = !1) {
|
|
2174
|
-
let syncState =
|
|
2209
|
+
let syncState = this._rustEngineSyncController.getSyncState(), externalReferences = includeExternalReferences ? this._externalFormulaDatasetConfig?.externalReferences ?? {} : void 0, externalReferenceSignature = externalReferences ? JSON.stringify(externalReferences) : this._syncedExternalReferenceSignature, shouldSendExternalReferences = includeExternalReferences && (externalReferenceSignature !== "{}" || this._syncedExternalReferenceSignature !== "{}"), rebuildSheetFormulas = this._syncedSnapshotEpoch !== syncState.snapshotEpoch || this._syncedDependencyInvalidationEpoch !== syncState.dependencyInvalidationEpoch || shouldSendExternalReferences, collectStartedAt = performance.now(), state = this._collectRustFormulaDependencySyncState(), collectMs = performance.now() - collectStartedAt;
|
|
2175
2210
|
if (!(shouldSendExternalReferences || rebuildSheetFormulas || state.featureCalculations.length > 0 || state.otherFormulas.length > 0))
|
|
2176
2211
|
return emitRustFormulaDebugEvent({
|
|
2177
2212
|
type: "syncDependencies",
|
|
@@ -2195,7 +2230,7 @@ var RustCalculateFormulaService = class extends Disposable3 {
|
|
|
2195
2230
|
featureCalculations: state.featureCalculations,
|
|
2196
2231
|
otherFormulas: state.otherFormulas,
|
|
2197
2232
|
...shouldSendExternalReferences ? { externalReferences } : {}
|
|
2198
|
-
}), stringifyMs = performance.now() - stringifyStartedAt, nativeStartedAt = performance.now(), outputJson =
|
|
2233
|
+
}), stringifyMs = performance.now() - stringifyStartedAt, nativeStartedAt = performance.now(), outputJson = this._rustEngineSyncController.engine.binding.rustEngineSyncFormulaDependencies(inputJson), nativeMs = performance.now() - nativeStartedAt, parseStartedAt = performance.now(), output = JSON.parse(outputJson), parseMs = performance.now() - parseStartedAt;
|
|
2199
2234
|
return emitRustFormulaDebugEvent({
|
|
2200
2235
|
type: "syncDependencies",
|
|
2201
2236
|
payload: {
|
|
@@ -2217,7 +2252,7 @@ var RustCalculateFormulaService = class extends Disposable3 {
|
|
|
2217
2252
|
}
|
|
2218
2253
|
_syncRustFormulaDependencyDefinitions() {
|
|
2219
2254
|
let state = this._collectRustFormulaDependencySyncState();
|
|
2220
|
-
return
|
|
2255
|
+
return this._rustEngineSyncController.engine.binding.rustEngineSyncFormulaDependencies(
|
|
2221
2256
|
JSON.stringify({
|
|
2222
2257
|
rebuildSheetFormulas: !1,
|
|
2223
2258
|
featureCalculations: state.featureCalculations,
|
|
@@ -2292,7 +2327,7 @@ var RustCalculateFormulaService = class extends Disposable3 {
|
|
|
2292
2327
|
dirtyUnitOtherFormulaMap: dirtyData.dirtyUnitOtherFormulaMap,
|
|
2293
2328
|
dirtyNameMap: dirtyData.dirtyNameMap,
|
|
2294
2329
|
dirtyDefinedNameMap: dirtyData.dirtyDefinedNameMap
|
|
2295
|
-
}, stringifyStartedAt = performance.now(), inputJson = JSON.stringify(payload), stringifyMs = performance.now() - stringifyStartedAt, nativeStartedAt = performance.now(), outputJson =
|
|
2330
|
+
}, stringifyStartedAt = performance.now(), inputJson = JSON.stringify(payload), stringifyMs = performance.now() - stringifyStartedAt, nativeStartedAt = performance.now(), outputJson = this._rustEngineSyncController.engine.binding.rustEngineMarkFormulaDirty(inputJson), nativeMs = performance.now() - nativeStartedAt, rustTimings;
|
|
2296
2331
|
try {
|
|
2297
2332
|
rustTimings = JSON.parse(outputJson).timings;
|
|
2298
2333
|
} catch {
|
|
@@ -2474,7 +2509,7 @@ var RustCalculateFormulaService = class extends Disposable3 {
|
|
|
2474
2509
|
});
|
|
2475
2510
|
}
|
|
2476
2511
|
async calculate(formulaString) {
|
|
2477
|
-
this._nativeLoaded || (await
|
|
2512
|
+
this._nativeLoaded || (await this._rustEngineSyncController.engine.initialize(), this._nativeLoaded = !0);
|
|
2478
2513
|
let unitId = "__rust_formula_calculate__", sheetId = "__sheet__", input = {
|
|
2479
2514
|
config: { maxIteration: 1, intervalCount: DEFAULT_INTERVAL_COUNT },
|
|
2480
2515
|
formulaData: {
|
|
@@ -2499,7 +2534,7 @@ var RustCalculateFormulaService = class extends Disposable3 {
|
|
|
2499
2534
|
return JSON.parse(executeOnRust(JSON.stringify(input))).runtimeData?.[unitId]?.[sheetId]?.[0]?.[0] ?? null;
|
|
2500
2535
|
}
|
|
2501
2536
|
async executeFormulas(formulas, rowData) {
|
|
2502
|
-
this._nativeLoaded || (await
|
|
2537
|
+
this._nativeLoaded || (await this._rustEngineSyncController.engine.initialize(), this._nativeLoaded = !0), this._currentConfigService.loadDataLite(rowData);
|
|
2503
2538
|
let unitData = this._currentConfigService.getUnitData(), definedNames = {};
|
|
2504
2539
|
for (let [unitId, names] of Object.entries(this._definedNamesService.getAllDefinedNames()))
|
|
2505
2540
|
for (let [id, name2] of Object.entries(names))
|
|
@@ -2522,12 +2557,12 @@ var RustCalculateFormulaService = class extends Disposable3 {
|
|
|
2522
2557
|
return this._formulaExecutionOutputToResultMap(formulas, output);
|
|
2523
2558
|
}
|
|
2524
2559
|
async getAllDependencyJson(_rowData) {
|
|
2525
|
-
this._nativeLoaded || (await
|
|
2560
|
+
this._nativeLoaded || (await this._rustEngineSyncController.engine.initialize(), this._nativeLoaded = !0), this._syncRustFormulaDependencyDefinitions();
|
|
2526
2561
|
let graph = this._getRustDependencyGraph(), inspect = this._getRustInspectGraph();
|
|
2527
2562
|
return this._rustAllDependencyJson(graph, inspect);
|
|
2528
2563
|
}
|
|
2529
2564
|
async getCellDependencyJson(unitId, sheetId, row, column, _rowData) {
|
|
2530
|
-
this._nativeLoaded || (await
|
|
2565
|
+
this._nativeLoaded || (await this._rustEngineSyncController.engine.initialize(), this._nativeLoaded = !0), this._syncRustFormulaDependencyDefinitions();
|
|
2531
2566
|
let graph = this._getRustDependencyGraph(unitId), all = this._rustGraphDependencyJson(graph), current = all.find(
|
|
2532
2567
|
(item) => item.unitId === unitId && item.subUnitId === sheetId && item.row === row && item.column === column
|
|
2533
2568
|
);
|
|
@@ -2541,16 +2576,18 @@ var RustCalculateFormulaService = class extends Disposable3 {
|
|
|
2541
2576
|
};
|
|
2542
2577
|
}
|
|
2543
2578
|
async getRangeDependents(unitRanges) {
|
|
2544
|
-
this._nativeLoaded || (await
|
|
2579
|
+
this._nativeLoaded || (await this._rustEngineSyncController.engine.initialize(), this._nativeLoaded = !0), this._syncRustFormulaDependencyDefinitions();
|
|
2545
2580
|
let graph = this._getRustDependencyGraph(), graphItems = this._rustGraphDependencyJson(graph), graphByCell = this._rustDependencyJsonByCell(graphItems), dirty = JSON.parse(
|
|
2546
|
-
|
|
2581
|
+
this._rustEngineSyncController.engine.binding.rustEngineGetDirtyDependencies(
|
|
2582
|
+
JSON.stringify(this._serializeUnitRanges(unitRanges))
|
|
2583
|
+
)
|
|
2547
2584
|
);
|
|
2548
2585
|
return this._uniqueDependencyJson(
|
|
2549
2586
|
(dirty.direct ?? dirty.affected ?? []).map((cell) => graphByCell.get(this._cellKey(cell))).filter(Boolean)
|
|
2550
2587
|
);
|
|
2551
2588
|
}
|
|
2552
2589
|
async getInRangeFormulas(unitRanges) {
|
|
2553
|
-
return this._nativeLoaded || (await
|
|
2590
|
+
return this._nativeLoaded || (await this._rustEngineSyncController.engine.initialize(), this._nativeLoaded = !0), this._syncRustFormulaDependencyDefinitions(), this._rustGraphDependencyJson(this._getRustDependencyGraph()).filter(
|
|
2554
2591
|
(item) => this._cellInUnitRanges(item.unitId, item.subUnitId, item.row, item.column, unitRanges)
|
|
2555
2592
|
);
|
|
2556
2593
|
}
|
|
@@ -2596,10 +2633,14 @@ var RustCalculateFormulaService = class extends Disposable3 {
|
|
|
2596
2633
|
}), result;
|
|
2597
2634
|
}
|
|
2598
2635
|
_getRustDependencyGraph(unitId) {
|
|
2599
|
-
return JSON.parse(
|
|
2636
|
+
return JSON.parse(
|
|
2637
|
+
this._rustEngineSyncController.engine.binding.rustEngineBuildDependencyGraph(unitId)
|
|
2638
|
+
);
|
|
2600
2639
|
}
|
|
2601
2640
|
_getRustInspectGraph() {
|
|
2602
|
-
return JSON.parse(
|
|
2641
|
+
return JSON.parse(
|
|
2642
|
+
this._rustEngineSyncController.engine.binding.rustEngineInspectFormulaDependencyGraph()
|
|
2643
|
+
);
|
|
2603
2644
|
}
|
|
2604
2645
|
_rustAllDependencyJson(graph, inspect) {
|
|
2605
2646
|
let cellItems = this._rustGraphDependencyJson(graph), seen = new Set(cellItems.map((item) => item.treeId)), nonCellItems = (inspect.nodes ?? []).filter((item) => item.node.nodeType !== "cellFormula" && !seen.has(item.index)).map((item) => this._rustFormulaNodeToDependencyJson(item.index, item.node));
|
|
@@ -2805,6 +2846,7 @@ export {
|
|
|
2805
2846
|
RUST_UPSERT_REFERENCE_DATA_MUTATION_ID,
|
|
2806
2847
|
RustCalculateFormulaService,
|
|
2807
2848
|
RustEngineSyncController,
|
|
2849
|
+
RustFormulaEngineSession,
|
|
2808
2850
|
RustFormulaProjectionService,
|
|
2809
2851
|
UniverRustFormulaEnginePlugin,
|
|
2810
2852
|
analyzeNumberFormatBatch,
|
package/lib/types/index.d.ts
CHANGED
|
@@ -5,25 +5,7 @@ import { ExternalReferenceModel, IFormulaReferenceDataService, UniverProFormulaE
|
|
|
5
5
|
import { Subject } from "rxjs";
|
|
6
6
|
import { ISheetBlock, ISnapshot } from "@univerjs/protocol";
|
|
7
7
|
//#region src/binding.d.ts
|
|
8
|
-
interface
|
|
9
|
-
formulaEngineExecute(inputJson: string): string;
|
|
10
|
-
formulaLexerTreeBuild(formula: string, transformSuffix?: boolean): string;
|
|
11
|
-
formulaSequenceNodesBuild(formula: string): string;
|
|
12
|
-
formulaCheckIfAddBracket(formula: string): number;
|
|
13
|
-
rustNumfmtFormat(inputJson: string): string;
|
|
14
|
-
rustNumfmtFormatBatch(inputJson: string): string;
|
|
15
|
-
rustNumfmtParse(inputJson: string): string;
|
|
16
|
-
rustNumfmtParseBatch(inputJson: string): string;
|
|
17
|
-
rustNumfmtParseMatrixBatch(inputJson: string): string;
|
|
18
|
-
rustNumfmtParseValue(inputJson: string): string;
|
|
19
|
-
rustNumfmtAnalyzeFormat(inputJson: string): string;
|
|
20
|
-
rustNumfmtAnalyzeBatch(inputJson: string): string;
|
|
21
|
-
rustNumfmtFormatInfo(inputJson: string): string;
|
|
22
|
-
rustNumfmtFormatDateInfo(inputJson: string): string;
|
|
23
|
-
rustNumfmtFormatColor(inputJson: string): string;
|
|
24
|
-
rustNumfmtDateToSerial(inputJson: string): string;
|
|
25
|
-
rustNumfmtDateFromSerial(inputJson: string): string;
|
|
26
|
-
rustNumfmtValidate(inputJson: string): string;
|
|
8
|
+
interface INativeFormulaEngine {
|
|
27
9
|
rustEngineLoadSnapshot(snapshotJson: string): string;
|
|
28
10
|
rustEngineLoadSnapshotBinary(snapshotBytes: Buffer): string;
|
|
29
11
|
rustEngineLoadSingleSheetColumnarSnapshot(unitId: string, workbookName: string | undefined | null, sheetId: string, sheetName: string | undefined | null, rowCount: number, columnCount: number, rows: Buffer, cols: Buffer, valueTags: Buffer, numbers: Buffer, valueStringOffsets: Buffer, valueStringBytes: Buffer, formulaOffsets: Buffer, formulaBytes: Buffer): string;
|
|
@@ -45,6 +27,28 @@ interface INativeBinding {
|
|
|
45
27
|
rustEngineClearFormulaDirty(): string;
|
|
46
28
|
rustEngineExecuteDirtyFormulas(maxIteration?: number, includeCalculatedNodes?: boolean, includeRuntimeData?: boolean, includeResultBatches?: boolean): string;
|
|
47
29
|
rustEngineGetFormulaNumberResultsColumnar(unitId: string, sheetId: string, startColumn?: number, endColumn?: number): Buffer;
|
|
30
|
+
dispose(): void;
|
|
31
|
+
}
|
|
32
|
+
interface INativeBinding extends Omit<INativeFormulaEngine, 'dispose'> {
|
|
33
|
+
formulaEngineExecute(inputJson: string): string;
|
|
34
|
+
formulaLexerTreeBuild(formula: string, transformSuffix?: boolean): string;
|
|
35
|
+
formulaSequenceNodesBuild(formula: string): string;
|
|
36
|
+
formulaCheckIfAddBracket(formula: string): number;
|
|
37
|
+
rustNumfmtFormat(inputJson: string): string;
|
|
38
|
+
rustNumfmtFormatBatch(inputJson: string): string;
|
|
39
|
+
rustNumfmtParse(inputJson: string): string;
|
|
40
|
+
rustNumfmtParseBatch(inputJson: string): string;
|
|
41
|
+
rustNumfmtParseMatrixBatch(inputJson: string): string;
|
|
42
|
+
rustNumfmtParseValue(inputJson: string): string;
|
|
43
|
+
rustNumfmtAnalyzeFormat(inputJson: string): string;
|
|
44
|
+
rustNumfmtAnalyzeBatch(inputJson: string): string;
|
|
45
|
+
rustNumfmtFormatInfo(inputJson: string): string;
|
|
46
|
+
rustNumfmtFormatDateInfo(inputJson: string): string;
|
|
47
|
+
rustNumfmtFormatColor(inputJson: string): string;
|
|
48
|
+
rustNumfmtDateToSerial(inputJson: string): string;
|
|
49
|
+
rustNumfmtDateFromSerial(inputJson: string): string;
|
|
50
|
+
rustNumfmtValidate(inputJson: string): string;
|
|
51
|
+
RustFormulaEngine: new () => INativeFormulaEngine;
|
|
48
52
|
rustMaterializeWorkbookSnapshot(workbookJson: Buffer, unitId: string, rev: number, dirtyInputJson?: string): Promise<INativeMaterializedWorkbook>;
|
|
49
53
|
}
|
|
50
54
|
interface INativeMaterializedBlock {
|
|
@@ -85,6 +89,14 @@ declare function markRustFormulaDirtyOnRust(inputJson: string): string;
|
|
|
85
89
|
declare function clearRustFormulaDependenciesOnRust(inputJson: string): string;
|
|
86
90
|
declare function clearRustFormulaDirtyOnRust(): string;
|
|
87
91
|
declare function materializeWorkbookSnapshotOnRust(workbookJson: Buffer, unitId: string, rev: number, dirtyInputJson?: string): Promise<INativeMaterializedWorkbook>;
|
|
92
|
+
/** Owns one native store. Loading and disposal never touch another session. */
|
|
93
|
+
declare class RustFormulaEngineSession {
|
|
94
|
+
private _engine;
|
|
95
|
+
private _disposed;
|
|
96
|
+
initialize(): Promise<void>;
|
|
97
|
+
get binding(): INativeFormulaEngine;
|
|
98
|
+
dispose(): void;
|
|
99
|
+
}
|
|
88
100
|
//#endregion
|
|
89
101
|
//#region src/types.d.ts
|
|
90
102
|
/**
|
|
@@ -569,6 +581,8 @@ declare function createProjectionWorkbookUpsertMutation(input: IRustProjectionWo
|
|
|
569
581
|
declare function rustExecutionOutputToFormulaCalculationPatch(output: IRustFormulaDependencyExecutionOutput): IFormulaCalculationPatch;
|
|
570
582
|
declare function createFormulaProjectionDesyncSignal(reason: string, error: unknown, mutationId?: string): IFormulaProjectionDesyncSignal;
|
|
571
583
|
declare class RustFormulaProjectionService {
|
|
584
|
+
readonly engine: RustFormulaEngineSession;
|
|
585
|
+
dispose(): void;
|
|
572
586
|
private _nativeLoaded;
|
|
573
587
|
load(workbooks: readonly IRustProjectionWorkbookInput[]): Promise<IRustFormulaProjectionLoadResult>;
|
|
574
588
|
applyMutation(mutation: IRustEngineMutation): Promise<IRustFormulaProjectionMutationResult>;
|
|
@@ -590,6 +604,10 @@ declare class RustFormulaProjectionService {
|
|
|
590
604
|
}
|
|
591
605
|
//#endregion
|
|
592
606
|
//#region src/controllers/rust-engine-sync.controller.d.ts
|
|
607
|
+
interface IRustEngineSyncState {
|
|
608
|
+
snapshotEpoch: number;
|
|
609
|
+
dependencyInvalidationEpoch: number;
|
|
610
|
+
}
|
|
593
611
|
/**
|
|
594
612
|
* Keeps Rust's in-memory formula workbook projection aligned with Univer.
|
|
595
613
|
*
|
|
@@ -599,6 +617,11 @@ declare class RustFormulaProjectionService {
|
|
|
599
617
|
*/
|
|
600
618
|
declare class RustEngineSyncController extends Disposable {
|
|
601
619
|
private readonly _commandService;
|
|
620
|
+
readonly engine: RustFormulaEngineSession;
|
|
621
|
+
private readonly _syncState;
|
|
622
|
+
getSyncState(): IRustEngineSyncState;
|
|
623
|
+
private _markSnapshotLoaded;
|
|
624
|
+
private _markDependenciesInvalidated;
|
|
602
625
|
private _nativeReady;
|
|
603
626
|
private _snapshotLoaded;
|
|
604
627
|
private _projectionLoadPromise;
|
|
@@ -627,7 +650,11 @@ declare class RustEngineSyncController extends Disposable {
|
|
|
627
650
|
private _queueOrSyncMutation;
|
|
628
651
|
private _flushPendingMutations;
|
|
629
652
|
private _syncMutation;
|
|
630
|
-
|
|
653
|
+
/**
|
|
654
|
+
* Marks the native projection as out of sync so the next mutation reloads it.
|
|
655
|
+
* Also used by the projection controller when a background projection load fails.
|
|
656
|
+
*/
|
|
657
|
+
markProjectionDesynced(): void;
|
|
631
658
|
private _shouldSyncMutation;
|
|
632
659
|
private _serializeMutation;
|
|
633
660
|
}
|
|
@@ -940,4 +967,4 @@ interface IMaterializationCalculationStats {
|
|
|
940
967
|
}
|
|
941
968
|
declare function materializeWorkbookSnapshot(workbook: IWorkbookData, unitID: string, rev: number, dirtyInput?: IRustFormulaDependencyDirtyInput): Promise<IMaterializedWorkbookSnapshot>;
|
|
942
969
|
//#endregion
|
|
943
|
-
export { type IAnalyzeNumberFormatBatchInput, type IAnalyzeNumberFormatBatchOutput, ICellValue, ICycleDependencyInfo, IDefinedName, IExecutionError, type IFormatNumberBatchInput, type IFormatNumberBatchOutput, type IFormulaCalculationError, type IFormulaCalculationPatch, IFormulaEngineConfig, IFormulaExecutionInput, IFormulaExecutionOutput, type IFormulaProjectionDesyncSignal, type IMaterializationCalculationStats, type IMaterializedWorkbookSnapshot, type INumberFormatAnalysis, type INumberFormatDiagnostic, type INumberFormatOptions, type IObjectArrayPrimitiveType, type IObjectMatrixPrimitiveType, type IParseNumberFormatBatchInput, type IParseNumberFormatBatchOutput, type IParseNumberFormatMatrixBatchInput, type IParseNumberFormatMatrixBatchOutput, type IParseNumberFormatMatrixCell, type IParsedNumberFormatMatrixValue, type IParsedNumberFormatValue, IRange, IRustCalculateFormulaService, IRustDefinedNameSnapshot, IRustDependencyCalculationPlanItem, IRustDependencyCalculationTree, IRustDependencyCell, IRustDependencyDirtyResult, IRustDependencyGraph, IRustDependencyNode, IRustDependencyRange, IRustEngineModelStats, IRustEngineMutation, IRustEngineSnapshot, IRustExternalFeatureCalculation, IRustExternalLinkSnapshot, IRustExternalOtherFormula, IRustExternalSheetSnapshot, IRustFormulaDataItem, IRustFormulaDependencyClearInput, IRustFormulaDependencyDirtyInput, IRustFormulaDependencyDirtyOutput, IRustFormulaDependencyExecutionOutput, IRustFormulaDependencyInspectGraph, IRustFormulaDependencyInspectNode, IRustFormulaDependencyNodeOutput, IRustFormulaDependencySyncInput, IRustFormulaDependencySyncOutput, type IRustFormulaProjectionLoadResult, type IRustFormulaProjectionMutationResult, IRustFormulaStoreState, type IRustProjectionWorkbookInput, IRustResourceSnapshot, IRustSheetSnapshot, IRustSheetState, IRustTableSnapshot, IRustVisibilityData, IRustWorkbookCalculationSnapshot, IRustWorkbookSnapshot, ISheetData, IUnitRange, type IUniverRustFormulaEngineConfig, type NumberFormatDateSystem, RUST_FORMULA_RELEVANT_MUTATIONS, RUST_INCREMENTAL_DEPENDENCY_MUTATIONS, RUST_UPSERT_PROJECTION_WORKBOOK_MUTATION_ID, RUST_UPSERT_REFERENCE_DATA_MUTATION_ID, RustCalculateFormulaService, RustEngineSyncController, RustFormulaProjectionService, UniverRustFormulaEnginePlugin, analyzeNumberFormatBatch, applyMutationOnRust, buildLexerTreeOnRust, buildRustDependencyGraphOnRust, buildSequenceNodesOnRust, checkIfAddBracketOnRust, clearRustFormulaDependenciesOnRust, clearRustFormulaDirtyOnRust, createFormulaProjectionDesyncSignal, createProjectionWorkbookUpsertMutation, disposeAllWorkbooksOnRust, disposeWorkbookOnRust, executeOnRust, formatNumberBatch, getNativeBindingSource, getRustCellOnRust, getRustDirtyDependenciesOnRust, getRustFormulaDataOnRust, getRustModelStats, getRustSheetStateOnRust, isRustFormulaRelevantMutation, isRustIncrementalDependencyMutation, loadNativeBinding, loadSnapshotOnRust, markRustFormulaDirtyOnRust, materializeWorkbookSnapshot, materializeWorkbookSnapshotOnRust, parseNumberFormatBatch, parseNumberFormatMatrixBatch, rustExecutionOutputToFormulaCalculationPatch, serializeRuntimeWorkbookSnapshot, serializeRuntimeWorkbookSnapshots, syncRustFormulaDependenciesOnRust };
|
|
970
|
+
export { type IAnalyzeNumberFormatBatchInput, type IAnalyzeNumberFormatBatchOutput, ICellValue, ICycleDependencyInfo, IDefinedName, IExecutionError, type IFormatNumberBatchInput, type IFormatNumberBatchOutput, type IFormulaCalculationError, type IFormulaCalculationPatch, IFormulaEngineConfig, IFormulaExecutionInput, IFormulaExecutionOutput, type IFormulaProjectionDesyncSignal, type IMaterializationCalculationStats, type IMaterializedWorkbookSnapshot, type INativeFormulaEngine, type INumberFormatAnalysis, type INumberFormatDiagnostic, type INumberFormatOptions, type IObjectArrayPrimitiveType, type IObjectMatrixPrimitiveType, type IParseNumberFormatBatchInput, type IParseNumberFormatBatchOutput, type IParseNumberFormatMatrixBatchInput, type IParseNumberFormatMatrixBatchOutput, type IParseNumberFormatMatrixCell, type IParsedNumberFormatMatrixValue, type IParsedNumberFormatValue, IRange, IRustCalculateFormulaService, IRustDefinedNameSnapshot, IRustDependencyCalculationPlanItem, IRustDependencyCalculationTree, IRustDependencyCell, IRustDependencyDirtyResult, IRustDependencyGraph, IRustDependencyNode, IRustDependencyRange, IRustEngineModelStats, IRustEngineMutation, IRustEngineSnapshot, IRustExternalFeatureCalculation, IRustExternalLinkSnapshot, IRustExternalOtherFormula, IRustExternalSheetSnapshot, IRustFormulaDataItem, IRustFormulaDependencyClearInput, IRustFormulaDependencyDirtyInput, IRustFormulaDependencyDirtyOutput, IRustFormulaDependencyExecutionOutput, IRustFormulaDependencyInspectGraph, IRustFormulaDependencyInspectNode, IRustFormulaDependencyNodeOutput, IRustFormulaDependencySyncInput, IRustFormulaDependencySyncOutput, type IRustFormulaProjectionLoadResult, type IRustFormulaProjectionMutationResult, IRustFormulaStoreState, type IRustProjectionWorkbookInput, IRustResourceSnapshot, IRustSheetSnapshot, IRustSheetState, IRustTableSnapshot, IRustVisibilityData, IRustWorkbookCalculationSnapshot, IRustWorkbookSnapshot, ISheetData, IUnitRange, type IUniverRustFormulaEngineConfig, type NumberFormatDateSystem, RUST_FORMULA_RELEVANT_MUTATIONS, RUST_INCREMENTAL_DEPENDENCY_MUTATIONS, RUST_UPSERT_PROJECTION_WORKBOOK_MUTATION_ID, RUST_UPSERT_REFERENCE_DATA_MUTATION_ID, RustCalculateFormulaService, RustEngineSyncController, RustFormulaEngineSession, RustFormulaProjectionService, UniverRustFormulaEnginePlugin, analyzeNumberFormatBatch, applyMutationOnRust, buildLexerTreeOnRust, buildRustDependencyGraphOnRust, buildSequenceNodesOnRust, checkIfAddBracketOnRust, clearRustFormulaDependenciesOnRust, clearRustFormulaDirtyOnRust, createFormulaProjectionDesyncSignal, createProjectionWorkbookUpsertMutation, disposeAllWorkbooksOnRust, disposeWorkbookOnRust, executeOnRust, formatNumberBatch, getNativeBindingSource, getRustCellOnRust, getRustDirtyDependenciesOnRust, getRustFormulaDataOnRust, getRustModelStats, getRustSheetStateOnRust, isRustFormulaRelevantMutation, isRustIncrementalDependencyMutation, loadNativeBinding, loadSnapshotOnRust, markRustFormulaDirtyOnRust, materializeWorkbookSnapshot, materializeWorkbookSnapshotOnRust, parseNumberFormatBatch, parseNumberFormatMatrixBatch, rustExecutionOutputToFormulaCalculationPatch, serializeRuntimeWorkbookSnapshot, serializeRuntimeWorkbookSnapshots, syncRustFormulaDependenciesOnRust };
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"author": "DreamNum Co., Ltd. <developer@univer.ai>",
|
|
3
3
|
"dependencies": {
|
|
4
|
-
"@univerjs-pro/engine-formula": "1.0.
|
|
5
|
-
"@univerjs-pro/engine-formula-rust-binding": "1.0.
|
|
6
|
-
"@univerjs/core": "1.0.
|
|
7
|
-
"@univerjs/engine-formula": "1.0.
|
|
8
|
-
"@univerjs/protocol": "1.0.
|
|
4
|
+
"@univerjs-pro/engine-formula": "1.0.1",
|
|
5
|
+
"@univerjs-pro/engine-formula-rust-binding": "1.0.1",
|
|
6
|
+
"@univerjs/core": "1.0.1",
|
|
7
|
+
"@univerjs/engine-formula": "1.0.1",
|
|
8
|
+
"@univerjs/protocol": "1.0.1"
|
|
9
9
|
},
|
|
10
10
|
"description": "Rust-backed formula engine plugin for Univer",
|
|
11
11
|
"files": [
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"url": "https://github.com/dream-num/univer-rs"
|
|
21
21
|
},
|
|
22
22
|
"type": "module",
|
|
23
|
-
"version": "1.0.
|
|
23
|
+
"version": "1.0.1",
|
|
24
24
|
"main": "./lib/cjs/index.cjs",
|
|
25
25
|
"module": "./lib/es/index.js",
|
|
26
26
|
"types": "./lib/types/index.d.ts",
|