Add VeilidRoutingContext class for WASM
This commit is contained in:
		
							
								
								
									
										2
									
								
								veilid-wasm/.cargo/config.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								veilid-wasm/.cargo/config.toml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| [build] | ||||
| target = "wasm32-unknown-unknown" | ||||
| @@ -26,7 +26,8 @@ use wasm_bindgen::prelude::*; | ||||
| use wasm_bindgen_futures::*; | ||||
|  | ||||
| pub mod veilid_client_js; | ||||
| pub mod veilid_table_js; | ||||
| pub mod veilid_routing_context_js; | ||||
| pub mod veilid_table_db_js; | ||||
|  | ||||
| // Allocator | ||||
| extern crate wee_alloc; | ||||
| @@ -139,8 +140,7 @@ pub struct VeilidWASMConfigLogging { | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Deserialize, Serialize)] | ||||
| #[cfg_attr(target_arch = "wasm32", derive(Tsify))] | ||||
| #[tsify(from_wasm_abi)] | ||||
| #[cfg_attr(target_arch = "wasm32", derive(Tsify), tsify(from_wasm_abi))] | ||||
| pub struct VeilidWASMConfig { | ||||
|     pub logging: VeilidWASMConfigLogging, | ||||
| } | ||||
| @@ -150,6 +150,7 @@ pub struct VeilidWASMConfig { | ||||
| pub struct VeilidRouteBlob { | ||||
|     pub route_id: veilid_core::RouteId, | ||||
|     #[serde(with = "veilid_core::as_human_base64")] | ||||
|     #[cfg_attr(target_arch = "wasm32", tsify(type = "string"))] | ||||
|     pub blob: Vec<u8>, | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										293
									
								
								veilid-wasm/src/veilid_routing_context_js.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										293
									
								
								veilid-wasm/src/veilid_routing_context_js.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,293 @@ | ||||
| #![allow(non_snake_case)] | ||||
| use super::*; | ||||
|  | ||||
| #[wasm_bindgen()] | ||||
| pub struct VeilidRoutingContext { | ||||
|     id: u32, | ||||
| } | ||||
|  | ||||
| #[wasm_bindgen()] | ||||
| impl VeilidRoutingContext { | ||||
|     #[wasm_bindgen(constructor)] | ||||
|     pub fn new(id: u32) -> Self { | ||||
|         Self { id } | ||||
|     } | ||||
|  | ||||
|     pub fn createWithoutPrivacy() -> VeilidAPIResult<VeilidRoutingContext> { | ||||
|         let veilid_api = get_veilid_api()?; | ||||
|         let routing_context = veilid_api.routing_context(); | ||||
|         let id = add_routing_context(routing_context); | ||||
|         Ok(VeilidRoutingContext { id }) | ||||
|     } | ||||
|  | ||||
|     pub async fn createWithPrivacy() -> VeilidAPIResult<VeilidRoutingContext> { | ||||
|         let veilid_api = get_veilid_api()?; | ||||
|         let routing_context = veilid_api.routing_context().with_privacy()?; | ||||
|         let id = add_routing_context(routing_context); | ||||
|         Ok(VeilidRoutingContext { id }) | ||||
|     } | ||||
|  | ||||
|     pub async fn createWithCustomPrivacy( | ||||
|         safetySelection: SafetySelection, | ||||
|     ) -> VeilidAPIResult<VeilidRoutingContext> { | ||||
|         let veilid_api = get_veilid_api()?; | ||||
|         let routing_context = veilid_api | ||||
|             .routing_context() | ||||
|             .with_custom_privacy(safetySelection)?; | ||||
|         let id = add_routing_context(routing_context); | ||||
|         Ok(VeilidRoutingContext { id }) | ||||
|     } | ||||
|  | ||||
|     pub fn createWithSequencing(sequencing: Sequencing) -> VeilidAPIResult<VeilidRoutingContext> { | ||||
|         let veilid_api = get_veilid_api()?; | ||||
|         let routing_context = veilid_api.routing_context().with_sequencing(sequencing); | ||||
|         let id = add_routing_context(routing_context); | ||||
|         Ok(VeilidRoutingContext { id }) | ||||
|     } | ||||
|  | ||||
|     pub async fn appMessage(&self, target_string: String, message: String) -> VeilidAPIResult<()> { | ||||
|         let routing_context = { | ||||
|             let rc = (*ROUTING_CONTEXTS).borrow(); | ||||
|             let Some(routing_context) = rc.get(&self.id) else { | ||||
|                 return APIResult::Err(veilid_core::VeilidAPIError::invalid_argument("routing_context_app_message", "id", self.id)); | ||||
|             }; | ||||
|             routing_context.clone() | ||||
|         }; | ||||
|  | ||||
|         let veilid_api = get_veilid_api()?; | ||||
|         let target = veilid_api.parse_as_target(target_string).await?; | ||||
|         routing_context | ||||
|             .app_message(target, message.into_bytes()) | ||||
|             .await?; | ||||
|         APIRESULT_UNDEFINED | ||||
|     } | ||||
|  | ||||
|     pub async fn appCall( | ||||
|         &self, | ||||
|         id: u32, | ||||
|         target_string: String, | ||||
|         request: String, | ||||
|     ) -> VeilidAPIResult<String> { | ||||
|         let routing_context = { | ||||
|             let rc = (*ROUTING_CONTEXTS).borrow(); | ||||
|             let Some(routing_context) = rc.get(&self.id) else { | ||||
|                 return APIResult::Err(veilid_core::VeilidAPIError::invalid_argument("routing_context_app_call", "id", self.id)); | ||||
|             }; | ||||
|             routing_context.clone() | ||||
|         }; | ||||
|  | ||||
|         let veilid_api = get_veilid_api()?; | ||||
|         let target = veilid_api.parse_as_target(target_string).await?; | ||||
|         let answer = routing_context | ||||
|             .app_call(target, request.into_bytes()) | ||||
|             .await?; | ||||
|         // let answer = data_encoding::BASE64URL_NOPAD.encode(&answer); | ||||
|         let answer = String::from_utf8_lossy(&answer).into_owned(); | ||||
|         APIResult::Ok(answer) | ||||
|     } | ||||
|  | ||||
|     pub async fn createDhtRecord(&self, schema: JsValue, kind: u32) -> VeilidAPIResult<JsValue> { | ||||
|         let schema: DHTSchema = serde_wasm_bindgen::from_value(schema).unwrap(); | ||||
|         let crypto_kind = if kind == 0 { | ||||
|             None | ||||
|         } else { | ||||
|             Some(veilid_core::FourCC::from(kind)) | ||||
|         }; | ||||
|         let routing_context = { | ||||
|             let rc = (*ROUTING_CONTEXTS).borrow(); | ||||
|             let Some(routing_context) = rc.get(&self.id) else { | ||||
|                 return APIResult::Err(veilid_core::VeilidAPIError::invalid_argument("routing_context_create_dht_record", "id", self.id)); | ||||
|             }; | ||||
|             routing_context.clone() | ||||
|         }; | ||||
|  | ||||
|         let dht_record_descriptor = routing_context | ||||
|             .create_dht_record(schema, crypto_kind) | ||||
|             .await?; | ||||
|         let out = serde_wasm_bindgen::to_value(&dht_record_descriptor).unwrap(); | ||||
|         APIResult::Ok(out) | ||||
|     } | ||||
|  | ||||
|     pub async fn openDhtRecord( | ||||
|         &self, | ||||
|         key: String, | ||||
|         writer: Option<String>, | ||||
|     ) -> VeilidAPIResult<JsValue> { | ||||
|         let key: veilid_core::TypedKey = veilid_core::deserialize_json(&key).unwrap(); | ||||
|         let writer: Option<veilid_core::KeyPair> = | ||||
|             writer.map(|s| veilid_core::deserialize_json(&s).unwrap()); | ||||
|         let routing_context = { | ||||
|             let rc = (*ROUTING_CONTEXTS).borrow(); | ||||
|             let Some(routing_context) = rc.get(&self.id) else { | ||||
|                 return APIResult::Err(veilid_core::VeilidAPIError::invalid_argument("routing_context_open_dht_record", "id", self.id)); | ||||
|             }; | ||||
|             routing_context.clone() | ||||
|         }; | ||||
|         let dht_record_descriptor = routing_context.open_dht_record(key, writer).await?; | ||||
|         let out = serde_wasm_bindgen::to_value(&dht_record_descriptor).unwrap(); | ||||
|         APIResult::Ok(out) | ||||
|     } | ||||
|  | ||||
|     pub async fn closeDhtRecord(&self, key: String) -> VeilidAPIResult<()> { | ||||
|         let key: veilid_core::TypedKey = veilid_core::deserialize_json(&key).unwrap(); | ||||
|         let routing_context = { | ||||
|             let rc = (*ROUTING_CONTEXTS).borrow(); | ||||
|             let Some(routing_context) = rc.get(&self.id) else { | ||||
|                 return APIResult::Err(veilid_core::VeilidAPIError::invalid_argument("routing_context_close_dht_record", "id", self.id)); | ||||
|             }; | ||||
|             routing_context.clone() | ||||
|         }; | ||||
|         routing_context.close_dht_record(key).await?; | ||||
|         APIRESULT_UNDEFINED | ||||
|     } | ||||
|  | ||||
|     pub async fn deleteDhtRecord(&self, key: String) -> VeilidAPIResult<()> { | ||||
|         let key: veilid_core::TypedKey = veilid_core::deserialize_json(&key).unwrap(); | ||||
|         let routing_context = { | ||||
|             let rc = (*ROUTING_CONTEXTS).borrow(); | ||||
|             let Some(routing_context) = rc.get(&self.id) else { | ||||
|                 return APIResult::Err(veilid_core::VeilidAPIError::invalid_argument("routing_context_delete_dht_record", "id", self.id)); | ||||
|             }; | ||||
|             routing_context.clone() | ||||
|         }; | ||||
|         routing_context.delete_dht_record(key).await?; | ||||
|         APIRESULT_UNDEFINED | ||||
|     } | ||||
|  | ||||
|     pub async fn getDhtValue( | ||||
|         &self, | ||||
|         key: String, | ||||
|         subKey: u32, | ||||
|         forceRefresh: bool, | ||||
|     ) -> VeilidAPIResult<JsValue> { | ||||
|         let key: veilid_core::TypedKey = veilid_core::deserialize_json(&key).unwrap(); | ||||
|         let routing_context = { | ||||
|             let rc = (*ROUTING_CONTEXTS).borrow(); | ||||
|             let Some(routing_context) = rc.get(&self.id) else { | ||||
|                     return APIResult::Err(veilid_core::VeilidAPIError::invalid_argument("routing_context_get_dht_value", "id", self.id)); | ||||
|                 }; | ||||
|             routing_context.clone() | ||||
|         }; | ||||
|         let res = routing_context | ||||
|             .get_dht_value(key, subKey, forceRefresh) | ||||
|             .await?; | ||||
|         let out = serde_wasm_bindgen::to_value(&res).unwrap(); | ||||
|         APIResult::Ok(out) | ||||
|     } | ||||
|  | ||||
|     pub async fn setDhtValue( | ||||
|         &self, | ||||
|         key: String, | ||||
|         subKey: u32, | ||||
|         data: String, | ||||
|     ) -> VeilidAPIResult<JsValue> { | ||||
|         let key: veilid_core::TypedKey = veilid_core::deserialize_json(&key).unwrap(); | ||||
|         let data: Vec<u8> = data_encoding::BASE64URL_NOPAD | ||||
|             .decode(&data.as_bytes()) | ||||
|             .unwrap(); | ||||
|  | ||||
|         let routing_context = { | ||||
|             let rc = (*ROUTING_CONTEXTS).borrow(); | ||||
|             let Some(routing_context) = rc.get(&self.id) else { | ||||
|                     return APIResult::Err(veilid_core::VeilidAPIError::invalid_argument("routing_context_set_dht_value", "id", self.id)); | ||||
|                 }; | ||||
|             routing_context.clone() | ||||
|         }; | ||||
|         let res = routing_context.set_dht_value(key, subKey, data).await?; | ||||
|         let out = serde_wasm_bindgen::to_value(&res).unwrap(); | ||||
|         APIResult::Ok(out) | ||||
|     } | ||||
|  | ||||
|     // pub async fn watchDhtValues( | ||||
|     //     &self, | ||||
|     //     key: String, | ||||
|     //     subKeys: ValueSubkeyRangeSet, | ||||
|     //     expiration: Timestamp, | ||||
|     //     count: u32, | ||||
|     // ) -> VeilidAPIResult<String> { | ||||
|     //     let key: veilid_core::TypedKey = veilid_core::deserialize_json(&key).unwrap(); | ||||
|     //     let subkeys: veilid_core::ValueSubkeyRangeSet = | ||||
|     //         veilid_core::deserialize_json(&subkeys).unwrap(); | ||||
|     //     let expiration = veilid_core::Timestamp::from_str(&expiration).unwrap(); | ||||
|  | ||||
|     //     let routing_context = { | ||||
|     //         let rc = (*ROUTING_CONTEXTS).borrow(); | ||||
|     //         let Some(routing_context) = rc.get(&id) else { | ||||
|     //             return APIResult::Err(veilid_core::VeilidAPIError::invalid_argument("routing_context_watch_dht_values", "id", self.id)); | ||||
|     //         }; | ||||
|     //         routing_context.clone() | ||||
|     //     }; | ||||
|     //     let res = routing_context | ||||
|     //         .watch_dht_values(key, subkeys, expiration, count) | ||||
|     //         .await?; | ||||
|     //     APIResult::Ok(res.to_string()) | ||||
|     // } | ||||
|  | ||||
|     // pub async fn cancelDhtWatch(id: u32, key: String, subkeys: String) -> Promise { | ||||
|     //     let key: veilid_core::TypedKey = veilid_core::deserialize_json(&key).unwrap(); | ||||
|     //     let subkeys: veilid_core::ValueSubkeyRangeSet = | ||||
|     //         veilid_core::deserialize_json(&subkeys).unwrap(); | ||||
|  | ||||
|     //     let routing_context = { | ||||
|     //         let rc = (*ROUTING_CONTEXTS).borrow(); | ||||
|     //         let Some(routing_context) = rc.get(&id) else { | ||||
|     //                 return APIResult::Err(veilid_core::VeilidAPIError::invalid_argument("routing_context_cancel_dht_watch", "id", self.id)); | ||||
|     //             }; | ||||
|     //         routing_context.clone() | ||||
|     //     }; | ||||
|     //     let res = routing_context.cancel_dht_watch(key, subkeys).await?; | ||||
|     //     APIResult::Ok(res) | ||||
|     // } | ||||
| } | ||||
|  | ||||
| #[wasm_bindgen()] | ||||
| pub async fn newPrivateRoute() -> VeilidAPIResult<JsValue> { | ||||
|     let veilid_api = get_veilid_api()?; | ||||
|  | ||||
|     let (route_id, blob) = veilid_api.new_private_route().await?; | ||||
|  | ||||
|     let route_blob = VeilidRouteBlob { route_id, blob }; | ||||
|     let out = serde_wasm_bindgen::to_value(&route_blob).unwrap(); | ||||
|     APIResult::Ok(out) | ||||
| } | ||||
|  | ||||
| #[wasm_bindgen()] | ||||
| pub async fn newCustomPrivateRoute( | ||||
|     stability: Stability, | ||||
|     sequencing: Sequencing, | ||||
| ) -> VeilidAPIResult<JsValue> { | ||||
|     let veilid_api = get_veilid_api()?; | ||||
|  | ||||
|     let (route_id, blob) = veilid_api | ||||
|         .new_custom_private_route(&veilid_core::VALID_CRYPTO_KINDS, stability, sequencing) | ||||
|         .await?; | ||||
|  | ||||
|     let route_blob = VeilidRouteBlob { route_id, blob }; | ||||
|     let out = serde_wasm_bindgen::to_value(&route_blob).unwrap(); | ||||
|     APIResult::Ok(out) | ||||
| } | ||||
|  | ||||
| #[wasm_bindgen()] | ||||
| pub async fn releasePrivateRoute(routeId: String) -> VeilidAPIResult<()> { | ||||
|     let route_id: veilid_core::RouteId = veilid_core::deserialize_json(&routeId).unwrap(); | ||||
|     let veilid_api = get_veilid_api()?; | ||||
|     veilid_api.release_private_route(route_id)?; | ||||
|     APIRESULT_UNDEFINED | ||||
| } | ||||
|  | ||||
| #[wasm_bindgen()] | ||||
| pub async fn appCallReply(callId: String, message: String) -> VeilidAPIResult<()> { | ||||
|     let call_id = match callId.parse() { | ||||
|         Ok(v) => v, | ||||
|         Err(e) => { | ||||
|             return APIResult::Err(veilid_core::VeilidAPIError::invalid_argument( | ||||
|                 e, "call_id", callId, | ||||
|             )) | ||||
|         } | ||||
|     }; | ||||
|     let veilid_api = get_veilid_api()?; | ||||
|     veilid_api | ||||
|         .app_call_reply(call_id, message.into_bytes()) | ||||
|         .await?; | ||||
|     APIRESULT_UNDEFINED | ||||
| } | ||||
| @@ -2,24 +2,24 @@ | ||||
| use super::*; | ||||
| 
 | ||||
| #[wasm_bindgen()] | ||||
| pub struct VeilidTable { | ||||
| pub struct VeilidTableDB { | ||||
|     id: u32, | ||||
|     tableName: String, | ||||
|     columnCount: u32, | ||||
| } | ||||
| 
 | ||||
| #[wasm_bindgen()] | ||||
| impl VeilidTable { | ||||
| impl VeilidTableDB { | ||||
|     #[wasm_bindgen(constructor)] | ||||
|     pub fn new(tableName: String, columnCount: u32) -> VeilidTable { | ||||
|         VeilidTable { | ||||
|     pub fn new(tableName: String, columnCount: u32) -> VeilidTableDB { | ||||
|         VeilidTableDB { | ||||
|             id: 0, | ||||
|             tableName, | ||||
|             columnCount, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub async fn openTable(&mut self) -> Result<u32, VeilidAPIError> { | ||||
|     pub async fn openTable(&mut self) -> VeilidAPIResult<u32> { | ||||
|         let veilid_api = get_veilid_api()?; | ||||
|         let tstore = veilid_api.table_store()?; | ||||
|         let table_db = tstore | ||||
| @@ -41,7 +41,7 @@ impl VeilidTable { | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     pub async fn deleteTable(&mut self) -> Result<bool, VeilidAPIError> { | ||||
|     pub async fn deleteTable(&mut self) -> VeilidAPIResult<bool> { | ||||
|         self.releaseTable(); | ||||
| 
 | ||||
|         let veilid_api = get_veilid_api()?; | ||||
| @@ -59,11 +59,7 @@ impl VeilidTable { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     pub async fn load( | ||||
|         &mut self, | ||||
|         columnId: u32, | ||||
|         key: String, | ||||
|     ) -> Result<Option<String>, VeilidAPIError> { | ||||
|     pub async fn load(&mut self, columnId: u32, key: String) -> VeilidAPIResult<Option<String>> { | ||||
|         self.ensureOpen().await; | ||||
| 
 | ||||
|         let table_db = { | ||||
| @@ -86,7 +82,7 @@ impl VeilidTable { | ||||
|         columnId: u32, | ||||
|         key: String, | ||||
|         value: String, | ||||
|     ) -> Result<(), VeilidAPIError> { | ||||
|     ) -> VeilidAPIResult<()> { | ||||
|         self.ensureOpen().await; | ||||
| 
 | ||||
|         let table_db = { | ||||
| @@ -103,11 +99,7 @@ impl VeilidTable { | ||||
|         APIRESULT_UNDEFINED | ||||
|     } | ||||
| 
 | ||||
|     pub async fn delete( | ||||
|         &mut self, | ||||
|         columnId: u32, | ||||
|         key: String, | ||||
|     ) -> Result<Option<String>, VeilidAPIError> { | ||||
|     pub async fn delete(&mut self, columnId: u32, key: String) -> VeilidAPIResult<Option<String>> { | ||||
|         self.ensureOpen().await; | ||||
| 
 | ||||
|         let table_db = { | ||||
| @@ -125,7 +117,7 @@ impl VeilidTable { | ||||
|     } | ||||
| 
 | ||||
|     // TODO try and figure out how to result a String[], maybe Box<[String]>?
 | ||||
|     pub async fn getKeys(&mut self, columnId: u32) -> Result<JsValue, VeilidAPIError> { | ||||
|     pub async fn getKeys(&mut self, columnId: u32) -> VeilidAPIResult<JsValue> { | ||||
|         self.ensureOpen().await; | ||||
| 
 | ||||
|         let table_db = { | ||||
		Reference in New Issue
	
	Block a user