SeuraaEdge
Docs/Use Cases
Use Cases

Show who is online in a room, document, or shared resource.

Build Presence

Use presence to receive membership updates for a presence:* channel.

Model The Channel

Use a presence:* channel for the shared resource:

ts
const channelName = `presence:document:${document.id}`;

The authenticated userId in the channel token becomes the member ID exposed by presence updates.

Sign A Presence Token

ts
export async function POST(request: Request) {
  const user = await requireUser(request);
  const { channel } = await request.json();
  const documentId = channel.replace("presence:document:", "");

  if (!(await canViewDocument(user.id, documentId))) {
    return Response.json({ error: "Forbidden" }, { status: 403 });
  }

  const session = edge.auth.signIn({
    channel,
    expiresInSeconds: 60,
    permissions: ["subscribe"],
    userId: user.id,
  });

  return Response.json({ token: session.token });
}

Presence member data contains identifiers only. Load names, avatars, and roles from your own application data.

Subscribe To Presence Updates

ts
const channel = edge.channel(`presence:document:${documentId}`);

channel.onRawEvent((event) => {
  if (event.type === "channel.snapshot" || event.type === "presence.updated") {
    setOnlineMemberIds(event.presence?.members.map((member) => member.id) ?? []);
  }
});

channel.snapshot can include the initial presence state. presence.updated carries later membership changes.

Combine Presence With Activity

Presence tells you who is connected. Publish separate events for what people are doing:

ts
await channel.publish("cursor.moved", {
  x,
  y,
});

Grant browser publish permissions only for ephemeral events such as cursors, selection, typing, and viewing state.

Query Presence From The Backend

Your backend can query current occupancy:

ts
const state = await edge.channels.presence(`presence:document:${documentId}`);

console.log(state.count);
console.log(state.members);

Generate This With AI

Use this prompt to generate a complete TanStack Start app that demonstrates the flow end to end.

text
Build a complete TanStack Start app that demonstrates live presence with Seuraa Edge.

Use @seuraa/edge in the browser and @seuraa/edge-node only in trusted backend code.

Implement:
- A minimal document-room UI with a signed-in demo user, an online-members list, and a shared document panel.
- A presence channel named `presence:document:${documentId}`.
- A TanStack Start API route at /api/edge/token.
- The endpoint must use a small mock requireUser() helper, accept { channel }, extract documentId from `presence:document:${documentId}`, and check that the user can view that document.
- The endpoint must sign a short-lived channel token locally with edge.auth.signIn({ channel, expiresInSeconds: 60, permissions: ["subscribe"], userId: user.id }).
- Do not call Edge to mint channel tokens. The backend SDK signs locally with SEURAA_APP_SECRET.
- A browser component that creates edge.channel(`presence:document:${documentId}`).
- Use channel.onRawEvent(...) to handle both "channel.snapshot" and "presence.updated".
- Store online member IDs from event.presence.members.
- Load display names and avatars from the app's own user data, not from Seuraa presence payloads.
- Call channel.unsubscribe() when the document view unmounts.
- A TanStack Start API route at /api/documents/demo/presence that uses edge.channels.presence(`presence:document:${documentId}`) to read current presence state.
- A button in the UI that calls /api/documents/demo/presence and displays the returned count and members.
- Loading, connected, and error states in the UI.
- A .env.example file and short README instructions for running the app.

Use these environment variables:
- SEURAA_APP_KEY
- SEURAA_APP_SECRET

Do not expose SEURAA_APP_SECRET to browser code.