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(

View File

@ -409,7 +409,7 @@ pub extern "C" fn routing_context_app_call(port: i64, id: u32, target: FfiStr, r
veilid_core::deserialize_opt_json(target.into_opt_string()).unwrap();
let request: Vec<u8> = data_encoding::BASE64URL_NOPAD
.decode(
veilid_core::deserialize_opt_json::<String>(request.into_opt_string())
request.into_opt_string()
.unwrap()
.as_bytes(),
)
@ -445,7 +445,7 @@ pub extern "C" fn routing_context_app_message(port: i64, id: u32, target: FfiStr
veilid_core::deserialize_opt_json(target.into_opt_string()).unwrap();
let message: Vec<u8> = data_encoding::BASE64URL_NOPAD
.decode(
veilid_core::deserialize_opt_json::<String>(message.into_opt_string())
message.into_opt_string()
.unwrap()
.as_bytes(),
)
@ -690,14 +690,14 @@ pub extern "C" fn table_db_transaction_rollback(port: i64, id: u32) {
pub extern "C" fn table_db_transaction_store(port: i64, id: u32, col: u32, key: FfiStr, value: FfiStr) {
let key: Vec<u8> = data_encoding::BASE64URL_NOPAD
.decode(
veilid_core::deserialize_opt_json::<String>(key.into_opt_string())
key.into_opt_string()
.unwrap()
.as_bytes(),
)
.unwrap();
let value: Vec<u8> = data_encoding::BASE64URL_NOPAD
.decode(
veilid_core::deserialize_opt_json::<String>(value.into_opt_string())
value.into_opt_string()
.unwrap()
.as_bytes(),
)
@ -721,7 +721,7 @@ pub extern "C" fn table_db_transaction_store(port: i64, id: u32, col: u32, key:
pub extern "C" fn table_db_transaction_delete(port: i64, id: u32, col: u32, key: FfiStr) {
let key: Vec<u8> = data_encoding::BASE64URL_NOPAD
.decode(
veilid_core::deserialize_opt_json::<String>(key.into_opt_string())
key.into_opt_string()
.unwrap()
.as_bytes(),
)
@ -744,14 +744,14 @@ pub extern "C" fn table_db_transaction_delete(port: i64, id: u32, col: u32, key:
pub extern "C" fn table_db_store(port: i64, id: u32, col: u32, key: FfiStr, value: FfiStr) {
let key: Vec<u8> = data_encoding::BASE64URL_NOPAD
.decode(
veilid_core::deserialize_opt_json::<String>(key.into_opt_string())
key.into_opt_string()
.unwrap()
.as_bytes(),
)
.unwrap();
let value: Vec<u8> = data_encoding::BASE64URL_NOPAD
.decode(
veilid_core::deserialize_opt_json::<String>(value.into_opt_string())
value.into_opt_string()
.unwrap()
.as_bytes(),
)
@ -773,13 +773,12 @@ pub extern "C" fn table_db_store(port: i64, id: u32, col: u32, key: FfiStr, valu
#[no_mangle]
pub extern "C" fn table_db_load(port: i64, id: u32, col: u32, key: FfiStr) {
let key: Vec<u8> = data_encoding::BASE64URL_NOPAD
.decode(
veilid_core::deserialize_opt_json::<String>(key.into_opt_string())
.decode(key.into_opt_string()
.unwrap()
.as_bytes(),
.as_bytes()
)
.unwrap();
DartIsolateWrapper::new(port).spawn_result_json(async move {
DartIsolateWrapper::new(port).spawn_result(async move {
let table_db = {
let table_dbs = TABLE_DBS.lock();
let Some(table_db) = table_dbs.get(&id) else {
@ -789,6 +788,7 @@ pub extern "C" fn table_db_load(port: i64, id: u32, col: u32, key: FfiStr) {
};
let out = table_db.load(col, &key).map_err(veilid_core::VeilidAPIError::generic)?;
let out = out.map(|x| data_encoding::BASE64URL_NOPAD.encode(&x));
APIResult::Ok(out)
});
}
@ -797,7 +797,7 @@ pub extern "C" fn table_db_load(port: i64, id: u32, col: u32, key: FfiStr) {
pub extern "C" fn table_db_delete(port: i64, id: u32, col: u32, key: FfiStr) {
let key: Vec<u8> = data_encoding::BASE64URL_NOPAD
.decode(
veilid_core::deserialize_opt_json::<String>(key.into_opt_string())
key.into_opt_string()
.unwrap()
.as_bytes(),
)

View File

@ -37,6 +37,10 @@ lazy_static! {
SendWrapper::new(RefCell::new(BTreeMap::new()));
static ref ROUTING_CONTEXTS: SendWrapper<RefCell<BTreeMap<u32, veilid_core::RoutingContext>>> =
SendWrapper::new(RefCell::new(BTreeMap::new()));
static ref TABLE_DBS: SendWrapper<RefCell<BTreeMap<u32, veilid_core::TableDB>>> =
SendWrapper::new(RefCell::new(BTreeMap::new()));
static ref TABLE_DB_TRANSACTIONS: SendWrapper<RefCell<BTreeMap<u32, veilid_core::TableDBTransaction>>> =
SendWrapper::new(RefCell::new(BTreeMap::new()));
}
fn get_veilid_api() -> Result<veilid_core::VeilidAPI, veilid_core::VeilidAPIError> {
@ -468,6 +472,255 @@ pub fn app_call_reply(id: String, message: String) -> Promise {
})
}
fn add_table_db(table_db: veilid_core::TableDB) -> u32 {
let mut next_id: u32 = 1;
let mut tdbs = (*TABLE_DBS).borrow_mut();
while tdbs.contains_key(&next_id) {
next_id += 1;
}
tdbs.insert(next_id, table_db);
next_id
}
#[wasm_bindgen()]
pub fn open_table_db(name: String, column_count: u32) -> Promise {
wrap_api_future(async move {
let veilid_api = get_veilid_api()?;
let tstore = veilid_api.table_store()?;
let table_db = tstore
.open(&name, column_count)
.await
.map_err(veilid_core::VeilidAPIError::generic)?;
let new_id = add_table_db(table_db);
Ok(new_id)
})
}
#[wasm_bindgen()]
pub fn release_table_db(id: u32) -> i32 {
let mut tdbs = (*TABLE_DBS).borrow_mut();
if tdbs.remove(&id).is_none() {
return 0;
}
return 1;
}
#[wasm_bindgen()]
pub fn delete_table_db(name: String) -> Promise {
wrap_api_future(async move {
let veilid_api = get_veilid_api()?;
let tstore = veilid_api.table_store()?;
let deleted = tstore
.delete(&name)
.await
.map_err(veilid_core::VeilidAPIError::generic)?;
Ok(deleted)
})
}
#[wasm_bindgen()]
pub fn table_db_get_column_count(id: u32) -> u32 {
let table_dbs = (*TABLE_DBS).borrow();
let Some(table_db) = table_dbs.get(&id) else {
return 0;
};
let Ok(cc) = table_db.clone().get_column_count() else {
return 0;
};
return cc;
}
#[wasm_bindgen()]
pub fn table_db_get_keys(id: u32, col: u32) -> Option<String> {
let table_dbs = (*TABLE_DBS).borrow();
let Some(table_db) = table_dbs.get(&id) else {
return None;
};
let Ok(keys) = table_db.clone().get_keys(col) else {
return None;
};
let keys: Vec<String> = keys
.into_iter()
.map(|k| data_encoding::BASE64URL_NOPAD.encode(&k))
.collect();
let out = veilid_core::serialize_json(keys);
Some(out)
}
fn add_table_db_transaction(tdbt: veilid_core::TableDBTransaction) -> u32 {
let mut next_id: u32 = 1;
let mut tdbts = (*TABLE_DB_TRANSACTIONS).borrow_mut();
while tdbts.contains_key(&next_id) {
next_id += 1;
}
tdbts.insert(next_id, tdbt);
next_id
}
#[wasm_bindgen()]
pub fn table_db_transact(id: u32) -> u32 {
let table_dbs = (*TABLE_DBS).borrow();
let Some(table_db) = table_dbs.get(&id) else {
return 0;
};
let tdbt = table_db.clone().transact();
let tdbtid = add_table_db_transaction(tdbt);
return tdbtid;
}
#[wasm_bindgen()]
pub fn release_table_db_transaction(id: u32) -> i32 {
let mut tdbts = (*TABLE_DB_TRANSACTIONS).borrow_mut();
if tdbts.remove(&id).is_none() {
return 0;
}
return 1;
}
#[wasm_bindgen()]
pub fn table_db_transaction_commit(id: u32) -> Promise {
wrap_api_future(async move {
let tdbt = {
let tdbts = (*TABLE_DB_TRANSACTIONS).borrow();
let Some(tdbt) = tdbts.get(&id) else {
return APIResult::Err(veilid_core::VeilidAPIError::invalid_argument("table_db_transaction_commit", "id", id));
};
tdbt.clone()
};
tdbt.commit()
.await
.map_err(veilid_core::VeilidAPIError::generic)?;
APIRESULT_UNDEFINED
})
}
#[wasm_bindgen()]
pub fn table_db_transaction_rollback(id: u32) -> Promise {
wrap_api_future(async move {
let tdbt = {
let tdbts = (*TABLE_DB_TRANSACTIONS).borrow();
let Some(tdbt) = tdbts.get(&id) else {
return APIResult::Err(veilid_core::VeilidAPIError::invalid_argument("table_db_transaction_rollback", "id", id));
};
tdbt.clone()
};
tdbt.rollback();
APIRESULT_UNDEFINED
})
}
#[wasm_bindgen()]
pub fn table_db_transaction_store(id: u32, col: u32, key: String, value: String) -> Promise {
let key: Vec<u8> = data_encoding::BASE64URL_NOPAD
.decode(key.as_bytes())
.unwrap();
let value: Vec<u8> = data_encoding::BASE64URL_NOPAD
.decode(value.as_bytes())
.unwrap();
wrap_api_future(async move {
let tdbt = {
let tdbts = (*TABLE_DB_TRANSACTIONS).borrow();
let Some(tdbt) = tdbts.get(&id) else {
return APIResult::Err(veilid_core::VeilidAPIError::invalid_argument("table_db_transaction_store", "id", id));
};
tdbt.clone()
};
tdbt.store(col, &key, &value);
APIRESULT_UNDEFINED
})
}
#[wasm_bindgen()]
pub fn table_db_transaction_delete(id: u32, col: u32, key: String) -> Promise {
let key: Vec<u8> = data_encoding::BASE64URL_NOPAD
.decode(key.as_bytes())
.unwrap();
wrap_api_future(async move {
let tdbt = {
let tdbts = (*TABLE_DB_TRANSACTIONS).borrow();
let Some(tdbt) = tdbts.get(&id) else {
return APIResult::Err(veilid_core::VeilidAPIError::invalid_argument("table_db_transaction_delete", "id", id));
};
tdbt.clone()
};
let out = tdbt.delete(col, &key);
APIResult::Ok(out)
})
}
#[wasm_bindgen()]
pub fn table_db_store(id: u32, col: u32, key: String, value: String) -> Promise {
let key: Vec<u8> = data_encoding::BASE64URL_NOPAD
.decode(key.as_bytes())
.unwrap();
let value: Vec<u8> = data_encoding::BASE64URL_NOPAD
.decode(value.as_bytes())
.unwrap();
wrap_api_future(async move {
let table_db = {
let table_dbs = (*TABLE_DBS).borrow();
let Some(table_db) = table_dbs.get(&id) else {
return APIResult::Err(veilid_core::VeilidAPIError::invalid_argument("table_db_store", "id", id));
};
table_db.clone()
};
table_db
.store(col, &key, &value)
.await
.map_err(veilid_core::VeilidAPIError::generic)?;
APIRESULT_UNDEFINED
})
}
#[wasm_bindgen()]
pub fn table_db_load(id: u32, col: u32, key: String) -> Promise {
let key: Vec<u8> = data_encoding::BASE64URL_NOPAD
.decode(key.as_bytes())
.unwrap();
wrap_api_future(async move {
let table_db = {
let table_dbs = (*TABLE_DBS).borrow();
let Some(table_db) = table_dbs.get(&id) else {
return APIResult::Err(veilid_core::VeilidAPIError::invalid_argument("table_db_load", "id", id));
};
table_db.clone()
};
let out = table_db
.load(col, &key)
.map_err(veilid_core::VeilidAPIError::generic)?;
let out = out.map(|x| data_encoding::BASE64URL_NOPAD.encode(&x));
APIResult::Ok(out)
})
}
#[wasm_bindgen()]
pub fn table_db_delete(id: u32, col: u32, key: String) -> Promise {
let key: Vec<u8> = data_encoding::BASE64URL_NOPAD
.decode(key.as_bytes())
.unwrap();
wrap_api_future(async move {
let table_db = {
let table_dbs = (*TABLE_DBS).borrow();
let Some(table_db) = table_dbs.get(&id) else {
return APIResult::Err(veilid_core::VeilidAPIError::invalid_argument("table_db_delete", "id", id));
};
table_db.clone()
};
let out = table_db
.delete(col, &key)
.await
.map_err(veilid_core::VeilidAPIError::generic)?;
APIResult::Ok(out)
})
}
#[wasm_bindgen()]
pub fn debug(command: String) -> Promise {
wrap_api_future(async move {