Texa (deno web framework)

Texa

https://deno.land/x/texa - https://github.com/ihack2712/texa

A Deno web-framework inspired by Oak and Express, with built-in support for WebSockets, middleware and routing.

Features

  • TLS
  • Middlewares
  • Router
  • WebSockets
  • Sleek request & response objects.

Todos

  • Cookies.

Importing

import { Application, Router } from "https://deno.land/x/texa/mod.ts";

Creating an app

const app = new Application("127.0.0.1:3000");

Disabling WebSockets

const app = new Application("127.0.0.1:3000", {
	allowWebSocket: false
});

WebSockets

app.on("connection", async socket => {
	socket.on("message", async message => {
		// text message
	});
	socket.on("binary", async data => {
		// binary message
	});
	socket.on("ping", async data => {
		// ping event
	});
	socket.on("pong", async data => {
		// pong event
	});
	socket.on("close", async (closer, code, reason) => {
		// Close event
	});
});

Adding middleware

app.use(
	async (req, res, next) => {
		let err: Error | null = null;
		try
		{
			await next();
		} catch (error)
		{
			err = error;
			await res.status(500).end("Internal server error, if you're a developer you can check the server logs.");
		}
		console.log(
			"%s %dms %s%s",                       // The log template.
			req.method,                           // The request method.
			Date.now() - req.at,                  // The amount of ms it took from start to finish.
			res.statusCode,                       // The status code that was sent back.
			req,url.pathname,                     // The requested resource.
			err !== null ? ` - ${err.stack}` : "" // Include an error if an error occured.
		);
	}
);

Creating a router.

const router = new Router();
app.use(router);

Adding routes

router.get("/hello", async (req, res) => {
	await res.end("World");
});

Adding middleware to routers.

router.use(
	async (req, res, next) => {
		// Do something.
		await next();
	}
);

Or only run on a specific path.

router.use(
	"/path",
	async (req, res, next) => {
		res.end(req.url.pathname);
	}
);

Router params

All request methods on the router, or the use method, accepts a path, which can contain a parameter.

router.get("/user/:param", async (req, res) => {
	console.log(req.params);
	// { param: ... }
});

Here are the possible param options.

"/:requiredParam"
"/:requiredParam(withRegex)"
"/:optionalParam?"
"/:optionalParam(withRegex)?"
"/:zeroOrMoreOccurances*"
"/:zeroOrMoreOccurances(withRegex)*"
"/:oneOrMoreOccurances+"
"/:oneOrMoreOccurances(withRegex)+"

Middleware on object.

import { Middleware } from "https://deno.land/x/texa/mod.ts";

class MyMiddleware extends Middleware
{
	public value: string = "World";
	
	public run: Middleware["run"] = async (req, res, next) => {
		res.headers.set("X-Hello", this.value);
		await next();
	};
}

const middleware = new MyMiddleware();
app.use(middleware);

middleware.value = "Something else now";

HTTP and HTTPS

// Imports
import { Application, Router } from "https://deno.land/x/texa/mod.ts";

// Create application.
const app = new Router();

app.get("/", async (req, res) => {
	await res.end("Welcome home!");
});

// Create http app.
const httpApp = new Application("0.0.0.0:80")
	.use(app);

// Create https app.
const httpsApp = new Application("0.0.0.0:443", {
	certFile: "/path/to/cert.pem",
	keyFile: "/path/to/key.pem"
}).use(app);

// Start listening for requests on both servers.
httpApp.start();
httpsApp.start();
7 Likes

I like this, I like this. :smiley:

I am going to use this

2 Likes

Eyy! I’m glad someone likes :smiley:

I will make a detailed guide on how to use the framework later, as well as a youtube video I think :slight_smile:

5 Likes

0.2.0

Sending files:

router.get("/home", async (req, res) => {
  await res.file("./index.html").end();
});
3 Likes

It would be cool if you could make a template glitch project to remix, I can possibly make an userscript to extend the New Project menu and include templates using frameworks like this

2 Likes

Here’s a ws echo server made on texa: https://texa-starter.glitch.me/
Edit link: https://glitch.com/edit/#!/texa-starter

3 Likes

This is very neat! Thanks for sharing!

4 Likes

Update 0.7.0

This is a rather cool update! Texa now has a built-in static files middleware to better serve your files! Not only does it serve static files, but it can serve ANY file type if you decide to add support for it. It also allows you to create vanity URLs by trying different extensions.

Static files.

// Imports
import { Static } from "https://deno.land/x/texa/mod.ts";

// Use the static middleware.
app.use(
	// The directory to serve from, relative from <CWD>.
	new Static("www")
);

Custom extension handlers.

app.use(
	new Static("www", {
		handlers: {
			ejs: async (pathname, req, res) => {
				// Compute compiledEJS somehow..
				return [ compiledEJS, "text/html" ];
			}
		}
	})
);

Index files.

app.use(
	new Static("www", {
		indexes: [ "index.html" ]
	})
);

Vanity URLs

You can add extensions to look for just like adding index files.

app.use(
	new Static("www", {
		vanityExtensions: [ "html" ]
	})
);

Other minor improvements

Here’s a list of other minor improvements:

  • Added response header method aliases in the response object.

    • <Response>.set(headerName, headerValue): Response

    • <Response>.get(headerName): Response

    • <Response>.has(headerName boolean

    • <Response>.delete(headerName Response

  • Added methods to quickly do things on the response object.

    • <Response>.type(mimeType): Response

    • <Response>.json(data: any): Promise<Response>

  • Made a new middleware object (SubMiddleware) that allows running more middleware. See (https://i.loli.net/2020/10/15/XmdlE3PnZ1rY5y4.png)

  • Router middleware now extends the SubMiddleware object.

3 Likes

Still waiting for Runkit to support import.

3 Likes

Seems like repl.it is working :stuck_out_tongue_winking_eye:

However, Texa isn’t going to work with node, due to Texa using the Deno runtime API.

2 Likes

This post was flagged by the community and is temporarily hidden.

2 Likes

Update 0.7.9!

This update contains code to automatically parse JSON contents in the request body if there are any. It also added support for request bodies in general.

The request body will automatically be applied as long as the request content-type header is set to application/json.

app.post("/json", async (req, res) => {
  console.log(req.body);
  await res.json(req.body);
});

There are currently no built-in support for any other media types (i.e. multipart/form-data). There will come more media-types later but for now JSON is the only one supported.

3 Likes

Simple Web Chat!

I’ve made a simple web chat using the Texa framework, the source code of this is available in the official repository of Texa at examples/texa-chat.

There’s a glitch app running this source code right now!

https://texa-chat.glitch.me

You can also add a /:pathname* to create your own unique rooms!

Emojies are also supported!

1 Like

oh…

in chromeos, mac, and windows for chrome all I have to do is drag the window. Is this the same for Firefox?

also I am proud of having duckduckgo

Express 2.0 is cool :smiley:

1 Like

Isn’t express at like version 4.17 something?

Also to answer your question: I rarely use my pointer, only when I have to and when I feel like it. I usually just use the keyboard. For instance in firefox when I want to focus the search bar I just press CMD + L.

1 Like

No I mean Texa

Ah, thank you! :joy:

1 Like

That 53 major release version doesn’t appear to exist on npm :thinking:

1 Like

Where are you seeing this? :joy:

Their git repo doesn’t even have any tags starting with 53.

This is their last created tags:

Also, what’s the deal here in your pic? :joy:

I’m pretty much aware :joy:

1 Like