Skip to content

Instantly share code, notes, and snippets.

@lancewalton
Last active October 20, 2021 15:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lancewalton/a56a91e16de9c03715e55bcc903ea120 to your computer and use it in GitHub Desktop.
Save lancewalton/a56a91e16de9c03715e55bcc903ea120 to your computer and use it in GitHub Desktop.
Problem with Laminar StrictSignal.foldLeft where the accumulated value is an EventStream
import com.raquo.laminar.api.L.*
import munit.FunSuite
import scala.collection.mutable
case class Foo(s: String)
case class Bar(s: String)
object Interpreter {
def interpret(foo: Foo): EventStream[Bar] = EventStream.fromValue(Bar(foo.s))
def interpretAndReconcile(foo: Foo, bar: Bar): EventStream[Bar] = EventStream.fromValue(Bar(s"${foo.s}(${bar.s})"))
}
class SignalTransformer extends FunSuite {
def transform(foos: StrictSignal[Foo], owner: Owner): EventStream[Bar] = {
val queue = mutable.Queue.empty[Foo]
val fooToProcess = new EventBus[Foo]
val bars = Var[Option[Bar]](None)
var shouldDequeue = true
def dequeueNext(): Unit =
if (shouldDequeue && queue.nonEmpty) {
shouldDequeue = false
fooToProcess.writer.onNext(queue.dequeue())
}
def doFirst(foo: Foo): Unit = {
Interpreter
.interpret(foo)
.foreach { bar =>
bars.writer.onNext(Some(bar))
shouldDequeue = true
dequeueNext()
}(owner)
()
}
def doSubsequent(acc: Bar, foo: Foo) = {
Interpreter
.interpretAndReconcile(foo, acc)
.foreach { bar =>
bars.writer.onNext(Some(bar))
shouldDequeue = true
dequeueNext()
}(owner)
()
}
fooToProcess.events.foreach { foo =>
bars
.now()
.fold(doFirst(foo))(currentBar => doSubsequent(currentBar, foo))
}(owner)
foos.foreach { foo =>
queue.enqueue(foo)
dequeueNext()
}(owner)
EventStream.merge(EventStream.fromValue(bars.now()), bars.signal.changes).collect { case Some(bar) => bar }
}
test("StrictSignal") {
val foo1: Foo = Foo("1")
val foo2: Foo = Foo("2")
val foo3: Foo = Foo("3")
val $foo: Var[Foo] = Var(foo1)
transform($foo.signal, unsafeWindowOwner).foreach(bar => println(bar))(unsafeWindowOwner)
$foo.set(foo2)
$foo.set(foo3)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment