glimr/loom/loom

Loom

Shared types and path conventions for the Loom template system. Both the compiler and the live runtime need to agree on file locations, event structures, and actor messages — centralizing them here prevents drift between compile-time and runtime assumptions.

Types

The WebSocket runtime receives events as JSON from the client and needs a typed representation to dispatch them. Bundling handler ID, event name, and special variables into one record lets the dispatch function pattern match without unpacking raw JSON fields.

pub type ClientEvent {
  ClientEvent(
    handler: String,
    event: String,
    special_vars: SpecialVars,
  )
}

Constructors

  • ClientEvent(
      handler: String,
      event: String,
      special_vars: SpecialVars,
    )

A single dynamic slot in a LiveTree. Can be a leaf string, a nested subtree (conditional/component), or a list of subtrees (loop output).

pub type Dynamic {
  DynString(String)
  DynTree(LiveTree)
  DynList(List(LiveTree))
}

Constructors

A template split into static HTML fragments and dynamic expressions. Statics never change between renders; only dynamics are diffed and sent over the WebSocket.

pub type LiveTree {
  LiveTree(statics: List(String), dynamics: List(Dynamic))
}

Constructors

  • LiveTree(statics: List(String), dynamics: List(Dynamic))

The live socket actor communicates with the WebSocket handler via typed messages. Separating event receipt, HTML patches, redirects, and shutdown into variants gives the actor a clear protocol without ad-hoc string-based message passing.

pub type SocketMessage {
  Event(ClientEvent)
  SendTrees(id: String, json: String)
  SendPatch(id: String, diff: String)
  SendRedirect(url: String)
  Stop
}

Constructors

  • Event(ClientEvent)

    Event received from the client via WebSocket

  • SendTrees(id: String, json: String)

    Send initial statics + dynamics tree to client

  • SendPatch(id: String, diff: String)

    Send changed dynamics only to client

  • SendRedirect(url: String)

    Send a redirect back to the client

  • Stop

    Stop the actor

Browser events carry context (input value, checkbox state, key pressed) that handlers may reference via value/checked /$key. Wrapping them as Options reflects that each is only present for certain event types — an input has $value, a checkbox has $checked.

pub type SpecialVars {
  SpecialVars(
    value: option.Option(String),
    checked: option.Option(Bool),
    key: option.Option(String),
  )
}

Constructors

Values

pub const app_path: String

Template authors can place Gleam modules alongside their templates (e.g., for live event handlers). The file watcher monitors this path to trigger recompilation when backing Gleam code changes.

pub fn find_components(files: List(String)) -> List(String)

Components must be compiled before pages because pages reference component slot and prop information during code generation. Separating component files lets the compiler process them first to build the required metadata maps.

pub fn find_files() -> List(String)

The compiler needs a complete list of template files to process during a full build. Filtering by .loom.html extension ensures only template files are collected, excluding any non-template files that may live in the views directory.

pub fn find_non_components(files: List(String)) -> List(String)

Pages are compiled after components, once all component metadata (props, slots) is available. Filtering out component files from the full list gives the compiler just the page templates for the second compilation pass.

pub fn is_app_path(path: String) -> Bool

Changes to backing Gleam files (event handlers, helpers) require recompiling the corresponding template so the generated code stays in sync. This guard identifies relevant Gleam file changes without reacting to unrelated source modifications.

pub fn is_views_path(path: String) -> Bool

The file watcher triggers on any file change, but only .loom.html files under views_path should cause a recompilation. This guard prevents wasted compile cycles when non-template files are modified in the same directory tree.

pub const output_path: String

Generated Gleam modules go here so they’re compiled by the Gleam build system alongside hand-written code. A dedicated output directory keeps generated files separate and easy to gitignore or clean.

pub const views_path: String

The compiler, file watcher, and response module all need to locate template source files. Deriving from response.views_path keeps this single-sourced so changing the views directory doesn’t require updating multiple locations.

Search Document