aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHayleigh Thompson <me@hayleigh.dev>2022-05-14 06:44:44 +0100
committerHayleigh Thompson <me@hayleigh.dev>2022-05-14 06:44:44 +0100
commitad02bc801e28b21f052e8a48f744c900f2ccc975 (patch)
treeb85c277fde9ce4d9872d5f99d535b4d682d09ed4
parent25a287bf529b66d8235b387301881dca0b1e9063 (diff)
downloadlustre-ad02bc801e28b21f052e8a48f744c900f2ccc975.tar.gz
lustre-ad02bc801e28b21f052e8a48f744c900f2ccc975.zip
:truck: Move FFI code to project root.
-rw-r--r--src/lustre.gleam23
-rw-r--r--src/lustre.mjs (renamed from src/lustre/ffi.mjs)5
-rw-r--r--src/lustre/element.gleam10
-rw-r--r--src/lustre/event.gleam2
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) {