Point aaw at a folder. Every .js file in it becomes an event the client
can await.
The path is the name. A folder is a namespace, and adding a capability is adding a file — there is no router to register with and no client to regenerate.
An async handler replies to the caller. Drop the keyword and the event is
fire‑and‑forget — nothing is sent back.
Third‑party services are handed to every handler. Pass them once when the server
starts and they arrive in the second argument, alongside ws and
room.
A handler that throws rejects the caller's promise with
{ error }. There is no status code to map and no envelope to unwrap.
Handlers can talk back without being asked. ws.broadcast reaches every
connection; a room reaches a named subset, and membership clears itself
when a client disconnects.
The fourth argument to room.emit is a connection to skip — pass
ws so the sender does not hear its own message.
Off by default. Turn it on with a fifth argument for server‑minted sessions, a folder convention for who may call what, and a SQLite store you never configure.
Events under auth/ need a session. Everything else is open.
Where the file sits is the rule — no per‑file flag, no policy list to keep in
sync. A protected handler never checks a token: it reads identity, because
the runtime refused the call otherwise.
Connecting is free. A token is what buys the right to call anything under
auth/. aaw's own events live under aaw/ and are called like any
other — there is no separate login API.
The session binds to the connection, so nothing carries a token in its body. Hand the
token back on the next page load and aaw restores it before open fires.
| Event | Does |
|---|---|
| aaw/register | Create an account and bind a session |
| aaw/login | Bind a session to this connection |
| aaw/resume | Re‑bind an existing token, which reconnects do for you |
| aaw/logout | End the session everywhere |
aaw mints the token and verifies it. Delivering it is yours — a
transport library has no business holding your mail credentials, so it hands you the token
through onPasswordReset. Here it is with
Resend; Postmark, SES, SMTP or your own
queue plug in the same place.
The token is crypto.randomUUID(), single use, and expires — checked
where the password changes, not only where the form renders. An unknown address answers
exactly like a known one, so the endpoint cannot discover who has an account. On success
the caller is logged straight in.
onPasswordReset handler there is no way to deliver a
token, so the request answers with an error rather than a success nobody can act on.The SQLite store is a default, not a requirement. Pass store and aaw never
opens a database — for when accounts already live in Mongo, or a "user" is an API
key in a committed file.
For credentials aaw knows nothing about — a licence key, a magic link, SSO — write an ordinary event and bind the session yourself.