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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@swizzyweb/swizzy-web-service

v0.5.5

Published

Web service framework for swizzy dyn serve

Readme

SwizzyWebService

Swizzy web service is a library for creating self contained web services. The library is object oriented and provides base implementations for all of the components necessary to get a web service up and running.

Getting Started

Install via npm

npm install --registry=https://npm.swizzyweb.com @swizzyweb/swizzy-web-service

Creating your first web service

Create web service

// ./web-service.ts
// WebServiceStatae containing properties used by web service, routers, or controllers
export interface SampleBackendWebServiceState {
  yourStatePropery: "my variable (can be any data type)"
...
}

// Constructor properties, can extend base interface to get base properties
export interface SampleBackendWebServiceProps
  extends IWebServiceProps<SampleBackendWebServiceState> {
  port: number;
  path?: string;
}

// Web service implementation, basically just need to inject properties
export class SampleBackendWebService extends WebService<SampleBackendWebServiceState> {
  constructor(props: SampleBackendWebServiceProps) {
    super({
      ...props,
      name: "SampleBackendWebService",
      path: props.path??'yourRootPath',
      packageName: "your-package-name",
      routerClasses: [
        YourRouter,
        ...
      ],
      middleware: [],
    });
  }
}

Create router

// ./routers/StatisticsRouter/statistics-router.ts

// Router state
export interface StatisticsRouterState {
  serverStartTime: number;
}
// Router state with properties used by router and controllers
export interface StatisticsRouterProps
  extends IWebRouterProps<
    SampleBackendWebServiceState,
    StatisticsRouterState
  > {}

// WebRouter implementation, wires up controllers, middleware, and state converter
export class StatisticsWebRouter extends WebRouter<
  SampleBackendWebServiceState,
  StatisticsRouterState
> {
  constructor(props: StatisticsRouterProps) {
    super({
      ...props,
      name: "StatisticsWebRouter",
      path: "stats",
      stateConverter: StatisticsRouterStateConverter,
      webControllerClasses: [UpTimeController],
      middleware: [
        SwizzyRequestMiddleware,
        RequestIdMiddleware,
        RequestLoggerMiddleware,
      ],
    });
  }
}

// State converter converting state from web service to router state.
const StatisticsRouterStateConverter: StateConverter<
  SampleBackendWebServiceState,
  StatisticsRouterState
> = async function (
  props: StateConverterProps<SampleBackendWebServiceState>,
): Promise<StatisticsRouterState> {
  return { ...props.state };
};

Create Controller

// ./routers/StatisticsRouter/controllers/uptime-controller.ts
// Controller state
export interface UpTimeControllerState {
  serverStartTime: number;
}

// Controller constructor properties
export interface UpTimeControllerProps
  extends IWebControllerProps<StatisticsRouterState, UpTimeControllerState> {}

// Controller implementation
export class UpTimeController extends WebController<
  StatisticsRouterState,
  UpTimeControllerState
> {
  constructor(props: UpTimeControllerProps) {
    super({
      ...props,
      name: "UpTimeController" /**Name of controller**/,
      action: "uptime" /**last component of url**/,
      method: RequestMethod.get /**Request method**/,
      /**State converter taking in router state and convert to this state**/
      stateConverter: DefaultStateExporter,
      middleware: [/**Any middleware to use**/],
    });
  }

  // This is where the main controller logic is handled.
  protected async getInitializedController(
/** This will be removed, use getState() instead **/
    props: IWebControllerInitProps<StatisticsRouterState> & {
      state: UpTimeControllerState | undefined;
    },
  ): Promise<WebControllerFunction> {
    const logger = this.logger;
    // Adding the bind here is required to use the state in the controller function.
    const getState = this.getState.bind(this);
    return async function (req: Request, res: Response) {
      try {
        const { serverStartTime } = getState()!;
        const now = Date.now();
        const upTime = now - serverStartTime;
        res.json({
          now,
          upSince: {
            epoch: serverStartTime,
            date: new Date(serverStartTime),
          },
          upTime,
        });
      } catch (e: any) {
        res.status(500);
        res.json({ message: "Internal error occurred" });
      }
    };
  }
}

Wire up stack and expose

./app.ts
// getWebservice props
export interface GetSampleFrontendWebserviceProps {
  serviceArgs: {
    /** web service specific arguments **/
    ...
  };
}
export async function getWebservice(
  props: GetSampleFrontendWebserviceProps & any,
) {
  const state = {
    serverStartTime: Date.now(),
  };
  return new SampleBackendWebService({
    ...props,
    ...props.serviceArgs,
    state,
  });
}

Add entrypoint to package.json

// package.json
{
  ...,
  "main": "dist/app.js"
  ...
}

Run

npm install
npm run build
swerve

Docs

https://swizzyweb.github.io/swizzy-web-service/

Sample apps

Frontend template

https://github.com/swizzyweb/swizzy-frontend-template-web-service

Backend template

https://github.com/swizzyweb/swizzy-backend-template-web-service

Architecture

The architecture of a swizzy web service is made up of 3 layers, the WebService, Router, and Controller.

WebService

The web service layer is the top layer of a SwizzyWebService and contains all other layers. It contains all other layers as well as the base path of the web service. The base implementation this class orchestrates the initialization of the web service when installed with swerve.

WebRouter

Web routers act as a collection of controllers that are the endpoints of the web service api. The Web router has a path that is appended to the web service path, and routes to child controllers. The controllers of a web router are injected in the base constructor of the WebRouter class.

WebController

Web controllers are the handler for user requests.

#Middleware

Middleware can be injected into any of the layers to peform request pre-processing. Common use cases are validation, authorization, logging, request parsing, and others.

State

State can be injected into a SwizzyWebService to share context between routers and controllers. This is a good place to inject database clients, service clients, or any dependency that you'll need in your controllers.

State Converter

State converters are used to transform state between each of the layers. WebRouters and WebControllers each have a state converter that takes in the parent state and transforms it to the current layers state. IE: WebServiceState -> WebRouterState, WebRouterState -> WebControllerState.

Notes

Tests now require node 24 as of v0.5.0