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
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ update model = case _ of

-- | `view` is called whenever the model is updated
view :: Model -> Html Message
view model = HE.main "main" [
HE.button [HA.onClick Decrement] "-",
view model = HE.main [HA.id "main"] [
HE.button [HA.onClick Decrement] [HE.text "-"],
HE.text $ show model,
HE.button [HA.onClick Increment] "+"
HE.button [HA.onClick Increment] [HE.text "+"]
]

-- | Events that come from outside the `view`
Expand Down
2 changes: 1 addition & 1 deletion benchmarks/js-framework-benchmark/keyed/index.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
require('./dce-output/Main').main();
require('./output-es/Main').main();
13 changes: 7 additions & 6 deletions benchmarks/js-framework-benchmark/keyed/package.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
{
"name": "js-framework-benchmark-keyed-flame",
"sideEffects": false,
"version": "1.0.0",
"version": "1.6.0",
"description": "Purescript Flame JS Benchmark",
"main": "index.js",
"js-framework-benchmark": {
"frameworkVersion": "1.0.0"
"frameworkVersion": "1.6.0"
},
"scripts": {
"postinstall": "spago install",
"clean": "rm -rf dist output .spago node_modules",
"build": "spago build",
"build-prod": "spago build --purs-args '--codegen corefn,js' && zephyr -f Main.main && webpack --config=webpack.flame.config.js"
"build-prod": "spago build && webpack --config=webpack.flame.config.js"
},
"keywords": [
"purescript",
Expand All @@ -25,9 +25,10 @@
"url": "https://github.com/krausest/js-framework-benchmark.git"
},
"devDependencies": {
"purescript": "0.14.4",
"spago": "0.20.3",
"webpack": "^4.44.1",
"purescript": "0.15.15",
"purs-backend-es": "^1.4.3",
"spago": "0.21.0",
"webpack": "^4.47.0",
"webpack-cli": "^3.3.12"
}
}
4 changes: 2 additions & 2 deletions benchmarks/js-framework-benchmark/keyed/packages.dhall
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
let upstream =
https://github.com/purescript/package-sets/releases/download/psc-0.15.0-20220527/packages.dhall
sha256:15dd8041480502850e4043ea2977ed22d6ab3fc24d565211acde6f8c5152a799
https://github.com/purescript/package-sets/releases/download/psc-0.15.15-20250904/packages.dhall
sha256:65df863430bac51dc71eb6c31d60f837bccf3837ddae929e1bc53830d299ab37

let overrides = {=}

Expand Down
18 changes: 11 additions & 7 deletions benchmarks/js-framework-benchmark/keyed/spago.dhall
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
{ name = "js-framework-benchmark-flame"
, dependencies = [
"flame",
"aff",
"arrays",
"effect",
"maybe",
"prelude" ]
, dependencies =
[ "aff"
, "arrays"
, "effect"
, "flame"
, "maybe"
, "prelude"
, "tuples"
, "web-dom"
]
, packages = ./packages.dhall
, sources = [ "src/**/*.purs" ]
, backend = "npx purs-backend-es build"
}
265 changes: 134 additions & 131 deletions benchmarks/js-framework-benchmark/keyed/src/Main.purs
Original file line number Diff line number Diff line change
Expand Up @@ -18,161 +18,164 @@ import Flame.Html.Element as HE
import Flame.Types (NodeData)
import Web.DOM.ParentNode (QuerySelector(..))

data Message =
Create Int |
DisplayCreated (Array Row) |
AppendOneThousand |
DisplayAppended (Array Row) |
UpdateEveryTenth |
Clear |
Swap |
Remove Int |
Select Int

type Model = {
rows :: Array Row,
lastID :: Int
}

type Row = {
id :: Int,
label :: String,
selected :: Boolean
}

type Button = {
id :: String,
label :: String,
message :: Message
}

foreign import createRandomNRows_ :: EffectFn2 Int Int (Array Row)

createRandomNRows :: Int -> Int -> Aff (Array Row)
data Message
= Create Int
| DisplayCreated (Array Row)
| AppendOneThousand
| DisplayAppended (Array Row)
| UpdateEveryTenth
| Clear
| Swap
| Remove Int
| Select Int

type Model =
{ rows Array Row
, lastID Int
}

type Row =
{ id Int
, label String
, selected Boolean
}

type Button =
{ id String
, label String
, message Message
}

foreign import createRandomNRows_ EffectFn2 Int Int (Array Row)

createRandomNRows Int Int Aff (Array Row)
createRandomNRows n lastID = liftEffect (EU.runEffectFn2 createRandomNRows_ n lastID)

main :: Effect Unit
main = F.mount_ (QuerySelector "body") {
model: model,
subscribe: [],
view,
update
}

model :: Model
model = {
rows: [],
lastID: 0
}

view :: Model -> Html Message
view model = HE.div [HA.class' "container"] [
jumbotron,
HE.table [HA.class' "table table-hover table-striped test-data"] [
HE.tbody_ (map renderLazyRow model.rows)
],
footer
]

jumbotron :: Html Message
jumbotron = HE.div [ HA.class' "jumbotron" ] [
HE.div [ HA.class' "row" ] [
HE.div [ HA.class' "col-md-6" ] [
HE.h1_ [ HE.text "Flame 1.0.0 (keyed)" ]
],
HE.div [ HA.class' "col-md-6" ] [
map renderActionButton buttons
]
]
]

renderActionButton :: Button -> Html Message
renderActionButton button = HE.div [ HA.class' "col-sm-6 smallpad" ] [
HE.button [
HA.class' "btn btn-primary btn-block",
HA.id button.id,
HA.createAttribute "ref" "text",
HA.onClick button.message
] [ HE.text button.label ]
]

buttons :: Array Button
buttons = [
{ id: "run", label: "Create 1,000 rows", message: Create 1000 },
{ id: "runlots", label: "Create 10,000 rows", message: Create 10000 },
{ id: "add", label: "Append 1,000 rows", message: AppendOneThousand },
{ id: "update", label: "Update every 10th row", message: UpdateEveryTenth },
{ id: "clear", label: "Clear", message: Clear },
{ id: "swaprows", label: "Swap Rows", message: Swap }
]

renderLazyRow :: Row -> Html Message
main Effect Unit
main = F.mount_ (QuerySelector "body")
{ model: model
, subscribe: []
, view
, update
}

model Model
model =
{ rows: []
, lastID: 0
}

view Model Html Message
view model = HE.div [ HA.class' "container" ]
[ jumbotron
, HE.table [ HA.class' "table table-hover table-striped test-data" ]
[ HE.tbody_ (map renderLazyRow model.rows)
]
, footer
]

jumbotron Html Message
jumbotron = HE.div [ HA.class' "jumbotron" ]
[ HE.div [ HA.class' "row" ]
[ HE.div [ HA.class' "col-md-6" ]
[ HE.h1_ [ HE.text "Flame 1.0.0 (keyed)" ]
]
, HE.div [ HA.class' "col-md-6" ] (map renderActionButton buttons)

]
]

renderActionButton ∷ Button → Html Message
renderActionButton button = HE.div [ HA.class' "col-sm-6 smallpad" ]
[ HE.button
[ HA.class' "btn btn-primary btn-block"
, HA.id button.id
, HA.createAttribute "ref" "text"
, HA.onClick button.message
]
[ HE.text button.label ]
]

buttons Array Button
buttons =
[ { id: "run", label: "Create 1,000 rows", message: Create 1000 }
, { id: "runlots", label: "Create 10,000 rows", message: Create 10000 }
, { id: "add", label: "Append 1,000 rows", message: AppendOneThousand }
, { id: "update", label: "Update every 10th row", message: UpdateEveryTenth }
, { id: "clear", label: "Clear", message: Clear }
, { id: "swaprows", label: "Swap Rows", message: Swap }
]

renderLazyRow Row Html Message
renderLazyRow row = HE.lazy (Just (show row.id)) renderRow row

renderRow :: Row -> Html Message
renderRow row = HE.tr [ HA.class' { "danger": row.selected }, HA.key (show row.id)] [
HE.td colMd1 [ HE.text (show row.id) ],
HE.td colMd4 [ HE.a [ HA.onClick (Select row.id) ] [ HE.text row.label ] ],
HE.td colMd1 [ HE.a [ HA.onClick (Remove row.id) ] removeIcon ],
spacer
]
renderRow Row Html Message
renderRow row = HE.tr [ HA.class' { "danger": row.selected }, HA.key (show row.id) ]
[ HE.td colMd1 [ HE.text (show row.id) ]
, HE.td colMd4 [ HE.a [ HA.onClick (Select row.id) ] [ HE.text row.label ] ]
, HE.td colMd1 [ HE.a [ HA.onClick (Remove row.id) ] removeIcon ]
, spacer
]

removeIcon :: Array (Html Message)
removeIcon = [
HE.span' [ HA.class' "glyphicon glyphicon-remove", HA.createAttribute "aria-hidden" "true"]
]
removeIcon Array (Html Message)
removeIcon =
[ HE.span' [ HA.class' "glyphicon glyphicon-remove", HA.createAttribute "aria-hidden" "true" ]
]

colMd1 :: Array (NodeData Message)
colMd1 Array (NodeData Message)
colMd1 = [ HA.class' "col-md-1" ]

colMd4 :: Array (NodeData Message)
colMd4 Array (NodeData Message)
colMd4 = [ HA.class' "col-md-4" ]

spacer :: Html Message
spacer Html Message
spacer = HE.td' [ HA.class' "col-md-6" ]

footer :: Html Message
footer Html Message
footer = HE.span' [ HA.class' "preloadicon glyphicon glyphicon-remove", HA.createAttribute "aria-hidden" "true" ]

update :: Update Model Message
update Update Model Message
update model =
case _ of
Create amount -> model /\ [map (\rows -> Just (DisplayCreated rows)) (createRandomNRows amount model.lastID)]
DisplayCreated rows -> F.noMessages (model { lastID = model.lastID + DA.length rows, rows = rows })
case _ of
Create amount model /\ [ map (\rows Just (DisplayCreated rows)) (createRandomNRows amount model.lastID) ]
DisplayCreated rows F.noMessages (model { lastID = model.lastID + DA.length rows, rows = rows })

AppendOneThousand ->
let amount = 1000
in model /\ [map (\rows -> Just (DisplayAppended rows)) (createRandomNRows amount model.lastID)]
DisplayAppended newRows -> F.noMessages (model { lastID = model.lastID + DA.length newRows, rows = model.rows <> newRows })
AppendOneThousand →
let
amount = 1000
in
model /\ [ map (\rows → Just (DisplayAppended rows)) (createRandomNRows amount model.lastID) ]
DisplayAppended newRows → F.noMessages (model { lastID = model.lastID + DA.length newRows, rows = model.rows <> newRows })

UpdateEveryTenth -> F.noMessages model { rows = DA.mapWithIndex updateLabel model.rows }
UpdateEveryTenth F.noMessages model { rows = DA.mapWithIndex updateLabel model.rows }

Clear -> F.noMessages (model { rows = [] })
Clear F.noMessages (model { rows = [] })

Swap ->
F.noMessages
(case swapRows model.rows 1 998 of
Nothing -> model
Just swappedRows -> model { rows = swappedRows })
Swap →
F.noMessages
( case swapRows model.rows 1 998 of
Nothing → model
Just swappedRows → model { rows = swappedRows }
)

Remove id -> F.noMessages (model { rows = DA.filter (\r -> r.id /= id) model.rows })
Remove id F.noMessages (model { rows = DA.filter (\r r.id /= id) model.rows })

Select id -> F.noMessages (model { rows = map (select id) model.rows })
Select id F.noMessages (model { rows = map (select id) model.rows })

updateLabel index row =
if index `mod` 10 == 0 then
row { label = row.label <> " !!!" }
else
row
if index `mod` 10 == 0 then
row { label = row.label <> " !!!" }
else
row

swapRows arr index otherIndex = do
rowA <- arr !! index
rowB <- arr !! otherIndex
arrA <- DA.updateAt index rowB arr
arrB <- DA.updateAt otherIndex rowA arrA
pure arrB
rowA arr !! index
rowB arr !! otherIndex
arrA DA.updateAt index rowB arr
arrB DA.updateAt otherIndex rowA arrA
pure arrB

select id row
| row.id == id = row { selected = true }
| row.selected = row { selected = false }
| otherwise = row
| row.id == id = row { selected = true }
| row.selected = row { selected = false }
| otherwise = row
2 changes: 1 addition & 1 deletion benchmarks/js-framework-benchmark/non-keyed/index.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
require('./dce-output/Main').main();
require('./output-es/Main').main();
Loading