Skip to content

Commit

Permalink
feat: support loro-crdt v1
Browse files Browse the repository at this point in the history
  • Loading branch information
ocavue authored and zxch3n committed Oct 25, 2024
1 parent bebd829 commit 901f50d
Show file tree
Hide file tree
Showing 9 changed files with 50 additions and 50 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ import {
undo,
redo,
} from "loro-prosemirror";
import { Loro } from "loro-crdt";
import { LoroDoc } from "loro-crdt";

const doc = new Loro();
const doc = new LoroDoc();
const awareness = new CursorAwareness(doc.peerIdStr);
const plugins = [
...pmPlugins,
Expand Down
2 changes: 1 addition & 1 deletion examples/stories/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"build-storybook": "storybook build"
},
"dependencies": {
"loro-crdt": "^0.16.3",
"loro-crdt": "^1.0.7",
"loro-prosemirror": "*",
"prosemirror-commands": "^1.5.2",
"prosemirror-example-setup": "^1.2.2",
Expand Down
12 changes: 6 additions & 6 deletions examples/stories/src/stories/Editor.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { Meta } from "@storybook/react";

import { Editor } from "./Editor";
import { Loro } from "loro-crdt";
import { CursorAwareness, LoroDocType } from "loro-prosemirror";
import { useEffect, useRef } from "react";
import { CursorAwareness } from "loro-prosemirror";
import { Editor } from "./Editor";
import { LoroDoc } from "loro-crdt";

const meta = {
title: "Editor/Basic",
Expand All @@ -17,7 +17,7 @@ const meta = {
export default meta;

export const Basic = () => {
const loroARef = useRef<Loro>(new Loro());
const loroARef = useRef<LoroDocType>(new LoroDoc());
const idA = loroARef.current.peerIdStr;
const awarenessA = useRef<CursorAwareness>(new CursorAwareness(idA));
return (
Expand All @@ -28,10 +28,10 @@ export const Basic = () => {
};

export const Sync = () => {
const loroARef = useRef<Loro>(new Loro());
const loroARef = useRef<LoroDocType>(new LoroDoc());
const idA = loroARef.current.peerIdStr;
const awarenessA = useRef<CursorAwareness>(new CursorAwareness(idA));
const loroBRef = useRef<Loro>(new Loro());
const loroBRef = useRef<LoroDocType>(new LoroDoc());
const idB = loroBRef.current.peerIdStr;
const awarenessB = useRef<CursorAwareness>(new CursorAwareness(idB));
useEffect(() => {
Expand Down
9 changes: 5 additions & 4 deletions examples/stories/src/stories/Editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@ import {
LoroUndoPlugin,
undo,
redo,
LoroDocType,
} from "loro-prosemirror";
import "./Editor.css";
import { Loro } from "loro-crdt";
import { LoroDoc } from "loro-crdt";
import { buildMenuItems } from "./menu";

const mySchema = new Schema({
Expand All @@ -33,9 +34,9 @@ export function Editor({
awareness,
onCreateLoro,
}: {
loro?: Loro;
loro?: LoroDocType;
awareness?: CursorAwareness;
onCreateLoro?: (loro: Loro) => void;
onCreateLoro?: (loro: LoroDocType) => void;
}) {
const editorRef = useRef<null | EditorView>(null);
const editorDom = useRef(null);
Expand All @@ -49,7 +50,7 @@ export function Editor({
useEffect(() => {
if (editorRef.current) return;
if (!loroRef.current) {
loroRef.current = new Loro();
loroRef.current = new LoroDoc();
onCreateLoro?.(loroRef.current);
}

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"lib0": "^0.2.42"
},
"peerDependencies": {
"loro-crdt": "^0.16.3",
"loro-crdt": "^1.0.7",
"prosemirror-model": "^1.18.1",
"prosemirror-state": "^1.4.1",
"prosemirror-view": "^1.28.0"
Expand Down
19 changes: 10 additions & 9 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions src/lib.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { simpleDiff } from "lib0/diff";
import { equalityDeep } from "lib0/function";

import type { ContainerID } from 'loro-crdt';
import type { ContainerID, LoroDoc } from 'loro-crdt';
import {
type Delta,
Loro,
Expand All @@ -23,7 +23,7 @@ type LoroNodeContainerType = {
[NODE_NAME_KEY]: string
}

export type LoroDocType = Loro<{
export type LoroDocType = LoroDoc<{
doc: LoroMap<LoroNodeContainerType>
}>;
export type LoroNode = LoroMap<LoroNodeContainerType>
Expand Down Expand Up @@ -79,9 +79,9 @@ export function updateLoroToPmState(

updateLoroMap(map, node, mapping);
if (isInit) {
doc.commit("sys:init")
doc.commit({ origin: "sys:init" });
} else {
doc.commit("loroSyncPlugin");
doc.commit({ origin: "loroSyncPlugin" });
}
}

Expand Down
15 changes: 8 additions & 7 deletions src/sync-plugin.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { Loro, type LoroEventBatch } from "loro-crdt";
import type { LoroEventBatch, Subscription } from "loro-crdt";
import { Fragment, Slice } from "prosemirror-model";
import {
EditorState,
Plugin,
PluginKey,
type StateField,
EditorState,
} from "prosemirror-state";
import { EditorView } from "prosemirror-view";
import { Slice, Fragment } from "prosemirror-model";
import {
type LoroDocType,
type LoroNodeMapping,
Expand Down Expand Up @@ -38,9 +38,9 @@ export interface LoroSyncPluginProps {
export interface LoroSyncPluginState extends LoroSyncPluginProps {
changedBy: "local" | "import" | "checkout";
mapping: LoroNodeMapping;
snapshot?: Loro | null;
snapshot?: LoroDocType | null;
view?: EditorView;
docSubscription?: number | null;
docSubscription?: Subscription | null;
}

export const LoroSyncPlugin = (props: LoroSyncPluginProps): Plugin => {
Expand Down Expand Up @@ -77,7 +77,7 @@ export const LoroSyncPlugin = (props: LoroSyncPluginProps): Plugin => {
break;
case "update-state":
state = { ...state, ...meta.state };
state.doc.commit("sys:init");
state.doc.commit({ origin: "sys:init" });
break;
default:
break;
Expand Down Expand Up @@ -109,9 +109,10 @@ export const LoroSyncPlugin = (props: LoroSyncPluginProps): Plugin => {
function init(view: EditorView) {
const state = loroSyncPluginKey.getState(view.state) as LoroSyncPluginState;


let docSubscription = state.docSubscription;
if (docSubscription != null) {
state.doc.unsubscribe(docSubscription);
docSubscription()
}
docSubscription = state.doc.subscribe((event) => updateNodeOnLoroEvent(view, event));

Expand Down
29 changes: 13 additions & 16 deletions tests/basic.test.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,24 @@
import { describe, assert, expect, test } from "vitest";
import { describe, expect, test } from "vitest";

import { Node, Schema, type NodeSpec, type MarkSpec } from "prosemirror-model";
import { EditorState } from "prosemirror-state";
import { Loro, LoroText } from "loro-crdt";
import { LoroDoc, LoroText } from "loro-crdt";

import {
type LoroDocType,
type LoroNodeMapping,
ROOT_DOC_KEY,
clearChangedNodes,
createNodeFromLoroObj,
getLoroMapAttributes,
getLoroMapChildren,
updateLoroToPmState,
type LoroDocType,
type LoroNodeMapping,
} from "../src/lib";

import { schema } from "./schema";
import {
createEditorState,
insertLoroMap,
insertLoroText,
setupLoroMap,
oneMs,
setupLoroMap,
} from "./utils";

const examplePmContent = {
Expand Down Expand Up @@ -196,14 +193,14 @@ const exampleLoroContent = {
describe("updateDoc", () => {
test("empty doc gets populated correctly", () => {
const editorState = createEditorState(schema, examplePmContent.doc);
const loroDoc: LoroDocType = new Loro();
const loroDoc: LoroDocType = new LoroDoc();
const mapping: LoroNodeMapping = new Map();
updateLoroToPmState(loroDoc, mapping, editorState);
expect(loroDoc.toJSON()).toEqual(exampleLoroContent);
});

test("doc syncs changes correctly", () => {
const loroDoc: LoroDocType = new Loro();
const loroDoc: LoroDocType = new LoroDoc();
const mapping: LoroNodeMapping = new Map();

// First we create an empty content
Expand Down Expand Up @@ -393,21 +390,21 @@ describe("createNodeFromLoroObj", () => {
// FIXME: Reusing the logic here to populate the loro doc as its
// json representation doesn't contain text marks
const _editorState = createEditorState(schema, examplePmContent.doc);
const loroDoc: LoroDocType = new Loro();
const loroDoc: LoroDocType = new LoroDoc();
const mapping: LoroNodeMapping = new Map();
updateLoroToPmState(loroDoc, mapping, _editorState);

const node = createNodeFromLoroObj(
schema,
loroDoc.getMap(ROOT_DOC_KEY),
mapping,
mapping
);
const editorState = createEditorState(schema, examplePmContent.doc);
expect(editorState.toJSON()).toEqual(examplePmContent);
});

test("node syncs changes correctly", async () => {
const loroDoc: LoroDocType = new Loro();
const loroDoc: LoroDocType = new LoroDoc();
const mapping: LoroNodeMapping = new Map();

loroDoc.subscribe((event) => clearChangedNodes(loroDoc, event, mapping));
Expand Down Expand Up @@ -492,20 +489,20 @@ describe("createNodeFromLoroObj", () => {
// Now lets add a bullet list
const bulletList = insertLoroMap(
getLoroMapChildren(loroInnerDoc),
"bulletList",
"bulletList"
);
const bullet1 = insertLoroMap(getLoroMapChildren(bulletList), "listItem");
const bullet1Paragraph = insertLoroMap(
getLoroMapChildren(bullet1),
"paragraph",
"paragraph"
);
const bullet1Text = insertLoroText(getLoroMapChildren(bullet1Paragraph));
bullet1Text.insert(0, "Bullet 1");

const bullet2 = insertLoroMap(getLoroMapChildren(bulletList), "listItem");
const bullet2Paragraph = insertLoroMap(
getLoroMapChildren(bullet2),
"paragraph",
"paragraph"
);
const bullet2Text = insertLoroText(getLoroMapChildren(bullet2Paragraph));
bullet2Text.insert(0, "Bullet 2");
Expand Down

0 comments on commit 901f50d

Please sign in to comment.