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

@generative-a11y/core

v0.3.0

Published

Framework-independent accessibility runtime that turns streaming AI and agent lifecycle events into paced screen-reader announcements.

Readme

@generative-a11y/core

Browser-independent event orchestration for generative-a11y.

Install

npm install @generative-a11y/core

Quick start

import { createGenerativeA11y } from "@generative-a11y/core";

const runtime = createGenerativeA11y({
  onAnnouncement(announcement) {
    deliveryDriver.announce(announcement);
  },
});

runtime.dispatch({ type: "response.started", responseId: "r1" });
runtime.dispatch({
  type: "response.text.delta",
  responseId: "r1",
  delta: "A complete sentence.",
});
runtime.dispatch({ type: "response.completed", responseId: "r1" });

Core emits announcement intents; it does not touch the DOM or claim that assistive technology spoke them. Applications normally consume this package through a framework adapter and DOM driver.

runtime.pendingCount() includes queued announcement candidates and owned response flush timers. Backend error fields are diagnostic-only; use an event's announcement field for short, localized, user-safe spoken error copy.

Hierarchical workflows

Core models run.* and step.* lifecycle directly rather than collapsing agent work into responses or tools. Stable logical IDs can be paired with explicit instance IDs for retries, parent run/step IDs for nesting, and optional run/step context on responses, tools and interactions.

runtime.dispatch({
  type: "run.started",
  runId: "research",
  runInstanceId: "1",
});
runtime.dispatch({
  type: "step.started",
  runId: "research",
  runInstanceId: "1",
  stepId: "sources",
  stepInstanceId: "sources-1",
  label: "Collect sources",
});
runtime.dispatch({
  type: "step.completed",
  runId: "research",
  runInstanceId: "1",
  stepId: "sources",
  stepInstanceId: "sources-1",
  label: "Collect sources",
});
runtime.dispatch({
  type: "run.completed",
  runId: "research",
  runInstanceId: "1",
});

The balanced policy announces terminal run summaries and only identified, long-running top-level steps. Nested steps and progress are quiet by default. A generic empty run completion is silent when its completed response boundary was already announced. A step event without stepId produces only an ephemeral partial-identity diagnostic: it cannot create a step snapshot, announcement, or run count. The runtime never uses display labels as identity. A failed child preserves sibling work, while retry replacement cancels only the replaced attempt and its descendants. Known active children block a successful parent completion.

Runtime contract

createGenerativeA11y(options) accepts a preset, nested policy overrides, an optional injected Clock, and optional delivery callbacks:

  • onAnnouncement(intent) optionally installs an initial listener for prepared polite/assertive intents. If it throws, scheduling continues and onDeliveryError(error, intent) is called. A runtime intended for subscribeAnnouncements() or connectRuntimeToDOM() does not need a no-op construction listener. An announcement emitted while no listener is attached receives a delivery-error diagnostic.
  • onDiagnostic(decision) observes best-effort queued, merged, suppressed, cancelled and announced decisions. Observer errors are isolated.
  • dispatch(event) returns true when a normalized response, tool, interaction, connection or citation event is accepted for immediate or nested processing. It returns false when the runtime is disposed or the current dispatch transaction has reached capacity. Dispatch attempts from an overflow-diagnostic observer also return false; their recursively redundant overflow diagnostics are suppressed so reporting always terminates.
  • getPolicy() returns a deeply frozen policy snapshot.
  • pendingCount() counts scheduler candidates and response flush timers.
  • subscribeAnnouncements(listener) adds an isolated output listener and returns an idempotent unsubscribe function. This is the attachment point used by browser delivery integrations; the optional construction callback is an initial listener when supplied.
  • subscribeDiagnostics(listener) observes subsequent diagnostic decisions and returns an idempotent unsubscribe function. Diagnostic listener failures are isolated.
  • subscribeDiagnosticEvents(listener) observes a versioned, ordered stream of normalized source events and diagnostic decisions. It is explicitly opt-in; listener failures are isolated and it never changes scheduling.
  • getDiagnosticSnapshot() returns an immutable, serializable snapshot of the active response/tool/run/step lifecycle plus pending announcement and flush timing. It intentionally excludes buffered response text, labels, errors, scopes, deduplication keys, and timer handles. Each pending announcement includes its stable ID, channel, source type, correlation IDs when present, scheduling time, due time, delay and queue sequence. Entries are ordered by due time and then queue sequence. The returned array and every entry are frozen.
  • dispose() is idempotent, cancels owned timers/queues and makes later subscription attempts throw; later dispatches return false.

Announcement listeners run from a stable snapshot. A throwing listener does not prevent later listeners from receiving the same intent, and every listener failure is reported through onDeliveryError. A delivery is diagnosed as failed only when every current announcement listener throws.

Responses and tools should always receive a terminal event. maxActiveEntities also prevents missing terminal events from growing active state without bound. responseInstanceId/nextResponseInstanceId and toolInstanceId reject late events when a logical ID is reused. Progress is normalized from 0 to 1; invalid values are suppressed diagnostically.

Policies and presets

presets contains deeply frozen minimal, balanced, verbose and completion-only policies. resolvePolicy(preset, overrides) validates and freezes a customized snapshot. Timing values must be finite and non-negative; queue/entity ceilings must be positive integers.

policy.workflows controls run boundary verbosity, step verbosity, the long-running step threshold, explicit progress, and nested-step announcements. No policy setting manufactures hierarchy that a source cannot identify.

Scheduler

createAnnouncementScheduler(options) is the lower-level prioritized queue used by the runtime. schedule(candidate) supports delay, scope cancellation, coalescing, explicit dedupe keys, and an optional capacityPriority of "status" or "content" for capacity retention. Candidates without a capacity priority retain the legacy content tier. cancelScope(scope) cancels queued candidates, pendingCount() reports queue length, and dispose() permanently clears it. The scheduler validates bounds, preserves assertive work under capacity pressure, isolates callback failures and defaults deduplication to the candidate's semantic entity.

getDiagnosticSnapshot() returns the scheduler's current pending work without announcement text, deduplication keys, scopes, or timer handles. Each entry contains stable delivery and correlation metadata plus scheduling, due-time, delay, and queue-sequence values. Entries are ordered by due time and then queue sequence. The returned array and each entry are frozen so diagnostic consumers cannot mutate scheduler state.

Most applications should use the runtime rather than schedule announcement text directly.

Clocks and deterministic testing

systemClock is the production clock. ManualClock supplies deterministic advanceBy, advanceTo, runNext, runUntilIdle and pendingCount methods; equal-time callbacks retain insertion order. runUntilIdle(maxTasks) throws before exceeding its safety limit.

createAnnouncementRecorder() returns a runtime wired to a ManualClock. transcript() contains delivered intents; diagnosticTranscript() also exposes stable dispositions and reason codes. A capacity diagnostic may include a serializable count when it represents multiple suppressed decisions, including dropped nested runtime events. These records prove runtime policy behavior, not actual assistive-technology speech.

For development tooling, RuntimeDiagnosticEventV1 has an explicit schema version and monotonically increasing sequence. A source event is emitted before the decisions caused by its dispatch. RuntimeDiagnosticSnapshotV1 exposes only safe lifecycle and queue timing metadata; core retains no diagnostic history. Capture tools should bound their own history and redact conversation content by default.

Record and replay

The optional @generative-a11y/core/testing entry records accepted normalized events, creates versioned replay fixtures, replays them with a ManualClock, and installs semantic Vitest matchers. It is intended for test code and does not add anything to the main core entry.

import { expect } from "vitest";
import { createAnnouncementRecorder } from "@generative-a11y/core";
import {
  installVitestMatchers,
  recordRuntime,
  replayEvents,
} from "@generative-a11y/core/testing";

const accessibilityExpect = installVitestMatchers(expect);

const recorder = createAnnouncementRecorder();
const recording = recordRuntime({
  runtime: recorder.runtime,
  clock: recorder.clock,
});

recording.runtime.dispatch({
  type: "response.started",
  responseId: "r1",
});
recording.runtime.dispatch({
  type: "response.interrupted",
  responseId: "r1",
});

const fixture = recording.fixture();
const replay = createAnnouncementRecorder({ startAt: fixture.startAt });
replayEvents(replay.runtime, replay.clock, fixture);
replay.clock.runUntilIdle();

accessibilityExpect(replay).toHaveAnnounced({
  sourceType: "response.interrupted",
});

Fixtures use a stable V1 JSON envelope, non-negative relative timestamps, and array order for simultaneous events. Replay validates the complete fixture before dispatch and does not run the clock until idle. Transcript assertions confirm deterministic runtime behavior, not browser delivery or spoken output. Run and step fixtures use the same event union and preserve explicit parent and attempt identity without inferring missing relationships.

Segmentation

segmentText(text, "sentence" | "paragraph", locale?) returns completed units and an unfinished remainder. It uses Intl.Segmenter when available, falls back safely, and tolerates malformed locales. normalizeAnnouncementText() collapses whitespace only at the delivery boundary.

Types

The package exports the normalized GenerativeA11yEvent union, announcement and diagnostic records, policy types, adapter fidelity metadata, scheduler types, and clock types. Events are serializable where practical; callbacks and clock handles are intentionally runtime-only.

Documentation

Related packages