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

@xyo-network/dapp-kit-vitest-config

v2.2.0

Published

Vitest config preset for XL1 dApps — node/browser base plus opt-in local chain installers

Readme

@xyo-network/dapp-kit-vitest-config

Public Vitest preset for XL1 dApps. Sister to @ariestools/vitest-config, with opt-in projects that boot a published local XL1 chain so dApp authors do not have to babysit xl1 start.

This is the publicly installable analog of the XYO-internal @xyo-network/xl1-vitest-config apiLocal harness. It does not depend on restricted @xyo-network/chain-test packages. The chain is the same public xl1 CLI used by @xyo-network/dapp-kit-local.

A green local run proves dApp chain interactions. It is not Sequence or mainnet qualification.

Install

pnpm add -D @xyo-network/dapp-kit-vitest-config @ariestools/vitest-config vitest
# optional browser project
pnpm add -D @vitest/browser-playwright playwright

An XL1 dApp already has @xyo-network/xl1-sdk and its peers; this package declares them as peers. @xyo-network/xl1-cli arrives as a dependency and is spawned by the local-xl1 setup. Do not import the CLI from application source.

Usage

Offline suite only

import { defineDappKitVitestConfig } from '@xyo-network/dapp-kit-vitest-config'

export default defineDappKitVitestConfig()

Defaults match @ariestools/vitest-config: the node project is named node, and a browser project (when enabled) re-runs shared specs. Swapping defineXyVitestConfig for this helper is not a silent topology change.

Local XL1, opt-in

import { defineDappKitVitestConfig } from '@xyo-network/dapp-kit-vitest-config'

export default defineDappKitVitestConfig({
  installers: { localXl1: { optInOnly: true } },
})
{
  "scripts": {
    "test": "vitest run",
    "test:local-xl1": "vitest run --project local-xl1"
  }
}

pnpm test stays offline. pnpm test:local-xl1 boots one published XL1 CLI chain per spec file.

Every local installer (all remain opt-in)

export default defineDappKitVitestConfig({ installers: true })

Installers

| Option id | Project name (--project) | Setup | |-----------|----------------------------|--------| | localXl1 | local-xl1 | Boots the published xl1 CLI (api + producer + finalizer) | | apiLocal | api-local | Same published CLI chain as localXl1, for specs under spec/api-local | | localEventPublisher | local-event-publisher | Boots its own XL1 chain and an Event Kit publisher fixture with signed HTTP subscriptions | | localDatalake | local-datalake | Isolates specs; no auto-setup | | localSystem | local-system | Isolates specs; serialized; 90s timeouts | | localBrowser | local-browser | Isolates specs; serialized |

installers: true enables every id. Each catalog default is optInOnly: true: include globs are stripped from the base node project, but the installer project only registers when selected via --project <name>.

installers shapes

| Value | Effect | |---|---| | omitted / false | no installer projects | | true | every id in DAPP_KIT_VITEST_DEFAULT_INSTALLERS | | ['localXl1'] | just those ids, each with catalog defaults | | { localXl1: true, localSystem: { hookTimeout: 120_000 } } | per-id enable / disable / override |

Per-installer overrides: env, hookTimeout, include, optInOnly, setupFiles, test, testTimeout. An unknown installer id throws at config load.

Resolution order for optInOnly, highest first: per-installer options → top-level optInOnly map → catalog default.

export default defineDappKitVitestConfig({
  installers: true,
  // Always boot a chain on `pnpm test` (usually the wrong default)
  optInOnly: { localXl1: false },
})

Where specs must live

The local-xl1 project's include globs come from the catalog, not from your include:

| Glob | Use | |---|---| | src/**/spec/local-xl1/**/*.spec.ts | single-package repo | | src/e2e/spec/local-xl1/**/*.spec.ts | root-level e2e package | | packages/**/src/**/spec/local-xl1/**/*.spec.ts | monorepo package specs |

A live spec outside these paths is not picked up by --project local-xl1, and (having no matching exclude) still runs in the offline project — where no chain exists.

Local chain with Event Kit publication

Enable this project when the dApp under test needs finalized-head wake delivery:

export default defineDappKitVitestConfig({
  installers: { localEventPublisher: true },
})

Put specs under src/**/spec/local-event-publisher/**/*.spec.ts (or packages/**/src/**/spec/local-event-publisher/**/*.spec.ts), then run:

pnpm vitest run --project local-event-publisher

This project owns one fresh chain and publisher identity per spec file. It includes the same rpcUrl, apiPort, and chainId globals as local-xl1; do not add that installer's setup too. The publisher is available through localEventPublisher() after setup's beforeAll hook. It accepts subscriptions in process; it does not expose an unauthenticated registration HTTP endpoint.

After starting your dApp's admission endpoint, register it:

import { localEventPublisher } from '@xyo-network/dapp-kit-vitest-config'

// In your test or beforeAll, after starting your dApp:
const publisher = localEventPublisher()
// Configure your dApp's admission policy to authorize publisher.publisher.
const subscription = await publisher.subscribe({
  endpoint: app.wakeUrl,       // your local dApp's actual HTTP admission endpoint
  audience: app.wakeAudience, // receiver-issued, exact audience
  deploymentId: app.deploymentId,
  lastProcessedPosition: app.fromPosition - 1,
  maxPositionsPerWake: app.maxPositionsPerWake,
  queueId: 'indexer',          // omit when the receiver route has no queue ID
})

// Publication is automatic; no runOnce() or synthetic head advance is needed.
// Assert your dApp's observable result here, then stop before closing its server.
await subscription.stop()

Each registration starts a real Event Kit WakePublisherActor. It reads the chain's finalized head through the XL1 SDK, signs canonical Event Kit wake Payloads with a fresh local account, and sends Authorization: Bearer <JWT> plus the raw Payload to the webhook. No signing key is exposed to the dApp. An every-block filter emits inclusive ranges, capped at 512 blocks by default; wakes may coalesce several finalized blocks. The first cursor defaults to the finalized head at registration, so only subsequent progress is published. Set lastProcessedPosition to an earlier block to backfill, or -1 to include genesis. A cursor ahead of finality is rejected. Configure the receiver with authorizationChainId: publisher.chainId, source: { kind: 'xl1-finalized', chainId: publisher.chainId }, and the same fromPosition and maxPositionsPerWake. Derive its filter hash with Event Kit's sourceWakeFilterHash and SOURCE_WAKE_FILTER_PROFILE, and bind the selected subscription. No legacy block-range envelope or version selector is supported.

Subscriptions have independent cursors and outboxes. A failed or timed-out delivery retries the same wake identity and content with a fresh JWT; the cursor advances only after HTTP 200 or 202. The receiver must return these statuses only after its own durable admission and handle duplicate wakes. Redirects and non-loopback destinations are rejected. A slow or failing subscriber does not block another subscriber.

subscription.status() reports the cursor, successful delivery count, pending outbox, last failure, and stopped state. publisher.assertHealthy() reports unresolved failures; automatic teardown checks health and stops every subscription, the SDK session, and the chain even when a test fails. Stop a subscription explicitly when intentionally testing rejection or before closing its endpoint. stop() is idempotent. For custom timing, use startLocalEventPublisher({ intervalMs: 100, requestTimeoutMs: 5000 }) in your own setup and always call its stop() in teardown.

Scope: this is an ephemeral local test publisher. Cursor/outbox state lasts for the fixture lifetime, matching the chain's in-memory lifetime; it is not a process-restart durability fixture. The dApp owns its actual admission gate, grants, inbox, queue, and consumer processing. Registration does not fabricate Statement Graph grants or exercise the on-chain publisher/subscriber handshake.

Optional Event Kit packages

Only this project needs @ariestools/actor (^1.3), @xyo-network/event-kit-actor (^0.1.4), and @xyo-network/event-kit-schemas (^0.1.4). These are optional peers and the runtime is loaded separately, so offline and chain-only consumers do not load them. Install compatible Event Kit artifacts in the consuming project before selecting this installer. The packed-consumer gate installs Event Kit 0.1.4 from npm in a fresh isolated store and proves signed delivery without workspace source links.

What the local-xl1 installer does

installLocalXl1Setup() registers a beforeAll / afterAll pair, so each spec file gets its own chain:

  1. picks a port — 8080 + VITEST_WORKER_ID, falling back to an OS-assigned ephemeral port when that one is busy (it does not scan upward);
  2. spawns the published xl1 CLI with api, producer, and finalizer, telemetry disabled, on loopback;
  3. waits until a typed XL1 viewer can read chainId and the current head;
  4. assigns test globals and logs dapp-kit local XL1 started: API on <port>, chain <id>;
  5. stops the child in afterAll (dapp-kit local XL1 stopped).

The chain uses the well-known insecure mnemonic test test test test test test test test test test test junk. Account 0 is genesis-funded. Storage is in-memory and resets every spec file. The chain id is ephemeral.

This is a dev chain: simplified consensus, no EVM staking layer. Treat a green run as "my chain interactions are correct," then validate against Sequence before shipping.

Test globals

| Global | Type | Contents | |---|---|---| | rpcUrl | string | http://127.0.0.1:<port>/rpc — use this | | apiPort | number | the chosen port | | chainId | string | fresh per boot |

Read globalThis.rpcUrl (or localXl1RpcUrl()); do not hardcode http://localhost:8080/rpc. Only the first spec file lands on 8080 — a parallel run boots additional chains on other ports.

Ambient types ship at @xyo-network/dapp-kit-vitest-config/globals:

{
  "compilerOptions": {
    "types": ["node", "@xyo-network/dapp-kit-vitest-config/globals"]
  }
}

Then build the gateway from the global:

import { assertEx } from '@ariestools/sdk'
import type { XyoViewer } from '@xyo-network/xl1-sdk'
import { GatewayBuilder } from '@xyo-network/xl1-sdk'
import { localXl1RpcUrl } from '@xyo-network/dapp-kit-vitest-config'
import {
  beforeAll, describe, expect, it,
} from 'vitest'

let viewer: XyoViewer

beforeAll(async () => {
  const gateway = await new GatewayBuilder()
    .name('local')
    .rpcUrl(localXl1RpcUrl())
    .build()
  viewer = assertEx(gateway.connection.viewer, () => 'local chain gateway exposed no viewer')
})

describe('finalized head (live local chain)', () => {
  it('advances as the chain finalizes blocks', async () => {
    const start = await viewer.finalization.headNumber()
    let head = start
    for (let attempt = 0; attempt < 40 && head <= start; attempt += 1) {
      await new Promise(resolve => setTimeout(resolve, 250))
      head = await viewer.finalization.headNumber()
    }
    expect(head).toBeGreaterThan(start)
  })
})

To sign, derive from LOCAL_XL1_DEV_MNEMONIC (account '0' is genesis-funded).

Running

pnpm test                              # offline: node (+ browser) projects only
pnpm vitest run --project local-xl1    # live: boots a chain per spec file
pnpm test:local-xl1                    # the same, via the package script

Repository self-qualification

The dapp-kit monorepo uses defineDappKitVitestConfig as its root configuration owner and registers the public apiLocal installer (published XL1 CLI, not the restricted @xyo-network/xl1-vitest-config package). The root imports this package's source entry deliberately, so a clean checkout can load Vitest before ignored dist/ output exists.

That source bootstrap is not treated as package evidence. The separate pnpm test:packed-dapp-kit-vitest-config gate builds and packs this package, installs the tarball into a temporary consumer with only declared dependencies, type-checks a consumer-owned config, runs its offline project, and boots a local XL1 chain through the packed local-xl1 setup export.

API

| Export | Description | |--------|-------------| | defineDappKitVitestConfig | Full root config (watch: false + projects + selection footer) | | defineDappKitVitestProjects | Projects array only | | defineDappKitInstallerProjects | Installer projects + base excludes + selection | | installLocalXl1Setup / startLocalXl1Chain | Chain lifecycle used by the setup file | | localXl1RpcUrl | Reads globalThis.rpcUrl or throws | | localEventPublisher | Reads the per-spec publisher fixture or throws before setup | | installLocalEventPublisherSetup / startLocalEventPublisher | Chain plus publisher lifecycle; the latter supports custom timing | | LOCAL_XL1_DEV_MNEMONIC | Insecure local-dev mnemonic | | formatProjectSelectionFooter / DappKitProjectSelectionReporter | Footer helpers | | Re-exports from @ariestools/vitest-config | defineXyVitestConfig, defineXySerializedProject, … |

Disable the post-run project-selection footer with projectSelectionFooter: false.