mirror of
https://github.com/samsonjs/vibetunnel.git
synced 2026-04-27 15:17:38 +00:00
- Fix session count display to show on single line in menu bar - Add conditional compilation to disable automatic updates in DEBUG mode - Add "Open Dashboard" menu item that opens internal server URL - Convert Help menu from popover to native macOS submenu style - Enable automatic update downloads in Sparkle configuration - Increase Advanced Settings tab height from 400 to 500 pixels - Add Tailscale recommendation with clickable markdown link - Fix Sendable protocol conformance issues throughout codebase - Add ApplicationMover utility for app installation location management These changes improve the overall user experience by making the UI more intuitive and ensuring automatic updates work correctly in production while being disabled during development.
73 lines
2 KiB
Swift
73 lines
2 KiB
Swift
import Foundation
|
|
import Observation
|
|
|
|
/// Monitors the HTTP server status and provides observable state for the UI
|
|
@MainActor
|
|
@Observable
|
|
public final class ServerMonitor {
|
|
public static let shared = ServerMonitor()
|
|
|
|
// Observable properties
|
|
public private(set) var isRunning = false
|
|
public private(set) var port: Int = 4_020
|
|
public private(set) var lastError: Error?
|
|
|
|
/// Reference to the actual server
|
|
private weak var server: TunnelServer?
|
|
|
|
private init() {}
|
|
|
|
/// Updates the monitor with the current server instance
|
|
public func setServer(_ server: TunnelServer?) {
|
|
self.server = server
|
|
updateStatus()
|
|
}
|
|
|
|
/// Updates the current status from the server
|
|
public func updateStatus() {
|
|
guard let server else {
|
|
isRunning = false
|
|
return
|
|
}
|
|
|
|
isRunning = server.isRunning
|
|
port = server.port
|
|
lastError = server.lastError
|
|
}
|
|
|
|
/// Starts the server if not already running
|
|
public func startServer() async throws {
|
|
guard let server else {
|
|
throw ServerError.failedToStart("No server instance available")
|
|
}
|
|
|
|
try await server.start()
|
|
updateStatus()
|
|
}
|
|
|
|
/// Stops the server if running
|
|
public func stopServer() async throws {
|
|
guard let server else { return }
|
|
|
|
try await server.stop()
|
|
updateStatus()
|
|
}
|
|
|
|
/// Checks if the server is healthy by making a health check request
|
|
public func checkHealth() async -> Bool {
|
|
guard isRunning else { return false }
|
|
|
|
do {
|
|
let url = URL(string: "http://127.0.0.1:\(port)/health")!
|
|
let request = URLRequest(url: url, timeoutInterval: 2.0)
|
|
let (_, response) = try await URLSession.shared.data(for: request)
|
|
|
|
if let httpResponse = response as? HTTPURLResponse {
|
|
return httpResponse.statusCode == 200
|
|
}
|
|
} catch {
|
|
// Server not responding
|
|
}
|
|
return false
|
|
}
|
|
}
|