phaethon

Fast, promise-based, non-magical server package for node.js.

Usage no npm install needed!

<script type="module">
  import phaethon from 'https://cdn.skypack.dev/phaethon';
</script>

README

phaethon

Fast, promise-based, non-magical server package for node.js.

Use it with TypeScript:

import * as phaethon from 'phaethon';

var server = new phaethon.Server();

server.listener = request => {
    var path = request.path.toLowerCase();

    if (path === '/') return new phaethon.ServerResponse('Hello World!');
    if (path === '/hello') return new phaethon.ServerResponse('Hello, ' + request.query.name + '!');
    
    throw new phaethon.ServerError(phaethon.http.Status.ClientErrorNotFound);
};

server.listenHttp(8800);

Or plain JavaScript:

var phaethon = require('phaethon');

var server = new phaethon.Server();

server.listener = function(request) {
    var path = request.path.toLowerCase();

    if (path === '/') return new phaethon.ServerResponse('Hello World!');
    if (path === '/hello') return new phaethon.ServerResponse('Hello, ' + request.query.name + '!');
    
    throw new phaethon.ServerError(404);
};

server.listenHttp(8800);

Installation

npm install phaethon

The package includes TypeScript declarations. It's not necessary to reference some declaration file, TypeScript will automatically find it.

Features

  • ES6 Promise based
  • Focus on performance
  • No callback hell

Routing

A router is just a function in phaethon, so you can write your router like this:

server.listener = (request: phaethon.ServerRequest) => {
    var path = request.path.toLowerCase();

    if (path === '/') return home(request);
    if (path === '/account') return account(request);
    
    throw new phaethon.ServerError(404);
};
function home(request: phaethon.ServerRequest) {
    return new phaethon.ServerResponse('Hello World!');
}
function account(request: phaethon.ServerRequest) {
    return new phaethon.ServerResponse('Your account');
}

Promises

The listener callback may return a promise, actually in most cases it will return one. Example:

declare function somePromiseTask(input: string): Promise<string>;

server.listener = (request: phaethon.ServerRequest) => {
    var values: string[] = [];
    somePromiseTask('').then(valueA => {
        values.push(valueA);
        console.log(valueA);
        return somePromiseTask(valueA);
    }).then(valueB => {
        values.push(valueB);
        return somePromiseTask(valueB);
    }).then(valueC => {
        return new phaethon.ServerResponse(values.join(',') + '; ' + valueC);
    }).catch((e) => {
        throw new phaethon.ServerError(404);
    });
}

Errors will be catched by phaethon. If a ServerError is caught, it will be shown to the user. ServerError is a class that just has the status code of the error and optionally a text and headers. Otherwise the user will see 500 Internal server error.

Async functions

You can also use phaethon with async functions, since async functions use promises. You can use Babel or TypeScript to transpile async functions. For TypeScript, set target to es6. Same example as above:

declare function somePromiseTask(input: string): Promise<string>;

server.listener = async (request: phaethon.ServerRequest) => {
    try {
        var values: string[] = [];
        var valueA = await somePromiseTask('');
        values.push(valueA);
        console.log(valueA);
        var valueB = await somePromiseTask(valueA);
        values.push(valueB);
        var valueC = await somePromiseTask(valueB);
        return new phaethon.ServerResponse(values.join(',') + '; ' + valueC);
    } catch (e) {
        throw new phaethon.ServerError(404);
    };
}

Sessions

Sessions can easily be implemented using the SessionStore:

import { Server, SessionStore } from 'phaethon';
interface SessionData {
    foo: string;
}
const sessionStore = new SessionStore<SessionData>(
    'session-cookie',    // Cookie name
    () => ({ foo: '' }), // Session data of new session
    60 * 60 * 1000,      // Lifetime
    100000               // Max number of sessions
);
const server =  new Server();
server.listener = async (request) => {
    const session = await sessionStore.findOrCreate(request);
    
    const response = ...
    sessionStore.addCookie(response, session);
    return response;
};

Or simplified:

server.listener = sessionStore.wrapListener(async (request, session) => {
    return ...;
});