@bilig/headless 0.8.0 → 0.8.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.
Files changed (164) hide show
  1. package/README.md +15 -0
  2. package/dist/persistence.d.ts +1 -1
  3. package/dist/persistence.js +13 -11
  4. package/dist/persistence.js.map +1 -1
  5. package/dist/tracked-cell-index-changes.d.ts +1 -7
  6. package/dist/tracked-cell-index-changes.js +20 -434
  7. package/dist/tracked-cell-index-changes.js.map +1 -1
  8. package/dist/tracked-cell-lazy-physical-changes.d.ts +21 -0
  9. package/dist/tracked-cell-lazy-physical-changes.js +333 -0
  10. package/dist/tracked-cell-lazy-physical-changes.js.map +1 -0
  11. package/dist/tracked-cell-value-read.d.ts +18 -0
  12. package/dist/tracked-cell-value-read.js +46 -0
  13. package/dist/tracked-cell-value-read.js.map +1 -0
  14. package/dist/tracked-engine-event-refs.d.ts +1 -1
  15. package/dist/tracked-engine-event-refs.js +14 -4
  16. package/dist/tracked-engine-event-refs.js.map +1 -1
  17. package/dist/tracked-index-source-order.d.ts +5 -0
  18. package/dist/tracked-index-source-order.js +15 -0
  19. package/dist/tracked-index-source-order.js.map +1 -0
  20. package/dist/work-paper-address-format.d.ts +33 -0
  21. package/dist/work-paper-address-format.js +116 -0
  22. package/dist/work-paper-address-format.js.map +1 -0
  23. package/dist/work-paper-axis-helpers.d.ts +26 -0
  24. package/dist/work-paper-axis-helpers.js +104 -0
  25. package/dist/work-paper-axis-helpers.js.map +1 -0
  26. package/dist/work-paper-capability-checks.d.ts +17 -0
  27. package/dist/work-paper-capability-checks.js +101 -0
  28. package/dist/work-paper-capability-checks.js.map +1 -0
  29. package/dist/work-paper-capability-operations.d.ts +34 -0
  30. package/dist/work-paper-capability-operations.js +70 -0
  31. package/dist/work-paper-capability-operations.js.map +1 -0
  32. package/dist/work-paper-capability-surface.d.ts +97 -0
  33. package/dist/work-paper-capability-surface.js +236 -0
  34. package/dist/work-paper-capability-surface.js.map +1 -0
  35. package/dist/work-paper-cell-content-setter.d.ts +37 -0
  36. package/dist/work-paper-cell-content-setter.js +87 -0
  37. package/dist/work-paper-cell-content-setter.js.map +1 -0
  38. package/dist/work-paper-cell-mutation-refs.d.ts +23 -0
  39. package/dist/work-paper-cell-mutation-refs.js +50 -0
  40. package/dist/work-paper-cell-mutation-refs.js.map +1 -0
  41. package/dist/work-paper-cell-read.d.ts +41 -0
  42. package/dist/work-paper-cell-read.js +54 -0
  43. package/dist/work-paper-cell-read.js.map +1 -0
  44. package/dist/work-paper-clipboard-operations.d.ts +24 -0
  45. package/dist/work-paper-clipboard-operations.js +56 -0
  46. package/dist/work-paper-clipboard-operations.js.map +1 -0
  47. package/dist/work-paper-clipboard.d.ts +13 -0
  48. package/dist/work-paper-clipboard.js +19 -0
  49. package/dist/work-paper-clipboard.js.map +1 -0
  50. package/dist/work-paper-config.d.ts +11 -0
  51. package/dist/work-paper-config.js +247 -0
  52. package/dist/work-paper-config.js.map +1 -0
  53. package/dist/work-paper-date-time.d.ts +4 -0
  54. package/dist/work-paper-date-time.js +38 -0
  55. package/dist/work-paper-date-time.js.map +1 -0
  56. package/dist/work-paper-dependency-refs.d.ts +11 -0
  57. package/dist/work-paper-dependency-refs.js +74 -0
  58. package/dist/work-paper-dependency-refs.js.map +1 -0
  59. package/dist/work-paper-emitter.d.ts +22 -0
  60. package/dist/work-paper-emitter.js +130 -0
  61. package/dist/work-paper-emitter.js.map +1 -0
  62. package/dist/work-paper-engine-event-tracker.d.ts +24 -0
  63. package/dist/work-paper-engine-event-tracker.js +92 -0
  64. package/dist/work-paper-engine-event-tracker.js.map +1 -0
  65. package/dist/work-paper-errors.d.ts +4 -0
  66. package/dist/work-paper-errors.js +7 -0
  67. package/dist/work-paper-errors.js.map +1 -1
  68. package/dist/work-paper-existing-numeric-fast-path.d.ts +31 -0
  69. package/dist/work-paper-existing-numeric-fast-path.js +120 -0
  70. package/dist/work-paper-existing-numeric-fast-path.js.map +1 -0
  71. package/dist/work-paper-fill-helpers.d.ts +8 -0
  72. package/dist/work-paper-fill-helpers.js +34 -0
  73. package/dist/work-paper-fill-helpers.js.map +1 -0
  74. package/dist/work-paper-formula-analysis.d.ts +18 -0
  75. package/dist/work-paper-formula-analysis.js +54 -0
  76. package/dist/work-paper-formula-analysis.js.map +1 -0
  77. package/dist/work-paper-formula-rewrite.d.ts +22 -0
  78. package/dist/work-paper-formula-rewrite.js +71 -0
  79. package/dist/work-paper-formula-rewrite.js.map +1 -0
  80. package/dist/work-paper-function-registry.d.ts +39 -0
  81. package/dist/work-paper-function-registry.js +66 -0
  82. package/dist/work-paper-function-registry.js.map +1 -0
  83. package/dist/work-paper-history-operations.d.ts +15 -0
  84. package/dist/work-paper-history-operations.js +14 -0
  85. package/dist/work-paper-history-operations.js.map +1 -0
  86. package/dist/work-paper-history.d.ts +50 -0
  87. package/dist/work-paper-history.js +136 -0
  88. package/dist/work-paper-history.js.map +1 -0
  89. package/dist/work-paper-internals.d.ts +24 -0
  90. package/dist/work-paper-internals.js +59 -0
  91. package/dist/work-paper-internals.js.map +1 -0
  92. package/dist/work-paper-literal-mutation-queue.d.ts +18 -0
  93. package/dist/work-paper-literal-mutation-queue.js +40 -0
  94. package/dist/work-paper-literal-mutation-queue.js.map +1 -0
  95. package/dist/work-paper-matrix-application.d.ts +31 -0
  96. package/dist/work-paper-matrix-application.js +85 -0
  97. package/dist/work-paper-matrix-application.js.map +1 -0
  98. package/dist/work-paper-mutation-queues.d.ts +29 -0
  99. package/dist/work-paper-mutation-queues.js +72 -0
  100. package/dist/work-paper-mutation-queues.js.map +1 -0
  101. package/dist/work-paper-named-expression-fast-path.d.ts +37 -0
  102. package/dist/work-paper-named-expression-fast-path.js +100 -0
  103. package/dist/work-paper-named-expression-fast-path.js.map +1 -0
  104. package/dist/work-paper-named-expression-helpers.d.ts +54 -0
  105. package/dist/work-paper-named-expression-helpers.js +179 -0
  106. package/dist/work-paper-named-expression-helpers.js.map +1 -0
  107. package/dist/work-paper-named-expression-operations.d.ts +39 -0
  108. package/dist/work-paper-named-expression-operations.js +82 -0
  109. package/dist/work-paper-named-expression-operations.js.map +1 -0
  110. package/dist/work-paper-public-surface.d.ts +73 -0
  111. package/dist/work-paper-public-surface.js +165 -0
  112. package/dist/work-paper-public-surface.js.map +1 -0
  113. package/dist/work-paper-read-operations.d.ts +52 -0
  114. package/dist/work-paper-read-operations.js +185 -0
  115. package/dist/work-paper-read-operations.js.map +1 -0
  116. package/dist/work-paper-runtime-adapters.d.ts +144 -0
  117. package/dist/work-paper-runtime-adapters.js +256 -0
  118. package/dist/work-paper-runtime-adapters.js.map +1 -0
  119. package/dist/work-paper-runtime-helpers.d.ts +27 -0
  120. package/dist/work-paper-runtime-helpers.js +305 -0
  121. package/dist/work-paper-runtime-helpers.js.map +1 -0
  122. package/dist/work-paper-runtime-surface.d.ts +137 -0
  123. package/dist/work-paper-runtime-surface.js +702 -0
  124. package/dist/work-paper-runtime-surface.js.map +1 -0
  125. package/dist/work-paper-runtime.d.ts +56 -285
  126. package/dist/work-paper-runtime.js +403 -4809
  127. package/dist/work-paper-runtime.js.map +1 -1
  128. package/dist/work-paper-scratch-evaluator.js +29 -26
  129. package/dist/work-paper-scratch-evaluator.js.map +1 -1
  130. package/dist/work-paper-sheet-dimension-cache.d.ts +36 -0
  131. package/dist/work-paper-sheet-dimension-cache.js +158 -0
  132. package/dist/work-paper-sheet-dimension-cache.js.map +1 -0
  133. package/dist/work-paper-sheet-initialization.d.ts +19 -0
  134. package/dist/work-paper-sheet-initialization.js +93 -0
  135. package/dist/work-paper-sheet-initialization.js.map +1 -0
  136. package/dist/work-paper-sheet-inspection.d.ts +66 -0
  137. package/dist/work-paper-sheet-inspection.js +204 -0
  138. package/dist/work-paper-sheet-inspection.js.map +1 -0
  139. package/dist/work-paper-sheet-operations.d.ts +59 -0
  140. package/dist/work-paper-sheet-operations.js +104 -0
  141. package/dist/work-paper-sheet-operations.js.map +1 -0
  142. package/dist/work-paper-sheet-read.d.ts +21 -0
  143. package/dist/work-paper-sheet-read.js +32 -0
  144. package/dist/work-paper-sheet-read.js.map +1 -0
  145. package/dist/work-paper-sheet-rename-fast-path.d.ts +18 -0
  146. package/dist/work-paper-sheet-rename-fast-path.js +43 -0
  147. package/dist/work-paper-sheet-rename-fast-path.js.map +1 -0
  148. package/dist/work-paper-static-api.d.ts +18 -0
  149. package/dist/work-paper-static-api.js +44 -0
  150. package/dist/work-paper-static-api.js.map +1 -0
  151. package/dist/work-paper-static-registry.d.ts +21 -0
  152. package/dist/work-paper-static-registry.js +150 -0
  153. package/dist/work-paper-static-registry.js.map +1 -0
  154. package/dist/work-paper-tracked-change-reducer.d.ts +41 -0
  155. package/dist/work-paper-tracked-change-reducer.js +281 -0
  156. package/dist/work-paper-tracked-change-reducer.js.map +1 -0
  157. package/dist/work-paper-tracked-event-helpers.d.ts +89 -0
  158. package/dist/work-paper-tracked-event-helpers.js +366 -0
  159. package/dist/work-paper-tracked-event-helpers.js.map +1 -0
  160. package/dist/work-paper-types.d.ts +6 -5
  161. package/dist/work-paper-visibility-snapshot.d.ts +36 -0
  162. package/dist/work-paper-visibility-snapshot.js +62 -0
  163. package/dist/work-paper-visibility-snapshot.js.map +1 -0
  164. package/package.json +13 -5
@@ -0,0 +1,702 @@
1
+ import { formatAddress } from '@bilig/formula';
2
+ import { assertRange, isCellRange } from './work-paper-runtime-helpers.js';
3
+ import { formatTrackedA1, sourceRangeRef } from './work-paper-address-format.js';
4
+ import { clearWorkPaperHistoryStacks, mergeWorkPaperUndoHistory, readWorkPaperHistoryStack, } from './work-paper-history.js';
5
+ import { WorkPaperEvaluationSuspendedError, WorkPaperNoOperationToRedoError, WorkPaperNoOperationToUndoError, WorkPaperNoSheetWithIdError, WorkPaperNoSheetWithNameError, WorkPaperOperationError, } from './work-paper-errors.js';
6
+ import { captureWorkPaperNamedExpressionValueSnapshot, computeWorkPaperNamedExpressionChanges, } from './work-paper-named-expression-helpers.js';
7
+ import { applyWorkPaperHistoryOperation } from './work-paper-history-operations.js';
8
+ import { applyWorkPaperCellMutationRefs } from './work-paper-cell-mutation-refs.js';
9
+ import { materializeTrackedIndexChangeSourcesWithMetadata, materializeTrackedIndexChangesWithMetadata, } from './tracked-cell-index-changes.js';
10
+ import { collectWorkPaperRangeDependencies, toWorkPaperDependencyRefs } from './work-paper-dependency-refs.js';
11
+ import { captureWorkPaperVisibilitySnapshot, computeWorkPaperCellChangesFromVisibilitySnapshots, } from './work-paper-visibility-snapshot.js';
12
+ import { computeWorkPaperTrackedCellChangesFromEvents, tryReadTinyTrackedEventChangesWithoutVisibility as tryReadTinyTrackedEventChangesWithoutVisibilityFromReducer, } from './work-paper-tracked-change-reducer.js';
13
+ import { TINY_TRACKED_CHANGE_LIMIT, readTrackedCellChange, readTrustedPhysicalTrackedChangeMetadata, readTinySortedPhysicalTrackedEventChanges as readTinySortedPhysicalTrackedEventChangesFromStore, trackedEventHasNoValueChanges, tryBuildDirectSingleLiteralTrackedChange, withEventChanges, } from './work-paper-tracked-event-helpers.js';
14
+ import { tryRenameWorkPaperSheetWithoutVisibilitySnapshots } from './work-paper-sheet-rename-fast-path.js';
15
+ import { WORKPAPER_PUBLIC_ERROR_NAMES } from './work-paper-config.js';
16
+ import { WorkPaperPublicSurface } from './work-paper-public-surface.js';
17
+ export const EMPTY_NAMED_EXPRESSION_VALUES = new Map();
18
+ export class WorkPaperRuntimeSurface extends WorkPaperPublicSurface {
19
+ getStats() {
20
+ this.assertNotDisposed();
21
+ return {
22
+ batchDepth: this.batchDepth,
23
+ evaluationSuspended: this.evaluationSuspended,
24
+ lastMetrics: structuredClone(this.engine.getLastMetrics()),
25
+ };
26
+ }
27
+ rebuildAndRecalculate() {
28
+ this.assertNotDisposed();
29
+ this.engineEvents.materializePendingLazyChanges();
30
+ if (this.shouldSuppressEvents()) {
31
+ try {
32
+ this.engine.recalculateNow();
33
+ this.sheetDimensionCache.invalidateAll();
34
+ }
35
+ catch (error) {
36
+ throw new WorkPaperOperationError(this.messageOf(error, 'Recalculation failed'));
37
+ }
38
+ return [];
39
+ }
40
+ const beforeVisibility = this.ensureVisibilityCache();
41
+ const beforeNames = this.namedExpressions.size > 0 ? this.ensureNamedExpressionValueCache() : EMPTY_NAMED_EXPRESSION_VALUES;
42
+ this.engineEvents.drain();
43
+ try {
44
+ this.engine.recalculateNow();
45
+ this.sheetDimensionCache.invalidateAll();
46
+ }
47
+ catch (error) {
48
+ throw new WorkPaperOperationError(this.messageOf(error, 'Recalculation failed'));
49
+ }
50
+ const afterVisibility = this.captureVisibilitySnapshot();
51
+ const afterNames = this.namedExpressions.size > 0 ? this.captureNamedExpressionValueSnapshot() : EMPTY_NAMED_EXPRESSION_VALUES;
52
+ this.visibilityCache = afterVisibility;
53
+ this.namedExpressionValueCache = afterNames;
54
+ const changes = [
55
+ ...this.computeCellChanges(beforeVisibility, afterVisibility),
56
+ ...this.computeNamedExpressionChanges(beforeNames, afterNames),
57
+ ];
58
+ if (changes.length > 0 && this.emitter.hasListeners('valuesUpdated')) {
59
+ this.emitter.emitDetailed({ eventName: 'valuesUpdated', payload: { changes } });
60
+ }
61
+ return changes;
62
+ }
63
+ batch(batchOperations) {
64
+ this.assertNotDisposed();
65
+ this.engineEvents.materializePendingLazyChanges();
66
+ const isOutermost = this.batchDepth === 0;
67
+ if (isOutermost) {
68
+ this.batchUsesTrackedFastPath = this.canUseTrackedMutationFastPath();
69
+ if (this.batchUsesTrackedFastPath) {
70
+ this.batchStartVisibility = null;
71
+ this.batchStartNamedValues = EMPTY_NAMED_EXPRESSION_VALUES;
72
+ }
73
+ else {
74
+ this.batchStartVisibility = this.ensureVisibilityCache();
75
+ this.batchStartNamedValues = this.ensureNamedExpressionValueCache();
76
+ }
77
+ this.batchUndoStackLength = this.getUndoStack().length;
78
+ this.engineEvents.drain();
79
+ }
80
+ this.batchDepth += 1;
81
+ try {
82
+ batchOperations();
83
+ }
84
+ finally {
85
+ this.batchDepth -= 1;
86
+ if (isOutermost) {
87
+ if (this.batchUsesTrackedFastPath) {
88
+ this.engineEvents.withRetainedIndices(() => {
89
+ this.flushPendingBatchOps();
90
+ });
91
+ }
92
+ else {
93
+ this.flushPendingBatchOps();
94
+ }
95
+ this.mergeUndoHistory(this.batchUndoStackLength);
96
+ }
97
+ }
98
+ if (!isOutermost) {
99
+ return [];
100
+ }
101
+ const shouldEmitValuesUpdated = this.emitter.hasListeners('valuesUpdated');
102
+ const changes = this.batchUsesTrackedFastPath
103
+ ? this.computeTrackedChangesWithoutVisibilityCache(this.engineEvents.drain(), {
104
+ preferLazyPublicChanges: !shouldEmitValuesUpdated,
105
+ })
106
+ : this.computeChangesAfterMutation(this.batchStartVisibility ?? new Map(), this.batchStartNamedValues ?? new Map());
107
+ this.batchUsesTrackedFastPath = false;
108
+ this.batchStartVisibility = null;
109
+ this.batchStartNamedValues = null;
110
+ if (!this.evaluationSuspended) {
111
+ this.flushQueuedEvents();
112
+ if (changes.length > 0 && shouldEmitValuesUpdated) {
113
+ this.emitter.emitDetailed({ eventName: 'valuesUpdated', payload: { changes } });
114
+ }
115
+ }
116
+ return changes;
117
+ }
118
+ suspendEvaluation() {
119
+ this.assertNotDisposed();
120
+ this.engineEvents.materializePendingLazyChanges();
121
+ if (this.evaluationSuspended) {
122
+ return;
123
+ }
124
+ this.evaluationSuspended = true;
125
+ this.flushPendingBatchOps();
126
+ if (this.visibilityCache === null && this.namedExpressions.size === 0) {
127
+ this.suspendedVisibility = null;
128
+ this.suspendedNamedValues = EMPTY_NAMED_EXPRESSION_VALUES;
129
+ this.suspendedUsesTrackedFastPath = true;
130
+ }
131
+ else {
132
+ this.suspendedVisibility = this.ensureVisibilityCache();
133
+ this.suspendedNamedValues = this.ensureNamedExpressionValueCache();
134
+ this.suspendedUsesTrackedFastPath = false;
135
+ }
136
+ this.engineEvents.drain();
137
+ this.emitter.emitDetailed({ eventName: 'evaluationSuspended', payload: {} });
138
+ }
139
+ resumeEvaluation() {
140
+ this.assertNotDisposed();
141
+ this.engineEvents.materializePendingLazyChanges();
142
+ if (!this.evaluationSuspended) {
143
+ return [];
144
+ }
145
+ if (this.suspendedUsesTrackedFastPath) {
146
+ this.engineEvents.withRetainedIndices(() => {
147
+ this.flushSuspendedCellMutations();
148
+ });
149
+ }
150
+ else {
151
+ this.flushSuspendedCellMutations();
152
+ }
153
+ const shouldEmitValuesUpdated = this.emitter.hasListeners('valuesUpdated');
154
+ const changes = this.suspendedUsesTrackedFastPath
155
+ ? this.computeTrackedChangesWithoutVisibilityCache(this.engineEvents.drain(), {
156
+ preferLazyPublicChanges: !shouldEmitValuesUpdated,
157
+ })
158
+ : this.computeChangesAfterMutation(this.suspendedVisibility ?? new Map(), this.suspendedNamedValues ?? new Map());
159
+ this.evaluationSuspended = false;
160
+ this.suspendedVisibility = null;
161
+ this.suspendedNamedValues = null;
162
+ this.suspendedUsesTrackedFastPath = false;
163
+ this.flushQueuedEvents();
164
+ this.emitter.emitDetailed({ eventName: 'evaluationResumed', payload: { changes } });
165
+ if (changes.length > 0 && shouldEmitValuesUpdated) {
166
+ this.emitter.emitDetailed({ eventName: 'valuesUpdated', payload: { changes } });
167
+ }
168
+ return changes;
169
+ }
170
+ isEvaluationSuspended() {
171
+ return this.evaluationSuspended;
172
+ }
173
+ undo() {
174
+ this.assertNotDisposed();
175
+ return this.applyHistoryOperation('undo');
176
+ }
177
+ redo() {
178
+ this.assertNotDisposed();
179
+ return this.applyHistoryOperation('redo');
180
+ }
181
+ isThereSomethingToUndo() {
182
+ return this.getUndoStack().length > 0;
183
+ }
184
+ isThereSomethingToRedo() {
185
+ return this.getRedoStack().length > 0;
186
+ }
187
+ clearUndoStack() {
188
+ this.getUndoStack().length = 0;
189
+ }
190
+ clearRedoStack() {
191
+ this.getRedoStack().length = 0;
192
+ }
193
+ getCellDependents(address) {
194
+ this.flushPendingBatchOps();
195
+ if (!isCellRange(address)) {
196
+ return this.toDependencyRefs(this.engine.getDependents(this.sheetName(address.sheet), this.a1(address)).directDependents);
197
+ }
198
+ return this.collectRangeDependencies(address, (cellAddress) => this.engine.getDependents(this.sheetName(cellAddress.sheet), this.a1(cellAddress)).directDependents);
199
+ }
200
+ getCellPrecedents(address) {
201
+ this.flushPendingBatchOps();
202
+ if (!isCellRange(address)) {
203
+ return this.getDirectPrecedentRefs(address);
204
+ }
205
+ return this.collectRangeDependencies(address, (cellAddress) => this.getDirectPrecedentStrings(cellAddress));
206
+ }
207
+ getSheetName(sheetId) {
208
+ return this.engine.workbook.getSheetById(sheetId)?.name;
209
+ }
210
+ getSheetNames() {
211
+ return this.listSheetRecords().map((sheet) => sheet.name);
212
+ }
213
+ getSheetId(name) {
214
+ return this.engine.workbook.getSheet(name)?.id;
215
+ }
216
+ doesSheetExist(name) {
217
+ return this.engine.workbook.getSheet(name) !== undefined;
218
+ }
219
+ countSheets() {
220
+ return this.listSheetRecords().length;
221
+ }
222
+ moveCells(source, target) {
223
+ if (!this.isItPossibleToMoveCells(source, target)) {
224
+ throw new WorkPaperOperationError('Cells cannot be moved');
225
+ }
226
+ const sourceHeight = source.end.row - source.start.row;
227
+ const sourceWidth = source.end.col - source.start.col;
228
+ return this.captureChanges(undefined, () => {
229
+ this.engine.moveRange(sourceRangeRef(this.sheetName(source.start.sheet), source), {
230
+ sheetName: this.sheetName(target.sheet),
231
+ startAddress: formatAddress(target.row, target.col),
232
+ endAddress: formatAddress(target.row + sourceHeight, target.col + sourceWidth),
233
+ });
234
+ this.sheetDimensionCache.invalidate(source.start.sheet);
235
+ this.sheetDimensionCache.invalidate(target.sheet);
236
+ });
237
+ }
238
+ applyHistoryOperation(kind) {
239
+ return applyWorkPaperHistoryOperation({
240
+ getStack: () => (kind === 'undo' ? this.getUndoStack() : this.getRedoStack()),
241
+ canUseTrackedMutationFastPath: () => this.canUseTrackedMutationFastPath(),
242
+ captureTrackedChangesWithoutVisibilityCache: (mutate, options) => this.captureTrackedChangesWithoutVisibilityCache(mutate, options),
243
+ captureChanges: (mutate, options) => this.captureChanges(undefined, mutate, options),
244
+ applyOperation: () => (kind === 'undo' ? this.engine.undo() : this.engine.redo()),
245
+ createMissingOperationError: () => (kind === 'undo' ? new WorkPaperNoOperationToUndoError() : new WorkPaperNoOperationToRedoError()),
246
+ invalidateAllSheetDimensions: () => this.sheetDimensionCache.invalidateAll(),
247
+ });
248
+ }
249
+ resetChangeTrackingCaches() {
250
+ this.sheetRecordsCache = null;
251
+ this.visibilityCache = null;
252
+ this.namedExpressionValueCache = null;
253
+ this.engineEvents.clearEvents();
254
+ }
255
+ ensureVisibilityCache() {
256
+ if (!this.visibilityCache) {
257
+ this.visibilityCache = this.captureVisibilitySnapshot();
258
+ }
259
+ return this.visibilityCache;
260
+ }
261
+ ensureNamedExpressionValueCache() {
262
+ if (!this.namedExpressionValueCache) {
263
+ this.namedExpressionValueCache =
264
+ this.namedExpressions.size > 0 ? this.captureNamedExpressionValueSnapshot() : EMPTY_NAMED_EXPRESSION_VALUES;
265
+ }
266
+ return this.namedExpressionValueCache;
267
+ }
268
+ flushPendingBatchOps() {
269
+ this.mutationQueues.flushPendingBatchOps();
270
+ }
271
+ applyCellMutationRefs(refs, options) {
272
+ applyWorkPaperCellMutationRefs(this.runtimeAdapters.cellMutationApplyRuntime, refs, options);
273
+ }
274
+ flushSuspendedCellMutations() {
275
+ this.mutationQueues.flushSuspendedCellMutations();
276
+ }
277
+ enqueueSuspendedLiteralMutation(sheetId, row, col, content, cellIndex) {
278
+ return (this.evaluationSuspended &&
279
+ this.mutationQueues.enqueueSuspendedLiteralMutation({
280
+ sheetId,
281
+ row,
282
+ col,
283
+ content,
284
+ cellIndex,
285
+ }));
286
+ }
287
+ enqueueDeferredBatchLiteral(sheetId, row, col, content, cellIndex) {
288
+ return (this.batchDepth !== 0 &&
289
+ !this.evaluationSuspended &&
290
+ this.mutationQueues.enqueueDeferredBatchLiteral({
291
+ sheetId,
292
+ row,
293
+ col,
294
+ content,
295
+ cellIndex,
296
+ }));
297
+ }
298
+ prepareReadableState() {
299
+ this.assertNotDisposed();
300
+ this.flushPendingBatchOps();
301
+ }
302
+ assertNotDisposed() {
303
+ if (this.disposed) {
304
+ throw new WorkPaperOperationError('Workbook has been disposed');
305
+ }
306
+ }
307
+ assertReadable() {
308
+ this.prepareReadableState();
309
+ if (this.evaluationSuspended) {
310
+ throw new WorkPaperEvaluationSuspendedError();
311
+ }
312
+ }
313
+ sheetRecord(sheetId) {
314
+ const sheet = this.engine.workbook.getSheetById(sheetId);
315
+ if (!sheet) {
316
+ throw new WorkPaperNoSheetWithIdError(sheetId);
317
+ }
318
+ return sheet;
319
+ }
320
+ sheetName(sheetId) {
321
+ return this.sheetRecord(sheetId).name;
322
+ }
323
+ capabilityContext() {
324
+ return {
325
+ config: this.config,
326
+ requireSheet: (sheetId) => {
327
+ void this.sheetRecord(sheetId);
328
+ },
329
+ doesSheetExist: (sheetName) => this.doesSheetExist(sheetName),
330
+ getSheetIdByName: (sheetName) => this.getSheetId(sheetName),
331
+ };
332
+ }
333
+ requireSheetId(name) {
334
+ const sheetId = this.getSheetId(name);
335
+ if (sheetId === undefined) {
336
+ throw new WorkPaperNoSheetWithNameError(name);
337
+ }
338
+ return sheetId;
339
+ }
340
+ a1(address) {
341
+ return formatAddress(address.row, address.col);
342
+ }
343
+ trackedA1(row, col) {
344
+ return formatTrackedA1(row, col);
345
+ }
346
+ rangeRef(range) {
347
+ assertRange(range);
348
+ return sourceRangeRef(this.sheetName(range.start.sheet), range);
349
+ }
350
+ getDirectPrecedentStrings(address) {
351
+ const precedents = new Set(this.engine.getDependencies(this.sheetName(address.sheet), this.a1(address)).directPrecedents);
352
+ const formula = this.getCellFormula(address);
353
+ if (formula) {
354
+ this.getNamedExpressionsFromFormula(formula).forEach((name) => {
355
+ precedents.add(name);
356
+ });
357
+ }
358
+ return [...precedents];
359
+ }
360
+ getDirectPrecedentRefs(address) {
361
+ return this.toDependencyRefs(this.getDirectPrecedentStrings(address));
362
+ }
363
+ listSheetRecords() {
364
+ if (this.sheetRecordsCache) {
365
+ return this.sheetRecordsCache;
366
+ }
367
+ this.sheetRecordsCache = [...this.engine.workbook.sheetsByName.values()].toSorted((left, right) => left.order - right.order || left.name.localeCompare(right.name));
368
+ return this.sheetRecordsCache;
369
+ }
370
+ captureVisibilitySnapshot() {
371
+ return captureWorkPaperVisibilitySnapshot({
372
+ sheets: this.listSheetRecords(),
373
+ cellStore: this.engine.workbook.cellStore,
374
+ strings: this.engine.strings,
375
+ });
376
+ }
377
+ captureNamedExpressionValueSnapshot() {
378
+ if (this.namedExpressions.size === 0) {
379
+ return EMPTY_NAMED_EXPRESSION_VALUES;
380
+ }
381
+ return captureWorkPaperNamedExpressionValueSnapshot(this.namedExpressions.values(), (expression) => this.evaluateNamedExpression(expression));
382
+ }
383
+ computeCellChanges(beforeVisibility, afterVisibility) {
384
+ return computeWorkPaperCellChangesFromVisibilitySnapshots({
385
+ beforeVisibility,
386
+ afterVisibility,
387
+ sheets: this.listSheetRecords(),
388
+ });
389
+ }
390
+ materializeTrackedEventChanges(event, lazy = false) {
391
+ if (event.patches && event.patches.length > 0) {
392
+ const cellPatches = event.patches.filter((patch) => patch.kind === 'cell');
393
+ return { changes: cellPatches, canReusePublicChanges: false, ordered: false };
394
+ }
395
+ const trustedPhysicalMetadata = lazy && event.changedCellIndices instanceof Uint32Array
396
+ ? readTrustedPhysicalTrackedChangeMetadata(event.changedCellIndices)
397
+ : undefined;
398
+ const materialized = materializeTrackedIndexChangesWithMetadata(this.engine, event.changedCellIndices, {
399
+ lazy,
400
+ ...(event.explicitChangedCount !== undefined ? { explicitChangedCount: event.explicitChangedCount } : {}),
401
+ ...trustedPhysicalMetadata,
402
+ });
403
+ if (lazy) {
404
+ this.engineEvents.trackLazyChanges(materialized.changes);
405
+ }
406
+ return {
407
+ changes: materialized.changes,
408
+ canReusePublicChanges: true,
409
+ ordered: materialized.ordered,
410
+ };
411
+ }
412
+ readSingleTrackedCellChange(cellIndex) {
413
+ return readTrackedCellChange({
414
+ cellIndex,
415
+ workbook: this.engine.workbook,
416
+ strings: this.engine.strings,
417
+ trackedA1: (row, col) => this.trackedA1(row, col),
418
+ });
419
+ }
420
+ readTinySortedPhysicalTrackedEventChanges(event) {
421
+ return readTinySortedPhysicalTrackedEventChangesFromStore({
422
+ event,
423
+ workbook: this.engine.workbook,
424
+ strings: this.engine.strings,
425
+ trackedA1: (row, col) => this.trackedA1(row, col),
426
+ });
427
+ }
428
+ tryReadTinyTrackedEventChangesWithoutVisibility(event) {
429
+ return tryReadTinyTrackedEventChangesWithoutVisibilityFromReducer({
430
+ event,
431
+ listSheets: () => this.listSheetRecords(),
432
+ materializeTrackedEventChanges: (trackedEvent, lazy) => this.materializeTrackedEventChanges(trackedEvent, lazy),
433
+ readSingleTrackedCellChange: (cellIndex) => this.readSingleTrackedCellChange(cellIndex),
434
+ readTinySortedPhysicalTrackedEventChanges: (trackedEvent) => this.readTinySortedPhysicalTrackedEventChanges(trackedEvent),
435
+ sheetOrder: (sheetId) => this.sheetRecord(sheetId).order,
436
+ });
437
+ }
438
+ computeCellChangesFromTrackedEvents(beforeVisibility, events, updateVisibility = true, options = {}) {
439
+ return computeWorkPaperTrackedCellChangesFromEvents({
440
+ beforeVisibility,
441
+ events,
442
+ updateVisibility,
443
+ ...(options.preferLazyPublicChanges !== undefined ? { preferLazyPublicChanges: options.preferLazyPublicChanges } : {}),
444
+ listSheets: () => this.listSheetRecords(),
445
+ materializeTrackedEventChanges: (event, lazy) => this.materializeTrackedEventChanges(event, lazy),
446
+ materializeTrackedEventSources: (trackedEvents, sourceOptions) => {
447
+ const materializedSources = materializeTrackedIndexChangeSourcesWithMetadata(this.engine, trackedEvents, {
448
+ deferLazyDetach: true,
449
+ ...(sourceOptions.preferLazyPublicChanges !== undefined ? { lazy: sourceOptions.preferLazyPublicChanges } : {}),
450
+ });
451
+ if (!materializedSources) {
452
+ return null;
453
+ }
454
+ this.engineEvents.trackLazyChanges(materializedSources.changes);
455
+ return materializedSources;
456
+ },
457
+ readSingleTrackedCellChange: (cellIndex) => this.readSingleTrackedCellChange(cellIndex),
458
+ readTinySortedPhysicalTrackedEventChanges: (event) => this.readTinySortedPhysicalTrackedEventChanges(event),
459
+ sheetOrder: (sheetId) => this.sheetRecord(sheetId).order,
460
+ });
461
+ }
462
+ computeNamedExpressionChanges(beforeNames, afterNames) {
463
+ return computeWorkPaperNamedExpressionChanges({
464
+ beforeNames,
465
+ afterNames,
466
+ expressionsByKey: this.namedExpressions,
467
+ });
468
+ }
469
+ canUseTrackedStructuralFastPath() {
470
+ return this.batchDepth === 0 && !this.evaluationSuspended && this.visibilityCache === null && this.namedExpressions.size === 0;
471
+ }
472
+ canUseTrackedMutationFastPath() {
473
+ return this.batchDepth === 0 && !this.evaluationSuspended && this.visibilityCache === null && this.namedExpressions.size === 0;
474
+ }
475
+ canUseNamedExpressionChangeFastPath() {
476
+ return this.batchDepth === 0 && !this.evaluationSuspended && this.visibilityCache === null && !this.emitter.hasAnyListeners();
477
+ }
478
+ canUseMetadataOnlySheetRenameFastPath() {
479
+ return this.batchDepth === 0 && !this.evaluationSuspended && this.visibilityCache === null && !this.emitter.hasAnyListeners();
480
+ }
481
+ downgradeTrackedBatchFastPath() {
482
+ if (!this.batchUsesTrackedFastPath || this.batchDepth === 0) {
483
+ return;
484
+ }
485
+ this.batchStartVisibility = this.ensureVisibilityCache();
486
+ this.batchStartNamedValues = this.namedExpressions.size > 0 ? this.ensureNamedExpressionValueCache() : EMPTY_NAMED_EXPRESSION_VALUES;
487
+ this.batchUsesTrackedFastPath = false;
488
+ }
489
+ computeTrackedChangesWithoutVisibilityCache(events, options = {}) {
490
+ if (events.length > 0 && events.every(trackedEventHasNoValueChanges)) {
491
+ return [];
492
+ }
493
+ if (events.length === 1) {
494
+ const event = events[0];
495
+ if (!options.preferLazyPublicChanges || event.changedCellIndices.length <= TINY_TRACKED_CHANGE_LIMIT) {
496
+ const tinyChanges = this.tryReadTinyTrackedEventChangesWithoutVisibility(event);
497
+ if (tinyChanges) {
498
+ return tinyChanges;
499
+ }
500
+ }
501
+ }
502
+ const fastPath = this.computeCellChangesFromTrackedEvents(new Map(), events, false, options);
503
+ if (!fastPath) {
504
+ throw new WorkPaperOperationError('Mutation emitted an unsupported invalidation pattern for tracked changes');
505
+ }
506
+ return fastPath.changes;
507
+ }
508
+ tryRenameSheetWithoutVisibilitySnapshots(oldName, newName) {
509
+ return tryRenameWorkPaperSheetWithoutVisibilitySnapshots(this.runtimeAdapters.sheetRenameFastPathRuntime, oldName, newName);
510
+ }
511
+ captureTrackedChangesWithoutVisibilityCache(mutate, options = {}) {
512
+ this.assertNotDisposed();
513
+ if (this.engineEvents.hasPendingLazyChanges) {
514
+ this.engineEvents.materializePendingLazyChanges(options.preservePendingTrackedPositions === undefined ? {} : { preservePositions: options.preservePendingTrackedPositions });
515
+ }
516
+ if (this.engineEvents.hasTrackedEvents) {
517
+ this.engineEvents.drain();
518
+ }
519
+ try {
520
+ this.engineEvents.withRetainedIndices(mutate);
521
+ }
522
+ catch (error) {
523
+ if (error instanceof Error && WORKPAPER_PUBLIC_ERROR_NAMES.has(error.name)) {
524
+ throw error;
525
+ }
526
+ throw new WorkPaperOperationError(this.messageOf(error, 'Mutation failed'));
527
+ }
528
+ const events = this.engineEvents.drain();
529
+ const directSingleLiteralChanges = tryBuildDirectSingleLiteralTrackedChange({
530
+ events,
531
+ ...(options.singleLiteralChange !== undefined ? { expected: options.singleLiteralChange } : {}),
532
+ cellStore: this.engine.workbook.cellStore,
533
+ strings: this.engine.strings,
534
+ trackedA1: (row, col) => this.trackedA1(row, col),
535
+ });
536
+ if (directSingleLiteralChanges) {
537
+ if (directSingleLiteralChanges.length > 0 && this.emitter.hasListeners('valuesUpdated')) {
538
+ this.emitter.emitDetailed({ eventName: 'valuesUpdated', payload: { changes: directSingleLiteralChanges } });
539
+ }
540
+ return directSingleLiteralChanges;
541
+ }
542
+ const shouldEmitValuesUpdated = this.emitter.hasListeners('valuesUpdated');
543
+ const changes = this.computeTrackedChangesWithoutVisibilityCache(events, {
544
+ preferLazyPublicChanges: !shouldEmitValuesUpdated,
545
+ });
546
+ if (changes.length > 0 && shouldEmitValuesUpdated) {
547
+ this.emitter.emitDetailed({ eventName: 'valuesUpdated', payload: { changes } });
548
+ }
549
+ return changes;
550
+ }
551
+ batchStructuralChanges(batchOperations) {
552
+ this.engineEvents.materializePendingLazyChanges();
553
+ if (!this.canUseTrackedStructuralFastPath()) {
554
+ this.downgradeTrackedBatchFastPath();
555
+ return this.batch(batchOperations);
556
+ }
557
+ this.assertNotDisposed();
558
+ const undoStackStart = this.getUndoStack().length;
559
+ this.engineEvents.drain();
560
+ this.batchDepth += 1;
561
+ try {
562
+ this.engineEvents.withRetainedIndices(batchOperations);
563
+ }
564
+ finally {
565
+ this.batchDepth -= 1;
566
+ this.flushPendingBatchOps();
567
+ this.mergeUndoHistory(undoStackStart);
568
+ }
569
+ const shouldEmitValuesUpdated = this.emitter.hasListeners('valuesUpdated');
570
+ const changes = this.computeTrackedChangesWithoutVisibilityCache(this.engineEvents.drain(), {
571
+ preferLazyPublicChanges: !shouldEmitValuesUpdated,
572
+ });
573
+ this.flushQueuedEvents();
574
+ if (changes.length > 0 && shouldEmitValuesUpdated) {
575
+ this.emitter.emitDetailed({ eventName: 'valuesUpdated', payload: { changes } });
576
+ }
577
+ return changes;
578
+ }
579
+ computeChangesAfterMutation(beforeVisibility, beforeNames) {
580
+ const hasNamedExpressions = this.namedExpressions.size > 0;
581
+ const afterNames = hasNamedExpressions ? this.captureNamedExpressionValueSnapshot() : EMPTY_NAMED_EXPRESSION_VALUES;
582
+ const fastPath = this.computeCellChangesFromTrackedEvents(beforeVisibility, this.engineEvents.drain());
583
+ let cellChanges;
584
+ if (fastPath) {
585
+ cellChanges = fastPath.changes;
586
+ this.visibilityCache = fastPath.nextVisibility;
587
+ }
588
+ else {
589
+ const afterVisibility = this.captureVisibilitySnapshot();
590
+ cellChanges = this.computeCellChanges(beforeVisibility, afterVisibility);
591
+ this.visibilityCache = afterVisibility;
592
+ }
593
+ this.namedExpressionValueCache = afterNames;
594
+ return hasNamedExpressions ? [...cellChanges, ...this.computeNamedExpressionChanges(beforeNames, afterNames)] : cellChanges;
595
+ }
596
+ captureChanges(semanticEvent, mutate, options = {}) {
597
+ this.assertNotDisposed();
598
+ this.engineEvents.materializePendingLazyChanges(options.preservePendingTrackedPositions === undefined ? {} : { preservePositions: options.preservePendingTrackedPositions });
599
+ this.downgradeTrackedBatchFastPath();
600
+ if (semanticEvent !== undefined) {
601
+ this.flushPendingBatchOps();
602
+ }
603
+ if (this.shouldSuppressEvents()) {
604
+ try {
605
+ mutate();
606
+ }
607
+ catch (error) {
608
+ if (error instanceof Error && WORKPAPER_PUBLIC_ERROR_NAMES.has(error.name)) {
609
+ throw error;
610
+ }
611
+ throw new WorkPaperOperationError(this.messageOf(error, 'Mutation failed'));
612
+ }
613
+ if (semanticEvent) {
614
+ this.queuedEvents.push(semanticEvent);
615
+ }
616
+ return [];
617
+ }
618
+ const beforeVisibility = this.ensureVisibilityCache();
619
+ const beforeNames = this.namedExpressions.size > 0 ? this.ensureNamedExpressionValueCache() : EMPTY_NAMED_EXPRESSION_VALUES;
620
+ this.engineEvents.drain();
621
+ try {
622
+ mutate();
623
+ }
624
+ catch (error) {
625
+ if (error instanceof Error && WORKPAPER_PUBLIC_ERROR_NAMES.has(error.name)) {
626
+ throw error;
627
+ }
628
+ throw new WorkPaperOperationError(this.messageOf(error, 'Mutation failed'));
629
+ }
630
+ const changes = semanticEvent === undefined
631
+ ? this.computeChangesAfterMutation(beforeVisibility, beforeNames)
632
+ : (() => {
633
+ const afterVisibility = this.captureVisibilitySnapshot();
634
+ const afterNames = this.captureNamedExpressionValueSnapshot();
635
+ this.visibilityCache = afterVisibility;
636
+ this.namedExpressionValueCache = afterNames;
637
+ return [
638
+ ...this.computeCellChanges(beforeVisibility, afterVisibility),
639
+ ...this.computeNamedExpressionChanges(beforeNames, afterNames),
640
+ ];
641
+ })();
642
+ if (semanticEvent) {
643
+ const event = withEventChanges(semanticEvent, changes);
644
+ if (this.shouldSuppressEvents()) {
645
+ this.queuedEvents.push(event);
646
+ }
647
+ else {
648
+ this.emitter.emitDetailed(event);
649
+ }
650
+ }
651
+ if (!this.shouldSuppressEvents() && changes.length > 0 && this.emitter.hasListeners('valuesUpdated')) {
652
+ this.emitter.emitDetailed({ eventName: 'valuesUpdated', payload: { changes } });
653
+ }
654
+ return changes;
655
+ }
656
+ shouldSuppressEvents() {
657
+ return this.batchDepth > 0 || this.evaluationSuspended;
658
+ }
659
+ flushQueuedEvents() {
660
+ const events = [...this.queuedEvents];
661
+ this.queuedEvents.length = 0;
662
+ events.forEach((event) => {
663
+ this.emitter.emitDetailed(event);
664
+ });
665
+ }
666
+ getUndoStack() {
667
+ return readWorkPaperHistoryStack(this.engine, 'undoStack');
668
+ }
669
+ getRedoStack() {
670
+ return readWorkPaperHistoryStack(this.engine, 'redoStack');
671
+ }
672
+ clearHistoryStacks() {
673
+ clearWorkPaperHistoryStacks(this.getUndoStack(), this.getRedoStack());
674
+ }
675
+ mergeUndoHistory(startIndex) {
676
+ mergeWorkPaperUndoHistory(this.getUndoStack(), startIndex, (sheetId) => this.getSheetName(sheetId));
677
+ }
678
+ nextSheetName() {
679
+ let index = 1;
680
+ while (this.doesSheetExist(`Sheet${index}`)) {
681
+ index += 1;
682
+ }
683
+ return `Sheet${index}`;
684
+ }
685
+ collectRangeDependencies(range, readDependencies) {
686
+ return collectWorkPaperRangeDependencies({
687
+ range,
688
+ readDependencies,
689
+ resolver: {
690
+ defaultSheetName: () => this.listSheetRecords()[0].name,
691
+ requireSheetId: (name) => this.requireSheetId(name),
692
+ },
693
+ });
694
+ }
695
+ toDependencyRefs(values) {
696
+ return toWorkPaperDependencyRefs(values, {
697
+ defaultSheetName: () => this.listSheetRecords()[0].name,
698
+ requireSheetId: (name) => this.requireSheetId(name),
699
+ });
700
+ }
701
+ }
702
+ //# sourceMappingURL=work-paper-runtime-surface.js.map