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

@michaelthielemann/kestrel-delivery-static

v5.8.1

Published

Steps delivery.publish/unpublish/readStatus/publishAll: renders published documents per locale via renderer@1, stores them in blobstore@1 and tracks a publish status.

Readme

delivery/static

Static delivery with a publish status per document and locale. Requires content@1, site@1, renderer@1 (the site's own renderer), blobstore@1 (filesystem or S3) and persistence@1. delivery.publish:<type> after content.create/update: for every locale whose own statusField equals publishedValue the document (fields with fallback, internal links resolved to public paths via site.resolveLinks, _links attached) is rendered in each configured format and stored under the path site.pathOf returns (default locale unprefixed unless prefixPrimary, home slug → /); other locales are removed. Outcome per locale in delivery_publish_status (live | error | draft, path, error, publishedAt); a failed render keeps the previous live output. delivery.unpublish:<type> after remove, delivery.readStatus:<type> for the editor's second lamp, delivery.publishAll:<type> to re-render everything. Formats come from the renderer (html, pdf, …) – formats: ["html", "pdf"] writes both. Assets the renderer returns (assets: [{ path: "/_nuxt/app.js", … }] – hydration bundles, CSS) are stored under <prefix><path> once per process; they are never removed on unpublish. With media configured, text output is scanned for <publicPath>/<id>/file and <publicPath>/<id>/variants/<size>.<ext> (HTML-escaped slashes, e.g. &#x2F;, are not matched) and copied to <prefix><target><folder>/<filename>[.<size>.<ext>], rewritten in place; each target is copied once per process, so a file re-uploaded under the same name is refreshed in the export only by publishAll. Unresolved references are logged and left untouched. delivery.exportLlms (always on; llms defaults to paths instead of URLs and no full file) (no argument; append it after delivery.publish/unpublish/publishAll and after saving the settings) writes <prefix>llms.txt per llmstxt.org from the live status rows of every delivered type: # <settings title>, > <settings description>, one ## <headings[type] ?? type> section with - [<seo.title || title>](<siteUrl><path>): <seo.description> per page; seo.noindex === true excludes a page. full: true also writes <prefix>llms-full.txt – the stored HTML of every page, restricted to <main>, converted with turndown (headings shifted three levels, root-relative links and images made absolute with siteUrl) – and needs "html" in formats; full: false removes a stale llms-full.txt. The result gains llms: { entries, full }. Every Delivery method returns a Result; a failure is an Err(KestrelError), never an exception. A render failure (RENDER_FAILED or TRANSIENT from renderer@1) is not a step failure: it is recorded on the status row as state: "error" with the message and the remaining locales are still published. Only wiring bugs throw (unknown type, unconfigured type, unsafe media/asset path, a media row whose blob is gone).

| Step | reads | writes | codes | |---|---|---|---| | delivery.publish:<type> | result.id | result (document, delivery) | TRANSIENT | | delivery.unpublish:<type> | params.id | – | VALIDATION (missing id), TRANSIENT | | delivery.readStatus:<type> | params.id | result | VALIDATION (missing id), TRANSIENT | | delivery.publishAll:<type> | – | result | TRANSIENT | | delivery.exportLlms | – | result.llms | TRANSIENT |

Not included: sitemap, CDN invalidation.

Internals

Media URL matching. Negative lookaheads pin each match to a segment boundary: /file-x and /fileabc do not match /file, and thumb.webp.bak does not match thumb.webp, while ? and / stay outside the class so a query string or a deeper path segment still terminates a match.

Media paths. Blob keys are built from a path this module sanitizes itself, the same check the renderer-asset branch applies to asset.path, rather than from the stored row as it is.

llms-full.txt. Pages sit at ### under their section heading, so a body's own <h1> starts at ####. The body match is greedy to the last </main>, so a nested <main> does not cut it short, and editor-authored text is escaped: a newline in it would forge a second document line and a leading marker a heading.

Generated from the manifest

@michaelthielemann/kestrel-delivery-static – module delivery/static: provides no contract; requires content@1, renderer@1, blobstore@1, persistence@1, site@1.

| Config | Type | Required | Default | |---|---|---|---| | types | record | yes | – | | formats | array | no | ["html"] | | prefix | string | no | "" | | prefixPrimary | boolean | no | false | | fallback | boolean | no | true | | media | object | no | – | | media.publicPath | string | no | "/media" | | media.collection | string | no | "media_items" | | media.variants | string | no | "images_variants" | | media.target | string | no | "media/" | | llms | object | no | {} | | llms.siteUrl | string | no | – | | llms.full | boolean | no | false | | llms.settings | object | no | {} | | llms.settings.type | string | no | "settings" | | llms.settings.titleField | string | no | "title" | | llms.settings.descriptionField | string | no | "description" | | llms.titleField | string | no | "title" | | llms.seoField | string | no | "seo" | | llms.headings | record | no | {} |

| Step | Summary | Reads | Writes | Input | Output | Errors | |---|---|---|---|---|---|---| | delivery.publish:<arg> | Render and store published locales of a | result.id | result | – | { document?: object, delivery?: object[], … } | – | | delivery.unpublish:<arg> | Remove rendered output of a | params.id | – | – | – | 400 missing id | | delivery.readStatus:<arg> | Publish status per locale of a | params.id | result | – | object[] | 400 missing id | | delivery.publishAll:<arg> | Re-render every | – | result | – | { documents?: number, live?: number, errors?: number, … } | – | | delivery.exportLlms | Write llms.txt (and llms-full.txt when llms.full is set) from the live output of every delivered type (adds llms: { entries, full } to the result) | – | result.llms | – | { llms: object, … } | – |

Pipelines in examples/minimal using these steps:

  • createPage (POST /pages): authn.requireUser → authz.require:pages.write → validate.check:pages.body → validate.sanitize:pages.body → validate.check:pages.body → references.check:pages → content.create:pages → revisions.record:pages → references.index:pages → links.extract:pages → delivery.publish:pages → delivery.exportLlms → events.emit:page.created
  • deletePage (DELETE /pages/:id): authn.requireUser → authz.require:pages.delete → references.guard:pages → content.remove:pages → revisions.remove:pages → references.unindex:pages → links.unextract:pages → delivery.unpublish:pages → delivery.exportLlms → events.emit:page.deleted
  • deletePageTranslation (DELETE /pages/:id/translations/:locale): authn.requireUser → authz.require:pages.write → content.removeTranslation:pages → revisions.removeTranslation:pages → references.index:pages → links.extract:pages → delivery.publish:pages → delivery.exportLlms → events.emit:page.translationRemoved
  • pagePublishStatus (GET /admin/publish-status/pages/:id): authn.requireUser → authz.require:pages.manage → delivery.readStatus:pages
  • publishAllPages (POST /admin/publish-all/pages): authn.requireUser → authz.require:pages.manage → delivery.publishAll:pages → redirects.export → delivery.exportLlms
  • restorePageRevision (POST /admin/pages/:id/revisions/:revisionId/restore): authn.requireUser → authz.require:pages.write → revisions.restore:pages → validate.check:pages.body → validate.sanitize:pages.body → validate.check:pages.body → references.check:pages → content.update:pages → revisions.record:pages → references.index:pages → links.extract:pages → delivery.publish:pages → delivery.exportLlms → revisions.reportRestore → events.emit:page.restored
  • setSettings (PUT /settings): authn.requireUser → authz.require:settings.write → validate.check:settings.navigation → content.set:settings → delivery.exportLlms
  • updatePage (PATCH /pages/:id): authn.requireUser → authz.require:pages.write → validate.check:pages.body → validate.sanitize:pages.body → validate.check:pages.body → references.check:pages → content.update:pages → revisions.record:pages → references.index:pages → links.extract:pages → delivery.publish:pages → delivery.exportLlms → events.emit:page.updated