mirror of
https://github.com/loro-dev/loro.git
synced 2025-02-06 12:25:03 +00:00
fix: transaction
This commit is contained in:
parent
2f74b13e70
commit
74a7aa6c1a
4 changed files with 49 additions and 28 deletions
|
@ -78,6 +78,10 @@ impl TransactionWrap {
|
||||||
let instance = txn.with_store(|s| s.get_container_by_idx(&idx));
|
let instance = txn.with_store(|s| s.get_container_by_idx(&idx));
|
||||||
instance.map(|i| Map::from_instance(i, txn.client_id))
|
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
|
// TODO: use String as Origin for now
|
||||||
|
@ -274,18 +278,23 @@ impl Transaction {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn commit(&mut self) {
|
pub fn commit(&mut self) -> Result<(), LoroError> {
|
||||||
if self.committed {
|
if self.committed {
|
||||||
return;
|
return Err(LoroError::TransactionError(
|
||||||
|
"Transaction already committed".into(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
self.committed = true;
|
self.committed = true;
|
||||||
self.emit_events();
|
self.emit_events();
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for Transaction {
|
impl Drop for Transaction {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.commit()
|
if !self.committed {
|
||||||
|
self.commit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ extern "C" {
|
||||||
pub type JsContainerID;
|
pub type JsContainerID;
|
||||||
#[wasm_bindgen(typescript_type = "Transaction | Loro")]
|
#[wasm_bindgen(typescript_type = "Transaction | Loro")]
|
||||||
pub type JsTransaction;
|
pub type JsTransaction;
|
||||||
#[wasm_bindgen(typescript_type = "String")]
|
#[wasm_bindgen(typescript_type = "string | undefined")]
|
||||||
pub type JsOrigin;
|
pub type JsOrigin;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -246,28 +246,14 @@ impl Loro {
|
||||||
self.0.borrow_mut().unsubscribe_deep(subscription)
|
self.0.borrow_mut().unsubscribe_deep(subscription)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transaction_impl(&self, txn: TransactionWrap, f: js_sys::Function) -> JsResult<()> {
|
/// It's the caller's responsibility to commit and free the transaction
|
||||||
let js_txn = JsValue::from(Transaction(txn));
|
#[wasm_bindgen(js_name = "__raw__transactionWithOrigin")]
|
||||||
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")]
|
|
||||||
pub fn transaction_with_origin(&self, origin: &JsOrigin, f: js_sys::Function) -> JsResult<()> {
|
pub fn transaction_with_origin(&self, origin: &JsOrigin, f: js_sys::Function) -> JsResult<()> {
|
||||||
let origin = origin.as_string().map(Origin::from);
|
let origin = origin.as_string().map(Origin::from);
|
||||||
let txn = self.0.borrow().transact_with(origin);
|
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]
|
#[wasm_bindgen]
|
||||||
pub struct Transaction(TransactionWrap);
|
pub struct Transaction(TransactionWrap);
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
impl Transaction {
|
||||||
|
pub fn commit(&self) -> JsResult<()> {
|
||||||
|
self.0.commit()?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn get_transaction_mut(txn: &JsTransaction) -> TransactionWrap {
|
fn get_transaction_mut(txn: &JsTransaction) -> TransactionWrap {
|
||||||
use wasm_bindgen::convert::RefMutFromWasmAbi;
|
use wasm_bindgen::convert::RefMutFromWasmAbi;
|
||||||
let js: &JsValue = txn.as_ref();
|
let js: &JsValue = txn.as_ref();
|
||||||
|
@ -524,7 +518,5 @@ export type ContainerID = { id: string; type: ContainerType } | {
|
||||||
interface Loro {
|
interface Loro {
|
||||||
exportFrom(version?: Uint8Array): Uint8Array;
|
exportFrom(version?: Uint8Array): Uint8Array;
|
||||||
getContainerById(id: ContainerID): LoroText | LoroMap | LoroList;
|
getContainerById(id: ContainerID): LoroText | LoroMap | LoroList;
|
||||||
transaction(callback: (txn: Transaction)=>void): void;
|
|
||||||
transactionWithOrigin(origin: string, callback: (txn: Transaction)=>void): void;
|
|
||||||
}
|
}
|
||||||
"#;
|
"#;
|
||||||
|
|
|
@ -3,14 +3,14 @@ lockfileVersion: 5.4
|
||||||
specifiers:
|
specifiers:
|
||||||
'@rollup/plugin-node-resolve': ^15.0.1
|
'@rollup/plugin-node-resolve': ^15.0.1
|
||||||
esbuild: ^0.17.12
|
esbuild: ^0.17.12
|
||||||
loro-wasm: '*'
|
loro-wasm: ^0.2.1
|
||||||
rollup: ^3.20.1
|
rollup: ^3.20.1
|
||||||
rollup-plugin-dts: ^5.3.0
|
rollup-plugin-dts: ^5.3.0
|
||||||
rollup-plugin-esbuild: ^5.0.0
|
rollup-plugin-esbuild: ^5.0.0
|
||||||
typescript: ^5.0.2
|
typescript: ^5.0.2
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
loro-wasm: link:node_modules/loro-wasm
|
loro-wasm: registry.npmmirror.com/loro-wasm/0.2.1
|
||||||
|
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@rollup/plugin-node-resolve': registry.npmmirror.com/@rollup/plugin-node-resolve/15.0.1_rollup@3.20.1
|
'@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
|
version: 3.2.0
|
||||||
dev: true
|
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:
|
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}
|
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
|
name: magic-string
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
export {
|
export {
|
||||||
Loro,
|
|
||||||
LoroList,
|
LoroList,
|
||||||
LoroMap,
|
LoroMap,
|
||||||
LoroText,
|
LoroText,
|
||||||
|
@ -9,9 +8,21 @@ export {
|
||||||
setPanicHook,
|
setPanicHook,
|
||||||
Transaction,
|
Transaction,
|
||||||
} from "loro-wasm";
|
} from "loro-wasm";
|
||||||
|
import { Loro, Transaction } from "loro-wasm";
|
||||||
|
|
||||||
export type { ContainerID, ContainerType } 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 {
|
interface Event {
|
||||||
local: boolean;
|
local: boolean;
|
||||||
origin?: string;
|
origin?: string;
|
||||||
|
@ -24,5 +35,8 @@ interface Listener {
|
||||||
declare module "loro-wasm" {
|
declare module "loro-wasm" {
|
||||||
interface Loro {
|
interface Loro {
|
||||||
subscribe(listener: Listener): void;
|
subscribe(listener: Listener): void;
|
||||||
|
transact(f: (tx: Transaction) => void, origin?: string): void;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export { Loro };
|
||||||
|
|
Loading…
Reference in a new issue