chore: rename position to fractional_index (#381)

Breaking Change:
- rename `position` to `fractional_index`
This commit is contained in:
Leon Zhao 2024-07-11 22:03:48 +08:00 committed by GitHub
parent 86c760abd0
commit 00e7bf2911
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 53 additions and 68 deletions

View file

@ -341,47 +341,6 @@ pub trait ActorTrait {
}
pub fn assert_value_eq(a: &LoroValue, b: &LoroValue) {
fn eq_without_position(a: &LoroValue, b: &LoroValue) -> bool {
match (a, b) {
(LoroValue::Map(a), LoroValue::Map(b)) => {
for (k, v) in a.iter() {
if k == "position" {
continue;
}
if !eq_without_position(v, b.get(k).unwrap_or(&LoroValue::I64(0))) {
return false;
}
}
for (k, v) in b.iter() {
if k == "position" {
continue;
}
if !eq_without_position(v, a.get(k).unwrap_or(&LoroValue::I64(0))) {
return false;
}
}
true
}
(LoroValue::List(a), LoroValue::List(b)) => {
if a.len() != b.len() {
return false;
}
if is_tree_values(a.as_ref()) {
assert_tree_value_eq(a, b);
true
} else {
a.iter()
.zip(b.iter())
.all(|(a, b)| eq_without_position(a, b))
}
}
(a, b) => a == b,
}
}
#[must_use]
fn eq(a: &LoroValue, b: &LoroValue) -> bool {
match (a, b) {
@ -425,10 +384,10 @@ pub fn assert_value_eq(a: &LoroValue, b: &LoroValue) {
assert_tree_value_eq(a_list, b_list);
true
} else {
eq_without_position(a, b)
a_list.iter().zip(b_list.iter()).all(|(a, b)| eq(a, b))
}
}
(a, b) => eq_without_position(a, b),
(a, b) => a == b,
}
}
assert!(
@ -445,7 +404,7 @@ pub fn is_tree_values(value: &[LoroValue]) -> bool {
return map_keys.contains("id")
&& map_keys.contains("parent")
&& map_keys.contains("meta")
&& map_keys.contains("position");
&& map_keys.contains("fractional_index");
}
false
}
@ -477,7 +436,7 @@ impl FlatNode {
let meta = map.get("meta").unwrap().as_map().unwrap().as_ref().clone();
let index = *map.get("index").unwrap().as_i64().unwrap() as usize;
let position = map
.get("position")
.get("fractional_index")
.unwrap()
.as_string()
.unwrap()
@ -497,7 +456,6 @@ impl Node {
let mut node_map = FxHashMap::default();
let mut parent_child_map = FxHashMap::default();
// 首先将所有扁平节点转换为TreeNode并存储在HashMap中以便快速查找
for flat_node in value.iter() {
let flat_node = FlatNode::from_loro_value(flat_node);
let tree_node = Node {

View file

@ -507,7 +507,7 @@ impl TreeNode {
None => LoroValue::Null,
},
);
map.insert("position".to_string(), self.position.clone().into());
map.insert("fractional_index".to_string(), self.position.clone().into());
map.insert("index".to_string(), (index as i64).into());
map
}

View file

@ -3857,7 +3857,7 @@ mod test {
.unwrap();
assert_eq!(meta, 123.into());
assert_eq!(
r#"[{"parent":null,"meta":{"a":123},"id":"0@1","index":0,"position":"80"}]"#,
r#"[{"parent":null,"meta":{"a":123},"id":"0@1","index":0,"fractional_index":"80"}]"#,
tree.get_deep_value().to_json()
);
let bytes = loro.export_snapshot();

View file

@ -1157,7 +1157,10 @@ impl TreeNode {
self.id.associated_meta_container().into(),
);
t.insert("index".to_string(), (self.index as i64).into());
t.insert("position".to_string(), self.position.to_string().into());
t.insert(
"fractional_index".to_string(),
self.position.to_string().into(),
);
t.into()
}
}

View file

@ -563,7 +563,7 @@ pub mod wasm {
js_sys::Reflect::set(&obj, &"index".into(), &(*index).into()).unwrap();
js_sys::Reflect::set(
&obj,
&"position".into(),
&"fractional_index".into(),
&position.to_string().into(),
)
.unwrap();
@ -583,7 +583,7 @@ pub mod wasm {
js_sys::Reflect::set(&obj, &"index".into(), &(*index).into()).unwrap();
js_sys::Reflect::set(
&obj,
&"position".into(),
&"fractional_index".into(),
&position.to_string().into(),
)
.unwrap();

View file

@ -3184,7 +3184,7 @@ impl LoroTree {
/// but also the metadata, you should use `toJson()`.
///
// TODO: perf
#[wasm_bindgen(js_name = "toArray")]
#[wasm_bindgen(js_name = "toArray", skip_typescript)]
pub fn to_array(&mut self) -> JsResult<Array> {
let value = self.handler.get_value().into_list().unwrap();
let ans = Array::new();
@ -3204,13 +3204,17 @@ impl LoroTree {
.unwrap_or(JsValue::undefined())
.into();
let index = *v["index"].as_i64().unwrap() as u32;
let position = v["position"].as_string().unwrap();
let position = v["fractional_index"].as_string().unwrap();
let map: LoroMap = self.get_node_by_id(&id).unwrap().data()?;
let obj = Object::new();
js_sys::Reflect::set(&obj, &"id".into(), &id)?;
js_sys::Reflect::set(&obj, &"parent".into(), &parent)?;
js_sys::Reflect::set(&obj, &"index".into(), &JsValue::from(index))?;
js_sys::Reflect::set(&obj, &"position".into(), &JsValue::from_str(position))?;
js_sys::Reflect::set(
&obj,
&"fractional_index".into(),
&JsValue::from_str(position),
)?;
js_sys::Reflect::set(&obj, &"meta".into(), &map.into())?;
ans.push(&obj);
}
@ -4144,6 +4148,18 @@ interface LoroList {
getCursor(pos: number, side?: Side): Cursor | undefined;
}
export type TreeNodeValue = {
id: TreeID,
parent: TreeID | undefined,
index: number,
fractionalIndex: string,
meta: LoroMap,
}
interface LoroTree{
toArray(): TreeNodeValue[];
}
interface LoroMovableList {
/**
* Get the cursor position at the given pos.

View file

@ -402,7 +402,7 @@ fn tree() {
root_meta.insert("color", "red").unwrap();
assert_eq!(
tree.get_value_with_meta().to_json(),
r#"[{"parent":null,"meta":{"color":"red"},"id":"0@1","index":0,"position":"80"},{"parent":"0@1","meta":{},"id":"1@1","index":0,"position":"80"}]"#
r#"[{"parent":null,"meta":{"color":"red"},"id":"0@1","index":0,"fractional_index":"80"},{"parent":"0@1","meta":{},"id":"1@1","index":0,"fractional_index":"80"}]"#
)
}

View file

@ -23,9 +23,10 @@ describe("compatibility", () => {
docA.getMap("map").set("key", "123");
docA.getList("list").insert(0, 1);
docA.getList("list").insert(0, "1");
const t = docA.getTree("tree");
const node = t.createNode();
t.createNode(node.id, 0);
// TODO: rename
// const t = docA.getTree("tree");
// const node = t.createNode();
// t.createNode(node.id, 0);
const bytes = docA.exportFrom();
const docB = new OLD.Loro();
@ -40,9 +41,9 @@ describe("compatibility", () => {
docA.getMap("map").set("key", "123");
docA.getList("list").insert(0, 1);
docA.getList("list").insert(0, "1");
const t = docA.getTree("tree");
const node = t.createNode();
t.createNode(node.id, 0);
// const t = docA.getTree("tree");
// const node = t.createNode();
// t.createNode(node.id, 0);
const bytes = docA.exportSnapshot();
const docB = new OLD.Loro();
@ -57,9 +58,9 @@ describe("compatibility", () => {
docA.getMap("map").set("key", "123");
docA.getList("list").insert(0, 1);
docA.getList("list").insert(0, "1");
const t = docA.getTree("tree");
const node = t.createNode();
t.createNode(node.id);
// const t = docA.getTree("tree");
// const node = t.createNode();
// t.createNode(node.id);
const bytes = docA.exportSnapshot();
const docB = new Loro();
@ -74,9 +75,10 @@ describe("compatibility", () => {
docA.getMap("map").set("key", "123");
docA.getList("list").insert(0, 1);
docA.getList("list").insert(0, "1");
const t = docA.getTree("tree");
const node = t.createNode();
t.createNode(node.id);
// const t = docA.getTree("tree");
// const node = t.createNode();
// t.createNode(node.id);
const bytes = docA.exportSnapshot();
const docB = new Loro();

View file

@ -1,4 +1,4 @@
import { describe, expect, it} from "vitest";
import { assert, describe, expect, it} from "vitest";
import { Loro, LoroTree, LoroTreeNode } from "../src";
function assertEquals(a: any, b: any) {
@ -83,6 +83,12 @@ describe("loro tree", () => {
tree2.createNode(root.id);
const arr = tree2.toArray();
assertEquals(arr.length, 3);
const keys = Object.keys(arr[0]);
assert(keys.includes("id"));
assert(keys.includes("parent"));
assert(keys.includes("index"));
assert(keys.includes("fractional_index"));
assert(keys.includes("meta"));
});
it("subscribe", async () => {