From 8f19ccfbb4f8d663646e30a6fedc0138ddf7ace3 Mon Sep 17 00:00:00 2001 From: Paul-Henri Froidmont Date: Mon, 18 Aug 2025 04:52:07 +0200 Subject: [PATCH] Use Dyn as key for LiveState --- core/src/TestLiveView.scala | 6 +++--- core/src/scalive/Fingerprint.scala | 2 +- core/src/scalive/HtmlElement.scala | 4 ++-- core/src/scalive/LiveState.scala | 11 ++++++----- core/src/scalive/Rendered.scala | 8 ++++---- core/src/scalive/Scalive.scala | 7 +++---- 6 files changed, 19 insertions(+), 19 deletions(-) diff --git a/core/src/TestLiveView.scala b/core/src/TestLiveView.scala index ca676c6..c27e3de 100644 --- a/core/src/TestLiveView.scala +++ b/core/src/TestLiveView.scala @@ -6,9 +6,9 @@ final case class Elem(name: String, age: Int) class TestView extends LiveView[TestView.Cmd]: import TestView.Cmd.* - private val textCls = LiveState.Key[String] - private val someBool = LiveState.Key[Boolean] - private val elems = LiveState.Key[List[Elem]] + private val textCls = Dyn[String] + private val someBool = Dyn[Boolean] + private val elems = Dyn[List[Elem]] def mount(state: LiveState): LiveState = state diff --git a/core/src/scalive/Fingerprint.scala b/core/src/scalive/Fingerprint.scala index ac6b642..48935a0 100644 --- a/core/src/scalive/Fingerprint.scala +++ b/core/src/scalive/Fingerprint.scala @@ -40,7 +40,7 @@ object Fingerprint: case Mod.DynAttrValueAsPresence(_, _) => md.update(Fingerprint.dynAttrValueAsPresence) case Mod.DynText(_) => md.update(Fingerprint.dynText) case Mod.When(_, _) => md.update(Fingerprint.dynWhen) - case Mod.Split(_, project) => md.update(digest(project(Dyn.dummy))) + case Mod.Split(_, project) => md.update(digest(project(Dyn.apply))) case Mod.Tag(el) => Right(digest(el)) } md.digest() diff --git a/core/src/scalive/HtmlElement.scala b/core/src/scalive/HtmlElement.scala index 5bfaeec..c6503b6 100644 --- a/core/src/scalive/HtmlElement.scala +++ b/core/src/scalive/HtmlElement.scala @@ -41,7 +41,7 @@ enum Mod: dynList: Dyn[List[T]], project: Dyn[T] => HtmlElement) -final case class Dyn[T](key: LiveState.Key, f: key.Type => T): +final case class Dyn[T] private[scalive] (key: LiveState.Key, f: key.Type => T): def render(state: LiveState, trackUpdates: Boolean): Option[T] = val entry = state(key) if !trackUpdates | entry.changed then Some(f(entry.value)) @@ -61,4 +61,4 @@ extension [T](dyn: Dyn[List[T]]) Mod.Split(dyn, project) object Dyn: - def dummy[T] = Dyn(LiveState.Key[T], identity) + def apply[T]: Dyn[T] = Dyn(LiveState.Key[T], identity) diff --git a/core/src/scalive/LiveState.scala b/core/src/scalive/LiveState.scala index 8907983..a7d6a08 100644 --- a/core/src/scalive/LiveState.scala +++ b/core/src/scalive/LiveState.scala @@ -3,9 +3,10 @@ package scalive final case class LiveState private (val data: Map[LiveState.Key, LiveState.Entry[Any]]): def get(k: LiveState.Key): Option[LiveState.Entry[k.Type]] = data.get(k).asInstanceOf[Option[LiveState.Entry[k.Type]]] - def set(k: LiveState.Key, v: k.Type): LiveState = - copy(data = data.updated(k, LiveState.Entry(true, v))) - def apply(k: LiveState.Key): LiveState.Entry[k.Type] = get(k).get + def set[T](k: Dyn[T], v: T): LiveState = + copy(data = data.updated(k.key, LiveState.Entry(true, v))) + def apply(k: LiveState.Key): LiveState.Entry[k.Type] = + get(k).getOrElse(throw new IllegalArgumentException("An assign of type")) def update(k: LiveState.Key, update: k.Type => k.Type): LiveState = copy(data = data.updatedWith(k)( @@ -24,8 +25,8 @@ object LiveState: class Key: type Type - def id: Dyn[Type] = Dyn(this, identity) - def apply[T](f: Type => T): Dyn[T] = Dyn(this, f) + def toDyn: Dyn[Type] = Dyn(this, identity) + def toDyn[T](f: Type => T): Dyn[T] = Dyn(this, f) object Key: def apply[T] = new Key: type Type = T diff --git a/core/src/scalive/Rendered.scala b/core/src/scalive/Rendered.scala index 0bf7a2a..185efbd 100644 --- a/core/src/scalive/Rendered.scala +++ b/core/src/scalive/Rendered.scala @@ -41,14 +41,14 @@ object Rendered: .render(state, trackUpdates) .collect { case items if items.nonEmpty => - val el = mod.project(Dyn.dummy) + val el = mod.project(Dyn.apply) Comprehension( Fingerprint.apply(el), el.static, items.map(item => - val localKey = LiveState.Key[Any] - val localState = LiveState.empty.set(localKey, item) - val localElem = mod.project(localKey.id) + val localDyn = Dyn[Any] + val localState = LiveState.empty.set(localDyn, item) + val localElem = mod.project(localDyn) trackElemUpdates => buildDynamicRendered(localElem, localState).map(_(trackElemUpdates)) ) diff --git a/core/src/scalive/Scalive.scala b/core/src/scalive/Scalive.scala index fddebea..c42b5f6 100644 --- a/core/src/scalive/Scalive.scala +++ b/core/src/scalive/Scalive.scala @@ -3,7 +3,6 @@ import scalive.defs.complex.ComplexHtmlKeys import scalive.defs.tags.HtmlTags package object scalive extends HtmlTags with HtmlAttrs with ComplexHtmlKeys: - implicit def stringToMod(v: String): Mod = Mod.Text(v) - implicit def htmlElementToMod(el: HtmlElement): Mod = Mod.Tag(el) - implicit def dynStringToMod(d: Dyn[String]): Mod = Mod.DynText(d) - implicit def keyToDyn(k: LiveState.Key): Dyn[k.Type] = k.id + implicit def stringToMod(v: String): Mod = Mod.Text(v) + implicit def htmlElementToMod(el: HtmlElement): Mod = Mod.Tag(el) + implicit def dynStringToMod(d: Dyn[String]): Mod = Mod.DynText(d)