@ai-matrx/office 0.8.20 → 0.8.22
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/CHANGELOG.md +21 -2
- package/dist/collab-sheets-transform.cjs +471 -17
- package/dist/collab-sheets-transform.cjs.map +1 -1
- package/dist/collab-sheets-transform.d.cts +32 -4
- package/dist/collab-sheets-transform.d.ts +32 -4
- package/dist/collab-sheets-transform.js +471 -17
- package/dist/collab-sheets-transform.js.map +1 -1
- package/dist/univer-collab.cjs +536 -28
- package/dist/univer-collab.cjs.map +1 -1
- package/dist/univer-collab.d.cts +6 -1
- package/dist/univer-collab.d.ts +6 -1
- package/dist/univer-collab.js +536 -28
- package/dist/univer-collab.js.map +1 -1
- package/package.json +4 -4
package/dist/univer-collab.cjs
CHANGED
|
@@ -1758,6 +1758,15 @@ var SHEET_MUTATIONS = {
|
|
|
1758
1758
|
"sheet.mutation.set-worksheet-row-auto-height": covered("size", "rowsAutoHeightInfo"),
|
|
1759
1759
|
"sheet.mutation.set-worksheet-col-width": covered("size", "ranges", "colWidth"),
|
|
1760
1760
|
"sheet.mutation.set-worksheet-name": covered("name", "name"),
|
|
1761
|
+
// ── covered (C5c) ────────────────────────────────────────────────────────────────────────────────
|
|
1762
|
+
"sheet.mutation.set.numfmt": covered("numfmt", "values", "refMap"),
|
|
1763
|
+
"sheet.mutation.remove.numfmt": covered("numfmt", "ranges"),
|
|
1764
|
+
"sheet.mutation.set-worksheet-row-count": covered("count", "rowCount"),
|
|
1765
|
+
"sheet.mutation.set-worksheet-column-count": covered("count", "columnCount"),
|
|
1766
|
+
"sheet.mutation.insert-sheet": covered("sheet", "index", "sheet"),
|
|
1767
|
+
"sheet.mutation.remove-sheet": covered("sheet", "sheetIndex", "sheetsLeft"),
|
|
1768
|
+
"sheet.mutation.set-worksheet-order": covered("sheet", "fromOrder", "toOrder"),
|
|
1769
|
+
"sheet.mutation.reorder-range": covered("sort", "range", "order"),
|
|
1761
1770
|
// ── never travels ────────────────────────────────────────────────────────────────────────────────
|
|
1762
1771
|
"formula.mutation.set-formula-calculation-start": never(FORMULA_RESULT),
|
|
1763
1772
|
"formula.mutation.set-trigger-formula-calculation-start": never(FORMULA_RESULT),
|
|
@@ -1791,13 +1800,7 @@ var SHEET_MUTATIONS = {
|
|
|
1791
1800
|
"thread-comment.mutation.resolve-comment": never(UNIVER_COMMENTS),
|
|
1792
1801
|
"thread-comment.mutation.delete-comment": never(UNIVER_COMMENTS),
|
|
1793
1802
|
// ── barriers: X (no transform yet, design §10) ───────────────────────────────────────────────────
|
|
1794
|
-
"sheet.mutation.reorder-range": barrier("X", "sort: a permutation, not transformed yet"),
|
|
1795
|
-
"sheet.mutation.set-worksheet-row-count": barrier("X", "absolute row count; needs delta semantics"),
|
|
1796
|
-
"sheet.mutation.set-worksheet-column-count": barrier("X", "absolute column count; needs delta semantics"),
|
|
1797
|
-
"sheet.mutation.set-worksheet-order": barrier("X", "absolute sheet order; needs move semantics"),
|
|
1798
1803
|
"sheet.mutation.move-range": barrier("X", "cut-paste carries the sender's cell matrices"),
|
|
1799
|
-
"sheet.mutation.insert-sheet": barrier("X", "sheet add: not in C5a"),
|
|
1800
|
-
"sheet.mutation.remove-sheet": barrier("X", "sheet remove: not in C5a"),
|
|
1801
1804
|
"sheet.mutation.set-worksheet-hidden": barrier("X", "sheet-level setting: not in C5a"),
|
|
1802
1805
|
"sheet.mutation.set-tab-color": barrier("X", "sheet-level setting: not in C5a"),
|
|
1803
1806
|
"sheet.mutation.set-workbook-name": barrier("X", "workbook-level setting: not in C5a"),
|
|
@@ -1812,8 +1815,6 @@ var SHEET_MUTATIONS = {
|
|
|
1812
1815
|
"sheet.mutation.set-row-visible": barrier("X", "row visibility: not in C5a"),
|
|
1813
1816
|
"sheet.mutation.set-col-hidden": barrier("X", "column visibility: not in C5a"),
|
|
1814
1817
|
"sheet.mutation.set-col-visible": barrier("X", "column visibility: not in C5a"),
|
|
1815
|
-
"sheet.mutation.set.numfmt": barrier("X", "number formats by range: not in C5a"),
|
|
1816
|
-
"sheet.mutation.remove.numfmt": barrier("X", "number formats by range: not in C5a"),
|
|
1817
1818
|
"sheet.mutation.add-range-protection": barrier("X", "permissions: not in C5a"),
|
|
1818
1819
|
"sheet.mutation.set-range-protection": barrier("X", "permissions: not in C5a"),
|
|
1819
1820
|
"sheet.mutation.delete-range-protection": barrier("X", "permissions: not in C5a"),
|
|
@@ -2208,7 +2209,7 @@ function refSheetsFor(texts, sheets) {
|
|
|
2208
2209
|
}
|
|
2209
2210
|
|
|
2210
2211
|
// src/collab/sheets/transform/transform.ts
|
|
2211
|
-
var SHEET_TRANSFORMER_VERSION = "
|
|
2212
|
+
var SHEET_TRANSFORMER_VERSION = "c5c-1";
|
|
2212
2213
|
var ID = {
|
|
2213
2214
|
values: "sheet.mutation.set-range-values",
|
|
2214
2215
|
insertRow: "sheet.mutation.insert-row",
|
|
@@ -2225,7 +2226,15 @@ var ID = {
|
|
|
2225
2226
|
colWidth: "sheet.mutation.set-worksheet-col-width",
|
|
2226
2227
|
name: "sheet.mutation.set-worksheet-name",
|
|
2227
2228
|
setName: "formula.mutation.set-defined-name",
|
|
2228
|
-
removeName: "formula.mutation.remove-defined-name"
|
|
2229
|
+
removeName: "formula.mutation.remove-defined-name",
|
|
2230
|
+
setNumfmt: "sheet.mutation.set.numfmt",
|
|
2231
|
+
removeNumfmt: "sheet.mutation.remove.numfmt",
|
|
2232
|
+
rowCount: "sheet.mutation.set-worksheet-row-count",
|
|
2233
|
+
colCount: "sheet.mutation.set-worksheet-column-count",
|
|
2234
|
+
insertSheet: "sheet.mutation.insert-sheet",
|
|
2235
|
+
removeSheet: "sheet.mutation.remove-sheet",
|
|
2236
|
+
sheetOrder: "sheet.mutation.set-worksheet-order",
|
|
2237
|
+
sort: "sheet.mutation.reorder-range"
|
|
2229
2238
|
};
|
|
2230
2239
|
var PAIR_BARRIERS = {};
|
|
2231
2240
|
var pairKey = (a, b) => a < b ? `${a}|${b}` : `${b}|${a}`;
|
|
@@ -2337,6 +2346,20 @@ function mergeThrough(s, m) {
|
|
|
2337
2346
|
}
|
|
2338
2347
|
return { range: m, fixup: false };
|
|
2339
2348
|
}
|
|
2349
|
+
function mergeFixupsOwed(m, mergesBefore) {
|
|
2350
|
+
const st = structuralOf(m);
|
|
2351
|
+
if (!st) return null;
|
|
2352
|
+
const remove = [];
|
|
2353
|
+
const add = [];
|
|
2354
|
+
for (const q of mergesBefore) {
|
|
2355
|
+
const t = mergeThrough(st, q);
|
|
2356
|
+
if (!t.fixup) continue;
|
|
2357
|
+
remove.push({ startRow: q.startRow, endRow: q.endRow, startColumn: q.startColumn, endColumn: q.endColumn, ...q.rangeType !== void 0 ? { rangeType: q.rangeType } : {} });
|
|
2358
|
+
if (t.range) add.push({ ...t.range });
|
|
2359
|
+
}
|
|
2360
|
+
return remove.length ? { remove, add } : null;
|
|
2361
|
+
}
|
|
2362
|
+
var isStructuralMutation = (m) => structuralOf(m) !== null;
|
|
2340
2363
|
function exactMergeRemovals(group, merges) {
|
|
2341
2364
|
const sim = new Map(Object.entries(merges).map(([k, v]) => [k, v.map((r) => ({ ...r }))]));
|
|
2342
2365
|
const out = [];
|
|
@@ -2383,8 +2406,24 @@ function cellsMutation(template, cells) {
|
|
|
2383
2406
|
function putCell(cells, r, c, v) {
|
|
2384
2407
|
(cells[r] ??= {})[c] = v;
|
|
2385
2408
|
}
|
|
2409
|
+
function cellsOverlap(a, b) {
|
|
2410
|
+
for (const r of Object.keys(a)) {
|
|
2411
|
+
const br = b[r];
|
|
2412
|
+
if (!br) continue;
|
|
2413
|
+
for (const c of Object.keys(a[r] ?? {})) if (c in br) return true;
|
|
2414
|
+
}
|
|
2415
|
+
return false;
|
|
2416
|
+
}
|
|
2386
2417
|
var isEmptyMatrix = (cells) => Object.values(cells).every((row) => Object.keys(row).length === 0);
|
|
2418
|
+
var cellBarrierCache = /* @__PURE__ */ new WeakMap();
|
|
2387
2419
|
function cellBarrier(m) {
|
|
2420
|
+
const hit = cellBarrierCache.get(m);
|
|
2421
|
+
if (hit !== void 0) return hit;
|
|
2422
|
+
const why = cellBarrierOf(m);
|
|
2423
|
+
cellBarrierCache.set(m, why);
|
|
2424
|
+
return why;
|
|
2425
|
+
}
|
|
2426
|
+
function cellBarrierOf(m) {
|
|
2388
2427
|
if (m.params.isOverrideStyle) return "set-range-values with isOverrideStyle (whole-style replace) is not covered";
|
|
2389
2428
|
let why = null;
|
|
2390
2429
|
forEachCell(cellsOf(m), (_r, _c, v) => {
|
|
@@ -2466,6 +2505,7 @@ function transformCell(X, Y4, side) {
|
|
|
2466
2505
|
function transformCellsOverCells(x, y, side) {
|
|
2467
2506
|
if (sheetOf(x) !== sheetOf(y)) return ok([x]);
|
|
2468
2507
|
const ycells = cellsOf(y);
|
|
2508
|
+
if (!cellsOverlap(cellsOf(x), ycells)) return ok([x]);
|
|
2469
2509
|
const xd = isDerived(x);
|
|
2470
2510
|
const yd = isDerived(y);
|
|
2471
2511
|
const eff = derivedSide(x, y, side);
|
|
@@ -2493,7 +2533,7 @@ function transformCellsOverCells(x, y, side) {
|
|
|
2493
2533
|
const op = passes.filter((p) => !isEmptyMatrix(p)).map((p) => cellsMutation(x, p));
|
|
2494
2534
|
return ok(op, lost, dropped);
|
|
2495
2535
|
}
|
|
2496
|
-
var SIDE_CAR_PARAMS = ["refSheets", "previousName", "derived"];
|
|
2536
|
+
var SIDE_CAR_PARAMS = ["refSheets", "previousName", "derived", "sheetIndex", "sheetsLeft"];
|
|
2497
2537
|
var isDerived = (m) => m.params.derived === true;
|
|
2498
2538
|
function derivedSide(x, y, side) {
|
|
2499
2539
|
const xd = isDerived(x);
|
|
@@ -2515,7 +2555,15 @@ function withRefSheets(params, rs) {
|
|
|
2515
2555
|
return out;
|
|
2516
2556
|
}
|
|
2517
2557
|
var hasFormulaText = (v) => !!v && (isFormulaText(v.f) || typeof v.ref === "string");
|
|
2558
|
+
var hasFormulaCache = /* @__PURE__ */ new WeakMap();
|
|
2518
2559
|
function hasFormula(m) {
|
|
2560
|
+
const hit = hasFormulaCache.get(m);
|
|
2561
|
+
if (hit !== void 0) return hit;
|
|
2562
|
+
const any = hasFormulaOf(m);
|
|
2563
|
+
hasFormulaCache.set(m, any);
|
|
2564
|
+
return any;
|
|
2565
|
+
}
|
|
2566
|
+
function hasFormulaOf(m) {
|
|
2519
2567
|
let any = false;
|
|
2520
2568
|
forEachCell(cellsOf(m), (_r, _c, v) => {
|
|
2521
2569
|
any ||= hasFormulaText(v);
|
|
@@ -2554,15 +2602,18 @@ function cellThrough(sheet, change, r, c) {
|
|
|
2554
2602
|
return nr === null || nc === null ? null : [nr, nc];
|
|
2555
2603
|
}
|
|
2556
2604
|
function cellsOverChange(x, change) {
|
|
2605
|
+
if (!hasFormula(x) && (change.kind !== "axis" || change.sheet !== sheetOf(x))) return ok([x]);
|
|
2557
2606
|
const ctx = formulaCtx(x);
|
|
2558
2607
|
const out = {};
|
|
2559
2608
|
const dropped = [];
|
|
2560
2609
|
let why = null;
|
|
2610
|
+
let changed = false;
|
|
2561
2611
|
forEachCell(cellsOf(x), (r, c, v) => {
|
|
2562
2612
|
if (why) return;
|
|
2563
2613
|
const at = cellThrough(sheetOf(x), change, r, c);
|
|
2564
2614
|
if (!at) {
|
|
2565
2615
|
dropped.push(cellRef(sheetOf(x), r, c));
|
|
2616
|
+
changed = true;
|
|
2566
2617
|
return;
|
|
2567
2618
|
}
|
|
2568
2619
|
let e = v;
|
|
@@ -2573,14 +2624,19 @@ function cellsOverChange(x, change) {
|
|
|
2573
2624
|
return;
|
|
2574
2625
|
}
|
|
2575
2626
|
e = res.entry;
|
|
2627
|
+
if (res.changed) changed = true;
|
|
2576
2628
|
}
|
|
2629
|
+
if (at[0] !== r || at[1] !== c) changed = true;
|
|
2577
2630
|
putCell(out, at[0], at[1], e);
|
|
2578
2631
|
});
|
|
2579
2632
|
if (why) return barrier2(why);
|
|
2580
|
-
const
|
|
2633
|
+
const rsAfter = refSheetsAfter(ctx.refSheets, change);
|
|
2634
|
+
if (!changed && JSON.stringify(rsAfter ?? null) === JSON.stringify(ctx.refSheets ?? null)) return ok([x]);
|
|
2635
|
+
const params = { ...withRefSheets(x.params, rsAfter), cellValue: out };
|
|
2581
2636
|
return ok(isEmptyMatrix(out) ? [] : [{ id: x.id, params }], [], dropped);
|
|
2582
2637
|
}
|
|
2583
2638
|
function rewritesOf(y, change) {
|
|
2639
|
+
if (!hasFormula(y)) return null;
|
|
2584
2640
|
const ctx = formulaCtx(y);
|
|
2585
2641
|
const out = {};
|
|
2586
2642
|
let why = null;
|
|
@@ -2726,6 +2782,368 @@ function buildSize(template, values) {
|
|
|
2726
2782
|
const value = uniform !== void 0 && [...values.values()].every((v) => v === uniform) ? uniform : Object.fromEntries(values);
|
|
2727
2783
|
return { id: template.id, params: { ...p, ranges, [field]: value } };
|
|
2728
2784
|
}
|
|
2785
|
+
var isNumfmt = (m) => m.id === ID.setNumfmt || m.id === ID.removeNumfmt;
|
|
2786
|
+
function nfParts(m) {
|
|
2787
|
+
if (m.id === ID.removeNumfmt) return [{ key: null, ranges: (m.params.ranges ?? []).map((r) => ({ ...r })) }];
|
|
2788
|
+
const values = m.params.values ?? {};
|
|
2789
|
+
return Object.keys(values).map((k) => ({ key: k, ranges: (values[k]?.ranges ?? []).map((r) => ({ ...r })) }));
|
|
2790
|
+
}
|
|
2791
|
+
function nfBuild(m, parts) {
|
|
2792
|
+
const keep = parts.filter((p) => p.ranges.length);
|
|
2793
|
+
if (!keep.length) return [];
|
|
2794
|
+
if (m.id === ID.removeNumfmt) return [{ id: m.id, params: { ...m.params, ranges: keep[0].ranges } }];
|
|
2795
|
+
const values = {};
|
|
2796
|
+
const refMap = {};
|
|
2797
|
+
const srcValues = m.params.values ?? {};
|
|
2798
|
+
const srcRef = m.params.refMap ?? {};
|
|
2799
|
+
for (const p of keep) {
|
|
2800
|
+
values[p.key] = { ...srcValues[p.key], ranges: p.ranges };
|
|
2801
|
+
refMap[p.key] = srcRef[p.key];
|
|
2802
|
+
}
|
|
2803
|
+
return [{ id: m.id, params: { ...m.params, values, refMap } }];
|
|
2804
|
+
}
|
|
2805
|
+
function nfValueAt(m, row, col) {
|
|
2806
|
+
for (const p of nfParts(m))
|
|
2807
|
+
if (p.ranges.some((r) => r.startRow <= row && row <= r.endRow && r.startColumn <= col && col <= r.endColumn)) {
|
|
2808
|
+
if (p.key === null) return null;
|
|
2809
|
+
const ref = (m.params.refMap ?? {})[p.key];
|
|
2810
|
+
return { pattern: ref?.pattern };
|
|
2811
|
+
}
|
|
2812
|
+
return void 0;
|
|
2813
|
+
}
|
|
2814
|
+
function spanThrough(op, lo, hi) {
|
|
2815
|
+
const pieces = [];
|
|
2816
|
+
if (op.kind === "insert") pieces.push([0, op.at - 1, 0], [op.at, Infinity, op.count]);
|
|
2817
|
+
else if (op.kind === "remove") pieces.push([0, op.start - 1, 0], [op.start + op.count, Infinity, -op.count]);
|
|
2818
|
+
else if (op.count <= 0 || op.to >= op.from && op.to <= op.from + op.count) pieces.push([0, Infinity, 0]);
|
|
2819
|
+
else if (op.to > op.from) {
|
|
2820
|
+
const n = op.count;
|
|
2821
|
+
pieces.push([0, op.from - 1, 0], [op.from, op.from + n - 1, op.to - n - op.from], [op.from + n, op.to - 1, -n], [op.to, Infinity, 0]);
|
|
2822
|
+
} else {
|
|
2823
|
+
const n = op.count;
|
|
2824
|
+
pieces.push([0, op.to - 1, 0], [op.to, op.from - 1, n], [op.from, op.from + n - 1, op.to - op.from], [op.from + n, Infinity, 0]);
|
|
2825
|
+
}
|
|
2826
|
+
const out = [];
|
|
2827
|
+
for (const [a, b, d] of pieces) {
|
|
2828
|
+
const x0 = Math.max(a, lo);
|
|
2829
|
+
const x1 = Math.min(b, hi);
|
|
2830
|
+
if (x0 <= x1) out.push([x0 + d, x1 + d]);
|
|
2831
|
+
}
|
|
2832
|
+
out.sort((p, q) => p[0] - q[0]);
|
|
2833
|
+
const merged = [];
|
|
2834
|
+
for (const p of out) {
|
|
2835
|
+
const last = merged[merged.length - 1];
|
|
2836
|
+
if (last && last[1] + 1 >= p[0]) last[1] = Math.max(last[1], p[1]);
|
|
2837
|
+
else merged.push([p[0], p[1]]);
|
|
2838
|
+
}
|
|
2839
|
+
return merged;
|
|
2840
|
+
}
|
|
2841
|
+
function rectsThrough(st, rects) {
|
|
2842
|
+
const [a0, a1] = S(st.axis);
|
|
2843
|
+
const out = [];
|
|
2844
|
+
for (const r of rects) for (const [lo, hi] of spanThrough(st.op, r[a0], r[a1])) out.push({ ...r, [a0]: lo, [a1]: hi });
|
|
2845
|
+
return out;
|
|
2846
|
+
}
|
|
2847
|
+
function rectMinus(a, b) {
|
|
2848
|
+
if (a.startRow > b.endRow || b.startRow > a.endRow || a.startColumn > b.endColumn || b.startColumn > a.endColumn) return [a];
|
|
2849
|
+
const out = [];
|
|
2850
|
+
if (a.startRow < b.startRow) out.push({ ...a, endRow: b.startRow - 1 });
|
|
2851
|
+
if (a.endRow > b.endRow) out.push({ ...a, startRow: b.endRow + 1 });
|
|
2852
|
+
const r0 = Math.max(a.startRow, b.startRow);
|
|
2853
|
+
const r1 = Math.min(a.endRow, b.endRow);
|
|
2854
|
+
if (a.startColumn < b.startColumn) out.push({ ...a, startRow: r0, endRow: r1, endColumn: b.startColumn - 1 });
|
|
2855
|
+
if (a.endColumn > b.endColumn) out.push({ ...a, startRow: r0, endRow: r1, startColumn: b.endColumn + 1 });
|
|
2856
|
+
return out;
|
|
2857
|
+
}
|
|
2858
|
+
function rectsMinus(as, bs) {
|
|
2859
|
+
let cur = as;
|
|
2860
|
+
for (const b of bs) cur = cur.flatMap((a) => rectMinus(a, b));
|
|
2861
|
+
return cur;
|
|
2862
|
+
}
|
|
2863
|
+
function nWrites(m) {
|
|
2864
|
+
const out = [];
|
|
2865
|
+
forEachCell(cellsOf(m), (r, c, v) => {
|
|
2866
|
+
if (v === null || v.s === null || v.s && typeof v.s === "object" && "n" in v.s)
|
|
2867
|
+
out.push({ startRow: r, endRow: r, startColumn: c, endColumn: c });
|
|
2868
|
+
});
|
|
2869
|
+
return out;
|
|
2870
|
+
}
|
|
2871
|
+
function numfmtPair(x, y, side, sx, sy) {
|
|
2872
|
+
const nx = isNumfmt(x);
|
|
2873
|
+
const ny = isNumfmt(y);
|
|
2874
|
+
if (!nx && !ny) return null;
|
|
2875
|
+
if (nx && sy) return ok(nfBuild(x, nfParts(x).map((p) => ({ ...p, ranges: rectsThrough(sy, p.ranges) }))));
|
|
2876
|
+
if (ny && sx) return ok([x]);
|
|
2877
|
+
if (nx && ny) {
|
|
2878
|
+
if (side === "left") return ok([x]);
|
|
2879
|
+
const ys = nfParts(y).flatMap((p) => p.ranges);
|
|
2880
|
+
return ok(nfBuild(x, nfParts(x).map((p) => ({ ...p, ranges: rectsMinus(p.ranges, ys) }))));
|
|
2881
|
+
}
|
|
2882
|
+
if (nx && y.id === ID.values) {
|
|
2883
|
+
if (side === "left") return ok([x]);
|
|
2884
|
+
const ys = nWrites(y);
|
|
2885
|
+
return ys.length ? ok(nfBuild(x, nfParts(x).map((p) => ({ ...p, ranges: rectsMinus(p.ranges, ys) })))) : ok([x]);
|
|
2886
|
+
}
|
|
2887
|
+
if (ny && x.id === ID.values) {
|
|
2888
|
+
if (side === "left") return ok([x]);
|
|
2889
|
+
const out = {};
|
|
2890
|
+
const tail = {};
|
|
2891
|
+
let touched = false;
|
|
2892
|
+
forEachCell(cellsOf(x), (r, c, v) => {
|
|
2893
|
+
const n = nfValueAt(y, r, c);
|
|
2894
|
+
if (n === void 0) return putCell(out, r, c, v);
|
|
2895
|
+
if (v === null || v.s === null) {
|
|
2896
|
+
putCell(out, r, c, v);
|
|
2897
|
+
if (n) {
|
|
2898
|
+
putCell(tail, r, c, { s: { n } });
|
|
2899
|
+
touched = true;
|
|
2900
|
+
}
|
|
2901
|
+
return;
|
|
2902
|
+
}
|
|
2903
|
+
if (v.s && typeof v.s === "object" && "n" in v.s) {
|
|
2904
|
+
const { n: _drop, ...rest } = v.s;
|
|
2905
|
+
const e = { ...v };
|
|
2906
|
+
if (Object.keys(rest).length) e.s = rest;
|
|
2907
|
+
else delete e.s;
|
|
2908
|
+
touched = true;
|
|
2909
|
+
if (Object.keys(e).length) putCell(out, r, c, e);
|
|
2910
|
+
return;
|
|
2911
|
+
}
|
|
2912
|
+
putCell(out, r, c, v);
|
|
2913
|
+
});
|
|
2914
|
+
if (!touched) return ok([x]);
|
|
2915
|
+
const ops = [];
|
|
2916
|
+
if (!isEmptyMatrix(out)) ops.push(cellsMutation(x, out));
|
|
2917
|
+
if (!isEmptyMatrix(tail)) ops.push({ id: ID.values, params: { subUnitId: sheetOf(x), cellValue: tail } });
|
|
2918
|
+
return ok(ops);
|
|
2919
|
+
}
|
|
2920
|
+
return ok([x]);
|
|
2921
|
+
}
|
|
2922
|
+
var isCount = (m) => m.id === ID.rowCount || m.id === ID.colCount;
|
|
2923
|
+
var countAxis = (m) => m.id === ID.rowCount ? "row" : "col";
|
|
2924
|
+
var countKey = (m) => m.id === ID.rowCount ? "rowCount" : "columnCount";
|
|
2925
|
+
function countPair(x, y, sy) {
|
|
2926
|
+
if (!isCount(x)) return isCount(y) ? ok([x]) : null;
|
|
2927
|
+
const k = countKey(x);
|
|
2928
|
+
const v = Number(x.params[k]);
|
|
2929
|
+
if (sy) {
|
|
2930
|
+
if (sy.axis !== countAxis(x) || sy.op.kind === "move") return ok([x]);
|
|
2931
|
+
const d = sy.op.kind === "insert" ? sy.op.count : -sy.op.count;
|
|
2932
|
+
return ok([{ id: x.id, params: { ...x.params, [k]: Math.max(1, v + d) } }]);
|
|
2933
|
+
}
|
|
2934
|
+
if (isCount(y) && y.id === x.id) {
|
|
2935
|
+
const w = Number(y.params[k]);
|
|
2936
|
+
return ok([w > v ? { id: x.id, params: { ...x.params, [k]: w } } : x]);
|
|
2937
|
+
}
|
|
2938
|
+
return ok([x]);
|
|
2939
|
+
}
|
|
2940
|
+
var isSheetOp = (m) => m.id === ID.insertSheet || m.id === ID.removeSheet || m.id === ID.sheetOrder;
|
|
2941
|
+
var sheetIdOf = (m) => m.id === ID.insertSheet ? String(m.params.sheet?.id ?? "") : sheetOf(m);
|
|
2942
|
+
function sheetAxisOf(m) {
|
|
2943
|
+
const p = m.params;
|
|
2944
|
+
if (m.id === ID.insertSheet) return typeof p.index === "number" ? { kind: "insert", at: p.index, count: 1 } : null;
|
|
2945
|
+
if (m.id === ID.removeSheet) return typeof p.sheetIndex === "number" ? { kind: "remove", start: p.sheetIndex, count: 1 } : null;
|
|
2946
|
+
if (m.id === ID.sheetOrder) {
|
|
2947
|
+
const f = Number(p.fromOrder);
|
|
2948
|
+
const t = Number(p.toOrder);
|
|
2949
|
+
return { kind: "move", from: f, count: 1, to: t > f ? t + 1 : t };
|
|
2950
|
+
}
|
|
2951
|
+
return null;
|
|
2952
|
+
}
|
|
2953
|
+
function buildSheetOp(template, op) {
|
|
2954
|
+
if (op.kind === "insert") return { id: template.id, params: { ...template.params, index: op.at } };
|
|
2955
|
+
if (op.kind === "remove") return { id: template.id, params: { ...template.params, sheetIndex: op.start } };
|
|
2956
|
+
return { id: template.id, params: { ...template.params, fromOrder: op.from, toOrder: op.to > op.from ? op.to - 1 : op.to } };
|
|
2957
|
+
}
|
|
2958
|
+
function namesSheet(m, id) {
|
|
2959
|
+
const rs = refSheetsOf(m);
|
|
2960
|
+
return !!rs && Object.values(rs).includes(id) && (m.id === ID.setName || hasFormula(m));
|
|
2961
|
+
}
|
|
2962
|
+
function sheetPair(x, y, side) {
|
|
2963
|
+
const xs = isSheetOp(x);
|
|
2964
|
+
const ys = isSheetOp(y);
|
|
2965
|
+
if (!xs && !ys) return null;
|
|
2966
|
+
if (xs && ys) {
|
|
2967
|
+
const a = sheetAxisOf(x);
|
|
2968
|
+
const b = sheetAxisOf(y);
|
|
2969
|
+
if (!a || !b) return barrier2("a sheet add or remove without its index (capture must call annotateSheetOps)");
|
|
2970
|
+
if (x.id === ID.insertSheet && y.id === ID.insertSheet && sheetIdOf(x) === sheetIdOf(y)) {
|
|
2971
|
+
return JSON.stringify(x.params) === JSON.stringify(y.params) ? ok([]) : barrier2("the same sheet id added twice with different content");
|
|
2972
|
+
}
|
|
2973
|
+
if (x.id === ID.removeSheet && typeof x.params.sheetsLeft === "number" && sheetIdOf(x) !== sheetIdOf(y) && (y.id === ID.removeSheet || y.id === ID.insertSheet)) {
|
|
2974
|
+
const left = x.params.sheetsLeft + (y.id === ID.insertSheet ? 1 : -1);
|
|
2975
|
+
if (left < 1) return barrier2("concurrent sheet removes would leave the workbook without a sheet");
|
|
2976
|
+
const out2 = transformAxis(a, b, side);
|
|
2977
|
+
if (!out2) return barrier2("sheet order: no transform");
|
|
2978
|
+
return ok(out2.map((o) => buildSheetOp({ id: x.id, params: { ...x.params, sheetsLeft: left } }, o)));
|
|
2979
|
+
}
|
|
2980
|
+
const out = transformAxis(a, b, side);
|
|
2981
|
+
if (!out) return barrier2("sheet order: no transform");
|
|
2982
|
+
return ok(out.map((o) => buildSheetOp(x, o)), [], out.length === 0 && x.id === ID.sheetOrder ? [`${sheetIdOf(x)}: sheet order`] : []);
|
|
2983
|
+
}
|
|
2984
|
+
if (ys) {
|
|
2985
|
+
if (y.id !== ID.removeSheet) return ok([x]);
|
|
2986
|
+
const gone2 = sheetOf(y);
|
|
2987
|
+
if (namesSheet(x, gone2)) return barrier2("a formula names a sheet removed at the same time");
|
|
2988
|
+
if (sheetOf(x) === gone2 && x.id !== ID.setName && x.id !== ID.removeName)
|
|
2989
|
+
return ok([], [], isDerived(x) ? [] : [`${gone2}: the sheet was removed`]);
|
|
2990
|
+
return ok([x]);
|
|
2991
|
+
}
|
|
2992
|
+
if (x.id !== ID.removeSheet) return ok([x]);
|
|
2993
|
+
const gone = sheetOf(x);
|
|
2994
|
+
if (namesSheet(y, gone)) return barrier2("a formula names a sheet removed at the same time");
|
|
2995
|
+
return ok([x], sheetOf(y) === gone && !isDerived(y) && y.id !== ID.setName && y.id !== ID.removeName ? [`${gone}: the sheet was removed`] : []);
|
|
2996
|
+
}
|
|
2997
|
+
function annotateSheetOps(group, sheetOrder) {
|
|
2998
|
+
const order = [...sheetOrder];
|
|
2999
|
+
return group.map((m) => {
|
|
3000
|
+
if (m.id === ID.insertSheet) {
|
|
3001
|
+
const index = typeof m.params.index === "number" ? Math.min(m.params.index, order.length) : order.length;
|
|
3002
|
+
order.splice(index, 0, sheetIdOf(m));
|
|
3003
|
+
return index === m.params.index ? m : { id: m.id, params: { ...m.params, index } };
|
|
3004
|
+
}
|
|
3005
|
+
if (m.id === ID.removeSheet) {
|
|
3006
|
+
const i = order.indexOf(sheetOf(m));
|
|
3007
|
+
if (i >= 0) order.splice(i, 1);
|
|
3008
|
+
return i >= 0 ? { id: m.id, params: { ...m.params, sheetIndex: i, sheetsLeft: order.length } } : m;
|
|
3009
|
+
}
|
|
3010
|
+
if (m.id === ID.sheetOrder) {
|
|
3011
|
+
const f = Number(m.params.fromOrder);
|
|
3012
|
+
const [id] = order.splice(f, 1);
|
|
3013
|
+
order.splice(Number(m.params.toOrder), 0, id ?? sheetOf(m));
|
|
3014
|
+
}
|
|
3015
|
+
return m;
|
|
3016
|
+
});
|
|
3017
|
+
}
|
|
3018
|
+
function inlineSheetStyles(sheet, styleOf) {
|
|
3019
|
+
const out = JSON.parse(JSON.stringify(sheet));
|
|
3020
|
+
const fix = (o) => {
|
|
3021
|
+
if (o && typeof o.s === "string") {
|
|
3022
|
+
const st = styleOf(o.s);
|
|
3023
|
+
if (st) o.s = JSON.parse(JSON.stringify(st));
|
|
3024
|
+
}
|
|
3025
|
+
};
|
|
3026
|
+
for (const row of Object.values(out.cellData ?? {})) for (const cell of Object.values(row ?? {})) fix(cell);
|
|
3027
|
+
for (const key of ["rowData", "columnData"]) for (const v of Object.values(out[key] ?? {})) fix(v);
|
|
3028
|
+
if (typeof out.defaultStyle === "string") {
|
|
3029
|
+
const st = styleOf(out.defaultStyle);
|
|
3030
|
+
if (st) out.defaultStyle = JSON.parse(JSON.stringify(st));
|
|
3031
|
+
}
|
|
3032
|
+
return out;
|
|
3033
|
+
}
|
|
3034
|
+
var isSort = (m) => m.id === ID.sort;
|
|
3035
|
+
function sortOf(m) {
|
|
3036
|
+
const P = /* @__PURE__ */ new Map();
|
|
3037
|
+
for (const [t, src] of Object.entries(m.params.order ?? {})) P.set(Number(t), Number(src));
|
|
3038
|
+
return { range: { ...m.params.range }, P };
|
|
3039
|
+
}
|
|
3040
|
+
var sortQ = (o) => new Map([...o.P].map(([t, s0]) => [s0, t]));
|
|
3041
|
+
function buildSort(template, o) {
|
|
3042
|
+
const order = {};
|
|
3043
|
+
for (const [t, s0] of [...o.P].sort((a, b) => a[0] - b[0])) if (t !== s0) order[t] = s0;
|
|
3044
|
+
if (!Object.keys(order).length || o.range.startRow > o.range.endRow || o.range.startColumn > o.range.endColumn) return [];
|
|
3045
|
+
return [{ id: template.id, params: { ...template.params, range: o.range, order } }];
|
|
3046
|
+
}
|
|
3047
|
+
var inSortCols = (o, c) => c >= o.range.startColumn && c <= o.range.endColumn;
|
|
3048
|
+
function sortThrough(o, st) {
|
|
3049
|
+
const r = o.range;
|
|
3050
|
+
if (st.axis === "col") {
|
|
3051
|
+
if (st.op.kind === "move") {
|
|
3052
|
+
const { from, count, to } = st.op;
|
|
3053
|
+
const touches = !(from + count - 1 < r.startColumn || from > r.endColumn) || to > r.startColumn && to <= r.endColumn;
|
|
3054
|
+
if (touches) return null;
|
|
3055
|
+
const spans3 = spanThrough(st.op, r.startColumn, r.endColumn);
|
|
3056
|
+
return spans3.length === 1 ? { range: { ...r, startColumn: spans3[0][0], endColumn: spans3[0][1] }, P: o.P } : null;
|
|
3057
|
+
}
|
|
3058
|
+
const spans2 = spanThrough(st.op, r.startColumn, r.endColumn);
|
|
3059
|
+
if (!spans2.length) return { range: { ...r, startColumn: 1, endColumn: 0 }, P: /* @__PURE__ */ new Map() };
|
|
3060
|
+
return { range: { ...r, startColumn: spans2[0][0], endColumn: spans2[spans2.length - 1][1] }, P: o.P };
|
|
3061
|
+
}
|
|
3062
|
+
const op = st.op;
|
|
3063
|
+
if (op.kind === "move") {
|
|
3064
|
+
const touches = !(op.from + op.count - 1 < r.startRow || op.from > r.endRow) || op.to > r.startRow && op.to <= r.endRow;
|
|
3065
|
+
if (touches) return null;
|
|
3066
|
+
}
|
|
3067
|
+
if (op.kind === "insert" || op.kind === "move") {
|
|
3068
|
+
const P2 = /* @__PURE__ */ new Map();
|
|
3069
|
+
for (const [t, s0] of o.P) P2.set(mapIndex(op, t), mapIndex(op, s0));
|
|
3070
|
+
const spans2 = spanThrough(op, r.startRow, r.endRow);
|
|
3071
|
+
return { range: { ...r, startRow: spans2[0][0], endRow: spans2[spans2.length - 1][1] }, P: P2 };
|
|
3072
|
+
}
|
|
3073
|
+
const removed = (i) => i >= op.start && i < op.start + op.count;
|
|
3074
|
+
const Q = sortQ(o);
|
|
3075
|
+
const goneTargets = [];
|
|
3076
|
+
for (let i = op.start; i < op.start + op.count; i++) goneTargets.push(Q.get(i) ?? i);
|
|
3077
|
+
goneTargets.sort((a, b) => a - b);
|
|
3078
|
+
const compact = (t) => t - goneTargets.filter((g) => g < t).length;
|
|
3079
|
+
const P = /* @__PURE__ */ new Map();
|
|
3080
|
+
for (const [t, s0] of o.P) if (!removed(s0)) P.set(compact(t), mapIndex(op, s0));
|
|
3081
|
+
const spans = spanThrough(op, r.startRow, r.endRow);
|
|
3082
|
+
if (!spans.length) return { range: { ...r, startRow: 1, endRow: 0 }, P: /* @__PURE__ */ new Map() };
|
|
3083
|
+
return { range: { ...r, startRow: spans[0][0], endRow: spans[spans.length - 1][1] }, P };
|
|
3084
|
+
}
|
|
3085
|
+
function sortPair(x, y, sx, sy) {
|
|
3086
|
+
const xs = isSort(x);
|
|
3087
|
+
const ys = isSort(y);
|
|
3088
|
+
if (!xs && !ys) return null;
|
|
3089
|
+
if (xs && ys) {
|
|
3090
|
+
const a = sortOf(x).range;
|
|
3091
|
+
const b = sortOf(y).range;
|
|
3092
|
+
const overlap = a.startRow <= b.endRow && b.startRow <= a.endRow && a.startColumn <= b.endColumn && b.startColumn <= a.endColumn;
|
|
3093
|
+
return overlap ? barrier2("two sorts of overlapping ranges at once") : ok([x]);
|
|
3094
|
+
}
|
|
3095
|
+
if (xs) {
|
|
3096
|
+
if (sy) {
|
|
3097
|
+
const t = sortThrough(sortOf(x), sy);
|
|
3098
|
+
return t ? ok(buildSort(x, t)) : barrier2("a row or column move through a sorted range");
|
|
3099
|
+
}
|
|
3100
|
+
return ok([x]);
|
|
3101
|
+
}
|
|
3102
|
+
const o = sortOf(y);
|
|
3103
|
+
const Q = sortQ(o);
|
|
3104
|
+
const moved = (r) => r >= o.range.startRow && r <= o.range.endRow && Q.has(r);
|
|
3105
|
+
if (sx) {
|
|
3106
|
+
if (sx.axis === "col") return sx.op.kind === "move" && !sortThrough(o, sx) ? barrier2("a column move through a sorted range") : ok([x]);
|
|
3107
|
+
if (sx.op.kind === "insert") return ok([x]);
|
|
3108
|
+
if (sx.op.kind === "move") return sortThrough(o, sx) ? ok([x]) : barrier2("a row move through a sorted range");
|
|
3109
|
+
const rows = [];
|
|
3110
|
+
let partial = false;
|
|
3111
|
+
for (let i = sx.op.start; i < sx.op.start + sx.op.count; i++) {
|
|
3112
|
+
if (moved(i)) partial = true;
|
|
3113
|
+
rows.push(Q.get(i) ?? i);
|
|
3114
|
+
}
|
|
3115
|
+
if (partial) return barrier2("a row remove against a concurrent sort of those rows");
|
|
3116
|
+
return ok([x]);
|
|
3117
|
+
}
|
|
3118
|
+
if (x.id === ID.values) {
|
|
3119
|
+
const out = {};
|
|
3120
|
+
let changed = false;
|
|
3121
|
+
forEachCell(cellsOf(x), (r, c, v) => {
|
|
3122
|
+
if (inSortCols(o, c) && moved(r)) {
|
|
3123
|
+
putCell(out, Q.get(r), c, v);
|
|
3124
|
+
changed = true;
|
|
3125
|
+
} else putCell(out, r, c, v);
|
|
3126
|
+
});
|
|
3127
|
+
return changed ? ok([cellsMutation(x, out)]) : ok([x]);
|
|
3128
|
+
}
|
|
3129
|
+
if (isNumfmt(x)) {
|
|
3130
|
+
const parts = nfParts(x).map((p) => {
|
|
3131
|
+
const ranges = [];
|
|
3132
|
+
for (const rc of p.ranges) {
|
|
3133
|
+
const inner = { ...rc, startRow: Math.max(rc.startRow, o.range.startRow), endRow: Math.min(rc.endRow, o.range.endRow), startColumn: Math.max(rc.startColumn, o.range.startColumn), endColumn: Math.min(rc.endColumn, o.range.endColumn) };
|
|
3134
|
+
if (inner.startRow > inner.endRow || inner.startColumn > inner.endColumn) {
|
|
3135
|
+
ranges.push(rc);
|
|
3136
|
+
continue;
|
|
3137
|
+
}
|
|
3138
|
+
ranges.push(...rectMinus(rc, inner));
|
|
3139
|
+
for (let r = inner.startRow; r <= inner.endRow; r++) ranges.push({ ...inner, startRow: Q.get(r) ?? r, endRow: Q.get(r) ?? r });
|
|
3140
|
+
}
|
|
3141
|
+
return { ...p, ranges };
|
|
3142
|
+
});
|
|
3143
|
+
return ok(nfBuild(x, parts));
|
|
3144
|
+
}
|
|
3145
|
+
return ok([x]);
|
|
3146
|
+
}
|
|
2729
3147
|
function familyOf(id) {
|
|
2730
3148
|
const e = SHEET_MUTATIONS[id];
|
|
2731
3149
|
return e && e.kind === "covered" ? e.family : "";
|
|
@@ -2742,6 +3160,8 @@ function transformMutation(x, y, side) {
|
|
|
2742
3160
|
}
|
|
2743
3161
|
const pb = PAIR_BARRIERS[pairKey(x.id, y.id)];
|
|
2744
3162
|
if (pb) return barrier2(`${x.id} \xD7 ${y.id}: ${pb.reason}${pb.seed === null ? "" : ` (fuzz seed ${pb.seed})`}`);
|
|
3163
|
+
const sp = sheetPair(x, y, side);
|
|
3164
|
+
if (sp) return sp;
|
|
2745
3165
|
const fp = formulaPair(x, y, side);
|
|
2746
3166
|
if (fp) return fp;
|
|
2747
3167
|
if (sheetOf(x) !== sheetOf(y)) return ok([x]);
|
|
@@ -2749,6 +3169,12 @@ function transformMutation(x, y, side) {
|
|
|
2749
3169
|
const fy = familyOf(y.id);
|
|
2750
3170
|
const sy = structuralOf(y);
|
|
2751
3171
|
const sx = structuralOf(x);
|
|
3172
|
+
const sortp = sortPair(x, y, sx, sy);
|
|
3173
|
+
if (sortp) return sortp;
|
|
3174
|
+
const cp = countPair(x, y, sy);
|
|
3175
|
+
if (cp) return cp;
|
|
3176
|
+
const np = numfmtPair(x, y, side, sx, sy);
|
|
3177
|
+
if (np) return np;
|
|
2752
3178
|
if (sx && sy) {
|
|
2753
3179
|
if (sx.axis !== sy.axis) return ok([x]);
|
|
2754
3180
|
const out = transformAxis(sx.op, sy.op, side);
|
|
@@ -2856,22 +3282,45 @@ function tSeq(xs, ys, side, acc) {
|
|
|
2856
3282
|
acc.dropped.push(...a.dropped);
|
|
2857
3283
|
return [a.op, b.op];
|
|
2858
3284
|
}
|
|
3285
|
+
const outX = [];
|
|
3286
|
+
let curY = ys;
|
|
3287
|
+
for (const x of xs) {
|
|
3288
|
+
let curX = [x];
|
|
3289
|
+
const nextY = [];
|
|
3290
|
+
for (const y of curY) {
|
|
3291
|
+
if (curX.length === 0) {
|
|
3292
|
+
nextY.push(y);
|
|
3293
|
+
continue;
|
|
3294
|
+
}
|
|
3295
|
+
const r = tSeq(curX, [y], side, acc);
|
|
3296
|
+
if (blocked(r)) return r;
|
|
3297
|
+
curX = r[0];
|
|
3298
|
+
for (const m of r[1]) nextY.push(m);
|
|
3299
|
+
}
|
|
3300
|
+
for (const m of curX) outX.push(m);
|
|
3301
|
+
curY = nextY;
|
|
3302
|
+
}
|
|
3303
|
+
return [outX, curY];
|
|
3304
|
+
}
|
|
3305
|
+
function tSeqOld(xs, ys, side, acc) {
|
|
3306
|
+
if (xs.length === 0 || ys.length === 0) return [xs, ys];
|
|
3307
|
+
if (xs.length === 1 && ys.length === 1) return tSeq(xs, ys, side, acc);
|
|
2859
3308
|
if (xs.length > 1) {
|
|
2860
|
-
const first2 =
|
|
3309
|
+
const first2 = tSeqOld([xs[0]], ys, side, acc);
|
|
2861
3310
|
if (blocked(first2)) return first2;
|
|
2862
|
-
const rest2 =
|
|
3311
|
+
const rest2 = tSeqOld(xs.slice(1), first2[1], side, acc);
|
|
2863
3312
|
if (blocked(rest2)) return rest2;
|
|
2864
3313
|
return [[...first2[0], ...rest2[0]], rest2[1]];
|
|
2865
3314
|
}
|
|
2866
|
-
const first =
|
|
3315
|
+
const first = tSeqOld(xs, [ys[0]], side, acc);
|
|
2867
3316
|
if (blocked(first)) return first;
|
|
2868
|
-
const rest =
|
|
3317
|
+
const rest = tSeqOld(first[0], ys.slice(1), side, acc);
|
|
2869
3318
|
if (blocked(rest)) return rest;
|
|
2870
3319
|
return [rest[0], [...first[1], ...rest[1]]];
|
|
2871
3320
|
}
|
|
2872
3321
|
function transformGroup(x, y, side) {
|
|
2873
3322
|
const acc = { lost: [], dropped: [] };
|
|
2874
|
-
const r = tSeq([...x], [...y], side, acc);
|
|
3323
|
+
const r = (process.env.OLD_TSEQ ? tSeqOld : tSeq)([...x], [...y], side, acc);
|
|
2875
3324
|
if (blocked(r)) return r;
|
|
2876
3325
|
return { op: r[0], lost: [...new Set(acc.lost)], dropped: [...new Set(acc.dropped)] };
|
|
2877
3326
|
}
|
|
@@ -2941,7 +3390,7 @@ async function sheetsStateHash(snapshot) {
|
|
|
2941
3390
|
}
|
|
2942
3391
|
|
|
2943
3392
|
// src/univer/collab/sheets-ot/room.ts
|
|
2944
|
-
var SHEETS_COLLAB_PROTO =
|
|
3393
|
+
var SHEETS_COLLAB_PROTO = 2;
|
|
2945
3394
|
var SHEETS_EDIT_GROUP = "sheets.edit";
|
|
2946
3395
|
var flip2 = (side) => side === "left" ? "right" : "left";
|
|
2947
3396
|
var isNoopSheetOp = (op) => op == null || op.length === 0;
|
|
@@ -2988,6 +3437,11 @@ function travelingShape(m) {
|
|
|
2988
3437
|
}
|
|
2989
3438
|
return { id: m.id, params };
|
|
2990
3439
|
}
|
|
3440
|
+
var shapedLists = /* @__PURE__ */ new WeakMap();
|
|
3441
|
+
function cachedShape(list) {
|
|
3442
|
+
const hit = shapedLists.get(list);
|
|
3443
|
+
return hit && hit.src.length === list.length && hit.src.every((m, i) => m === list[i]) ? hit.shaped : null;
|
|
3444
|
+
}
|
|
2991
3445
|
function rebaseSheetUndoStack(items, remote, unitId) {
|
|
2992
3446
|
if (isNoopSheetOp(remote)) return 0;
|
|
2993
3447
|
let dropped = 0;
|
|
@@ -2999,7 +3453,11 @@ function rebaseSheetUndoStack(items, remote, unitId) {
|
|
|
2999
3453
|
if (!ok2 || !list?.length) continue;
|
|
3000
3454
|
const isOperation = (id) => !SHEET_MUTATIONS[id] && id.includes(".operation.");
|
|
3001
3455
|
const operations = list.filter((m) => isOperation(m.id));
|
|
3002
|
-
|
|
3456
|
+
let shaped = cachedShape(list);
|
|
3457
|
+
if (!shaped) {
|
|
3458
|
+
shaped = list.filter((m) => !isOperation(m.id)).map(travelingShape);
|
|
3459
|
+
shapedLists.set(list, { src: list.slice(), shaped });
|
|
3460
|
+
}
|
|
3003
3461
|
if (shaped.some((m) => m === null)) {
|
|
3004
3462
|
ok2 = false;
|
|
3005
3463
|
continue;
|
|
@@ -3011,8 +3469,10 @@ function rebaseSheetUndoStack(items, remote, unitId) {
|
|
|
3011
3469
|
ok2 = false;
|
|
3012
3470
|
continue;
|
|
3013
3471
|
}
|
|
3014
|
-
if (
|
|
3015
|
-
|
|
3472
|
+
if (r.op.length === shaped.length && r.op.every((m, i2) => m === shaped[i2])) continue;
|
|
3473
|
+
const next = [...r.op.map((m) => ({ id: m.id, params: { ...forApply(m).params, unitId } })), ...operations];
|
|
3474
|
+
shapedLists.set(next, { src: next.slice(), shaped: r.op });
|
|
3475
|
+
item[key] = next;
|
|
3016
3476
|
} catch {
|
|
3017
3477
|
ok2 = false;
|
|
3018
3478
|
}
|
|
@@ -3087,7 +3547,7 @@ function createSheetsOtAdapter(port, hooks = {}) {
|
|
|
3087
3547
|
});
|
|
3088
3548
|
});
|
|
3089
3549
|
}
|
|
3090
|
-
return sheetsStateHash(port.snapshot());
|
|
3550
|
+
return (hooks.stateHash ?? sheetsStateHash)(port.snapshot());
|
|
3091
3551
|
},
|
|
3092
3552
|
held: () => queue.length,
|
|
3093
3553
|
rebaseLocalOverHeld(local) {
|
|
@@ -3199,6 +3659,8 @@ var VALUES = "sheet.mutation.set-range-values";
|
|
|
3199
3659
|
var ADD_MERGE = "sheet.mutation.add-worksheet-merge";
|
|
3200
3660
|
var REMOVE_MERGE = "sheet.mutation.remove-worksheet-merge";
|
|
3201
3661
|
var SHEET_NAME = "sheet.mutation.set-worksheet-name";
|
|
3662
|
+
var INSERT_SHEET = "sheet.mutation.insert-sheet";
|
|
3663
|
+
var RESHAPE = /* @__PURE__ */ new Set(["sheet.mutation.set-worksheet-row-count", "sheet.mutation.set-worksheet-column-count", "sheet.mutation.remove-sheet", INSERT_SHEET]);
|
|
3202
3664
|
var DEPTH_GUARD = /* @__PURE__ */ Symbol.for("ai-matrx.office.sheets.command-depth-guard");
|
|
3203
3665
|
var json = (v) => v === void 0 ? v : JSON.parse(JSON.stringify(v));
|
|
3204
3666
|
var flagged = (options) => {
|
|
@@ -3235,7 +3697,8 @@ function univerSheetsOtPort(o) {
|
|
|
3235
3697
|
for (const [id, d] of Object.entries(map)) out[id] = String(d?.name ?? "");
|
|
3236
3698
|
return out;
|
|
3237
3699
|
};
|
|
3238
|
-
const
|
|
3700
|
+
const sheetOrder = () => (o.workbook()?.getSheets() ?? []).map((ws) => ws.getSheetId());
|
|
3701
|
+
const openGroup = (label) => ({ label, order: sheetOrder(), sheets: sheetNames(), names: definedNames(), mutations: [], inverses: [], notShared: null });
|
|
3239
3702
|
const emit = (e) => {
|
|
3240
3703
|
for (const l of [...listeners]) {
|
|
3241
3704
|
try {
|
|
@@ -3251,7 +3714,8 @@ function univerSheetsOtPort(o) {
|
|
|
3251
3714
|
if (!g) return;
|
|
3252
3715
|
if (g.notShared) emit({ kind: "not_shared", mutationId: g.notShared, label: g.label });
|
|
3253
3716
|
else if (g.mutations.length) {
|
|
3254
|
-
const mutations = annotateFormulas(g.mutations, g.sheets, g.names);
|
|
3717
|
+
const mutations = annotateSheetOps(annotateFormulas(g.mutations, g.sheets, g.names), g.order);
|
|
3718
|
+
if (mutations.some((m) => isStructuralMutation(m) || RESHAPE.has(m.id))) clampSelection();
|
|
3255
3719
|
const known = g.inverses.every((i) => i !== void 0);
|
|
3256
3720
|
const inverse = known ? annotateFormulas(g.inverses.slice().reverse().flat(), g.sheets, g.names) : void 0;
|
|
3257
3721
|
emit({ kind: "group", mutations, ...inverse !== void 0 ? { inverse } : {}, label: g.label });
|
|
@@ -3285,7 +3749,27 @@ function univerSheetsOtPort(o) {
|
|
|
3285
3749
|
}
|
|
3286
3750
|
if (info.id === SHEET_NAME) record.name = ws.getName();
|
|
3287
3751
|
pre.set(p, record);
|
|
3752
|
+
const owed = isStructuralMutation({ id: info.id, params: p }) ? mergeFixupsOwed({ id: info.id, params: p }, record.merges ?? []) : null;
|
|
3753
|
+
if (owed) {
|
|
3754
|
+
runOwn(REMOVE_MERGE, String(p.subUnitId), owed.remove, ADD_MERGE);
|
|
3755
|
+
if (owed.add.length) record.addAfter = owed.add;
|
|
3756
|
+
}
|
|
3288
3757
|
});
|
|
3758
|
+
const runOwn = (id, sheet, ranges, inverseId) => {
|
|
3759
|
+
const u = unitId();
|
|
3760
|
+
if (!u) return;
|
|
3761
|
+
applying = true;
|
|
3762
|
+
try {
|
|
3763
|
+
cs.syncExecuteCommand(id, { unitId: u, subUnitId: sheet, ranges: json(ranges) }, { onlyLocal: true });
|
|
3764
|
+
} finally {
|
|
3765
|
+
applying = false;
|
|
3766
|
+
}
|
|
3767
|
+
if (!group) group = openGroup(null);
|
|
3768
|
+
if (!group.notShared) {
|
|
3769
|
+
group.mutations.push({ id, params: { subUnitId: sheet, ranges: json(ranges) } });
|
|
3770
|
+
group.inverses.push([{ id: inverseId, params: { subUnitId: sheet, ranges: json(ranges) } }]);
|
|
3771
|
+
}
|
|
3772
|
+
};
|
|
3289
3773
|
const after = cs.onCommandExecuted((info) => {
|
|
3290
3774
|
if (info.type !== COMMAND) return;
|
|
3291
3775
|
const at = tracker.stack.lastIndexOf(info.id);
|
|
@@ -3383,6 +3867,8 @@ function univerSheetsOtPort(o) {
|
|
|
3383
3867
|
if (!m2) return { m: null, inverse: void 0 };
|
|
3384
3868
|
return { m: m2, inverse: [{ id: ADD_MERGE, params: { subUnitId: sheet, ranges: json(m2.params.ranges) } }] };
|
|
3385
3869
|
}
|
|
3870
|
+
if (info.id === INSERT_SHEET && params.sheet && typeof params.sheet === "object")
|
|
3871
|
+
params.sheet = inlineSheetStyles(params.sheet, (id) => o.workbook()?.getStyles().get(id));
|
|
3386
3872
|
const m = { id: info.id, params };
|
|
3387
3873
|
switch (info.id) {
|
|
3388
3874
|
case "sheet.mutation.insert-row":
|
|
@@ -3391,6 +3877,11 @@ function univerSheetsOtPort(o) {
|
|
|
3391
3877
|
return { m, inverse: [{ id: "sheet.mutation.remove-col", params: { subUnitId: sheet, range: json(params.range) } }] };
|
|
3392
3878
|
case ADD_MERGE:
|
|
3393
3879
|
return { m, inverse: [{ id: REMOVE_MERGE, params: { subUnitId: sheet, ranges: json(params.ranges) } }] };
|
|
3880
|
+
case "sheet.mutation.reorder-range": {
|
|
3881
|
+
const order = {};
|
|
3882
|
+
for (const [t, src] of Object.entries(params.order ?? {})) order[String(src)] = Number(t);
|
|
3883
|
+
return { m, inverse: [{ id: info.id, params: { subUnitId: sheet, range: json(params.range), order } }] };
|
|
3884
|
+
}
|
|
3394
3885
|
case SHEET_NAME:
|
|
3395
3886
|
return { m, inverse: before2.name !== void 0 ? [{ id: SHEET_NAME, params: { subUnitId: sheet, name: before2.name } }] : void 0 };
|
|
3396
3887
|
default:
|
|
@@ -3399,8 +3890,7 @@ function univerSheetsOtPort(o) {
|
|
|
3399
3890
|
};
|
|
3400
3891
|
const collab = cs.onMutationExecutedForCollab((info, options) => {
|
|
3401
3892
|
if (applying || flagged(options) || !mine(info.params)) return;
|
|
3402
|
-
|
|
3403
|
-
if (lone) group = openGroup(null);
|
|
3893
|
+
if (!group) group = openGroup(null);
|
|
3404
3894
|
const g = group;
|
|
3405
3895
|
if (!g.notShared) {
|
|
3406
3896
|
const r = capture(info);
|
|
@@ -3410,11 +3900,29 @@ function univerSheetsOtPort(o) {
|
|
|
3410
3900
|
g.inverses.push(r.inverse);
|
|
3411
3901
|
}
|
|
3412
3902
|
}
|
|
3413
|
-
|
|
3903
|
+
const owedAdd = pre.get(info.params)?.addAfter;
|
|
3904
|
+
if (owedAdd?.length) runOwn(ADD_MERGE, String(info.params.subUnitId ?? ""), owedAdd, REMOVE_MERGE);
|
|
3905
|
+
if (tracker.stack.length === 0) settle();
|
|
3414
3906
|
});
|
|
3907
|
+
const clampSelection = () => {
|
|
3908
|
+
const sel = o.selections;
|
|
3909
|
+
if (!sel) return;
|
|
3910
|
+
try {
|
|
3911
|
+
const sheet = sel.sheetId();
|
|
3912
|
+
const ws = sheet ? o.workbook()?.getSheetBySheetId(sheet) : null;
|
|
3913
|
+
const current = sel.get();
|
|
3914
|
+
if (!ws || !current?.length) return;
|
|
3915
|
+
const rows = ws.getMaxRows?.() ?? Number.MAX_SAFE_INTEGER;
|
|
3916
|
+
const cols = ws.getMaxColumns?.() ?? Number.MAX_SAFE_INTEGER;
|
|
3917
|
+
const next = moveSelectionsThrough(json(current), { id: "", params: {} }, rows, cols);
|
|
3918
|
+
if (JSON.stringify(next) !== JSON.stringify(current)) sel.set(next);
|
|
3919
|
+
} catch (err) {
|
|
3920
|
+
console.warn("[sheets-ot] could not keep this seat's selection inside the sheet after its own row or column change", err);
|
|
3921
|
+
}
|
|
3922
|
+
};
|
|
3415
3923
|
const followSelection = (m) => {
|
|
3416
3924
|
const sel = o.selections;
|
|
3417
|
-
if (!sel || !axisOpOf(m)) return;
|
|
3925
|
+
if (!sel || !axisOpOf(m) && !RESHAPE.has(m.id)) return;
|
|
3418
3926
|
try {
|
|
3419
3927
|
const sheet = String(m.params.subUnitId ?? "");
|
|
3420
3928
|
if (sel.sheetId() !== sheet) return;
|