Skip to content

docs: Add documentation page for experimental support #87

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/.config/docs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

name: srvx
shortDescription: Universal Server API
description: Based on web platform standards and works seamlessly with Deno, Bun and Node.js and more.
description: Built atop web platform standards to integrate seamlessly with Deno, Bun, Node.js, and more.
github: h3js/srvx
themeColor: red
socials:
Expand Down
2 changes: 2 additions & 0 deletions docs/1.guide/.navigation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
icon: i-ph:book-open-duotone
title: Guide
56 changes: 56 additions & 0 deletions docs/1.guide/0.index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---
icon: pixel:play
---

# Getting Started

> Get to know srvx and familiarize yourself with basic usage.

Srvx provides a unified API for creating HTTP servers based on web standard primitives such as [fetch][fetch], [Request][Request], and [Response][Response], working seamlessly with [Deno][Deno], [Bun][Bun], [Node.js][Node.js], and more.

:read-more{to="/guide/basics/why" title="Why srvx?"}

## Quick Start

First, create an HTTP server using the `serve` function from the `srvx` package.

```js [server.mjs]
import { serve } from "srvx";

const server = serve({
fetch(request) {
return new Response("👋 Hello there!");
},
});
```

Then, install `srvx` as a dependency:

:pm-install{name="srvx"}

Finally, run the server using your favorite runtime:

::code-group

```bash [node]
node server.mjs
```

```bash [deno]
deno run --allow-env --allow-net server.mjs
```

```bash [bun]
bun run server.mjs
```

::

[Deno]: https://deno.com/
[Bun]: https://bun.sh/
[Node.js]: https://nodejs.org/
[Fetch]: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
[Request]: https://developer.mozilla.org/en-US/docs/Web/API/Request
[Response]: https://developer.mozilla.org/en-US/docs/Web/API/Response
[IncomingMessage]: https://nodejs.org/api/http.html#http_class_http_incomingmessage
[ServerResponse]: https://nodejs.org/api/http.html#http_class_http_serverresponse
2 changes: 2 additions & 0 deletions docs/1.guide/1.basics/.navigation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
icon: ph:book-open-duotone
title: Guide
90 changes: 90 additions & 0 deletions docs/1.guide/1.basics/0.why.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
---
icon: clarity:rack-server-outline-alerted
---

# Why srvx?

> Why does srx exist and why would you want to use it?

Srvx provides a unified API for creating HTTP servers based on web standard primitives such as [fetch][fetch], [Request][Request], and [Response][Response], working seamlessly with [Deno][Deno], [Bun][Bun], [Node.js][Node.js], and more.

Usage is simple, low-level, and universal, and in most cases, introduces no or minimum overhead.

The main use-case of srvx is for tools and frameworks that wish to be runtime agnostic. Instead of depending on idiosyncratic runtime APIs, and introducing adapters, using srvx as unified building block.

**Example:** Same code working regardless of runtime.

```js
import { serve } from "srvx";

const server = serve({
port: 3000,
// tls: {}
fetch(request) {
return new Response(`👋 Your IP address is ${request.ip}`);
},
});
```

## Runtime APIs

### Deno and Bun

[Deno][Deno] and [Bun][Bun] use web standard APIs for HTTP servers, with slight differences and extensions on top of the standard.

**Example:** [Deno][Deno] server ([learn more](https://docs.deno.com/api/deno/~/Deno.serve)):

```js
Deno.serve(
{ port: 3000 },
(request, info) =>
new Response(`👋 Your IP address is ${info.remoteAddr.hostname}`),
);
```

**Example:** [Bun][Bun] server ([learn more](https://bun.sh/docs/api/http)):

```js
Bun.serve({
port: 3000,
fetch: (request, server) =>
new Response(`👋 Your IP address is ${server.requestIP(request).address}`),
});
```

> [!TIP]
> Srvx unifies usage by adding [extensions directly to request](/guide/basics/handler#extended-request-serverrequest) and unified [options](/guide/basics/options).

### Node.js

[Node.js][Node.js], provides [`node:http`](https://nodejs.org/api/http.html), [`node:https`](https://nodejs.org/api/https.html) and [`node:http2`](https://nodejs.org/api/http2.html) to create HTTP servers.

**Example:** Node.js HTTP server ([learn more](https://nodejs.org/en/learn/getting-started/introduction-to-nodejs)):

```js
import { createServer } from "node:http";

createServer((req, res) => {
res.end(`👋 Your IP address is ${req.socket.remoteAddress}`);
}).listen(3000);
```

Whenever a new request is received, the request event is called with two Node objects:

- Request (conventionally `req`), which is of the type [node:IncomingMessage][IncomingMessage], and passed in as the first argument of the event and enables access to the HTTP request details.
- Response (conventionally `res`), which is of the type [node:ServerResponse][ServerResponse], and passed in as the second argument of the event and allows preparing and sending of an HTTP response.

Srvx uses a lightweight proxy layer to emulate web standard APIs for Node.js.

:read-more{to="/guide/advanced/node" title="Node.js support"}

[Node.js]: https://nodejs.org/
[Deno]: https://deno.com/
[Bun]: https://bun.sh/
[Express]: https://expressjs.com/
[Fastify]: https://fastify.dev/
[Fetch]: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
[Request]: https://developer.mozilla.org/en-US/docs/Web/API/Request
[Response]: https://developer.mozilla.org/en-US/docs/Web/API/Response
[IncomingMessage]: https://nodejs.org/api/http.html#http_class_http_incomingmessage
[ServerResponse]: https://nodejs.org/api/http.html#http_class_http_serverresponse
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
102 changes: 0 additions & 102 deletions docs/1.guide/1.index.md

This file was deleted.

2 changes: 2 additions & 0 deletions docs/1.guide/2.advanced/.navigation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
icon: gis:cube-3d
title: Advanced
7 changes: 3 additions & 4 deletions docs/1.guide/7.node.md → docs/1.guide/2.advanced/0.node.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@ icon: akar-icons:node-fill

> Learn more about Node.js support with srvx.

> [!NOTE]
> This is an advanced section, explaining internal mechanism of srvx for Node.js support.
## View from Above

As explained in the [why srvx](/guide/why) section, [Node.js][Node.js] uses different API for handling incoming http requests and sending responses.
As explained in the [Why srvx?](/guide/basics/why) page, [Node.js][Node.js] uses different APIs for handling incoming http requests and sending responses.

srvx internally uses a lightweight proxy system that wraps [node:IncomingMessage][IncomingMessage] as [Request][Request] and converts the final state of [node:ServerResponse][ServerResponse] to a [Response][Response] object.
The internal mechanisms of **srvx** use a lightweight proxy system that wraps the [node:IncomingMessage][IncomingMessage] in a [Request][Request] and converts its final state of [node:ServerResponse][ServerResponse] to a [Response][Response] object.

## How Node.js Compatibility Works

Expand Down
74 changes: 74 additions & 0 deletions docs/1.guide/2.advanced/1.experimental.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
---
icon: game-icons:soap-experiment
---

# Experimental Support

> See what the team is working on to improve srvx's core offering.

## Caution! Scientists at work!

Currently, **srvx** provides support for two experimental adapters: [Cloudflare][Cloudflare] and the web [Service Worker API][Service Worker].
The aim is to enable engineers to leverage **srvx** in any conceivable server environment,
even those that impose specific handling of requests/responses, such as Cloudflare's Edge Network or browser-based Service Workers.
**srvx**'s lean ergonomics and middleware are maintained to ensure the same experience across adapters.

## Cloudflare

The Cloudflare brand has rapidly established a name that developers trust,
so it only serves to reason that their Worker runtime environment would be a desirable target for **srvx** users.
The framework provides its universal compat layer for any requests in the Worker Environment by utilizing Cloudflare's Fetch Handler API,
ensuring that Cloudflare-specific properties, environment variables, and execution context are all accommodated.
Care is taken to preserve access to critical capabilities, like `waitUntil()` for background tasks, and
runtime metadata is attached to identify the execution context. This enables any application making use of **srvx**
to be deployed as a Cloudflare Worker while maintaining the niceties of the web standard API.

Upcoming: Handling IP addresses

**Ex.** - Cloudflare Workers ([learn more](https://www.cloudflare.com/developer-platform/products/workers/)):

```js
import { serve } from "srvx/adapters/cloudflare";

export default serve({
fetch(request) {
return new Response(`<h1>Hello from Cloudflare!</h1>`, {
headers: { "Content-Type": "text/html; charset=UTF-8" },
});
},
});
```

## Service Workers

Anytime a Browser application has need for a proxy server to act in the absence of network availability, Service Workers are turned to. Whether completing computationally intensive tasks,
intercepting network requests, creating offline experiences, sending push notifications, or running background sync APIs, these are the purview of the
Service Worker. Retaining this core functionality is of crucial importance as any dev reaching for a Service Worker solution will expect consistency.
To this end, **srvx** smartly detects if it's running in a Browser or Service Worker context and delivers the commensurate behavior for each environment.
The entire Service Worker lifecycle is supported and managed as **srvx** self-registers, activates, and unregisters automatically. Critical features,
such as `waitUntil` capability for background operations, "claim immediately" behavior, and per-update page reloads so that new clients can be claimed.
During self-registration scenarios, any heavier application logic should be lazy loaded when performance implications are a concern (but when aren't they...? :smirk:).

> [!NOTE]
> As a safety measure, 404 responses and requests for static assets (i.e. URLs with file extensions) are skipped to avoid breaking normal browser behaviors.

Upcoming: An option for 404 handling will be explored

**Ex.** - Service Workers ([learn more](https://stackblitz.com/github/h3js/srvx/tree/main/playground?file=app.mjs)):

```js
import { serve } from "../node_modules/srvx/dist/adapters/service-worker.mjs";

// Internally the service worker is implemented by passing it as an option to the `serve()` function alongside `fetch()`
serve({
serviceWorker: { url: import.meta.url },
fetch(_request) {
return new Response(`<h1>👋 Hello there!</h1>`, {
headers: { "Content-Type": "text/html; charset=UTF-8" },
});
},
});
```

[Cloudflare]: https://www.cloudflare.com/
[Service Worker]: https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API
10 changes: 10 additions & 0 deletions docs/1.guide/2.advanced/2.plugins.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
icon: bi:plugin
---

# Plugins

> Learn more about how we leverage plugins to extend the srvx foundation with new functionalities.

> [!NOTE]
> More to come!! Keep watching this space...
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "srvx",
"version": "0.8.0",
"description": "Universal Server API based on web platform standards. Works seamlessly with Deno, Bun and Node.js.",
"description": "Universal Server API built atop web platform standards to integrate seamlessly with Deno, Bun, Node.js, and more.",
"homepage": "https://srvx.h3.dev",
"repository": "h3js/srvx",
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion test/bench-node/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Node.js Cmpatibility Benchmarks
# Node.js Compatibility Benchmarks

Simple benchmarks primarily focus on how closely we can approach native `node:http` performance while using a web standards compatibility layer.

Expand Down