fix: transaction

This commit is contained in:
Zixuan Chen 2023-03-24 11:20:59 +08:00
parent 2f74b13e70
commit 74a7aa6c1a
4 changed files with 49 additions and 28 deletions

View file

@ -78,6 +78,10 @@ impl TransactionWrap {
let instance = txn.with_store(|s| s.get_container_by_idx(&idx));
instance.map(|i| Map::from_instance(i, txn.client_id))
}
pub fn commit(&self) -> Result<(), LoroError> {
self.0.borrow_mut().commit()
}
}
// TODO: use String as Origin for now
@ -274,18 +278,23 @@ impl Transaction {
Ok(())
}
pub fn commit(&mut self) {
pub fn commit(&mut self) -> Result<(), LoroError> {
if self.committed {
return;
return Err(LoroError::TransactionError(
"Transaction already committed".into(),
));
}
self.committed = true;
self.emit_events();
Ok(())
}
}
impl Drop for Transaction {
fn drop(&mut self) {
self.commit()
if !self.committed {
self.commit();
}
}
}

View file

@ -46,7 +46,7 @@ extern "C" {
pub type JsContainerID;
#[wasm_bindgen(typescript_type = "Transaction | Loro")]
pub type JsTransaction;
#[wasm_bindgen(typescript_type = "String")]
#[wasm_bindgen(typescript_type = "string | undefined")]
pub type JsOrigin;
}
@ -246,28 +246,14 @@ impl Loro {
self.0.borrow_mut().unsubscribe_deep(subscription)
}
fn transaction_impl(&self, txn: TransactionWrap, f: js_sys::Function) -> JsResult<()> {
let js_txn = JsValue::from(Transaction(txn));
f.call1(&JsValue::NULL, &js_txn)?;
// TODO: what is the best way to drop txn
// Or Reference Y-crdt: https://github.com/y-crdt/y-crdt/blob/3e7450114ab3d5d4cba93eeb0710f92371e57c74/tests-wasm/testHelper.js#L6
let ptr = Reflect::get(&js_txn, &JsValue::from_str("ptr"))?;
let ptr = ptr.as_f64().ok_or(JsValue::NULL).unwrap() as u32;
use wasm_bindgen::convert::FromWasmAbi;
drop(unsafe { Transaction::from_abi(ptr) });
Ok(())
}
pub fn transaction(&self, f: js_sys::Function) -> JsResult<()> {
let txn = self.0.borrow().transact();
self.transaction_impl(txn, f)
}
#[wasm_bindgen(js_name = "transactionWithOrigin")]
/// It's the caller's responsibility to commit and free the transaction
#[wasm_bindgen(js_name = "__raw__transactionWithOrigin")]
pub fn transaction_with_origin(&self, origin: &JsOrigin, f: js_sys::Function) -> JsResult<()> {
let origin = origin.as_string().map(Origin::from);
let txn = self.0.borrow().transact_with(origin);
self.transaction_impl(txn, f)
let js_txn = JsValue::from(Transaction(txn));
f.call1(&JsValue::NULL, &js_txn)?;
Ok(())
}
}
@ -296,6 +282,14 @@ impl Event {
#[wasm_bindgen]
pub struct Transaction(TransactionWrap);
#[wasm_bindgen]
impl Transaction {
pub fn commit(&self) -> JsResult<()> {
self.0.commit()?;
Ok(())
}
}
fn get_transaction_mut(txn: &JsTransaction) -> TransactionWrap {
use wasm_bindgen::convert::RefMutFromWasmAbi;
let js: &JsValue = txn.as_ref();
@ -524,7 +518,5 @@ export type ContainerID = { id: string; type: ContainerType } | {
interface Loro {
exportFrom(version?: Uint8Array): Uint8Array;
getContainerById(id: ContainerID): LoroText | LoroMap | LoroList;
transaction(callback: (txn: Transaction)=>void): void;
transactionWithOrigin(origin: string, callback: (txn: Transaction)=>void): void;
}
"#;

View file

@ -3,14 +3,14 @@ lockfileVersion: 5.4
specifiers:
'@rollup/plugin-node-resolve': ^15.0.1
esbuild: ^0.17.12
loro-wasm: '*'
loro-wasm: ^0.2.1
rollup: ^3.20.1
rollup-plugin-dts: ^5.3.0
rollup-plugin-esbuild: ^5.0.0
typescript: ^5.0.2
dependencies:
loro-wasm: link:node_modules/loro-wasm
loro-wasm: registry.npmmirror.com/loro-wasm/0.2.1
devDependencies:
'@rollup/plugin-node-resolve': registry.npmmirror.com/@rollup/plugin-node-resolve/15.0.1_rollup@3.20.1
@ -546,6 +546,12 @@ packages:
version: 3.2.0
dev: true
registry.npmmirror.com/loro-wasm/0.2.1:
resolution: {integrity: sha512-kswaRi9RUeMW3MAdZq1kBob2AkSrihPE18FaiOEOzjpvlNHN0X2GClR5dbtouGXccEMDWlASpgVdhQPu5kO5IA==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/loro-wasm/-/loro-wasm-0.2.1.tgz}
name: loro-wasm
version: 0.2.1
dev: false
registry.npmmirror.com/magic-string/0.30.0:
resolution: {integrity: sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ==, registry: https://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/magic-string/-/magic-string-0.30.0.tgz}
name: magic-string

View file

@ -1,5 +1,4 @@
export {
Loro,
LoroList,
LoroMap,
LoroText,
@ -9,9 +8,21 @@ export {
setPanicHook,
Transaction,
} from "loro-wasm";
import { Loro, Transaction } from "loro-wasm";
export type { ContainerID, ContainerType } from "loro-wasm";
Loro.prototype.transact = function (cb, origin) {
this.__raw__transactionWithOrigin(origin, (txn: Transaction) => {
try {
cb(txn);
} finally {
txn.commit();
txn.free();
}
});
};
interface Event {
local: boolean;
origin?: string;
@ -24,5 +35,8 @@ interface Listener {
declare module "loro-wasm" {
interface Loro {
subscribe(listener: Listener): void;
transact(f: (tx: Transaction) => void, origin?: string): void;
}
}
export { Loro };