@ai-matrx/office 0.8.15 → 0.8.17

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.
@@ -57,6 +57,7 @@ __export(collab_exports, {
57
57
  invertDocsOp: () => invertDocsOp,
58
58
  isCellEditorScratch: () => isCellEditorScratch,
59
59
  isNoopDocsOp: () => isNoopDocsOp,
60
+ moveSelectionsThrough: () => moveSelectionsThrough,
60
61
  normalizeDocsOp: () => normalizeDocsOp,
61
62
  openDocsOtRoom: () => openDocsOtRoom,
62
63
  openSheetsOtRoom: () => openSheetsOtRoom,
@@ -1292,37 +1293,8 @@ var Y2 = __toESM(require("yjs"), 1);
1292
1293
  var import_awareness2 = require("y-protocols/awareness");
1293
1294
  var import_collab3 = require("@ai-matrx/data/realtime/collab");
1294
1295
 
1295
- // src/docs/document-model.ts
1296
- var import_core2 = require("@univerjs/core");
1297
-
1298
- // src/univer/openEditorContent.ts
1299
- var replacers = /* @__PURE__ */ new Map();
1300
- var keyOf = (kind, recordId) => `${kind}:${recordId}`;
1301
- function hasOpenEditorContent(kind, recordId) {
1302
- return replacers.has(keyOf(kind, recordId));
1303
- }
1304
- async function showSavedSnapshot(kind, recordId, row) {
1305
- const replace = replacers.get(keyOf(kind, recordId));
1306
- if (!replace) return false;
1307
- await replace(row);
1308
- return true;
1309
- }
1310
-
1311
- // src/docs/document-model.ts
1312
- function moveRangesThroughBodyEdit(ranges, actions) {
1313
- const a = actions;
1314
- if (!Array.isArray(a) || a[0] !== "body") return null;
1315
- const sub = a[1];
1316
- if (!sub || sub.et !== "text-x" || !Array.isArray(sub.e)) return null;
1317
- const e = sub.e;
1318
- return ranges.map((r) => {
1319
- const collapsed = r.startOffset === r.endOffset;
1320
- const startOffset = import_core2.TextX.transformPosition(e, r.startOffset, collapsed);
1321
- return { startOffset, endOffset: collapsed ? startOffset : import_core2.TextX.transformPosition(e, r.endOffset, true) };
1322
- });
1323
- }
1324
-
1325
1296
  // src/docs/remote-carets.ts
1297
+ var import_core2 = require("@univerjs/core");
1326
1298
  var CARET_HEARTBEAT_MS = 2e3;
1327
1299
  var CARET_STALE_MS = 12e3;
1328
1300
  var CARET_MAX_RANGES = 4;
@@ -1332,6 +1304,18 @@ function publishedCaretFromSelection(sel, now) {
1332
1304
  const ranges = sel.slice(0, CARET_MAX_RANGES).map((r) => ({ start: Math.min(r.startOffset, r.endOffset), end: Math.max(r.startOffset, r.endOffset) }));
1333
1305
  return { ranges, at: now };
1334
1306
  }
1307
+ function movePeerRangesThroughBodyEdit(ranges, actions) {
1308
+ const a = actions;
1309
+ if (!Array.isArray(a) || a[0] !== "body") return null;
1310
+ const sub = a[1];
1311
+ if (!sub || sub.et !== "text-x" || !Array.isArray(sub.e)) return null;
1312
+ const e = sub.e;
1313
+ return ranges.map((r) => {
1314
+ const collapsed = r.start === r.end;
1315
+ const start = import_core2.TextX.transformPosition(e, r.start, false);
1316
+ return { start, end: collapsed ? start : import_core2.TextX.transformPosition(e, r.end, true) };
1317
+ });
1318
+ }
1335
1319
  var sameRanges = (a, b) => a.length === b.length && a.every((r, i) => r.start === b[i].start && r.end === b[i].end);
1336
1320
  function readCaret(raw) {
1337
1321
  const c = raw?.caret;
@@ -1383,9 +1367,8 @@ var RemoteCaretBook = class {
1383
1367
  shiftThrough(actions) {
1384
1368
  let moved = false;
1385
1369
  for (const c of this.carets.values()) {
1386
- const next = moveRangesThroughBodyEdit(c.ranges.map((r) => ({ startOffset: r.start, endOffset: r.end })), actions);
1387
- if (!next) return false;
1388
- const ranges = next.map((r) => ({ start: r.startOffset, end: r.endOffset }));
1370
+ const ranges = movePeerRangesThroughBodyEdit(c.ranges, actions);
1371
+ if (!ranges) return false;
1389
1372
  if (!sameRanges(ranges, c.ranges)) {
1390
1373
  c.ranges = ranges;
1391
1374
  moved = true;
@@ -1588,6 +1571,21 @@ function documentOtFactory(o) {
1588
1571
 
1589
1572
  // src/docs/document-restore.ts
1590
1573
  var import_collab4 = require("@ai-matrx/data/realtime/collab");
1574
+
1575
+ // src/univer/openEditorContent.ts
1576
+ var replacers = /* @__PURE__ */ new Map();
1577
+ var keyOf = (kind, recordId) => `${kind}:${recordId}`;
1578
+ function hasOpenEditorContent(kind, recordId) {
1579
+ return replacers.has(keyOf(kind, recordId));
1580
+ }
1581
+ async function showSavedSnapshot(kind, recordId, row) {
1582
+ const replace = replacers.get(keyOf(kind, recordId));
1583
+ if (!replace) return false;
1584
+ await replace(row);
1585
+ return true;
1586
+ }
1587
+
1588
+ // src/docs/document-restore.ts
1591
1589
  var defaultDeps = {
1592
1590
  client: () => getDocsHost().getSupabase(),
1593
1591
  roomExists: import_collab4.collabRoomExists,
@@ -3187,21 +3185,36 @@ function univerSheetsOtPort(o) {
3187
3185
  settle();
3188
3186
  });
3189
3187
  const guarded = cs;
3190
- if (!guarded[DEPTH_GUARD] && typeof cs.executeCommand === "function") {
3188
+ if (!guarded[DEPTH_GUARD]) {
3191
3189
  const trackers = /* @__PURE__ */ new Set();
3192
3190
  guarded[DEPTH_GUARD] = trackers;
3193
- const original = cs.executeCommand.bind(cs);
3194
- cs.executeCommand = async (id, params, options) => {
3195
- const depths = new Map([...trackers].map((t) => [t, t.stack.length]));
3191
+ const restore = (depths) => {
3192
+ for (const [t, d] of depths) {
3193
+ if (t.stack.length > d) {
3194
+ t.stack.length = d;
3195
+ t.settle();
3196
+ }
3197
+ }
3198
+ };
3199
+ const depthsNow = () => new Map([...trackers].map((t) => [t, t.stack.length]));
3200
+ if (typeof cs.executeCommand === "function") {
3201
+ const original = cs.executeCommand.bind(cs);
3202
+ cs.executeCommand = async (id, params, options) => {
3203
+ const depths = depthsNow();
3204
+ try {
3205
+ return await original(id, params, options);
3206
+ } finally {
3207
+ restore(depths);
3208
+ }
3209
+ };
3210
+ }
3211
+ const originalSync = cs.syncExecuteCommand.bind(cs);
3212
+ cs.syncExecuteCommand = (id, params, options) => {
3213
+ const depths = depthsNow();
3196
3214
  try {
3197
- return await original(id, params, options);
3215
+ return originalSync(id, params, options);
3198
3216
  } finally {
3199
- for (const [t, d] of depths) {
3200
- if (t.stack.length > d) {
3201
- t.stack.length = d;
3202
- t.settle();
3203
- }
3204
- }
3217
+ restore(depths);
3205
3218
  }
3206
3219
  };
3207
3220
  }
@@ -3291,12 +3304,30 @@ function univerSheetsOtPort(o) {
3291
3304
  }
3292
3305
  if (lone && tracker.stack.length === 0) settle();
3293
3306
  });
3307
+ const followSelection = (m) => {
3308
+ const sel = o.selections;
3309
+ if (!sel || !axisOpOf(m)) return;
3310
+ try {
3311
+ const sheet = String(m.params.subUnitId ?? "");
3312
+ if (sel.sheetId() !== sheet) return;
3313
+ const ws = o.workbook()?.getSheetBySheetId(sheet);
3314
+ const current = sel.get();
3315
+ if (!ws || !current?.length) return;
3316
+ const rows = ws.getMaxRows?.() ?? Number.MAX_SAFE_INTEGER;
3317
+ const cols = ws.getMaxColumns?.() ?? Number.MAX_SAFE_INTEGER;
3318
+ sel.set(moveSelectionsThrough(json(current), m, rows, cols));
3319
+ } catch (err) {
3320
+ console.warn("[sheets-ot] could not move this seat's selection past a collaborator's row or column change", err);
3321
+ }
3322
+ };
3294
3323
  return {
3295
3324
  onLocal(listener) {
3296
3325
  listeners.add(listener);
3297
3326
  return () => void listeners.delete(listener);
3298
3327
  },
3299
3328
  busy: () => tracker.stack.length > 0 || group !== null,
3329
+ /** The outermost commands still running here (why the port is busy), for logs. */
3330
+ running: () => [...tracker.stack, ...group && tracker.stack.length === 0 ? ["(group)"] : []],
3300
3331
  whenIdle(fn) {
3301
3332
  if (tracker.stack.length === 0 && !group) fn();
3302
3333
  else idle.push(fn);
@@ -3312,6 +3343,7 @@ function univerSheetsOtPort(o) {
3312
3343
  } finally {
3313
3344
  applying = false;
3314
3345
  }
3346
+ followSelection(m);
3315
3347
  },
3316
3348
  snapshot() {
3317
3349
  const wb = o.workbook();
@@ -3349,6 +3381,68 @@ function fullContent(cell) {
3349
3381
  if (out.v === null) delete out.t;
3350
3382
  return out;
3351
3383
  }
3384
+ function axisOpOf(m) {
3385
+ const p = m.params;
3386
+ const span = (r, axis) => axis === "row" ? [r.startRow, r.endRow - r.startRow + 1] : [r.startColumn, r.endColumn - r.startColumn + 1];
3387
+ switch (m.id) {
3388
+ case "sheet.mutation.insert-row": {
3389
+ const [at, count] = span(p.range, "row");
3390
+ return { axis: "row", op: { kind: "insert", at, count } };
3391
+ }
3392
+ case "sheet.mutation.insert-col": {
3393
+ const [at, count] = span(p.range, "col");
3394
+ return { axis: "col", op: { kind: "insert", at, count } };
3395
+ }
3396
+ case "sheet.mutation.remove-rows": {
3397
+ const [start, count] = span(p.range, "row");
3398
+ return { axis: "row", op: { kind: "remove", start, count } };
3399
+ }
3400
+ case "sheet.mutation.remove-col": {
3401
+ const [start, count] = span(p.range, "col");
3402
+ return { axis: "col", op: { kind: "remove", start, count } };
3403
+ }
3404
+ case "sheet.mutation.move-rows": {
3405
+ const [from, count] = span(p.sourceRange, "row");
3406
+ return { axis: "row", op: { kind: "move", from, count, to: p.targetRange.startRow } };
3407
+ }
3408
+ case "sheet.mutation.move-columns": {
3409
+ const [from, count] = span(p.sourceRange, "col");
3410
+ return { axis: "col", op: { kind: "move", from, count, to: p.targetRange.startColumn } };
3411
+ }
3412
+ default:
3413
+ return null;
3414
+ }
3415
+ }
3416
+ function moveSelectionsThrough(selections, m, maxRows, maxCols) {
3417
+ const a = axisOpOf(m);
3418
+ const clamp = (v, max) => Math.max(0, Math.min(v, Math.max(0, max - 1)));
3419
+ const through = (i, axis) => {
3420
+ if (typeof i !== "number") return i;
3421
+ let next = i;
3422
+ if (a && a.axis === axis) {
3423
+ const mapped = mapIndex(a.op, i);
3424
+ next = mapped ?? (a.op.kind === "remove" ? a.op.start : i);
3425
+ }
3426
+ return clamp(next, axis === "row" ? maxRows : maxCols);
3427
+ };
3428
+ const box = (r, rangeType) => {
3429
+ const out = { ...r };
3430
+ for (const k of ["startRow", "endRow", "actualRow"]) if (k in out) out[k] = through(out[k], "row");
3431
+ for (const k of ["startColumn", "endColumn", "actualColumn"]) if (k in out) out[k] = through(out[k], "col");
3432
+ if (typeof out.startRow === "number" && typeof out.endRow === "number" && out.endRow < out.startRow) out.endRow = out.startRow;
3433
+ if (typeof out.startColumn === "number" && typeof out.endColumn === "number" && out.endColumn < out.startColumn) out.endColumn = out.startColumn;
3434
+ if (rangeType === 1 || rangeType === 3) {
3435
+ out.startColumn = 0;
3436
+ out.endColumn = Math.max(0, maxCols - 1);
3437
+ }
3438
+ if (rangeType === 2 || rangeType === 3) {
3439
+ out.startRow = 0;
3440
+ out.endRow = Math.max(0, maxRows - 1);
3441
+ }
3442
+ return out;
3443
+ };
3444
+ return selections.map((s) => ({ ...s, range: box(s.range, s.range.rangeType), ...s.primary ? { primary: box(s.primary) } : {} }));
3445
+ }
3352
3446
 
3353
3447
  // src/sheets/workbook-ot-room.ts
3354
3448
  var Y3 = __toESM(require("yjs"), 1);