lily/session
Session persistence allows certain model fields to survive page navigations
via localStorage. This lets users carry authentication tokens,
preferences, shopping cart data, and other session state across page loads
without cookies. In Phoenix LiveView, the socket holds this persistence,
and in some other frameworks, this may be purely server-side.
Session data is stored as individual fields in localStorage with the
prefix lily_session_. Each field has its own encoder/decoder for
type-safe serialisation.
Unlike the page store (which tears down on navigation), session data persists until explicitly cleared or expired.
Types
Configuration for a single persisted field within the session.
pub opaque type Field(session)
Complete session persistence configuration. Build using
session.persistence and add fields with
session.field.
pub opaque type Persistence(session)
Values
pub fn attach(
runtime: client.Runtime(model, message),
persistence persistence: Persistence(session),
get get: fn(model) -> session,
set set: fn(model, session) -> model,
) -> client.Runtime(model, message)
Attach session persistence to the runtime. Reads localStorage on start to
hydrate the initial model, then writes changes to localStorage after each
update. The get and set functions extract and inject the session slice
from the model. The session data can be stored within your model for access.
How you choose to do this is completely up to you, as session.attach only
needs get and set functions as parameters.
Call this after creating the store but before client.start, or in the
pipe chain after client.start.
Example
let persistence =
session.persistence()
|> session.field(
key: "token",
get: fn(session) { session.token },
set: fn(session, value) { SessionData(..session, token: value) },
encode: json.nullable(json.string),
decoder: decode.optional(decode.string),
)
store.new(Model(session: empty_session, ..), with: update)
|> session.attach(
persistence:,
get: fn(model) { model.session },
set: fn(model, session) { Model(..model, session: session) },
)
|> client.start
pub fn clear() -> Nil
Clear all session data from localStorage. Removes all keys with the
lily_session_ prefix.
Example
// On logout
fn update(model, msg) {
case msg {
Logout -> {
session.clear()
// Navigate to login page or clear session in model
model
}
_ -> model
}
}
pub fn field(
persistence: Persistence(session),
key key: String,
get get: fn(session) -> a,
set set: fn(session, a) -> session,
encode encode: fn(a) -> json.Json,
decoder decoder: decode.Decoder(a),
) -> Persistence(session)
Add a field to the session persistence configuration. Each field represents
a single value stored in localStorage under lily_session_{key}.
The get and set functions extract and inject the field from the session
type. The encode and decoder handle JSON serialisation.
Example
session.persistence()
|> session.field(
key: "theme",
get: fn(session) { session.theme },
set: fn(session, theme) { SessionData(..session, theme: theme) },
encode: theme_to_json,
decoder: theme_decoder,
)
pub fn persistence() -> Persistence(session)
Create an empty session persistence configuration. Add fields using
session.field.
Example
let persistence = session.persistence()