Skip to content

Commit a2e27b4

Browse files
committed
feat: Program functions for StreamRendering
1 parent 14dec57 commit a2e27b4

File tree

3 files changed

+65
-4
lines changed

3 files changed

+65
-4
lines changed

src/Bolero/Components.fs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,7 @@ and [<AbstractClass>]
194194
with _ -> () // fails if run in prerender
195195
)
196196

197-
override this.OnInitialized() =
198-
base.OnInitialized()
197+
override this.OnInitializedAsync() =
199198
let setDispatch d =
200199
dispatch <- d
201200
program <-
@@ -207,12 +206,25 @@ and [<AbstractClass>]
207206
id id
208207
(fun _ model dispatch -> setState model dispatch)
209208
id id
210-
runProgramLoop <- Program'.runFirstRender this program
209+
210+
let updateInitState, initModel, loop = Program'.runFirstRender this program
211+
runProgramLoop <- loop
211212
setState <- fun model dispatch ->
212213
match oldModel with
213214
| Some oldModel when this.ShouldRender(oldModel, model) -> this.ForceSetState(model, dispatch)
214215
| _ -> ()
215216

217+
match this.StreamingInit with
218+
| None ->
219+
Task.CompletedTask
220+
| Some init ->
221+
task {
222+
let! model, cmd = init initModel
223+
updateInitState model cmd
224+
}
225+
226+
member val internal StreamingInit : ('model -> Task<'model * Cmd<'msg>>) option = None with get, set
227+
216228
member internal this.InitRouter
217229
(
218230
r: IRouter<'model, 'msg>,

src/Bolero/Program.fs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,48 @@
2323
module Bolero.Program
2424

2525
open System.Reflection
26+
open System.Threading.Tasks
2627
open Elmish
2728

29+
/// <summary>
30+
/// Create a simple program for a component that uses StreamRendering.
31+
/// </summary>
32+
/// <param name="initialModel">The model that is shown initially.</param>
33+
/// <param name="load">Load the model to be stream-rendered.</param>
34+
/// <param name="update">The Elmish update function.</param>
35+
/// <param name="view">The Elmish view function.</param>
36+
let mkSimpleStreamRendering
37+
(initialModel: 'model)
38+
(load: 'model -> Task<'model>)
39+
(update: 'msg -> 'model -> 'model)
40+
(view: 'model -> Dispatch<'msg> -> Node)
41+
: Program<'model, 'msg> =
42+
Program.mkSimple (fun (comp: ProgramComponent<'model, 'msg>) ->
43+
comp.StreamingInit <- Some (fun x -> task {
44+
let! model = load x
45+
return model, Cmd.none
46+
})
47+
initialModel)
48+
update view
49+
50+
/// <summary>
51+
/// Create a program for a component that uses StreamRendering.
52+
/// </summary>
53+
/// <param name="initialModel">The model that is shown initially.</param>
54+
/// <param name="load">Load the model to be stream-rendered.</param>
55+
/// <param name="update">The Elmish update function.</param>
56+
/// <param name="view">The Elmish view function.</param>
57+
let mkStreamRendering
58+
(initialModel: 'model)
59+
(load: 'model -> Task<'model * Cmd<'msg>>)
60+
(update: 'msg -> 'model -> 'model * Cmd<'msg>)
61+
(view: 'model -> Dispatch<'msg> -> Node)
62+
: Program<'model, 'msg> =
63+
Program.mkProgram (fun (comp: ProgramComponent<'model, 'msg>) ->
64+
comp.StreamingInit <- Some load
65+
initialModel, [])
66+
update view
67+
2868
/// <summary>
2969
/// Attach `router` to `program` when it is run as the `Program` of a `ProgramComponent`.
3070
/// </summary>

src/Bolero/ProgramRun.fs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,17 @@ module internal Program' =
105105

106106
reentered <- true
107107
setState model dispatch
108-
fun () ->
108+
let mutable cmd = cmd
109+
110+
let updateInitState m cmd' =
111+
setState m dispatch
112+
state <- m
113+
cmd <- cmd @ cmd'
114+
115+
let run () =
109116
cmd |> Cmd.exec (fun ex -> onError ("Error intitializing:", ex)) dispatch
110117
activeSubs <- Subs.diff activeSubs sub |> Subs.Fx.change onError dispatch
111118
processMsgs ()
112119
reentered <- false
120+
121+
updateInitState, model, run

0 commit comments

Comments
 (0)