Merge nucleic/warm-north-vole-pf37 into dev
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
namespace NucleicApp.Services;
|
||||
|
||||
public enum OnboardingPhase
|
||||
{
|
||||
Idle,
|
||||
StartingHost,
|
||||
Connecting,
|
||||
Ready,
|
||||
Failed,
|
||||
}
|
||||
|
||||
/// First-run coordinator for the item-11 core. Component installation and OAuth screens plug
|
||||
/// into the same phase surface once their host intents land; host launch + authenticated local
|
||||
/// sync are real today.
|
||||
public sealed class OnboardingService
|
||||
{
|
||||
private readonly HostdLauncher launcher;
|
||||
private readonly HostConnection connection;
|
||||
|
||||
public OnboardingPhase Phase { get; private set; } = OnboardingPhase.Idle;
|
||||
public string? Failure { get; private set; }
|
||||
public event Action<OnboardingPhase>? PhaseChanged;
|
||||
|
||||
public OnboardingService(HostdLauncher launcher, HostConnection connection)
|
||||
{
|
||||
this.launcher = launcher;
|
||||
this.connection = connection;
|
||||
}
|
||||
|
||||
public async Task StartAsync(string rendezvousPath, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
SetPhase(OnboardingPhase.StartingHost);
|
||||
_ = await launcher.EnsureRunningAsync(cancellationToken).ConfigureAwait(false);
|
||||
SetPhase(OnboardingPhase.Connecting);
|
||||
|
||||
var ready = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
void Changed(HostConnectionState state)
|
||||
{
|
||||
if (state == HostConnectionState.Connected) ready.TrySetResult();
|
||||
else if (state == HostConnectionState.Failed)
|
||||
ready.TrySetException(new InvalidOperationException(
|
||||
connection.LastProtocolState?.Message ?? "local host connection failed"));
|
||||
}
|
||||
connection.StateChanged += Changed;
|
||||
try
|
||||
{
|
||||
await connection.StartLocalAsync(rendezvousPath, cancellationToken).ConfigureAwait(false);
|
||||
await ready.Task.WaitAsync(TimeSpan.FromSeconds(30), cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
finally { connection.StateChanged -= Changed; }
|
||||
SetPhase(OnboardingPhase.Ready);
|
||||
}
|
||||
catch (Exception error)
|
||||
{
|
||||
Failure = error.Message;
|
||||
SetPhase(OnboardingPhase.Failed);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetPhase(OnboardingPhase phase)
|
||||
{
|
||||
if (Phase == phase) return;
|
||||
Phase = phase;
|
||||
PhaseChanged?.Invoke(phase);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user