mirror of
https://gitlab.com/veilid/veilidchat.git
synced 2024-12-25 15:49:28 -05:00
better logging
This commit is contained in:
parent
f896fc822c
commit
2cf1c5f4e9
@ -178,7 +178,9 @@ class AccountRepository {
|
|||||||
/// Creates a new master identity, an account associated with the master
|
/// Creates a new master identity, an account associated with the master
|
||||||
/// identity, stores the account in the identity key and then logs into
|
/// identity, stores the account in the identity key and then logs into
|
||||||
/// that account with no password set at this time
|
/// that account with no password set at this time
|
||||||
Future<void> createMasterIdentity(NewProfileSpec newProfileSpec) async {
|
Future<void> createWithNewMasterIdentity(
|
||||||
|
NewProfileSpec newProfileSpec) async {
|
||||||
|
log.debug('Creating master identity');
|
||||||
final imws = await IdentityMasterWithSecrets.create();
|
final imws = await IdentityMasterWithSecrets.create();
|
||||||
try {
|
try {
|
||||||
final localAccount = await _newLocalAccount(
|
final localAccount = await _newLocalAccount(
|
||||||
@ -204,6 +206,8 @@ class AccountRepository {
|
|||||||
required NewProfileSpec newProfileSpec,
|
required NewProfileSpec newProfileSpec,
|
||||||
EncryptionKeyType encryptionKeyType = EncryptionKeyType.none,
|
EncryptionKeyType encryptionKeyType = EncryptionKeyType.none,
|
||||||
String encryptionKey = ''}) async {
|
String encryptionKey = ''}) async {
|
||||||
|
log.debug('Creating new local account');
|
||||||
|
|
||||||
final localAccounts = await _localAccounts.get();
|
final localAccounts = await _localAccounts.get();
|
||||||
|
|
||||||
// Add account with profile to DHT
|
// Add account with profile to DHT
|
||||||
@ -212,15 +216,18 @@ class AccountRepository {
|
|||||||
accountKey: veilidChatAccountKey,
|
accountKey: veilidChatAccountKey,
|
||||||
createAccountCallback: (parent) async {
|
createAccountCallback: (parent) async {
|
||||||
// Make empty contact list
|
// Make empty contact list
|
||||||
|
log.debug('Creating contacts list');
|
||||||
final contactList = await (await DHTShortArray.create(parent: parent))
|
final contactList = await (await DHTShortArray.create(parent: parent))
|
||||||
.scope((r) async => r.record.ownedDHTRecordPointer);
|
.scope((r) async => r.record.ownedDHTRecordPointer);
|
||||||
|
|
||||||
// Make empty contact invitation record list
|
// Make empty contact invitation record list
|
||||||
|
log.debug('Creating contact invitation records list');
|
||||||
final contactInvitationRecords =
|
final contactInvitationRecords =
|
||||||
await (await DHTShortArray.create(parent: parent))
|
await (await DHTShortArray.create(parent: parent))
|
||||||
.scope((r) async => r.record.ownedDHTRecordPointer);
|
.scope((r) async => r.record.ownedDHTRecordPointer);
|
||||||
|
|
||||||
// Make empty chat record list
|
// Make empty chat record list
|
||||||
|
log.debug('Creating chat records list');
|
||||||
final chatRecords = await (await DHTShortArray.create(parent: parent))
|
final chatRecords = await (await DHTShortArray.create(parent: parent))
|
||||||
.scope((r) async => r.record.ownedDHTRecordPointer);
|
.scope((r) async => r.record.ownedDHTRecordPointer);
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ class NewAccountPageState extends State<NewAccountPage> {
|
|||||||
NewProfileSpec(name: name, pronouns: pronouns);
|
NewProfileSpec(name: name, pronouns: pronouns);
|
||||||
|
|
||||||
await AccountRepository.instance
|
await AccountRepository.instance
|
||||||
.createMasterIdentity(newProfileSpec);
|
.createWithNewMasterIdentity(newProfileSpec);
|
||||||
} on Exception catch (e) {
|
} on Exception catch (e) {
|
||||||
if (context.mounted) {
|
if (context.mounted) {
|
||||||
await showErrorModal(context, translate('new_account_page.error'),
|
await showErrorModal(context, translate('new_account_page.error'),
|
||||||
|
@ -25,29 +25,20 @@ class MessagesCubit extends Cubit<AsyncValue<IList<proto.Message>>> {
|
|||||||
required TypedKey remoteConversationRecordKey,
|
required TypedKey remoteConversationRecordKey,
|
||||||
required TypedKey remoteMessagesRecordKey})
|
required TypedKey remoteMessagesRecordKey})
|
||||||
: _activeAccountInfo = activeAccountInfo,
|
: _activeAccountInfo = activeAccountInfo,
|
||||||
_localMessagesRecordKey = localMessagesRecordKey,
|
|
||||||
_remoteIdentityPublicKey = remoteIdentityPublicKey,
|
_remoteIdentityPublicKey = remoteIdentityPublicKey,
|
||||||
_remoteMessagesRecordKey = remoteMessagesRecordKey,
|
|
||||||
_remoteMessagesQueue = StreamController(),
|
_remoteMessagesQueue = StreamController(),
|
||||||
super(const AsyncValue.loading()) {
|
super(const AsyncValue.loading()) {
|
||||||
// Local messages key
|
// Local messages key
|
||||||
Future.delayed(Duration.zero, () async {
|
Future.delayed(
|
||||||
final crypto = await getMessagesCrypto();
|
Duration.zero,
|
||||||
final writer = _activeAccountInfo.conversationWriter;
|
() async => _initLocalMessages(
|
||||||
final record = await DHTShortArray.openWrite(
|
localConversationRecordKey, localMessagesRecordKey));
|
||||||
_localMessagesRecordKey, writer,
|
|
||||||
parent: localConversationRecordKey, crypto: crypto);
|
|
||||||
await _setLocalMessages(record);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Remote messages key
|
// Remote messages key
|
||||||
Future.delayed(Duration.zero, () async {
|
Future.delayed(
|
||||||
// Open remote record key if it is specified
|
Duration.zero,
|
||||||
final crypto = await getMessagesCrypto();
|
() async => _initRemoteMessages(
|
||||||
final record = await DHTShortArray.openRead(_remoteMessagesRecordKey,
|
remoteConversationRecordKey, remoteMessagesRecordKey));
|
||||||
parent: remoteConversationRecordKey, crypto: crypto);
|
|
||||||
await _setRemoteMessages(record);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Remote messages listener
|
// Remote messages listener
|
||||||
Future.delayed(Duration.zero, () async {
|
Future.delayed(Duration.zero, () async {
|
||||||
@ -59,8 +50,11 @@ class MessagesCubit extends Cubit<AsyncValue<IList<proto.Message>>> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> close() async {
|
Future<void> close() async {
|
||||||
|
await _remoteMessagesQueue.close();
|
||||||
await _localSubscription?.cancel();
|
await _localSubscription?.cancel();
|
||||||
await _remoteSubscription?.cancel();
|
await _remoteSubscription?.cancel();
|
||||||
|
await _localMessagesCubit?.close();
|
||||||
|
await _remoteMessagesCubit?.close();
|
||||||
await super.close();
|
await super.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,20 +123,29 @@ class MessagesCubit extends Cubit<AsyncValue<IList<proto.Message>>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Open local messages key
|
// Open local messages key
|
||||||
Future<void> _setLocalMessages(DHTShortArray localMessagesRecord) async {
|
Future<void> _initLocalMessages(TypedKey localConversationRecordKey,
|
||||||
assert(_localMessagesCubit == null, 'shoud not set local messages twice');
|
TypedKey localMessagesRecordKey) async {
|
||||||
_localMessagesCubit = DHTShortArrayCubit.value(
|
final crypto = await getMessagesCrypto();
|
||||||
shortArray: localMessagesRecord,
|
final writer = _activeAccountInfo.conversationWriter;
|
||||||
|
|
||||||
|
_localMessagesCubit = DHTShortArrayCubit(
|
||||||
|
open: () async => DHTShortArray.openWrite(
|
||||||
|
localMessagesRecordKey, writer,
|
||||||
|
parent: localConversationRecordKey, crypto: crypto),
|
||||||
decodeElement: proto.Message.fromBuffer);
|
decodeElement: proto.Message.fromBuffer);
|
||||||
_localSubscription =
|
_localSubscription =
|
||||||
_localMessagesCubit!.stream.listen(updateLocalMessagesState);
|
_localMessagesCubit!.stream.listen(updateLocalMessagesState);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open remote messages key
|
// Open remote messages key
|
||||||
Future<void> _setRemoteMessages(DHTShortArray remoteMessagesRecord) async {
|
Future<void> _initRemoteMessages(TypedKey remoteConversationRecordKey,
|
||||||
assert(_remoteMessagesCubit == null, 'shoud not set remote messages twice');
|
TypedKey remoteMessagesRecordKey) async {
|
||||||
_remoteMessagesCubit = DHTShortArrayCubit.value(
|
// Open remote record key if it is specified
|
||||||
shortArray: remoteMessagesRecord,
|
final crypto = await getMessagesCrypto();
|
||||||
|
|
||||||
|
_remoteMessagesCubit = DHTShortArrayCubit(
|
||||||
|
open: () async => DHTShortArray.openRead(remoteMessagesRecordKey,
|
||||||
|
parent: remoteConversationRecordKey, crypto: crypto),
|
||||||
decodeElement: proto.Message.fromBuffer);
|
decodeElement: proto.Message.fromBuffer);
|
||||||
_remoteSubscription =
|
_remoteSubscription =
|
||||||
_remoteMessagesCubit!.stream.listen(updateRemoteMessagesState);
|
_remoteMessagesCubit!.stream.listen(updateRemoteMessagesState);
|
||||||
@ -208,8 +211,6 @@ class MessagesCubit extends Cubit<AsyncValue<IList<proto.Message>>> {
|
|||||||
|
|
||||||
final ActiveAccountInfo _activeAccountInfo;
|
final ActiveAccountInfo _activeAccountInfo;
|
||||||
final TypedKey _remoteIdentityPublicKey;
|
final TypedKey _remoteIdentityPublicKey;
|
||||||
final TypedKey _localMessagesRecordKey;
|
|
||||||
final TypedKey _remoteMessagesRecordKey;
|
|
||||||
DHTShortArrayCubit<proto.Message>? _localMessagesCubit;
|
DHTShortArrayCubit<proto.Message>? _localMessagesCubit;
|
||||||
DHTShortArrayCubit<proto.Message>? _remoteMessagesCubit;
|
DHTShortArrayCubit<proto.Message>? _remoteMessagesCubit;
|
||||||
final StreamController<_MessageQueueEntry> _remoteMessagesQueue;
|
final StreamController<_MessageQueueEntry> _remoteMessagesQueue;
|
||||||
|
@ -2,31 +2,44 @@ import 'package:veilid/veilid.dart';
|
|||||||
|
|
||||||
Map<String, dynamic> getDefaultVeilidPlatformConfig(
|
Map<String, dynamic> getDefaultVeilidPlatformConfig(
|
||||||
bool isWeb, String appName) {
|
bool isWeb, String appName) {
|
||||||
|
final ignoreLogTargetsStr =
|
||||||
|
// ignore: do_not_use_environment
|
||||||
|
const String.fromEnvironment('IGNORE_LOG_TARGETS').trim();
|
||||||
|
final ignoreLogTargets = ignoreLogTargetsStr.isEmpty
|
||||||
|
? <String>[]
|
||||||
|
: ignoreLogTargetsStr.split(',').map((e) => e.trim()).toList();
|
||||||
|
|
||||||
if (isWeb) {
|
if (isWeb) {
|
||||||
return const VeilidWASMConfig(
|
return VeilidWASMConfig(
|
||||||
logging: VeilidWASMConfigLogging(
|
logging: VeilidWASMConfigLogging(
|
||||||
performance: VeilidWASMConfigLoggingPerformance(
|
performance: VeilidWASMConfigLoggingPerformance(
|
||||||
enabled: true,
|
enabled: true,
|
||||||
level: VeilidConfigLogLevel.debug,
|
level: VeilidConfigLogLevel.debug,
|
||||||
logsInTimings: true,
|
logsInTimings: true,
|
||||||
logsInConsole: false),
|
logsInConsole: false,
|
||||||
|
ignoreLogTargets: ignoreLogTargets),
|
||||||
api: VeilidWASMConfigLoggingApi(
|
api: VeilidWASMConfigLoggingApi(
|
||||||
enabled: true, level: VeilidConfigLogLevel.info)))
|
enabled: true,
|
||||||
|
level: VeilidConfigLogLevel.info,
|
||||||
|
ignoreLogTargets: ignoreLogTargets)))
|
||||||
.toJson();
|
.toJson();
|
||||||
}
|
}
|
||||||
return VeilidFFIConfig(
|
return VeilidFFIConfig(
|
||||||
logging: VeilidFFIConfigLogging(
|
logging: VeilidFFIConfigLogging(
|
||||||
terminal: const VeilidFFIConfigLoggingTerminal(
|
terminal: VeilidFFIConfigLoggingTerminal(
|
||||||
enabled: false,
|
enabled: false,
|
||||||
level: VeilidConfigLogLevel.debug,
|
level: VeilidConfigLogLevel.debug,
|
||||||
),
|
ignoreLogTargets: ignoreLogTargets),
|
||||||
otlp: VeilidFFIConfigLoggingOtlp(
|
otlp: VeilidFFIConfigLoggingOtlp(
|
||||||
enabled: false,
|
enabled: false,
|
||||||
level: VeilidConfigLogLevel.trace,
|
level: VeilidConfigLogLevel.trace,
|
||||||
grpcEndpoint: '127.0.0.1:4317',
|
grpcEndpoint: '127.0.0.1:4317',
|
||||||
serviceName: appName),
|
serviceName: appName,
|
||||||
api: const VeilidFFIConfigLoggingApi(
|
ignoreLogTargets: ignoreLogTargets),
|
||||||
enabled: true, level: VeilidConfigLogLevel.info)))
|
api: VeilidFFIConfigLoggingApi(
|
||||||
|
enabled: true,
|
||||||
|
level: VeilidConfigLogLevel.info,
|
||||||
|
ignoreLogTargets: ignoreLogTargets)))
|
||||||
.toJson();
|
.toJson();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,9 +3,9 @@ import 'dart:typed_data';
|
|||||||
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
|
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
import 'package:protobuf/protobuf.dart';
|
import 'package:protobuf/protobuf.dart';
|
||||||
import 'package:veilid/veilid.dart';
|
|
||||||
|
|
||||||
import '../dht_support/dht_support.dart';
|
import '../veilid_support.dart';
|
||||||
|
import 'veilid_log.dart';
|
||||||
|
|
||||||
part 'identity.freezed.dart';
|
part 'identity.freezed.dart';
|
||||||
part 'identity.g.dart';
|
part 'identity.g.dart';
|
||||||
@ -161,42 +161,44 @@ extension IdentityMasterExtension on IdentityMaster {
|
|||||||
/////// Add account with profile to DHT
|
/////// Add account with profile to DHT
|
||||||
|
|
||||||
// Open identity key for writing
|
// Open identity key for writing
|
||||||
|
veilidLoggy.debug('Opening master identity');
|
||||||
return (await pool.openWrite(
|
return (await pool.openWrite(
|
||||||
identityRecordKey, identityWriter(identitySecret),
|
identityRecordKey, identityWriter(identitySecret),
|
||||||
parent: masterRecordKey))
|
parent: masterRecordKey))
|
||||||
.scope((identityRec) async =>
|
.scope((identityRec) async {
|
||||||
// Create new account to insert into identity
|
// Create new account to insert into identity
|
||||||
(await pool.create(parent: identityRec.key))
|
veilidLoggy.debug('Creating new account');
|
||||||
|
return (await pool.create(parent: identityRec.key))
|
||||||
.deleteScope((accountRec) async {
|
.deleteScope((accountRec) async {
|
||||||
final account = await createAccountCallback(accountRec.key);
|
final account = await createAccountCallback(accountRec.key);
|
||||||
// Write account key
|
// Write account key
|
||||||
|
veilidLoggy.debug('Writing account record');
|
||||||
await accountRec.eventualWriteProtobuf(account);
|
await accountRec.eventualWriteProtobuf(account);
|
||||||
|
|
||||||
// Update identity key to include account
|
// Update identity key to include account
|
||||||
final newAccountRecordInfo = AccountRecordInfo(
|
final newAccountRecordInfo = AccountRecordInfo(
|
||||||
accountRecord: OwnedDHTRecordPointer(
|
accountRecord: OwnedDHTRecordPointer(
|
||||||
recordKey: accountRec.key,
|
recordKey: accountRec.key, owner: accountRec.ownerKeyPair!));
|
||||||
owner: accountRec.ownerKeyPair!));
|
|
||||||
|
|
||||||
|
veilidLoggy.debug('Updating identity with new account');
|
||||||
await identityRec.eventualUpdateJson(Identity.fromJson,
|
await identityRec.eventualUpdateJson(Identity.fromJson,
|
||||||
(oldIdentity) async {
|
(oldIdentity) async {
|
||||||
if (oldIdentity == null) {
|
if (oldIdentity == null) {
|
||||||
throw IdentityException.readError;
|
throw IdentityException.readError;
|
||||||
}
|
}
|
||||||
final oldAccountRecords =
|
final oldAccountRecords = IMapOfSets.from(oldIdentity.accountRecords);
|
||||||
IMapOfSets.from(oldIdentity.accountRecords);
|
|
||||||
|
|
||||||
if (oldAccountRecords.get(accountKey).length >= maxAccounts) {
|
if (oldAccountRecords.get(accountKey).length >= maxAccounts) {
|
||||||
throw IdentityException.limitExceeded;
|
throw IdentityException.limitExceeded;
|
||||||
}
|
}
|
||||||
final accountRecords = oldAccountRecords
|
final accountRecords =
|
||||||
.add(accountKey, newAccountRecordInfo)
|
oldAccountRecords.add(accountKey, newAccountRecordInfo).asIMap();
|
||||||
.asIMap();
|
|
||||||
return oldIdentity.copyWith(accountRecords: accountRecords);
|
return oldIdentity.copyWith(accountRecords: accountRecords);
|
||||||
});
|
});
|
||||||
|
|
||||||
return newAccountRecordInfo;
|
return newAccountRecordInfo;
|
||||||
}));
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,10 +221,12 @@ class IdentityMasterWithSecrets {
|
|||||||
final pool = DHTRecordPool.instance;
|
final pool = DHTRecordPool.instance;
|
||||||
|
|
||||||
// IdentityMaster DHT record is public/unencrypted
|
// IdentityMaster DHT record is public/unencrypted
|
||||||
|
veilidLoggy.debug('Creating master identity record');
|
||||||
return (await pool.create(crypto: const DHTRecordCryptoPublic()))
|
return (await pool.create(crypto: const DHTRecordCryptoPublic()))
|
||||||
.deleteScope((masterRec) async =>
|
.deleteScope((masterRec) async {
|
||||||
|
veilidLoggy.debug('Creating identity record');
|
||||||
// Identity record is private
|
// Identity record is private
|
||||||
(await pool.create(parent: masterRec.key))
|
return (await pool.create(parent: masterRec.key))
|
||||||
.scope((identityRec) async {
|
.scope((identityRec) async {
|
||||||
// Make IdentityMaster
|
// Make IdentityMaster
|
||||||
final masterRecordKey = masterRec.key;
|
final masterRecordKey = masterRec.key;
|
||||||
@ -239,13 +243,12 @@ class IdentityMasterWithSecrets {
|
|||||||
|
|
||||||
assert(masterRecordKey.kind == identityRecordKey.kind,
|
assert(masterRecordKey.kind == identityRecordKey.kind,
|
||||||
'new master and identity should have same cryptosystem');
|
'new master and identity should have same cryptosystem');
|
||||||
final crypto =
|
final crypto = await pool.veilid.getCryptoSystem(masterRecordKey.kind);
|
||||||
await pool.veilid.getCryptoSystem(masterRecordKey.kind);
|
|
||||||
|
|
||||||
final identitySignature = await crypto.signWithKeyPair(
|
final identitySignature =
|
||||||
masterOwner, identitySigBuf.toBytes());
|
await crypto.signWithKeyPair(masterOwner, identitySigBuf.toBytes());
|
||||||
final masterSignature = await crypto.signWithKeyPair(
|
final masterSignature =
|
||||||
identityOwner, masterSigBuf.toBytes());
|
await crypto.signWithKeyPair(identityOwner, masterSigBuf.toBytes());
|
||||||
|
|
||||||
final identityMaster = IdentityMaster(
|
final identityMaster = IdentityMaster(
|
||||||
identityRecordKey: identityRecordKey,
|
identityRecordKey: identityRecordKey,
|
||||||
@ -268,7 +271,8 @@ class IdentityMasterWithSecrets {
|
|||||||
identityMaster: identityMaster,
|
identityMaster: identityMaster,
|
||||||
masterSecret: masterOwner.secret,
|
masterSecret: masterOwner.secret,
|
||||||
identitySecret: identityOwner.secret);
|
identitySecret: identityOwner.secret);
|
||||||
}));
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'package:loggy/loggy.dart';
|
import 'package:loggy/loggy.dart';
|
||||||
|
import 'package:meta/meta.dart';
|
||||||
import 'package:veilid/veilid.dart';
|
import 'package:veilid/veilid.dart';
|
||||||
|
|
||||||
// Loggy tools
|
// Loggy tools
|
||||||
@ -37,7 +38,8 @@ class VeilidLoggy implements LoggyType {
|
|||||||
Loggy<VeilidLoggy> get loggy => Loggy<VeilidLoggy>('Veilid');
|
Loggy<VeilidLoggy> get loggy => Loggy<VeilidLoggy>('Veilid');
|
||||||
}
|
}
|
||||||
|
|
||||||
Loggy get _veilidLoggy => Loggy<VeilidLoggy>('Veilid');
|
@internal
|
||||||
|
Loggy get veilidLoggy => Loggy<VeilidLoggy>('Veilid');
|
||||||
|
|
||||||
void processLog(VeilidLog log) {
|
void processLog(VeilidLog log) {
|
||||||
StackTrace? stackTrace;
|
StackTrace? stackTrace;
|
||||||
@ -50,19 +52,19 @@ void processLog(VeilidLog log) {
|
|||||||
|
|
||||||
switch (log.logLevel) {
|
switch (log.logLevel) {
|
||||||
case VeilidLogLevel.error:
|
case VeilidLogLevel.error:
|
||||||
_veilidLoggy.error(log.message, error, stackTrace);
|
veilidLoggy.error(log.message, error, stackTrace);
|
||||||
break;
|
break;
|
||||||
case VeilidLogLevel.warn:
|
case VeilidLogLevel.warn:
|
||||||
_veilidLoggy.warning(log.message, error, stackTrace);
|
veilidLoggy.warning(log.message, error, stackTrace);
|
||||||
break;
|
break;
|
||||||
case VeilidLogLevel.info:
|
case VeilidLogLevel.info:
|
||||||
_veilidLoggy.info(log.message, error, stackTrace);
|
veilidLoggy.info(log.message, error, stackTrace);
|
||||||
break;
|
break;
|
||||||
case VeilidLogLevel.debug:
|
case VeilidLogLevel.debug:
|
||||||
_veilidLoggy.debug(log.message, error, stackTrace);
|
veilidLoggy.debug(log.message, error, stackTrace);
|
||||||
break;
|
break;
|
||||||
case VeilidLogLevel.trace:
|
case VeilidLogLevel.trace:
|
||||||
_veilidLoggy.trace(log.message, error, stackTrace);
|
veilidLoggy.trace(log.message, error, stackTrace);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,4 +12,4 @@ export 'src/json_tools.dart';
|
|||||||
export 'src/memory_tools.dart';
|
export 'src/memory_tools.dart';
|
||||||
export 'src/protobuf_tools.dart';
|
export 'src/protobuf_tools.dart';
|
||||||
export 'src/table_db.dart';
|
export 'src/table_db.dart';
|
||||||
export 'src/veilid_log.dart';
|
export 'src/veilid_log.dart' hide veilidLoggy;
|
||||||
|
@ -1618,4 +1618,4 @@ packages:
|
|||||||
version: "1.1.2"
|
version: "1.1.2"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.3.0 <4.0.0"
|
dart: ">=3.3.0 <4.0.0"
|
||||||
flutter: ">=3.19.0"
|
flutter: ">=3.19.1"
|
||||||
|
@ -5,7 +5,7 @@ version: 1.0.2+0
|
|||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=3.2.0 <4.0.0'
|
sdk: '>=3.2.0 <4.0.0'
|
||||||
flutter: ">=3.10.0"
|
flutter: '>=3.19.1'
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
animated_theme_switcher: ^2.0.10
|
animated_theme_switcher: ^2.0.10
|
||||||
|
Loading…
Reference in New Issue
Block a user