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

have Fable compiler support Suave F# webserver for cross language development #778

Open
jkone27 opened this issue Jan 2, 2024 · 1 comment

Comments

@jkone27
Copy link

jkone27 commented Jan 2, 2024

would be grate if suave could be the cross language web platform we all dream of, i tried to compile it with fable on a single fsx script (dotnet fable), got this error, seems the fish custom operator is not defined, maybe there is work arounds..

Suave_Operators_op_GreaterEqualsGreater

here the full code, to be compiled with dotnet fable (defaults to javascript)

// npm init type module, npm add express, dotnet tool install fable, dotnet fable express.fsx, node express.fs.js
#r "nuget: Suave"
#r "nuget: Fable.Core"
#r "nuget: Feliz.ViewEngine"
#r "nuget: Feliz.ViewEngine.Htmx"
#r "nuget: Feliz.Bulma"

open Suave
open Suave.Filters
open Suave.Operators
open Suave.Successful
open Suave.Control
open Feliz.ViewEngine
open Feliz.ViewEngine.Htmx

module View =

    let buttonOne =
        Html.button [
            prop.className "button is-primary"
            prop.text "NEW BUTTON"
            hx.post "/button-one"
            hx.swap "innerHtml"
        ]

    let buttonOneHtml =
        buttonOne 
        |> Render.htmlView

    let view =
        Html.html [
            Html.head [
                Html.link [
                    prop.rel "stylesheet"
                    prop.href "https://cdn.jsdelivr.net/npm/[email protected]/css/bulma.min.css"
                ]
                Html.script [
                    prop.src "https://unpkg.com/[email protected]"
                ]
            ]
            Html.body [
                Html.h1 [
                    prop.className "hero is-primary"
                    prop.text "Hello Feliz from express!" 
                ]
                Html.section [
                    Html.p "here is a button..."
                    buttonOne
                ]
            ]
        ]
        |> Render.htmlView 

    let buttonTwo =
        Html.button [
            prop.className "button is-error"
            prop.text "FROM HTMX"
            hx.post "/button-two"
        ]
        |> Render.htmlView 

let mainApp =
    (Suave.Filters.path "/") 
    >=> (Suave.Successful.OK View.view)

let getResponseApp = 
    (Suave.Filters.path "/button-one")
    >=> (Suave.Successful.OK View.buttonOneHtml)

let click2Response = 
    (Suave.Filters.path "/button-two")
    >=> (Suave.Successful.OK View.buttonTwo)

let app =
    Suave.Filters.GET
    >=> (Suave.WebPart.choose [ 
        mainApp
        getResponseApp
        click2Response
    ])

Suave.Web.startWebServer Suave.Web.defaultConfig app
@njlr
Copy link
Contributor

njlr commented Feb 20, 2024

For Fable to work:

  1. The source code needs to be bundled in the package.
  2. The code must only call functions that Fable supports.

(1) is quite easy to fix but (2) is significant work.

The approach would be to isolate the platform code that is .NET specific and provide the same API using Node.js built-ins.

To get an idea of how much code this is, see the error message from running dotnet fable ./src/Suave/Suave.fsproj.

e.g.

./src/Suave/WebSocket.fs(225,29): (225,41) error FABLE: System.Memory`1..ctor (static) is not supported by Fable

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants