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

@plurnk/plurnk-schemes

v0.31.4

Published

Framework + contract for the @plurnk/plurnk-schemes-* URI handler family.

Readme

plurnk-schemes

Framework + contract for @plurnk/plurnk-schemes-* URI handler packages. Consumed by plurnk-service.

Documentation

Write a scheme

Ship a scheme by publishing a package — under any scope (@acme/whatever; discovery keys on plurnk.kind, not the @plurnk scope) — that declares itself and default-exports a SchemeHandler. Install it and it lights up; there is no first-party allow-list (scope-agnostic discovery, SPEC §6).

1. Declare in package.json

{
  "plurnk": { "kind": "scheme", "name": "foo" }
}

plurnk.name is the URI prefix you claim (foo://…). The consumer's scope-agnostic node_modules scan registers you by it; two packages claiming one prefix fail-hard.

2. Default-export a SchemeHandler

import type {
  SchemeHandler, SchemeManifest, SchemeCtx, SchemeResult, ReadStatement,
} from "@plurnk/plurnk-schemes";

export default class Foo implements SchemeHandler {
  static manifest: SchemeManifest = { /* step 3 */ };

  async read(statement: ReadStatement, ctx: SchemeCtx): Promise<SchemeResult> {
    /* … reach the substrate ONLY through ctx capabilities (SPEC §3.bis, §5) … */
  }
}

Implement only the op methods you support — read / find / edit / copy / move / send / … — all optional; the engine calls handler[op.toLowerCase()](statement, ctx) and returns 501 for any op you omit. implements SchemeHandler gives you compile-time signature checking. The statement + path types (ReadStatement, SendStatement, UrlPath, …) are re-exported from this package, so you depend on and exact-pin only @plurnk/plurnk-schemes — grammar rides underneath.

3. Declare the manifest — including self-doc

import { readFile } from "node:fs/promises";

// Deep doc lives in docs/foo.md (convention); loaded at module init.
const documentation = await readFile(new URL("../docs/foo.md", import.meta.url), "utf-8");

static manifest: SchemeManifest = {
  name: "foo",
  channels: { body: "text/markdown" },
  defaultChannel: "body",
  category: "data",
  scope: "session",
  writableBy: ["model", "client"],
  volatile: false,
  modelVisible: true,
  glyph: "🦊",                          // display icon; omit → the name is shown
  example: "READ(foo://thing/42)",      // terse hot-path one-liner, rendered every turn
  documentation,                        // deep doc from docs/foo.md, pulled at plurnk://docs/foo.md
};
  • example — the scheme's terse hot-path one-liner, rendered in the live catalogue every turn (like an execs runtime's example). Keep it to one canonical usage line; depth goes in documentation. Omit → not advertised.
  • documentation — the deep doc (ops, channels, edge cases). The consumer materializes it as a pull-able plurnk://docs/<name>.md entry the model READs on demand — off the hot path. Mirrors ExecInfo.documentation. Convention: keep it in a docs/<name>.md file (root) and load it at module init with the snippet above — ../ resolves the same from src/ (test) and dist/ (built); add docs/**/* to files. A missing file fails-hard at import.
  • glyph — a display icon (emoji / nerdfont). Omit it and the scheme name is rendered in its place.

4. Self-doc: terse pushes, depth pulls

example/glyph render every turn — keep them terse. documentation is the deep prose; the consumer materializes it at plurnk://docs/<name>.md for the model to READ on demand. Don't dump prose into example (it floods the hot path) — put it in documentation.

That's the whole contract: declare, implements SchemeHandler, manifest with self-doc. Publish, install, discovered.

Exports

Types

  • Manifest/flags: SchemeManifest (incl. example / documentation / glyph self-doc), SchemeFlagAffinity, WriterTier, LoopFlags, DEFAULT_LOOP_FLAGS.
  • Behavior contract: SchemeHandler + optional PacketSectionTransformer (PacketSection); the re-exported scheme-facing grammar types (PlurnkStatement + per-op statements + ParsedPath / LocalPath / UrlPath).
  • Result families: SchemeResult / EntryResult / ProposalResult / PassthroughResult / SchemeResultBase / TelemetryEvent.
  • Capability ctx: SchemeCtx + EntryCaps / ChannelCaps / TagCaps / NotifyCaps / SubscriptionCaps / CrossSchemeCaps, plus EntryData / ChannelState / SubscriptionHandle / ProposalAware.

Helpers (export default class, static methods)

  • SchemeResolver.forLoop(handlers, flags) — active-scheme resolution under loop flags.
  • MimetypeClassifier.isBinary / .isLineNavigable / .isJson / .normalizeAutoText (+ TEXT_PRIMITIVE_MIMETYPE named export) — mimetype classification.
  • Slicer.lines / .linesRaw / .jsonItems / .lineMarkerEdit / .jsonItemEdit<L> slicing + structural EDIT.
  • PathMimetype.resolve(pathname, default, mimetypes) — path-extension mimetype resolver.
  • Matcher.matchAgainstContent(body, content, mimetype, mimetypes, baseLine?) — body-matcher dispatch over Mimetypes.query (glob/regex/jsonpath/xpath).
  • Results.error / .logCoordinate / .isEntry / .isProposal / .isPassthrough / .isErrorStatus — result builders + guards.
  • SchemeDiscovery.discover({ cwd? }) — scope-agnostic node_modules scan for plurnk.kind:"scheme" packages (trust-gated, fail-hard on prefix collision); returns descriptors for the consumer to register (SPEC §6).

The capability ctx (SchemeCtx) is the DB-free authoring surface for siblings — interfaces only; plurnk-service injects the db-backed impl (see SPEC §3.bis). The db-backed implementations themselves (CRUD primitives, entry-op handlers, channel writes, subscription registry) stay in plurnk-service.

Tests

test:lint, test:unit.