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

wiggly.js

v1.0.13

Published

File-based routing framework based on Hono.js

Downloads

188

Readme

Wiggly Documentation

Introduction

Wiggly is a lightweight framework built on top of the Hono library that simplifies setting up a server with middleware and dynamic routing through a file-based routing system. This guide will walk you through the steps to get started with Wiggly, including setting up middleware, defining routes, and running the server on both Node.js and Bun environments.

Installation

First, install the necessary dependencies:

npm install wiggly.js

Setup

Directory Structure

Wiggly expects a specific directory structure for routes and middleware. The directory structure should look like this, each route can have children and deeply nested children:

project-root/
├── routes/
│   ├── middleware/
│   │   ├── _index.ts
│   ├── your route/
│   │   ├── _middleware.ts
│   │   ├── index.ts
│   │   └── [id].ts
│   │   └── [id]/child dynamic route/
│   │       └── index.ts
|   |          └── /details
|   |               └── index.ts
│   ├── your second route/
│   │   ├── _middleware.ts
│   │   ├── index.ts
│   │   └── [id].ts
|   ├── more routes /
│   │         ├── _middleware.ts
│   │         ├── index.ts
│   │         └── [id].ts
└── index.ts
  • routes/: Contains all your route handlers.
    • middleware/: Global middleware applied to all routes.
      • _index.ts: Global middleware or handlers applied to the root path.
    • your route/: A subdirectory containing route handlers for the your endpoint.
      • _middleware.ts: Middleware specific to the route endpoint.
      • index.ts: Handler for the /user endpoint.
      • [id].ts: Dynamic route handler for /user/:id.
      • [id]/child dynamic route/: A deeply nested directory with its own index.ts handler.
    • Similar structure for other endpoints like more routes/.

Route Handlers

Each route handler file should export functions corresponding to HTTP methods (get, post, put, delete, patch) and/or a default middleware function (_).

Example: routes/user/index.ts

import { Context } from 'hono';

export default {
  get: (c: Context) => {
    const exampleVariable = c.get('exampleVariable');
    const url = c.get('url');
    return c.json({
      message: `message from middleware: ${exampleVariable}, ${url}`,
    });
  },
  post: (c: Context) => {
    const body = c.req.json();
    return c.json({
      message: body,
    });
  },
};

Example: routes/user/[id].ts

import { Context } from 'hono';

export default {
  get: (c: Context) => {
    const id = c.req.param('id');
    return c.json({ message: `User ID: ${id}` });
  },
};

Example: routes/user/[id]/projects/index.ts

import { Context } from 'hono';

export default {
  get: (c: Context) => {
    const id = c.req.param('id');
    return c.json({ message: `Projects for User ID: ${id}` });
  },
};

Middleware

Middleware files should export a default object with a _ function.

Example: routes/middleware/_index.ts

import { Context, Next } from 'hono';

export default {
  _: (c: Context, next: Next) => {
    c.set('exampleVariable', 'Hello 👋');
    return next();
  },
};

Example: routes/user/_middleware.ts

import { Context, Next } from 'hono';

export default {
  _: (c: Context, next: Next) => {
    c.set('url', `google.com`);
    next();
  },
};

Server Setup

Create a new file index.ts at the root of your project:

import { Hono } from 'hono';
import Wiggly from './src/lib/wiggly';

// Initialize Wiggly with base path
const hono_app = new Hono();

// Initialize Wiggly with base path
// Middleware directory and routes directory are by default `/routes` in your project root but should be specified here if different
const wiggly = new Wiggly({
  port: 3000,
  app: new Hono(),
  basePath: '/api/v1',
  routesDir: './src/routes',
  middlewareDir: './src/middleware',
  useLogger: true,
  useNode: true,
});

// Start the server
wiggle.serve();

Running the Server

To start the server, run the following command:

npx tsx index.ts

Server Options

Wiggly supports running the server using either Node.js or Bun. You can specify which server to use by setting the is_node_server flag in the serve method.

Node.js Server

Default option. Uses Node.js's serve function to start the server.

await wiggle.serve(port, true);

Bun Server

To use Bun as the server, set is_node_server to false. Make sure Bun is installed and configured in your environment.

await wiggle.serve(port, false);

API Reference

Wiggly Class

Constructor

new Wiggly(default_args: {
  app?: Hono;
  base_path: string;
  middleware_dir?: string;
  routes_dir?: string;
});
  • app: Optional. Your instance of Hono. If not provided, a new instance is created. See Hono docs.
  • base_path: The base path for all routes.
  • middleware_dir: Optional. Path to the global middleware directory.
  • routes_dir: Optional. Path to the routes directory.

Methods

build_routes(directory: string = this.default_dir, base_path: string = ''): void

Loads route handlers from the specified directory and sets up routing.

  • directory: The directory to load routes from. Defaults to the /routes directory or uses the routes_dir specified in the Wiggly class config.
  • base_path: The base path for the routes.
serve(port: number = 8080, is_node_server: boolean = true, node?: Parameters<typeof node_serve>, bun?: Parameters<typeof bun_serve>): Promise<void>

Starts the server on the specified port.

  • port: The port to start the server on. Defaults to 8080.
  • is_node_server: Boolean flag to determine the server type. Set to true for Node.js or false for Bun.
  • node: Optional arguments for the Node.js serve function. These arguments are used to customize the behavior of the Node.js server.
  • bun: Optional arguments for the Bun serve function. These arguments are used to customize the behavior of the Bun server.

Examples

Example 1: Basic Setup

import Wiggly from 'wiggly';

// Initialize Wiggly with base path
const wiggle = new Wiggly({
  base_path: '/api/v1/',
  middleware_dir: 'src/example/routes/middleware',
  routes_dir: 'src/example/routes',
});

wiggle.serve(8080);

Example 2: Custom Route Handler

Create a custom route handler in routes/user/index.ts:

import { Context } from 'hono';

export default {
  get: (c: Context) => {
    const exampleVariable = c.get('exampleVariable');
    const url = c.get('url');
    return c.json({
      message: `message from middleware: ${exampleVariable}, ${url}`,
    });
  },
  post: async (c: Context) => {
    const body = await c.req.json();
    return c.json({
      message: body,
    });
  },
};

Example 3: Deeply Nested Routes

Wiggly supports deeply nested routes. If you have a file like routes/user/[id]/projects/index.ts, it will work for both /user/:id and /user/:id/projects as long as [id]/projects has its own index.ts. Just pass your parameter as needed.

Start the server:

import { Hono } from 'hono';
import Wiggly from './src/lib/wiggly';

// Initialize Wiggly with base path
const wiggle = new Wiggly({
  base_path: '/api/v1/',
  middleware_dir: 'src/example/routes/middleware',
  routes_dir: 'src/example/routes',
});

wiggle.build_routes();
wiggle.serve(8080);

Conclusion

This documentation provides an overview of how to set up and use the Wiggly framework for building a server with middleware and dynamic routing through a file-based routing system. Follow the directory structure, create your route handlers, and start your server with ease on either Node.js or Bun. Happy coding!