Skip to content

@fkn/lib/rooms

type Room = object;

A joined room. The same object survives a broker replacement, so it is safe to hold for as long as the chat lasts.

backlog: (after, limit?) => Promise<RoomBacklog>;

replays stored messages above after as message events marked replayed, one page at a time

number

number

Promise<RoomBacklog>

block: (id) => Promise<void>;

sends a member out of the room and keeps them out, with the block permission (denied, rooms: permission denied). On a room claimed under an app’s scope, from another app of the claim’s account, it is refused denied (rooms: only the app that claimed the room can change it), as claim says.

string

Promise<void>

claim: (options?) => Promise<void>;

keeps the name for the signed-in premium account, and a mailbox unless asked not to. The only thing in rooms that premium buys. description says what the room is for, shown to the account in its fkn.app settings; a permanent claim with an unchanged one on every open is free. Claiming on every open also claims the room again after the account unclaims it from fkn.app, so claim when the person wants the room kept, or make it temporary.

temporary makes the claim end by itself, in milliseconds (true is 7 days), that long after its last claim: a temporary claim goes to the account’s ledger every time, which is what restarts its clock. When it ends the app hears a claim event with claimed: false, exactly as for an Unclaim from fkn.app, and the stored messages are gone. A broker too old to carry it refuses the call unavailable (rooms: temporary claims are not available) rather than make the claim permanent.

mailbox: false keeps the name and stores nothing: the room relays as an unclaimed one does. It is read only when the call starts the claim and ignored on a room the account already holds, so claiming on every open never undoes the owner’s choice.

Who changes a claimed room depends on its scope. A room under an app’s scope, which is every room but a global one, is changed by the claim’s account only through the app that claimed it (the same app once it is verified): from another app of the account setDefault, limit, grant, revoke, remove, block, unblock, setMailbox, edit and delete are refused denied (rooms: only the app that claimed the room can change it), the account’s own messages included, and nothing changes. That other app, which reaches the room through its invite, still joins, reads and sends. A claimed global room is changed by any app of the account, which also describes it, sets its temporary and releases it. The account changes every room it claimed from its fkn.app settings, whichever app claimed it, and members of other accounts are answered as in any room. While the room cannot tell whether two apps are one, such a change is refused unavailable (rooms: rooms are unavailable) and can be sent again.

Past the account’s room limit the call waits while fkn.app shows the person their claimed rooms over your app, with Unclaim on each: it resolves once one is unclaimed and this claim is made, and rejects full (rooms: too many claims) when they close the card or when fkn.app cannot show it. Nothing about the account’s other rooms reaches your app.

RoomClaimOptions

Promise<void>

readonly claimed: boolean;

whether a premium account keeps this name. Whether it keeps the messages too is mailbox.

readonly closed: Promise<RoomEnd>;

Settles once, when the room ends for this app. Never rejects.

defaults: () => RoomDefaults;

RoomDefaults

delete: (from, to?) => Promise<void>;

drops stored messages: one of your own, or any range as the owner. On a room claimed under an app’s scope, from another app of the claim’s account, it is refused denied (rooms: only the app that claimed the room can change it), the account’s own messages included, as claim says.

number

number

Promise<void>

edit: (seq, text) => Promise<void>;

replaces a stored message’s text: one of your own, or any as the owner. On a room claimed under an app’s scope, from another app of the claim’s account, it is refused denied (rooms: only the app that claimed the room can change it), the account’s own messages included, as claim says.

number

string

Promise<void>

grant: (id, permission) => Promise<void>;

gives a member a permission over the room default, from the owner only (denied, rooms: not the room owner). On a room claimed under an app’s scope, from another app of the claim’s account, it is refused denied (rooms: only the app that claimed the room can change it), as claim says.

string

RoomPermission

Promise<void>

readonly id: string;

<scope>/<name>: the name under this app’s own scope, or under global

readonly invite: string;

key and id as one string, the thing to put in a link

readonly key: string;

the room key, base64url. The server never sees it. Anyone holding it and the id can join.

leave: () => Promise<void>;

Promise<void>

limit: {
(maxMessageBytes, id?): Promise<void>;
(maxMessageBytes, id): Promise<void>;
};

the message size cap, from 1 to 33,554,432. With no id it sets the room default, which is always a number. With an id it sets that member’s override, and null clears the override. From the owner only (denied, rooms: not the room owner); on a room claimed under an app’s scope, from another app of the claim’s account, it is refused denied (rooms: only the app that claimed the room can change it), as claim says.

(maxMessageBytes, id?): Promise<void>;

number

string

Promise<void>

(maxMessageBytes, id): Promise<void>;

number | null

string

Promise<void>

readonly mailbox: RoomMailbox | null;

what the mailbox holds, as the room last said. Null while the room keeps no messages: nobody has claimed it, or its claim keeps none. The account can clear the room, unclaim it, turn its messages off or on, or set a lower cap from its fkn.app settings, which the app hears as a deleted or a claim event; usage() reads the figures again.

members: () => Promise<RoomMember[]>;

Promise<RoomMember[]>

readonly name: string;
on: (listener) => Promise<() => void>;

Await the returned unsubscribe in cleanup, the account.onChange shape.

(event) => void

Promise<() => void>

readonly owner: string;

the owner’s member id, or ” while a claimed room’s owner has never joined

release: () => Promise<void>;

gives the claim back: the mailbox is deleted and whoever is present stays in an ordinary room. On a room under an app’s scope, the app that claimed it only (the same app once it is verified), and from another app it is refused denied (rooms: only the app that claimed the room can release it); on a global room, any app of the account. The account can also unclaim it from its fkn.app settings.

Promise<void>

remove: (id) => Promise<void>;

sends a member out of the room, which they may join again, with the remove permission (denied, rooms: permission denied). On a room claimed under an app’s scope, from another app of the claim’s account, it is refused denied (rooms: only the app that claimed the room can change it), as claim says.

string

Promise<void>

revoke: (id, permission) => Promise<void>;

takes a permission from a member over the room default, from the owner only (denied, rooms: not the room owner). On a room claimed under an app’s scope, from another app of the claim’s account, it is refused denied (rooms: only the app that claimed the room can change it), as claim says.

string

RoomPermission

Promise<void>

readonly self: RoomMember;

this app’s member record, as this room sees it. The id is fresh in every room.

send: (text) => Promise<void>;

sealed before it leaves the browser. Rejects too-large past self.maxMessageBytes on the wire, never truncates.

string

Promise<void>

setDefault: (permission, value) => Promise<void>;

whether a member with no override may send or receive, from the owner only (denied, rooms: not the room owner). On a room claimed under an app’s scope, from another app of the claim’s account, it is refused denied (rooms: only the app that claimed the room can change it), as claim says.

"send" | "receive"

boolean

Promise<void>

setMailbox: (on) => Promise<void>;

turns a claimed room’s mailbox off or on, from the room’s owner only, which in a claimed room is the claim’s account. Off deletes every stored message at once, the archive included, and the room then relays as an unclaimed one does while keeping its claim; whoever is present hears a claim event with mailbox: false and no deleted, so what an app shows stays. On starts an empty mailbox that keeps messages from the next seq, and nothing deleted comes back. Turning it on needs premium, as a claim does (denied, rooms: claiming needs premium); turning it off never does. Setting what it already is changes nothing. Resolves once the room answered, with mailbox reading the new state, or a newer one when a release or the account’s own switch landed before the answer.

Refused invalid (rooms: the room is not claimed) on an unclaimed room, denied (rooms: not the room owner) from anyone else, denied (rooms: only the app that claimed the room can change it) from another app of the claim’s account on a room claimed under an app’s scope, as claim says, and invalid (rooms: malformed frame) for anything but a boolean. A broker too old to carry it refuses unavailable (rooms: the mailbox switch is not available). The account can do the same from its fkn.app settings, whichever app claimed the room.

boolean

Promise<void>

unblock: (id) => Promise<void>;

lets a blocked member join again, with the block permission (denied, rooms: permission denied). On a room claimed under an app’s scope, from another app of the claim’s account, it is refused denied (rooms: only the app that claimed the room can change it), as claim says.

string

Promise<void>

usage: () => Promise<RoomMailbox | null>;

Promise<RoomMailbox | null>


type RoomsError = Error & object;

Thrown by every member of this namespace. Match on code, never on the message.

code: RoomsErrorCode;
function available(): Promise<boolean>;

Whether this realm can join a room: false in Node, false in a worker nothing bridged, false against a shell older than named rooms. Answers rather than rejecting.

Promise<boolean>


function create(options?): Promise<Room>;

Open a room under a random name and become its owner. Share room.invite to let anyone else in.

RoomOpenOptions

Promise<Room>


function join(invite, options?): Promise<Room>;

invite is room.invite: a key and a room id joined by a dot.

string

RoomJoinOptions

Promise<Room>


function open(name, options?): Promise<Room>;

Open a room by name: a name under this app’s own scope, or global/<name> for the shared one. Nobody there means the room comes into being with you as its owner; somebody there means you join them, and the key has to match theirs. Share room.invite to let anyone else in.

string

RoomOpenOptions

Promise<Room>

Renames and re-exports RoomClaimOptions


Renames and re-exports RoomCreateOptions


Renames and re-exports RoomJoinOptions


Renames and re-exports RoomOpenOptions


Re-exports RoomBacklog


Re-exports RoomDefaults


Re-exports RoomEnd


Re-exports RoomEvent


Re-exports RoomMailbox


Re-exports RoomMember


Re-exports RoomMessage


Re-exports RoomPermission


Re-exports RoomPermissions


Re-exports RoomsErrorCode