diff --git a/build.sbt b/build.sbt index bf5ddaf..7ba3a1b 100644 --- a/build.sbt +++ b/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" - ) diff --git a/dom/src/main/scala/top/davidon/sfs/dom/ScalaFullStackDOM.scala b/dom/src/main/scala/top/davidon/sfs/dom/ScalaFullStackDOM.scala index 0bbf933..0d58748 100644 --- a/dom/src/main/scala/top/davidon/sfs/dom/ScalaFullStackDOM.scala +++ b/dom/src/main/scala/top/davidon/sfs/dom/ScalaFullStackDOM.scala @@ -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) + } + } } diff --git a/dom/src/main/scala/top/davidon/sfs/dom/keys/AriaAttr.scala b/dom/src/main/scala/top/davidon/sfs/dom/keys/AriaAttr.scala index 3e8f538..3b25167 100644 --- a/dom/src/main/scala/top/davidon/sfs/dom/keys/AriaAttr.scala +++ b/dom/src/main/scala/top/davidon/sfs/dom/keys/AriaAttr.scala @@ -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) } } diff --git a/dom/src/main/scala/top/davidon/sfs/dom/keys/EventProp.scala b/dom/src/main/scala/top/davidon/sfs/dom/keys/EventProp.scala index 1161e78..c528a0f 100644 --- a/dom/src/main/scala/top/davidon/sfs/dom/keys/EventProp.scala +++ b/dom/src/main/scala/top/davidon/sfs/dom/keys/EventProp.scala @@ -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 { diff --git a/dom/src/main/scala/top/davidon/sfs/dom/keys/HtmlAttr.scala b/dom/src/main/scala/top/davidon/sfs/dom/keys/HtmlAttr.scala index 811074e..edf4a91 100644 --- a/dom/src/main/scala/top/davidon/sfs/dom/keys/HtmlAttr.scala +++ b/dom/src/main/scala/top/davidon/sfs/dom/keys/HtmlAttr.scala @@ -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) } } diff --git a/dom/src/main/scala/top/davidon/sfs/dom/keys/HtmlProp.scala b/dom/src/main/scala/top/davidon/sfs/dom/keys/HtmlProp.scala index 4ea7752..60422cd 100644 --- a/dom/src/main/scala/top/davidon/sfs/dom/keys/HtmlProp.scala +++ b/dom/src/main/scala/top/davidon/sfs/dom/keys/HtmlProp.scala @@ -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) } } diff --git a/dom/src/main/scala/top/davidon/sfs/dom/keys/SvgAttr.scala b/dom/src/main/scala/top/davidon/sfs/dom/keys/SvgAttr.scala index 646945e..99b50e6 100644 --- a/dom/src/main/scala/top/davidon/sfs/dom/keys/SvgAttr.scala +++ b/dom/src/main/scala/top/davidon/sfs/dom/keys/SvgAttr.scala @@ -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) } } diff --git a/dom/src/main/scala/top/davidon/sfs/dom/mods/Modifier.scala b/dom/src/main/scala/top/davidon/sfs/dom/mods/Modifier.scala index c27a451..acde005 100644 --- a/dom/src/main/scala/top/davidon/sfs/dom/mods/Modifier.scala +++ b/dom/src/main/scala/top/davidon/sfs/dom/mods/Modifier.scala @@ -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) ) } } diff --git a/dom/src/main/scala/top/davidon/sfs/dom/reactive/Observable.scala b/dom/src/main/scala/top/davidon/sfs/dom/reactive/Observable.scala deleted file mode 100644 index 56f828b..0000000 --- a/dom/src/main/scala/top/davidon/sfs/dom/reactive/Observable.scala +++ /dev/null @@ -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 -} diff --git a/dom/src/main/scala/top/davidon/sfs/dom/reactive/ReactiveValue.scala b/dom/src/main/scala/top/davidon/sfs/dom/reactive/ReactiveValue.scala index 5412c1c..eeb89e2 100644 --- a/dom/src/main/scala/top/davidon/sfs/dom/reactive/ReactiveValue.scala +++ b/dom/src/main/scala/top/davidon/sfs/dom/reactive/ReactiveValue.scala @@ -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 = { diff --git a/sfs/.js/src/main/scala/top/davidon/sfs/renderers/ClientSideRenderer.scala b/sfs/.js/src/main/scala/top/davidon/sfs/renderers/ClientSideRenderer.scala index b534c21..d227da6 100644 --- a/sfs/.js/src/main/scala/top/davidon/sfs/renderers/ClientSideRenderer.scala +++ b/sfs/.js/src/main/scala/top/davidon/sfs/renderers/ClientSideRenderer.scala @@ -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)