grmble / purescript-bonsai Goto Github PK
View Code? Open in Web Editor NEWFunctional web programming in Purescript. Heavily inspired by Elm
License: MIT License
Functional web programming in Purescript. Heavily inspired by Elm
License: MIT License
The current render function of Bonsai.Html always produces a single Html node - VNode msg
.
Sometimes you need several html nodes though, and they end up wrapped in an artificial div.
I want a function render'
that produces Array (VNode msg
. Single results would be wrapped in an array, array results would be returned as is.
Lazy rendering to the Virtual Dom should be supported by the markup DSL.
Nice to have: enable markup DSL attributes and styles for the top element of keyedElement
Pros:
Cons:
Bonsai.DOM should have simple APIs for accessing local/session storage.
There are implementations, but Bonsai.DOM can be used with JSDOM
Working with (Maybe Element) in the Eff monad is cumbersome. Compare and contrast with F - it's a joy to work with.
So: Change Bonsai.DOM to use F. Also move out any dependencies on Bonsai.VirtualDom or Bonsai.Types. It should be possible to import Bonsai.DOM from those packages after the split.
innerHTML
querySelector
/querySelectorAll
Currently the effects used by Bonsai.Core are exposed to the client.
It could be argued that this is an implementation detail - the client does not need to know exactly what effects are used internally. Changes are also less likely to break existing client code - less major releases in the long run. Plus the types would become muss less cumbersome to type.
Proposal: make a BONSAI effect, do not expose any other effects in externally visible code.
Currently it's only in Bonsai.Types, if the user does not know about it he won't find it ...
Data.Foreign.F composes well for decoding browser events, and it is a full monad. The approach used currently (composing event handlers by making Property a functor) does not scale well, and I don't thing there is a monad instance - so this can't be used to raise errors.
Change event handling code to compose via (F msg).
This is the opposite of #2
Updating the page is done synchronously right now. Elm does it via requestAnimationFrame.
There should be tests for
There should also be a testing framework for applications using bonsai.
This testing framework should probably be in a different project
so it can be a dev-dependency.
Needed for the Form DSL
Starting background or init tasks from outside the update function is cumbersome - the types are ugly and you need to use coerce if any effects are in place.
In particular, this should be possible using only one function (instead of taskContext/emitMessages as of now). Since it issues a command, issueCommand ?
It should be possible to obtain a TaskContext for a Program, to start emitting Tasks from outside the program. Compare to Sub in Elm - e.g. a long running task that emits a message every second, or provide callbacks to external javascript libraries.
Currently, it is only possible to create TaskCmd from an event handler or from the update function (and this would need to be triggered by an initial event).
Directly producing VirtualDom nodes works, but the view code reads horrible.
Better alternatives would be something like the API from the Purescript-by-example book, or a modified Smolder API.
I don't think using Smolder directly would work. They have mutating event handlers and don't need to encode the type of the emitted messages in the type of the emitted nodes.
I would like to borrow their syntax, though.
Let's say an application wants to have something like the Elm Debugger (i.e. display a list of messages, allow to import/export this list, and be able to go backwards and forwards having the app display the state).
One approach would be
Tasks that do DOM manipulation may be run before their target elements exist - they will be rendered the next time the model is rendered, but that happens in a requestAnimationFrame.
It would be useful to have a primitive that delays into a requestAnimationFrame where the Bonsai program state is clean (a model change will make it dirty, a render will make it clean again - this is already in Core.purs)
Hi,
your project looks really cool. I'm just curious: What makes it different from purescript-pux?
Do away with the EventDecoder / CmdDecoder distinction.
on
should take an event handler, the conversion from F to whatever is needed for the callbacks should be handled internally.
... which does not work in Edge.
It should be appendChild of course.
Client Routing is a thing. 2 things are needed
I'd put in the Cmd now. The parser should probably be in its own package
That way, a loading message could be displayed while the compiled javascript is loaded by the browser
It's just Tuple emptyCommand
now. And the name is backwards - it takes a plainResult and procudes a full/cmdFull/whatever one. If we have to have this, it should be fromPlainResult
If Property were a monad, event handling code would be simpler and more powerful.
EventDecoder might become unnecessary.
Two example apps with comparable page complexity
forms-demo uses an additional level of indirection in the html generation, but I suspect it's the number of event handlers on the pages.
There is lots of Elm code in the documentation comments of VirtualDom.purs
Should be replaced by purescript/bonsai examples or deleted.
Hi,
Just one question:
Does it happens to have a minimal working example?
module Examples.Counter where
import Prelude
import Bonsai (domElementById, program, text)
import Bonsai.Types (Cmd(..))
import Control.Monad.Eff.Console (error)
import DOM.Node.Types (ElementId(..))
import Data.Maybe (Maybe(..))
data Msg = Inc | Dec
type Model = Int
programContainer = do
domElementById $ ElementId "counter"
initialState :: Model
initialState = 0
update model msg = { model : model, cmd : NoCmd }
view = show >>> text
main = do
mContainer <- programContainer
case mContainer of
Just c -> program c update view initialState
Nothing -> error "no container with specified id"
I came up with this, so far, but not sure how to go further
Thanks!
I just noticed that Elm has the update function arguments in the order Msg -> Model.
This is actually much better than Model -> Msg. Applying only the message argument leads to a natural operation on the model.
This will break every program.
Things to think about:
Since there is no Reader involved anymore ...
Brainstorming:
Effectful commands should be supported. Examples would be setting the focus element on the page or triggering an Ajax request and updating the page after it completes.
This would make helpers at the Cmd level (e.g. focusCmd, focusSelectCmd) much much nicer to use in combination with other Cmds, e.g animations)
I think the current design of the Cmd ADT could be made into a Monoid and/or Applicative. Ap could be even made parallel. Monad should possible but would be a lot of work, and confusing to use - all those ansychronous emits.
Current aim: sequential <>, parallel <*>. No monad.
Support attaching (bonsai) event handlers on non-bonsai elements.
E.g. general page layout html not generated by bonsai with links/buttons that should issue bonsai commands.
The events seem to fire ... something else is wrong here
The browser DOM has 2 ways of manipulating DOM attributes: the DOM way, with methods like get/set/removeAttribute, and via properties of the JS object.
n.setAttribute('type', 'text');
n['type'] = 'text';
The Elm html library uses mostly properties (as does Bonsai.Html.Attributes - it's basically a transliteration of the Elm library). There are some attributes as well though - I presume because the property access would not work.
Some properties that maybe should be attributes:
type
: IE errors when input type properties are set that it can't handle. E.g. using a html date input.pattern
: empty phantom patterns can show up on input fields, these will never validatefor
: empty for element will prevent the associated checkbox from workingNotable properties that MUST stay properties:
value
: setting the value after every model change only works with the property. My very first bonsai mistake, could not get it to work until I noticed that Elm is using the property ...onSubmit puts all the input values in a map without checking the input's checked attribute.
E.g. checkboxes are always reported as on.
If someone really needs the old onSubmit, they can make their own alias - it's a one liner.
Tasks that are executed only for side-effects are implemented using emittingTask at the moment.
However, this seems much more common than are real emittingTask that emits multiple commands.
A convenience helper unitTask might be useful.
Common options could be curried.
This all-in-one package is getting a little unwieldy. Also there is a chicken-egg problem with a testing library - an external library depending on the all-in-one package can't be used for testing inside the all-in-one package.
Make sure to link the new packages to the new project home page.
Optional: All modules under their respective root module. E.g. Bonsai.EventHandlers would become Bonsai.Core.EventHandlers. But all these renames would pollute the pursuit namespace. Maybe not a good idea.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.