js api
This commit is contained in:
parent
ef313133cf
commit
60aa3fafc0
@ -21,7 +21,7 @@ EXTERNAL SOURCES:
|
||||
SPEC CHECKSUMS:
|
||||
FlutterMacOS: ae6af50a8ea7d6103d888583d46bd8328a7e9811
|
||||
path_provider_macos: 3c0c3b4b0d4a76d2bf989a913c2de869c5641a19
|
||||
veilid: 6bed3adec63fd8708a2ace498e0e17941c9fc32b
|
||||
veilid: f2b3b5b3ac8cd93fc5443ab830d5153575dacf36
|
||||
|
||||
PODFILE CHECKSUM: 6eac6b3292e5142cfc23bdeb71848a40ec51c14c
|
||||
|
||||
|
@ -337,30 +337,40 @@ Stream<T> processStreamJson<T>(
|
||||
}
|
||||
}
|
||||
|
||||
class _Ctx {
|
||||
final int id;
|
||||
final VeilidFFI ffi;
|
||||
_Ctx(this.id, this.ffi);
|
||||
}
|
||||
|
||||
// FFI implementation of VeilidRoutingContext
|
||||
class VeilidRoutingContextFFI implements VeilidRoutingContext {
|
||||
final int _id;
|
||||
final VeilidFFI _ffi;
|
||||
final _Ctx _ctx;
|
||||
static final Finalizer<_Ctx> _finalizer =
|
||||
Finalizer((ctx) => {ctx.ffi._releaseRoutingContext(ctx.id)});
|
||||
|
||||
VeilidRoutingContextFFI._(this._ctx) {
|
||||
_finalizer.attach(this, _ctx, detach: this);
|
||||
}
|
||||
|
||||
VeilidRoutingContextFFI._(this._id, this._ffi);
|
||||
@override
|
||||
VeilidRoutingContextFFI withPrivacy() {
|
||||
final newId = _ffi._routingContextWithPrivacy(_id);
|
||||
return VeilidRoutingContextFFI._(newId, _ffi);
|
||||
final newId = _ctx.ffi._routingContextWithPrivacy(_ctx.id);
|
||||
return VeilidRoutingContextFFI._(_Ctx(newId, _ctx.ffi));
|
||||
}
|
||||
|
||||
@override
|
||||
VeilidRoutingContextFFI withCustomPrivacy(Stability stability) {
|
||||
final newId = _ffi._routingContextWithCustomPrivacy(
|
||||
_id, stability.json.toNativeUtf8());
|
||||
return VeilidRoutingContextFFI._(newId, _ffi);
|
||||
final newId = _ctx.ffi._routingContextWithCustomPrivacy(
|
||||
_ctx.id, stability.json.toNativeUtf8());
|
||||
return VeilidRoutingContextFFI._(_Ctx(newId, _ctx.ffi));
|
||||
}
|
||||
|
||||
@override
|
||||
VeilidRoutingContextFFI withSequencing(Sequencing sequencing) {
|
||||
final newId =
|
||||
_ffi._routingContextWithSequencing(_id, sequencing.json.toNativeUtf8());
|
||||
return VeilidRoutingContextFFI._(newId, _ffi);
|
||||
final newId = _ctx.ffi
|
||||
._routingContextWithSequencing(_ctx.id, sequencing.json.toNativeUtf8());
|
||||
return VeilidRoutingContextFFI._(_Ctx(newId, _ctx.ffi));
|
||||
}
|
||||
|
||||
@override
|
||||
@ -370,8 +380,8 @@ class VeilidRoutingContextFFI implements VeilidRoutingContext {
|
||||
|
||||
final recvPort = ReceivePort("routing_context_app_call");
|
||||
final sendPort = recvPort.sendPort;
|
||||
_ffi._routingContextAppCall(
|
||||
sendPort.nativePort, _id, nativeEncodedTarget, nativeEncodedRequest);
|
||||
_ctx.ffi._routingContextAppCall(sendPort.nativePort, _ctx.id,
|
||||
nativeEncodedTarget, nativeEncodedRequest);
|
||||
final out = await processFuturePlain(recvPort.first);
|
||||
return base64Decode(out);
|
||||
}
|
||||
@ -381,10 +391,10 @@ class VeilidRoutingContextFFI implements VeilidRoutingContext {
|
||||
var nativeEncodedTarget = target.toNativeUtf8();
|
||||
var nativeEncodedMessage = base64UrlEncode(message).toNativeUtf8();
|
||||
|
||||
final recvPort = ReceivePort("routing_context_app_call");
|
||||
final recvPort = ReceivePort("routing_context_app_message");
|
||||
final sendPort = recvPort.sendPort;
|
||||
_ffi._routingContextAppCall(
|
||||
sendPort.nativePort, _id, nativeEncodedTarget, nativeEncodedMessage);
|
||||
_ctx.ffi._routingContextAppMessage(sendPort.nativePort, _ctx.id,
|
||||
nativeEncodedTarget, nativeEncodedMessage);
|
||||
return processFutureVoid(recvPort.first);
|
||||
}
|
||||
}
|
||||
@ -566,7 +576,7 @@ class VeilidFFI implements Veilid {
|
||||
final sendPort = recvPort.sendPort;
|
||||
_routingContext(sendPort.nativePort);
|
||||
final id = await processFuturePlain(recvPort.first);
|
||||
return VeilidRoutingContextFFI._(id, this);
|
||||
return VeilidRoutingContextFFI._(_Ctx(id, this));
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -19,59 +19,62 @@ Future<T> _wrapApiPromise<T>(Object p) {
|
||||
VeilidAPIException.fromJson(jsonDecode(error as String))));
|
||||
}
|
||||
|
||||
class _Ctx {
|
||||
final int id;
|
||||
final VeilidJS js;
|
||||
_Ctx(this.id, this.js);
|
||||
}
|
||||
|
||||
// JS implementation of VeilidRoutingContext
|
||||
class VeilidRoutingContextJS implements VeilidRoutingContext {
|
||||
final int _id;
|
||||
final VeilidFFI _ffi;
|
||||
final _Ctx _ctx;
|
||||
static final Finalizer<_Ctx> _finalizer = Finalizer((ctx) => {
|
||||
js_util.callMethod(wasm, "release_routing_context", [ctx.id])
|
||||
});
|
||||
|
||||
VeilidRoutingContextFFI._(this._id, this._ffi);
|
||||
@override
|
||||
VeilidRoutingContextFFI withPrivacy() {
|
||||
final newId = _ffi._routingContextWithPrivacy(_id);
|
||||
return VeilidRoutingContextFFI._(newId, _ffi);
|
||||
VeilidRoutingContextJS._(this._ctx) {
|
||||
_finalizer.attach(this, _ctx, detach: this);
|
||||
}
|
||||
|
||||
@override
|
||||
VeilidRoutingContextFFI withCustomPrivacy(Stability stability) {
|
||||
final newId = _ffi._routingContextWithCustomPrivacy(
|
||||
_id, stability.json.toNativeUtf8());
|
||||
return VeilidRoutingContextFFI._(newId, _ffi);
|
||||
VeilidRoutingContextJS withPrivacy() {
|
||||
int newId =
|
||||
js_util.callMethod(wasm, "routing_context_with_privacy", [_ctx.id]);
|
||||
return VeilidRoutingContextJS._(_Ctx(newId, _ctx.js));
|
||||
}
|
||||
|
||||
@override
|
||||
VeilidRoutingContextFFI withSequencing(Sequencing sequencing) {
|
||||
final newId =
|
||||
_ffi._routingContextWithSequencing(_id, sequencing.json.toNativeUtf8());
|
||||
return VeilidRoutingContextFFI._(newId, _ffi);
|
||||
VeilidRoutingContextJS withCustomPrivacy(Stability stability) {
|
||||
final newId = js_util.callMethod(
|
||||
wasm, "routing_context_with_custom_privacy", [_ctx.id, stability.json]);
|
||||
|
||||
return VeilidRoutingContextJS._(_Ctx(newId, _ctx.js));
|
||||
}
|
||||
|
||||
@override
|
||||
VeilidRoutingContextJS withSequencing(Sequencing sequencing) {
|
||||
final newId = js_util.callMethod(
|
||||
wasm, "routing_context_with_sequencing", [_ctx.id, sequencing.json]);
|
||||
return VeilidRoutingContextJS._(_Ctx(newId, _ctx.js));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Uint8List> appCall(String target, Uint8List request) async {
|
||||
var nativeEncodedTarget = target.toNativeUtf8();
|
||||
var nativeEncodedRequest = base64UrlEncode(request).toNativeUtf8();
|
||||
var encodedRequest = base64UrlEncode(request);
|
||||
|
||||
final recvPort = ReceivePort("routing_context_app_call");
|
||||
final sendPort = recvPort.sendPort;
|
||||
_ffi._routingContextAppCall(
|
||||
sendPort.nativePort, _id, nativeEncodedTarget, nativeEncodedRequest);
|
||||
final out = await processFuturePlain(recvPort.first);
|
||||
return base64Decode(out);
|
||||
return base64Decode(await _wrapApiPromise(js_util.callMethod(
|
||||
wasm, "routing_context_app_call", [_ctx.id, encodedRequest])));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> appMessage(String target, Uint8List message) async {
|
||||
var nativeEncodedTarget = target.toNativeUtf8();
|
||||
var nativeEncodedMessage = base64UrlEncode(message).toNativeUtf8();
|
||||
var encodedMessage = base64UrlEncode(message);
|
||||
|
||||
final recvPort = ReceivePort("routing_context_app_call");
|
||||
final sendPort = recvPort.sendPort;
|
||||
_ffi._routingContextAppCall(
|
||||
sendPort.nativePort, _id, nativeEncodedTarget, nativeEncodedMessage);
|
||||
return processFutureVoid(recvPort.first);
|
||||
return _wrapApiPromise(js_util.callMethod(
|
||||
wasm, "routing_context_app_message", [_ctx.id, encodedMessage]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// JS implementation of high level Veilid API
|
||||
|
||||
class VeilidJS implements Veilid {
|
||||
@ -133,30 +136,32 @@ class VeilidJS implements Veilid {
|
||||
js_util.callMethod(wasm, "shutdown_veilid_core", []));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
Future<VeilidRoutingContext> routingContext() async {
|
||||
final recvPort = ReceivePort("routing_context");
|
||||
final sendPort = recvPort.sendPort;
|
||||
_routingContext(sendPort.nativePort);
|
||||
final id = await processFuturePlain(recvPort.first);
|
||||
return VeilidRoutingContextFFI._(id, this);
|
||||
int id = jsonDecode(
|
||||
await _wrapApiPromise(js_util.callMethod(wasm, "routing_context", [])));
|
||||
return VeilidRoutingContextJS._(_Ctx(id, this));
|
||||
}
|
||||
|
||||
@override
|
||||
Future<KeyBlob> newPrivateRoute() async {
|
||||
final recvPort = ReceivePort("new_private_route");
|
||||
final sendPort = recvPort.sendPort;
|
||||
_newPrivateRoute(sendPort.nativePort);
|
||||
return processFutureJson(KeyBlob.fromJson, recvPort.first);
|
||||
Map<String, dynamic> blobJson = jsonDecode(await _wrapApiPromise(
|
||||
js_util.callMethod(wasm, "new_private_route", [])));
|
||||
return KeyBlob.fromJson(blobJson);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<KeyBlob> newCustomPrivateRoute(
|
||||
Stability stability, Sequencing sequencing) async {
|
||||
return _wrapApiPromise(
|
||||
js_util.callMethod(wasm, "new_custom_private_route", [stability, sequencing]));
|
||||
var stabilityString =
|
||||
jsonEncode(stability, toEncodable: veilidApiToEncodable);
|
||||
var sequencingString =
|
||||
jsonEncode(sequencing, toEncodable: veilidApiToEncodable);
|
||||
|
||||
Map<String, dynamic> blobJson = jsonDecode(await _wrapApiPromise(js_util
|
||||
.callMethod(
|
||||
wasm, "new_private_route", [stabilityString, sequencingString])));
|
||||
return KeyBlob.fromJson(blobJson);
|
||||
}
|
||||
|
||||
@override
|
||||
@ -178,7 +183,7 @@ class VeilidJS implements Veilid {
|
||||
return _wrapApiPromise(
|
||||
js_util.callMethod(wasm, "app_call_reply", [id, encodedMessage]));
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
Future<String> debug(String command) {
|
||||
return _wrapApiPromise(js_util.callMethod(wasm, "debug", [command]));
|
||||
@ -191,7 +196,7 @@ class VeilidJS implements Veilid {
|
||||
|
||||
@override
|
||||
VeilidVersion veilidVersion() {
|
||||
var jsonVersion =
|
||||
Map<String, dynamic> jsonVersion =
|
||||
jsonDecode(js_util.callMethod(wasm, "veilid_version", []));
|
||||
return VeilidVersion(
|
||||
jsonVersion["major"], jsonVersion["minor"], jsonVersion["patch"]);
|
||||
|
@ -9,6 +9,7 @@ use alloc::sync::Arc;
|
||||
use alloc::*;
|
||||
use core::any::{Any, TypeId};
|
||||
use core::cell::RefCell;
|
||||
use core::fmt::Debug;
|
||||
use futures_util::FutureExt;
|
||||
use gloo_utils::format::JsValueSerdeExt;
|
||||
use js_sys::*;
|
||||
@ -21,6 +22,7 @@ use tracing_subscriber::*;
|
||||
use tracing_wasm::{WASMLayerConfigBuilder, *};
|
||||
use veilid_core::tools::*;
|
||||
use veilid_core::*;
|
||||
use wasm_bindgen::prelude::*;
|
||||
use wasm_bindgen_futures::*;
|
||||
|
||||
// Allocator
|
||||
@ -57,11 +59,13 @@ fn take_veilid_api() -> Result<veilid_core::VeilidAPI, veilid_core::VeilidAPIErr
|
||||
}
|
||||
|
||||
// JSON Helpers for WASM
|
||||
pub fn to_json<T: Serialize>(val: T) -> JsValue {
|
||||
pub fn to_json<T: Serialize + Debug>(val: T) -> JsValue {
|
||||
JsValue::from_str(&serialize_json(val))
|
||||
}
|
||||
|
||||
pub fn from_json<T: de::DeserializeOwned>(val: JsValue) -> Result<T, veilid_core::VeilidAPIError> {
|
||||
pub fn from_json<T: de::DeserializeOwned + Debug>(
|
||||
val: JsValue,
|
||||
) -> Result<T, veilid_core::VeilidAPIError> {
|
||||
let s = val
|
||||
.as_string()
|
||||
.ok_or_else(|| veilid_core::VeilidAPIError::ParseError {
|
||||
@ -78,7 +82,7 @@ const APIRESULT_UNDEFINED: APIResult<()> = APIResult::Ok(());
|
||||
pub fn wrap_api_future<F, T>(future: F) -> Promise
|
||||
where
|
||||
F: Future<Output = APIResult<T>> + 'static,
|
||||
T: Serialize + 'static,
|
||||
T: Serialize + Debug + 'static,
|
||||
{
|
||||
future_to_promise(future.map(|res| {
|
||||
res.map(|v| {
|
||||
@ -121,7 +125,7 @@ pub struct VeilidWASMConfig {
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct VeilidFFIKeyBlob {
|
||||
pub struct VeilidKeyBlob {
|
||||
pub key: veilid_core::DHTKey,
|
||||
#[serde(with = "veilid_core::json_as_base64")]
|
||||
pub blob: Vec<u8>,
|
||||
@ -256,17 +260,201 @@ pub fn shutdown_veilid_core() -> Promise {
|
||||
})
|
||||
}
|
||||
|
||||
fn add_routing_context(routing_context: veilid_core::RoutingContext) -> u32 {
|
||||
let mut next_id: u32 = 1;
|
||||
let mut rc = (*ROUTING_CONTEXTS).borrow_mut();
|
||||
while rc.contains_key(&next_id) {
|
||||
next_id += 1;
|
||||
}
|
||||
rc.insert(next_id, routing_context);
|
||||
next_id
|
||||
}
|
||||
|
||||
#[wasm_bindgen()]
|
||||
pub fn debug(command: String) -> Promise {
|
||||
pub fn routing_context() -> Promise {
|
||||
wrap_api_future(async move {
|
||||
let veilid_api = get_veilid_api()?;
|
||||
let out = veilid_api.debug(command).await?;
|
||||
Ok(out)
|
||||
let routing_context = veilid_api.routing_context();
|
||||
let new_id = add_routing_context(routing_context);
|
||||
APIResult::Ok(new_id)
|
||||
})
|
||||
}
|
||||
|
||||
#[wasm_bindgen()]
|
||||
pub fn release_routing_context(id: u32) -> i32 {
|
||||
let mut rc = (*ROUTING_CONTEXTS).borrow_mut();
|
||||
if rc.remove(&id).is_none() {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#[wasm_bindgen()]
|
||||
pub fn routing_context_with_privacy(id: u32) -> u32 {
|
||||
let rc = (*ROUTING_CONTEXTS).borrow();
|
||||
let Some(routing_context) = rc.get(&id) else {
|
||||
return 0;
|
||||
};
|
||||
let Ok(routing_context) = routing_context.clone().with_privacy() else {
|
||||
return 0;
|
||||
};
|
||||
let new_id = add_routing_context(routing_context);
|
||||
new_id
|
||||
}
|
||||
|
||||
#[wasm_bindgen()]
|
||||
pub fn routing_context_with_custom_privacy(id: u32, stability: String) -> u32 {
|
||||
let stability: veilid_core::Stability = veilid_core::deserialize_json(&stability).unwrap();
|
||||
|
||||
let rc = (*ROUTING_CONTEXTS).borrow();
|
||||
let Some(routing_context) = rc.get(&id) else {
|
||||
return 0;
|
||||
};
|
||||
let Ok(routing_context) = routing_context.clone().with_custom_privacy(stability) else {
|
||||
return 0;
|
||||
};
|
||||
let new_id = add_routing_context(routing_context);
|
||||
new_id
|
||||
}
|
||||
|
||||
#[wasm_bindgen()]
|
||||
pub fn routing_context_with_sequencing(id: u32, sequencing: String) -> u32 {
|
||||
let sequencing: veilid_core::Sequencing = veilid_core::deserialize_json(&sequencing).unwrap();
|
||||
|
||||
let rc = (*ROUTING_CONTEXTS).borrow();
|
||||
let Some(routing_context) = rc.get(&id) else {
|
||||
return 0;
|
||||
};
|
||||
let routing_context = routing_context.clone().with_sequencing(sequencing);
|
||||
let new_id = add_routing_context(routing_context);
|
||||
new_id
|
||||
}
|
||||
|
||||
#[wasm_bindgen()]
|
||||
pub fn routing_context_app_call(id: u32, target: String, request: String) -> Promise {
|
||||
let request: Vec<u8> = data_encoding::BASE64URL_NOPAD
|
||||
.decode(request.as_bytes())
|
||||
.unwrap();
|
||||
wrap_api_future(async move {
|
||||
let veilid_api = get_veilid_api()?;
|
||||
let routing_table = veilid_api.routing_table()?;
|
||||
let rss = routing_table.route_spec_store();
|
||||
|
||||
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_app_call", "id", id));
|
||||
};
|
||||
routing_context.clone()
|
||||
};
|
||||
|
||||
let target: DHTKey =
|
||||
DHTKey::try_decode(&target).map_err(|e| VeilidAPIError::parse_error(e, &target))?;
|
||||
|
||||
let target = if rss.get_remote_private_route(&target).is_some() {
|
||||
veilid_core::Target::PrivateRoute(target)
|
||||
} else {
|
||||
veilid_core::Target::NodeId(veilid_core::NodeId::new(target))
|
||||
};
|
||||
|
||||
let answer = routing_context.app_call(target, request).await?;
|
||||
let answer = data_encoding::BASE64URL_NOPAD.encode(&answer);
|
||||
APIResult::Ok(answer)
|
||||
})
|
||||
}
|
||||
|
||||
#[wasm_bindgen()]
|
||||
pub fn routing_context_app_message(id: u32, target: String, message: String) -> Promise {
|
||||
let message: Vec<u8> = data_encoding::BASE64URL_NOPAD
|
||||
.decode(message.as_bytes())
|
||||
.unwrap();
|
||||
wrap_api_future(async move {
|
||||
let veilid_api = get_veilid_api()?;
|
||||
let routing_table = veilid_api.routing_table()?;
|
||||
let rss = routing_table.route_spec_store();
|
||||
|
||||
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_app_call", "id", id));
|
||||
};
|
||||
routing_context.clone()
|
||||
};
|
||||
|
||||
let target: DHTKey =
|
||||
DHTKey::try_decode(&target).map_err(|e| VeilidAPIError::parse_error(e, &target))?;
|
||||
|
||||
let target = if rss.get_remote_private_route(&target).is_some() {
|
||||
veilid_core::Target::PrivateRoute(target)
|
||||
} else {
|
||||
veilid_core::Target::NodeId(veilid_core::NodeId::new(target))
|
||||
};
|
||||
|
||||
routing_context.app_message(target, message).await?;
|
||||
APIRESULT_UNDEFINED
|
||||
})
|
||||
}
|
||||
|
||||
#[wasm_bindgen()]
|
||||
pub fn new_private_route() -> Promise {
|
||||
wrap_api_future(async move {
|
||||
let veilid_api = get_veilid_api()?;
|
||||
|
||||
let (key, blob) = veilid_api.new_private_route().await?;
|
||||
|
||||
let keyblob = VeilidKeyBlob { key, blob };
|
||||
|
||||
APIResult::Ok(keyblob)
|
||||
})
|
||||
}
|
||||
|
||||
#[wasm_bindgen()]
|
||||
pub fn new_custom_private_route(stability: String, sequencing: String) -> Promise {
|
||||
let stability: veilid_core::Stability = veilid_core::deserialize_json(&stability).unwrap();
|
||||
let sequencing: veilid_core::Sequencing = veilid_core::deserialize_json(&sequencing).unwrap();
|
||||
|
||||
wrap_api_future(async move {
|
||||
let veilid_api = get_veilid_api()?;
|
||||
|
||||
let (key, blob) = veilid_api
|
||||
.new_custom_private_route(stability, sequencing)
|
||||
.await?;
|
||||
|
||||
let keyblob = VeilidKeyBlob { key, blob };
|
||||
|
||||
APIResult::Ok(keyblob)
|
||||
})
|
||||
}
|
||||
|
||||
#[wasm_bindgen()]
|
||||
pub fn import_remote_private_route(blob: String) -> Promise {
|
||||
let blob: Vec<u8> = data_encoding::BASE64URL_NOPAD
|
||||
.decode(blob.as_bytes())
|
||||
.unwrap();
|
||||
wrap_api_future(async move {
|
||||
let veilid_api = get_veilid_api()?;
|
||||
|
||||
let key = veilid_api.import_remote_private_route(blob)?;
|
||||
|
||||
APIResult::Ok(key.encode())
|
||||
})
|
||||
}
|
||||
|
||||
#[wasm_bindgen()]
|
||||
pub fn release_private_route(key: String) -> Promise {
|
||||
let key: veilid_core::DHTKey = veilid_core::deserialize_json(&key).unwrap();
|
||||
wrap_api_future(async move {
|
||||
let veilid_api = get_veilid_api()?;
|
||||
veilid_api.release_private_route(&key)?;
|
||||
APIRESULT_UNDEFINED
|
||||
})
|
||||
}
|
||||
|
||||
#[wasm_bindgen()]
|
||||
pub fn app_call_reply(id: String, message: String) -> Promise {
|
||||
let message: Vec<u8> = data_encoding::BASE64URL_NOPAD
|
||||
.decode(message.as_bytes())
|
||||
.unwrap();
|
||||
wrap_api_future(async move {
|
||||
let id = match id.parse() {
|
||||
Ok(v) => v,
|
||||
@ -274,15 +462,21 @@ pub fn app_call_reply(id: String, message: String) -> Promise {
|
||||
return APIResult::Err(veilid_core::VeilidAPIError::invalid_argument(e, "id", id))
|
||||
}
|
||||
};
|
||||
let message = data_encoding::BASE64URL_NOPAD
|
||||
.decode(message.as_bytes())
|
||||
.map_err(|e| veilid_core::VeilidAPIError::invalid_argument(e, "message", message))?;
|
||||
let veilid_api = get_veilid_api()?;
|
||||
let out = veilid_api.app_call_reply(id, message).await?;
|
||||
Ok(out)
|
||||
})
|
||||
}
|
||||
|
||||
#[wasm_bindgen()]
|
||||
pub fn debug(command: String) -> Promise {
|
||||
wrap_api_future(async move {
|
||||
let veilid_api = get_veilid_api()?;
|
||||
let out = veilid_api.debug(command).await?;
|
||||
Ok(out)
|
||||
})
|
||||
}
|
||||
|
||||
#[wasm_bindgen()]
|
||||
pub fn veilid_version_string() -> String {
|
||||
veilid_core::veilid_version_string()
|
||||
|
Loading…
Reference in New Issue
Block a user