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

@metanorma/mirror

v0.1.1

Published

TypeScript library and Vue components for the Metanorma Mirror document format

Readme

@metanorma/mirror

TypeScript library and optional Vue 3 components for the Metanorma Mirror document format — a JSON tree representation of standards documents (clauses, terms, tables, formulas, lists, etc.).

The library is framework-agnostic. The Vue layer is opt-in via a separate subpath export.

Install

npm install @metanorma/mirror

For the Vue components, Vue 3 (>=3.4) is a peer dependency:

npm install @metanorma/mirror vue

Entry points

| Subpath | Description | | --- | --- | | @metanorma/mirror | Core types, traversal, mark registry, math helpers | | @metanorma/mirror/vue | <MirrorNode> and <MirrorText> Vue 3 components |

Core usage

import {
  buildToc,
  findNodes,
  getNodeText,
  type MirrorDocument,
} from '@metanorma/mirror'

const doc: MirrorDocument = {
  type: 'doc',
  content: [
    {
      type: 'clause',
      attrs: { id: 'scope', title: 'Scope', number: '1' },
      content: [
        {
          type: 'paragraph',
          content: [
            { type: 'text', text: 'Hello ' },
            { type: 'text', text: 'world', marks: [{ type: 'strong' }] },
          ],
        },
      ],
    },
  ],
}

buildToc(doc)
// => [{ id: 'scope', title: '1 Scope', depth: 0 }]

findNodes(doc, n => n.type === 'paragraph').length
// => 1

getNodeText(doc)
// => 'Hello world'

Mark registry

Inline marks (strong, emphasis, link, xref, footnote, stem, …) are resolved through a registry. Built-ins can be overridden and custom marks can be added via registerMark:

import { registerMark, resolveMark } from '@metanorma/mirror'

registerMark('highlight', { tag: 'mark', classes: 'hl' })
resolveMark({ type: 'highlight' })
// => { tag: 'mark', classes: 'hl' }

getMarkHref extracts the URL from link and xref marks (reads attrs.target, falls back to attrs.href for link).

Math formulas

Formula nodes may carry pre-computed MathML in attrs.mathml, or AsciiMath in attrs.asciimath / attrs.math_text. renderFormula returns MathML when available, otherwise lazily converts AsciiMath → MathML via @plurimath/plurimath, falling back to the raw AsciiMath string if conversion fails.

import { renderFormula } from '@metanorma/mirror'

await renderFormula({ type: 'formula', attrs: { asciimath: 'E = mc^2' } })

Vue usage

<script setup lang="ts">
import { MirrorNode } from '@metanorma/mirror/vue'
import type { MirrorDocument } from '@metanorma/mirror'

const doc: MirrorDocument = /* … */
</script>

<template>
  <MirrorNode :node="doc" :depth="0" />
</template>

<MirrorNode> walks the node tree recursively and emits semantic HTML with mirror-<type> class names (e.g. mirror-paragraph, mirror-section, mirror-table). <MirrorText> renders a text node with the first matching mark as the appropriate HTML element (<strong>, <em>, <a>, <sub>, <sup>, etc.).

CSS is intentionally not bundled — apply your own styles to the .mirror-* classes, or override the component templates.

Node model

Every node shares the shape { type, attrs?, content?, marks?, text? }. Node types are partitioned into disjoint categories exported from the core:

  • STRUCTURAL_TYPESdoc, preface, sections, bibliography
  • SECTION_TYPESclause, annex, terms, definitions, references, …
  • BLOCK_TYPESparagraph, note, admonition, example, quote, formula, sourcecode, review
  • LIST_TYPES, TABLE_TYPES, MEDIA_TYPES, FOOTNOTE_TYPES, LEAF_TYPES

SECTION_TYPES is used by buildToc to decide which nodes become TOC entries.

Development

npm install
npm run build          # vite build → dist + .d.ts via vite-plugin-dts
npm run lint           # eslint
npm test               # vitest unit tests
npm run test:e2e       # puppeteer e2e
npm run test:all       # both suites

Requires Node.js 20+.

Releases

Releases are automated through .github/workflows/release.yml. A v* tag push, or a workflow_dispatch run with a version input, runs npm publish --provenance --access public --tag <dist-tag> and creates a GitHub release. The dist-tag is derived from the version (0.1.0latest, 0.1.0-beta.1beta, 0.9.0-rc.2rc).

Publishing uses npm's Trusted Publisher (OIDC) — no NPM_TOKEN secret is required. The npm package lists this repository's release.yml workflow as a Trusted Publisher, and the workflow carries permissions.id-token: write, which is what npm's OIDC exchange needs.

License

BSD-3-Clause — see LICENSE.