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

anton-bakker-feedback

v0.4.4

Published

Zero-dependency business logic layer for feedback collection — types, capture, transport, config, i18n, observability

Readme

anton-bakker-feedback

Zero-dependency feedback collection package with LLM-powered dialogue intake, auto-capture, classification, and observability.

Exports

| Entry point | Purpose | |-------------|---------| | anton-bakker-feedback | Core: types, capture, transport, config, i18n, observability | | anton-bakker-feedback/react | Widget: FeedbackProvider, FeedbackPanel, FeedbackButton, etc. | | anton-bakker-feedback/react/admin | Admin pages: List, Detail, Update | | anton-bakker-feedback/server | Server handlers: DynamoDB + Bedrock factories | | anton-bakker-feedback/manifest | Package manifest for plugin discovery |

Central Ingest Transport

The core entry exports createIngestTransport — a FeedbackSubmitTransport that writes feedback to the central ingest API instead of a bespoke direct-DynamoDB writer (the central-storage principle: reach central storage only through an authenticated API). The consuming app mints a short-lived OAuth2 client-credentials JWT and POSTs the feedback content to POST /records/feedback; the server attributes the write to the token identity (client_id) and stamps the canonical keys, so the app holds no AWS principal and sends no partition/identity fields. Zero dependencies — uses fetch.

import { createIngestTransport } from 'anton-bakker-feedback';

const transport = createIngestTransport({
  apiUrl: process.env.FEEDBACK_INGEST_URL!,     // https://<id>.execute-api.<region>.amazonaws.com
  tokenUrl: process.env.FEEDBACK_TOKEN_URL!,    // Cognito client-credentials token endpoint
  clientId: process.env.FEEDBACK_CLIENT_ID!,    // this app's client id (its identity)
  clientSecret: await resolveSecret('feedback/ingest/<app>'), // from your secret store — never commit
  // OR, if the host already manages the token: tokenProvider: () => getToken()
});

const result = await transport.submit(item);    // → { success, feedbackId, error?, retryable? }

The transport mints and caches the token (refreshing before expiry), strips server-owned key fields (PK/SK/GSI*) before sending, and never fails silently: a 5xx or network error returns { success: false, retryable: true }; a 4xx returns { success: false, retryable: false } with the server's error message.

The direct-DynamoDB write path (FeedbackService.put, ./server) is @deprecated — it is the pattern the central-storage principle removes. New writers use this transport.

Admin Pages

The ./react/admin entry point provides three headless page-level components for managing submitted feedback. Components are unstyled — pass className props to integrate with Tailwind CSS or any other CSS framework.

Import

import {
  FeedbackListPage,
  FeedbackDetailPage,
  FeedbackUpdatePage,
} from 'anton-bakker-feedback/react/admin';

Admin pages are tree-shakeable. Apps that import only from ./react (the widget) do not bundle admin page code.

Props contract

All three pages use Inversion of Control — you provide the data and navigation functions; the component provides the UI structure.

| Prop | Type | Used by | Description | |------|------|---------|-------------| | items | StoredFeedbackItem[] | List | Feedback items to display | | loading | boolean | List | Show loading state | | fetchItem | (id: string) => Promise<StoredFeedbackItem> | Detail, Update | Load a single item | | updateItem | (id: string, patch: Partial<StoredFeedbackItem>) => Promise<void> | Update | Persist changes | | onNavigate | (path: string) => void | All | Consumer-owned routing | | currentUser | { userId: string; name?: string } | All (optional) | For assignee display | | className | string | All (optional) | Root element class | | feedbackId | string | Detail, Update | Item to load/edit |

Minimal example

import { FeedbackListPage } from 'anton-bakker-feedback/react/admin';

export function AdminFeedbackRoute({ items, loading }) {
  return (
    <FeedbackListPage
      items={items}
      loading={loading}
      onNavigate={(path) => router.push(path)}
      className="my-admin-list"
    />
  );
}

Error handling

Components handle loading and empty-state UI internally. Data fetch errors should be caught in your fetchItem/updateItem implementations and surfaced via your consumer-level error boundary.

Development

npm install
npm run build        # Build all entry points
npx vitest run       # Run tests
npx tsc --noEmit     # Type check

License

MIT