Create a new stored room.
Admit a user from the waiting room (owner only).
Advertise a room for discovery (owner action).
Attach a broadcast transport. The store routes dominant +
hand-raised through it (publish + subscribe). Replaces any
previously attached transport. Pass null to detach.
Clear the active rooms error.
Clear recording error.
Reset stored rooms to initial state (e.g. on user change / logout).
Clear the stored rooms error.
Clear streaming error.
Clear the unread message counter.
Reset user files to initial state (e.g. on user change / logout).
Clear the user files error.
Close the current no-video room and disconnect.
Connect to the active rooms SSE stream for real-time room discovery. The stream delivers snapshot, room-added, room-removed, and room-updated events.
Connect to the user-files SSE stream for real-time file updates. Delivers snapshot, file-added, file-updated, file-removed, and resync events.
Create a no-video (offline/signaling-only) room as the owner. Connects via signaling for chat, files, whiteboard, etc. — no WebRTC media.
Create a new room as the owner/host.
Optionaloptions: CreateRoomOptionsCreate a new folder at the given location.
OptionalroomName: stringDelete a stored room by roomName.
Delete a user file by ID.
Delete a folder at the given location.
Destroy the store, clean up all resources.
Disable real-time coaching.
Disconnect from the active rooms SSE stream (stops any reconnect).
Disconnect from the user-files SSE stream (stops any reconnect).
Dismiss a coaching hint by ID.
Enable real-time coaching with a specific variant.
Enrich recent transcriptions with mood/sentiment data.
Fetch active rooms (one-shot query for late joiners).
OptionaluserId: stringFetch all stored rooms for a user.
Optionaloptions: { consumerOnly?: boolean; enabledOnly?: boolean; offlineOnly?: boolean }Fetch all files across all rooms for a user (room owners only).
Honors the share-patch guard window two ways:
USER_FILES_SHARE_PATCH_GUARD_MS AND that the server still
returns, the server's sharedWith / sharing fields are
dropped from the fetched record and the local optimistic ACL
is kept.LessonRoomShell broadcast handler
calls upsertUserFileLocal to add the file locally; the
student's next fetchUserFiles might race the cloud read
replica which hasn't propagated the share yet — without (2)
the file would be DROPPED from the student's slice and they'd
have to force-refresh to see it. (2) also covers the
unshared-and-removed-locally case: removeUserFileLocal sets
a guard too, but the file is gone from prev.files so there's
no prior to re-add — the guard there just stops a lagged
server view from briefly resurrecting the file.Without this, the cloud's read replica (which lags the primary
write by enough to routinely return the pre-share view) would
clobber a fresh share/unshare any time a refetch ran inside the
guard window — e.g. the periodic 30s safety-net refetch in lesson
rooms, an explicit onRefresh call, or a remount-driven re-fetch.
Other fields on the file (rename, move, content updates) are
still merged through normally.
Optionalopts: { brandOrgId?: string; hasPublicFilesRole?: boolean }Apply every buffered op in ARRIVAL ORDER in a single slice update, so a burst costs one re-render instead of one per event. Public so a teardown (or a test) can drain deterministically.
Returns the slice unchanged when nothing actually differs — updateSlice
bails on identity, so a stream of no-op patches costs zero renders.
Get the raw Client instance (for advanced usage).
Which file-tree model this user's clients should build, plus whether the beta-filesystem toggle may be shown. Server-decided on both counts.
OptionaluserId: stringGet room information from a join token without joining.
Get a specific state slice (immutable snapshot).
Get the full current state (immutable snapshot).
Get a single stored room by roomName.
Get the streaming URLs for the current stream.
Get a presigned URL for a file.
File identifier.
Optionaloptions: { stream?: boolean }Optionalstream?: booleanWhen true, returns an inline-streamable URL (no
Content-Disposition: attachment header) suitable for <video>,
<img>, <iframe>, etc. Default (false) returns a download URL.
Join an existing no-video (offline/signaling-only) room as a participant. Connects via signaling for chat, files, whiteboard, etc. — no WebRTC media.
Join an existing room as a participant.
Join a room using a join token (from an invite link).
Leave the current room and disconnect.
Load chat history from the server.
Optionalcursor: string | nullLower all raised hands in the room (host only).
Move a user file to a new location/folder.
Mute/unmute a remote participant's audio output locally (owner only).
Reject a user from the waiting room (owner only).
Remotely mute/unmute a participant's audio (owner only).
Remotely mute/unmute a participant's video (owner only).
Remove an advertised room from discovery (owner action).
Remove a file from the local userFiles slice without going to the
server. Companion to upsertUserFileLocal for unshare-style
broadcasts: when a peer learns a file is no longer shared with
them, they can drop it from local state instantly.
Rename a user file.
Rename a folder by its stable id — id-model users only (the server
answers 403 unless this user's folder migration is 'complete', and
refuses system folders, reserved/invalid names and sibling collisions
with client-safe messages). The server rewrites location on every row
in the subtree, so the refresh afterwards is what makes the new tree
appear.
Invalidate the cached lightweight client so the next API call generates a fresh room token for the new user. Call this on user change / logout to prevent stale-token data leaks.
Back to 0 dB (the direct path) for one participant.
Back to 0 dB for every participant, and forget the remembered gains.
Send a data message (arbitrary JSON).
Send a text chat message.
Switch the active room name for file operations on an existing no-video connection. Avoids tearing down and re-establishing the signaling connection.
Switch to a different microphone.
Switch to a different speaker.
Choose how the microphone is captured — see AudioProfile. Takes
effect at once on a live microphone; before a room is joined it applies
to the first capture. Remembered when persistDeviceChanges is on.
Set the dominant speaker for video grid layouts (owner only).
Flip this user between the path-based and id-based tree models
(beta-filesystem role required; the server refuses anyone else, and
returns 'complete' only when its own re-read verified the migration —
'pending' with violations means nothing was flipped).
OptionaluserId: stringSet the microphone gain (0-100).
Lift a quiet microphone by db decibels (0 = as captured, up to
MICROPHONE_BOOST_MAX_DB), before the encoder and behind a limiter.
Needs the enableMicrophoneBoost option. Takes effect at once; remembered
with the devices when persistDeviceChanges is on.
Set how loud a REMOTE participant plays for THIS user, in dB relative to
the stream as received (clamped to PARTICIPANT_GAIN_MIN_DB…MAX_DB; the
minimum is silence). Local only: nothing is sent, and the recording is
unaffected. 0 removes the entry so the tile returns to the direct path.
Remembered per remote user id when persistDeviceChanges is on.
Switch to a different camera.
Share a user file with other users.
Patches the local cache in place rather than refetching the full user-files list. The previous "POST /upload/files/all on every share" pattern hit the cloud's per-IP file-ops rate limit (50/min) in cascade-share scenarios — e.g. an assignment with several embedded files, or a clip-composition fanning out to N clip media files. Each individual share triggered a list refetch, easily burning 20+ list-fetches per save.
When the SSE stream is connected the server's file-updated event
arrives shortly and reconciles the cache against server canon.
When it isn't (degraded session, before initial connect), we fall
back to the full refetch so the cache doesn't drift indefinitely.
OptionalsharedRoom: stringOptionalallowReshare: booleanStart recording. Returns true if API call succeeded.
Optionaloptions: RecordingOptionsStart sharing screen.
Start real-time transcription. Returns true if API call succeeded.
Stop the current recording.
Stop sharing screen.
Stop live streaming.
Stop transcription.
Subscribe to all state changes. Returns unsubscribe function.
Subscribe to changes in a specific state slice. Returns unsubscribe function.
Switch the featured user in the stream.
Toggle local microphone mute/unmute.
Toggle the local user's hand raised state.
Toggle speaker/output mute.
Toggle local camera on/off.
Trigger post-recording transcription and analysis on a completed recording. Unlike real-time transcription, this processes an existing recording asynchronously. Poll transcription status to track progress.
Update an advertised room's metadata (owner action).
Update coaching data from the coaching endpoint response.
Update an existing stored room by roomName.
Update application-specific metadata for a file without re-uploading content.
Skips the full-list refetch (which would re-sort and lose selection) and
patches the matching entry in the local userFiles cache in place, so
subscribers see the new appData immediately. Callers can still call
fetchUserFiles to force a full refresh when they need server canon.
Upload a file to the user's file storage.
OptionalresourceType: stringOptionaluserIdOverride: stringUpload as this user when the file slice has not been primed. Callers
with no listable library of their own — a room-link guest, whose file
view is built from relay broadcasts and who therefore never calls
fetchUserFiles — have no slice userId, and without this every upload
failed the ensureFileOps guard.
The deployment's signaling-region pin, if one was configured.
Exposed so SECONDARY clients created outside the store (ghost cameras, auxiliary connections) can join the SAME stack as the store's own clients. Without the pin a secondary client latency-probes for the closest region, which selects a stack by proximity rather than by environment — from a production session it can land on a dev stack whose JWT secrets don't match the session's room token, failing every mint.