Packages
Multi-surface application runtime for Elixir. One TEA module renders to terminal, browser (LiveView), SSH, and MCP (agents). 30+ widgets, flexbox + CSS grid, AI agent runtime, distributed swarm with CRDTs, time-travel debugging, session recording, sandboxed REPL, and agentic commerce.
Current section
Files
Jump to
Current section
Files
lib/raxol/plugins/manager/cells.ex
defmodule Raxol.Plugins.Manager.Cells do
@moduledoc """
Handles cell processing functionality.
Provides functions for processing and transforming cells through plugins.
"""
import Raxol.Guards
require Raxol.Core.Runtime.Log
alias Raxol.Plugins.CellProcessor
alias Raxol.Plugins.Manager.Core
@doc """
Allows plugins to process or replace cells generated by the renderer.
Delegates processing to `Raxol.Plugins.CellProcessor`.
Returns `{:ok, updated_manager, processed_cells, collected_commands}`.
"""
def handle_cells(%Core{} = manager, cells, emulator_state)
when list?(cells) do
# Delegate to the CellProcessor module
CellProcessor.process(manager, cells, emulator_state)
end
@doc """
Processes a single cell through all enabled plugins.
Returns {:ok, updated_manager, processed_cell} or {:error, reason}.
"""
def process_cell(%Core{} = manager, cell, emulator_state) do
Enum.reduce_while(
manager.plugins,
{:ok, manager, cell},
&process_plugin_cell(&1, &2, emulator_state)
)
end
defp process_plugin_cell(
{_name, plugin},
{:ok, acc_manager, acc_cell},
emulator_state
) do
if plugin.enabled do
module = plugin.__struct__
if function_exported?(module, :process_cell, 3) do
handle_plugin_cell(
module,
plugin,
acc_cell,
acc_manager,
emulator_state
)
else
{:cont, {:ok, acc_manager, acc_cell}}
end
else
{:cont, {:ok, acc_manager, acc_cell}}
end
end
defp handle_plugin_cell(module, plugin, acc_cell, acc_manager, emulator_state) do
case module.process_cell(plugin, acc_cell, emulator_state) do
{:ok, updated_plugin, processed_cell} ->
updated_manager =
Core.update_plugins(
acc_manager,
Map.put(acc_manager.plugins, plugin.name, updated_plugin)
)
{:cont, {:ok, updated_manager, processed_cell}}
{:error, reason} ->
{:halt, {:error, reason}}
end
end
@doc """
Collects cell-related commands from all enabled plugins.
Returns {:ok, updated_manager, commands}.
"""
def collect_cell_commands(%Core{} = manager) do
Enum.reduce(manager.plugins, {:ok, manager, []}, &collect_plugin_commands/2)
end
defp collect_plugin_commands(
{_name, plugin},
{:ok, acc_manager, acc_commands}
) do
if plugin.enabled do
module = plugin.__struct__
if function_exported?(module, :get_cell_commands, 1) do
handle_plugin_commands(module, plugin, acc_manager, acc_commands)
else
{:ok, acc_manager, acc_commands}
end
else
{:ok, acc_manager, acc_commands}
end
end
defp handle_plugin_commands(module, plugin, acc_manager, acc_commands) do
case module.get_cell_commands(plugin) do
{:ok, updated_plugin, commands} ->
updated_manager =
Core.update_plugins(
acc_manager,
Map.put(acc_manager.plugins, plugin.name, updated_plugin)
)
{:ok, updated_manager, commands ++ acc_commands}
{:ok, updated_plugin} ->
updated_manager =
Core.update_plugins(
acc_manager,
Map.put(acc_manager.plugins, plugin.name, updated_plugin)
)
{:ok, updated_manager, acc_commands}
commands when list?(commands) ->
{:ok, acc_manager, commands ++ acc_commands}
end
end
end