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 🙏

© 2026 – Pkg Stats / Ryan Hefner

edge-workers-sdk

v0.2.0

Published

AssemblyScript SDK for edge-workers

Readme

edge-workers-sdk

AssemblyScript SDK for writing Edge Workers. Provides typed HttpRequest / HttpResponse objects, a handler-registration API, and an outbound fetch() for calling external services. WASM ABI and JSON wire format are handled internally.

Install

npm install edge-workers-sdk

Configure

This SDK depends on json-as, which uses an AssemblyScript compile-time transformer. You must enable it in your project's asconfig.json:

{
  "options": {
    "transform": ["json-as"]
  }
}

Without this, the SDK will not compile.

A working example lives at examples/ifconfig/. Run make example to build it.

Quick start

import { onClientRequest, onClientResponse } from "edge-workers-sdk";

// Re-export the WASM ABI exports the host calls into.
// Only re-export the phases you actually handle.
export {
  alloc,
  on_client_request,
  on_client_response,
} from "edge-workers-sdk/assembly/index";

onClientRequest((req) => {
  if (req.uri == "/healthz") {
    req.respondText(200, "ok");
    return;
  }
  req.setHeader("x-edge-worker", "hello");
});

onClientResponse((resp) => {
  resp.setHeader("x-served-by", "edge-worker");
});

Compile with asc as usual. You must re-export alloc and the phase-specific ABI exports (on_client_request, on_origin_request, on_client_response, on_origin_response) for the host to find them.

Phases

The host invokes the worker at up to four points per request. Each maps to one registration function and one ABI export:

| Phase | Register with | ABI export | When it runs | | --- | --- | --- | --- | | Client request | onClientRequest | on_client_request | Before cache lookup. Only phase that can call fetch(). | | Origin request | onOriginRequest | on_origin_request | On cache miss, before going to origin. | | Client response | onClientResponse | on_client_response | After cache lookup, before sending to client. | | Origin response | onOriginResponse | on_origin_response | On cache miss, after origin responds. |

Only re-export the ABI symbols for phases your worker actually handles.

API

Registration

  • onClientRequest((req: HttpRequest) => void): void
  • onOriginRequest((req: HttpRequest) => void): void
  • onClientResponse((resp: HttpResponse) => void): void
  • onOriginResponse((resp: HttpResponse) => void): void

Each registers a handler for the corresponding phase. Mutate req / resp in place. In the request phases, req.respond(...) / req.respondText(...) short-circuits the chain and returns the given response.

HttpRequest

| Field | Type | Notes | | --- | --- | --- | | method | string | HTTP method (e.g. "GET") | | uri | string | Request URI | | headers | string[][] | Array of [name, value] pairs | | body | Uint8Array \| null | Raw request body bytes | | earlyResponse | HttpResponse \| null | Set via respond() to short-circuit upstream |

Methods:

  • getHeader(name) — case-insensitive lookup, returns string \| null
  • setHeader(name, value) — replaces if present, appends otherwise
  • removeHeader(name) — removes all matching headers
  • text() — UTF-8 decode of body; throws on invalid UTF-8
  • bytes() — alias for body (mirrors WHATWG Response.bytes())
  • json<T>() — parse body as JSON into T (json-as @json class); throws on invalid JSON or null body
  • setBodyText(text) — UTF-8 encode text into body
  • respond(status, body?, headers?) — short-circuit with a binary body; bypass upstream and return this response
  • respondText(status, body?, headers?) — same as respond but takes a string body (UTF-8 encoded)
  • bypassChallenge() — sets x-bypass-challenge: 1 to skip the bot/security challenge

HttpResponse

| Field / getter | Type | Notes | | --- | --- | --- | | status | u16 | HTTP status code (0 on transport error from fetch) | | ok | bool | true iff status is in 200..299 | | headers | string[][] | Array of [name, value] pairs | | body | Uint8Array \| null | Raw response body bytes | | errorKind | string \| null | Set by fetch() on transport-level failure. Always null for proxy responses. | | errorMessage | string \| null | Human-readable detail when errorKind != null |

Methods:

  • getHeader / setHeader / removeHeader — same as on HttpRequest
  • text() / bytes() / json<T>() — same body accessors as on HttpRequest
  • setBodyText(text) — UTF-8 encode text into body
  • isError()true iff errorKind != null
  • forceCache() — sets x-cache-force: 1 to force this response to be cached
  • bypassCache() — sets x-cache-bypass: 1 to prevent this response from being cached

fetch(url, method?, headers?, body?) → HttpResponse

Make an outbound HTTP request from the guest. Returns an HttpResponse (the same type used by the proxy callbacks). Synchronous from the guest's perspective — wasmtime suspends execution while the host's async fetch runs.

Available only in the client-request phase (before cache lookup). Calling it from any other phase returns an HttpResponse with errorKind set.

The returned response covers both success and failure:

  • Transport-level failures (timeout, connection refused, body too large, etc.) come back with errorKind / errorMessage populated and status === 0. Use resp.isError() to check.
  • HTTP-level failures (4xx, 5xx) come back as normal responses with errorKind === null and ok === false.

AssemblyScript does not support exceptions, so errors are surfaced via fields rather than thrown — unlike WHATWG / Node fetch.

| Param | Type | Default | | --- | --- | --- | | url | string | required | | method | string | "GET" | | headers | string[][] | [] | | body | Uint8Array \| null | null |

import { fetch, onClientRequest } from "edge-workers-sdk";

onClientRequest((req) => {
  const bodyBytes = Uint8Array.wrap(String.UTF8.encode('{"foo":"bar"}'));
  const resp = fetch(
    "https://api.example.com/v1/x",
    "POST",
    [["authorization", "Bearer ..."]],
    bodyBytes,
  );

  if (resp.isError()) {
    req.respondText(502, "fetch failed: " + resp.errorKind!);
    return;
  }

  if (!resp.ok) {
    req.respondText(resp.status, "upstream error");
    return;
  }

  const json = resp.text();
  // ...
});

errorKind values: timeout, too_many_inflight, request_too_large, response_too_large, body_read, transport, plus a host-defined value (e.g. phase_not_allowed) when called outside the client-request phase.

Host-enforced limits (do not need to be re-checked in the guest):

  • 2 s end-to-end timeout
  • 10 MiB request body cap
  • 10 MiB response body cap
  • Per-worker concurrency limit (FIFO queue)

getenv(name) → string | null

Look up an environment variable provided by the host. Returns null if the variable is not set.

import { getenv, onClientRequest } from "edge-workers-sdk";

onClientRequest((req) => {
  const apiKey = getenv("API_KEY");
  if (apiKey !== null) {
    req.setHeader("authorization", "Bearer " + apiKey);
  }
});

Notes

  • Bodies are raw bytes (Uint8Array). Use text() / setBodyText() for UTF-8; json<T>() for typed JSON; everything else (binary content, gzip, etc.) is just bytes.
  • Headers are preserved in the order they arrive and are compared case-insensitively.