@ai-matrx/office 0.8.22 → 0.8.24
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 +7 -1
- package/dist/collab-sheets-transform.cjs +151 -79
- package/dist/collab-sheets-transform.cjs.map +1 -1
- package/dist/collab-sheets-transform.d.cts +1 -1
- package/dist/collab-sheets-transform.d.ts +1 -1
- package/dist/collab-sheets-transform.js +151 -79
- package/dist/collab-sheets-transform.js.map +1 -1
- package/dist/docs.cjs +74 -1
- package/dist/docs.cjs.map +1 -1
- package/dist/docs.d.cts +52 -1
- package/dist/docs.d.ts +52 -1
- package/dist/docs.js +73 -0
- package/dist/docs.js.map +1 -1
- package/dist/sheets-comment-anchors.cjs +217 -0
- package/dist/sheets-comment-anchors.cjs.map +1 -0
- package/dist/sheets-comment-anchors.d.cts +52 -0
- package/dist/sheets-comment-anchors.d.ts +52 -0
- package/dist/sheets-comment-anchors.js +217 -0
- package/dist/sheets-comment-anchors.js.map +1 -0
- package/dist/univer-collab.cjs +286 -96
- package/dist/univer-collab.cjs.map +1 -1
- package/dist/univer-collab.d.cts +23 -2
- package/dist/univer-collab.d.ts +23 -2
- package/dist/univer-collab.js +288 -96
- package/dist/univer-collab.js.map +1 -1
- package/package.json +22 -4
package/dist/univer-collab.js
CHANGED
|
@@ -1113,25 +1113,25 @@ function rebaseUndoStack(items, remote) {
|
|
|
1113
1113
|
let dropped = 0;
|
|
1114
1114
|
for (let i = items.length - 1; i >= 0; i--) {
|
|
1115
1115
|
const item = items[i];
|
|
1116
|
-
let
|
|
1116
|
+
let ok3 = true;
|
|
1117
1117
|
for (const list of [item.undoMutations, item.redoMutations]) {
|
|
1118
1118
|
for (const m of list ?? []) {
|
|
1119
1119
|
if (m.id !== RICH_TEXT_EDITING) continue;
|
|
1120
1120
|
try {
|
|
1121
1121
|
if (touchesPageSetup(m.params.actions) && touchesPageSetup(remote)) throw new Error("page setup");
|
|
1122
1122
|
const r = transformDocsOp(m.params.actions, remote, "left");
|
|
1123
|
-
if (isNoopDocsOp(r.op))
|
|
1123
|
+
if (isNoopDocsOp(r.op)) ok3 = false;
|
|
1124
1124
|
else {
|
|
1125
1125
|
m.params = { ...m.params, actions: r.op };
|
|
1126
1126
|
delete m.params.textRanges;
|
|
1127
1127
|
delete m.params.layoutState;
|
|
1128
1128
|
}
|
|
1129
1129
|
} catch {
|
|
1130
|
-
|
|
1130
|
+
ok3 = false;
|
|
1131
1131
|
}
|
|
1132
1132
|
}
|
|
1133
1133
|
}
|
|
1134
|
-
if (!
|
|
1134
|
+
if (!ok3) {
|
|
1135
1135
|
items.splice(i, 1);
|
|
1136
1136
|
dropped++;
|
|
1137
1137
|
}
|
|
@@ -1290,7 +1290,9 @@ function openDocsOtRoom(o) {
|
|
|
1290
1290
|
...o.presence ? { presence: o.presence } : {},
|
|
1291
1291
|
onNotice: (n) => notice(n),
|
|
1292
1292
|
...o.onIncident ? { onIncident: o.onIncident } : {},
|
|
1293
|
-
...o.onStatus ? { onStatus: o.onStatus } : {}
|
|
1293
|
+
...o.onStatus ? { onStatus: o.onStatus } : {},
|
|
1294
|
+
...o.offline ? { offline: o.offline } : {},
|
|
1295
|
+
...o.onOffline ? { onOffline: o.onOffline } : {}
|
|
1294
1296
|
});
|
|
1295
1297
|
const isSaver = () => {
|
|
1296
1298
|
if (!o.presence) return true;
|
|
@@ -1328,6 +1330,7 @@ import * as Y2 from "yjs";
|
|
|
1328
1330
|
import { Awareness as Awareness2 } from "y-protocols/awareness";
|
|
1329
1331
|
import {
|
|
1330
1332
|
awarenessOpPresence,
|
|
1333
|
+
browserOfflineOptions,
|
|
1331
1334
|
claimCollaboratorColor as claimCollaboratorColor2,
|
|
1332
1335
|
collabReplace,
|
|
1333
1336
|
collabRoomExists,
|
|
@@ -1565,7 +1568,9 @@ function documentOtFactory(o) {
|
|
|
1565
1568
|
replace: ({ snapshot, stateHash, clientId }) => collabReplace(client, { roomId: o.documentId, snapshot, stateHash, origin: "restore", clientId }),
|
|
1566
1569
|
...o.onNotice ? { onNotice: o.onNotice } : {},
|
|
1567
1570
|
...o.onIncident ? { onIncident: o.onIncident } : {},
|
|
1568
|
-
...o.onStatus ? { onStatus: o.onStatus } : {}
|
|
1571
|
+
...o.onStatus ? { onStatus: o.onStatus } : {},
|
|
1572
|
+
offline: browserOfflineOptions(`${o.documentId}:${o.uid}`),
|
|
1573
|
+
...o.onOffline ? { onOffline: o.onOffline } : {}
|
|
1569
1574
|
});
|
|
1570
1575
|
await room.session.ready;
|
|
1571
1576
|
let lastKey = "";
|
|
@@ -1693,6 +1698,8 @@ var SHEET_MUTATIONS = {
|
|
|
1693
1698
|
"sheet.mutation.insert-sheet": covered("sheet", "index", "sheet"),
|
|
1694
1699
|
"sheet.mutation.remove-sheet": covered("sheet", "sheetIndex", "sheetsLeft"),
|
|
1695
1700
|
"sheet.mutation.set-worksheet-order": covered("sheet", "fromOrder", "toOrder"),
|
|
1701
|
+
// ── covered (C9): our own cell comment anchors (comment-anchor-transform.ts; not emitted by Univer) ──────
|
|
1702
|
+
"matrx.mutation.set-comment-anchor": covered("anchor", "anchorId", "cell"),
|
|
1696
1703
|
"sheet.mutation.reorder-range": covered("sort", "range", "order"),
|
|
1697
1704
|
// ── never travels ────────────────────────────────────────────────────────────────────────────────
|
|
1698
1705
|
"formula.mutation.set-formula-calculation-start": never(FORMULA_RESULT),
|
|
@@ -2144,6 +2151,74 @@ function refSheetsFor(texts, sheets) {
|
|
|
2144
2151
|
return Object.keys(out).length ? out : void 0;
|
|
2145
2152
|
}
|
|
2146
2153
|
|
|
2154
|
+
// src/collab/sheets/comment-anchor-transform.ts
|
|
2155
|
+
var SET_SHEET_COMMENT_ANCHOR = "matrx.mutation.set-comment-anchor";
|
|
2156
|
+
var REMOVE_SHEET = "sheet.mutation.remove-sheet";
|
|
2157
|
+
function structuralAxisOp(id, params) {
|
|
2158
|
+
const p = params;
|
|
2159
|
+
switch (id) {
|
|
2160
|
+
case "sheet.mutation.insert-row":
|
|
2161
|
+
return p.range ? { axis: "row", op: { kind: "insert", at: p.range.startRow, count: p.range.endRow - p.range.startRow + 1 } } : null;
|
|
2162
|
+
case "sheet.mutation.remove-rows":
|
|
2163
|
+
return p.range ? { axis: "row", op: { kind: "remove", start: p.range.startRow, count: p.range.endRow - p.range.startRow + 1 } } : null;
|
|
2164
|
+
case "sheet.mutation.insert-col":
|
|
2165
|
+
return p.range ? { axis: "col", op: { kind: "insert", at: p.range.startColumn, count: p.range.endColumn - p.range.startColumn + 1 } } : null;
|
|
2166
|
+
case "sheet.mutation.remove-col":
|
|
2167
|
+
return p.range ? { axis: "col", op: { kind: "remove", start: p.range.startColumn, count: p.range.endColumn - p.range.startColumn + 1 } } : null;
|
|
2168
|
+
case "sheet.mutation.move-rows":
|
|
2169
|
+
return p.sourceRange && p.targetRange ? { axis: "row", op: { kind: "move", from: p.sourceRange.startRow, count: p.sourceRange.endRow - p.sourceRange.startRow + 1, to: p.targetRange.startRow } } : null;
|
|
2170
|
+
case "sheet.mutation.move-columns":
|
|
2171
|
+
return p.sourceRange && p.targetRange ? {
|
|
2172
|
+
axis: "col",
|
|
2173
|
+
op: { kind: "move", from: p.sourceRange.startColumn, count: p.sourceRange.endColumn - p.sourceRange.startColumn + 1, to: p.targetRange.startColumn }
|
|
2174
|
+
} : null;
|
|
2175
|
+
default:
|
|
2176
|
+
return null;
|
|
2177
|
+
}
|
|
2178
|
+
}
|
|
2179
|
+
function moveSheetAnchorCell(cell, sheet, id, params) {
|
|
2180
|
+
if (String(params.subUnitId ?? "") !== sheet) return cell;
|
|
2181
|
+
if (id === REMOVE_SHEET) return null;
|
|
2182
|
+
const s = structuralAxisOp(id, params);
|
|
2183
|
+
if (!s) return cell;
|
|
2184
|
+
if (s.axis === "row") {
|
|
2185
|
+
const row = mapIndex(s.op, cell.row);
|
|
2186
|
+
return row === null ? null : row === cell.row ? cell : { row, col: cell.col };
|
|
2187
|
+
}
|
|
2188
|
+
const col = mapIndex(s.op, cell.col);
|
|
2189
|
+
return col === null ? null : col === cell.col ? cell : { row: cell.row, col };
|
|
2190
|
+
}
|
|
2191
|
+
function colName(c) {
|
|
2192
|
+
let s = "";
|
|
2193
|
+
for (let n = c + 1; n > 0; n = Math.floor((n - 1) / 26)) s = String.fromCharCode(65 + (n - 1) % 26) + s;
|
|
2194
|
+
return s;
|
|
2195
|
+
}
|
|
2196
|
+
var sheetCellName = (cell) => `${colName(cell.col)}${cell.row + 1}`;
|
|
2197
|
+
function cellOf(m) {
|
|
2198
|
+
const c = m.params.cell;
|
|
2199
|
+
return c && typeof c.row === "number" && typeof c.col === "number" ? c : null;
|
|
2200
|
+
}
|
|
2201
|
+
var ok = (op, lost = [], dropped = []) => ({ op, lost, dropped });
|
|
2202
|
+
var label = (m) => {
|
|
2203
|
+
const c = cellOf(m);
|
|
2204
|
+
return `${String(m.params.subUnitId ?? "")}!${c ? sheetCellName(c) : "?"} comment`;
|
|
2205
|
+
};
|
|
2206
|
+
function transformCommentAnchor(x, y, side) {
|
|
2207
|
+
const xa = x.id === SET_SHEET_COMMENT_ANCHOR;
|
|
2208
|
+
const ya = y.id === SET_SHEET_COMMENT_ANCHOR;
|
|
2209
|
+
if (!xa && !ya) return null;
|
|
2210
|
+
if (!xa) return ok([x]);
|
|
2211
|
+
if (ya) {
|
|
2212
|
+
if (x.params.anchorId !== y.params.anchorId || x.params.subUnitId !== y.params.subUnitId) return ok([x]);
|
|
2213
|
+
return side === "left" ? ok([x], [label(y)]) : ok([], [], [label(x)]);
|
|
2214
|
+
}
|
|
2215
|
+
const cell = cellOf(x);
|
|
2216
|
+
if (!cell) return ok([x]);
|
|
2217
|
+
const moved = moveSheetAnchorCell(cell, String(x.params.subUnitId ?? ""), y.id, y.params);
|
|
2218
|
+
if (!moved) return ok([], [], [label(x)]);
|
|
2219
|
+
return ok([moved === cell ? x : { id: x.id, params: { ...x.params, cell: moved } }]);
|
|
2220
|
+
}
|
|
2221
|
+
|
|
2147
2222
|
// src/collab/sheets/transform/transform.ts
|
|
2148
2223
|
var SHEET_TRANSFORMER_VERSION = "c5c-1";
|
|
2149
2224
|
var ID = {
|
|
@@ -2175,16 +2250,16 @@ var ID = {
|
|
|
2175
2250
|
var PAIR_BARRIERS = {};
|
|
2176
2251
|
var pairKey = (a, b) => a < b ? `${a}|${b}` : `${b}|${a}`;
|
|
2177
2252
|
var barrier2 = (reason) => ({ barrier: true, reason });
|
|
2178
|
-
var
|
|
2253
|
+
var ok2 = (op, lost = [], dropped = []) => ({ op, lost, dropped });
|
|
2179
2254
|
var flip = (side) => side === "left" ? "right" : "left";
|
|
2180
2255
|
var sheetOf = (m) => String(m.params.subUnitId ?? "");
|
|
2181
|
-
function
|
|
2256
|
+
function colName2(c) {
|
|
2182
2257
|
let s = "";
|
|
2183
2258
|
for (let n = c + 1; n > 0; n = Math.floor((n - 1) / 26)) s = String.fromCharCode(65 + (n - 1) % 26) + s;
|
|
2184
2259
|
return s;
|
|
2185
2260
|
}
|
|
2186
|
-
var cellRef = (sheet, row, col) => `${sheet}!${
|
|
2187
|
-
var rangeRef = (sheet, r) => `${sheet}!${
|
|
2261
|
+
var cellRef = (sheet, row, col) => `${sheet}!${colName2(col)}${row + 1}`;
|
|
2262
|
+
var rangeRef = (sheet, r) => `${sheet}!${colName2(r.startColumn)}${r.startRow + 1}:${colName2(r.endColumn)}${r.endRow + 1}`;
|
|
2188
2263
|
function structuralOf(m) {
|
|
2189
2264
|
const p = m.params;
|
|
2190
2265
|
switch (m.id) {
|
|
@@ -2439,9 +2514,9 @@ function transformCell(X, Y4, side) {
|
|
|
2439
2514
|
return { entries: Object.keys(out).length ? [out, ...tail] : tail, xLost, yLost };
|
|
2440
2515
|
}
|
|
2441
2516
|
function transformCellsOverCells(x, y, side) {
|
|
2442
|
-
if (sheetOf(x) !== sheetOf(y)) return
|
|
2517
|
+
if (sheetOf(x) !== sheetOf(y)) return ok2([x]);
|
|
2443
2518
|
const ycells = cellsOf(y);
|
|
2444
|
-
if (!cellsOverlap(cellsOf(x), ycells)) return
|
|
2519
|
+
if (!cellsOverlap(cellsOf(x), ycells)) return ok2([x]);
|
|
2445
2520
|
const xd = isDerived(x);
|
|
2446
2521
|
const yd = isDerived(y);
|
|
2447
2522
|
const eff = derivedSide(x, y, side);
|
|
@@ -2467,7 +2542,7 @@ function transformCellsOverCells(x, y, side) {
|
|
|
2467
2542
|
});
|
|
2468
2543
|
if (why) return barrier2(why);
|
|
2469
2544
|
const op = passes.filter((p) => !isEmptyMatrix(p)).map((p) => cellsMutation(x, p));
|
|
2470
|
-
return
|
|
2545
|
+
return ok2(op, lost, dropped);
|
|
2471
2546
|
}
|
|
2472
2547
|
var SIDE_CAR_PARAMS = ["refSheets", "previousName", "derived", "sheetIndex", "sheetsLeft"];
|
|
2473
2548
|
var isDerived = (m) => m.params.derived === true;
|
|
@@ -2538,7 +2613,7 @@ function cellThrough(sheet, change, r, c) {
|
|
|
2538
2613
|
return nr === null || nc === null ? null : [nr, nc];
|
|
2539
2614
|
}
|
|
2540
2615
|
function cellsOverChange(x, change) {
|
|
2541
|
-
if (!hasFormula(x) && (change.kind !== "axis" || change.sheet !== sheetOf(x))) return
|
|
2616
|
+
if (!hasFormula(x) && (change.kind !== "axis" || change.sheet !== sheetOf(x))) return ok2([x]);
|
|
2542
2617
|
const ctx = formulaCtx(x);
|
|
2543
2618
|
const out = {};
|
|
2544
2619
|
const dropped = [];
|
|
@@ -2567,9 +2642,9 @@ function cellsOverChange(x, change) {
|
|
|
2567
2642
|
});
|
|
2568
2643
|
if (why) return barrier2(why);
|
|
2569
2644
|
const rsAfter = refSheetsAfter(ctx.refSheets, change);
|
|
2570
|
-
if (!changed && JSON.stringify(rsAfter ?? null) === JSON.stringify(ctx.refSheets ?? null)) return
|
|
2645
|
+
if (!changed && JSON.stringify(rsAfter ?? null) === JSON.stringify(ctx.refSheets ?? null)) return ok2([x]);
|
|
2571
2646
|
const params = { ...withRefSheets(x.params, rsAfter), cellValue: out };
|
|
2572
|
-
return
|
|
2647
|
+
return ok2(isEmptyMatrix(out) ? [] : [{ id: x.id, params }], [], dropped);
|
|
2573
2648
|
}
|
|
2574
2649
|
function rewritesOf(y, change) {
|
|
2575
2650
|
if (!hasFormula(y)) return null;
|
|
@@ -2616,36 +2691,36 @@ function formulaPair(x, y, side) {
|
|
|
2616
2691
|
const fy = familyOf(y.id);
|
|
2617
2692
|
const SET_NAME_BARRIER = "set-defined-name without previousName (capture must record the name it replaces) against formula text";
|
|
2618
2693
|
if (fx === "defname" && fy === "defname") {
|
|
2619
|
-
if (String(x.params.id) !== String(y.params.id)) return
|
|
2694
|
+
if (String(x.params.id) !== String(y.params.id)) return ok2([x]);
|
|
2620
2695
|
const eff = derivedSide(x, y, side);
|
|
2621
|
-
if (eff === "left") return
|
|
2622
|
-
return
|
|
2696
|
+
if (eff === "left") return ok2([x], isDerived(y) ? [] : [`defined name "${String(y.params.name)}"`]);
|
|
2697
|
+
return ok2([], [], isDerived(x) ? [] : [`defined name "${String(x.params.name)}"`]);
|
|
2623
2698
|
}
|
|
2624
2699
|
if (fx === "defname") {
|
|
2625
2700
|
if (fy === "cell") {
|
|
2626
2701
|
if (setNameWithoutPrevious(x) && hasFormula(y)) return barrier2(SET_NAME_BARRIER);
|
|
2627
2702
|
const ch2 = refChangeOf(x);
|
|
2628
|
-
if (!ch2) return
|
|
2703
|
+
if (!ch2) return ok2([x]);
|
|
2629
2704
|
const add = rewritesOf(y, ch2);
|
|
2630
2705
|
if (typeof add === "string") return barrier2(add);
|
|
2631
|
-
return
|
|
2706
|
+
return ok2(add ? [x, add] : [x]);
|
|
2632
2707
|
}
|
|
2633
2708
|
const ch = refChangeOf(y);
|
|
2634
|
-
if (!ch) return
|
|
2709
|
+
if (!ch) return ok2([x]);
|
|
2635
2710
|
const r = definedNameThrough(x, ch);
|
|
2636
|
-
return typeof r === "string" ? barrier2(r) :
|
|
2711
|
+
return typeof r === "string" ? barrier2(r) : ok2([r.op]);
|
|
2637
2712
|
}
|
|
2638
2713
|
if (fy === "defname") {
|
|
2639
2714
|
if (fx === "cell") {
|
|
2640
2715
|
if (setNameWithoutPrevious(y) && hasFormula(x)) return barrier2(SET_NAME_BARRIER);
|
|
2641
2716
|
const ch2 = refChangeOf(y);
|
|
2642
|
-
return ch2 ? cellsOverChange(x, ch2) :
|
|
2717
|
+
return ch2 ? cellsOverChange(x, ch2) : ok2([x]);
|
|
2643
2718
|
}
|
|
2644
2719
|
const ch = refChangeOf(x);
|
|
2645
|
-
if (!ch) return
|
|
2720
|
+
if (!ch) return ok2([x]);
|
|
2646
2721
|
const r = definedNameThrough(y, ch);
|
|
2647
2722
|
if (typeof r === "string") return barrier2(r);
|
|
2648
|
-
return
|
|
2723
|
+
return ok2(r.changed ? [x, asDerived(r.op)] : [x]);
|
|
2649
2724
|
}
|
|
2650
2725
|
if (fx === "cell") {
|
|
2651
2726
|
const ch = refChangeOf(y);
|
|
@@ -2660,7 +2735,7 @@ function formulaPair(x, y, side) {
|
|
|
2660
2735
|
});
|
|
2661
2736
|
const add = rewritesOf(y, ch);
|
|
2662
2737
|
if (typeof add === "string") return barrier2(add);
|
|
2663
|
-
return
|
|
2738
|
+
return ok2(add ? [x, add] : [x], lost);
|
|
2664
2739
|
}
|
|
2665
2740
|
return null;
|
|
2666
2741
|
}
|
|
@@ -2808,20 +2883,20 @@ function numfmtPair(x, y, side, sx, sy) {
|
|
|
2808
2883
|
const nx = isNumfmt(x);
|
|
2809
2884
|
const ny = isNumfmt(y);
|
|
2810
2885
|
if (!nx && !ny) return null;
|
|
2811
|
-
if (nx && sy) return
|
|
2812
|
-
if (ny && sx) return
|
|
2886
|
+
if (nx && sy) return ok2(nfBuild(x, nfParts(x).map((p) => ({ ...p, ranges: rectsThrough(sy, p.ranges) }))));
|
|
2887
|
+
if (ny && sx) return ok2([x]);
|
|
2813
2888
|
if (nx && ny) {
|
|
2814
|
-
if (side === "left") return
|
|
2889
|
+
if (side === "left") return ok2([x]);
|
|
2815
2890
|
const ys = nfParts(y).flatMap((p) => p.ranges);
|
|
2816
|
-
return
|
|
2891
|
+
return ok2(nfBuild(x, nfParts(x).map((p) => ({ ...p, ranges: rectsMinus(p.ranges, ys) }))));
|
|
2817
2892
|
}
|
|
2818
2893
|
if (nx && y.id === ID.values) {
|
|
2819
|
-
if (side === "left") return
|
|
2894
|
+
if (side === "left") return ok2([x]);
|
|
2820
2895
|
const ys = nWrites(y);
|
|
2821
|
-
return ys.length ?
|
|
2896
|
+
return ys.length ? ok2(nfBuild(x, nfParts(x).map((p) => ({ ...p, ranges: rectsMinus(p.ranges, ys) })))) : ok2([x]);
|
|
2822
2897
|
}
|
|
2823
2898
|
if (ny && x.id === ID.values) {
|
|
2824
|
-
if (side === "left") return
|
|
2899
|
+
if (side === "left") return ok2([x]);
|
|
2825
2900
|
const out = {};
|
|
2826
2901
|
const tail = {};
|
|
2827
2902
|
let touched = false;
|
|
@@ -2847,31 +2922,31 @@ function numfmtPair(x, y, side, sx, sy) {
|
|
|
2847
2922
|
}
|
|
2848
2923
|
putCell(out, r, c, v);
|
|
2849
2924
|
});
|
|
2850
|
-
if (!touched) return
|
|
2925
|
+
if (!touched) return ok2([x]);
|
|
2851
2926
|
const ops = [];
|
|
2852
2927
|
if (!isEmptyMatrix(out)) ops.push(cellsMutation(x, out));
|
|
2853
2928
|
if (!isEmptyMatrix(tail)) ops.push({ id: ID.values, params: { subUnitId: sheetOf(x), cellValue: tail } });
|
|
2854
|
-
return
|
|
2929
|
+
return ok2(ops);
|
|
2855
2930
|
}
|
|
2856
|
-
return
|
|
2931
|
+
return ok2([x]);
|
|
2857
2932
|
}
|
|
2858
2933
|
var isCount = (m) => m.id === ID.rowCount || m.id === ID.colCount;
|
|
2859
2934
|
var countAxis = (m) => m.id === ID.rowCount ? "row" : "col";
|
|
2860
2935
|
var countKey = (m) => m.id === ID.rowCount ? "rowCount" : "columnCount";
|
|
2861
2936
|
function countPair(x, y, sy) {
|
|
2862
|
-
if (!isCount(x)) return isCount(y) ?
|
|
2937
|
+
if (!isCount(x)) return isCount(y) ? ok2([x]) : null;
|
|
2863
2938
|
const k = countKey(x);
|
|
2864
2939
|
const v = Number(x.params[k]);
|
|
2865
2940
|
if (sy) {
|
|
2866
|
-
if (sy.axis !== countAxis(x) || sy.op.kind === "move") return
|
|
2941
|
+
if (sy.axis !== countAxis(x) || sy.op.kind === "move") return ok2([x]);
|
|
2867
2942
|
const d = sy.op.kind === "insert" ? sy.op.count : -sy.op.count;
|
|
2868
|
-
return
|
|
2943
|
+
return ok2([{ id: x.id, params: { ...x.params, [k]: Math.max(1, v + d) } }]);
|
|
2869
2944
|
}
|
|
2870
2945
|
if (isCount(y) && y.id === x.id) {
|
|
2871
2946
|
const w = Number(y.params[k]);
|
|
2872
|
-
return
|
|
2947
|
+
return ok2([w > v ? { id: x.id, params: { ...x.params, [k]: w } } : x]);
|
|
2873
2948
|
}
|
|
2874
|
-
return
|
|
2949
|
+
return ok2([x]);
|
|
2875
2950
|
}
|
|
2876
2951
|
var isSheetOp = (m) => m.id === ID.insertSheet || m.id === ID.removeSheet || m.id === ID.sheetOrder;
|
|
2877
2952
|
var sheetIdOf = (m) => m.id === ID.insertSheet ? String(m.params.sheet?.id ?? "") : sheetOf(m);
|
|
@@ -2904,31 +2979,31 @@ function sheetPair(x, y, side) {
|
|
|
2904
2979
|
const b = sheetAxisOf(y);
|
|
2905
2980
|
if (!a || !b) return barrier2("a sheet add or remove without its index (capture must call annotateSheetOps)");
|
|
2906
2981
|
if (x.id === ID.insertSheet && y.id === ID.insertSheet && sheetIdOf(x) === sheetIdOf(y)) {
|
|
2907
|
-
return JSON.stringify(x.params) === JSON.stringify(y.params) ?
|
|
2982
|
+
return JSON.stringify(x.params) === JSON.stringify(y.params) ? ok2([]) : barrier2("the same sheet id added twice with different content");
|
|
2908
2983
|
}
|
|
2909
2984
|
if (x.id === ID.removeSheet && typeof x.params.sheetsLeft === "number" && sheetIdOf(x) !== sheetIdOf(y) && (y.id === ID.removeSheet || y.id === ID.insertSheet)) {
|
|
2910
2985
|
const left = x.params.sheetsLeft + (y.id === ID.insertSheet ? 1 : -1);
|
|
2911
2986
|
if (left < 1) return barrier2("concurrent sheet removes would leave the workbook without a sheet");
|
|
2912
2987
|
const out2 = transformAxis(a, b, side);
|
|
2913
2988
|
if (!out2) return barrier2("sheet order: no transform");
|
|
2914
|
-
return
|
|
2989
|
+
return ok2(out2.map((o) => buildSheetOp({ id: x.id, params: { ...x.params, sheetsLeft: left } }, o)));
|
|
2915
2990
|
}
|
|
2916
2991
|
const out = transformAxis(a, b, side);
|
|
2917
2992
|
if (!out) return barrier2("sheet order: no transform");
|
|
2918
|
-
return
|
|
2993
|
+
return ok2(out.map((o) => buildSheetOp(x, o)), [], out.length === 0 && x.id === ID.sheetOrder ? [`${sheetIdOf(x)}: sheet order`] : []);
|
|
2919
2994
|
}
|
|
2920
2995
|
if (ys) {
|
|
2921
|
-
if (y.id !== ID.removeSheet) return
|
|
2996
|
+
if (y.id !== ID.removeSheet) return ok2([x]);
|
|
2922
2997
|
const gone2 = sheetOf(y);
|
|
2923
2998
|
if (namesSheet(x, gone2)) return barrier2("a formula names a sheet removed at the same time");
|
|
2924
2999
|
if (sheetOf(x) === gone2 && x.id !== ID.setName && x.id !== ID.removeName)
|
|
2925
|
-
return
|
|
2926
|
-
return
|
|
3000
|
+
return ok2([], [], isDerived(x) ? [] : [`${gone2}: the sheet was removed`]);
|
|
3001
|
+
return ok2([x]);
|
|
2927
3002
|
}
|
|
2928
|
-
if (x.id !== ID.removeSheet) return
|
|
3003
|
+
if (x.id !== ID.removeSheet) return ok2([x]);
|
|
2929
3004
|
const gone = sheetOf(x);
|
|
2930
3005
|
if (namesSheet(y, gone)) return barrier2("a formula names a sheet removed at the same time");
|
|
2931
|
-
return
|
|
3006
|
+
return ok2([x], sheetOf(y) === gone && !isDerived(y) && y.id !== ID.setName && y.id !== ID.removeName ? [`${gone}: the sheet was removed`] : []);
|
|
2932
3007
|
}
|
|
2933
3008
|
function annotateSheetOps(group, sheetOrder) {
|
|
2934
3009
|
const order = [...sheetOrder];
|
|
@@ -3026,22 +3101,22 @@ function sortPair(x, y, sx, sy) {
|
|
|
3026
3101
|
const a = sortOf(x).range;
|
|
3027
3102
|
const b = sortOf(y).range;
|
|
3028
3103
|
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") :
|
|
3104
|
+
return overlap ? barrier2("two sorts of overlapping ranges at once") : ok2([x]);
|
|
3030
3105
|
}
|
|
3031
3106
|
if (xs) {
|
|
3032
3107
|
if (sy) {
|
|
3033
3108
|
const t = sortThrough(sortOf(x), sy);
|
|
3034
|
-
return t ?
|
|
3109
|
+
return t ? ok2(buildSort(x, t)) : barrier2("a row or column move through a sorted range");
|
|
3035
3110
|
}
|
|
3036
|
-
return
|
|
3111
|
+
return ok2([x]);
|
|
3037
3112
|
}
|
|
3038
3113
|
const o = sortOf(y);
|
|
3039
3114
|
const Q = sortQ(o);
|
|
3040
3115
|
const moved = (r) => r >= o.range.startRow && r <= o.range.endRow && Q.has(r);
|
|
3041
3116
|
if (sx) {
|
|
3042
|
-
if (sx.axis === "col") return sx.op.kind === "move" && !sortThrough(o, sx) ? barrier2("a column move through a sorted range") :
|
|
3043
|
-
if (sx.op.kind === "insert") return
|
|
3044
|
-
if (sx.op.kind === "move") return sortThrough(o, sx) ?
|
|
3117
|
+
if (sx.axis === "col") return sx.op.kind === "move" && !sortThrough(o, sx) ? barrier2("a column move through a sorted range") : ok2([x]);
|
|
3118
|
+
if (sx.op.kind === "insert") return ok2([x]);
|
|
3119
|
+
if (sx.op.kind === "move") return sortThrough(o, sx) ? ok2([x]) : barrier2("a row move through a sorted range");
|
|
3045
3120
|
const rows = [];
|
|
3046
3121
|
let partial = false;
|
|
3047
3122
|
for (let i = sx.op.start; i < sx.op.start + sx.op.count; i++) {
|
|
@@ -3049,7 +3124,7 @@ function sortPair(x, y, sx, sy) {
|
|
|
3049
3124
|
rows.push(Q.get(i) ?? i);
|
|
3050
3125
|
}
|
|
3051
3126
|
if (partial) return barrier2("a row remove against a concurrent sort of those rows");
|
|
3052
|
-
return
|
|
3127
|
+
return ok2([x]);
|
|
3053
3128
|
}
|
|
3054
3129
|
if (x.id === ID.values) {
|
|
3055
3130
|
const out = {};
|
|
@@ -3060,7 +3135,7 @@ function sortPair(x, y, sx, sy) {
|
|
|
3060
3135
|
changed = true;
|
|
3061
3136
|
} else putCell(out, r, c, v);
|
|
3062
3137
|
});
|
|
3063
|
-
return changed ?
|
|
3138
|
+
return changed ? ok2([cellsMutation(x, out)]) : ok2([x]);
|
|
3064
3139
|
}
|
|
3065
3140
|
if (isNumfmt(x)) {
|
|
3066
3141
|
const parts = nfParts(x).map((p) => {
|
|
@@ -3076,9 +3151,9 @@ function sortPair(x, y, sx, sy) {
|
|
|
3076
3151
|
}
|
|
3077
3152
|
return { ...p, ranges };
|
|
3078
3153
|
});
|
|
3079
|
-
return
|
|
3154
|
+
return ok2(nfBuild(x, parts));
|
|
3080
3155
|
}
|
|
3081
|
-
return
|
|
3156
|
+
return ok2([x]);
|
|
3082
3157
|
}
|
|
3083
3158
|
function familyOf(id) {
|
|
3084
3159
|
const e = SHEET_MUTATIONS[id];
|
|
@@ -3094,13 +3169,15 @@ function transformMutation(x, y, side) {
|
|
|
3094
3169
|
if (why) return barrier2(why);
|
|
3095
3170
|
}
|
|
3096
3171
|
}
|
|
3172
|
+
const ca = transformCommentAnchor(x, y, side);
|
|
3173
|
+
if (ca) return ca;
|
|
3097
3174
|
const pb = PAIR_BARRIERS[pairKey(x.id, y.id)];
|
|
3098
3175
|
if (pb) return barrier2(`${x.id} \xD7 ${y.id}: ${pb.reason}${pb.seed === null ? "" : ` (fuzz seed ${pb.seed})`}`);
|
|
3099
3176
|
const sp = sheetPair(x, y, side);
|
|
3100
3177
|
if (sp) return sp;
|
|
3101
3178
|
const fp = formulaPair(x, y, side);
|
|
3102
3179
|
if (fp) return fp;
|
|
3103
|
-
if (sheetOf(x) !== sheetOf(y)) return
|
|
3180
|
+
if (sheetOf(x) !== sheetOf(y)) return ok2([x]);
|
|
3104
3181
|
const fx = familyOf(x.id);
|
|
3105
3182
|
const fy = familyOf(y.id);
|
|
3106
3183
|
const sy = structuralOf(y);
|
|
@@ -3112,11 +3189,11 @@ function transformMutation(x, y, side) {
|
|
|
3112
3189
|
const np = numfmtPair(x, y, side, sx, sy);
|
|
3113
3190
|
if (np) return np;
|
|
3114
3191
|
if (sx && sy) {
|
|
3115
|
-
if (sx.axis !== sy.axis) return
|
|
3192
|
+
if (sx.axis !== sy.axis) return ok2([x]);
|
|
3116
3193
|
const out = transformAxis(sx.op, sy.op, side);
|
|
3117
3194
|
if (!out) return barrier2(`${x.id} over ${y.id}: moved blocks overlap in part, or the block would split`);
|
|
3118
3195
|
const dropped = out.length === 0 && sx.op.kind === "move" ? [`${sheetOf(x)}: moved ${sx.axis}s`] : [];
|
|
3119
|
-
return
|
|
3196
|
+
return ok2(out.map((o) => buildStructural(x, sx.axis, o)), [], dropped);
|
|
3120
3197
|
}
|
|
3121
3198
|
if (sy) {
|
|
3122
3199
|
if (fx === "merge") {
|
|
@@ -3127,23 +3204,23 @@ function transformMutation(x, y, side) {
|
|
|
3127
3204
|
if (t) kept.push(t);
|
|
3128
3205
|
else dropped.push(rangeRef(sheetOf(x), r));
|
|
3129
3206
|
}
|
|
3130
|
-
return
|
|
3207
|
+
return ok2(kept.length ? [withRanges(x, kept)] : [], [], x.id === ID.addMerge ? dropped : []);
|
|
3131
3208
|
}
|
|
3132
3209
|
if (fx === "size") {
|
|
3133
3210
|
const size = sizeOf(x);
|
|
3134
|
-
if (size.axis !== sy.axis) return
|
|
3211
|
+
if (size.axis !== sy.axis) return ok2([x]);
|
|
3135
3212
|
const next = /* @__PURE__ */ new Map();
|
|
3136
3213
|
for (const [i, v] of size.values) {
|
|
3137
3214
|
const m = mapIndex(sy.op, i);
|
|
3138
3215
|
if (m !== null) next.set(m, v);
|
|
3139
3216
|
}
|
|
3140
3217
|
const built = buildSize(x, next);
|
|
3141
|
-
return
|
|
3218
|
+
return ok2(built ? [built] : []);
|
|
3142
3219
|
}
|
|
3143
|
-
return
|
|
3220
|
+
return ok2([x]);
|
|
3144
3221
|
}
|
|
3145
3222
|
if (sx) {
|
|
3146
|
-
if (fy !== "merge" || y.id !== ID.addMerge) return
|
|
3223
|
+
if (fy !== "merge" || y.id !== ID.addMerge) return ok2([x]);
|
|
3147
3224
|
const remove = [];
|
|
3148
3225
|
const add = [];
|
|
3149
3226
|
for (const r of mergeRanges(y)) {
|
|
@@ -3153,11 +3230,11 @@ function transformMutation(x, y, side) {
|
|
|
3153
3230
|
if (t.range) add.push(t.range);
|
|
3154
3231
|
}
|
|
3155
3232
|
const lostMerges = mergeRanges(y).filter((r) => mergeThrough(sx, r).range === null).map((r) => rangeRef(sheetOf(y), r));
|
|
3156
|
-
if (!remove.length) return
|
|
3233
|
+
if (!remove.length) return ok2([x], lostMerges);
|
|
3157
3234
|
const sheet = sheetOf(x);
|
|
3158
3235
|
const pre = sx.op.kind === "insert" ? [] : [mergeMutation(ID.removeMerge, sheet, remove)];
|
|
3159
3236
|
const mid = sx.op.kind === "insert" ? [mergeMutation(ID.removeMerge, sheet, remove)] : [];
|
|
3160
|
-
return
|
|
3237
|
+
return ok2([...pre, x, ...mid, ...add.length ? [mergeMutation(ID.addMerge, sheet, add)] : []], lostMerges);
|
|
3161
3238
|
}
|
|
3162
3239
|
if (fx === "cell" && fy === "cell") return transformCellsOverCells(x, y, side);
|
|
3163
3240
|
if (fx === "merge" && fy === "merge") {
|
|
@@ -3166,45 +3243,45 @@ function transformMutation(x, y, side) {
|
|
|
3166
3243
|
const hit = (r) => yr.some((q) => intersects(r, q));
|
|
3167
3244
|
const sheet = sheetOf(x);
|
|
3168
3245
|
if (x.id === ID.addMerge && y.id === ID.addMerge) {
|
|
3169
|
-
if (!xr.some(hit)) return
|
|
3246
|
+
if (!xr.some(hit)) return ok2([x]);
|
|
3170
3247
|
if (side === "left") {
|
|
3171
3248
|
const lost = yr.filter((q) => xr.some((r) => intersects(r, q))).map((q) => rangeRef(sheet, q));
|
|
3172
|
-
return
|
|
3249
|
+
return ok2([mergeMutation(ID.removeMerge, sheet, xr.filter(hit)), x], lost);
|
|
3173
3250
|
}
|
|
3174
3251
|
const kept = xr.filter((r) => !hit(r));
|
|
3175
|
-
return
|
|
3252
|
+
return ok2(kept.length ? [withRanges(x, kept)] : [], [], xr.filter(hit).map((r) => rangeRef(sheet, r)));
|
|
3176
3253
|
}
|
|
3177
3254
|
if (x.id === ID.addMerge && y.id === ID.removeMerge) {
|
|
3178
|
-
if (side === "left" || !xr.some(hit)) return
|
|
3255
|
+
if (side === "left" || !xr.some(hit)) return ok2([x], side === "left" && xr.some(hit) ? yr.filter((q) => xr.some((r) => intersects(r, q))).map((q) => rangeRef(sheet, q)) : []);
|
|
3179
3256
|
const kept = xr.filter((r) => !hit(r));
|
|
3180
|
-
return
|
|
3257
|
+
return ok2(kept.length ? [withRanges(x, kept)] : [], [], xr.filter(hit).map((r) => rangeRef(sheet, r)));
|
|
3181
3258
|
}
|
|
3182
3259
|
if (x.id === ID.removeMerge && y.id === ID.addMerge) {
|
|
3183
3260
|
const touched = yr.filter((q) => xr.some((r) => intersects(r, q)));
|
|
3184
|
-
if (!touched.length) return
|
|
3185
|
-
if (side === "left") return
|
|
3186
|
-
return
|
|
3261
|
+
if (!touched.length) return ok2([x]);
|
|
3262
|
+
if (side === "left") return ok2([x], touched.map((q) => rangeRef(sheet, q)));
|
|
3263
|
+
return ok2([x, mergeMutation(ID.addMerge, sheet, touched)], [], xr.filter(hit).map((r) => rangeRef(sheet, r)));
|
|
3187
3264
|
}
|
|
3188
|
-
return
|
|
3265
|
+
return ok2([x]);
|
|
3189
3266
|
}
|
|
3190
3267
|
if (fx === "size" && fy === "size") {
|
|
3191
3268
|
const a = sizeOf(x);
|
|
3192
3269
|
const b = sizeOf(y);
|
|
3193
|
-
if (a.axis !== b.axis || a.attr !== b.attr) return
|
|
3270
|
+
if (a.axis !== b.axis || a.attr !== b.attr) return ok2([x]);
|
|
3194
3271
|
if (side === "left") {
|
|
3195
3272
|
const lost = [...a.values.keys()].filter((i) => b.values.has(i)).map((i) => `${sheetOf(x)}: ${a.axis} ${i + 1} ${a.attr}`);
|
|
3196
|
-
return
|
|
3273
|
+
return ok2([x], lost);
|
|
3197
3274
|
}
|
|
3198
3275
|
const next = new Map([...a.values].filter(([i]) => !b.values.has(i)));
|
|
3199
3276
|
const built = buildSize(x, next);
|
|
3200
3277
|
const dropped = [...a.values.keys()].filter((i) => b.values.has(i)).map((i) => `${sheetOf(x)}: ${a.axis} ${i + 1} ${a.attr}`);
|
|
3201
|
-
return
|
|
3278
|
+
return ok2(built ? [built] : [], [], dropped);
|
|
3202
3279
|
}
|
|
3203
3280
|
if (fx === "name" && fy === "name") {
|
|
3204
|
-
if (side === "left") return
|
|
3205
|
-
return
|
|
3281
|
+
if (side === "left") return ok2([x], [`${sheetOf(x)}: name "${String(y.params.name)}"`]);
|
|
3282
|
+
return ok2([], [], [`${sheetOf(x)}: name "${String(x.params.name)}"`]);
|
|
3206
3283
|
}
|
|
3207
|
-
return
|
|
3284
|
+
return ok2([x]);
|
|
3208
3285
|
}
|
|
3209
3286
|
var blocked = (p) => !Array.isArray(p);
|
|
3210
3287
|
function tSeq(xs, ys, side, acc) {
|
|
@@ -3383,10 +3460,10 @@ function rebaseSheetUndoStack(items, remote, unitId) {
|
|
|
3383
3460
|
let dropped = 0;
|
|
3384
3461
|
for (let i = items.length - 1; i >= 0; i--) {
|
|
3385
3462
|
const item = items[i];
|
|
3386
|
-
let
|
|
3463
|
+
let ok3 = true;
|
|
3387
3464
|
for (const key of ["undoMutations", "redoMutations"]) {
|
|
3388
3465
|
const list = item[key];
|
|
3389
|
-
if (!
|
|
3466
|
+
if (!ok3 || !list?.length) continue;
|
|
3390
3467
|
const isOperation = (id) => !SHEET_MUTATIONS[id] && id.includes(".operation.");
|
|
3391
3468
|
const operations = list.filter((m) => isOperation(m.id));
|
|
3392
3469
|
let shaped = cachedShape(list);
|
|
@@ -3395,14 +3472,14 @@ function rebaseSheetUndoStack(items, remote, unitId) {
|
|
|
3395
3472
|
shapedLists.set(list, { src: list.slice(), shaped });
|
|
3396
3473
|
}
|
|
3397
3474
|
if (shaped.some((m) => m === null)) {
|
|
3398
|
-
|
|
3475
|
+
ok3 = false;
|
|
3399
3476
|
continue;
|
|
3400
3477
|
}
|
|
3401
3478
|
if (!shaped.length) continue;
|
|
3402
3479
|
try {
|
|
3403
3480
|
const r = transformGroup(shaped, remote, "left");
|
|
3404
3481
|
if (isBarrier(r) || r.op.length === 0) {
|
|
3405
|
-
|
|
3482
|
+
ok3 = false;
|
|
3406
3483
|
continue;
|
|
3407
3484
|
}
|
|
3408
3485
|
if (r.op.length === shaped.length && r.op.every((m, i2) => m === shaped[i2])) continue;
|
|
@@ -3410,10 +3487,10 @@ function rebaseSheetUndoStack(items, remote, unitId) {
|
|
|
3410
3487
|
shapedLists.set(next, { src: next.slice(), shaped: r.op });
|
|
3411
3488
|
item[key] = next;
|
|
3412
3489
|
} catch {
|
|
3413
|
-
|
|
3490
|
+
ok3 = false;
|
|
3414
3491
|
}
|
|
3415
3492
|
}
|
|
3416
|
-
if (!
|
|
3493
|
+
if (!ok3) {
|
|
3417
3494
|
items.splice(i, 1);
|
|
3418
3495
|
dropped++;
|
|
3419
3496
|
}
|
|
@@ -3557,7 +3634,9 @@ function openSheetsOtRoom(o) {
|
|
|
3557
3634
|
...o.presence ? { presence: o.presence } : {},
|
|
3558
3635
|
onNotice: (n) => notice(n),
|
|
3559
3636
|
...o.onIncident ? { onIncident: o.onIncident } : {},
|
|
3560
|
-
...o.onStatus ? { onStatus: o.onStatus } : {}
|
|
3637
|
+
...o.onStatus ? { onStatus: o.onStatus } : {},
|
|
3638
|
+
...o.offline ? { offline: o.offline } : {},
|
|
3639
|
+
...o.onOffline ? { onOffline: o.onOffline } : {}
|
|
3561
3640
|
});
|
|
3562
3641
|
const isSaver = () => {
|
|
3563
3642
|
if (!o.presence) return true;
|
|
@@ -3588,6 +3667,65 @@ function openSheetsOtRoom(o) {
|
|
|
3588
3667
|
};
|
|
3589
3668
|
}
|
|
3590
3669
|
|
|
3670
|
+
// src/univer/collab/sheets-ot/plugin-teardown.ts
|
|
3671
|
+
var perSheetList = (data) => Object.entries(data).flatMap(([sheet, list]) => Array.isArray(list) ? [[sheet, list.filter((x) => !!x && typeof x === "object")]] : []);
|
|
3672
|
+
var PLUGIN_TEARDOWNS = [
|
|
3673
|
+
{
|
|
3674
|
+
resource: "SHEET_CONDITIONAL_FORMATTING_PLUGIN",
|
|
3675
|
+
removals: (unitId, data) => perSheetList(data).flatMap(
|
|
3676
|
+
([subUnitId, rules]) => rules.filter((r) => typeof r.cfId === "string").map((r) => ({ id: "sheet.mutation.delete-conditional-rule", params: { unitId, subUnitId, cfId: r.cfId } }))
|
|
3677
|
+
)
|
|
3678
|
+
},
|
|
3679
|
+
{
|
|
3680
|
+
resource: "SHEET_DATA_VALIDATION_PLUGIN",
|
|
3681
|
+
removals: (unitId, data) => perSheetList(data).flatMap(([subUnitId, rules]) => {
|
|
3682
|
+
const ids = rules.map((r) => r.uid).filter((u) => typeof u === "string");
|
|
3683
|
+
return ids.length ? [{ id: "data-validation.mutation.removeRule", params: { unitId, subUnitId, ruleId: ids, source: "command" } }] : [];
|
|
3684
|
+
})
|
|
3685
|
+
},
|
|
3686
|
+
{
|
|
3687
|
+
resource: "SHEET_NOTE_PLUGIN",
|
|
3688
|
+
removals: (unitId, data) => Object.entries(data).flatMap(
|
|
3689
|
+
([sheetId, rows]) => Object.entries(rows ?? {}).flatMap(
|
|
3690
|
+
([row, cols]) => Object.entries(cols ?? {}).map(([col, note]) => ({
|
|
3691
|
+
id: "sheet.mutation.remove-note",
|
|
3692
|
+
params: { unitId, sheetId, row: Number(row), col: Number(col), ...note && typeof note.id === "string" ? { noteId: note.id } : {}, silent: true }
|
|
3693
|
+
}))
|
|
3694
|
+
)
|
|
3695
|
+
)
|
|
3696
|
+
}
|
|
3697
|
+
];
|
|
3698
|
+
function resourcesOf(saved) {
|
|
3699
|
+
const out = /* @__PURE__ */ new Map();
|
|
3700
|
+
const list = saved?.resources;
|
|
3701
|
+
for (const r of Array.isArray(list) ? list : []) {
|
|
3702
|
+
if (!r?.name) continue;
|
|
3703
|
+
try {
|
|
3704
|
+
const data = typeof r.data === "string" ? r.data ? JSON.parse(r.data) : null : r.data;
|
|
3705
|
+
if (data && typeof data === "object") out.set(r.name, data);
|
|
3706
|
+
} catch {
|
|
3707
|
+
}
|
|
3708
|
+
}
|
|
3709
|
+
return out;
|
|
3710
|
+
}
|
|
3711
|
+
function releaseUnitPluginState(cs, unitId, saved) {
|
|
3712
|
+
const resources = resourcesOf(saved);
|
|
3713
|
+
let ran = 0;
|
|
3714
|
+
for (const t of PLUGIN_TEARDOWNS) {
|
|
3715
|
+
const data = resources.get(t.resource);
|
|
3716
|
+
if (!data) continue;
|
|
3717
|
+
for (const m of t.removals(unitId, data)) {
|
|
3718
|
+
try {
|
|
3719
|
+
cs.syncExecuteCommand(m.id, m.params, { onlyLocal: true });
|
|
3720
|
+
ran++;
|
|
3721
|
+
} catch (err) {
|
|
3722
|
+
console.warn(`[sheets-ot] could not release ${t.resource} state before a reload`, err);
|
|
3723
|
+
}
|
|
3724
|
+
}
|
|
3725
|
+
}
|
|
3726
|
+
return ran;
|
|
3727
|
+
}
|
|
3728
|
+
|
|
3591
3729
|
// src/univer/collab/sheets-ot/univer-port.ts
|
|
3592
3730
|
var COMMAND = 0;
|
|
3593
3731
|
var MUTATION = 2;
|
|
@@ -3634,7 +3772,7 @@ function univerSheetsOtPort(o) {
|
|
|
3634
3772
|
return out;
|
|
3635
3773
|
};
|
|
3636
3774
|
const sheetOrder = () => (o.workbook()?.getSheets() ?? []).map((ws) => ws.getSheetId());
|
|
3637
|
-
const openGroup = (
|
|
3775
|
+
const openGroup = (label2) => ({ label: label2, order: sheetOrder(), sheets: sheetNames(), names: definedNames(), mutations: [], inverses: [], notShared: null });
|
|
3638
3776
|
const emit = (e) => {
|
|
3639
3777
|
for (const l of [...listeners]) {
|
|
3640
3778
|
try {
|
|
@@ -3890,8 +4028,8 @@ function univerSheetsOtPort(o) {
|
|
|
3890
4028
|
const a = forApply(m);
|
|
3891
4029
|
applying = true;
|
|
3892
4030
|
try {
|
|
3893
|
-
const
|
|
3894
|
-
if (
|
|
4031
|
+
const ok3 = cs.syncExecuteCommand(a.id, { ...json(a.params), unitId: u }, { fromCollab: true });
|
|
4032
|
+
if (ok3 === false) throw new Error(`"${m.id}" was refused by the editor`);
|
|
3895
4033
|
} finally {
|
|
3896
4034
|
applying = false;
|
|
3897
4035
|
}
|
|
@@ -3907,6 +4045,8 @@ function univerSheetsOtPort(o) {
|
|
|
3907
4045
|
group = null;
|
|
3908
4046
|
applying = true;
|
|
3909
4047
|
try {
|
|
4048
|
+
const u = unitId();
|
|
4049
|
+
if (u) releaseUnitPluginState(cs, u, o.saveUnit?.(u) ?? null);
|
|
3910
4050
|
o.load(snapshot);
|
|
3911
4051
|
} finally {
|
|
3912
4052
|
applying = false;
|
|
@@ -3996,11 +4136,59 @@ function moveSelectionsThrough(selections, m, maxRows, maxCols) {
|
|
|
3996
4136
|
return selections.map((s) => ({ ...s, range: box(s.range, s.range.rangeType), ...s.primary ? { primary: box(s.primary) } : {} }));
|
|
3997
4137
|
}
|
|
3998
4138
|
|
|
4139
|
+
// src/univer/collab/offline-text.ts
|
|
4140
|
+
var colName3 = (c) => {
|
|
4141
|
+
let n = c;
|
|
4142
|
+
let s = "";
|
|
4143
|
+
do {
|
|
4144
|
+
s = String.fromCharCode(65 + n % 26) + s;
|
|
4145
|
+
n = Math.floor(n / 26) - 1;
|
|
4146
|
+
} while (n >= 0);
|
|
4147
|
+
return s;
|
|
4148
|
+
};
|
|
4149
|
+
function collectDocText(v, out) {
|
|
4150
|
+
if (Array.isArray(v)) {
|
|
4151
|
+
for (const x of v) collectDocText(x, out);
|
|
4152
|
+
return;
|
|
4153
|
+
}
|
|
4154
|
+
if (!v || typeof v !== "object") return;
|
|
4155
|
+
const o = v;
|
|
4156
|
+
if (typeof o.dataStream === "string" && o.dataStream.length) out.push(o.dataStream);
|
|
4157
|
+
for (const k of Object.keys(o)) if (k !== "dataStream") collectDocText(o[k], out);
|
|
4158
|
+
}
|
|
4159
|
+
function collectCells(cellValue, out) {
|
|
4160
|
+
if (!cellValue || typeof cellValue !== "object") return;
|
|
4161
|
+
for (const [r, cols] of Object.entries(cellValue)) {
|
|
4162
|
+
if (!cols || typeof cols !== "object") continue;
|
|
4163
|
+
for (const [c, cell] of Object.entries(cols)) {
|
|
4164
|
+
const x = cell;
|
|
4165
|
+
const val = x?.f ?? x?.v;
|
|
4166
|
+
if (val !== void 0 && val !== null && val !== "") out.push(`${colName3(Number(c))}${Number(r) + 1}: ${String(val)}`);
|
|
4167
|
+
}
|
|
4168
|
+
}
|
|
4169
|
+
}
|
|
4170
|
+
function offlineTextOfGroups(buffers) {
|
|
4171
|
+
const docs = [];
|
|
4172
|
+
const cells = [];
|
|
4173
|
+
for (const groups of buffers) {
|
|
4174
|
+
for (const g of groups) {
|
|
4175
|
+
for (const m of g.mutations) {
|
|
4176
|
+
const p = m.params;
|
|
4177
|
+
if (p && "cellValue" in p) collectCells(p.cellValue, cells);
|
|
4178
|
+
else collectDocText(p, docs);
|
|
4179
|
+
}
|
|
4180
|
+
}
|
|
4181
|
+
}
|
|
4182
|
+
const text = docs.join("").replace(/\r/g, "\n").replace(/\u0000/g, "");
|
|
4183
|
+
return [text, cells.join("\n")].filter((s) => s.length > 0).join("\n");
|
|
4184
|
+
}
|
|
4185
|
+
|
|
3999
4186
|
// src/sheets/workbook-ot-room.ts
|
|
4000
4187
|
import * as Y3 from "yjs";
|
|
4001
4188
|
import { Awareness as Awareness3 } from "y-protocols/awareness";
|
|
4002
4189
|
import {
|
|
4003
4190
|
awarenessOpPresence as awarenessOpPresence2,
|
|
4191
|
+
browserOfflineOptions as browserOfflineOptions2,
|
|
4004
4192
|
claimCollaboratorColor as claimCollaboratorColor3,
|
|
4005
4193
|
collabReplace as collabReplace3,
|
|
4006
4194
|
collabRoomExists as collabRoomExists3,
|
|
@@ -4105,6 +4293,7 @@ async function startWorkbookOtRoom(port, o) {
|
|
|
4105
4293
|
await provider.connect();
|
|
4106
4294
|
publishAwareness();
|
|
4107
4295
|
const client = db4();
|
|
4296
|
+
const offline = browserOfflineOptions2(`${o.workbookId}:${o.uid}`);
|
|
4108
4297
|
const room = openSheetsOtRoom({
|
|
4109
4298
|
port,
|
|
4110
4299
|
clientId: o.clientId,
|
|
@@ -4125,7 +4314,9 @@ async function startWorkbookOtRoom(port, o) {
|
|
|
4125
4314
|
replace: ({ snapshot, stateHash, clientId }) => collabReplace3(client, { roomId: o.workbookId, snapshot, stateHash, origin: "restore", clientId }),
|
|
4126
4315
|
...o.onNotice ? { onNotice: o.onNotice } : {},
|
|
4127
4316
|
...o.onIncident ? { onIncident: o.onIncident } : {},
|
|
4128
|
-
...o.onStatus ? { onStatus: o.onStatus } : {}
|
|
4317
|
+
...o.onStatus ? { onStatus: o.onStatus } : {},
|
|
4318
|
+
...offline ? { offline } : {},
|
|
4319
|
+
...o.onOffline ? { onOffline: o.onOffline } : {}
|
|
4129
4320
|
});
|
|
4130
4321
|
await room.session.ready;
|
|
4131
4322
|
return {
|
|
@@ -4178,6 +4369,7 @@ export {
|
|
|
4178
4369
|
isNoopDocsOp,
|
|
4179
4370
|
moveSelectionsThrough,
|
|
4180
4371
|
normalizeDocsOp,
|
|
4372
|
+
offlineTextOfGroups,
|
|
4181
4373
|
openDocsOtRoom,
|
|
4182
4374
|
openSheetsOtRoom,
|
|
4183
4375
|
rebaseSheetUndoStack,
|