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

@uiresponse/resolver

v0.2.0

Published

Executes one declared UIR dataset's query against a connector. The single host tool behind every UIR page's data.

Readme

UIR resolver

resolve(pageDoc, datasetName, params) executes one declared dataset's query (per spec/foundations/data.schema.json) against whatever connector its source.connector names, and returns:

{
  rows: object[],
  columns: object[],      // the dataset's declared columns[]
  errors: object[],       // structured errors — see index.mjs's header comment for the full list
  meta: {
    complete: boolean,    // see "meta.complete" below
    row_count: number,    // rows.length, for convenience
    limit: number | null, // the EFFECTIVE limit applied (query.limit, or the resolver's own
                           // DEFAULT_LIMIT when the query names none) — null only when the
                           // dataset itself couldn't be found at all
  },
}

meta is additive — everything else about resolve()'s signature and the shape of rows/ columns/errors is unchanged from Stage 3c. See index.mjs's header comment for the full pipeline (derive → filter → select/group_by → sort → limit → D5 verification → projection). Wiring docs for specific deployments live with the deployment, not here.

meta.complete

true iff the returned rows are the WHOLE matching set — nothing was cut short by the query's limit, and the connector itself didn't cap its own fetch short of the true count either. Both have to hold:

  • Resolver-side: the row count before the limit slice was strictly less than the effective limit. Landing on EXACTLY the limit is treated as "maybe there's more, can't tell" — conservatively not complete, rather than assuming the count hit the limit by coincidence. (Confirmed against live data: artist-pipeline.page.json's pipeline dataset, limit: 500, against a resource holding more than that, returns exactly 500 rows and complete: false — correctly, since there genuinely are more.)
  • Connector-side: a connector reports its own completeness by returning either a plain rows[] array (the implicit claim: "I never cap, this is everything" — true for connectors/seed.mjs, which always returns its whole fixture) or {rows, complete} when it CAN cap and wants to say so honestly (connectors/postgrest.mjs, hitting PostgREST's row limits — this caught a real bug: an unlimited query silently truncated at PostgREST's default 1000-row cap until the connector was taught to paginate and report complete honestly). An object return with no complete: true is treated as NOT complete — an unstated claim is not a claim, and assuming completeness a connector never asserted is exactly the confident-lie failure this field exists to prevent.

Host optimization rule

A host holding a prior, meta.complete: true result for a dataset MAY satisfy a param-driven re-resolution client-side, by re-evaluating the changed predicate over the rows it already has — via evaluatePredicateOverRows (below) — instead of calling resolve() again. Same semantics, zero latency, zero network round-trip.

This is valid when and only when both hold:

  1. The prior result was complete (meta.complete === true). Filtering a truncated window silently drops rows that exist beyond the cut — the confident-lie failure R9/D5 already exist to prevent elsewhere in this resolver, showing up again one layer up. A host that filters an incomplete result client-side will show fewer matches than actually exist, with nothing to indicate the difference.
  2. The changed predicate is post-derive, row-level, with no group_by/aggregate reshaping downstream of it in the dataset's query. derive has already run and its columns are already real properties on the rows the host is holding, so re-filtering needs no re-derivation — but if the query also selects with group_by/aggregate, the rows the host holds are already RESHAPED (one row per group, values already collapsed). You cannot correctly "further filter" an already-aggregated result and get what a real re-query with the new filter would produce — the correct rows to aggregate are different from the ones that made it into the old groups. A dataset with no select/group_by at all (a plain filter → sort → limit, e.g. unsigned-contracts.page.json's unsigned dataset, or artist-pipeline.page.json's pipeline dataset) is always eligible; stage_counts/monthly_earnings-shaped datasets never are.

Outside those two conditions, a host MUST re-query (call resolve() again). This is a policy for the HOST to apply, not something this resolver can enforce from the inside — resolve() has no way to know what a caller intends to do with the rows it hands back.

evaluatePredicateOverRows(rows, filter, params, opts)

import { evaluatePredicateOverRows } from "uir/resolver/index.mjs";

const kept = evaluatePredicateOverRows(priorResult.rows, dataset.query.filter, newParams, { now });

Reuses the EXACT SAME predicate grammar resolve() itself runs internally (all/any/not, every comparison op, $param substitution, $now resolution, optional: true dropping) — a host never reimplements or drifts from the grammar. It is a mechanical re-filter only: it does not re-run derive, and it has no opinion on whether using it here is actually eligible per the rule above — that check is the caller's responsibility.

  • rows — rows from a prior resolve() call (already carrying any derived columns the filter references).
  • filter — a UIR predicate tree; in practice, usually the dataset's own query.filter taken as-is, since the eligible case is "the same filter, a different parameter value."
  • params — already-resolved parameter values, same shape resolve()'s third argument takes.
  • opts.now — defaults to new Date(), exactly like resolve()'s own opts.now.

Proven, not just asserted: resolver/tests.mjs resolves unsigned-contracts.page.json's unsigned dataset once with no artist filter (a complete result), then shows that re-evaluating that SAME dataset's own filter client-side with evaluatePredicateOverRows for a specific artist produces bit-for-bit the same rows as a real second resolve() call for that artist.

Writing a connector

A connector is async ({ source, query, params }) => rows[] | { rows: object[], complete: boolean }.

  • Return a plain array if your connector never caps short of the true count (the common case — see connectors/seed.mjs).
  • Return { rows, complete } if your connector CAN cap (a page-size limit, a server-side default, a hard ceiling) and wants meta.complete to reflect reality instead of silently defaulting to "not complete" — see connectors/postgrest.mjs's pgrestSelectAll, which pages through PostgREST's Range header until a short page proves there's nothing left, and reports complete: false (not an error) if it ever exhausts its page ceiling without finding one.
  • The resolver always re-applies the FULL query (derive/filter/select/group_by/sort/ limit) regardless of what a connector returns — pushing filter/sort/limit down (as connectors/postgrest.mjs does, conservatively, for a real efficiency win) is optional and never a correctness dependency.

MCP resources

The built-in mcp connector is read-only by construction. A page declares only a logical name:

{ "connector": "mcp", "resource": "release_notes" }

The host maps that name to one trusted MCP read operation through UIR_MCP_SERVERS. Each entry uses either a stdio command or a Streamable HTTP URL and configures exactly one tool or uri:

{
  "release_notes": {
    "transport": "stdio",
    "command": "node",
    "args": ["./release-notes-server.mjs"],
    "tool": "list_release_notes",
    "arguments": { "limit": { "$query": "limit" }, "artist": { "$param": "artist" } },
    "description": "Approved release notes.",
    "columns": [
      { "name": "release_id", "type": "string", "role": "id" },
      { "name": "published_at", "type": "date", "nullable": true }
    ],
    "timeout_ms": 10000
  },
  "campaign_briefs": {
    "url": "https://mcp.internal.example/mcp",
    "uri": "briefs://campaigns/current",
    "columns": [{ "name": "campaign", "type": "string" }]
  }
}

Tool argument templates may contain {$param:"name"}, {$query:"limit"} (including dotted query paths), {$source:"resource"}, and {$now:true}. The connector performs the MCP initialize handshake using protocol version 2025-11-25, then only tools/call or resources/read; it exposes no write path. Returned values must be JSON rows: a tool may return an array or { "rows": [...] } in structuredContent or JSON text content, and a resource may return the same shapes as JSON text/blob contents.

MCP calls are optimization-neutral: the shared resolver always reapplies the whole UIR query, verifies declared column types, and drops undeclared fields. A transport error, MCP error, malformed result, or timeout becomes connector_error, never a successful empty dataset. Since MCP has no universal pagination signal, results default to meta.complete: false; set "complete": true only when that configured operation is guaranteed to return the whole set.