slate-yjs
Version:
Yjs bindings for Slate.
103 lines • 7.48 kB
JavaScript
import { Editor } from 'slate';
import invariant from 'tiny-invariant';
import { applyYjsEvents } from '../applyToSlate';
import applySlateOps from '../applyToYjs';
import { slateYjsOriginSymbol } from '../model';
import { toSlateDoc } from '../utils';
const IS_REMOTE = new WeakSet();
const LOCAL_OPERATIONS = new WeakMap();
const SHARED_TYPES = new WeakMap();
export const YjsEditor = {
/**
* Set the editor value to the content of the to the editor bound shared type.
*/
synchronizeValue: (e) => {
Editor.withoutNormalizing(e, () => {
e.children = toSlateDoc(e.sharedType);
e.onChange();
});
},
/**
* Returns whether the editor currently is applying remote changes.
*/
sharedType: (editor) => {
const sharedType = SHARED_TYPES.get(editor);
invariant(sharedType, 'YjsEditor without attached shared type');
return sharedType;
},
/**
* Returns whether the editor currently is applying remote changes.
*/
isRemote: (editor) => {
return IS_REMOTE.has(editor);
},
/**
* Performs an action as a remote operation.
*/
asRemote: (editor, fn) => {
const wasRemote = YjsEditor.isRemote(editor);
IS_REMOTE.add(editor);
fn();
if (!wasRemote) {
IS_REMOTE.delete(editor);
}
},
/**
* Unobserves the shared type.
*/
destroy: (editor) => {
editor.destroy();
},
};
function localOperations(editor) {
const operations = LOCAL_OPERATIONS.get(editor);
invariant(operations, 'YjsEditor without attached local operations');
return operations;
}
function trackLocalOperations(editor, operation) {
if (!YjsEditor.isRemote(editor)) {
localOperations(editor).add(operation);
}
}
/**
* Applies a slate operations to the bound shared type.
*/
function applyLocalOperations(editor) {
const editorLocalOperations = localOperations(editor);
applySlateOps(YjsEditor.sharedType(editor), Array.from(editorLocalOperations), slateYjsOriginSymbol);
editorLocalOperations.clear();
}
/**
* Apply Yjs events to slate
*/
function applyRemoteYjsEvents(editor, events) {
Editor.withoutNormalizing(editor, () => YjsEditor.asRemote(editor, () => applyYjsEvents(editor, events.filter((event) => event.transaction.origin !== slateYjsOriginSymbol))));
}
export function withYjs(editor, sharedType, { synchronizeValue = true } = {}) {
const e = editor;
e.sharedType = sharedType;
SHARED_TYPES.set(editor, sharedType);
LOCAL_OPERATIONS.set(editor, new Set());
if (synchronizeValue) {
setTimeout(() => YjsEditor.synchronizeValue(e), 0);
}
const applyEvents = (events) => applyRemoteYjsEvents(e, events);
sharedType.observeDeep(applyEvents);
const { apply, onChange, destroy } = e;
e.apply = (op) => {
trackLocalOperations(e, op);
apply(op);
};
e.onChange = () => {
applyLocalOperations(e);
onChange();
};
e.destroy = () => {
sharedType.unobserveDeep(applyEvents);
if (destroy) {
destroy();
}
};
return e;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoieWpzRWRpdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3BsdWdpbi95anNFZGl0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBYSxNQUFNLE9BQU8sQ0FBQztBQUMxQyxPQUFPLFNBQVMsTUFBTSxnQkFBZ0IsQ0FBQztBQUV2QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDakQsT0FBTyxhQUFhLE1BQU0sZUFBZSxDQUFDO0FBQzFDLE9BQU8sRUFBYyxvQkFBb0IsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUM1RCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBRXRDLE1BQU0sU0FBUyxHQUFvQixJQUFJLE9BQU8sRUFBRSxDQUFDO0FBQ2pELE1BQU0sZ0JBQWdCLEdBQW9DLElBQUksT0FBTyxFQUFFLENBQUM7QUFDeEUsTUFBTSxZQUFZLEdBQWdDLElBQUksT0FBTyxFQUFFLENBQUM7QUFRaEUsTUFBTSxDQUFDLE1BQU0sU0FBUyxHQUFHO0lBQ3ZCOztPQUVHO0lBQ0gsZ0JBQWdCLEVBQUUsQ0FBQyxDQUFZLEVBQVEsRUFBRTtRQUN2QyxNQUFNLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxFQUFFLEdBQUcsRUFBRTtZQUNoQyxDQUFDLENBQUMsUUFBUSxHQUFHLFVBQVUsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDdEMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ2YsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxVQUFVLEVBQUUsQ0FBQyxNQUFpQixFQUFjLEVBQUU7UUFDNUMsTUFBTSxVQUFVLEdBQUcsWUFBWSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM1QyxTQUFTLENBQUMsVUFBVSxFQUFFLHdDQUF3QyxDQUFDLENBQUM7UUFDaEUsT0FBTyxVQUFVLENBQUM7SUFD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