WSXServer

The main server class that manages WebSocket connections and request handling.

Constructor

new WSXServer(adapter: WSXServerAdapter)
Creates a new WSX server instance with the provided adapter. Parameters:
  • adapter - A WSXServerAdapter implementation (Express, Hono, or custom)
Example:
import { WSXServer } from "@wsx-sh/core";
import { createExpressAdapter } from "@wsx-sh/express";

const adapter = createExpressAdapter();
const wsx = new WSXServer(adapter);

Methods

on()

Register handlers for WebSocket requests.
on(handler: string, handlerFunction: WSXHandler): WSXServer
on(handlerFunction: WSXHandler): WSXServer
Parameters:
  • handler (optional) - Handler name to match against wx-send attribute
  • handlerFunction - Function to handle the request
Returns: WSXServer instance for chaining Examples:
// Named handler
wsx.on("update-user", async (request, connection) => {
  return {
    id: request.id,
    target: request.target,
    html: `<div>User updated</div>`,
  };
});

// Catch-all handler
wsx.on(async (request, connection) => {
  console.log(`Received: ${request.handler}`);
  return {
    id: request.id,
    target: request.target,
    html: `<div>Handled: ${request.handler}</div>`,
  };
});

broadcast()

Send a message to all connected clients.
broadcast(target: string, html: string, swap?: string): void
Parameters:
  • target - CSS selector for the target element
  • html - HTML content to insert
  • swap (optional) - Swap method (default: ‘innerHTML’)
Example:
wsx.broadcast("#status", "<div>Server updated</div>", "innerHTML");

sendToConnection()

Send a message to a specific connection.
sendToConnection(connectionId: string, target: string, html: string, swap?: string): void
Parameters:
  • connectionId - ID of the target connection
  • target - CSS selector for the target element
  • html - HTML content to insert
  • swap (optional) - Swap method (default: ‘innerHTML’)
Example:
wsx.sendToConnection(
  "conn_123",
  "#notification",
  "<div>Personal message</div>"
);

getConnections()

Get all active connections.
getConnections(): WSXConnection[]
Returns: Array of active WSXConnection objects Example:
const connections = wsx.getConnections();
console.log(`Active connections: ${connections.length}`);

getConnectionCount()

Get the number of active connections.
getConnectionCount(): number
Returns: Number of active connections Example:
const count = wsx.getConnectionCount();
console.log(`${count} clients connected`);

removeConnection()

Remove a connection from the server.
removeConnection(connectionId: string): void
Parameters:
  • connectionId - ID of the connection to remove
Example:
wsx.removeConnection("conn_123");

getApp()

Get the underlying framework app instance.
getApp(): any
Returns: The framework-specific app instance (Express app, Hono app, etc.) Example:
const app = wsx.getApp();
app.get("/health", (req, res) => res.json({ status: "ok" }));

WSXRequest

Interface representing an incoming WebSocket request.
interface WSXRequest {
  id: string; // Unique request ID
  handler: string; // Handler name from wx-send
  target: string; // CSS selector from wx-target
  trigger: string; // Event trigger name
  data?: Record<string, any>; // Form data or wx-data
  swap?: string; // Swap specification
}
Properties:
  • id - Unique identifier for the request
  • handler - Handler name specified in wx-send attribute
  • target - CSS selector from wx-target attribute
  • trigger - Event that triggered the request
  • data - Form data or data from wx-data attribute
  • swap - Swap specification from wx-swap attribute

WSXResponse

Interface representing a response to send back to the client.
interface WSXResponse {
  id: string; // Request ID to match
  target: string; // CSS selector for target element
  html: string; // HTML content to insert
  swap?: string; // Swap method
  oob?: WSXOOBUpdate[]; // Out-of-band updates
}
Properties:
  • id - Must match the request ID
  • target - CSS selector for the element to update
  • html - HTML content to insert
  • swap - How to insert the content (innerHTML, outerHTML, etc.)
  • oob - Array of out-of-band updates for other elements

WSXOOBUpdate

Interface for out-of-band updates.
interface WSXOOBUpdate {
  target: string; // CSS selector
  html: string; // HTML content
  swap?: string; // Swap method
}
Properties:
  • target - CSS selector for the element to update
  • html - HTML content to insert
  • swap - How to insert the content

WSXConnection

Interface representing a WebSocket connection.
interface WSXConnection {
  id: string; // Unique connection ID
  sessionData?: Record<string, any>; // Session data
  send(data: string): void; // Send data to client
  close(): void; // Close connection
}
Properties:
  • id - Unique identifier for the connection
  • sessionData - Object for storing session-specific data
  • send() - Method to send data to the client
  • close() - Method to close the connection

WSXHandler

Type definition for handler functions.
type WSXHandler = (
  request: WSXRequest,
  connection: WSXConnection
) => Promise<WSXResponse | WSXResponse[] | void>;
Parameters:
  • request - The incoming request
  • connection - The connection that sent the request
Returns: Promise that resolves to:
  • WSXResponse - Single response
  • WSXResponse[] - Array of responses
  • void - No response (useful for side effects only)

WSXServerAdapter

Interface that framework adapters must implement.
interface WSXServerAdapter {
  setupWebSocket(
    path: string,
    onMessage: (data: string, connection: WSXConnection) => void
  ): void;
  onConnection?(connection: WSXConnection): void;
  onDisconnection?(connection: WSXConnection): void;
  getApp(): any;
}
Methods:
  • setupWebSocket() - Set up WebSocket handling
  • onConnection() - Optional connection handler
  • onDisconnection() - Optional disconnection handler
  • getApp() - Return the framework app instance

Error Handling

WSX provides built-in error handling, but you can customize it:
wsx.on("error-prone-handler", async (request, connection) => {
  try {
    // Your logic here
    return {
      id: request.id,
      target: request.target,
      html: "<div>Success</div>",
    };
  } catch (error) {
    console.error("Handler error:", error);
    return {
      id: request.id,
      target: request.target,
      html: '<div class="error">Something went wrong</div>',
    };
  }
});

Best Practices

Handler Organization

// Group related handlers
const userHandlers = {
  async updateUser(request, connection) {
    // Update user logic
  },

  async deleteUser(request, connection) {
    // Delete user logic
  },
};

// Register handlers
Object.entries(userHandlers).forEach(([name, handler]) => {
  wsx.on(name, handler);
});

Connection Management

// Track user sessions
const userSessions = new Map();

wsx.on("login", async (request, connection) => {
  const userId = request.data.userId;
  userSessions.set(connection.id, userId);
  connection.sessionData = { userId };

  return {
    id: request.id,
    target: request.target,
    html: "<div>Logged in successfully</div>",
  };
});

Broadcasting Patterns

// Broadcast to specific users
function broadcastToUser(userId, target, html) {
  const connections = wsx.getConnections();
  connections
    .filter((conn) => conn.sessionData?.userId === userId)
    .forEach((conn) => {
      wsx.sendToConnection(conn.id, target, html);
    });
}

// Broadcast to all except sender
function broadcastExcept(senderId, target, html) {
  const connections = wsx.getConnections();
  connections
    .filter((conn) => conn.id !== senderId)
    .forEach((conn) => {
      wsx.sendToConnection(conn.id, target, html);
    });
}

Next Steps