@lexical/yjs
Version:
The library provides Yjs editor bindings for Lexical.
376 lines (301 loc) • 7.92 kB
Flow
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict
*/
import type {Doc, RelativePosition, UndoManager, XmlText} from 'yjs';
import type {
DecoratorNode,
EditorState,
ElementNode,
LexicalCommand,
LexicalEditor,
LexicalNode,
LineBreakNode,
NodeMap,
NodeKey,
TextNode,
} from 'lexical';
// $FlowFixMe: todo
export type YjsEvent = Object;
export type UserState = {
anchorPos: null | RelativePosition,
color: string,
focusing: boolean,
focusPos: null | RelativePosition,
name: string,
};
export type ProviderAwareness = {
getLocalState: () => UserState | null,
getStates: () => Map<number, UserState>,
off: (type: 'update', cb: () => void) => void,
on: (type: 'update', cb: () => void) => void,
setLocalState: (UserState) => void,
};
declare interface Provider {
awareness: ProviderAwareness;
connect(): void | Promise<void>;
disconnect(): void;
off(type: 'sync', cb: (isSynced: boolean) => void): void;
// $FlowFixMe: temp
off(type: 'update', cb: (any) => void): void;
off(type: 'status', cb: ({status: string}) => void): void;
off(type: 'reload', cb: (doc: Doc) => void): void;
on(type: 'sync', cb: (isSynced: boolean) => void): void;
on(type: 'status', cb: ({status: string}) => void): void;
// $FlowFixMe: temp
on(type: 'update', cb: (any) => void): void;
on(type: 'reload', cb: (doc: Doc) => void): void;
}
export type ClientID = number;
// $FlowFixMe: work around for internal
export type XmlElement = Object;
// $FlowFixMe: work around for internal
export type YMap = Object;
// $FlowFixMe: work around for internal
export type TextOperation = {
insert?: string | mixed,
delete?: number,
retain?: number,
attributes?: {
[x: string]: mixed,
},
};
export type CursorSelection = {
anchor: {
key: NodeKey,
offset: number,
},
caret: HTMLElement,
color: string,
focus: {
key: NodeKey,
offset: number,
},
name: HTMLSpanElement,
selections: Array<HTMLElement>,
};
export type Cursor = {
color: string,
name: string,
selection: null | CursorSelection,
};
export type Binding = {
clientID: number,
collabNodeMap: Map<
NodeKey,
| CollabElementNode
| CollabTextNode
| CollabDecoratorNode
| CollabLineBreakNode,
>,
cursors: Map<ClientID, Cursor>,
cursorsContainer: null | HTMLElement,
doc: Doc,
docMap: Map<string, Doc>,
editor: LexicalEditor,
id: string,
nodeProperties: Map<string, Array<string>>,
root: CollabElementNode,
};
export type ExcludedProperties = Map<Class<LexicalNode>, Set<string>>;
declare export class CollabDecoratorNode {
_xmlElem: XmlElement;
_key: NodeKey;
_parent: CollabElementNode;
_type: string;
_unobservers: Set<() => void>;
constructor(
xmlElem: XmlElement,
parent: CollabElementNode,
type: string,
): void;
getPrevNode(nodeMap: null | NodeMap): null | DecoratorNode<{...}>;
getNode(): null | DecoratorNode<{...}>;
getSharedType(): XmlElement;
getType(): string;
getKey(): NodeKey;
getSize(): number;
getOffset(): number;
syncPropertiesFromLexical(
binding: Binding,
nextLexicalNode: DecoratorNode<{...}>,
prevNodeMap: null | NodeMap,
): void;
syncPropertiesFromYjs(
binding: Binding,
keysChanged: null | Set<string>,
): void;
destroy(binding: Binding): void;
}
declare export class CollabLineBreakNode {
_map: YMap;
_key: NodeKey;
_parent: CollabElementNode;
_type: 'linebreak';
constructor(map: YMap, parent: CollabElementNode): void;
getNode(): null | LineBreakNode;
getKey(): NodeKey;
getSharedType(): YMap;
getType(): string;
getSize(): number;
getOffset(): number;
destroy(binding: Binding): void;
}
declare export class CollabTextNode {
_map: YMap;
_key: NodeKey;
_parent: CollabElementNode;
_text: string;
_type: string;
_normalized: boolean;
constructor(
map: YMap,
text: string,
parent: CollabElementNode,
type: string,
): void;
getPrevNode(nodeMap: null | NodeMap): null | TextNode;
getNode(): null | TextNode;
getSharedType(): YMap;
getType(): string;
getKey(): NodeKey;
getSize(): number;
getOffset(): number;
spliceText(index: number, delCount: number, newText: string): void;
syncPropertiesAndTextFromLexical(
binding: Binding,
nextLexicalNode: TextNode,
prevNodeMap: null | NodeMap,
): void;
syncPropertiesAndTextFromYjs(
binding: Binding,
keysChanged: null | Set<string>,
): void;
destroy(binding: Binding): void;
}
type IntentionallyMarkedAsDirtyElement = boolean;
declare export class CollabElementNode {
_key: NodeKey;
_children: Array<
| CollabElementNode
| CollabTextNode
| CollabDecoratorNode
| CollabLineBreakNode,
>;
_xmlText: XmlText;
_type: string;
_parent: null | CollabElementNode;
constructor(
xmlText: XmlText,
parent: null | CollabElementNode,
type: string,
): void;
getPrevNode(nodeMap: null | NodeMap): null | ElementNode;
getNode(): null | ElementNode;
getSharedType(): XmlText;
getType(): string;
getKey(): NodeKey;
isEmpty(): boolean;
getSize(): number;
getOffset(): number;
syncPropertiesFromYjs(
binding: Binding,
keysChanged: null | Set<string>,
): void;
applyChildrenYjsDelta(binding: Binding, deltas: Array<TextOperation>): void;
syncChildrenFromYjs(binding: Binding): void;
syncPropertiesFromLexical(
binding: Binding,
nextLexicalNode: ElementNode,
prevNodeMap: null | NodeMap,
): void;
_syncChildFromLexical(
binding: Binding,
index: number,
key: NodeKey,
prevNodeMap: null | NodeMap,
dirtyElements: null | Map<NodeKey, IntentionallyMarkedAsDirtyElement>,
dirtyLeaves: null | Set<NodeKey>,
): void;
syncChildrenFromLexical(
binding: Binding,
nextLexicalNode: ElementNode,
prevNodeMap: null | NodeMap,
dirtyElements: null | Map<NodeKey, IntentionallyMarkedAsDirtyElement>,
dirtyLeaves: null | Set<NodeKey>,
): void;
append(
collabNode:
| CollabElementNode
| CollabDecoratorNode
| CollabTextNode
| CollabLineBreakNode,
): void;
splice(
binding: Binding,
index: number,
delCount: number,
collabNode?:
| CollabElementNode
| CollabDecoratorNode
| CollabTextNode
| CollabLineBreakNode,
): void;
getChildOffset(
collabNode:
| CollabElementNode
| CollabTextNode
| CollabDecoratorNode
| CollabLineBreakNode,
): number;
destroy(binding: Binding): void;
}
declare export function createUndoManager(
binding: Binding,
root: XmlText,
): UndoManager;
declare export function initLocalState(
provider: Provider,
name: string,
color: string,
focusing: boolean,
): void;
declare export function setLocalStateFocus(
provider: Provider,
name: string,
color: string,
focusing: boolean,
): void;
declare export function createBinding(
editor: LexicalEditor,
provider: Provider,
id: string,
doc: ?Doc,
docMap: Map<string, Doc>,
): Binding;
declare export function syncCursorPositions(
binding: Binding,
provider: Provider,
): void;
declare export function syncLexicalUpdateToYjs(
binding: Binding,
provider: Provider,
prevEditorState: EditorState,
currEditorState: EditorState,
dirtyElements: Map<NodeKey, IntentionallyMarkedAsDirtyElement>,
dirtyLeaves: Set<NodeKey>,
normalizedNodes: Set<NodeKey>,
tags: Set<string>,
): void;
declare export function syncYjsChangesToLexical(
binding: Binding,
provider: Provider,
events: Array<YjsEvent>,
): void;
declare export var CONNECTED_COMMAND: LexicalCommand<boolean>;
declare export var TOGGLE_CONNECT_COMMAND: LexicalCommand<boolean>;
export type {Provider};