@rowsncolumns/y-spreadsheet 14.0.32
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/LICENSE.md +100 -0
- package/Readme.md +77 -0
- package/dist/cjs/helpers.d.ts +179 -0
- package/dist/cjs/helpers.d.ts.map +1 -0
- package/dist/cjs/helpers.js +1635 -0
- package/dist/cjs/index.d.ts +6 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +8 -0
- package/dist/cjs/observables.d.ts +10 -0
- package/dist/cjs/observables.d.ts.map +1 -0
- package/dist/cjs/observables.js +90 -0
- package/dist/cjs/profiling/batch-profile.spec.d.ts +2 -0
- package/dist/cjs/profiling/batch-profile.spec.d.ts.map +1 -0
- package/dist/cjs/profiling/batch-profile.spec.js +175 -0
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -0
- package/dist/cjs/types.d.ts +62 -0
- package/dist/cjs/types.d.ts.map +1 -0
- package/dist/cjs/types.js +2 -0
- package/dist/cjs/use-yspreadsheet-v2.d.ts +152 -0
- package/dist/cjs/use-yspreadsheet-v2.d.ts.map +1 -0
- package/dist/cjs/use-yspreadsheet-v2.js +980 -0
- package/dist/cjs/use-yspreadsheet.d.ts +39 -0
- package/dist/cjs/use-yspreadsheet.d.ts.map +1 -0
- package/dist/cjs/use-yspreadsheet.js +430 -0
- package/dist/cjs/vitest.config.d.ts +3 -0
- package/dist/cjs/vitest.config.d.ts.map +1 -0
- package/dist/cjs/vitest.config.js +23 -0
- package/dist/esm/helpers.d.ts +179 -0
- package/dist/esm/helpers.d.ts.map +1 -0
- package/dist/esm/helpers.js +1346 -0
- package/dist/esm/index.d.ts +6 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +5 -0
- package/dist/esm/observables.d.ts +10 -0
- package/dist/esm/observables.d.ts.map +1 -0
- package/dist/esm/observables.js +51 -0
- package/dist/esm/profiling/batch-profile.spec.d.ts +2 -0
- package/dist/esm/profiling/batch-profile.spec.d.ts.map +1 -0
- package/dist/esm/profiling/batch-profile.spec.js +131 -0
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -0
- package/dist/esm/types.d.ts +62 -0
- package/dist/esm/types.d.ts.map +1 -0
- package/dist/esm/types.js +1 -0
- package/dist/esm/use-yspreadsheet-v2.d.ts +152 -0
- package/dist/esm/use-yspreadsheet-v2.d.ts.map +1 -0
- package/dist/esm/use-yspreadsheet-v2.js +814 -0
- package/dist/esm/use-yspreadsheet.d.ts +39 -0
- package/dist/esm/use-yspreadsheet.d.ts.map +1 -0
- package/dist/esm/use-yspreadsheet.js +304 -0
- package/dist/esm/vitest.config.d.ts +3 -0
- package/dist/esm/vitest.config.d.ts.map +1 -0
- package/dist/esm/vitest.config.js +21 -0
- package/package.json +54 -0
|
@@ -0,0 +1,1635 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.processSheetDataEventsV3 = exports.addSheetDataPatchesV3 = exports.getSheetDataV3 = exports.deleteSheetV3 = exports.deleteCellV3 = exports.setCellV3 = exports.getCellV3 = exports.sheetDataV3ToV2 = exports.sheetDataV2ToV3 = exports.createCellDataV3 = exports.parseCellKeyV3 = exports.createCellKeyV3 = exports.processSheetDataEvents = exports.applyMapPatches = exports.validateSheets = exports.updateArrayType = exports.mergeErrorEffectiveValueIntoCellData = exports.shouldPersistErrorCellPatch = exports.filterErrorCellPatches = exports.getCellDataErrorValue = exports.getCellDataFromYSheetData = exports.removeRowData = exports.setCellDataInRowData = exports.getRowDataFromSheet = exports.deleteSheetFromYSheetData = exports.getSheetFromYSheetData = exports.addSheetDataPatches = exports.applyPatchesToYDoc = void 0;
|
|
4
|
+
var tslib_1 = require("tslib");
|
|
5
|
+
var utils_1 = require("@rowsncolumns/utils");
|
|
6
|
+
var Y = tslib_1.__importStar(require("yjs"));
|
|
7
|
+
var cloneDeep_1 = tslib_1.__importDefault(require("lodash/cloneDeep"));
|
|
8
|
+
var isEqual_1 = tslib_1.__importDefault(require("lodash/isEqual"));
|
|
9
|
+
var set_1 = tslib_1.__importDefault(require("lodash/set"));
|
|
10
|
+
var get_1 = tslib_1.__importDefault(require("lodash/get"));
|
|
11
|
+
var unset_1 = tslib_1.__importDefault(require("lodash/unset"));
|
|
12
|
+
/**
|
|
13
|
+
* Apply patches to yjs
|
|
14
|
+
* @param doc
|
|
15
|
+
* @param userId
|
|
16
|
+
* @param patches
|
|
17
|
+
* @param source
|
|
18
|
+
* @param sheetDataVersion - Version of sheet data format ("v2" or "v3"). Falls back to docMeta if undefined.
|
|
19
|
+
*/
|
|
20
|
+
var applyPatchesToYDoc = function (doc, userId, patches, source, sheetDataVersion) {
|
|
21
|
+
var e_1, _a;
|
|
22
|
+
var _b, _c;
|
|
23
|
+
var ySheetDataV2 = doc.getMap("sheetDataV2");
|
|
24
|
+
var ySheetDataV3 = doc.getMap("sheetDataV3");
|
|
25
|
+
var yDocMeta = doc.getMap("docMeta");
|
|
26
|
+
var yRecalcCells = doc.getArray("recalcCells");
|
|
27
|
+
var ySheets = doc.getArray("sheets");
|
|
28
|
+
var yTables = doc.getArray("tables");
|
|
29
|
+
var yEmbeds = doc.getArray("embeds");
|
|
30
|
+
var yCharts = doc.getArray("charts");
|
|
31
|
+
var yConditionalFormats = doc.getArray("conditionalFormats");
|
|
32
|
+
var yDataValidations = doc.getArray("dataValidations");
|
|
33
|
+
var yNamedRanges = doc.getArray("namedRanges");
|
|
34
|
+
var ySharedStringsMap = doc.getMap("sharedStringsMap");
|
|
35
|
+
var yProtectedRanges = doc.getArray("protectedRanges");
|
|
36
|
+
var yCellXfs = doc.getMap("cellXfs");
|
|
37
|
+
var yDisableRecalc = doc.getMap("disableRecalc");
|
|
38
|
+
// Check version flag to determine which sheet data format to use
|
|
39
|
+
// Use param if provided, otherwise fall back to docMeta for backwards compatibility
|
|
40
|
+
var resolvedVersion = sheetDataVersion !== null && sheetDataVersion !== void 0 ? sheetDataVersion : yDocMeta.get("sheetDataVersion");
|
|
41
|
+
var isV3 = resolvedVersion === "v3";
|
|
42
|
+
try {
|
|
43
|
+
for (var patches_1 = tslib_1.__values(patches), patches_1_1 = patches_1.next(); !patches_1_1.done; patches_1_1 = patches_1.next()) {
|
|
44
|
+
var _d = tslib_1.__read(patches_1_1.value, 2), patch = _d[0], _e = _d[1], type = _e === void 0 ? "redo" : _e;
|
|
45
|
+
type = type !== null && type !== void 0 ? type : "redo";
|
|
46
|
+
var patchKey = type === "redo" ? "patches" : "inversePatches";
|
|
47
|
+
if (patch.sheetData) {
|
|
48
|
+
var patches_2 = (_b = patch.sheetData) === null || _b === void 0 ? void 0 : _b[patchKey];
|
|
49
|
+
if (isV3) {
|
|
50
|
+
(0, exports.addSheetDataPatchesV3)(ySheetDataV3, patches_2);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
(0, exports.addSheetDataPatches)(ySheetDataV2, patches_2);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (patch.sheets) {
|
|
57
|
+
var patches_3 = patch.sheets[patchKey];
|
|
58
|
+
(0, exports.updateArrayType)(ySheets, patches_3);
|
|
59
|
+
}
|
|
60
|
+
if (patch.tables) {
|
|
61
|
+
var patches_4 = patch.tables[patchKey];
|
|
62
|
+
(0, exports.updateArrayType)(yTables, patches_4);
|
|
63
|
+
}
|
|
64
|
+
if (patch.embeds) {
|
|
65
|
+
var patches_5 = patch.embeds[patchKey];
|
|
66
|
+
(0, exports.updateArrayType)(yEmbeds, patches_5);
|
|
67
|
+
}
|
|
68
|
+
if (patch.charts) {
|
|
69
|
+
var patches_6 = patch.charts[patchKey];
|
|
70
|
+
(0, exports.updateArrayType)(yCharts, patches_6);
|
|
71
|
+
}
|
|
72
|
+
if (patch.conditionalFormats) {
|
|
73
|
+
var patches_7 = patch.conditionalFormats[patchKey];
|
|
74
|
+
(0, exports.updateArrayType)(yConditionalFormats, patches_7);
|
|
75
|
+
}
|
|
76
|
+
if (patch.dataValidations) {
|
|
77
|
+
var patches_8 = patch.dataValidations[patchKey];
|
|
78
|
+
(0, exports.updateArrayType)(yDataValidations, patches_8);
|
|
79
|
+
}
|
|
80
|
+
if (patch.namedRanges) {
|
|
81
|
+
var patches_9 = patch.namedRanges[patchKey];
|
|
82
|
+
(0, exports.updateArrayType)(yNamedRanges, patches_9);
|
|
83
|
+
}
|
|
84
|
+
if (patch.sharedStrings) {
|
|
85
|
+
var patches_10 = patch.sharedStrings[patchKey];
|
|
86
|
+
// Always use Map for shared strings
|
|
87
|
+
(0, exports.applyMapPatches)(ySharedStringsMap, patches_10);
|
|
88
|
+
}
|
|
89
|
+
if (patch.protectedRanges) {
|
|
90
|
+
var patches_11 = patch.protectedRanges[patchKey];
|
|
91
|
+
(0, exports.updateArrayType)(yProtectedRanges, patches_11);
|
|
92
|
+
}
|
|
93
|
+
if (patch.cellXfs) {
|
|
94
|
+
var patches_12 = patch.cellXfs[patchKey];
|
|
95
|
+
(0, exports.applyMapPatches)(yCellXfs, patches_12);
|
|
96
|
+
}
|
|
97
|
+
// Recalc cells
|
|
98
|
+
if ((_c = patch.recalcCells) === null || _c === void 0 ? void 0 : _c[type]) {
|
|
99
|
+
// Removing this
|
|
100
|
+
// multiple calls to update_sheet_range deletes recalc cells
|
|
101
|
+
// yRecalcCells.delete(0, yRecalcCells.length);
|
|
102
|
+
yRecalcCells.push([
|
|
103
|
+
{
|
|
104
|
+
userId: userId,
|
|
105
|
+
patches: Array.from(patch.recalcCells[type]).map(function (value) {
|
|
106
|
+
return tslib_1.__spreadArray(tslib_1.__spreadArray([], tslib_1.__read(value), false), [source !== null && source !== void 0 ? source : "agent"], false);
|
|
107
|
+
}),
|
|
108
|
+
},
|
|
109
|
+
]);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
114
|
+
finally {
|
|
115
|
+
try {
|
|
116
|
+
if (patches_1_1 && !patches_1_1.done && (_a = patches_1.return)) _a.call(patches_1);
|
|
117
|
+
}
|
|
118
|
+
finally { if (e_1) throw e_1.error; }
|
|
119
|
+
}
|
|
120
|
+
// Set disable recalc flag (only if it's currently truthy, to avoid redundant Y.Map writes)
|
|
121
|
+
if (yDisableRecalc.get("disableRecalc") !== false) {
|
|
122
|
+
yDisableRecalc.set("disableRecalc", false);
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
exports.applyPatchesToYDoc = applyPatchesToYDoc;
|
|
126
|
+
/**
|
|
127
|
+
* Add sheet data to a yjs map using immer patches
|
|
128
|
+
*
|
|
129
|
+
* Optimized for bulk operations (paste, import) by consolidating cell-level
|
|
130
|
+
* patches before applying to Y.js. This reduces overhead by:
|
|
131
|
+
* 1. Deduplicating patches targeting the same cell (later patches win)
|
|
132
|
+
* 2. Grouping updates by sheet/row for efficient batch application
|
|
133
|
+
*/
|
|
134
|
+
var addSheetDataPatches = function (ySheetData, patches) {
|
|
135
|
+
var e_2, _a, e_3, _b, e_4, _c, e_5, _d, e_6, _e;
|
|
136
|
+
// Optimization: Pre-process and consolidate cell-level patches
|
|
137
|
+
// For bulk operations like paste (10k+ rows), this dramatically reduces overhead
|
|
138
|
+
// Key format: "sheetId:rowIndex:columnIndex"
|
|
139
|
+
var cellUpdates = new Map();
|
|
140
|
+
var otherPatches = [];
|
|
141
|
+
try {
|
|
142
|
+
// First pass: categorize and consolidate patches
|
|
143
|
+
for (var patches_13 = tslib_1.__values(patches), patches_13_1 = patches_13.next(); !patches_13_1.done; patches_13_1 = patches_13.next()) {
|
|
144
|
+
var patch = patches_13_1.value;
|
|
145
|
+
var op = patch.op, path = patch.path, value = patch.value;
|
|
146
|
+
var _f = tslib_1.__read(path, 1), sheetIdRaw = _f[0];
|
|
147
|
+
// Handle undefined sheetId separately (full replace)
|
|
148
|
+
if (typeof sheetIdRaw === "undefined") {
|
|
149
|
+
otherPatches.push(patch);
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
// Use string representation for sheet ID to handle both string and numeric IDs
|
|
153
|
+
var sheetIdStr = String(sheetIdRaw);
|
|
154
|
+
if (op === "replace" || op === "add") {
|
|
155
|
+
// [sheetId, rowIndex, 'values', columnIndex] - Single cell update (most common in paste)
|
|
156
|
+
if (path.length === 4) {
|
|
157
|
+
var _g = tslib_1.__read(path, 4), rowIndex = _g[1], columnIndex = _g[3];
|
|
158
|
+
var rowIdx = Number(rowIndex);
|
|
159
|
+
var colIdx = Number(columnIndex);
|
|
160
|
+
var key = "".concat(sheetIdStr, ":").concat(rowIdx, ":").concat(colIdx);
|
|
161
|
+
// Later patches override earlier ones for the same cell
|
|
162
|
+
cellUpdates.set(key, { sheetIdStr: sheetIdStr, rowIdx: rowIdx, colIdx: colIdx, value: value });
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
// Row-level or sheet-level updates
|
|
166
|
+
otherPatches.push(patch);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
else if (op === "remove") {
|
|
170
|
+
if (path.length === 4) {
|
|
171
|
+
var _h = tslib_1.__read(path, 4), rowIndex = _h[1], columnIndex = _h[3];
|
|
172
|
+
var rowIdx = Number(rowIndex);
|
|
173
|
+
var colIdx = Number(columnIndex);
|
|
174
|
+
var key = "".concat(sheetIdStr, ":").concat(rowIdx, ":").concat(colIdx);
|
|
175
|
+
cellUpdates.set(key, { sheetIdStr: sheetIdStr, rowIdx: rowIdx, colIdx: colIdx, value: null });
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
otherPatches.push(patch);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
otherPatches.push(patch);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
187
|
+
finally {
|
|
188
|
+
try {
|
|
189
|
+
if (patches_13_1 && !patches_13_1.done && (_a = patches_13.return)) _a.call(patches_13);
|
|
190
|
+
}
|
|
191
|
+
finally { if (e_2) throw e_2.error; }
|
|
192
|
+
}
|
|
193
|
+
// Second pass: Group cell updates by sheet and row for efficient batch application
|
|
194
|
+
// This minimizes Y.js operations by batching updates to the same row
|
|
195
|
+
var sheetRowUpdates = new Map();
|
|
196
|
+
try {
|
|
197
|
+
for (var cellUpdates_1 = tslib_1.__values(cellUpdates), cellUpdates_1_1 = cellUpdates_1.next(); !cellUpdates_1_1.done; cellUpdates_1_1 = cellUpdates_1.next()) {
|
|
198
|
+
var _j = tslib_1.__read(cellUpdates_1_1.value, 2), _k = _j[1], sheetIdStr = _k.sheetIdStr, rowIdx = _k.rowIdx, colIdx = _k.colIdx, value = _k.value;
|
|
199
|
+
if (!sheetRowUpdates.has(sheetIdStr)) {
|
|
200
|
+
sheetRowUpdates.set(sheetIdStr, new Map());
|
|
201
|
+
}
|
|
202
|
+
var rowUpdates = sheetRowUpdates.get(sheetIdStr);
|
|
203
|
+
if (!rowUpdates.has(rowIdx)) {
|
|
204
|
+
rowUpdates.set(rowIdx, new Map());
|
|
205
|
+
}
|
|
206
|
+
rowUpdates.get(rowIdx).set(colIdx, value);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
|
210
|
+
finally {
|
|
211
|
+
try {
|
|
212
|
+
if (cellUpdates_1_1 && !cellUpdates_1_1.done && (_b = cellUpdates_1.return)) _b.call(cellUpdates_1);
|
|
213
|
+
}
|
|
214
|
+
finally { if (e_3) throw e_3.error; }
|
|
215
|
+
}
|
|
216
|
+
try {
|
|
217
|
+
// Apply batched cell updates
|
|
218
|
+
for (var sheetRowUpdates_1 = tslib_1.__values(sheetRowUpdates), sheetRowUpdates_1_1 = sheetRowUpdates_1.next(); !sheetRowUpdates_1_1.done; sheetRowUpdates_1_1 = sheetRowUpdates_1.next()) {
|
|
219
|
+
var _l = tslib_1.__read(sheetRowUpdates_1_1.value, 2), sheetIdStr = _l[0], rowUpdates = _l[1];
|
|
220
|
+
var ysheet = (0, exports.getSheetFromYSheetData)(ySheetData, sheetIdStr);
|
|
221
|
+
try {
|
|
222
|
+
for (var rowUpdates_1 = (e_5 = void 0, tslib_1.__values(rowUpdates)), rowUpdates_1_1 = rowUpdates_1.next(); !rowUpdates_1_1.done; rowUpdates_1_1 = rowUpdates_1.next()) {
|
|
223
|
+
var _m = tslib_1.__read(rowUpdates_1_1.value, 2), rowIdx = _m[0], colUpdates = _m[1];
|
|
224
|
+
var rowData = (0, exports.getRowDataFromSheet)(ysheet, rowIdx);
|
|
225
|
+
try {
|
|
226
|
+
for (var colUpdates_1 = (e_6 = void 0, tslib_1.__values(colUpdates)), colUpdates_1_1 = colUpdates_1.next(); !colUpdates_1_1.done; colUpdates_1_1 = colUpdates_1.next()) {
|
|
227
|
+
var _o = tslib_1.__read(colUpdates_1_1.value, 2), colIdx = _o[0], value = _o[1];
|
|
228
|
+
(0, exports.setCellDataInRowData)(rowData, colIdx, value);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
catch (e_6_1) { e_6 = { error: e_6_1 }; }
|
|
232
|
+
finally {
|
|
233
|
+
try {
|
|
234
|
+
if (colUpdates_1_1 && !colUpdates_1_1.done && (_e = colUpdates_1.return)) _e.call(colUpdates_1);
|
|
235
|
+
}
|
|
236
|
+
finally { if (e_6) throw e_6.error; }
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
catch (e_5_1) { e_5 = { error: e_5_1 }; }
|
|
241
|
+
finally {
|
|
242
|
+
try {
|
|
243
|
+
if (rowUpdates_1_1 && !rowUpdates_1_1.done && (_d = rowUpdates_1.return)) _d.call(rowUpdates_1);
|
|
244
|
+
}
|
|
245
|
+
finally { if (e_5) throw e_5.error; }
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
catch (e_4_1) { e_4 = { error: e_4_1 }; }
|
|
250
|
+
finally {
|
|
251
|
+
try {
|
|
252
|
+
if (sheetRowUpdates_1_1 && !sheetRowUpdates_1_1.done && (_c = sheetRowUpdates_1.return)) _c.call(sheetRowUpdates_1);
|
|
253
|
+
}
|
|
254
|
+
finally { if (e_4) throw e_4.error; }
|
|
255
|
+
}
|
|
256
|
+
// Process non-cell-level patches using original logic
|
|
257
|
+
var processPatch = function (_a) {
|
|
258
|
+
var op = _a.op, path = _a.path, value = _a.value;
|
|
259
|
+
var _b = tslib_1.__read(path, 1), sheetId = _b[0];
|
|
260
|
+
if (typeof sheetId === "undefined") {
|
|
261
|
+
// Replace. User is replacing the entire data
|
|
262
|
+
if (op === "replace") {
|
|
263
|
+
// Remove all sheet data
|
|
264
|
+
ySheetData.clear();
|
|
265
|
+
}
|
|
266
|
+
// Assign values
|
|
267
|
+
for (var curSheetId in value) {
|
|
268
|
+
var sheetId_1 = Number(curSheetId);
|
|
269
|
+
processPatch({
|
|
270
|
+
op: "replace",
|
|
271
|
+
path: [sheetId_1],
|
|
272
|
+
value: value[curSheetId],
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
if (op === "replace" || op === "add") {
|
|
278
|
+
var ysheet_1 = (0, exports.getSheetFromYSheetData)(ySheetData, sheetId);
|
|
279
|
+
// Cell-level patches (path.length === 4) are already handled above via consolidation
|
|
280
|
+
// [sheetId, rowIndex, 'values'] - Replace values array directly
|
|
281
|
+
if (path.length === 3 && path[2] === "values") {
|
|
282
|
+
var _c = tslib_1.__read(path, 2), rowIndex = _c[1];
|
|
283
|
+
var rowData_1 = (0, exports.getRowDataFromSheet)(ysheet_1, rowIndex);
|
|
284
|
+
// Clear existing row data
|
|
285
|
+
rowData_1.delete(0, rowData_1.length);
|
|
286
|
+
if (Array.isArray(value)) {
|
|
287
|
+
// Value is the values array directly
|
|
288
|
+
// Sort keys to maintain order during insertion
|
|
289
|
+
Object.entries(value)
|
|
290
|
+
.sort(function (_a, _b) {
|
|
291
|
+
var _c = tslib_1.__read(_a, 1), a = _c[0];
|
|
292
|
+
var _d = tslib_1.__read(_b, 1), b = _d[0];
|
|
293
|
+
return Number(a) - Number(b);
|
|
294
|
+
})
|
|
295
|
+
.forEach(function (_a) {
|
|
296
|
+
var _b = tslib_1.__read(_a, 2), columnIndex = _b[0], cellData = _b[1];
|
|
297
|
+
(0, exports.setCellDataInRowData)(rowData_1, Number(columnIndex), cellData);
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
// [sheetId, rowIndex] - Entire row update
|
|
302
|
+
else if (path.length === 2) {
|
|
303
|
+
var _d = tslib_1.__read(path, 2), rowIndex = _d[1];
|
|
304
|
+
if (value === null || value === void 0 ? void 0 : value.values) {
|
|
305
|
+
// Replace entire row with new values
|
|
306
|
+
var rowData_2 = (0, exports.getRowDataFromSheet)(ysheet_1, rowIndex);
|
|
307
|
+
// Clear existing row data
|
|
308
|
+
rowData_2.delete(0, rowData_2.length);
|
|
309
|
+
// Add new cell values
|
|
310
|
+
// Sort keys to maintain order during insertion
|
|
311
|
+
Object.entries(value.values)
|
|
312
|
+
.sort(function (_a, _b) {
|
|
313
|
+
var _c = tslib_1.__read(_a, 1), a = _c[0];
|
|
314
|
+
var _d = tslib_1.__read(_b, 1), b = _d[0];
|
|
315
|
+
return Number(a) - Number(b);
|
|
316
|
+
})
|
|
317
|
+
.forEach(function (_a) {
|
|
318
|
+
var _b = tslib_1.__read(_a, 2), columnIndex = _b[0], cellData = _b[1];
|
|
319
|
+
(0, exports.setCellDataInRowData)(rowData_2, Number(columnIndex), cellData);
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
else {
|
|
323
|
+
// Remove row if value is null/undefined
|
|
324
|
+
(0, exports.removeRowData)(ysheet_1, rowIndex);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
// [sheetId] - Entire sheet update
|
|
328
|
+
else if (path.length === 1) {
|
|
329
|
+
if (value) {
|
|
330
|
+
// Clear entire sheet
|
|
331
|
+
ysheet_1.delete(0, ysheet_1.length);
|
|
332
|
+
// Add all new data
|
|
333
|
+
Object.entries(value)
|
|
334
|
+
.sort(function (_a, _b) {
|
|
335
|
+
var _c = tslib_1.__read(_a, 1), a = _c[0];
|
|
336
|
+
var _d = tslib_1.__read(_b, 1), b = _d[0];
|
|
337
|
+
return Number(a) - Number(b);
|
|
338
|
+
})
|
|
339
|
+
.forEach(function (_a) {
|
|
340
|
+
var _b = tslib_1.__read(_a, 2), rowIndex = _b[0], rowData = _b[1];
|
|
341
|
+
if (rowData === null || rowData === void 0 ? void 0 : rowData.values) {
|
|
342
|
+
var rowDataArray_1 = (0, exports.getRowDataFromSheet)(ysheet_1, Number(rowIndex));
|
|
343
|
+
Object.entries(rowData.values)
|
|
344
|
+
.sort(function (_a, _b) {
|
|
345
|
+
var _c = tslib_1.__read(_a, 1), a = _c[0];
|
|
346
|
+
var _d = tslib_1.__read(_b, 1), b = _d[0];
|
|
347
|
+
return Number(a) - Number(b);
|
|
348
|
+
})
|
|
349
|
+
.forEach(function (_a) {
|
|
350
|
+
var _b = tslib_1.__read(_a, 2), columnIndex = _b[0], cellData = _b[1];
|
|
351
|
+
(0, exports.setCellDataInRowData)(rowDataArray_1, Number(columnIndex), cellData);
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
else if (op === "remove") {
|
|
359
|
+
// Cell-level removes (path.length === 4) are already handled above via consolidation
|
|
360
|
+
// [sheetId, rowIndex] - Remove entire row
|
|
361
|
+
if (path.length === 2) {
|
|
362
|
+
var _e = tslib_1.__read(path, 2), rowIndex = _e[1];
|
|
363
|
+
var ysheet = (0, exports.getSheetFromYSheetData)(ySheetData, sheetId);
|
|
364
|
+
(0, exports.removeRowData)(ysheet, rowIndex);
|
|
365
|
+
}
|
|
366
|
+
// [sheetId] - Remove entire sheet
|
|
367
|
+
else if (path.length === 1) {
|
|
368
|
+
(0, exports.deleteSheetFromYSheetData)(ySheetData, sheetId);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
};
|
|
372
|
+
// Only process non-cell-level patches (cell-level already handled via consolidation)
|
|
373
|
+
otherPatches.forEach(processPatch);
|
|
374
|
+
};
|
|
375
|
+
exports.addSheetDataPatches = addSheetDataPatches;
|
|
376
|
+
var getSheetFromYSheetData = function (ySheetData, sheetId) {
|
|
377
|
+
var id = String(sheetId);
|
|
378
|
+
var sheet = ySheetData.get(id);
|
|
379
|
+
if (!sheet) {
|
|
380
|
+
sheet = new Y.Array();
|
|
381
|
+
ySheetData.set(id, sheet);
|
|
382
|
+
}
|
|
383
|
+
return sheet;
|
|
384
|
+
};
|
|
385
|
+
exports.getSheetFromYSheetData = getSheetFromYSheetData;
|
|
386
|
+
var deleteSheetFromYSheetData = function (ySheetData, sheetId) {
|
|
387
|
+
var id = String(sheetId);
|
|
388
|
+
ySheetData.delete(id);
|
|
389
|
+
};
|
|
390
|
+
exports.deleteSheetFromYSheetData = deleteSheetFromYSheetData;
|
|
391
|
+
var getRowDataFromSheet = function (ysheet, rowIndex) {
|
|
392
|
+
var index = Number(rowIndex);
|
|
393
|
+
if (index < 0) {
|
|
394
|
+
throw new Error("Row index cannot be negative");
|
|
395
|
+
}
|
|
396
|
+
// Extend array if needed
|
|
397
|
+
if (index >= ysheet.length) {
|
|
398
|
+
var padding = new Array(index - ysheet.length).fill(null);
|
|
399
|
+
ysheet.insert(ysheet.length, padding);
|
|
400
|
+
ysheet.insert(index, [null]); // Insert null first
|
|
401
|
+
// Create new row data
|
|
402
|
+
var newRowData = new Y.Map();
|
|
403
|
+
newRowData.set("values", new Y.Array());
|
|
404
|
+
// Replace the null
|
|
405
|
+
ysheet.insert(index, [newRowData]);
|
|
406
|
+
ysheet.delete(index + 1, 1);
|
|
407
|
+
// Delete the initially inserted null (wait, index shifts)
|
|
408
|
+
// index is target.
|
|
409
|
+
// Insert padding up to index. length = index.
|
|
410
|
+
// Insert null at index. length = index+1.
|
|
411
|
+
// Replace null at index.
|
|
412
|
+
// Insert newRowData at index. length = index+2.
|
|
413
|
+
// Delete at index+1. length = index+1.
|
|
414
|
+
// Correct.
|
|
415
|
+
return newRowData.get("values");
|
|
416
|
+
}
|
|
417
|
+
// Get or create existing row data
|
|
418
|
+
var rowData = ysheet.get(index);
|
|
419
|
+
if (!rowData || !rowData.get("values")) {
|
|
420
|
+
// Create new row data if it doesn't exist or is incomplete
|
|
421
|
+
var newRowData = new Y.Map();
|
|
422
|
+
newRowData.set("values", new Y.Array());
|
|
423
|
+
// Replace the existing item
|
|
424
|
+
ysheet.insert(index, [newRowData]);
|
|
425
|
+
ysheet.delete(index + 1, 1);
|
|
426
|
+
return newRowData.get("values");
|
|
427
|
+
}
|
|
428
|
+
return rowData.get("values");
|
|
429
|
+
};
|
|
430
|
+
exports.getRowDataFromSheet = getRowDataFromSheet;
|
|
431
|
+
var setCellDataInRowData = function (rowData, columnIndex, cellData) {
|
|
432
|
+
if (cellData === void 0) { cellData = null; }
|
|
433
|
+
var index = Number(columnIndex);
|
|
434
|
+
// Extend array if needed
|
|
435
|
+
if (index >= rowData.length) {
|
|
436
|
+
var padding = new Array(index - rowData.length).fill(null);
|
|
437
|
+
if (padding.length > 0) {
|
|
438
|
+
rowData.insert(rowData.length, padding);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
if (index === rowData.length) {
|
|
442
|
+
rowData.insert(index, [cellData]);
|
|
443
|
+
}
|
|
444
|
+
else {
|
|
445
|
+
// Replace cell data
|
|
446
|
+
rowData.insert(index, [cellData]);
|
|
447
|
+
rowData.delete(index + 1, 1);
|
|
448
|
+
}
|
|
449
|
+
};
|
|
450
|
+
exports.setCellDataInRowData = setCellDataInRowData;
|
|
451
|
+
var removeRowData = function (ysheet, rowIndex) {
|
|
452
|
+
var index = Number(rowIndex);
|
|
453
|
+
// Only remove if index is valid
|
|
454
|
+
if (index >= 0 && index < ysheet.length) {
|
|
455
|
+
ysheet.insert(index, [null]);
|
|
456
|
+
ysheet.delete(index + 1, 1);
|
|
457
|
+
}
|
|
458
|
+
};
|
|
459
|
+
exports.removeRowData = removeRowData;
|
|
460
|
+
/**
|
|
461
|
+
* Read a cell's data from the V2 Y.js structure without creating any
|
|
462
|
+
* missing sheet/row/values containers (unlike getSheetFromYSheetData /
|
|
463
|
+
* getRowDataFromSheet, which lazily create them).
|
|
464
|
+
*/
|
|
465
|
+
var getCellDataFromYSheetData = function (ySheetData, sheetId, rowIndex, columnIndex) {
|
|
466
|
+
var sheet = ySheetData.get(String(sheetId));
|
|
467
|
+
var rowIdx = Number(rowIndex);
|
|
468
|
+
if (!sheet || rowIdx < 0 || rowIdx >= sheet.length) {
|
|
469
|
+
return undefined;
|
|
470
|
+
}
|
|
471
|
+
var row = sheet.get(rowIdx);
|
|
472
|
+
var values = row === null || row === void 0 ? void 0 : row.get("values");
|
|
473
|
+
var colIdx = Number(columnIndex);
|
|
474
|
+
if (!values || colIdx < 0 || colIdx >= values.length) {
|
|
475
|
+
return undefined;
|
|
476
|
+
}
|
|
477
|
+
return values.get(colIdx);
|
|
478
|
+
};
|
|
479
|
+
exports.getCellDataFromYSheetData = getCellDataFromYSheetData;
|
|
480
|
+
/**
|
|
481
|
+
* Extract the error effective value from cell data, if any.
|
|
482
|
+
* SheetCell.setErrorValue persists formula errors as
|
|
483
|
+
* `ev.ev = { type: "Error", name, message }` (legacy long form:
|
|
484
|
+
* `effectiveValue.errorValue`).
|
|
485
|
+
*/
|
|
486
|
+
var getCellDataErrorValue = function (cellData) {
|
|
487
|
+
return (0, utils_1.getExtendedValueError)((0, utils_1.getCellEffectiveValue)(cellData));
|
|
488
|
+
};
|
|
489
|
+
exports.getCellDataErrorValue = getCellDataErrorValue;
|
|
490
|
+
/**
|
|
491
|
+
* Keep only the cell-level sheetData patches
|
|
492
|
+
* (`[sheetId, rowIndex, "values", columnIndex]`) whose new cell data carries
|
|
493
|
+
* an error effective value (#VALUE!, #NAME?, …). Used to let calc-result
|
|
494
|
+
* errors bypass the leader gate: errors must reach the Y.Doc even from
|
|
495
|
+
* non-leader clients, otherwise they render blank after reload.
|
|
496
|
+
*/
|
|
497
|
+
var filterErrorCellPatches = function (patches) {
|
|
498
|
+
return patches.filter(function (patch) {
|
|
499
|
+
return (patch.op === "add" || patch.op === "replace") &&
|
|
500
|
+
patch.path.length === 4 &&
|
|
501
|
+
patch.path[2] === "values" &&
|
|
502
|
+
Boolean((0, exports.getCellDataErrorValue)(patch.value));
|
|
503
|
+
});
|
|
504
|
+
};
|
|
505
|
+
exports.filterErrorCellPatches = filterErrorCellPatches;
|
|
506
|
+
/**
|
|
507
|
+
* Normalize an extended value (short or legacy long keys) into the short-key
|
|
508
|
+
* shape so semantically identical values compare equal regardless of which
|
|
509
|
+
* key shape produced them.
|
|
510
|
+
*/
|
|
511
|
+
var normalizeExtendedValue = function (extValue) {
|
|
512
|
+
if (extValue === null || extValue === undefined) {
|
|
513
|
+
return undefined;
|
|
514
|
+
}
|
|
515
|
+
var normalized = {};
|
|
516
|
+
var numberValue = (0, utils_1.getExtendedValueNumber)(extValue);
|
|
517
|
+
if (numberValue !== undefined) {
|
|
518
|
+
normalized.nv = numberValue;
|
|
519
|
+
}
|
|
520
|
+
var stringValue = (0, utils_1.getExtendedValueString)(extValue);
|
|
521
|
+
if (stringValue !== undefined) {
|
|
522
|
+
normalized.sv = stringValue;
|
|
523
|
+
}
|
|
524
|
+
var boolValue = (0, utils_1.getExtendedValueBool)(extValue);
|
|
525
|
+
if (boolValue !== undefined) {
|
|
526
|
+
normalized.bv = boolValue;
|
|
527
|
+
}
|
|
528
|
+
var formulaValue = (0, utils_1.getExtendedValueFormula)(extValue);
|
|
529
|
+
if (formulaValue !== undefined) {
|
|
530
|
+
normalized.fv = formulaValue;
|
|
531
|
+
}
|
|
532
|
+
var errorValue = (0, utils_1.getExtendedValueError)(extValue);
|
|
533
|
+
if (errorValue !== undefined) {
|
|
534
|
+
normalized.ev = errorValue;
|
|
535
|
+
}
|
|
536
|
+
return normalized;
|
|
537
|
+
};
|
|
538
|
+
/**
|
|
539
|
+
* Containment guard for the non-leader error-persistence path
|
|
540
|
+
* (use-yspreadsheet-v2 onBroadcastPatch, gated disableRecalc branch).
|
|
541
|
+
* A gated error cell patch may be written ONLY when all of these hold:
|
|
542
|
+
*
|
|
543
|
+
* 1. The incoming cell data carries an error effective value.
|
|
544
|
+
* 2. The current doc cell holds no effective value at all (the
|
|
545
|
+
* blank-after-reload case) or its effective value is itself an error.
|
|
546
|
+
* A non-error result (number/string/bool/formula result) is never
|
|
547
|
+
* overwritten — a stale non-leader error must not clobber a newer
|
|
548
|
+
* leader-written success.
|
|
549
|
+
* 3. If the doc cell exists, its user-entered value (`ue`, short or legacy
|
|
550
|
+
* key shape) matches the incoming patch's — a cell edited after the
|
|
551
|
+
* calculation started is never touched.
|
|
552
|
+
* 4. The persisted error differs from the incoming one (identical errors
|
|
553
|
+
* are dropped so concurrent non-leaders don't append redundant
|
|
554
|
+
* Y.js updates).
|
|
555
|
+
*/
|
|
556
|
+
var shouldPersistErrorCellPatch = function (currentCellData, incomingCellData) {
|
|
557
|
+
var incomingError = (0, exports.getCellDataErrorValue)(incomingCellData);
|
|
558
|
+
if (!incomingError) {
|
|
559
|
+
return false;
|
|
560
|
+
}
|
|
561
|
+
var currentEffectiveValue = (0, utils_1.getCellEffectiveValue)(currentCellData);
|
|
562
|
+
var currentError = (0, utils_1.getExtendedValueError)(currentEffectiveValue);
|
|
563
|
+
if (currentEffectiveValue !== null &&
|
|
564
|
+
currentEffectiveValue !== undefined &&
|
|
565
|
+
!currentError) {
|
|
566
|
+
return false;
|
|
567
|
+
}
|
|
568
|
+
if (currentCellData !== null && currentCellData !== undefined) {
|
|
569
|
+
var currentUserEnteredValue = normalizeExtendedValue((0, utils_1.getCellUserEnteredValue)(currentCellData));
|
|
570
|
+
var incomingUserEnteredValue = normalizeExtendedValue((0, utils_1.getCellUserEnteredValue)(incomingCellData));
|
|
571
|
+
if (!(0, isEqual_1.default)(currentUserEnteredValue, incomingUserEnteredValue)) {
|
|
572
|
+
return false;
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
return !(0, isEqual_1.default)(currentError, incomingError);
|
|
576
|
+
};
|
|
577
|
+
exports.shouldPersistErrorCellPatch = shouldPersistErrorCellPatch;
|
|
578
|
+
/**
|
|
579
|
+
* Build the cell data to write for a gated error patch that passed
|
|
580
|
+
* shouldPersistErrorCellPatch. If the doc cell doesn't exist yet there is
|
|
581
|
+
* nothing to destroy and the incoming cell data is written as-is. If it
|
|
582
|
+
* does exist, ONLY the error effective value is merged in — every other
|
|
583
|
+
* field of the doc cell (ue, formats, notes, …) is preserved so this write
|
|
584
|
+
* path can never remove doc state it didn't produce. The effective value is
|
|
585
|
+
* written into whichever key shape(s) the doc cell already uses (short `ev`
|
|
586
|
+
* by default).
|
|
587
|
+
*/
|
|
588
|
+
var mergeErrorEffectiveValueIntoCellData = function (currentCellData, incomingCellData) {
|
|
589
|
+
if (currentCellData === null || currentCellData === undefined) {
|
|
590
|
+
return incomingCellData;
|
|
591
|
+
}
|
|
592
|
+
var incomingEffectiveValue = (0, utils_1.getCellEffectiveValue)(incomingCellData);
|
|
593
|
+
var merged = tslib_1.__assign({}, currentCellData);
|
|
594
|
+
var hasLegacyKey = "effectiveValue" in merged;
|
|
595
|
+
if (hasLegacyKey) {
|
|
596
|
+
merged.effectiveValue = incomingEffectiveValue;
|
|
597
|
+
}
|
|
598
|
+
if ("ev" in merged || !hasLegacyKey) {
|
|
599
|
+
merged.ev = incomingEffectiveValue;
|
|
600
|
+
}
|
|
601
|
+
return merged;
|
|
602
|
+
};
|
|
603
|
+
exports.mergeErrorEffectiveValueIntoCellData = mergeErrorEffectiveValueIntoCellData;
|
|
604
|
+
/**
|
|
605
|
+
* Update array type with immer patches
|
|
606
|
+
*/
|
|
607
|
+
var updateArrayType = function (yarray, patches) {
|
|
608
|
+
// Consecutive nested-path patches targeting the same array item are
|
|
609
|
+
// consolidated into one cloneDeep + one Y.Array write. An immer splice on
|
|
610
|
+
// a nested array (e.g. a sheet's rowMetadata on row insert/delete) emits
|
|
611
|
+
// one patch per shifted entry; writing each patch individually clones and
|
|
612
|
+
// re-serializes the entire item per entry — O(n²) on large sheets, which
|
|
613
|
+
// freezes the tab.
|
|
614
|
+
var pending = null;
|
|
615
|
+
var flushPending = function () {
|
|
616
|
+
if (!pending) {
|
|
617
|
+
return;
|
|
618
|
+
}
|
|
619
|
+
var index = pending.index, item = pending.item;
|
|
620
|
+
pending = null;
|
|
621
|
+
ensureArraySize(yarray, index);
|
|
622
|
+
yarray.insert(index, [item]);
|
|
623
|
+
yarray.delete(index + 1, 1);
|
|
624
|
+
};
|
|
625
|
+
patches.forEach(function (_a) {
|
|
626
|
+
var op = _a.op, path = _a.path, value = _a.value;
|
|
627
|
+
var _b = tslib_1.__read(path), arrayIndex = _b[0], nestedPath = _b.slice(1);
|
|
628
|
+
var index = Number(arrayIndex);
|
|
629
|
+
if (isNaN(index)) {
|
|
630
|
+
flushPending();
|
|
631
|
+
// User is replacing the entire array
|
|
632
|
+
if (op === "replace") {
|
|
633
|
+
yarray.delete(0, yarray.length);
|
|
634
|
+
yarray.push(value);
|
|
635
|
+
}
|
|
636
|
+
return;
|
|
637
|
+
}
|
|
638
|
+
if (op === "replace" || op === "add") {
|
|
639
|
+
if (nestedPath.length === 0) {
|
|
640
|
+
flushPending();
|
|
641
|
+
// Direct array item replacement
|
|
642
|
+
ensureArraySize(yarray, index);
|
|
643
|
+
yarray.insert(index, [value]);
|
|
644
|
+
yarray.delete(index + 1, 1);
|
|
645
|
+
}
|
|
646
|
+
else {
|
|
647
|
+
// Nested property update within array item
|
|
648
|
+
var updatedItem = void 0;
|
|
649
|
+
if (pending && pending.index === index) {
|
|
650
|
+
updatedItem = pending.item;
|
|
651
|
+
}
|
|
652
|
+
else {
|
|
653
|
+
flushPending();
|
|
654
|
+
var item = index < yarray.length ? yarray.get(index) : {};
|
|
655
|
+
var baseItem = item === null || item === undefined ? {} : item;
|
|
656
|
+
// Clone the item and use lodash to set the nested property
|
|
657
|
+
updatedItem = (0, cloneDeep_1.default)(baseItem);
|
|
658
|
+
pending = { index: index, item: updatedItem };
|
|
659
|
+
}
|
|
660
|
+
(0, set_1.default)(updatedItem, nestedPath, value);
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
else if (op === "remove") {
|
|
664
|
+
if (nestedPath.length === 0) {
|
|
665
|
+
flushPending();
|
|
666
|
+
// Remove entire array item
|
|
667
|
+
if (index >= 0 && index < yarray.length) {
|
|
668
|
+
yarray.delete(index, 1);
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
else {
|
|
672
|
+
// Remove nested property from array item
|
|
673
|
+
var updatedItem = null;
|
|
674
|
+
if (pending && pending.index === index) {
|
|
675
|
+
if (pending.item && typeof pending.item === "object") {
|
|
676
|
+
updatedItem = pending.item;
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
else {
|
|
680
|
+
flushPending();
|
|
681
|
+
if (index >= 0 && index < yarray.length) {
|
|
682
|
+
var item = yarray.get(index);
|
|
683
|
+
if (item && typeof item === "object") {
|
|
684
|
+
updatedItem = (0, cloneDeep_1.default)(item);
|
|
685
|
+
pending = { index: index, item: updatedItem };
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
if (updatedItem) {
|
|
690
|
+
// Check if we're removing from an array
|
|
691
|
+
var parentPath = nestedPath.slice(0, -1);
|
|
692
|
+
var lastKey = nestedPath[nestedPath.length - 1];
|
|
693
|
+
if (parentPath.length > 0) {
|
|
694
|
+
var parentValue = (0, get_1.default)(updatedItem, parentPath);
|
|
695
|
+
if (Array.isArray(parentValue) && typeof lastKey === "number") {
|
|
696
|
+
// Remove array element using splice
|
|
697
|
+
parentValue.splice(lastKey, 1);
|
|
698
|
+
}
|
|
699
|
+
else {
|
|
700
|
+
// Remove object property
|
|
701
|
+
(0, unset_1.default)(updatedItem, nestedPath);
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
else {
|
|
705
|
+
// Direct property removal
|
|
706
|
+
(0, unset_1.default)(updatedItem, nestedPath);
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
});
|
|
712
|
+
flushPending();
|
|
713
|
+
};
|
|
714
|
+
exports.updateArrayType = updateArrayType;
|
|
715
|
+
/**
|
|
716
|
+
* Helper function to ensure array is large enough
|
|
717
|
+
*/
|
|
718
|
+
function ensureArraySize(yarray, index) {
|
|
719
|
+
if (index >= yarray.length) {
|
|
720
|
+
var gaps = new Array(index - yarray.length).fill(null);
|
|
721
|
+
yarray.insert(yarray.length, gaps);
|
|
722
|
+
yarray.insert(index, [null]); // Insert placeholder that will be replaced
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
/**
|
|
726
|
+
* Normalize values to always be an array, converting object notation if needed
|
|
727
|
+
*/
|
|
728
|
+
function normalizeValuesToArray(values) {
|
|
729
|
+
if (!values) {
|
|
730
|
+
return [];
|
|
731
|
+
}
|
|
732
|
+
if (Array.isArray(values)) {
|
|
733
|
+
return tslib_1.__spreadArray([], tslib_1.__read(values), false);
|
|
734
|
+
}
|
|
735
|
+
// Convert object notation to array
|
|
736
|
+
var entries = Object.entries(values);
|
|
737
|
+
if (entries.length === 0) {
|
|
738
|
+
return [];
|
|
739
|
+
}
|
|
740
|
+
var maxIndex = Math.max.apply(Math, tslib_1.__spreadArray([], tslib_1.__read(entries.map(function (_a) {
|
|
741
|
+
var _b = tslib_1.__read(_a, 1), key = _b[0];
|
|
742
|
+
return Number(key);
|
|
743
|
+
})), false));
|
|
744
|
+
var result = new Array(maxIndex + 1).fill(null);
|
|
745
|
+
entries.forEach(function (_a) {
|
|
746
|
+
var _b = tslib_1.__read(_a, 2), key = _b[0], value = _b[1];
|
|
747
|
+
result[Number(key)] = value;
|
|
748
|
+
});
|
|
749
|
+
return result;
|
|
750
|
+
}
|
|
751
|
+
/**
|
|
752
|
+
* Validate and clean sheets data
|
|
753
|
+
*/
|
|
754
|
+
var validateSheets = function (sheets) {
|
|
755
|
+
return sheets.filter(Boolean).map(function (sheet) {
|
|
756
|
+
var _a;
|
|
757
|
+
return (tslib_1.__assign(tslib_1.__assign({}, sheet), {
|
|
758
|
+
// Ensure merges is always an array and filter out falsy values
|
|
759
|
+
merges: (_a = sheet.merges) === null || _a === void 0 ? void 0 : _a.filter(Boolean) }));
|
|
760
|
+
});
|
|
761
|
+
};
|
|
762
|
+
exports.validateSheets = validateSheets;
|
|
763
|
+
/**
|
|
764
|
+
* Map operations
|
|
765
|
+
*/
|
|
766
|
+
var applyMapPatches = function (yMap, patches) {
|
|
767
|
+
var e_7, _a, e_8, _b, e_9, _c;
|
|
768
|
+
try {
|
|
769
|
+
for (var patches_14 = tslib_1.__values(patches), patches_14_1 = patches_14.next(); !patches_14_1.done; patches_14_1 = patches_14.next()) {
|
|
770
|
+
var _d = patches_14_1.value, op = _d.op, path = _d.path, value = _d.value;
|
|
771
|
+
if (!path || !path.length) {
|
|
772
|
+
if (op === "remove") {
|
|
773
|
+
// Only clear if there's something to clear
|
|
774
|
+
if (yMap.size > 0)
|
|
775
|
+
yMap.clear();
|
|
776
|
+
}
|
|
777
|
+
else if (op === "replace") {
|
|
778
|
+
// Diff against current contents instead of clear-and-rewrite, so keys
|
|
779
|
+
// whose references haven't changed don't generate Y.Map tombstones.
|
|
780
|
+
var incoming = new Map(value);
|
|
781
|
+
try {
|
|
782
|
+
for (var _e = (e_8 = void 0, tslib_1.__values(Array.from(yMap.keys()))), _f = _e.next(); !_f.done; _f = _e.next()) {
|
|
783
|
+
var k = _f.value;
|
|
784
|
+
if (!incoming.has(k))
|
|
785
|
+
yMap.delete(k);
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
catch (e_8_1) { e_8 = { error: e_8_1 }; }
|
|
789
|
+
finally {
|
|
790
|
+
try {
|
|
791
|
+
if (_f && !_f.done && (_b = _e.return)) _b.call(_e);
|
|
792
|
+
}
|
|
793
|
+
finally { if (e_8) throw e_8.error; }
|
|
794
|
+
}
|
|
795
|
+
try {
|
|
796
|
+
for (var incoming_1 = (e_9 = void 0, tslib_1.__values(incoming)), incoming_1_1 = incoming_1.next(); !incoming_1_1.done; incoming_1_1 = incoming_1.next()) {
|
|
797
|
+
var _g = tslib_1.__read(incoming_1_1.value, 2), k = _g[0], v = _g[1];
|
|
798
|
+
if (yMap.get(k) !== v)
|
|
799
|
+
yMap.set(k, v);
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
catch (e_9_1) { e_9 = { error: e_9_1 }; }
|
|
803
|
+
finally {
|
|
804
|
+
try {
|
|
805
|
+
if (incoming_1_1 && !incoming_1_1.done && (_c = incoming_1.return)) _c.call(incoming_1);
|
|
806
|
+
}
|
|
807
|
+
finally { if (e_9) throw e_9.error; }
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
continue;
|
|
811
|
+
}
|
|
812
|
+
var index = path[0];
|
|
813
|
+
if (op === "remove") {
|
|
814
|
+
if (yMap.has(index))
|
|
815
|
+
yMap.delete(index);
|
|
816
|
+
}
|
|
817
|
+
else if (op === "add" || op === "replace") {
|
|
818
|
+
if (yMap.get(index) !== value)
|
|
819
|
+
yMap.set(index, value);
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
catch (e_7_1) { e_7 = { error: e_7_1 }; }
|
|
824
|
+
finally {
|
|
825
|
+
try {
|
|
826
|
+
if (patches_14_1 && !patches_14_1.done && (_a = patches_14.return)) _a.call(patches_14);
|
|
827
|
+
}
|
|
828
|
+
finally { if (e_7) throw e_7.error; }
|
|
829
|
+
}
|
|
830
|
+
};
|
|
831
|
+
exports.applyMapPatches = applyMapPatches;
|
|
832
|
+
/**
|
|
833
|
+
* Process events to find changes in sheet data
|
|
834
|
+
* Returns a new sheet data object with only the changes applied if possible, or null if a full reload is needed
|
|
835
|
+
*/
|
|
836
|
+
var processSheetDataEvents = function (events, currentSheetData, ySheetDataV2) {
|
|
837
|
+
var e_10, _a;
|
|
838
|
+
var changes = new Map();
|
|
839
|
+
var fullReloadSheets = new Set();
|
|
840
|
+
var _loop_1 = function (event_1) {
|
|
841
|
+
var path = event_1.path;
|
|
842
|
+
if (path.length > 0) {
|
|
843
|
+
var sheetId_2 = String(path[0]);
|
|
844
|
+
if (!changes.has(sheetId_2)) {
|
|
845
|
+
changes.set(sheetId_2, new Map());
|
|
846
|
+
}
|
|
847
|
+
var rows_1 = changes.get(sheetId_2);
|
|
848
|
+
// Path structure: [sheetId, rowIndex, "values", colIndex] or [sheetId, rowIndex]
|
|
849
|
+
if (path.length >= 4 && path[2] === "values") {
|
|
850
|
+
var rowIndex = Number(path[1]);
|
|
851
|
+
var columnIndex = Number(path[3]);
|
|
852
|
+
if (!isNaN(rowIndex) && !isNaN(columnIndex)) {
|
|
853
|
+
var existing = rows_1.get(rowIndex);
|
|
854
|
+
if (existing) {
|
|
855
|
+
if (!existing.full) {
|
|
856
|
+
existing.columns.add(columnIndex);
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
else {
|
|
860
|
+
rows_1.set(rowIndex, {
|
|
861
|
+
full: false,
|
|
862
|
+
columns: new Set([columnIndex]),
|
|
863
|
+
});
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
else if (path.length >= 2) {
|
|
868
|
+
var rowIndex = Number(path[1]);
|
|
869
|
+
if (!isNaN(rowIndex)) {
|
|
870
|
+
var existing = rows_1.get(rowIndex);
|
|
871
|
+
if (existing) {
|
|
872
|
+
existing.full = true;
|
|
873
|
+
existing.columns.clear();
|
|
874
|
+
}
|
|
875
|
+
else {
|
|
876
|
+
rows_1.set(rowIndex, { full: true, columns: new Set() });
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
else if (path.length === 1) {
|
|
881
|
+
if (event_1.isYArrayEvent && event_1.delta) {
|
|
882
|
+
var index_1 = 0;
|
|
883
|
+
event_1.delta.forEach(function (op) {
|
|
884
|
+
if (op.retain) {
|
|
885
|
+
index_1 += op.retain;
|
|
886
|
+
}
|
|
887
|
+
if (op.insert) {
|
|
888
|
+
var count = Array.isArray(op.insert) ? op.insert.length : 1;
|
|
889
|
+
for (var i = 0; i < count; i++) {
|
|
890
|
+
var rowIndex = index_1 + i;
|
|
891
|
+
var existing = rows_1.get(rowIndex);
|
|
892
|
+
if (existing) {
|
|
893
|
+
existing.full = true;
|
|
894
|
+
existing.columns.clear();
|
|
895
|
+
}
|
|
896
|
+
else {
|
|
897
|
+
rows_1.set(rowIndex, { full: true, columns: new Set() });
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
index_1 += count;
|
|
901
|
+
}
|
|
902
|
+
if (op.delete) {
|
|
903
|
+
fullReloadSheets.add(sheetId_2); // Mark full sheet reload
|
|
904
|
+
}
|
|
905
|
+
});
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
};
|
|
910
|
+
try {
|
|
911
|
+
for (var events_1 = tslib_1.__values(events), events_1_1 = events_1.next(); !events_1_1.done; events_1_1 = events_1.next()) {
|
|
912
|
+
var event_1 = events_1_1.value;
|
|
913
|
+
_loop_1(event_1);
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
catch (e_10_1) { e_10 = { error: e_10_1 }; }
|
|
917
|
+
finally {
|
|
918
|
+
try {
|
|
919
|
+
if (events_1_1 && !events_1_1.done && (_a = events_1.return)) _a.call(events_1);
|
|
920
|
+
}
|
|
921
|
+
finally { if (e_10) throw e_10.error; }
|
|
922
|
+
}
|
|
923
|
+
if (changes.size > 0 || fullReloadSheets.size > 0) {
|
|
924
|
+
var next_1 = tslib_1.__assign({}, currentSheetData);
|
|
925
|
+
var hasChanges_1 = false;
|
|
926
|
+
fullReloadSheets.forEach(function (sheetId) {
|
|
927
|
+
var ySheet = ySheetDataV2.get(sheetId);
|
|
928
|
+
if (!ySheet)
|
|
929
|
+
return;
|
|
930
|
+
var sheetData = ySheet.toJSON();
|
|
931
|
+
next_1[sheetId] = sheetData;
|
|
932
|
+
hasChanges_1 = true;
|
|
933
|
+
});
|
|
934
|
+
changes.forEach(function (rowIndices, sheetId) {
|
|
935
|
+
var ySheet = ySheetDataV2.get(sheetId);
|
|
936
|
+
if (!ySheet)
|
|
937
|
+
return;
|
|
938
|
+
// If full sheet reload needed
|
|
939
|
+
if (fullReloadSheets.has(sheetId)) {
|
|
940
|
+
var sheetData = ySheet.toJSON();
|
|
941
|
+
next_1[sheetId] = sheetData;
|
|
942
|
+
hasChanges_1 = true;
|
|
943
|
+
return;
|
|
944
|
+
}
|
|
945
|
+
// Partial update
|
|
946
|
+
if (!next_1[sheetId]) {
|
|
947
|
+
next_1[sheetId] = [];
|
|
948
|
+
}
|
|
949
|
+
if (next_1[sheetId].length < ySheet.length) {
|
|
950
|
+
if (next_1[sheetId].length !== ySheet.length) {
|
|
951
|
+
var sheetData = ySheet.toJSON();
|
|
952
|
+
next_1[sheetId] = sheetData;
|
|
953
|
+
hasChanges_1 = true;
|
|
954
|
+
return;
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
var nextSheet = tslib_1.__spreadArray([], tslib_1.__read(next_1[sheetId]), false);
|
|
958
|
+
rowIndices.forEach(function (change, rowIndex) {
|
|
959
|
+
var _a;
|
|
960
|
+
if (rowIndex < 0 || rowIndex >= ySheet.length)
|
|
961
|
+
return;
|
|
962
|
+
var yRow = ySheet.get(rowIndex);
|
|
963
|
+
if (change.full) {
|
|
964
|
+
var normalizedRow = null;
|
|
965
|
+
if (yRow) {
|
|
966
|
+
var rowJson = yRow.toJSON();
|
|
967
|
+
normalizedRow = rowJson;
|
|
968
|
+
}
|
|
969
|
+
nextSheet[rowIndex] = normalizedRow;
|
|
970
|
+
}
|
|
971
|
+
else {
|
|
972
|
+
var currentRow = (_a = nextSheet[rowIndex]) !== null && _a !== void 0 ? _a : null;
|
|
973
|
+
if (!yRow) {
|
|
974
|
+
if (currentRow) {
|
|
975
|
+
nextSheet[rowIndex] = currentRow;
|
|
976
|
+
}
|
|
977
|
+
return;
|
|
978
|
+
}
|
|
979
|
+
var yValues_1 = yRow.get("values");
|
|
980
|
+
if (!yValues_1) {
|
|
981
|
+
if (currentRow) {
|
|
982
|
+
nextSheet[rowIndex] = currentRow;
|
|
983
|
+
}
|
|
984
|
+
return;
|
|
985
|
+
}
|
|
986
|
+
var baseRow = currentRow !== null && currentRow !== void 0 ? currentRow : yRow.toJSON();
|
|
987
|
+
if (!baseRow) {
|
|
988
|
+
return;
|
|
989
|
+
}
|
|
990
|
+
var baseValues = baseRow.values;
|
|
991
|
+
// Always normalize to array to ensure .entries() works in calculation code
|
|
992
|
+
var mergedValues_1 = normalizeValuesToArray(baseValues);
|
|
993
|
+
change.columns.forEach(function (columnIndex) {
|
|
994
|
+
var nextValue = yValues_1.get(columnIndex);
|
|
995
|
+
mergedValues_1[columnIndex] =
|
|
996
|
+
nextValue === undefined ? null : nextValue;
|
|
997
|
+
});
|
|
998
|
+
nextSheet[rowIndex] = tslib_1.__assign(tslib_1.__assign({}, baseRow), { values: mergedValues_1 });
|
|
999
|
+
}
|
|
1000
|
+
});
|
|
1001
|
+
next_1[sheetId] = nextSheet;
|
|
1002
|
+
hasChanges_1 = true;
|
|
1003
|
+
});
|
|
1004
|
+
return hasChanges_1 ? next_1 : null;
|
|
1005
|
+
}
|
|
1006
|
+
return null;
|
|
1007
|
+
};
|
|
1008
|
+
exports.processSheetDataEvents = processSheetDataEvents;
|
|
1009
|
+
// ============================================================================
|
|
1010
|
+
// V3 Helper Functions (Flat Map Structure)
|
|
1011
|
+
// ============================================================================
|
|
1012
|
+
/**
|
|
1013
|
+
* Convert letter to column index (1-based)
|
|
1014
|
+
* A = 1, B = 2, ..., Z = 26, AA = 27, etc.
|
|
1015
|
+
*/
|
|
1016
|
+
var letterToColumnIndex = function (letters) {
|
|
1017
|
+
return letters
|
|
1018
|
+
.toUpperCase()
|
|
1019
|
+
.split("")
|
|
1020
|
+
.reduce(function (r, a) { return r * 26 + parseInt(a, 36) - 9; }, 0);
|
|
1021
|
+
};
|
|
1022
|
+
/**
|
|
1023
|
+
* Create a V3 cell key from sheet ID, row and column indices
|
|
1024
|
+
* Format: `${sheetId}!${A1Address}` (e.g., "1!A1", "2!B5")
|
|
1025
|
+
*/
|
|
1026
|
+
var createCellKeyV3 = function (sheetId, rowIndex, columnIndex) {
|
|
1027
|
+
var _a;
|
|
1028
|
+
var address = (_a = (0, utils_1.cellToAddress)({ rowIndex: rowIndex, columnIndex: columnIndex })) !== null && _a !== void 0 ? _a : "".concat(String.fromCharCode(65 + columnIndex - 1)).concat(rowIndex);
|
|
1029
|
+
return "".concat(sheetId, "!").concat(address);
|
|
1030
|
+
};
|
|
1031
|
+
exports.createCellKeyV3 = createCellKeyV3;
|
|
1032
|
+
/**
|
|
1033
|
+
* Parse a V3 cell key to extract sheet ID and position information
|
|
1034
|
+
* Example: parseCellKeyV3("1!A1") => { sheetId: 1, address: "A1", rowIndex: 1, columnIndex: 1 }
|
|
1035
|
+
*/
|
|
1036
|
+
var parseCellKeyV3 = function (cellKey) {
|
|
1037
|
+
var match = cellKey.match(/^(\d+)!([A-Z]+)(\d+)$/i);
|
|
1038
|
+
if (!match)
|
|
1039
|
+
return null;
|
|
1040
|
+
var _a = tslib_1.__read(match, 4), sheetIdStr = _a[1], columnLetters = _a[2], rowIndexStr = _a[3];
|
|
1041
|
+
return {
|
|
1042
|
+
sheetId: Number(sheetIdStr),
|
|
1043
|
+
address: "".concat(columnLetters.toUpperCase()).concat(rowIndexStr),
|
|
1044
|
+
rowIndex: Number(rowIndexStr),
|
|
1045
|
+
columnIndex: letterToColumnIndex(columnLetters),
|
|
1046
|
+
};
|
|
1047
|
+
};
|
|
1048
|
+
exports.parseCellKeyV3 = parseCellKeyV3;
|
|
1049
|
+
/**
|
|
1050
|
+
* Create a CellDataV3 object with position and sheetId
|
|
1051
|
+
*/
|
|
1052
|
+
var createCellDataV3 = function (value, sheetId, rowIndex, columnIndex) { return ({
|
|
1053
|
+
value: value,
|
|
1054
|
+
sId: sheetId,
|
|
1055
|
+
r: rowIndex,
|
|
1056
|
+
c: columnIndex,
|
|
1057
|
+
}); };
|
|
1058
|
+
exports.createCellDataV3 = createCellDataV3;
|
|
1059
|
+
/**
|
|
1060
|
+
* Convert V2 SheetData to V3 flat Map format
|
|
1061
|
+
* V2: { sheetId: [rows with values arrays] }
|
|
1062
|
+
* V3: Map<cellKey, CellDataV3>
|
|
1063
|
+
*/
|
|
1064
|
+
var sheetDataV2ToV3 = function (v2Data) {
|
|
1065
|
+
var v3Map = new Map();
|
|
1066
|
+
var _loop_2 = function (sheetIdStr) {
|
|
1067
|
+
var sheetId = Number(sheetIdStr);
|
|
1068
|
+
var rows = v2Data[sheetId];
|
|
1069
|
+
if (!rows)
|
|
1070
|
+
return "continue";
|
|
1071
|
+
rows.forEach(function (row, rowIndex) {
|
|
1072
|
+
if (!(row === null || row === void 0 ? void 0 : row.values))
|
|
1073
|
+
return;
|
|
1074
|
+
row.values.forEach(function (cellData, colIndex) {
|
|
1075
|
+
if (cellData) {
|
|
1076
|
+
var key = (0, exports.createCellKeyV3)(sheetId, rowIndex, colIndex);
|
|
1077
|
+
v3Map.set(key, (0, exports.createCellDataV3)(cellData, sheetId, rowIndex, colIndex));
|
|
1078
|
+
}
|
|
1079
|
+
});
|
|
1080
|
+
});
|
|
1081
|
+
};
|
|
1082
|
+
for (var sheetIdStr in v2Data) {
|
|
1083
|
+
_loop_2(sheetIdStr);
|
|
1084
|
+
}
|
|
1085
|
+
return v3Map;
|
|
1086
|
+
};
|
|
1087
|
+
exports.sheetDataV2ToV3 = sheetDataV2ToV3;
|
|
1088
|
+
/**
|
|
1089
|
+
* Convert V3 flat Map format to V2 SheetData
|
|
1090
|
+
* V3: Map<cellKey, CellDataV3>
|
|
1091
|
+
* V2: { sheetId: [rows with values arrays] }
|
|
1092
|
+
*/
|
|
1093
|
+
var sheetDataV3ToV2 = function (v3Data) {
|
|
1094
|
+
var e_11, _a;
|
|
1095
|
+
var sheetData = {};
|
|
1096
|
+
try {
|
|
1097
|
+
for (var v3Data_1 = tslib_1.__values(v3Data), v3Data_1_1 = v3Data_1.next(); !v3Data_1_1.done; v3Data_1_1 = v3Data_1.next()) {
|
|
1098
|
+
var _b = tslib_1.__read(v3Data_1_1.value, 2), _1 = _b[0], cellDataV3 = _b[1];
|
|
1099
|
+
if (!cellDataV3)
|
|
1100
|
+
continue;
|
|
1101
|
+
var sheetId = cellDataV3.sId, rowIdx = cellDataV3.r, colIdx = cellDataV3.c, value = cellDataV3.value;
|
|
1102
|
+
// Ensure sheet exists
|
|
1103
|
+
if (!sheetData[sheetId]) {
|
|
1104
|
+
sheetData[sheetId] = [];
|
|
1105
|
+
}
|
|
1106
|
+
// Ensure row exists
|
|
1107
|
+
while (sheetData[sheetId].length <= rowIdx) {
|
|
1108
|
+
sheetData[sheetId].push(null);
|
|
1109
|
+
}
|
|
1110
|
+
if (!sheetData[sheetId][rowIdx]) {
|
|
1111
|
+
sheetData[sheetId][rowIdx] = { values: [] };
|
|
1112
|
+
}
|
|
1113
|
+
var row = sheetData[sheetId][rowIdx];
|
|
1114
|
+
if (!row.values)
|
|
1115
|
+
row.values = [];
|
|
1116
|
+
// Ensure values array is long enough
|
|
1117
|
+
while (row.values.length <= colIdx) {
|
|
1118
|
+
row.values.push(null);
|
|
1119
|
+
}
|
|
1120
|
+
row.values[colIdx] = value;
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
catch (e_11_1) { e_11 = { error: e_11_1 }; }
|
|
1124
|
+
finally {
|
|
1125
|
+
try {
|
|
1126
|
+
if (v3Data_1_1 && !v3Data_1_1.done && (_a = v3Data_1.return)) _a.call(v3Data_1);
|
|
1127
|
+
}
|
|
1128
|
+
finally { if (e_11) throw e_11.error; }
|
|
1129
|
+
}
|
|
1130
|
+
return sheetData;
|
|
1131
|
+
};
|
|
1132
|
+
exports.sheetDataV3ToV2 = sheetDataV3ToV2;
|
|
1133
|
+
/**
|
|
1134
|
+
* Get a cell from V3 flat structure
|
|
1135
|
+
*/
|
|
1136
|
+
var getCellV3 = function (ySheetDataV3, sheetId, rowIndex, columnIndex) {
|
|
1137
|
+
var key = (0, exports.createCellKeyV3)(sheetId, rowIndex, columnIndex);
|
|
1138
|
+
return ySheetDataV3.get(key);
|
|
1139
|
+
};
|
|
1140
|
+
exports.getCellV3 = getCellV3;
|
|
1141
|
+
/**
|
|
1142
|
+
* Set a cell in V3 flat structure
|
|
1143
|
+
*/
|
|
1144
|
+
var setCellV3 = function (ySheetDataV3, sheetId, rowIndex, columnIndex, value) {
|
|
1145
|
+
var key = (0, exports.createCellKeyV3)(sheetId, rowIndex, columnIndex);
|
|
1146
|
+
ySheetDataV3.set(key, (0, exports.createCellDataV3)(value, sheetId, rowIndex, columnIndex));
|
|
1147
|
+
};
|
|
1148
|
+
exports.setCellV3 = setCellV3;
|
|
1149
|
+
/**
|
|
1150
|
+
* Delete a cell from V3 flat structure
|
|
1151
|
+
*/
|
|
1152
|
+
var deleteCellV3 = function (ySheetDataV3, sheetId, rowIndex, columnIndex) {
|
|
1153
|
+
var key = (0, exports.createCellKeyV3)(sheetId, rowIndex, columnIndex);
|
|
1154
|
+
ySheetDataV3.delete(key);
|
|
1155
|
+
};
|
|
1156
|
+
exports.deleteCellV3 = deleteCellV3;
|
|
1157
|
+
/**
|
|
1158
|
+
* Delete all cells for a sheet from V3 flat structure
|
|
1159
|
+
*/
|
|
1160
|
+
var deleteSheetV3 = function (ySheetDataV3, sheetId) {
|
|
1161
|
+
var e_12, _a;
|
|
1162
|
+
var prefix = "".concat(sheetId, "!");
|
|
1163
|
+
try {
|
|
1164
|
+
for (var _b = tslib_1.__values(ySheetDataV3.keys()), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
1165
|
+
var key = _c.value;
|
|
1166
|
+
if (key.startsWith(prefix)) {
|
|
1167
|
+
ySheetDataV3.delete(key);
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
catch (e_12_1) { e_12 = { error: e_12_1 }; }
|
|
1172
|
+
finally {
|
|
1173
|
+
try {
|
|
1174
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
1175
|
+
}
|
|
1176
|
+
finally { if (e_12) throw e_12.error; }
|
|
1177
|
+
}
|
|
1178
|
+
};
|
|
1179
|
+
exports.deleteSheetV3 = deleteSheetV3;
|
|
1180
|
+
/**
|
|
1181
|
+
* Get V3 sheet data map from Y.Doc
|
|
1182
|
+
*/
|
|
1183
|
+
var getSheetDataV3 = function (doc) {
|
|
1184
|
+
return doc.getMap("sheetDataV3");
|
|
1185
|
+
};
|
|
1186
|
+
exports.getSheetDataV3 = getSheetDataV3;
|
|
1187
|
+
/**
|
|
1188
|
+
* Apply immer patches to V3 sheet data (flat map structure)
|
|
1189
|
+
*
|
|
1190
|
+
* Optimized for bulk operations (paste, import) by consolidating cell-level
|
|
1191
|
+
* patches before applying to Y.js. This reduces overhead by:
|
|
1192
|
+
* 1. Deduplicating patches targeting the same cell (later patches win)
|
|
1193
|
+
* 2. Processing all cell updates in a single pass
|
|
1194
|
+
*/
|
|
1195
|
+
var addSheetDataPatchesV3 = function (ySheetDataV3, patches) {
|
|
1196
|
+
var e_13, _a, e_14, _b;
|
|
1197
|
+
// Optimization: Pre-process and consolidate cell-level patches
|
|
1198
|
+
// For bulk operations like paste (10k+ rows), this dramatically reduces overhead
|
|
1199
|
+
var cellUpdates = new Map();
|
|
1200
|
+
var otherPatches = [];
|
|
1201
|
+
try {
|
|
1202
|
+
// First pass: categorize and consolidate patches
|
|
1203
|
+
for (var patches_15 = tslib_1.__values(patches), patches_15_1 = patches_15.next(); !patches_15_1.done; patches_15_1 = patches_15.next()) {
|
|
1204
|
+
var patch = patches_15_1.value;
|
|
1205
|
+
var op = patch.op, path = patch.path, value = patch.value;
|
|
1206
|
+
var _c = tslib_1.__read(path, 1), sheetIdRaw = _c[0];
|
|
1207
|
+
// Handle undefined sheetId separately (full replace)
|
|
1208
|
+
if (typeof sheetIdRaw === "undefined") {
|
|
1209
|
+
otherPatches.push(patch);
|
|
1210
|
+
continue;
|
|
1211
|
+
}
|
|
1212
|
+
var sheetId = Number(sheetIdRaw);
|
|
1213
|
+
if (op === "replace" || op === "add") {
|
|
1214
|
+
// [sheetId, rowIndex, 'values', columnIndex] - Single cell update (most common in paste)
|
|
1215
|
+
if (path.length === 4) {
|
|
1216
|
+
var _d = tslib_1.__read(path, 4), rowIndex = _d[1], columnIndex = _d[3];
|
|
1217
|
+
var rowIdx = Number(rowIndex);
|
|
1218
|
+
var colIdx = Number(columnIndex);
|
|
1219
|
+
var key = (0, exports.createCellKeyV3)(sheetId, rowIdx, colIdx);
|
|
1220
|
+
// Later patches override earlier ones for the same cell
|
|
1221
|
+
cellUpdates.set(key, { sheetId: sheetId, rowIdx: rowIdx, colIdx: colIdx, value: value });
|
|
1222
|
+
}
|
|
1223
|
+
else {
|
|
1224
|
+
// Row-level or sheet-level updates
|
|
1225
|
+
otherPatches.push(patch);
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
else if (op === "remove") {
|
|
1229
|
+
if (path.length === 4) {
|
|
1230
|
+
var _e = tslib_1.__read(path, 4), rowIndex = _e[1], columnIndex = _e[3];
|
|
1231
|
+
var rowIdx = Number(rowIndex);
|
|
1232
|
+
var colIdx = Number(columnIndex);
|
|
1233
|
+
var key = (0, exports.createCellKeyV3)(sheetId, rowIdx, colIdx);
|
|
1234
|
+
cellUpdates.set(key, { sheetId: sheetId, rowIdx: rowIdx, colIdx: colIdx, value: null });
|
|
1235
|
+
}
|
|
1236
|
+
else {
|
|
1237
|
+
otherPatches.push(patch);
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
else {
|
|
1241
|
+
otherPatches.push(patch);
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
}
|
|
1245
|
+
catch (e_13_1) { e_13 = { error: e_13_1 }; }
|
|
1246
|
+
finally {
|
|
1247
|
+
try {
|
|
1248
|
+
if (patches_15_1 && !patches_15_1.done && (_a = patches_15.return)) _a.call(patches_15);
|
|
1249
|
+
}
|
|
1250
|
+
finally { if (e_13) throw e_13.error; }
|
|
1251
|
+
}
|
|
1252
|
+
try {
|
|
1253
|
+
// Second pass: Apply consolidated cell updates in batch
|
|
1254
|
+
// This is much faster than processing each patch individually
|
|
1255
|
+
for (var cellUpdates_2 = tslib_1.__values(cellUpdates), cellUpdates_2_1 = cellUpdates_2.next(); !cellUpdates_2_1.done; cellUpdates_2_1 = cellUpdates_2.next()) {
|
|
1256
|
+
var _f = tslib_1.__read(cellUpdates_2_1.value, 2), key = _f[0], _g = _f[1], sheetId = _g.sheetId, rowIdx = _g.rowIdx, colIdx = _g.colIdx, value = _g.value;
|
|
1257
|
+
if (value) {
|
|
1258
|
+
ySheetDataV3.set(key, (0, exports.createCellDataV3)(value, sheetId, rowIdx, colIdx));
|
|
1259
|
+
}
|
|
1260
|
+
else {
|
|
1261
|
+
ySheetDataV3.delete(key);
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
}
|
|
1265
|
+
catch (e_14_1) { e_14 = { error: e_14_1 }; }
|
|
1266
|
+
finally {
|
|
1267
|
+
try {
|
|
1268
|
+
if (cellUpdates_2_1 && !cellUpdates_2_1.done && (_b = cellUpdates_2.return)) _b.call(cellUpdates_2);
|
|
1269
|
+
}
|
|
1270
|
+
finally { if (e_14) throw e_14.error; }
|
|
1271
|
+
}
|
|
1272
|
+
// Row-targeted patches (e.g. the per-shifted-row patches an immer array
|
|
1273
|
+
// splice emits for a row insert/delete) previously scanned the entire flat
|
|
1274
|
+
// cell map once per patch — O(patches × totalCells), which freezes the tab
|
|
1275
|
+
// when inserting a row near the top of a large sheet. Build a
|
|
1276
|
+
// row → cell-keys index once per batch instead, and keep it in sync as
|
|
1277
|
+
// patches apply.
|
|
1278
|
+
var rowCellKeyIndex = null;
|
|
1279
|
+
var rowIndexKey = function (sheetId, rowIdx) {
|
|
1280
|
+
return "".concat(sheetId, ":").concat(rowIdx);
|
|
1281
|
+
};
|
|
1282
|
+
var ensureRowCellKeyIndex = function () {
|
|
1283
|
+
var e_15, _a;
|
|
1284
|
+
if (rowCellKeyIndex) {
|
|
1285
|
+
return rowCellKeyIndex;
|
|
1286
|
+
}
|
|
1287
|
+
rowCellKeyIndex = new Map();
|
|
1288
|
+
try {
|
|
1289
|
+
for (var _b = tslib_1.__values(ySheetDataV3.entries()), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
1290
|
+
var _d = tslib_1.__read(_c.value, 2), key = _d[0], cellData = _d[1];
|
|
1291
|
+
var rk = rowIndexKey(cellData === null || cellData === void 0 ? void 0 : cellData.sId, cellData === null || cellData === void 0 ? void 0 : cellData.r);
|
|
1292
|
+
var keys = rowCellKeyIndex.get(rk);
|
|
1293
|
+
if (!keys) {
|
|
1294
|
+
keys = new Set();
|
|
1295
|
+
rowCellKeyIndex.set(rk, keys);
|
|
1296
|
+
}
|
|
1297
|
+
keys.add(key);
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1300
|
+
catch (e_15_1) { e_15 = { error: e_15_1 }; }
|
|
1301
|
+
finally {
|
|
1302
|
+
try {
|
|
1303
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
1304
|
+
}
|
|
1305
|
+
finally { if (e_15) throw e_15.error; }
|
|
1306
|
+
}
|
|
1307
|
+
return rowCellKeyIndex;
|
|
1308
|
+
};
|
|
1309
|
+
var trackCellKeySet = function (sheetId, rowIdx, key) {
|
|
1310
|
+
if (!rowCellKeyIndex) {
|
|
1311
|
+
return;
|
|
1312
|
+
}
|
|
1313
|
+
var rk = rowIndexKey(sheetId, rowIdx);
|
|
1314
|
+
var keys = rowCellKeyIndex.get(rk);
|
|
1315
|
+
if (!keys) {
|
|
1316
|
+
keys = new Set();
|
|
1317
|
+
rowCellKeyIndex.set(rk, keys);
|
|
1318
|
+
}
|
|
1319
|
+
keys.add(key);
|
|
1320
|
+
};
|
|
1321
|
+
var deleteRowCells = function (sheetId, rowIdx) {
|
|
1322
|
+
var e_16, _a;
|
|
1323
|
+
var keys = ensureRowCellKeyIndex().get(rowIndexKey(sheetId, rowIdx));
|
|
1324
|
+
if (!keys) {
|
|
1325
|
+
return;
|
|
1326
|
+
}
|
|
1327
|
+
try {
|
|
1328
|
+
for (var keys_1 = tslib_1.__values(keys), keys_1_1 = keys_1.next(); !keys_1_1.done; keys_1_1 = keys_1.next()) {
|
|
1329
|
+
var key = keys_1_1.value;
|
|
1330
|
+
ySheetDataV3.delete(key);
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
catch (e_16_1) { e_16 = { error: e_16_1 }; }
|
|
1334
|
+
finally {
|
|
1335
|
+
try {
|
|
1336
|
+
if (keys_1_1 && !keys_1_1.done && (_a = keys_1.return)) _a.call(keys_1);
|
|
1337
|
+
}
|
|
1338
|
+
finally { if (e_16) throw e_16.error; }
|
|
1339
|
+
}
|
|
1340
|
+
rowCellKeyIndex.delete(rowIndexKey(sheetId, rowIdx));
|
|
1341
|
+
};
|
|
1342
|
+
var dropSheetFromIndex = function (sheetId) {
|
|
1343
|
+
var e_17, _a;
|
|
1344
|
+
if (!rowCellKeyIndex) {
|
|
1345
|
+
return;
|
|
1346
|
+
}
|
|
1347
|
+
var prefix = "".concat(sheetId, ":");
|
|
1348
|
+
try {
|
|
1349
|
+
for (var _b = tslib_1.__values(Array.from(rowCellKeyIndex.keys())), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
1350
|
+
var rk = _c.value;
|
|
1351
|
+
if (rk.startsWith(prefix)) {
|
|
1352
|
+
rowCellKeyIndex.delete(rk);
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
catch (e_17_1) { e_17 = { error: e_17_1 }; }
|
|
1357
|
+
finally {
|
|
1358
|
+
try {
|
|
1359
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
1360
|
+
}
|
|
1361
|
+
finally { if (e_17) throw e_17.error; }
|
|
1362
|
+
}
|
|
1363
|
+
};
|
|
1364
|
+
// Process non-cell-level patches using original logic
|
|
1365
|
+
var processPatch = function (_a) {
|
|
1366
|
+
var e_18, _b, e_19, _c, e_20, _d;
|
|
1367
|
+
var op = _a.op, path = _a.path, value = _a.value;
|
|
1368
|
+
var _e = tslib_1.__read(path, 1), sheetIdRaw = _e[0];
|
|
1369
|
+
if (typeof sheetIdRaw === "undefined") {
|
|
1370
|
+
// Replace entire data
|
|
1371
|
+
if (op === "replace") {
|
|
1372
|
+
try {
|
|
1373
|
+
// Clear all cells
|
|
1374
|
+
for (var _f = tslib_1.__values(ySheetDataV3.keys()), _g = _f.next(); !_g.done; _g = _f.next()) {
|
|
1375
|
+
var key = _g.value;
|
|
1376
|
+
ySheetDataV3.delete(key);
|
|
1377
|
+
}
|
|
1378
|
+
}
|
|
1379
|
+
catch (e_18_1) { e_18 = { error: e_18_1 }; }
|
|
1380
|
+
finally {
|
|
1381
|
+
try {
|
|
1382
|
+
if (_g && !_g.done && (_b = _f.return)) _b.call(_f);
|
|
1383
|
+
}
|
|
1384
|
+
finally { if (e_18) throw e_18.error; }
|
|
1385
|
+
}
|
|
1386
|
+
if (rowCellKeyIndex) {
|
|
1387
|
+
rowCellKeyIndex.clear();
|
|
1388
|
+
}
|
|
1389
|
+
}
|
|
1390
|
+
var _loop_3 = function (curSheetId) {
|
|
1391
|
+
var sheetId_3 = Number(curSheetId);
|
|
1392
|
+
var rows = value[curSheetId];
|
|
1393
|
+
if (!rows)
|
|
1394
|
+
return "continue";
|
|
1395
|
+
Object.entries(rows).forEach(function (_a) {
|
|
1396
|
+
var _b = tslib_1.__read(_a, 2), rowIndexStr = _b[0], rowData = _b[1];
|
|
1397
|
+
if (!(rowData === null || rowData === void 0 ? void 0 : rowData.values))
|
|
1398
|
+
return;
|
|
1399
|
+
var rowIdx = Number(rowIndexStr);
|
|
1400
|
+
Object.entries(rowData.values).forEach(function (_a) {
|
|
1401
|
+
var _b = tslib_1.__read(_a, 2), colIndexStr = _b[0], cellData = _b[1];
|
|
1402
|
+
if (cellData) {
|
|
1403
|
+
var colIdx = Number(colIndexStr);
|
|
1404
|
+
var key = (0, exports.createCellKeyV3)(sheetId_3, rowIdx, colIdx);
|
|
1405
|
+
ySheetDataV3.set(key, (0, exports.createCellDataV3)(cellData, sheetId_3, rowIdx, colIdx));
|
|
1406
|
+
trackCellKeySet(sheetId_3, rowIdx, key);
|
|
1407
|
+
}
|
|
1408
|
+
});
|
|
1409
|
+
});
|
|
1410
|
+
};
|
|
1411
|
+
// Assign values from the replacement object
|
|
1412
|
+
for (var curSheetId in value) {
|
|
1413
|
+
_loop_3(curSheetId);
|
|
1414
|
+
}
|
|
1415
|
+
return;
|
|
1416
|
+
}
|
|
1417
|
+
var sheetId = Number(sheetIdRaw);
|
|
1418
|
+
if (op === "replace" || op === "add") {
|
|
1419
|
+
// Cell-level patches (path.length === 4) are already handled above via consolidation
|
|
1420
|
+
// [sheetId, rowIndex, 'values', columnIndex, ...nestedPath] - Deep nested property update
|
|
1421
|
+
if (path.length > 4) {
|
|
1422
|
+
var _h = tslib_1.__read(path), rowIndex = _h[1], columnIndex = _h[3], nestedPath = _h.slice(4);
|
|
1423
|
+
var rowIdx = Number(rowIndex);
|
|
1424
|
+
var colIdx = Number(columnIndex);
|
|
1425
|
+
var key = (0, exports.createCellKeyV3)(sheetId, rowIdx, colIdx);
|
|
1426
|
+
// Get existing cell data or create empty
|
|
1427
|
+
var existing = ySheetDataV3.get(key);
|
|
1428
|
+
var cellData = (existing === null || existing === void 0 ? void 0 : existing.value) ? (0, cloneDeep_1.default)(existing.value) : {};
|
|
1429
|
+
// Apply nested property change
|
|
1430
|
+
(0, set_1.default)(cellData, nestedPath, value);
|
|
1431
|
+
ySheetDataV3.set(key, (0, exports.createCellDataV3)(cellData, sheetId, rowIdx, colIdx));
|
|
1432
|
+
trackCellKeySet(sheetId, rowIdx, key);
|
|
1433
|
+
}
|
|
1434
|
+
// [sheetId, rowIndex, 'values'] - Replace values array
|
|
1435
|
+
else if (path.length === 3 && path[2] === "values") {
|
|
1436
|
+
var _j = tslib_1.__read(path, 2), rowIndex = _j[1];
|
|
1437
|
+
var rowIdx_1 = Number(rowIndex);
|
|
1438
|
+
// Delete existing cells for this row
|
|
1439
|
+
deleteRowCells(sheetId, rowIdx_1);
|
|
1440
|
+
// Add new cells
|
|
1441
|
+
if (Array.isArray(value)) {
|
|
1442
|
+
value.forEach(function (cellData, colIndex) {
|
|
1443
|
+
if (cellData) {
|
|
1444
|
+
var key = (0, exports.createCellKeyV3)(sheetId, rowIdx_1, colIndex);
|
|
1445
|
+
ySheetDataV3.set(key, (0, exports.createCellDataV3)(cellData, sheetId, rowIdx_1, colIndex));
|
|
1446
|
+
trackCellKeySet(sheetId, rowIdx_1, key);
|
|
1447
|
+
}
|
|
1448
|
+
});
|
|
1449
|
+
}
|
|
1450
|
+
}
|
|
1451
|
+
// [sheetId, rowIndex] - Entire row update
|
|
1452
|
+
else if (path.length === 2) {
|
|
1453
|
+
var _k = tslib_1.__read(path, 2), rowIndex = _k[1];
|
|
1454
|
+
var rowIdx_2 = Number(rowIndex);
|
|
1455
|
+
// Delete existing cells for this row
|
|
1456
|
+
deleteRowCells(sheetId, rowIdx_2);
|
|
1457
|
+
// Add new cells from row data
|
|
1458
|
+
if (value === null || value === void 0 ? void 0 : value.values) {
|
|
1459
|
+
Object.entries(value.values).forEach(function (_a) {
|
|
1460
|
+
var _b = tslib_1.__read(_a, 2), colIndexStr = _b[0], cellData = _b[1];
|
|
1461
|
+
if (cellData) {
|
|
1462
|
+
var colIndex = Number(colIndexStr);
|
|
1463
|
+
var key = (0, exports.createCellKeyV3)(sheetId, rowIdx_2, colIndex);
|
|
1464
|
+
ySheetDataV3.set(key, (0, exports.createCellDataV3)(cellData, sheetId, rowIdx_2, colIndex));
|
|
1465
|
+
trackCellKeySet(sheetId, rowIdx_2, key);
|
|
1466
|
+
}
|
|
1467
|
+
});
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
1470
|
+
// [sheetId] - Entire sheet update
|
|
1471
|
+
else if (path.length === 1) {
|
|
1472
|
+
// Delete all cells for this sheet
|
|
1473
|
+
var prefix = "".concat(sheetId, "!");
|
|
1474
|
+
try {
|
|
1475
|
+
for (var _l = tslib_1.__values(ySheetDataV3.keys()), _m = _l.next(); !_m.done; _m = _l.next()) {
|
|
1476
|
+
var key = _m.value;
|
|
1477
|
+
if (key.startsWith(prefix)) {
|
|
1478
|
+
ySheetDataV3.delete(key);
|
|
1479
|
+
}
|
|
1480
|
+
}
|
|
1481
|
+
}
|
|
1482
|
+
catch (e_19_1) { e_19 = { error: e_19_1 }; }
|
|
1483
|
+
finally {
|
|
1484
|
+
try {
|
|
1485
|
+
if (_m && !_m.done && (_c = _l.return)) _c.call(_l);
|
|
1486
|
+
}
|
|
1487
|
+
finally { if (e_19) throw e_19.error; }
|
|
1488
|
+
}
|
|
1489
|
+
dropSheetFromIndex(sheetId);
|
|
1490
|
+
// Add all new data
|
|
1491
|
+
if (value) {
|
|
1492
|
+
Object.entries(value).forEach(function (_a) {
|
|
1493
|
+
var _b = tslib_1.__read(_a, 2), rowIndexStr = _b[0], rowData = _b[1];
|
|
1494
|
+
if (rowData === null || rowData === void 0 ? void 0 : rowData.values) {
|
|
1495
|
+
var rowIdx_3 = Number(rowIndexStr);
|
|
1496
|
+
Object.entries(rowData.values).forEach(function (_a) {
|
|
1497
|
+
var _b = tslib_1.__read(_a, 2), colIndexStr = _b[0], cellData = _b[1];
|
|
1498
|
+
if (cellData) {
|
|
1499
|
+
var colIndex = Number(colIndexStr);
|
|
1500
|
+
var key = (0, exports.createCellKeyV3)(sheetId, rowIdx_3, colIndex);
|
|
1501
|
+
ySheetDataV3.set(key, (0, exports.createCellDataV3)(cellData, sheetId, rowIdx_3, colIndex));
|
|
1502
|
+
trackCellKeySet(sheetId, rowIdx_3, key);
|
|
1503
|
+
}
|
|
1504
|
+
});
|
|
1505
|
+
}
|
|
1506
|
+
});
|
|
1507
|
+
}
|
|
1508
|
+
}
|
|
1509
|
+
}
|
|
1510
|
+
else if (op === "remove") {
|
|
1511
|
+
// Cell-level removes (path.length === 4) are already handled above via consolidation
|
|
1512
|
+
// [sheetId, rowIndex, values, columnIndex, ...nestedPath] - Remove nested property
|
|
1513
|
+
if (path.length > 4) {
|
|
1514
|
+
var _o = tslib_1.__read(path), rowIndex = _o[1], columnIndex = _o[3], nestedPath = _o.slice(4);
|
|
1515
|
+
var rowIdx = Number(rowIndex);
|
|
1516
|
+
var colIdx = Number(columnIndex);
|
|
1517
|
+
var key = (0, exports.createCellKeyV3)(sheetId, rowIdx, colIdx);
|
|
1518
|
+
var existing = ySheetDataV3.get(key);
|
|
1519
|
+
if ((existing === null || existing === void 0 ? void 0 : existing.value) && typeof existing.value === "object") {
|
|
1520
|
+
var cellData = (0, cloneDeep_1.default)(existing.value);
|
|
1521
|
+
(0, unset_1.default)(cellData, nestedPath);
|
|
1522
|
+
ySheetDataV3.set(key, (0, exports.createCellDataV3)(cellData, sheetId, rowIdx, colIdx));
|
|
1523
|
+
trackCellKeySet(sheetId, rowIdx, key);
|
|
1524
|
+
}
|
|
1525
|
+
}
|
|
1526
|
+
// [sheetId, rowIndex] - Remove entire row
|
|
1527
|
+
else if (path.length === 2) {
|
|
1528
|
+
var _p = tslib_1.__read(path, 2), rowIndex = _p[1];
|
|
1529
|
+
var rowIdx = Number(rowIndex);
|
|
1530
|
+
deleteRowCells(sheetId, rowIdx);
|
|
1531
|
+
}
|
|
1532
|
+
// [sheetId] - Remove entire sheet
|
|
1533
|
+
else if (path.length === 1) {
|
|
1534
|
+
var prefix = "".concat(sheetId, "!");
|
|
1535
|
+
try {
|
|
1536
|
+
for (var _q = tslib_1.__values(ySheetDataV3.keys()), _r = _q.next(); !_r.done; _r = _q.next()) {
|
|
1537
|
+
var key = _r.value;
|
|
1538
|
+
if (key.startsWith(prefix)) {
|
|
1539
|
+
ySheetDataV3.delete(key);
|
|
1540
|
+
}
|
|
1541
|
+
}
|
|
1542
|
+
}
|
|
1543
|
+
catch (e_20_1) { e_20 = { error: e_20_1 }; }
|
|
1544
|
+
finally {
|
|
1545
|
+
try {
|
|
1546
|
+
if (_r && !_r.done && (_d = _q.return)) _d.call(_q);
|
|
1547
|
+
}
|
|
1548
|
+
finally { if (e_20) throw e_20.error; }
|
|
1549
|
+
}
|
|
1550
|
+
dropSheetFromIndex(sheetId);
|
|
1551
|
+
}
|
|
1552
|
+
}
|
|
1553
|
+
};
|
|
1554
|
+
// Only process non-cell-level patches (cell-level already handled via consolidation)
|
|
1555
|
+
otherPatches.forEach(processPatch);
|
|
1556
|
+
};
|
|
1557
|
+
exports.addSheetDataPatchesV3 = addSheetDataPatchesV3;
|
|
1558
|
+
/**
|
|
1559
|
+
* Process V3 events and return updated sheet data
|
|
1560
|
+
* @param changedKeys - Pre-extracted changes from Yjs event
|
|
1561
|
+
* @param currentSheetData - Current sheet data state
|
|
1562
|
+
* @param ySheetDataV3 - The Y.Map for V3 data
|
|
1563
|
+
*/
|
|
1564
|
+
var processSheetDataEventsV3 = function (changedKeys, currentSheetData, ySheetDataV3) {
|
|
1565
|
+
if (changedKeys.size === 0)
|
|
1566
|
+
return null;
|
|
1567
|
+
var next = tslib_1.__assign({}, currentSheetData);
|
|
1568
|
+
// Track which sheets/rows have been cloned to avoid re-cloning
|
|
1569
|
+
var clonedSheets = new Set();
|
|
1570
|
+
var clonedRows = new Map(); // "sheetId:rowIdx" -> cloned
|
|
1571
|
+
var hasChanges = false;
|
|
1572
|
+
changedKeys.forEach(function (change, cellKey) {
|
|
1573
|
+
var parsed = (0, exports.parseCellKeyV3)(cellKey);
|
|
1574
|
+
if (!parsed)
|
|
1575
|
+
return;
|
|
1576
|
+
var sheetId = parsed.sheetId, rowIndex = parsed.rowIndex, columnIndex = parsed.columnIndex;
|
|
1577
|
+
var rowIdx = rowIndex;
|
|
1578
|
+
var colIdx = columnIndex;
|
|
1579
|
+
var rowKey = "".concat(sheetId, ":").concat(rowIdx);
|
|
1580
|
+
// Ensure sheet exists and is cloned (to avoid mutating frozen React state)
|
|
1581
|
+
if (!next[sheetId]) {
|
|
1582
|
+
next[sheetId] = [];
|
|
1583
|
+
clonedSheets.add(sheetId);
|
|
1584
|
+
}
|
|
1585
|
+
else if (!clonedSheets.has(sheetId)) {
|
|
1586
|
+
// Clone the sheet array to avoid mutating frozen state
|
|
1587
|
+
next[sheetId] = tslib_1.__spreadArray([], tslib_1.__read(next[sheetId]), false);
|
|
1588
|
+
clonedSheets.add(sheetId);
|
|
1589
|
+
}
|
|
1590
|
+
var sheet = next[sheetId];
|
|
1591
|
+
// Extend array efficiently using length assignment instead of while loop
|
|
1592
|
+
if (sheet.length <= rowIdx) {
|
|
1593
|
+
sheet.length = rowIdx + 1;
|
|
1594
|
+
}
|
|
1595
|
+
if (change.action === "delete") {
|
|
1596
|
+
// Cell was deleted
|
|
1597
|
+
var row = sheet[rowIdx];
|
|
1598
|
+
if ((row === null || row === void 0 ? void 0 : row.values) && colIdx < row.values.length && row.values[colIdx]) {
|
|
1599
|
+
// Clone row values only once per row
|
|
1600
|
+
if (!clonedRows.has(rowKey)) {
|
|
1601
|
+
sheet[rowIdx] = tslib_1.__assign(tslib_1.__assign({}, row), { values: tslib_1.__spreadArray([], tslib_1.__read(row.values), false) });
|
|
1602
|
+
clonedRows.set(rowKey, true);
|
|
1603
|
+
}
|
|
1604
|
+
sheet[rowIdx].values[colIdx] = null;
|
|
1605
|
+
hasChanges = true;
|
|
1606
|
+
}
|
|
1607
|
+
}
|
|
1608
|
+
else {
|
|
1609
|
+
// Cell was added or updated
|
|
1610
|
+
var cellDataV3 = ySheetDataV3.get(cellKey);
|
|
1611
|
+
if (cellDataV3) {
|
|
1612
|
+
// Ensure row exists
|
|
1613
|
+
if (!sheet[rowIdx]) {
|
|
1614
|
+
sheet[rowIdx] = { values: [] };
|
|
1615
|
+
clonedRows.set(rowKey, true);
|
|
1616
|
+
}
|
|
1617
|
+
else if (!clonedRows.has(rowKey)) {
|
|
1618
|
+
// Clone row values only once per row
|
|
1619
|
+
var row = sheet[rowIdx];
|
|
1620
|
+
sheet[rowIdx] = tslib_1.__assign(tslib_1.__assign({}, row), { values: row.values ? tslib_1.__spreadArray([], tslib_1.__read(row.values), false) : [] });
|
|
1621
|
+
clonedRows.set(rowKey, true);
|
|
1622
|
+
}
|
|
1623
|
+
var values = sheet[rowIdx].values;
|
|
1624
|
+
// Extend array efficiently using length assignment
|
|
1625
|
+
if (values.length <= colIdx) {
|
|
1626
|
+
values.length = colIdx + 1;
|
|
1627
|
+
}
|
|
1628
|
+
values[colIdx] = cellDataV3.value;
|
|
1629
|
+
hasChanges = true;
|
|
1630
|
+
}
|
|
1631
|
+
}
|
|
1632
|
+
});
|
|
1633
|
+
return hasChanges ? next : null;
|
|
1634
|
+
};
|
|
1635
|
+
exports.processSheetDataEventsV3 = processSheetDataEventsV3;
|