### Install next-ws and ws Source: https://github.com/k0d13/next-ws/blob/main/README.md Install the necessary packages using npm, pnpm, or yarn. ```bash npm install next-ws ws ``` ```bash pnpm add next-ws ws ``` ```bash yarn add next-ws ws ``` -------------------------------- ### Custom Server Setup with next-ws Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/configuration.md This example illustrates how to manually initialize next-ws when using a custom Node.js server. It involves calling `setupWebSocketServer` after the Next.js app is prepared. ```typescript import { Server } from 'node:http'; import { parse } from 'node:url'; import next from 'next'; import { setupWebSocketServer } from 'next-ws/server'; const httpServer = new Server(); const dev = process.env.NODE_ENV !== 'production'; const app = next({ dev, customServer: true }); const handle = app.getRequestHandler(); app.prepare().then(() => { // Setup WebSocket support setupWebSocketServer(app); httpServer .on('request', async (req, res) => { if (!req.url) return; const parsedUrl = parse(req.url, true); await handle(req, res, parsedUrl); }) .listen(3000, () => { console.log('Server ready on http://localhost:3000'); }); }); ``` -------------------------------- ### Usage Recommendations - Starting Point Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/DOCUMENTATION_SUMMARY.txt Recommends the starting point for users to navigate and understand the project documentation. ```APIDOC ## Usage Recommendations: START HERE ### Description Guides users on where to begin their exploration of the project documentation. ### Primary Entry Point - **README.md**: Provides navigation to all topics, explains project structure, and lists common tasks. ``` -------------------------------- ### Minimal WebSocket Route Example Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/configuration.md This example demonstrates the basic structure for a WebSocket route in the Next.js App Directory. It includes the required GET handler for upgrading and the UPGRADE handler for WebSocket communication. ```typescript // app/api/ws/route.ts export function GET() { return new Response('Upgrade Required', { status: 426, headers: { 'Connection': 'Upgrade', 'Upgrade': 'websocket', }, }); } export function UPGRADE(client, server, request, context) { client.on('message', (message) => { client.send(message); }); } ``` -------------------------------- ### Server Setup Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/INDEX.md Sets up the WebSocket server integrated with the Next.js server. ```APIDOC ## setupWebSocketServer ### Description Sets up the WebSocket server integrated with the Next.js server. ### Function Signature `setupWebSocketServer(nextServer, options?)` ### Parameters - `nextServer`: The Next.js server instance. - `options` (object, optional): Configuration options for the WebSocket server. ``` -------------------------------- ### Configuring setupWebSocketServer with an Adapter Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/server-setup.md Example of passing a custom adapter to setupWebSocketServer for multi-instance deployments. Ensure the adapter is correctly implemented. ```typescript setupWebSocketServer(nextServer, { adapter: new RedisAdapter(), }); ``` -------------------------------- ### Setup WebSocket Server (No Adapter) Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/configuration.md Use this configuration for single-instance deployments where no external message broker is needed. ```typescript import { setupWebSocketServer } from 'next-ws/server'; setupWebSocketServer(nextServer, { // adapter is optional; omit for single-instance deployments }); ``` -------------------------------- ### Core Setup Flow Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/architecture.md Illustrates the sequence of operations for setting up the WebSocket server, from server initialization to request handling and message broadcasting. ```mermaid setupWebSocketServer() ↓ 1. Get/Create HTTP Server (persistent.ts) 2. Get/Create WebSocket Server (persistent.ts) 3. Get/Create Request Storage (persistent.ts) 4. Attach 'upgrade' handler to HTTP server 5. For each upgrade event: a. Convert IncomingMessage to NextRequest (request.ts) b. Find matching route (match.ts) c. Import route module (module.ts) d. Extract UPGRADE or SOCKET handler e. Run handler with RequestStorage context f. If adapter configured, broadcast messages (adapter.ts) ``` -------------------------------- ### CLI Command - Patch Installation Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/quick-start.md Commands to patch the installation for next-ws. ```APIDOC ### Patch Installation ```bash npx next-ws patch # Interactive npx next-ws patch --yes # Auto-confirm ``` ``` -------------------------------- ### View next-ws Version Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/cli-reference.md Displays the installed version of the next-ws CLI. ```bash npx next-ws --version ``` -------------------------------- ### Code Examples Overview Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/DOCUMENTATION_SUMMARY.txt Summarizes the quantity, types, and nature of code examples provided within the documentation. ```APIDOC ## Code Examples Overview ### Description Details the scope and quality of code examples available in the documentation. ### Details - Total examples: 15+ - Types of examples: Setup, usage, patterns, advanced - All examples are real usage (no pseudocode) ``` -------------------------------- ### Minimal Echo Server Setup Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/quick-start.md Demonstrates how to set up a basic WebSocket server that echoes messages back to the client. This involves creating a route handler and a client-side connection. ```APIDOC ## Minimal Echo Server Create `app/api/ws/route.ts`: ```typescript export function GET() { const headers = new Headers(); headers.set('Connection', 'Upgrade'); headers.set('Upgrade', 'websocket'); return new Response('Upgrade Required', { status: 426, headers }); } export function UPGRADE(client, server) { client.on('message', (msg) => client.send(msg)); } ``` Connect from client: ```typescript 'use client'; import { useEffect } from 'react'; export default function Home() { useEffect(() => { const ws = new WebSocket('ws://localhost:3000/api/ws'); ws.onmessage = (e) => console.log(e.data); ws.onopen = () => ws.send('hello'); }, []); return
Check console
; } ``` ``` -------------------------------- ### Route Structure - Basic Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/quick-start.md Example of a basic WebSocket route handler in Next.js. ```APIDOC ### Basic Route ```typescript // app/api/ws/route.ts export function GET() { /* ... */ } export function UPGRADE(client, server, request, context) { /* ... */ } ``` ``` -------------------------------- ### Adapter Message Flow Example Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/architecture.md Illustrates the message flow in a multi-instance deployment using Redis for broadcasting messages between instances via route-specific channels. ```plaintext Instance 1 Redis Instance 2 Client 1 sends "hello" → publish(room, msg) → Subscriber listens for room messages Adapter.broadcast() → [redis channel] → Adapter.onMessage() routes as rooms handler fires ``` -------------------------------- ### CI/CD Environment Patch Verification Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/cli-reference.md Ensures a properly patched Next.js installation in CI/CD environments before building and starting the application. It automatically patches if necessary. ```bash #!/bin/bash npx next-ws verify --ensure npm run build npm start ``` -------------------------------- ### Adapter Interface Example Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/README.md Optional interface for multi-instance deployments. Enables broadcasting messages from one server instance to all instances handling the same route. ```typescript interface Adapter { broadcast(room: string, message: unknown): Promise; onMessage(room: string, handler: (msg: unknown) => void): void | Promise; close(): Promise; } ``` -------------------------------- ### Adapter Storage Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/INDEX.md Utilities for getting and setting the adapter. ```APIDOC ## Adapter Storage ### Description Provides functions to manage the adapter used for server communication. ### Functions - `getAdapter()`: Retrieves the current adapter. - `setAdapter(value)`: Sets the adapter. ``` -------------------------------- ### Basic WebSocket Server Setup in Next.js Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/server-setup.md Integrates next-ws with a Next.js custom server. Ensure the HTTP server is listening before calling setupWebSocketServer. ```typescript import { Server } from 'node:http'; import { parse } from 'node:url'; import next from 'next'; import { setupWebSocketServer } from 'next-ws/server'; const dev = process.env.NODE_ENV !== 'production'; const app = next({ dev, customServer: true }); const handle = app.getRequestHandler(); const httpServer = new Server(); app.prepare().then(() => { httpServer .on('request', async (req, res) => { if (!req.url) return; const parsedUrl = parse(req.url, true); await handle(req, res, parsedUrl); }) .listen(3000, () => { // Setup WebSocket support after app is ready setupWebSocketServer(app); console.log('Server ready on http://localhost:3000'); }); }); ``` -------------------------------- ### Example Usage in Custom Server with Optional Redis Adapter Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/configuration.md Demonstrates setting up a custom Next.js server with next-ws, conditionally enabling the Redis adapter if REDIS_URL is provided. This is for multi-instance deployments. ```typescript import { Server } from 'node:http'; import Redis from 'ioredis'; import next from 'next'; import { setupWebSocketServer, type Adapter } from 'next-ws/server'; const dev = process.env.NODE_ENV !== 'production'; const hostname = process.env.HOSTNAME || 'localhost'; const port = Number.parseInt(process.env.PORT ?? '3000', 10); // For multi-instance deployments, set REDIS_URL environment variable const redisUrl = process.env.REDIS_URL; class RedisAdapter implements Adapter { private pub = new Redis(redisUrl); private sub = new Redis(redisUrl); // ... rest of implementation } const httpServer = new Server(); const app = next({ dev, hostname, port, customServer: true }); app.prepare().then(() => { // Only use adapter if Redis is configured if (redisUrl) { setupWebSocketServer(app, { adapter: new RedisAdapter() }); } else { setupWebSocketServer(app); } httpServer.listen(port, () => { console.log(`Server ready on http://${hostname}:${port}`); }); }); ``` -------------------------------- ### Example: Echo Server Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/handlers.md Implement an echo server by sending back any message received from the client. This handler is called once per client connection. ```typescript // app/api/ws/route.ts export function GET() { const headers = new Headers(); headers.set('Connection', 'Upgrade'); headers.set('Upgrade', 'websocket'); return new Response('Upgrade Required', { status: 426, headers }); } export function UPGRADE(client, server, request, context) { console.log('Client connected'); client.on('message', (message) => { // Echo the message back to the client client.send(message); }); client.once('close', () => { console.log('Client disconnected'); }); } ``` -------------------------------- ### Configure npm prepare script for Patching Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/cli-reference.md Automatically patches Next.js on every npm install by adding the patch command to the 'prepare' script in your package.json. This ensures your installation is always up-to-date. ```json { "scripts": { "prepare": "next-ws patch" } } ``` -------------------------------- ### Setup WebSocket Server in Custom Server Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/quick-start.md Integrate next-ws into a custom Next.js server using `setupWebSocketServer`. This can be done directly after `app.prepare()` or with an adapter like Redis. ```typescript import { setupWebSocketServer } from 'next-ws/server'; // In custom server after app.prepare() setupWebSocketServer(app); // With adapter setupWebSocketServer(app, { adapter: new RedisAdapter() }); ``` -------------------------------- ### RouteContext with Catch-All Parameter Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/types.md Example demonstrating how to access a catch-all route parameter (e.g., 'filepath') as an array of strings from RouteContext.params. ```typescript // Route: app/api/files/[...filepath]/route.ts export function UPGRADE(client, server, request, context) { const filepath = context.params.filepath; // string[] console.log(`File path: ${filepath.join('/')}`); } ``` -------------------------------- ### Setup WebSocket Server with Redis Adapter Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/configuration.md Configure for multi-instance deployments using a custom RedisAdapter to enable broadcasting messages across server instances. Ensure REDIS_URL is set. ```typescript import Redis from 'ioredis'; import { setupWebSocketServer, type Adapter } from 'next-ws/server'; class RedisAdapter implements Adapter { private pub = new Redis(process.env.REDIS_URL); private sub = new Redis(process.env.REDIS_URL); private handlers = new Map void>>(); constructor() { this.sub.on('message', (channel: string, msg: string) => { const handlers = this.handlers.get(channel); if (!handlers) return; for (const handler of handlers) { handler(JSON.parse(msg)); } }); } async broadcast(room: string, message: unknown): Promise { const messageStr = typeof message === 'string' ? message : JSON.stringify(message); await this.pub.publish(room, messageStr); } async onMessage( room: string, handler: (message: unknown) => void, ): Promise { if (!this.handlers.has(room)) { this.handlers.set(room, new Set()); await this.sub.subscribe(room); } this.handlers.get(room)?.add(handler); } async close(): Promise { await Promise.all([this.pub.quit(), this.sub.quit()]); } } // Setup with adapter const adapter = new RedisAdapter(); setupWebSocketServer(nextServer, { adapter }); ``` -------------------------------- ### Add Prepare Script to package.json Source: https://github.com/k0d13/next-ws/blob/main/README.md Include the prepare script in your package.json to automatically patch Next.js with next-ws during installation. ```json { "scripts": { "prepare": "next-ws patch" } } ``` -------------------------------- ### Patch Next.js Installation Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/cli-reference.md Applies the necessary modifications to your Next.js installation to support WebSockets. This command detects your Next.js version and applies the appropriate patch. ```bash npx next-ws patch ``` -------------------------------- ### HTTP Server Storage Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/INDEX.md Utilities for getting, setting, and using the HTTP server instance. ```APIDOC ## HTTP Server Storage ### Description Provides functions to manage the HTTP server instance within the application. ### Functions - `getHttpServer()`: Retrieves the current HTTP server instance. - `setHttpServer(value)`: Sets the HTTP server instance. - `useHttpServer(getter)`: Uses a getter function to access the HTTP server instance. ``` -------------------------------- ### Route Structure - Dynamic Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/quick-start.md Example of a dynamic WebSocket route handler in Next.js, using route parameters. ```APIDOC ### Dynamic Route ```typescript // app/api/room/[roomId]/ws/route.ts export function UPGRADE(client, server, request, context) { const roomId = context.params.roomId as string; } ``` ``` -------------------------------- ### Route Structure - Catch-All Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/quick-start.md Example of a catch-all WebSocket route handler in Next.js, capturing multiple path segments. ```APIDOC ### Catch-All Route ```typescript // app/api/[...path]/ws/route.ts export function UPGRADE(client, server, request, context) { const path = context.params.path as string[]; } ``` ``` -------------------------------- ### Broadcast to All Clients Pattern Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/quick-start.md Example of broadcasting a received message to all connected clients. ```APIDOC ### Broadcast to All Clients ```typescript export function UPGRADE(client, server) { client.on('message', (data) => { for (const other of server.clients) { if (other.readyState === other.OPEN) { other.send(data); } } }); } ``` ``` -------------------------------- ### Example: Chat Broadcast Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/handlers.md Create a chat application where messages are broadcast to all connected clients. Handles user joining and leaving notifications. ```typescript // app/api/chat/route.ts export function UPGRADE(client, server) { // Notify all other clients that a new user joined for (const other of server.clients) { if (client !== other && other.readyState === other.OPEN) { other.send(JSON.stringify({ type: 'user-joined', userCount: server.clients.size, })); } } client.on('message', (message) => { // Broadcast message to all other clients for (const other of server.clients) { if (client !== other && other.readyState === other.OPEN) { other.send(message); } } }); client.once('close', () => { // Notify other clients that a user left for (const other of server.clients) { if (other.readyState === other.OPEN) { other.send(JSON.stringify({ type: 'user-left', userCount: server.clients.size - 1, })); } } }); } ``` -------------------------------- ### Set Up Custom Server with Next-WS Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/quick-start.md This snippet shows how to integrate next-ws with a custom Node.js server for Next.js applications. Ensure you have a custom server setup. ```typescript import { Server } from 'node:http'; import next from 'next'; import { setupWebSocketServer } from 'next-ws/server'; const app = next({ customServer: true }); const server = new Server(); app.prepare().then(() => { setupWebSocketServer(app); server.listen(3000); }); ``` -------------------------------- ### useHttpServer() Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/server-persistent.md Gets or creates the HTTP server instance. If an instance already exists, it's returned. Otherwise, a getter function is called to create and store a new instance. ```APIDOC ## useHttpServer() ### Description Gets or creates the HTTP server instance. If an instance already exists, returns it. Otherwise, calls the getter function to create one and stores it. ### Signature ```typescript function useHttpServer(getter: () => import('node:http').Server): import('node:http').Server ``` ### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | getter | `() => import('node:http').Server` | yes | Function that creates and returns a new HTTP server instance | ### Return Value `import('node:http').Server` — The existing HTTP server instance, or the result of calling `getter()` if none exists. ### Example ```typescript import { Server } from 'node:http'; import { useHttpServer } from 'next-ws/server'; const server = useHttpServer(() => new Server()); ``` ``` -------------------------------- ### WebSocket Server Storage Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/INDEX.md Utilities for getting, setting, and using the WebSocket server instance. ```APIDOC ## WebSocket Server Storage ### Description Provides functions to manage the WebSocket server instance within the application. ### Functions - `getWebSocketServer()`: Retrieves the current WebSocket server instance. - `setWebSocketServer(value)`: Sets the WebSocket server instance. - `useWebSocketServer(getter)`: Uses a getter function to access the WebSocket server instance. ``` -------------------------------- ### Production Deployment Checklist with next-ws Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/cli-reference.md Essential commands to run before deploying your Next.js application to production, ensuring patches are verified, the application is built, tests pass, and the server starts correctly. ```bash # Verify patches are in place npx next-ws verify # Build the application npm run build # Test WebSocket routes npm test # Start the server npm start ``` -------------------------------- ### WebSocket Server Setup with Redis Adapter Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/server-setup.md Configures next-ws with a custom Redis adapter for multi-instance support. This allows broadcasting messages across different server instances. ```typescript import { Server } from 'node:http'; import Redis from 'ioredis'; import { setupWebSocketServer, type Adapter } from 'next-ws/server'; class RedisAdapter implements Adapter { private pub = new Redis(process.env.REDIS_URL); private sub = new Redis(process.env.REDIS_URL); private handlers = new Map void>>(); async broadcast(room: string, message: unknown): Promise { await this.pub.publish(room, JSON.stringify(message)); } async onMessage( room: string, handler: (message: unknown) => void, ): Promise { if (!this.handlers.has(room)) { this.handlers.set(room, new Set()); await this.sub.subscribe(room); } this.handlers.get(room)?.add(handler); } async close(): Promise { await Promise.all([this.pub.quit(), this.sub.quit()]); } } const httpServer = new Server(); const adapter = new RedisAdapter(); app.prepare().then(() => { // Setup with multi-instance support setupWebSocketServer(app, { adapter }); httpServer.listen(3000); }); ``` -------------------------------- ### Patch Installation Commands Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/quick-start.md Commands to patch the Next.js server for next-ws integration. Use the interactive mode or the `--yes` flag for automatic confirmation. ```bash npx next-ws patch # Interactive npx next-ws patch --yes # Auto-confirm ``` -------------------------------- ### RouteContext with Simple Parameter Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/types.md Example demonstrating how to access a single string route parameter (e.g., 'userId') from the RouteContext.params object. ```typescript // Route: app/api/user/[userId]/route.ts export function UPGRADE(client, server, request, context) { const userId = context.params.userId; // string console.log(`User ID: ${userId}`); } ``` -------------------------------- ### Example: Dynamic Routes with Parameters Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/handlers.md Handle WebSocket connections in dynamic routes, accessing route parameters like 'roomId'. Messages are logged and a success response is sent back. ```typescript // app/api/room/[roomId]/route.ts export function UPGRADE(client, server, request, context) { const roomId = context.params.roomId as string; console.log(`Client joined room: ${roomId}`); // Handle messages for this room client.on('message', (message) => { const data = JSON.parse(message.toString()); console.log(`Message in room ${roomId}: ${data.text}`); client.send(JSON.stringify({ success: true, room: roomId, })); }); } ``` -------------------------------- ### useAdapter() Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/server-persistent.md Gets or creates the adapter instance. If an instance already exists, it is returned. Otherwise, a getter function is called to create a new instance, which is then stored and returned. ```APIDOC ## useAdapter() ### Description Gets or creates the adapter instance. If an instance already exists, returns it. Otherwise, calls the getter function to create one and stores it. ### Signature ```typescript function useAdapter(getter: () => import('./helpers/adapter').Adapter): import('./helpers/adapter').Adapter ``` ### Parameters #### Path Parameters - **getter** (() => Adapter) - Required - Function that creates and returns a new adapter instance ### Return Value `Adapter` — The existing adapter instance, or the result of calling `getter()` if none exists. ### Example ```typescript import { useAdapter, type Adapter } from 'next-ws/server'; const adapter = useAdapter(() => new MyCustomAdapter()); ``` ``` -------------------------------- ### Implement Redis Adapter for Message Broadcasting Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/quick-start.md An example of a Redis adapter for broadcasting messages across multiple instances of your Next.js application. This requires the 'ioredis' package. ```typescript import Redis from 'ioredis'; class RedisAdapter { private pub = new Redis(); private sub = new Redis(); private handlers = new Map(); constructor() { this.sub.on('message', (channel, msg) => { this.handlers.get(channel)?.forEach(h => h(msg)); }); } async broadcast(room, message) { await this.pub.publish(room, JSON.stringify(message)); } async onMessage(room, handler) { if (!this.handlers.has(room)) { this.handlers.set(room, new Set()); await this.sub.subscribe(room); } this.handlers.get(room).add(handler); } async close() { await Promise.all([this.pub.quit(), this.sub.quit()]); } } ``` -------------------------------- ### Example Usage of RouteParams Type Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/types.md Demonstrates how to use the RouteParams type to infer the shape of route parameters for different URL patterns. ```typescript type Params = RouteParams<'/api/user/[userId]'>; // Results in: { userId: string } type Params2 = RouteParams<'/api/files/[...filepath]'>; // Results in: { filepath: string[] } type Params3 = RouteParams<'/api/docs/[[...slug]]'>; // Results in: { slug?: string[] } ``` -------------------------------- ### UPGRADE Handler Example Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/README.md The main handler function exported from WebSocket routes. Receives the connected client, server, request, and route parameters. Can be async. ```typescript export function UPGRADE(client, server, request, context) { client.on('message', (msg) => { // handle message }); } ``` -------------------------------- ### Verify next-ws Patches in GitHub Actions CI/CD Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/cli-reference.md Integrate next-ws verification and build steps into your CI/CD pipeline to ensure patches are applied correctly before deployment. This example uses GitHub Actions. ```yaml # GitHub Actions example - name: Verify patches run: npx next-ws verify --ensure - name: Build run: npm run build - name: Deploy run: npm start ``` -------------------------------- ### Verify and Auto-patch if Needed Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/cli-reference.md Verifies the Next.js patch status and automatically runs the patch command if the installation is not patched. This is useful for ensuring a patched environment. ```bash npx next-ws verify --ensure ``` -------------------------------- ### Redis Adapter Implementation Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/types.md An example implementation of the Adapter interface using Redis for pub/sub message broadcasting across multiple server instances. Ensure a Redis instance is accessible at the specified URL. ```typescript import Redis from 'ioredis'; import type { Adapter } from 'next-ws/server'; class RedisAdapter implements Adapter { private pub: Redis; private sub: Redis; private handlers = new Map void>>(); constructor(redisUrl: string = 'redis://localhost:6379') { this.pub = new Redis(redisUrl); this.sub = new Redis(redisUrl); this.sub.on('message', (channel: string, msg: string) => { const roomHandlers = this.handlers.get(channel); if (!roomHandlers) return; for (const handler of roomHandlers) { handler(JSON.parse(msg)); } }); } async broadcast(room: string, message: unknown): Promise { const messageStr = typeof message === 'string' ? message : JSON.stringify(message); await this.pub.publish(room, messageStr); } async onMessage( room: string, handler: (message: unknown) => void, ): Promise { if (!this.handlers.has(room)) { this.handlers.set(room, new Set()); await this.sub.subscribe(room); } this.handlers.get(room)?.add(handler); } async close(): Promise { await Promise.all([this.pub.quit(), this.sub.quit()]); } } ``` -------------------------------- ### Request Storage Example Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/README.md AsyncLocalStorage wrapper providing access to request headers and cookies in async context without passing request through call stack. ```typescript const storage = getRequestStorage(); const authHeader = storage.headers.get('authorization'); ``` -------------------------------- ### Run next-ws patch command Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/configuration.md Execute the CLI command to patch your local Next.js installation for WebSocket support. Use --yes to skip confirmation prompts. ```bash next-ws patch [options] ``` -------------------------------- ### RouteContext with Multiple Parameters Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/types.md Example showing how to access multiple string route parameters (e.g., 'orgId', 'teamId') from the RouteContext.params object. ```typescript // Route: app/api/org/[orgId]/team/[teamId]/route.ts export function UPGRADE(client, server, request, context) { const orgId = context.params.orgId; // string const teamId = context.params.teamId; // string } ``` -------------------------------- ### Project Documentation Coverage Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/DOCUMENTATION_SUMMARY.txt Details the extent of documentation for various aspects of the project, including the public API, handlers, configuration, CLI commands, and examples. ```APIDOC ## Project Documentation Coverage ### Description Provides a high-level overview of the documentation's completeness for the /k0d13/next-ws project. ### Details - Public API: 100% documented - Handler types: 100% covered (current and deprecated) - Configuration options: 100% covered - CLI commands: 100% covered - Examples: 6 complete, runnable implementations - Architecture: Complete module analysis ``` -------------------------------- ### useWebSocketServer() Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/server-persistent.md Gets or creates the WebSocket server instance. If an instance already exists, it's returned. Otherwise, a getter function is called to create and store a new instance. ```APIDOC ## useWebSocketServer() ### Description Gets or creates the WebSocket server instance. If an instance already exists, returns it. Otherwise, calls the getter function to create one and stores it. ### Signature ```typescript function useWebSocketServer(getter: () => import('ws').WebSocketServer): import('ws').WebSocketServer ``` ### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | getter | `() => import('ws').WebSocketServer` | yes | Function that creates and returns a new WebSocket server instance | ### Return Value `import('ws').WebSocketServer` — The existing WebSocket server instance, or the result of calling `getter()` if none exists. ### Example ```typescript import { WebSocketServer } from 'ws'; import { useWebSocketServer } from 'next-ws/server'; const wsServer = useWebSocketServer(() => new WebSocketServer({ noServer: true })); ``` ``` -------------------------------- ### Route Context Example Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/README.md Type-safe object containing parsed dynamic route parameters. Type parameter is the route path for parameter inference. ```typescript context: RouteContext<'/api/room/[roomId]'> context.params.roomId // string ``` -------------------------------- ### Initialize Request Storage Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/types.md Shows how to get or create the request storage using useRequestStorage, which takes a factory function to initialize a new AsyncLocalStorage if one doesn't exist. Requires importing from 'next-ws/server' and 'node:async_hooks'. ```typescript import { useRequestStorage } from 'next-ws/server'; import { AsyncLocalStorage } from 'node:async_hooks'; const storage = useRequestStorage(() => new AsyncLocalStorage()); ``` -------------------------------- ### RouteContext with Optional Catch-All Parameter Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/types.md Example showing how to access an optional catch-all route parameter (e.g., 'slug') which can be an array of strings or undefined, from RouteContext.params. ```typescript // Route: app/api/docs/[[...slug]]/route.ts export function UPGRADE(client, server, request, context) { const slug = context.params.slug; // string[] | undefined if (slug) { console.log(`Documentation page: ${slug.join('/')}`); } else { console.log('Home page'); } } ``` -------------------------------- ### Client-side WebSocket Connection Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/quick-start.md Connect to the WebSocket server from a Next.js client component and log received messages. This example sends 'hello' upon successful connection. ```typescript 'use client'; import { useEffect } from 'react'; export default function Home() { useEffect(() => { const ws = new WebSocket('ws://localhost:3000/api/ws'); ws.onmessage = (e) => console.log(e.data); ws.onopen = () => ws.send('hello'); }, []); return
Check console
; } ``` -------------------------------- ### Dynamic Route Parameters in WebSocket Handler Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/configuration.md This example shows how to access dynamic route parameters within a WebSocket handler. The parameters are available in the `context.params` object. ```typescript // app/api/room/[roomId]/ws/route.ts export function GET() { return new Response('Upgrade Required', { status: 426 }); } export async function UPGRADE(client, server, request, context) { const roomId = context.params.roomId as string; console.log(`Client connected to room: ${roomId}`); } ``` -------------------------------- ### Use WebSocket Server Instance Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/server-persistent.md Gets or creates a WebSocket server instance. If one exists, it's returned. Otherwise, a new instance is created via the getter function and then stored. ```typescript import { WebSocketServer } from 'ws'; import { useWebSocketServer } from 'next-ws/server'; const wsServer = useWebSocketServer(() => new WebSocketServer({ noServer: true })); ``` -------------------------------- ### Use HTTP Server Instance Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/server-persistent.md Gets or creates an HTTP server instance. If an instance already exists, it's returned. Otherwise, a new instance is created using the provided getter function and then stored. ```typescript import { Server } from 'node:http'; import { useHttpServer } from 'next-ws/server'; const server = useHttpServer(() => new Server()); ``` -------------------------------- ### Verify next-ws Patch Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/configuration.md Run this command to check if your local Next.js installation has been successfully patched by next-ws. It verifies the patch trace file and Next.js version. ```bash next-ws verify [options] ``` -------------------------------- ### ReadonlyRequestsCookies Usage Example Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/server-helpers.md Illustrates the usage of `ReadonlyRequestsCookies`. Read methods like `get()` are functional, whereas attempting to modify cookies using `set()` will throw an error. ```typescript const cookies = new ReadonlyRequestsCookies(headers); console.log(cookies.get('sessionId')?.value); // Works cookies.set('sessionId', 'abc123'); // Throws Error ``` -------------------------------- ### ReadonlyHeaders Usage Example Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/server-helpers.md Demonstrates how to use `ReadonlyHeaders`. Read methods like `get()` work normally, but attempting to modify the headers using `set()` will result in an error. ```typescript const headers = new ReadonlyHeaders(originalHeaders); console.log(headers.get('content-type')); // Works headers.set('x-custom', 'value'); // Throws Error ``` -------------------------------- ### Minimal Echo Server Route Handler Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/quick-start.md Set up a basic WebSocket endpoint in Next.js that echoes messages back to the client. This requires defining both GET and UPGRADE functions in your route handler. ```typescript export function GET() { const headers = new Headers(); headers.set('Connection', 'Upgrade'); headers.set('Upgrade', 'websocket'); return new Response('Upgrade Required', { status: 426, headers }); } export function UPGRADE(client, server) { client.on('message', (msg) => client.send(msg)); } ``` -------------------------------- ### Use Adapter Instance Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/server-persistent.md Gets or creates the adapter instance. If an instance already exists, returns it. Otherwise, calls the getter function to create one and stores it. This is useful for lazy initialization of the adapter. ```typescript import { useAdapter, type Adapter } from 'next-ws/server'; const adapter = useAdapter(() => new MyCustomAdapter()); ``` -------------------------------- ### Get WebSocket Server Instance Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/server-persistent.md Retrieves the globally stored WebSocket server instance. Use this to access an existing WebSocket server, for example, to check the number of connected clients. ```typescript import { getWebSocketServer } from 'next-ws/server'; const wsServer = getWebSocketServer(); if (wsServer) { console.log(`WebSocket server has ${wsServer.clients.size} clients`); } ``` -------------------------------- ### setupWebSocketServer() Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/server-setup.md Initializes and attaches the WebSocket server to a Next.js HTTP server instance. This is the primary entry point for integrating next-ws with a Next.js app directory project. ```APIDOC ## setupWebSocketServer(nextServer, options?) ### Description Initializes and attaches the WebSocket server to a Next.js HTTP server instance. This is the primary entry point for integrating next-ws with a Next.js app directory project. ### Method Function ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **nextServer** (`NextNodeServer`) - Required - The Next.js Node server instance, typically obtained from `app.prepare()` when using a custom server - **options** (`SetupOptions`) - Optional - Configuration options for setup, including optional adapter for multi-instance support - **options.adapter** (`Adapter`) - Optional - Custom adapter implementation for broadcasting messages across multiple server instances via pub/sub ### Response #### Success Response `void` — The function attaches the WebSocket server directly to the provided HTTP server and does not return a value. ### Example #### Basic Setup with Custom Server ```typescript import { Server } from 'node:http'; import { parse } from 'node:url'; import next from 'next'; import { setupWebSocketServer } from 'next-ws/server'; const dev = process.env.NODE_ENV !== 'production'; const app = next({ dev, customServer: true }); const handle = app.getRequestHandler(); const httpServer = new Server(); app.prepare().then(() => { httpServer .on('request', async (req, res) => { if (!req.url) return; const parsedUrl = parse(req.url, true); await handle(req, res, parsedUrl); }) .listen(3000, () => { // Setup WebSocket support after app is ready setupWebSocketServer(app); console.log('Server ready on http://localhost:3000'); }); }); ``` #### Setup with Redis Adapter ```typescript import { Server } from 'node:http'; import Redis from 'ioredis'; import { setupWebSocketServer, type Adapter } from 'next-ws/server'; class RedisAdapter implements Adapter { private pub = new Redis(process.env.REDIS_URL); private sub = new Redis(process.env.REDIS_URL); private handlers = new Map void>>(); async broadcast(room: string, message: unknown): Promise { await this.pub.publish(room, JSON.stringify(message)); } async onMessage( room: string, handler: (message: unknown) => void, ): Promise { if (!this.handlers.has(room)) { this.handlers.set(room, new Set()); await this.sub.subscribe(room); } this.handlers.get(room)?.add(handler); } async close(): Promise { await Promise.all([this.pub.quit(), this.sub.quit()]); } } const httpServer = new Server(); const adapter = new RedisAdapter(); app.prepare().then(() => { // Setup with multi-instance support setupWebSocketServer(app, { adapter }); httpServer.listen(3000); }); ``` ``` -------------------------------- ### GET Handler Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/handlers.md A required GET handler that responds with an error when the connection is not upgraded to WebSocket, adhering to HTTP protocol requirements. ```APIDOC ## GET / ### Description A WebSocket API route must export a `GET` handler that responds with an error when the connection is not upgraded to WebSocket. This is required by HTTP protocol. ### Method GET ### Endpoint / ### Response #### Success Response (426) - **Headers**: `Connection: Upgrade`, `Upgrade: websocket` - **Body**: `Upgrade Required` ### Request Example ```typescript export function GET() { const headers = new Headers(); headers.set('Connection', 'Upgrade'); headers.set('Upgrade', 'websocket'); return new Response('Upgrade Required', { status: 426, headers }); } ``` ``` -------------------------------- ### setupWebSocketServer() API Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/quick-start.md API for setting up the WebSocket server, with options for custom servers and adapters. ```APIDOC ### setupWebSocketServer() ```typescript import { setupWebSocketServer } from 'next-ws/server'; // In custom server after app.prepare() setupWebSocketServer(app); // With adapter setupWebSocketServer(app, { adapter: new RedisAdapter() }); ``` ``` -------------------------------- ### View All next-ws Commands Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/cli-reference.md Displays a list of all available commands and their descriptions for the next-ws CLI. ```bash npx next-ws --help ``` -------------------------------- ### Implement GET Handler for WebSocket Route Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/handlers.md Provides the required GET handler for a WebSocket API route. This handler returns a '426 Upgrade Required' response to enforce WebSocket protocol adherence. ```typescript export function GET() { const headers = new Headers(); headers.set('Connection', 'Upgrade'); headers.set('Upgrade', 'websocket'); return new Response('Upgrade Required', { status: 426, headers }); } ``` -------------------------------- ### Imports for src/server/setup.ts Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/architecture.md Shows the external and internal module imports required by the `setup.ts` file. ```typescript // Imports: `ws`, `next/dist/build/output/log`, `next/dist/server/next-server` // Internal imports: `adapter.ts`, `match.ts`, `module.ts`, `request.ts`, `persistent.ts` // Exports: `setupWebSocketServer()`, `SetupOptions` interface ``` -------------------------------- ### View Specific Command Help Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/cli-reference.md Shows detailed help information for a specific next-ws command, such as 'patch' or 'verify'. ```bash npx next-ws patch --help ``` ```bash npx next-ws verify --help ``` -------------------------------- ### Error Handling Pattern Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/quick-start.md Provides examples for handling errors during message processing and WebSocket connection errors. ```APIDOC ### Error Handling ```typescript client.on('message', (data) => { try { // process message } catch (err) { const message = err instanceof Error ? err.message : 'Unknown error'; client.send(JSON.stringify({ error: message })); } }); client.on('error', (err) => { console.error('WebSocket error:', err); }); ``` ``` -------------------------------- ### Initial Patching or Re-patching Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/cli-reference.md Run the patch command to apply necessary patches if Next.js has not been patched or if the trace file is missing. Alternatively, use 'verify --ensure' to auto-patch. ```bash npx next-ws patch ``` ```bash npx next-ws verify --ensure ``` -------------------------------- ### Broadcast to All Except Sender Pattern Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/quick-start.md Example of broadcasting a received message to all connected clients except the sender. ```APIDOC ### Broadcast to All Except Sender ```typescript client.on('message', (data) => { for (const other of server.clients) { if (client !== other && other.readyState === other.OPEN) { other.send(data); } } }); ``` ``` -------------------------------- ### Package.json Scripts for Development and Production Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/examples.md These scripts configure the development server, production build, and multi-instance deployment using `concurrently`. The `prepare` script is essential for patching Next.js. ```json { "scripts": { "dev": "node server.ts", "build": "next build", "start": "NODE_ENV=production node server.ts", "start:multi": "concurrently 'INSTANCE_ID=1 node server.ts' 'INSTANCE_ID=2 PORT=3001 node server.ts'", "prepare": "next-ws patch" } } ``` -------------------------------- ### Get Request Storage Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/server-persistent.md Retrieves the stored request storage instance, if one has been set. This instance is typically an AsyncLocalStorage. ```typescript import { getRequestStorage } from 'next-ws/server'; const storage = getRequestStorage(); if (storage) { console.log('Request storage is available'); } ``` -------------------------------- ### Get Adapter Instance Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/server-persistent.md Retrieves the globally stored adapter instance. Use this to access the configured adapter for multi-instance scenarios. ```typescript import { getAdapter } from 'next-ws/server'; const adapter = getAdapter(); if (adapter) { console.log('Multi-instance adapter is configured'); } ``` -------------------------------- ### Project Structure Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/architecture.md The project is organized into distinct modules for CLI, client-side helpers, core server implementation, and CLI commands. ```tree src/ ├── cli.ts # CLI entry point ├── client/ # Client-side React helpers (deprecated) │ ├── context.tsx │ └── index.ts ├── server/ # Core server implementation │ ├── setup.ts # Main WebSocket setup function │ ├── persistent.ts # Global singleton storage │ ├── helpers/ │ │ ├── adapter.ts # Multi-instance adapter interface │ │ ├── socket.ts # Handler type definitions │ │ ├── module.ts # Route module loading │ │ ├── request.ts # Request conversion utilities │ │ ├── match.ts # Route matching logic │ │ └── store.ts # Request storage API │ └── index.ts # Server module exports └── commands/ # CLI implementation ├── index.ts # Command group definition ├── patch.ts # Patch command ├── verify.ts # Verify command └── helpers/ # CLI utilities ├── define.ts # Command definition helpers ├── console.ts # Console utilities └── semver.ts # Version utilities ``` -------------------------------- ### Usage Recommendations - Learning Path Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/DOCUMENTATION_SUMMARY.txt Suggests a learning path for users to progressively understand the project's features and APIs. ```APIDOC ## Usage Recommendations: LEARNING PATH ### Description Recommends a sequence for learning the project's concepts and APIs. ### Recommended Order 1. quick-start.md (overview) 2. examples.md (usage patterns) 3. api-reference/handlers.md (handler API) 4. api-reference/server-setup.md (setup) 5. types.md (type details) ``` -------------------------------- ### Import Server and Client APIs Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/quick-start.md Demonstrates the correct import paths for server-side and client-side APIs provided by the next-ws library. Note the deprecated client API. ```typescript // Server API import { setupWebSocketServer } from 'next-ws/server'; import type { Adapter, RouteContext } from 'next-ws/server'; // Client API (deprecated) import { WebSocketProvider, useWebSocket } from 'next-ws/client'; // Types import type { UpgradeHandler } from 'next-ws/server'; ``` -------------------------------- ### Get HTTP Server Instance Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/server-persistent.md Retrieves the globally stored HTTP server instance. Use this when you need to access an existing HTTP server. ```typescript import { getHttpServer } from 'next-ws/server'; const server = getHttpServer(); if (server) { console.log('HTTP server is available'); } ``` -------------------------------- ### Adapter Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/types.md Interface for multi-instance WebSocket deployments, enabling message broadcasting across multiple server instances via pub/sub. ```APIDOC ## Interface: Adapter ### Description Interface for multi-instance WebSocket deployments. Enables message broadcasting across multiple server instances via pub/sub. ### Methods #### broadcast(room: string, message: unknown): Promise Broadcasts a message to all instances subscribed to the specified room. **Parameters:** - **room** (string): Room identifier, typically the route pathname (e.g., `/api/chat`) - **message** (unknown): Message to broadcast; will be JSON stringified if needed #### onMessage(room: string, handler: (message: unknown) => void): void | Promise Subscribes to messages for a specific room. **Parameters:** - **room** (string): Room identifier to subscribe to - **handler** (`(message: unknown) => void`): Callback invoked when messages arrive for this room #### close(): Promise Cleans up adapter resources: closes connections, unsubscribes from channels, and releases all stored references. ``` -------------------------------- ### getHttpServer() Source: https://github.com/k0d13/next-ws/blob/main/_autodocs/api-reference/server-persistent.md Retrieves the stored HTTP server instance. Returns the instance if set, otherwise undefined. ```APIDOC ## getHttpServer() ### Description Retrieves the stored HTTP server instance, if one has been set. ### Signature ```typescript function getHttpServer(): import('node:http').Server | undefined ``` ### Return Value `import('node:http').Server | undefined` — The stored HTTP server instance, or `undefined` if not yet set. ### Example ```typescript import { getHttpServer } from 'next-ws/server'; const server = getHttpServer(); if (server) { console.log('HTTP server is available'); } ``` ```