diff --git a/lib/livebook/live_markdown/export.ex b/lib/livebook/live_markdown/export.ex index 72e9849e1..8d5feccff 100644 --- a/lib/livebook/live_markdown/export.ex +++ b/lib/livebook/live_markdown/export.ex @@ -28,19 +28,18 @@ defmodule Livebook.LiveMarkdown.Export do for( section <- notebook.sections, %{outputs: outputs} <- section.cells, - {_idx, %{type: :js, js_view: js_view, export: export}} <- outputs, - export == true or is_map(export), - do: {js_view.ref, js_view.pid, export}, + {_idx, %{type: :js, js_view: js_view, export: true}} <- outputs, + do: {js_view.ref, js_view.pid}, uniq: true ) - |> Enum.map(fn {ref, pid, export} -> - Task.async(fn -> {ref, get_js_output_export(pid, ref, export)} end) + |> Enum.map(fn {ref, pid} -> + Task.async(fn -> {ref, get_js_output_export(pid, ref)} end) end) |> Task.await_many(:infinity) |> Map.new() end - defp get_js_output_export(pid, ref, true) do + defp get_js_output_export(pid, ref) do send(pid, {:export, self(), %{ref: ref}}) monitor_ref = Process.monitor(pid) @@ -56,27 +55,6 @@ defmodule Livebook.LiveMarkdown.Export do data end - # TODO: remove on Livebook v0.13 - # Handle old flow for backward compatibility with Kino <= 0.10.0 - defp get_js_output_export(pid, ref, %{info_string: info_string, key: key}) do - send(pid, {:connect, self(), %{origin: inspect(self()), ref: ref}}) - - monitor_ref = Process.monitor(pid) - - data = - receive do - {:connect_reply, data, %{ref: ^ref}} -> data - {:DOWN, ^monitor_ref, :process, _pid, _reason} -> nil - end - - Process.demonitor(monitor_ref, [:flush]) - - if data do - payload = if key && is_map(data), do: data[key], else: data - {info_string, payload} - end - end - defp render_notebook(notebook, ctx) do %{setup_section: %{cells: [setup_cell]}} = notebook diff --git a/test/livebook/live_markdown/export_test.exs b/test/livebook/live_markdown/export_test.exs index 8a92ad184..9068ff76d 100644 --- a/test/livebook/live_markdown/export_test.exs +++ b/test/livebook/live_markdown/export_test.exs @@ -701,7 +701,7 @@ defmodule Livebook.LiveMarkdown.ExportTest do type: :js, js_view: %{ ref: "1", - pid: spawn_widget_with_data("1", "data"), + pid: spawn_widget_with_export("1", {"json", "{}"}), assets: %{archive_path: "", hash: "abcd", js_path: "main.js"} }, export: false @@ -779,168 +779,51 @@ defmodule Livebook.LiveMarkdown.ExportTest do assert expected_document == document end + end - test "includes js output with legacy export info" do - notebook = %{ - Notebook.new() - | name: "My Notebook", - sections: [ - %{ - Notebook.Section.new() - | name: "Section 1", - cells: [ - %{ - Notebook.Cell.new(:code) - | source: ":ok", - outputs: [ - {0, - %{ - type: :js, - js_view: %{ - ref: "1", - pid: spawn_widget_with_data("1", "graph TD;\nA-->B;"), - assets: %{archive_path: "", hash: "abcd", js_path: "main.js"} - }, - export: %{info_string: "mermaid", key: nil} - }} - ] - } - ] - } - ] - } + test "ignores js output with legacy export info" do + notebook = %{ + Notebook.new() + | name: "My Notebook", + sections: [ + %{ + Notebook.Section.new() + | name: "Section 1", + cells: [ + %{ + Notebook.Cell.new(:code) + | source: ":ok", + outputs: [ + {0, + %{ + type: :js, + js_view: %{ + ref: "1", + pid: spawn_widget_with_export("1", {"json", "{}"}), + assets: %{archive_path: "", hash: "abcd", js_path: "main.js"} + }, + export: %{info_string: "mermaid", key: nil} + }} + ] + } + ] + } + ] + } - expected_document = """ - # My Notebook + expected_document = """ + # My Notebook - ## Section 1 + ## Section 1 - ```elixir - :ok - ``` + ```elixir + :ok + ``` + """ - + {document, []} = Export.notebook_to_livemd(notebook, include_outputs: true) - ```mermaid - graph TD; - A-->B; - ``` - """ - - {document, []} = Export.notebook_to_livemd(notebook, include_outputs: true) - - assert expected_document == document - end - - test "serializes js output data to JSON if not binary" do - notebook = %{ - Notebook.new() - | name: "My Notebook", - sections: [ - %{ - Notebook.Section.new() - | name: "Section 1", - cells: [ - %{ - Notebook.Cell.new(:code) - | source: ":ok", - outputs: [ - {0, - %{ - type: :js, - js_view: %{ - ref: "1", - pid: spawn_widget_with_data("1", %{height: 50, width: 50}), - assets: %{archive_path: "", hash: "abcd", js_path: "main.js"} - }, - export: %{info_string: "box", key: nil} - }} - ] - } - ] - } - ] - } - - expected_document = """ - # My Notebook - - ## Section 1 - - ```elixir - :ok - ``` - - - - ```box - {"height":50,"width":50} - ``` - """ - - {document, []} = Export.notebook_to_livemd(notebook, include_outputs: true) - - assert expected_document == document - end - - test "exports partial js output data when export_key is set" do - notebook = %{ - Notebook.new() - | name: "My Notebook", - sections: [ - %{ - Notebook.Section.new() - | name: "Section 1", - cells: [ - %{ - Notebook.Cell.new(:code) - | source: ":ok", - outputs: [ - {0, - %{ - type: :js, - js_view: %{ - ref: "1", - pid: - spawn_widget_with_data("1", %{ - spec: %{ - "height" => 50, - "width" => 50, - "data" => %{"x" => 1, "y" => 1, "date" => ~D[2024-05-24]} - }, - datasets: [] - }), - assets: %{archive_path: "", hash: "abcd", js_path: "main.js"} - }, - export: %{info_string: "vega-lite", key: :spec} - }} - ] - } - ] - } - ] - } - - expected_document = """ - # My Notebook - - ## Section 1 - - ```elixir - :ok - ``` - - - - ```vega-lite - {"data":{"date":"2024-05-24","x":1,"y":1},"height":50,"width":50} - ``` - """ - - {document, []} = Export.notebook_to_livemd(notebook, include_outputs: true) - - assert expected_document == document - end + assert expected_document == document end test "includes only the first tabs output that can be exported" do @@ -1422,12 +1305,4 @@ defmodule Livebook.LiveMarkdown.ExportTest do end end) end - - defp spawn_widget_with_data(ref, data) do - spawn(fn -> - receive do - {:connect, pid, %{ref: ^ref}} -> send(pid, {:connect_reply, data, %{ref: ref}}) - end - end) - end end