wasm fixes

This commit is contained in:
Christien Rioux 2023-10-14 20:18:37 -04:00
parent a363bb0462
commit e40975104e
10 changed files with 90 additions and 43 deletions

View File

@ -1,3 +1,3 @@
#!/bin/bash #!/bin/bash
set -e set -e
dart run build_runner build dart run build_runner build --delete-conflicting-outputs

View File

@ -123,7 +123,7 @@ class ValueData with _$ValueData {
@Assert('seq >= 0', 'seq out of range') @Assert('seq >= 0', 'seq out of range')
const factory ValueData({ const factory ValueData({
required int seq, required int seq,
@Uint8ListJsonConverter() required Uint8List data, @Uint8ListJsonConverter.jsIsArray() required Uint8List data,
required PublicKey writer, required PublicKey writer,
}) = _ValueData; }) = _ValueData;

View File

@ -969,7 +969,7 @@ ValueData _$ValueDataFromJson(Map<String, dynamic> json) {
/// @nodoc /// @nodoc
mixin _$ValueData { mixin _$ValueData {
int get seq => throw _privateConstructorUsedError; int get seq => throw _privateConstructorUsedError;
@Uint8ListJsonConverter() @Uint8ListJsonConverter.jsIsArray()
Uint8List get data => throw _privateConstructorUsedError; Uint8List get data => throw _privateConstructorUsedError;
FixedEncodedString43 get writer => throw _privateConstructorUsedError; FixedEncodedString43 get writer => throw _privateConstructorUsedError;
@ -986,7 +986,7 @@ abstract class $ValueDataCopyWith<$Res> {
@useResult @useResult
$Res call( $Res call(
{int seq, {int seq,
@Uint8ListJsonConverter() Uint8List data, @Uint8ListJsonConverter.jsIsArray() Uint8List data,
FixedEncodedString43 writer}); FixedEncodedString43 writer});
} }
@ -1033,7 +1033,7 @@ abstract class _$$_ValueDataCopyWith<$Res> implements $ValueDataCopyWith<$Res> {
@useResult @useResult
$Res call( $Res call(
{int seq, {int seq,
@Uint8ListJsonConverter() Uint8List data, @Uint8ListJsonConverter.jsIsArray() Uint8List data,
FixedEncodedString43 writer}); FixedEncodedString43 writer});
} }
@ -1074,7 +1074,7 @@ class __$$_ValueDataCopyWithImpl<$Res>
class _$_ValueData implements _ValueData { class _$_ValueData implements _ValueData {
const _$_ValueData( const _$_ValueData(
{required this.seq, {required this.seq,
@Uint8ListJsonConverter() required this.data, @Uint8ListJsonConverter.jsIsArray() required this.data,
required this.writer}) required this.writer})
: assert(seq >= 0, 'seq out of range'); : assert(seq >= 0, 'seq out of range');
@ -1084,7 +1084,7 @@ class _$_ValueData implements _ValueData {
@override @override
final int seq; final int seq;
@override @override
@Uint8ListJsonConverter() @Uint8ListJsonConverter.jsIsArray()
final Uint8List data; final Uint8List data;
@override @override
final FixedEncodedString43 writer; final FixedEncodedString43 writer;
@ -1126,7 +1126,7 @@ class _$_ValueData implements _ValueData {
abstract class _ValueData implements ValueData { abstract class _ValueData implements ValueData {
const factory _ValueData( const factory _ValueData(
{required final int seq, {required final int seq,
@Uint8ListJsonConverter() required final Uint8List data, @Uint8ListJsonConverter.jsIsArray() required final Uint8List data,
required final FixedEncodedString43 writer}) = _$_ValueData; required final FixedEncodedString43 writer}) = _$_ValueData;
factory _ValueData.fromJson(Map<String, dynamic> json) = factory _ValueData.fromJson(Map<String, dynamic> json) =
@ -1135,7 +1135,7 @@ abstract class _ValueData implements ValueData {
@override @override
int get seq; int get seq;
@override @override
@Uint8ListJsonConverter() @Uint8ListJsonConverter.jsIsArray()
Uint8List get data; Uint8List get data;
@override @override
FixedEncodedString43 get writer; FixedEncodedString43 get writer;

View File

@ -80,14 +80,14 @@ Map<String, dynamic> _$$_ValueSubkeyRangeToJson(_$_ValueSubkeyRange instance) =>
_$_ValueData _$$_ValueDataFromJson(Map<String, dynamic> json) => _$_ValueData( _$_ValueData _$$_ValueDataFromJson(Map<String, dynamic> json) => _$_ValueData(
seq: json['seq'] as int, seq: json['seq'] as int,
data: const Uint8ListJsonConverter().fromJson(json['data'] as String), data: const Uint8ListJsonConverter.jsIsArray().fromJson(json['data']),
writer: FixedEncodedString43.fromJson(json['writer']), writer: FixedEncodedString43.fromJson(json['writer']),
); );
Map<String, dynamic> _$$_ValueDataToJson(_$_ValueData instance) => Map<String, dynamic> _$$_ValueDataToJson(_$_ValueData instance) =>
<String, dynamic>{ <String, dynamic>{
'seq': instance.seq, 'seq': instance.seq,
'data': const Uint8ListJsonConverter().toJson(instance.data), 'data': const Uint8ListJsonConverter.jsIsArray().toJson(instance.data),
'writer': instance.writer.toJson(), 'writer': instance.writer.toJson(),
}; };
@ -109,7 +109,7 @@ Map<String, dynamic> _$$_SafetySpecToJson(_$_SafetySpec instance) =>
_$_RouteBlob _$$_RouteBlobFromJson(Map<String, dynamic> json) => _$_RouteBlob( _$_RouteBlob _$$_RouteBlobFromJson(Map<String, dynamic> json) => _$_RouteBlob(
routeId: json['route_id'] as String, routeId: json['route_id'] as String,
blob: const Uint8ListJsonConverter().fromJson(json['blob'] as String), blob: const Uint8ListJsonConverter().fromJson(json['blob']),
); );
Map<String, dynamic> _$$_RouteBlobToJson(_$_RouteBlob instance) => Map<String, dynamic> _$$_RouteBlobToJson(_$_RouteBlob instance) =>

View File

@ -1,9 +1,13 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:typed_data';
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:flutter/foundation.dart';
import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:freezed_annotation/freezed_annotation.dart';
import 'veilid_stub.dart'
if (dart.library.io) 'veilid_ffi.dart'
if (dart.library.js) 'veilid_js.dart';
String base64UrlNoPadEncode(List<int> bytes) { String base64UrlNoPadEncode(List<int> bytes) {
var x = base64Url.encode(bytes); var x = base64Url.encode(bytes);
while (x.endsWith('=')) { while (x.endsWith('=')) {
@ -20,13 +24,20 @@ Uint8List base64UrlNoPadDecode(String source) {
Uint8List base64UrlNoPadDecodeDynamic(dynamic source) => Uint8List base64UrlNoPadDecodeDynamic(dynamic source) =>
base64UrlNoPadDecode(source as String); base64UrlNoPadDecode(source as String);
class Uint8ListJsonConverter implements JsonConverter<Uint8List, String> { class Uint8ListJsonConverter implements JsonConverter<Uint8List, dynamic> {
const Uint8ListJsonConverter(); const Uint8ListJsonConverter() : _jsIsArray = false;
const Uint8ListJsonConverter.jsIsArray() : _jsIsArray = true;
final bool _jsIsArray;
@override @override
Uint8List fromJson(dynamic json) => base64UrlNoPadDecode(json as String); Uint8List fromJson(dynamic json) => kIsWeb && _jsIsArray
? convertUint8ListFromJson(json)
: base64UrlNoPadDecode(json as String);
@override @override
String toJson(Uint8List data) => base64UrlNoPadEncode(data); dynamic toJson(Uint8List data) => kIsWeb && _jsIsArray
? convertUint8ListToJson(data)
: base64UrlNoPadEncode(data);
} }
@immutable @immutable

View File

@ -246,6 +246,11 @@ const int messageStreamClose = 8;
// Interface factory for high level Veilid API // Interface factory for high level Veilid API
Veilid getVeilid() => VeilidFFI(_dylib); Veilid getVeilid() => VeilidFFI(_dylib);
// Uint8List marshaling
Uint8List convertUint8ListFromJson(dynamic json) =>
base64UrlNoPadDecode(json as String);
dynamic convertUint8ListToJson(Uint8List data) => base64UrlNoPadEncode(data);
// Parse handle async returns // Parse handle async returns
Future<T> processFuturePlain<T>(Future<dynamic> future) async => Future<T> processFuturePlain<T>(Future<dynamic> future) async =>
future.then((value) { future.then((value) {

View File

@ -2,6 +2,7 @@ import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'dart:html' as html; import 'dart:html' as html;
import 'dart:js' as js; import 'dart:js' as js;
import 'dart:js_interop' as js_interop;
import 'dart:js_util' as js_util; import 'dart:js_util' as js_util;
import 'dart:typed_data'; import 'dart:typed_data';
@ -13,14 +14,26 @@ Veilid getVeilid() => VeilidJS();
Object wasm = js_util.getProperty(html.window, 'veilid_wasm'); Object wasm = js_util.getProperty(html.window, 'veilid_wasm');
Uint8List convertUint8ListFromJson(dynamic json) => Uint8List.fromList(
((json as js_interop.JSArray).dartify()! as List<Object?>)
.map((e) => e! as int)
.toList());
dynamic convertUint8ListToJson(Uint8List data) => data.toList().jsify();
Future<T> _wrapApiPromise<T>(Object p) => js_util Future<T> _wrapApiPromise<T>(Object p) => js_util
.promiseToFuture<T>(p) .promiseToFuture<T>(p)
.then((value) => value) .then((value) => value)
// ignore: inference_failure_on_untyped_parameter // ignore: inference_failure_on_untyped_parameter
.catchError((e) { .catchError((e) {
// Wrap all other errors in VeilidAPIExceptionInternal try {
throw VeilidAPIExceptionInternal(e.toString()); final ex = VeilidAPIException.fromJson(jsonDecode(e as String));
}, test: (e) => e is! VeilidAPIException); throw ex;
} on Exception catch (_) {
// Wrap all other errors in VeilidAPIExceptionInternal
throw VeilidAPIExceptionInternal(e.toString());
}
});
class _Ctx { class _Ctx {
_Ctx(int id, this.js) : _id = id; _Ctx(int id, this.js) : _id = id;
@ -142,7 +155,11 @@ class VeilidRoutingContextJS extends VeilidRoutingContext {
wasm, wasm,
'routing_context_get_dht_value', 'routing_context_get_dht_value',
[id, jsonEncode(key), subkey, forceRefresh])); [id, jsonEncode(key), subkey, forceRefresh]));
return opt == null ? null : ValueData.fromJson(jsonDecode(opt)); if (opt == null) {
return null;
}
final jsonOpt = jsonDecode(opt);
return jsonOpt == null ? null : ValueData.fromJson(jsonOpt);
} }
@override @override
@ -153,7 +170,11 @@ class VeilidRoutingContextJS extends VeilidRoutingContext {
wasm, wasm,
'routing_context_set_dht_value', 'routing_context_set_dht_value',
[id, jsonEncode(key), subkey, base64UrlNoPadEncode(data)])); [id, jsonEncode(key), subkey, base64UrlNoPadEncode(data)]));
return opt == null ? null : ValueData.fromJson(jsonDecode(opt)); if (opt == null) {
return null;
}
final jsonOpt = jsonDecode(opt);
return jsonOpt == null ? null : ValueData.fromJson(jsonOpt);
} }
@override @override

View File

@ -129,8 +129,7 @@ Map<String, dynamic> _$$VeilidLogToJson(_$VeilidLog instance) =>
_$VeilidAppMessage _$$VeilidAppMessageFromJson(Map<String, dynamic> json) => _$VeilidAppMessage _$$VeilidAppMessageFromJson(Map<String, dynamic> json) =>
_$VeilidAppMessage( _$VeilidAppMessage(
message: message: const Uint8ListJsonConverter().fromJson(json['message']),
const Uint8ListJsonConverter().fromJson(json['message'] as String),
sender: json['sender'] == null sender: json['sender'] == null
? null ? null
: Typed<FixedEncodedString43>.fromJson(json['sender']), : Typed<FixedEncodedString43>.fromJson(json['sender']),
@ -146,8 +145,7 @@ Map<String, dynamic> _$$VeilidAppMessageToJson(_$VeilidAppMessage instance) =>
_$VeilidAppCall _$$VeilidAppCallFromJson(Map<String, dynamic> json) => _$VeilidAppCall _$$VeilidAppCallFromJson(Map<String, dynamic> json) =>
_$VeilidAppCall( _$VeilidAppCall(
message: message: const Uint8ListJsonConverter().fromJson(json['message']),
const Uint8ListJsonConverter().fromJson(json['message'] as String),
callId: json['call_id'] as String, callId: json['call_id'] as String,
sender: json['sender'] == null sender: json['sender'] == null
? null ? null

View File

@ -1,3 +1,9 @@
import 'dart:typed_data';
import 'veilid.dart'; import 'veilid.dart';
Veilid getVeilid() => throw UnsupportedError('Cannot create Veilid object'); Veilid getVeilid() => throw UnsupportedError('Cannot create Veilid object');
Uint8List convertUint8ListFromJson(dynamic json) =>
throw UnsupportedError('Cannot convertUint8ListFromJson');
dynamic convertUint8ListToJson(Uint8List data) =>
throw UnsupportedError('Cannot convertUint8ListToJson');

View File

@ -345,11 +345,14 @@ pub fn release_routing_context(id: u32) -> i32 {
#[wasm_bindgen()] #[wasm_bindgen()]
pub fn routing_context_with_privacy(id: u32) -> u32 { pub fn routing_context_with_privacy(id: u32) -> u32 {
let rc = (*ROUTING_CONTEXTS).borrow(); let routing_context = {
let Some(routing_context) = rc.get(&id) else { let rc = (*ROUTING_CONTEXTS).borrow();
return 0; let Some(routing_context) = rc.get(&id) else {
return 0;
};
routing_context.clone()
}; };
let Ok(routing_context) = routing_context.clone().with_privacy() else { let Ok(routing_context) = routing_context.with_privacy() else {
return 0; return 0;
}; };
add_routing_context(routing_context) add_routing_context(routing_context)
@ -360,14 +363,14 @@ pub fn routing_context_with_custom_privacy(id: u32, safety_selection: String) ->
let safety_selection: veilid_core::SafetySelection = let safety_selection: veilid_core::SafetySelection =
veilid_core::deserialize_json(&safety_selection).unwrap(); veilid_core::deserialize_json(&safety_selection).unwrap();
let rc = (*ROUTING_CONTEXTS).borrow(); let routing_context = {
let Some(routing_context) = rc.get(&id) else { let rc = (*ROUTING_CONTEXTS).borrow();
return 0; let Some(routing_context) = rc.get(&id) else {
return 0;
};
routing_context.clone()
}; };
let Ok(routing_context) = routing_context let Ok(routing_context) = routing_context.with_custom_privacy(safety_selection) else {
.clone()
.with_custom_privacy(safety_selection)
else {
return 0; return 0;
}; };
add_routing_context(routing_context) add_routing_context(routing_context)
@ -377,11 +380,14 @@ pub fn routing_context_with_custom_privacy(id: u32, safety_selection: String) ->
pub fn routing_context_with_sequencing(id: u32, sequencing: String) -> u32 { pub fn routing_context_with_sequencing(id: u32, sequencing: String) -> u32 {
let sequencing: veilid_core::Sequencing = veilid_core::deserialize_json(&sequencing).unwrap(); let sequencing: veilid_core::Sequencing = veilid_core::deserialize_json(&sequencing).unwrap();
let rc = (*ROUTING_CONTEXTS).borrow(); let routing_context = {
let Some(routing_context) = rc.get(&id) else { let rc = (*ROUTING_CONTEXTS).borrow();
return 0; let Some(routing_context) = rc.get(&id) else {
return 0;
};
routing_context.clone()
}; };
let routing_context = routing_context.clone().with_sequencing(sequencing); let routing_context = routing_context.with_sequencing(sequencing);
add_routing_context(routing_context) add_routing_context(routing_context)
} }
@ -1544,8 +1550,8 @@ pub fn crypto_crypt_no_auth(
} }
#[wasm_bindgen()] #[wasm_bindgen()]
pub fn now() -> u64 { pub fn now() -> String {
veilid_core::get_aligned_timestamp().as_u64() veilid_core::get_aligned_timestamp().as_u64().to_string()
} }
#[wasm_bindgen()] #[wasm_bindgen()]