From 0a421d3931084af604130f0817bd2790e90cab45 Mon Sep 17 00:00:00 2001 From: Zixuan Chen Date: Fri, 24 Mar 2023 18:00:33 +0800 Subject: [PATCH] fix: add event diff test & fix related bugs --- crates/loro-internal/src/value.rs | 22 ++++--- loro-js/src/index.ts | 25 +++++--- loro-js/tests/event.test.ts | 100 +++++++++++++++++++++++++++++- 3 files changed, 131 insertions(+), 16 deletions(-) diff --git a/crates/loro-internal/src/value.rs b/crates/loro-internal/src/value.rs index e1f53db6..c4c67432 100644 --- a/crates/loro-internal/src/value.rs +++ b/crates/loro-internal/src/value.rs @@ -501,7 +501,7 @@ pub mod wasm { let added = Object::new(); for (key, value) in value.added.iter() { js_sys::Reflect::set( - &obj, + &added, &JsValue::from_str(key), &JsValue::from(value.clone()), ) @@ -515,7 +515,7 @@ pub mod wasm { let deleted = Object::new(); for (key, value) in value.deleted.iter() { js_sys::Reflect::set( - &obj, + &deleted, &JsValue::from_str(key), &JsValue::from(value.clone()), ) @@ -529,12 +529,20 @@ pub mod wasm { let updated = Object::new(); for (key, pair) in value.updated.iter() { let pair_obj = Object::new(); - js_sys::Reflect::set(&obj, &JsValue::from_str("old"), &pair.old.clone().into()) - .unwrap(); - js_sys::Reflect::set(&obj, &JsValue::from_str("new"), &pair.new.clone().into()) - .unwrap(); js_sys::Reflect::set( - &obj, + &pair_obj, + &JsValue::from_str("old"), + &pair.old.clone().into(), + ) + .unwrap(); + js_sys::Reflect::set( + &pair_obj, + &JsValue::from_str("new"), + &pair.new.clone().into(), + ) + .unwrap(); + js_sys::Reflect::set( + &updated, &JsValue::from_str(key), &pair_obj.into_js_result().unwrap(), ) diff --git a/loro-js/src/index.ts b/loro-js/src/index.ts index 4c1ce8e5..4dd21170 100644 --- a/loro-js/src/index.ts +++ b/loro-js/src/index.ts @@ -50,25 +50,34 @@ export type Delta = { len: number; }; -export type Diff = { +export type ListDiff = { type: "list"; - diff: Delta; -} | { - type: "list"; - diff: Delta; -} | { + diff: Delta[]; +}; + +export type TextDiff = { + type: "text"; + diff: Delta[]; +}; + +export type MapDIff = { type: "map"; diff: { added: Record; deleted: Record; - updated: Record; + updated: Record; }; }; +export type Diff = ListDiff | TextDiff | MapDIff; + export interface LoroEvent { local: boolean; origin?: string; - diff: Diff; + diff: Diff[]; target: ContainerID; path: Path; } diff --git a/loro-js/tests/event.test.ts b/loro-js/tests/event.test.ts index 572f8026..548a4952 100644 --- a/loro-js/tests/event.test.ts +++ b/loro-js/tests/event.test.ts @@ -1,5 +1,13 @@ import { describe, expect, it } from "vitest"; -import { Loro, LoroEvent, LoroMap } from "../src"; +import { + Diff, + ListDiff, + Loro, + LoroEvent, + LoroMap, + MapDIff as MapDiff, + TextDiff, +} from "../src"; describe("event", () => { it("target", async () => { @@ -29,10 +37,100 @@ describe("event", () => { const list = subMap.insertContainer(loro, "list", "List"); list.insert(loro, 0, "2"); const text = list.insertContainer(loro, 1, "Text"); + await zeroMs(); text.insert(loro, 0, "3"); await zeroMs(); expect(lastEvent?.path).toStrictEqual(["map", "sub", "list", 1]); }); + + it("text diff", async () => { + const loro = new Loro(); + let lastEvent: undefined | LoroEvent; + loro.subscribe((event) => { + lastEvent = event; + }); + const text = loro.getText("t"); + text.insert(loro, 0, "3"); + await zeroMs(); + expect(lastEvent?.diff).toStrictEqual( + [{ type: "text", diff: [{ type: "insert", value: "3" }] } as TextDiff], + ); + text.insert(loro, 1, "12"); + await zeroMs(); + expect(lastEvent?.diff).toStrictEqual( + [{ + type: "text", + diff: [{ type: "retain", len: 1 }, { type: "insert", value: "12" }], + } as TextDiff], + ); + }); + + it("list diff", async () => { + const loro = new Loro(); + let lastEvent: undefined | LoroEvent; + loro.subscribe((event) => { + lastEvent = event; + }); + const text = loro.getList("l"); + text.insert(loro, 0, "3"); + await zeroMs(); + expect(lastEvent?.diff).toStrictEqual( + [{ type: "list", diff: [{ type: "insert", value: ["3"] }] } as ListDiff], + ); + text.insert(loro, 1, "12"); + await zeroMs(); + expect(lastEvent?.diff).toStrictEqual( + [{ + type: "list", + diff: [{ type: "retain", len: 1 }, { type: "insert", value: ["12"] }], + } as ListDiff], + ); + }); + + it("map diff", async () => { + const loro = new Loro(); + let lastEvent: undefined | LoroEvent; + loro.subscribe((event) => { + lastEvent = event; + }); + const map = loro.getMap("m"); + loro.transact((tx) => { + map.set(tx, "0", "3"); + map.set(tx, "1", "2"); + }); + await zeroMs(); + expect(lastEvent?.diff).toStrictEqual( + [{ + type: "map", + diff: { + added: { + "0": "3", + "1": "2", + }, + deleted: {}, + updated: {}, + }, + } as MapDiff], + ); + loro.transact((tx) => { + map.set(tx, "0", "0"); + map.set(tx, "1", "1"); + }); + await zeroMs(); + expect(lastEvent?.diff).toStrictEqual( + [{ + type: "map", + diff: { + added: {}, + updated: { + "0": { old: "3", new: "0" }, + "1": { old: "2", new: "1" }, + }, + deleted: {}, + }, + } as MapDiff], + ); + }); }); function zeroMs(): Promise {