ffi/js flutter for tabledb

This commit is contained in:
John Smith
2022-12-28 22:53:58 -05:00
parent de8349004d
commit f0d7c9baf3
5 changed files with 764 additions and 80 deletions

View File

@@ -31,7 +31,7 @@ class VeilidFFIConfigLoggingTerminal {
};
}
VeilidFFIConfigLoggingTerminal.fromJson(Map<String, dynamic> json)
VeilidFFIConfigLoggingTerminal.fromJson(dynamic json)
: enabled = json['enabled'],
level = veilidConfigLogLevelFromJson(json['level']);
}
@@ -58,7 +58,7 @@ class VeilidFFIConfigLoggingOtlp {
};
}
VeilidFFIConfigLoggingOtlp.fromJson(Map<String, dynamic> json)
VeilidFFIConfigLoggingOtlp.fromJson(dynamic json)
: enabled = json['enabled'],
level = veilidConfigLogLevelFromJson(json['level']),
grpcEndpoint = json['grpc_endpoint'],
@@ -81,7 +81,7 @@ class VeilidFFIConfigLoggingApi {
};
}
VeilidFFIConfigLoggingApi.fromJson(Map<String, dynamic> json)
VeilidFFIConfigLoggingApi.fromJson(dynamic json)
: enabled = json['enabled'],
level = veilidConfigLogLevelFromJson(json['level']);
}
@@ -102,7 +102,7 @@ class VeilidFFIConfigLogging {
};
}
VeilidFFIConfigLogging.fromJson(Map<String, dynamic> json)
VeilidFFIConfigLogging.fromJson(dynamic json)
: terminal = VeilidFFIConfigLoggingTerminal.fromJson(json['terminal']),
otlp = VeilidFFIConfigLoggingOtlp.fromJson(json['otlp']),
api = VeilidFFIConfigLoggingApi.fromJson(json['api']);
@@ -150,7 +150,7 @@ class VeilidWASMConfigLoggingPerformance {
};
}
VeilidWASMConfigLoggingPerformance.fromJson(Map<String, dynamic> json)
VeilidWASMConfigLoggingPerformance.fromJson(dynamic json)
: enabled = json['enabled'],
level = veilidConfigLogLevelFromJson(json['level']),
logsInTimings = json['logs_in_timings'],
@@ -173,7 +173,7 @@ class VeilidWASMConfigLoggingApi {
};
}
VeilidWASMConfigLoggingApi.fromJson(Map<String, dynamic> json)
VeilidWASMConfigLoggingApi.fromJson(dynamic json)
: enabled = json['enabled'],
level = veilidConfigLogLevelFromJson(json['level']);
}
@@ -191,7 +191,7 @@ class VeilidWASMConfigLogging {
};
}
VeilidWASMConfigLogging.fromJson(Map<String, dynamic> json)
VeilidWASMConfigLogging.fromJson(dynamic json)
: performance =
VeilidWASMConfigLoggingPerformance.fromJson(json['performance']),
api = VeilidWASMConfigLoggingApi.fromJson(json['api']);
@@ -210,7 +210,7 @@ class VeilidWASMConfig {
};
}
VeilidWASMConfig.fromJson(Map<String, dynamic> json)
VeilidWASMConfig.fromJson(dynamic json)
: logging = VeilidWASMConfigLogging.fromJson(json['logging']);
}
@@ -324,7 +324,7 @@ class VeilidConfigHTTPS {
};
}
VeilidConfigHTTPS.fromJson(Map<String, dynamic> json)
VeilidConfigHTTPS.fromJson(dynamic json)
: enabled = json['enabled'],
listenAddress = json['listen_address'],
path = json['path'],
@@ -355,7 +355,7 @@ class VeilidConfigHTTP {
};
}
VeilidConfigHTTP.fromJson(Map<String, dynamic> json)
VeilidConfigHTTP.fromJson(dynamic json)
: enabled = json['enabled'],
listenAddress = json['listen_address'],
path = json['path'],
@@ -380,7 +380,7 @@ class VeilidConfigApplication {
};
}
VeilidConfigApplication.fromJson(Map<String, dynamic> json)
VeilidConfigApplication.fromJson(dynamic json)
: https = VeilidConfigHTTPS.fromJson(json['https']),
http = VeilidConfigHTTP.fromJson(json['http']);
}
@@ -408,7 +408,7 @@ class VeilidConfigUDP {
};
}
VeilidConfigUDP.fromJson(Map<String, dynamic> json)
VeilidConfigUDP.fromJson(dynamic json)
: enabled = json['enabled'],
socketPoolSize = json['socket_pool_size'],
listenAddress = json['listen_address'],
@@ -441,7 +441,7 @@ class VeilidConfigTCP {
};
}
VeilidConfigTCP.fromJson(Map<String, dynamic> json)
VeilidConfigTCP.fromJson(dynamic json)
: connect = json['connect'],
listen = json['listen'],
maxConnections = json['max_connections'],
@@ -478,7 +478,7 @@ class VeilidConfigWS {
};
}
VeilidConfigWS.fromJson(Map<String, dynamic> json)
VeilidConfigWS.fromJson(dynamic json)
: connect = json['connect'],
listen = json['listen'],
maxConnections = json['max_connections'],
@@ -516,7 +516,7 @@ class VeilidConfigWSS {
};
}
VeilidConfigWSS.fromJson(Map<String, dynamic> json)
VeilidConfigWSS.fromJson(dynamic json)
: connect = json['connect'],
listen = json['listen'],
maxConnections = json['max_connections'],
@@ -549,7 +549,7 @@ class VeilidConfigProtocol {
};
}
VeilidConfigProtocol.fromJson(Map<String, dynamic> json)
VeilidConfigProtocol.fromJson(dynamic json)
: udp = VeilidConfigUDP.fromJson(json['udp']),
tcp = VeilidConfigTCP.fromJson(json['tcp']),
ws = VeilidConfigWS.fromJson(json['ws']),
@@ -577,7 +577,7 @@ class VeilidConfigTLS {
};
}
VeilidConfigTLS.fromJson(Map<String, dynamic> json)
VeilidConfigTLS.fromJson(dynamic json)
: certificatePath = json['certificate_path'],
privateKeyPath = json['private_key_path'],
connectionInitialTimeoutMs = json['connection_initial_timeout_ms'];
@@ -633,7 +633,7 @@ class VeilidConfigDHT {
};
}
VeilidConfigDHT.fromJson(Map<String, dynamic> json)
VeilidConfigDHT.fromJson(dynamic json)
: resolveNodeTimeoutMs = json['resolve_node_timeout_ms'],
resolveNodeCount = json['resolve_node_count'],
resolveNodeFanout = json['resolve_node_fanout'],
@@ -682,7 +682,7 @@ class VeilidConfigRPC {
};
}
VeilidConfigRPC.fromJson(Map<String, dynamic> json)
VeilidConfigRPC.fromJson(dynamic json)
: concurrency = json['concurrency'],
queueSize = json['queue_size'],
maxTimestampBehindMs = json['max_timestamp_behind_ms'],
@@ -719,7 +719,7 @@ class VeilidConfigRoutingTable {
};
}
VeilidConfigRoutingTable.fromJson(Map<String, dynamic> json)
VeilidConfigRoutingTable.fromJson(dynamic json)
: limitOverAttached = json['limit_over_attached'],
limitFullyAttached = json['limit_fully_attached'],
limitAttachedStrong = json['limit_attached_strong'],
@@ -805,7 +805,7 @@ class VeilidConfigNetwork {
};
}
VeilidConfigNetwork.fromJson(Map<String, dynamic> json)
VeilidConfigNetwork.fromJson(dynamic json)
: connectionInitialTimeoutMs = json['connection_initial_timeout_ms'],
connectionInactivityTimeoutMs =
json['connection_inactivity_timeout_ms'],
@@ -848,7 +848,7 @@ class VeilidConfigTableStore {
return {'directory': directory, 'delete': delete};
}
VeilidConfigTableStore.fromJson(Map<String, dynamic> json)
VeilidConfigTableStore.fromJson(dynamic json)
: directory = json['directory'],
delete = json['delete'];
}
@@ -868,7 +868,7 @@ class VeilidConfigBlockStore {
return {'directory': directory, 'delete': delete};
}
VeilidConfigBlockStore.fromJson(Map<String, dynamic> json)
VeilidConfigBlockStore.fromJson(dynamic json)
: directory = json['directory'],
delete = json['delete'];
}
@@ -897,7 +897,7 @@ class VeilidConfigProtectedStore {
};
}
VeilidConfigProtectedStore.fromJson(Map<String, dynamic> json)
VeilidConfigProtectedStore.fromJson(dynamic json)
: allowInsecureFallback = json['allow_insecure_fallback'],
alwaysUseInsecureStorage = json['always_use_insecure_storage'],
insecureFallbackDirectory = json['insecure_fallback_directory'],
@@ -937,7 +937,7 @@ class VeilidConfigCapabilities {
};
}
VeilidConfigCapabilities.fromJson(Map<String, dynamic> json)
VeilidConfigCapabilities.fromJson(dynamic json)
: protocolUDP = json['protocol_udp'],
protocolConnectTCP = json['protocol_connect_tcp'],
protocolAcceptTCP = json['protocol_accept_tcp'],
@@ -980,7 +980,7 @@ class VeilidConfig {
};
}
VeilidConfig.fromJson(Map<String, dynamic> json)
VeilidConfig.fromJson(dynamic json)
: programName = json['program_name'],
namespace = json['namespace'],
capabilities = VeilidConfigCapabilities.fromJson(json['capabilities']),
@@ -1012,7 +1012,7 @@ class LatencyStats {
};
}
LatencyStats.fromJson(Map<String, dynamic> json)
LatencyStats.fromJson(dynamic json)
: fastest = BigInt.parse(json['fastest']),
average = BigInt.parse(json['average']),
slowest = BigInt.parse(json['slowest']);
@@ -1042,7 +1042,7 @@ class TransferStats {
};
}
TransferStats.fromJson(Map<String, dynamic> json)
TransferStats.fromJson(dynamic json)
: total = BigInt.parse(json['total']),
maximum = BigInt.parse(json['maximum']),
average = BigInt.parse(json['average']),
@@ -1067,7 +1067,7 @@ class TransferStatsDownUp {
};
}
TransferStatsDownUp.fromJson(Map<String, dynamic> json)
TransferStatsDownUp.fromJson(dynamic json)
: down = TransferStats.fromJson(json['down']),
up = TransferStats.fromJson(json['up']);
}
@@ -1108,7 +1108,7 @@ class RPCStats {
};
}
RPCStats.fromJson(Map<String, dynamic> json)
RPCStats.fromJson(dynamic json)
: messagesSent = json['messages_sent'],
messagesRcvd = json['messages_rcvd'],
questionsInFlight = json['questions_in_flight'],
@@ -1149,7 +1149,7 @@ class PeerStats {
};
}
PeerStats.fromJson(Map<String, dynamic> json)
PeerStats.fromJson(dynamic json)
: timeAdded = BigInt.parse(json['time_added']),
rpcStats = RPCStats.fromJson(json['rpc_stats']),
latency = json['latency'] != null
@@ -1179,7 +1179,7 @@ class PeerTableData {
};
}
PeerTableData.fromJson(Map<String, dynamic> json)
PeerTableData.fromJson(dynamic json)
: nodeId = json['node_id'],
peerAddress = PeerAddress.fromJson(json['peer_address']),
peerStats = PeerStats.fromJson(json['peer_stats']);
@@ -1223,7 +1223,7 @@ class PeerAddress {
};
}
PeerAddress.fromJson(Map<String, dynamic> json)
PeerAddress.fromJson(dynamic json)
: protocolType = protocolTypeFromJson(json['protocol_type']),
socketAddress = json['socket_address'];
}
@@ -1232,7 +1232,7 @@ class PeerAddress {
/// VeilidUpdate
abstract class VeilidUpdate {
factory VeilidUpdate.fromJson(Map<String, dynamic> json) {
factory VeilidUpdate.fromJson(dynamic json) {
switch (json["kind"]) {
case "Log":
{
@@ -1406,7 +1406,7 @@ class VeilidStateAttachment {
VeilidStateAttachment(
this.state, this.publicInternetReady, this.localNetworkReady);
VeilidStateAttachment.fromJson(Map<String, dynamic> json)
VeilidStateAttachment.fromJson(dynamic json)
: state = attachmentStateFromJson(json['state']),
publicInternetReady = json['public_internet_ready'],
localNetworkReady = json['local_network_ready'];
@@ -1435,7 +1435,7 @@ class VeilidStateNetwork {
required this.bpsUp,
required this.peers});
VeilidStateNetwork.fromJson(Map<String, dynamic> json)
VeilidStateNetwork.fromJson(dynamic json)
: started = json['started'],
bpsDown = BigInt.parse(json['bps_down']),
bpsUp = BigInt.parse(json['bps_up']),
@@ -1462,8 +1462,7 @@ class VeilidStateConfig {
required this.config,
});
VeilidStateConfig.fromJson(Map<String, dynamic> json)
: config = json['config'];
VeilidStateConfig.fromJson(dynamic json) : config = json['config'];
Map<String, dynamic> get json {
return {'config': config};
@@ -1482,7 +1481,7 @@ class VeilidStateRoute {
required this.deadRemoteRoutes,
});
VeilidStateRoute.fromJson(Map<String, dynamic> json)
VeilidStateRoute.fromJson(dynamic json)
: deadRoutes = List<String>.from(json['dead_routes'].map((j) => j)),
deadRemoteRoutes =
List<String>.from(json['dead_remote_routes'].map((j) => j));
@@ -1503,7 +1502,7 @@ class VeilidState {
final VeilidStateNetwork network;
final VeilidStateConfig config;
VeilidState.fromJson(Map<String, dynamic> json)
VeilidState.fromJson(dynamic json)
: attachment = VeilidStateAttachment.fromJson(json['attachment']),
network = VeilidStateNetwork.fromJson(json['network']),
config = VeilidStateConfig.fromJson(json['config']);
@@ -1521,7 +1520,7 @@ class VeilidState {
/// VeilidAPIException
abstract class VeilidAPIException implements Exception {
factory VeilidAPIException.fromJson(Map<String, dynamic> json) {
factory VeilidAPIException.fromJson(dynamic json) {
switch (json["kind"]) {
case "NotInitialized":
{
@@ -1828,7 +1827,7 @@ class KeyBlob {
KeyBlob(this.key, this.blob);
KeyBlob.fromJson(Map<String, dynamic> json)
KeyBlob.fromJson(dynamic json)
: key = json['key'],
blob = base64Decode(json['blob']);
@@ -1853,9 +1852,13 @@ abstract class VeilidTableDBTransaction {
Future<void> commit();
Future<void> rollback();
Future<void> store(int col, Uint8List key, Uint8List value);
Future<void> storeJson(int col, Uint8List key, Object? object,
{Object? Function(Object? nonEncodable) toEncodable});
Future<bool> delete(int col, Uint8List key);
Future<void> storeJson(int col, Uint8List key, Object? object,
{Object? Function(Object? nonEncodable)? toEncodable}) async {
return store(col, key,
utf8.encoder.convert(jsonEncode(object, toEncodable: toEncodable)));
}
}
abstract class VeilidTableDB {
@@ -1863,12 +1866,23 @@ abstract class VeilidTableDB {
List<Uint8List> getKeys(int col);
VeilidTableDBTransaction transact();
Future<void> store(int col, Uint8List key, Uint8List value);
Future<void> storeJson(int col, Uint8List key, Object? object,
{Object? Function(Object? nonEncodable) toEncodable});
Future<Uint8List?> load(int col, Uint8List key);
Future<Object?> loadJson(int col, Uint8List key,
{Object? Function(Object? key, Object? value) reviver});
Future<bool> delete(int col, Uint8List key);
Future<void> storeJson(int col, Uint8List key, Object? object,
{Object? Function(Object? nonEncodable)? toEncodable}) {
return store(col, key,
utf8.encoder.convert(jsonEncode(object, toEncodable: toEncodable)));
}
Future<Object?> loadJson(int col, Uint8List key,
{Object? Function(Object? key, Object? value)? reviver}) async {
var s = await load(col, key);
if (s == null) {
return null;
}
return jsonDecode(utf8.decode(s, allowMalformed: false));
}
}
//////////////////////////////////////

View File

@@ -95,6 +95,55 @@ typedef _ReleasePrivateRouteDart = void Function(int, Pointer<Utf8>);
typedef _AppCallReplyC = Void Function(Int64, Pointer<Utf8>, Pointer<Utf8>);
typedef _AppCallReplyDart = void Function(int, Pointer<Utf8>, Pointer<Utf8>);
// fn open_table_db(port: i64, name: FfiStr, column_count: u32)
typedef _OpenTableDbC = Void Function(Int64, Pointer<Utf8>, Uint32);
typedef _OpenTableDbDart = void Function(int, Pointer<Utf8>, int);
// fn release_table_db(id: u32) -> i32
typedef _ReleaseTableDbC = Int32 Function(Uint32);
typedef _ReleaseTableDbDart = int Function(int);
// fn delete_table_db(port: i64, name: FfiStr)
typedef _DeleteTableDbC = Void Function(Int64, Pointer<Utf8>);
typedef _DeleteTableDbDart = void Function(int, Pointer<Utf8>);
// fn table_db_get_column_count(id: u32) -> u32
typedef _TableDbGetColumnCountC = Uint32 Function(Uint32);
typedef _TableDbGetColumnCountDart = int Function(int);
// fn table_db_get_keys(id: u32, col: u32) -> *mut c_char
typedef _TableDbGetKeysC = Pointer<Utf8> Function(Uint32, Uint32);
typedef _TableDbGetKeysDart = Pointer<Utf8> Function(int, int);
// fn table_db_store(port: i64, id: u32, col: u32, key: FfiStr, value: FfiStr)
typedef _TableDbStoreC = Void Function(
Int64, Uint32, Uint32, Pointer<Utf8>, Pointer<Utf8>);
typedef _TableDbStoreDart = void Function(
int, int, int, Pointer<Utf8>, Pointer<Utf8>);
// fn table_db_load(port: i64, id: u32, col: u32, key: FfiStr)
typedef _TableDbLoadC = Void Function(Int64, Uint32, Uint32, Pointer<Utf8>);
typedef _TableDbLoadDart = void Function(int, int, int, Pointer<Utf8>);
// fn table_db_delete(port: i64, id: u32, col: u32, key: FfiStr)
typedef _TableDbDeleteC = Void Function(Int64, Uint32, Uint32, Pointer<Utf8>);
typedef _TableDbDeleteDart = void Function(int, int, int, Pointer<Utf8>);
// fn table_db_transact(id: u32) -> u32
typedef _TableDbTransactC = Uint32 Function(Uint32);
typedef _TableDbTransactDart = int Function(int);
// fn release_table_db_transaction(id: u32) -> i32
typedef _ReleaseTableDbTransactionC = Int32 Function(Uint32);
typedef _ReleaseTableDbTransactionDart = int Function(int);
// fn table_db_transaction_commit(port: i64, id: u32)
typedef _TableDbTransactionCommitC = Void Function(Uint64, Uint32);
typedef _TableDbTransactionCommitDart = void Function(int, int);
// fn table_db_transaction_rollback(port: i64, id: u32)
typedef _TableDbTransactionRollbackC = Void Function(Uint64, Uint32);
typedef _TableDbTransactionRollbackDart = void Function(int, int);
// fn table_db_transaction_store(port: i64, id: u32, col: u32, key: FfiStr, value: FfiStr)
typedef _TableDbTransactionStoreC = Void Function(
Int64, Uint32, Uint32, Pointer<Utf8>, Pointer<Utf8>);
typedef _TableDbTransactionStoreDart = void Function(
int, int, int, Pointer<Utf8>, Pointer<Utf8>);
// fn table_db_transaction_delete(port: i64, id: u32, col: u32, key: FfiStr)
typedef _TableDbTransactionDeleteC = Void Function(
Int64, Uint32, Uint32, Pointer<Utf8>);
typedef _TableDbTransactionDeleteDart = void Function(
int, int, int, Pointer<Utf8>);
// fn debug(port: i64, log_level: FfiStr)
typedef _DebugC = Void Function(Int64, Pointer<Utf8>);
typedef _DebugDart = void Function(int, Pointer<Utf8>);
@@ -168,7 +217,7 @@ Future<T> processFuturePlain<T>(Future<dynamic> future) {
}
Future<T> processFutureJson<T>(
T Function(Map<String, dynamic>) jsonConstructor, Future<dynamic> future) {
T Function(dynamic) jsonConstructor, Future<dynamic> future) {
return future.then((value) {
final list = value as List<dynamic>;
switch (list[0] as int) {
@@ -388,8 +437,8 @@ class VeilidRoutingContextFFI implements VeilidRoutingContext {
@override
Future<void> appMessage(String target, Uint8List message) async {
var nativeEncodedTarget = target.toNativeUtf8();
var nativeEncodedMessage = base64UrlEncode(message).toNativeUtf8();
final nativeEncodedTarget = target.toNativeUtf8();
final nativeEncodedMessage = base64UrlEncode(message).toNativeUtf8();
final recvPort = ReceivePort("routing_context_app_message");
final sendPort = recvPort.sendPort;
@@ -399,6 +448,170 @@ class VeilidRoutingContextFFI implements VeilidRoutingContext {
}
}
class _TDBT {
final int id;
VeilidTableDBFFI tdbffi;
VeilidFFI ffi;
_TDBT(this.id, this.tdbffi, this.ffi);
}
// FFI implementation of VeilidTableDBTransaction
class VeilidTableDBTransactionFFI extends VeilidTableDBTransaction {
final _TDBT _tdbt;
static final Finalizer<_TDBT> _finalizer =
Finalizer((tdbt) => {tdbt.ffi._releaseTableDbTransaction(tdbt.id)});
VeilidTableDBTransactionFFI._(this._tdbt) {
_finalizer.attach(this, _tdbt, detach: this);
}
@override
Future<void> commit() {
final recvPort = ReceivePort("veilid_table_db_transaction_commit");
final sendPort = recvPort.sendPort;
_tdbt.ffi._tableDbTransactionCommit(
sendPort.nativePort,
_tdbt.id,
);
return processFutureVoid(recvPort.first);
}
@override
Future<void> rollback() {
final recvPort = ReceivePort("veilid_table_db_transaction_rollback");
final sendPort = recvPort.sendPort;
_tdbt.ffi._tableDbTransactionRollback(
sendPort.nativePort,
_tdbt.id,
);
return processFutureVoid(recvPort.first);
}
@override
Future<void> store(int col, Uint8List key, Uint8List value) {
final nativeEncodedKey = base64UrlEncode(key).toNativeUtf8();
final nativeEncodedValue = base64UrlEncode(value).toNativeUtf8();
final recvPort = ReceivePort("veilid_table_db_transaction_store");
final sendPort = recvPort.sendPort;
_tdbt.ffi._tableDbTransactionStore(
sendPort.nativePort,
_tdbt.id,
col,
nativeEncodedKey,
nativeEncodedValue,
);
return processFutureVoid(recvPort.first);
}
@override
Future<bool> delete(int col, Uint8List key) {
final nativeEncodedKey = base64UrlEncode(key).toNativeUtf8();
final recvPort = ReceivePort("veilid_table_db_transaction_delete");
final sendPort = recvPort.sendPort;
_tdbt.ffi._tableDbTransactionDelete(
sendPort.nativePort,
_tdbt.id,
col,
nativeEncodedKey,
);
return processFuturePlain(recvPort.first);
}
}
class _TDB {
final int id;
VeilidFFI ffi;
_TDB(this.id, this.ffi);
}
// FFI implementation of VeilidTableDB
class VeilidTableDBFFI extends VeilidTableDB {
final _TDB _tdb;
static final Finalizer<_TDB> _finalizer =
Finalizer((tdb) => {tdb.ffi._releaseTableDb(tdb.id)});
VeilidTableDBFFI._(this._tdb) {
_finalizer.attach(this, _tdb, detach: this);
}
@override
int getColumnCount() {
return _tdb.ffi._tableDbGetColumnCount(_tdb.id);
}
@override
List<Uint8List> getKeys(int col) {
final s = _tdb.ffi._tableDbGetKeys(_tdb.id, col);
if (s.address == nullptr.address) {
throw VeilidAPIExceptionInternal("No db for id");
}
String ja = s.toDartString();
_tdb.ffi._freeString(s);
List<dynamic> jarr = jsonDecode(ja);
return jarr.map((e) => base64Decode(e)).toList();
}
@override
VeilidTableDBTransaction transact() {
final id = _tdb.ffi._tableDbTransact(_tdb.id);
return VeilidTableDBTransactionFFI._(_TDBT(id, this, _tdb.ffi));
}
@override
Future<void> store(int col, Uint8List key, Uint8List value) {
final nativeEncodedKey = base64UrlEncode(key).toNativeUtf8();
final nativeEncodedValue = base64UrlEncode(value).toNativeUtf8();
final recvPort = ReceivePort("veilid_table_db_store");
final sendPort = recvPort.sendPort;
_tdb.ffi._tableDbStore(
sendPort.nativePort,
_tdb.id,
col,
nativeEncodedKey,
nativeEncodedValue,
);
return processFutureVoid(recvPort.first);
}
@override
Future<Uint8List?> load(int col, Uint8List key) async {
final nativeEncodedKey = base64UrlEncode(key).toNativeUtf8();
final recvPort = ReceivePort("veilid_table_db_load");
final sendPort = recvPort.sendPort;
_tdb.ffi._tableDbLoad(
sendPort.nativePort,
_tdb.id,
col,
nativeEncodedKey,
);
String? out = await processFuturePlain(recvPort.first);
if (out == null) {
return null;
}
return base64Decode(out);
}
@override
Future<bool> delete(int col, Uint8List key) {
final nativeEncodedKey = base64UrlEncode(key).toNativeUtf8();
final recvPort = ReceivePort("veilid_table_db_delete");
final sendPort = recvPort.sendPort;
_tdb.ffi._tableDbLoad(
sendPort.nativePort,
_tdb.id,
col,
nativeEncodedKey,
);
return processFuturePlain(recvPort.first);
}
}
// FFI implementation of high level Veilid API
class VeilidFFI implements Veilid {
// veilid_core shared library
@@ -429,6 +642,21 @@ class VeilidFFI implements Veilid {
final _AppCallReplyDart _appCallReply;
final _OpenTableDbDart _openTableDb;
final _ReleaseTableDbDart _releaseTableDb;
final _DeleteTableDbDart _deleteTableDb;
final _TableDbGetColumnCountDart _tableDbGetColumnCount;
final _TableDbGetKeysDart _tableDbGetKeys;
final _TableDbStoreDart _tableDbStore;
final _TableDbLoadDart _tableDbLoad;
final _TableDbDeleteDart _tableDbDelete;
final _TableDbTransactDart _tableDbTransact;
final _ReleaseTableDbTransactionDart _releaseTableDbTransaction;
final _TableDbTransactionCommitDart _tableDbTransactionCommit;
final _TableDbTransactionRollbackDart _tableDbTransactionRollback;
final _TableDbTransactionStoreDart _tableDbTransactionStore;
final _TableDbTransactionDeleteDart _tableDbTransactionDelete;
final _DebugDart _debug;
final _VeilidVersionStringDart _veilidVersionString;
final _VeilidVersionDart _veilidVersion;
@@ -486,6 +714,44 @@ class VeilidFFI implements Veilid {
_ReleasePrivateRouteDart>('release_private_route'),
_appCallReply = dylib.lookupFunction<_AppCallReplyC, _AppCallReplyDart>(
'app_call_reply'),
_openTableDb = dylib
.lookupFunction<_OpenTableDbC, _OpenTableDbDart>('open_table_db'),
_releaseTableDb =
dylib.lookupFunction<_ReleaseTableDbC, _ReleaseTableDbDart>(
'release_table_db'),
_deleteTableDb =
dylib.lookupFunction<_DeleteTableDbC, _DeleteTableDbDart>(
'delete_table_db'),
_tableDbGetColumnCount = dylib.lookupFunction<_TableDbGetColumnCountC,
_TableDbGetColumnCountDart>('table_db_get_column_count'),
_tableDbGetKeys =
dylib.lookupFunction<_TableDbGetKeysC, _TableDbGetKeysDart>(
'table_db_get_keys'),
_tableDbStore = dylib.lookupFunction<_TableDbStoreC, _TableDbStoreDart>(
'table_db_store'),
_tableDbLoad = dylib
.lookupFunction<_TableDbLoadC, _TableDbLoadDart>('table_db_load'),
_tableDbDelete =
dylib.lookupFunction<_TableDbDeleteC, _TableDbDeleteDart>(
'table_db_delete'),
_tableDbTransact =
dylib.lookupFunction<_TableDbTransactC, _TableDbTransactDart>(
'table_db_transact'),
_releaseTableDbTransaction = dylib.lookupFunction<
_ReleaseTableDbTransactionC,
_ReleaseTableDbTransactionDart>('release_table_db_transaction'),
_tableDbTransactionCommit = dylib.lookupFunction<
_TableDbTransactionCommitC,
_TableDbTransactionCommitDart>('table_db_transaction_commit'),
_tableDbTransactionRollback = dylib.lookupFunction<
_TableDbTransactionRollbackC,
_TableDbTransactionRollbackDart>('table_db_transaction_rollback'),
_tableDbTransactionStore = dylib.lookupFunction<
_TableDbTransactionStoreC,
_TableDbTransactionStoreDart>('table_db_transaction_store'),
_tableDbTransactionDelete = dylib.lookupFunction<
_TableDbTransactionDeleteC,
_TableDbTransactionDeleteDart>('table_db_transaction_delete'),
_debug = dylib.lookupFunction<_DebugC, _DebugDart>('debug'),
_veilidVersionString = dylib.lookupFunction<_VeilidVersionStringC,
_VeilidVersionStringDart>('veilid_version_string'),
@@ -539,7 +805,7 @@ class VeilidFFI implements Veilid {
}
@override
Future<VeilidState> getVeilidState() async {
Future<VeilidState> getVeilidState() {
final recvPort = ReceivePort("get_veilid_state");
final sendPort = recvPort.sendPort;
_getVeilidState(sendPort.nativePort);
@@ -547,7 +813,7 @@ class VeilidFFI implements Veilid {
}
@override
Future<void> attach() async {
Future<void> attach() {
final recvPort = ReceivePort("attach");
final sendPort = recvPort.sendPort;
_attach(sendPort.nativePort);
@@ -555,7 +821,7 @@ class VeilidFFI implements Veilid {
}
@override
Future<void> detach() async {
Future<void> detach() {
final recvPort = ReceivePort("detach");
final sendPort = recvPort.sendPort;
_detach(sendPort.nativePort);
@@ -563,7 +829,7 @@ class VeilidFFI implements Veilid {
}
@override
Future<void> shutdownVeilidCore() async {
Future<void> shutdownVeilidCore() {
final recvPort = ReceivePort("shutdown_veilid_core");
final sendPort = recvPort.sendPort;
_shutdownVeilidCore(sendPort.nativePort);
@@ -580,7 +846,7 @@ class VeilidFFI implements Veilid {
}
@override
Future<KeyBlob> newPrivateRoute() async {
Future<KeyBlob> newPrivateRoute() {
final recvPort = ReceivePort("new_private_route");
final sendPort = recvPort.sendPort;
_newPrivateRoute(sendPort.nativePort);
@@ -599,8 +865,8 @@ class VeilidFFI implements Veilid {
}
@override
Future<String> importRemotePrivateRoute(Uint8List blob) async {
var nativeEncodedBlob = base64UrlEncode(blob).toNativeUtf8();
Future<String> importRemotePrivateRoute(Uint8List blob) {
final nativeEncodedBlob = base64UrlEncode(blob).toNativeUtf8();
final recvPort = ReceivePort("import_remote_private_route");
final sendPort = recvPort.sendPort;
@@ -609,8 +875,8 @@ class VeilidFFI implements Veilid {
}
@override
Future<void> releasePrivateRoute(String key) async {
var nativeEncodedKey = key.toNativeUtf8();
Future<void> releasePrivateRoute(String key) {
final nativeEncodedKey = key.toNativeUtf8();
final recvPort = ReceivePort("release_private_route");
final sendPort = recvPort.sendPort;
@@ -619,15 +885,33 @@ class VeilidFFI implements Veilid {
}
@override
Future<void> appCallReply(String id, Uint8List message) async {
var nativeId = id.toNativeUtf8();
var nativeEncodedMessage = base64UrlEncode(message).toNativeUtf8();
Future<void> appCallReply(String id, Uint8List message) {
final nativeId = id.toNativeUtf8();
final nativeEncodedMessage = base64UrlEncode(message).toNativeUtf8();
final recvPort = ReceivePort("app_call_reply");
final sendPort = recvPort.sendPort;
_appCallReply(sendPort.nativePort, nativeId, nativeEncodedMessage);
return processFutureVoid(recvPort.first);
}
@override
Future<VeilidTableDB> openTableDB(String name, int columnCount) async {
final recvPort = ReceivePort("open_table_db");
final sendPort = recvPort.sendPort;
_openTableDb(sendPort.nativePort, name.toNativeUtf8(), columnCount);
final id = await processFuturePlain(recvPort.first);
return VeilidTableDBFFI._(_TDB(id, this));
}
@override
Future<bool> deleteTableDB(String name) async {
final recvPort = ReceivePort("delete_table_db");
final sendPort = recvPort.sendPort;
_deleteTableDb(sendPort.nativePort, name.toNativeUtf8());
final deleted = await processFuturePlain(recvPort.first);
return deleted;
}
@override
Future<String> debug(String command) async {
var nativeCommand = command.toNativeUtf8();

View File

@@ -67,7 +67,7 @@ class VeilidRoutingContextJS implements VeilidRoutingContext {
}
@override
Future<void> appMessage(String target, Uint8List message) async {
Future<void> appMessage(String target, Uint8List message) {
var encodedMessage = base64UrlEncode(message);
return _wrapApiPromise(js_util.callMethod(
@@ -75,6 +75,127 @@ class VeilidRoutingContextJS implements VeilidRoutingContext {
}
}
class _TDBT {
final int id;
VeilidTableDBJS tdbjs;
VeilidJS js;
_TDBT(this.id, this.tdbjs, this.js);
}
// JS implementation of VeilidTableDBTransaction
class VeilidTableDBTransactionJS extends VeilidTableDBTransaction {
final _TDBT _tdbt;
static final Finalizer<_TDBT> _finalizer = Finalizer((tdbt) => {
js_util.callMethod(wasm, "release_table_db_transaction", [tdbt.id])
});
VeilidTableDBTransactionJS._(this._tdbt) {
_finalizer.attach(this, _tdbt, detach: this);
}
@override
Future<void> commit() {
return _wrapApiPromise(js_util
.callMethod(wasm, "veilid_table_db_transaction_commit", [_tdbt.id]));
}
@override
Future<void> rollback() {
return _wrapApiPromise(js_util
.callMethod(wasm, "veilid_table_db_transaction_rollback", [_tdbt.id]));
}
@override
Future<void> store(int col, Uint8List key, Uint8List value) {
final encodedKey = base64UrlEncode(key);
final encodedValue = base64UrlEncode(value);
return _wrapApiPromise(js_util.callMethod(
wasm,
"veilid_table_db_transaction_store",
[_tdbt.id, encodedKey, encodedValue]));
}
@override
Future<bool> delete(int col, Uint8List key) {
final encodedKey = base64UrlEncode(key);
return _wrapApiPromise(js_util.callMethod(
wasm, "veilid_table_db_transaction_delete", [_tdbt.id, encodedKey]));
}
}
class _TDB {
final int id;
VeilidJS js;
_TDB(this.id, this.js);
}
// JS implementation of VeilidTableDB
class VeilidTableDBJS extends VeilidTableDB {
final _TDB _tdb;
static final Finalizer<_TDB> _finalizer = Finalizer((tdb) => {
js_util.callMethod(wasm, "release_table_db", [tdb.id])
});
VeilidTableDBJS._(this._tdb) {
_finalizer.attach(this, _tdb, detach: this);
}
@override
int getColumnCount() {
return js_util.callMethod(wasm, "table_db_get_column_count", [_tdb.id]);
}
@override
List<Uint8List> getKeys(int col) {
String? s = js_util.callMethod(wasm, "table_db_get_keys", [_tdb.id, col]);
if (s == null) {
throw VeilidAPIExceptionInternal("No db for id");
}
List<dynamic> jarr = jsonDecode(s);
return jarr.map((e) => base64Decode(e)).toList();
}
@override
VeilidTableDBTransaction transact() {
final id = js_util.callMethod(wasm, "table_db_transact", [_tdb.id]);
return VeilidTableDBTransactionJS._(_TDBT(id, this, _tdb.js));
}
@override
Future<void> store(int col, Uint8List key, Uint8List value) {
final encodedKey = base64UrlEncode(key);
final encodedValue = base64UrlEncode(value);
return _wrapApiPromise(js_util.callMethod(
wasm, "veilid_table_db_store", [_tdb.id, encodedKey, encodedValue]));
}
@override
Future<Uint8List?> load(int col, Uint8List key) async {
final encodedKey = base64UrlEncode(key);
String? out = await _wrapApiPromise(js_util
.callMethod(wasm, "veilid_table_db_store", [_tdb.id, encodedKey]));
if (out == null) {
return null;
}
return base64Decode(out);
}
@override
Future<bool> delete(int col, Uint8List key) {
final encodedKey = base64UrlEncode(key);
return _wrapApiPromise(js_util
.callMethod(wasm, "veilid_table_db_delete", [_tdb.id, encodedKey]));
}
}
// JS implementation of high level Veilid API
class VeilidJS implements Veilid {
@@ -121,12 +242,12 @@ class VeilidJS implements Veilid {
}
@override
Future<void> attach() async {
Future<void> attach() {
return _wrapApiPromise(js_util.callMethod(wasm, "attach", []));
}
@override
Future<void> detach() async {
Future<void> detach() {
return _wrapApiPromise(js_util.callMethod(wasm, "detach", []));
}
@@ -165,14 +286,14 @@ class VeilidJS implements Veilid {
}
@override
Future<String> importRemotePrivateRoute(Uint8List blob) async {
Future<String> importRemotePrivateRoute(Uint8List blob) {
var encodedBlob = base64UrlEncode(blob);
return _wrapApiPromise(
js_util.callMethod(wasm, "import_remote_private_route", [encodedBlob]));
}
@override
Future<void> releasePrivateRoute(String key) async {
Future<void> releasePrivateRoute(String key) {
return _wrapApiPromise(
js_util.callMethod(wasm, "release_private_route", [key]));
}
@@ -184,6 +305,18 @@ class VeilidJS implements Veilid {
js_util.callMethod(wasm, "app_call_reply", [id, encodedMessage]));
}
@override
Future<VeilidTableDB> openTableDB(String name, int columnCount) async {
int id = await _wrapApiPromise(
js_util.callMethod(wasm, "open_table_db", [name, columnCount]));
return VeilidTableDBJS._(_TDB(id, this));
}
@override
Future<bool> deleteTableDB(String name) {
return _wrapApiPromise(js_util.callMethod(wasm, "delete_table_db", [name]));
}
@override
Future<String> debug(String command) async {
return jsonDecode(