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

@pieceful/ravel-explorer

v0.2.0

Published

Portable focused graph projections and host contracts for Ravel Explorer.

Readme

@pieceful/ravel-explorer

This allows for visual exploration of the graphs generated by Ravel.

npm install @pieceful/ravel-explorer

Use the default entry point to create a bounded, serializable projection of a completed program. Import ./browser only in the UI that renders it; that entry point adds Cytoscape and ELK for interactive layout.

The package turns a completed RavelProgram plus optional pretransform and live execution context into a deterministic, bounded ExplorerSnapshot. It does not read files, execute transforms, write source, or depend on VS Code.

import { createExplorerSnapshot } from "@pieceful/ravel-explorer";

const snapshot = createExplorerSnapshot(
  {
    program,
    pretransform,
    livePlan,
    revision: "editor-buffer-42",
  },
  {
    focus: ["guide::main"],
    upstream: 3,
    downstream: 1,
    maxNodes: 500,
  },
);

Dependency and value-flow edges point from producer to consumer. Source composition uses references; live JSON-value dependencies use consumes. This distinction is intentionally preserved.

Stable identities

Explorer identities are deterministic within snapshot version 1:

  • documents: document:<document-id>;
  • chunks: chunk:<canonical-chunk-id>;
  • deliverables: deliverable:<output-name>;
  • definition transforms: transform:<chunk-id>:<zero-based-phase>:<name>;
  • directives: directive kind, authored source span, and stable directive index;
  • compose steps: their directive identity and ordered path inside the compose tree;
  • ordinary edges: a stable fingerprint of kind, endpoints, authored source span, phase, and label;
  • collapsed boundary edges: a stable fingerprint of kind and visible endpoints.

An explicit host revision identifies the evaluated editor overlay. Without one, the package derives a deterministic revision from graph, output, provenance, diagnostic, and live-plan data. Hosts should supply their own revision whenever they need concurrency control for edit proposals.

The default entry point contains the model and projection foundation. The ./browser entry point adapts snapshots to Cytoscape.js and ELK without changing this contract:

import { createExplorerView } from "@pieceful/ravel-explorer/browser";

const view = createExplorerView(document.querySelector("#graph"), snapshot, {
  onSelect(entity) {
    host.postMessage({ type: "entity/select", entity });
  },
});

await view.ready;

For a browser application, defer the renderer until the user opens a graph view so the layout engine stays out of the initial bundle:

const { createExplorerView } = await import("@pieceful/ravel-explorer/browser");
const view = createExplorerView(container, snapshot, {
  onSelect: (entity) => revealSource(entity.source),
});
await view.ready;
view.fit();

The Explorer is read-only. It neither loads a project nor evaluates code: the embedding host supplies a completed RavelProgram, owns source navigation, and chooses any later edit workflow.

Chunk bodies and evaluated values are intentionally not embedded in every snapshot. Hosts can request bounded details after selection:

import { createExplorerEntityDetails } from "@pieceful/ravel-explorer";

const details = createExplorerEntityDetails(
  { program, pretransform, revision },
  selectedEntityId,
);

For authored chunks, details.authored is the adapter's pre-transform body and details.evaluated is the current completed value. Deliverables expose their generated value. Selecting a definition transform returns the owning chunk's before/after text; directive and compose selections return the generated chunk or output when one exists. Each text field reports its full length and whether the returned preview was truncated.

Generated deliverables have a separate bounded provenance projection. It sends only the visible output prefix and segment summaries, then explains one selected UTF-16 generated offset on demand:

import { createExplorerOutputDetails } from "@pieceful/ravel-explorer";

const output = createExplorerOutputDetails(context, "deliverable:dist/app.js", {
  generatedOffset: 218,
  maxTextLength: 20_000,
  maxSegments: 1_000,
});

The explanation identifies exact character correspondence or honest coarse attribution, the defining chunk, retained origins, derivation steps, and the dependency path.

Reverse queries are bounded separately from visible graph state:

const occurrences = createExplorerGeneratedMatches(context, sourceSelection, {
  maxMatches: 500,
});

A cursor queries one source offset; a nonempty source selection queries and clips the corresponding generated ranges across every deliverable.

Folding remains a projection operation so collapsed boundary edges retain Ravel edge kinds and counts. The renderer does not depend on the unmaintained Cytoscape expand/collapse extension.

Saved and candidate revisions can also be projected as one change graph:

import {
  createExplorerChangeSnapshot,
  diffExplorerSnapshots,
} from "@pieceful/ravel-explorer";

const diff = diffExplorerSnapshots(saved, candidate);
const changes = createExplorerChangeSnapshot(saved, candidate, diff);

Candidate entities are marked added or changed; saved-only entities remain selectable and are marked removed. The browser renderer gives those states distinct green, amber, and dashed-red treatments.

FizzBuzz browser harness

From the repository root:

npm run build:explorer-demo
python3 -m http.server 4173 --directory browser-test

Open http://localhost:4173/explorer.html. The build derives the snapshot from the real migration project; the browser never reads the workspace or runs a transform.