Skip to content

Commit 4f06faf

Browse files
committed
feat(net9): use RenderInfo to not need custom Elmish Program.run
1 parent 3416a35 commit 4f06faf

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed

src/Bolero/Components.fs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,9 @@ and [<AbstractClass>]
118118

119119
let mutable oldModel = None
120120
let mutable view = Node(fun _ _ s -> s)
121+
#if !NET9_0_OR_GREATER
121122
let mutable runProgramLoop = fun () -> ()
123+
#endif
122124
let mutable dispatch = ignore<'msg>
123125
let mutable program = Unchecked.defaultof<Program<'model, 'msg>>
124126
let mutable router = None : option<IRouter<'model, 'msg>>
@@ -194,9 +196,52 @@ and [<AbstractClass>]
194196
with _ -> () // fails if run in prerender
195197
)
196198

199+
#if NET9_0_OR_GREATER
200+
override this.OnInitializedAsync() =
201+
program <- this.Program
202+
let initModel, initCmd = Program.init program this
203+
view <- Program.view program initModel (fun cmd -> dispatch cmd)
204+
oldModel <- Some initModel
205+
let isInteractive = this.RendererInfo.IsInteractive
206+
207+
task {
208+
if isInteractive then
209+
let setDispatch d =
210+
dispatch <- d
211+
212+
setState <- fun model dispatch ->
213+
match oldModel with
214+
| Some oldModel when this.ShouldRender(oldModel, model) -> this.ForceSetState(model, dispatch)
215+
| _ -> ()
216+
217+
match this.StreamingInit with
218+
| None ->
219+
program <-
220+
program
221+
|> Program.map
222+
(fun _ _ -> initModel, setDispatch :: initCmd)
223+
id id
224+
(fun _ model dispatch -> setState model dispatch)
225+
id id
226+
227+
| Some streamInit ->
228+
let! streamedModel, streamedCmd = streamInit initModel
229+
view <- Program.view program streamedModel (fun cmd -> dispatch cmd)
230+
oldModel <- Some streamedModel
231+
program <-
232+
program
233+
|> Program.map
234+
(fun _ _ -> streamedModel, setDispatch :: initCmd @ streamedCmd)
235+
id id
236+
(fun _ model dispatch -> setState model dispatch)
237+
id id
238+
}
239+
240+
#else
197241
override this.OnInitializedAsync() =
198242
let setDispatch d =
199243
dispatch <- d
244+
200245
program <-
201246
this.Program
202247
|> Program.map
@@ -222,6 +267,7 @@ and [<AbstractClass>]
222267
let! model, cmd = init initModel
223268
updateInitState model cmd
224269
}
270+
#endif
225271

226272
member val internal StreamingInit : ('model -> Task<'model * Cmd<'msg>>) option = None with get, set
227273

@@ -245,7 +291,11 @@ and [<AbstractClass>]
245291
override this.OnAfterRenderAsync(firstRender) =
246292
task {
247293
if firstRender then
294+
#if NET9_0_OR_GREATER
295+
Program.runWith this program
296+
#else
248297
runProgramLoop()
298+
#endif
249299
if router.IsSome then
250300
do! this.NavigationInterception.EnableNavigationInterceptionAsync()
251301

src/Bolero/ProgramRun.fs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// https://github.com/elmish/elmish/issues/210
33
// As soon as the above issue is solved, this file can go.
44
namespace Elmish
5+
#if !NET9_0_OR_GREATER
56

67
[<Struct>]
78
type internal RingState<'item> =
@@ -119,3 +120,5 @@ module internal Program' =
119120
reentered <- false
120121

121122
updateInitState, model, run
123+
124+
#endif

0 commit comments

Comments
 (0)