Added odin logging + store middleware
This commit is contained in:
parent
f294ab7009
commit
d455175044
@ -33,7 +33,9 @@ libraryDependencies ++= Seq(
|
||||
// "io.circe" %%% "circe-config" % "0.8.0",
|
||||
"org.akka-js" %%% "shocon" % "1.0.0",
|
||||
"com.beachape" %%% "enumeratum-circe" % "1.6.1",
|
||||
"com.github.valskalla" %%% "odin-core" % "0.7.0+95-ab4381ae+20201227-1831-SNAPSHOT"
|
||||
"com.github.valskalla" %%% "odin-core" % "0.7.0+95-ab4381ae+20201227-1831-SNAPSHOT",
|
||||
"io.github.cquiroz" %%% "scala-java-time" % "2.1.0",
|
||||
"io.github.cquiroz" %%% "scala-java-time-tzdb" % "2.1.0"
|
||||
// "com.clovellytech" %%% "outwatch-router" % "0.0.9+7-5be0b1a2+20201227-2019-SNAPSHOT"
|
||||
)
|
||||
|
||||
|
@ -4,10 +4,10 @@ import scala.concurrent.duration._
|
||||
|
||||
import colibri.ext.monix._
|
||||
import com.softwaremill.macwire._
|
||||
import io.odin.consoleLogger
|
||||
import monix.bio.Task
|
||||
import monix.eval.Coeval
|
||||
import monix.reactive.Observable
|
||||
import outwatchapp.ui.components.todo.TodoListStore
|
||||
import org.scalajs.dom.raw.Element
|
||||
import outwatch._
|
||||
import outwatch.dsl._
|
||||
@ -15,10 +15,11 @@ import outwatch.router._
|
||||
import outwatchapp.components.CounterDemo
|
||||
import outwatchapp.components.RequestDemo
|
||||
import outwatchapp.components.todo.ChartjsDemo
|
||||
import outwatchapp.pages.HomePage
|
||||
import outwatchapp.util.reactive.WorkerData
|
||||
import outwatchapp.util.reactive.WebWorker
|
||||
import outwatchapp.components.todo.FusejsDemo
|
||||
import outwatchapp.pages.HomePage
|
||||
import outwatchapp.ui.components.todo.TodoListStore
|
||||
import outwatchapp.util.reactive.WebWorker
|
||||
import outwatchapp.util.reactive.WorkerData
|
||||
|
||||
class MainApp(el: Element)(implicit
|
||||
backend: AppTypes.Backend,
|
||||
@ -34,7 +35,7 @@ class MainApp(el: Element)(implicit
|
||||
for {
|
||||
counterDemo <- CounterDemo()
|
||||
chartDemo <- ChartjsDemo()
|
||||
todoStore <- TodoListStore()
|
||||
todoStore <- TodoListStore(consoleLogger[Task]())
|
||||
requestDemo <- RequestDemo(todoStore)
|
||||
demoWorker <- WebWorker[WorkerData]("/worker.js")
|
||||
} yield {
|
||||
|
@ -14,7 +14,7 @@ import scalajs.js
|
||||
@JSImport("bootstrap/dist/css/bootstrap.min.css", JSImport.Namespace)
|
||||
@js.native
|
||||
object BootstrapBundleCss extends js.Object
|
||||
@JSImport("bootstrap", JSImport.Namespace)
|
||||
@JSImport("bootstrap/dist/js/bootstrap.bundle.min.js", JSImport.Namespace)
|
||||
@js.native
|
||||
object BootstrapBundleJs extends js.Object
|
||||
|
||||
|
@ -1,15 +1,18 @@
|
||||
package nova.monadic_sfx.ui.components.todo
|
||||
package outwatchapp.ui.components.todo
|
||||
|
||||
import scala.scalajs.js.annotation.JSExportAll
|
||||
|
||||
import cats.kernel.Eq
|
||||
import com.softwaremill.quicklens._
|
||||
import io.circe.generic.JsonCodec
|
||||
import io.odin.Logger
|
||||
import monix.bio.Task
|
||||
import nova.monadic_sfx.util.reactive.store.Reducer
|
||||
import nova.monadic_sfx.util.reactive.store.Store
|
||||
import outwatchapp.util.reactive.store.Middlewares.actionLoggerMiddleware
|
||||
import outwatchapp.util.reactive.store.Reducer
|
||||
import outwatchapp.util.reactive.store.Store
|
||||
|
||||
@JSExportAll
|
||||
@JsonCodec
|
||||
case class Todo(id: Int, content: String)
|
||||
object Todo {
|
||||
implicit val eqForTodo = Eq.fromUniversalEquals[Todo]
|
||||
@ -37,18 +40,16 @@ object TodoListStore {
|
||||
implicit val eqForState = Eq.fromUniversalEquals[State]
|
||||
}
|
||||
|
||||
def reducer()(
|
||||
def reducer(logger: Logger[Task])(
|
||||
state: State,
|
||||
action: Action
|
||||
): (State, Option[Task[Action]]) =
|
||||
action match {
|
||||
case Init => (state, None)
|
||||
case Add(content) =>
|
||||
println("hello")
|
||||
val nextAction = Some(for {
|
||||
// do some validation
|
||||
// _ <- logger.debug(s"Received $content")
|
||||
_ <- Task(println(s"Received $content"))
|
||||
res <- Task.pure(InternalAdd(content))
|
||||
} yield res)
|
||||
(state, nextAction)
|
||||
@ -68,19 +69,21 @@ object TodoListStore {
|
||||
.using(_ :+ Todo(state.counter, content))
|
||||
.modify(_.counter)
|
||||
.using(_ + 1)
|
||||
(nextState, Some(Task.pure(End)))
|
||||
(nextState, Some(logger.debug(s"Received $content") >> Task.pure(End)))
|
||||
case End => (state, None)
|
||||
}
|
||||
|
||||
def apply(): Task[Store[Action, State]] =
|
||||
def apply(logger: Logger[Task]): Task[Store[Action, State]] =
|
||||
Task.deferAction(implicit s =>
|
||||
for {
|
||||
logMware <- actionLoggerMiddleware[Action, State](logger, "TodoStore")
|
||||
store <-
|
||||
Store
|
||||
.createL[Action, State](
|
||||
Init,
|
||||
State(Vector.empty[Todo], 0),
|
||||
Reducer.withOptionalEffects(reducer() _)
|
||||
Reducer.withOptionalEffects(reducer(logger) _),
|
||||
Seq(logMware)
|
||||
)
|
||||
} yield store
|
||||
)
|
||||
|
@ -2,11 +2,17 @@ package outwatchapp.util.reactive.store
|
||||
|
||||
import java.time.LocalDateTime
|
||||
|
||||
import io.circe.Encoder
|
||||
import io.circe.Printer
|
||||
import io.circe.generic.JsonCodec
|
||||
// object Middleware {
|
||||
// def apply[A,M,T](ob: Observable[(A,M)], cb: (A,M) => T): Observable[(A,M)] = ob
|
||||
// }
|
||||
import io.circe.syntax._
|
||||
import io.odin.Logger
|
||||
import io.odin.LoggerMessage
|
||||
import io.odin.formatter.options.PositionFormat
|
||||
import io.odin.formatter.options.ThrowableFormat
|
||||
import io.odin.meta.Render
|
||||
import monix.bio.Task
|
||||
import monix.reactive.Observable
|
||||
|
||||
@JsonCodec
|
||||
final case class StoreInfo[A](
|
||||
@ -17,6 +23,42 @@ final case class StoreInfo[A](
|
||||
|
||||
object StoreInfo {
|
||||
val printer = Printer.noSpaces
|
||||
implicit def render[T: Encoder]: Render[StoreInfo[T]] =
|
||||
new Render[StoreInfo[T]] {
|
||||
override def render(m: StoreInfo[T]): String = printer.print(m.asJson)
|
||||
}
|
||||
}
|
||||
|
||||
object Middlewares {}
|
||||
object Middlewares {
|
||||
|
||||
val format = create(ThrowableFormat.Default, PositionFormat.Full)
|
||||
|
||||
def create(
|
||||
throwableFormat: ThrowableFormat,
|
||||
positionFormat: PositionFormat
|
||||
): io.odin.formatter.Formatter = (msg: LoggerMessage) => msg.message.value
|
||||
|
||||
def actionStateLoggerMiddleware[A, M](
|
||||
logger: Logger[Task]
|
||||
): Task[Middleware[A, M]] =
|
||||
Task.deferAction(implicit s =>
|
||||
Task((obs: Observable[(A, M)]) =>
|
||||
obs.doOnNextF { case (a, m) =>
|
||||
logger.debug(s"Received action $a with state $m")
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
def actionLoggerMiddleware[A: Encoder, M](
|
||||
logger: Logger[Task],
|
||||
name: String
|
||||
): Task[Middleware[A, M]] =
|
||||
Task.deferAction(implicit s =>
|
||||
Task((obs: Observable[(A, M)]) =>
|
||||
obs.doOnNextF { case (a, _) =>
|
||||
Task(LocalDateTime.now())
|
||||
.flatMap(curTime => logger.debug(StoreInfo(name, a, curTime)))
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user