Initial commit

This commit is contained in:
gasaichandesu
2025-08-30 19:47:42 +04:00
commit 58d7808a8d
100 changed files with 6186 additions and 0 deletions
@@ -0,0 +1,24 @@
sealed class DownloadException implements Exception {
final String message;
const DownloadException(this.message);
@override
String toString() => '$runtimeType: $message';
}
final class NetworkException extends DownloadException {
const NetworkException(super.message);
}
final class RemoteException extends DownloadException {
const RemoteException(super.message);
}
final class IoException extends DownloadException {
const IoException(super.message);
}
final class CancelledException extends DownloadException {
const CancelledException() : super('Cancelled');
}
@@ -0,0 +1,27 @@
/// Represents the state of a download.
final class DownloadProgress {
/// Download speed in bytes per second.
final int speed;
/// Total bytes downloaded so far.
final int downloaded;
/// Total bytes to download.
final int total;
/// Estimated time of arrival (ETA) for the download to complete.
final Duration eta;
const DownloadProgress({
required this.speed,
required this.downloaded,
required this.total,
required this.eta,
});
const DownloadProgress.initial()
: speed = 0,
downloaded = 0,
total = 0,
eta = Duration.zero;
}
@@ -0,0 +1,7 @@
/// Represents a request to download an object from a storage bucket.
class DownloadRequest {
/// Local file path to save the downloaded object
final String destinationPath;
const DownloadRequest({required this.destinationPath});
}
@@ -0,0 +1,17 @@
/// Represents the result of a download operation.
class DownloadResult {
/// Local file path where the downloaded object is stored.
final String path;
/// Number of bytes downloaded.
final int bytes;
/// Entity tag (ETag) of the downloaded object.
final String eTag;
const DownloadResult({
required this.path,
required this.bytes,
required this.eTag,
});
}
@@ -0,0 +1,10 @@
/// Represents metadata for a remote object in a storage bucket.
class RemoteObjectMeta {
/// Size of the object in bytes.
final int size;
/// Entity tag (ETag) of the object.
final String eTag;
const RemoteObjectMeta({required this.size, required this.eTag});
}
@@ -0,0 +1,29 @@
import 'dart:async';
/// Interface for interacting with the file system.
abstract interface class FileSystem {
/// Ensures that the parent directory of the given path exists.
Future<void> ensureParentExists(String path);
/// Checks if a file or directory exists at the given path.
Future<bool> exists(String path);
/// Returns the size of the file at the given path.
Future<int> sizeOf(String path);
/// Truncates the file at the given path to zero length.
Future<void> truncate(String path);
/// Creates an empty file at the given path.
Future<void> createEmpty(String path);
/// Opens a stream sink for appending data to the file at the given path.
Future<StreamSink<List<int>>> openAppend(String path);
/// Verifies the integrity of a file at the given path.
Future<bool> verifyFile(
String path, {
required String expected,
required String algo,
});
}
@@ -0,0 +1,14 @@
import 'package:moonwell_launcher/features/downloader/domain/entities/remote_object_meta.dart';
/// Interface for reading data from storage.
abstract interface class StorageReader {
/// Retrieves metadata about a remote object.
Future<RemoteObjectMeta> stat({required String bucket, required String key});
/// Reads data from a remote object starting at the specified offset.
Future<Stream<List<int>>> readFromOffset({
required String bucket,
required String key,
required int startOffset,
});
}