import 'dart:typed_data'; import '../about/external/data/Docker.dart'; import '../about/external/data/Health.dart'; import '../about/external/data/Kafka.dart'; import '../about/external/data/Redis.dart'; import '../about/internal/application/DeploymentRecord.dart'; import '../about/internal/application/ServerProfile.dart'; import '../about/internal/application/ServiceConfig.dart'; import '../about/internal/application/StepTracker.dart'; import '../about/internal/file/BuildService.dart'; import '../about/internal/file/ConnectFileStorage.dart'; import '../comms/Comms.dart'; import '../comms/ConnectComms.dart'; import '../memory/ConnectInternalMemory.dart'; import 'DataManager.dart'; /// The single concrete [DataManager], constructed once in `ParentViewModel` and /// shared by every screen. It holds no logic — it only forwards each call to /// whichever of the three collaborators owns it. class AppDataManager implements DataManager { final ConnectInternalMemory memory; final ConnectComms comms; final ConnectFileStorage files; AppDataManager(this.memory, this.comms, this.files); // ── memory ──────────────────────────────────────────────────────────────── @override Future> getServers() => memory.getServers(); @override Future setServers(List servers) => memory.setServers(servers); @override Future deleteServerSecret(String serverId) => memory.deleteServerSecret(serverId); @override Future> getDeployments() => memory.getDeployments(); @override Future> addDeployment(DeploymentRecord record) => memory.addDeployment(record); @override Future clearDeployments() => memory.clearDeployments(); @override Future getThemeMode() => memory.getThemeMode(); @override Future setThemeMode(String mode) => memory.setThemeMode(mode); // ── comms: session ──────────────────────────────────────────────────────── @override bool get isConnected => comms.isConnected; @override bool get canRevert => comms.canRevert; @override Stream get logs => comms.logs; @override Stream get transferProgress => comms.transferProgress; @override Stream> get stepStream => comms.stepStream; @override Future connect(ServerProfile s) => comms.connect(s); @override void requestCancel() => comms.requestCancel(); @override void disconnect() => comms.disconnect(); @override void dispose() => comms.dispose(); // ── comms: deployment ───────────────────────────────────────────────────── @override Future deploy({ required ServerProfile server, required ServiceConfig service, required Uint8List jarBytes, required String jarLabel, }) => comms.deploy( server: server, service: service, jarBytes: jarBytes, jarLabel: jarLabel, ); @override Future deployWeb({ required ServerProfile server, required ServiceConfig service, required Uint8List archiveBytes, required int fileCount, }) => comms.deployWeb( server: server, service: service, archiveBytes: archiveBytes, fileCount: fileCount, ); @override Future restartOnly( ServerProfile server, ServiceConfig service, ) => comms.restartOnly(server, service); @override Future revert() => comms.revert(); @override Future discardBackup() => comms.discardBackup(); // ── comms: provisioning ─────────────────────────────────────────────────── @override Future installSystemdUnit({ required ServerProfile server, required String unitName, required String unitContent, bool enable = true, bool startNow = true, }) => comms.installSystemdUnit( server: server, unitName: unitName, unitContent: unitContent, enable: enable, startNow: startNow, ); @override Future detectPackageManager(ServerProfile server) => comms.detectPackageManager(server); @override Future> probeEnvironment( ServerProfile server, List detectByKey, ) => comms.probeEnvironment(server, detectByKey); @override Future installEnvironment({ required ServerProfile server, required String command, required List units, }) => comms.installEnvironment(server: server, command: command, units: units); @override Future installPackages({ required ServerProfile server, required String command, String? enableUnit, }) => comms.installPackages( server: server, command: command, enableUnit: enableUnit, ); // ── comms: service & health ─────────────────────────────────────────────── @override Future checkHealth( ServerProfile server, ServiceConfig service, ) => comms.checkHealth(server, service); @override Future serviceStatus(ServerProfile server, ServiceConfig service) => comms.serviceStatus(server, service); @override Future serviceControl( ServerProfile server, ServiceConfig service, String action, ) => comms.serviceControl(server, service, action); @override Future> nginxRoots(ServerProfile server) => comms.nginxRoots(server); // ── comms: logs ─────────────────────────────────────────────────────────── @override Future fetchLogs( ServerProfile server, ServiceConfig service, { DateTime? since, DateTime? until, }) => comms.fetchLogs(server, service, since: since, until: until); @override Future followLogs(ServerProfile server, ServiceConfig service) => comms.followLogs(server, service); @override void stopLogs() => comms.stopLogs(); // ── comms: redis ────────────────────────────────────────────────────────── @override Future<(bool, String)> redisPing( ServerProfile server, { String host = '127.0.0.1', int port = 6379, String pass = '', int db = 0, }) => comms.redisPing(server, host: host, port: port, pass: pass, db: db); @override Future redisConfigPassword(ServerProfile server) => comms.redisConfigPassword(server); @override Future redisDbSize( ServerProfile server, { String host = '127.0.0.1', int port = 6379, String pass = '', int db = 0, }) => comms.redisDbSize(server, host: host, port: port, pass: pass, db: db); @override Future<(int, Map)> redisDatabases( ServerProfile server, { String host = '127.0.0.1', int port = 6379, String pass = '', }) => comms.redisDatabases(server, host: host, port: port, pass: pass); @override Future> redisKeysTyped( ServerProfile server, { String pattern = '*', String filterType = '', int limit = 50000, String host = '127.0.0.1', int port = 6379, String pass = '', int db = 0, }) => comms.redisKeysTyped( server, pattern: pattern, filterType: filterType, limit: limit, host: host, port: port, pass: pass, db: db, ); @override Future> redisKeys( ServerProfile server, { String pattern = '*', int limit = 100000, String host = '127.0.0.1', int port = 6379, String pass = '', int db = 0, }) => comms.redisKeys( server, pattern: pattern, limit: limit, host: host, port: port, pass: pass, db: db, ); @override Future redisGet( ServerProfile server, String key, { String host = '127.0.0.1', int port = 6379, String pass = '', int db = 0, }) => comms.redisGet(server, key, host: host, port: port, pass: pass, db: db); // ── comms: docker ───────────────────────────────────────────────────────── @override Future dockerStatus(ServerProfile server) => comms.dockerStatus(server); @override Future> dockerPs( ServerProfile server, { bool all = true, }) => comms.dockerPs(server, all: all); @override Future dockerAction(ServerProfile server, String id, String action) => comms.dockerAction(server, id, action); @override Future dockerLogs( ServerProfile server, String id, { int tail = 300, }) => comms.dockerLogs(server, id, tail: tail); @override Future dockerTest(ServerProfile server) => comms.dockerTest(server); @override Future<(bool, String)> dockerRun(ServerProfile server, DockerRunSpec spec) => comms.dockerRun(server, spec); // ── comms: kafka ────────────────────────────────────────────────────────── @override Future kafkaDetect(ServerProfile server) => comms.kafkaDetect(server); @override Future kafkaTest( ServerProfile server, { required String binDir, required String suffix, required String bootstrap, }) => comms.kafkaTest( server, binDir: binDir, suffix: suffix, bootstrap: bootstrap, ); @override Future> kafkaTopics( ServerProfile server, { required String binDir, required String suffix, required String bootstrap, bool includeInternal = false, }) => comms.kafkaTopics( server, binDir: binDir, suffix: suffix, bootstrap: bootstrap, includeInternal: includeInternal, ); @override Future> kafkaGroups( ServerProfile server, { required String binDir, required String suffix, required String bootstrap, }) => comms.kafkaGroups( server, binDir: binDir, suffix: suffix, bootstrap: bootstrap, ); @override Future kafkaCluster( ServerProfile server, { required String binDir, required String suffix, required String bootstrap, }) => comms.kafkaCluster( server, binDir: binDir, suffix: suffix, bootstrap: bootstrap, ); // ── comms: remote filesystem ────────────────────────────────────────────── @override Future> listDir(ServerProfile server, String path) => comms.listDir(server, path); @override Future resolveHome(ServerProfile server) => comms.resolveHome(server); @override Future uploadFile( ServerProfile server, Uint8List bytes, String remotePath, ) => comms.uploadFile(server, bytes, remotePath); @override Future downloadFile(ServerProfile server, String remotePath) => comms.downloadFile(server, remotePath); @override Future deleteRemote( ServerProfile server, String remotePath, bool isDir, ) => comms.deleteRemote(server, remotePath, isDir); // ── files ───────────────────────────────────────────────────────────────── @override bool get buildSupported => files.buildSupported; @override Stream get buildLogs => files.buildLogs; @override Stream> get buildStepStream => files.buildStepStream; @override Future build(ServiceConfig service) => files.build(service); @override Future buildWeb(ServiceConfig service) => files.buildWeb(service); @override void cancelBuild() => files.cancelBuild(); @override Future readArtifact(String path) => files.readArtifact(path); @override Future artifactExists(String path) => files.artifactExists(path); @override Future<(Uint8List, int)> packageWeb(String directoryPath) => files.packageWeb(directoryPath); }