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

@mercury-fx/schema

v3.0.0

Published

Mercury documents — the portable, versioned, JSON-safe page format: block schemas, validation with declared limits, atomic commands and migrations. No React, no Effector, no DOM handles.

Readme

@mercury-fx/schema

The portable document format of the Mercury design system: versioned, JSON-safe page data with block schemas, validation at declared limits, and one command layer that applies edits atomically or refuses them. No React, no Effector, no DOM: a renderer, an editor and a server read the same documents. The contract is the AUS mercury.20.

import { applyCommand, createSchemaRegistry, parseDocument } from "@mercury-fx/schema";

const registry = createSchemaRegistry({
  blocks: [
    { type: "section", version: 1, props: {}, slots: { content: {} } },
    { type: "heading", version: 1, props: { text: { kind: "string" }, level: { kind: "number", integer: true, min: 1, max: 6 } } },
  ],
});

const parsed = parseDocument(jsonText, registry); // { ok: true, document } or { ok: false, code, path, reason }
if (parsed.ok) {
  const result = applyCommand(
    { document: parsed.document, revision: 0 },
    { kind: "set-properties", expectedRevision: 0, node: "title", props: { level: 2 } },
    { registry },
  ); // { ok: true, local: { document, revision: 1 }, impact } or a refusal; the input is unchanged
}
  • Document: format, id, kind (page, fragment, template), ordered roots and a flat nodes map. A node has id, type, version, JSON props and named slots of child IDs. Fields the format does not name are kept as they are.
  • Refusals share one shape: a typed code, a JSON Pointer path in its URI-fragment form (#/…, percent-encoded), a reason, the subject the path points into (document, command or state) and, when there is one, the node. Parsing, commands and migration never return a partial document, and hostile input (a throwing getter, a revoked proxy) is refused, not thrown.
  • Commands: insert, remove, move, duplicate and set-properties, each against an expected local revision. Duplicate mints fresh node IDs and keeps references. An edit to a fragment reports every document that references it.
  • Limits (maxDepth, maxBytes, maxNodes, maxPropDepth) are declared per registry and hold for every result: an edit or a migration that would outgrow them is refused. maxBytes counts the document's compact JSON, so whitespace never changes a verdict.
  • Tokens: a token prop admits only a name from a set the registry declares (tokens).
  • Migration: migrateDocument steps older block versions forward through each definition's deterministic migrations, on a copy; a refusal hands back the untouched original, and a step that drops data needs { allowLossy: true }. Format 1 is the first portable format.
  • Unknown blocks (an unregistered type or a newer version) are kept unchanged through parsing, edits elsewhere, saves and migration, their slots included; inspectDocument reports them unsupported.
  • References ({ "$ref": "asset" | "route" | "entity" | "fragment", "id" }, plus any JSON fields a later version adds) resolve beside the document with resolveReferences; an unauthorized target keeps only its identity. indexConsumers follows fragments inside fragments.
  • Responsive values ({ "$responsive": { "base", "overrides" } }) keep absent, explicit and removed ({ "$removed": true }) distinct; resolveResponsive reads one width and writes nothing.

Client validation helps authors; the host still authorizes every change on its server.