Releases: KernAIO/module-meet
Release list
v0.5.4
v0.5.3
0.5.3
Patch Changes
-
c16e361: chore: remove four fields nothing reads
ConnectOptions.namewas passed on every connect and read by nobody — the display name comes from
the token the server minted, which is the only place it can honestly come from, and a field that
looks like the client naming itself is a rule the next person will build on.Tile.cameraOnwas
set from three places and read from none: whether there is a picture isattach, which is null
both for a closed camera and for a track that has not arrived.MeetingSession.othersand
meetKeys.allhad no callers either — the second because this module has no writes yet, so a key
for the blunt invalidation after one is a claim about a mechanism that does not exist.No behaviour changes. Each of them is the same defect as a permission nothing checks, one size
down.
v0.5.2
0.5.2
Patch Changes
-
72bc4ec: fix: answer 404 for a meeting that does not exist, on every path into one
The auto-join path —
?join=1, which is how a person who has already agreed skips the door — put
the demo's fixture participants on screen without asking the server anything. So a made-up meeting
id rendered three faces and a meeting nobody was in, where the same id typed into the pre-join
answered "No such meeting". Found by opening a made-up id rather than by reading the code, and it
is the shape of defect the mock exists to prevent rather than to cause: there is one join path now,
for the same reason there is one place a LiveKit token is minted.The refusal also offers a way back to the workspace, and
meet.ended_backbecomes
meet.back_to_workspacebecause two screens say it.
v0.5.1
0.5.1
Patch Changes
-
f121cc9: fix: make the meeting screen reachable, and fit on it
Four defects found by rendering the screen rather than by reading it, all of them invisible to a
type-check.?join=1did nothing.autoJoinwas read at component init, and the shell fills its navigation
singleton from an$effectin the app layout — which runs after its children have mounted — so
the value was always empty. It is$derivednow. Underneath that sat a second one: the reset of a
stale session and the join were two effects, andleave()wrote its state after awaiting the
disconnect, so the reset landed in a microtask and wiped the meeting that had just started. They
are one effect, andleave()resets before it disposes — which is also better for a person, since
pressing Leave now changes the screen at once rather than when the network is done.The big tile was 16:9 across the whole content area, which is around 500px on a laptop and pushes
the strip and the control bar — Leave included — below the fold. It states a height instead:
capping a tile that has a ratio keeps the ratio by shrinking the width, leaving the stage two
thirds of the way across the page.A visually hidden
<span>is 1px square with a clip-path rather thandisplay:none, so a contrast
audit still measures its text: the "Muted" label inside a danger-toned badge came out at 3.19:1 in
dark mode. The badges carryrole="img"and anaria-labelnow, and an unmuted microphone gets no
badge at all.The pre-join also lists devices in the demo —
enumerateDevicesprompts for nothing, so the
pickers are the real ones while no camera is opened — and the microphone meter is drawn only while
a microphone is actually open, rather than as a bar that can never move.
v0.5.0
0.5.0
Minor Changes
-
7504fc8: feat: start a meeting and be in it
The module ships its first screen:
/{workspace}/meet/m/{id}, behindmeet.call.joinand the
callscapability, plus ameet.startcommand that opens one. A pre-join screen previews the
camera, meters the microphone and remembers which camera, microphone and speaker somebody chose;
joining callsmeetings.join— still the only place a LiveKit token is minted — and connects. In
the call there is an active-speaker stage with a strip, a participant list, a screen share that
takes the stage, and a chat panel whose header says in five locales that its messages end with the
meeting.The states are the screen, and each is a screen rather than a toast: connecting; the browser
refusing the camera, with the three steps that re-grant it; no devices found, offering to join and
listen; an insecure context, saying that a plain-HTTP install is why there is no camera rather than
letting the browser blame the reader; reconnecting, as a band that keeps the tiles; a connection
that failed, naming the blocked UDP path; alone in the meeting, with a copy-link button; ended; a
meeting in another workspace as 404; and an instance with no media server, naming
LIVEKIT_API_SECRETand the--profile callscommand.livekit-clientis reachable only through the route's own dynamic import and then only when
somebody presses Join, so a WebRTC SDK never reaches the first paint of a page in a workspace that
has meetings switched off;bundle.test.tswalks the import graph and holds it there. The
screen-share button is absent, not disabled, where the browser has nogetDisplayMedia.
v0.4.0
0.4.0
Minor Changes
-
851e94d: feat: keep occupancy and history true without asking a browser
participantsandmeetingsnow have exactly two writers, and neither is a client. A client that
reports its own attendance reports it wrong the moment it crashes, and the row it leaves behind puts
a face on the rooms page belonging to somebody who went home an hour ago.The first writer is a raw HTTP route at
POST /api/meet/webhooks/livekit, which is the address
livekit.yaml'swebhook:block names. It verifies LiveKit's JWT and then checks the signed digest
against the exact bytes that arrived —raw: truehands the handler aBuffer. Verified against
a reallivekit/livekit-server:1.13.6, whoseroom_startedandroom_finisheddeliveries both
verify and are both refused with one byte flipped. It appliesroom_started,participant_joined
(idempotent against the partial unique
index, because LiveKit retries),participant_leftandroom_finished, which closes the meeting and
emits the newmeet.meeting.endedevent exactly once. It answers 401 to everything when
LIVEKIT_API_SECRETis empty, so an instance that has not enabled meetings has no unauthenticated
write endpoint, and 5xx for anything it could not apply, so LiveKit retries rather than the event
being lost.The second is
meet.reconcile, a job on a one-minute clock that bindsapp.workspace_id = '*', asks
LiveKit which rooms and participants exist, closes meetings whose room is gone (reconciled, with a
two-minute grace period so a call is not ended between its row being written and the first browser
connecting) and stamps out anybody the media server no longer sees.
v0.3.0
0.3.0
Minor Changes
-
f7cb7b6: feat: answer config.get and mint a join token for one room
/api/meetmounts three procedures.meet.config.getreports whether LiveKit is configured,
whether it is reachable (a reallistRooms()), the browser's media URL and the workspace's
participant limit — behind workspace membership andmeet.call.join, and deliberately behind no
capability, so an administrator whose meetings do not work can find out why.meetings.startand
meetings.joinsit behindrequiresCapability('meet', 'calls'), which defaults to off, so a
workspace that has touched nothing answers 404 to both.meetings.joinis the only place a LiveKit token is minted. The grant isroomJoinfor one room
name the server derived, plus publish, subscribe and data; it carries neitherroomAdminnor
roomCreate, fixesidentityto the Kern user id, and expires in ten minutes.
v0.2.5
0.2.5
Patch Changes
- chore: check the packed tarball can resolve its own imports
v0.2.4
0.2.4
Patch Changes
- chore(renovate): drop dead @kernhq automerge rule
v0.2.3
0.2.3
Patch Changes
- build(deps): raise @kernhq/testing to ^0.1.14