README

#Subscriptions

The sub package models long-lived external signals that should feed back into your TEA update loop.

Unlike Cmd, which runs once, a Sub stays installed until your app stops returning it.

#Basic shape

In Rabbita, subscriptions are usually returned from the subscriptions callback of create_state.

///|
fn subscriptions(model : Model, emit : Emit[Msg]) -> @sub.Sub {
if model.running {
@sub.every(1000, emit(Tick))
} else {
@sub.none
}
}

#Building subscriptions

Use none when nothing should be active:

///|
test "sub none" {
let _ : Sub = @sub.none
}

Use batch to combine multiple subscriptions:

///|
test "sub batch" {
let _ : Sub = @sub.batch([none, every(1000, @cmd.none)])
}

#Emitting messages

Event-based subscriptions usually work with emit.map(...), just like HTML event handlers.

///|
enum Msg {
Resized(ViewPort)
MouseMoved(Mouse)
}

///|
fn subscriptions(_model : Model, emit : Emit[Msg]) -> @sub.Sub {
@sub.batch([
@sub.on_resize(v => emit(Resized(v))),
@sub.on_mouse_move(m => emit(MouseMoved(m))),
])
}

#
RunningSub

pub(all) struct RunningSub {
unload : (&
Scheduler
) -> Unit
update_tagger : (Error) -> Unit
}

#
Scope

pub(all) enum Scope {
Local
Global
}

#
Sub

type Sub

A long-lived subscription managed by the Rabbita runtime.

Use subscriptions to listen to external signals such as timers, window resize, scrolling, keyboard input, visibility changes, or WebSocket events. Browser event sources are inert on native targets.

#
SubLoader

pub(all) struct SubLoader((Error, &
Scheduler
) -> RunningSub?)

Custom subscriptions loader.

#
batch

fn batch(xs : Array[Sub]) -> Sub

Combine multiple subscriptions into one.

If multiple subscriptions use the same internal key, the later one wins.

#
custom_sub

fn custom_sub(key : String, scope : Scope, payload : Error, loader : SubLoader) -> Sub

Create a custom subscription

#
every

fn every(ms : Int, cmd :
Cmd
) -> Sub

Repeatedly enqueue cmd every ms milliseconds.

#
none

let none : Sub

A subscription that does nothing.

#
on_animation_frame

fn on_animation_frame(msg :
Emit
[Double]) -> Sub

Subscribe to requestAnimationFrame ticks.

The handler receives the browser timestamp for each frame while the subscription is active.

#
on_key_down

Subscribe to document keydown events.

The handler receives a normalized Keyboard value from @common.

#
on_key_up

Subscribe to document keyup events.

The handler receives a normalized Keyboard value from @common.

#
on_mouse_move

Subscribe to document mousemove events.

The handler receives a normalized Mouse value from @common.

#
on_resize

Subscribe to window resize events.

The handler receives the latest viewport width and height.

#
on_scroll

Subscribe to window scroll events.

This reports page-level scrolling on window, not scrolling of an inner element. The handler receives the current scroll offset and document scroll size as a Scroll value.

#
on_url_changed

Subscribe to browser location changes.

This is an app-scoped subscription. It is only active when returned from the root cell's subscriptions callback; if a non-root cell returns it, the subscription is ignored.

#
on_url_request

Subscribe to captured navigation requests from @html.a(...).

This is an app-scoped subscription. It is only active when returned from the root cell's subscriptions callback; if a non-root cell returns it, the subscription is ignored.

#
on_visibility_change

fn on_visibility_change(msg :
Emit
[Bool]) -> Sub

Subscribe to document visibility changes.

The handler receives true when the document is hidden, and false when it becomes visible again.

Source Files

Powered by MoonBit

Site sourceReport issuePackagesBuild queueSkillsStatistics

© 2026 mooncakes.io