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
raxol lib raxol terminal session storage.ex
Raw

lib/raxol/terminal/session/storage.ex

defmodule Raxol.Terminal.Session.Storage do
@moduledoc """
Handles persistence of terminal sessions.
"""
alias Raxol.Terminal.Session.Serializer
@doc """
Saves a session state to persistent storage.
"""
@spec save_session(Raxol.Terminal.Session.t()) :: :ok | {:error, term()}
def save_session(session) do
case Serializer.serialize(session) do
{:ok, serialized_data} ->
storage_path = get_storage_path(session.id)
case File.write(storage_path, :erlang.term_to_binary(serialized_data)) do
:ok -> :ok
{:error, reason} -> {:error, reason}
end
{:error, reason} ->
{:error, reason}
end
end
@doc """
Loads a session state from persistent storage.
"""
@spec load_session(String.t()) ::
{:ok, Raxol.Terminal.Session.t()} | {:error, term()}
def load_session(session_id) do
storage_path = get_storage_path(session_id)
case File.read(storage_path) do
{:ok, binary} ->
case Raxol.Core.ErrorHandling.safe_call(fn ->
serialized_data = :erlang.binary_to_term(binary)
Serializer.deserialize(serialized_data)
end) do
{:ok, {:ok, result}} -> {:ok, result}
{:ok, {:error, _reason}} -> {:error, :invalid_session_data}
{:error, _} -> {:error, :invalid_session_data}
end
{:error, reason} ->
{:error, reason}
end
end
@doc """
Deletes a saved session.
"""
@spec delete_session(String.t()) :: :ok | {:error, term()}
def delete_session(session_id) do
storage_path = get_storage_path(session_id)
File.rm(storage_path)
end
@doc """
Lists all saved sessions.
"""
@spec list_sessions() :: {:ok, [String.t()]} | {:error, term()}
def list_sessions do
storage_dir = get_storage_dir()
case File.ls(storage_dir) do
{:ok, files} ->
sessions =
files
|> Enum.filter(&String.ends_with?(&1, ".session"))
|> Enum.map(&String.replace(&1, ".session", ""))
{:ok, sessions}
{:error, reason} ->
{:error, reason}
end
end
defp get_storage_dir do
base_dir =
Application.get_env(:raxol, :session_storage_dir, ".tmp/sessions")
File.mkdir_p!(base_dir)
base_dir
end
defp get_storage_path(session_id) do
Path.join(get_storage_dir(), "#{session_id}.session")
end
end