@ai-matrx/office 0.8.23 → 0.8.25
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 +1 -15
- package/dist/univer-collab.cjs +188 -10
- package/dist/univer-collab.cjs.map +1 -1
- package/dist/univer-collab.d.cts +31 -2
- package/dist/univer-collab.d.ts +31 -2
- package/dist/univer-collab.js +190 -10
- package/dist/univer-collab.js.map +1 -1
- package/package.json +10 -2
package/dist/univer-collab.d.cts
CHANGED
|
@@ -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, OpDocumentAdapter } from '@ai-matrx/data/realtime/collab';
|
|
3
|
+
import { OpSessionNotice, OpSession, OpTransport, OpPresence, OpSessionIncident, OpSessionStatus, OpOfflineOptions, OpOfflineState, AwarenessState, CollabRpcClient, collabReplace, OpDocumentAdapter, CollabGroup } 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
|
|
|
@@ -362,6 +362,10 @@ interface OpenDocsOtRoomOptions {
|
|
|
362
362
|
onNotice?: (n: DocsOtNotice) => void;
|
|
363
363
|
onIncident?: (i: OpSessionIncident) => void;
|
|
364
364
|
onStatus?: (s: OpSessionStatus) => void;
|
|
365
|
+
/** C10: unsent edits persist on this device under a lease (the host builds it: `browserOfflineOptions`). */
|
|
366
|
+
offline?: OpOfflineOptions | null;
|
|
367
|
+
/** C10: the chrome's offline state. */
|
|
368
|
+
onOffline?: (s: OpOfflineState) => void;
|
|
365
369
|
/** Watch IME composition here (default: `document`). */
|
|
366
370
|
compositionTarget?: Pick<Document, "addEventListener" | "removeEventListener"> | null;
|
|
367
371
|
}
|
|
@@ -481,6 +485,8 @@ interface DocumentOtFactoryOptions {
|
|
|
481
485
|
onNotice?: (n: DocsOtNotice) => void;
|
|
482
486
|
onIncident?: (i: OpSessionIncident) => void;
|
|
483
487
|
onStatus?: (s: OpSessionStatus) => void;
|
|
488
|
+
/** C10: the chrome's offline state (unsent edits are kept on this device, one tab per document and person owns them). */
|
|
489
|
+
onOffline?: (s: OpOfflineState) => void;
|
|
484
490
|
}
|
|
485
491
|
/** The `DocumentModel.startOtRoom` factory for one document. */
|
|
486
492
|
declare function documentOtFactory(o: DocumentOtFactoryOptions): DocumentOtFactory;
|
|
@@ -599,6 +605,12 @@ interface SheetsOtPort {
|
|
|
599
605
|
service: unknown;
|
|
600
606
|
unitId: string;
|
|
601
607
|
}>;
|
|
608
|
+
/**
|
|
609
|
+
* Run `fn` right before this seat takes an undo or redo (synchronously, before the command reads its stack). With
|
|
610
|
+
* it the room rebases the undo stack lazily: a remote op only queues, and an undo catches its stack up first.
|
|
611
|
+
* Without it every remote op rebases the whole stack at once.
|
|
612
|
+
*/
|
|
613
|
+
beforeUndo?(fn: () => void): () => void;
|
|
602
614
|
/** Ask for a save (the record's one coalesced save). */
|
|
603
615
|
markDirty(): void;
|
|
604
616
|
}
|
|
@@ -651,6 +663,8 @@ declare function rebaseSheetUndoStack(items: UndoItem[], remote: SheetOp, unitId
|
|
|
651
663
|
interface SheetsOtAdapterHooks {
|
|
652
664
|
/** Called once per applied remote op that rebased this seat's undo stacks (for tests and logs). */
|
|
653
665
|
onUndoRebased?: (dropped: number) => void;
|
|
666
|
+
/** Called with the milliseconds of undo bookkeeping each remote op (and each catch-up) cost (tests, logs). */
|
|
667
|
+
onUndoWork?: (ms: number, kind: "remote" | "catch_up") => void;
|
|
654
668
|
/**
|
|
655
669
|
* The state hash of a snapshot (default `sheetsStateHash`, Web Crypto). A seeded test passes a synchronous one:
|
|
656
670
|
* Web Crypto resolves on a worker thread, outside a virtual clock, so the same seed would not replay.
|
|
@@ -683,6 +697,10 @@ interface OpenSheetsOtRoomOptions {
|
|
|
683
697
|
onNotice?: (n: SheetsOtNotice) => void;
|
|
684
698
|
onIncident?: (i: OpSessionIncident) => void;
|
|
685
699
|
onStatus?: (s: OpSessionStatus) => void;
|
|
700
|
+
/** C10: unsent edits persist on this device under a lease (the host builds it: `browserOfflineOptions`). */
|
|
701
|
+
offline?: OpOfflineOptions | null;
|
|
702
|
+
/** C10: the chrome's offline state. */
|
|
703
|
+
onOffline?: (s: OpOfflineState) => void;
|
|
686
704
|
}
|
|
687
705
|
interface SheetsOtRoom {
|
|
688
706
|
session: OpSession<SheetOp>;
|
|
@@ -821,6 +839,15 @@ declare const canonicalSheetString: (snapshot: unknown) => string;
|
|
|
821
839
|
/** SHA-256 (hex) of the canonical form. Web Crypto, so the browser and Node compute the same hash. */
|
|
822
840
|
declare function sheetsStateHash(snapshot: unknown): Promise<string>;
|
|
823
841
|
|
|
842
|
+
/**
|
|
843
|
+
* "Copy my offline text" (C10): the words a person typed while offline, pulled out of the wire groups of a buffer
|
|
844
|
+
* the room refused (changed protocol, document trashed). Format-light on purpose: Docs inserts carry their text in
|
|
845
|
+
* `body.dataStream`; Sheets writes carry cell values in `cellValue`. Anything else contributes nothing, and the
|
|
846
|
+
* caller says so when nothing could be read (the record stays on the device regardless).
|
|
847
|
+
*/
|
|
848
|
+
|
|
849
|
+
declare function offlineTextOfGroups(buffers: CollabGroup[][]): string;
|
|
850
|
+
|
|
824
851
|
/** `collab.ot_rooms` (§12.2): which workbooks without a room open one. */
|
|
825
852
|
type WorkbookOtRoomsKnob = "off" | "new" | "all";
|
|
826
853
|
/** Whether this workbook opens on the ordered log: its room exists, or the knob opens one. */
|
|
@@ -836,6 +863,8 @@ interface WorkbookOtRoomOptions {
|
|
|
836
863
|
onNotice?: (n: SheetsOtNotice) => void;
|
|
837
864
|
onIncident?: (i: OpSessionIncident) => void;
|
|
838
865
|
onStatus?: (s: OpSessionStatus) => void;
|
|
866
|
+
/** C10: the chrome's offline state (unsent edits are kept on this device, one tab per workbook and person owns them). */
|
|
867
|
+
onOffline?: (s: OpOfflineState) => void;
|
|
839
868
|
}
|
|
840
869
|
interface WorkbookOtRoomHandle {
|
|
841
870
|
session: OpSession<SheetOp>;
|
|
@@ -857,4 +886,4 @@ declare function startWorkbookOtRoom(port: SheetsOtPort & {
|
|
|
857
886
|
dispose?: () => void;
|
|
858
887
|
}, o: WorkbookOtRoomOptions): Promise<WorkbookOtRoomHandle>;
|
|
859
888
|
|
|
860
|
-
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 };
|
|
889
|
+
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, offlineTextOfGroups, openDocsOtRoom, openSheetsOtRoom, rebaseSheetUndoStack, rebaseUndoStack, restoreDocumentSnapshot, sheetsStateHash, stampCovered, stampDeterministicIds, startWorkbookOtRoom, stripSenderView, takeCovered, transformDocsOp, transformSheetOp, transformTextX, undoStacksOf, univerSheetsOtPort, workbookUsesOrderedRoom };
|
package/dist/univer-collab.d.ts
CHANGED
|
@@ -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, OpDocumentAdapter } from '@ai-matrx/data/realtime/collab';
|
|
3
|
+
import { OpSessionNotice, OpSession, OpTransport, OpPresence, OpSessionIncident, OpSessionStatus, OpOfflineOptions, OpOfflineState, AwarenessState, CollabRpcClient, collabReplace, OpDocumentAdapter, CollabGroup } 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
|
|
|
@@ -362,6 +362,10 @@ interface OpenDocsOtRoomOptions {
|
|
|
362
362
|
onNotice?: (n: DocsOtNotice) => void;
|
|
363
363
|
onIncident?: (i: OpSessionIncident) => void;
|
|
364
364
|
onStatus?: (s: OpSessionStatus) => void;
|
|
365
|
+
/** C10: unsent edits persist on this device under a lease (the host builds it: `browserOfflineOptions`). */
|
|
366
|
+
offline?: OpOfflineOptions | null;
|
|
367
|
+
/** C10: the chrome's offline state. */
|
|
368
|
+
onOffline?: (s: OpOfflineState) => void;
|
|
365
369
|
/** Watch IME composition here (default: `document`). */
|
|
366
370
|
compositionTarget?: Pick<Document, "addEventListener" | "removeEventListener"> | null;
|
|
367
371
|
}
|
|
@@ -481,6 +485,8 @@ interface DocumentOtFactoryOptions {
|
|
|
481
485
|
onNotice?: (n: DocsOtNotice) => void;
|
|
482
486
|
onIncident?: (i: OpSessionIncident) => void;
|
|
483
487
|
onStatus?: (s: OpSessionStatus) => void;
|
|
488
|
+
/** C10: the chrome's offline state (unsent edits are kept on this device, one tab per document and person owns them). */
|
|
489
|
+
onOffline?: (s: OpOfflineState) => void;
|
|
484
490
|
}
|
|
485
491
|
/** The `DocumentModel.startOtRoom` factory for one document. */
|
|
486
492
|
declare function documentOtFactory(o: DocumentOtFactoryOptions): DocumentOtFactory;
|
|
@@ -599,6 +605,12 @@ interface SheetsOtPort {
|
|
|
599
605
|
service: unknown;
|
|
600
606
|
unitId: string;
|
|
601
607
|
}>;
|
|
608
|
+
/**
|
|
609
|
+
* Run `fn` right before this seat takes an undo or redo (synchronously, before the command reads its stack). With
|
|
610
|
+
* it the room rebases the undo stack lazily: a remote op only queues, and an undo catches its stack up first.
|
|
611
|
+
* Without it every remote op rebases the whole stack at once.
|
|
612
|
+
*/
|
|
613
|
+
beforeUndo?(fn: () => void): () => void;
|
|
602
614
|
/** Ask for a save (the record's one coalesced save). */
|
|
603
615
|
markDirty(): void;
|
|
604
616
|
}
|
|
@@ -651,6 +663,8 @@ declare function rebaseSheetUndoStack(items: UndoItem[], remote: SheetOp, unitId
|
|
|
651
663
|
interface SheetsOtAdapterHooks {
|
|
652
664
|
/** Called once per applied remote op that rebased this seat's undo stacks (for tests and logs). */
|
|
653
665
|
onUndoRebased?: (dropped: number) => void;
|
|
666
|
+
/** Called with the milliseconds of undo bookkeeping each remote op (and each catch-up) cost (tests, logs). */
|
|
667
|
+
onUndoWork?: (ms: number, kind: "remote" | "catch_up") => void;
|
|
654
668
|
/**
|
|
655
669
|
* The state hash of a snapshot (default `sheetsStateHash`, Web Crypto). A seeded test passes a synchronous one:
|
|
656
670
|
* Web Crypto resolves on a worker thread, outside a virtual clock, so the same seed would not replay.
|
|
@@ -683,6 +697,10 @@ interface OpenSheetsOtRoomOptions {
|
|
|
683
697
|
onNotice?: (n: SheetsOtNotice) => void;
|
|
684
698
|
onIncident?: (i: OpSessionIncident) => void;
|
|
685
699
|
onStatus?: (s: OpSessionStatus) => void;
|
|
700
|
+
/** C10: unsent edits persist on this device under a lease (the host builds it: `browserOfflineOptions`). */
|
|
701
|
+
offline?: OpOfflineOptions | null;
|
|
702
|
+
/** C10: the chrome's offline state. */
|
|
703
|
+
onOffline?: (s: OpOfflineState) => void;
|
|
686
704
|
}
|
|
687
705
|
interface SheetsOtRoom {
|
|
688
706
|
session: OpSession<SheetOp>;
|
|
@@ -821,6 +839,15 @@ declare const canonicalSheetString: (snapshot: unknown) => string;
|
|
|
821
839
|
/** SHA-256 (hex) of the canonical form. Web Crypto, so the browser and Node compute the same hash. */
|
|
822
840
|
declare function sheetsStateHash(snapshot: unknown): Promise<string>;
|
|
823
841
|
|
|
842
|
+
/**
|
|
843
|
+
* "Copy my offline text" (C10): the words a person typed while offline, pulled out of the wire groups of a buffer
|
|
844
|
+
* the room refused (changed protocol, document trashed). Format-light on purpose: Docs inserts carry their text in
|
|
845
|
+
* `body.dataStream`; Sheets writes carry cell values in `cellValue`. Anything else contributes nothing, and the
|
|
846
|
+
* caller says so when nothing could be read (the record stays on the device regardless).
|
|
847
|
+
*/
|
|
848
|
+
|
|
849
|
+
declare function offlineTextOfGroups(buffers: CollabGroup[][]): string;
|
|
850
|
+
|
|
824
851
|
/** `collab.ot_rooms` (§12.2): which workbooks without a room open one. */
|
|
825
852
|
type WorkbookOtRoomsKnob = "off" | "new" | "all";
|
|
826
853
|
/** Whether this workbook opens on the ordered log: its room exists, or the knob opens one. */
|
|
@@ -836,6 +863,8 @@ interface WorkbookOtRoomOptions {
|
|
|
836
863
|
onNotice?: (n: SheetsOtNotice) => void;
|
|
837
864
|
onIncident?: (i: OpSessionIncident) => void;
|
|
838
865
|
onStatus?: (s: OpSessionStatus) => void;
|
|
866
|
+
/** C10: the chrome's offline state (unsent edits are kept on this device, one tab per workbook and person owns them). */
|
|
867
|
+
onOffline?: (s: OpOfflineState) => void;
|
|
839
868
|
}
|
|
840
869
|
interface WorkbookOtRoomHandle {
|
|
841
870
|
session: OpSession<SheetOp>;
|
|
@@ -857,4 +886,4 @@ declare function startWorkbookOtRoom(port: SheetsOtPort & {
|
|
|
857
886
|
dispose?: () => void;
|
|
858
887
|
}, o: WorkbookOtRoomOptions): Promise<WorkbookOtRoomHandle>;
|
|
859
888
|
|
|
860
|
-
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 };
|
|
889
|
+
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, offlineTextOfGroups, openDocsOtRoom, openSheetsOtRoom, rebaseSheetUndoStack, rebaseUndoStack, restoreDocumentSnapshot, sheetsStateHash, stampCovered, stampDeterministicIds, startWorkbookOtRoom, stripSenderView, takeCovered, transformDocsOp, transformSheetOp, transformTextX, undoStacksOf, univerSheetsOtPort, workbookUsesOrderedRoom };
|
package/dist/univer-collab.js
CHANGED
|
@@ -1290,7 +1290,9 @@ function openDocsOtRoom(o) {
|
|
|
1290
1290
|
...o.presence ? { presence: o.presence } : {},
|
|
1291
1291
|
onNotice: (n) => notice(n),
|
|
1292
1292
|
...o.onIncident ? { onIncident: o.onIncident } : {},
|
|
1293
|
-
...o.onStatus ? { onStatus: o.onStatus } : {}
|
|
1293
|
+
...o.onStatus ? { onStatus: o.onStatus } : {},
|
|
1294
|
+
...o.offline ? { offline: o.offline } : {},
|
|
1295
|
+
...o.onOffline ? { onOffline: o.onOffline } : {}
|
|
1294
1296
|
});
|
|
1295
1297
|
const isSaver = () => {
|
|
1296
1298
|
if (!o.presence) return true;
|
|
@@ -1328,6 +1330,7 @@ import * as Y2 from "yjs";
|
|
|
1328
1330
|
import { Awareness as Awareness2 } from "y-protocols/awareness";
|
|
1329
1331
|
import {
|
|
1330
1332
|
awarenessOpPresence,
|
|
1333
|
+
browserOfflineOptions,
|
|
1331
1334
|
claimCollaboratorColor as claimCollaboratorColor2,
|
|
1332
1335
|
collabReplace,
|
|
1333
1336
|
collabRoomExists,
|
|
@@ -1565,7 +1568,9 @@ function documentOtFactory(o) {
|
|
|
1565
1568
|
replace: ({ snapshot, stateHash, clientId }) => collabReplace(client, { roomId: o.documentId, snapshot, stateHash, origin: "restore", clientId }),
|
|
1566
1569
|
...o.onNotice ? { onNotice: o.onNotice } : {},
|
|
1567
1570
|
...o.onIncident ? { onIncident: o.onIncident } : {},
|
|
1568
|
-
...o.onStatus ? { onStatus: o.onStatus } : {}
|
|
1571
|
+
...o.onStatus ? { onStatus: o.onStatus } : {},
|
|
1572
|
+
offline: browserOfflineOptions(`${o.documentId}:${o.uid}`),
|
|
1573
|
+
...o.onOffline ? { onOffline: o.onOffline } : {}
|
|
1569
1574
|
});
|
|
1570
1575
|
await room.session.ready;
|
|
1571
1576
|
let lastKey = "";
|
|
@@ -3495,17 +3500,65 @@ function rebaseSheetUndoStack(items, remote, unitId) {
|
|
|
3495
3500
|
function createSheetsOtAdapter(port, hooks = {}) {
|
|
3496
3501
|
let queue = [];
|
|
3497
3502
|
let draining = false;
|
|
3503
|
+
const lazy = typeof port.beforeUndo === "function";
|
|
3504
|
+
let pending = [];
|
|
3505
|
+
let pendingBase = 0;
|
|
3506
|
+
let applied = 0;
|
|
3507
|
+
let currentAt = /* @__PURE__ */ new WeakMap();
|
|
3508
|
+
const PENDING_CAP = 2e3;
|
|
3509
|
+
const now = () => typeof performance !== "undefined" ? performance.now() : Date.now();
|
|
3510
|
+
const stacksOfTargets = () => port.undoTargets().flatMap((t) => {
|
|
3511
|
+
const stacks = undoStacksOf2(t.service);
|
|
3512
|
+
return stacks ? [stacks.undo, stacks.redo].map((map) => ({ items: map.get(t.unitId), unitId: t.unitId, isUndo: map === stacks.undo })) : [];
|
|
3513
|
+
});
|
|
3514
|
+
const markNew = (items) => {
|
|
3515
|
+
for (let i = items.length - 1; i >= 0 && !currentAt.has(items[i]); i--) currentAt.set(items[i], applied);
|
|
3516
|
+
};
|
|
3517
|
+
const catchUpItem = (item, unitId) => {
|
|
3518
|
+
const from = currentAt.get(item) ?? applied;
|
|
3519
|
+
for (let k = from - pendingBase; k < pending.length; k++) if (rebaseSheetUndoStack([item], pending[k], unitId) > 0) return false;
|
|
3520
|
+
currentAt.set(item, applied);
|
|
3521
|
+
return true;
|
|
3522
|
+
};
|
|
3523
|
+
const catchUp = () => {
|
|
3524
|
+
if (!pending.length) return;
|
|
3525
|
+
const t0 = now();
|
|
3526
|
+
let dropped = 0;
|
|
3527
|
+
for (const { items, unitId } of stacksOfTargets()) {
|
|
3528
|
+
if (!items?.length) continue;
|
|
3529
|
+
for (let i = items.length - 1; i >= 0; i--)
|
|
3530
|
+
if (!catchUpItem(items[i], unitId)) {
|
|
3531
|
+
items.splice(i, 1);
|
|
3532
|
+
dropped++;
|
|
3533
|
+
}
|
|
3534
|
+
}
|
|
3535
|
+
pending = [];
|
|
3536
|
+
pendingBase = applied;
|
|
3537
|
+
hooks.onUndoWork?.(now() - t0, "catch_up");
|
|
3538
|
+
if (dropped) hooks.onUndoRebased?.(dropped);
|
|
3539
|
+
};
|
|
3540
|
+
if (lazy) port.beforeUndo(catchUp);
|
|
3498
3541
|
const applyNow = (op) => {
|
|
3499
3542
|
for (const m of op) port.applyRemote(m);
|
|
3543
|
+
const t0 = now();
|
|
3500
3544
|
let dropped = 0;
|
|
3501
|
-
|
|
3502
|
-
const
|
|
3503
|
-
|
|
3504
|
-
for (const
|
|
3505
|
-
|
|
3506
|
-
|
|
3545
|
+
if (!lazy) {
|
|
3546
|
+
for (const { items, unitId } of stacksOfTargets()) if (items?.length) dropped += rebaseSheetUndoStack(items, op, unitId);
|
|
3547
|
+
} else if (!isNoopSheetOp(op)) {
|
|
3548
|
+
for (const { items, unitId, isUndo } of stacksOfTargets()) {
|
|
3549
|
+
if (!items?.length) continue;
|
|
3550
|
+
markNew(items);
|
|
3551
|
+
const top = items[items.length - 1];
|
|
3552
|
+
if (isUndo && (!catchUpItem(top, unitId) || rebaseSheetUndoStack([top], op, unitId) > 0)) {
|
|
3553
|
+
items.pop();
|
|
3554
|
+
dropped++;
|
|
3555
|
+
} else if (isUndo) currentAt.set(top, applied + 1);
|
|
3507
3556
|
}
|
|
3557
|
+
pending.push(op);
|
|
3558
|
+
applied++;
|
|
3559
|
+
if (pending.length > PENDING_CAP) catchUp();
|
|
3508
3560
|
}
|
|
3561
|
+
hooks.onUndoWork?.(now() - t0, "remote");
|
|
3509
3562
|
hooks.onUndoRebased?.(dropped);
|
|
3510
3563
|
port.markDirty();
|
|
3511
3564
|
};
|
|
@@ -3543,6 +3596,9 @@ function createSheetsOtAdapter(port, hooks = {}) {
|
|
|
3543
3596
|
stacks?.undo.delete(t.unitId);
|
|
3544
3597
|
stacks?.redo.delete(t.unitId);
|
|
3545
3598
|
}
|
|
3599
|
+
pending = [];
|
|
3600
|
+
pendingBase = applied;
|
|
3601
|
+
currentAt = /* @__PURE__ */ new WeakMap();
|
|
3546
3602
|
},
|
|
3547
3603
|
snapshot: () => port.snapshot(),
|
|
3548
3604
|
async hash() {
|
|
@@ -3629,7 +3685,9 @@ function openSheetsOtRoom(o) {
|
|
|
3629
3685
|
...o.presence ? { presence: o.presence } : {},
|
|
3630
3686
|
onNotice: (n) => notice(n),
|
|
3631
3687
|
...o.onIncident ? { onIncident: o.onIncident } : {},
|
|
3632
|
-
...o.onStatus ? { onStatus: o.onStatus } : {}
|
|
3688
|
+
...o.onStatus ? { onStatus: o.onStatus } : {},
|
|
3689
|
+
...o.offline ? { offline: o.offline } : {},
|
|
3690
|
+
...o.onOffline ? { onOffline: o.onOffline } : {}
|
|
3633
3691
|
});
|
|
3634
3692
|
const isSaver = () => {
|
|
3635
3693
|
if (!o.presence) return true;
|
|
@@ -3660,6 +3718,65 @@ function openSheetsOtRoom(o) {
|
|
|
3660
3718
|
};
|
|
3661
3719
|
}
|
|
3662
3720
|
|
|
3721
|
+
// src/univer/collab/sheets-ot/plugin-teardown.ts
|
|
3722
|
+
var perSheetList = (data) => Object.entries(data).flatMap(([sheet, list]) => Array.isArray(list) ? [[sheet, list.filter((x) => !!x && typeof x === "object")]] : []);
|
|
3723
|
+
var PLUGIN_TEARDOWNS = [
|
|
3724
|
+
{
|
|
3725
|
+
resource: "SHEET_CONDITIONAL_FORMATTING_PLUGIN",
|
|
3726
|
+
removals: (unitId, data) => perSheetList(data).flatMap(
|
|
3727
|
+
([subUnitId, rules]) => rules.filter((r) => typeof r.cfId === "string").map((r) => ({ id: "sheet.mutation.delete-conditional-rule", params: { unitId, subUnitId, cfId: r.cfId } }))
|
|
3728
|
+
)
|
|
3729
|
+
},
|
|
3730
|
+
{
|
|
3731
|
+
resource: "SHEET_DATA_VALIDATION_PLUGIN",
|
|
3732
|
+
removals: (unitId, data) => perSheetList(data).flatMap(([subUnitId, rules]) => {
|
|
3733
|
+
const ids = rules.map((r) => r.uid).filter((u) => typeof u === "string");
|
|
3734
|
+
return ids.length ? [{ id: "data-validation.mutation.removeRule", params: { unitId, subUnitId, ruleId: ids, source: "command" } }] : [];
|
|
3735
|
+
})
|
|
3736
|
+
},
|
|
3737
|
+
{
|
|
3738
|
+
resource: "SHEET_NOTE_PLUGIN",
|
|
3739
|
+
removals: (unitId, data) => Object.entries(data).flatMap(
|
|
3740
|
+
([sheetId, rows]) => Object.entries(rows ?? {}).flatMap(
|
|
3741
|
+
([row, cols]) => Object.entries(cols ?? {}).map(([col, note]) => ({
|
|
3742
|
+
id: "sheet.mutation.remove-note",
|
|
3743
|
+
params: { unitId, sheetId, row: Number(row), col: Number(col), ...note && typeof note.id === "string" ? { noteId: note.id } : {}, silent: true }
|
|
3744
|
+
}))
|
|
3745
|
+
)
|
|
3746
|
+
)
|
|
3747
|
+
}
|
|
3748
|
+
];
|
|
3749
|
+
function resourcesOf(saved) {
|
|
3750
|
+
const out = /* @__PURE__ */ new Map();
|
|
3751
|
+
const list = saved?.resources;
|
|
3752
|
+
for (const r of Array.isArray(list) ? list : []) {
|
|
3753
|
+
if (!r?.name) continue;
|
|
3754
|
+
try {
|
|
3755
|
+
const data = typeof r.data === "string" ? r.data ? JSON.parse(r.data) : null : r.data;
|
|
3756
|
+
if (data && typeof data === "object") out.set(r.name, data);
|
|
3757
|
+
} catch {
|
|
3758
|
+
}
|
|
3759
|
+
}
|
|
3760
|
+
return out;
|
|
3761
|
+
}
|
|
3762
|
+
function releaseUnitPluginState(cs, unitId, saved) {
|
|
3763
|
+
const resources = resourcesOf(saved);
|
|
3764
|
+
let ran = 0;
|
|
3765
|
+
for (const t of PLUGIN_TEARDOWNS) {
|
|
3766
|
+
const data = resources.get(t.resource);
|
|
3767
|
+
if (!data) continue;
|
|
3768
|
+
for (const m of t.removals(unitId, data)) {
|
|
3769
|
+
try {
|
|
3770
|
+
cs.syncExecuteCommand(m.id, m.params, { onlyLocal: true });
|
|
3771
|
+
ran++;
|
|
3772
|
+
} catch (err) {
|
|
3773
|
+
console.warn(`[sheets-ot] could not release ${t.resource} state before a reload`, err);
|
|
3774
|
+
}
|
|
3775
|
+
}
|
|
3776
|
+
}
|
|
3777
|
+
return ran;
|
|
3778
|
+
}
|
|
3779
|
+
|
|
3663
3780
|
// src/univer/collab/sheets-ot/univer-port.ts
|
|
3664
3781
|
var COMMAND = 0;
|
|
3665
3782
|
var MUTATION = 2;
|
|
@@ -3669,6 +3786,8 @@ var REMOVE_MERGE = "sheet.mutation.remove-worksheet-merge";
|
|
|
3669
3786
|
var SHEET_NAME = "sheet.mutation.set-worksheet-name";
|
|
3670
3787
|
var INSERT_SHEET = "sheet.mutation.insert-sheet";
|
|
3671
3788
|
var RESHAPE = /* @__PURE__ */ new Set(["sheet.mutation.set-worksheet-row-count", "sheet.mutation.set-worksheet-column-count", "sheet.mutation.remove-sheet", INSERT_SHEET]);
|
|
3789
|
+
var UNDO = "univer.command.undo";
|
|
3790
|
+
var REDO = "univer.command.redo";
|
|
3672
3791
|
var DEPTH_GUARD = /* @__PURE__ */ Symbol.for("ai-matrx.office.sheets.command-depth-guard");
|
|
3673
3792
|
var json = (v) => v === void 0 ? v : JSON.parse(JSON.stringify(v));
|
|
3674
3793
|
var flagged = (options) => {
|
|
@@ -3678,6 +3797,7 @@ var flagged = (options) => {
|
|
|
3678
3797
|
function univerSheetsOtPort(o) {
|
|
3679
3798
|
const cs = o.commandService;
|
|
3680
3799
|
const listeners = /* @__PURE__ */ new Set();
|
|
3800
|
+
const undoWatchers = /* @__PURE__ */ new Set();
|
|
3681
3801
|
const idle = [];
|
|
3682
3802
|
const pre = /* @__PURE__ */ new WeakMap();
|
|
3683
3803
|
const tracker = { stack: [], settle: () => settle() };
|
|
@@ -3734,6 +3854,7 @@ function univerSheetsOtPort(o) {
|
|
|
3734
3854
|
if (tracker.stack.length === 0 && !group) for (const fn of idle.splice(0)) fn();
|
|
3735
3855
|
}
|
|
3736
3856
|
const before = cs.beforeCommandExecuted((info, options) => {
|
|
3857
|
+
if (info.id === UNDO || info.id === REDO) for (const fn of [...undoWatchers]) fn();
|
|
3737
3858
|
if (info.type === COMMAND) {
|
|
3738
3859
|
if (tracker.stack.length === 0 && !group) group = openGroup(info.id);
|
|
3739
3860
|
tracker.stack.push(info.id);
|
|
@@ -3979,6 +4100,8 @@ function univerSheetsOtPort(o) {
|
|
|
3979
4100
|
group = null;
|
|
3980
4101
|
applying = true;
|
|
3981
4102
|
try {
|
|
4103
|
+
const u = unitId();
|
|
4104
|
+
if (u) releaseUnitPluginState(cs, u, o.saveUnit?.(u) ?? null);
|
|
3982
4105
|
o.load(snapshot);
|
|
3983
4106
|
} finally {
|
|
3984
4107
|
applying = false;
|
|
@@ -3989,8 +4112,13 @@ function univerSheetsOtPort(o) {
|
|
|
3989
4112
|
const service = o.undoRedo?.();
|
|
3990
4113
|
return u && service ? [{ service, unitId: u }] : [];
|
|
3991
4114
|
},
|
|
4115
|
+
beforeUndo(fn) {
|
|
4116
|
+
undoWatchers.add(fn);
|
|
4117
|
+
return () => void undoWatchers.delete(fn);
|
|
4118
|
+
},
|
|
3992
4119
|
markDirty: () => o.markDirty(),
|
|
3993
4120
|
dispose() {
|
|
4121
|
+
undoWatchers.clear();
|
|
3994
4122
|
before.dispose();
|
|
3995
4123
|
after.dispose();
|
|
3996
4124
|
collab.dispose();
|
|
@@ -4068,11 +4196,59 @@ function moveSelectionsThrough(selections, m, maxRows, maxCols) {
|
|
|
4068
4196
|
return selections.map((s) => ({ ...s, range: box(s.range, s.range.rangeType), ...s.primary ? { primary: box(s.primary) } : {} }));
|
|
4069
4197
|
}
|
|
4070
4198
|
|
|
4199
|
+
// src/univer/collab/offline-text.ts
|
|
4200
|
+
var colName3 = (c) => {
|
|
4201
|
+
let n = c;
|
|
4202
|
+
let s = "";
|
|
4203
|
+
do {
|
|
4204
|
+
s = String.fromCharCode(65 + n % 26) + s;
|
|
4205
|
+
n = Math.floor(n / 26) - 1;
|
|
4206
|
+
} while (n >= 0);
|
|
4207
|
+
return s;
|
|
4208
|
+
};
|
|
4209
|
+
function collectDocText(v, out) {
|
|
4210
|
+
if (Array.isArray(v)) {
|
|
4211
|
+
for (const x of v) collectDocText(x, out);
|
|
4212
|
+
return;
|
|
4213
|
+
}
|
|
4214
|
+
if (!v || typeof v !== "object") return;
|
|
4215
|
+
const o = v;
|
|
4216
|
+
if (typeof o.dataStream === "string" && o.dataStream.length) out.push(o.dataStream);
|
|
4217
|
+
for (const k of Object.keys(o)) if (k !== "dataStream") collectDocText(o[k], out);
|
|
4218
|
+
}
|
|
4219
|
+
function collectCells(cellValue, out) {
|
|
4220
|
+
if (!cellValue || typeof cellValue !== "object") return;
|
|
4221
|
+
for (const [r, cols] of Object.entries(cellValue)) {
|
|
4222
|
+
if (!cols || typeof cols !== "object") continue;
|
|
4223
|
+
for (const [c, cell] of Object.entries(cols)) {
|
|
4224
|
+
const x = cell;
|
|
4225
|
+
const val = x?.f ?? x?.v;
|
|
4226
|
+
if (val !== void 0 && val !== null && val !== "") out.push(`${colName3(Number(c))}${Number(r) + 1}: ${String(val)}`);
|
|
4227
|
+
}
|
|
4228
|
+
}
|
|
4229
|
+
}
|
|
4230
|
+
function offlineTextOfGroups(buffers) {
|
|
4231
|
+
const docs = [];
|
|
4232
|
+
const cells = [];
|
|
4233
|
+
for (const groups of buffers) {
|
|
4234
|
+
for (const g of groups) {
|
|
4235
|
+
for (const m of g.mutations) {
|
|
4236
|
+
const p = m.params;
|
|
4237
|
+
if (p && "cellValue" in p) collectCells(p.cellValue, cells);
|
|
4238
|
+
else collectDocText(p, docs);
|
|
4239
|
+
}
|
|
4240
|
+
}
|
|
4241
|
+
}
|
|
4242
|
+
const text = docs.join("").replace(/\r/g, "\n").replace(/\u0000/g, "");
|
|
4243
|
+
return [text, cells.join("\n")].filter((s) => s.length > 0).join("\n");
|
|
4244
|
+
}
|
|
4245
|
+
|
|
4071
4246
|
// src/sheets/workbook-ot-room.ts
|
|
4072
4247
|
import * as Y3 from "yjs";
|
|
4073
4248
|
import { Awareness as Awareness3 } from "y-protocols/awareness";
|
|
4074
4249
|
import {
|
|
4075
4250
|
awarenessOpPresence as awarenessOpPresence2,
|
|
4251
|
+
browserOfflineOptions as browserOfflineOptions2,
|
|
4076
4252
|
claimCollaboratorColor as claimCollaboratorColor3,
|
|
4077
4253
|
collabReplace as collabReplace3,
|
|
4078
4254
|
collabRoomExists as collabRoomExists3,
|
|
@@ -4177,6 +4353,7 @@ async function startWorkbookOtRoom(port, o) {
|
|
|
4177
4353
|
await provider.connect();
|
|
4178
4354
|
publishAwareness();
|
|
4179
4355
|
const client = db4();
|
|
4356
|
+
const offline = browserOfflineOptions2(`${o.workbookId}:${o.uid}`);
|
|
4180
4357
|
const room = openSheetsOtRoom({
|
|
4181
4358
|
port,
|
|
4182
4359
|
clientId: o.clientId,
|
|
@@ -4197,7 +4374,9 @@ async function startWorkbookOtRoom(port, o) {
|
|
|
4197
4374
|
replace: ({ snapshot, stateHash, clientId }) => collabReplace3(client, { roomId: o.workbookId, snapshot, stateHash, origin: "restore", clientId }),
|
|
4198
4375
|
...o.onNotice ? { onNotice: o.onNotice } : {},
|
|
4199
4376
|
...o.onIncident ? { onIncident: o.onIncident } : {},
|
|
4200
|
-
...o.onStatus ? { onStatus: o.onStatus } : {}
|
|
4377
|
+
...o.onStatus ? { onStatus: o.onStatus } : {},
|
|
4378
|
+
...offline ? { offline } : {},
|
|
4379
|
+
...o.onOffline ? { onOffline: o.onOffline } : {}
|
|
4201
4380
|
});
|
|
4202
4381
|
await room.session.ready;
|
|
4203
4382
|
return {
|
|
@@ -4250,6 +4429,7 @@ export {
|
|
|
4250
4429
|
isNoopDocsOp,
|
|
4251
4430
|
moveSelectionsThrough,
|
|
4252
4431
|
normalizeDocsOp,
|
|
4432
|
+
offlineTextOfGroups,
|
|
4253
4433
|
openDocsOtRoom,
|
|
4254
4434
|
openSheetsOtRoom,
|
|
4255
4435
|
rebaseSheetUndoStack,
|