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

@schemastud/facets

v0.2.1

Published

The schema-driven facets surface: a resource-agnostic filter/sort bar over the x-filter / x-sort vendor keywords, with injected transport, injected UI primitives, and an injected URL-state seam. Host-agnostic and grammar-blind — no vendor vocabulary, no b

Readme

@schemastud/facets

The schema-driven facets surface: a resource-agnostic filter/sort bar that reads the x-filter / x-sort vendor keywords a backend emits (the rushing/laravel-data-filters PHP spine) and renders a batteries-included list-filtering UX — chips, popovers, a sort control, saved views — with zero per-resource code.

This package is a frame-rung tracer for the planned @schemastud/frame. It exists to prove, end-to-end, the three injection seams a batteries-UX rung needs on top of the lean @schemastud/seam mechanism rung:

  1. Injected transport — a named-method FacetsTransport, not a bundled HTTP client. (Diverges from seam's single-function schemaFetcher: a list needs five operations, not one.)
  2. Injected UI primitives — a FacetsPrimitives bundle (Button, Input, Label, Popover, SimpleSelect, Badge). Seam has no precedent here — it renders through RJSF's theme; a bespoke-chrome surface must receive its primitives.
  3. Injected URL-state — a useUrlState hook seam, so the package carries no router dependency (the app binds react-router's useSearchParams).

Usage

Provide the injection bundle once at the app root:

import { FacetsProvider, type FacetsInjection } from '@schemastud/facets';

const injection: FacetsInjection = { transport, primitives, useUrlState };

<FacetsProvider value={injection}>
    <App />
</FacetsProvider>;

Then any list page is pure wiring:

import { ListFilters, useListFilters, useFilterChangeDim } from '@schemastud/facets';

function FragmentsPage() {
    const listFilters = useListFilters('fragment');
    const rows = useRows(listFilters.requestParams);
    const dimming = useFilterChangeDim(listFilters.filterFingerprint, rows.isFetching);
    return (
        <>
            <ListFilters {...listFilters} />
            <DataTable data={rows.data} loading={dimming} sorting={listFilters} />
        </>
    );
}

Variants and saved views

getFilterVariants(resource) returns { resource, variants }, where each variant declares key, resource, canonical, and sameAsCanonical. The generic list offers selection when noncanonical variants exist, including when the default vocabulary is empty. Selection calls getFilterSchema(resource, variant) and travels with ordinary list requests as the top-level filterVariant URL parameter. Switching clears filters, sort and page; saved views preserve the variant and restore only filters and sorts its current schema declares.

Saved-view support comes from the schema response's savedViewsResource. Mutation controls also require server permissions: savedViewsCan.create for Save and each saved row's can.delete for Delete. Missing permissions leave readable views applicable and hide the corresponding mutation. An optional FacetsInjection.can(action, resource, record?) can further restrict those actions; it receives the advertised saved-view resource and, for deletion, the actual row. FrameProvider forwards its existing can callback. The backend remains the authority when a request executes.

Peers

react >=18, @tanstack/react-query ^5, lucide-react. No router, no HTTP client.

Canonical types

FilterDescriptor / SortDescriptor mirror the emission of the laravel-data-filters operators. The canonical source of truth is co-located with the operators at laravel-data-filters/resources/types/filter-schema.ts, and a PHP conformance test fails if the operator emission drifts from it. Keep this copy in lockstep.

Transport lifetime and query caching

Keep the injected transport object stable while its realm, tenant and principal are stable. Replace it when that authority changes. Frame and facets scope cached reads, mutations and pending saved-view application to that object, so providers may share a QueryClient safely. Changing credentials inside an existing transport does not change its cache identity.

The implicit identity is opaque and runtime-local. It does not provide a persistent-cache or SSR hydration protocol. Existing resource query prefixes still support deliberate broad invalidation; Frame's resourceQueryKey(transport, resource, ...parts) builds an exact key for seeding or targeting one transport. Mutation hooks invalidate their own transport only.