mirror of
https://gitlab.com/veilid/veilidchat.git
synced 2025-05-06 08:15:26 -04:00
better dht record class
This commit is contained in:
parent
90fc2e5f85
commit
bf813d7d0f
7 changed files with 300 additions and 132 deletions
109
lib/tools/dht_record.dart
Normal file
109
lib/tools/dht_record.dart
Normal file
|
@ -0,0 +1,109 @@
|
|||
import 'package:veilid/veilid.dart';
|
||||
import 'dart:typed_data';
|
||||
import 'tools.dart';
|
||||
|
||||
class DHTRecord {
|
||||
final VeilidRoutingContext _dhtctx;
|
||||
final DHTRecordDescriptor _recordDescriptor;
|
||||
final int _defaultSubkey;
|
||||
|
||||
static Future<DHTRecord> create(VeilidRoutingContext dhtctx,
|
||||
{DHTSchema schema = const DHTSchema.dflt(oCnt: 1),
|
||||
int defaultSubkey = 0}) async {
|
||||
DHTRecordDescriptor recordDescriptor = await dhtctx.createDHTRecord(schema);
|
||||
return DHTRecord(
|
||||
dhtctx: dhtctx,
|
||||
recordDescriptor: recordDescriptor,
|
||||
defaultSubkey: defaultSubkey);
|
||||
}
|
||||
|
||||
static Future<DHTRecord> open(
|
||||
VeilidRoutingContext dhtctx, TypedKey recordKey, KeyPair? writer,
|
||||
{int defaultSubkey = 0}) async {
|
||||
DHTRecordDescriptor recordDescriptor =
|
||||
await dhtctx.openDHTRecord(recordKey, writer);
|
||||
return DHTRecord(
|
||||
dhtctx: dhtctx,
|
||||
recordDescriptor: recordDescriptor,
|
||||
defaultSubkey: defaultSubkey);
|
||||
}
|
||||
|
||||
DHTRecord(
|
||||
{required VeilidRoutingContext dhtctx,
|
||||
required DHTRecordDescriptor recordDescriptor,
|
||||
int defaultSubkey = 0})
|
||||
: _dhtctx = dhtctx,
|
||||
_recordDescriptor = recordDescriptor,
|
||||
_defaultSubkey = defaultSubkey;
|
||||
|
||||
int _subkey(int subkey) => (subkey == -1) ? _defaultSubkey : subkey;
|
||||
|
||||
Future<Uint8List?> get({int subkey = -1, bool forceRefresh = false}) async {
|
||||
ValueData? valueData = await _dhtctx.getDHTValue(
|
||||
_recordDescriptor.key, _subkey(subkey), false);
|
||||
if (valueData == null) {
|
||||
return null;
|
||||
}
|
||||
return valueData.data;
|
||||
}
|
||||
|
||||
Future<T?> getJson<T>(T Function(Map<String, dynamic>) fromJson,
|
||||
{int subkey = -1, bool forceRefresh = false}) async {
|
||||
ValueData? valueData = await _dhtctx.getDHTValue(
|
||||
_recordDescriptor.key, _subkey(subkey), false);
|
||||
if (valueData == null) {
|
||||
return null;
|
||||
}
|
||||
return valueData.readJsonData(fromJson);
|
||||
}
|
||||
|
||||
Future<void> eventualWriteBytes(Uint8List newValue, {int subkey = -1}) async {
|
||||
// Get existing identity key
|
||||
ValueData? valueData;
|
||||
do {
|
||||
// Ensure it exists already
|
||||
if (valueData == null) {
|
||||
throw const FormatException("value does not exist");
|
||||
}
|
||||
|
||||
// Set the new data
|
||||
valueData = await _dhtctx.setDHTValue(
|
||||
_recordDescriptor.key, _subkey(subkey), newValue);
|
||||
|
||||
// Repeat if newer data on the network was found
|
||||
} while (valueData != null);
|
||||
}
|
||||
|
||||
Future<void> eventualUpdateBytes(
|
||||
Future<Uint8List> Function(Uint8List oldValue) update,
|
||||
{int subkey = -1}) async {
|
||||
// Get existing identity key
|
||||
ValueData? valueData = await _dhtctx.getDHTValue(
|
||||
_recordDescriptor.key, _subkey(subkey), false);
|
||||
do {
|
||||
// Ensure it exists already
|
||||
if (valueData == null) {
|
||||
throw const FormatException("value does not exist");
|
||||
}
|
||||
|
||||
// Update the data
|
||||
final newData = await update(valueData.data);
|
||||
|
||||
// Set it back
|
||||
valueData = await _dhtctx.setDHTValue(
|
||||
_recordDescriptor.key, _subkey(subkey), newData);
|
||||
|
||||
// Repeat if newer data on the network was found
|
||||
} while (valueData != null);
|
||||
}
|
||||
|
||||
Future<void> eventualWriteJson<T>(T newValue, {int subkey = -1}) {
|
||||
return eventualWriteBytes(jsonEncodeBytes(newValue), subkey: subkey);
|
||||
}
|
||||
|
||||
Future<void> eventualUpdateJson<T>(
|
||||
T Function(Map<String, dynamic>) fromJson, Future<T> Function(T) update,
|
||||
{int subkey = -1}) {
|
||||
return eventualUpdateBytes(jsonUpdate(fromJson, update), subkey: subkey);
|
||||
}
|
||||
}
|
30
lib/tools/json_tools.dart
Normal file
30
lib/tools/json_tools.dart
Normal file
|
@ -0,0 +1,30 @@
|
|||
// import 'package:fast_immutable_collections/fast_immutable_collections.dart';
|
||||
import 'package:veilid/veilid.dart';
|
||||
import 'dart:typed_data';
|
||||
import 'dart:convert';
|
||||
|
||||
extension FromValueDataJsonExt on ValueData {
|
||||
T readJsonData<T>(T Function(Map<String, dynamic>) fromJson) {
|
||||
return fromJson(jsonDecode(utf8.decode(data)));
|
||||
}
|
||||
}
|
||||
|
||||
Uint8List jsonEncodeBytes(Object? object,
|
||||
{Object? Function(Object?)? toEncodable}) {
|
||||
return Uint8List.fromList(
|
||||
utf8.encode(jsonEncode(object, toEncodable: toEncodable)));
|
||||
}
|
||||
|
||||
Future<Uint8List> jsonUpdateBytes<T>(T Function(Map<String, dynamic>) fromJson,
|
||||
Uint8List oldBytes, Future<T> Function(T) update) async {
|
||||
T oldObj = fromJson(jsonDecode(utf8.decode(oldBytes)));
|
||||
T newObj = await update(oldObj);
|
||||
return jsonEncodeBytes(newObj);
|
||||
}
|
||||
|
||||
Future<Uint8List> Function(Uint8List) jsonUpdate<T>(
|
||||
T Function(Map<String, dynamic>) fromJson, Future<T> Function(T) update) {
|
||||
return (Uint8List oldBytes) {
|
||||
return jsonUpdateBytes(fromJson, oldBytes, update);
|
||||
};
|
||||
}
|
|
@ -1,9 +1,4 @@
|
|||
export 'external_stream_state.dart';
|
||||
import 'package:veilid/veilid.dart';
|
||||
import 'dart:convert';
|
||||
|
||||
extension FromValueDataJsonExt on ValueData {
|
||||
T readJsonData<T>(T Function(Map<String, dynamic>) fromJson) {
|
||||
return fromJson(jsonDecode(utf8.decode(data)));
|
||||
}
|
||||
}
|
||||
export 'dht_record.dart';
|
||||
export 'json_tools.dart';
|
||||
export 'phono_byte.dart';
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue