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

@open-ve/headers

v1.7.1

Published

Virtual-environment mechanism for Chrome MV3 extensions: per-tab request-header injection, DNR redirect/base-dir loading, build probes, a status banner, and request call-tree traces — embeddable via initVeHeaders().

Downloads

1,663

Readme

@open-ve/headers

An embeddable virtual-environment mechanism for Chrome MV3 extensions.

Preview a browser tab into a "virtual environment": inject a per-tab request header (default x-virtual-env) on your API hosts, transparently load a branch/preview build of a web app (document swap, SPA prefix, or entry-script swap), and show a status banner with a request call-tree. It's a small, dependency-free engine you wire into your own extension's service worker and drive from your own UI.

Install

npm i @open-ve/headers

Wire it into your extension

1. Service worker — call initVeHeaders() at the top level (MV3 requires listeners to register in the first event-loop turn):

import { initVeHeaders } from "@open-ve/headers/background";

initVeHeaders({
  contentScript: "ve-content.js", // where the banner script lands in your build
  defaultConfig: {                // seeded on install; omit to start config-less
    apiScope: ["*.example.com"],  // hosts that receive the header
    apps: [
      { name: "web", hosts: ["app.example.com"], docSwap: true },
    ],
  },
});

2. Manifest permissions

"permissions": ["declarativeNetRequest", "webRequest", "scripting", "storage"],
"host_permissions": ["<all_urls>"]

Do not declare the banner in content_scripts — the engine registers it dynamically from your config.

3. Banner content script — @open-ve/headers/content is a self-contained script. Copy it into your build output at the path you passed as contentScript (e.g. a public/ copy step: cp node_modules/@open-ve/headers/content.js public/ve-content.js).

4. UI — drive it from the typed client:

import * as ve from "@open-ve/headers/client";

const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
await ve.preview(tab.id, "feature/PAY-456");
await ve.getPreview(tab.id);
await ve.exitPreview(tab.id);
await ve.setEnabled(false); // master off — exits preview every tab

Config (VEConfig)

{
  headerName?: string;   // default "x-virtual-env"
  apiScope: string[];    // required, non-empty — host patterns that get the header
  apps: Array<{
    name: string;
    hosts: string[];
    assetsBase?: string;          // default https://<first host>
    docSwap?: boolean;            // serve the branch document at the apex URL
    kind?: "spa";                 // prefix-navigate to /<identity>/…
    entrySwap?: { entryFiles: string[] }; // relocate entry scripts to /<identity>/…
    importMap?: string;           // relocate MFE modules that have a branch build
    subdomainEntry?: boolean;     // <slug>.<host> → <host>?ve=<slug> (pre-DNS)
  }>;
}

The package is org-agnostic and ships no default config — you provide one.

Entry paths

Once configured, a tab enters a virtual environment via:

  1. Programmatically — ve.preview(tabId, slug) from your UI.
  2. ?ve=<slug> on any configured host — a shareable link (non-extension viewers just get origin).
  3. /<identity>/… on a configured host that carries its own build (kind: "spa" or docSwap) — auto-previews when a build exists at that prefix, recovering the git ref from the build's manifest (below).
  4. https://<slug>.<host>/… on hosts flagged "subdomainEntry": true — the extension rewrites the URL onto the real host before DNS, so the subdomain needs no DNS record. These URLs work only for extension users.

Build detection (ve-manifest.json)

Before it swaps anything, the engine asks: is there actually a build published for this identity? The primary signal is a manifest at the identity root — ve-manifest.json, written by the publisher after every asset upload, so its presence means the build is published and complete:

{
  "branch":      "feature/ABC-1",  // required: the git ref (the only thing an asset dir cannot yield)
  "flavor":      "",               // "" for the bare identity, e.g. "-ci" for an ephemeral publish
  "headerValue": "abc-1-1a2b",     // the routing header value for this build
  "identity":    "feature-abc-1",  // the directory this file sits in
  "app":         "web",
  "commit":      "…40-hex…",
  "builtAt":     "2026-09-04T12:00:00Z",
  "entry":       "index.html",     // entry file, relative to the identity root
  "publisher":   "ci"
}

Where it is looked for:

| App's own build (docSwap, kind:"spa") | <assetsBase>/<identity>/ve-manifest.json | |---|---| | an importMap module | the module's candidate URL cut right after its /<identity>/ segment (manifestUrlFor) — an MFE's identity root sits above the module file |

Only branch is required; everything else is informational. A non-JSON content-type (an SPA host soft-404ing its own document) counts as absent.

Fallback. With no manifest, the engine falls back to the legacy probes: a 200 compared against a known-missing control path (identical length ⇒ we were served the origin's soft-404 fallback ⇒ no build) plus, for modules, a content-type check. These are guesses — a real build whose HTML happens to match the fallback byte-for-byte reads as no build — so publishing a manifest is what makes detection exact.

Which signal won is recorded per app/module in the preview record:

const { preview } = await ve.getPreview(tab.id);
preview.builds["web"];
// { source: "manifest" | "probe", url, branch, flavor, commit, builtAt,
//   publisher, app, identity, entry, headerValue }

source: "probe" rows carry only url (nothing else is knowable). Every probe and manifest fetch is time-boxed at PROBE_TIMEOUT_MS = 8000 ms; a timeout is treated exactly like a network error (not a build), so an unresponsive CDN can never wedge a preview.

Exports

| Import | What | |---|---| | @open-ve/headers/background | initVeHeaders(options) — the service-worker engine | | @open-ve/headers/content | the banner/URL-trigger content script (side-effect import / copy) | | @open-ve/headers/client | typed wrappers over the message API, isInstalled(), and the pure helpers (fuzzyMatch/fuzzyFilter, manifestUrlFor/parseBuildManifest/summarizeBuild) | | @open-ve/headers/lib/build-state.js | the build-state helpers on their own, for a consumer that wants them without the client |

License

MIT