Repository F# setup
open System
open System.IO
open System.Threading
open System.Threading.Tasks
open Axial
open Axial.Layers
open Axial.Console
open Axial.FileSystem
open Axial.Hosting
open Axial.Hosting.Browser
open Axial.Hosting.Node
open Axial.HttpClient
open Axial.PlatformService
open Axial.Process
open Axial.State
open Axial.Telemetry
open Axial.Telemetry.JavaScriptApplication Lifecycle
App runs one root Flow as an owned application. Use it when the workflow represents the lifetime of a CLI,
desktop process, browser mount, Node process, worker, or another application rather than one request or operation.
Application code remains an ordinary Flow value. Provision its environment before handing it to App:
type AppEnv =
{ Orders: IOrderRepository
Log: ILog }
type AppError =
| ConfigurationError of string
| OrderError of string
let program : Flow<AppEnv, AppError, unit> =
flow {
let! orders = Flow.envWith _.Orders
return! orders.ProcessPending()
}
let root : Flow<StartupInputs, AppError, unit> =
program
|> Layer.provide Live.appLayerRun a Finite Application
Use App.run when the caller only needs the final outcome:
let run inputs = async {
let! exit = App.run inputs root
match exit with
| Exit.Success () -> return 0
| Exit.Failure cause ->
eprintfn "%s" (Cause.prettyPrint AppError.describe cause)
return 1
}Own a Long-Running Application
Use App.start when another module controls when the application stops:
let running = App.start inputs root
printfn "State: %A" running.Status
// Called later by a signal handler, window close event, or UI unmount:
let stop = async {
let! exit = running.Stop()
printfn "Final exit: %A" exit
}Status:Running,Stopping, orCompleted.Completion: the one finalExit, available to any number of observers.Stop(): requests cooperative interruption and waits for cleanup.
Calling Stop() several times is safe. Every caller observes the same final exit. Disposing the handle requests stop
but cannot await asynchronous finalizers; application shutdown code should await Stop() or Completion.
External Cancellation
Use App.startWithCancellation or App.runWithCancellation when an existing owner already supplies a
CancellationToken:
let running =
App.startWithCancellation hostStopping inputs rootApp and Direct Flow Execution
Flow.run, Flow.startTask, and Flow.toAsync remain the direct execution interface for individual workflows and
interop boundaries. App adds ownership around a root workflow:
| Use | Entry point |
|---|---|
| Execute one operation | workflow |> Flow.run env or workflow |> Flow.startTask env |
| Run a finite root application | App.run env application |
| Start and later stop a root application | App.start env application |
| Integrate with .NET Generic Host | Axial.Hosting |
| Run under Node signals | Node hosting |
| Tie lifetime to a browser owner | Browser hosting |
App does not render errors, choose process exit codes, or subscribe to platform lifecycle events. Those decisions
belong to the application edge or one of the platform hosting packages.

