diff --git a/01_basic.test.ts b/01_basic.test.ts index 0e9d68c..ed80e8f 100644 --- a/01_basic.test.ts +++ b/01_basic.test.ts @@ -1,4 +1,4 @@ -import { Loro, LoroList, LoroMap } from "npm:loro-crdt@0.6.3" +import { Loro, LoroList, LoroMap, LoroText } from "npm:loro-crdt@0.15.0" import { expect } from "npm:expect@29.7.0" Deno.test("Basic usage", () => { @@ -37,11 +37,11 @@ Deno.test("Sub containers", () => { const list: LoroList = doc.getList("list"); const map: LoroMap = doc.getMap("list"); // insert a List container at index 0, and get the handler to that list - const subList = list.insertContainer(0, "List"); + const subList = list.insertContainer(0, new LoroList()); subList.insert(0, "A"); expect(list.toJson()).toStrictEqual([["A"]]); // create a Text container inside the Map container - const subtext = map.setContainer("text", "Text"); + const subtext = map.setContainer("text", new LoroText()); subtext.insert(0, "Hi"); expect(map.toJson()).toStrictEqual({ text: "Hi" }); }); diff --git a/02_text.test.ts b/02_text.test.ts index a814885..77228cb 100644 --- a/02_text.test.ts +++ b/02_text.test.ts @@ -1,4 +1,4 @@ -import { Delta, Loro } from "npm:loro-crdt@0.6.3"; +import { Delta, Loro } from "npm:loro-crdt@0.15.0"; import { expect } from "npm:expect@29.7.0"; Deno.test("Text", () => { @@ -37,9 +37,10 @@ Deno.test("Rich text custom expand behavior - Bold", () => { * - Link: will not expand the style when inserting new text at the boundary. */ const doc = new Loro(); + doc.configTextStyle({ bold: { expand: "after" } }) const text = doc.getText("text"); text.insert(0, "Hello world!"); - text.mark({ start: 0, end: 5, expand: "after" }, "bold", true); + text.mark({ start: 0, end: 5 }, "bold", true); text.insert(5, "!"); expect(text.toDelta()).toStrictEqual([{ insert: "Hello!", @@ -59,9 +60,12 @@ Deno.test("Rich text custom expand behavior - Link", () => { * - Link: will not expand the style when inserting new text at the boundary. */ const doc = new Loro(); + doc.configTextStyle({ + link: { expand: "none" }, + }) const text = doc.getText("text"); text.insert(0, "Hello world!"); - text.mark({ start: 0, end: 5, expand: "none" }, "link", true); + text.mark({ start: 0, end: 5 }, "link", true); text.insert(5, "!"); expect(text.toDelta()).toStrictEqual([{ insert: "Hello", @@ -80,13 +84,15 @@ Deno.test("Rich text event", async () => { text.insert(0, "Hello world!"); doc.commit(); let ran = false; - text.subscribe(doc, (event) => { - if (event.diff.type === "text") { - expect(event.diff.diff).toStrictEqual([{ - retain: 5, - attributes: { bold: true } - }]); - ran = true; + text.subscribe((events) => { + for (const event of events.events) { + if (event.diff.type === "text") { + expect(event.diff.diff).toStrictEqual([{ + retain: 5, + attributes: { bold: true } + }]); + ran = true; + } } }); text.mark({ start: 0, end: 5 }, "bold", true); diff --git a/03_version.test.ts b/03_version.test.ts index bd72203..7492530 100644 --- a/03_version.test.ts +++ b/03_version.test.ts @@ -1,4 +1,4 @@ -import { Loro, OpId } from "npm:loro-crdt@0.6.3"; +import { Loro, OpId } from "npm:loro-crdt@0.15.0"; import { expect } from "npm:expect@29.7.0"; @@ -16,8 +16,8 @@ Deno.test("Frontiers & Version Vector Conversion", () => { doc1.commit(); const frontiers = doc1.frontiers(); - expect(frontiers).toStrictEqual([{ peer: 1n, counter: 1 } as OpId]) + expect(frontiers).toStrictEqual([{ peer: "1", counter: 1 } as OpId]) const vv = doc1.frontiersToVV(frontiers); - expect(vv).toStrictEqual(new Map([[0n, 1], [1n, 2]])) + expect(vv.toJSON()).toStrictEqual(new Map([["0", 1], ["1", 2]])) expect(doc1.vvToFrontiers(vv)).toStrictEqual(frontiers); }) diff --git a/04_time_travel.test.ts b/04_time_travel.test.ts index 51a0cd8..4ba7a26 100644 --- a/04_time_travel.test.ts +++ b/04_time_travel.test.ts @@ -1,4 +1,4 @@ -import { Loro } from "npm:loro-crdt@0.6.3"; +import { Loro } from "npm:loro-crdt@0.15.0"; import { expect } from "npm:expect@29.7.0"; Deno.test("Time Travel", () => { @@ -16,12 +16,12 @@ Deno.test("Time Travel", () => { }); // Every unicode char insertion is a single operation for Text container - doc.checkout([{ peer: 0n, counter: 0 }]); + doc.checkout([{ peer: "0", counter: 0 }]); expect(doc.toJson()).toStrictEqual({ text: "H" }); - doc.checkout([{ peer: 0n, counter: 4 }]); + doc.checkout([{ peer: "0", counter: 4 }]); expect(doc.toJson()).toStrictEqual({ text: "Hello" }); diff --git a/05_save_and_load.test.ts b/05_save_and_load.test.ts index ff57d1d..f2fb8b6 100644 --- a/05_save_and_load.test.ts +++ b/05_save_and_load.test.ts @@ -1,4 +1,4 @@ -import { Loro } from "npm:loro-crdt@0.6.3"; +import { Loro } from "npm:loro-crdt@0.15.0"; import { expect } from "npm:expect@29.7.0"; Deno.test("Save and load", () => { diff --git a/06_event.test.ts b/06_event.test.ts index 5b992ff..dd6439b 100644 --- a/06_event.test.ts +++ b/06_event.test.ts @@ -1,25 +1,27 @@ -import { Loro, LoroText, getType } from "npm:loro-crdt@0.6.3"; +import { Loro, LoroMap, LoroText, getType } from "npm:loro-crdt@0.15.0"; import { expect } from "npm:expect@29.7.0"; Deno.test("Event have delta that contains Container", async () => { const doc = new Loro(); const list = doc.getList("list"); let ran = false; - doc.subscribe(event => { - if (event.diff.type === "list") { - for (const item of event.diff.diff) { - expect(item.insert?.length).toBe(2); - expect(getType(item.insert![0])).toBe("Text") - expect(getType(item.insert![1])).toBe("Map") - const t = item.insert![0] as LoroText; - expect(t.toString()).toBe("Hello") + doc.subscribe(events => { + for (const event of events.events) { + if (event.diff.type === "list") { + for (const item of event.diff.diff) { + expect(item.insert?.length).toBe(2); + expect(getType(item.insert![0])).toBe("Text") + expect(getType(item.insert![1])).toBe("Map") + const t = item.insert![0] as LoroText; + expect(t.toString()).toBe("Hello") + } + ran = true; } - ran = true; } }) - list.insertContainer(0, "Map"); - const t = list.insertContainer(0, "Text"); + list.insertContainer(0, new LoroMap()); + const t = list.insertContainer(0, new LoroText()); t.insert(0, "He"); t.insert(2, "llo"); doc.commit(); diff --git a/07_list.test.ts b/07_list.test.ts new file mode 100644 index 0000000..a96e933 --- /dev/null +++ b/07_list.test.ts @@ -0,0 +1,33 @@ +import { Loro, LoroList, LoroMovableList, LoroText } from "npm:loro-crdt@0.15.0"; +import { expect } from "npm:expect@29.7.0"; + +Deno.test("List", () => { + let list = new LoroList(); + list.push(0); + list.push("1"); + const doc = new Loro(); + const map = doc.getMap("root"); + list = map.setContainer("list", list); + expect(doc.toJson()).toStrictEqual({ root: { list: [0, "1"] } }); + list.delete(0, 1); + expect(doc.toJson()).toStrictEqual({ root: { list: ["1"] } }); +}) + +Deno.test("MovableList", () => { + let list = new LoroMovableList(); + list.push(0); + list.push("1"); + const doc = new Loro(); + const map = doc.getMap("root"); + list = map.setContainer("list", list); + expect(doc.toJson()).toStrictEqual({ root: { list: [0, "1"] } }); + list.move(0, 1); + expect(doc.toJson()).toStrictEqual({ root: { list: ["1", 0] } }); + // Uint8Array is a special type in Loro + list.set(1, new Uint8Array([1, 2, 3])); + expect(doc.toJson()).toStrictEqual({ root: { list: ["1", new Uint8Array([1, 2, 3])] } }); + const text = list.setContainer(0, new LoroText()); + text.insert(0, "Hello") + expect(doc.toJson()).toStrictEqual({ root: { list: ["Hello", new Uint8Array([1, 2, 3])] } }); +}) + diff --git a/deno.lock b/deno.lock index f132ac0..ff2fb9e 100644 --- a/deno.lock +++ b/deno.lock @@ -3,6 +3,7 @@ "packages": { "specifiers": { "npm:expect@29.7.0": "npm:expect@29.7.0", + "npm:loro-crdt@0.15.0": "npm:loro-crdt@0.15.0", "npm:loro-crdt@0.6.2": "npm:loro-crdt@0.6.2", "npm:loro-crdt@0.6.3": "npm:loro-crdt@0.6.3" }, @@ -243,6 +244,12 @@ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dependencies": {} }, + "loro-crdt@0.15.0": { + "integrity": "sha512-fRDXQYAtrGbRKuhHcLigZItkov5veGptbObE0XkD3cUinrBlIQ60ENO9g9yd9OhowaZ16+15wEseIEyTorjX6g==", + "dependencies": { + "loro-wasm": "loro-wasm@0.15.0" + } + }, "loro-crdt@0.6.2": { "integrity": "sha512-OsNnZbtWhRMItGKJcpxC+NAXVhXiRrbSh7D07oiAyPUkH2sEXwgRXmS0JN7Qt8JU9BsreOUgsthpyesX95OGXg==", "dependencies": { @@ -255,6 +262,10 @@ "loro-wasm": "loro-wasm@0.6.1" } }, + "loro-wasm@0.15.0": { + "integrity": "sha512-BYVs3z/zs7fW2BXTwHPbVxitJ2l/EdCheT4MhH2ZQGCmi7SKHUoUZ5svW0sksuVmS9potDRcXAgtVvNtfWvCSw==", + "dependencies": {} + }, "loro-wasm@0.6.1": { "integrity": "sha512-rpkUMmbHdoDoWGE28p40Q1fxzWSxdefpqirKglHqEqlkmcU5e5aSarLltklPbf1jtT8E988v8Qx0aA98Z47emw==", "dependencies": {}