@ai-matrx/office 0.8.16 → 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.
@@ -736,6 +736,8 @@ interface SheetsCommandService {
736
736
  interface SheetsWorksheetLike {
737
737
  getSheetId(): string;
738
738
  getName(): string;
739
+ getMaxRows?(): number;
740
+ getMaxColumns?(): number;
739
741
  getCellRaw(row: number, col: number): Obj | null | undefined;
740
742
  getMergeData(): SheetRange[];
741
743
  }
@@ -760,13 +762,44 @@ interface UniverSheetsOtPortOptions {
760
762
  saveUnit?(unitId: string): unknown | null;
761
763
  /** Univer's undo/redo service. */
762
764
  undoRedo?(): unknown | null;
765
+ /**
766
+ * This seat's selections on the active sheet (`SheetsSelectionsService`). A remote row/column insert, remove or
767
+ * move carries this seat's selection with it, and a selection a remote remove took away is clamped to the
768
+ * sheet: a selection left past the sheet's edge breaks every reader of the active range.
769
+ */
770
+ selections?: {
771
+ sheetId(): string | null;
772
+ get(): SheetSelection[] | null | undefined;
773
+ set(selections: SheetSelection[]): void;
774
+ };
763
775
  /** Replace the workbook's whole content, keeping its unit id. */
764
776
  load(snapshot: unknown): void;
765
777
  markDirty(): void;
766
778
  }
779
+ /** One selection as `SheetsSelectionsService` holds it (range, primary cell, style). */
780
+ interface SheetSelection {
781
+ range: SheetRange & {
782
+ rangeType?: number;
783
+ };
784
+ primary?: (Record<string, unknown> & {
785
+ startRow?: number;
786
+ endRow?: number;
787
+ startColumn?: number;
788
+ endColumn?: number;
789
+ actualRow?: number;
790
+ actualColumn?: number;
791
+ }) | null;
792
+ style?: unknown;
793
+ }
767
794
  declare function univerSheetsOtPort(o: UniverSheetsOtPortOptions): SheetsOtPort & {
768
795
  dispose(): void;
796
+ running(): string[];
769
797
  };
798
+ /**
799
+ * This seat's selections after a remote structural op: indices move with their rows/columns; one the op removed
800
+ * lands on the first surviving index; everything is clamped to the sheet; whole-row/column ranges span the sheet.
801
+ */
802
+ declare function moveSelectionsThrough(selections: SheetSelection[], m: SheetMutation, maxRows: number, maxCols: number): SheetSelection[];
770
803
 
771
804
  /**
772
805
  * The canonical Sheets state hash (COLLAB-DESIGN §7.2, C0 item 6, §21.3): two seats holding the same workbook
@@ -823,4 +856,4 @@ declare function startWorkbookOtRoom(port: SheetsOtPort & {
823
856
  dispose?: () => void;
824
857
  }, o: WorkbookOtRoomOptions): Promise<WorkbookOtRoomHandle>;
825
858
 
826
- export { COLLAB_COVERED_KEY, type CollabBase, type CollabMutationInfo, type CollabProviderLike, type CommandServiceLike, DOCS_COLLAB_PROTO, DOCS_TRANSFORM_VERSION, DOC_LOCAL_KEYS, type DocsLocalMutation, type DocsLost, type DocsOp, type DocsOtNotice, type DocsOtPort, type DocsOtRoom, type DocsTransformResult, type DocumentOtFactoryOptions, type DocumentRestoreDeps, type DocumentRestoreResult, type OpenDocsOtRoomOptions, type OpenSheetsOtRoomOptions, type OtRoomsKnob, RICH_TEXT_EDITING, SENDER_VIEW_PARAMS, SHEETS_COLLAB_PROTO, SHEETS_EDIT_GROUP, type SheetOp, type SheetsCommandService, type SheetsLocalEvent, type SheetsLocalGroup, type SheetsNotShared, type SheetsOtAdapter, type SheetsOtAdapterHooks, type SheetsOtNotice, type SheetsOtPort, type SheetsOtRoom, type SheetsWorkbookLike, type SheetsWorksheetLike, type UniverSheetsOtPortOptions, WorkbookCollabSession, type WorkbookCollabSessionOptions, type WorkbookOtRoomHandle, type WorkbookOtRoomOptions, type WorkbookOtRoomsKnob, applyDocsOp, canonicalDocsSnapshot, canonicalDocsString, canonicalKeys, canonicalSheet, canonicalSheetString, composeDocsOps, createSheetsOtAdapter, decodeSheetOp, docsStateHash, documentOtFactory, documentUsesOrderedRoom, dropEmptyStyleRetains, encodeSheetOp, invertDocsOp, isCellEditorScratch, isNoopDocsOp, normalizeDocsOp, openDocsOtRoom, openSheetsOtRoom, rebaseSheetUndoStack, rebaseUndoStack, restoreDocumentSnapshot, sheetsStateHash, stampCovered, stampDeterministicIds, startWorkbookOtRoom, stripSenderView, takeCovered, transformDocsOp, transformSheetOp, transformTextX, undoStacksOf, univerSheetsOtPort, workbookUsesOrderedRoom };
859
+ export { COLLAB_COVERED_KEY, type CollabBase, type CollabMutationInfo, type CollabProviderLike, type CommandServiceLike, DOCS_COLLAB_PROTO, DOCS_TRANSFORM_VERSION, DOC_LOCAL_KEYS, type DocsLocalMutation, type DocsLost, type DocsOp, type DocsOtNotice, type DocsOtPort, type DocsOtRoom, type DocsTransformResult, type DocumentOtFactoryOptions, type DocumentRestoreDeps, type DocumentRestoreResult, type OpenDocsOtRoomOptions, type OpenSheetsOtRoomOptions, type OtRoomsKnob, RICH_TEXT_EDITING, SENDER_VIEW_PARAMS, SHEETS_COLLAB_PROTO, SHEETS_EDIT_GROUP, type SheetOp, type SheetSelection, type SheetsCommandService, type SheetsLocalEvent, type SheetsLocalGroup, type SheetsNotShared, type SheetsOtAdapter, type SheetsOtAdapterHooks, type SheetsOtNotice, type SheetsOtPort, type SheetsOtRoom, type SheetsWorkbookLike, type SheetsWorksheetLike, type UniverSheetsOtPortOptions, WorkbookCollabSession, type WorkbookCollabSessionOptions, type WorkbookOtRoomHandle, type WorkbookOtRoomOptions, type WorkbookOtRoomsKnob, applyDocsOp, canonicalDocsSnapshot, canonicalDocsString, canonicalKeys, canonicalSheet, canonicalSheetString, composeDocsOps, createSheetsOtAdapter, decodeSheetOp, docsStateHash, documentOtFactory, documentUsesOrderedRoom, dropEmptyStyleRetains, encodeSheetOp, invertDocsOp, isCellEditorScratch, isNoopDocsOp, moveSelectionsThrough, normalizeDocsOp, openDocsOtRoom, openSheetsOtRoom, rebaseSheetUndoStack, rebaseUndoStack, restoreDocumentSnapshot, sheetsStateHash, stampCovered, stampDeterministicIds, startWorkbookOtRoom, stripSenderView, takeCovered, transformDocsOp, transformSheetOp, transformTextX, undoStacksOf, univerSheetsOtPort, workbookUsesOrderedRoom };
@@ -736,6 +736,8 @@ interface SheetsCommandService {
736
736
  interface SheetsWorksheetLike {
737
737
  getSheetId(): string;
738
738
  getName(): string;
739
+ getMaxRows?(): number;
740
+ getMaxColumns?(): number;
739
741
  getCellRaw(row: number, col: number): Obj | null | undefined;
740
742
  getMergeData(): SheetRange[];
741
743
  }
@@ -760,13 +762,44 @@ interface UniverSheetsOtPortOptions {
760
762
  saveUnit?(unitId: string): unknown | null;
761
763
  /** Univer's undo/redo service. */
762
764
  undoRedo?(): unknown | null;
765
+ /**
766
+ * This seat's selections on the active sheet (`SheetsSelectionsService`). A remote row/column insert, remove or
767
+ * move carries this seat's selection with it, and a selection a remote remove took away is clamped to the
768
+ * sheet: a selection left past the sheet's edge breaks every reader of the active range.
769
+ */
770
+ selections?: {
771
+ sheetId(): string | null;
772
+ get(): SheetSelection[] | null | undefined;
773
+ set(selections: SheetSelection[]): void;
774
+ };
763
775
  /** Replace the workbook's whole content, keeping its unit id. */
764
776
  load(snapshot: unknown): void;
765
777
  markDirty(): void;
766
778
  }
779
+ /** One selection as `SheetsSelectionsService` holds it (range, primary cell, style). */
780
+ interface SheetSelection {
781
+ range: SheetRange & {
782
+ rangeType?: number;
783
+ };
784
+ primary?: (Record<string, unknown> & {
785
+ startRow?: number;
786
+ endRow?: number;
787
+ startColumn?: number;
788
+ endColumn?: number;
789
+ actualRow?: number;
790
+ actualColumn?: number;
791
+ }) | null;
792
+ style?: unknown;
793
+ }
767
794
  declare function univerSheetsOtPort(o: UniverSheetsOtPortOptions): SheetsOtPort & {
768
795
  dispose(): void;
796
+ running(): string[];
769
797
  };
798
+ /**
799
+ * This seat's selections after a remote structural op: indices move with their rows/columns; one the op removed
800
+ * lands on the first surviving index; everything is clamped to the sheet; whole-row/column ranges span the sheet.
801
+ */
802
+ declare function moveSelectionsThrough(selections: SheetSelection[], m: SheetMutation, maxRows: number, maxCols: number): SheetSelection[];
770
803
 
771
804
  /**
772
805
  * The canonical Sheets state hash (COLLAB-DESIGN §7.2, C0 item 6, §21.3): two seats holding the same workbook
@@ -823,4 +856,4 @@ declare function startWorkbookOtRoom(port: SheetsOtPort & {
823
856
  dispose?: () => void;
824
857
  }, o: WorkbookOtRoomOptions): Promise<WorkbookOtRoomHandle>;
825
858
 
826
- export { COLLAB_COVERED_KEY, type CollabBase, type CollabMutationInfo, type CollabProviderLike, type CommandServiceLike, DOCS_COLLAB_PROTO, DOCS_TRANSFORM_VERSION, DOC_LOCAL_KEYS, type DocsLocalMutation, type DocsLost, type DocsOp, type DocsOtNotice, type DocsOtPort, type DocsOtRoom, type DocsTransformResult, type DocumentOtFactoryOptions, type DocumentRestoreDeps, type DocumentRestoreResult, type OpenDocsOtRoomOptions, type OpenSheetsOtRoomOptions, type OtRoomsKnob, RICH_TEXT_EDITING, SENDER_VIEW_PARAMS, SHEETS_COLLAB_PROTO, SHEETS_EDIT_GROUP, type SheetOp, type SheetsCommandService, type SheetsLocalEvent, type SheetsLocalGroup, type SheetsNotShared, type SheetsOtAdapter, type SheetsOtAdapterHooks, type SheetsOtNotice, type SheetsOtPort, type SheetsOtRoom, type SheetsWorkbookLike, type SheetsWorksheetLike, type UniverSheetsOtPortOptions, WorkbookCollabSession, type WorkbookCollabSessionOptions, type WorkbookOtRoomHandle, type WorkbookOtRoomOptions, type WorkbookOtRoomsKnob, applyDocsOp, canonicalDocsSnapshot, canonicalDocsString, canonicalKeys, canonicalSheet, canonicalSheetString, composeDocsOps, createSheetsOtAdapter, decodeSheetOp, docsStateHash, documentOtFactory, documentUsesOrderedRoom, dropEmptyStyleRetains, encodeSheetOp, invertDocsOp, isCellEditorScratch, isNoopDocsOp, normalizeDocsOp, openDocsOtRoom, openSheetsOtRoom, rebaseSheetUndoStack, rebaseUndoStack, restoreDocumentSnapshot, sheetsStateHash, stampCovered, stampDeterministicIds, startWorkbookOtRoom, stripSenderView, takeCovered, transformDocsOp, transformSheetOp, transformTextX, undoStacksOf, univerSheetsOtPort, workbookUsesOrderedRoom };
859
+ export { COLLAB_COVERED_KEY, type CollabBase, type CollabMutationInfo, type CollabProviderLike, type CommandServiceLike, DOCS_COLLAB_PROTO, DOCS_TRANSFORM_VERSION, DOC_LOCAL_KEYS, type DocsLocalMutation, type DocsLost, type DocsOp, type DocsOtNotice, type DocsOtPort, type DocsOtRoom, type DocsTransformResult, type DocumentOtFactoryOptions, type DocumentRestoreDeps, type DocumentRestoreResult, type OpenDocsOtRoomOptions, type OpenSheetsOtRoomOptions, type OtRoomsKnob, RICH_TEXT_EDITING, SENDER_VIEW_PARAMS, SHEETS_COLLAB_PROTO, SHEETS_EDIT_GROUP, type SheetOp, type SheetSelection, type SheetsCommandService, type SheetsLocalEvent, type SheetsLocalGroup, type SheetsNotShared, type SheetsOtAdapter, type SheetsOtAdapterHooks, type SheetsOtNotice, type SheetsOtPort, type SheetsOtRoom, type SheetsWorkbookLike, type SheetsWorksheetLike, type UniverSheetsOtPortOptions, WorkbookCollabSession, type WorkbookCollabSessionOptions, type WorkbookOtRoomHandle, type WorkbookOtRoomOptions, type WorkbookOtRoomsKnob, applyDocsOp, canonicalDocsSnapshot, canonicalDocsString, canonicalKeys, canonicalSheet, canonicalSheetString, composeDocsOps, createSheetsOtAdapter, decodeSheetOp, docsStateHash, documentOtFactory, documentUsesOrderedRoom, dropEmptyStyleRetains, encodeSheetOp, invertDocsOp, isCellEditorScratch, isNoopDocsOp, moveSelectionsThrough, normalizeDocsOp, openDocsOtRoom, openSheetsOtRoom, rebaseSheetUndoStack, rebaseUndoStack, restoreDocumentSnapshot, sheetsStateHash, stampCovered, stampDeterministicIds, startWorkbookOtRoom, stripSenderView, takeCovered, transformDocsOp, transformSheetOp, transformTextX, undoStacksOf, univerSheetsOtPort, workbookUsesOrderedRoom };
@@ -3240,12 +3240,30 @@ function univerSheetsOtPort(o) {
3240
3240
  }
3241
3241
  if (lone && tracker.stack.length === 0) settle();
3242
3242
  });
3243
+ const followSelection = (m) => {
3244
+ const sel = o.selections;
3245
+ if (!sel || !axisOpOf(m)) return;
3246
+ try {
3247
+ const sheet = String(m.params.subUnitId ?? "");
3248
+ if (sel.sheetId() !== sheet) return;
3249
+ const ws = o.workbook()?.getSheetBySheetId(sheet);
3250
+ const current = sel.get();
3251
+ if (!ws || !current?.length) return;
3252
+ const rows = ws.getMaxRows?.() ?? Number.MAX_SAFE_INTEGER;
3253
+ const cols = ws.getMaxColumns?.() ?? Number.MAX_SAFE_INTEGER;
3254
+ sel.set(moveSelectionsThrough(json(current), m, rows, cols));
3255
+ } catch (err) {
3256
+ console.warn("[sheets-ot] could not move this seat's selection past a collaborator's row or column change", err);
3257
+ }
3258
+ };
3243
3259
  return {
3244
3260
  onLocal(listener) {
3245
3261
  listeners.add(listener);
3246
3262
  return () => void listeners.delete(listener);
3247
3263
  },
3248
3264
  busy: () => tracker.stack.length > 0 || group !== null,
3265
+ /** The outermost commands still running here (why the port is busy), for logs. */
3266
+ running: () => [...tracker.stack, ...group && tracker.stack.length === 0 ? ["(group)"] : []],
3249
3267
  whenIdle(fn) {
3250
3268
  if (tracker.stack.length === 0 && !group) fn();
3251
3269
  else idle.push(fn);
@@ -3261,6 +3279,7 @@ function univerSheetsOtPort(o) {
3261
3279
  } finally {
3262
3280
  applying = false;
3263
3281
  }
3282
+ followSelection(m);
3264
3283
  },
3265
3284
  snapshot() {
3266
3285
  const wb = o.workbook();
@@ -3298,6 +3317,68 @@ function fullContent(cell) {
3298
3317
  if (out.v === null) delete out.t;
3299
3318
  return out;
3300
3319
  }
3320
+ function axisOpOf(m) {
3321
+ const p = m.params;
3322
+ const span = (r, axis) => axis === "row" ? [r.startRow, r.endRow - r.startRow + 1] : [r.startColumn, r.endColumn - r.startColumn + 1];
3323
+ switch (m.id) {
3324
+ case "sheet.mutation.insert-row": {
3325
+ const [at, count] = span(p.range, "row");
3326
+ return { axis: "row", op: { kind: "insert", at, count } };
3327
+ }
3328
+ case "sheet.mutation.insert-col": {
3329
+ const [at, count] = span(p.range, "col");
3330
+ return { axis: "col", op: { kind: "insert", at, count } };
3331
+ }
3332
+ case "sheet.mutation.remove-rows": {
3333
+ const [start, count] = span(p.range, "row");
3334
+ return { axis: "row", op: { kind: "remove", start, count } };
3335
+ }
3336
+ case "sheet.mutation.remove-col": {
3337
+ const [start, count] = span(p.range, "col");
3338
+ return { axis: "col", op: { kind: "remove", start, count } };
3339
+ }
3340
+ case "sheet.mutation.move-rows": {
3341
+ const [from, count] = span(p.sourceRange, "row");
3342
+ return { axis: "row", op: { kind: "move", from, count, to: p.targetRange.startRow } };
3343
+ }
3344
+ case "sheet.mutation.move-columns": {
3345
+ const [from, count] = span(p.sourceRange, "col");
3346
+ return { axis: "col", op: { kind: "move", from, count, to: p.targetRange.startColumn } };
3347
+ }
3348
+ default:
3349
+ return null;
3350
+ }
3351
+ }
3352
+ function moveSelectionsThrough(selections, m, maxRows, maxCols) {
3353
+ const a = axisOpOf(m);
3354
+ const clamp = (v, max) => Math.max(0, Math.min(v, Math.max(0, max - 1)));
3355
+ const through = (i, axis) => {
3356
+ if (typeof i !== "number") return i;
3357
+ let next = i;
3358
+ if (a && a.axis === axis) {
3359
+ const mapped = mapIndex(a.op, i);
3360
+ next = mapped ?? (a.op.kind === "remove" ? a.op.start : i);
3361
+ }
3362
+ return clamp(next, axis === "row" ? maxRows : maxCols);
3363
+ };
3364
+ const box = (r, rangeType) => {
3365
+ const out = { ...r };
3366
+ for (const k of ["startRow", "endRow", "actualRow"]) if (k in out) out[k] = through(out[k], "row");
3367
+ for (const k of ["startColumn", "endColumn", "actualColumn"]) if (k in out) out[k] = through(out[k], "col");
3368
+ if (typeof out.startRow === "number" && typeof out.endRow === "number" && out.endRow < out.startRow) out.endRow = out.startRow;
3369
+ if (typeof out.startColumn === "number" && typeof out.endColumn === "number" && out.endColumn < out.startColumn) out.endColumn = out.startColumn;
3370
+ if (rangeType === 1 || rangeType === 3) {
3371
+ out.startColumn = 0;
3372
+ out.endColumn = Math.max(0, maxCols - 1);
3373
+ }
3374
+ if (rangeType === 2 || rangeType === 3) {
3375
+ out.startRow = 0;
3376
+ out.endRow = Math.max(0, maxRows - 1);
3377
+ }
3378
+ return out;
3379
+ };
3380
+ return selections.map((s) => ({ ...s, range: box(s.range, s.range.rangeType), ...s.primary ? { primary: box(s.primary) } : {} }));
3381
+ }
3301
3382
 
3302
3383
  // src/sheets/workbook-ot-room.ts
3303
3384
  import * as Y3 from "yjs";
@@ -3485,6 +3566,7 @@ export {
3485
3566
  invertDocsOp,
3486
3567
  isCellEditorScratch,
3487
3568
  isNoopDocsOp,
3569
+ moveSelectionsThrough,
3488
3570
  normalizeDocsOp,
3489
3571
  openDocsOtRoom,
3490
3572
  openSheetsOtRoom,