@ai-matrx/office 0.8.19 → 0.8.21
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 +23 -0
- package/dist/collab-sheets-transform.cjs +354 -16
- 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 +354 -16
- package/dist/collab-sheets-transform.js.map +1 -1
- package/dist/univer-collab.cjs +420 -64
- package/dist/univer-collab.cjs.map +1 -1
- package/dist/univer-collab.d.cts +7 -1
- package/dist/univer-collab.d.ts +7 -1
- package/dist/univer-collab.js +424 -67
- package/dist/univer-collab.js.map +1 -1
- package/package.json +4 -4
package/dist/univer-collab.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// src/univer/collab/WorkbookCollabSession.ts
|
|
4
4
|
import * as Y from "yjs";
|
|
5
5
|
import { Awareness } from "y-protocols/awareness";
|
|
6
|
-
import { electCollabHost, remoteOriginOf, REMOTE_PARAM_TAG } from "@ai-matrx/data/realtime/collab";
|
|
6
|
+
import { claimCollaboratorColor, electCollabHost, remoteOriginOf, REMOTE_PARAM_TAG } from "@ai-matrx/data/realtime/collab";
|
|
7
7
|
|
|
8
8
|
// src/univer/collab/covered.ts
|
|
9
9
|
var COLLAB_COVERED_KEY = "__matrxCollabCovered";
|
|
@@ -39,6 +39,7 @@ var WorkbookCollabSession = class {
|
|
|
39
39
|
muted = 0;
|
|
40
40
|
started = false;
|
|
41
41
|
disposed = false;
|
|
42
|
+
stopColor = null;
|
|
42
43
|
/** Room entries this seat holds in its content: applied from a peer, or made here. */
|
|
43
44
|
applied = /* @__PURE__ */ new Set();
|
|
44
45
|
/** Entries without an id (a peer on an older build) are applied once, by identity. */
|
|
@@ -60,12 +61,12 @@ var WorkbookCollabSession = class {
|
|
|
60
61
|
uid: this.options.uid,
|
|
61
62
|
clientId: this.options.clientId,
|
|
62
63
|
name: this.options.uid.slice(0, 8),
|
|
63
|
-
color: pickColor(this.options.uid),
|
|
64
64
|
sheetId: null,
|
|
65
65
|
row: null,
|
|
66
66
|
col: null,
|
|
67
67
|
ts: Date.now()
|
|
68
68
|
});
|
|
69
|
+
this.stopColor = claimCollaboratorColor(this.awareness, { uid: this.options.uid, clientId: this.options.clientId });
|
|
69
70
|
this.provider = this.options.makeProvider({
|
|
70
71
|
workbookId: this.options.workbookId,
|
|
71
72
|
clientId: this.options.clientId,
|
|
@@ -126,6 +127,8 @@ var WorkbookCollabSession = class {
|
|
|
126
127
|
this.awareness.off("change", this.awarenessObserver);
|
|
127
128
|
this.awarenessObserver = null;
|
|
128
129
|
}
|
|
130
|
+
this.stopColor?.();
|
|
131
|
+
this.stopColor = null;
|
|
129
132
|
this.provider?.disconnect();
|
|
130
133
|
this.provider = null;
|
|
131
134
|
if (this.awareness) {
|
|
@@ -332,32 +335,6 @@ function stripSenderView(params) {
|
|
|
332
335
|
function isCellEditorScratch(info) {
|
|
333
336
|
return typeof info.id === "string" && info.id.startsWith("doc.mutation.");
|
|
334
337
|
}
|
|
335
|
-
var CURSOR_PALETTE = [
|
|
336
|
-
"#3b82f6",
|
|
337
|
-
// blue
|
|
338
|
-
"#10b981",
|
|
339
|
-
// emerald
|
|
340
|
-
"#f59e0b",
|
|
341
|
-
// amber
|
|
342
|
-
"#ef4444",
|
|
343
|
-
// red
|
|
344
|
-
"#8b5cf6",
|
|
345
|
-
// violet
|
|
346
|
-
"#06b6d4",
|
|
347
|
-
// cyan
|
|
348
|
-
"#ec4899",
|
|
349
|
-
// pink
|
|
350
|
-
"#84cc16"
|
|
351
|
-
// lime
|
|
352
|
-
];
|
|
353
|
-
function pickColor(uid) {
|
|
354
|
-
let h = 2166136261;
|
|
355
|
-
for (let i = 0; i < uid.length; i++) {
|
|
356
|
-
h ^= uid.charCodeAt(i);
|
|
357
|
-
h = Math.imul(h, 16777619);
|
|
358
|
-
}
|
|
359
|
-
return CURSOR_PALETTE[Math.abs(h) % CURSOR_PALETTE.length] ?? "#ec4899";
|
|
360
|
-
}
|
|
361
338
|
|
|
362
339
|
// src/univer/collab/docs-ot/transform.ts
|
|
363
340
|
import { JSONX, TextX, getBodySliceForSplitTextXAction, normalizeTextRuns, merge as univerMerge } from "@univerjs/core";
|
|
@@ -1351,7 +1328,7 @@ import * as Y2 from "yjs";
|
|
|
1351
1328
|
import { Awareness as Awareness2 } from "y-protocols/awareness";
|
|
1352
1329
|
import {
|
|
1353
1330
|
awarenessOpPresence,
|
|
1354
|
-
claimCollaboratorColor,
|
|
1331
|
+
claimCollaboratorColor as claimCollaboratorColor2,
|
|
1355
1332
|
collabReplace,
|
|
1356
1333
|
collabRoomExists,
|
|
1357
1334
|
SupabaseYjsProvider,
|
|
@@ -1530,7 +1507,7 @@ function documentOtFactory(o) {
|
|
|
1530
1507
|
const doc = new Y2.Doc();
|
|
1531
1508
|
const awareness = new Awareness2(doc);
|
|
1532
1509
|
awareness.setLocalState({ uid: o.uid, clientId: o.clientId, name: o.displayName ?? o.uid.slice(0, 8), ts: Date.now() });
|
|
1533
|
-
const stopColor =
|
|
1510
|
+
const stopColor = claimCollaboratorColor2(awareness, { uid: o.uid, clientId: o.clientId });
|
|
1534
1511
|
const carets = new RemoteCaretBook(awareness.clientID);
|
|
1535
1512
|
const emit = () => onAwareness({ states: new Map(awareness.getStates()), selfUid: o.uid, carets: carets.list() });
|
|
1536
1513
|
const publishAwareness = () => {
|
|
@@ -1708,6 +1685,14 @@ var SHEET_MUTATIONS = {
|
|
|
1708
1685
|
"sheet.mutation.set-worksheet-row-auto-height": covered("size", "rowsAutoHeightInfo"),
|
|
1709
1686
|
"sheet.mutation.set-worksheet-col-width": covered("size", "ranges", "colWidth"),
|
|
1710
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"),
|
|
1711
1696
|
// ── never travels ────────────────────────────────────────────────────────────────────────────────
|
|
1712
1697
|
"formula.mutation.set-formula-calculation-start": never(FORMULA_RESULT),
|
|
1713
1698
|
"formula.mutation.set-trigger-formula-calculation-start": never(FORMULA_RESULT),
|
|
@@ -1742,12 +1727,7 @@ var SHEET_MUTATIONS = {
|
|
|
1742
1727
|
"thread-comment.mutation.delete-comment": never(UNIVER_COMMENTS),
|
|
1743
1728
|
// ── barriers: X (no transform yet, design §10) ───────────────────────────────────────────────────
|
|
1744
1729
|
"sheet.mutation.reorder-range": barrier("X", "sort: a permutation, not transformed yet"),
|
|
1745
|
-
"sheet.mutation.set-worksheet-row-count": barrier("X", "absolute row count; needs delta semantics"),
|
|
1746
|
-
"sheet.mutation.set-worksheet-column-count": barrier("X", "absolute column count; needs delta semantics"),
|
|
1747
|
-
"sheet.mutation.set-worksheet-order": barrier("X", "absolute sheet order; needs move semantics"),
|
|
1748
1730
|
"sheet.mutation.move-range": barrier("X", "cut-paste carries the sender's cell matrices"),
|
|
1749
|
-
"sheet.mutation.insert-sheet": barrier("X", "sheet add: not in C5a"),
|
|
1750
|
-
"sheet.mutation.remove-sheet": barrier("X", "sheet remove: not in C5a"),
|
|
1751
1731
|
"sheet.mutation.set-worksheet-hidden": barrier("X", "sheet-level setting: not in C5a"),
|
|
1752
1732
|
"sheet.mutation.set-tab-color": barrier("X", "sheet-level setting: not in C5a"),
|
|
1753
1733
|
"sheet.mutation.set-workbook-name": barrier("X", "workbook-level setting: not in C5a"),
|
|
@@ -1762,8 +1742,6 @@ var SHEET_MUTATIONS = {
|
|
|
1762
1742
|
"sheet.mutation.set-row-visible": barrier("X", "row visibility: not in C5a"),
|
|
1763
1743
|
"sheet.mutation.set-col-hidden": barrier("X", "column visibility: not in C5a"),
|
|
1764
1744
|
"sheet.mutation.set-col-visible": barrier("X", "column visibility: not in C5a"),
|
|
1765
|
-
"sheet.mutation.set.numfmt": barrier("X", "number formats by range: not in C5a"),
|
|
1766
|
-
"sheet.mutation.remove.numfmt": barrier("X", "number formats by range: not in C5a"),
|
|
1767
1745
|
"sheet.mutation.add-range-protection": barrier("X", "permissions: not in C5a"),
|
|
1768
1746
|
"sheet.mutation.set-range-protection": barrier("X", "permissions: not in C5a"),
|
|
1769
1747
|
"sheet.mutation.delete-range-protection": barrier("X", "permissions: not in C5a"),
|
|
@@ -2167,7 +2145,7 @@ function refSheetsFor(texts, sheets) {
|
|
|
2167
2145
|
}
|
|
2168
2146
|
|
|
2169
2147
|
// src/collab/sheets/transform/transform.ts
|
|
2170
|
-
var SHEET_TRANSFORMER_VERSION = "
|
|
2148
|
+
var SHEET_TRANSFORMER_VERSION = "c5c-1";
|
|
2171
2149
|
var ID = {
|
|
2172
2150
|
values: "sheet.mutation.set-range-values",
|
|
2173
2151
|
insertRow: "sheet.mutation.insert-row",
|
|
@@ -2184,7 +2162,14 @@ var ID = {
|
|
|
2184
2162
|
colWidth: "sheet.mutation.set-worksheet-col-width",
|
|
2185
2163
|
name: "sheet.mutation.set-worksheet-name",
|
|
2186
2164
|
setName: "formula.mutation.set-defined-name",
|
|
2187
|
-
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"
|
|
2188
2173
|
};
|
|
2189
2174
|
var PAIR_BARRIERS = {};
|
|
2190
2175
|
var pairKey = (a, b) => a < b ? `${a}|${b}` : `${b}|${a}`;
|
|
@@ -2296,6 +2281,20 @@ function mergeThrough(s, m) {
|
|
|
2296
2281
|
}
|
|
2297
2282
|
return { range: m, fixup: false };
|
|
2298
2283
|
}
|
|
2284
|
+
function mergeFixupsOwed(m, mergesBefore) {
|
|
2285
|
+
const st = structuralOf(m);
|
|
2286
|
+
if (!st) return null;
|
|
2287
|
+
const remove = [];
|
|
2288
|
+
const add = [];
|
|
2289
|
+
for (const q of mergesBefore) {
|
|
2290
|
+
const t = mergeThrough(st, q);
|
|
2291
|
+
if (!t.fixup) continue;
|
|
2292
|
+
remove.push({ startRow: q.startRow, endRow: q.endRow, startColumn: q.startColumn, endColumn: q.endColumn, ...q.rangeType !== void 0 ? { rangeType: q.rangeType } : {} });
|
|
2293
|
+
if (t.range) add.push({ ...t.range });
|
|
2294
|
+
}
|
|
2295
|
+
return remove.length ? { remove, add } : null;
|
|
2296
|
+
}
|
|
2297
|
+
var isStructuralMutation = (m) => structuralOf(m) !== null;
|
|
2299
2298
|
function exactMergeRemovals(group, merges) {
|
|
2300
2299
|
const sim = new Map(Object.entries(merges).map(([k, v]) => [k, v.map((r) => ({ ...r }))]));
|
|
2301
2300
|
const out = [];
|
|
@@ -2342,8 +2341,24 @@ function cellsMutation(template, cells) {
|
|
|
2342
2341
|
function putCell(cells, r, c, v) {
|
|
2343
2342
|
(cells[r] ??= {})[c] = v;
|
|
2344
2343
|
}
|
|
2344
|
+
function cellsOverlap(a, b) {
|
|
2345
|
+
for (const r of Object.keys(a)) {
|
|
2346
|
+
const br = b[r];
|
|
2347
|
+
if (!br) continue;
|
|
2348
|
+
for (const c of Object.keys(a[r] ?? {})) if (c in br) return true;
|
|
2349
|
+
}
|
|
2350
|
+
return false;
|
|
2351
|
+
}
|
|
2345
2352
|
var isEmptyMatrix = (cells) => Object.values(cells).every((row) => Object.keys(row).length === 0);
|
|
2353
|
+
var cellBarrierCache = /* @__PURE__ */ new WeakMap();
|
|
2346
2354
|
function cellBarrier(m) {
|
|
2355
|
+
const hit = cellBarrierCache.get(m);
|
|
2356
|
+
if (hit !== void 0) return hit;
|
|
2357
|
+
const why = cellBarrierOf(m);
|
|
2358
|
+
cellBarrierCache.set(m, why);
|
|
2359
|
+
return why;
|
|
2360
|
+
}
|
|
2361
|
+
function cellBarrierOf(m) {
|
|
2347
2362
|
if (m.params.isOverrideStyle) return "set-range-values with isOverrideStyle (whole-style replace) is not covered";
|
|
2348
2363
|
let why = null;
|
|
2349
2364
|
forEachCell(cellsOf(m), (_r, _c, v) => {
|
|
@@ -2425,6 +2440,7 @@ function transformCell(X, Y4, side) {
|
|
|
2425
2440
|
function transformCellsOverCells(x, y, side) {
|
|
2426
2441
|
if (sheetOf(x) !== sheetOf(y)) return ok([x]);
|
|
2427
2442
|
const ycells = cellsOf(y);
|
|
2443
|
+
if (!cellsOverlap(cellsOf(x), ycells)) return ok([x]);
|
|
2428
2444
|
const xd = isDerived(x);
|
|
2429
2445
|
const yd = isDerived(y);
|
|
2430
2446
|
const eff = derivedSide(x, y, side);
|
|
@@ -2452,7 +2468,7 @@ function transformCellsOverCells(x, y, side) {
|
|
|
2452
2468
|
const op = passes.filter((p) => !isEmptyMatrix(p)).map((p) => cellsMutation(x, p));
|
|
2453
2469
|
return ok(op, lost, dropped);
|
|
2454
2470
|
}
|
|
2455
|
-
var SIDE_CAR_PARAMS = ["refSheets", "previousName", "derived"];
|
|
2471
|
+
var SIDE_CAR_PARAMS = ["refSheets", "previousName", "derived", "sheetIndex", "sheetsLeft"];
|
|
2456
2472
|
var isDerived = (m) => m.params.derived === true;
|
|
2457
2473
|
function derivedSide(x, y, side) {
|
|
2458
2474
|
const xd = isDerived(x);
|
|
@@ -2474,7 +2490,15 @@ function withRefSheets(params, rs) {
|
|
|
2474
2490
|
return out;
|
|
2475
2491
|
}
|
|
2476
2492
|
var hasFormulaText = (v) => !!v && (isFormulaText(v.f) || typeof v.ref === "string");
|
|
2493
|
+
var hasFormulaCache = /* @__PURE__ */ new WeakMap();
|
|
2477
2494
|
function hasFormula(m) {
|
|
2495
|
+
const hit = hasFormulaCache.get(m);
|
|
2496
|
+
if (hit !== void 0) return hit;
|
|
2497
|
+
const any = hasFormulaOf(m);
|
|
2498
|
+
hasFormulaCache.set(m, any);
|
|
2499
|
+
return any;
|
|
2500
|
+
}
|
|
2501
|
+
function hasFormulaOf(m) {
|
|
2478
2502
|
let any = false;
|
|
2479
2503
|
forEachCell(cellsOf(m), (_r, _c, v) => {
|
|
2480
2504
|
any ||= hasFormulaText(v);
|
|
@@ -2513,15 +2537,18 @@ function cellThrough(sheet, change, r, c) {
|
|
|
2513
2537
|
return nr === null || nc === null ? null : [nr, nc];
|
|
2514
2538
|
}
|
|
2515
2539
|
function cellsOverChange(x, change) {
|
|
2540
|
+
if (!hasFormula(x) && (change.kind !== "axis" || change.sheet !== sheetOf(x))) return ok([x]);
|
|
2516
2541
|
const ctx = formulaCtx(x);
|
|
2517
2542
|
const out = {};
|
|
2518
2543
|
const dropped = [];
|
|
2519
2544
|
let why = null;
|
|
2545
|
+
let changed = false;
|
|
2520
2546
|
forEachCell(cellsOf(x), (r, c, v) => {
|
|
2521
2547
|
if (why) return;
|
|
2522
2548
|
const at = cellThrough(sheetOf(x), change, r, c);
|
|
2523
2549
|
if (!at) {
|
|
2524
2550
|
dropped.push(cellRef(sheetOf(x), r, c));
|
|
2551
|
+
changed = true;
|
|
2525
2552
|
return;
|
|
2526
2553
|
}
|
|
2527
2554
|
let e = v;
|
|
@@ -2532,14 +2559,19 @@ function cellsOverChange(x, change) {
|
|
|
2532
2559
|
return;
|
|
2533
2560
|
}
|
|
2534
2561
|
e = res.entry;
|
|
2562
|
+
if (res.changed) changed = true;
|
|
2535
2563
|
}
|
|
2564
|
+
if (at[0] !== r || at[1] !== c) changed = true;
|
|
2536
2565
|
putCell(out, at[0], at[1], e);
|
|
2537
2566
|
});
|
|
2538
2567
|
if (why) return barrier2(why);
|
|
2539
|
-
const
|
|
2568
|
+
const rsAfter = refSheetsAfter(ctx.refSheets, change);
|
|
2569
|
+
if (!changed && JSON.stringify(rsAfter ?? null) === JSON.stringify(ctx.refSheets ?? null)) return ok([x]);
|
|
2570
|
+
const params = { ...withRefSheets(x.params, rsAfter), cellValue: out };
|
|
2540
2571
|
return ok(isEmptyMatrix(out) ? [] : [{ id: x.id, params }], [], dropped);
|
|
2541
2572
|
}
|
|
2542
2573
|
function rewritesOf(y, change) {
|
|
2574
|
+
if (!hasFormula(y)) return null;
|
|
2543
2575
|
const ctx = formulaCtx(y);
|
|
2544
2576
|
const out = {};
|
|
2545
2577
|
let why = null;
|
|
@@ -2685,6 +2717,255 @@ function buildSize(template, values) {
|
|
|
2685
2717
|
const value = uniform !== void 0 && [...values.values()].every((v) => v === uniform) ? uniform : Object.fromEntries(values);
|
|
2686
2718
|
return { id: template.id, params: { ...p, ranges, [field]: value } };
|
|
2687
2719
|
}
|
|
2720
|
+
var isNumfmt = (m) => m.id === ID.setNumfmt || m.id === ID.removeNumfmt;
|
|
2721
|
+
function nfParts(m) {
|
|
2722
|
+
if (m.id === ID.removeNumfmt) return [{ key: null, ranges: (m.params.ranges ?? []).map((r) => ({ ...r })) }];
|
|
2723
|
+
const values = m.params.values ?? {};
|
|
2724
|
+
return Object.keys(values).map((k) => ({ key: k, ranges: (values[k]?.ranges ?? []).map((r) => ({ ...r })) }));
|
|
2725
|
+
}
|
|
2726
|
+
function nfBuild(m, parts) {
|
|
2727
|
+
const keep = parts.filter((p) => p.ranges.length);
|
|
2728
|
+
if (!keep.length) return [];
|
|
2729
|
+
if (m.id === ID.removeNumfmt) return [{ id: m.id, params: { ...m.params, ranges: keep[0].ranges } }];
|
|
2730
|
+
const values = {};
|
|
2731
|
+
const refMap = {};
|
|
2732
|
+
const srcValues = m.params.values ?? {};
|
|
2733
|
+
const srcRef = m.params.refMap ?? {};
|
|
2734
|
+
for (const p of keep) {
|
|
2735
|
+
values[p.key] = { ...srcValues[p.key], ranges: p.ranges };
|
|
2736
|
+
refMap[p.key] = srcRef[p.key];
|
|
2737
|
+
}
|
|
2738
|
+
return [{ id: m.id, params: { ...m.params, values, refMap } }];
|
|
2739
|
+
}
|
|
2740
|
+
function nfValueAt(m, row, col) {
|
|
2741
|
+
for (const p of nfParts(m))
|
|
2742
|
+
if (p.ranges.some((r) => r.startRow <= row && row <= r.endRow && r.startColumn <= col && col <= r.endColumn)) {
|
|
2743
|
+
if (p.key === null) return null;
|
|
2744
|
+
const ref = (m.params.refMap ?? {})[p.key];
|
|
2745
|
+
return { pattern: ref?.pattern };
|
|
2746
|
+
}
|
|
2747
|
+
return void 0;
|
|
2748
|
+
}
|
|
2749
|
+
function spanThrough(op, lo, hi) {
|
|
2750
|
+
const pieces = [];
|
|
2751
|
+
if (op.kind === "insert") pieces.push([0, op.at - 1, 0], [op.at, Infinity, op.count]);
|
|
2752
|
+
else if (op.kind === "remove") pieces.push([0, op.start - 1, 0], [op.start + op.count, Infinity, -op.count]);
|
|
2753
|
+
else if (op.count <= 0 || op.to >= op.from && op.to <= op.from + op.count) pieces.push([0, Infinity, 0]);
|
|
2754
|
+
else if (op.to > op.from) {
|
|
2755
|
+
const n = op.count;
|
|
2756
|
+
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]);
|
|
2757
|
+
} else {
|
|
2758
|
+
const n = op.count;
|
|
2759
|
+
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]);
|
|
2760
|
+
}
|
|
2761
|
+
const out = [];
|
|
2762
|
+
for (const [a, b, d] of pieces) {
|
|
2763
|
+
const x0 = Math.max(a, lo);
|
|
2764
|
+
const x1 = Math.min(b, hi);
|
|
2765
|
+
if (x0 <= x1) out.push([x0 + d, x1 + d]);
|
|
2766
|
+
}
|
|
2767
|
+
out.sort((p, q) => p[0] - q[0]);
|
|
2768
|
+
const merged = [];
|
|
2769
|
+
for (const p of out) {
|
|
2770
|
+
const last = merged[merged.length - 1];
|
|
2771
|
+
if (last && last[1] + 1 >= p[0]) last[1] = Math.max(last[1], p[1]);
|
|
2772
|
+
else merged.push([p[0], p[1]]);
|
|
2773
|
+
}
|
|
2774
|
+
return merged;
|
|
2775
|
+
}
|
|
2776
|
+
function rectsThrough(st, rects) {
|
|
2777
|
+
const [a0, a1] = S(st.axis);
|
|
2778
|
+
const out = [];
|
|
2779
|
+
for (const r of rects) for (const [lo, hi] of spanThrough(st.op, r[a0], r[a1])) out.push({ ...r, [a0]: lo, [a1]: hi });
|
|
2780
|
+
return out;
|
|
2781
|
+
}
|
|
2782
|
+
function rectMinus(a, b) {
|
|
2783
|
+
if (a.startRow > b.endRow || b.startRow > a.endRow || a.startColumn > b.endColumn || b.startColumn > a.endColumn) return [a];
|
|
2784
|
+
const out = [];
|
|
2785
|
+
if (a.startRow < b.startRow) out.push({ ...a, endRow: b.startRow - 1 });
|
|
2786
|
+
if (a.endRow > b.endRow) out.push({ ...a, startRow: b.endRow + 1 });
|
|
2787
|
+
const r0 = Math.max(a.startRow, b.startRow);
|
|
2788
|
+
const r1 = Math.min(a.endRow, b.endRow);
|
|
2789
|
+
if (a.startColumn < b.startColumn) out.push({ ...a, startRow: r0, endRow: r1, endColumn: b.startColumn - 1 });
|
|
2790
|
+
if (a.endColumn > b.endColumn) out.push({ ...a, startRow: r0, endRow: r1, startColumn: b.endColumn + 1 });
|
|
2791
|
+
return out;
|
|
2792
|
+
}
|
|
2793
|
+
function rectsMinus(as, bs) {
|
|
2794
|
+
let cur = as;
|
|
2795
|
+
for (const b of bs) cur = cur.flatMap((a) => rectMinus(a, b));
|
|
2796
|
+
return cur;
|
|
2797
|
+
}
|
|
2798
|
+
function nWrites(m) {
|
|
2799
|
+
const out = [];
|
|
2800
|
+
forEachCell(cellsOf(m), (r, c, v) => {
|
|
2801
|
+
if (v === null || v.s === null || v.s && typeof v.s === "object" && "n" in v.s)
|
|
2802
|
+
out.push({ startRow: r, endRow: r, startColumn: c, endColumn: c });
|
|
2803
|
+
});
|
|
2804
|
+
return out;
|
|
2805
|
+
}
|
|
2806
|
+
function numfmtPair(x, y, side, sx, sy) {
|
|
2807
|
+
const nx = isNumfmt(x);
|
|
2808
|
+
const ny = isNumfmt(y);
|
|
2809
|
+
if (!nx && !ny) return null;
|
|
2810
|
+
if (nx && sy) return ok(nfBuild(x, nfParts(x).map((p) => ({ ...p, ranges: rectsThrough(sy, p.ranges) }))));
|
|
2811
|
+
if (ny && sx) return ok([x]);
|
|
2812
|
+
if (nx && ny) {
|
|
2813
|
+
if (side === "left") return ok([x]);
|
|
2814
|
+
const ys = nfParts(y).flatMap((p) => p.ranges);
|
|
2815
|
+
return ok(nfBuild(x, nfParts(x).map((p) => ({ ...p, ranges: rectsMinus(p.ranges, ys) }))));
|
|
2816
|
+
}
|
|
2817
|
+
if (nx && y.id === ID.values) {
|
|
2818
|
+
if (side === "left") return ok([x]);
|
|
2819
|
+
const ys = nWrites(y);
|
|
2820
|
+
return ys.length ? ok(nfBuild(x, nfParts(x).map((p) => ({ ...p, ranges: rectsMinus(p.ranges, ys) })))) : ok([x]);
|
|
2821
|
+
}
|
|
2822
|
+
if (ny && x.id === ID.values) {
|
|
2823
|
+
if (side === "left") return ok([x]);
|
|
2824
|
+
const out = {};
|
|
2825
|
+
const tail = {};
|
|
2826
|
+
let touched = false;
|
|
2827
|
+
forEachCell(cellsOf(x), (r, c, v) => {
|
|
2828
|
+
const n = nfValueAt(y, r, c);
|
|
2829
|
+
if (n === void 0) return putCell(out, r, c, v);
|
|
2830
|
+
if (v === null || v.s === null) {
|
|
2831
|
+
putCell(out, r, c, v);
|
|
2832
|
+
if (n) {
|
|
2833
|
+
putCell(tail, r, c, { s: { n } });
|
|
2834
|
+
touched = true;
|
|
2835
|
+
}
|
|
2836
|
+
return;
|
|
2837
|
+
}
|
|
2838
|
+
if (v.s && typeof v.s === "object" && "n" in v.s) {
|
|
2839
|
+
const { n: _drop, ...rest } = v.s;
|
|
2840
|
+
const e = { ...v };
|
|
2841
|
+
if (Object.keys(rest).length) e.s = rest;
|
|
2842
|
+
else delete e.s;
|
|
2843
|
+
touched = true;
|
|
2844
|
+
if (Object.keys(e).length) putCell(out, r, c, e);
|
|
2845
|
+
return;
|
|
2846
|
+
}
|
|
2847
|
+
putCell(out, r, c, v);
|
|
2848
|
+
});
|
|
2849
|
+
if (!touched) return ok([x]);
|
|
2850
|
+
const ops = [];
|
|
2851
|
+
if (!isEmptyMatrix(out)) ops.push(cellsMutation(x, out));
|
|
2852
|
+
if (!isEmptyMatrix(tail)) ops.push({ id: ID.values, params: { subUnitId: sheetOf(x), cellValue: tail } });
|
|
2853
|
+
return ok(ops);
|
|
2854
|
+
}
|
|
2855
|
+
return ok([x]);
|
|
2856
|
+
}
|
|
2857
|
+
var isCount = (m) => m.id === ID.rowCount || m.id === ID.colCount;
|
|
2858
|
+
var countAxis = (m) => m.id === ID.rowCount ? "row" : "col";
|
|
2859
|
+
var countKey = (m) => m.id === ID.rowCount ? "rowCount" : "columnCount";
|
|
2860
|
+
function countPair(x, y, sy) {
|
|
2861
|
+
if (!isCount(x)) return isCount(y) ? ok([x]) : null;
|
|
2862
|
+
const k = countKey(x);
|
|
2863
|
+
const v = Number(x.params[k]);
|
|
2864
|
+
if (sy) {
|
|
2865
|
+
if (sy.axis !== countAxis(x) || sy.op.kind === "move") return ok([x]);
|
|
2866
|
+
const d = sy.op.kind === "insert" ? sy.op.count : -sy.op.count;
|
|
2867
|
+
return ok([{ id: x.id, params: { ...x.params, [k]: Math.max(1, v + d) } }]);
|
|
2868
|
+
}
|
|
2869
|
+
if (isCount(y) && y.id === x.id) {
|
|
2870
|
+
const w = Number(y.params[k]);
|
|
2871
|
+
return ok([w > v ? { id: x.id, params: { ...x.params, [k]: w } } : x]);
|
|
2872
|
+
}
|
|
2873
|
+
return ok([x]);
|
|
2874
|
+
}
|
|
2875
|
+
var isSheetOp = (m) => m.id === ID.insertSheet || m.id === ID.removeSheet || m.id === ID.sheetOrder;
|
|
2876
|
+
var sheetIdOf = (m) => m.id === ID.insertSheet ? String(m.params.sheet?.id ?? "") : sheetOf(m);
|
|
2877
|
+
function sheetAxisOf(m) {
|
|
2878
|
+
const p = m.params;
|
|
2879
|
+
if (m.id === ID.insertSheet) return typeof p.index === "number" ? { kind: "insert", at: p.index, count: 1 } : null;
|
|
2880
|
+
if (m.id === ID.removeSheet) return typeof p.sheetIndex === "number" ? { kind: "remove", start: p.sheetIndex, count: 1 } : null;
|
|
2881
|
+
if (m.id === ID.sheetOrder) {
|
|
2882
|
+
const f = Number(p.fromOrder);
|
|
2883
|
+
const t = Number(p.toOrder);
|
|
2884
|
+
return { kind: "move", from: f, count: 1, to: t > f ? t + 1 : t };
|
|
2885
|
+
}
|
|
2886
|
+
return null;
|
|
2887
|
+
}
|
|
2888
|
+
function buildSheetOp(template, op) {
|
|
2889
|
+
if (op.kind === "insert") return { id: template.id, params: { ...template.params, index: op.at } };
|
|
2890
|
+
if (op.kind === "remove") return { id: template.id, params: { ...template.params, sheetIndex: op.start } };
|
|
2891
|
+
return { id: template.id, params: { ...template.params, fromOrder: op.from, toOrder: op.to > op.from ? op.to - 1 : op.to } };
|
|
2892
|
+
}
|
|
2893
|
+
function namesSheet(m, id) {
|
|
2894
|
+
const rs = refSheetsOf(m);
|
|
2895
|
+
return !!rs && Object.values(rs).includes(id) && (m.id === ID.setName || hasFormula(m));
|
|
2896
|
+
}
|
|
2897
|
+
function sheetPair(x, y, side) {
|
|
2898
|
+
const xs = isSheetOp(x);
|
|
2899
|
+
const ys = isSheetOp(y);
|
|
2900
|
+
if (!xs && !ys) return null;
|
|
2901
|
+
if (xs && ys) {
|
|
2902
|
+
const a = sheetAxisOf(x);
|
|
2903
|
+
const b = sheetAxisOf(y);
|
|
2904
|
+
if (!a || !b) return barrier2("a sheet add or remove without its index (capture must call annotateSheetOps)");
|
|
2905
|
+
if (x.id === ID.insertSheet && y.id === ID.insertSheet && sheetIdOf(x) === sheetIdOf(y)) {
|
|
2906
|
+
return JSON.stringify(x.params) === JSON.stringify(y.params) ? ok([]) : barrier2("the same sheet id added twice with different content");
|
|
2907
|
+
}
|
|
2908
|
+
if (x.id === ID.removeSheet && typeof x.params.sheetsLeft === "number" && sheetIdOf(x) !== sheetIdOf(y) && (y.id === ID.removeSheet || y.id === ID.insertSheet)) {
|
|
2909
|
+
const left = x.params.sheetsLeft + (y.id === ID.insertSheet ? 1 : -1);
|
|
2910
|
+
if (left < 1) return barrier2("concurrent sheet removes would leave the workbook without a sheet");
|
|
2911
|
+
const out2 = transformAxis(a, b, side);
|
|
2912
|
+
if (!out2) return barrier2("sheet order: no transform");
|
|
2913
|
+
return ok(out2.map((o) => buildSheetOp({ id: x.id, params: { ...x.params, sheetsLeft: left } }, o)));
|
|
2914
|
+
}
|
|
2915
|
+
const out = transformAxis(a, b, side);
|
|
2916
|
+
if (!out) return barrier2("sheet order: no transform");
|
|
2917
|
+
return ok(out.map((o) => buildSheetOp(x, o)), [], out.length === 0 && x.id === ID.sheetOrder ? [`${sheetIdOf(x)}: sheet order`] : []);
|
|
2918
|
+
}
|
|
2919
|
+
if (ys) {
|
|
2920
|
+
if (y.id !== ID.removeSheet) return ok([x]);
|
|
2921
|
+
const gone2 = sheetOf(y);
|
|
2922
|
+
if (namesSheet(x, gone2)) return barrier2("a formula names a sheet removed at the same time");
|
|
2923
|
+
if (sheetOf(x) === gone2 && x.id !== ID.setName && x.id !== ID.removeName)
|
|
2924
|
+
return ok([], [], isDerived(x) ? [] : [`${gone2}: the sheet was removed`]);
|
|
2925
|
+
return ok([x]);
|
|
2926
|
+
}
|
|
2927
|
+
if (x.id !== ID.removeSheet) return ok([x]);
|
|
2928
|
+
const gone = sheetOf(x);
|
|
2929
|
+
if (namesSheet(y, gone)) return barrier2("a formula names a sheet removed at the same time");
|
|
2930
|
+
return ok([x], sheetOf(y) === gone && !isDerived(y) && y.id !== ID.setName && y.id !== ID.removeName ? [`${gone}: the sheet was removed`] : []);
|
|
2931
|
+
}
|
|
2932
|
+
function annotateSheetOps(group, sheetOrder) {
|
|
2933
|
+
const order = [...sheetOrder];
|
|
2934
|
+
return group.map((m) => {
|
|
2935
|
+
if (m.id === ID.insertSheet) {
|
|
2936
|
+
const index = typeof m.params.index === "number" ? Math.min(m.params.index, order.length) : order.length;
|
|
2937
|
+
order.splice(index, 0, sheetIdOf(m));
|
|
2938
|
+
return index === m.params.index ? m : { id: m.id, params: { ...m.params, index } };
|
|
2939
|
+
}
|
|
2940
|
+
if (m.id === ID.removeSheet) {
|
|
2941
|
+
const i = order.indexOf(sheetOf(m));
|
|
2942
|
+
if (i >= 0) order.splice(i, 1);
|
|
2943
|
+
return i >= 0 ? { id: m.id, params: { ...m.params, sheetIndex: i, sheetsLeft: order.length } } : m;
|
|
2944
|
+
}
|
|
2945
|
+
if (m.id === ID.sheetOrder) {
|
|
2946
|
+
const f = Number(m.params.fromOrder);
|
|
2947
|
+
const [id] = order.splice(f, 1);
|
|
2948
|
+
order.splice(Number(m.params.toOrder), 0, id ?? sheetOf(m));
|
|
2949
|
+
}
|
|
2950
|
+
return m;
|
|
2951
|
+
});
|
|
2952
|
+
}
|
|
2953
|
+
function inlineSheetStyles(sheet, styleOf) {
|
|
2954
|
+
const out = JSON.parse(JSON.stringify(sheet));
|
|
2955
|
+
const fix = (o) => {
|
|
2956
|
+
if (o && typeof o.s === "string") {
|
|
2957
|
+
const st = styleOf(o.s);
|
|
2958
|
+
if (st) o.s = JSON.parse(JSON.stringify(st));
|
|
2959
|
+
}
|
|
2960
|
+
};
|
|
2961
|
+
for (const row of Object.values(out.cellData ?? {})) for (const cell of Object.values(row ?? {})) fix(cell);
|
|
2962
|
+
for (const key of ["rowData", "columnData"]) for (const v of Object.values(out[key] ?? {})) fix(v);
|
|
2963
|
+
if (typeof out.defaultStyle === "string") {
|
|
2964
|
+
const st = styleOf(out.defaultStyle);
|
|
2965
|
+
if (st) out.defaultStyle = JSON.parse(JSON.stringify(st));
|
|
2966
|
+
}
|
|
2967
|
+
return out;
|
|
2968
|
+
}
|
|
2688
2969
|
function familyOf(id) {
|
|
2689
2970
|
const e = SHEET_MUTATIONS[id];
|
|
2690
2971
|
return e && e.kind === "covered" ? e.family : "";
|
|
@@ -2701,6 +2982,8 @@ function transformMutation(x, y, side) {
|
|
|
2701
2982
|
}
|
|
2702
2983
|
const pb = PAIR_BARRIERS[pairKey(x.id, y.id)];
|
|
2703
2984
|
if (pb) return barrier2(`${x.id} \xD7 ${y.id}: ${pb.reason}${pb.seed === null ? "" : ` (fuzz seed ${pb.seed})`}`);
|
|
2985
|
+
const sp = sheetPair(x, y, side);
|
|
2986
|
+
if (sp) return sp;
|
|
2704
2987
|
const fp = formulaPair(x, y, side);
|
|
2705
2988
|
if (fp) return fp;
|
|
2706
2989
|
if (sheetOf(x) !== sheetOf(y)) return ok([x]);
|
|
@@ -2708,6 +2991,10 @@ function transformMutation(x, y, side) {
|
|
|
2708
2991
|
const fy = familyOf(y.id);
|
|
2709
2992
|
const sy = structuralOf(y);
|
|
2710
2993
|
const sx = structuralOf(x);
|
|
2994
|
+
const cp = countPair(x, y, sy);
|
|
2995
|
+
if (cp) return cp;
|
|
2996
|
+
const np = numfmtPair(x, y, side, sx, sy);
|
|
2997
|
+
if (np) return np;
|
|
2711
2998
|
if (sx && sy) {
|
|
2712
2999
|
if (sx.axis !== sy.axis) return ok([x]);
|
|
2713
3000
|
const out = transformAxis(sx.op, sy.op, side);
|
|
@@ -2815,22 +3102,45 @@ function tSeq(xs, ys, side, acc) {
|
|
|
2815
3102
|
acc.dropped.push(...a.dropped);
|
|
2816
3103
|
return [a.op, b.op];
|
|
2817
3104
|
}
|
|
3105
|
+
const outX = [];
|
|
3106
|
+
let curY = ys;
|
|
3107
|
+
for (const x of xs) {
|
|
3108
|
+
let curX = [x];
|
|
3109
|
+
const nextY = [];
|
|
3110
|
+
for (const y of curY) {
|
|
3111
|
+
if (curX.length === 0) {
|
|
3112
|
+
nextY.push(y);
|
|
3113
|
+
continue;
|
|
3114
|
+
}
|
|
3115
|
+
const r = tSeq(curX, [y], side, acc);
|
|
3116
|
+
if (blocked(r)) return r;
|
|
3117
|
+
curX = r[0];
|
|
3118
|
+
for (const m of r[1]) nextY.push(m);
|
|
3119
|
+
}
|
|
3120
|
+
for (const m of curX) outX.push(m);
|
|
3121
|
+
curY = nextY;
|
|
3122
|
+
}
|
|
3123
|
+
return [outX, curY];
|
|
3124
|
+
}
|
|
3125
|
+
function tSeqOld(xs, ys, side, acc) {
|
|
3126
|
+
if (xs.length === 0 || ys.length === 0) return [xs, ys];
|
|
3127
|
+
if (xs.length === 1 && ys.length === 1) return tSeq(xs, ys, side, acc);
|
|
2818
3128
|
if (xs.length > 1) {
|
|
2819
|
-
const first2 =
|
|
3129
|
+
const first2 = tSeqOld([xs[0]], ys, side, acc);
|
|
2820
3130
|
if (blocked(first2)) return first2;
|
|
2821
|
-
const rest2 =
|
|
3131
|
+
const rest2 = tSeqOld(xs.slice(1), first2[1], side, acc);
|
|
2822
3132
|
if (blocked(rest2)) return rest2;
|
|
2823
3133
|
return [[...first2[0], ...rest2[0]], rest2[1]];
|
|
2824
3134
|
}
|
|
2825
|
-
const first =
|
|
3135
|
+
const first = tSeqOld(xs, [ys[0]], side, acc);
|
|
2826
3136
|
if (blocked(first)) return first;
|
|
2827
|
-
const rest =
|
|
3137
|
+
const rest = tSeqOld(first[0], ys.slice(1), side, acc);
|
|
2828
3138
|
if (blocked(rest)) return rest;
|
|
2829
3139
|
return [rest[0], [...first[1], ...rest[1]]];
|
|
2830
3140
|
}
|
|
2831
3141
|
function transformGroup(x, y, side) {
|
|
2832
3142
|
const acc = { lost: [], dropped: [] };
|
|
2833
|
-
const r = tSeq([...x], [...y], side, acc);
|
|
3143
|
+
const r = (process.env.OLD_TSEQ ? tSeqOld : tSeq)([...x], [...y], side, acc);
|
|
2834
3144
|
if (blocked(r)) return r;
|
|
2835
3145
|
return { op: r[0], lost: [...new Set(acc.lost)], dropped: [...new Set(acc.dropped)] };
|
|
2836
3146
|
}
|
|
@@ -2900,7 +3210,7 @@ async function sheetsStateHash(snapshot) {
|
|
|
2900
3210
|
}
|
|
2901
3211
|
|
|
2902
3212
|
// src/univer/collab/sheets-ot/room.ts
|
|
2903
|
-
var SHEETS_COLLAB_PROTO =
|
|
3213
|
+
var SHEETS_COLLAB_PROTO = 2;
|
|
2904
3214
|
var SHEETS_EDIT_GROUP = "sheets.edit";
|
|
2905
3215
|
var flip2 = (side) => side === "left" ? "right" : "left";
|
|
2906
3216
|
var isNoopSheetOp = (op) => op == null || op.length === 0;
|
|
@@ -2947,6 +3257,11 @@ function travelingShape(m) {
|
|
|
2947
3257
|
}
|
|
2948
3258
|
return { id: m.id, params };
|
|
2949
3259
|
}
|
|
3260
|
+
var shapedLists = /* @__PURE__ */ new WeakMap();
|
|
3261
|
+
function cachedShape(list) {
|
|
3262
|
+
const hit = shapedLists.get(list);
|
|
3263
|
+
return hit && hit.src.length === list.length && hit.src.every((m, i) => m === list[i]) ? hit.shaped : null;
|
|
3264
|
+
}
|
|
2950
3265
|
function rebaseSheetUndoStack(items, remote, unitId) {
|
|
2951
3266
|
if (isNoopSheetOp(remote)) return 0;
|
|
2952
3267
|
let dropped = 0;
|
|
@@ -2958,7 +3273,11 @@ function rebaseSheetUndoStack(items, remote, unitId) {
|
|
|
2958
3273
|
if (!ok2 || !list?.length) continue;
|
|
2959
3274
|
const isOperation = (id) => !SHEET_MUTATIONS[id] && id.includes(".operation.");
|
|
2960
3275
|
const operations = list.filter((m) => isOperation(m.id));
|
|
2961
|
-
|
|
3276
|
+
let shaped = cachedShape(list);
|
|
3277
|
+
if (!shaped) {
|
|
3278
|
+
shaped = list.filter((m) => !isOperation(m.id)).map(travelingShape);
|
|
3279
|
+
shapedLists.set(list, { src: list.slice(), shaped });
|
|
3280
|
+
}
|
|
2962
3281
|
if (shaped.some((m) => m === null)) {
|
|
2963
3282
|
ok2 = false;
|
|
2964
3283
|
continue;
|
|
@@ -2970,8 +3289,10 @@ function rebaseSheetUndoStack(items, remote, unitId) {
|
|
|
2970
3289
|
ok2 = false;
|
|
2971
3290
|
continue;
|
|
2972
3291
|
}
|
|
2973
|
-
if (
|
|
2974
|
-
|
|
3292
|
+
if (r.op.length === shaped.length && r.op.every((m, i2) => m === shaped[i2])) continue;
|
|
3293
|
+
const next = [...r.op.map((m) => ({ id: m.id, params: { ...forApply(m).params, unitId } })), ...operations];
|
|
3294
|
+
shapedLists.set(next, { src: next.slice(), shaped: r.op });
|
|
3295
|
+
item[key] = next;
|
|
2975
3296
|
} catch {
|
|
2976
3297
|
ok2 = false;
|
|
2977
3298
|
}
|
|
@@ -3046,7 +3367,7 @@ function createSheetsOtAdapter(port, hooks = {}) {
|
|
|
3046
3367
|
});
|
|
3047
3368
|
});
|
|
3048
3369
|
}
|
|
3049
|
-
return sheetsStateHash(port.snapshot());
|
|
3370
|
+
return (hooks.stateHash ?? sheetsStateHash)(port.snapshot());
|
|
3050
3371
|
},
|
|
3051
3372
|
held: () => queue.length,
|
|
3052
3373
|
rebaseLocalOverHeld(local) {
|
|
@@ -3158,6 +3479,8 @@ var VALUES = "sheet.mutation.set-range-values";
|
|
|
3158
3479
|
var ADD_MERGE = "sheet.mutation.add-worksheet-merge";
|
|
3159
3480
|
var REMOVE_MERGE = "sheet.mutation.remove-worksheet-merge";
|
|
3160
3481
|
var SHEET_NAME = "sheet.mutation.set-worksheet-name";
|
|
3482
|
+
var INSERT_SHEET = "sheet.mutation.insert-sheet";
|
|
3483
|
+
var RESHAPE = /* @__PURE__ */ new Set(["sheet.mutation.set-worksheet-row-count", "sheet.mutation.set-worksheet-column-count", "sheet.mutation.remove-sheet", INSERT_SHEET]);
|
|
3161
3484
|
var DEPTH_GUARD = /* @__PURE__ */ Symbol.for("ai-matrx.office.sheets.command-depth-guard");
|
|
3162
3485
|
var json = (v) => v === void 0 ? v : JSON.parse(JSON.stringify(v));
|
|
3163
3486
|
var flagged = (options) => {
|
|
@@ -3194,7 +3517,8 @@ function univerSheetsOtPort(o) {
|
|
|
3194
3517
|
for (const [id, d] of Object.entries(map)) out[id] = String(d?.name ?? "");
|
|
3195
3518
|
return out;
|
|
3196
3519
|
};
|
|
3197
|
-
const
|
|
3520
|
+
const sheetOrder = () => (o.workbook()?.getSheets() ?? []).map((ws) => ws.getSheetId());
|
|
3521
|
+
const openGroup = (label) => ({ label, order: sheetOrder(), sheets: sheetNames(), names: definedNames(), mutations: [], inverses: [], notShared: null });
|
|
3198
3522
|
const emit = (e) => {
|
|
3199
3523
|
for (const l of [...listeners]) {
|
|
3200
3524
|
try {
|
|
@@ -3210,7 +3534,8 @@ function univerSheetsOtPort(o) {
|
|
|
3210
3534
|
if (!g) return;
|
|
3211
3535
|
if (g.notShared) emit({ kind: "not_shared", mutationId: g.notShared, label: g.label });
|
|
3212
3536
|
else if (g.mutations.length) {
|
|
3213
|
-
const mutations = annotateFormulas(g.mutations, g.sheets, g.names);
|
|
3537
|
+
const mutations = annotateSheetOps(annotateFormulas(g.mutations, g.sheets, g.names), g.order);
|
|
3538
|
+
if (mutations.some((m) => isStructuralMutation(m) || RESHAPE.has(m.id))) clampSelection();
|
|
3214
3539
|
const known = g.inverses.every((i) => i !== void 0);
|
|
3215
3540
|
const inverse = known ? annotateFormulas(g.inverses.slice().reverse().flat(), g.sheets, g.names) : void 0;
|
|
3216
3541
|
emit({ kind: "group", mutations, ...inverse !== void 0 ? { inverse } : {}, label: g.label });
|
|
@@ -3244,7 +3569,27 @@ function univerSheetsOtPort(o) {
|
|
|
3244
3569
|
}
|
|
3245
3570
|
if (info.id === SHEET_NAME) record.name = ws.getName();
|
|
3246
3571
|
pre.set(p, record);
|
|
3572
|
+
const owed = isStructuralMutation({ id: info.id, params: p }) ? mergeFixupsOwed({ id: info.id, params: p }, record.merges ?? []) : null;
|
|
3573
|
+
if (owed) {
|
|
3574
|
+
runOwn(REMOVE_MERGE, String(p.subUnitId), owed.remove, ADD_MERGE);
|
|
3575
|
+
if (owed.add.length) record.addAfter = owed.add;
|
|
3576
|
+
}
|
|
3247
3577
|
});
|
|
3578
|
+
const runOwn = (id, sheet, ranges, inverseId) => {
|
|
3579
|
+
const u = unitId();
|
|
3580
|
+
if (!u) return;
|
|
3581
|
+
applying = true;
|
|
3582
|
+
try {
|
|
3583
|
+
cs.syncExecuteCommand(id, { unitId: u, subUnitId: sheet, ranges: json(ranges) }, { onlyLocal: true });
|
|
3584
|
+
} finally {
|
|
3585
|
+
applying = false;
|
|
3586
|
+
}
|
|
3587
|
+
if (!group) group = openGroup(null);
|
|
3588
|
+
if (!group.notShared) {
|
|
3589
|
+
group.mutations.push({ id, params: { subUnitId: sheet, ranges: json(ranges) } });
|
|
3590
|
+
group.inverses.push([{ id: inverseId, params: { subUnitId: sheet, ranges: json(ranges) } }]);
|
|
3591
|
+
}
|
|
3592
|
+
};
|
|
3248
3593
|
const after = cs.onCommandExecuted((info) => {
|
|
3249
3594
|
if (info.type !== COMMAND) return;
|
|
3250
3595
|
const at = tracker.stack.lastIndexOf(info.id);
|
|
@@ -3342,6 +3687,8 @@ function univerSheetsOtPort(o) {
|
|
|
3342
3687
|
if (!m2) return { m: null, inverse: void 0 };
|
|
3343
3688
|
return { m: m2, inverse: [{ id: ADD_MERGE, params: { subUnitId: sheet, ranges: json(m2.params.ranges) } }] };
|
|
3344
3689
|
}
|
|
3690
|
+
if (info.id === INSERT_SHEET && params.sheet && typeof params.sheet === "object")
|
|
3691
|
+
params.sheet = inlineSheetStyles(params.sheet, (id) => o.workbook()?.getStyles().get(id));
|
|
3345
3692
|
const m = { id: info.id, params };
|
|
3346
3693
|
switch (info.id) {
|
|
3347
3694
|
case "sheet.mutation.insert-row":
|
|
@@ -3358,8 +3705,7 @@ function univerSheetsOtPort(o) {
|
|
|
3358
3705
|
};
|
|
3359
3706
|
const collab = cs.onMutationExecutedForCollab((info, options) => {
|
|
3360
3707
|
if (applying || flagged(options) || !mine(info.params)) return;
|
|
3361
|
-
|
|
3362
|
-
if (lone) group = openGroup(null);
|
|
3708
|
+
if (!group) group = openGroup(null);
|
|
3363
3709
|
const g = group;
|
|
3364
3710
|
if (!g.notShared) {
|
|
3365
3711
|
const r = capture(info);
|
|
@@ -3369,11 +3715,29 @@ function univerSheetsOtPort(o) {
|
|
|
3369
3715
|
g.inverses.push(r.inverse);
|
|
3370
3716
|
}
|
|
3371
3717
|
}
|
|
3372
|
-
|
|
3718
|
+
const owedAdd = pre.get(info.params)?.addAfter;
|
|
3719
|
+
if (owedAdd?.length) runOwn(ADD_MERGE, String(info.params.subUnitId ?? ""), owedAdd, REMOVE_MERGE);
|
|
3720
|
+
if (tracker.stack.length === 0) settle();
|
|
3373
3721
|
});
|
|
3722
|
+
const clampSelection = () => {
|
|
3723
|
+
const sel = o.selections;
|
|
3724
|
+
if (!sel) return;
|
|
3725
|
+
try {
|
|
3726
|
+
const sheet = sel.sheetId();
|
|
3727
|
+
const ws = sheet ? o.workbook()?.getSheetBySheetId(sheet) : null;
|
|
3728
|
+
const current = sel.get();
|
|
3729
|
+
if (!ws || !current?.length) return;
|
|
3730
|
+
const rows = ws.getMaxRows?.() ?? Number.MAX_SAFE_INTEGER;
|
|
3731
|
+
const cols = ws.getMaxColumns?.() ?? Number.MAX_SAFE_INTEGER;
|
|
3732
|
+
const next = moveSelectionsThrough(json(current), { id: "", params: {} }, rows, cols);
|
|
3733
|
+
if (JSON.stringify(next) !== JSON.stringify(current)) sel.set(next);
|
|
3734
|
+
} catch (err) {
|
|
3735
|
+
console.warn("[sheets-ot] could not keep this seat's selection inside the sheet after its own row or column change", err);
|
|
3736
|
+
}
|
|
3737
|
+
};
|
|
3374
3738
|
const followSelection = (m) => {
|
|
3375
3739
|
const sel = o.selections;
|
|
3376
|
-
if (!sel || !axisOpOf(m)) return;
|
|
3740
|
+
if (!sel || !axisOpOf(m) && !RESHAPE.has(m.id)) return;
|
|
3377
3741
|
try {
|
|
3378
3742
|
const sheet = String(m.params.subUnitId ?? "");
|
|
3379
3743
|
if (sel.sheetId() !== sheet) return;
|
|
@@ -3516,6 +3880,7 @@ import * as Y3 from "yjs";
|
|
|
3516
3880
|
import { Awareness as Awareness3 } from "y-protocols/awareness";
|
|
3517
3881
|
import {
|
|
3518
3882
|
awarenessOpPresence as awarenessOpPresence2,
|
|
3883
|
+
claimCollaboratorColor as claimCollaboratorColor3,
|
|
3519
3884
|
collabReplace as collabReplace3,
|
|
3520
3885
|
collabRoomExists as collabRoomExists3,
|
|
3521
3886
|
SupabaseYjsProvider as SupabaseYjsProvider2,
|
|
@@ -3585,15 +3950,6 @@ async function workbookUsesOrderedRoom(workbookId, knob, isNewWorkbook) {
|
|
|
3585
3950
|
if (knob === "new") return isNewWorkbook();
|
|
3586
3951
|
return false;
|
|
3587
3952
|
}
|
|
3588
|
-
function pickColor2(uid) {
|
|
3589
|
-
const palette = ["#ef4444", "#f59e0b", "#10b981", "#3b82f6", "#8b5cf6", "#ec4899", "#14b8a6", "#f97316"];
|
|
3590
|
-
let h = 2166136261;
|
|
3591
|
-
for (let i = 0; i < uid.length; i++) {
|
|
3592
|
-
h ^= uid.charCodeAt(i);
|
|
3593
|
-
h = Math.imul(h, 16777619);
|
|
3594
|
-
}
|
|
3595
|
-
return palette[Math.abs(h) % palette.length] ?? "#ec4899";
|
|
3596
|
-
}
|
|
3597
3953
|
async function startWorkbookOtRoom(port, o) {
|
|
3598
3954
|
const latest = await getLatestSnapshot(o.workbookId);
|
|
3599
3955
|
if (!latest.success) throw new Error(latest.error);
|
|
@@ -3610,12 +3966,12 @@ async function startWorkbookOtRoom(port, o) {
|
|
|
3610
3966
|
uid: o.uid,
|
|
3611
3967
|
clientId: o.clientId,
|
|
3612
3968
|
name: o.displayName ?? o.uid.slice(0, 8),
|
|
3613
|
-
color: pickColor2(o.uid),
|
|
3614
3969
|
sheetId: null,
|
|
3615
3970
|
row: null,
|
|
3616
3971
|
col: null,
|
|
3617
3972
|
ts: Date.now()
|
|
3618
3973
|
});
|
|
3974
|
+
const stopColor = claimCollaboratorColor3(awareness, { uid: o.uid, clientId: o.clientId });
|
|
3619
3975
|
const publishAwareness = () => o.onAwareness?.(new Map(awareness.getStates()));
|
|
3620
3976
|
awareness.on("change", publishAwareness);
|
|
3621
3977
|
const provider = new SupabaseYjsProvider2({
|
|
@@ -3661,6 +4017,7 @@ async function startWorkbookOtRoom(port, o) {
|
|
|
3661
4017
|
awareness.setLocalState({ ...current, sheetId: c.sheetId, row: c.row, col: c.col, ts: Date.now() });
|
|
3662
4018
|
},
|
|
3663
4019
|
stop() {
|
|
4020
|
+
stopColor();
|
|
3664
4021
|
room.stop();
|
|
3665
4022
|
port.dispose?.();
|
|
3666
4023
|
awareness.off("change", publishAwareness);
|