diff --git a/setup_linux.sh b/setup_linux.sh index d7897d1d..20a225e0 100755 --- a/setup_linux.sh +++ b/setup_linux.sh @@ -55,14 +55,13 @@ else exit 1 fi -# install android targets +# install targets rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android -# install cargo ndk -cargo install cargo-ndk -cargo install cargo-apk +# install cargo packages +cargo install wasm-bindgen-cli # Ensure packages are installed -sudo apt-get install libc6-dev-i386 libc6:i386 libncurses5:i386 libstdc++6:i386 lib32z1 libbz2-1.0:i386 openjdk-11-jdk llvm +sudo apt-get install libc6-dev-i386 libc6:i386 libncurses5:i386 libstdc++6:i386 lib32z1 libbz2-1.0:i386 openjdk-11-jdk llvm wabt diff --git a/setup_macos.sh b/setup_macos.sh index d714dcae..89fd4fe4 100755 --- a/setup_macos.sh +++ b/setup_macos.sh @@ -6,15 +6,19 @@ if [ ! "$(uname)" == "Darwin" ]; then exit 1 fi -# install android targets +# install targets rustup target add aarch64-apple-darwin aarch64-apple-ios x86_64-apple-darwin x86_64-apple-ios +# install cargo packages +cargo install wasm-bindgen-cli + +# install bitcode compatible ios toolchain echo Manual Step: echo install +ios-arm64-1.57.0 toolchain for bitcode from https://github.com/getditto/rust-bitcode/releases/latest and unzip echo xattr -d -r com.apple.quarantine . echo ./install.sh -# Ensure brew is installed +# ensure brew is installed if command -v brew &> /dev/null; then echo '[X] brew is available in the path' else @@ -22,7 +26,7 @@ else exit 1 fi -# Ensure xcode is installed +# ensure xcode is installed if command -v xcode-select &> /dev/null; then echo '[X] XCode is available in the path' else @@ -30,10 +34,10 @@ else exit 1 fi -# Ensure we have command line tools +# ensure we have command line tools xcode-select --install -# Ensure packages are installed +# ensure packages are installed if [ "$BREW_USER" == "" ]; then BREW_USER=`ls -lad /opt/homebrew/. | cut -d\ -f4` echo "Must sudo to homebrew user \"$BREW_USER\" to install capnp package:" diff --git a/veilid-core/src/rpc_processor/mod.rs b/veilid-core/src/rpc_processor/mod.rs index 5b5d5d72..17e7ebed 100644 --- a/veilid-core/src/rpc_processor/mod.rs +++ b/veilid-core/src/rpc_processor/mod.rs @@ -1484,9 +1484,6 @@ impl RPCProcessor { let own_peer_info = self .routing_table() .get_own_peer_info(self.default_peer_scope); - if own_peer_info.dial_infos.is_empty() { - return Err(rpc_error_internal("No valid public dial info for own node")); - } encode_peer_info(&own_peer_info, &mut peer_info_builder)?; diff --git a/veilid-flutter/example/lib/main.dart b/veilid-flutter/example/lib/main.dart index fc96e889..d0eddb1a 100644 --- a/veilid-flutter/example/lib/main.dart +++ b/veilid-flutter/example/lib/main.dart @@ -89,10 +89,11 @@ class _MyAppState extends State with UiLoggy { // Platform messages may fail, so we use a try/catch PlatformException. // We also handle the message potentially returning null. try { - veilidVersion = await Veilid.instance.veilidVersionString(); + veilidVersion = Veilid.instance.veilidVersionString(); } on Exception { veilidVersion = 'Failed to get veilid version.'; } + print("veilidVersionString $veilidVersion"); // In case of hot restart shut down first try { diff --git a/veilid-flutter/example/pubspec.lock b/veilid-flutter/example/pubspec.lock index 49a2cb3d..7a9996d9 100644 --- a/veilid-flutter/example/pubspec.lock +++ b/veilid-flutter/example/pubspec.lock @@ -149,13 +149,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.7.0" - mutex: - dependency: transitive - description: - name: mutex - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.0" path: dependency: transitive description: @@ -308,13 +301,6 @@ packages: relative: true source: path version: "0.0.1" - wasm_interop: - dependency: transitive - description: - name: wasm_interop - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.1" win32: dependency: transitive description: diff --git a/veilid-flutter/example/web/index.html b/veilid-flutter/example/web/index.html index 79f547e1..d87886d6 100644 --- a/veilid-flutter/example/web/index.html +++ b/veilid-flutter/example/web/index.html @@ -31,8 +31,27 @@ veilid_example + + + + + xxx figure out how to switch to debug, maybe do this from dart land + + + diff --git a/veilid-flutter/example/web/wasm b/veilid-flutter/example/web/wasm new file mode 120000 index 00000000..75fb9e0b --- /dev/null +++ b/veilid-flutter/example/web/wasm @@ -0,0 +1 @@ +../../../target/wasm32-unknown-unknown/release/pkg \ No newline at end of file diff --git a/veilid-flutter/lib/veilid.dart b/veilid-flutter/lib/veilid.dart index 06e3b7f3..5232b6f2 100644 --- a/veilid-flutter/lib/veilid.dart +++ b/veilid-flutter/lib/veilid.dart @@ -996,6 +996,6 @@ abstract class Veilid { Future changeLogLevel(VeilidConfigLogLevel logLevel); Future shutdownVeilidCore(); Future debug(String command); - Future veilidVersionString(); - Future veilidVersion(); + String veilidVersionString(); + VeilidVersion veilidVersion(); } diff --git a/veilid-flutter/lib/veilid_ffi.dart b/veilid-flutter/lib/veilid_ffi.dart index 03fb011a..a37cb411 100644 --- a/veilid-flutter/lib/veilid_ffi.dart +++ b/veilid-flutter/lib/veilid_ffi.dart @@ -326,7 +326,7 @@ class VeilidFFI implements Veilid { } @override - Future veilidVersionString() async { + String veilidVersionString() { final versionString = _veilidVersionString(); String ret = versionString.toDartString(); _freeString(versionString); @@ -334,7 +334,7 @@ class VeilidFFI implements Veilid { } @override - Future veilidVersion() async { + VeilidVersion veilidVersion() { final version = _veilidVersion(); return VeilidVersion( version.major, diff --git a/veilid-flutter/lib/veilid_js.dart b/veilid-flutter/lib/veilid_js.dart index d4a15039..344bc9a9 100644 --- a/veilid-flutter/lib/veilid_js.dart +++ b/veilid-flutter/lib/veilid_js.dart @@ -1,81 +1,76 @@ import 'veilid.dart'; -import 'dart:js'; -import 'dart:js_util'; +import 'dart:html' as html; +import 'dart:js' as js; +import 'dart:js_util' as js_util; import 'dart:async'; import 'dart:convert'; -import 'package:flutter/services.dart' show NetworkAssetBundle; -import 'package:wasm_interop/wasm_interop.dart'; -import 'package:mutex/mutex.dart'; ////////////////////////////////////////////////////////// Veilid getVeilid() => VeilidJS(); -Instance? _wasmInstance; -final _wasmInstanceMutex = Mutex(); +Object wasm = js_util.getProperty(html.window, "veilid_wasm"); -Future getWasmInstance() async { - await _wasmInstanceMutex.acquire(); - var _wi = _wasmInstance; - if (_wi == null) { - final bytes = await http???.get(Uri.parse("/wasm/veilid_wasm.wasm")); - _wi = await Instance.fromBufferAsync(bytes.buffer); - _wasmInstance = _wi; - } - _wasmInstanceMutex.release(); - return _wi; +Future _wrapApiPromise(Object p) { + return js_util.promiseToFuture(p).then((value) => value as T).catchError( + (error) => Future.error( + VeilidAPIException.fromJson(jsonDecode(error as String)))); } class VeilidJS implements Veilid { @override Stream startupVeilidCore(VeilidConfig config) async* { - var wasm = (await getWasmInstance()); var streamController = StreamController(); - await promiseToFuture( - wasm.functions["startup_veilid_core"]!.call((String update) { - streamController.add(VeilidUpdate.fromJson(jsonDecode(update))); - }, jsonEncode(config.json, toEncodable: veilidApiToEncodable))); + updateCallback(String update) { + var updateJson = jsonDecode(update); + if (updateJson["kind"] == "Shutdown") { + streamController.close(); + } else { + var update = VeilidUpdate.fromJson(updateJson); + streamController.add(update); + } + } + + await _wrapApiPromise(js_util.callMethod(wasm, "startup_veilid_core", [ + js.allowInterop(updateCallback), + jsonEncode(config.json, toEncodable: veilidApiToEncodable) + ])); yield* streamController.stream; } @override Future getVeilidState() async { - var wasm = (await getWasmInstance()); - return VeilidState.fromJson(jsonDecode( - await promiseToFuture(wasm.functions["get_veilid_state"]!.call()))); + return VeilidState.fromJson(jsonDecode(await _wrapApiPromise( + js_util.callMethod(wasm, "get_veilid_state", [])))); } @override - Future changeLogLevel(VeilidConfigLogLevel logLevel) async { - var wasm = (await getWasmInstance()); - await promiseToFuture(wasm.functions["change_log_level"]! - .call(jsonEncode(logLevel.json, toEncodable: veilidApiToEncodable))); + Future changeLogLevel(VeilidConfigLogLevel logLevel) { + return _wrapApiPromise(js_util.callMethod(wasm, "change_log_level", + [jsonEncode(logLevel.json, toEncodable: veilidApiToEncodable)])); } @override - Future shutdownVeilidCore() async { - var wasm = (await getWasmInstance()); - await promiseToFuture(wasm.functions["shutdown_veilid_core"]!.call()); + Future shutdownVeilidCore() { + return _wrapApiPromise( + js_util.callMethod(wasm, "shutdown_veilid_core", [])); } @override - Future debug(String command) async { - var wasm = (await getWasmInstance()); - return await promiseToFuture(wasm.functions["debug"]!.call(command)); + Future debug(String command) { + return _wrapApiPromise(js_util.callMethod(wasm, "debug", [command])); } @override - Future veilidVersionString() async { - var wasm = (await getWasmInstance()); - return await promiseToFuture(wasm.functions["debug"]!.call()); + String veilidVersionString() { + return js_util.callMethod(wasm, "veilid_version_string", []); } @override - Future veilidVersion() async { - var wasm = (await getWasmInstance()); - var jsonVersion = jsonDecode( - await promiseToFuture(wasm.functions["get_veilid_state"]!.call())); + VeilidVersion veilidVersion() { + var jsonVersion = + jsonDecode(js_util.callMethod(wasm, "veilid_version", [])); return VeilidVersion( jsonVersion["major"], jsonVersion["minor"], jsonVersion["patch"]); } diff --git a/veilid-flutter/pubspec.yaml b/veilid-flutter/pubspec.yaml index 8965ab62..a661be04 100644 --- a/veilid-flutter/pubspec.yaml +++ b/veilid-flutter/pubspec.yaml @@ -17,8 +17,6 @@ dependencies: change_case: ^1.0.1 path_provider: ^2.0.9 path: ^1.8.0 - wasm_interop: ^2.0.1 - mutex: ^3.0.0 dev_dependencies: flutter_test: diff --git a/veilid-wasm/src/lib.rs b/veilid-wasm/src/lib.rs index 25f3bfaa..63b1e608 100644 --- a/veilid-wasm/src/lib.rs +++ b/veilid-wasm/src/lib.rs @@ -138,7 +138,7 @@ pub fn get_veilid_state() -> Promise { }) } -#[wasm_bindgen(js_namespace = veilid)] +#[wasm_bindgen()] pub fn change_log_level(log_level: String) -> Promise { wrap_api_future(async move { let veilid_api = get_veilid_api()?; diff --git a/veilid-wasm/wasm_build.sh b/veilid-wasm/wasm_build.sh index 0174c81a..2d226550 100755 --- a/veilid-wasm/wasm_build.sh +++ b/veilid-wasm/wasm_build.sh @@ -1,16 +1,25 @@ #!/bin/bash SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +pushd $SCRIPTDIR &> /dev/null + if [[ "$1" == "release" ]]; then - RELEASE=-r - GENERATE_SOURCE_MAP= + OUTPUTDIR=../target/wasm32-unknown-unknown/release/pkg + INPUTDIR=../target/wasm32-unknown-unknown/release + + cargo build --target wasm32-unknown-unknown --release + mkdir -p $OUTPUTDIR + wasm-bindgen --out-dir $OUTPUTDIR --target web --no-typescript $INPUTDIR/veilid_wasm.wasm + wasm-strip $OUTPUTDIR/veilid_wasm_bg.wasm else - RELEASE= - RUSTFLAGS="-O -g" - GENERATE_SOURCE_MAP="./wasm-sourcemap.py ../target/wasm32-unknown-unknown/debug/veilid_wasm.wasm -o ../target/wasm32-unknown-unknown/debug/veilid_wasm.wasm.map --dwarfdump `which llvm-dwarfdump`" + OUTPUTDIR=../target/wasm32-unknown-unknown/debug/pkg + INPUTDIR=../target/wasm32-unknown-unknown/debug + + RUSTFLAGS="-O -g" cargo build --target wasm32-unknown-unknown + mkdir -p $OUTPUTDIR + wasm-bindgen --out-dir $OUTPUTDIR --target web --no-typescript --keep-debug --debug $INPUTDIR/veilid_wasm.wasm + ./wasm-sourcemap.py $OUTPUTDIR/veilid_wasm_bg.wasm -o $OUTPUTDIR/veilid_wasm_bg.wasm.map --dwarfdump `which llvm-dwarfdump` + wasm-strip $OUTPUTDIR/veilid_wasm_bg.wasm fi -pushd $SCRIPTDIR 2> /dev/null -cargo build --target wasm32-unknown-unknown $RELEASE -$GENERATE_SOURCE_MAP -popd 2> /dev/null \ No newline at end of file +popd &> /dev/null