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

flaska

v1.5.1

Published

Flaska is a micro web-framework for node. It is designed to be fast, simple and lightweight, and is distributed as a single file module with no dependencies.

Downloads

331

Readme

Flaska

Flaska is a micro web-framework for node. It is designed to be fast, simple and lightweight, and is distributed as a single file module with no dependencies.

Heavily inspired by koa and koa-router it takes liberties of implementing most of the common functionality required for most sites without sacrificing anything. And the fact that the footprint for this is much smaller than koa while also being more powerful and faster shows the testament that is flaska.

Installation

$ npm install flaska

Hello Flaska

import { Flaska } from '../flaska.mjs'
const flaska = new Flaska()

flaska.get('/', function(ctx) {
  ctx.body = 'Hello Flaska';
})

// flaska.listen(3000);
flaska.listenAsync(3000).then(function() {
  console.log('listening on port 3000')
}, function(err) {
  console.error('Error listening:', err)
})

Router/Handlers

Flaska supports all the common verbs out of the box:

  • flaska.get(url, [middlewares], handler)
  • flaska.post(url, [middlewares], handler)
  • flaska.put(url, [middlewares], handler)
  • flaska.delete(url, [middlewares], handler)
  • flaska.options(url, [middlewares], handler)
  • flaska.patch(url, [middlewares], handler)

Example:

flaska.get('/path/to/url', async function(ctx) {
  // Perform action
})

In addition, each route can have none, one or many middlewares:

flaska.get('/handlequery', QueryHandler(), async function(ctx) {
  // Perform action
})

flaska.get('/query/and/json', [QueryHandler(), JsonHandler()], async function(ctx) {
  // Perform action
})

You can also run global middlewares at the start or end of every request:

import { Flaska, QueryHandler, JsonHandler } from '../flaska.mjs'
const flaska = new Flaska()

flaska.before(QueryHandler())
flaska.before(JsonHandler())
flaska.beforeAsync(MyLoadDatabase())

flaska.after(function(ctx) {
  ctx.log.info('Request finished.')
})

Context, Request and Response

Each handler receives a Flaska Context object that encapsulates an incoming http message and the corresponding response to that message. For those familiar with koa will be famililar with this concept. ctx is often used as the parameter name for the context object.

app.before(function(ctx) {
  ctx.log.info('Got request')
})
app.beforeAsync(async function(ctx) {
  // Do some database fetching maybe
})

The context ctx that gets generated includes the following properties for the incoming request:

  • log: Log handler.
  • req: The Request's IncomingMessage.
  • res: The Response's ServerResponse.
  • method: The HTTP method ('GET', 'POST', etc.).
  • url: The full URL path.
  • search: The URL search.
  • state: Anonymous object for user-defined data.
  • query: Map containing the key/value for the url search.

The following context specific variables can be specified by you the user to instruct Flaska on what to return in response:

  • status: The status code to return in response (default 200).
  • body: The body contents to return in response (default null).
  • type: The content-type for the header (default null).
  • length: The length of the body in bytes (default null).

More on this next.

ctx.body

At the end of each request, flaska will read ctx.body and determine the best course of action based on the type of content is being sent.

Javascript object

In cases where the response body is a normal object, Flaska will automatically JSON.stringify it, set the Content-Type to application/json and set the total length in Content-Length. This is provided for you at no expense on your behalf so you don't have to worry about it:

flaska.get('/api/test', function(ctx) {
  ctx.body = {
    message: 'Hello world',
  }
})

pipe

In cases where the response body is a pipe object (detected from the existance of .pipe property), flaska will automatically pipe it for you. In addition, if a file stream is used, it will read the extension of the file being streamed and automatically fill in the mime-type for you in the Content-Type header.

flaska.get('/test.png', function(ctx) {
  ctx.body = fs.createReadStream('./test/test.png')
})

Flaska will automatically close the file stream for you so you don't have to worry about that.

FileResponse

Alternatively, if you want proper file support, I recommend using FileResponse object:

import { FileResponse } from '../flaska.mjs'

flaska.get('/test.txt', function(ctx) {
  return fs.stat('./test/test.txt').then(function(stat) {
    ctx.body = new FileResponse('./test/test.txt', stat)
  })
})

This performs a real file stream support, uses pipes and supports all the HTTP shenanigans when it comes to dealing with files, including sending proper etag header, supporting partial response and lots of other things. This is one of the few libraries that actually implements full HTTP partial and etag support in a proper way, almost all other have one or two quirks that don't follow the spec properly.

String

In other instances, Flaska will .toString() the body and send it in response with the specified type or default to text/plain if unspecified.

flaska.get('/file.html', function(ctx) {
  ctx.body = `
<!doctype html>
<html lang="en">
<body>
  <h1>Hello world</h1>
</body>
</html>
`
  ctx.type = 'text/html; charset=utf-8'
})

The Context object also provides shortcuts for methods on its request and response. In the prior examples, ctx.type can be used instead of ctx.response.type and ctx.accepts can be used instead of ctx.request.accepts.

Built-in middlewares and handlers

Flaska comes with a few middlewares out of the box.

  • QueryHandler()

Parse the search query and create a map with key->value in ctx.query.

  • JsonHandler()

Parse incoming request body as json and store it in ctx.req.body.

  • CorsHandler()

A secure implementation for handling CORS requests.

  • FormidableHandler()

Provides a wrapper to handle an incoming file upload using Formidable@1.