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

@nolgard/webapps-search

v0.1.3

Published

Same-origin, typed search client for Pinecone addons.

Readme

@nolgard/webapps-search

License

Copyright (c) 2026 Johan Lindqvist. Use of material not already licensed requires prior written permission. See LICENSE.txt. Previously granted MIT and third-party rights remain unchanged.

Framework-independent client for Pinecone's public GET /rest-api/v1/search. No runtime dependencies or API keys. Requires Fetch, URL and AbortController (modern browsers or Node.js 18+). TypeScript declarations are included.

import { createSearchClient, SearchClientError } from '@nolgard/webapps-search'

const search = createSearchClient({ apiBase: '/pinecone/rest-api/v1/' })
const controller = new AbortController()

try {
  const result = await search.search(
    { q: 'education', limit: 20, label_ids: [3], sort: 'relevance' },
    { signal: controller.signal },
  )
  // Render titles/excerpts as text, never as HTML.
  console.log(result.count)
} catch (error) {
  if (error instanceof SearchClientError && error.code !== 'aborted') {
    // Map the stable code/status to a localized message.
    // Do not log queries, metadata values, URLs or response bodies.
    console.error(error.code, error.status)
  }
}

suggest({ q: 'edu', limit: 5 }) uses prefix search and returns distinct, non-empty result titles (case-insensitive deduplication). Debounce and cancel requests in the addon; the package deliberately performs no automatic retries. Automatic suggestion prefixes apply only to plain queries; explicit operators, wildcards and quoted phrases are transmitted unchanged without an implicit prefix. SQLite supports wildcard search, pagination, sorting, operators, section filters and metadata filters. Legacy JSON capabilities remain backend-defined.

Query syntax (SQLite)

  • Plain words use AND and match whole indexed words; +word explicitly requires a word (the same AND behavior). -word excludes it.
  • "exact phrase" matches adjacent words in order; -"excluded phrase" excludes that phrase. Quotes do not support wildcards or backslash escaping.
  • word* matches words starting with word, *word matches words ending with it, and *word* matches words containing it. Combine with +/-, for example +*education* -course*.
  • Wildcard roots require at least three Unicode letters/digits. Stars inside words, repeated stars, empty phrases and exclusion-only queries are rejected. AND/OR/NOT typed into a query are literal search words, not executable syntax.
  • Leading wildcards expand the FTS5 vocabulary with the index's Unicode normalization. At most 256 expanded words across the query are permitted. Overly broad queries return HTTP 400, never silently truncated results. Native trailing prefixes do not need vocabulary expansion.
  • Advanced syntax requires SQLite; the legacy JSON backend returns HTTP 400. No new request fields, index rebuild or stored-data migration are required.

getSearchHighlightTerms(query) returns deduplicated lowercase positive words for display highlighting, excluding -terms, excluded phrases and operators. It preserves substring highlighting inside compound words. It is not a syntax validator: the backend validates the complete query. Non-string, invalid Unicode or more than 200 code points throws SearchClientError (invalid_query).

Contract

search accepts the backend parameter names: q (at most 200 Unicode code points), limit (1..50), page (1..1000), section_ids/label_ids (at most 50 positive safe integer IDs), label_mode (any/all), include_descendants and prefix_search (booleans), sort (relevance/title/updated), and metadata (at most ten { key, operator, value } filters). Operators are eq, in, gte, lte; in takes 1..20 scalar values. Strings in metadata filters must not exceed 500 UTF-8 bytes. Unknown request/configuration keys are rejected, not forwarded.

Results expose only the documented fields in index.d.ts, validate result URLs as same-origin HTTP(S), and normalize them to absolute URLs. Highlight offsets are Unicode code points. Text may contain HTML-looking characters; consumers must use text rendering, never innerHTML or Svelte {@html}. Pagination, generation and highlights are optional to support the JSON engine.

Security and errors

  • API URLs must be same-origin HTTP(S), without user info, query or fragment. Protocol-relative URLs and redirects are rejected.
  • Requests use mode: same-origin, credentials: same-origin, redirect: error, cache: no-store and referrerPolicy: no-referrer. Session cookies are managed by the browser; the client never reads cookies or storage and never adds auth headers. Use HTTPS in production.
  • No API key/token option, global credential lookup, persistent result cache, query logging, telemetry or server diagnostic passthrough.
  • Errors expose stable code, HTTP status and numeric retryAfter (seconds), never the response body, request URL, exception cause or supplied abort reason. Codes: invalid_options, invalid_query, unsafe_url, invalid_response, request_failed, network_error, timeout, aborted.
  • A default 10-second timeout covers both Fetch and JSON reading. timeoutMs accepts 1..60000. Cancellation uses code aborted and name AbortError.
  • JSON responses are read as bounded UTF-8 streams (maximum 2 MiB). Oversized, malformed or non-JSON responses fail with invalid_response.
  • Backend authorization and public metadata selection remain authoritative: a browser library cannot conceal data that a server already exposes. Never store secrets in searchable public content, metadata, queries or addon config.
  • apiBase is recommended for nonstandard installation paths. Otherwise the client detects /pinecone (including nested paths), or uses the site root. searchApiUrl selects an explicit same-origin endpoint. Browser location is used by default; tests/SSR must supply location and may supply fetch.

Development

Run npm test in this directory. Publish with npm publish --access public. Only the implementation, types and README are included in the npm package.