Skip to content

Web workers in Fable made easy, exposed as React hooks and Elmish commands.

License

Notifications You must be signed in to change notification settings

Shmew/Feliz.UseWorker

Repository files navigation

Feliz.UseWorker Nuget

Web workers in Fable made easy, exposed as React hooks and Elmish commands all within a single project.

Includes features such as sync-fallback, message timeouts, automatic non-primitive serialization, and reactive status updates.

A worker file:

module Workers.Sort

open Feliz.UseWorker

let rng = System.Random()

let sortNumbers' () =
    Array.init 3000000 (fun _ -> rng.NextDouble() * 1000000.)
    |> Array.sort
    |> Array.sum
    |> int

let sortNumbers = WorkerFunc.Create("Sort", "sortNumbers", sortNumbers')

Elmish:

open Feliz.UseWorker

type State =
    { Count: int 
      Worker: Worker<unit,int> option
      WorkerState: WorkerStatus }

    interface System.IDisposable with
        member this.Dispose () =
            this.Worker |> Option.iter (fun w -> w.Dispose())

type Msg =
    | ChangeWorkerState of WorkerStatus
    | ExecuteWorker
    | KillWorker
    | RestartWorker
    | SetWorker of Worker<unit,int>
    | WorkerResult of int

let init = 
    { Count = 0
      Worker = None
      WorkerState = WorkerStatus.Pending }, 
    Cmd.Worker.create Workers.Sort.sortNumbers SetWorker ChangeWorkerState

let update (msg: Msg) (state: State) =
    match msg with
    | ChangeWorkerState workerState ->
        { state with WorkerState = workerState }, Cmd.none
    | ExecuteWorker ->
        state, Cmd.Worker.exec state.Worker () WorkerResult
    | KillWorker ->
        state, Cmd.Worker.kill state.Worker
    | RestartWorker ->
        state, Cmd.Worker.restart state.Worker
    | SetWorker worker ->
        { state with Worker = Some worker }, Cmd.none
    | WorkerResult i ->
        { state with Count = i }, Cmd.none

Hooks:

open Feliz.UseWorker

let render = React.functionComponent(fun () ->
    let worker,workerStatus = React.useWorker(Workers.Sort.sortNumbers)
    let count,setCount = React.useState 0

    Html.div [
        prop.children [
            ...
            Html.button [
                prop.onClick <| fun _ -> worker.invoke((), setCount) 
                prop.text "Execute"
            ]
            Html.button [
                prop.onClick <| fun _ -> worker.kill()
                prop.text "Kill"
            ]
            Html.button [
                prop.onClick <| fun _ -> worker.restart()
                prop.text "Restart"
            ]
        ]
    ])

See the full documentation with live examples here.

About

Web workers in Fable made easy, exposed as React hooks and Elmish commands.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published