Skip to content

adz/Axial

Repository files navigation

Axial

Axial

Axial is a set of F# libraries for two common application problems:

  • turning untrusted input into domain values without constructing a failed model;
  • composing async work while keeping dependencies and expected failures visible.

Use either part on its own.

ci NuGet License

Warning

Axial 0.7.0 is the first planned release under the Axial name. It replaces the former monolithic FsFlow package with smaller packages. The public surface is still pre-1.0 and may change.

Parse input into domain values

A schema describes fields, parsing, constraints, and construction in one value:

open Axial.Schema

type Signup =
    { Email: string
      Age: int }

let signupSchema =
    Schema.recordFor<Signup, _> (fun email age -> { Email = email; Age = age })
    |> Schema.field "email" _.Email
        (Schema.text
         |> Schema.constrainAll [ Constraint.required; Constraint.email ])
    |> Schema.field "age" _.Age
        (Schema.int |> Schema.constrain (Constraint.atLeast 13))
    |> Schema.build

match (Schema.parse signupSchema rawInput).Result with
| Ok signup -> register signup
| Error diagnostics -> display diagnostics

Schema.parse either returns the model or path-aware diagnostics. The same declaration can drive checking, JSON Schema, compiled codecs, form redisplay, test-data generation, and versioned wire contracts.

A schema only controls values produced through the schema. When every value of a type must satisfy an invariant, use a private representation and expose a fallible constructor or named domain operations.

Start here:

Install the core package:

dotnet add package Axial.Schema

Keep workflow dependencies visible

Flow<'env, 'error, 'value> describes async work, its dependencies, and its expected failure type:

open Axial.Flow

type RegistrationError =
    | UserNotFound
    | SaveFailed of string

type RegistrationEnv =
    { LoadUser: int -> Task<Result<User, RegistrationError>>
      SaveUser: User -> Task<Result<unit, RegistrationError>> }

let register userId : Flow<RegistrationEnv, RegistrationError, unit> =
    flow {
        let! loadUser = Flow.read _.LoadUser
        let! saveUser = Flow.read _.SaveUser
        let! user = loadUser userId
        return! saveUser user
    }

Tests supply a small record of fakes. The application host supplies live implementations. Cancellation, resource scopes, retries, and child fibers stay within the workflow runtime.

Start here:

Install Flow:

dotnet add package Axial.Flow

Plain Result remains the simple option

Small functions do not need schemas or workflows. Axial.ErrorHandling adds reusable checks and focused helpers while keeping ordinary Result<'value, 'error> in your interfaces.

open Axial.ErrorHandling

let requireName value =
    value
    |> Check.String.present
    |> Result.orError NameMissing

Platforms and examples

The authored schema and workflow paths avoid runtime reflection. The core packages support NativeAOT, trimming, and Fable; individual host and service packages document their supported targets.

About

Axial is an F# library for typed results, explicit context, and async/task interop.

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages