Use Dyn as key for LiveState

This commit is contained in:
Paul-Henri Froidmont 2025-08-18 04:52:07 +02:00
parent 57f43a0780
commit 8f19ccfbb4
Signed by: phfroidmont
GPG key ID: BE948AFD7E7873BE
6 changed files with 19 additions and 19 deletions

View file

@ -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

View file

@ -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()

View file

@ -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)

View file

@ -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

View file

@ -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))
)

View file

@ -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)