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

@archal/vitest

v0.1.2

Published

Hosted Archal route-mode support for Vitest

Downloads

431

Readme

@archal/vitest

Hosted route-mode bootstrap for Vitest.

This package is hosted-only. It does not boot local twins. It configures Vitest to start an Archal hosted session, install route-mode request rewriting, and expose the resolved hosted runtime state to tests.

Two Usage Patterns

Pick whichever matches your existing Vitest setup.

1. Single vitest.config.ts (recommended for most projects)

import { defineConfig } from 'vitest/config';
import { archalVitestConfig } from '@archal/vitest';

export default defineConfig({
  test: archalVitestConfig({
    services: {
      stripe: { mode: 'route', seed: 'small-business' },
      github: { mode: 'route', seed: 'small-project' },
    },
  }),
});

archalVitestConfig() returns a complete Vitest test config — wire it into defineConfig({ test: ... }) directly.

2. vitest.workspace.ts (for multi-project monorepos)

import { archalVitestProject } from '@archal/vitest';

export default [
  archalVitestProject(
    {
      name: 'github-hosted-live',
      services: {
        github: { mode: 'route', seed: 'small-project' },
        stripe: { mode: 'route' },
      },
    },
    {
      include: ['__tests__/hosted-live.test.ts'],
    },
  ),
];

archalVitestProject() returns a workspace project definition — use it inside the array exported from vitest.workspace.ts. Do not wrap it in defineConfig({ test: archalVitestProject(...) }) — that pattern silently drops the setup files and lets requests hit real SaaS APIs. Use archalVitestConfig() instead for the single-config pattern.

Defaults Applied Automatically

Both helpers apply the same defaults so a developer's first run works without extra tuning:

  • hookTimeout: 120_000 and testTimeout: 120_000 — ECS Fargate cold-start for twins can take 30s+, which exceeds Vitest's 10s/5s defaults.
  • exclude: ['**/node_modules/**', ...] — prevents Vitest from walking into bundled Archal tests when installed as an npm dependency.
  • setupFiles: [<route-mode bootstrap>] — wires the hosted session provisioning and request interception.

Pass your own hookTimeout/testTimeout/exclude/include in the second argument to override these.

Reset Twin State Between Tests

By default, twin state accumulates across tests in a run. Use resetArchalTwins() in beforeEach to get a fresh world:

import { beforeEach } from 'vitest';
import { resetArchalTwins } from '@archal/vitest';

beforeEach(async () => {
  await resetArchalTwins();
});

This restores each twin to the post-seed state that was captured during session bootstrap — no re-provisioning, no cold start, just a clean state snapshot pushed back to each twin in parallel. Typical cost is a few hundred milliseconds.

resetArchalTwins() also drains the twins' pending webhook queues so each test starts with no leftover deliveries from the previous one.

Webhook Testing

Test your webhook handlers without needing a tunnel, public URL, or mock server. The hosted twin runs in AWS ECS and can't reach your localhost, so instead of the twin POSTing to you, your test pulls queued deliveries over the same session and invokes your handler directly.

import { waitForArchalWebhook, listArchalWebhooks, clearArchalWebhooks } from '@archal/vitest';

it('records subscription via webhook handler', async () => {
  // 1. Register an endpoint so the twin knows to queue events
  await stripe.webhookEndpoints.create({
    url: 'http://test.local/wh',
    enabled_events: ['customer.subscription.created'],
  });

  // 2. Fire the event via normal SDK calls
  const customer = await stripe.customers.create({ email: '[email protected]' });
  const sub = await stripe.subscriptions.create({ customer: customer.id, items: [...] });

  // 3. Pull the queued delivery; default timeout 2000ms, default consume:true
  const event = await waitForArchalWebhook('stripe', 'customer.subscription.created');

  // 4. Invoke your handler with the exact payload the twin queued
  await handleStripeWebhook(event.body, event.headers['Stripe-Signature'], secret);
});

API:

  • waitForArchalWebhook(service, eventTypeOrMatcher, options?) — polls the twin, returns first match within timeout (default 2000ms). With consume: true (default), drops the service's queue after matching so it can't be re-returned. Pass consume: false for sequence assertions.
  • waitForArchalWebhook(service, { eventType, where, timeout, consume }) — the full options form. where is a predicate (delivery) => boolean applied after eventType.
  • listArchalWebhooks(service) — one-shot snapshot of currently queued deliveries. Does not consume.
  • clearArchalWebhooks(service) — manually drop the service's queue.

Supported services:

| Service | Webhook helper support | |---|---| | Stripe, GitHub, Slack | ✅ Full — signatures computed at queue time | | Jira, Linear | ✅ Via history buffer — survives their inline flush() | | Supabase | ❌ Database-triggered webhooks; test against real Postgres | | Google Workspace | ❌ Uses GCP Pub/Sub, not webhooks |

Signature verification: delivery.body is the exact JSON string the twin would have POSTed; use it with delivery.headers[SIGNATURE_HEADER] and the endpoint's secret. Do NOT re-serialize delivery.payload — key order/spacing changes will break HMAC verification.

Parallel worker safety: per-worker twin state isolation (shipped alongside this helper) gives each vitest worker its own webhook queue automatically. Worker A cannot consume worker B's deliveries when both workers use isolation-enabled twins. Twins without isolation (Supabase, Google Workspace, Telegram, Ramp, Browser) still share a queue across workers — for those, set testIsolation: 'serial' if you depend on event ordering.

Slack caveat: Slack verifies signatures at the receiver (timestamp + body, not a sender-side header). delivery.headers from a Slack twin delivery won't include X-Slack-Signature; stub verification in tests or compute the header yourself.

Silence: the webhook queue-drain that runs inside resetArchalTwins() is best-effort and doesn't log.

Session Reuse Across Runs

The integration computes a stable session key from (projectName, services, seeds) so that repeated vitest run invocations with the same configuration reuse an already-provisioned hosted session. First run pays the 30s cold-start cost; subsequent runs finish in ~2s until the session's 30-minute idle TTL expires or the configuration changes.

Inspecting Resolved Runtime

Use getInstalledArchalVitestSession() inside a test to see what the backend actually resolved:

import { getInstalledArchalVitestSession } from '@archal/vitest';

const session = getInstalledArchalVitestSession();

console.log(session?.resolvedRuntime.resolvedServices);
console.log(session?.resolvedRuntime.resolvedSeeds);
console.log(session?.resolvedRuntime.manifestVersions);
console.log(session?.resolvedRuntime.capabilityVersion);
console.log(session?.resolvedRuntime.runtimeVersion);

That makes seed resolution and backend/runtime drift visible in CI failures instead of hidden in client defaults.

The session object returned here is a redacted snapshot — it deliberately does not expose routed-request auth headers or other credentials. The route runtime injects auth internally when forwarding test requests to twins; userland code should never need the raw token.

Authentication

The integration needs an Archal token to provision twin sessions. In priority order:

  1. ARCHAL_VITEST_TOKEN env var
  2. ARCHAL_TOKEN env var
  3. Stored credentials from archal login in ~/.archal/credentials.json

When stored credentials are used, the adapter refreshes them automatically before hosted-session API calls and keeps the routed twin auth header current during long watch runs.

Credential Sandbox Under Tests

When running under Vitest, Jest, or node --test, the credential store automatically redirects to a per-worker sandbox in the OS temp directory. On first access it copies your real ~/.archal/credentials.json into the sandbox, so reads see valid credentials. Any writes stay isolated from your real home directory — tests cannot clobber your login.

Set ARCHAL_HOME explicitly to opt out of the sandbox and point the credential store at a specific directory.

Environment

  • ARCHAL_VITEST_TOKEN or ARCHAL_TOKEN
  • ARCHAL_HOME — explicit credential directory (skips test sandbox)
  • ARCHAL_VITEST_API_URL — override hosted API endpoint
  • ARCHAL_VITEST_SESSION_READY_TIMEOUT_MS — override 5min default ready timeout

Packaging Status

The published artifact bundles its internal Archal runtime and auth helpers, so consumers do not need the Archal monorepo to install or use it.