@ai-matrx/office 0.8.13 → 0.8.15

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.
@@ -1,6 +1,6 @@
1
1
  import * as Y from 'yjs';
2
2
  import { Awareness } from 'y-protocols/awareness';
3
- import { OpSessionNotice, OpSession, OpTransport, OpPresence, OpSessionIncident, OpSessionStatus, AwarenessState, CollabRpcClient, collabReplace } from '@ai-matrx/data/realtime/collab';
3
+ import { OpSessionNotice, OpSession, OpTransport, OpPresence, OpSessionIncident, OpSessionStatus, AwarenessState, CollabRpcClient, collabReplace, OpDocumentAdapter } from '@ai-matrx/data/realtime/collab';
4
4
  import { IDocumentData } from '@univerjs/core';
5
5
  import { CommitReason } from '@ai-matrx/kit/working-copy';
6
6
 
@@ -385,7 +385,7 @@ interface DocsOtRoom {
385
385
  * through `encode`, so `encode` must not depend on key order or every acknowledgement looks like a mismatch.
386
386
  */
387
387
  declare function canonicalKeys<T>(v: T): T;
388
- interface UndoItem {
388
+ interface UndoItem$1 {
389
389
  unitID?: string;
390
390
  undoMutations?: Array<{
391
391
  id: string;
@@ -398,11 +398,11 @@ interface UndoItem {
398
398
  }
399
399
  /** The Univer 1.0.4 fields the undo rebase reads; a forcing test fails if they move (Univer is pinned). */
400
400
  declare function undoStacksOf(service: unknown): {
401
- undo: Map<string, UndoItem[]>;
402
- redo: Map<string, UndoItem[]>;
401
+ undo: Map<string, UndoItem$1[]>;
402
+ redo: Map<string, UndoItem$1[]>;
403
403
  } | null;
404
404
  /** §6.9: rebase one stack over a remote op; items that cannot follow are dropped. Returns how many were dropped. */
405
- declare function rebaseUndoStack(items: UndoItem[], remote: DocsOp): number;
405
+ declare function rebaseUndoStack(items: UndoItem$1[], remote: DocsOp): number;
406
406
  declare function openDocsOtRoom(o: OpenDocsOtRoomOptions): DocsOtRoom;
407
407
 
408
408
  interface CaretRange {
@@ -536,4 +536,291 @@ declare function restoreDocumentSnapshot(args: {
536
536
  label: string | null;
537
537
  }, deps?: Partial<DocumentRestoreDeps>): Promise<DocumentRestoreResult>;
538
538
 
539
- 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 OtRoomsKnob, RICH_TEXT_EDITING, SENDER_VIEW_PARAMS, WorkbookCollabSession, type WorkbookCollabSessionOptions, applyDocsOp, canonicalDocsSnapshot, canonicalDocsString, canonicalKeys, composeDocsOps, docsStateHash, documentOtFactory, documentUsesOrderedRoom, dropEmptyStyleRetains, invertDocsOp, isCellEditorScratch, isNoopDocsOp, normalizeDocsOp, openDocsOtRoom, rebaseUndoStack, restoreDocumentSnapshot, stampCovered, stampDeterministicIds, stripSenderView, takeCovered, transformDocsOp, transformTextX, undoStacksOf };
539
+ /**
540
+ * Sheet co-editing transforms (C5a): the shapes. Pure data; no Univer import.
541
+ *
542
+ * Convention (COLLAB-DESIGN §6.4): `transform(x, y, side)` returns `x` rewritten to apply AFTER `y`, where
543
+ * `side` is x's side. The later-committed op always takes "left": it wins overwrites and sits first on
544
+ * position ties.
545
+ */
546
+ /** One allowlisted Univer mutation as it travels: no `unitId` (the receiver re-addresses to its own unit). */
547
+ interface SheetMutation {
548
+ readonly id: string;
549
+ readonly params: Readonly<Record<string, unknown>>;
550
+ }
551
+ interface Barrier {
552
+ readonly barrier: true;
553
+ readonly reason: string;
554
+ }
555
+ interface SheetRange {
556
+ startRow: number;
557
+ endRow: number;
558
+ startColumn: number;
559
+ endColumn: number;
560
+ rangeType?: number;
561
+ [k: string]: unknown;
562
+ }
563
+
564
+ /** A changeset: allowlisted sheet mutations in order. `null` / `[]` is the no-op. */
565
+ type SheetOp = SheetMutation[] | null;
566
+ /**
567
+ * The room's protocol (§6.4): Univer 1.0.4 + transformer `SHEET_TRANSFORMER_VERSION`. Any Univer or transformer
568
+ * change raises it; a room at another proto opens read-only for this build.
569
+ */
570
+ declare const SHEETS_COLLAB_PROTO = 1;
571
+ declare const SHEETS_EDIT_GROUP = "sheets.edit";
572
+ /** One outermost command's traveling mutations, as the port hands them over. */
573
+ interface SheetsLocalGroup {
574
+ kind: "group";
575
+ mutations: SheetMutation[];
576
+ /** The group's inverse against the pre-state (§6.3), or undefined when one of its mutations has none. */
577
+ inverse?: SheetMutation[];
578
+ /** The outermost command id (the change's label in a rollback notice). */
579
+ label: string | null;
580
+ }
581
+ /** A local change that cannot travel (no allowlist: a barrier id, an unknown id, a whole-style override …). */
582
+ interface SheetsNotShared {
583
+ kind: "not_shared";
584
+ mutationId: string;
585
+ label: string | null;
586
+ }
587
+ type SheetsLocalEvent = SheetsLocalGroup | SheetsNotShared;
588
+ /** What the workbook editor lends the room (implemented by `univerSheetsOtPort`). */
589
+ interface SheetsOtPort {
590
+ onLocal(listener: (e: SheetsLocalEvent) => void): () => void;
591
+ /** True while a local command is still running (its group is not handed over yet). */
592
+ busy(): boolean;
593
+ /** Run `fn` once no local command is running (immediately when none is). */
594
+ whenIdle(fn: () => void): void;
595
+ /** Apply one committed mutation to this seat's workbook; throws when the editor refused it. */
596
+ applyRemote(m: SheetMutation): void;
597
+ /** The workbook as the editor holds it now (with resources), or null when none is mounted. */
598
+ snapshot(): unknown | null;
599
+ /** Replace the workbook's whole content (same unit id). */
600
+ load(snapshot: unknown): void;
601
+ /** Univer's undo/redo service and this seat's unit. */
602
+ undoTargets(): Array<{
603
+ service: unknown;
604
+ unitId: string;
605
+ }>;
606
+ /** Ask for a save (the record's one coalesced save). */
607
+ markDirty(): void;
608
+ }
609
+ type SheetsOtNotice = OpSessionNotice<SheetOp> | {
610
+ kind: "not_shared";
611
+ mutationId: string;
612
+ } | {
613
+ kind: "not_live";
614
+ };
615
+ /**
616
+ * The adapter's transform: the C5a/C5b group transform, with `lost` widened by what y can no longer apply
617
+ * after x (y's `dropped` over x). The session tells an earlier author through `lost`; without this, an edit
618
+ * in a column a later op removed would vanish without a word.
619
+ */
620
+ declare function transformSheetOp(x: SheetOp, y: SheetOp, side: "left" | "right"): Barrier | {
621
+ op: SheetOp;
622
+ lost: string[];
623
+ dropped: string[];
624
+ };
625
+ /**
626
+ * The wire form. Keys in one canonical order: the log stores groups as jsonb, which hands object keys back in
627
+ * its own order, and the session compares wire forms (its ack check) through `encode` (C3's rule).
628
+ */
629
+ declare function encodeSheetOp(op: SheetOp): {
630
+ cmd: string;
631
+ mutations: {
632
+ id: string;
633
+ params: Readonly<Record<string, unknown>>;
634
+ }[];
635
+ }[];
636
+ declare function decodeSheetOp(groups: Array<{
637
+ mutations: Array<{
638
+ id: string;
639
+ params: unknown;
640
+ }>;
641
+ }>): SheetOp;
642
+ interface UndoItem {
643
+ unitID?: string;
644
+ undoMutations?: Array<{
645
+ id: string;
646
+ params: Record<string, unknown>;
647
+ }>;
648
+ redoMutations?: Array<{
649
+ id: string;
650
+ params: Record<string, unknown>;
651
+ }>;
652
+ }
653
+ /** §6.9: rebase one stack over a remote op; items that cannot follow are dropped. Returns how many were dropped. */
654
+ declare function rebaseSheetUndoStack(items: UndoItem[], remote: SheetOp, unitId: string): number;
655
+ interface SheetsOtAdapterHooks {
656
+ /** Called once per applied remote op that rebased this seat's undo stacks (for tests and logs). */
657
+ onUndoRebased?: (dropped: number) => void;
658
+ }
659
+ /** The `OpDocumentAdapter` over a sheets port, plus the held-remote queue the room drives. */
660
+ interface SheetsOtAdapter extends OpDocumentAdapter<SheetOp> {
661
+ /** Remote ops held while a local command runs. */
662
+ held(): number;
663
+ /** A local group finished while remote ops were held: rebase it over them and them over it (Docs IME rule). */
664
+ rebaseLocalOverHeld(local: SheetMutation[]): SheetMutation[] | "barrier";
665
+ clearHeld(): void;
666
+ }
667
+ declare function createSheetsOtAdapter(port: SheetsOtPort, hooks?: SheetsOtAdapterHooks): SheetsOtAdapter;
668
+ interface OpenSheetsOtRoomOptions {
669
+ port: SheetsOtPort;
670
+ transport: OpTransport;
671
+ clientId: string;
672
+ presence?: OpPresence;
673
+ /** `collab_replace` for this room (restore, whole import). */
674
+ replace: (req: {
675
+ snapshot: unknown;
676
+ stateHash: string;
677
+ clientId: string;
678
+ }) => Promise<{
679
+ rev: number;
680
+ ref: string;
681
+ }>;
682
+ onNotice?: (n: SheetsOtNotice) => void;
683
+ onIncident?: (i: OpSessionIncident) => void;
684
+ onStatus?: (s: OpSessionStatus) => void;
685
+ }
686
+ interface SheetsOtRoom {
687
+ session: OpSession<SheetOp>;
688
+ /** The record's save: a checkpoint at a quiet point (§7.3). False when this seat does not write now. */
689
+ write(reason: "manual" | string): Promise<boolean>;
690
+ /** Restore / whole import through `collab_replace`. */
691
+ replace(snapshot: unknown): Promise<void>;
692
+ /** This seat is the one that saves on its own. */
693
+ isSaver(): boolean;
694
+ stop(): void;
695
+ }
696
+ declare function openSheetsOtRoom(o: OpenSheetsOtRoomOptions): SheetsOtRoom;
697
+
698
+ /**
699
+ * The `SheetsOtPort` over a live Univer workbook (COLLAB-DESIGN §6.3, §6.7, C0 items 4, 6, 7, C5a/C5b capture
700
+ * rules). The host lends Univer's services (it resolves them with its own tokens, so this module never pulls a
701
+ * second copy of Univer's DI into the app); this module does every capture rule:
702
+ *
703
+ * - FILTER. Only mutations of THIS seat's unit, never `onlyLocal` or `fromCollab` ones (formula results, our own
704
+ * remote applies), never the never-travels class.
705
+ * - GROUP. By the outermost COMMAND (`beforeCommandExecuted` / `onCommandExecuted` depth), with a try/finally
706
+ * around `executeCommand` so a command that mutates and then throws still closes its group (C0 surprise 7).
707
+ * One hand-over per group: the formula annotation needs the whole group (a rewrite after a structural op is
708
+ * `derived`, §21.2).
709
+ * - ALLOWLIST. `allowParams`; an id without one (a barrier id, an unknown id) makes the group `not_shared`.
710
+ * - THE THREE C5a RULES. Cell content is completed from the cell right after the mutation
711
+ * (`completeCellContent`); a remove-merge names the exact merges it removed (`exactMergeRemovals`, merges read
712
+ * right before the mutation); a style travels as its object, never a seat-local id. A whole-style override
713
+ * (paste) is restated as a merge with explicit nulls, which every seat applies identically.
714
+ * - FORMULAS. `annotateFormulas` with the sheet names and defined names as they were before the command.
715
+ * - INVERSE from the APPLIED params against a COPY of the pre-state taken in `beforeCommandExecuted`
716
+ * (C0 surprise 6). Families without a safe inverse leave it unknown.
717
+ */
718
+
719
+ type Obj = Record<string, unknown>;
720
+ type CommandInfo = {
721
+ id: string;
722
+ type?: number;
723
+ params?: unknown;
724
+ };
725
+ type Disposable = {
726
+ dispose: () => void;
727
+ };
728
+ /** Univer's command service as the workbook editor lends it. */
729
+ interface SheetsCommandService {
730
+ onMutationExecutedForCollab(listener: (info: CommandInfo, options?: unknown) => void): Disposable;
731
+ beforeCommandExecuted(listener: (info: CommandInfo, options?: unknown) => void): Disposable;
732
+ onCommandExecuted(listener: (info: CommandInfo, options?: unknown) => void): Disposable;
733
+ syncExecuteCommand(id: string, params?: unknown, options?: unknown): unknown;
734
+ executeCommand?: (id: string, params?: unknown, options?: unknown) => Promise<unknown>;
735
+ }
736
+ interface SheetsWorksheetLike {
737
+ getSheetId(): string;
738
+ getName(): string;
739
+ getCellRaw(row: number, col: number): Obj | null | undefined;
740
+ getMergeData(): SheetRange[];
741
+ }
742
+ interface SheetsWorkbookLike {
743
+ getUnitId(): string;
744
+ getSheets(): SheetsWorksheetLike[];
745
+ getSheetBySheetId(id: string): SheetsWorksheetLike | null | undefined;
746
+ getStyles(): {
747
+ get(id: string): unknown;
748
+ };
749
+ getSnapshot(): unknown;
750
+ }
751
+ interface UniverSheetsOtPortOptions {
752
+ commandService: SheetsCommandService;
753
+ /** This seat's workbook unit right now (a content swap keeps the unit id). */
754
+ workbook(): SheetsWorkbookLike | null;
755
+ /** `IDefinedNamesService.getDefinedNameMap(unitId)`: defined-name id → entry. */
756
+ definedNames?(unitId: string): Record<string, {
757
+ name?: string;
758
+ }> | null | undefined;
759
+ /** `IResourceLoaderService.saveUnit(unitId)`: the snapshot with its resources (what a save stores). */
760
+ saveUnit?(unitId: string): unknown | null;
761
+ /** Univer's undo/redo service. */
762
+ undoRedo?(): unknown | null;
763
+ /** Replace the workbook's whole content, keeping its unit id. */
764
+ load(snapshot: unknown): void;
765
+ markDirty(): void;
766
+ }
767
+ declare function univerSheetsOtPort(o: UniverSheetsOtPortOptions): SheetsOtPort & {
768
+ dispose(): void;
769
+ };
770
+
771
+ /**
772
+ * The canonical Sheets state hash (COLLAB-DESIGN §7.2, C0 item 6, §21.3): two seats holding the same workbook
773
+ * hash equal, whatever their seat-local differences.
774
+ *
775
+ * - Dropped: the unit `id`, `rev`, the collab stamps, and per sheet `zoomRatio`, `scrollTop`, `scrollLeft`,
776
+ * `selections`.
777
+ * - Style ids are seat-local (C0 surprise 4): every `s` id is replaced by its style object; `styles` is dropped.
778
+ * - A cell holding a formula (`f` or `si`) drops its computed `v` and `t`: recalculation timing differs per seat.
779
+ * - Empty values, cells and rows are dropped; keys are sorted.
780
+ * - `mergeData` is a set (Univer never reads its order); concurrent merges leave one set in two orders.
781
+ * - Resources are parsed and key-sorted, so the defined names (`SHEET_DEFINED_NAME_PLUGIN`, a map keyed by id)
782
+ * are compared sorted by id; a `definedNames` list (the transform tests' seats) is sorted by id too.
783
+ */
784
+ /** The canonical form of a workbook snapshot (`IWorkbookData`, optionally with a `definedNames` list). */
785
+ declare function canonicalSheet(snapshot: unknown): unknown;
786
+ declare const canonicalSheetString: (snapshot: unknown) => string;
787
+ /** SHA-256 (hex) of the canonical form. Web Crypto, so the browser and Node compute the same hash. */
788
+ declare function sheetsStateHash(snapshot: unknown): Promise<string>;
789
+
790
+ /** `collab.ot_rooms` (§12.2): which workbooks without a room open one. */
791
+ type WorkbookOtRoomsKnob = "off" | "new" | "all";
792
+ /** Whether this workbook opens on the ordered log: its room exists, or the knob opens one. */
793
+ declare function workbookUsesOrderedRoom(workbookId: string, knob: WorkbookOtRoomsKnob, isNewWorkbook: () => Promise<boolean>): Promise<boolean>;
794
+ interface WorkbookOtRoomOptions {
795
+ workbookId: string;
796
+ uid: string;
797
+ /** One per open tab; never reused. */
798
+ clientId: string;
799
+ displayName?: string;
800
+ readAntiEntropyIntervalMs?: () => Promise<number>;
801
+ onAwareness?: (states: Map<number, AwarenessState>) => void;
802
+ onNotice?: (n: SheetsOtNotice) => void;
803
+ onIncident?: (i: OpSessionIncident) => void;
804
+ onStatus?: (s: OpSessionStatus) => void;
805
+ }
806
+ interface WorkbookOtRoomHandle {
807
+ session: OpSession<SheetOp>;
808
+ isSaver(): boolean;
809
+ /** The record's save: a checkpoint at a quiet point. False when this seat does not write now. */
810
+ write(reason: "manual" | string): Promise<boolean>;
811
+ /** Restore / whole import through `collab_replace`. */
812
+ replace(snapshot: unknown): Promise<void>;
813
+ /** This seat's cell, for the other seats' cursor rings. */
814
+ setCursor(c: {
815
+ sheetId: string | null;
816
+ row: number | null;
817
+ col: number | null;
818
+ }): void;
819
+ stop(): void;
820
+ }
821
+ /** Join the workbook's ordered-log room with the editor's port (`univerSheetsOtPort`). */
822
+ declare function startWorkbookOtRoom(port: SheetsOtPort & {
823
+ dispose?: () => void;
824
+ }, o: WorkbookOtRoomOptions): Promise<WorkbookOtRoomHandle>;
825
+
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 };
@@ -1,6 +1,6 @@
1
1
  import * as Y from 'yjs';
2
2
  import { Awareness } from 'y-protocols/awareness';
3
- import { OpSessionNotice, OpSession, OpTransport, OpPresence, OpSessionIncident, OpSessionStatus, AwarenessState, CollabRpcClient, collabReplace } from '@ai-matrx/data/realtime/collab';
3
+ import { OpSessionNotice, OpSession, OpTransport, OpPresence, OpSessionIncident, OpSessionStatus, AwarenessState, CollabRpcClient, collabReplace, OpDocumentAdapter } from '@ai-matrx/data/realtime/collab';
4
4
  import { IDocumentData } from '@univerjs/core';
5
5
  import { CommitReason } from '@ai-matrx/kit/working-copy';
6
6
 
@@ -385,7 +385,7 @@ interface DocsOtRoom {
385
385
  * through `encode`, so `encode` must not depend on key order or every acknowledgement looks like a mismatch.
386
386
  */
387
387
  declare function canonicalKeys<T>(v: T): T;
388
- interface UndoItem {
388
+ interface UndoItem$1 {
389
389
  unitID?: string;
390
390
  undoMutations?: Array<{
391
391
  id: string;
@@ -398,11 +398,11 @@ interface UndoItem {
398
398
  }
399
399
  /** The Univer 1.0.4 fields the undo rebase reads; a forcing test fails if they move (Univer is pinned). */
400
400
  declare function undoStacksOf(service: unknown): {
401
- undo: Map<string, UndoItem[]>;
402
- redo: Map<string, UndoItem[]>;
401
+ undo: Map<string, UndoItem$1[]>;
402
+ redo: Map<string, UndoItem$1[]>;
403
403
  } | null;
404
404
  /** §6.9: rebase one stack over a remote op; items that cannot follow are dropped. Returns how many were dropped. */
405
- declare function rebaseUndoStack(items: UndoItem[], remote: DocsOp): number;
405
+ declare function rebaseUndoStack(items: UndoItem$1[], remote: DocsOp): number;
406
406
  declare function openDocsOtRoom(o: OpenDocsOtRoomOptions): DocsOtRoom;
407
407
 
408
408
  interface CaretRange {
@@ -536,4 +536,291 @@ declare function restoreDocumentSnapshot(args: {
536
536
  label: string | null;
537
537
  }, deps?: Partial<DocumentRestoreDeps>): Promise<DocumentRestoreResult>;
538
538
 
539
- 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 OtRoomsKnob, RICH_TEXT_EDITING, SENDER_VIEW_PARAMS, WorkbookCollabSession, type WorkbookCollabSessionOptions, applyDocsOp, canonicalDocsSnapshot, canonicalDocsString, canonicalKeys, composeDocsOps, docsStateHash, documentOtFactory, documentUsesOrderedRoom, dropEmptyStyleRetains, invertDocsOp, isCellEditorScratch, isNoopDocsOp, normalizeDocsOp, openDocsOtRoom, rebaseUndoStack, restoreDocumentSnapshot, stampCovered, stampDeterministicIds, stripSenderView, takeCovered, transformDocsOp, transformTextX, undoStacksOf };
539
+ /**
540
+ * Sheet co-editing transforms (C5a): the shapes. Pure data; no Univer import.
541
+ *
542
+ * Convention (COLLAB-DESIGN §6.4): `transform(x, y, side)` returns `x` rewritten to apply AFTER `y`, where
543
+ * `side` is x's side. The later-committed op always takes "left": it wins overwrites and sits first on
544
+ * position ties.
545
+ */
546
+ /** One allowlisted Univer mutation as it travels: no `unitId` (the receiver re-addresses to its own unit). */
547
+ interface SheetMutation {
548
+ readonly id: string;
549
+ readonly params: Readonly<Record<string, unknown>>;
550
+ }
551
+ interface Barrier {
552
+ readonly barrier: true;
553
+ readonly reason: string;
554
+ }
555
+ interface SheetRange {
556
+ startRow: number;
557
+ endRow: number;
558
+ startColumn: number;
559
+ endColumn: number;
560
+ rangeType?: number;
561
+ [k: string]: unknown;
562
+ }
563
+
564
+ /** A changeset: allowlisted sheet mutations in order. `null` / `[]` is the no-op. */
565
+ type SheetOp = SheetMutation[] | null;
566
+ /**
567
+ * The room's protocol (§6.4): Univer 1.0.4 + transformer `SHEET_TRANSFORMER_VERSION`. Any Univer or transformer
568
+ * change raises it; a room at another proto opens read-only for this build.
569
+ */
570
+ declare const SHEETS_COLLAB_PROTO = 1;
571
+ declare const SHEETS_EDIT_GROUP = "sheets.edit";
572
+ /** One outermost command's traveling mutations, as the port hands them over. */
573
+ interface SheetsLocalGroup {
574
+ kind: "group";
575
+ mutations: SheetMutation[];
576
+ /** The group's inverse against the pre-state (§6.3), or undefined when one of its mutations has none. */
577
+ inverse?: SheetMutation[];
578
+ /** The outermost command id (the change's label in a rollback notice). */
579
+ label: string | null;
580
+ }
581
+ /** A local change that cannot travel (no allowlist: a barrier id, an unknown id, a whole-style override …). */
582
+ interface SheetsNotShared {
583
+ kind: "not_shared";
584
+ mutationId: string;
585
+ label: string | null;
586
+ }
587
+ type SheetsLocalEvent = SheetsLocalGroup | SheetsNotShared;
588
+ /** What the workbook editor lends the room (implemented by `univerSheetsOtPort`). */
589
+ interface SheetsOtPort {
590
+ onLocal(listener: (e: SheetsLocalEvent) => void): () => void;
591
+ /** True while a local command is still running (its group is not handed over yet). */
592
+ busy(): boolean;
593
+ /** Run `fn` once no local command is running (immediately when none is). */
594
+ whenIdle(fn: () => void): void;
595
+ /** Apply one committed mutation to this seat's workbook; throws when the editor refused it. */
596
+ applyRemote(m: SheetMutation): void;
597
+ /** The workbook as the editor holds it now (with resources), or null when none is mounted. */
598
+ snapshot(): unknown | null;
599
+ /** Replace the workbook's whole content (same unit id). */
600
+ load(snapshot: unknown): void;
601
+ /** Univer's undo/redo service and this seat's unit. */
602
+ undoTargets(): Array<{
603
+ service: unknown;
604
+ unitId: string;
605
+ }>;
606
+ /** Ask for a save (the record's one coalesced save). */
607
+ markDirty(): void;
608
+ }
609
+ type SheetsOtNotice = OpSessionNotice<SheetOp> | {
610
+ kind: "not_shared";
611
+ mutationId: string;
612
+ } | {
613
+ kind: "not_live";
614
+ };
615
+ /**
616
+ * The adapter's transform: the C5a/C5b group transform, with `lost` widened by what y can no longer apply
617
+ * after x (y's `dropped` over x). The session tells an earlier author through `lost`; without this, an edit
618
+ * in a column a later op removed would vanish without a word.
619
+ */
620
+ declare function transformSheetOp(x: SheetOp, y: SheetOp, side: "left" | "right"): Barrier | {
621
+ op: SheetOp;
622
+ lost: string[];
623
+ dropped: string[];
624
+ };
625
+ /**
626
+ * The wire form. Keys in one canonical order: the log stores groups as jsonb, which hands object keys back in
627
+ * its own order, and the session compares wire forms (its ack check) through `encode` (C3's rule).
628
+ */
629
+ declare function encodeSheetOp(op: SheetOp): {
630
+ cmd: string;
631
+ mutations: {
632
+ id: string;
633
+ params: Readonly<Record<string, unknown>>;
634
+ }[];
635
+ }[];
636
+ declare function decodeSheetOp(groups: Array<{
637
+ mutations: Array<{
638
+ id: string;
639
+ params: unknown;
640
+ }>;
641
+ }>): SheetOp;
642
+ interface UndoItem {
643
+ unitID?: string;
644
+ undoMutations?: Array<{
645
+ id: string;
646
+ params: Record<string, unknown>;
647
+ }>;
648
+ redoMutations?: Array<{
649
+ id: string;
650
+ params: Record<string, unknown>;
651
+ }>;
652
+ }
653
+ /** §6.9: rebase one stack over a remote op; items that cannot follow are dropped. Returns how many were dropped. */
654
+ declare function rebaseSheetUndoStack(items: UndoItem[], remote: SheetOp, unitId: string): number;
655
+ interface SheetsOtAdapterHooks {
656
+ /** Called once per applied remote op that rebased this seat's undo stacks (for tests and logs). */
657
+ onUndoRebased?: (dropped: number) => void;
658
+ }
659
+ /** The `OpDocumentAdapter` over a sheets port, plus the held-remote queue the room drives. */
660
+ interface SheetsOtAdapter extends OpDocumentAdapter<SheetOp> {
661
+ /** Remote ops held while a local command runs. */
662
+ held(): number;
663
+ /** A local group finished while remote ops were held: rebase it over them and them over it (Docs IME rule). */
664
+ rebaseLocalOverHeld(local: SheetMutation[]): SheetMutation[] | "barrier";
665
+ clearHeld(): void;
666
+ }
667
+ declare function createSheetsOtAdapter(port: SheetsOtPort, hooks?: SheetsOtAdapterHooks): SheetsOtAdapter;
668
+ interface OpenSheetsOtRoomOptions {
669
+ port: SheetsOtPort;
670
+ transport: OpTransport;
671
+ clientId: string;
672
+ presence?: OpPresence;
673
+ /** `collab_replace` for this room (restore, whole import). */
674
+ replace: (req: {
675
+ snapshot: unknown;
676
+ stateHash: string;
677
+ clientId: string;
678
+ }) => Promise<{
679
+ rev: number;
680
+ ref: string;
681
+ }>;
682
+ onNotice?: (n: SheetsOtNotice) => void;
683
+ onIncident?: (i: OpSessionIncident) => void;
684
+ onStatus?: (s: OpSessionStatus) => void;
685
+ }
686
+ interface SheetsOtRoom {
687
+ session: OpSession<SheetOp>;
688
+ /** The record's save: a checkpoint at a quiet point (§7.3). False when this seat does not write now. */
689
+ write(reason: "manual" | string): Promise<boolean>;
690
+ /** Restore / whole import through `collab_replace`. */
691
+ replace(snapshot: unknown): Promise<void>;
692
+ /** This seat is the one that saves on its own. */
693
+ isSaver(): boolean;
694
+ stop(): void;
695
+ }
696
+ declare function openSheetsOtRoom(o: OpenSheetsOtRoomOptions): SheetsOtRoom;
697
+
698
+ /**
699
+ * The `SheetsOtPort` over a live Univer workbook (COLLAB-DESIGN §6.3, §6.7, C0 items 4, 6, 7, C5a/C5b capture
700
+ * rules). The host lends Univer's services (it resolves them with its own tokens, so this module never pulls a
701
+ * second copy of Univer's DI into the app); this module does every capture rule:
702
+ *
703
+ * - FILTER. Only mutations of THIS seat's unit, never `onlyLocal` or `fromCollab` ones (formula results, our own
704
+ * remote applies), never the never-travels class.
705
+ * - GROUP. By the outermost COMMAND (`beforeCommandExecuted` / `onCommandExecuted` depth), with a try/finally
706
+ * around `executeCommand` so a command that mutates and then throws still closes its group (C0 surprise 7).
707
+ * One hand-over per group: the formula annotation needs the whole group (a rewrite after a structural op is
708
+ * `derived`, §21.2).
709
+ * - ALLOWLIST. `allowParams`; an id without one (a barrier id, an unknown id) makes the group `not_shared`.
710
+ * - THE THREE C5a RULES. Cell content is completed from the cell right after the mutation
711
+ * (`completeCellContent`); a remove-merge names the exact merges it removed (`exactMergeRemovals`, merges read
712
+ * right before the mutation); a style travels as its object, never a seat-local id. A whole-style override
713
+ * (paste) is restated as a merge with explicit nulls, which every seat applies identically.
714
+ * - FORMULAS. `annotateFormulas` with the sheet names and defined names as they were before the command.
715
+ * - INVERSE from the APPLIED params against a COPY of the pre-state taken in `beforeCommandExecuted`
716
+ * (C0 surprise 6). Families without a safe inverse leave it unknown.
717
+ */
718
+
719
+ type Obj = Record<string, unknown>;
720
+ type CommandInfo = {
721
+ id: string;
722
+ type?: number;
723
+ params?: unknown;
724
+ };
725
+ type Disposable = {
726
+ dispose: () => void;
727
+ };
728
+ /** Univer's command service as the workbook editor lends it. */
729
+ interface SheetsCommandService {
730
+ onMutationExecutedForCollab(listener: (info: CommandInfo, options?: unknown) => void): Disposable;
731
+ beforeCommandExecuted(listener: (info: CommandInfo, options?: unknown) => void): Disposable;
732
+ onCommandExecuted(listener: (info: CommandInfo, options?: unknown) => void): Disposable;
733
+ syncExecuteCommand(id: string, params?: unknown, options?: unknown): unknown;
734
+ executeCommand?: (id: string, params?: unknown, options?: unknown) => Promise<unknown>;
735
+ }
736
+ interface SheetsWorksheetLike {
737
+ getSheetId(): string;
738
+ getName(): string;
739
+ getCellRaw(row: number, col: number): Obj | null | undefined;
740
+ getMergeData(): SheetRange[];
741
+ }
742
+ interface SheetsWorkbookLike {
743
+ getUnitId(): string;
744
+ getSheets(): SheetsWorksheetLike[];
745
+ getSheetBySheetId(id: string): SheetsWorksheetLike | null | undefined;
746
+ getStyles(): {
747
+ get(id: string): unknown;
748
+ };
749
+ getSnapshot(): unknown;
750
+ }
751
+ interface UniverSheetsOtPortOptions {
752
+ commandService: SheetsCommandService;
753
+ /** This seat's workbook unit right now (a content swap keeps the unit id). */
754
+ workbook(): SheetsWorkbookLike | null;
755
+ /** `IDefinedNamesService.getDefinedNameMap(unitId)`: defined-name id → entry. */
756
+ definedNames?(unitId: string): Record<string, {
757
+ name?: string;
758
+ }> | null | undefined;
759
+ /** `IResourceLoaderService.saveUnit(unitId)`: the snapshot with its resources (what a save stores). */
760
+ saveUnit?(unitId: string): unknown | null;
761
+ /** Univer's undo/redo service. */
762
+ undoRedo?(): unknown | null;
763
+ /** Replace the workbook's whole content, keeping its unit id. */
764
+ load(snapshot: unknown): void;
765
+ markDirty(): void;
766
+ }
767
+ declare function univerSheetsOtPort(o: UniverSheetsOtPortOptions): SheetsOtPort & {
768
+ dispose(): void;
769
+ };
770
+
771
+ /**
772
+ * The canonical Sheets state hash (COLLAB-DESIGN §7.2, C0 item 6, §21.3): two seats holding the same workbook
773
+ * hash equal, whatever their seat-local differences.
774
+ *
775
+ * - Dropped: the unit `id`, `rev`, the collab stamps, and per sheet `zoomRatio`, `scrollTop`, `scrollLeft`,
776
+ * `selections`.
777
+ * - Style ids are seat-local (C0 surprise 4): every `s` id is replaced by its style object; `styles` is dropped.
778
+ * - A cell holding a formula (`f` or `si`) drops its computed `v` and `t`: recalculation timing differs per seat.
779
+ * - Empty values, cells and rows are dropped; keys are sorted.
780
+ * - `mergeData` is a set (Univer never reads its order); concurrent merges leave one set in two orders.
781
+ * - Resources are parsed and key-sorted, so the defined names (`SHEET_DEFINED_NAME_PLUGIN`, a map keyed by id)
782
+ * are compared sorted by id; a `definedNames` list (the transform tests' seats) is sorted by id too.
783
+ */
784
+ /** The canonical form of a workbook snapshot (`IWorkbookData`, optionally with a `definedNames` list). */
785
+ declare function canonicalSheet(snapshot: unknown): unknown;
786
+ declare const canonicalSheetString: (snapshot: unknown) => string;
787
+ /** SHA-256 (hex) of the canonical form. Web Crypto, so the browser and Node compute the same hash. */
788
+ declare function sheetsStateHash(snapshot: unknown): Promise<string>;
789
+
790
+ /** `collab.ot_rooms` (§12.2): which workbooks without a room open one. */
791
+ type WorkbookOtRoomsKnob = "off" | "new" | "all";
792
+ /** Whether this workbook opens on the ordered log: its room exists, or the knob opens one. */
793
+ declare function workbookUsesOrderedRoom(workbookId: string, knob: WorkbookOtRoomsKnob, isNewWorkbook: () => Promise<boolean>): Promise<boolean>;
794
+ interface WorkbookOtRoomOptions {
795
+ workbookId: string;
796
+ uid: string;
797
+ /** One per open tab; never reused. */
798
+ clientId: string;
799
+ displayName?: string;
800
+ readAntiEntropyIntervalMs?: () => Promise<number>;
801
+ onAwareness?: (states: Map<number, AwarenessState>) => void;
802
+ onNotice?: (n: SheetsOtNotice) => void;
803
+ onIncident?: (i: OpSessionIncident) => void;
804
+ onStatus?: (s: OpSessionStatus) => void;
805
+ }
806
+ interface WorkbookOtRoomHandle {
807
+ session: OpSession<SheetOp>;
808
+ isSaver(): boolean;
809
+ /** The record's save: a checkpoint at a quiet point. False when this seat does not write now. */
810
+ write(reason: "manual" | string): Promise<boolean>;
811
+ /** Restore / whole import through `collab_replace`. */
812
+ replace(snapshot: unknown): Promise<void>;
813
+ /** This seat's cell, for the other seats' cursor rings. */
814
+ setCursor(c: {
815
+ sheetId: string | null;
816
+ row: number | null;
817
+ col: number | null;
818
+ }): void;
819
+ stop(): void;
820
+ }
821
+ /** Join the workbook's ordered-log room with the editor's port (`univerSheetsOtPort`). */
822
+ declare function startWorkbookOtRoom(port: SheetsOtPort & {
823
+ dispose?: () => void;
824
+ }, o: WorkbookOtRoomOptions): Promise<WorkbookOtRoomHandle>;
825
+
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 };