@univerjs-pro/collaboration-client 0.1.9
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/README.md +18 -0
- package/lib/cjs/index.js +4 -0
- package/lib/es/index.js +3626 -0
- package/lib/index.css +1 -0
- package/lib/types/controllers/collab-cursor/__tests__/doc-collab-cursor.controller.spec.d.ts +1 -0
- package/lib/types/controllers/collab-cursor/__tests__/serialize-text-ranges.spec.d.ts +1 -0
- package/lib/types/controllers/collab-cursor/__tests__/sheet-collab-cursor.controller.spec.d.ts +1 -0
- package/lib/types/controllers/collab-cursor/collab-cursor.controller.d.ts +24 -0
- package/lib/types/controllers/collab-cursor/doc-collab-cursor-entity.d.ts +40 -0
- package/lib/types/controllers/collab-cursor/doc-collab-cursor-render.controller.d.ts +22 -0
- package/lib/types/controllers/collab-cursor/serialize-text-ranges.d.ts +4 -0
- package/lib/types/controllers/collab-cursor/sheet-collab-cursor-entity.d.ts +41 -0
- package/lib/types/controllers/collab-cursor/sheet-collab-cursor-render.controller.d.ts +23 -0
- package/lib/types/controllers/collab-status/collab-status.controller.d.ts +18 -0
- package/lib/types/controllers/collaboration/__tests__/collaboration.controller.spec.d.ts +5 -0
- package/lib/types/controllers/collaboration/__tests__/mock-text-selection-render-manager.service.d.ts +10 -0
- package/lib/types/controllers/collaboration/__tests__/mocks.d.ts +55 -0
- package/lib/types/controllers/collaboration/collaboration-state.d.ts +266 -0
- package/lib/types/controllers/collaboration/collaboration.controller.d.ts +110 -0
- package/lib/types/controllers/collaboration/utils/changeset-utils.d.ts +17 -0
- package/lib/types/controllers/data-loader/__tests__/data-loader.controller.spec.d.ts +1 -0
- package/lib/types/controllers/data-loader/data-loader.controller.d.ts +23 -0
- package/lib/types/controllers/file-name/file-name.controller.d.ts +13 -0
- package/lib/types/index.d.ts +11 -0
- package/lib/types/locale/en-US.d.ts +4 -0
- package/lib/types/locale/index.d.ts +2 -0
- package/lib/types/locale/zh-CN.d.ts +29 -0
- package/lib/types/models/cursor.d.ts +29 -0
- package/lib/types/plugin.d.ts +20 -0
- package/lib/types/services/auth-server/auth-server.service.d.ts +15 -0
- package/lib/types/services/collaboration-session/collaboration-session.service.d.ts +107 -0
- package/lib/types/services/color-assign/color-assign.service.d.ts +11 -0
- package/lib/types/services/ime-cache-transform/doc-transform-ime-cache.service.d.ts +12 -0
- package/lib/types/services/local-cache/local-cache.service.d.ts +43 -0
- package/lib/types/services/member/member.service.d.ts +33 -0
- package/lib/types/services/range-selection/sheet-transform-selections.service.d.ts +9 -0
- package/lib/types/services/single-active-unit/single-active-unit.service.d.ts +40 -0
- package/lib/types/services/snapshot-server/snapshot-server.service.d.ts +22 -0
- package/lib/types/services/socket/collaboration-socket.service.d.ts +36 -0
- package/lib/types/services/socket/serialize.d.ts +4 -0
- package/lib/types/services/sync-editing-collab-cursor/doc-sync-editing-collab-cursor.service.d.ts +14 -0
- package/lib/types/services/text-selection/doc-transform-selections.service.d.ts +9 -0
- package/lib/types/services/undoredo/collaborative-undoredo.service.d.ts +20 -0
- package/lib/types/services/url/url.service.d.ts +13 -0
- package/lib/types/services/url/web-url.service.d.ts +11 -0
- package/lib/types/views/components/CollabStatus.d.ts +14 -0
- package/lib/types/views/components/CollabStatus.stories.d.ts +9 -0
- package/lib/types/views/shapes/doc-collab-cursor.d.ts +27 -0
- package/lib/types/views/shapes/sheet-collab-cursor.shape.d.ts +27 -0
- package/lib/types/views/shapes/text-bubble.shape.d.ts +20 -0
- package/lib/umd/index.js +4 -0
- package/package.json +102 -0
package/lib/index.css
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
.univer-online-status-icon{display:flex;margin-right:8px;font-size:20px}.univer-online-status-title{font-size:14px;line-height:32px;color:rgb(var(--grey-600))}.univer-online-status.univer-online .univer-online-status-icon{color:rgb(var(--green-500))}.univer-online-status.univer-offline .univer-online-status-icon{color:rgb(var(--red-500))}
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
package/lib/types/controllers/collab-cursor/__tests__/sheet-collab-cursor.controller.spec.d.ts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1,24 @@
|
|
1
|
+
import { CollaborationSessionService } from '../../services/collaboration-session/collaboration-session.service';
|
2
|
+
import { IDocCollabCursor, ISheetCollabCursor } from '../../models/cursor';
|
3
|
+
import { Observable } from 'rxjs';
|
4
|
+
import { Injector } from '@wendellhu/redi';
|
5
|
+
import { IUniverInstanceService, RxDisposable } from '@univerjs/core';
|
6
|
+
|
7
|
+
/**
|
8
|
+
* This controller adds collaboration cursors to Univer. It works with `CollabCursorRenderController`.
|
9
|
+
*
|
10
|
+
* This controller is also responsible for managing online collaborators' data.
|
11
|
+
*/
|
12
|
+
export declare class CollabCursorController extends RxDisposable {
|
13
|
+
private readonly _univerInstanceService;
|
14
|
+
private readonly _injector;
|
15
|
+
private readonly _collabSessionService;
|
16
|
+
private readonly _entities;
|
17
|
+
private readonly _entityInit$;
|
18
|
+
constructor(_univerInstanceService: IUniverInstanceService, _injector: Injector, _collabSessionService: CollaborationSessionService);
|
19
|
+
dispose(): void;
|
20
|
+
getCollabCursors$(unitID: string): Observable<Map<string, ISheetCollabCursor> | Map<string, IDocCollabCursor>>;
|
21
|
+
private _init;
|
22
|
+
private _startSheetCollabCursor;
|
23
|
+
private _startDocCollabCursor;
|
24
|
+
}
|
@@ -0,0 +1,40 @@
|
|
1
|
+
import { DocSyncEditingCollabCursorService } from '../../services/sync-editing-collab-cursor/doc-sync-editing-collab-cursor.service';
|
2
|
+
import { MemberService } from '../../services/member/member.service';
|
3
|
+
import { ColorAssignService } from '../../services/color-assign/color-assign.service';
|
4
|
+
import { CollaborationSession } from '../../services/collaboration-session/collaboration-session.service';
|
5
|
+
import { IDocCollabCursor } from '../../models/cursor';
|
6
|
+
import { Injector } from '@wendellhu/redi';
|
7
|
+
import { ICollaborationUser, ITransformService } from '@univerjs-pro/collaboration';
|
8
|
+
import { ICommandService, IUniverInstanceService, RxDisposable } from '@univerjs/core';
|
9
|
+
|
10
|
+
/**
|
11
|
+
* Each univer document instance would map to an `CollabCursorEntity` to handle collaborated editing events.
|
12
|
+
*/
|
13
|
+
export declare class DocCollabCursorEntity extends RxDisposable {
|
14
|
+
readonly unitID: string;
|
15
|
+
private readonly _session;
|
16
|
+
private readonly _injector;
|
17
|
+
private readonly _colorAssignService;
|
18
|
+
private readonly _memberService;
|
19
|
+
private readonly _syncEditingCollabCursorService;
|
20
|
+
private readonly _transformService;
|
21
|
+
private readonly _univerInstanceService;
|
22
|
+
private readonly _commandService;
|
23
|
+
private _online;
|
24
|
+
private _init;
|
25
|
+
/** Cursor info of the collaboration room members. The key would be the memberID. */
|
26
|
+
private _cursorInfo$;
|
27
|
+
cursorInfo$: import('rxjs').Observable<Map<string, IDocCollabCursor>>;
|
28
|
+
get cursorInfo(): Readonly<Map<string, IDocCollabCursor>>;
|
29
|
+
private _roomMembers$;
|
30
|
+
roomMembers$: import('rxjs').Observable<ICollaborationUser[]>;
|
31
|
+
get roomMembers(): Readonly<ICollaborationUser[]>;
|
32
|
+
constructor(unitID: string, _session: CollaborationSession, _injector: Injector, _colorAssignService: ColorAssignService, _memberService: MemberService, _syncEditingCollabCursorService: DocSyncEditingCollabCursorService, _transformService: ITransformService, _univerInstanceService: IUniverInstanceService, _commandService: ICommandService);
|
33
|
+
dispose(): void;
|
34
|
+
init(): void;
|
35
|
+
private _onCursorUpdate;
|
36
|
+
private _onCursorDelete;
|
37
|
+
private _updateLocalCursor;
|
38
|
+
private _toggleOnline;
|
39
|
+
private _toggleOffline;
|
40
|
+
}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
import { CollabCursorController } from './collab-cursor.controller';
|
2
|
+
import { DocSkeletonManagerService } from '@univerjs/docs';
|
3
|
+
import { IRenderManagerService } from '@univerjs/engine-render';
|
4
|
+
import { IUniverInstanceService, RxDisposable, ThemeService } from '@univerjs/core';
|
5
|
+
|
6
|
+
/**
|
7
|
+
* This controller works with `CollabCursorController` to render doc collaboration cursors.
|
8
|
+
*/
|
9
|
+
export declare class DocCollabCursorRenderController extends RxDisposable {
|
10
|
+
private readonly _collabCursorController;
|
11
|
+
private readonly _univerInstanceService;
|
12
|
+
private readonly _renderManagerService;
|
13
|
+
private readonly _docSkeletonManagerService;
|
14
|
+
private readonly _themeService;
|
15
|
+
/** Cursors stored for different Workbooks. */
|
16
|
+
private _cursors;
|
17
|
+
constructor(_collabCursorController: CollabCursorController, _univerInstanceService: IUniverInstanceService, _renderManagerService: IRenderManagerService, _docSkeletonManagerService: DocSkeletonManagerService, _themeService: ThemeService);
|
18
|
+
private _init;
|
19
|
+
private _updateCollabCursors;
|
20
|
+
private _removeCollabCursors;
|
21
|
+
private _getDocObject;
|
22
|
+
}
|
@@ -0,0 +1,41 @@
|
|
1
|
+
import { MemberService } from '../../services/member/member.service';
|
2
|
+
import { ColorAssignService } from '../../services/color-assign/color-assign.service';
|
3
|
+
import { CollaborationSession } from '../../services/collaboration-session/collaboration-session.service';
|
4
|
+
import { ISheetCollabCursor } from '../../models/cursor';
|
5
|
+
import { Injector } from '@wendellhu/redi';
|
6
|
+
import { ICollaborationUser } from '@univerjs-pro/collaboration';
|
7
|
+
import { RefRangeService } from '@univerjs/sheets';
|
8
|
+
import { ICommandService, IUniverInstanceService, RxDisposable } from '@univerjs/core';
|
9
|
+
|
10
|
+
/**
|
11
|
+
* Each univer document instance would map to an `CollabCursorEntity` to handle collaborated editing events.
|
12
|
+
*/
|
13
|
+
export declare class SheetCollabCursorEntity extends RxDisposable {
|
14
|
+
readonly unitID: string;
|
15
|
+
private readonly _session;
|
16
|
+
private readonly _injector;
|
17
|
+
private readonly _colorAssignService;
|
18
|
+
private readonly _memberService;
|
19
|
+
private readonly _univerInstanceService;
|
20
|
+
private readonly _commandService;
|
21
|
+
private _refRangeService;
|
22
|
+
private _online;
|
23
|
+
private _init;
|
24
|
+
/** Cursor info of the collaboration room members. The key would be the memberID. */
|
25
|
+
private _cursorInfo$;
|
26
|
+
cursorInfo$: import('rxjs').Observable<Map<string, ISheetCollabCursor>>;
|
27
|
+
get cursorInfo(): Readonly<Map<string, ISheetCollabCursor>>;
|
28
|
+
private _roomMembers$;
|
29
|
+
roomMembers$: import('rxjs').Observable<ICollaborationUser[]>;
|
30
|
+
get roomMembers(): Readonly<ICollaborationUser[]>;
|
31
|
+
constructor(unitID: string, _session: CollaborationSession, _injector: Injector, _colorAssignService: ColorAssignService, _memberService: MemberService, _univerInstanceService: IUniverInstanceService, _commandService: ICommandService, _refRangeService: RefRangeService);
|
32
|
+
dispose(): void;
|
33
|
+
init(): void;
|
34
|
+
private _onCursorUpdate;
|
35
|
+
private _onCursorDelete;
|
36
|
+
private _getMergeRange;
|
37
|
+
private _onRefRangeChange;
|
38
|
+
private _updateLocalCursor;
|
39
|
+
private _toggleOnline;
|
40
|
+
private _toggleOffline;
|
41
|
+
}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
import { CollabCursorController } from './collab-cursor.controller';
|
2
|
+
import { SheetSkeletonManagerService } from '@univerjs/sheets-ui';
|
3
|
+
import { IRenderManagerService } from '@univerjs/engine-render';
|
4
|
+
import { IUniverInstanceService, RxDisposable, ThemeService } from '@univerjs/core';
|
5
|
+
|
6
|
+
/**
|
7
|
+
* This controller works with `CollabCursorController` to render sheet collaboration cursors.
|
8
|
+
*/
|
9
|
+
export declare class SheetCollabCursorRenderController extends RxDisposable {
|
10
|
+
private readonly _collabCursorController;
|
11
|
+
private readonly _univerInstanceService;
|
12
|
+
private readonly _renderManagerService;
|
13
|
+
private readonly _sheetSkeletonManagerService;
|
14
|
+
private readonly _themeService;
|
15
|
+
/** Cursors stored for different Workbooks. */
|
16
|
+
private _cursors;
|
17
|
+
private _lastPointer;
|
18
|
+
constructor(_collabCursorController: CollabCursorController, _univerInstanceService: IUniverInstanceService, _renderManagerService: IRenderManagerService, _sheetSkeletonManagerService: SheetSkeletonManagerService, _themeService: ThemeService);
|
19
|
+
private _init;
|
20
|
+
private _updateCollabCursors;
|
21
|
+
private _removeCollabCursors;
|
22
|
+
private _getSheetObject;
|
23
|
+
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
import { CollaborationController } from '../collaboration/collaboration.controller';
|
2
|
+
import { Injector } from '@wendellhu/redi';
|
3
|
+
import { IDesktopUIController } from '@univerjs/ui';
|
4
|
+
import { Disposable, IUniverInstanceService } from '@univerjs/core';
|
5
|
+
|
6
|
+
/**
|
7
|
+
* This controller is responsible for monitoring the collaboration status of the currently focused unit.
|
8
|
+
*/
|
9
|
+
export declare class DesktopCollaborationStatusDisplayController extends Disposable {
|
10
|
+
private readonly _uiController;
|
11
|
+
private readonly _univerInstanceService;
|
12
|
+
private readonly _injector;
|
13
|
+
private readonly _collaborationController;
|
14
|
+
private readonly _status$;
|
15
|
+
constructor(_uiController: IDesktopUIController, _univerInstanceService: IUniverInstanceService, _injector: Injector, _collaborationController: CollaborationController);
|
16
|
+
private _mountOnlineHint;
|
17
|
+
private _initStatusListener;
|
18
|
+
}
|
@@ -0,0 +1,10 @@
|
|
1
|
+
import { ITextSelectionInnerParam } from '@univerjs/engine-render';
|
2
|
+
import { Nullable } from '@univerjs/core';
|
3
|
+
|
4
|
+
export declare class TextSelectionRenderManager {
|
5
|
+
private readonly _textSelectionInner$;
|
6
|
+
readonly textSelectionInner$: import('rxjs').Observable<Nullable<ITextSelectionInnerParam>>;
|
7
|
+
removeAllTextRanges(): void;
|
8
|
+
addTextRanges(): void;
|
9
|
+
}
|
10
|
+
export declare const ITextSelectionRenderManager: import('@wendellhu/redi').IdentifierDecorator<TextSelectionRenderManager>;
|
@@ -0,0 +1,55 @@
|
|
1
|
+
import { ICollaborationSocket, ICollaborationSocketService } from '../../../services/socket/collaboration-socket.service';
|
2
|
+
import { Subject } from 'rxjs';
|
3
|
+
import { IDisposable } from '@wendellhu/redi';
|
4
|
+
import { ICombResponseEvent } from '@univerjs-pro/collaboration';
|
5
|
+
import { IBeforeCloseService, IMessageService, INotificationService } from '@univerjs/ui';
|
6
|
+
import { IMessageMethodOptions, IMessageProps } from '@univerjs/design';
|
7
|
+
import { ILocalStorageService, Nullable, ILogService } from '@univerjs/core';
|
8
|
+
|
9
|
+
/**
|
10
|
+
* The handler object for a mocked socket connection. You can terminate, send messages / error through this object.
|
11
|
+
*/
|
12
|
+
export interface IMockCollabSessionSocketHandler extends ICollaborationSocket {
|
13
|
+
socket: ICollaborationSocket;
|
14
|
+
close$: Subject<CloseEvent>;
|
15
|
+
error$: Subject<Event>;
|
16
|
+
open$: Subject<Event>;
|
17
|
+
message$: Subject<ICombResponseEvent>;
|
18
|
+
}
|
19
|
+
/**
|
20
|
+
* This service provides a mocked
|
21
|
+
*/
|
22
|
+
export declare class MockCollaborationSocketService implements ICollaborationSocketService {
|
23
|
+
private readonly _logService;
|
24
|
+
private readonly _handlers;
|
25
|
+
constructor(_logService: ILogService);
|
26
|
+
createSocket(url: string): Nullable<ICollaborationSocket>;
|
27
|
+
/** Test scripts could get the session handler from this method to mock network events. */
|
28
|
+
getHandler(url: string): Nullable<IMockCollabSessionSocketHandler>;
|
29
|
+
}
|
30
|
+
export declare class MockBeforeCloseService implements IBeforeCloseService {
|
31
|
+
private _onCloseCallbacks;
|
32
|
+
private _beforeCloseCallbacks;
|
33
|
+
registerBeforeClose(callback: () => string | undefined): IDisposable;
|
34
|
+
registerOnClose(callback: () => void): IDisposable;
|
35
|
+
}
|
36
|
+
/**
|
37
|
+
* A mocked local storage service which use in-memory storage.
|
38
|
+
*/
|
39
|
+
export declare class MockLocalStorageService implements ILocalStorageService {
|
40
|
+
private readonly _inMemoryCache;
|
41
|
+
getItem<T>(key: string): Promise<T | null>;
|
42
|
+
setItem<T>(key: string, value: T): Promise<T>;
|
43
|
+
removeItem(key: string): Promise<void>;
|
44
|
+
clear(): Promise<void>;
|
45
|
+
key(index: number): Promise<string | null>;
|
46
|
+
keys(): Promise<string[]>;
|
47
|
+
iterate<T, U>(iteratee: (value: T, key: string, iterationNumber: number) => U): Promise<U>;
|
48
|
+
}
|
49
|
+
export declare class MockMessageService implements IMessageService {
|
50
|
+
show(options: IMessageMethodOptions & Omit<IMessageProps, 'key'>): IDisposable;
|
51
|
+
setContainer(container: HTMLElement): void;
|
52
|
+
}
|
53
|
+
export declare class MockNotificationService implements INotificationService {
|
54
|
+
show(): IDisposable;
|
55
|
+
}
|
@@ -0,0 +1,266 @@
|
|
1
|
+
import { ICollabEditingCursor } from '../../services/sync-editing-collab-cursor/doc-sync-editing-collab-cursor.service';
|
2
|
+
import { ICollaborativeUndoRedoService } from '../../services/undoredo/collaborative-undoredo.service';
|
3
|
+
import { MemberService } from '../../services/member/member.service';
|
4
|
+
import { LocalCacheService } from '../../services/local-cache/local-cache.service';
|
5
|
+
import { Injector } from '@wendellhu/redi';
|
6
|
+
import { UniverType } from '@univerjs/protocol';
|
7
|
+
import { IAcknowledgedChangeset, IChangeset, ITransformService, RevisionService } from '@univerjs-pro/collaboration';
|
8
|
+
import { INotificationService } from '@univerjs/ui';
|
9
|
+
import { IMutationInfo, Nullable, ICommandService, IConfigService, ILogService, IUniverInstanceService, LocaleService, UniverPermissionService } from '@univerjs/core';
|
10
|
+
|
11
|
+
/**
|
12
|
+
* Determines how often should we send changesets.
|
13
|
+
*/
|
14
|
+
export declare const SEND_CHANGESET_TIMEOUT_KEY = "SEND_CHANGESET_TIMEOUT";
|
15
|
+
/** Provide both states when and after changing, so the parent could examine if state transition is correct. */
|
16
|
+
export type StateChangeHandler = (before: CollaborationState, after: CollaborationState) => void;
|
17
|
+
/** A network interface to send changeset and */
|
18
|
+
export type SendChangesetHandler = (changeset: IChangeset) => void;
|
19
|
+
export type MissingChangesetsHandler = (params: {
|
20
|
+
from: number;
|
21
|
+
to: number;
|
22
|
+
}) => void;
|
23
|
+
export type TransformSelectionsHandler = (changeset: IChangeset) => void;
|
24
|
+
export type TransformIMEHandler = (changeset: IChangeset) => void;
|
25
|
+
export type SyncEditingCollabCursorHandler = (params: ICollabEditingCursor) => void;
|
26
|
+
export type TransformRemoteChangesetByIMECache = (changeset: IChangeset) => IChangeset;
|
27
|
+
export interface ICollaborationStateHandler {
|
28
|
+
onStateChange: StateChangeHandler;
|
29
|
+
onSendChangeset: SendChangesetHandler;
|
30
|
+
onMissingChangesets: MissingChangesetsHandler;
|
31
|
+
onTransformSelections?: TransformSelectionsHandler;
|
32
|
+
onTransformIME?: TransformIMEHandler;
|
33
|
+
onSyncEditingCollabCursor?: SyncEditingCollabCursorHandler;
|
34
|
+
onTransformRemoteChangesetByIMECache?: TransformRemoteChangesetByIMECache;
|
35
|
+
}
|
36
|
+
export declare enum CollaborationStatus {
|
37
|
+
NOT_COLLAB = "not_collab",
|
38
|
+
SYNCED = "synced",
|
39
|
+
PENDING = "pending",
|
40
|
+
AWAITING = "awaiting",
|
41
|
+
AWAITING_WITH_PENDING = "awaiting_with_pending",
|
42
|
+
FETCH_MISS = "fetch_missing",
|
43
|
+
CONFLICT = "conflict",
|
44
|
+
OFFLINE = "offline"
|
45
|
+
}
|
46
|
+
/**
|
47
|
+
* Use state machine to manage syncing states.
|
48
|
+
* An explanation to how these states are transformed to each other.
|
49
|
+
*/
|
50
|
+
export declare abstract class CollaborationState {
|
51
|
+
readonly unitID: string;
|
52
|
+
readonly type: UniverType;
|
53
|
+
/** State may change internally. Parent module should provide a callback to handle this event. */
|
54
|
+
protected readonly _handler: ICollaborationStateHandler;
|
55
|
+
protected readonly _commandService: ICommandService;
|
56
|
+
protected readonly _undoRedoService: ICollaborativeUndoRedoService;
|
57
|
+
protected readonly _revisionService: RevisionService;
|
58
|
+
protected readonly _localCacheService: LocalCacheService;
|
59
|
+
abstract readonly status: CollaborationStatus;
|
60
|
+
/** Mutations that has been sent to the server but not yet acknowledged by the server. */
|
61
|
+
protected _awaitingChangeset: Nullable<IChangeset>;
|
62
|
+
/** Mutations that has not been sent to the server. */
|
63
|
+
protected _pendingMutations: IMutationInfo[];
|
64
|
+
constructor(unitID: string, type: UniverType, awaitingChangeset: Nullable<IChangeset>, pendingMutations: IMutationInfo[],
|
65
|
+
/** State may change internally. Parent module should provide a callback to handle this event. */
|
66
|
+
_handler: ICollaborationStateHandler, _commandService: ICommandService, _undoRedoService: ICollaborativeUndoRedoService, _revisionService: RevisionService, _localCacheService: LocalCacheService);
|
67
|
+
abstract resend(): void;
|
68
|
+
/**
|
69
|
+
* Append a location mutation to collaboration queue.
|
70
|
+
*
|
71
|
+
* @param mutation a mutation that happened locally and should be broadcasted to other peers
|
72
|
+
*/
|
73
|
+
abstract appendMutation(mutation: IMutationInfo): CollaborationState;
|
74
|
+
/**
|
75
|
+
* Received a changeset from the server.
|
76
|
+
* @param changeset
|
77
|
+
*/
|
78
|
+
abstract onRemoteChangeset(changeset: IChangeset): CollaborationState;
|
79
|
+
/**
|
80
|
+
* Received an acknowledgement from the server.
|
81
|
+
*/
|
82
|
+
abstract onRemoteAck(changeset: IAcknowledgedChangeset): CollaborationState;
|
83
|
+
/**
|
84
|
+
* Received a rejection from the server, meaning that conflict could be resolved by the algorithm.
|
85
|
+
*/
|
86
|
+
abstract onRemoteRej(): CollaborationState;
|
87
|
+
abstract toggleOffline(): CollaborationState;
|
88
|
+
abstract toggleOnline(): CollaborationState;
|
89
|
+
/**
|
90
|
+
* Check if there are some changesets missing. If true, the state should abort this changeset and request
|
91
|
+
* for missing changesets. Missing changesets will later be passed to `onRemoteChangeset` method.
|
92
|
+
*
|
93
|
+
* @param changeset The changeset sent from the remote collaboration server.
|
94
|
+
* @returns There is some changeset missing.
|
95
|
+
*/
|
96
|
+
protected _checkMissing(changeset: IChangeset | IAcknowledgedChangeset): boolean;
|
97
|
+
/** Transform undo redo mutations in the undo redo stack. */
|
98
|
+
protected _transformUndoredo(changeset: IChangeset): void;
|
99
|
+
/** Transform selections by calling the selection manager service. */
|
100
|
+
protected _transformSelections(changeset: IChangeset): void;
|
101
|
+
protected _transformIMECache(changeset: IChangeset): void | undefined;
|
102
|
+
protected _transformRemoteChangesetByIMECache(changeset: IChangeset): IChangeset;
|
103
|
+
protected _syncEditingCollabCursor(changeset: IChangeset): void;
|
104
|
+
/** @internal */
|
105
|
+
_updateLocalCache(): void;
|
106
|
+
protected _getCurrentRevision(): number;
|
107
|
+
protected _incrementRevisionNumber(): void;
|
108
|
+
protected _executeRemoteChangeset(changeset: IChangeset): void;
|
109
|
+
}
|
110
|
+
/**
|
111
|
+
* All local changesets are sent to and acknowledged by the server.
|
112
|
+
*/
|
113
|
+
export declare class SyncedState extends CollaborationState {
|
114
|
+
private readonly _injector;
|
115
|
+
private readonly _logService;
|
116
|
+
readonly status = CollaborationStatus.SYNCED;
|
117
|
+
constructor(unitID: string, type: UniverType, handler: ICollaborationStateHandler, revisionService: RevisionService, localCacheService: LocalCacheService, _injector: Injector, undoRedoService: ICollaborativeUndoRedoService, commandService: ICommandService, _logService: ILogService);
|
118
|
+
appendMutation(mutation: IMutationInfo): CollaborationState;
|
119
|
+
onRemoteChangeset(changeset: IChangeset): CollaborationState;
|
120
|
+
onRemoteAck(): never;
|
121
|
+
onRemoteRej(): CollaborationState;
|
122
|
+
toggleOffline(): CollaborationState;
|
123
|
+
toggleOnline(): CollaborationState;
|
124
|
+
resend(): void;
|
125
|
+
}
|
126
|
+
/**
|
127
|
+
* Some local changes are waiting to be sent to the server. But no changesets are waiting for acknowledgement.
|
128
|
+
*
|
129
|
+
* You should call schedule task after you create a `PendingState`.
|
130
|
+
*/
|
131
|
+
export declare class PendingState extends CollaborationState {
|
132
|
+
private readonly _injector;
|
133
|
+
private readonly _memberService;
|
134
|
+
private readonly _logService;
|
135
|
+
private readonly _configService;
|
136
|
+
private readonly _transformService;
|
137
|
+
private readonly _univerInstanceService;
|
138
|
+
readonly status = CollaborationStatus.PENDING;
|
139
|
+
private _scheduleTimestamp;
|
140
|
+
private _sendingTimer;
|
141
|
+
constructor(unitID: string, type: UniverType, pendingMutations: IMutationInfo[], handler: ICollaborationStateHandler, _injector: Injector, _revisionService: RevisionService, _localCacheService: LocalCacheService, _memberService: MemberService, _logService: ILogService, commandService: ICommandService, _configService: IConfigService, _transformService: ITransformService, _univerInstanceService: IUniverInstanceService, _undoRedoService: ICollaborativeUndoRedoService);
|
142
|
+
appendMutation(mutation: IMutationInfo): CollaborationState;
|
143
|
+
onRemoteChangeset(changeset: IChangeset): CollaborationState;
|
144
|
+
onRemoteAck(): CollaborationState;
|
145
|
+
onRemoteRej(): CollaborationState;
|
146
|
+
toggleOffline(): CollaborationState;
|
147
|
+
toggleOnline(): CollaborationState;
|
148
|
+
/**
|
149
|
+
* Schedule a task to send changeset to the server.
|
150
|
+
*
|
151
|
+
* @internal
|
152
|
+
*/
|
153
|
+
_schedule(timeout?: number): void;
|
154
|
+
private _getSendChangesetTimeout;
|
155
|
+
resend(): void;
|
156
|
+
private _clearScheduledTask;
|
157
|
+
private _onConflict;
|
158
|
+
}
|
159
|
+
/**
|
160
|
+
* All local mutations are sent to the server and waiting for acknowledgement.
|
161
|
+
*/
|
162
|
+
export declare class AwaitingState extends CollaborationState {
|
163
|
+
private readonly _injector;
|
164
|
+
private readonly _logService;
|
165
|
+
private readonly _transformService;
|
166
|
+
readonly status = CollaborationStatus.AWAITING;
|
167
|
+
constructor(unitID: string, type: UniverType, awaitingChangeset: IChangeset, handler: ICollaborationStateHandler, _injector: Injector, revisionService: RevisionService, localCacheService: LocalCacheService, commandService: ICommandService, _logService: ILogService, _transformService: ITransformService, undoRedoService: ICollaborativeUndoRedoService);
|
168
|
+
appendMutation(mutation: IMutationInfo): CollaborationState;
|
169
|
+
onRemoteChangeset(changeset: IChangeset): CollaborationState;
|
170
|
+
onRemoteAck(changeset: IAcknowledgedChangeset): CollaborationState;
|
171
|
+
onRemoteRej(): CollaborationState;
|
172
|
+
toggleOffline(): CollaborationState;
|
173
|
+
toggleOnline(): CollaborationState;
|
174
|
+
resend(): void;
|
175
|
+
private _onConflict;
|
176
|
+
}
|
177
|
+
/**
|
178
|
+
* Some local mutations are sent to the server and waiting for acknowledgement, yet still some local mutations
|
179
|
+
* are waiting to be sent to the server.
|
180
|
+
*/
|
181
|
+
export declare class AwaitingWithPendingState extends CollaborationState {
|
182
|
+
private readonly _injector;
|
183
|
+
private readonly _logService;
|
184
|
+
private readonly _transformService;
|
185
|
+
readonly status = CollaborationStatus.AWAITING_WITH_PENDING;
|
186
|
+
constructor(unitID: string, type: UniverType, awaitingChangeset: IChangeset, pendingMutations: IMutationInfo[], handler: ICollaborationStateHandler, _injector: Injector, revisionService: RevisionService, localCacheService: LocalCacheService, commandService: ICommandService, _logService: ILogService, _transformService: ITransformService, undoRedoService: ICollaborativeUndoRedoService);
|
187
|
+
appendMutation(mutation: IMutationInfo): CollaborationState;
|
188
|
+
onRemoteChangeset(changeset: IChangeset): CollaborationState;
|
189
|
+
onRemoteAck(changeset: IAcknowledgedChangeset): CollaborationState;
|
190
|
+
onRemoteRej(): CollaborationState;
|
191
|
+
toggleOffline(): CollaborationState;
|
192
|
+
toggleOnline(): CollaborationState;
|
193
|
+
resend(): void;
|
194
|
+
private _onConflict;
|
195
|
+
}
|
196
|
+
/**
|
197
|
+
* This state is special for handling collaboration conflicts.
|
198
|
+
*
|
199
|
+
* `ConflictState` is a dead end state. It cannot transit to any other state. User could only reload the page to
|
200
|
+
* reload the document.
|
201
|
+
*/
|
202
|
+
export declare class ConflictState extends CollaborationState {
|
203
|
+
private readonly _univerPermissionService;
|
204
|
+
private readonly _localeService;
|
205
|
+
private readonly _notificationService;
|
206
|
+
readonly status = CollaborationStatus.CONFLICT;
|
207
|
+
constructor(unitID: string, type: UniverType, awaitingChangeset: Nullable<IChangeset>, pendingMutations: IMutationInfo[], handler: ICollaborationStateHandler, _univerPermissionService: UniverPermissionService, commandService: ICommandService, undoRedoService: ICollaborativeUndoRedoService, localCacheService: LocalCacheService, revisionService: RevisionService, _localeService: LocaleService, _notificationService: INotificationService);
|
208
|
+
appendMutation(): CollaborationState;
|
209
|
+
onRemoteChangeset(): CollaborationState;
|
210
|
+
onRemoteAck(): CollaborationState;
|
211
|
+
onRemoteRej(): CollaborationState;
|
212
|
+
toggleOffline(): CollaborationState;
|
213
|
+
toggleOnline(): CollaborationState;
|
214
|
+
resend(): void;
|
215
|
+
private _clearLocalCache;
|
216
|
+
private _showConflictNotification;
|
217
|
+
private _disableEditing;
|
218
|
+
}
|
219
|
+
export declare class OfflineState extends CollaborationState {
|
220
|
+
private readonly _injector;
|
221
|
+
readonly status = CollaborationStatus.OFFLINE;
|
222
|
+
constructor(unitID: string, type: UniverType, awaitingChangeset: Nullable<IChangeset>, pendingMutations: IMutationInfo[], handler: ICollaborationStateHandler, _injector: Injector, revisionService: RevisionService, localCacheService: LocalCacheService, commandService: ICommandService, undoRedoService: ICollaborativeUndoRedoService);
|
223
|
+
appendMutation(mutation: IMutationInfo): CollaborationState;
|
224
|
+
onRemoteChangeset(_changeset: IChangeset): CollaborationState;
|
225
|
+
onRemoteAck(): CollaborationState;
|
226
|
+
onRemoteRej(): CollaborationState;
|
227
|
+
toggleOffline(): CollaborationState;
|
228
|
+
toggleOnline(): CollaborationState;
|
229
|
+
resend(): void;
|
230
|
+
}
|
231
|
+
/**
|
232
|
+
* When the client is trying to fetch missed changesets:
|
233
|
+
*
|
234
|
+
* 1. local changesets would not be send to the server until the missed changesets are fetched
|
235
|
+
* 2. remote changesets would not be applied util the missed changesets are fetched and applied
|
236
|
+
*/
|
237
|
+
export declare class FetchingMissState extends CollaborationState {
|
238
|
+
/**
|
239
|
+
* The awaiting changeset may have been acknowledged when missing is detected.
|
240
|
+
* We need to transform missing changeset against this acknowledged changeset,
|
241
|
+
* so other state should pass this acknowledged changeset to this parameter.
|
242
|
+
*/
|
243
|
+
private _acknowledgedAwaitingChangeset;
|
244
|
+
private readonly _queuedRemoteChangesets;
|
245
|
+
private readonly _injector;
|
246
|
+
private readonly _logService;
|
247
|
+
private readonly _transformService;
|
248
|
+
readonly status = CollaborationStatus.FETCH_MISS;
|
249
|
+
constructor(unitID: string, type: UniverType, awaitingChangeset: Nullable<IChangeset>, pendingMutations: IMutationInfo[],
|
250
|
+
/**
|
251
|
+
* The awaiting changeset may have been acknowledged when missing is detected.
|
252
|
+
* We need to transform missing changeset against this acknowledged changeset,
|
253
|
+
* so other state should pass this acknowledged changeset to this parameter.
|
254
|
+
*/
|
255
|
+
_acknowledgedAwaitingChangeset: Nullable<IChangeset>, _queuedRemoteChangesets: IChangeset[], handler: ICollaborationStateHandler, _injector: Injector, revisionService: RevisionService, localCacheService: LocalCacheService, _logService: ILogService, commandService: ICommandService, undoRedoService: ICollaborativeUndoRedoService, _transformService: ITransformService);
|
256
|
+
onMissedChangesetFetched(changesets: IChangeset[]): CollaborationState;
|
257
|
+
resend(): void;
|
258
|
+
appendMutation(mutation: IMutationInfo<object>): CollaborationState;
|
259
|
+
onRemoteChangeset(changeset: IChangeset): CollaborationState;
|
260
|
+
onRemoteAck(changeset: IAcknowledgedChangeset): CollaborationState;
|
261
|
+
onRemoteRej(): CollaborationState;
|
262
|
+
toggleOffline(): CollaborationState;
|
263
|
+
toggleOnline(): CollaborationState;
|
264
|
+
private _onConflict;
|
265
|
+
}
|
266
|
+
export declare function createOnlineState(injector: Injector, unitID: string, type: UniverType, awaitingChangeset: Nullable<IChangeset>, mutations: IMutationInfo[], handler: ICollaborationStateHandler): SyncedState | PendingState | AwaitingState | AwaitingWithPendingState;
|
@@ -0,0 +1,110 @@
|
|
1
|
+
import { CollaborationState, ICollaborationStateHandler, CollaborationStatus } from './collaboration-state';
|
2
|
+
import { SheetTransformSelectionsService } from '../../services/range-selection/sheet-transform-selections.service';
|
3
|
+
import { DocSyncEditingCollabCursorService } from '../../services/sync-editing-collab-cursor/doc-sync-editing-collab-cursor.service';
|
4
|
+
import { DocTransformSelectionsService } from '../../services/text-selection/doc-transform-selections.service';
|
5
|
+
import { DocTransformIMECacheService } from '../../services/ime-cache-transform/doc-transform-ime-cache.service';
|
6
|
+
import { ISingleActiveUnitService } from '../../services/single-active-unit/single-active-unit.service';
|
7
|
+
import { LocalCacheService } from '../../services/local-cache/local-cache.service';
|
8
|
+
import { CollaborationSession, CollaborationSessionService } from '../../services/collaboration-session/collaboration-session.service';
|
9
|
+
import { DocStateChangeManagerService } from '@univerjs/docs';
|
10
|
+
import { Observable, BehaviorSubject } from 'rxjs';
|
11
|
+
import { IDisposable, Injector } from '@wendellhu/redi';
|
12
|
+
import { UniverType } from '@univerjs/protocol';
|
13
|
+
import { CompressMutationService, RevisionService } from '@univerjs-pro/collaboration';
|
14
|
+
import { IMessageService } from '@univerjs/ui';
|
15
|
+
import { IMutationInfo, Nullable, ICommandService, ILogService, IUniverInstanceService, LocaleService, RxDisposable, UniverPermissionService } from '@univerjs/core';
|
16
|
+
|
17
|
+
export declare class CollaborationController extends RxDisposable {
|
18
|
+
private readonly _injector;
|
19
|
+
private readonly _collabSessionService;
|
20
|
+
private readonly _univerInstanceService;
|
21
|
+
private readonly _entities;
|
22
|
+
private readonly _entityInit$;
|
23
|
+
constructor(_injector: Injector, _collabSessionService: CollaborationSessionService, _univerInstanceService: IUniverInstanceService);
|
24
|
+
dispose(): void;
|
25
|
+
getCollabEntity(id: string): Nullable<CollaborationEntity>;
|
26
|
+
getCollabEntity$(id: string): Observable<CollaborationEntity>;
|
27
|
+
private _init;
|
28
|
+
/**
|
29
|
+
* Start collaboration on a document.
|
30
|
+
*
|
31
|
+
* @param unitID ID of the document to start collaboration.
|
32
|
+
* @returns A disposable to stop collaboration.
|
33
|
+
*/
|
34
|
+
private _startCollaboration;
|
35
|
+
private _getCtorByUniverType;
|
36
|
+
}
|
37
|
+
/**
|
38
|
+
* Each univer document instance would map to an `CollaborationEntity` to handle collaborated editing events.
|
39
|
+
*/
|
40
|
+
export declare abstract class CollaborationEntity extends RxDisposable {
|
41
|
+
readonly unitID: string;
|
42
|
+
protected readonly _type: UniverType;
|
43
|
+
protected readonly _session: CollaborationSession;
|
44
|
+
protected readonly _injector: Injector;
|
45
|
+
protected readonly _localCacheService: LocalCacheService;
|
46
|
+
protected readonly _univerPermissionService: UniverPermissionService;
|
47
|
+
protected readonly _compressMutationService: CompressMutationService;
|
48
|
+
protected readonly _localeService: LocaleService;
|
49
|
+
protected readonly _revisionService: RevisionService;
|
50
|
+
protected readonly _logService: ILogService;
|
51
|
+
protected readonly _commandService: ICommandService;
|
52
|
+
protected readonly _messageService: IMessageService;
|
53
|
+
protected readonly _singleActiveUnitService?: ISingleActiveUnitService | undefined;
|
54
|
+
protected _state$: BehaviorSubject<Nullable<CollaborationState>>;
|
55
|
+
readonly state$: Observable<Nullable<CollaborationState>>;
|
56
|
+
protected _state: CollaborationState;
|
57
|
+
get state(): CollaborationState;
|
58
|
+
protected _collaborationPaused: boolean;
|
59
|
+
readonly status$: Observable<CollaborationStatus>;
|
60
|
+
constructor(unitID: string, _type: UniverType, _session: CollaborationSession, _injector: Injector, _localCacheService: LocalCacheService, _univerPermissionService: UniverPermissionService, _compressMutationService: CompressMutationService, _localeService: LocaleService, _revisionService: RevisionService, _logService: ILogService, _commandService: ICommandService, _messageService: IMessageService, _singleActiveUnitService?: ISingleActiveUnitService | undefined);
|
61
|
+
init(): Promise<void>;
|
62
|
+
/**
|
63
|
+
* Pause collaboration on the document. Remote changesets would be inserted to a queue and wait for resuming.
|
64
|
+
* @returns a disposable which will resume collaboration when called.
|
65
|
+
*/
|
66
|
+
pauseCollaboration(): IDisposable;
|
67
|
+
private _updateState;
|
68
|
+
protected _init(): Promise<CollaborationState>;
|
69
|
+
/**
|
70
|
+
* Could not transit the state twice at the same time. So we put a lock here in case of implementation fault.
|
71
|
+
*/
|
72
|
+
private _transitionLocked;
|
73
|
+
private _unlockTransition;
|
74
|
+
private _lockTransition;
|
75
|
+
protected _onLocalMutation(command: IMutationInfo): void;
|
76
|
+
private _remoteChangesetQueue;
|
77
|
+
private _onRemoteChangeset;
|
78
|
+
private _exhaustRemoteChangesetQueue;
|
79
|
+
private _applyRemoteChangeset;
|
80
|
+
private _onRemoteACK;
|
81
|
+
private _onRemoteRejected;
|
82
|
+
private _onFetchMissResult;
|
83
|
+
private _toggleOffline;
|
84
|
+
private _toggleOnline;
|
85
|
+
private _createInitialState;
|
86
|
+
protected _createHandler(): ICollaborationStateHandler;
|
87
|
+
private _createInitialStateImpl;
|
88
|
+
private _replayCachedMutations;
|
89
|
+
}
|
90
|
+
export declare class DocCollaborationEntity extends CollaborationEntity {
|
91
|
+
readonly unitID: string;
|
92
|
+
readonly type: UniverType;
|
93
|
+
readonly session: CollaborationSession;
|
94
|
+
private readonly _docStateChangeManagerService;
|
95
|
+
private readonly _docTransformIMECacheService;
|
96
|
+
private readonly _docTransformSelectionsService;
|
97
|
+
private readonly _docSyncEditingCollabCursorService;
|
98
|
+
constructor(unitID: string, type: UniverType, session: CollaborationSession, injector: Injector, localCacheService: LocalCacheService, univerPermissionService: UniverPermissionService, compressMutationService: CompressMutationService, localeService: LocaleService, revisionService: RevisionService, _docStateChangeManagerService: DocStateChangeManagerService, _docTransformIMECacheService: DocTransformIMECacheService, _docTransformSelectionsService: DocTransformSelectionsService, _docSyncEditingCollabCursorService: DocSyncEditingCollabCursorService, logService: ILogService, commandService: ICommandService, messageService: IMessageService, singleActiveUnitService?: ISingleActiveUnitService);
|
99
|
+
protected _createHandler(): ICollaborationStateHandler;
|
100
|
+
protected _init(): Promise<CollaborationState>;
|
101
|
+
}
|
102
|
+
export declare class SheetCollaborationEntity extends CollaborationEntity {
|
103
|
+
readonly unitID: string;
|
104
|
+
readonly type: UniverType;
|
105
|
+
readonly session: CollaborationSession;
|
106
|
+
private readonly _sheetTransformSelectionsService;
|
107
|
+
constructor(unitID: string, type: UniverType, session: CollaborationSession, injector: Injector, localCacheService: LocalCacheService, univerPermissionService: UniverPermissionService, compressMutationService: CompressMutationService, localeService: LocaleService, revisionService: RevisionService, _sheetTransformSelectionsService: SheetTransformSelectionsService, logService: ILogService, commandService: ICommandService, messageService: IMessageService, singleActiveUnitService?: ISingleActiveUnitService);
|
108
|
+
protected _createHandler(): ICollaborationStateHandler;
|
109
|
+
protected _init(): Promise<CollaborationState>;
|
110
|
+
}
|