diff options
author | Hayleigh Thompson <me@hayleigh.dev> | 2022-05-14 06:44:44 +0100 |
---|---|---|
committer | Hayleigh Thompson <me@hayleigh.dev> | 2022-05-14 06:44:44 +0100 |
commit | ad02bc801e28b21f052e8a48f744c900f2ccc975 (patch) | |
tree | b85c277fde9ce4d9872d5f99d535b4d682d09ed4 | |
parent | 25a287bf529b66d8235b387301881dca0b1e9063 (diff) | |
download | lustre-ad02bc801e28b21f052e8a48f744c900f2ccc975.tar.gz lustre-ad02bc801e28b21f052e8a48f744c900f2ccc975.zip |
:truck: Move FFI code to project root.
-rw-r--r-- | src/lustre.gleam | 23 | ||||
-rw-r--r-- | src/lustre.mjs (renamed from src/lustre/ffi.mjs) | 5 | ||||
-rw-r--r-- | src/lustre/element.gleam | 10 | ||||
-rw-r--r-- | src/lustre/event.gleam | 2 |
4 files changed, 30 insertions, 10 deletions
diff --git a/src/lustre.gleam b/src/lustre.gleam index da0730b..adba034 100644 --- a/src/lustre.gleam +++ b/src/lustre.gleam @@ -5,6 +5,7 @@ import lustre/element import lustre/attribute +import gleam/result // TYPES ----------------------------------------------------------------------- @@ -22,6 +23,9 @@ pub opaque type Program(state, action) { pub type Element(action) = element.Element(action) pub type Attribute(action) = attribute.Attribute(action) +pub type Error { + ElementNotFound +} // These types aren't exposed, but they're just here to try and shrink the type // annotations for `Program` and `program` a little bit. When generating docs, @@ -39,7 +43,8 @@ type Render(state, action) = fn (state) -> Element(action) /// you can still create components with local state. /// /// Basic lustre programs don't have any *global* application state and so the -/// plumbing is a lot simpler. If you find yourself passing state +/// plumbing is a lot simpler. If you find yourself passing lot's state of state +/// around, you might want to consider using `application` instead. /// pub fn basic (element: Element(any)) -> Program(Nil, any) { let init = Nil @@ -53,7 +58,10 @@ pub fn basic (element: Element(any)) -> Program(Nil, any) { /// start with some initial `state`, a function to update that state, and then /// a render function to derive our program's view from that state. /// -/// +/// Events produced by elements are passed a `dispatch` function that can be +/// used to emit actions that trigger your `update` function to be called and +/// trigger a rerender. +/// pub fn application (init: state, update: Update(state, action), render: Render(state, action)) -> Program(state, action) { Program(init, update, render) } @@ -61,6 +69,15 @@ pub fn application (init: state, update: Update(state, action), render: Render(s // EFFECTS --------------------------------------------------------------------- +/// Once you have created a program with either `basic` or `application`, you +/// need to actually start it! This function will mount your program to the DOM +/// node that matches the query selector you provide. /// -pub external fn start (program: Program(state, action), selector: String) -> Nil +pub fn start (program: Program(state, action), selector: String) -> Result(Nil, Error) { + mount(program, selector) + |> result.replace_error(ElementNotFound) +} + + +external fn mount (program: Program(state, action), selector: String) -> Result(Nil, Nil) = "./lustre/ffi.mjs" "mount" diff --git a/src/lustre/ffi.mjs b/src/lustre.mjs index 594b71f..2352f01 100644 --- a/src/lustre/ffi.mjs +++ b/src/lustre.mjs @@ -1,5 +1,6 @@ import * as React from 'react' import * as ReactDOM from 'react-dom' +import * as Gleam from './gleam.mjs' // ----------------------------------------------------------------------------- @@ -16,7 +17,7 @@ export const mount = ({ init, update, view }, selector) => { 'to your script tag to make sure that can\'t happen.' ].join('\n')) - return + return new Gleam.Error() } const App = React.createElement(() => { @@ -26,6 +27,8 @@ export const mount = ({ init, update, view }, selector) => { }) ReactDOM.render(App, root) + + return new Gleam.Ok() } // ----------------------------------------------------------------------------- diff --git a/src/lustre/element.gleam b/src/lustre/element.gleam index e5bb180..48784ee 100644 --- a/src/lustre/element.gleam +++ b/src/lustre/element.gleam @@ -16,7 +16,7 @@ pub external type Element(action) /// child elements. /// pub external fn node (tag: String, attributes: List(Attribute(action)), children: List(Element(action))) -> Element(action) - = "./ffi.mjs" "node" + = "../lustre.mjs" "node" /// A stateful element is exactly what it sounds like: some element with local /// encapsulated state! The `render` function we must provide is called with the @@ -27,18 +27,18 @@ pub external fn node (tag: String, attributes: List(Attribute(action)), children /// Those are just regular Gleam functions that return `Element`s! /// pub external fn stateful (init: state, render: fn (state, fn (state) -> Nil) -> Element(action)) -> Element(action) - = "./ffi.mjs" "stateful" + = "../lustre.mjs" "stateful" /// A fragment doesn't appear in the DOM, but allows us to treat a list of elements /// as if it were a single one. /// pub external fn fragment (children: List(Element(action))) -> Element(action) - = "./ffi.mjs" "fragment" + = "../lustre.mjs" "fragment" /// Render a Gleam string as an HTML text node. /// pub external fn text (content: String) -> Element(action) - = "./ffi.mjs" "text" + = "../lustre.mjs" "text" // MANIPULATIONS --------------------------------------------------------------- @@ -46,7 +46,7 @@ pub external fn text (content: String) -> Element(action) /// Transforms the actions produced by some element. /// pub external fn map (element: Element(a), f: fn (a) -> b) -> Element(b) - = "./ffi.mjs" "map" + = "../lustre.mjs" "map" // CONSTRUCTING NODES ---------------------------------------------------------- diff --git a/src/lustre/event.gleam b/src/lustre/event.gleam index 75c540b..088dfd0 100644 --- a/src/lustre/event.gleam +++ b/src/lustre/event.gleam @@ -2,7 +2,7 @@ import gleam/dynamic.{ Dynamic } import lustre/attribute.{ Attribute } pub external fn ignore () -> action - = "./ffi.mjs" "ignore" + = "../lustre.mjs" "ignore" pub fn on (name: String, handler: fn (Dynamic, fn (action) -> Nil) -> Nil) -> Attribute(action) { |