WebSocket API

Dunena provides a WebSocket endpoint for real-time cache operations and event streaming.

Connecting

const ws = new WebSocket("ws://localhost:3000/ws");

ws.onopen = () => console.log("Connected");
ws.onmessage = (e) => console.log(JSON.parse(e.data));

On connect, the server sends a connected message with your session ID:

{ "type": "connected", "data": { "id": "abc-123-..." }, "timestamp": 1710000000000 }
If authentication is configured, the WebSocket upgrade request must include the Authorization: Bearer <token> header. Query-parameter auth is not supported by the server.

Message Types

All messages are JSON. Send messages with a type field. All responses include a timestamp.

ping

Keep-alive heartbeat.

// Send
{ "type": "ping" }

// Receive
{ "type": "pong", "timestamp": 1710000000000 }

get

Retrieve a cached value.

// Send
{ "type": "get", "key": "mykey" }

// With namespace
{ "type": "get", "key": "mykey", "ns": "sessions" }

// Receive
{ "type": "result", "data": { "key": "mykey", "value": "hello" }, "timestamp": ... }

set

Store a value. Supports optional ttl (ms) and ns (namespace).

// Send
{ "type": "set", "key": "mykey", "value": "hello", "ttl": 60000, "ns": "app" }

// Receive
{ "type": "result", "data": { "key": "mykey", "ok": true }, "timestamp": ... }

del

Delete a key.

// Send
{ "type": "del", "key": "mykey", "ns": "app" }

// Receive
{ "type": "result", "data": { "key": "mykey", "deleted": true }, "timestamp": ... }

mget

Batch get multiple keys.

// Send
{ "type": "mget", "keys": ["k1", "k2", "k3"], "ns": "app" }

// Receive
{ "type": "result", "data": { "result": { "k1": "v1", "k2": null, "k3": "v3" } }, "timestamp": ... }

mset

Batch set multiple key-value pairs.

// Send
{
  "type": "mset",
  "entries": [
    { "key": "k1", "value": "v1" },
    { "key": "k2", "value": "v2", "ttl": 5000 }
  ],
  "ns": "app"
}

// Receive
{ "type": "result", "data": { "stored": 2 }, "timestamp": ... }

subscribe / unsubscribe

Subscribe to Bun pub/sub topics for real-time event streaming.

// Subscribe to a channel
{ "type": "subscribe", "channel": "cache-events" }

// Receive confirmation
{ "type": "subscribed", "data": { "channel": "cache-events" }, "timestamp": ... }

// Unsubscribe
{ "type": "unsubscribe", "channel": "cache-events" }

Event Streaming

Connected clients automatically subscribe to cache-events. Events are published by the PubSub service when cache mutations occur.

Event Types

EventDescriptionData
setKey was created/updated{ key, size }
deleteKey was deleted{ key }
expiredKey TTL expired{ key }
clearCache was flushed{}

Example: Live Event Listener

const ws = new WebSocket("ws://localhost:3000/ws");

ws.onmessage = (e) => {
  const msg = JSON.parse(e.data);

  if (msg.channel === "cache" && msg.event) {
    console.log(`Cache ${msg.event}:`, msg.data);
  }
};

Error Handling

If a message is invalid, the server responds with:

{ "type": "error", "data": "Key contains invalid characters", "timestamp": ... }

Common Errors

ErrorCause
Invalid JSONMessage could not be parsed
Key must not be emptyEmpty key string
Key contains invalid charactersNon-printable ASCII in key
Value must be a stringNon-string value in set
TTL must be a non-negative integerNegative or non-integer TTL
Unknown message type: ...Unsupported message type