Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
dotnet-version: ['9.0.x']
dotnet-version: ['10.0.x']
steps:
- uses: actions/checkout@v2

Expand Down
13 changes: 13 additions & 0 deletions Falco.Datastar.sln
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Streaming", "Examples\Strea
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Falco.Datastar.Tests", "test\Falco.Datastar.Tests\Falco.Datastar.Tests.fsproj", "{772A0FC5-A796-4408-9751-53842F8B8C77}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "InputForm", "examples\InputForm\InputForm.fsproj", "{19E053A0-6EA6-4818-AF0D-5BE0B36D55EF}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "environment", "environment", "{13C18205-082E-4DED-9AD4-D3001ABDFECA}"
ProjectSection(SolutionItems) = preProject
global.json = global.json
.github\workflows\build.yml = .github\workflows\build.yml
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -30,6 +38,7 @@ Global
{8E2C0AA3-07E5-40D8-8F16-905F5F1D30AE} = {305B55B6-83D0-453C-A77E-080214FA0657}
{0187E584-68DF-4D8C-874C-FF8E061932DF} = {305B55B6-83D0-453C-A77E-080214FA0657}
{AECB950B-20DD-40C4-9ACA-3A8FF1CFBC05} = {305B55B6-83D0-453C-A77E-080214FA0657}
{19E053A0-6EA6-4818-AF0D-5BE0B36D55EF} = {305B55B6-83D0-453C-A77E-080214FA0657}
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{6BCE09E2-DA8E-44F9-B5EC-C4F76E329471}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
Expand Down Expand Up @@ -64,5 +73,9 @@ Global
{772A0FC5-A796-4408-9751-53842F8B8C77}.Debug|Any CPU.Build.0 = Debug|Any CPU
{772A0FC5-A796-4408-9751-53842F8B8C77}.Release|Any CPU.ActiveCfg = Release|Any CPU
{772A0FC5-A796-4408-9751-53842F8B8C77}.Release|Any CPU.Build.0 = Release|Any CPU
{19E053A0-6EA6-4818-AF0D-5BE0B36D55EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{19E053A0-6EA6-4818-AF0D-5BE0B36D55EF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{19E053A0-6EA6-4818-AF0D-5BE0B36D55EF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{19E053A0-6EA6-4818-AF0D-5BE0B36D55EF}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ Some important notes: Signals defined later in the DOM tree override those defin
## _Creating Signals_

Create signals, which are reactive variables that automatically propagate their value to all references of the signal.
Important: Never use hyphens when naming signals.

### [Ds.signals / Ds.signal : `data-signals`](https://data-star.dev/reference/attributes#data-signals)

Expand Down Expand Up @@ -428,7 +429,6 @@ Each request action can also be provided a number of options, explained in depth
```fsharp
Elem.button [ Ds.onClick (Ds.get ("/endpoint",
{ RequestOptions.Defaults with
IncludeLocal = true;
Headers = [ ("X-Csrf-Token", "JImikTbsoCYQ9...") ]
OpenWhenHidden = true }
)) ] [ Text.raw "Push the Button" ]
Expand Down
90 changes: 90 additions & 0 deletions examples/InputForm/InputForm.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
open Falco
open Falco.Datastar.Selector
open Falco.Datastar.SignalPath
open Falco.Markup
open Falco.Routing
open Falco.Datastar
open Microsoft.AspNetCore.Builder
open Microsoft.AspNetCore.Http

module View =
let template content =
Elem.html [ Attr.lang "en" ] [
Elem.head [] [ Ds.cdnScript ]
Elem.body [] content
]

module App =
let handleIndex : HttpHandler =
let checkbox name =
[ Text.raw $"{name}:"; Elem.input [ Attr.type' "checkbox"; Attr.name "checkboxes"; Attr.value name ] ]
let html =
View.template [
Text.h1 "Example: Input Form"
Elem.div [] [
Elem.form [ Attr.id "myform" ] [
yield! checkbox "foo"
yield! checkbox "bar"
yield! checkbox "baz"
Elem.button [ Ds.onClick (Ds.get("/endpoint1", RequestOptions.With(Form))) ] [ Text.raw "Submit GET Request" ]
Elem.button [ Ds.onClick (Ds.post("/endpoint1", RequestOptions.With(Form))) ] [ Text.raw "Submit POST Request" ]
]
Elem.button [ Ds.onClick (Ds.get("/endpoint1", RequestOptions.With(SelectedForm (sel"#myform")))) ] [
Text.raw "Submit GET request from outside the form"
]
]
Elem.hr []
Elem.div [] [
Elem.form [ Ds.onEvent ("submit", (Ds.post ("/endpoint2", RequestOptions.With(Form)))) ] [
Text.raw "foo:"
Elem.input [ Attr.type' "text"; Attr.name "foo"; Attr.required ]
Elem.button [] [ Text.raw "Submit Form" ]
]
]
]
Response.ofHtml html

let handleEndpointOne (getForm:HttpContext -> RequestData) : HttpHandler = (fun ctx -> task {
let method = ctx.Request.Method
let form = ctx |> getForm
let foo = form.GetStringList("checkboxes")

let alertString = $"Form data received via {method} request: checkboxes = {foo}"
let alertScript = $"alert('{alertString}')"

return Response.ofExecuteScript alertScript ctx
})

let handleEndpointTwo (getForm:HttpContext -> RequestData): HttpHandler = (fun ctx -> task {
let method = ctx.Request.Method
let form = ctx |> getForm
let foo = form.GetString("foo")

let alertString = $"Form data received via {method} request: foo = {foo}"
let alertScript = $"alert('{alertString}')"

return Response.ofExecuteScript alertScript ctx
})


[<EntryPoint>]
let main args =
let wapp = WebApplication.Create()

let endpoints =
[
get "/" App.handleIndex
all "/endpoint1" [
GET, (App.handleEndpointOne Request.getQuery)
POST, (App.handleEndpointOne (fun ctx -> (ctx |> Request.getForm).Result))
]
all "/endpoint2" [
GET, (App.handleEndpointTwo Request.getQuery)
POST, (App.handleEndpointTwo (fun ctx -> (ctx |> Request.getForm).Result))
]
]

wapp.UseRouting()
.UseFalco(endpoints)
.Run()
0 // Exit code
19 changes: 19 additions & 0 deletions examples/InputForm/InputForm.fsproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Include="InputForm.fs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Falco" Version="5.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Falco.Datastar\Falco.Datastar.fsproj" />
</ItemGroup>
<ItemGroup>
<Content Update="wwwroot\style.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>
8 changes: 8 additions & 0 deletions examples/InputForm/appsettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"Urls": "http://localhost:5001",
"Logging": {
"LogLevel": {
"Default": "Information"
}
}
}
2 changes: 1 addition & 1 deletion examples/Streaming/Animation.fs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ let private totalBadAppleFrames = badAppleFrames |> Array.length
backgroundTask {
while true do
currentBadAppleFrame <- (currentBadAppleFrame + 1) % totalBadAppleFrames
do! Task.Delay(TimeSpan.FromMilliseconds(50))
do! Task.Delay(TimeSpan.FromMilliseconds(50L))
} |> ignore

let getCurrentBadAppleFrame () = badAppleFrames[currentBadAppleFrame]
6 changes: 2 additions & 4 deletions examples/Streaming/Streaming.fs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ let handleIndex ctx = task {
Elem.html [] [
Elem.head [ Attr.title "Streaming" ] [
Ds.cdnScript
Elem.script [ Attr.type' "module"; Attr.src "datastar-inspector.js" ] []
Elem.script [ Attr.type' "module" ] []
]
Elem.body [
Ds.signal (SignalPath.userName, user)
Expand All @@ -62,8 +62,6 @@ let handleIndex ctx = task {
Elem.label [ Attr.for' "streamDisplayGuids" ] [ Text.raw "Viewers" ]

Elem.div [ Attr.id ElementIds.streamView ] []

Elem.create "datastar-inspector" [] []
]
]
return Response.ofHtml (html (Guid.NewGuid())) ctx
Expand Down Expand Up @@ -110,7 +108,7 @@ let handleStream ctx = task {
]

do! Response.sseHtmlElements ctx patch
do! Task.Delay (TimeSpan.FromSeconds(10L), ctx.RequestAborted)
do! Task.Delay (TimeSpan.FromMilliseconds(50), ctx.RequestAborted)
finally
userDisplays.AddOrUpdate (signalUser, UserState.displayBadApple, Func<User, UserState, UserState>(fun _ _ -> UserState.loggedOff)) |> ignore
return ()
Expand Down
7 changes: 7 additions & 0 deletions global.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"sdk": {
"version": "10.0.0",
"rollForward": "latestFeature",
"allowPrerelease": false
}
}
Loading