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.JavaScriptAxial.PlatformService covers the five capabilities that would otherwise be read straight from static globals:
DateTimeOffset.UtcNow, a logger, Random, Guid.NewGuid(), and Environment.GetEnvironmentVariable. Each becomes
a declared dependency, which is what makes a workflow that reads the time or generates an identifier reproducible in
a test.
open System
open Axial
open Axial.PlatformService
SystemAxialPlatformServiceThese are the smallest services Axial ships, and the most valuable to make explicit. A function that reads the clock
directly cannot be tested at a chosen instant; one that declares IHasClock can:
let isExpired (expiry: DateTimeOffset) : Flow<#IHasClock, Never, bool> =
Clock.now |> Flow.map (fun now -> now >= expiry)
isExpired: DateTimeOffset -> Flow<'a,Never,bool>expiry: DateTimeOffsetSystem.DateTimeOffsetRepresents a point in time, typically expressed as a date and time of day, relative to Coordinated Universal Time (UTC).
Axial.Flow`3Represents a cold workflow that reads an environment, returns a typed result, and is executed explicitly through one of its execution members such as ToTask, ToAsync, or RunSynchronously. The type of the environment dependency. The type of the failure value. The type of the success value.
Axial.PlatformService.IHasClockDeclares that an environment supplies the clock service.
Axial.NeverRepresents an error channel that cannot occur.
boolAn 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)
now: DateTimeOffset(>=): 'T -> 'T -> boolStructural greater-than-or-equal The first parameter. The second parameter. The result of the comparison. 5 >= 1 // Evaluates to true 5 >= 5 // Evaluates to true [1; 5] >= [1; 6] // Evaluates to false
Applications rarely want one of these — they want all five. BaseRuntime is the record that bundles them, and it
implements one contract per service, so a workflow requiring any combination is satisfied by the single value:
let liveRuntime : BaseRuntime = BaseRuntime.liveValue
liveRuntime: 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.
Most applications extend BaseRuntime rather than replacing it — see
Tutorial: Composing Built-in Services for the composition, and
platform services getting started for the shortest path to a
running host.
Deterministic implementations
Every module ships test doubles beside its live value, so a test rarely needs to write an object expression:
let fixedRuntime : BaseRuntime =
{ Clock = Clock.fromValue (DateTimeOffset.Parse "2026-01-01T00:00:00Z")
Log = Log.live
Random = Random.fromValue 7
Guid = Guid.fromValue (System.Guid.Parse "00000000-0000-0000-0000-000000000001")
EnvironmentVariables = EnvironmentVariables.fromPairs [ "AXIAL_ENV", "test" ] }
fixedRuntime: BaseRuntimeAxial.PlatformService.BaseRuntimeGroups the standard operational services commonly used by workflow hosts.
Clock: IClockAxial.PlatformService.ClockHelpers for the clock service.
fromValue: DateTimeOffset -> IClockCreates a deterministic clock that always returns the supplied instant.
System.DateTimeOffsetRepresents a point in time, typically expressed as a date and time of day, relative to Coordinated Universal Time (UTC).
Parse: string -> DateTimeOffsetConverts the specified string representation of a date, time, and offset to its equivalent. A string that contains a date and time to convert. An object that is equivalent to the date and time that is contained in . The offset is greater than 14 hours or less than -14 hours. is . does not contain a valid string representation of a date and time. -or- contains the string representation of an offset value without a date or time.
Log: ILogAxial.PlatformService.LogHelpers for the logging service.
live: ILogCreates a no-op logger for tests and local service bundles.
Random: IRandomAxial.PlatformService.RandomHelpers for the random-number service.
fromValue: int -> IRandomCreates a deterministic random generator that always returns the supplied value.
Guid: IGuidAxial.PlatformService.GuidHelpers for the GUID service.
fromValue: Guid -> IGuidCreates a deterministic GUID service that always returns the supplied value.
SystemParse: string -> GuidConverts the string representation of a GUID to the equivalent structure. The string to convert. A structure that contains the value that was parsed. is . is not in a recognized format.
System.GuidRepresents a globally unique identifier (GUID).
EnvironmentVariables: IEnvironmentVariablesAxial.PlatformService.EnvironmentVariablesHelpers for the environment-variable service.
fromPairs: (string * string) seq -> IEnvironmentVariablesCreates a deterministic provider from a fixed set of name/value pairs.
In this section
- Clock — the current instant, and why it belongs in the environment.
- Logging —
ILoglevels, sinks, and its relationship to telemetry. - Randomness and GUIDs — non-determinism you can pin in a test.
- Environment variables — typed reads with
EnvironmentVariableError.

