mirror of
https://github.com/loro-dev/loro.git
synced 2024-11-28 09:25:36 +00:00
chore: rename position to fractional_index (#381)
Breaking Change: - rename `position` to `fractional_index`
This commit is contained in:
parent
86c760abd0
commit
00e7bf2911
9 changed files with 53 additions and 68 deletions
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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"}]"#
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 () => {
|
||||
|
|
Loading…
Reference in a new issue