mirror of
https://github.com/loro-dev/loro.git
synced 2025-01-23 05:24:51 +00:00
refactor: call events subs without await now
This commit is contained in:
parent
88003bdffe
commit
6860132ada
4 changed files with 78 additions and 71 deletions
|
@ -118,12 +118,19 @@ impl Loro {
|
||||||
Self(RefCell::new(LoroDoc::new()))
|
Self(RefCell::new(LoroDoc::new()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn txn(&self) -> Transaction {
|
/// Create a new Loro transaction.
|
||||||
Transaction(self.0.borrow().txn().unwrap())
|
/// There can be only one transaction at a time.
|
||||||
}
|
///
|
||||||
|
/// It's caller's responsibility to call `commit` or `abort` on the transaction.
|
||||||
pub fn txn_with_origin(&self, origin: &str) -> Transaction {
|
/// Transaction.free() will commit the transaction if it's not committed or aborted.
|
||||||
Transaction(self.0.borrow().txn_with_origin(origin).unwrap())
|
#[wasm_bindgen(js_name = "newTransaction")]
|
||||||
|
pub fn new_transaction(&self, origin: Option<String>) -> Transaction {
|
||||||
|
Transaction(Some(
|
||||||
|
self.0
|
||||||
|
.borrow()
|
||||||
|
.txn_with_origin(&origin.unwrap_or_default())
|
||||||
|
.unwrap(),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen(js_name = "clientId", method, getter)]
|
#[wasm_bindgen(js_name = "clientId", method, getter)]
|
||||||
|
@ -247,7 +254,7 @@ impl Loro {
|
||||||
self.0
|
self.0
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.subscribe_deep(Arc::new(move |e| {
|
.subscribe_deep(Arc::new(move |e| {
|
||||||
call_after_micro_task(observer.clone(), e);
|
call_subscriber(observer.clone(), e);
|
||||||
}))
|
}))
|
||||||
.into_u32()
|
.into_u32()
|
||||||
}
|
}
|
||||||
|
@ -268,25 +275,43 @@ impl Loro {
|
||||||
let origin = origin.as_string().unwrap();
|
let origin = origin.as_string().unwrap();
|
||||||
debug_log::group!("transaction with origin: {}", origin);
|
debug_log::group!("transaction with origin: {}", origin);
|
||||||
let txn = self.0.borrow().txn_with_origin(&origin)?;
|
let txn = self.0.borrow().txn_with_origin(&origin)?;
|
||||||
let js_txn = JsValue::from(Transaction(txn));
|
let js_txn = JsValue::from(Transaction(Some(txn)));
|
||||||
let ans = f.call1(&JsValue::NULL, &js_txn);
|
let ans = f.call1(&JsValue::NULL, &js_txn);
|
||||||
debug_log::group_end!();
|
debug_log::group_end!();
|
||||||
ans
|
ans
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call_after_micro_task(ob: observer::Observer, e: DiffEvent) {
|
fn call_subscriber(ob: observer::Observer, e: DiffEvent) {
|
||||||
let promise = Promise::resolve(&JsValue::NULL);
|
|
||||||
type C = Closure<dyn FnMut(JsValue)>;
|
|
||||||
let drop_handler: Rc<RefCell<Option<C>>> = Rc::new(RefCell::new(None));
|
|
||||||
let copy = drop_handler.clone();
|
|
||||||
let event = Event {
|
let event = Event {
|
||||||
|
from_children: e.from_children,
|
||||||
local: e.doc.local,
|
local: e.doc.local,
|
||||||
origin: e.doc.origin.to_string(),
|
origin: e.doc.origin.to_string(),
|
||||||
target: e.container.id.clone(),
|
target: e.container.id.clone(),
|
||||||
diff: Either::A(e.container.diff.to_owned()),
|
diff: Either::A(e.container.diff.to_owned()),
|
||||||
path: Either::A(e.container.path.iter().map(|x| x.1.clone()).collect()),
|
path: Either::A(e.container.path.iter().map(|x| x.1.clone()).collect()),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if let Err(e) = ob.call1(&event.into()) {
|
||||||
|
console_error!("Error when calling observer: {:#?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unused)]
|
||||||
|
fn call_after_micro_task(ob: observer::Observer, e: DiffEvent) {
|
||||||
|
let promise = Promise::resolve(&JsValue::NULL);
|
||||||
|
type C = Closure<dyn FnMut(JsValue)>;
|
||||||
|
let drop_handler: Rc<RefCell<Option<C>>> = Rc::new(RefCell::new(None));
|
||||||
|
let copy = drop_handler.clone();
|
||||||
|
let event = Event {
|
||||||
|
from_children: e.from_children,
|
||||||
|
local: e.doc.local,
|
||||||
|
origin: e.doc.origin.to_string(),
|
||||||
|
target: e.container.id.clone(),
|
||||||
|
diff: Either::A(e.container.diff.to_owned()),
|
||||||
|
path: Either::A(e.container.path.iter().map(|x| x.1.clone()).collect()),
|
||||||
|
};
|
||||||
|
|
||||||
let closure = Closure::once(move |_: JsValue| {
|
let closure = Closure::once(move |_: JsValue| {
|
||||||
let ans = ob.call1(&event.into());
|
let ans = ob.call1(&event.into());
|
||||||
drop(copy);
|
drop(copy);
|
||||||
|
@ -294,6 +319,7 @@ fn call_after_micro_task(ob: observer::Observer, e: DiffEvent) {
|
||||||
console_error!("Error when calling observer: {:#?}", e);
|
console_error!("Error when calling observer: {:#?}", e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let _ = promise.then(&closure);
|
let _ = promise.then(&closure);
|
||||||
drop_handler.borrow_mut().replace(closure);
|
drop_handler.borrow_mut().replace(closure);
|
||||||
}
|
}
|
||||||
|
@ -312,6 +338,7 @@ enum Either<A, B> {
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub struct Event {
|
pub struct Event {
|
||||||
pub local: bool,
|
pub local: bool,
|
||||||
|
pub from_children: bool,
|
||||||
origin: String,
|
origin: String,
|
||||||
target: ContainerID,
|
target: ContainerID,
|
||||||
diff: Either<Diff, JsValue>,
|
diff: Either<Diff, JsValue>,
|
||||||
|
@ -360,14 +387,29 @@ impl Event {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub struct Transaction(Txn);
|
pub struct Transaction(Option<Txn>);
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
impl Transaction {
|
impl Transaction {
|
||||||
pub fn commit(self) -> JsResult<()> {
|
pub fn commit(&mut self) -> JsResult<()> {
|
||||||
self.0.commit()?;
|
if let Some(x) = self.0.take() {
|
||||||
|
x.commit()?;
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn abort(&mut self) -> JsResult<()> {
|
||||||
|
if let Some(x) = self.0.take() {
|
||||||
|
x.abort();
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_mut(&mut self) -> JsResult<&mut Txn> {
|
||||||
|
self.0
|
||||||
|
.as_mut()
|
||||||
|
.ok_or_else(|| JsValue::from_str("Transaction is aborted"))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
|
@ -381,7 +423,7 @@ impl LoroText {
|
||||||
index: usize,
|
index: usize,
|
||||||
content: &str,
|
content: &str,
|
||||||
) -> JsResult<()> {
|
) -> JsResult<()> {
|
||||||
self.0.insert_utf16(&mut txn.0, index, content)?;
|
self.0.insert_utf16(txn.as_mut()?, index, content)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,7 +433,7 @@ impl LoroText {
|
||||||
index: usize,
|
index: usize,
|
||||||
len: usize,
|
len: usize,
|
||||||
) -> JsResult<()> {
|
) -> JsResult<()> {
|
||||||
self.0.delete_utf16(&mut txn.0, index, len)?;
|
self.0.delete_utf16(txn.as_mut()?, index, len)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -417,7 +459,7 @@ impl LoroText {
|
||||||
let ans = loro.0.borrow_mut().subscribe(
|
let ans = loro.0.borrow_mut().subscribe(
|
||||||
&self.0.id(),
|
&self.0.id(),
|
||||||
Arc::new(move |e| {
|
Arc::new(move |e| {
|
||||||
call_after_micro_task(observer.clone(), e);
|
call_subscriber(observer.clone(), e);
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -444,12 +486,12 @@ impl LoroMap {
|
||||||
key: &str,
|
key: &str,
|
||||||
value: JsValue,
|
value: JsValue,
|
||||||
) -> JsResult<()> {
|
) -> JsResult<()> {
|
||||||
self.0.insert(&mut txn.0, key, value.into())?;
|
self.0.insert(txn.as_mut()?, key, value.into())?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn __txn_delete(&mut self, txn: &mut Transaction, key: &str) -> JsResult<()> {
|
pub fn __txn_delete(&mut self, txn: &mut Transaction, key: &str) -> JsResult<()> {
|
||||||
self.0.delete(&mut txn.0, key)?;
|
self.0.delete(txn.as_mut()?, key)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -487,12 +529,13 @@ impl LoroMap {
|
||||||
"list" | "List" => ContainerType::List,
|
"list" | "List" => ContainerType::List,
|
||||||
_ => return Err(JsValue::from_str(CONTAINER_TYPE_ERR)),
|
_ => return Err(JsValue::from_str(CONTAINER_TYPE_ERR)),
|
||||||
};
|
};
|
||||||
let idx = self.0.insert_container(&mut txn.0, key, type_)?;
|
let t = txn.as_mut()?;
|
||||||
|
let idx = self.0.insert_container(t, key, type_)?;
|
||||||
|
|
||||||
let container = match type_ {
|
let container = match type_ {
|
||||||
ContainerType::Text => LoroText(txn.0.get_text(idx)).into(),
|
ContainerType::Text => LoroText(t.get_text(idx)).into(),
|
||||||
ContainerType::Map => LoroMap(txn.0.get_map(idx)).into(),
|
ContainerType::Map => LoroMap(t.get_map(idx)).into(),
|
||||||
ContainerType::List => LoroList(txn.0.get_list(idx)).into(),
|
ContainerType::List => LoroList(t.get_list(idx)).into(),
|
||||||
};
|
};
|
||||||
Ok(container)
|
Ok(container)
|
||||||
}
|
}
|
||||||
|
@ -502,7 +545,7 @@ impl LoroMap {
|
||||||
let id = loro.0.borrow_mut().subscribe(
|
let id = loro.0.borrow_mut().subscribe(
|
||||||
&self.0.id(),
|
&self.0.id(),
|
||||||
Arc::new(move |e| {
|
Arc::new(move |e| {
|
||||||
call_after_micro_task(observer.clone(), e);
|
call_subscriber(observer.clone(), e);
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -526,7 +569,7 @@ impl LoroList {
|
||||||
index: usize,
|
index: usize,
|
||||||
value: JsValue,
|
value: JsValue,
|
||||||
) -> JsResult<()> {
|
) -> JsResult<()> {
|
||||||
self.0.insert(&mut txn.0, index, value.into())?;
|
self.0.insert(txn.as_mut()?, index, value.into())?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -536,7 +579,7 @@ impl LoroList {
|
||||||
index: usize,
|
index: usize,
|
||||||
len: usize,
|
len: usize,
|
||||||
) -> JsResult<()> {
|
) -> JsResult<()> {
|
||||||
self.0.delete(&mut txn.0, index, len)?;
|
self.0.delete(txn.as_mut()?, index, len)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -574,11 +617,12 @@ impl LoroList {
|
||||||
"list" | "List" => ContainerType::List,
|
"list" | "List" => ContainerType::List,
|
||||||
_ => return Err(JsValue::from_str(CONTAINER_TYPE_ERR)),
|
_ => return Err(JsValue::from_str(CONTAINER_TYPE_ERR)),
|
||||||
};
|
};
|
||||||
let idx = self.0.insert_container(&mut txn.0, pos, _type)?;
|
let t = txn.as_mut()?;
|
||||||
|
let idx = self.0.insert_container(t, pos, _type)?;
|
||||||
let container = match _type {
|
let container = match _type {
|
||||||
ContainerType::Text => LoroText(txn.0.get_text(idx)).into(),
|
ContainerType::Text => LoroText(t.get_text(idx)).into(),
|
||||||
ContainerType::Map => LoroMap(txn.0.get_map(idx)).into(),
|
ContainerType::Map => LoroMap(t.get_map(idx)).into(),
|
||||||
ContainerType::List => LoroList(txn.0.get_list(idx)).into(),
|
ContainerType::List => LoroList(t.get_list(idx)).into(),
|
||||||
};
|
};
|
||||||
Ok(container)
|
Ok(container)
|
||||||
}
|
}
|
||||||
|
@ -588,7 +632,7 @@ impl LoroList {
|
||||||
let ans = loro.0.borrow_mut().subscribe(
|
let ans = loro.0.borrow_mut().subscribe(
|
||||||
&self.0.id(),
|
&self.0.id(),
|
||||||
Arc::new(move |e| {
|
Arc::new(move |e| {
|
||||||
call_after_micro_task(observer.clone(), e);
|
call_subscriber(observer.clone(), e);
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
Ok(ans.into_u32())
|
Ok(ans.into_u32())
|
||||||
|
|
|
@ -22,7 +22,6 @@ describe("event", () => {
|
||||||
loro.transact((tx) => {
|
loro.transact((tx) => {
|
||||||
text.insert(tx, 0, "123");
|
text.insert(tx, 0, "123");
|
||||||
});
|
});
|
||||||
await zeroMs();
|
|
||||||
expect(lastEvent?.target).toEqual(id);
|
expect(lastEvent?.target).toEqual(id);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -39,7 +38,6 @@ describe("event", () => {
|
||||||
return subMap;
|
return subMap;
|
||||||
});
|
});
|
||||||
|
|
||||||
await zeroMs();
|
|
||||||
expect(lastEvent?.path).toStrictEqual(["map", "sub"]);
|
expect(lastEvent?.path).toStrictEqual(["map", "sub"]);
|
||||||
const text = loro.transact((tx) => {
|
const text = loro.transact((tx) => {
|
||||||
const list = subMap.insertContainer(tx, "list", "List");
|
const list = subMap.insertContainer(tx, "list", "List");
|
||||||
|
@ -47,11 +45,9 @@ describe("event", () => {
|
||||||
const text = list.insertContainer(tx, 1, "Text");
|
const text = list.insertContainer(tx, 1, "Text");
|
||||||
return text;
|
return text;
|
||||||
});
|
});
|
||||||
await zeroMs();
|
|
||||||
loro.transact((tx) => {
|
loro.transact((tx) => {
|
||||||
text.insert(tx, 0, "3");
|
text.insert(tx, 0, "3");
|
||||||
});
|
});
|
||||||
await zeroMs();
|
|
||||||
expect(lastEvent?.path).toStrictEqual(["map", "sub", "list", 1]);
|
expect(lastEvent?.path).toStrictEqual(["map", "sub", "list", 1]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -65,14 +61,12 @@ describe("event", () => {
|
||||||
loro.transact(tx => {
|
loro.transact(tx => {
|
||||||
text.insert(tx, 0, "3");
|
text.insert(tx, 0, "3");
|
||||||
})
|
})
|
||||||
await zeroMs();
|
|
||||||
expect(lastEvent?.diff).toStrictEqual(
|
expect(lastEvent?.diff).toStrictEqual(
|
||||||
{ type: "text", diff: [{ type: "insert", value: "3" }] } as TextDiff,
|
{ type: "text", diff: [{ type: "insert", value: "3" }] } as TextDiff,
|
||||||
);
|
);
|
||||||
loro.transact(tx => {
|
loro.transact(tx => {
|
||||||
text.insert(tx, 1, "12");
|
text.insert(tx, 1, "12");
|
||||||
})
|
})
|
||||||
await zeroMs();
|
|
||||||
expect(lastEvent?.diff).toStrictEqual(
|
expect(lastEvent?.diff).toStrictEqual(
|
||||||
{
|
{
|
||||||
type: "text",
|
type: "text",
|
||||||
|
@ -91,14 +85,12 @@ describe("event", () => {
|
||||||
loro.transact(tx => {
|
loro.transact(tx => {
|
||||||
text.insert(tx, 0, "3");
|
text.insert(tx, 0, "3");
|
||||||
})
|
})
|
||||||
await zeroMs();
|
|
||||||
expect(lastEvent?.diff).toStrictEqual(
|
expect(lastEvent?.diff).toStrictEqual(
|
||||||
{ type: "list", diff: [{ type: "insert", value: ["3"] }] } as ListDiff,
|
{ type: "list", diff: [{ type: "insert", value: ["3"] }] } as ListDiff,
|
||||||
);
|
);
|
||||||
loro.transact(tx => {
|
loro.transact(tx => {
|
||||||
text.insert(tx, 1, "12");
|
text.insert(tx, 1, "12");
|
||||||
})
|
})
|
||||||
await zeroMs();
|
|
||||||
expect(lastEvent?.diff).toStrictEqual(
|
expect(lastEvent?.diff).toStrictEqual(
|
||||||
{
|
{
|
||||||
type: "list",
|
type: "list",
|
||||||
|
@ -118,7 +110,6 @@ describe("event", () => {
|
||||||
map.set(tx, "0", "3");
|
map.set(tx, "0", "3");
|
||||||
map.set(tx, "1", "2");
|
map.set(tx, "1", "2");
|
||||||
});
|
});
|
||||||
await zeroMs();
|
|
||||||
expect(lastEvent?.diff).toStrictEqual(
|
expect(lastEvent?.diff).toStrictEqual(
|
||||||
{
|
{
|
||||||
type: "map",
|
type: "map",
|
||||||
|
@ -132,7 +123,6 @@ describe("event", () => {
|
||||||
map.set(tx, "0", "0");
|
map.set(tx, "0", "0");
|
||||||
map.set(tx, "1", "1");
|
map.set(tx, "1", "1");
|
||||||
});
|
});
|
||||||
await zeroMs();
|
|
||||||
expect(lastEvent?.diff).toStrictEqual(
|
expect(lastEvent?.diff).toStrictEqual(
|
||||||
{
|
{
|
||||||
type: "map",
|
type: "map",
|
||||||
|
@ -165,7 +155,6 @@ describe("event", () => {
|
||||||
loro.transact(tx => {
|
loro.transact(tx => {
|
||||||
text.insert(tx, 1, "456");
|
text.insert(tx, 1, "456");
|
||||||
});
|
});
|
||||||
await zeroMs();
|
|
||||||
expect(ran).toBeTruthy();
|
expect(ran).toBeTruthy();
|
||||||
// subscribeOnce test
|
// subscribeOnce test
|
||||||
expect(text.toString()).toEqual("145623");
|
expect(text.toString()).toEqual("145623");
|
||||||
|
@ -192,19 +181,15 @@ describe("event", () => {
|
||||||
loro.transact(tx =>
|
loro.transact(tx =>
|
||||||
map.insertContainer(tx, "sub", "Map")
|
map.insertContainer(tx, "sub", "Map")
|
||||||
);
|
);
|
||||||
await zeroMs();
|
|
||||||
expect(times).toBe(1);
|
expect(times).toBe(1);
|
||||||
const text = loro.transact(tx => subMap.insertContainer(tx, "k", "Text"));
|
const text = loro.transact(tx => subMap.insertContainer(tx, "k", "Text"));
|
||||||
await zeroMs();
|
|
||||||
expect(times).toBe(2);
|
expect(times).toBe(2);
|
||||||
loro.transact(tx => text.insert(tx, 0, "123"));
|
loro.transact(tx => text.insert(tx, 0, "123"));
|
||||||
await zeroMs();
|
|
||||||
expect(times).toBe(3);
|
expect(times).toBe(3);
|
||||||
|
|
||||||
// unsubscribe
|
// unsubscribe
|
||||||
loro.unsubscribe(sub);
|
loro.unsubscribe(sub);
|
||||||
loro.transact(tx => text.insert(tx, 0, "123"));
|
loro.transact(tx => text.insert(tx, 0, "123"));
|
||||||
await zeroMs();
|
|
||||||
expect(times).toBe(3);
|
expect(times).toBe(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -217,16 +202,13 @@ describe("event", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const text = loro.transact(tx => list.insertContainer(tx, 0, "Text"));
|
const text = loro.transact(tx => list.insertContainer(tx, 0, "Text"));
|
||||||
await zeroMs();
|
|
||||||
expect(times).toBe(1);
|
expect(times).toBe(1);
|
||||||
loro.transact(tx => text.insert(tx, 0, "123"));
|
loro.transact(tx => text.insert(tx, 0, "123"));
|
||||||
await zeroMs();
|
|
||||||
expect(times).toBe(2);
|
expect(times).toBe(2);
|
||||||
|
|
||||||
// unsubscribe
|
// unsubscribe
|
||||||
loro.unsubscribe(sub);
|
loro.unsubscribe(sub);
|
||||||
loro.transact(tx => text.insert(tx, 0, "123"));
|
loro.transact(tx => text.insert(tx, 0, "123"));
|
||||||
await zeroMs();
|
|
||||||
expect(times).toBe(2);
|
expect(times).toBe(2);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -257,19 +239,15 @@ describe("event", () => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
loro.transact(tx => text.insert(tx, 0, "你好"));
|
loro.transact(tx => text.insert(tx, 0, "你好"));
|
||||||
await zeroMs();
|
|
||||||
expect(text.toString()).toBe(string);
|
expect(text.toString()).toBe(string);
|
||||||
|
|
||||||
loro.transact(tx => text.insert(tx, 1, "世界"));
|
loro.transact(tx => text.insert(tx, 1, "世界"));
|
||||||
await zeroMs();
|
|
||||||
expect(text.toString()).toBe(string);
|
expect(text.toString()).toBe(string);
|
||||||
|
|
||||||
loro.transact(tx => text.insert(tx, 2, "👍"));
|
loro.transact(tx => text.insert(tx, 2, "👍"));
|
||||||
await zeroMs();
|
|
||||||
expect(text.toString()).toBe(string);
|
expect(text.toString()).toBe(string);
|
||||||
|
|
||||||
loro.transact(tx => text.insert(tx, 2, "♪(^∇^*)"));
|
loro.transact(tx => text.insert(tx, 2, "♪(^∇^*)"));
|
||||||
await zeroMs();
|
|
||||||
expect(text.toString()).toBe(string);
|
expect(text.toString()).toBe(string);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -14,7 +14,7 @@ describe("Frontiers", () => {
|
||||||
it("two clients", () => {
|
it("two clients", () => {
|
||||||
const doc = new Loro();
|
const doc = new Loro();
|
||||||
const text = doc.getText("text");
|
const text = doc.getText("text");
|
||||||
const txn = doc.txn();
|
const txn = doc.newTransaction("");
|
||||||
text.insert(txn, 0, "0");
|
text.insert(txn, 0, "0");
|
||||||
txn.commit();
|
txn.commit();
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,11 @@
|
||||||
import { assertType, describe, expect, it } from "vitest";
|
import { assertType, describe, expect, it } from "vitest";
|
||||||
import {
|
import {
|
||||||
Delta,
|
|
||||||
ListDiff,
|
|
||||||
Loro,
|
Loro,
|
||||||
LoroEvent,
|
|
||||||
LoroList,
|
LoroList,
|
||||||
LoroMap,
|
LoroMap,
|
||||||
MapDiff as MapDiff,
|
|
||||||
PrelimList,
|
PrelimList,
|
||||||
PrelimMap,
|
PrelimMap,
|
||||||
PrelimText,
|
PrelimText,
|
||||||
TextDiff,
|
|
||||||
Transaction,
|
Transaction,
|
||||||
} from "../src";
|
} from "../src";
|
||||||
import { expectTypeOf } from "vitest";
|
import { expectTypeOf } from "vitest";
|
||||||
|
@ -35,7 +30,6 @@ describe("transaction", () => {
|
||||||
text.insert(txn, 0, "hello world");
|
text.insert(txn, 0, "hello world");
|
||||||
assertEquals(count, 0);
|
assertEquals(count, 0);
|
||||||
});
|
});
|
||||||
await one_ms();
|
|
||||||
assertEquals(count, 1);
|
assertEquals(count, 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -55,7 +49,6 @@ describe("transaction", () => {
|
||||||
text.insert(txn, 0, "hello world");
|
text.insert(txn, 0, "hello world");
|
||||||
assertEquals(count, 0);
|
assertEquals(count, 0);
|
||||||
}, "origin");
|
}, "origin");
|
||||||
await one_ms();
|
|
||||||
assertEquals(count, 1);
|
assertEquals(count, 1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -81,18 +74,15 @@ describe("subscribe", () => {
|
||||||
text.insert(txn, 0, "hello world");
|
text.insert(txn, 0, "hello world");
|
||||||
})
|
})
|
||||||
|
|
||||||
await one_ms();
|
|
||||||
assertEquals(count, 2);
|
assertEquals(count, 2);
|
||||||
loro.transact((txn) => {
|
loro.transact((txn) => {
|
||||||
text.insert(txn, 0, "hello world");
|
text.insert(txn, 0, "hello world");
|
||||||
});
|
});
|
||||||
await one_ms();
|
|
||||||
assertEquals(count, 3);
|
assertEquals(count, 3);
|
||||||
loro.unsubscribe(sub);
|
loro.unsubscribe(sub);
|
||||||
loro.transact(txn => {
|
loro.transact(txn => {
|
||||||
text.insert(txn, 0, "hello world");
|
text.insert(txn, 0, "hello world");
|
||||||
})
|
})
|
||||||
await one_ms();
|
|
||||||
assertEquals(count, 3);
|
assertEquals(count, 3);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -109,7 +99,6 @@ describe("subscribe", () => {
|
||||||
text.insert(txn, 0, "hello world");
|
text.insert(txn, 0, "hello world");
|
||||||
})
|
})
|
||||||
|
|
||||||
await one_ms();
|
|
||||||
assertEquals(count, 1);
|
assertEquals(count, 1);
|
||||||
loro.transact(txn => {
|
loro.transact(txn => {
|
||||||
text.insert(txn, 0, "hello world");
|
text.insert(txn, 0, "hello world");
|
||||||
|
@ -128,18 +117,15 @@ describe("subscribe", () => {
|
||||||
loro.transact(loro => {
|
loro.transact(loro => {
|
||||||
text.insert(loro, 0, "hello world");
|
text.insert(loro, 0, "hello world");
|
||||||
})
|
})
|
||||||
await one_ms();
|
|
||||||
assertEquals(count, 1);
|
assertEquals(count, 1);
|
||||||
loro.transact(loro => {
|
loro.transact(loro => {
|
||||||
text.insert(loro, 0, "hello world");
|
text.insert(loro, 0, "hello world");
|
||||||
})
|
})
|
||||||
await one_ms();
|
|
||||||
assertEquals(count, 2);
|
assertEquals(count, 2);
|
||||||
loro.unsubscribe(sub);
|
loro.unsubscribe(sub);
|
||||||
loro.transact(loro => {
|
loro.transact(loro => {
|
||||||
text.insert(loro, 0, "hello world");
|
text.insert(loro, 0, "hello world");
|
||||||
})
|
})
|
||||||
await one_ms();
|
|
||||||
assertEquals(count, 2);
|
assertEquals(count, 2);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -170,7 +156,6 @@ describe("sync", () => {
|
||||||
aText.insert(txn, 0, "abc");
|
aText.insert(txn, 0, "abc");
|
||||||
});
|
});
|
||||||
|
|
||||||
await one_ms();
|
|
||||||
assertEquals(aText.toString(), bText.toString());
|
assertEquals(aText.toString(), bText.toString());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue