Deno Samples

Deno runtime examples including HTTP server, WebSocket, Oak framework, and NanoJS

Key Facts

Category
Web Frameworks
Items
4
Format Families
sample

Sample Overview

Deno runtime examples including HTTP server, WebSocket, Oak framework, and NanoJS This sample set belongs to Web Frameworks and can be used to test related workflows inside Elysia Tools.

💻 Deno Hello World typescript

🟢 simple

Basic Deno HTTP server setup and Hello World application

// Deno Hello World Examples

// 1. Basic HTTP server using std/http
import { serve } from "https://deno.land/[email protected]/http/server.ts";

async function handler(req: Request): Promise<Response> {
    const url = new URL(req.url);

    switch (url.pathname) {
        case '/':
            return new Response("Hello, World!");
        case '/hello':
            return new Response("Hello from Deno!");
        case '/hello/:name':
            const name = url.pathname.split('/')[2];
            return new Response(`Hello, ${name}!`);
        default:
            return new Response("Not Found", { status: 404 });
    }
}

console.log("Listening on http://localhost:8000");
await serve(handler, { port: 8000 });

// 2. JSON response
async function handler(req: Request): Promise<Response> {
    const url = new URL(req.url);

    if (url.pathname === '/api/hello') {
        return Response.json({
            message: 'Hello, World!',
            timestamp: new Date().toISOString(),
            version: '1.0.0',
            runtime: 'Deno'
        });
    }

    return new Response('Hello, World!');
}

// 3. HTTP methods handling
async function handler(req: Request): Promise<Response> {
    const url = new URL(req.url);
    const method = req.method;

    if (url.pathname === '/api/users') {
        switch (method) {
            case 'GET':
                return Response.json(['Alice', 'Bob', 'Charlie']);
            case 'POST':
                return new Response('User created', { status: 201 });
            default:
                return new Response('Method Not Allowed', { status: 405 });
        }
    }

    return new Response('Hello, World!');
}

// 4. Request body parsing
async function handler(req: Request): Promise<Response> {
    const url = new URL(req.url);

    if (url.pathname === '/api/hello' && req.method === 'POST') {
        const body = await req.json();
        return Response.json({
            greeting: `Hello, ${body.name || 'World'}!`,
            message: body.message || 'Welcome to Deno',
            receivedAt: new Date().toISOString()
        });
    }

    return new Response('Hello, World!');
}

// 5. HTML response
async function handler(req: Request): Promise<Response> {
    const url = new URL(req.url);

    if (url.pathname === '/') {
        const html = `
            <!DOCTYPE html>
            <html>
            <head>
                <title>Hello Deno</title>
            </head>
            <body>
                <h1>Hello, World!</h1>
                <p>This is an HTML response from Deno</p>
            </body>
            </html>
        `;
        return new Response(html, {
            headers: { 'Content-Type': 'text/html' }
        });
    }

    return new Response('Hello, World!');
}

// 6. Error handling
async function handler(req: Request): Promise<Response> {
    const url = new URL(req.url);

    if (url.pathname === '/error') {
        throw new Error('Something went wrong!');
    }

    return new Response('Hello, World!');
}

// Run with error handling
try {
    await serve(handler, { port: 8000 });
} catch (error) {
    console.error('Server error:', error);
}

// 7. File serving
import { dirname, join } from "https://deno.land/[email protected]/path/mod.ts";

async function fileHandler(req: Request): Promise<Response> {
    const url = new URL(req.url);
    const filePath = url.pathname === '/' ? './public/index.html' : `./public${url.pathname}`;

    try {
        const file = await Deno.open(filePath);
        const fileInfo = await file.stat();

        if (fileInfo.isDirectory) {
            file.close();
            const indexPath = join(filePath, 'index.html');
            const indexFile = await Deno.open(indexPath);
            return new Response(indexFile.readable);
        }

        return new Response(file.readable);
    } catch (error) {
        return new Response('File not found', { status: 404 });
    }
}

console.log("File server listening on http://localhost:8000");
await serve(fileHandler, { port: 8000 });

// 8. Streaming response
async function streamingHandler(req: Request): Promise<Response> {
    const url = new URL(req.url);

    if (url.pathname === '/stream') {
        const encoder = new TextEncoder();
        const readable = new ReadableStream({
            start(controller) {
                let count = 0;
                const interval = setInterval(() => {
                    controller.enqueue(encoder.encode(`data: Message ${count++}\n\n`));
                    if (count >= 10) {
                        clearInterval(interval);
                        controller.close();
                    }
                }, 1000);
            }
        });

        return new Response(readable, {
            headers: {
                'Content-Type': 'text/event-stream',
                'Cache-Control': 'no-cache',
                'Connection': 'keep-alive'
            }
        });
    }

    return new Response('Hello, World!');
}

console.log("Streaming server listening on http://localhost:8000");
await serve(streamingHandler, { port: 8000 });

💻 Deno Oak Framework typescript

🟡 intermediate

Web application development using Oak framework for Deno

// Deno Oak Framework Examples

// 1. Basic Oak application
import { Application, Router, Context } from "https://deno.land/x/[email protected]/mod.ts";
import { create, verify } from "https://deno.land/x/[email protected]/mod.ts";

const app = new Application();
const router = new Router();

// Basic routes
router.get("/", (ctx) => {
    ctx.response.body = "Hello, Oak!";
});

router.get("/hello/:name", (ctx) => {
    const { name } = ctx.params;
    ctx.response.body = `Hello, ${name}!`;
});

app.use(router.routes());
app.use(router.allowedMethods());

console.log("Oak server listening on http://localhost:8000");
await app.listen({ port: 8000 });

// 2. Oak with middleware
const appWithMiddleware = new Application();

// Logger middleware
appWithMiddleware.use(async (ctx, next) => {
    await next();
    const rt = ctx.response.headers.get("X-Response-Time");
    console.log(`${ctx.request.method} ${ctx.request.url} - ${rt}`);
});

// Timing middleware
appWithMiddleware.use(async (ctx, next) => {
    const start = Date.now();
    await next();
    const ms = Date.now() - start;
    ctx.response.headers.set("X-Response-Time", `${ms}ms`);
});

// CORS middleware
appWithMiddleware.use(async (ctx, next) => {
    ctx.response.headers.set("Access-Control-Allow-Origin", "*");
    ctx.response.headers.set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
    ctx.response.headers.set("Access-Control-Allow-Headers", "Content-Type, Authorization");
    await next();
});

// Router with routes
const middlewareRouter = new Router();

middlewareRouter.get("/", (ctx) => {
    ctx.response.body = {
        message: "Hello from Oak!",
        timestamp: new Date().toISOString()
    };
});

middlewareRouter.get("/api/users", (ctx) => {
    ctx.response.body = [
        { id: 1, name: "John Doe", email: "[email protected]" },
        { id: 2, name: "Jane Smith", email: "[email protected]" }
    ];
});

middlewareRouter.post("/api/users", async (ctx) => {
    const body = ctx.request.body({ type: "json" });
    const user = await body.value;

    ctx.response.body = {
        id: 3,
        ...user,
        createdAt: new Date().toISOString()
    };
    ctx.response.status = 201;
});

appWithMiddleware.use(middlewareRouter.routes());
appWithMiddleware.use(middlewareRouter.allowedMethods());

// Error handling middleware
appWithMiddleware.use(async (ctx, next) => {
    try {
        await next();
    } catch (err) {
        console.error(err);
        ctx.response.status = 500;
        ctx.response.body = { error: "Internal Server Error" };
    }
});

console.log("Oak server with middleware listening on http://localhost:8000");
await appWithMiddleware.listen({ port: 8000 });

// 3. Oak with static files and templates
const appWithTemplates = new Application();
const templateRouter = new Router();

// Template function
function renderTemplate(template: string, data: Record<string, any> = {}): string {
    return template.replace(/\{\{(\w+)\}\}/g, (match, key) => {
        return data[key] || match;
    });
}

// HTML template
const indexTemplate = `
<!DOCTYPE html>
<html>
<head>
    <title>{{title}}</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 40px; }
        .container { max-width: 800px; margin: 0 auto; }
        .user { border: 1px solid #ddd; padding: 10px; margin: 10px 0; }
    </style>
</head>
<body>
    <div class="container">
        <h1>{{title}}</h1>
        <p>{{message}}</p>
        <div class="users">
            {{users}}
        </div>
    </div>
</body>
</html>
`;

// Routes
templateRouter.get("/", async (ctx) => {
    const html = renderTemplate(indexTemplate, {
        title: "Oak Demo",
        message: "Welcome to Oak framework with Deno!",
        users: `
            <div class="user">
                <h3>John Doe</h3>
                <p>Email: [email protected]</p>
            </div>
            <div class="user">
                <h3>Jane Smith</h3>
                <p>Email: [email protected]</p>
            </div>
        `
    });

    ctx.response.body = html;
    ctx.response.headers.set("Content-Type", "text/html");
});

templateRouter.get("/api/data", (ctx) => {
    ctx.response.body = {
        users: [
            { id: 1, name: "John Doe", email: "[email protected]" },
            { id: 2, name: "Jane Smith", email: "[email protected]" }
        ],
        timestamp: new Date().toISOString()
    };
});

// Static file serving
appWithTemplates.use(async (ctx, next) => {
    const path = ctx.request.url.pathname;

    if (path.startsWith("/static/")) {
        try {
            const file = await Deno.open(`.${path}`);
            ctx.response.body = file.readable;
            return;
        } catch (error) {
            // File not found, continue to next middleware
        }
    }

    await next();
});

appWithTemplates.use(templateRouter.routes());
appWithTemplates.use(templateRouter.allowedMethods());

console.log("Oak server with templates listening on http://localhost:8000");
await appWithTemplates.listen({ port: 8000 });

// 4. Oak REST API with authentication middleware

interface User {
    id: number;
    name: string;
    email: string;
    role: string;
}

const users: User[] = [
    { id: 1, name: "John Doe", email: "[email protected]", role: "admin" },
    { id: 2, name: "Jane Smith", email: "[email protected]", role: "user" }
];

const JWT_SECRET = "your-secret-key";

const authApp = new Application();
const authRouter = new Router();

// Authentication middleware
async function jwtAuthMiddleware(ctx: Context, next: () => Promise<void>) {
    const authHeader = ctx.request.headers.get("Authorization");

    if (!authHeader?.startsWith("Bearer ")) {
        ctx.response.status = 401;
        ctx.response.body = { error: "No token provided" };
        return;
    }

    const token = authHeader.slice(7);

    try {
        const payload = await verify(token, JWT_SECRET);
        ctx.state.user = payload;
        await next();
    } catch (error) {
        ctx.response.status = 401;
        ctx.response.body = { error: "Invalid token" };
    }
}

// Role-based authorization middleware
function roleMiddleware(requiredRole: string) {
    return async (ctx: Context, next: () => Promise<void>) => {
        const user = ctx.state.user;

        if (!user || user.role !== requiredRole) {
            ctx.response.status = 403;
            ctx.response.body = { error: "Insufficient permissions" };
            return;
        }

        await next();
    };
}

// Public routes
authRouter.post("/auth/login", async (ctx) => {
    const { email, password } = await ctx.request.body({ type: "json" }).value;

    // Mock authentication
    if (email === "[email protected]" && password === "password") {
        const user = users.find(u => u.email === email);
        const jwt = await create({ alg: "HS256", typ: "JWT" }, { ...user }, JWT_SECRET);

        ctx.response.body = { token: jwt, user };
    } else {
        ctx.response.status = 401;
        ctx.response.body = { error: "Invalid credentials" };
    }
});

// Protected routes
authRouter.get("/api/users", jwtAuthMiddleware, (ctx) => {
    ctx.response.body = users;
});

authRouter.get("/api/users/:id", jwtAuthMiddleware, (ctx) => {
    const id = parseInt(ctx.params.id!);
    const user = users.find(u => u.id === id);

    if (!user) {
        ctx.response.status = 404;
        ctx.response.body = { error: "User not found" };
        return;
    }

    ctx.response.body = user;
});

authRouter.delete("/api/users/:id", jwtAuthMiddleware, roleMiddleware("admin"), (ctx) => {
    const id = parseInt(ctx.params.id!);
    const index = users.findIndex(u => u.id === id);

    if (index === -1) {
        ctx.response.status = 404;
        ctx.response.body = { error: "User not found" };
        return;
    }

    users.splice(index, 1);
    ctx.response.body = { message: "User deleted successfully" };
});

authApp.use(authRouter.routes());
authApp.use(authRouter.allowedMethods());

console.log("Oak API server with auth listening on http://localhost:8000");
await authApp.listen({ port: 8000 });

💻 Deno NanoJS Framework typescript

🟡 intermediate

Lightweight web framework NanoJS for Deno applications

// Deno NanoJS Framework Examples

// 1. Basic NanoJS application
import { nanoServer } from "https://deno.land/x/[email protected]/mod.ts";

const server = nanoServer();

// GET routes
server.get("/", () => "Hello, NanoJS!");

server.get("/hello/:name", (req) => {
    return `Hello, ${req.params.name}!`;
});

server.get("/api/hello", () => {
    return {
        message: "Hello, World!",
        timestamp: new Date().toISOString(),
        framework: "NanoJS"
    };
});

// POST routes
server.post("/api/hello", (req) => {
    return {
        greeting: `Hello, ${req.body.name || 'World'}!`,
        message: req.body.message || "Welcome to NanoJS"
    };
});

// Start server
server.listen({ port: 8000 });
console.log("NanoJS server listening on http://localhost:8000");

// 2. NanoJS with middleware
import { nanoServer } from "https://deno.land/x/[email protected]/mod.ts";

const server = nanoServer();

// Logger middleware
server.use((req, res, next) => {
    console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`);
    next();
});

// CORS middleware
server.use((req, res, next) => {
    res.setHeader("Access-Control-Allow-Origin", "*");
    res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
    res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
    next();
});

// Rate limiting middleware
const requests = new Map<string, { count: number; resetTime: number }>();

server.use((req, res, next) => {
    const ip = req.headers.get("x-forwarded-for") || "127.0.0.1";
    const now = Date.now();
    const windowMs = 60000; // 1 minute
    const maxRequests = 100;

    const record = requests.get(ip);

    if (!record || now > record.resetTime) {
        requests.set(ip, { count: 1, resetTime: now + windowMs });
        next();
        return;
    }

    if (record.count >= maxRequests) {
        res.status = 429;
        res.body = { error: "Too Many Requests" };
        return;
    }

    record.count++;
    next();
});

// Routes
server.get("/", () => "Hello, NanoJS with middleware!");

server.get("/api/users", () => {
    return [
        { id: 1, name: "John Doe", email: "[email protected]" },
        { id: 2, name: "Jane Smith", email: "[email protected]" }
    ];
});

server.post("/api/users", (req) => {
    const newUser = {
        id: Date.now(),
        ...req.body,
        createdAt: new Date().toISOString()
    };

    return { message: "User created", user: newUser };
});

server.listen({ port: 8000 });
console.log("NanoJS server with middleware listening on http://localhost:8000");

// 3. NanoJS REST API with validation
import { nanoServer } from "https://deno.land/x/[email protected]/mod.ts";

const server = nanoServer();

// Validation middleware
function validateBody(schema: Record<string, any>) {
    return (req: any, res: any, next: any) => {
        const errors: string[] = [];

        for (const [key, rules] of Object.entries(schema)) {
            const value = req.body[key];

            if (rules.required && (value === undefined || value === null)) {
                errors.push(`${key} is required`);
                continue;
            }

            if (value !== undefined && rules.type && typeof value !== rules.type) {
                errors.push(`${key} must be of type ${rules.type}`);
            }

            if (rules.minLength && value && value.length < rules.minLength) {
                errors.push(`${key} must be at least ${rules.minLength} characters`);
            }

            if (rules.pattern && value && !rules.pattern.test(value)) {
                errors.push(`${key} format is invalid`);
            }
        }

        if (errors.length > 0) {
            res.status = 400;
            res.body = { errors };
            return;
        }

        next();
    };
}

// User schema
const userSchema = {
    name: { required: true, type: "string", minLength: 2 },
    email: {
        required: true,
        type: "string",
        pattern: /^[^\s@]+@[^\s@]+\.[^\s@]+$/
    },
    age: { type: "number", minimum: 18 }
};

// In-memory users database
let users = [
    { id: 1, name: "John Doe", email: "[email protected]", age: 30 },
    { id: 2, name: "Jane Smith", email: "[email protected]", age: 25 }
];

let userIdCounter = 3;

// API Routes
server.get("/api/users", (req, res) => {
    const page = parseInt(req.query.page || "1");
    const limit = parseInt(req.query.limit || "10");
    const search = req.query.search;

    let filteredUsers = users;

    if (search) {
        filteredUsers = users.filter(user =>
            user.name.toLowerCase().includes(search.toLowerCase()) ||
            user.email.toLowerCase().includes(search.toLowerCase())
        );
    }

    const startIndex = (page - 1) * limit;
    const endIndex = startIndex + limit;
    const paginatedUsers = filteredUsers.slice(startIndex, endIndex);

    res.body = {
        users: paginatedUsers,
        pagination: {
            page,
            limit,
            total: filteredUsers.length,
            pages: Math.ceil(filteredUsers.length / limit)
        }
    };
});

server.get("/api/users/:id", (req, res) => {
    const id = parseInt(req.params.id);
    const user = users.find(u => u.id === id);

    if (!user) {
        res.status = 404;
        res.body = { error: "User not found" };
        return;
    }

    res.body = user;
});

server.post("/api/users", validateBody(userSchema), (req, res) => {
    const newUser = {
        id: userIdCounter++,
        ...req.body,
        createdAt: new Date().toISOString()
    };

    users.push(newUser);
    res.status = 201;
    res.body = { message: "User created", user: newUser };
});

server.put("/api/users/:id", validateBody(userSchema), (req, res) => {
    const id = parseInt(req.params.id);
    const userIndex = users.findIndex(u => u.id === id);

    if (userIndex === -1) {
        res.status = 404;
        res.body = { error: "User not found" };
        return;
    }

    users[userIndex] = { ...users[userIndex], ...req.body };
    res.body = { message: "User updated", user: users[userIndex] };
});

server.delete("/api/users/:id", (req, res) => {
    const id = parseInt(req.params.id);
    const userIndex = users.findIndex(u => u.id === id);

    if (userIndex === -1) {
        res.status = 404;
        res.body = { error: "User not found" };
        return;
    }

    const deletedUser = users.splice(userIndex, 1)[0];
    res.body = { message: "User deleted", user: deletedUser };
});

// Health check
server.get("/health", (req, res) => {
    res.body = {
        status: "ok",
        timestamp: new Date().toISOString(),
        uptime: Deno.stdout?.rid || 0,
        stats: {
            users: users.length
        }
    };
});

server.listen({ port: 8000 });
console.log("NanoJS REST API listening on http://localhost:8000");

// 4. NanoJS with WebSocket support
import { nanoServer } from "https://deno.land/x/[email protected]/mod.ts";

const server = nanoServer();

// WebSocket upgrade handling
server.upgrade("/ws", (req, socket) => {
    console.log("WebSocket connection established");

    socket.addEventListener("message", (event) => {
        console.log("Received:", event.data);
        socket.send(`Echo: ${event.data}`);
    });

    socket.addEventListener("close", () => {
        console.log("WebSocket connection closed");
    });

    socket.send("Welcome to NanoJS WebSocket server!");
});

// Regular HTTP routes
server.get("/", () => `
    <!DOCTYPE html>
    <html>
    <head>
        <title>NanoJS WebSocket Demo</title>
    </head>
    <body>
        <h1>NanoJS WebSocket Demo</h1>
        <input type="text" id="messageInput" placeholder="Type a message...">
        <button onclick="sendMessage()">Send</button>
        <div id="messages"></div>

        <script>
            const ws = new WebSocket('ws://localhost:8000/ws');
            const messagesDiv = document.getElementById('messages');
            const messageInput = document.getElementById('messageInput');

            ws.onmessage = function(event) {
                const message = document.createElement('div');
                message.textContent = event.data;
                messagesDiv.appendChild(message);
            };

            function sendMessage() {
                const message = messageInput.value;
                if (message) {
                    ws.send(message);
                    messageInput.value = '';
                }
            }

            messageInput.addEventListener('keypress', function(e) {
                if (e.key === 'Enter') {
                    sendMessage();
                }
            });
        </script>
    </body>
    </html>
`);

server.get("/api/status", () => {
    return {
        message: "NanoJS server with WebSocket support",
        websocket: "ws://localhost:8000/ws",
        timestamp: new Date().toISOString()
    };
});

server.listen({ port: 8000 });
console.log("NanoJS server with WebSocket listening on http://localhost:8000");

💻 Deno WebSocket Server typescript

🟡 intermediate

WebSocket server implementation with Deno and std WebSocket library

// Deno WebSocket Server Examples

// 1. Basic WebSocket server
import { serve } from "https://deno.land/[email protected]/http/server.ts";

async function handler(req: Request): Promise<Response> {
    const url = new URL(req.url);

    if (url.pathname === "/ws") {
        const upgrade = req.headers.get("upgrade") || "";
        if (upgrade.toLowerCase() !== "websocket") {
            return new Response("Expected websocket", { status: 426 });
        }

        const { socket, response } = Deno.upgradeWebSocket(req);

        socket.onopen = () => {
            console.log("WebSocket connection opened");
            socket.send("Welcome to Deno WebSocket server!");
        };

        socket.onmessage = (event) => {
            console.log("Received:", event.data);
            socket.send(`Echo: ${event.data}`);
        };

        socket.onclose = () => {
            console.log("WebSocket connection closed");
        };

        socket.onerror = (error) => {
            console.error("WebSocket error:", error);
        };

        return response;
    }

    return new Response("WebSocket server running");
}

console.log("WebSocket server listening on http://localhost:8000");
await serve(handler, { port: 8000 });

// 2. Chat server with multiple clients
import { serve } from "https://deno.land/[email protected]/http/server.ts";

interface Message {
    type: "message" | "join" | "leave";
    user: string;
    content: string;
    timestamp: string;
}

const clients = new Map<string, WebSocket>();

async function chatHandler(req: Request): Promise<Response> {
    const url = new URL(req.url);

    if (url.pathname === "/chat") {
        const upgrade = req.headers.get("upgrade") || "";
        if (upgrade.toLowerCase() !== "websocket") {
            return new Response("Expected websocket", { status: 426 });
        }

        const { socket, response } = Deno.upgradeWebSocket(req);
        const userId = `user_${Math.random().toString(36).substr(2, 9)}`;

        clients.set(userId, socket);

        // Send join message to all clients
        broadcast({
            type: "join",
            user: "System",
            content: `${userId} joined the chat`,
            timestamp: new Date().toISOString()
        });

        socket.onopen = () => {
            console.log(`${userId} connected`);
            socket.send(`Welcome to the chat! Your ID: ${userId}`);
        };

        socket.onmessage = (event) => {
            const message: Message = {
                type: "message",
                user: userId,
                content: event.data,
                timestamp: new Date().toISOString()
            };

            broadcast(message);
            console.log(`${userId}: ${event.data}`);
        };

        socket.onclose = () => {
            clients.delete(userId);
            console.log(`${userId} disconnected`);

            // Send leave message to all clients
            broadcast({
                type: "leave",
                user: "System",
                content: `${userId} left the chat`,
                timestamp: new Date().toISOString()
            });
        };

        return response;
    }

    // Serve HTML page for chat
    if (url.pathname === "/") {
        return new Response(`
            <!DOCTYPE html>
            <html>
            <head>
                <title>Deno WebSocket Chat</title>
                <style>
                    body { font-family: Arial, sans-serif; margin: 20px; }
                    #messages {
                        border: 1px solid #ccc;
                        height: 400px;
                        overflow-y: scroll;
                        padding: 10px;
                        margin: 10px 0;
                    }
                    #input {
                        width: 70%;
                        padding: 5px;
                    }
                    #send {
                        width: 25%;
                        padding: 5px;
                    }
                    .join { color: green; }
                    .leave { color: red; }
                </style>
            </head>
            <body>
                <h1>Deno WebSocket Chat</h1>
                <div id="messages"></div>
                <input type="text" id="input" placeholder="Type a message...">
                <button id="send">Send</button>

                <script>
                    const ws = new WebSocket('ws://localhost:8000/chat');
                    const messages = document.getElementById('messages');
                    const input = document.getElementById('input');
                    const send = document.getElementById('send');

                    ws.onmessage = function(event) {
                        const data = JSON.parse(event.data);
                        const message = document.createElement('div');
                        message.className = data.type;
                        message.innerHTML = `
                            <strong>${data.user}:</strong>
                            ${data.content}
                            <small>(${new Date(data.timestamp).toLocaleTimeString()})</small>
                        `;
                        messages.appendChild(message);
                        messages.scrollTop = messages.scrollHeight;
                    };

                    function sendMessage() {
                        const text = input.value.trim();
                        if (text) {
                            ws.send(text);
                            input.value = '';
                        }
                    }

                    send.onclick = sendMessage;
                    input.onkeypress = function(e) {
                        if (e.key === 'Enter') sendMessage();
                    };
                </script>
            </body>
            </html>
        `, {
            headers: { "Content-Type": "text/html" }
        });
    }

    return new Response("Chat server running", { status: 404 });
}

function broadcast(message: Message) {
    const messageStr = JSON.stringify(message);
    clients.forEach((client) => {
        client.send(messageStr);
    });
}

console.log("Chat server listening on http://localhost:8000");
await serve(chatHandler, { port: 8000 });

// 3. Real-time notifications server
import { serve } from "https://deno.land/[email protected]/http/server.ts";

interface Notification {
    type: "notification" | "alert" | "update";
    title: string;
    message: string;
    timestamp: string;
}

const notificationClients = new Set<WebSocket>();

async function notificationHandler(req: Request): Promise<Response> {
    const url = new URL(req.url);

    if (url.pathname === "/notifications") {
        const upgrade = req.headers.get("upgrade") || "";
        if (upgrade.toLowerCase() !== "websocket") {
            return new Response("Expected websocket", { status: 426 });
        }

        const { socket, response } = Deno.upgradeWebSocket(req);

        notificationClients.add(socket);

        socket.onopen = () => {
            console.log("Notification client connected");

            // Send periodic notifications
            const interval = setInterval(() => {
                const notifications: Notification[] = [
                    { type: "notification", title: "System Update", message: `Server time: ${new Date().toLocaleTimeString()}`, timestamp: new Date().toISOString() },
                    { type: "alert", title: "Security Alert", message: "Security scan completed successfully", timestamp: new Date().toISOString() },
                    { type: "update", title: "New Feature", message: "Check out our latest updates!", timestamp: new Date().toISOString() }
                ];

                const notification = notifications[Math.floor(Math.random() * notifications.length)];

                notificationClients.forEach(client => {
                    client.send(JSON.stringify(notification));
                });
            }, 5000);

            socket.data.interval = interval;
        };

        socket.onclose = () => {
            notificationClients.delete(socket);
            if (socket.data.interval) {
                clearInterval(socket.data.interval);
            }
        };

        return response;
    }

    // API to send custom notifications
    if (url.pathname === "/api/notify" && req.method === "POST") {
        const body = await req.json();
        const notification: Notification = {
            type: body.type || "notification",
            title: body.title,
            message: body.message,
            timestamp: new Date().toISOString()
        };

        notificationClients.forEach(client => {
            client.send(JSON.stringify(notification));
        });

        return Response.json({ success: true, notification });
    }

    return new Response("Notification server running");
}

console.log("Notification server listening on http://localhost:8000");
await serve(notificationHandler, { port: 8000 });

// 4. WebSocket with authentication
import { serve } from "https://deno.land/[email protected]/http/server.ts";
import { create, verify } from "https://deno.land/x/[email protected]/mod.ts";

const JWT_SECRET = "your-secret-key";

async function authHandler(req: Request): Promise<Response> {
    const url = new URL(req.url);

    // Login endpoint to get token
    if (url.pathname === "/login" && req.method === "POST") {
        const { username, password } = await req.json();

        // Mock authentication
        if (username === "admin" && password === "password") {
            const token = await create(
                { alg: "HS256", typ: "JWT" },
                { username, role: "admin" },
                JWT_SECRET
            );

            return Response.json({ token });
        }

        return Response.json({ error: "Invalid credentials" }, { status: 401 });
    }

    if (url.pathname === "/protected-ws") {
        const authHeader = req.headers.get("authorization");
        if (!authHeader?.startsWith("Bearer ")) {
            return new Response("Unauthorized", { status: 401 });
        }

        const token = authHeader.slice(7);

        try {
            const payload = await verify(token, JWT_SECRET);
            console.log("Authenticated user:", payload);

            const upgrade = req.headers.get("upgrade") || "";
            if (upgrade.toLowerCase() !== "websocket") {
                return new Response("Expected websocket", { status: 426 });
            }

            const { socket, response } = Deno.upgradeWebSocket(req);

            socket.onopen = () => {
                console.log(`${payload.username} connected to protected WebSocket`);
                socket.send(`Welcome ${payload.username}!`);
            };

            socket.onmessage = (event) => {
                console.log(`${payload.username}: ${event.data}`);
                socket.send(`Authenticated message from ${payload.username}: ${event.data}`);
            };

            return response;
        } catch (error) {
            return new Response("Invalid token", { status: 401 });
        }
    }

    return new Response("WebSocket auth server running");
}

console.log("WebSocket auth server listening on http://localhost:8000");
await serve(authHandler, { port: 8000 });