feat: use rescala by default for reactivity
downscale operations, supporting multiple reactive backends is too complex
This commit is contained in:
parent
07e4e4006a
commit
ec478533c3
11 changed files with 35 additions and 57 deletions
28
build.sbt
28
build.sbt
|
@ -36,7 +36,10 @@ lazy val dom = crossProject(JSPlatform, JVMPlatform)
|
|||
.in(file("./dom"))
|
||||
.settings(
|
||||
name := "sfs-dom",
|
||||
version := "0.1.0-alpha"
|
||||
version := "0.1.0-alpha",
|
||||
libraryDependencies ++= Seq(
|
||||
"de.tu-darmstadt.stg" %% "rescala" % "0.35.1"
|
||||
)
|
||||
)
|
||||
.jvmSettings(
|
||||
libraryDependencies ++= Seq(
|
||||
|
@ -57,26 +60,3 @@ lazy val sfs = crossProject(JSPlatform, JVMPlatform)
|
|||
version := "0.1.0-alpha"
|
||||
)
|
||||
.dependsOn(dom)
|
||||
|
||||
lazy val sfsRouter = crossProject(JSPlatform, JVMPlatform)
|
||||
.crossType(CrossType.Pure)
|
||||
.in(file("./router"))
|
||||
.settings(
|
||||
name := "sfs-router",
|
||||
version := "0.1.0-alpha"
|
||||
)
|
||||
|
||||
lazy val sfsReScala = crossProject(JSPlatform, JVMPlatform)
|
||||
.crossType(CrossType.Pure)
|
||||
.in(file("./reactive/rescala"))
|
||||
.settings(
|
||||
name := "sfs-rescala",
|
||||
version := "0.1.0-alpha"
|
||||
)
|
||||
|
||||
lazy val sfsZio = project
|
||||
.in(file("./integrations/zio"))
|
||||
.settings(
|
||||
name := "sfs-zio",
|
||||
version := "0.1.0-alpha"
|
||||
)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package top.davidon.sfs.dom
|
||||
|
||||
import rescala.default.Signal
|
||||
import top.davidon.sfs.dom.codecs.*
|
||||
import top.davidon.sfs.dom.defs.attrs.{AriaAttrs, HtmlAttrs, SvgAttrs}
|
||||
import top.davidon.sfs.dom.defs.complex.{ComplexHtmlKeys, ComplexSvgKeys}
|
||||
|
@ -7,6 +8,7 @@ import top.davidon.sfs.dom.defs.eventProps.GlobalEventProps
|
|||
import top.davidon.sfs.dom.defs.props.HtmlProps
|
||||
import top.davidon.sfs.dom.defs.tags.{HtmlTags, SvgTags}
|
||||
import top.davidon.sfs.dom.plain.PlainValue
|
||||
import top.davidon.sfs.dom.reactive.ReactiveValue
|
||||
|
||||
trait ScalaFullStackDOM
|
||||
extends HtmlTags
|
||||
|
@ -42,4 +44,11 @@ trait ScalaFullStackDOM
|
|||
def apply(from: Iterable[String]): PlainValue[Iterable[String], String] =
|
||||
PlainValue(from, IterableAsSpaceSeparatedStringCodec)
|
||||
}
|
||||
|
||||
given signalToVal: Conversion[Signal[String], ReactiveValue[String, String]]
|
||||
with {
|
||||
def apply(from: Signal[String]): ReactiveValue[String, String] = {
|
||||
ReactiveValue(from, StringAsIsCodec)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
package top.davidon.sfs.dom.keys
|
||||
import rescala.default.Signal
|
||||
import top.davidon.sfs.dom.codecs.Codec
|
||||
import top.davidon.sfs.dom.mods.Modifier
|
||||
import top.davidon.sfs.dom.plain.{PlainModifier, PlainValue}
|
||||
import top.davidon.sfs.dom.reactive.{
|
||||
Observable,
|
||||
ReactiveModifier,
|
||||
ReactiveValue
|
||||
}
|
||||
import top.davidon.sfs.dom.reactive.{ReactiveModifier, ReactiveValue}
|
||||
|
||||
class AriaAttr[V](
|
||||
suffix: String,
|
||||
|
@ -14,11 +11,11 @@ class AriaAttr[V](
|
|||
) extends Key {
|
||||
override val name: String = "aria-" + suffix
|
||||
|
||||
@inline def apply(value: V | Observable[V]): Modifier[V, String] = {
|
||||
@inline def apply(value: V | Signal[V]): Modifier[V, String] = {
|
||||
this := value
|
||||
}
|
||||
|
||||
def :=(value: V | Observable[V]): Modifier[V, String] = {
|
||||
def :=(value: V | Signal[V]): Modifier[V, String] = {
|
||||
Modifier.fromVorObservableV(this, value, codec)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import top.davidon.sfs.dom.Value
|
|||
import top.davidon.sfs.dom.codecs.{EmptyCodec, StringAsIsCodec}
|
||||
import top.davidon.sfs.dom.mods.{EventMod, Modifier}
|
||||
import top.davidon.sfs.dom.plain.{PlainModifier, PlainValue}
|
||||
import top.davidon.sfs.dom.reactive.Observable
|
||||
|
||||
class EventProp[E <: dom.Event](override val name: String) extends Key {
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
package top.davidon.sfs.dom.keys
|
||||
|
||||
import rescala.default.Signal
|
||||
import top.davidon.sfs.dom.codecs.Codec
|
||||
import top.davidon.sfs.dom.Value
|
||||
import top.davidon.sfs.dom.mods.Modifier
|
||||
import top.davidon.sfs.dom.plain.{PlainModifier, PlainValue}
|
||||
import top.davidon.sfs.dom.reactive.{
|
||||
Observable,
|
||||
ReactiveModifier,
|
||||
ReactiveValue
|
||||
}
|
||||
|
@ -14,11 +14,11 @@ class HtmlAttr[V](
|
|||
override val name: String,
|
||||
val codec: Codec[V, String]
|
||||
) extends Key {
|
||||
@inline def apply(value: V | Observable[V]): Modifier[V, String] = {
|
||||
@inline def apply(value: V | Signal[V]): Modifier[V, String] = {
|
||||
this := value
|
||||
}
|
||||
|
||||
def :=(value: V | Observable[V]): Modifier[V, String] = {
|
||||
def :=(value: V | Signal[V]): Modifier[V, String] = {
|
||||
Modifier.fromVorObservableV(this, value, codec)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
package top.davidon.sfs.dom.keys
|
||||
import rescala.default.Signal
|
||||
import top.davidon.sfs.dom.codecs.Codec
|
||||
import top.davidon.sfs.dom.Value
|
||||
import top.davidon.sfs.dom.mods.Modifier
|
||||
import top.davidon.sfs.dom.plain.PlainValue
|
||||
import top.davidon.sfs.dom.reactive.Observable
|
||||
|
||||
class HtmlProp[V, DomV](
|
||||
override val name: String,
|
||||
val codec: Codec[V, DomV]
|
||||
) extends Key {
|
||||
@inline def apply(value: V | Observable[V]): Modifier[V, DomV] = {
|
||||
@inline def apply(value: V | Signal[V]): Modifier[V, DomV] = {
|
||||
this := value
|
||||
}
|
||||
|
||||
def :=(value: V | Observable[V]): Modifier[V, DomV] = {
|
||||
def :=(value: V | Signal[V]): Modifier[V, DomV] = {
|
||||
Modifier.fromVorObservableV(this, value, codec)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package top.davidon.sfs.dom.keys
|
||||
import rescala.default.Signal
|
||||
import top.davidon.sfs.dom.codecs.Codec
|
||||
import top.davidon.sfs.dom.mods.Modifier
|
||||
import top.davidon.sfs.dom.reactive.Observable
|
||||
|
||||
class SvgAttr[V](
|
||||
val localName: String,
|
||||
|
@ -13,11 +13,11 @@ class SvgAttr[V](
|
|||
|
||||
val namespaceUri: Option[String] = namespacePrefix.map(SvgAttr.namespaceUri)
|
||||
|
||||
@inline def apply(value: V | Observable[V]): Modifier[V, String] = {
|
||||
@inline def apply(value: V | Signal[V]): Modifier[V, String] = {
|
||||
this := value
|
||||
}
|
||||
|
||||
def :=(value: V | Observable[V]): Modifier[V, String] = {
|
||||
def :=(value: V | Signal[V]): Modifier[V, String] = {
|
||||
Modifier.fromVorObservableV(this, value, codec)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
package top.davidon.sfs.dom.mods
|
||||
|
||||
import rescala.default.Signal
|
||||
import top.davidon.sfs.dom.Value
|
||||
import top.davidon.sfs.dom.codecs.Codec
|
||||
import top.davidon.sfs.dom.keys.Key
|
||||
import top.davidon.sfs.dom.plain.{PlainModifier, PlainValue}
|
||||
import top.davidon.sfs.dom.reactive.{
|
||||
Observable,
|
||||
ReactiveModifier,
|
||||
ReactiveValue
|
||||
}
|
||||
|
@ -18,16 +18,16 @@ class Modifier[F, T] protected (
|
|||
object Modifier {
|
||||
def fromVorObservableV[F, T](
|
||||
key: Key,
|
||||
value: F | Observable[F],
|
||||
value: F | Signal[F],
|
||||
codec: Codec[F, T]
|
||||
): Modifier[F, T] = {
|
||||
value match {
|
||||
case _: F =>
|
||||
PlainModifier(key, PlainValue(value.asInstanceOf[F], codec))
|
||||
case _: Observable[F] =>
|
||||
case _: Signal[F] =>
|
||||
ReactiveModifier(
|
||||
key,
|
||||
ReactiveValue(value.asInstanceOf[Observable[F]], codec)
|
||||
ReactiveValue(value.asInstanceOf[Signal[F]], codec)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
package top.davidon.sfs.dom.reactive
|
||||
|
||||
abstract class Observable[T](var value: T) {
|
||||
def subscribe(observer: T => Unit): Unit
|
||||
def unsubscribe(observer: T => Unit): Unit
|
||||
def update(value: T): Unit
|
||||
def now(): T
|
||||
}
|
|
@ -1,11 +1,12 @@
|
|||
package top.davidon.sfs.dom.reactive
|
||||
|
||||
import rescala.default.Signal
|
||||
import top.davidon.sfs.dom.Value
|
||||
import top.davidon.sfs.dom.codecs.Codec
|
||||
import top.davidon.sfs.dom.plain.PlainValue
|
||||
|
||||
class ReactiveValue[F, T](
|
||||
val reactiveValue: Observable[F],
|
||||
val reactiveValue: Signal[F],
|
||||
codec: Codec[F, T]
|
||||
) extends Value[F, T](reactiveValue.now(), codec) {
|
||||
override def apply(): T = {
|
||||
|
|
|
@ -55,7 +55,7 @@ class ClientSideRenderer(val root: dom.Element) extends Renderer[Unit] {
|
|||
m.value
|
||||
.asInstanceOf[ReactiveValue[?, ?]]
|
||||
.reactiveValue
|
||||
.subscribe(value => { modifierFunc(el, m) })
|
||||
.observe({ value => modifierFunc(el, m) })
|
||||
}
|
||||
case _: EventProp[?] =>
|
||||
el.addEventListener(
|
||||
|
@ -67,14 +67,14 @@ class ClientSideRenderer(val root: dom.Element) extends Renderer[Unit] {
|
|||
m.value
|
||||
.asInstanceOf[ReactiveValue[?, ?]]
|
||||
.reactiveValue
|
||||
.subscribe(value => { modifierFunc(el, m) })
|
||||
.observe({ value => modifierFunc(el, m) })
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
valueFunc(el, element.children)
|
||||
element.children.foreach { case r: ReactiveValue[?, String] =>
|
||||
r.reactiveValue.subscribe(value => { valueFunc(el, element.children) })
|
||||
r.reactiveValue.observe({ value => valueFunc(el, element.children) })
|
||||
}
|
||||
|
||||
parent.append(el)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue