npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

serve-cold

v0.0.1

Published

A powerful, flexible HTTP/HTTPS server implementation for Node.js that closely mimics web browser APIs while providing additional features like WebSockets, Server-Sent Events, middleware, and routing.

Downloads

154

Readme

Serve Cold ❄️

[!WARNING] Serve cold has been deprecated in favor of LeServe

"HTTP is a dish best best serve co... wait a minute... does that make sense?"

npm version License: MIT

A simple HTTP server with support for modern JavaScript features.

Installation

npm install serve-cold

Usage: serve

(See similar: Deno.serve)

import serve from "serve-cold/serve";

const handler = (request) => {
  return new Response("Hello, World!", {
    status: 200,
    headers: { "Content-Type": "text/plain" },
  });
};

const server = serve(handler, { port: 3000 });

API

serve(handlerOrOptions, maybeHandler)

  • handlerOrOptions: Either a handler function or an options object.
  • maybeHandler: If the first argument is an options object, this should be the handler function.
Options
  • port: Port number (default: 8000)
  • hostname: Hostname (default: 'localhost')
  • cert: SSL certificate for HTTPS (optional)
  • key: SSL key for HTTPS (optional)
Handler Function

The handler function receives a Request object and should return a Response object or a Promise that resolves to a Response object.

Usage: events + controls

(See similar: WinterJS)

import "serve-cold/events";
import { start } from "serve-cold/controls";
start({ port: 3000 });
addEventListener("fetch", (event) => {
  event.respondWith(new Response("Hello, World!", { status: 200 }));
});

Features

Event Listeners

  • addEventListener(event, handler): Add an event listener
  • removeEventListener(event, handler): Remove an event listener

Available events:

| Event | Description | | --------- | ------------------------------------------------------ | | fetch | Emitted for handling HTTP requests | | start | Emitted when the server starts | | stop | Emitted when the server stops | | error | Emitted when a server error occurs | | request | Emitted for every incoming request | | websocket | Emitted when a new WebSocket connection is established |

Server Control

  • start(options): Start the server
  • stop(): Stop the server
  • emit(event, ...args): Emit a custom event

Middleware

use(async (req, res) => {
  console.log(`[Middleware] ${req.method} ${req.url}`);
  return req;
});

Routing

route("GET", "/hello/:name", async (req, params) => {
  return new Response(`Hello, ${params.name}!`, { status: 200 });
});

WebSockets

addEventListener("websocket", (ws) => {
  ws.on("message", (message) => {
    console.log("Received:", message);
    ws.send(`Echo: ${message}`);
  });
});

Server-Sent Events

addEventListener("fetch", async (event) => {
  if (event.request.url.endsWith("/sse")) {
    const headers = new Headers({
      "Content-Type": "text/event-stream",
      "Cache-Control": "no-cache",
      Connection: "keep-alive",
    });
    const response = new Response(null, { headers });

    const stream = new ReadableStream({
      start(controller) {
        setInterval(() => {
          const event = createServerSentEvent(
            { time: new Date().toISOString() },
            "update"
          );
          controller.enqueue(event);
        }, 1000);
      },
    });

    response.body = stream;
    event.respondWith(response);
  }
});

API Reference

Server Options

type ServerOptions = {
  port: number;
  https?: {
    key: string;
    cert: string;
  };
};

Middleware Function

type MiddlewareFunction = (
  req: Request,
  res: Response
) => Promise<Request | Response | void>;

Route Handler

type RouteHandler = (
  req: Request,
  params: Record<string, string>
) => Promise<Response>;

Global Functions

  • addEventListener(event: string, handler: Function): void
  • removeEventListener(event: string, handler: Function): void

Controls

  • start(options: ServerOptions): Promise<void>
  • stop(): Promise<void>
  • emit(event: string, ...args: any[]): boolean
  • use(middleware: MiddlewareFunction): void
  • route(method: string, path: string, handler: RouteHandler): void
  • createServerSentEvent(data: any, event?: string, id?: string): string

Global Types

The following Web API types are made available globally:

  • Request
  • Response
  • Headers
  • URL
  • URLSearchParams
  • WebSocket

Examples

Starting an HTTPS Server

import fs from "fs";

const httpsOptions = {
  key: fs.readFileSync("path/to/key.pem"),
  cert: fs.readFileSync("path/to/cert.pem"),
};

start({ port: 3000, https: httpsOptions });

Using Middleware and Routing

use(async (req, res) => {
  console.log(`[Middleware] ${req.method} ${req.url}`);
  return req;
});

route("GET", "/hello/:name", async (req, params) => {
  return new Response(`Hello, ${params.name}!`, { status: 200 });
});

route("POST", "/echo", async (req) => {
  const body = await req.json();
  return new Response(JSON.stringify(body), {
    status: 200,
    headers: { "Content-Type": "application/json" },
  });
});

WebSocket Echo Server

addEventListener("websocket", (ws) => {
  console.log("New WebSocket connection");
  ws.on("message", (message) => {
    console.log("Received:", message);
    ws.send(`Echo: ${message}`);
  });
});

Server-Sent Events

addEventListener("fetch", async (event) => {
  if (event.request.url.endsWith("/sse")) {
    const headers = new Headers({
      "Content-Type": "text/event-stream",
      "Cache-Control": "no-cache",
      Connection: "keep-alive",
    });
    const response = new Response(null, { headers });
    let counter = 0;

    const stream = new ReadableStream({
      start(controller) {
        const interval = setInterval(() => {
          const event = createServerSentEvent({ counter: counter++ }, "update");
          controller.enqueue(event);
        }, 1000);

        setTimeout(() => {
          clearInterval(interval);
          controller.close();
        }, 10000);
      },
    });

    response.body = stream;
    event.respondWith(response);
  }
});

Usage: CLI

A flexible CLI tool for serving JavaScript modules with various options.

Installation

npm install -g serve-cold

Usage

serve-cold <path-to-file> [options]

Or

npx serve-cold <path-to-file> [options]

Options

  • -p, --port <port>: Specify the port number (default: 8000)
  • -e, --export <name>: Specify the export name to use (default: 'default')
  • -E, --events: Enable events mode
  • --echo: Enable echo mode

Default Behavior

By default, serve-cold serves the default export from the specified file at localhost:8000 using ./serve.mjs.

Example:

// myHandler.mjs
export default (request) => {
  return new Response("Default Handler", {
    headers: {
      "content-type": "text/plain",
    },
  });
};
serve-cold myHandler.mjs

This serves the default export from myHandler.mjs at localhost:8000.

Port Flag

You can specify a custom port using the -p or --port flag:

serve-cold myHandler.mjs -p 8001

This serves the default export from myHandler.mjs at localhost:8001.

Export Flag

You can choose an alternative export with the -e or --export flag:

// myHandlers.mjs
export const handler = (request) => {
  return new Response("Named Handler", {
    headers: {
      "content-type": "text/plain",
    },
  });
};
serve-cold myHandlers.mjs -p 8080 -e handler

This serves the export named 'handler' from myHandlers.mjs at localhost:8080.

Events Mode

Using the -E or --events flag causes the server to respond to events using ./controls.mjs and ./event.mjs.

Example:

// myEventHandler.mjs
addEventListener("fetch", async (event) => {
  event.respondWith(new Response("Event!"));
});
serve-cold myEventHandler.mjs -E

This listens for events at localhost:8000.

You can still use the port flag in events mode:

serve-cold myEventHandler.mjs -E -p 8080

This listens for events at localhost:8080.

Echo Mode

Using the -E or --events flag causes the server to respond as an echo server.

serve-cold --echo

echos back requests as responses in JSON format on port 8000.

License

This project is licensed under the MIT License.