]> BookStack Code Mirror - bookstack/blob - resources/js/wysiwyg/lexical/yjs/index.ts
Add optional OIDC avatar fetching from the “picture” claim
[bookstack] / resources / js / wysiwyg / lexical / yjs / index.ts
1 /**
2  * Copyright (c) Meta Platforms, Inc. and affiliates.
3  *
4  * This source code is licensed under the MIT license found in the
5  * LICENSE file in the root directory of this source tree.
6  *
7  */
8
9 import type {Binding} from './Bindings';
10 import type {LexicalCommand} from 'lexical';
11 import type {Doc, RelativePosition, UndoManager, XmlText} from 'yjs';
12
13 import {createCommand} from 'lexical';
14 import {UndoManager as YjsUndoManager} from 'yjs';
15
16 export type UserState = {
17   anchorPos: null | RelativePosition;
18   color: string;
19   focusing: boolean;
20   focusPos: null | RelativePosition;
21   name: string;
22   awarenessData: object;
23 };
24 export const CONNECTED_COMMAND: LexicalCommand<boolean> =
25   createCommand('CONNECTED_COMMAND');
26 export const TOGGLE_CONNECT_COMMAND: LexicalCommand<boolean> = createCommand(
27   'TOGGLE_CONNECT_COMMAND',
28 );
29 export type ProviderAwareness = {
30   getLocalState: () => UserState | null;
31   getStates: () => Map<number, UserState>;
32   off: (type: 'update', cb: () => void) => void;
33   on: (type: 'update', cb: () => void) => void;
34   setLocalState: (arg0: UserState) => void;
35 };
36 declare interface Provider {
37   awareness: ProviderAwareness;
38   connect(): void | Promise<void>;
39   disconnect(): void;
40   off(type: 'sync', cb: (isSynced: boolean) => void): void;
41   off(type: 'update', cb: (arg0: unknown) => void): void;
42   off(type: 'status', cb: (arg0: {status: string}) => void): void;
43   off(type: 'reload', cb: (doc: Doc) => void): void;
44   on(type: 'sync', cb: (isSynced: boolean) => void): void;
45   on(type: 'status', cb: (arg0: {status: string}) => void): void;
46   on(type: 'update', cb: (arg0: unknown) => void): void;
47   on(type: 'reload', cb: (doc: Doc) => void): void;
48 }
49 export type Operation = {
50   attributes: {
51     __type: string;
52   };
53   insert: string | Record<string, unknown>;
54 };
55 export type Delta = Array<Operation>;
56 export type YjsNode = Record<string, unknown>;
57 export type YjsEvent = Record<string, unknown>;
58 export type {Provider};
59 export type {Binding, ClientID, ExcludedProperties} from './Bindings';
60 export {createBinding} from './Bindings';
61
62 export function createUndoManager(
63   binding: Binding,
64   root: XmlText,
65 ): UndoManager {
66   return new YjsUndoManager(root, {
67     trackedOrigins: new Set([binding, null]),
68   });
69 }
70
71 export function initLocalState(
72   provider: Provider,
73   name: string,
74   color: string,
75   focusing: boolean,
76   awarenessData: object,
77 ): void {
78   provider.awareness.setLocalState({
79     anchorPos: null,
80     awarenessData,
81     color,
82     focusPos: null,
83     focusing: focusing,
84     name,
85   });
86 }
87
88 export function setLocalStateFocus(
89   provider: Provider,
90   name: string,
91   color: string,
92   focusing: boolean,
93   awarenessData: object,
94 ): void {
95   const {awareness} = provider;
96   let localState = awareness.getLocalState();
97
98   if (localState === null) {
99     localState = {
100       anchorPos: null,
101       awarenessData,
102       color,
103       focusPos: null,
104       focusing: focusing,
105       name,
106     };
107   }
108
109   localState.focusing = focusing;
110   awareness.setLocalState(localState);
111 }
112 export {syncCursorPositions} from './SyncCursors';
113 export {
114   syncLexicalUpdateToYjs,
115   syncYjsChangesToLexical,
116 } from './SyncEditorStates';