@ai-matrx/office 0.8.16 → 0.8.18
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 +39 -2
- package/dist/{chunk-HX5TXQIX.cjs → chunk-JMVPAJJA.cjs} +6 -5
- package/dist/chunk-JMVPAJJA.cjs.map +1 -0
- package/dist/{chunk-2X3KR6Y4.js → chunk-TRA2BTPL.js} +6 -5
- package/dist/{chunk-2X3KR6Y4.js.map → chunk-TRA2BTPL.js.map} +1 -1
- package/dist/docs-io.cjs +6 -6
- package/dist/docs-io.js +1 -1
- package/dist/docs.cjs +2 -2
- package/dist/docs.d.cts +5 -1
- package/dist/docs.d.ts +5 -1
- package/dist/docs.js +1 -1
- package/dist/univer-collab.cjs +224 -34
- package/dist/univer-collab.cjs.map +1 -1
- package/dist/univer-collab.d.cts +40 -12
- package/dist/univer-collab.d.ts +40 -12
- package/dist/univer-collab.js +206 -15
- package/dist/univer-collab.js.map +1 -1
- package/package.json +2 -2
- package/dist/chunk-HX5TXQIX.cjs.map +0 -1
package/dist/univer-collab.d.cts
CHANGED
|
@@ -252,19 +252,14 @@ declare function invertDocsOp(op: DocsOp, preDoc: unknown): DocsOp;
|
|
|
252
252
|
/** Part of `proto` (§6.4): Univer 1.0.4 + this transformer, rules R1–R6. */
|
|
253
253
|
declare const DOCS_TRANSFORM_VERSION = "univer-1.0.4+docs-ot-r6";
|
|
254
254
|
|
|
255
|
-
/**
|
|
256
|
-
* The canonical Docs state hash (COLLAB-DESIGN §7.2; C0 item 6, `spikes/c0-collab/lib.mjs`).
|
|
257
|
-
*
|
|
258
|
-
* SHA-256 of the canonical snapshot: keys sorted, empty values dropped, the unit id and seat-local fields
|
|
259
|
-
* removed (revision counter, collab stamps, layout state, selections), adjacent equal text runs merged, split
|
|
260
|
-
* pieces of one custom range or decoration folded, and `paragraphId` dropped (Univer's TextX.apply mints a
|
|
261
|
-
* random one per seat, C0 surprise 3). Header, footer and note bodies get the same rules.
|
|
262
|
-
*
|
|
263
|
-
* Two seats with equal content hash equal; one character more hashes differently. Browser and Node: the
|
|
264
|
-
* digest is Web Crypto's.
|
|
265
|
-
*/
|
|
266
255
|
/** Never content: the collab stamps, revision counters, seat-local view state. */
|
|
267
256
|
declare const DOC_LOCAL_KEYS: string[];
|
|
257
|
+
/**
|
|
258
|
+
* The snapshot as a seat holds it after loading it: what `DocumentModel` / the editor mount do (deterministic
|
|
259
|
+
* ids, `sanitizeUniverDocSnapshot`), then Univer's own model normalisation (`createDocumentSnapshot` inside
|
|
260
|
+
* `DocumentDataModel`). Idempotent: a snapshot a seat saved comes back unchanged in content.
|
|
261
|
+
*/
|
|
262
|
+
declare function asLoadedDocsSnapshot(snapshot: unknown): Record<string, unknown>;
|
|
268
263
|
/** The canonical Docs snapshot: content only, keys sorted, runs normalized, local fields removed. */
|
|
269
264
|
declare function canonicalDocsSnapshot(snapshot: unknown): unknown;
|
|
270
265
|
/** The canonical form as the string the hash digests (tests compare these directly). */
|
|
@@ -736,6 +731,8 @@ interface SheetsCommandService {
|
|
|
736
731
|
interface SheetsWorksheetLike {
|
|
737
732
|
getSheetId(): string;
|
|
738
733
|
getName(): string;
|
|
734
|
+
getMaxRows?(): number;
|
|
735
|
+
getMaxColumns?(): number;
|
|
739
736
|
getCellRaw(row: number, col: number): Obj | null | undefined;
|
|
740
737
|
getMergeData(): SheetRange[];
|
|
741
738
|
}
|
|
@@ -760,13 +757,44 @@ interface UniverSheetsOtPortOptions {
|
|
|
760
757
|
saveUnit?(unitId: string): unknown | null;
|
|
761
758
|
/** Univer's undo/redo service. */
|
|
762
759
|
undoRedo?(): unknown | null;
|
|
760
|
+
/**
|
|
761
|
+
* This seat's selections on the active sheet (`SheetsSelectionsService`). A remote row/column insert, remove or
|
|
762
|
+
* move carries this seat's selection with it, and a selection a remote remove took away is clamped to the
|
|
763
|
+
* sheet: a selection left past the sheet's edge breaks every reader of the active range.
|
|
764
|
+
*/
|
|
765
|
+
selections?: {
|
|
766
|
+
sheetId(): string | null;
|
|
767
|
+
get(): SheetSelection[] | null | undefined;
|
|
768
|
+
set(selections: SheetSelection[]): void;
|
|
769
|
+
};
|
|
763
770
|
/** Replace the workbook's whole content, keeping its unit id. */
|
|
764
771
|
load(snapshot: unknown): void;
|
|
765
772
|
markDirty(): void;
|
|
766
773
|
}
|
|
774
|
+
/** One selection as `SheetsSelectionsService` holds it (range, primary cell, style). */
|
|
775
|
+
interface SheetSelection {
|
|
776
|
+
range: SheetRange & {
|
|
777
|
+
rangeType?: number;
|
|
778
|
+
};
|
|
779
|
+
primary?: (Record<string, unknown> & {
|
|
780
|
+
startRow?: number;
|
|
781
|
+
endRow?: number;
|
|
782
|
+
startColumn?: number;
|
|
783
|
+
endColumn?: number;
|
|
784
|
+
actualRow?: number;
|
|
785
|
+
actualColumn?: number;
|
|
786
|
+
}) | null;
|
|
787
|
+
style?: unknown;
|
|
788
|
+
}
|
|
767
789
|
declare function univerSheetsOtPort(o: UniverSheetsOtPortOptions): SheetsOtPort & {
|
|
768
790
|
dispose(): void;
|
|
791
|
+
running(): string[];
|
|
769
792
|
};
|
|
793
|
+
/**
|
|
794
|
+
* This seat's selections after a remote structural op: indices move with their rows/columns; one the op removed
|
|
795
|
+
* lands on the first surviving index; everything is clamped to the sheet; whole-row/column ranges span the sheet.
|
|
796
|
+
*/
|
|
797
|
+
declare function moveSelectionsThrough(selections: SheetSelection[], m: SheetMutation, maxRows: number, maxCols: number): SheetSelection[];
|
|
770
798
|
|
|
771
799
|
/**
|
|
772
800
|
* The canonical Sheets state hash (COLLAB-DESIGN §7.2, C0 item 6, §21.3): two seats holding the same workbook
|
|
@@ -823,4 +851,4 @@ declare function startWorkbookOtRoom(port: SheetsOtPort & {
|
|
|
823
851
|
dispose?: () => void;
|
|
824
852
|
}, o: WorkbookOtRoomOptions): Promise<WorkbookOtRoomHandle>;
|
|
825
853
|
|
|
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 };
|
|
854
|
+
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, asLoadedDocsSnapshot, 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 };
|
package/dist/univer-collab.d.ts
CHANGED
|
@@ -252,19 +252,14 @@ declare function invertDocsOp(op: DocsOp, preDoc: unknown): DocsOp;
|
|
|
252
252
|
/** Part of `proto` (§6.4): Univer 1.0.4 + this transformer, rules R1–R6. */
|
|
253
253
|
declare const DOCS_TRANSFORM_VERSION = "univer-1.0.4+docs-ot-r6";
|
|
254
254
|
|
|
255
|
-
/**
|
|
256
|
-
* The canonical Docs state hash (COLLAB-DESIGN §7.2; C0 item 6, `spikes/c0-collab/lib.mjs`).
|
|
257
|
-
*
|
|
258
|
-
* SHA-256 of the canonical snapshot: keys sorted, empty values dropped, the unit id and seat-local fields
|
|
259
|
-
* removed (revision counter, collab stamps, layout state, selections), adjacent equal text runs merged, split
|
|
260
|
-
* pieces of one custom range or decoration folded, and `paragraphId` dropped (Univer's TextX.apply mints a
|
|
261
|
-
* random one per seat, C0 surprise 3). Header, footer and note bodies get the same rules.
|
|
262
|
-
*
|
|
263
|
-
* Two seats with equal content hash equal; one character more hashes differently. Browser and Node: the
|
|
264
|
-
* digest is Web Crypto's.
|
|
265
|
-
*/
|
|
266
255
|
/** Never content: the collab stamps, revision counters, seat-local view state. */
|
|
267
256
|
declare const DOC_LOCAL_KEYS: string[];
|
|
257
|
+
/**
|
|
258
|
+
* The snapshot as a seat holds it after loading it: what `DocumentModel` / the editor mount do (deterministic
|
|
259
|
+
* ids, `sanitizeUniverDocSnapshot`), then Univer's own model normalisation (`createDocumentSnapshot` inside
|
|
260
|
+
* `DocumentDataModel`). Idempotent: a snapshot a seat saved comes back unchanged in content.
|
|
261
|
+
*/
|
|
262
|
+
declare function asLoadedDocsSnapshot(snapshot: unknown): Record<string, unknown>;
|
|
268
263
|
/** The canonical Docs snapshot: content only, keys sorted, runs normalized, local fields removed. */
|
|
269
264
|
declare function canonicalDocsSnapshot(snapshot: unknown): unknown;
|
|
270
265
|
/** The canonical form as the string the hash digests (tests compare these directly). */
|
|
@@ -736,6 +731,8 @@ interface SheetsCommandService {
|
|
|
736
731
|
interface SheetsWorksheetLike {
|
|
737
732
|
getSheetId(): string;
|
|
738
733
|
getName(): string;
|
|
734
|
+
getMaxRows?(): number;
|
|
735
|
+
getMaxColumns?(): number;
|
|
739
736
|
getCellRaw(row: number, col: number): Obj | null | undefined;
|
|
740
737
|
getMergeData(): SheetRange[];
|
|
741
738
|
}
|
|
@@ -760,13 +757,44 @@ interface UniverSheetsOtPortOptions {
|
|
|
760
757
|
saveUnit?(unitId: string): unknown | null;
|
|
761
758
|
/** Univer's undo/redo service. */
|
|
762
759
|
undoRedo?(): unknown | null;
|
|
760
|
+
/**
|
|
761
|
+
* This seat's selections on the active sheet (`SheetsSelectionsService`). A remote row/column insert, remove or
|
|
762
|
+
* move carries this seat's selection with it, and a selection a remote remove took away is clamped to the
|
|
763
|
+
* sheet: a selection left past the sheet's edge breaks every reader of the active range.
|
|
764
|
+
*/
|
|
765
|
+
selections?: {
|
|
766
|
+
sheetId(): string | null;
|
|
767
|
+
get(): SheetSelection[] | null | undefined;
|
|
768
|
+
set(selections: SheetSelection[]): void;
|
|
769
|
+
};
|
|
763
770
|
/** Replace the workbook's whole content, keeping its unit id. */
|
|
764
771
|
load(snapshot: unknown): void;
|
|
765
772
|
markDirty(): void;
|
|
766
773
|
}
|
|
774
|
+
/** One selection as `SheetsSelectionsService` holds it (range, primary cell, style). */
|
|
775
|
+
interface SheetSelection {
|
|
776
|
+
range: SheetRange & {
|
|
777
|
+
rangeType?: number;
|
|
778
|
+
};
|
|
779
|
+
primary?: (Record<string, unknown> & {
|
|
780
|
+
startRow?: number;
|
|
781
|
+
endRow?: number;
|
|
782
|
+
startColumn?: number;
|
|
783
|
+
endColumn?: number;
|
|
784
|
+
actualRow?: number;
|
|
785
|
+
actualColumn?: number;
|
|
786
|
+
}) | null;
|
|
787
|
+
style?: unknown;
|
|
788
|
+
}
|
|
767
789
|
declare function univerSheetsOtPort(o: UniverSheetsOtPortOptions): SheetsOtPort & {
|
|
768
790
|
dispose(): void;
|
|
791
|
+
running(): string[];
|
|
769
792
|
};
|
|
793
|
+
/**
|
|
794
|
+
* This seat's selections after a remote structural op: indices move with their rows/columns; one the op removed
|
|
795
|
+
* lands on the first surviving index; everything is clamped to the sheet; whole-row/column ranges span the sheet.
|
|
796
|
+
*/
|
|
797
|
+
declare function moveSelectionsThrough(selections: SheetSelection[], m: SheetMutation, maxRows: number, maxCols: number): SheetSelection[];
|
|
770
798
|
|
|
771
799
|
/**
|
|
772
800
|
* The canonical Sheets state hash (COLLAB-DESIGN §7.2, C0 item 6, §21.3): two seats holding the same workbook
|
|
@@ -823,4 +851,4 @@ declare function startWorkbookOtRoom(port: SheetsOtPort & {
|
|
|
823
851
|
dispose?: () => void;
|
|
824
852
|
}, o: WorkbookOtRoomOptions): Promise<WorkbookOtRoomHandle>;
|
|
825
853
|
|
|
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 };
|
|
854
|
+
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, asLoadedDocsSnapshot, 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 };
|
package/dist/univer-collab.js
CHANGED
|
@@ -870,6 +870,104 @@ function invertDocsOp(op, preDoc) {
|
|
|
870
870
|
}
|
|
871
871
|
var DOCS_TRANSFORM_VERSION = "univer-1.0.4+docs-ot-r6";
|
|
872
872
|
|
|
873
|
+
// src/univer/collab/docs-ot/state-hash.ts
|
|
874
|
+
import { DocumentDataModel } from "@univerjs/core";
|
|
875
|
+
|
|
876
|
+
// src/docs/sanitize-univer-doc-snapshot.ts
|
|
877
|
+
import { NamedStyleType } from "@univerjs/core";
|
|
878
|
+
|
|
879
|
+
// src/core/document-page-style.ts
|
|
880
|
+
var TRADITIONAL = 1;
|
|
881
|
+
var PORTRAIT = 0;
|
|
882
|
+
var PX_PER_INCH = 96;
|
|
883
|
+
var DEFAULT_DOCUMENT_PAGE_STYLE = {
|
|
884
|
+
pageSize: { width: 816, height: 1056 },
|
|
885
|
+
documentFlavor: TRADITIONAL,
|
|
886
|
+
pageOrient: PORTRAIT,
|
|
887
|
+
marginTop: PX_PER_INCH,
|
|
888
|
+
marginBottom: PX_PER_INCH,
|
|
889
|
+
marginLeft: PX_PER_INCH,
|
|
890
|
+
marginRight: PX_PER_INCH,
|
|
891
|
+
// Univer applies no paragraph spacing to a paginated page by itself; without this every paragraph
|
|
892
|
+
// runs into the next (Google Docs' own default: 1.15 lines, 10px after).
|
|
893
|
+
defaultParagraphStyle: { spaceAbove: { v: 0 }, spaceBelow: { v: 10 }, lineSpacing: 1.15 }
|
|
894
|
+
};
|
|
895
|
+
function defaultDocumentPageStyle() {
|
|
896
|
+
return {
|
|
897
|
+
...DEFAULT_DOCUMENT_PAGE_STYLE,
|
|
898
|
+
pageSize: { ...DEFAULT_DOCUMENT_PAGE_STYLE.pageSize },
|
|
899
|
+
defaultParagraphStyle: { ...DEFAULT_DOCUMENT_PAGE_STYLE.defaultParagraphStyle }
|
|
900
|
+
};
|
|
901
|
+
}
|
|
902
|
+
function isLegacySqueezedPageStyle(style) {
|
|
903
|
+
const size = style?.pageSize;
|
|
904
|
+
return !!size && size.width === 595 && size.height === 842 && style?.marginLeft === 90 && style?.marginRight === 90 && style?.marginTop === 72 && style?.marginBottom === 72;
|
|
905
|
+
}
|
|
906
|
+
var PAGE_COLORS = ["#ffffff", "#fff8e7", "#f3f3f3", "#e8f0fe", "#e6f4ea", "#fef7e0"];
|
|
907
|
+
var DEFAULT_PAGE_COLOR = PAGE_COLORS[0];
|
|
908
|
+
|
|
909
|
+
// src/docs/sanitize-univer-doc-snapshot.ts
|
|
910
|
+
var NAMED_STYLE_STRING_TO_NUMBER = Object.fromEntries(
|
|
911
|
+
Object.entries(NamedStyleType).filter(([key, val]) => typeof val === "number" && isNaN(Number(key))).map(([key, val]) => [key, val])
|
|
912
|
+
);
|
|
913
|
+
function sanitizeUniverDocSnapshot(snapshot, docId, opts = {}) {
|
|
914
|
+
restorePageStyle(snapshot, docId, opts.quiet === true);
|
|
915
|
+
ensureTextRuns(snapshot);
|
|
916
|
+
const paragraphs = snapshot?.body?.paragraphs;
|
|
917
|
+
if (!Array.isArray(paragraphs)) return snapshot;
|
|
918
|
+
let fixed = 0;
|
|
919
|
+
for (const paragraph of paragraphs) {
|
|
920
|
+
const style = paragraph?.paragraphStyle;
|
|
921
|
+
const value = style?.namedStyleType;
|
|
922
|
+
if (typeof value === "string") {
|
|
923
|
+
const numeric = NAMED_STYLE_STRING_TO_NUMBER[value];
|
|
924
|
+
if (numeric !== void 0) {
|
|
925
|
+
style.namedStyleType = numeric;
|
|
926
|
+
fixed += 1;
|
|
927
|
+
} else {
|
|
928
|
+
delete style.namedStyleType;
|
|
929
|
+
fixed += 1;
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
if (fixed > 0 && opts.quiet !== true) {
|
|
934
|
+
console.warn(
|
|
935
|
+
`[data-tables] RECOVERY: sanitized ${fixed} string namedStyleType value(s) to numeric NamedStyleType in document snapshot${docId ? ` ${docId}` : ""}. The snapshot was written with the wrong enum encoding (string instead of number) and would have crashed Univer's <ParagraphMenu>. Fix the snapshot writer to emit numeric NamedStyleType values.`
|
|
936
|
+
);
|
|
937
|
+
}
|
|
938
|
+
return snapshot;
|
|
939
|
+
}
|
|
940
|
+
function restorePageStyle(snapshot, docId, quiet = false) {
|
|
941
|
+
if (!snapshot || typeof snapshot !== "object") return;
|
|
942
|
+
const style = snapshot.documentStyle;
|
|
943
|
+
if (style?.pageSize?.width && isLegacySqueezedPageStyle(style)) {
|
|
944
|
+
const page = defaultDocumentPageStyle();
|
|
945
|
+
snapshot.documentStyle = { ...style, ...page, defaultParagraphStyle: style.defaultParagraphStyle ?? page.defaultParagraphStyle };
|
|
946
|
+
return;
|
|
947
|
+
}
|
|
948
|
+
if (style?.pageSize?.width) {
|
|
949
|
+
if (!style.documentFlavor) {
|
|
950
|
+
const page = defaultDocumentPageStyle();
|
|
951
|
+
Object.assign(style, { documentFlavor: page.documentFlavor });
|
|
952
|
+
if (page.defaultParagraphStyle) style.defaultParagraphStyle ??= page.defaultParagraphStyle;
|
|
953
|
+
}
|
|
954
|
+
return;
|
|
955
|
+
}
|
|
956
|
+
snapshot.documentStyle = {
|
|
957
|
+
...defaultDocumentPageStyle(),
|
|
958
|
+
...snapshot.documentStyle ?? {},
|
|
959
|
+
pageSize: defaultDocumentPageStyle().pageSize
|
|
960
|
+
};
|
|
961
|
+
if (quiet) return;
|
|
962
|
+
console.warn(
|
|
963
|
+
`[data-tables] RECOVERY: document snapshot${docId ? ` ${docId}` : ""} had no documentStyle.pageSize \u2014 restored the default Letter page geometry. Without a page box Univer lays the body out unbounded: text does not wrap and the viewport has no scrollable extent, so the document appears frozen. Fix the snapshot writer (agent/markdown converters must stamp DEFAULT_DOCUMENT_PAGE_STYLE).`
|
|
964
|
+
);
|
|
965
|
+
}
|
|
966
|
+
function ensureTextRuns(snapshot) {
|
|
967
|
+
const body = snapshot?.body;
|
|
968
|
+
if (body && typeof body === "object" && !Array.isArray(body.textRuns)) body.textRuns = [];
|
|
969
|
+
}
|
|
970
|
+
|
|
873
971
|
// src/univer/collab/docs-ot/state-hash.ts
|
|
874
972
|
var DOC_LOCAL_KEYS = ["rev", "__matrxCollabCovered", "__collab", "disabled", "layoutState", "textRanges", "selections"];
|
|
875
973
|
function sortDeep(v) {
|
|
@@ -929,6 +1027,7 @@ function canonicalBody(body) {
|
|
|
929
1027
|
const b = { ...body };
|
|
930
1028
|
b.textRuns = canonicalRuns(b.textRuns);
|
|
931
1029
|
if (Array.isArray(b.paragraphs)) b.paragraphs = b.paragraphs.map(({ paragraphId: _p, ...p }) => p);
|
|
1030
|
+
if (Array.isArray(b.sectionBreaks)) b.sectionBreaks = b.sectionBreaks.map(({ sectionId: _s, ...x }) => x);
|
|
932
1031
|
b.customRanges = foldPieces(b.customRanges, (r) => JSON.stringify([rootId(r.rangeId), r.rangeType, sortDeep(r.properties ?? {})])).map((r) => ({
|
|
933
1032
|
...r,
|
|
934
1033
|
rangeId: rootId(r.rangeId)
|
|
@@ -943,8 +1042,20 @@ function canonicalBody(body) {
|
|
|
943
1042
|
}
|
|
944
1043
|
return b;
|
|
945
1044
|
}
|
|
1045
|
+
function asLoadedDocsSnapshot(snapshot) {
|
|
1046
|
+
const s = stampDeterministicIds(structuredClone(snapshot ?? {}));
|
|
1047
|
+
delete s.id;
|
|
1048
|
+
for (const k of DOC_LOCAL_KEYS) delete s[k];
|
|
1049
|
+
sanitizeUniverDocSnapshot(s, void 0, { quiet: true });
|
|
1050
|
+
const model = new DocumentDataModel(s);
|
|
1051
|
+
try {
|
|
1052
|
+
return structuredClone(model.getSnapshot());
|
|
1053
|
+
} finally {
|
|
1054
|
+
model.dispose();
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
946
1057
|
function canonicalDocsSnapshot(snapshot) {
|
|
947
|
-
const s =
|
|
1058
|
+
const s = asLoadedDocsSnapshot(snapshot);
|
|
948
1059
|
delete s.id;
|
|
949
1060
|
for (const k of DOC_LOCAL_KEYS) delete s[k];
|
|
950
1061
|
s.body = canonicalBody(s.body);
|
|
@@ -1153,7 +1264,10 @@ function openDocsOtRoom(o) {
|
|
|
1153
1264
|
queue = next.filter((q) => !isNoopDocsOp(q));
|
|
1154
1265
|
if (isNoopDocsOp(op)) return;
|
|
1155
1266
|
}
|
|
1156
|
-
if (!session.local(op, { ...inverse !== void 0 ? { inverse } : {}, label: m.cmd ?? RICH_TEXT_EDITING }))
|
|
1267
|
+
if (!session.local(op, { ...inverse !== void 0 ? { inverse } : {}, label: m.cmd ?? RICH_TEXT_EDITING })) {
|
|
1268
|
+
notice({ kind: "not_live" });
|
|
1269
|
+
session.rebuild("not_live");
|
|
1270
|
+
}
|
|
1157
1271
|
};
|
|
1158
1272
|
const unsubLocal = port.onLocal(onLocal);
|
|
1159
1273
|
const target = o.compositionTarget === void 0 ? typeof document !== "undefined" ? document : null : o.compositionTarget;
|
|
@@ -1214,6 +1328,7 @@ import * as Y2 from "yjs";
|
|
|
1214
1328
|
import { Awareness as Awareness2 } from "y-protocols/awareness";
|
|
1215
1329
|
import {
|
|
1216
1330
|
awarenessOpPresence,
|
|
1331
|
+
claimCollaboratorColor,
|
|
1217
1332
|
collabReplace,
|
|
1218
1333
|
collabRoomExists,
|
|
1219
1334
|
SupabaseYjsProvider,
|
|
@@ -1378,15 +1493,6 @@ async function documentUsesOrderedRoom(documentId, knob, isNewDocument) {
|
|
|
1378
1493
|
if (knob === "new") return isNewDocument();
|
|
1379
1494
|
return false;
|
|
1380
1495
|
}
|
|
1381
|
-
function pickColor2(uid) {
|
|
1382
|
-
const palette = ["#ef4444", "#f59e0b", "#10b981", "#3b82f6", "#8b5cf6", "#ec4899", "#14b8a6", "#f97316"];
|
|
1383
|
-
let h = 2166136261;
|
|
1384
|
-
for (let i = 0; i < uid.length; i++) {
|
|
1385
|
-
h ^= uid.charCodeAt(i);
|
|
1386
|
-
h = Math.imul(h, 16777619);
|
|
1387
|
-
}
|
|
1388
|
-
return palette[Math.abs(h) % palette.length] ?? "#ec4899";
|
|
1389
|
-
}
|
|
1390
1496
|
function documentOtFactory(o) {
|
|
1391
1497
|
return async (basePort, onAwareness) => {
|
|
1392
1498
|
const latest = await getLatestDocumentSnapshot(o.documentId);
|
|
@@ -1400,7 +1506,8 @@ function documentOtFactory(o) {
|
|
|
1400
1506
|
}
|
|
1401
1507
|
const doc = new Y2.Doc();
|
|
1402
1508
|
const awareness = new Awareness2(doc);
|
|
1403
|
-
awareness.setLocalState({ uid: o.uid, clientId: o.clientId, name: o.displayName ?? o.uid.slice(0, 8),
|
|
1509
|
+
awareness.setLocalState({ uid: o.uid, clientId: o.clientId, name: o.displayName ?? o.uid.slice(0, 8), ts: Date.now() });
|
|
1510
|
+
const stopColor = claimCollaboratorColor(awareness, { uid: o.uid, clientId: o.clientId });
|
|
1404
1511
|
const carets = new RemoteCaretBook(awareness.clientID);
|
|
1405
1512
|
const emit = () => onAwareness({ states: new Map(awareness.getStates()), selfUid: o.uid, carets: carets.list() });
|
|
1406
1513
|
const publishAwareness = () => {
|
|
@@ -1486,6 +1593,7 @@ function documentOtFactory(o) {
|
|
|
1486
1593
|
replace: (snapshot) => room.replace(snapshot),
|
|
1487
1594
|
stop: () => {
|
|
1488
1595
|
clearInterval(caretTimer);
|
|
1596
|
+
stopColor();
|
|
1489
1597
|
room.stop();
|
|
1490
1598
|
awareness.off("change", publishAwareness);
|
|
1491
1599
|
provider.disconnect();
|
|
@@ -3240,12 +3348,30 @@ function univerSheetsOtPort(o) {
|
|
|
3240
3348
|
}
|
|
3241
3349
|
if (lone && tracker.stack.length === 0) settle();
|
|
3242
3350
|
});
|
|
3351
|
+
const followSelection = (m) => {
|
|
3352
|
+
const sel = o.selections;
|
|
3353
|
+
if (!sel || !axisOpOf(m)) return;
|
|
3354
|
+
try {
|
|
3355
|
+
const sheet = String(m.params.subUnitId ?? "");
|
|
3356
|
+
if (sel.sheetId() !== sheet) return;
|
|
3357
|
+
const ws = o.workbook()?.getSheetBySheetId(sheet);
|
|
3358
|
+
const current = sel.get();
|
|
3359
|
+
if (!ws || !current?.length) return;
|
|
3360
|
+
const rows = ws.getMaxRows?.() ?? Number.MAX_SAFE_INTEGER;
|
|
3361
|
+
const cols = ws.getMaxColumns?.() ?? Number.MAX_SAFE_INTEGER;
|
|
3362
|
+
sel.set(moveSelectionsThrough(json(current), m, rows, cols));
|
|
3363
|
+
} catch (err) {
|
|
3364
|
+
console.warn("[sheets-ot] could not move this seat's selection past a collaborator's row or column change", err);
|
|
3365
|
+
}
|
|
3366
|
+
};
|
|
3243
3367
|
return {
|
|
3244
3368
|
onLocal(listener) {
|
|
3245
3369
|
listeners.add(listener);
|
|
3246
3370
|
return () => void listeners.delete(listener);
|
|
3247
3371
|
},
|
|
3248
3372
|
busy: () => tracker.stack.length > 0 || group !== null,
|
|
3373
|
+
/** The outermost commands still running here (why the port is busy), for logs. */
|
|
3374
|
+
running: () => [...tracker.stack, ...group && tracker.stack.length === 0 ? ["(group)"] : []],
|
|
3249
3375
|
whenIdle(fn) {
|
|
3250
3376
|
if (tracker.stack.length === 0 && !group) fn();
|
|
3251
3377
|
else idle.push(fn);
|
|
@@ -3256,11 +3382,12 @@ function univerSheetsOtPort(o) {
|
|
|
3256
3382
|
const a = forApply(m);
|
|
3257
3383
|
applying = true;
|
|
3258
3384
|
try {
|
|
3259
|
-
const ok2 = cs.syncExecuteCommand(a.id, { ...json(a.params), unitId: u }, {
|
|
3385
|
+
const ok2 = cs.syncExecuteCommand(a.id, { ...json(a.params), unitId: u }, { fromCollab: true });
|
|
3260
3386
|
if (ok2 === false) throw new Error(`"${m.id}" was refused by the editor`);
|
|
3261
3387
|
} finally {
|
|
3262
3388
|
applying = false;
|
|
3263
3389
|
}
|
|
3390
|
+
followSelection(m);
|
|
3264
3391
|
},
|
|
3265
3392
|
snapshot() {
|
|
3266
3393
|
const wb = o.workbook();
|
|
@@ -3298,6 +3425,68 @@ function fullContent(cell) {
|
|
|
3298
3425
|
if (out.v === null) delete out.t;
|
|
3299
3426
|
return out;
|
|
3300
3427
|
}
|
|
3428
|
+
function axisOpOf(m) {
|
|
3429
|
+
const p = m.params;
|
|
3430
|
+
const span = (r, axis) => axis === "row" ? [r.startRow, r.endRow - r.startRow + 1] : [r.startColumn, r.endColumn - r.startColumn + 1];
|
|
3431
|
+
switch (m.id) {
|
|
3432
|
+
case "sheet.mutation.insert-row": {
|
|
3433
|
+
const [at, count] = span(p.range, "row");
|
|
3434
|
+
return { axis: "row", op: { kind: "insert", at, count } };
|
|
3435
|
+
}
|
|
3436
|
+
case "sheet.mutation.insert-col": {
|
|
3437
|
+
const [at, count] = span(p.range, "col");
|
|
3438
|
+
return { axis: "col", op: { kind: "insert", at, count } };
|
|
3439
|
+
}
|
|
3440
|
+
case "sheet.mutation.remove-rows": {
|
|
3441
|
+
const [start, count] = span(p.range, "row");
|
|
3442
|
+
return { axis: "row", op: { kind: "remove", start, count } };
|
|
3443
|
+
}
|
|
3444
|
+
case "sheet.mutation.remove-col": {
|
|
3445
|
+
const [start, count] = span(p.range, "col");
|
|
3446
|
+
return { axis: "col", op: { kind: "remove", start, count } };
|
|
3447
|
+
}
|
|
3448
|
+
case "sheet.mutation.move-rows": {
|
|
3449
|
+
const [from, count] = span(p.sourceRange, "row");
|
|
3450
|
+
return { axis: "row", op: { kind: "move", from, count, to: p.targetRange.startRow } };
|
|
3451
|
+
}
|
|
3452
|
+
case "sheet.mutation.move-columns": {
|
|
3453
|
+
const [from, count] = span(p.sourceRange, "col");
|
|
3454
|
+
return { axis: "col", op: { kind: "move", from, count, to: p.targetRange.startColumn } };
|
|
3455
|
+
}
|
|
3456
|
+
default:
|
|
3457
|
+
return null;
|
|
3458
|
+
}
|
|
3459
|
+
}
|
|
3460
|
+
function moveSelectionsThrough(selections, m, maxRows, maxCols) {
|
|
3461
|
+
const a = axisOpOf(m);
|
|
3462
|
+
const clamp = (v, max) => Math.max(0, Math.min(v, Math.max(0, max - 1)));
|
|
3463
|
+
const through = (i, axis) => {
|
|
3464
|
+
if (typeof i !== "number") return i;
|
|
3465
|
+
let next = i;
|
|
3466
|
+
if (a && a.axis === axis) {
|
|
3467
|
+
const mapped = mapIndex(a.op, i);
|
|
3468
|
+
next = mapped ?? (a.op.kind === "remove" ? a.op.start : i);
|
|
3469
|
+
}
|
|
3470
|
+
return clamp(next, axis === "row" ? maxRows : maxCols);
|
|
3471
|
+
};
|
|
3472
|
+
const box = (r, rangeType) => {
|
|
3473
|
+
const out = { ...r };
|
|
3474
|
+
for (const k of ["startRow", "endRow", "actualRow"]) if (k in out) out[k] = through(out[k], "row");
|
|
3475
|
+
for (const k of ["startColumn", "endColumn", "actualColumn"]) if (k in out) out[k] = through(out[k], "col");
|
|
3476
|
+
if (typeof out.startRow === "number" && typeof out.endRow === "number" && out.endRow < out.startRow) out.endRow = out.startRow;
|
|
3477
|
+
if (typeof out.startColumn === "number" && typeof out.endColumn === "number" && out.endColumn < out.startColumn) out.endColumn = out.startColumn;
|
|
3478
|
+
if (rangeType === 1 || rangeType === 3) {
|
|
3479
|
+
out.startColumn = 0;
|
|
3480
|
+
out.endColumn = Math.max(0, maxCols - 1);
|
|
3481
|
+
}
|
|
3482
|
+
if (rangeType === 2 || rangeType === 3) {
|
|
3483
|
+
out.startRow = 0;
|
|
3484
|
+
out.endRow = Math.max(0, maxRows - 1);
|
|
3485
|
+
}
|
|
3486
|
+
return out;
|
|
3487
|
+
};
|
|
3488
|
+
return selections.map((s) => ({ ...s, range: box(s.range, s.range.rangeType), ...s.primary ? { primary: box(s.primary) } : {} }));
|
|
3489
|
+
}
|
|
3301
3490
|
|
|
3302
3491
|
// src/sheets/workbook-ot-room.ts
|
|
3303
3492
|
import * as Y3 from "yjs";
|
|
@@ -3373,7 +3562,7 @@ async function workbookUsesOrderedRoom(workbookId, knob, isNewWorkbook) {
|
|
|
3373
3562
|
if (knob === "new") return isNewWorkbook();
|
|
3374
3563
|
return false;
|
|
3375
3564
|
}
|
|
3376
|
-
function
|
|
3565
|
+
function pickColor2(uid) {
|
|
3377
3566
|
const palette = ["#ef4444", "#f59e0b", "#10b981", "#3b82f6", "#8b5cf6", "#ec4899", "#14b8a6", "#f97316"];
|
|
3378
3567
|
let h = 2166136261;
|
|
3379
3568
|
for (let i = 0; i < uid.length; i++) {
|
|
@@ -3398,7 +3587,7 @@ async function startWorkbookOtRoom(port, o) {
|
|
|
3398
3587
|
uid: o.uid,
|
|
3399
3588
|
clientId: o.clientId,
|
|
3400
3589
|
name: o.displayName ?? o.uid.slice(0, 8),
|
|
3401
|
-
color:
|
|
3590
|
+
color: pickColor2(o.uid),
|
|
3402
3591
|
sheetId: null,
|
|
3403
3592
|
row: null,
|
|
3404
3593
|
col: null,
|
|
@@ -3469,6 +3658,7 @@ export {
|
|
|
3469
3658
|
SHEETS_EDIT_GROUP,
|
|
3470
3659
|
WorkbookCollabSession,
|
|
3471
3660
|
applyDocsOp,
|
|
3661
|
+
asLoadedDocsSnapshot,
|
|
3472
3662
|
canonicalDocsSnapshot,
|
|
3473
3663
|
canonicalDocsString,
|
|
3474
3664
|
canonicalKeys,
|
|
@@ -3485,6 +3675,7 @@ export {
|
|
|
3485
3675
|
invertDocsOp,
|
|
3486
3676
|
isCellEditorScratch,
|
|
3487
3677
|
isNoopDocsOp,
|
|
3678
|
+
moveSelectionsThrough,
|
|
3488
3679
|
normalizeDocsOp,
|
|
3489
3680
|
openDocsOtRoom,
|
|
3490
3681
|
openSheetsOtRoom,
|