Host & Participant Identity
Both the host and participants use the same ADJECTIVE-NOUN identity format β uppercase, hyphen-separated, drawn from a wine-themed vocabulary. Examples: TANNIC-BARREL, SILKY-MERLOT, FRUITY-CHAMPAGNE.
Identity formatβ
The vocabulary uses 25 wine adjectives Γ 25 wine nouns = 625 unique combinations. All words are wine-world terms and are recognisable to French speakers (most are cognates or direct borrowings between French and English).
A unique identity is generated by the function generateIdentity(usedIds?) in back/utils.ts. If somehow all combinations are exhausted, it falls back to WINE-#### (4 random digits).
Side-by-side comparisonβ
| Host | Participant | |
|---|---|---|
| Identity format | TANNIC-BARREL | SILKY-MERLOT |
| Generated | Once on first visit (stored in localStorage) | Once on join_session (issued by server) |
| Also called | Host ID (hostId) | Pseudonym (pseudonym) |
| URL after connecting | /host?code=1234&id=TANNIC-BARREL | /play?code=1234&id=SILKY-MERLOT |
| Rejoin event | rejoin_host { hostId } | rejoin_session { pseudonym } |
| Server response | host:state_snapshot | participant:state_snapshot |
| localStorage key | sommelierArena:hostId | sommelierArena:rejoin (as { id, code }) |
Host identityβ
The host's identity is generated once in the browser by hostStore.ts:
- Stored in
localStorageunder keysommelierArena:hostId - Preserved across page refreshes on the same device
- Restorable on a different device by opening the share URL
?id=TANNIC-BARREL
The host's session list in the KV store is indexed under host:TANNIC-BARREL.
Participant identity (pseudonym)β
Participants receive their pseudonym from the server when they send join_session. The server guarantees uniqueness within the session (using the same ADJECTIVE-NOUN pool).
The credential is stored in localStorage under sommelierArena:rejoin as { id: "SILKY-MERLOT", code: "1234" }.
Rejoin flow β same browserβ
On every page load, if the credential exists in localStorage, the client auto-sends the rejoin event as soon as the socket opens:
- Host:
rejoin_host { hostId: "TANNIC-BARREL" }β server replies withhost:state_snapshot - Participant:
rejoin_session { pseudonym: "SILKY-MERLOT" }β server replies withparticipant:state_snapshot
No user action is needed.
Rejoin flow β different deviceβ
Open the URL that appears in the browser address bar after connecting:
- Host:
https://sommelier-arena.ducatillon.net/host?code=1234&id=TANNIC-BARREL - Participant:
https://sommelier-arena.ducatillon.net/play?code=1234&id=SILKY-MERLOT
The ?id= parameter is read on mount by HostApp / ParticipantApp and sets the credential in localStorage before the socket opens.
A participant URL without ?id= (e.g. /play?code=1234) performs a fresh join and assigns a new pseudonym β the session code is pre-filled but the participant joins as a new player.
Share link in SessionCreatedβ
When the host creates a session, the Copy participant link button and share buttons (WhatsApp, iMessage) generate a link in the form:
https://sommelier-arena.ducatillon.net/play?code=1234
Opening this link auto-joins the session without requiring the participant to type the code manually. After joining, their browser address bar updates to include ?id=THEIR-PSEUDONYM for future rejoin.
Session lifecycle & credential cleanupβ
When the session ends (session:ended event), the frontend clears the sommelierArena:rejoin key from localStorage, so participants cannot rejoin a finished session.