Several people edit one model at once through a server you run yourself (archify-vscode-ext-sync); the files stay ordinary files on each disk. Sign-in through the browser, offline-first with later merge, teammates' cursors in the Source view and text editors, and a Shared section on the model page with people, versions, Compare and Restore. Without a server nothing changes: the sync code is a separate bundle that loads only when a model is shared, after a sign-in, or when a sync command or invite link is used.
34 lines
1.4 KiB
TypeScript
34 lines
1.4 KiB
TypeScript
import * as Y from 'yjs';
|
|
import { TextChange, minimalChange } from '../util/textDiff';
|
|
|
|
const isHigh = (code: number) => code >= 0xd800 && code <= 0xdbff;
|
|
const isLow = (code: number) => code >= 0xdc00 && code <= 0xdfff;
|
|
|
|
/**
|
|
* `minimalChange`, widened so it never splits a surrogate pair: Yjs would
|
|
* replace half a pair with U+FFFD, and every copy would get the broken text.
|
|
*/
|
|
export function safeChange(before: string, after: string): TextChange | undefined {
|
|
const change = minimalChange(before, after);
|
|
if (!change) return undefined;
|
|
let { from, to } = change;
|
|
let endAfter = after.length - (before.length - to);
|
|
// A common start ending in a high surrogate, or a common end starting with
|
|
// a low one, would split a pair: take the whole character into the change.
|
|
if (from > 0 && isHigh(before.charCodeAt(from - 1))) from--;
|
|
if (to < before.length && isLow(before.charCodeAt(to))) {
|
|
to++;
|
|
endAfter++;
|
|
}
|
|
return { from, to, insert: after.slice(from, endAfter) };
|
|
}
|
|
|
|
/** Makes the Y.Text read `after` with one minimal edit; false when it already does. */
|
|
export function applyToYText(text: Y.Text, after: string): boolean {
|
|
const change = safeChange(text.toString(), after);
|
|
if (!change) return false;
|
|
if (change.to > change.from) text.delete(change.from, change.to - change.from);
|
|
if (change.insert) text.insert(change.from, change.insert);
|
|
return true;
|
|
}
|