Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add facilities for StreamRendering #356

Merged
merged 3 commits into from
Aug 4, 2024
Merged

Conversation

Tarmil
Copy link
Member

@Tarmil Tarmil commented May 23, 2024

  • For stream rendering SSR: add class StreamRenderingComponent<'model>.

    Example use:

    type Model = { text: string }
    
    type MySlowComponent() =
        inherit StreamRenderingComponent<Model>()
    
        override _.InitialModel = { text = "loading..." }
    
        override _.LoadModel(initialModel) = task {
            do! Task.Delay (TimeSpan.FromSeconds 2) // Simulate slow loading
            return { initialModel with text = "loaded!" }
        }
    
        override _.Render(model) =
            div { $"Stream-rendered component is {model.text}" }
    
    let index = doctypeHtml {
        head { ... }
        body {
            comp<MySlowComponent>
            boleroScript
        }
    }

    Note: unfortunately, it's not possible to create a function that would take initialModel, loadModel and render as arguments and instantiate the component, similarly to lazyComp. This would involve passing function-typed parameters to the component, but stream rendering requires serializable parameters.

  • For stream rendering Elmish program:

    • Program.mkStreamRendering, similar to Program.mkProgram except instead of an init function, it takes an initial model and a load function that returns a task.
    • Program.mkSimpleStreamRendering, similarly based on Program.mkSimple.

    Example use:

    type Model = { text: string }
    
    type Msg = ...
    
    let update msg model = ...
    
    let init = { text = "loading..." }
    
    let load initialModel = task {
        do! Task.Delay (TimeSpan.FromSeconds 2) // Simulate slow loading
        return ({ model with text = "loaded!" }, Cmd.none)
    }
    
    let view model dispatch =
        div { $"Stream-rendered component is {model.text}" }
    
    type MySlowComponent() =
        inherit ProgramComponent<Model, Msg>()
    
        override _.Program =
            Program.mkStreamRendering init load update view
    
    
    let index = doctypeHtml {
        head { ... }
        body {
            // Also works with InteractiveWebAssemblyRenderMode.
            // Needs prerender = false, otherwise the initial model will show up again while the dynamic page runs load.
            comp<MySlowComponent> { attr.renderMode (InteractiveServerRenderMode(prerender = false)) }
            boleroScript
        }
    }

@Tarmil Tarmil added the enhancement New feature or request label May 23, 2024
@Tarmil Tarmil marked this pull request as ready for review May 25, 2024 07:18
@Tarmil Tarmil merged commit a9e7157 into releases/v0.24 Aug 4, 2024
7 checks passed
@Tarmil Tarmil deleted the stream-rendering branch August 4, 2024 13:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant