Skip to content

Commit

Permalink
Merge branch 'releases/v0.24'
Browse files Browse the repository at this point in the history
  • Loading branch information
Tarmil committed Nov 17, 2024
2 parents a77fce1 + da0d86f commit 441847d
Show file tree
Hide file tree
Showing 12 changed files with 148 additions and 24 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- name: Setup dotnet
uses: actions/setup-dotnet@v1
with:
dotnet-version: '8.0.100'
dotnet-version: '8.0.101'

- name: NuGet cache
uses: actions/cache@v1
Expand Down Expand Up @@ -68,12 +68,12 @@ jobs:
prerelease:
runs-on: ubuntu-latest
needs: build
if: ${{ github.ref == 'refs/heads/master' }}
if: ${{ github.ref == 'refs/heads/master' || contains(github.ref, 'releases') }}
steps:
- name: Setup dotnet
uses: actions/setup-dotnet@v1
with:
dotnet-version: '8.0.100'
dotnet-version: '8.0.101'

- name: Download nupkg
uses: actions/download-artifact@v4.1.7
Expand All @@ -97,7 +97,7 @@ jobs:
- name: Setup dotnet
uses: actions/setup-dotnet@v1
with:
dotnet-version: '8.0.100'
dotnet-version: '8.0.101'

- name: Prepare
run: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
- name: Setup dotnet
uses: actions/setup-dotnet@v1
with:
dotnet-version: '8.0.100'
dotnet-version: '8.0.101'

- name: Download nupkg
uses: dawidd6/action-download-artifact@v2
Expand Down
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
# Changelog

## 0.24

* [#347](https://github.com/fsbolero/Bolero/issues/347) Add Blazor Interactive Render Modes.

* `IServiceCollection.AddBoleroComponents()` to be called instead of `IServiceCollection.AddBoleroHost()` to use interactive render modes.
When that is used, `boleroScript` will include `blazor.web.js` instead of `blazor.server.js` or `blazor.webassembly.js`.

* `BoleroRenderModeAttribute` can be used to indicate the render mode of the component it is applied to.

* Alternately, `Bolero.Server.Html.attr.renderMode` can be used to indicate the render mode of the component it is applied to.

* Add `Program.mkStreamRendering` and `Program.mkSimpleStreamRendering` functions.

* Add `StreamRenderingComponent` base class with members `InitialModel: 'model` and `LoadModel: 'model -> Task<'model>`.

* [#279](https://github.com/fsbolero/Bolero/issues/279) Re-enable the generation of reference assemblies.

* [#355](https://github.com/fsbolero/Bolero/issues/355) Fix CSS isolation on rebuild.

## 0.23

* [#308](https://github.com/fsbolero/Bolero/issues/308) Add router functions to decide what to do when the URL is invalid.
Expand Down
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"sdk": {
"version": "8.0.100",
"version": "8.0.101",
"rollForward": "feature",
"allowPrerelease": true
}
Expand Down
6 changes: 5 additions & 1 deletion src/Bolero.Build/Bolero.Build.targets
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
<_BoleroApplyCssScopesBeforeTargets>ResolveScopedCssOutputs;CoreCompile</_BoleroApplyCssScopesBeforeTargets>
</PropertyGroup>

<ItemGroup Condition="Exists('$(_BoleroScopedCssSourceFile)')">
<CompileBefore Include="$(_BoleroScopedCssSourceFile)" />
</ItemGroup>

<UsingTask AssemblyFile="$(BoleroTaskAssemblyPath)" TaskName="Bolero.Build.BoleroStripFSharpMetadata"
Condition="'$(BoleroStripAssemblies)' != 'False'" />
<UsingTask AssemblyFile="$(BoleroTaskAssemblyPath)" TaskName="Bolero.Build.BoleroApplyCssScopes" />
Expand All @@ -25,7 +29,7 @@
</Target>

<!-- Generate the CSS Scope identifier for *.bolero.css -->
<Target Name="_BoleroComputeCssScope" DependsOnTargets="$(_BoleroComputeCssScopeDependsOn)">
<Target Name="_BoleroComputeCssScope" DependsOnTargets="$(_BoleroComputeCssScopeDependsOn)" BeforeTargets="$(_BoleroApplyCssScopesBeforeTargets)">
<ComputeCssScope ScopedCssInput="@(BoleroScopedCss)" Targetname="$(TargetName)">
<Output TaskParameter="ScopedCss" ItemName="_BoleroScopedCss" />
</ComputeCssScope>
Expand Down
24 changes: 24 additions & 0 deletions src/Bolero.Server/Components.fs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,30 @@ type BoleroScript() =
override this.BuildRenderTree(builder) =
builder.AddMarkupContent(0, BoleroHostConfig.Body(this.Config))

#if NET8_0_OR_GREATER
[<AbstractClass; StreamRendering true>]
type StreamRenderingComponent<'model>() =
inherit Component<'model>()

let mutable model = Unchecked.defaultof<'model>

abstract InitialModel : 'model

abstract LoadModel : 'model -> Task<'model>

abstract Render : 'model -> Node

override this.OnInitializedAsync() =
model <- this.InitialModel
task {
let! newModel = this.LoadModel(model)
model <- newModel
}

override this.Render() =
this.Render(model)
#endif

module Rendering =

let private emptyContent = Task.FromResult { new IHtmlContent with member _.WriteTo(_, _) = () }
Expand Down
18 changes: 15 additions & 3 deletions src/Bolero/Components.fs
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,7 @@ and [<AbstractClass>]
with _ -> () // fails if run in prerender
)

override this.OnInitialized() =
base.OnInitialized()
override this.OnInitializedAsync() =
let setDispatch d =
dispatch <- d
program <-
Expand All @@ -207,12 +206,25 @@ and [<AbstractClass>]
id id
(fun _ model dispatch -> setState model dispatch)
id id
runProgramLoop <- Program'.runFirstRender this program

let updateInitState, initModel, loop = Program'.runFirstRender this program
runProgramLoop <- loop
setState <- fun model dispatch ->
match oldModel with
| Some oldModel when this.ShouldRender(oldModel, model) -> this.ForceSetState(model, dispatch)
| _ -> ()

match this.StreamingInit with
| None ->
Task.CompletedTask
| Some init ->
task {
let! model, cmd = init initModel
updateInitState model cmd
}

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

member internal this.InitRouter
(
r: IRouter<'model, 'msg>,
Expand Down
40 changes: 40 additions & 0 deletions src/Bolero/Program.fs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,48 @@
module Bolero.Program

open System.Reflection
open System.Threading.Tasks
open Elmish

/// <summary>
/// Create a simple program for a component that uses StreamRendering.
/// </summary>
/// <param name="initialModel">The model that is shown initially.</param>
/// <param name="load">Load the model to be stream-rendered.</param>
/// <param name="update">The Elmish update function.</param>
/// <param name="view">The Elmish view function.</param>
let mkSimpleStreamRendering
(initialModel: 'model)
(load: 'model -> Task<'model>)
(update: 'msg -> 'model -> 'model)
(view: 'model -> Dispatch<'msg> -> Node)
: Program<'model, 'msg> =
Program.mkSimple (fun (comp: ProgramComponent<'model, 'msg>) ->
comp.StreamingInit <- Some (fun x -> task {
let! model = load x
return model, Cmd.none
})
initialModel)
update view

/// <summary>
/// Create a program for a component that uses StreamRendering.
/// </summary>
/// <param name="initialModel">The model that is shown initially.</param>
/// <param name="load">Load the model to be stream-rendered.</param>
/// <param name="update">The Elmish update function.</param>
/// <param name="view">The Elmish view function.</param>
let mkStreamRendering
(initialModel: 'model)
(load: 'model -> Task<'model * Cmd<'msg>>)
(update: 'msg -> 'model -> 'model * Cmd<'msg>)
(view: 'model -> Dispatch<'msg> -> Node)
: Program<'model, 'msg> =
Program.mkProgram (fun (comp: ProgramComponent<'model, 'msg>) ->
comp.StreamingInit <- Some load
initialModel, [])
update view

/// <summary>
/// Attach `router` to `program` when it is run as the `Program` of a `ProgramComponent`.
/// </summary>
Expand Down
11 changes: 10 additions & 1 deletion src/Bolero/ProgramRun.fs
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,17 @@ module internal Program' =

reentered <- true
setState model dispatch
fun () ->
let mutable cmd = cmd

let updateInitState m cmd' =
setState m dispatch
state <- m
cmd <- cmd @ cmd'

let run () =
cmd |> Cmd.exec (fun ex -> onError ("Error intitializing:", ex)) dispatch
activeSubs <- Subs.diff activeSubs sub |> Subs.Fx.change onError dispatch
processMsgs ()
reentered <- false

updateInitState, model, run
7 changes: 0 additions & 7 deletions src/Bolero/Router.fs
Original file line number Diff line number Diff line change
Expand Up @@ -190,15 +190,8 @@ exception InvalidRouter of kind: InvalidRouterKind with
type PageModel<'T> =
{ Model: 'T }

#if NET8_0
static let prop = typeof<PageModel<'T>>.GetProperty("Model")

member internal this.SetModel(value) =
prop.SetValue(this, value)
#else
member internal this.SetModel(value) =
Unsafe.AsRef<'T>(&this.Model) <- value
#endif

[<AutoOpen>]
module private RouterImpl =
Expand Down
19 changes: 14 additions & 5 deletions tests/Remoting.Client/Main.fs
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,17 @@

module Bolero.Tests.Remoting.Client

open System
open System.Collections.Generic
open System.Threading.Tasks
open Microsoft.AspNetCore.Components
open Microsoft.AspNetCore.Components.Authorization
open Bolero
open Bolero.Html
open Bolero.Remoting
open Bolero.Remoting.Client
open Elmish
open Microsoft.Extensions.Logging

type MyApi =
{
Expand Down Expand Up @@ -220,22 +224,27 @@ let Display model dispatch =
}
}

[<StreamRendering true>] //; BoleroRenderMode(BoleroRenderMode.Server, prerender = false)>]
type MyApp() =
inherit ProgramComponent<Model, Message>()

override this.Program =
let myApi = this.Remote<MyApi>()
Program.mkProgram (fun _ -> InitModel, Cmd.batch [
let load model = task {
do! Task.Delay 2000
return { model with currentKey = 42 }, Cmd.batch [
Cmd.ofMsg RefreshItems
Cmd.ofMsg GetLogin
]) (Update myApi) Display
]
}

override this.Program =
let myApi = this.Remote<MyApi>()
Program.mkStreamRendering InitModel load (Update myApi) Display
|> Program.withRouter router


open Microsoft.AspNetCore.Components.WebAssembly.Hosting
open Microsoft.Extensions.DependencyInjection
open System.Security.Claims
open System.Threading.Tasks

type DummyAuthProvider() =
inherit AuthenticationStateProvider()
Expand Down
16 changes: 15 additions & 1 deletion tests/Remoting.Server/Startup.fs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ namespace Bolero.Tests.Remoting

open System
open System.Text.Json.Serialization
open System.Threading.Tasks
open Bolero.Tests.Remoting.Client
open Microsoft.AspNetCore
open Microsoft.AspNetCore.Authentication.Cookies
Expand All @@ -40,14 +41,27 @@ module Page =
open Bolero.Html
open Bolero.Server.Html

type MyStreamedComponent() =
inherit Components.StreamRenderingComponent<string>()

override _.InitialModel = "loading..."

override _.LoadModel(_initialModel) = task {
do! Task.Delay (TimeSpan.FromSeconds 2)
return "loaded!"
}

override _.Render(model) = div { $"Static stream content {model}" }

let index = doctypeHtml {
head {
title { "Bolero (remoting)" }
meta { attr.charset "UTF-8" }
``base`` { attr.href "/" }
}
body {
div { attr.id "main"; comp<MyApp> { attr.renderMode RenderMode.InteractiveAuto } }
div { attr.id "main"; comp<MyApp> { attr.renderMode (InteractiveWebAssemblyRenderMode(prerender = false)) } }
comp<MyStreamedComponent>
script { attr.src "_content/Microsoft.AspNetCore.Components.WebAssembly.Authentication/AuthenticationService.js" }
boleroScript
}
Expand Down

0 comments on commit 441847d

Please sign in to comment.