glimr/loom/live_socket
Loom Live Socket
Each live template connection needs its own isolated state — the current prop values — that persists across events and survives concurrent connections. An OTP actor per connection provides this isolation naturally, owns the prop state, and serializes event handling so two simultaneous clicks on the same page don’t race.
Types
Callers interact with the actor via its Subject but don’t need to know the message type. This alias provides a semantic name that communicates intent while hiding the internal SocketMessage protocol.
pub type LiveSocket =
process.Subject(loom.SocketMessage)
The actor needs the reply subject to push patches back, the module name for dynamic dispatch into the generated handle_json/render_json functions, and the current props as JSON so they can be passed through the handle/render cycle without the actor knowing the actual prop types.
pub type LiveSocketState {
LiveSocketState(
id: String,
reply_to: process.Subject(loom.SocketMessage),
module: String,
props_json: String,
prev_tree_json: String,
)
}
Constructors
-
LiveSocketState( id: String, reply_to: process.Subject(loom.SocketMessage), module: String, props_json: String, prev_tree_json: String, )Arguments
- id
-
Component ID for multiplexed WebSocket routing
- reply_to
-
Subject to send responses back to the WebSocket handler
- module
-
Module name for dynamic dispatch (e.g., “compiled/loom/counter”)
- props_json
-
Current props state as JSON string
- prev_tree_json
-
Previous tree JSON for diffing (set after initial render)
Values
pub fn start(
id: String,
reply_to: process.Subject(loom.SocketMessage),
module: String,
props_json: String,
) -> Result(process.Subject(loom.SocketMessage), actor.StartError)
Each WebSocket connection starts its own actor so prop state is isolated per user session. The reply_to subject ties this actor back to the specific WebSocket handler that owns it, ensuring patches reach the right browser tab.