Utilities

Low-level helpers from sevo for custom integration, advanced middleware composition, and framework authoring.

Before You Reach For These

Most applications only need:

  • Server
  • route tables
  • middleware
  • createContextKey()

The helpers on this page are mainly useful if you are:

  • composing handlers programmatically
  • integrating sevo into another host runtime
  • building higher-level abstractions on top of sevo
  • coordinating request-scoped async work manually

Import

import {
  createContextKey,
  createWaitUntil,
  InvocationContext,
  raceRequestAbort,
  runMiddleware,
  toServerHandlerObject,
  wrapFetch,
  type HTTPMethod,
  type MaybePromise,
} from "sevo";

InvocationContext

InvocationContext is the core object passed to handlers and middleware. It contains the request, runtime capabilities, route parameters, and a context map for sharing state.

Creating a context

Normally you don't create contexts manually - they are created by Server:

const ctx = server.createContext(request);

Deriving a context

Use with() to create a derived context with modifications:

const newCtx = ctx.with({
  params: { id: "123" },
  request: new Request(ctx.request, { headers: newHeaders }),
});

The new context inherits all values from the parent context's internal map. Override request, params, capabilities, or waitUntil only when you need a modified view for downstream code.

raceRequestAbort()

Tie async work to a request's abort signal.

If the request aborts before the promise settles, the returned promise rejects with the abort reason.

import { raceRequestAbort } from "sevo";

async function readUser(request: Request) {
  return raceRequestAbort(fetch("https://example.com/api/user"), request);
}

This is useful when you are writing helpers that should stop surfacing results for requests the client has already abandoned.

createWaitUntil()

Create a small registry for background tasks.

This mirrors service-worker-style waitUntil() behavior: register promises as work that should still be awaited later.

import { createWaitUntil } from "sevo";

const waiter = createWaitUntil();

waiter.waitUntil(sendAnalytics());
waiter.waitUntil(writeAuditLog());

await waiter.wait();

Rejected promises are logged and removed so a later wait() call can still finish cleanly.

Handler Composition

toServerHandlerObject()

Normalize a bare handler or handler object into the object form used by sevo.

const ctx = new InvocationContext({
  request: new Request("http://localhost/hello"),
  capabilities: {} as any,
  params: {},
});

const handlerObject = toServerHandlerObject((ctx) => {
  return new Response(`Hello ${new URL(ctx.request.url).pathname}`);
});

await handlerObject.handleRequest(ctx);

This is useful when your own abstraction wants to accept either:

  • a bare ServerHandler
  • or a { handleRequest, middleware } object

runMiddleware()

Execute a middleware chain against a terminal handler.

const ctx = new InvocationContext({
  request: new Request("http://localhost/hello"),
  capabilities: {} as any,
  params: {},
});

const response = await runMiddleware(
  middleware,
  ctx,
  async (ctx) => new Response(new URL(ctx.request.url).pathname),
);

runMiddleware() is a low-level primitive. Callers are expected to pass a valid InvocationContext, not a raw Request.

If the terminal handler is a handler object with its own middleware, that inner middleware runs after the outer middleware array completes.

wrapFetch()

Compose a Server instance into the final request handler.

Server uses this internally after plugins and runtime adapter setup. You usually do not need it unless you are testing or building a custom abstraction around Server.

const kernel = wrapFetch(server);
const response = await kernel(server.createContext(new Request("http://localhost/")));

Type Helpers

MaybePromise<T>

Use MaybePromise<T> for APIs that may return either a sync value or a promise.

type Loader<T> = () => MaybePromise<T>;

HTTPMethod

HTTPMethod is the string union used by route-table method maps:

  • GET
  • POST
  • PUT
  • DELETE
  • PATCH
  • HEAD
  • OPTIONS
Read more in Invocation Context.
Read more in Middleware.