Open carlos-verdes opened 6 months ago
Hi @carlos-verdes !
Could you explain a bit more what you are requesting here?
An example maybe?
Hepek is using https://com-lihaoyi.github.io/scalatags undercover, which renders Frags as a String, in memory.
This is more or less what I have done with scala.xml
// my query returns a stream of Pet
val myPets: ZStream[R, Throwable, Pet] = ???
def petToNode(pet: Pet): scala.xml.Node = ???
// new type of document Node called StreamNode
case class StreamNode(nodes: Stream[Throwable, Node]) extends Node:
def child: collection.Seq[xml.Node] = Seq.empty
def label: String = "Stream"
// Inject the pet stream inside a dom tree
val myTemplate: scala.xml.Node =
<table>
{{StreamNode(myPets.map(petToNode))}}
</table>
// traverse the dom tree and create 1 stream entry per element
// when we reach our custom StreamNode we just need to map to string as it's already a stream
tree
extension (node: scala.xml.Node)
def toZStream: Stream[Throwable, String] =
node match
case elem: Elem =>
val attributes = if elem.attributes != null then elem.attributes.toString else ""
val pre: Stream[Throwable, String] = ZStream("<" + elem.label + attributes + ">")
elem.child.foldLeft(pre)((accum, node) => accum ++ node.toZStream) ++
ZStream("</" + elem.label + ">")
case Group(nodes) =>
val emptyStream: Stream[Throwable, String] = ZStream.empty
nodes.foldLeft(emptyStream)((accum, newNode) => accum ++ newNode.toZStream)
case StreamNode(nodes) =>
nodes.map(_.toString)
case other => ZStream(other.toString)
// then in my app I can build a body from stream and serve streamed results (protecting my backedn from OOM errors)
def app = Http.collectHttp[Request]:
// sources
case Method.GET -> Root / "myPets" =>
Handler
.fromZIO:
for env <- ZIO.environment[R]
yield
Handler.fromBody(Body.fromStream(myTemplate.toZStream))
.flatten
.toHttp
Previous code will generate the next stream:
ZStream("<table>") ++ myPetsStream.map(_.toString) ++ ZStream("</table>")
I'm opening these issues as suggestions but also I'll try to participate with my own code
I created an abstraction on top of scala.xml to serve content using ZIO.ZStream, so I can stream results from server instead of loading all content in memory and then flush to the client.
It would be really good to have a feature like that on your library.