### start_server_component/3 Source: https://hexdocs.pm/lissome/Lissome.LustreServerComponent.html Starts a Lustre server component. ```APIDOC ## start_server_component/3 ### Description Starts a Lustre server component. ### Parameters * `module` - The module of the server component to start. * `flags` - Flags for starting the server component. * `opts` - Options for starting the server component. Defaults to `[]`. ### Returns The PID of the started server component. ``` -------------------------------- ### Start Lustre Server Component Source: https://hexdocs.pm/lissome/Lissome.LustreServerComponent.html Starts a Lustre server component with the given module, flags, and options. ```Elixir start_server_component(module, flags, opts \\ []) ``` -------------------------------- ### Install dependencies Source: https://hexdocs.pm/lissome/readme.html Run this command to fetch the newly added dependencies. ```bash mix deps.get ``` -------------------------------- ### Start Lustre Server Component (Bang Version) Source: https://hexdocs.pm/lissome/Lissome.LustreServerComponent.html Starts a Lustre server component, raising an error if the startup fails. Use for critical component startups where failure must be immediately handled. ```Elixir start_server_component!(module, flags, opts \\ []) ``` -------------------------------- ### start_server_component/3 Source: https://hexdocs.pm/lissome/Lissome.LustreServerComponent.html Starts a Lustre server component in a separate process. ```APIDOC ## start_server_component(module, flags, opts) ### Description Starts the Gleam module as a server component. Multiple clients can connect to this component using subscribe_to_server_component/2. ### Parameters - **module** (atom) - Required - The Gleam module to render. - **flags** (any) - Required - Flags passed to the Lustre application. - **opts** (keyword) - Optional - Options including :entry_fn (default :component) and :flags_type (default nil). ### Response - **{:ok, server_component}** (tuple) - Success response containing the process reference. - **{:error, reason}** (tuple) - Error response if the component fails to start. ``` -------------------------------- ### start_server_component!/3 Source: https://hexdocs.pm/lissome/Lissome.LustreServerComponent.html Same as `start_server_component/3`, but raises if there are any error starting the server component. ```APIDOC ## start_server_component!/3 ### Description Starts a Lustre server component, raising an error if it fails. ### Parameters * `module` - The module of the server component to start. * `flags` - Flags for starting the server component. * `opts` - Options for starting the server component. Defaults to `[]`. ### Returns The PID of the started server component. ### Raises An error if the server component fails to start. ``` -------------------------------- ### Start Lustre Server Component Source: https://hexdocs.pm/lissome/Lissome.LustreServerComponent.html Starts a Lustre server component to render a Gleam module. Use this when you need to run a Gleam module as a server component that can be subscribed to by multiple clients. Returns `{:ok, server_component}` on success or `{:error, reason}` on failure. ```gleam Lissome.LustreServerComponent.start_server_component(:my_gleam_module, nil) ``` -------------------------------- ### Initialize Per-User Server Component Source: https://hexdocs.pm/lissome/Lissome.LustreServerComponent.html Start a unique server component instance for each individual user connection. ```elixir defmodule MyAppWeb.MySocket do use Lissome.LustreServerComponent def init(state) do # Start a server component for each user # server_component is a tuple representing the started process server_component = start_server_component!(:my_gleam_module, nil) # Subscribe to our server component so this process can # start receiving messages from the server component process # subject is a tuple that represents this process subject = subscribe_to_server_component(server_component) # Put server_component and subject in the state # because they will be needed later state = state |> Map.put(:server_component, server_component) |> Map.put(:server_component, subject) {:ok, state} end end ``` -------------------------------- ### Example: Encode and Convert Message Source: https://hexdocs.pm/lissome/Lissome.LustreServerComponent.html Demonstrates encoding a message and converting the resulting charlist to a string. ```IEx iex> msg = {:reconcile, 1, {:patch, 0, 0, [], []}} ...> Lissome.LustreServerComponent.encode_client_message(msg) [ ~c"{", [[34, "kind", 34], 58 | "1"], [[44, [34, "patch", 34], 58 | "{}"]], ~c"}" ] ``` ```IEx iex> charlist = [ ...> ~c"{", ...> [[34, "kind", 34], 58 | "1"], ...> [[44, [34, "patch", 34], 58 | "{}"]], ...> ~c"}" ...> ] ...> Lissome.LustreServerComponent.json_to_string(charlist) "{"kind":1,"patch":{}}" ``` -------------------------------- ### Build Gleam projects with Lissome.GleamBuilder Source: https://hexdocs.pm/lissome/Lissome.GleamBuilder.html Examples of building Gleam source files for different targets and with custom configuration options. ```elixir iex> Lissome.GleamBuilder.build_gleam(:erlang) iex> Lissome.GleamBuilder.build_gleam([:javascript, :erlang]) iex> Lissome.GleamBuilder.build_gleam(:javascript, ...> gleam_dir: "assets/my_gleam_app", ...> compile_package: true, ...> watch: true ...> ) ``` -------------------------------- ### Example: Successful Client Message Parse Source: https://hexdocs.pm/lissome/Lissome.LustreServerComponent.html Shows a successful parsing of a JSON message from the Lustre client runtime. ```IEx iex> json = ~S({"kind":1,"path":"2 2","name":"click","event":{}}) ...> Lissome.LustreServerComponent.parse_client_message(json) {:ok, {:client_dispatched_message, {:event_fired, 1, "2\n2", "click", %{}}}} ``` -------------------------------- ### Gleam Module for Lustre App Initialization Source: https://hexdocs.pm/lissome/index.html Define a Gleam module with `init`, `update`, `view`, and `main` functions to initialize and render a Lustre application. The `main` function typically starts the Lustre app using `lustre.simple` or `lustre.application`. ```gleam //// src/hello.gleam pub fn init() { //... } pub fn update(msg, model) { //... } pub fn view(model) { //... } pub fn main() { let app = lustre.simple(init, update, view) let assert Ok(_) = lustre.start(app, "#app", Nil) Nil } ``` -------------------------------- ### Lissome.GleamReloader API Source: https://hexdocs.pm/lissome/Lissome.GleamReloader.html API documentation for the Lissome.GleamReloader module, including functions for starting, registering targets, and handling information. ```APIDOC ## Lissome.GleamReloader ### Description A `GenServer` to watch for changes to Gleam files and recompile them. This module requires the `FileSystem` package, which is not included with Lissome. In typical Phoenix projects, `FileSystem` is already available in the `:dev` environment through `phoenix_live_reload`. ### Functions #### `handle_info(arg, state)` - **arg** (any) - The message received by the GenServer. - **state** (any) - The current state of the GenServer. ### `init(args)` - **args** (any) - Initialization arguments for the GenServer. ### `register_target(target, path \ nil)` Registers a new target for the Gleam reloader to watch and compile. This function starts a new reloader GenServer if one doesn't exist, or adds the target to an existing GenServer. - **target** (any) - The target to register. - **path** (any, optional) - The path associated with the target. Defaults to `nil`. ### `start_link(args)` Starts the Gleam reloader GenServer. - **args** (any) - Initialization arguments for the GenServer. ``` -------------------------------- ### Example: Failed Client Message Parse Source: https://hexdocs.pm/lissome/Lissome.LustreServerComponent.html Illustrates a failed parsing of a JSON message due to missing required fields. ```IEx iex> json = ~S({"other from": "Lustre runtime"}) {:error, [ {:decode_error, "Field", "Nothing", ["kind"]}, {:decode_error, "Field", "Nothing", ["name"]}, {:decode_error, "Field", "Nothing", ["value"]} ]} ``` -------------------------------- ### Specify Entry Function for Lustre App Source: https://hexdocs.pm/lissome/index.html Customize the entry point for your Lustre application by using the `entry_fn` attribute on the `.lustre` component. This allows you to specify a different function than `main` to start your Gleam module. ```elixir <.lustre id="app" name={:hello} entry_fn={:my_custom_start_function} /> ``` -------------------------------- ### Initialize Gleam project Source: https://hexdocs.pm/lissome/readme.html Create a new Gleam project and add Lustre as a dependency. ```bash gleam new my_gleam_app cd my_gleam_app gleam add lustre ``` -------------------------------- ### Create and Configure Gleam Project Source: https://hexdocs.pm/lissome/index.html Create a new Gleam project, add Lustre as a dependency, and configure Lissome to point to your Gleam project directory. ```bash gleam new my_gleam_app cd my_gleam_app gleam add lustre ``` ```elixir # config/config.exs config :lissome, :gleam_dir: "my_dir/my_gleam_app" ``` -------------------------------- ### Add Lissome and Lustre to mix.exs Source: https://hexdocs.pm/lissome/index.html Add Lissome and Lustre as dependencies in your `mix.exs` file. Ensure you are using compatible versions. ```elixir def deps do [ ..., {:lissome, "~> 0.4"}, {:lustre, "~> 5.0", app: false, manager: :rebar3} ] end ``` -------------------------------- ### Initialize LiveView Communication with Lissome Source: https://hexdocs.pm/lissome/index.html Construct your app with `lissome.application` to enable bidirectional communication between Gleam and LiveView. This wrapper allows your `init` and `update` functions to receive the LiveView hook instance. ```gleam // other imports import lissome import lissome/live_view type Model { Model(name: String, email: String) } type Msg { ServerUpdatedName(String) UserUpdatedEmail(String) ServerReply(live_view.LiveViewPushResponse) } pub fn init(flags, lv_hook: lissome.LiveViewHook) { let eff = live_view.handle_event( lv_hook: lv_hook, event: "send-name", on_reply: ServerUpdatedName ) #(flags, eff) } pub fn update(model, msg, lv_hook: lissome.LiveViewHook) { case msg { ServerUpdatedName(name) -> #(Model(..model, name:), effect.none()) UserUpdatedEmail(email) -> { let eff = live_view.push_event( lv_hook: lv_hook, event: "update-email", payload: email, on_reply: ServerReply ) #(Model(..model, email:), eff) } ServerReply(live_view.LiveViewPushResponse(_reply, _ref)) -> #( model, effect.none(), ) } } pub fn view(model) { //... } pub fn main(hook: lissome.LiveViewHook) { let flags = Model("John", "jhon@gmail.com") let app = lissome.application(init, update, view, hook) let assert Ok(_) = lustre.start(app, "#app", flags) Nil } ``` -------------------------------- ### Build Gleam Source Files Source: https://hexdocs.pm/lissome/Mix.Tasks.Lissome.BuildGleam.html Use this command to build Gleam source files. The default target is Erlang. You can specify the target as 'javascript' or 'erlang'. The Gleam directory can also be specified. ```bash mix lissome.build_gleam ``` ```bash mix lissome.build_gleam --target [javascript | erlang] ``` ```bash mix lissome.build_gleam "path/to/my_gleam_dir" --target [javascript | erlang] ``` -------------------------------- ### render/1 Source: https://hexdocs.pm/lissome/Lissome.LustreServerComponent.html Renders the markup for a Lustre server component. ```APIDOC ## render/1 ### Description Renders the markup for a Lustre server component. ### Attributes * `route` (`:string`, required) - The route where the server component will connect to. Examples include `"/my-socket/websocket"`, and `"/my-socket/longpoll"`. * `method` (`:atom`, optional) - The transport method used by the server component. Defaults to `:web_socket`. * `attributes` (`:list`, optional) - A list of Lustre attributes to pass to the server component. Each Lustre attribute is a tuple of the form: `{:attribute, 0, attribute_name, attribute_value}`, where the last two elements must be binaries. Lustre will take each of those tuples and set the corresponding HTML attribute in the server component with the specified value. Since the two first values of a Lustre attribute tuple are always the same, you can pass a two element tuple, containing just the attribute name and the attribute value, and Lissome will convert it to a Lustre attribute tuple. Defaults to `[]`. ### Example ```elixir ``` ``` -------------------------------- ### Initialize Global Shared Server Component Source: https://hexdocs.pm/lissome/Lissome.LustreServerComponent.html Use an Agent to maintain a single shared server component instance across all user connections. ```elixir defmodule MyAppWeb.MySocket do use Lissome.LustreServerComponent use Agent def start_link(_opts) do # start once the server component and store it for later use server_component = start_server_component!(:my_gleam_module, nil) Agent.start_link(fn -> server_component end, name: __MODULE__) end def global_server_component do Agent.get(__MODULE__, & &1) end def connect(state) do # This is invoked once per connection # All we need to do here is to ensure that the server component is in our state {:ok, Map.put_new(state, :server_component, global_server_component())} end def init(state) do # Instead of starting a new server component, # we just subscribe to the one we already started subject = subscribe_to_server_component(state.server_component) # Put subject in the state {:ok, Map.put(state, :subject, subject)} end end ``` -------------------------------- ### subscribe_to_server_component/2 Source: https://hexdocs.pm/lissome/Lissome.LustreServerComponent.html Subscribes to a Lustre server component. ```APIDOC ## subscribe_to_server_component/2 ### Description Subscribes a process to a Lustre server component. ### Parameters * `server_component` - The server component to subscribe to. * `pid` (optional) - The PID of the process to subscribe. Defaults to the current process. ### Returns An atom indicating the result of the subscription. ``` -------------------------------- ### Compile Gleam Source Files with Lissome Source: https://hexdocs.pm/lissome/Mix.Tasks.Compile.Gleam.html Include this task in your project's `mix.exs` to enable Gleam compilation. It first converts Gleam to Erlang files and then compiles them to BEAM bytecode. ```elixir def project do [ compilers: Mix.compilers() ++ [:gleam], ] end ``` -------------------------------- ### Configure Gleam directory Source: https://hexdocs.pm/lissome/readme.html Set the path to your Gleam project in the Phoenix configuration. ```elixir # config/config.exs config :lissome, :gleam_dir: "my_dir/my_gleam_app" ``` -------------------------------- ### Add Lissome as a Gleam Path Dependency Source: https://hexdocs.pm/lissome/index.html Include Lissome as a path dependency in your Gleam project's `gleam.toml` file to enable interop with Phoenix LiveView. ```toml # gleam.toml [dependencies] lissome = { path = "path/to/deps/lissome/src_gleam" } ``` -------------------------------- ### Lissome.Lustre Functions Source: https://hexdocs.pm/lissome/Lissome.Lustre.html API documentation for the functions within the Lissome.Lustre module. ```APIDOC ## element_to_string(lustre_html) ### Description Converts a Lustre element tuple to the corresponding HTML string. ### Method N/A (Function Call) ### Endpoint N/A ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```elixir el = :lustre@element@html.div([], [:lustre@element@html.text("Hello, world!")]) element_to_string(el) ``` ### Response #### Success Response (200) - **html_string** (string) - The HTML string representation of the Lustre element. #### Response Example ``` "
Hello, world!
" ``` ## process_flags(flags, module_name, flags_type, opts \\ []) ### Description Prepares flags to be passed to a Lustre application. If `flags_type` is `nil`, then this function returns `flags` unchanged unless `flags` are a `Lissome.GleamType` struct, in that case, it convert `flags` to the corresponding tuple using `Lissome.GleamType.to_erlang_tuple/1` before returning it. If `flags_type` is not `nil`, then this function returns an Erlang record constructed using `flags_type` and the `flags` as the values. ### Method N/A (Function Call) ### Endpoint N/A ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```elixir Lissome.Lustre.process_flags(%{count: 10, label: "Clicks"}, :my_gleam_mod, :flags) Lissome.Lustre.process_flags(%{count: 10}, :my_gleam_mod, nil) flags = %Lissome.GleamType{name: :ok, values: :val} Lissome.Lustre.process_flags(flags, :my_gleam_mod, nil) ``` ### Response #### Success Response (200) - **processed_flags** (tuple | nil) - The processed flags, either as a tuple or nil. #### Response Example ``` {:flags, 10, "Clicks"} nil {:ok, :val} ``` ## render(module_name, flags, opts) ### Description Renders a Lustre application. Returns a HTML string with a `div` container that will mount the application on the client using a Phoenix LiveView hook. ### Method N/A (Function Call) ### Endpoint N/A ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```elixir # Example usage would depend on context, typically called within a Phoenix view or controller. ``` ### Response #### Success Response (200) - **html_output** (string) - HTML string containing the rendered Lustre application. #### Response Example ```html
``` ## server_render(module_name, flags, opts) ### Description Pre-renders a Lustre application on the server. Calls the specified `init_fn` and `view_fn` from the Gleam module to generate the initial HTML, and embeds the initial model as JSON for client-side hydration. Returns a HTML string containing the initial HTML of the Lustre application wrapped in a `div` container that will start the hydration process on the client using a Phoenix LiveView hook. ### Method N/A (Function Call) ### Endpoint N/A ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```elixir # Example usage would depend on context, typically called within a Phoenix view or controller. ``` ### Response #### Success Response (200) - **html_output** (string) - HTML string containing the pre-rendered Lustre application. #### Response Example ```html
``` ``` -------------------------------- ### Lissome.GleamBuilder.build_gleam/2 Source: https://hexdocs.pm/lissome/Lissome.GleamBuilder.html Builds Gleam source files to the specified target using the `gleam build` command. Supports multiple targets and various build options. ```APIDOC ## Lissome.GleamBuilder.build_gleam/2 ### Description Builds Gleam source files to the specified target using the `gleam build` command. The target can be `:javascript`, `:erlang`, or a list of both. Returns `:ok`. ### Method `build_gleam(target, opts \\ [])` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Options - `:gleam_dir` - Path to the Gleam project. Defaults to the `:gleam_dir` config in `lissome`, or `"assets/lustre_app"` if not set. - `:compile_package` - If `true`, uses `gleam compile-package` instead of `gleam build` (default: `false`). - `:watch` - If `true`, watches for file changes and rebuilds automatically. Requires the `FileSystem` package to be available (default: `false`). - `:load_beam_modules` - If `true` and the target is `:erlang`, loads compiled modules automatically (default: `true`). - `:erlang_outdir` - Custom output directory for Erlang beam files (only used with the `:erlang` target). Defaults to `"{build_path}/lib/_{gleam_app}/"`, where `gleam_app` is the name from `gleam.toml`. ### Request Example ```elixir Lissome.GleamBuilder.build_gleam(:erlang) Lissome.GleamBuilder.build_gleam([:javascript, :erlang]) Lissome.GleamBuilder.build_gleam(:javascript, gleam_dir: "assets/my_gleam_app", compile_package: true, watch: true ) ``` ### Response #### Success Response (200) - `:ok` - Indicates successful compilation. ``` -------------------------------- ### mix lissome.build_gleam Source: https://hexdocs.pm/lissome/Mix.Tasks.Lissome.BuildGleam.html Builds Gleam source files to either JavaScript or Erlang targets using the gleam build command. ```APIDOC ## mix lissome.build_gleam ### Description Builds Gleam source files to either JavaScript or Erlang targets using the `gleam build` command. The task uses the configured `:gleam_dir` or a provided path argument. ### Usage - `mix lissome.build_gleam` - `mix lissome.build_gleam --target [javascript | erlang]` - `mix lissome.build_gleam "path/to/my_gleam_dir" --target [javascript | erlang]` ### Parameters #### Arguments - **gleam_dir** (string) - Optional - The path to the directory containing Gleam source files. #### Options - **--target** (string) - Optional - The compilation target. Supported values: `javascript`, `erlang`. Defaults to `erlang`. ``` -------------------------------- ### Configure Gleam Compiler for SSR Source: https://hexdocs.pm/lissome/index.html Add the :gleam compiler to your mix.exs file to enable Gleam compilation for SSR. ```elixir # mix.exs def project do [ compilers: Mix.compilers() ++ [:gleam] ] end ``` -------------------------------- ### Subscribe to Lustre Server Component Source: https://hexdocs.pm/lissome/Lissome.LustreServerComponent.html Subscribes a process to a Lustre server component to receive rendering updates. If no `pid` is provided, the calling process's pid is used. Returns a `subject` representing the subscription. ```gleam server_component = Lissome.LustreServerComponent.start_server_component(:my_gleam_module, nil) Lissome.LustreServerComponent.subscribe_to_server_component(server_component) ``` -------------------------------- ### Subscribe to Server Component Source: https://hexdocs.pm/lissome/Lissome.LustreServerComponent.html Subscribes a process to a Lustre server component to receive updates. Defaults to subscribing the current process if no PID is provided. ```Elixir subscribe_to_server_component(server_component, pid \\ nil) ``` -------------------------------- ### subscribe_to_server_component/2 Source: https://hexdocs.pm/lissome/Lissome.LustreServerComponent.html Subscribes a process to receive updates from a Lustre server component. ```APIDOC ## subscribe_to_server_component(server_component, pid) ### Description The specified process will start receiving messages from the server component containing diffs for the Lustre client runtime. ### Parameters - **server_component** (tuple) - Required - The server component reference. - **pid** (pid) - Optional - The process to subscribe. Defaults to the calling process (self/0). ### Response - **subject** (tuple) - Returns a subject representing the subscription. ``` -------------------------------- ### Configure Gleam Watcher for Live Reloading Source: https://hexdocs.pm/lissome/index.html Add a watcher in `config/dev.exs` to enable live reloading for your Gleam project during development. This ensures changes in your Gleam code are reflected automatically. ```elixir # config/dev.exs config :my_app, MyAppWeb.Endpoint, ..., watchers: [ ..., gleam: {Lissome.GleamBuilder, :build_gleam, [:javascript, [watch: true]]} ] ``` -------------------------------- ### Handle LiveView Events in Gleam Source: https://hexdocs.pm/lissome/index.html Use `live_view.handle_event` within the `init` function to manage incoming events from the LiveView. The `on_reply` argument specifies the message constructor to use when a reply is received. ```gleam let eff = live_view.handle_event( lv_hook: lv_hook, event: "send-name", on_reply: ServerUpdatedName ) ``` -------------------------------- ### Lissome Utils API Source: https://hexdocs.pm/lissome/Lissome.Utils.html API documentation for Lissome utility functions. ```APIDOC ## gleam_app() ### Description Returns the app name of the configured Gleam project. ### Method N/A (Function Call) ### Endpoint N/A ### Parameters None ### Request Example ``` // Example usage in Gleam app_name = Lissome.Utils.gleam_app() ``` ### Response #### Success Response (String) - **app_name** (string) - The name of the configured Gleam application. #### Response Example ```json { "app_name": "my_gleam_app" } ``` ``` ```APIDOC ## gleam_dir_path() ### Description Returns the directory path to the configured Gleam project. ### Method N/A (Function Call) ### Endpoint N/A ### Parameters None ### Request Example ``` // Example usage in Gleam gleam_path = Lissome.Utils.gleam_dir_path() ``` ### Response #### Success Response (String) - **dir_path** (string) - The absolute path to the configured Gleam project directory. #### Response Example ```json { "dir_path": "/path/to/your/gleam/project" } ``` ``` -------------------------------- ### Render Lustre App in HEEX Template Source: https://hexdocs.pm/lissome/index.html Use the `.lustre` component within your HEEX templates to render a Gleam/Lustre application. Specify the `id` and `name` of the component to link it to your Gleam module. ```elixir defmodule MyAppWeb.MyLiveView do use MyAppWeb, :live_view import Lissome.Component def mount(_params, _session, socket) do {:ok, socket} end def render(assigns) do ~H"""
Content rendered with Phoenix Live View
<.lustre id="app" name={:hello} />
""" end end ``` -------------------------------- ### Add Gleam Dependencies for SSR Source: https://hexdocs.pm/lissome/index.html When performing SSR, ensure all necessary Gleam dependencies, besides Lustre and the Gleam standard library, are listed in your mix.exs file. Use `app: false` and `manager: :rebar3` for Gleam dependencies. -------------------------------- ### Render Server Component in Template Source: https://hexdocs.pm/lissome/Lissome.LustreServerComponent.html Use the render function within a Phoenix HEEx template to display the component. ```elixir defmodule MyAppWeb.ServerComponentExampleHTML do use MyAppWeb, :html alias Lissome.LustreServerComponent def my_page(assings) do ~H""" ``` -------------------------------- ### Render Lustre Server Component Source: https://hexdocs.pm/lissome/Lissome.LustreServerComponent.html Renders the markup for a Lustre server component. The `route` attribute is required to specify the connection endpoint. ```Elixir ``` -------------------------------- ### Create Lissome Hook in LiveSocket Source: https://hexdocs.pm/lissome/index.html Register a `LissomeHook` with your `LiveSocket` instance using `createLissomeHook`. This function takes an object mapping module names to the actual Gleam modules you want to render. ```javascript // app.js import { createLissomeHook } from "path/to/deps/lissome/assets/lissome.mjs" import * as hello from "path/to/my_gleam_project/build/dev/javascript/my_gleam_app/hello.mjs" import * as about from "path/to/my_gleam_project/build/dev/javascript/my_gleam_app/pages/about.mjs" const lustreModules = { hello, about } let liveSocket = new LiveSocket("/live", Socket, { ..., hooks: { ..., LissomeHook: createLissomeHook(lustreModules) }, }); ``` -------------------------------- ### Handle Server-to-Client Messages Source: https://hexdocs.pm/lissome/Lissome.LustreServerComponent.html Encode and push messages from the server component to the client runtime. ```elixir def handle_info({msg, _ref}, state) do json = msg |> encode_client_message() |> json_to_string() {:push, {:text, json}, state} end ``` -------------------------------- ### Push Events to LiveView from Gleam Source: https://hexdocs.pm/lissome/index.html Utilize `live_view.push_event` within the `update` function to send data to the LiveView. The `on_reply` argument specifies how to handle the server's response. ```gleam let eff = live_view.push_event( lv_hook: lv_hook, event: "update-email", payload: email, on_reply: ServerReply ) ``` -------------------------------- ### send_to_server_component/2 Source: https://hexdocs.pm/lissome/Lissome.LustreServerComponent.html Sends a message to a running Lustre server component. Generally, you should only use this function with decoded client messages that you want to sent to a running Lustre server component, as those match the expected format. If you want to send a message with another shape, instead use `send/2` directly with the `pid` of the server component. ```APIDOC ## send_to_server_component/2 ### Description Sends a message to a running Lustre server component. ### Parameters * `server_component` - The server component to send the message to. * `message` - The message to send. Expected to be in the format expected by `:lustre.send/2`. ### Returns `nil`. ``` -------------------------------- ### unsubscribe_from_server_component/2 Source: https://hexdocs.pm/lissome/Lissome.LustreServerComponent.html Unsubscribes a process from a Lustre server component. ```APIDOC ## unsubscribe_from_server_component(server_component, subject) ### Description Stops the process from receiving further updates from the server component. ### Parameters - **server_component** (tuple) - Required - The server component reference. - **subject** (tuple) - Required - The subscription subject to remove. ### Response - **:ok** (atom) - Indicates successful unsubscription. ``` -------------------------------- ### unsubscribe_from_server_component/2 Source: https://hexdocs.pm/lissome/Lissome.LustreServerComponent.html Unsubscribes a process from a Lustre server component and therefore it will no longer receive updates from it. ```APIDOC ## unsubscribe_from_server_component/2 ### Description Unsubscribes a process from a Lustre server component. ### Parameters * `server_component` - The server component to unsubscribe from. * `subject` - The subject to unsubscribe from. ### Returns An atom indicating the result of the unsubscription. ``` -------------------------------- ### Configure Gleam Compiler in Mix Source: https://hexdocs.pm/lissome/Lissome.LustreServerComponent.html Add the :gleam compiler to your mix.exs file to ensure Gleam code is compiled to Erlang for your Elixir project. ```elixir def project do [ compilers: Mix.compilers() ++ [:gleam] ] end ``` -------------------------------- ### Mix Tasks Source: https://hexdocs.pm/lissome/api-reference.html This section details the available Mix tasks for managing Gleam projects within Lissome. ```APIDOC ## mix compile.gleam ### Description Compiles Gleam source files to BEAM files. ### Method MIX TASK ### Endpoint N/A ### Parameters N/A ### Request Example N/A ### Response N/A ``` ```APIDOC ## mix lissome.build_gleam ### Description Builds Gleam source files to either JavaScript or Erlang targets using the `gleam build` command. ### Method MIX TASK ### Endpoint N/A ### Parameters N/A ### Request Example N/A ### Response N/A ``` -------------------------------- ### Define a Lustre Server Component Socket Source: https://hexdocs.pm/lissome/Lissome.LustreServerComponent.html Create a new Elixir module that uses Lissome.LustreServerComponent to handle connections between the server component and the Lustre client runtime. This injects the Phoenix.Socket.Transport behaviour. ```elixir defmodule MyAppWeb.MySocket do use Lissome.LustreServerComponent end ``` -------------------------------- ### Enable SSR for Lustre Component Source: https://hexdocs.pm/lissome/index.html Pass the `ssr={true}` attribute to a .lustre component to enable server-side rendering. Optionally specify custom init and view functions using `init_fn` and `view_fn`. ```html <.lustre id="app" ssr={true} name={:hello} init_fn={:my_init_function} view_fn={:my_view_function} /> ``` -------------------------------- ### Update esbuild Target to es2020 Source: https://hexdocs.pm/lissome/index.html Modify your esbuild configuration in `config.exs` to use the `es2020` target. This is often required for compatibility with modern JavaScript features used by Lissome and Lustre. ```elixir # config.exs config :esbuild, ..., my_app: [ args: ~w(js/app.js --bundle --target=es2020 --outdir=../priv/static/assets --external:/fonts/* --external:/images/*), ... ] ``` -------------------------------- ### Lissome.Component - lustre function Source: https://hexdocs.pm/lissome/Lissome.Component.html The `lustre` function is used to render a Lustre application. It accepts various attributes to configure the rendering process. ```APIDOC ## lustre(assigns) ### Description Renders a lustre app. ### Method (Not applicable, this is a function call within a framework) ### Endpoint (Not applicable) ### Parameters #### Path Parameters (None) #### Query Parameters (None) #### Request Body (Not applicable) ### Request Example (Not applicable) ### Response #### Success Response (200) (Not applicable, this is a function call) #### Response Example (Not applicable) ### Attributes - **name** (:atom) - Required - The name of the Gleam module to render relative to the src directory. Examples include `:my_lustre_app`, and `:pages@home`. - **flags** (:any) - Optional - Initial values to pass to the Gleam module. Defaults to `nil`. - **entry_fn** (:atom) - Optional - The name of your Gleam function that starts the Lustre application. Defaults to `:main`. - **init_fn** (:atom) - Optional - The name of your Gleam function that initializes the model. Defaults to `:init`. - **view_fn** (:atom) - Optional - The name of your Gleam function that renders the view. Defaults to `:view`. - **flags_type** (:atom) - Optional - The name of your Gleam type that represents the flags your init function receives. Defaults to `nil`. - **id** (:string) - Optional - The id Lustre targets to render into. Defaults to `"app"`. - **class** (:string) - Optional - The class name to apply to the rendered app. Defaults to `""`. - **ssr** (:boolean) - Optional - Whether to render the app on the server side. Defaults to `false`. ``` -------------------------------- ### Create Lissome.GleamType for Gleam Types with Fields Source: https://hexdocs.pm/lissome/index.html Use `Lissome.GleamType.from_record/4` to represent Gleam types that compile to Erlang records, which have multiple fields. Provide the type constructor name, module name, and a map of field values. ```elixir <.lustre module={:hello} ssr={true} flags={Lissome.GleamType.from_record( :person, :hello, %{name: "Jhon", age: 30} )} > ``` -------------------------------- ### Process Flags for Lustre Application Source: https://hexdocs.pm/lissome/Lissome.Lustre.html Use `process_flags/3` to prepare flags for a Lustre application. If `flags_type` is nil, it returns flags unchanged or converts GleamType structs to Erlang tuples. If `flags_type` is provided, it constructs an Erlang record. ```elixir iex> Lissome.Lustre.process_flags(%{count: 10, label: "Clicks"}, :my_gleam_mod, :flags) {:flags, 10, "Clicks"} ``` ```elixir iex> Lissome.Lustre.process_flags(%{count: 10}, :my_gleam_mod, nil) nil ``` ```elixir iex> flags = %Lissome.GleamType{name: :ok, values: :val} ...> Lissome.Lustre.process_flags(flags, :my_gleam_mod, nil) {:ok, :val} ``` -------------------------------- ### Create Lissome.GleamType for Simple Gleam Types Source: https://hexdocs.pm/lissome/index.html Use `Lissome.GleamType.from_value/2` to represent Gleam types that compile to simple tuples, such as `Ok(a)` or `Some(a)`. This is useful when passing non-primitive types as flags during SSR. ```elixir <.lustre module={:hello} ssr={true} flags={Lissome.GleamType.from_value(:some, "Jhon")} > ``` -------------------------------- ### Handle Client-to-Server Messages Source: https://hexdocs.pm/lissome/Lissome.LustreServerComponent.html Parse incoming JSON messages from the client and forward them to the server component. ```elixir def handle_in({msg, _ref}, state) do # The Lissome.LustreServerComponent.parse_client_message!/1 function will raise # if we pass it a message sent by something other than the Lustre client runtime # In this example it's fine because our socket only receives messages # from the Lustre client runtime, but if you are connecting # other clients using the same socket, you might want to use the non-raise variant # `Lissome.LustreServerComponent.parse_client_message/1` instead # and pattern match on the result to handle both the # success and the error case as needed runtime_message = parse_client_message!(msg) send_to_server_component(state.component, runtime_message) {:ok, state} end ``` -------------------------------- ### Parse Client Message (Bang Version) Source: https://hexdocs.pm/lissome/Lissome.LustreServerComponent.html Parses a JSON message from the Lustre client runtime, raising an error if decoding fails. Use with caution for validated input. ```Elixir Lissome.LustreServerComponent.parse_client_message!(json) ``` -------------------------------- ### Create GleamType from Record Source: https://hexdocs.pm/lissome/Lissome.GleamType.html Constructs a GleamType from a Gleam record, extracting field information from an .hrl file. Requires options like :hrl_file_path, :gleam_dir, or :gleam_app to locate the record definition. ```elixir iex> from_record(:person, :my_gleam_module, %{name: "John", age: 30}) %GleamType{name: :person, values: %{name: {0, "John"}, age: {1, 30}, record?: true}} ``` -------------------------------- ### Send Message to Server Component Source: https://hexdocs.pm/lissome/Lissome.LustreServerComponent.html Sends a message to a running Lustre server component using the expected Erlang record format. Internally calls `:lustre.send/2`. ```Elixir send_to_server_component(server_component, message) ``` -------------------------------- ### Configure Phoenix Endpoint Socket Source: https://hexdocs.pm/lissome/Lissome.LustreServerComponent.html Define the socket route in your Phoenix endpoint module. ```elixir defmodule MyAppWeb.Endpoint do ... socket "/my-socket", MyAppWeb.MySocket, webscoket: true end ``` -------------------------------- ### Unsubscribe from Server Component Source: https://hexdocs.pm/lissome/Lissome.LustreServerComponent.html Unsubscribes a process from a Lustre server component, ceasing the reception of updates. ```Elixir unsubscribe_from_server_component(server_component, subject) ``` -------------------------------- ### Retrieve Flags from Gleam using lissome.get_flags Source: https://hexdocs.pm/lissome/index.html Access flags passed from the server as a JSON object in a script tag. Use the `lissome.get_flags` helper in Gleam to decode and retrieve these flags, providing a default model if decoding fails. ```gleam import lissome // <- remember to add this to your project as a path dependency pub fn main() { let decoder = { use count <- decode.field("count", decode.int) use light_on <- decode.field("light_on", decode.bool) decode.success(Model(count, light_on)) } let flags = case lissome.get_flags(id: "ls-model", using: decoder) { Ok(flags) -> flags Error(_) -> Model(8, True) } } ``` -------------------------------- ### Terminate Server Component Subscription Source: https://hexdocs.pm/lissome/Lissome.LustreServerComponent.html Clean up by unsubscribing from the server component when the socket process terminates. ```elixir def terminate(_reason, state) do unsubscribe_from_server_component(state.server_component) end ``` -------------------------------- ### Create GleamType from Value Source: https://hexdocs.pm/lissome/Lissome.GleamType.html Wraps a given value with a Gleam type name. Use `from_record/4` for types with multiple fields. ```elixir iex> from_value(:some, "hello") %GleamType{name: :some, values: "hello"} ``` ```elixir iex> from_value(:error, "something went wrong") %GleamType{name: :error, values: "something went wrong"} ``` -------------------------------- ### Convert Lustre Element to HTML String Source: https://hexdocs.pm/lissome/Lissome.Lustre.html Use `element_to_string/1` to convert a Lustre element tuple into its corresponding HTML string representation. This is useful for generating static HTML from Lustre components. ```elixir iex> el = :lustre@element@html.div([], [:lustre@element@html.text("Hello, world!")]) ...> element_to_string(el) "
Hello, world!
" ``` -------------------------------- ### encode_client_message/1 Source: https://hexdocs.pm/lissome/Lissome.LustreServerComponent.html Encodes a message from the Lustre server component runtime into a JSON charlist. This function is usually chained with `json_to_string/1` to turn the charlist into a string before sending it to the Lustre client runtime. ```APIDOC ## encode_client_message/1 ### Description Encodes a message from the Lustre server component runtime into a JSON charlist. ### Parameters * `msg` - The message to encode. ### Returns A charlist representing the encoded message. ### Example ```elixir msg = {:reconcile, 1, {:patch, 0, 0, [], []}} Lissome.LustreServerComponent.encode_client_message(msg) # Returns: ["{", ["\"kind\"", ":", "1"], [[",", "\"patch\"", ":", "{}"]], "}"] ``` ``` -------------------------------- ### Encode Client Message to JSON Charlist Source: https://hexdocs.pm/lissome/Lissome.LustreServerComponent.html Encodes a message from the Lustre server component runtime into a JSON charlist. Typically chained with `json_to_string/1` before sending to the client. ```Elixir Lissome.LustreServerComponent.encode_client_message(msg) ``` -------------------------------- ### Configure Tailwind CSS Content for Gleam Files Source: https://hexdocs.pm/lissome/index.html If using Tailwind CSS, update your `tailwind.config.js` to include your Gleam files in the `content` array. This allows Tailwind to scan your Gleam code for classes and generate appropriate styles. ```javascript // tailwind.config.js module.exports = { content: [ ..., "../path/to/my_gleam_app/src/**/*.gleam", ], } ``` -------------------------------- ### Lissome.GleamBuilder.is_valid_target/1 Source: https://hexdocs.pm/lissome/Lissome.GleamBuilder.html Checks if the provided target is a valid Gleam build target. ```APIDOC ## Lissome.GleamBuilder.is_valid_target/1 ### Description Checks if the provided target is a valid Gleam build target. ### Method `is_valid_target(target)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```elixir Lissome.GleamBuilder.is_valid_target(:javascript) ``` ### Response #### Success Response (200) - `boolean` - Returns `true` if the target is valid, `false` otherwise. ``` -------------------------------- ### parse_client_message!/1 Source: https://hexdocs.pm/lissome/Lissome.LustreServerComponent.html Same as `parse_client_message/1`, but raises if there are any errors decoding the json. This function must be used carefully, as it will raise if we pass it a json string that does not come from the Lustre client runtime or matches its format. ```APIDOC ## parse_client_message!/1 ### Description Parses a JSON message sent from the Lustre client runtime, raising an error if decoding fails. ### Parameters * `json` - The JSON string to parse. ### Returns The parsed data if successful. ### Raises An error if the JSON is invalid or does not match the expected format. ``` -------------------------------- ### json_to_string/1 Source: https://hexdocs.pm/lissome/Lissome.LustreServerComponent.html Converts a JSON charlist into a string. Useful for turning JSON encoded data from the Lustre server component runtime to a string we can send to the Lustre client runtime. ```APIDOC ## json_to_string/1 ### Description Converts a JSON charlist into a string. ### Parameters * `json` - The JSON charlist to convert. ### Returns A string representing the JSON data. ### Example ```elixir charlist = [ ~c"{", [[34, "kind", 34], 58 | "1"], [[44, [34, "patch", 34], 58 | "{}"]], ~c"}" ] Lissome.LustreServerComponent.json_to_string(charlist) # Returns: "{\"kind\":1,\"patch\":{}}" ``` ```