@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.js
CHANGED
|
@@ -1685,6 +1685,15 @@ var SHEET_MUTATIONS = {
|
|
|
1685
1685
|
"sheet.mutation.set-worksheet-row-auto-height": covered("size", "rowsAutoHeightInfo"),
|
|
1686
1686
|
"sheet.mutation.set-worksheet-col-width": covered("size", "ranges", "colWidth"),
|
|
1687
1687
|
"sheet.mutation.set-worksheet-name": covered("name", "name"),
|
|
1688
|
+
// ── covered (C5c) ────────────────────────────────────────────────────────────────────────────────
|
|
1689
|
+
"sheet.mutation.set.numfmt": covered("numfmt", "values", "refMap"),
|
|
1690
|
+
"sheet.mutation.remove.numfmt": covered("numfmt", "ranges"),
|
|
1691
|
+
"sheet.mutation.set-worksheet-row-count": covered("count", "rowCount"),
|
|
1692
|
+
"sheet.mutation.set-worksheet-column-count": covered("count", "columnCount"),
|
|
1693
|
+
"sheet.mutation.insert-sheet": covered("sheet", "index", "sheet"),
|
|
1694
|
+
"sheet.mutation.remove-sheet": covered("sheet", "sheetIndex", "sheetsLeft"),
|
|
1695
|
+
"sheet.mutation.set-worksheet-order": covered("sheet", "fromOrder", "toOrder"),
|
|
1696
|
+
"sheet.mutation.reorder-range": covered("sort", "range", "order"),
|
|
1688
1697
|
// ── never travels ────────────────────────────────────────────────────────────────────────────────
|
|
1689
1698
|
"formula.mutation.set-formula-calculation-start": never(FORMULA_RESULT),
|
|
1690
1699
|
"formula.mutation.set-trigger-formula-calculation-start": never(FORMULA_RESULT),
|
|
@@ -1718,13 +1727,7 @@ var SHEET_MUTATIONS = {
|
|
|
1718
1727
|
"thread-comment.mutation.resolve-comment": never(UNIVER_COMMENTS),
|
|
1719
1728
|
"thread-comment.mutation.delete-comment": never(UNIVER_COMMENTS),
|
|
1720
1729
|
// ── barriers: X (no transform yet, design §10) ───────────────────────────────────────────────────
|
|
1721
|
-
"sheet.mutation.reorder-range": barrier("X", "sort: a permutation, not transformed yet"),
|
|
1722
|
-
"sheet.mutation.set-worksheet-row-count": barrier("X", "absolute row count; needs delta semantics"),
|
|
1723
|
-
"sheet.mutation.set-worksheet-column-count": barrier("X", "absolute column count; needs delta semantics"),
|
|
1724
|
-
"sheet.mutation.set-worksheet-order": barrier("X", "absolute sheet order; needs move semantics"),
|
|
1725
1730
|
"sheet.mutation.move-range": barrier("X", "cut-paste carries the sender's cell matrices"),
|
|
1726
|
-
"sheet.mutation.insert-sheet": barrier("X", "sheet add: not in C5a"),
|
|
1727
|
-
"sheet.mutation.remove-sheet": barrier("X", "sheet remove: not in C5a"),
|
|
1728
1731
|
"sheet.mutation.set-worksheet-hidden": barrier("X", "sheet-level setting: not in C5a"),
|
|
1729
1732
|
"sheet.mutation.set-tab-color": barrier("X", "sheet-level setting: not in C5a"),
|
|
1730
1733
|
"sheet.mutation.set-workbook-name": barrier("X", "workbook-level setting: not in C5a"),
|
|
@@ -1739,8 +1742,6 @@ var SHEET_MUTATIONS = {
|
|
|
1739
1742
|
"sheet.mutation.set-row-visible": barrier("X", "row visibility: not in C5a"),
|
|
1740
1743
|
"sheet.mutation.set-col-hidden": barrier("X", "column visibility: not in C5a"),
|
|
1741
1744
|
"sheet.mutation.set-col-visible": barrier("X", "column visibility: not in C5a"),
|
|
1742
|
-
"sheet.mutation.set.numfmt": barrier("X", "number formats by range: not in C5a"),
|
|
1743
|
-
"sheet.mutation.remove.numfmt": barrier("X", "number formats by range: not in C5a"),
|
|
1744
1745
|
"sheet.mutation.add-range-protection": barrier("X", "permissions: not in C5a"),
|
|
1745
1746
|
"sheet.mutation.set-range-protection": barrier("X", "permissions: not in C5a"),
|
|
1746
1747
|
"sheet.mutation.delete-range-protection": barrier("X", "permissions: not in C5a"),
|
|
@@ -2144,7 +2145,7 @@ function refSheetsFor(texts, sheets) {
|
|
|
2144
2145
|
}
|
|
2145
2146
|
|
|
2146
2147
|
// src/collab/sheets/transform/transform.ts
|
|
2147
|
-
var SHEET_TRANSFORMER_VERSION = "
|
|
2148
|
+
var SHEET_TRANSFORMER_VERSION = "c5c-1";
|
|
2148
2149
|
var ID = {
|
|
2149
2150
|
values: "sheet.mutation.set-range-values",
|
|
2150
2151
|
insertRow: "sheet.mutation.insert-row",
|
|
@@ -2161,7 +2162,15 @@ var ID = {
|
|
|
2161
2162
|
colWidth: "sheet.mutation.set-worksheet-col-width",
|
|
2162
2163
|
name: "sheet.mutation.set-worksheet-name",
|
|
2163
2164
|
setName: "formula.mutation.set-defined-name",
|
|
2164
|
-
removeName: "formula.mutation.remove-defined-name"
|
|
2165
|
+
removeName: "formula.mutation.remove-defined-name",
|
|
2166
|
+
setNumfmt: "sheet.mutation.set.numfmt",
|
|
2167
|
+
removeNumfmt: "sheet.mutation.remove.numfmt",
|
|
2168
|
+
rowCount: "sheet.mutation.set-worksheet-row-count",
|
|
2169
|
+
colCount: "sheet.mutation.set-worksheet-column-count",
|
|
2170
|
+
insertSheet: "sheet.mutation.insert-sheet",
|
|
2171
|
+
removeSheet: "sheet.mutation.remove-sheet",
|
|
2172
|
+
sheetOrder: "sheet.mutation.set-worksheet-order",
|
|
2173
|
+
sort: "sheet.mutation.reorder-range"
|
|
2165
2174
|
};
|
|
2166
2175
|
var PAIR_BARRIERS = {};
|
|
2167
2176
|
var pairKey = (a, b) => a < b ? `${a}|${b}` : `${b}|${a}`;
|
|
@@ -2273,6 +2282,20 @@ function mergeThrough(s, m) {
|
|
|
2273
2282
|
}
|
|
2274
2283
|
return { range: m, fixup: false };
|
|
2275
2284
|
}
|
|
2285
|
+
function mergeFixupsOwed(m, mergesBefore) {
|
|
2286
|
+
const st = structuralOf(m);
|
|
2287
|
+
if (!st) return null;
|
|
2288
|
+
const remove = [];
|
|
2289
|
+
const add = [];
|
|
2290
|
+
for (const q of mergesBefore) {
|
|
2291
|
+
const t = mergeThrough(st, q);
|
|
2292
|
+
if (!t.fixup) continue;
|
|
2293
|
+
remove.push({ startRow: q.startRow, endRow: q.endRow, startColumn: q.startColumn, endColumn: q.endColumn, ...q.rangeType !== void 0 ? { rangeType: q.rangeType } : {} });
|
|
2294
|
+
if (t.range) add.push({ ...t.range });
|
|
2295
|
+
}
|
|
2296
|
+
return remove.length ? { remove, add } : null;
|
|
2297
|
+
}
|
|
2298
|
+
var isStructuralMutation = (m) => structuralOf(m) !== null;
|
|
2276
2299
|
function exactMergeRemovals(group, merges) {
|
|
2277
2300
|
const sim = new Map(Object.entries(merges).map(([k, v]) => [k, v.map((r) => ({ ...r }))]));
|
|
2278
2301
|
const out = [];
|
|
@@ -2319,8 +2342,24 @@ function cellsMutation(template, cells) {
|
|
|
2319
2342
|
function putCell(cells, r, c, v) {
|
|
2320
2343
|
(cells[r] ??= {})[c] = v;
|
|
2321
2344
|
}
|
|
2345
|
+
function cellsOverlap(a, b) {
|
|
2346
|
+
for (const r of Object.keys(a)) {
|
|
2347
|
+
const br = b[r];
|
|
2348
|
+
if (!br) continue;
|
|
2349
|
+
for (const c of Object.keys(a[r] ?? {})) if (c in br) return true;
|
|
2350
|
+
}
|
|
2351
|
+
return false;
|
|
2352
|
+
}
|
|
2322
2353
|
var isEmptyMatrix = (cells) => Object.values(cells).every((row) => Object.keys(row).length === 0);
|
|
2354
|
+
var cellBarrierCache = /* @__PURE__ */ new WeakMap();
|
|
2323
2355
|
function cellBarrier(m) {
|
|
2356
|
+
const hit = cellBarrierCache.get(m);
|
|
2357
|
+
if (hit !== void 0) return hit;
|
|
2358
|
+
const why = cellBarrierOf(m);
|
|
2359
|
+
cellBarrierCache.set(m, why);
|
|
2360
|
+
return why;
|
|
2361
|
+
}
|
|
2362
|
+
function cellBarrierOf(m) {
|
|
2324
2363
|
if (m.params.isOverrideStyle) return "set-range-values with isOverrideStyle (whole-style replace) is not covered";
|
|
2325
2364
|
let why = null;
|
|
2326
2365
|
forEachCell(cellsOf(m), (_r, _c, v) => {
|
|
@@ -2402,6 +2441,7 @@ function transformCell(X, Y4, side) {
|
|
|
2402
2441
|
function transformCellsOverCells(x, y, side) {
|
|
2403
2442
|
if (sheetOf(x) !== sheetOf(y)) return ok([x]);
|
|
2404
2443
|
const ycells = cellsOf(y);
|
|
2444
|
+
if (!cellsOverlap(cellsOf(x), ycells)) return ok([x]);
|
|
2405
2445
|
const xd = isDerived(x);
|
|
2406
2446
|
const yd = isDerived(y);
|
|
2407
2447
|
const eff = derivedSide(x, y, side);
|
|
@@ -2429,7 +2469,7 @@ function transformCellsOverCells(x, y, side) {
|
|
|
2429
2469
|
const op = passes.filter((p) => !isEmptyMatrix(p)).map((p) => cellsMutation(x, p));
|
|
2430
2470
|
return ok(op, lost, dropped);
|
|
2431
2471
|
}
|
|
2432
|
-
var SIDE_CAR_PARAMS = ["refSheets", "previousName", "derived"];
|
|
2472
|
+
var SIDE_CAR_PARAMS = ["refSheets", "previousName", "derived", "sheetIndex", "sheetsLeft"];
|
|
2433
2473
|
var isDerived = (m) => m.params.derived === true;
|
|
2434
2474
|
function derivedSide(x, y, side) {
|
|
2435
2475
|
const xd = isDerived(x);
|
|
@@ -2451,7 +2491,15 @@ function withRefSheets(params, rs) {
|
|
|
2451
2491
|
return out;
|
|
2452
2492
|
}
|
|
2453
2493
|
var hasFormulaText = (v) => !!v && (isFormulaText(v.f) || typeof v.ref === "string");
|
|
2494
|
+
var hasFormulaCache = /* @__PURE__ */ new WeakMap();
|
|
2454
2495
|
function hasFormula(m) {
|
|
2496
|
+
const hit = hasFormulaCache.get(m);
|
|
2497
|
+
if (hit !== void 0) return hit;
|
|
2498
|
+
const any = hasFormulaOf(m);
|
|
2499
|
+
hasFormulaCache.set(m, any);
|
|
2500
|
+
return any;
|
|
2501
|
+
}
|
|
2502
|
+
function hasFormulaOf(m) {
|
|
2455
2503
|
let any = false;
|
|
2456
2504
|
forEachCell(cellsOf(m), (_r, _c, v) => {
|
|
2457
2505
|
any ||= hasFormulaText(v);
|
|
@@ -2490,15 +2538,18 @@ function cellThrough(sheet, change, r, c) {
|
|
|
2490
2538
|
return nr === null || nc === null ? null : [nr, nc];
|
|
2491
2539
|
}
|
|
2492
2540
|
function cellsOverChange(x, change) {
|
|
2541
|
+
if (!hasFormula(x) && (change.kind !== "axis" || change.sheet !== sheetOf(x))) return ok([x]);
|
|
2493
2542
|
const ctx = formulaCtx(x);
|
|
2494
2543
|
const out = {};
|
|
2495
2544
|
const dropped = [];
|
|
2496
2545
|
let why = null;
|
|
2546
|
+
let changed = false;
|
|
2497
2547
|
forEachCell(cellsOf(x), (r, c, v) => {
|
|
2498
2548
|
if (why) return;
|
|
2499
2549
|
const at = cellThrough(sheetOf(x), change, r, c);
|
|
2500
2550
|
if (!at) {
|
|
2501
2551
|
dropped.push(cellRef(sheetOf(x), r, c));
|
|
2552
|
+
changed = true;
|
|
2502
2553
|
return;
|
|
2503
2554
|
}
|
|
2504
2555
|
let e = v;
|
|
@@ -2509,14 +2560,19 @@ function cellsOverChange(x, change) {
|
|
|
2509
2560
|
return;
|
|
2510
2561
|
}
|
|
2511
2562
|
e = res.entry;
|
|
2563
|
+
if (res.changed) changed = true;
|
|
2512
2564
|
}
|
|
2565
|
+
if (at[0] !== r || at[1] !== c) changed = true;
|
|
2513
2566
|
putCell(out, at[0], at[1], e);
|
|
2514
2567
|
});
|
|
2515
2568
|
if (why) return barrier2(why);
|
|
2516
|
-
const
|
|
2569
|
+
const rsAfter = refSheetsAfter(ctx.refSheets, change);
|
|
2570
|
+
if (!changed && JSON.stringify(rsAfter ?? null) === JSON.stringify(ctx.refSheets ?? null)) return ok([x]);
|
|
2571
|
+
const params = { ...withRefSheets(x.params, rsAfter), cellValue: out };
|
|
2517
2572
|
return ok(isEmptyMatrix(out) ? [] : [{ id: x.id, params }], [], dropped);
|
|
2518
2573
|
}
|
|
2519
2574
|
function rewritesOf(y, change) {
|
|
2575
|
+
if (!hasFormula(y)) return null;
|
|
2520
2576
|
const ctx = formulaCtx(y);
|
|
2521
2577
|
const out = {};
|
|
2522
2578
|
let why = null;
|
|
@@ -2662,6 +2718,368 @@ function buildSize(template, values) {
|
|
|
2662
2718
|
const value = uniform !== void 0 && [...values.values()].every((v) => v === uniform) ? uniform : Object.fromEntries(values);
|
|
2663
2719
|
return { id: template.id, params: { ...p, ranges, [field]: value } };
|
|
2664
2720
|
}
|
|
2721
|
+
var isNumfmt = (m) => m.id === ID.setNumfmt || m.id === ID.removeNumfmt;
|
|
2722
|
+
function nfParts(m) {
|
|
2723
|
+
if (m.id === ID.removeNumfmt) return [{ key: null, ranges: (m.params.ranges ?? []).map((r) => ({ ...r })) }];
|
|
2724
|
+
const values = m.params.values ?? {};
|
|
2725
|
+
return Object.keys(values).map((k) => ({ key: k, ranges: (values[k]?.ranges ?? []).map((r) => ({ ...r })) }));
|
|
2726
|
+
}
|
|
2727
|
+
function nfBuild(m, parts) {
|
|
2728
|
+
const keep = parts.filter((p) => p.ranges.length);
|
|
2729
|
+
if (!keep.length) return [];
|
|
2730
|
+
if (m.id === ID.removeNumfmt) return [{ id: m.id, params: { ...m.params, ranges: keep[0].ranges } }];
|
|
2731
|
+
const values = {};
|
|
2732
|
+
const refMap = {};
|
|
2733
|
+
const srcValues = m.params.values ?? {};
|
|
2734
|
+
const srcRef = m.params.refMap ?? {};
|
|
2735
|
+
for (const p of keep) {
|
|
2736
|
+
values[p.key] = { ...srcValues[p.key], ranges: p.ranges };
|
|
2737
|
+
refMap[p.key] = srcRef[p.key];
|
|
2738
|
+
}
|
|
2739
|
+
return [{ id: m.id, params: { ...m.params, values, refMap } }];
|
|
2740
|
+
}
|
|
2741
|
+
function nfValueAt(m, row, col) {
|
|
2742
|
+
for (const p of nfParts(m))
|
|
2743
|
+
if (p.ranges.some((r) => r.startRow <= row && row <= r.endRow && r.startColumn <= col && col <= r.endColumn)) {
|
|
2744
|
+
if (p.key === null) return null;
|
|
2745
|
+
const ref = (m.params.refMap ?? {})[p.key];
|
|
2746
|
+
return { pattern: ref?.pattern };
|
|
2747
|
+
}
|
|
2748
|
+
return void 0;
|
|
2749
|
+
}
|
|
2750
|
+
function spanThrough(op, lo, hi) {
|
|
2751
|
+
const pieces = [];
|
|
2752
|
+
if (op.kind === "insert") pieces.push([0, op.at - 1, 0], [op.at, Infinity, op.count]);
|
|
2753
|
+
else if (op.kind === "remove") pieces.push([0, op.start - 1, 0], [op.start + op.count, Infinity, -op.count]);
|
|
2754
|
+
else if (op.count <= 0 || op.to >= op.from && op.to <= op.from + op.count) pieces.push([0, Infinity, 0]);
|
|
2755
|
+
else if (op.to > op.from) {
|
|
2756
|
+
const n = op.count;
|
|
2757
|
+
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]);
|
|
2758
|
+
} else {
|
|
2759
|
+
const n = op.count;
|
|
2760
|
+
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]);
|
|
2761
|
+
}
|
|
2762
|
+
const out = [];
|
|
2763
|
+
for (const [a, b, d] of pieces) {
|
|
2764
|
+
const x0 = Math.max(a, lo);
|
|
2765
|
+
const x1 = Math.min(b, hi);
|
|
2766
|
+
if (x0 <= x1) out.push([x0 + d, x1 + d]);
|
|
2767
|
+
}
|
|
2768
|
+
out.sort((p, q) => p[0] - q[0]);
|
|
2769
|
+
const merged = [];
|
|
2770
|
+
for (const p of out) {
|
|
2771
|
+
const last = merged[merged.length - 1];
|
|
2772
|
+
if (last && last[1] + 1 >= p[0]) last[1] = Math.max(last[1], p[1]);
|
|
2773
|
+
else merged.push([p[0], p[1]]);
|
|
2774
|
+
}
|
|
2775
|
+
return merged;
|
|
2776
|
+
}
|
|
2777
|
+
function rectsThrough(st, rects) {
|
|
2778
|
+
const [a0, a1] = S(st.axis);
|
|
2779
|
+
const out = [];
|
|
2780
|
+
for (const r of rects) for (const [lo, hi] of spanThrough(st.op, r[a0], r[a1])) out.push({ ...r, [a0]: lo, [a1]: hi });
|
|
2781
|
+
return out;
|
|
2782
|
+
}
|
|
2783
|
+
function rectMinus(a, b) {
|
|
2784
|
+
if (a.startRow > b.endRow || b.startRow > a.endRow || a.startColumn > b.endColumn || b.startColumn > a.endColumn) return [a];
|
|
2785
|
+
const out = [];
|
|
2786
|
+
if (a.startRow < b.startRow) out.push({ ...a, endRow: b.startRow - 1 });
|
|
2787
|
+
if (a.endRow > b.endRow) out.push({ ...a, startRow: b.endRow + 1 });
|
|
2788
|
+
const r0 = Math.max(a.startRow, b.startRow);
|
|
2789
|
+
const r1 = Math.min(a.endRow, b.endRow);
|
|
2790
|
+
if (a.startColumn < b.startColumn) out.push({ ...a, startRow: r0, endRow: r1, endColumn: b.startColumn - 1 });
|
|
2791
|
+
if (a.endColumn > b.endColumn) out.push({ ...a, startRow: r0, endRow: r1, startColumn: b.endColumn + 1 });
|
|
2792
|
+
return out;
|
|
2793
|
+
}
|
|
2794
|
+
function rectsMinus(as, bs) {
|
|
2795
|
+
let cur = as;
|
|
2796
|
+
for (const b of bs) cur = cur.flatMap((a) => rectMinus(a, b));
|
|
2797
|
+
return cur;
|
|
2798
|
+
}
|
|
2799
|
+
function nWrites(m) {
|
|
2800
|
+
const out = [];
|
|
2801
|
+
forEachCell(cellsOf(m), (r, c, v) => {
|
|
2802
|
+
if (v === null || v.s === null || v.s && typeof v.s === "object" && "n" in v.s)
|
|
2803
|
+
out.push({ startRow: r, endRow: r, startColumn: c, endColumn: c });
|
|
2804
|
+
});
|
|
2805
|
+
return out;
|
|
2806
|
+
}
|
|
2807
|
+
function numfmtPair(x, y, side, sx, sy) {
|
|
2808
|
+
const nx = isNumfmt(x);
|
|
2809
|
+
const ny = isNumfmt(y);
|
|
2810
|
+
if (!nx && !ny) return null;
|
|
2811
|
+
if (nx && sy) return ok(nfBuild(x, nfParts(x).map((p) => ({ ...p, ranges: rectsThrough(sy, p.ranges) }))));
|
|
2812
|
+
if (ny && sx) return ok([x]);
|
|
2813
|
+
if (nx && ny) {
|
|
2814
|
+
if (side === "left") return ok([x]);
|
|
2815
|
+
const ys = nfParts(y).flatMap((p) => p.ranges);
|
|
2816
|
+
return ok(nfBuild(x, nfParts(x).map((p) => ({ ...p, ranges: rectsMinus(p.ranges, ys) }))));
|
|
2817
|
+
}
|
|
2818
|
+
if (nx && y.id === ID.values) {
|
|
2819
|
+
if (side === "left") return ok([x]);
|
|
2820
|
+
const ys = nWrites(y);
|
|
2821
|
+
return ys.length ? ok(nfBuild(x, nfParts(x).map((p) => ({ ...p, ranges: rectsMinus(p.ranges, ys) })))) : ok([x]);
|
|
2822
|
+
}
|
|
2823
|
+
if (ny && x.id === ID.values) {
|
|
2824
|
+
if (side === "left") return ok([x]);
|
|
2825
|
+
const out = {};
|
|
2826
|
+
const tail = {};
|
|
2827
|
+
let touched = false;
|
|
2828
|
+
forEachCell(cellsOf(x), (r, c, v) => {
|
|
2829
|
+
const n = nfValueAt(y, r, c);
|
|
2830
|
+
if (n === void 0) return putCell(out, r, c, v);
|
|
2831
|
+
if (v === null || v.s === null) {
|
|
2832
|
+
putCell(out, r, c, v);
|
|
2833
|
+
if (n) {
|
|
2834
|
+
putCell(tail, r, c, { s: { n } });
|
|
2835
|
+
touched = true;
|
|
2836
|
+
}
|
|
2837
|
+
return;
|
|
2838
|
+
}
|
|
2839
|
+
if (v.s && typeof v.s === "object" && "n" in v.s) {
|
|
2840
|
+
const { n: _drop, ...rest } = v.s;
|
|
2841
|
+
const e = { ...v };
|
|
2842
|
+
if (Object.keys(rest).length) e.s = rest;
|
|
2843
|
+
else delete e.s;
|
|
2844
|
+
touched = true;
|
|
2845
|
+
if (Object.keys(e).length) putCell(out, r, c, e);
|
|
2846
|
+
return;
|
|
2847
|
+
}
|
|
2848
|
+
putCell(out, r, c, v);
|
|
2849
|
+
});
|
|
2850
|
+
if (!touched) return ok([x]);
|
|
2851
|
+
const ops = [];
|
|
2852
|
+
if (!isEmptyMatrix(out)) ops.push(cellsMutation(x, out));
|
|
2853
|
+
if (!isEmptyMatrix(tail)) ops.push({ id: ID.values, params: { subUnitId: sheetOf(x), cellValue: tail } });
|
|
2854
|
+
return ok(ops);
|
|
2855
|
+
}
|
|
2856
|
+
return ok([x]);
|
|
2857
|
+
}
|
|
2858
|
+
var isCount = (m) => m.id === ID.rowCount || m.id === ID.colCount;
|
|
2859
|
+
var countAxis = (m) => m.id === ID.rowCount ? "row" : "col";
|
|
2860
|
+
var countKey = (m) => m.id === ID.rowCount ? "rowCount" : "columnCount";
|
|
2861
|
+
function countPair(x, y, sy) {
|
|
2862
|
+
if (!isCount(x)) return isCount(y) ? ok([x]) : null;
|
|
2863
|
+
const k = countKey(x);
|
|
2864
|
+
const v = Number(x.params[k]);
|
|
2865
|
+
if (sy) {
|
|
2866
|
+
if (sy.axis !== countAxis(x) || sy.op.kind === "move") return ok([x]);
|
|
2867
|
+
const d = sy.op.kind === "insert" ? sy.op.count : -sy.op.count;
|
|
2868
|
+
return ok([{ id: x.id, params: { ...x.params, [k]: Math.max(1, v + d) } }]);
|
|
2869
|
+
}
|
|
2870
|
+
if (isCount(y) && y.id === x.id) {
|
|
2871
|
+
const w = Number(y.params[k]);
|
|
2872
|
+
return ok([w > v ? { id: x.id, params: { ...x.params, [k]: w } } : x]);
|
|
2873
|
+
}
|
|
2874
|
+
return ok([x]);
|
|
2875
|
+
}
|
|
2876
|
+
var isSheetOp = (m) => m.id === ID.insertSheet || m.id === ID.removeSheet || m.id === ID.sheetOrder;
|
|
2877
|
+
var sheetIdOf = (m) => m.id === ID.insertSheet ? String(m.params.sheet?.id ?? "") : sheetOf(m);
|
|
2878
|
+
function sheetAxisOf(m) {
|
|
2879
|
+
const p = m.params;
|
|
2880
|
+
if (m.id === ID.insertSheet) return typeof p.index === "number" ? { kind: "insert", at: p.index, count: 1 } : null;
|
|
2881
|
+
if (m.id === ID.removeSheet) return typeof p.sheetIndex === "number" ? { kind: "remove", start: p.sheetIndex, count: 1 } : null;
|
|
2882
|
+
if (m.id === ID.sheetOrder) {
|
|
2883
|
+
const f = Number(p.fromOrder);
|
|
2884
|
+
const t = Number(p.toOrder);
|
|
2885
|
+
return { kind: "move", from: f, count: 1, to: t > f ? t + 1 : t };
|
|
2886
|
+
}
|
|
2887
|
+
return null;
|
|
2888
|
+
}
|
|
2889
|
+
function buildSheetOp(template, op) {
|
|
2890
|
+
if (op.kind === "insert") return { id: template.id, params: { ...template.params, index: op.at } };
|
|
2891
|
+
if (op.kind === "remove") return { id: template.id, params: { ...template.params, sheetIndex: op.start } };
|
|
2892
|
+
return { id: template.id, params: { ...template.params, fromOrder: op.from, toOrder: op.to > op.from ? op.to - 1 : op.to } };
|
|
2893
|
+
}
|
|
2894
|
+
function namesSheet(m, id) {
|
|
2895
|
+
const rs = refSheetsOf(m);
|
|
2896
|
+
return !!rs && Object.values(rs).includes(id) && (m.id === ID.setName || hasFormula(m));
|
|
2897
|
+
}
|
|
2898
|
+
function sheetPair(x, y, side) {
|
|
2899
|
+
const xs = isSheetOp(x);
|
|
2900
|
+
const ys = isSheetOp(y);
|
|
2901
|
+
if (!xs && !ys) return null;
|
|
2902
|
+
if (xs && ys) {
|
|
2903
|
+
const a = sheetAxisOf(x);
|
|
2904
|
+
const b = sheetAxisOf(y);
|
|
2905
|
+
if (!a || !b) return barrier2("a sheet add or remove without its index (capture must call annotateSheetOps)");
|
|
2906
|
+
if (x.id === ID.insertSheet && y.id === ID.insertSheet && sheetIdOf(x) === sheetIdOf(y)) {
|
|
2907
|
+
return JSON.stringify(x.params) === JSON.stringify(y.params) ? ok([]) : barrier2("the same sheet id added twice with different content");
|
|
2908
|
+
}
|
|
2909
|
+
if (x.id === ID.removeSheet && typeof x.params.sheetsLeft === "number" && sheetIdOf(x) !== sheetIdOf(y) && (y.id === ID.removeSheet || y.id === ID.insertSheet)) {
|
|
2910
|
+
const left = x.params.sheetsLeft + (y.id === ID.insertSheet ? 1 : -1);
|
|
2911
|
+
if (left < 1) return barrier2("concurrent sheet removes would leave the workbook without a sheet");
|
|
2912
|
+
const out2 = transformAxis(a, b, side);
|
|
2913
|
+
if (!out2) return barrier2("sheet order: no transform");
|
|
2914
|
+
return ok(out2.map((o) => buildSheetOp({ id: x.id, params: { ...x.params, sheetsLeft: left } }, o)));
|
|
2915
|
+
}
|
|
2916
|
+
const out = transformAxis(a, b, side);
|
|
2917
|
+
if (!out) return barrier2("sheet order: no transform");
|
|
2918
|
+
return ok(out.map((o) => buildSheetOp(x, o)), [], out.length === 0 && x.id === ID.sheetOrder ? [`${sheetIdOf(x)}: sheet order`] : []);
|
|
2919
|
+
}
|
|
2920
|
+
if (ys) {
|
|
2921
|
+
if (y.id !== ID.removeSheet) return ok([x]);
|
|
2922
|
+
const gone2 = sheetOf(y);
|
|
2923
|
+
if (namesSheet(x, gone2)) return barrier2("a formula names a sheet removed at the same time");
|
|
2924
|
+
if (sheetOf(x) === gone2 && x.id !== ID.setName && x.id !== ID.removeName)
|
|
2925
|
+
return ok([], [], isDerived(x) ? [] : [`${gone2}: the sheet was removed`]);
|
|
2926
|
+
return ok([x]);
|
|
2927
|
+
}
|
|
2928
|
+
if (x.id !== ID.removeSheet) return ok([x]);
|
|
2929
|
+
const gone = sheetOf(x);
|
|
2930
|
+
if (namesSheet(y, gone)) return barrier2("a formula names a sheet removed at the same time");
|
|
2931
|
+
return ok([x], sheetOf(y) === gone && !isDerived(y) && y.id !== ID.setName && y.id !== ID.removeName ? [`${gone}: the sheet was removed`] : []);
|
|
2932
|
+
}
|
|
2933
|
+
function annotateSheetOps(group, sheetOrder) {
|
|
2934
|
+
const order = [...sheetOrder];
|
|
2935
|
+
return group.map((m) => {
|
|
2936
|
+
if (m.id === ID.insertSheet) {
|
|
2937
|
+
const index = typeof m.params.index === "number" ? Math.min(m.params.index, order.length) : order.length;
|
|
2938
|
+
order.splice(index, 0, sheetIdOf(m));
|
|
2939
|
+
return index === m.params.index ? m : { id: m.id, params: { ...m.params, index } };
|
|
2940
|
+
}
|
|
2941
|
+
if (m.id === ID.removeSheet) {
|
|
2942
|
+
const i = order.indexOf(sheetOf(m));
|
|
2943
|
+
if (i >= 0) order.splice(i, 1);
|
|
2944
|
+
return i >= 0 ? { id: m.id, params: { ...m.params, sheetIndex: i, sheetsLeft: order.length } } : m;
|
|
2945
|
+
}
|
|
2946
|
+
if (m.id === ID.sheetOrder) {
|
|
2947
|
+
const f = Number(m.params.fromOrder);
|
|
2948
|
+
const [id] = order.splice(f, 1);
|
|
2949
|
+
order.splice(Number(m.params.toOrder), 0, id ?? sheetOf(m));
|
|
2950
|
+
}
|
|
2951
|
+
return m;
|
|
2952
|
+
});
|
|
2953
|
+
}
|
|
2954
|
+
function inlineSheetStyles(sheet, styleOf) {
|
|
2955
|
+
const out = JSON.parse(JSON.stringify(sheet));
|
|
2956
|
+
const fix = (o) => {
|
|
2957
|
+
if (o && typeof o.s === "string") {
|
|
2958
|
+
const st = styleOf(o.s);
|
|
2959
|
+
if (st) o.s = JSON.parse(JSON.stringify(st));
|
|
2960
|
+
}
|
|
2961
|
+
};
|
|
2962
|
+
for (const row of Object.values(out.cellData ?? {})) for (const cell of Object.values(row ?? {})) fix(cell);
|
|
2963
|
+
for (const key of ["rowData", "columnData"]) for (const v of Object.values(out[key] ?? {})) fix(v);
|
|
2964
|
+
if (typeof out.defaultStyle === "string") {
|
|
2965
|
+
const st = styleOf(out.defaultStyle);
|
|
2966
|
+
if (st) out.defaultStyle = JSON.parse(JSON.stringify(st));
|
|
2967
|
+
}
|
|
2968
|
+
return out;
|
|
2969
|
+
}
|
|
2970
|
+
var isSort = (m) => m.id === ID.sort;
|
|
2971
|
+
function sortOf(m) {
|
|
2972
|
+
const P = /* @__PURE__ */ new Map();
|
|
2973
|
+
for (const [t, src] of Object.entries(m.params.order ?? {})) P.set(Number(t), Number(src));
|
|
2974
|
+
return { range: { ...m.params.range }, P };
|
|
2975
|
+
}
|
|
2976
|
+
var sortQ = (o) => new Map([...o.P].map(([t, s0]) => [s0, t]));
|
|
2977
|
+
function buildSort(template, o) {
|
|
2978
|
+
const order = {};
|
|
2979
|
+
for (const [t, s0] of [...o.P].sort((a, b) => a[0] - b[0])) if (t !== s0) order[t] = s0;
|
|
2980
|
+
if (!Object.keys(order).length || o.range.startRow > o.range.endRow || o.range.startColumn > o.range.endColumn) return [];
|
|
2981
|
+
return [{ id: template.id, params: { ...template.params, range: o.range, order } }];
|
|
2982
|
+
}
|
|
2983
|
+
var inSortCols = (o, c) => c >= o.range.startColumn && c <= o.range.endColumn;
|
|
2984
|
+
function sortThrough(o, st) {
|
|
2985
|
+
const r = o.range;
|
|
2986
|
+
if (st.axis === "col") {
|
|
2987
|
+
if (st.op.kind === "move") {
|
|
2988
|
+
const { from, count, to } = st.op;
|
|
2989
|
+
const touches = !(from + count - 1 < r.startColumn || from > r.endColumn) || to > r.startColumn && to <= r.endColumn;
|
|
2990
|
+
if (touches) return null;
|
|
2991
|
+
const spans3 = spanThrough(st.op, r.startColumn, r.endColumn);
|
|
2992
|
+
return spans3.length === 1 ? { range: { ...r, startColumn: spans3[0][0], endColumn: spans3[0][1] }, P: o.P } : null;
|
|
2993
|
+
}
|
|
2994
|
+
const spans2 = spanThrough(st.op, r.startColumn, r.endColumn);
|
|
2995
|
+
if (!spans2.length) return { range: { ...r, startColumn: 1, endColumn: 0 }, P: /* @__PURE__ */ new Map() };
|
|
2996
|
+
return { range: { ...r, startColumn: spans2[0][0], endColumn: spans2[spans2.length - 1][1] }, P: o.P };
|
|
2997
|
+
}
|
|
2998
|
+
const op = st.op;
|
|
2999
|
+
if (op.kind === "move") {
|
|
3000
|
+
const touches = !(op.from + op.count - 1 < r.startRow || op.from > r.endRow) || op.to > r.startRow && op.to <= r.endRow;
|
|
3001
|
+
if (touches) return null;
|
|
3002
|
+
}
|
|
3003
|
+
if (op.kind === "insert" || op.kind === "move") {
|
|
3004
|
+
const P2 = /* @__PURE__ */ new Map();
|
|
3005
|
+
for (const [t, s0] of o.P) P2.set(mapIndex(op, t), mapIndex(op, s0));
|
|
3006
|
+
const spans2 = spanThrough(op, r.startRow, r.endRow);
|
|
3007
|
+
return { range: { ...r, startRow: spans2[0][0], endRow: spans2[spans2.length - 1][1] }, P: P2 };
|
|
3008
|
+
}
|
|
3009
|
+
const removed = (i) => i >= op.start && i < op.start + op.count;
|
|
3010
|
+
const Q = sortQ(o);
|
|
3011
|
+
const goneTargets = [];
|
|
3012
|
+
for (let i = op.start; i < op.start + op.count; i++) goneTargets.push(Q.get(i) ?? i);
|
|
3013
|
+
goneTargets.sort((a, b) => a - b);
|
|
3014
|
+
const compact = (t) => t - goneTargets.filter((g) => g < t).length;
|
|
3015
|
+
const P = /* @__PURE__ */ new Map();
|
|
3016
|
+
for (const [t, s0] of o.P) if (!removed(s0)) P.set(compact(t), mapIndex(op, s0));
|
|
3017
|
+
const spans = spanThrough(op, r.startRow, r.endRow);
|
|
3018
|
+
if (!spans.length) return { range: { ...r, startRow: 1, endRow: 0 }, P: /* @__PURE__ */ new Map() };
|
|
3019
|
+
return { range: { ...r, startRow: spans[0][0], endRow: spans[spans.length - 1][1] }, P };
|
|
3020
|
+
}
|
|
3021
|
+
function sortPair(x, y, sx, sy) {
|
|
3022
|
+
const xs = isSort(x);
|
|
3023
|
+
const ys = isSort(y);
|
|
3024
|
+
if (!xs && !ys) return null;
|
|
3025
|
+
if (xs && ys) {
|
|
3026
|
+
const a = sortOf(x).range;
|
|
3027
|
+
const b = sortOf(y).range;
|
|
3028
|
+
const overlap = a.startRow <= b.endRow && b.startRow <= a.endRow && a.startColumn <= b.endColumn && b.startColumn <= a.endColumn;
|
|
3029
|
+
return overlap ? barrier2("two sorts of overlapping ranges at once") : ok([x]);
|
|
3030
|
+
}
|
|
3031
|
+
if (xs) {
|
|
3032
|
+
if (sy) {
|
|
3033
|
+
const t = sortThrough(sortOf(x), sy);
|
|
3034
|
+
return t ? ok(buildSort(x, t)) : barrier2("a row or column move through a sorted range");
|
|
3035
|
+
}
|
|
3036
|
+
return ok([x]);
|
|
3037
|
+
}
|
|
3038
|
+
const o = sortOf(y);
|
|
3039
|
+
const Q = sortQ(o);
|
|
3040
|
+
const moved = (r) => r >= o.range.startRow && r <= o.range.endRow && Q.has(r);
|
|
3041
|
+
if (sx) {
|
|
3042
|
+
if (sx.axis === "col") return sx.op.kind === "move" && !sortThrough(o, sx) ? barrier2("a column move through a sorted range") : ok([x]);
|
|
3043
|
+
if (sx.op.kind === "insert") return ok([x]);
|
|
3044
|
+
if (sx.op.kind === "move") return sortThrough(o, sx) ? ok([x]) : barrier2("a row move through a sorted range");
|
|
3045
|
+
const rows = [];
|
|
3046
|
+
let partial = false;
|
|
3047
|
+
for (let i = sx.op.start; i < sx.op.start + sx.op.count; i++) {
|
|
3048
|
+
if (moved(i)) partial = true;
|
|
3049
|
+
rows.push(Q.get(i) ?? i);
|
|
3050
|
+
}
|
|
3051
|
+
if (partial) return barrier2("a row remove against a concurrent sort of those rows");
|
|
3052
|
+
return ok([x]);
|
|
3053
|
+
}
|
|
3054
|
+
if (x.id === ID.values) {
|
|
3055
|
+
const out = {};
|
|
3056
|
+
let changed = false;
|
|
3057
|
+
forEachCell(cellsOf(x), (r, c, v) => {
|
|
3058
|
+
if (inSortCols(o, c) && moved(r)) {
|
|
3059
|
+
putCell(out, Q.get(r), c, v);
|
|
3060
|
+
changed = true;
|
|
3061
|
+
} else putCell(out, r, c, v);
|
|
3062
|
+
});
|
|
3063
|
+
return changed ? ok([cellsMutation(x, out)]) : ok([x]);
|
|
3064
|
+
}
|
|
3065
|
+
if (isNumfmt(x)) {
|
|
3066
|
+
const parts = nfParts(x).map((p) => {
|
|
3067
|
+
const ranges = [];
|
|
3068
|
+
for (const rc of p.ranges) {
|
|
3069
|
+
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) };
|
|
3070
|
+
if (inner.startRow > inner.endRow || inner.startColumn > inner.endColumn) {
|
|
3071
|
+
ranges.push(rc);
|
|
3072
|
+
continue;
|
|
3073
|
+
}
|
|
3074
|
+
ranges.push(...rectMinus(rc, inner));
|
|
3075
|
+
for (let r = inner.startRow; r <= inner.endRow; r++) ranges.push({ ...inner, startRow: Q.get(r) ?? r, endRow: Q.get(r) ?? r });
|
|
3076
|
+
}
|
|
3077
|
+
return { ...p, ranges };
|
|
3078
|
+
});
|
|
3079
|
+
return ok(nfBuild(x, parts));
|
|
3080
|
+
}
|
|
3081
|
+
return ok([x]);
|
|
3082
|
+
}
|
|
2665
3083
|
function familyOf(id) {
|
|
2666
3084
|
const e = SHEET_MUTATIONS[id];
|
|
2667
3085
|
return e && e.kind === "covered" ? e.family : "";
|
|
@@ -2678,6 +3096,8 @@ function transformMutation(x, y, side) {
|
|
|
2678
3096
|
}
|
|
2679
3097
|
const pb = PAIR_BARRIERS[pairKey(x.id, y.id)];
|
|
2680
3098
|
if (pb) return barrier2(`${x.id} \xD7 ${y.id}: ${pb.reason}${pb.seed === null ? "" : ` (fuzz seed ${pb.seed})`}`);
|
|
3099
|
+
const sp = sheetPair(x, y, side);
|
|
3100
|
+
if (sp) return sp;
|
|
2681
3101
|
const fp = formulaPair(x, y, side);
|
|
2682
3102
|
if (fp) return fp;
|
|
2683
3103
|
if (sheetOf(x) !== sheetOf(y)) return ok([x]);
|
|
@@ -2685,6 +3105,12 @@ function transformMutation(x, y, side) {
|
|
|
2685
3105
|
const fy = familyOf(y.id);
|
|
2686
3106
|
const sy = structuralOf(y);
|
|
2687
3107
|
const sx = structuralOf(x);
|
|
3108
|
+
const sortp = sortPair(x, y, sx, sy);
|
|
3109
|
+
if (sortp) return sortp;
|
|
3110
|
+
const cp = countPair(x, y, sy);
|
|
3111
|
+
if (cp) return cp;
|
|
3112
|
+
const np = numfmtPair(x, y, side, sx, sy);
|
|
3113
|
+
if (np) return np;
|
|
2688
3114
|
if (sx && sy) {
|
|
2689
3115
|
if (sx.axis !== sy.axis) return ok([x]);
|
|
2690
3116
|
const out = transformAxis(sx.op, sy.op, side);
|
|
@@ -2792,22 +3218,45 @@ function tSeq(xs, ys, side, acc) {
|
|
|
2792
3218
|
acc.dropped.push(...a.dropped);
|
|
2793
3219
|
return [a.op, b.op];
|
|
2794
3220
|
}
|
|
3221
|
+
const outX = [];
|
|
3222
|
+
let curY = ys;
|
|
3223
|
+
for (const x of xs) {
|
|
3224
|
+
let curX = [x];
|
|
3225
|
+
const nextY = [];
|
|
3226
|
+
for (const y of curY) {
|
|
3227
|
+
if (curX.length === 0) {
|
|
3228
|
+
nextY.push(y);
|
|
3229
|
+
continue;
|
|
3230
|
+
}
|
|
3231
|
+
const r = tSeq(curX, [y], side, acc);
|
|
3232
|
+
if (blocked(r)) return r;
|
|
3233
|
+
curX = r[0];
|
|
3234
|
+
for (const m of r[1]) nextY.push(m);
|
|
3235
|
+
}
|
|
3236
|
+
for (const m of curX) outX.push(m);
|
|
3237
|
+
curY = nextY;
|
|
3238
|
+
}
|
|
3239
|
+
return [outX, curY];
|
|
3240
|
+
}
|
|
3241
|
+
function tSeqOld(xs, ys, side, acc) {
|
|
3242
|
+
if (xs.length === 0 || ys.length === 0) return [xs, ys];
|
|
3243
|
+
if (xs.length === 1 && ys.length === 1) return tSeq(xs, ys, side, acc);
|
|
2795
3244
|
if (xs.length > 1) {
|
|
2796
|
-
const first2 =
|
|
3245
|
+
const first2 = tSeqOld([xs[0]], ys, side, acc);
|
|
2797
3246
|
if (blocked(first2)) return first2;
|
|
2798
|
-
const rest2 =
|
|
3247
|
+
const rest2 = tSeqOld(xs.slice(1), first2[1], side, acc);
|
|
2799
3248
|
if (blocked(rest2)) return rest2;
|
|
2800
3249
|
return [[...first2[0], ...rest2[0]], rest2[1]];
|
|
2801
3250
|
}
|
|
2802
|
-
const first =
|
|
3251
|
+
const first = tSeqOld(xs, [ys[0]], side, acc);
|
|
2803
3252
|
if (blocked(first)) return first;
|
|
2804
|
-
const rest =
|
|
3253
|
+
const rest = tSeqOld(first[0], ys.slice(1), side, acc);
|
|
2805
3254
|
if (blocked(rest)) return rest;
|
|
2806
3255
|
return [rest[0], [...first[1], ...rest[1]]];
|
|
2807
3256
|
}
|
|
2808
3257
|
function transformGroup(x, y, side) {
|
|
2809
3258
|
const acc = { lost: [], dropped: [] };
|
|
2810
|
-
const r = tSeq([...x], [...y], side, acc);
|
|
3259
|
+
const r = (process.env.OLD_TSEQ ? tSeqOld : tSeq)([...x], [...y], side, acc);
|
|
2811
3260
|
if (blocked(r)) return r;
|
|
2812
3261
|
return { op: r[0], lost: [...new Set(acc.lost)], dropped: [...new Set(acc.dropped)] };
|
|
2813
3262
|
}
|
|
@@ -2877,7 +3326,7 @@ async function sheetsStateHash(snapshot) {
|
|
|
2877
3326
|
}
|
|
2878
3327
|
|
|
2879
3328
|
// src/univer/collab/sheets-ot/room.ts
|
|
2880
|
-
var SHEETS_COLLAB_PROTO =
|
|
3329
|
+
var SHEETS_COLLAB_PROTO = 2;
|
|
2881
3330
|
var SHEETS_EDIT_GROUP = "sheets.edit";
|
|
2882
3331
|
var flip2 = (side) => side === "left" ? "right" : "left";
|
|
2883
3332
|
var isNoopSheetOp = (op) => op == null || op.length === 0;
|
|
@@ -2924,6 +3373,11 @@ function travelingShape(m) {
|
|
|
2924
3373
|
}
|
|
2925
3374
|
return { id: m.id, params };
|
|
2926
3375
|
}
|
|
3376
|
+
var shapedLists = /* @__PURE__ */ new WeakMap();
|
|
3377
|
+
function cachedShape(list) {
|
|
3378
|
+
const hit = shapedLists.get(list);
|
|
3379
|
+
return hit && hit.src.length === list.length && hit.src.every((m, i) => m === list[i]) ? hit.shaped : null;
|
|
3380
|
+
}
|
|
2927
3381
|
function rebaseSheetUndoStack(items, remote, unitId) {
|
|
2928
3382
|
if (isNoopSheetOp(remote)) return 0;
|
|
2929
3383
|
let dropped = 0;
|
|
@@ -2935,7 +3389,11 @@ function rebaseSheetUndoStack(items, remote, unitId) {
|
|
|
2935
3389
|
if (!ok2 || !list?.length) continue;
|
|
2936
3390
|
const isOperation = (id) => !SHEET_MUTATIONS[id] && id.includes(".operation.");
|
|
2937
3391
|
const operations = list.filter((m) => isOperation(m.id));
|
|
2938
|
-
|
|
3392
|
+
let shaped = cachedShape(list);
|
|
3393
|
+
if (!shaped) {
|
|
3394
|
+
shaped = list.filter((m) => !isOperation(m.id)).map(travelingShape);
|
|
3395
|
+
shapedLists.set(list, { src: list.slice(), shaped });
|
|
3396
|
+
}
|
|
2939
3397
|
if (shaped.some((m) => m === null)) {
|
|
2940
3398
|
ok2 = false;
|
|
2941
3399
|
continue;
|
|
@@ -2947,8 +3405,10 @@ function rebaseSheetUndoStack(items, remote, unitId) {
|
|
|
2947
3405
|
ok2 = false;
|
|
2948
3406
|
continue;
|
|
2949
3407
|
}
|
|
2950
|
-
if (
|
|
2951
|
-
|
|
3408
|
+
if (r.op.length === shaped.length && r.op.every((m, i2) => m === shaped[i2])) continue;
|
|
3409
|
+
const next = [...r.op.map((m) => ({ id: m.id, params: { ...forApply(m).params, unitId } })), ...operations];
|
|
3410
|
+
shapedLists.set(next, { src: next.slice(), shaped: r.op });
|
|
3411
|
+
item[key] = next;
|
|
2952
3412
|
} catch {
|
|
2953
3413
|
ok2 = false;
|
|
2954
3414
|
}
|
|
@@ -3023,7 +3483,7 @@ function createSheetsOtAdapter(port, hooks = {}) {
|
|
|
3023
3483
|
});
|
|
3024
3484
|
});
|
|
3025
3485
|
}
|
|
3026
|
-
return sheetsStateHash(port.snapshot());
|
|
3486
|
+
return (hooks.stateHash ?? sheetsStateHash)(port.snapshot());
|
|
3027
3487
|
},
|
|
3028
3488
|
held: () => queue.length,
|
|
3029
3489
|
rebaseLocalOverHeld(local) {
|
|
@@ -3135,6 +3595,8 @@ var VALUES = "sheet.mutation.set-range-values";
|
|
|
3135
3595
|
var ADD_MERGE = "sheet.mutation.add-worksheet-merge";
|
|
3136
3596
|
var REMOVE_MERGE = "sheet.mutation.remove-worksheet-merge";
|
|
3137
3597
|
var SHEET_NAME = "sheet.mutation.set-worksheet-name";
|
|
3598
|
+
var INSERT_SHEET = "sheet.mutation.insert-sheet";
|
|
3599
|
+
var RESHAPE = /* @__PURE__ */ new Set(["sheet.mutation.set-worksheet-row-count", "sheet.mutation.set-worksheet-column-count", "sheet.mutation.remove-sheet", INSERT_SHEET]);
|
|
3138
3600
|
var DEPTH_GUARD = /* @__PURE__ */ Symbol.for("ai-matrx.office.sheets.command-depth-guard");
|
|
3139
3601
|
var json = (v) => v === void 0 ? v : JSON.parse(JSON.stringify(v));
|
|
3140
3602
|
var flagged = (options) => {
|
|
@@ -3171,7 +3633,8 @@ function univerSheetsOtPort(o) {
|
|
|
3171
3633
|
for (const [id, d] of Object.entries(map)) out[id] = String(d?.name ?? "");
|
|
3172
3634
|
return out;
|
|
3173
3635
|
};
|
|
3174
|
-
const
|
|
3636
|
+
const sheetOrder = () => (o.workbook()?.getSheets() ?? []).map((ws) => ws.getSheetId());
|
|
3637
|
+
const openGroup = (label) => ({ label, order: sheetOrder(), sheets: sheetNames(), names: definedNames(), mutations: [], inverses: [], notShared: null });
|
|
3175
3638
|
const emit = (e) => {
|
|
3176
3639
|
for (const l of [...listeners]) {
|
|
3177
3640
|
try {
|
|
@@ -3187,7 +3650,8 @@ function univerSheetsOtPort(o) {
|
|
|
3187
3650
|
if (!g) return;
|
|
3188
3651
|
if (g.notShared) emit({ kind: "not_shared", mutationId: g.notShared, label: g.label });
|
|
3189
3652
|
else if (g.mutations.length) {
|
|
3190
|
-
const mutations = annotateFormulas(g.mutations, g.sheets, g.names);
|
|
3653
|
+
const mutations = annotateSheetOps(annotateFormulas(g.mutations, g.sheets, g.names), g.order);
|
|
3654
|
+
if (mutations.some((m) => isStructuralMutation(m) || RESHAPE.has(m.id))) clampSelection();
|
|
3191
3655
|
const known = g.inverses.every((i) => i !== void 0);
|
|
3192
3656
|
const inverse = known ? annotateFormulas(g.inverses.slice().reverse().flat(), g.sheets, g.names) : void 0;
|
|
3193
3657
|
emit({ kind: "group", mutations, ...inverse !== void 0 ? { inverse } : {}, label: g.label });
|
|
@@ -3221,7 +3685,27 @@ function univerSheetsOtPort(o) {
|
|
|
3221
3685
|
}
|
|
3222
3686
|
if (info.id === SHEET_NAME) record.name = ws.getName();
|
|
3223
3687
|
pre.set(p, record);
|
|
3688
|
+
const owed = isStructuralMutation({ id: info.id, params: p }) ? mergeFixupsOwed({ id: info.id, params: p }, record.merges ?? []) : null;
|
|
3689
|
+
if (owed) {
|
|
3690
|
+
runOwn(REMOVE_MERGE, String(p.subUnitId), owed.remove, ADD_MERGE);
|
|
3691
|
+
if (owed.add.length) record.addAfter = owed.add;
|
|
3692
|
+
}
|
|
3224
3693
|
});
|
|
3694
|
+
const runOwn = (id, sheet, ranges, inverseId) => {
|
|
3695
|
+
const u = unitId();
|
|
3696
|
+
if (!u) return;
|
|
3697
|
+
applying = true;
|
|
3698
|
+
try {
|
|
3699
|
+
cs.syncExecuteCommand(id, { unitId: u, subUnitId: sheet, ranges: json(ranges) }, { onlyLocal: true });
|
|
3700
|
+
} finally {
|
|
3701
|
+
applying = false;
|
|
3702
|
+
}
|
|
3703
|
+
if (!group) group = openGroup(null);
|
|
3704
|
+
if (!group.notShared) {
|
|
3705
|
+
group.mutations.push({ id, params: { subUnitId: sheet, ranges: json(ranges) } });
|
|
3706
|
+
group.inverses.push([{ id: inverseId, params: { subUnitId: sheet, ranges: json(ranges) } }]);
|
|
3707
|
+
}
|
|
3708
|
+
};
|
|
3225
3709
|
const after = cs.onCommandExecuted((info) => {
|
|
3226
3710
|
if (info.type !== COMMAND) return;
|
|
3227
3711
|
const at = tracker.stack.lastIndexOf(info.id);
|
|
@@ -3319,6 +3803,8 @@ function univerSheetsOtPort(o) {
|
|
|
3319
3803
|
if (!m2) return { m: null, inverse: void 0 };
|
|
3320
3804
|
return { m: m2, inverse: [{ id: ADD_MERGE, params: { subUnitId: sheet, ranges: json(m2.params.ranges) } }] };
|
|
3321
3805
|
}
|
|
3806
|
+
if (info.id === INSERT_SHEET && params.sheet && typeof params.sheet === "object")
|
|
3807
|
+
params.sheet = inlineSheetStyles(params.sheet, (id) => o.workbook()?.getStyles().get(id));
|
|
3322
3808
|
const m = { id: info.id, params };
|
|
3323
3809
|
switch (info.id) {
|
|
3324
3810
|
case "sheet.mutation.insert-row":
|
|
@@ -3327,6 +3813,11 @@ function univerSheetsOtPort(o) {
|
|
|
3327
3813
|
return { m, inverse: [{ id: "sheet.mutation.remove-col", params: { subUnitId: sheet, range: json(params.range) } }] };
|
|
3328
3814
|
case ADD_MERGE:
|
|
3329
3815
|
return { m, inverse: [{ id: REMOVE_MERGE, params: { subUnitId: sheet, ranges: json(params.ranges) } }] };
|
|
3816
|
+
case "sheet.mutation.reorder-range": {
|
|
3817
|
+
const order = {};
|
|
3818
|
+
for (const [t, src] of Object.entries(params.order ?? {})) order[String(src)] = Number(t);
|
|
3819
|
+
return { m, inverse: [{ id: info.id, params: { subUnitId: sheet, range: json(params.range), order } }] };
|
|
3820
|
+
}
|
|
3330
3821
|
case SHEET_NAME:
|
|
3331
3822
|
return { m, inverse: before2.name !== void 0 ? [{ id: SHEET_NAME, params: { subUnitId: sheet, name: before2.name } }] : void 0 };
|
|
3332
3823
|
default:
|
|
@@ -3335,8 +3826,7 @@ function univerSheetsOtPort(o) {
|
|
|
3335
3826
|
};
|
|
3336
3827
|
const collab = cs.onMutationExecutedForCollab((info, options) => {
|
|
3337
3828
|
if (applying || flagged(options) || !mine(info.params)) return;
|
|
3338
|
-
|
|
3339
|
-
if (lone) group = openGroup(null);
|
|
3829
|
+
if (!group) group = openGroup(null);
|
|
3340
3830
|
const g = group;
|
|
3341
3831
|
if (!g.notShared) {
|
|
3342
3832
|
const r = capture(info);
|
|
@@ -3346,11 +3836,29 @@ function univerSheetsOtPort(o) {
|
|
|
3346
3836
|
g.inverses.push(r.inverse);
|
|
3347
3837
|
}
|
|
3348
3838
|
}
|
|
3349
|
-
|
|
3839
|
+
const owedAdd = pre.get(info.params)?.addAfter;
|
|
3840
|
+
if (owedAdd?.length) runOwn(ADD_MERGE, String(info.params.subUnitId ?? ""), owedAdd, REMOVE_MERGE);
|
|
3841
|
+
if (tracker.stack.length === 0) settle();
|
|
3350
3842
|
});
|
|
3843
|
+
const clampSelection = () => {
|
|
3844
|
+
const sel = o.selections;
|
|
3845
|
+
if (!sel) return;
|
|
3846
|
+
try {
|
|
3847
|
+
const sheet = sel.sheetId();
|
|
3848
|
+
const ws = sheet ? o.workbook()?.getSheetBySheetId(sheet) : null;
|
|
3849
|
+
const current = sel.get();
|
|
3850
|
+
if (!ws || !current?.length) return;
|
|
3851
|
+
const rows = ws.getMaxRows?.() ?? Number.MAX_SAFE_INTEGER;
|
|
3852
|
+
const cols = ws.getMaxColumns?.() ?? Number.MAX_SAFE_INTEGER;
|
|
3853
|
+
const next = moveSelectionsThrough(json(current), { id: "", params: {} }, rows, cols);
|
|
3854
|
+
if (JSON.stringify(next) !== JSON.stringify(current)) sel.set(next);
|
|
3855
|
+
} catch (err) {
|
|
3856
|
+
console.warn("[sheets-ot] could not keep this seat's selection inside the sheet after its own row or column change", err);
|
|
3857
|
+
}
|
|
3858
|
+
};
|
|
3351
3859
|
const followSelection = (m) => {
|
|
3352
3860
|
const sel = o.selections;
|
|
3353
|
-
if (!sel || !axisOpOf(m)) return;
|
|
3861
|
+
if (!sel || !axisOpOf(m) && !RESHAPE.has(m.id)) return;
|
|
3354
3862
|
try {
|
|
3355
3863
|
const sheet = String(m.params.subUnitId ?? "");
|
|
3356
3864
|
if (sel.sheetId() !== sheet) return;
|