Skip to content

risa.state.placement

Where a view keeps its durable state: InMessage or InStore.

DEFAULT_PLACEMENT module-attribute

DEFAULT_PLACEMENT: Final[InMessage] = InMessage()

The placement of a view that declares none: InMessage with the default codec.

DEFAULT_STORE module-attribute

DEFAULT_STORE: Final[str] = 'default'

The name of the client's store=, for InStore(store=...).

StatePlacement

StatePlacement = InMessage | InStore

Either placement a view can declare as its state=.

InMessage

InMessage(codec: Codec = BASE85)

Bases: Struct

Keep a view's durable state inside the message it renders.

The default placement. The state is written into the spare characters of the rendered components' custom_ids and read back from the message on every click. It needs no infrastructure, survives restarts, and lives exactly as long as the message. It is bounded by what the components can carry: up to about 70 bytes per interactive component with the default codec.

The state is readable by anyone who can see the message, so never keep secrets in durable fields. A click cannot change it: risa reads it from the message Discord delivers with the click.

A rerender that changes the state changes the custom_id of the buttons that carry it. In tests Discord refused a click on a custom_id the message no longer has, so someone whose client still shows the old button gets a failed click and can click again. Discord does not document this and risa does not check it, so do not rely on the refusal. A view many people click at once fits InStore better: its custom_ids hold a key instead of the state, so they change only when a bound argument does.

Attributes:

  • codec (Codec) –

    How the state is written into custom_ids. risa.codecs.BASE85 by default; BASE32768 and URO14 from the [radixly] extra carry more than twice as much.

InStore

InStore(ttl: float | None, store: str = DEFAULT_STORE)

Bases: Struct

Keep a view's durable state in a store, under a key the message carries.

The components carry only a random key, and the state is one record in the client's store of the name store. It has no size bound, every process of a bot shares it through a distributed store, and it expires.

Attributes:

  • ttl (float | None) –

    Seconds an untouched record lives. Every click restarts the clock, so only abandoned views expire. None keeps records forever, including the ones a deleted message or a failed send leaves behind. There is no default, since no lifetime suits both a confirmation dialog and a role menu.

  • store (str) –

    Which of the client's stores holds the state: "default" for the client's store=, or a key of its stores=.

codec property

codec: Codec

The codec the store key is written in, always base85.