lint cleanup

This commit is contained in:
Christien Rioux 2023-07-26 15:12:28 -04:00
parent f91a350bfc
commit d49c631fac
3 changed files with 243 additions and 199 deletions

View File

@ -39,26 +39,15 @@ Object? veilidApiToEncodable(Object? value) {
throw UnsupportedError('Cannot convert to JSON: $value'); throw UnsupportedError('Cannot convert to JSON: $value');
} }
T? Function(dynamic) optFromJson<T>(
T Function(Map<String, dynamic>) jsonConstructor) => (dynamic j) {
if (j == null) {
return null;
} else {
return jsonConstructor(j);
}
};
List<T> Function(dynamic) jsonListConstructor<T>( List<T> Function(dynamic) jsonListConstructor<T>(
T Function(Map<String, dynamic>) jsonConstructor) => (dynamic j) => (j as List<Map<String, dynamic>>) T Function(dynamic) jsonConstructor) =>
.map((e) => jsonConstructor(e)) (dynamic j) => (j as List<dynamic>).map((e) => jsonConstructor(e)).toList();
.toList();
////////////////////////////////////// //////////////////////////////////////
/// VeilidVersion /// VeilidVersion
@immutable @immutable
class VeilidVersion extends Equatable { class VeilidVersion extends Equatable {
const VeilidVersion(this.major, this.minor, this.patch); const VeilidVersion(this.major, this.minor, this.patch);
final int major; final int major;
final int minor; final int minor;
@ -71,7 +60,6 @@ class VeilidVersion extends Equatable {
/// Timestamp /// Timestamp
@immutable @immutable
class Timestamp extends Equatable { class Timestamp extends Equatable {
const Timestamp({required this.value}); const Timestamp({required this.value});
factory Timestamp.fromString(String s) => Timestamp(value: BigInt.parse(s)); factory Timestamp.fromString(String s) => Timestamp(value: BigInt.parse(s));
factory Timestamp.fromJson(dynamic json) => factory Timestamp.fromJson(dynamic json) =>
@ -94,7 +82,6 @@ class Timestamp extends Equatable {
@immutable @immutable
class TimestampDuration extends Equatable { class TimestampDuration extends Equatable {
const TimestampDuration({required this.value}); const TimestampDuration({required this.value});
factory TimestampDuration.fromString(String s) => factory TimestampDuration.fromString(String s) =>
TimestampDuration(value: BigInt.parse(s)); TimestampDuration(value: BigInt.parse(s));

View File

@ -5,8 +5,9 @@ import 'package:freezed_annotation/freezed_annotation.dart';
@immutable @immutable
abstract class VeilidAPIException implements Exception { abstract class VeilidAPIException implements Exception {
factory VeilidAPIException.fromJson(dynamic json) { factory VeilidAPIException.fromJson(dynamic j) {
switch (json['kind']) { final json = j as Map<String, dynamic>;
switch (json['kind']! as String) {
case 'NotInitialized': case 'NotInitialized':
{ {
return VeilidAPIExceptionNotInitialized(); return VeilidAPIExceptionNotInitialized();
@ -33,42 +34,44 @@ abstract class VeilidAPIException implements Exception {
} }
case 'NoConnection': case 'NoConnection':
{ {
return VeilidAPIExceptionNoConnection(json['message']); return VeilidAPIExceptionNoConnection(json['message']! as String);
} }
case 'KeyNotFound': case 'KeyNotFound':
{ {
return VeilidAPIExceptionKeyNotFound(json['key']); return VeilidAPIExceptionKeyNotFound(json['key']! as String);
} }
case 'Internal': case 'Internal':
{ {
return VeilidAPIExceptionInternal(json['message']); return VeilidAPIExceptionInternal(json['message']! as String);
} }
case 'Unimplemented': case 'Unimplemented':
{ {
return VeilidAPIExceptionUnimplemented(json['unimplemented']); return VeilidAPIExceptionUnimplemented(
json['unimplemented']! as String);
} }
case 'ParseError': case 'ParseError':
{ {
return VeilidAPIExceptionParseError(json['message'], json['value']); return VeilidAPIExceptionParseError(
json['message']! as String, json['value']! as String);
} }
case 'InvalidArgument': case 'InvalidArgument':
{ {
return VeilidAPIExceptionInvalidArgument( return VeilidAPIExceptionInvalidArgument(json['context']! as String,
json['context'], json['argument'], json['value']); json['argument']! as String, json['value']! as String);
} }
case 'MissingArgument': case 'MissingArgument':
{ {
return VeilidAPIExceptionMissingArgument( return VeilidAPIExceptionMissingArgument(
json['context'], json['argument']); json['context']! as String, json['argument']! as String);
} }
case 'Generic': case 'Generic':
{ {
return VeilidAPIExceptionGeneric(json['message']); return VeilidAPIExceptionGeneric(json['message']! as String);
} }
default: default:
{ {
throw VeilidAPIExceptionInternal( throw VeilidAPIExceptionInternal(
"Invalid VeilidAPIException type: ${json['kind']}"); "Invalid VeilidAPIException type: ${json['kind']! as String}");
} }
} }
} }
@ -132,7 +135,6 @@ class VeilidAPIExceptionInvalidTarget implements VeilidAPIException {
@immutable @immutable
class VeilidAPIExceptionNoConnection implements VeilidAPIException { class VeilidAPIExceptionNoConnection implements VeilidAPIException {
// //
const VeilidAPIExceptionNoConnection(this.message); const VeilidAPIExceptionNoConnection(this.message);
final String message; final String message;
@ -145,7 +147,6 @@ class VeilidAPIExceptionNoConnection implements VeilidAPIException {
@immutable @immutable
class VeilidAPIExceptionKeyNotFound implements VeilidAPIException { class VeilidAPIExceptionKeyNotFound implements VeilidAPIException {
// //
const VeilidAPIExceptionKeyNotFound(this.key); const VeilidAPIExceptionKeyNotFound(this.key);
final String key; final String key;
@ -158,7 +159,6 @@ class VeilidAPIExceptionKeyNotFound implements VeilidAPIException {
@immutable @immutable
class VeilidAPIExceptionInternal implements VeilidAPIException { class VeilidAPIExceptionInternal implements VeilidAPIException {
// //
const VeilidAPIExceptionInternal(this.message); const VeilidAPIExceptionInternal(this.message);
final String message; final String message;
@ -172,7 +172,6 @@ class VeilidAPIExceptionInternal implements VeilidAPIException {
@immutable @immutable
class VeilidAPIExceptionUnimplemented implements VeilidAPIException { class VeilidAPIExceptionUnimplemented implements VeilidAPIException {
// //
const VeilidAPIExceptionUnimplemented(this.message); const VeilidAPIExceptionUnimplemented(this.message);
final String message; final String message;
@ -186,14 +185,14 @@ class VeilidAPIExceptionUnimplemented implements VeilidAPIException {
@immutable @immutable
class VeilidAPIExceptionParseError implements VeilidAPIException { class VeilidAPIExceptionParseError implements VeilidAPIException {
// //
const VeilidAPIExceptionParseError(this.message, this.value); const VeilidAPIExceptionParseError(this.message, this.value);
final String message; final String message;
final String value; final String value;
@override @override
String toString() => 'VeilidAPIException: ParseError ($message)\n value: $value'; String toString() =>
'VeilidAPIException: ParseError ($message)\n value: $value';
@override @override
String toDisplayError() => 'Parse error: $message'; String toDisplayError() => 'Parse error: $message';
@ -201,7 +200,6 @@ class VeilidAPIExceptionParseError implements VeilidAPIException {
@immutable @immutable
class VeilidAPIExceptionInvalidArgument implements VeilidAPIException { class VeilidAPIExceptionInvalidArgument implements VeilidAPIException {
// //
const VeilidAPIExceptionInvalidArgument( const VeilidAPIExceptionInvalidArgument(
this.context, this.argument, this.value); this.context, this.argument, this.value);
@ -210,7 +208,8 @@ class VeilidAPIExceptionInvalidArgument implements VeilidAPIException {
final String value; final String value;
@override @override
String toString() => 'VeilidAPIException: InvalidArgument ($context:$argument)\n value: $value'; String toString() =>
'VeilidAPIException: InvalidArgument ($context:$argument)\n value: $value';
@override @override
String toDisplayError() => 'Invalid argument for $context: $argument'; String toDisplayError() => 'Invalid argument for $context: $argument';
@ -218,14 +217,14 @@ class VeilidAPIExceptionInvalidArgument implements VeilidAPIException {
@immutable @immutable
class VeilidAPIExceptionMissingArgument implements VeilidAPIException { class VeilidAPIExceptionMissingArgument implements VeilidAPIException {
// //
const VeilidAPIExceptionMissingArgument(this.context, this.argument); const VeilidAPIExceptionMissingArgument(this.context, this.argument);
final String context; final String context;
final String argument; final String argument;
@override @override
String toString() => 'VeilidAPIException: MissingArgument ($context:$argument)'; String toString() =>
'VeilidAPIException: MissingArgument ($context:$argument)';
@override @override
String toDisplayError() => 'Missing argument for $context: $argument'; String toDisplayError() => 'Missing argument for $context: $argument';
@ -233,7 +232,6 @@ class VeilidAPIExceptionMissingArgument implements VeilidAPIException {
@immutable @immutable
class VeilidAPIExceptionGeneric implements VeilidAPIException { class VeilidAPIExceptionGeneric implements VeilidAPIException {
// //
const VeilidAPIExceptionGeneric(this.message); const VeilidAPIExceptionGeneric(this.message);
final String message; final String message;

View File

@ -13,8 +13,11 @@ Veilid getVeilid() => VeilidJS();
Object wasm = js_util.getProperty(html.window, 'veilid_wasm'); Object wasm = js_util.getProperty(html.window, 'veilid_wasm');
Future<T> _wrapApiPromise<T>(Object p) => js_util.promiseToFuture(p).then((value) => value as T).catchError( Future<T> _wrapApiPromise<T>(Object p) => js_util
(error) => Future<T>.error( .promiseToFuture<T>(p)
.then((value) => value)
// ignore: inference_failure_on_untyped_parameter
.catchError((error) => Future<T>.error(
VeilidAPIException.fromJson(jsonDecode(error as String)))); VeilidAPIException.fromJson(jsonDecode(error as String))));
class _Ctx { class _Ctx {
@ -29,7 +32,7 @@ class _Ctx {
void close() { void close() {
if (id != null) { if (id != null) {
js_util.callMethod(wasm, 'release_routing_context', [id!]); js_util.callMethod<void>(wasm, 'release_routing_context', [id]);
id = null; id = null;
} }
} }
@ -37,7 +40,6 @@ class _Ctx {
// JS implementation of VeilidRoutingContext // JS implementation of VeilidRoutingContext
class VeilidRoutingContextJS extends VeilidRoutingContext { class VeilidRoutingContextJS extends VeilidRoutingContext {
VeilidRoutingContextJS._(this._ctx) { VeilidRoutingContextJS._(this._ctx) {
_finalizer.attach(this, _ctx, detach: this); _finalizer.attach(this, _ctx, detach: this);
} }
@ -60,10 +62,11 @@ class VeilidRoutingContextJS extends VeilidRoutingContext {
@override @override
VeilidRoutingContextJS withCustomPrivacy(SafetySelection safetySelection) { VeilidRoutingContextJS withCustomPrivacy(SafetySelection safetySelection) {
_ctx.ensureValid(); _ctx.ensureValid();
final newId = js_util.callMethod( final id = _ctx.id!;
final newId = js_util.callMethod<int>(
wasm, wasm,
'routing_context_with_custom_privacy', 'routing_context_with_custom_privacy',
[_ctx.id!, jsonEncode(safetySelection)]); [id, jsonEncode(safetySelection)]);
return VeilidRoutingContextJS._(_Ctx(newId, _ctx.js)); return VeilidRoutingContextJS._(_Ctx(newId, _ctx.js));
} }
@ -71,45 +74,50 @@ class VeilidRoutingContextJS extends VeilidRoutingContext {
@override @override
VeilidRoutingContextJS withSequencing(Sequencing sequencing) { VeilidRoutingContextJS withSequencing(Sequencing sequencing) {
_ctx.ensureValid(); _ctx.ensureValid();
final newId = js_util.callMethod(wasm, 'routing_context_with_sequencing', final id = _ctx.id!;
[_ctx.id!, jsonEncode(sequencing)]); final newId = js_util.callMethod<int>(
wasm, 'routing_context_with_sequencing', [id, jsonEncode(sequencing)]);
return VeilidRoutingContextJS._(_Ctx(newId, _ctx.js)); return VeilidRoutingContextJS._(_Ctx(newId, _ctx.js));
} }
@override @override
Future<Uint8List> appCall(String target, Uint8List request) async { Future<Uint8List> appCall(String target, Uint8List request) async {
_ctx.ensureValid(); _ctx.ensureValid();
final id = _ctx.id!;
final encodedRequest = base64UrlNoPadEncode(request); final encodedRequest = base64UrlNoPadEncode(request);
return base64UrlNoPadDecode(await _wrapApiPromise(js_util.callMethod( return base64UrlNoPadDecode(await _wrapApiPromise(js_util.callMethod(
wasm, 'routing_context_app_call', [_ctx.id!, target, encodedRequest]))); wasm, 'routing_context_app_call', [id, target, encodedRequest])));
} }
@override @override
Future<void> appMessage(String target, Uint8List message) { Future<void> appMessage(String target, Uint8List message) {
_ctx.ensureValid(); _ctx.ensureValid();
final id = _ctx.id!;
final encodedMessage = base64UrlNoPadEncode(message); final encodedMessage = base64UrlNoPadEncode(message);
return _wrapApiPromise(js_util.callMethod(wasm, return _wrapApiPromise(js_util.callMethod(
'routing_context_app_message', [_ctx.id!, target, encodedMessage])); wasm, 'routing_context_app_message', [id, target, encodedMessage]));
} }
@override @override
Future<DHTRecordDescriptor> createDHTRecord(DHTSchema schema, Future<DHTRecordDescriptor> createDHTRecord(DHTSchema schema,
{CryptoKind kind = 0}) async { {CryptoKind kind = 0}) async {
_ctx.ensureValid(); _ctx.ensureValid();
final id = _ctx.id!;
return DHTRecordDescriptor.fromJson(jsonDecode(await _wrapApiPromise(js_util return DHTRecordDescriptor.fromJson(jsonDecode(await _wrapApiPromise(js_util
.callMethod(wasm, 'routing_context_create_dht_record', .callMethod(wasm, 'routing_context_create_dht_record',
[_ctx.id!, jsonEncode(schema), kind])))); [id, jsonEncode(schema), kind]))));
} }
@override @override
Future<DHTRecordDescriptor> openDHTRecord( Future<DHTRecordDescriptor> openDHTRecord(
TypedKey key, KeyPair? writer) async { TypedKey key, KeyPair? writer) async {
_ctx.ensureValid(); _ctx.ensureValid();
final id = _ctx.id!;
return DHTRecordDescriptor.fromJson(jsonDecode(await _wrapApiPromise(js_util return DHTRecordDescriptor.fromJson(jsonDecode(await _wrapApiPromise(js_util
.callMethod(wasm, 'routing_context_open_dht_record', [ .callMethod(wasm, 'routing_context_open_dht_record', [
_ctx.id!, id,
jsonEncode(key), jsonEncode(key),
if (writer != null) jsonEncode(writer) else null if (writer != null) jsonEncode(writer) else null
])))); ]))));
@ -118,25 +126,28 @@ class VeilidRoutingContextJS extends VeilidRoutingContext {
@override @override
Future<void> closeDHTRecord(TypedKey key) { Future<void> closeDHTRecord(TypedKey key) {
_ctx.ensureValid(); _ctx.ensureValid();
final id = _ctx.id!;
return _wrapApiPromise(js_util.callMethod( return _wrapApiPromise(js_util.callMethod(
wasm, 'routing_context_close_dht_record', [_ctx.id!, jsonEncode(key)])); wasm, 'routing_context_close_dht_record', [id, jsonEncode(key)]));
} }
@override @override
Future<void> deleteDHTRecord(TypedKey key) { Future<void> deleteDHTRecord(TypedKey key) {
_ctx.ensureValid(); _ctx.ensureValid();
return _wrapApiPromise(js_util.callMethod(wasm, final id = _ctx.id!;
'routing_context_delete_dht_record', [_ctx.id!, jsonEncode(key)])); return _wrapApiPromise(js_util.callMethod(
wasm, 'routing_context_delete_dht_record', [id, jsonEncode(key)]));
} }
@override @override
Future<ValueData?> getDHTValue( Future<ValueData?> getDHTValue(
TypedKey key, int subkey, bool forceRefresh) async { TypedKey key, int subkey, bool forceRefresh) async {
_ctx.ensureValid(); _ctx.ensureValid();
final opt = await _wrapApiPromise(js_util.callMethod( final id = _ctx.id!;
final opt = await _wrapApiPromise<String?>(js_util.callMethod(
wasm, wasm,
'routing_context_get_dht_value', 'routing_context_get_dht_value',
[_ctx.id!, jsonEncode(key), subkey, forceRefresh])); [id, jsonEncode(key), subkey, forceRefresh]));
return opt == null ? null : ValueData.fromJson(jsonDecode(opt)); return opt == null ? null : ValueData.fromJson(jsonDecode(opt));
} }
@ -144,10 +155,11 @@ class VeilidRoutingContextJS extends VeilidRoutingContext {
Future<ValueData?> setDHTValue( Future<ValueData?> setDHTValue(
TypedKey key, int subkey, Uint8List data) async { TypedKey key, int subkey, Uint8List data) async {
_ctx.ensureValid(); _ctx.ensureValid();
final opt = await _wrapApiPromise(js_util.callMethod( final id = _ctx.id!;
final opt = await _wrapApiPromise<String?>(js_util.callMethod(
wasm, wasm,
'routing_context_set_dht_value', 'routing_context_set_dht_value',
[_ctx.id!, jsonEncode(key), subkey, base64UrlNoPadEncode(data)])); [id, jsonEncode(key), subkey, base64UrlNoPadEncode(data)]));
return opt == null ? null : ValueData.fromJson(jsonDecode(opt)); return opt == null ? null : ValueData.fromJson(jsonDecode(opt));
} }
@ -155,9 +167,10 @@ class VeilidRoutingContextJS extends VeilidRoutingContext {
Future<Timestamp> watchDHTValues(TypedKey key, List<ValueSubkeyRange> subkeys, Future<Timestamp> watchDHTValues(TypedKey key, List<ValueSubkeyRange> subkeys,
Timestamp expiration, int count) async { Timestamp expiration, int count) async {
_ctx.ensureValid(); _ctx.ensureValid();
final ts = await _wrapApiPromise(js_util.callMethod( final id = _ctx.id!;
final ts = await _wrapApiPromise<String>(js_util.callMethod(
wasm, 'routing_context_watch_dht_values', [ wasm, 'routing_context_watch_dht_values', [
_ctx.id!, id,
jsonEncode(key), jsonEncode(key),
jsonEncode(subkeys), jsonEncode(subkeys),
expiration.toString(), expiration.toString(),
@ -169,16 +182,16 @@ class VeilidRoutingContextJS extends VeilidRoutingContext {
@override @override
Future<bool> cancelDHTWatch(TypedKey key, List<ValueSubkeyRange> subkeys) { Future<bool> cancelDHTWatch(TypedKey key, List<ValueSubkeyRange> subkeys) {
_ctx.ensureValid(); _ctx.ensureValid();
final id = _ctx.id!;
return _wrapApiPromise(js_util.callMethod( return _wrapApiPromise(js_util.callMethod(
wasm, wasm,
'routing_context_cancel_dht_watch', 'routing_context_cancel_dht_watch',
[_ctx.id!, jsonEncode(key), jsonEncode(subkeys)])); [id, jsonEncode(key), jsonEncode(subkeys)]));
} }
} }
// JS implementation of VeilidCryptoSystem // JS implementation of VeilidCryptoSystem
class VeilidCryptoSystemJS extends VeilidCryptoSystem { class VeilidCryptoSystemJS extends VeilidCryptoSystem {
VeilidCryptoSystemJS._(this._js, this._kind) { VeilidCryptoSystemJS._(this._js, this._kind) {
// Keep the reference // Keep the reference
_js; _js;
@ -190,17 +203,22 @@ class VeilidCryptoSystemJS extends VeilidCryptoSystem {
CryptoKind kind() => _kind; CryptoKind kind() => _kind;
@override @override
Future<SharedSecret> cachedDH(PublicKey key, SecretKey secret) async => SharedSecret.fromJson(jsonDecode(await _wrapApiPromise(js_util Future<SharedSecret> cachedDH(PublicKey key, SecretKey secret) async =>
.callMethod(wasm, 'crypto_cached_dh', SharedSecret.fromJson(jsonDecode(await _wrapApiPromise(js_util.callMethod(
wasm,
'crypto_cached_dh',
[_kind, jsonEncode(key), jsonEncode(secret)])))); [_kind, jsonEncode(key), jsonEncode(secret)]))));
@override @override
Future<SharedSecret> computeDH(PublicKey key, SecretKey secret) async => SharedSecret.fromJson(jsonDecode(await _wrapApiPromise(js_util Future<SharedSecret> computeDH(PublicKey key, SecretKey secret) async =>
.callMethod(wasm, 'crypto_compute_dh', SharedSecret.fromJson(jsonDecode(await _wrapApiPromise(js_util.callMethod(
wasm,
'crypto_compute_dh',
[_kind, jsonEncode(key), jsonEncode(secret)])))); [_kind, jsonEncode(key), jsonEncode(secret)]))));
@override @override
Future<Uint8List> randomBytes(int len) async => base64UrlNoPadDecode(await _wrapApiPromise( Future<Uint8List> randomBytes(int len) async =>
base64UrlNoPadDecode(await _wrapApiPromise(
js_util.callMethod(wasm, 'crypto_random_bytes', [_kind, len]))); js_util.callMethod(wasm, 'crypto_random_bytes', [_kind, len])));
@override @override
@ -208,56 +226,66 @@ class VeilidCryptoSystemJS extends VeilidCryptoSystem {
js_util.callMethod(wasm, 'crypto_default_salt_length', [_kind])); js_util.callMethod(wasm, 'crypto_default_salt_length', [_kind]));
@override @override
Future<String> hashPassword(Uint8List password, Uint8List salt) => _wrapApiPromise(js_util.callMethod(wasm, 'crypto_hash_password', Future<String> hashPassword(Uint8List password, Uint8List salt) =>
_wrapApiPromise(js_util.callMethod(wasm, 'crypto_hash_password',
[_kind, base64UrlNoPadEncode(password), base64UrlNoPadEncode(salt)])); [_kind, base64UrlNoPadEncode(password), base64UrlNoPadEncode(salt)]));
@override @override
Future<bool> verifyPassword(Uint8List password, String passwordHash) => _wrapApiPromise(js_util.callMethod(wasm, 'crypto_verify_password', Future<bool> verifyPassword(Uint8List password, String passwordHash) =>
_wrapApiPromise(js_util.callMethod(wasm, 'crypto_verify_password',
[_kind, base64UrlNoPadEncode(password), passwordHash])); [_kind, base64UrlNoPadEncode(password), passwordHash]));
@override @override
Future<SharedSecret> deriveSharedSecret( Future<SharedSecret> deriveSharedSecret(
Uint8List password, Uint8List salt) async => SharedSecret.fromJson(jsonDecode(await _wrapApiPromise(js_util Uint8List password, Uint8List salt) async =>
.callMethod(wasm, 'crypto_derive_shared_secret', [ SharedSecret.fromJson(jsonDecode(await _wrapApiPromise(js_util.callMethod(
wasm, 'crypto_derive_shared_secret', [
_kind, _kind,
base64UrlNoPadEncode(password), base64UrlNoPadEncode(password),
base64UrlNoPadEncode(salt) base64UrlNoPadEncode(salt)
])))); ]))));
@override @override
Future<Nonce> randomNonce() async => Nonce.fromJson(jsonDecode(await _wrapApiPromise( Future<Nonce> randomNonce() async =>
Nonce.fromJson(jsonDecode(await _wrapApiPromise(
js_util.callMethod(wasm, 'crypto_random_nonce', [_kind])))); js_util.callMethod(wasm, 'crypto_random_nonce', [_kind]))));
@override @override
Future<SharedSecret> randomSharedSecret() async => SharedSecret.fromJson(jsonDecode(await _wrapApiPromise( Future<SharedSecret> randomSharedSecret() async =>
SharedSecret.fromJson(jsonDecode(await _wrapApiPromise(
js_util.callMethod(wasm, 'crypto_random_shared_secret', [_kind])))); js_util.callMethod(wasm, 'crypto_random_shared_secret', [_kind]))));
@override @override
Future<KeyPair> generateKeyPair() async => KeyPair.fromJson(jsonDecode(await _wrapApiPromise( Future<KeyPair> generateKeyPair() async =>
KeyPair.fromJson(jsonDecode(await _wrapApiPromise(
js_util.callMethod(wasm, 'crypto_generate_key_pair', [_kind])))); js_util.callMethod(wasm, 'crypto_generate_key_pair', [_kind]))));
@override @override
Future<HashDigest> generateHash(Uint8List data) async => HashDigest.fromJson(jsonDecode(await _wrapApiPromise(js_util Future<HashDigest> generateHash(Uint8List data) async =>
.callMethod(wasm, 'crypto_generate_hash', HashDigest.fromJson(jsonDecode(await _wrapApiPromise(js_util.callMethod(
[_kind, base64UrlNoPadEncode(data)])))); wasm, 'crypto_generate_hash', [_kind, base64UrlNoPadEncode(data)]))));
@override @override
Future<bool> validateKeyPair(PublicKey key, SecretKey secret) => _wrapApiPromise(js_util.callMethod(wasm, 'crypto_validate_key_pair', Future<bool> validateKeyPair(PublicKey key, SecretKey secret) =>
_wrapApiPromise(js_util.callMethod(wasm, 'crypto_validate_key_pair',
[_kind, jsonEncode(key), jsonEncode(secret)])); [_kind, jsonEncode(key), jsonEncode(secret)]));
@override @override
Future<bool> validateHash(Uint8List data, HashDigest hash) => _wrapApiPromise(js_util.callMethod(wasm, 'crypto_validate_hash', Future<bool> validateHash(Uint8List data, HashDigest hash) =>
_wrapApiPromise(js_util.callMethod(wasm, 'crypto_validate_hash',
[_kind, base64UrlNoPadEncode(data), jsonEncode(hash)])); [_kind, base64UrlNoPadEncode(data), jsonEncode(hash)]));
@override @override
Future<CryptoKeyDistance> distance(CryptoKey key1, CryptoKey key2) async => CryptoKeyDistance.fromJson(jsonDecode(await _wrapApiPromise(js_util Future<CryptoKeyDistance> distance(CryptoKey key1, CryptoKey key2) async =>
CryptoKeyDistance.fromJson(jsonDecode(await _wrapApiPromise(js_util
.callMethod(wasm, 'crypto_distance', .callMethod(wasm, 'crypto_distance',
[_kind, jsonEncode(key1), jsonEncode(key2)])))); [_kind, jsonEncode(key1), jsonEncode(key2)]))));
@override @override
Future<Signature> sign( Future<Signature> sign(
PublicKey key, SecretKey secret, Uint8List data) async => Signature.fromJson(jsonDecode(await _wrapApiPromise(js_util PublicKey key, SecretKey secret, Uint8List data) async =>
.callMethod(wasm, 'crypto_sign', [ Signature.fromJson(jsonDecode(await _wrapApiPromise(js_util.callMethod(
wasm, 'crypto_sign', [
_kind, _kind,
jsonEncode(key), jsonEncode(key),
jsonEncode(secret), jsonEncode(secret),
@ -265,7 +293,8 @@ class VeilidCryptoSystemJS extends VeilidCryptoSystem {
])))); ]))));
@override @override
Future<void> verify(PublicKey key, Uint8List data, Signature signature) => _wrapApiPromise(js_util.callMethod(wasm, 'crypto_verify', [ Future<void> verify(PublicKey key, Uint8List data, Signature signature) =>
_wrapApiPromise(js_util.callMethod(wasm, 'crypto_verify', [
_kind, _kind,
jsonEncode(key), jsonEncode(key),
base64UrlNoPadEncode(data), base64UrlNoPadEncode(data),
@ -278,29 +307,38 @@ class VeilidCryptoSystemJS extends VeilidCryptoSystem {
@override @override
Future<Uint8List> decryptAead(Uint8List body, Nonce nonce, Future<Uint8List> decryptAead(Uint8List body, Nonce nonce,
SharedSecret sharedSecret, Uint8List? associatedData) async => base64UrlNoPadDecode( SharedSecret sharedSecret, Uint8List? associatedData) async =>
await _wrapApiPromise(js_util.callMethod(wasm, 'crypto_decrypt_aead', [ base64UrlNoPadDecode(await _wrapApiPromise(
js_util.callMethod(wasm, 'crypto_decrypt_aead', [
_kind, _kind,
base64UrlNoPadEncode(body), base64UrlNoPadEncode(body),
jsonEncode(nonce), jsonEncode(nonce),
jsonEncode(sharedSecret), jsonEncode(sharedSecret),
if (associatedData != null) base64UrlNoPadEncode(associatedData) else null if (associatedData != null)
base64UrlNoPadEncode(associatedData)
else
null
]))); ])));
@override @override
Future<Uint8List> encryptAead(Uint8List body, Nonce nonce, Future<Uint8List> encryptAead(Uint8List body, Nonce nonce,
SharedSecret sharedSecret, Uint8List? associatedData) async => base64UrlNoPadDecode( SharedSecret sharedSecret, Uint8List? associatedData) async =>
await _wrapApiPromise(js_util.callMethod(wasm, 'crypto_encrypt_aead', [ base64UrlNoPadDecode(await _wrapApiPromise(
js_util.callMethod(wasm, 'crypto_encrypt_aead', [
_kind, _kind,
base64UrlNoPadEncode(body), base64UrlNoPadEncode(body),
jsonEncode(nonce), jsonEncode(nonce),
jsonEncode(sharedSecret), jsonEncode(sharedSecret),
if (associatedData != null) base64UrlNoPadEncode(associatedData) else null if (associatedData != null)
base64UrlNoPadEncode(associatedData)
else
null
]))); ])));
@override @override
Future<Uint8List> cryptNoAuth( Future<Uint8List> cryptNoAuth(
Uint8List body, Nonce nonce, SharedSecret sharedSecret) async => base64UrlNoPadDecode(await _wrapApiPromise(js_util.callMethod( Uint8List body, Nonce nonce, SharedSecret sharedSecret) async =>
base64UrlNoPadDecode(await _wrapApiPromise(js_util.callMethod(
wasm, 'crypto_crypt_no_auth', [ wasm, 'crypto_crypt_no_auth', [
_kind, _kind,
base64UrlNoPadEncode(body), base64UrlNoPadEncode(body),
@ -310,7 +348,6 @@ class VeilidCryptoSystemJS extends VeilidCryptoSystem {
} }
class _TDBT { class _TDBT {
_TDBT(this.id, this.tdbjs, this.js); _TDBT(this.id, this.tdbjs, this.js);
int? id; int? id;
final VeilidTableDBJS tdbjs; final VeilidTableDBJS tdbjs;
@ -323,7 +360,7 @@ class _TDBT {
void close() { void close() {
if (id != null) { if (id != null) {
js_util.callMethod(wasm, 'release_table_db_transaction', [id!]); js_util.callMethod<void>(wasm, 'release_table_db_transaction', [id]);
id = null; id = null;
} }
} }
@ -331,7 +368,6 @@ class _TDBT {
// JS implementation of VeilidTableDBTransaction // JS implementation of VeilidTableDBTransaction
class VeilidTableDBTransactionJS extends VeilidTableDBTransaction { class VeilidTableDBTransactionJS extends VeilidTableDBTransaction {
VeilidTableDBTransactionJS._(this._tdbt) { VeilidTableDBTransactionJS._(this._tdbt) {
_finalizer.attach(this, _tdbt, detach: this); _finalizer.attach(this, _tdbt, detach: this);
} }
@ -344,41 +380,44 @@ class VeilidTableDBTransactionJS extends VeilidTableDBTransaction {
@override @override
Future<void> commit() async { Future<void> commit() async {
_tdbt.ensureValid(); _tdbt.ensureValid();
await _wrapApiPromise( final id = _tdbt.id!;
js_util.callMethod(wasm, 'table_db_transaction_commit', [_tdbt.id!])); await _wrapApiPromise<void>(
js_util.callMethod(wasm, 'table_db_transaction_commit', [id]));
_tdbt.close(); _tdbt.close();
} }
@override @override
Future<void> rollback() async { Future<void> rollback() async {
_tdbt.ensureValid(); _tdbt.ensureValid();
await _wrapApiPromise( final id = _tdbt.id!;
js_util.callMethod(wasm, 'table_db_transaction_rollback', [_tdbt.id!])); await _wrapApiPromise<void>(
js_util.callMethod(wasm, 'table_db_transaction_rollback', [id]));
_tdbt.close(); _tdbt.close();
} }
@override @override
Future<void> store(int col, Uint8List key, Uint8List value) async { Future<void> store(int col, Uint8List key, Uint8List value) async {
_tdbt.ensureValid(); _tdbt.ensureValid();
final id = _tdbt.id!;
final encodedKey = base64UrlNoPadEncode(key); final encodedKey = base64UrlNoPadEncode(key);
final encodedValue = base64UrlNoPadEncode(value); final encodedValue = base64UrlNoPadEncode(value);
await _wrapApiPromise(js_util.callMethod(wasm, 'table_db_transaction_store', await _wrapApiPromise<void>(js_util.callMethod(wasm,
[_tdbt.id!, col, encodedKey, encodedValue])); 'table_db_transaction_store', [id, col, encodedKey, encodedValue]));
} }
@override @override
Future<void> delete(int col, Uint8List key) async { Future<void> delete(int col, Uint8List key) async {
_tdbt.ensureValid(); _tdbt.ensureValid();
final id = _tdbt.id!;
final encodedKey = base64UrlNoPadEncode(key); final encodedKey = base64UrlNoPadEncode(key);
await _wrapApiPromise(js_util.callMethod( await _wrapApiPromise<void>(js_util.callMethod(
wasm, 'table_db_transaction_delete', [_tdbt.id!, col, encodedKey])); wasm, 'table_db_transaction_delete', [id, col, encodedKey]));
} }
} }
class _TDB { class _TDB {
_TDB(int this.id, this.js); _TDB(int this.id, this.js);
int? id; int? id;
final VeilidJS js; final VeilidJS js;
@ -390,7 +429,7 @@ class _TDB {
void close() { void close() {
if (id != null) { if (id != null) {
js_util.callMethod(wasm, 'release_table_db', [id!]); js_util.callMethod<void>(wasm, 'release_table_db', [id]);
id = null; id = null;
} }
} }
@ -398,7 +437,6 @@ class _TDB {
// JS implementation of VeilidTableDB // JS implementation of VeilidTableDB
class VeilidTableDBJS extends VeilidTableDB { class VeilidTableDBJS extends VeilidTableDB {
VeilidTableDBJS._(this._tdb) { VeilidTableDBJS._(this._tdb) {
_finalizer.attach(this, _tdb, detach: this); _finalizer.attach(this, _tdb, detach: this);
} }
@ -419,35 +457,39 @@ class VeilidTableDBJS extends VeilidTableDB {
@override @override
Future<List<Uint8List>> getKeys(int col) async { Future<List<Uint8List>> getKeys(int col) async {
_tdb.ensureValid(); _tdb.ensureValid();
final id = _tdb.id!;
return jsonListConstructor(base64UrlNoPadDecodeDynamic)(jsonDecode( return jsonListConstructor(base64UrlNoPadDecodeDynamic)(jsonDecode(
await js_util.callMethod(wasm, 'table_db_get_keys', [_tdb.id!, col]))); await js_util.callMethod(wasm, 'table_db_get_keys', [id, col])));
} }
@override @override
VeilidTableDBTransaction transact() { VeilidTableDBTransaction transact() {
_tdb.ensureValid(); _tdb.ensureValid();
final id = js_util.callMethod(wasm, 'table_db_transact', [_tdb.id!]); final id = _tdb.id!;
final xid = js_util.callMethod<int>(wasm, 'table_db_transact', [id]);
return VeilidTableDBTransactionJS._(_TDBT(id, this, _tdb.js)); return VeilidTableDBTransactionJS._(_TDBT(xid, this, _tdb.js));
} }
@override @override
Future<void> store(int col, Uint8List key, Uint8List value) { Future<void> store(int col, Uint8List key, Uint8List value) {
_tdb.ensureValid(); _tdb.ensureValid();
final id = _tdb.id!;
final encodedKey = base64UrlNoPadEncode(key); final encodedKey = base64UrlNoPadEncode(key);
final encodedValue = base64UrlNoPadEncode(value); final encodedValue = base64UrlNoPadEncode(value);
return _wrapApiPromise(js_util.callMethod( return _wrapApiPromise(js_util.callMethod(
wasm, 'table_db_store', [_tdb.id!, col, encodedKey, encodedValue])); wasm, 'table_db_store', [id, col, encodedKey, encodedValue]));
} }
@override @override
Future<Uint8List?> load(int col, Uint8List key) async { Future<Uint8List?> load(int col, Uint8List key) async {
_tdb.ensureValid(); _tdb.ensureValid();
final id = _tdb.id!;
final encodedKey = base64UrlNoPadEncode(key); final encodedKey = base64UrlNoPadEncode(key);
final out = await _wrapApiPromise( final out = await _wrapApiPromise<String?>(
js_util.callMethod(wasm, 'table_db_load', [_tdb.id!, col, encodedKey])); js_util.callMethod(wasm, 'table_db_load', [id, col, encodedKey]));
if (out == null) { if (out == null) {
return null; return null;
} }
@ -455,12 +497,17 @@ class VeilidTableDBJS extends VeilidTableDB {
} }
@override @override
Future<Uint8List?> delete(int col, Uint8List key) { Future<Uint8List?> delete(int col, Uint8List key) async {
_tdb.ensureValid(); _tdb.ensureValid();
final id = _tdb.id!;
final encodedKey = base64UrlNoPadEncode(key); final encodedKey = base64UrlNoPadEncode(key);
return _wrapApiPromise(js_util final out = await _wrapApiPromise<String?>(
.callMethod(wasm, 'table_db_delete', [_tdb.id!, col, encodedKey])); js_util.callMethod(wasm, 'table_db_delete', [id, col, encodedKey]));
if (out == null) {
return null;
}
return base64UrlNoPadDecode(out);
} }
} }
@ -470,48 +517,52 @@ class VeilidJS extends Veilid {
@override @override
void initializeVeilidCore(Map<String, dynamic> platformConfigJson) { void initializeVeilidCore(Map<String, dynamic> platformConfigJson) {
final platformConfigJsonString = jsonEncode(platformConfigJson); final platformConfigJsonString = jsonEncode(platformConfigJson);
js_util js_util.callMethod<void>(
.callMethod(wasm, 'initialize_veilid_core', [platformConfigJsonString]); wasm, 'initialize_veilid_core', [platformConfigJsonString]);
} }
@override @override
void changeLogLevel(String layer, VeilidConfigLogLevel logLevel) { void changeLogLevel(String layer, VeilidConfigLogLevel logLevel) {
final logLevelJsonString = jsonEncode(logLevel); final logLevelJsonString = jsonEncode(logLevel);
js_util.callMethod(wasm, 'change_log_level', [layer, logLevelJsonString]); js_util.callMethod<void>(
wasm, 'change_log_level', [layer, logLevelJsonString]);
} }
@override @override
Future<Stream<VeilidUpdate>> startupVeilidCore(VeilidConfig config) async { Future<Stream<VeilidUpdate>> startupVeilidCore(VeilidConfig config) async {
final streamController = StreamController<VeilidUpdate>(); final streamController = StreamController<VeilidUpdate>();
updateCallback(String update) { void updateCallback(String update) {
final updateJson = jsonDecode(update); final updateJson = jsonDecode(update) as Map<String, dynamic>;
if (updateJson['kind'] == 'Shutdown') { if (updateJson['kind'] == 'Shutdown') {
streamController.close(); unawaited(streamController.close());
} else { } else {
final update = VeilidUpdate.fromJson(updateJson); final update = VeilidUpdate.fromJson(updateJson);
streamController.add(update); streamController.add(update);
} }
} }
await _wrapApiPromise(js_util.callMethod(wasm, 'startup_veilid_core', await _wrapApiPromise<void>(js_util.callMethod(wasm, 'startup_veilid_core',
[js.allowInterop(updateCallback), jsonEncode(config)])); [js.allowInterop(updateCallback), jsonEncode(config)]));
return streamController.stream; return streamController.stream;
} }
@override @override
Future<VeilidState> getVeilidState() async => VeilidState.fromJson(jsonDecode(await _wrapApiPromise( Future<VeilidState> getVeilidState() async =>
VeilidState.fromJson(jsonDecode(await _wrapApiPromise<String>(
js_util.callMethod(wasm, 'get_veilid_state', [])))); js_util.callMethod(wasm, 'get_veilid_state', []))));
@override @override
Future<void> attach() => _wrapApiPromise(js_util.callMethod(wasm, 'attach', [])); Future<void> attach() =>
_wrapApiPromise(js_util.callMethod(wasm, 'attach', []));
@override @override
Future<void> detach() => _wrapApiPromise(js_util.callMethod(wasm, 'detach', [])); Future<void> detach() =>
_wrapApiPromise(js_util.callMethod(wasm, 'detach', []));
@override @override
Future<void> shutdownVeilidCore() => _wrapApiPromise( Future<void> shutdownVeilidCore() =>
js_util.callMethod(wasm, 'shutdown_veilid_core', [])); _wrapApiPromise(js_util.callMethod(wasm, 'shutdown_veilid_core', []));
@override @override
List<CryptoKind> validCryptoKinds() { List<CryptoKind> validCryptoKinds() {
@ -534,8 +585,9 @@ class VeilidJS extends Veilid {
@override @override
Future<List<TypedKey>> verifySignatures(List<TypedKey> nodeIds, Future<List<TypedKey>> verifySignatures(List<TypedKey> nodeIds,
Uint8List data, List<TypedSignature> signatures) async => jsonListConstructor(TypedKey.fromJson)(jsonDecode( Uint8List data, List<TypedSignature> signatures) async =>
await _wrapApiPromise(js_util.callMethod(wasm, 'verify_signatures', [ jsonListConstructor(TypedKey.fromJson)(jsonDecode(await _wrapApiPromise(
js_util.callMethod(wasm, 'verify_signatures', [
jsonEncode(nodeIds), jsonEncode(nodeIds),
base64UrlNoPadEncode(data), base64UrlNoPadEncode(data),
jsonEncode(signatures) jsonEncode(signatures)
@ -543,23 +595,26 @@ class VeilidJS extends Veilid {
@override @override
Future<List<TypedSignature>> generateSignatures( Future<List<TypedSignature>> generateSignatures(
Uint8List data, List<TypedKeyPair> keyPairs) async => jsonListConstructor(TypedSignature.fromJson)(jsonDecode( Uint8List data, List<TypedKeyPair> keyPairs) async =>
jsonListConstructor(TypedSignature.fromJson)(jsonDecode(
await _wrapApiPromise(js_util.callMethod(wasm, 'generate_signatures', await _wrapApiPromise(js_util.callMethod(wasm, 'generate_signatures',
[base64UrlNoPadEncode(data), jsonEncode(keyPairs)])))); [base64UrlNoPadEncode(data), jsonEncode(keyPairs)]))));
@override @override
Future<TypedKeyPair> generateKeyPair(CryptoKind kind) async => TypedKeyPair.fromJson(jsonDecode(await _wrapApiPromise( Future<TypedKeyPair> generateKeyPair(CryptoKind kind) async =>
TypedKeyPair.fromJson(jsonDecode(await _wrapApiPromise(
js_util.callMethod(wasm, 'generate_key_pair', [kind])))); js_util.callMethod(wasm, 'generate_key_pair', [kind]))));
@override @override
Future<VeilidRoutingContext> routingContext() async { Future<VeilidRoutingContext> routingContext() async {
final var id = final rcid = await _wrapApiPromise<int>(
await _wrapApiPromise(js_util.callMethod(wasm, 'routing_context', [])); js_util.callMethod(wasm, 'routing_context', []));
return VeilidRoutingContextJS._(_Ctx(id, this)); return VeilidRoutingContextJS._(_Ctx(rcid, this));
} }
@override @override
Future<RouteBlob> newPrivateRoute() async => RouteBlob.fromJson(jsonDecode(await _wrapApiPromise( Future<RouteBlob> newPrivateRoute() async =>
RouteBlob.fromJson(jsonDecode(await _wrapApiPromise(
js_util.callMethod(wasm, 'new_private_route', [])))); js_util.callMethod(wasm, 'new_private_route', []))));
@override @override
@ -581,8 +636,8 @@ class VeilidJS extends Veilid {
} }
@override @override
Future<void> releasePrivateRoute(String key) => _wrapApiPromise( Future<void> releasePrivateRoute(String key) =>
js_util.callMethod(wasm, 'release_private_route', [key])); _wrapApiPromise(js_util.callMethod(wasm, 'release_private_route', [key]));
@override @override
Future<void> appCallReply(String callId, Uint8List message) { Future<void> appCallReply(String callId, Uint8List message) {
@ -593,28 +648,32 @@ class VeilidJS extends Veilid {
@override @override
Future<VeilidTableDB> openTableDB(String name, int columnCount) async { Future<VeilidTableDB> openTableDB(String name, int columnCount) async {
final id = await _wrapApiPromise( final dbid = await _wrapApiPromise<int>(
js_util.callMethod(wasm, 'open_table_db', [name, columnCount])); js_util.callMethod(wasm, 'open_table_db', [name, columnCount]));
return VeilidTableDBJS._(_TDB(id, this)); return VeilidTableDBJS._(_TDB(dbid, this));
} }
@override @override
Future<bool> deleteTableDB(String name) => _wrapApiPromise(js_util.callMethod(wasm, 'delete_table_db', [name])); Future<bool> deleteTableDB(String name) =>
_wrapApiPromise(js_util.callMethod(wasm, 'delete_table_db', [name]));
@override @override
Timestamp now() => Timestamp.fromString(js_util.callMethod(wasm, 'now', [])); Timestamp now() => Timestamp.fromString(js_util.callMethod(wasm, 'now', []));
@override @override
Future<String> debug(String command) async => await _wrapApiPromise(js_util.callMethod(wasm, 'debug', [command])); Future<String> debug(String command) async =>
_wrapApiPromise(js_util.callMethod(wasm, 'debug', [command]));
@override @override
String veilidVersionString() => js_util.callMethod(wasm, 'veilid_version_string', []); String veilidVersionString() =>
js_util.callMethod(wasm, 'veilid_version_string', []);
@override @override
VeilidVersion veilidVersion() { VeilidVersion veilidVersion() {
Map<String, dynamic> jsonVersion = final jsonVersion =
jsonDecode(js_util.callMethod(wasm, 'veilid_version', [])); jsonDecode(js_util.callMethod(wasm, 'veilid_version', []))
return VeilidVersion( as Map<String, dynamic>;
jsonVersion['major'], jsonVersion['minor'], jsonVersion['patch']); return VeilidVersion(jsonVersion['major'] as int,
jsonVersion['minor'] as int, jsonVersion['patch'] as int);
} }
} }