Skip to content

Commit

Permalink
api cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
buntec committed Apr 3, 2023
1 parent 982a5ae commit c33d449
Show file tree
Hide file tree
Showing 11 changed files with 48 additions and 49 deletions.
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Global / onChangedBuildSource := ReloadOnSourceChanges
Global / resolvers += "Sonatype S01 OSS Snapshots" at "https://s01.oss.sonatype.org/content/repositories/snapshots"

ThisBuild / tlBaseVersion := "0.7"
ThisBuild / tlBaseVersion := "0.9"

lazy val scala213 = "2.13.10"
ThisBuild / scalaVersion := scala213
Expand Down
5 changes: 4 additions & 1 deletion examples/src/main/scala/examples/Main.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,7 @@

package examples

object Main extends ff4s.IOEntryPoint(new example2.App)
object Main
extends ff4s.IOEntryPoint(
new example2.App // replace with `example<N>.App` to try the other examples
)
4 changes: 2 additions & 2 deletions examples/src/main/scala/examples/example1/App.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ class App[F[_]: Concurrent] extends ff4s.App[F, State, Action] {

// Build our store by assigning actions to effects.
val store: Resource[F, Store[F, State, Action]] =
ff4s.Store[F, State, Action](State()) { ref => (a: Action) =>
a match {
ff4s.Store[F, State, Action](State()) { ref =>
_ match {
case Action.AddTodo =>
ref.update { state =>
val nextId = state.nextId
Expand Down
12 changes: 6 additions & 6 deletions examples/src/main/scala/examples/example2/Store.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ object Store {

wsSendQ <- Queue.bounded[F, String](100).toResource

store <- ff4s.Store[F, State, Action](State()) { ref => (a: Action) =>
a match {
store <- ff4s.Store[F, State, Action](State()) { ref =>
_ match {
case Action.WebsocketMessageReceived(msg) =>
ref.update(state => state.copy(websocketResponse = Some(msg)))
case Action.SendWebsocketMessage(msg) => wsSendQ.offer(msg)
Expand Down Expand Up @@ -69,7 +69,7 @@ object Store {
"wss://ws.postman-echo.com/raw/",
is =>
is.evalMap { msg =>
store.dispatcher(Action.WebsocketMessageReceived(msg))
store.dispatch(Action.WebsocketMessageReceived(msg))
},
Stream.fromQueueUnterminated(wsSendQ)
)
Expand All @@ -79,7 +79,7 @@ object Store {
_ <- Async[F].background(
(fs2.Stream.emit(()) ++ fs2.Stream.fixedDelay(5.second))
.covary[F]
.evalMap(_ => store.dispatcher(Action.GetActivity))
.evalMap(_ => store.dispatch(Action.GetActivity))
.compile
.drain
)
Expand All @@ -92,7 +92,7 @@ object Store {
}
.changes
.filter(p => p._1 == Ramen.toString && p._2 == 3)
.evalMap(_ => store.dispatcher(Action.Magic))
.evalMap(_ => store.dispatch(Action.Magic))
.compile
.drain
)
Expand All @@ -107,7 +107,7 @@ object Store {
y <- rng.betweenDouble(10.0, 90.0)
} yield (x, y)
}
.evalMap { case (x, y) => store.dispatcher(Action.SetSvgCoords(x, y)) }
.evalMap { case (x, y) => store.dispatch(Action.SetSvgCoords(x, y)) }
.compile
.drain
)
Expand Down
4 changes: 2 additions & 2 deletions examples/src/main/scala/examples/example3/App.scala
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ class App[F[_]](implicit val F: Concurrent[F])
extends ff4s.App[F, State, Action] {

val store: Resource[F, Store[F, State, Action]] =
ff4s.Store[F, State, Action](State()) { ref => (a: Action) =>
a match {
ff4s.Store[F, State, Action](State()) { ref =>
_ match {
case Action.ButtonClick() =>
ref.update(state =>
state.copy(
Expand Down
2 changes: 1 addition & 1 deletion examples/src/main/scala/examples/example5/App.scala
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class App[F[_]](implicit F: Temporal[F]) extends ff4s.App[F, State, Action] {
// increment the counter once per second
Stream
.fixedDelay[F](1.second)
.evalMap(_ => store.dispatcher(Inc(1)))
.evalMap(_ => store.dispatch(Inc(1)))
.compile
.drain
.background
Expand Down
7 changes: 3 additions & 4 deletions ff4s/src/main/scala/ff4s/App.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,12 @@ import cats.effect.kernel.Resource

trait App[F[_], State, Action] {

final val dsl = ff4s.Dsl[F, State, Action]

import dsl._
final implicit val dsl: ff4s.Dsl[F, State, Action] =
ff4s.Dsl[F, State, Action]

def rootElementId = "app"

def root: View[VNode[F]]
def root: dsl.View[VNode[F]]

def store: Resource[F, Store[F, State, Action]]

Expand Down
23 changes: 13 additions & 10 deletions ff4s/src/main/scala/ff4s/Dsl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ class Dsl[F[_], State, Action]
with StyleDsl[F, State, Action]
with ModifierDsl[F, State, Action] { self =>

sealed trait ViewA[A]
private[ff4s] sealed trait ViewA[A]

case class Element(
private[ff4s] case class Element(
tag: String,
children: Seq[VNode[F]],
eventHandlers: Map[String, dom.Event => Option[Action]],
Expand All @@ -52,13 +52,13 @@ class Dsl[F[_], State, Action]
thunkArgs: Option[State => Any]
) extends ViewA[VNode[F]]

case class Literal(html: String) extends ViewA[VNode[F]]
private[ff4s] case class Literal(html: String) extends ViewA[VNode[F]]

case class Text(s: String) extends ViewA[VNode[F]]
private[ff4s] case class Text(s: String) extends ViewA[VNode[F]]

case class Empty() extends ViewA[VNode[F]]
private[ff4s] case class Empty() extends ViewA[VNode[F]]

case class GetState() extends ViewA[State]
private[ff4s] case class GetState() extends ViewA[State]

type View[A] = Free[ViewA, A]

Expand Down Expand Up @@ -107,9 +107,12 @@ class Dsl[F[_], State, Action]

implicit class ViewOfVNodeOps(view: View[VNode[F]]) {

def renderInto(
private[ff4s] def renderInto(
selector: String
)(implicit async: Async[F], store: Resource[F, Store[F, State, Action]]) =
)(implicit
async: Async[F],
store: Resource[F, Store[F, State, Action]]
): F[Nothing] =
Render.apply(self, store)(view, selector)

}
Expand All @@ -120,7 +123,7 @@ class Dsl[F[_], State, Action]
*/
def useState[A](f: State => View[A]): View[A] = getState.flatMap(f)

def element(
private[ff4s] def element(
tag: String,
children: Seq[VNode[F]] = Seq.empty,
eventHandlers: Map[String, dom.Event => Option[Action]] = Map.empty,
Expand Down Expand Up @@ -167,7 +170,7 @@ class Dsl[F[_], State, Action]
thunkArgs: Option[State => Any] = None
)

class ElementBuilder[A](tag: String, void: Boolean) {
private[ff4s] class ElementBuilder[A](tag: String, void: Boolean) {

def apply(
modifiers: Modifier*
Expand Down
8 changes: 2 additions & 6 deletions ff4s/src/main/scala/ff4s/IOEntryPoint.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,12 @@
package ff4s

import cats.effect.IO
import cats.effect.kernel.Async
import cats.effect.unsafe.implicits.global

class IOEntryPoint[State, Action](app: App[IO, State, Action]) {

final def main(args: Array[String]): Unit = {
import app.dsl._
app.root
.renderInto(s"#${app.rootElementId}")(Async[IO], app.store)
final def main(args: Array[String]): Unit =
Render(app.dsl, app.store)(app.root, s"#${app.rootElementId}")
.unsafeRunAndForget()
}

}
4 changes: 2 additions & 2 deletions ff4s/src/main/scala/ff4s/Render.scala
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,13 @@ private[ff4s] object Render {
s <- store
state0 <- Resource.eval(s.state.get)
vnode0 <- Resource.eval(
F.pure(view.foldMap(Compiler(dsl, state0, s.dispatcher)))
F.pure(view.foldMap(Compiler(dsl, state0, s.dispatch _)))
)
proxy0 <- Resource.eval(
F.delay(patch(root, vnode0.toSnabbdom(dispatcher)))
)
_ <- s.state.discrete
.map(state => view.foldMap(Compiler(dsl, state, s.dispatcher)))
.map(state => view.foldMap(Compiler(dsl, state, s.dispatch _)))
.evalMapAccumulate(proxy0) { case (prevProxy, vnode) =>
F.delay(patch(prevProxy, vnode.toSnabbdom(dispatcher))).map((_, ()))
}
Expand Down
26 changes: 12 additions & 14 deletions ff4s/src/main/scala/ff4s/Store.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,60 +26,58 @@ import org.http4s.Uri

trait Store[F[_], State, Action] {

def dispatcher: Store.Dispatcher[F, Action]
def dispatch(action: Action): F[Unit]

def state: Signal[F, State]

}

object Store {

type Dispatcher[F[_], Action] = Action => F[Unit]

def apply[F[_]: Concurrent, State, Action](
initial: State
initialState: State
)(
makeDispatcher: SignallingRef[F, State] => Dispatcher[F, Action]
makeDispatcher: SignallingRef[F, State] => Action => F[Unit]
): Resource[F, Store[F, State, Action]] = for {

state0 <- Resource.eval(SignallingRef.of[F, State](initial))
state0 <- SignallingRef.of[F, State](initialState).toResource

dispatcher0 = makeDispatcher(state0)
dispatcher = makeDispatcher(state0)

} yield (new Store[F, State, Action] {

override def dispatcher: Dispatcher[F, Action] = dispatcher0
override def dispatch(action: Action): F[Unit] = dispatcher(action)

override def state: Signal[F, State] = state0

})

def withRouter[F[_], State, Action](initial: State)(
def withRouter[F[_], State, Action](initialState: State)(
onUriChange: Uri => Action
)(
makeDispatcher: (
SignallingRef[F, State],
Router[F]
) => Dispatcher[F, Action]
) => Action => F[Unit]
)(implicit F: Async[F]) = for {

state0 <- Resource.eval(SignallingRef.of[F, State](initial))
state0 <- SignallingRef.of[F, State](initialState).toResource

history = fs2.dom.Window[F].history[Unit]

router <- Router[F](history)

dispatcher0 = makeDispatcher(state0, router)
dispatcher = makeDispatcher(state0, router)

_ <- router.location.discrete
.evalMap(uri => dispatcher0(onUriChange(uri)))
.evalMap(uri => dispatcher(onUriChange(uri)))
.compile
.drain
.background

} yield new Store[F, State, Action] {

override def dispatcher: Dispatcher[F, Action] = dispatcher0
override def dispatch(action: Action): F[Unit] = dispatcher(action)

override def state: Signal[F, State] = state0

Expand Down

0 comments on commit c33d449

Please sign in to comment.