Inertial.Client
0.2.2
See the version list below for details.
dotnet add package Inertial.Client --version 0.2.2
NuGet\Install-Package Inertial.Client -Version 0.2.2
<PackageReference Include="Inertial.Client" Version="0.2.2" />
<PackageVersion Include="Inertial.Client" Version="0.2.2" />
<PackageReference Include="Inertial.Client" />
paket add Inertial.Client --version 0.2.2
#r "nuget: Inertial.Client, 0.2.2"
#:package Inertial.Client@0.2.2
#addin nuget:?package=Inertial.Client&version=0.2.2
#tool nuget:?package=Inertial.Client&version=0.2.2
Inertial.Client Module Reference
This document describes each module in the Inertial.Client library.
Overview
Inertial.Client is a Fable/F# client library that works with Inertial (server) to provide InertiaJS-style single page application behavior. It uses Sutil for reactive UI rendering.
Modules
JsCookie.fs
Purpose: JavaScript interop for the js-cookie library.
Dependencies: js-cookie npm package
Exports:
get : string -> string option- Get a cookie by nameset : string -> string -> obj option- Set a cookieremove : string -> unit- Remove a cookie
Usage:
let token = JsCookie.get "XSRF-TOKEN"
JsCookie.set "session" "abc123"
JsCookie.remove "old-cookie"
NProgress.fs
Purpose: JavaScript interop for the nprogress progress bar library.
Dependencies: nprogress npm package
Exports:
start : unit -> unit- Start the progress barset : int -> unit- Set progress to specific valueinc : unit -> unit- Increment progressdone : unit -> unit- Complete the progress barconfigure : obj -> unit- Configure NProgress options
Usage:
NProgress.start()
// ... loading ...
NProgress.``done``()
Common.fs (Core module)
Purpose: Core types and utility functions used throughout the library.
Types:
Method- HTTP method union (Get, Post, Put, Patch, Delete) with dataRouterLocation<'Props,'Shared>- Current router state including pathname, query, pageObj
Functions:
split : string -> string -> string list- Split string by delimitersplitRoute : string -> string list- Split URL path by "/"splitQueryParam : string -> string list- Split query string by "&"splitKeyValuePair : string -> string list- Split by "="getKeyValuePair : 'a list -> ('a * 'a) option- Extract key-value pair from list
Usage:
let segments = splitRoute "/users/123/profile"
// ["users"; "123"; "profile"]
let method = Post [("name", box "John"); ("age", box 30)]
let dataMap = method.ToDataMap()
Route.fs
Purpose: Active patterns for parsing URL segments. Inspired by Feliz.Router.
Active Patterns:
(|Int|_|)- Parse integer(|Int64|_|)- Parse 64-bit integer(|Guid|_|)- Parse GUID(|Number|_|)- Parse floating point number(|Decimal|_|)- Parse decimal(|Bool|_|)- Parse boolean ("true", "false", "1", "0", "")(|Query|_|)- Parse query string into key-value pairs
Usage:
match segment with
| Int id -> loadUser id
| Guid uuid -> loadByGuid uuid
| _ -> notFound()
match queryString with
| Query params ->
params |> List.tryFind (fst >> (=) "page")
| _ -> None
Scroll.fs
Purpose: Scroll position persistence using sessionStorage.
Functions:
save : string -> float -> unit- Save scroll position for a componentrestore : string -> float- Restore scroll position (returns 0 if not found)
Storage Key Format: scrollPosition:{componentName}
Usage:
// Save current scroll position
Scroll.save "UserList" window.pageYOffset
// Restore scroll position
let y = Scroll.restore "UserList"
window.scroll(0, y)
Inertia.fs
Purpose: HTTP request handling with Inertial protocol headers and caching logic.
Key Functions:
addInertiaHeaders- Add all required Inertial headers to HTTP requestgetCacheForComponent- Retrieve cached prop values from sessionStorageresolveReEvals- Determine which props need re-evaluation vs cachemissingFromCacheMap- Find props not in cacheresolveNextPropsToEval- Determine final PropsToEval based on cache stateinertiaHttp- Main HTTP function for Inertial requests
Caching: The module handles client-side prop caching:
- Props can be stored in sessionStorage per component
- Cache storage key:
cache:{componentName}:{fieldName} - Supports
StoreAll,StoreToCache,StoreNonestrategies - Supports
CheckForAll,CheckForCached,SkipCacheretrieval
Headers Set:
X-Inertial: trueX-Inertial-Version: {version}X-Inertial-Id: {connectionId}X-Inertial-Partial-Component/X-Inertial-Full-ComponentX-Inertial-Partial-DataX-Inertial-SSE,X-Inertial-ReloadX-Inertial-CacheStorage,X-Inertial-CacheRetrievalX-XSRF-TOKEN
RxSSE.fs
Purpose: Server-Sent Events (SSE) integration with FSharp.Control reactive extensions.
Functions:
ofEventSource<'ev>- Convert EventSource to IAsyncObservableeventPredicates- Check if SSE event matches predicates for current pagessePartialReload- Trigger partial reload when SSE event is received
Predicates Supported:
ComponentIsOneOf- Event applies to specific componentsComponentIsAny- Event applies to all componentsComponentIsAnyExcept- Event applies to all except specifiedUserIdIsOneOf- Event applies to specific users
Usage:
// SSE events trigger automatic partial reloads when predicates match
let eventSource = EventSource("/sse")
let observable = RxSSE.ofEventSource eventSource
Deferred.fs
Purpose: Sutil render helpers for Deferred<'T> values.
Modules:
Deferred (render functions)
render- Render with explicit handlers for Loading/Loaded/FailedrenderSimple- Render with default loading text and error displayrenderWithLoading- Render with custom loading elementrenderList- Render Deferred list with empty state handlingrenderOption- Render Deferred option with None handlingrenderResult- Render Deferred Result with Ok/Error handling
Bind (reactive bindings)
deferred- Bind Deferred store with all handlersdeferredSimple- Bind with default loading/errordeferredList- Bind Deferred list storedeferredOption- Bind Deferred option store
DeferredExtensions (helper functions)
isLoading- Check if PendingisLoaded- Check if LoadedisFailed- Check if FailedtryGetLoaded- Get value or NonegetLoadedOr- Get value or defaulttryGetError- Get exception or None
Usage:
// Simple rendering
Deferred.renderSimple (fun items ->
Html.ul [ for item in items -> Html.li [ Html.text item.Name ] ]
) props.Items
// Reactive binding
Bind.deferred itemsStore
(fun () -> Html.text "Loading...")
(fun items -> renderItems items)
(fun ex -> Html.text $"Error: {ex.Message}")
Router.fs
Purpose: Main router component handling navigation, page loading, and SSE integration.
Key Responsibilities:
- Initialize router from
data-pageattribute on mount - Handle link clicks for SPA navigation
- Manage browser history (pushState/popState)
- Trigger partial reloads for
reloadOnMountprops - Connect to SSE for real-time updates
- Manage scroll position restoration
- Show/hide progress bar during navigation
Router State (RouterLocation<'Props,'Shared>):
pathname- Current URL pathquery- Query stringpageObj- Current page object with props and metadataallowPartialReload- Whether partial reloads are allowedcancellationTokenSource- For cancelling in-flight requests
Page Configuration via PageObj:
component- Component nametitle- Page titleprops- Page props (typed)shared- Shared data across pagesreloadOnMount- Deferred field loading configurationrefreshOnBack- Whether to reload on back navigationpreserveScroll- Whether to restore scroll positionrealTime- Whether SSE updates are enabledurlComponentMap- URL to component mapping for prefetching
Usage:
// In your app entry point
Router.router
propsDecoder
sharedDecoder
toFieldNames
toMap
resolver
currentUserId
renderPage
Using Custom JavaScript
Projects using Inertial.Client can integrate custom JavaScript in several ways:
Import JS Files Alongside F# Code
Place .js files in your client project and import them:
// src/Client/utils.js
export function formatDate(d) {
return new Intl.DateTimeFormat('en-US').format(d);
}
// src/Client/App.fs
open Fable.Core
[<Import("formatDate", from="./utils.js")>]
let formatDate: System.DateTime -> string = jsNative
npm Packages
Install via npm and import:
npm install chart.js
[<Import("Chart", from="chart.js")>]
let Chart: obj = jsNative
// Or with types
type IChart =
abstract member destroy: unit -> unit
abstract member update: unit -> unit
[<Import("Chart", from="chart.js")>]
let Chart: obj -> IChart = jsNative
Global Scripts via HTML
Add to your base HTML template:
<script src="/js/custom/myLibrary.js"></script>
Then access from F#:
[<Emit("window.MyLibrary.doThing($0)")>]
let doThing (x: string): unit = jsNative
Inline JavaScript with Emit
For one-off JavaScript expressions:
open Fable.Core
[<Emit("console.log($0)")>]
let log (msg: string): unit = jsNative
[<Emit("eval($0)")>]
let evalJs (code: string): obj = jsNative
// Dynamic expression
let result = emitJsExpr () "navigator.userAgent"
Dynamic Imports (Lazy Loading)
[<Emit("import($0)")>]
let importModule (path: string): JS.Promise<obj> = jsNative
// Usage
let loadChart() = promise {
let! chartModule = importModule "chart.js"
// use chartModule
}
Typical Project Structure
src/
├── Client/
│ ├── Client.fsproj
│ ├── App.fs
│ ├── custom.js ← Your custom JS
│ └── package.json ← npm dependencies
└── Server/
└── ...
Your bundler (Vite/webpack/esbuild) handles resolving JS imports when Fable compiles.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Fable.Browser.Dom (>= 2.18.0)
- Fable.Browser.EventSource (>= 1.0.0)
- Fable.Core (>= 4.3.0)
- Fable.Promise (>= 3.2.0)
- Fable.Reaction (>= 3.5.0)
- Fable.SimpleHttp (>= 3.6.0)
- FSharp.Core (>= 10.0.100)
- Inertial.Lib (>= 0.1.5)
- Sutil (>= 2.0.16)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.