diff --git a/lib/kino/control.ex b/lib/kino/control.ex index 89744ec1..f9f676b6 100644 --- a/lib/kino/control.ex +++ b/lib/kino/control.ex @@ -401,6 +401,8 @@ defmodule Kino.Control do @doc """ Same as `stream/1`, but attaches custom tag to every stream item. + Tags can be arbitrary terms. + ## Example button = Kino.Control.button("Hello") @@ -414,17 +416,17 @@ defmodule Kino.Control do #=> {:hello, %{origin: "client1", type: :click}} #=> {:check, %{origin: "client1", type: :change, value: true}} """ - @spec tagged_stream(keyword(event_source())) :: Enumerable.t() + @spec tagged_stream(list({tag :: term(), event_source()})) :: Enumerable.t() def tagged_stream(entries) when is_list(entries) do {tagged_topics, tagged_intervals} = for entry <- entries, reduce: {[], []} do {tagged_topics, tagged_intervals} -> case entry do - {tag, source} when is_atom(tag) -> + {_tag, source} -> assert_stream_source!(source) _other -> - raise ArgumentError, "expected a keyword list, got: #{inspect(entries)}" + raise ArgumentError, "expected a list of 2-element tuples, got: #{inspect(entries)}" end {tag, source} = entry diff --git a/test/kino/control_test.exs b/test/kino/control_test.exs index 56b2ac53..4bc4a265 100644 --- a/test/kino/control_test.exs +++ b/test/kino/control_test.exs @@ -165,7 +165,7 @@ defmodule Kino.ControlTest do describe "tagged_stream/1" do test "raises on invalid argument" do - assert_raise ArgumentError, "expected a keyword list, got: [0]", fn -> + assert_raise ArgumentError, "expected a list of 2-element tuples, got: [0]", fn -> Kino.Control.tagged_stream([0]) end @@ -191,6 +191,16 @@ defmodule Kino.ControlTest do |> Enum.take(2) assert Enum.sort(events) == [{:click, %{origin: "client1"}}, {:name, %{origin: "client2"}}] + + events = + [{{:click, "button"}, button}, {{:name, "text"}, input}] + |> Kino.Control.tagged_stream() + |> Enum.take(2) + + assert Enum.sort(events) == [ + {{:click, "button"}, %{origin: "client1"}}, + {{:name, "text"}, %{origin: "client2"}} + ] end end