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.PlatformService
open Axial.State
open Axial.Telemetry
open Axial.Telemetry.JavaScriptSupplying Platform Services
A host needs the standard operational services before it can run application workflows: a clock, a logger,
randomness, GUIDs, and environment variables. Axial.PlatformService bundles all five as BaseRuntime.
Use the live bundle:
Show page setup
// Setup for the checked example on this page.
open System
open Axial
open Axial.Layers
open Axial.PlatformService
/// Fails the docs test when an example's result differs from the value shown.
let shouldEqual expected actual =
if actual <> expected then failwithf "Expected %A but got %A" expected actualopen Axial
open Axial.PlatformService
AxialPlatformServicelet runtime : BaseRuntime = BaseRuntime.liveValue
runtime: BaseRuntimeAxial.PlatformService.BaseRuntimeGroups the standard operational services commonly used by workflow hosts.
Axial.PlatformService.BaseRuntimeModuleHelpers for constructing the standard explicit service bundle used by workflow hosts.
liveValue: BaseRuntimeCreates the standard live base runtime as an explicit service bundle.
BaseRuntime implements one contract per service, so any workflow requiring some combination of them
runs against this single value:
let startup : Flow<BaseRuntime, EnvironmentVariableError, int> =
flow {
let! port = EnvironmentVariable.getInt "PORT"
do! Log.info $"Listening on {port}"
return port
}
startup: Flow<BaseRuntime,EnvironmentVariableError,int>Axial.Flow`3Axial.PlatformService.BaseRuntimeGroups the standard operational services commonly used by workflow hosts.
Axial.PlatformService.EnvironmentVariableErrorintAn abbreviation for the CLI type . Basic Types
flow: FlowBuilderThe universal flow { } computation expression.
port: intAxial.PlatformService.EnvironmentVariableHelpers for reading and parsing environment variables through an explicit service.
getInt: string -> Flow<'env,EnvironmentVariableError,int>Reads an integer environment variable through an explicit service.
Axial.PlatformService.LogHelpers for the logging service.
info: string -> Flow<'env,'error,unit>Writes an informational log message through an explicit logging service.
The block does not name the service types. IHasEnvironmentVariables and IHasLog are distinct contracts, so their constraints merge.
Use BaseRuntime.live when the environment is composed from layers, and BaseRuntime.fromServiceProvider when the
host already has an IServiceProvider; that variant reports missing registrations as typed BaseRuntimeError
startup failures rather than resolution exceptions.
BaseRuntime.live is a Layer<unit, Never, BaseRuntime>, so provision it over a workflow whose environment it
satisfies. The checked run below overrides the clock with a fixed value so the year is deterministic; the layer
shape and the Layer.provide call are the same as the real BaseRuntime.live:
let currentYear : Flow<BaseRuntime, Never, int> =
Clock.now |> Flow.map _.Year
currentYear: Flow<BaseRuntime,Never,int>Axial.Flow`3Axial.PlatformService.BaseRuntimeGroups the standard operational services commonly used by workflow hosts.
Axial.NeverRepresents an error channel that cannot occur.
intAn abbreviation for the CLI type . Basic Types
Axial.PlatformService.ClockHelpers for the clock service.
now: Flow<'env,'error,DateTimeOffset>Reads the current UTC timestamp from an explicit clock service.
(|>): 'T1 -> ('T1 -> 'U) -> 'UApply a function to a value, the value being on the left, the function on the right The argument. The function. The function result. let doubleIt x = x * 2 3 |> doubleIt // Evaluates to 6
Axial.Flowmap: ('value -> 'next) -> Flow<'env,'error,'value> -> Flow<'env,'error,'next>Transforms the successful value of a flow. If the source fails, the is not executed. The original failure cause is preserved, including typed failures, interruption, and defects. Use map for pure value transformations after an effect has succeeded. A function of type 'value -> 'next to transform the successful value. The source flow of type to transform. A new with the transformed success value of type 'next. let flow = Flow.succeed 1 |> Flow.map (fun x -> x + 1)
_arg1: DateTimeOffsetYear: intGets the year component of the date represented by the current object. The year component of the current object, expressed as an integer value between 0 and 9999.
let fixedRuntime =
{ BaseRuntime.liveValue with Clock = Clock.fromValue (DateTimeOffset(2026, 1, 1, 0, 0, 0, TimeSpan.Zero)) }
currentYear |> Layer.provide (Layer.succeed fixedRuntime) |> Flow.run () |> function
| Exit.Success year -> shouldEqual 2026 year
| other -> failwithf "Expected a year, got %A" other
fixedRuntime: BaseRuntimeAxial.PlatformService.BaseRuntimeGroups the standard operational services commonly used by workflow hosts.
Axial.PlatformService.BaseRuntimeModuleHelpers for constructing the standard explicit service bundle used by workflow hosts.
liveValue: BaseRuntimeCreates the standard live base runtime as an explicit service bundle.
Clock: IClockcurrentYear: Flow<BaseRuntime,Never,int>(|>): 'T1 -> ('T1 -> 'U) -> 'UApply a function to a value, the value being on the left, the function on the right The argument. The function. The function result. let doubleIt x = x * 2 3 |> doubleIt // Evaluates to 6
Axial.Layers.LayerModuleprovide: Layer<'input,'error,'environment> -> Flow<'environment,'error,'value> -> Flow<'input,'error,'value>Builds an environment with a layer, runs a downstream flow, and always closes the layer scope. This is the provisioning boundary. It creates a fresh scope, builds the supplied layer inside that scope, runs the downstream flow with the built environment, and finalizes all acquired resources when the downstream flow completes or fails. The layer that builds the downstream environment. The flow to run with the provided environment. A flow that requires only the input environment of the layer. let program () = let runtimeLayer = Layer.succeed "production" let workflow = Flow.envWith String.length Layer.provide runtimeLayer workflow
succeed: 'output -> Layer<'input,'error,'output>Creates a layer that succeeds with a fixed output value.
Axial.Flowrun: 'env -> Flow<'env,'error,'value> -> Exit<'value,'error>Runs the workflow and blocks until the final exit is available. The environment used by the workflow. The workflow to run. The final workflow exit. let exit = workflow |> Flow.run environment
Axial.Exit`2Represents the final outcome of a workflow execution. The type of the success value. The type of the domain-specific failure value.
SuccessThe workflow completed successfully.
year: intshouldEqual: 'a -> 'a -> unitother: Exit<int,Never>failwithf: Printf.StringFormat<'T,'Result> -> 'TPrint to a string buffer and raise an exception with the given result. Helper printers must return strings. The formatter. The formatted result. See Printf.failwithf (link: ) for examples.
BaseRuntime.fromServiceProvider consumes an IServiceProvider and reports a missing registration as
BaseRuntimeError.MissingService before the workflow runs; the checked composition and failure are in
Providing the environment.
Applications normally extend the bundle with their own services rather than using it bare; see building a base runtime.
Service details
Platform services documents each service's operations, deterministic test doubles, and typed environment-variable error model.

