Example: Chat App (WebSocket)

A real-time chat application using SpaceNode's built-in WebSocket support.

app.js

import { createApp } from 'SpaceNode'

const app = await createApp({ static: './public' })
const rooms = new Map()  // room → Set<socket>

// REST endpoint — list rooms
app.setRoute('GET', '/api/rooms', ({ send }) => {
  const list = [...rooms.entries()].map(([name, s]) => ({
    name, users: s.size,
  }))
  send(list)
})

// WebSocket — chat
app.ws('/chat', (socket, req) => {
  const url = new URL(req.url, 'http://localhost')
  const room = url.searchParams.get('room') || 'general'
  const username = url.searchParams.get('name') || 'Anonymous'

  // Join room
  if (!rooms.has(room)) rooms.set(room, new Set())
  rooms.get(room).add(socket)

  broadcast(room, { type: 'join', user: username })

  socket.on('message', (msg) => {
    broadcast(room, {
      type: 'message',
      user: username,
      text: msg,
      time: new Date().toISOString(),
    })
  })

  socket.on('close', () => {
    rooms.get(room)?.delete(socket)
    broadcast(room, { type: 'leave', user: username })
  })
})

function broadcast(room, data) {
  const msg = JSON.stringify(data)
  for (const client of rooms.get(room) || []) {
    if (client.readyState === 1) client.send(msg)
  }
}

app.listen(3000)

public/index.html (Client)

<!-- Minimal chat client -->
<div id="messages"></div>
<input id="input" placeholder="Type a message...">

<script>
const ws = new WebSocket('ws://localhost:3000/chat?room=general&name=John')

ws.onmessage = (e) => {
  const data = JSON.parse(e.data)
  const div = document.createElement('div')
  div.textContent = `${data.user}: ${data.text || data.type}`
  messages.appendChild(div)
}

input.adorgentListener('keydown', (e) => {
  if (e.key === 'Enter' && input.value) {
    ws.send(input.value)
    input.value = ''
  }
})
</script>
Zero dependencies — This entire chat app requires zero npm packages beyond SpaceNode itself. The WebSocket server is built-in.