fix: wasm change peerid should be bigint

This commit is contained in:
Zixuan Chen 2023-11-12 20:36:38 +08:00
parent c297534607
commit 48611c5f15
No known key found for this signature in database
2 changed files with 37 additions and 31 deletions

View file

@ -1,6 +1,6 @@
use js_sys::{Array, Object, Promise, Reflect, Uint8Array}; use js_sys::{Array, Object, Promise, Reflect, Uint8Array};
use loro_internal::{ use loro_internal::{
change::{Lamport, Timestamp}, change::Lamport,
container::{ container::{
richtext::{ExpandType, TextStyleInfoFlag}, richtext::{ExpandType, TextStyleInfoFlag},
ContainerID, ContainerID,
@ -198,11 +198,18 @@ fn js_value_to_version(version: &JsValue) -> Result<VersionVector, JsValue> {
#[derive(Debug, Clone, Serialize)] #[derive(Debug, Clone, Serialize)]
struct ChangeMeta { struct ChangeMeta {
lamport: Lamport, lamport: Lamport,
length: usize, length: u32,
peer: PeerID, peer: PeerID,
counter: Counter, counter: Counter,
deps: Vec<ID>, deps: Vec<ID>,
timestamp: Timestamp, timestamp: f64,
}
impl ChangeMeta {
fn to_js(&self) -> JsValue {
let s = serde_wasm_bindgen::Serializer::new().serialize_large_number_types_as_bigints(true);
self.serialize(&s).unwrap()
}
} }
#[wasm_bindgen] #[wasm_bindgen]
@ -632,7 +639,7 @@ impl Loro {
/// const text = list.insertContainer(0, "Text"); /// const text = list.insertContainer(0, "Text");
/// text.insert(0, "Hello"); /// text.insert(0, "Hello");
/// const map = list.insertContainer(1, "Map"); /// const map = list.insertContainer(1, "Map");
/// map.set("foo", "bar"); /// map.set("foo", "bar");
/// /* /// /*
/// {"list": ["Hello", {"foo": "bar"}]} /// {"list": ["Hello", {"foo": "bar"}]}
/// *\/ /// *\/
@ -728,13 +735,13 @@ impl Loro {
for (i, change) in changes.iter().enumerate() { for (i, change) in changes.iter().enumerate() {
let change = ChangeMeta { let change = ChangeMeta {
lamport: change.lamport, lamport: change.lamport,
length: change.atom_len(), length: change.atom_len() as u32,
peer: change.peer(), peer: change.peer(),
counter: change.id.counter, counter: change.id.counter,
deps: change.deps.iter().cloned().collect(), deps: change.deps.iter().cloned().collect(),
timestamp: change.timestamp, timestamp: change.timestamp as f64,
}; };
row.set(i as u32, serde_wasm_bindgen::to_value(&change).unwrap()); row.set(i as u32, change.to_js());
} }
ans.set(&js_sys::BigInt::from(*peer_id).into(), &row); ans.set(&js_sys::BigInt::from(*peer_id).into(), &row);
} }
@ -753,13 +760,13 @@ impl Loro {
.ok_or_else(|| JsError::new(&format!("Change {:?} not found", id)))?; .ok_or_else(|| JsError::new(&format!("Change {:?} not found", id)))?;
let change = ChangeMeta { let change = ChangeMeta {
lamport: change.lamport, lamport: change.lamport,
length: change.atom_len(), length: change.atom_len() as u32,
peer: change.peer(), peer: change.peer(),
counter: change.id.counter, counter: change.id.counter,
deps: change.deps.iter().cloned().collect(), deps: change.deps.iter().cloned().collect(),
timestamp: change.timestamp, timestamp: change.timestamp as f64,
}; };
Ok(serde_wasm_bindgen::to_value(&change).unwrap().into()) Ok(change.to_js().into())
} }
/// Get all ops of the change of a specific ID /// Get all ops of the change of a specific ID
@ -1939,12 +1946,12 @@ fn vv_to_js_value(vv: VersionVector) -> JsValue {
const TYPES: &'static str = r#" const TYPES: &'static str = r#"
/** /**
* Container types supported by loro. * Container types supported by loro.
* *
* It is most commonly used to specify the type of subcontainer to be created. * It is most commonly used to specify the type of subcontainer to be created.
* @example * @example
* ```ts * ```ts
* import { Loro } from "loro-crdt"; * import { Loro } from "loro-crdt";
* *
* const doc = new Loro(); * const doc = new Loro();
* const list = doc.getList("list"); * const list = doc.getList("list");
* list.insert(0, 100); * list.insert(0, 100);
@ -1956,11 +1963,11 @@ export type ContainerType = "Text" | "Map" | "List"| "Tree";
/** /**
* The unique id of each container. * The unique id of each container.
* *
* @example * @example
* ```ts * ```ts
* import { Loro } from "loro-crdt"; * import { Loro } from "loro-crdt";
* *
* const doc = new Loro(); * const doc = new Loro();
* const list = doc.getList("list"); * const list = doc.getList("list");
* const containerId = list.id; * const containerId = list.id;
@ -1985,14 +1992,14 @@ interface Loro {
* @typeparam T - The data type for the `insert` operation. * @typeparam T - The data type for the `insert` operation.
* *
* The `Delta` type can be one of three distinct shapes: * The `Delta` type can be one of three distinct shapes:
* *
* 1. Insert Operation: * 1. Insert Operation:
* - `insert`: The item to be inserted, of type T. * - `insert`: The item to be inserted, of type T.
* - `attributes`: (Optional) A dictionary of attributes, describing styles in richtext * - `attributes`: (Optional) A dictionary of attributes, describing styles in richtext
* *
* 2. Delete Operation: * 2. Delete Operation:
* - `delete`: The number of elements to delete. * - `delete`: The number of elements to delete.
* *
* 3. Retain Operation: * 3. Retain Operation:
* - `retain`: The number of elements to retain. * - `retain`: The number of elements to retain.
* - `attributes`: (Optional) A dictionary of attributes, describing styles in richtext * - `attributes`: (Optional) A dictionary of attributes, describing styles in richtext
@ -2024,7 +2031,7 @@ export type OpId = { peer: bigint, counter: number };
* Change is a group of continuous operations * Change is a group of continuous operations
*/ */
export interface Change { export interface Change {
peer: BigInt, peer: bigint,
counter: number, counter: number,
lamport: number, lamport: number,
length: number, length: number,

View file

@ -1,10 +1,5 @@
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
import { import { Loro, toReadableVersion, setPanicHook, OpId } from "../src";
Loro,
toReadableVersion,
setPanicHook,
OpId,
} from "../src";
setPanicHook(); setPanicHook();
describe("Frontiers", () => { describe("Frontiers", () => {
@ -52,23 +47,27 @@ describe("Version", () => {
expect(toReadableVersion(a.version())).toStrictEqual(vv); expect(toReadableVersion(a.version())).toStrictEqual(vv);
expect(a.vvToFrontiers(vv)).toStrictEqual(a.frontiers()); expect(a.vvToFrontiers(vv)).toStrictEqual(a.frontiers());
expect(a.vvToFrontiers(a.version())).toStrictEqual(a.frontiers()); expect(a.vvToFrontiers(a.version())).toStrictEqual(a.frontiers());
expect(a.frontiers()).toStrictEqual([{ peer: 0n, counter: 2 }] as OpId[]) expect(a.frontiers()).toStrictEqual([{ peer: 0n, counter: 2 }] as OpId[]);
} }
}) });
it("get changes", () => { it("get changes", () => {
const changes = a.getAllChanges(); const changes = a.getAllChanges();
expect(typeof changes.get(0n)?.[0].peer == "bigint").toBeTruthy();
expect(changes.size).toBe(2); expect(changes.size).toBe(2);
expect(changes.get(0n)?.length).toBe(2); expect(changes.get(0n)?.length).toBe(2);
expect(changes.get(0n)?.[0].length).toBe(2); expect(changes.get(0n)?.[0].length).toBe(2);
expect(changes.get(0n)?.[1].lamport).toBe(2); expect(changes.get(0n)?.[1].lamport).toBe(2);
expect(changes.get(0n)?.[1].deps).toStrictEqual([{ peer: 0, counter: 1 }, { peer: 1, counter: 1 }]); expect(changes.get(0n)?.[1].deps).toStrictEqual([
{ peer: 0n, counter: 1 },
{ peer: 1n, counter: 1 },
]);
expect(changes.get(1n)?.length).toBe(1); expect(changes.get(1n)?.length).toBe(1);
}) });
it("get ops inside changes", () => { it("get ops inside changes", () => {
const change = a.getOpsInChange({ peer: 0n, counter: 2 }); const change = a.getOpsInChange({ peer: 0n, counter: 2 });
expect(change.length).toBe(1); expect(change.length).toBe(1);
console.dir(change, { depth: 100 }) console.dir(change, { depth: 100 });
}) });
}) });