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-projection

v0.2.0

Published

Browser-safe virtual documents, source projections, and generated-code context for Ravel.

Downloads

19

Readme

@pieceful/ravel-projection

Browser-safe virtual documents, bidirectional source mappings, expansion occurrences, generated-code context, incremental deltas, and composable transform maps for Ravel programs.

The package consumes the public RavelProgram/Deliverable provenance shape from @pieceful/ravel-core. It has no Node, filesystem, process, editor, or language-server dependency, so the same projection can run in an editor host or browser worker.

Projection service

One service owns the current projection snapshot. Supply every target/artifact variant in projections; IDs and pieceful-virtual: URIs remain stable while their monotonically increasing document versions change.

import { createProjectionService } from "@pieceful/ravel-projection";

const projections = createProjectionService({
  workspaceId: "demo",
  projections: [
    {
      targetId: "web",
      artifactId: "dist/app.ts",
      languageId: "typescript",
      stage: "assembled",
    },
  ],
});

const delta = await projections.update({
  id: "snapshot-1",
  program,
  sourceVersions: { "guide.md": 7 },
  sourceTexts: { "guide.md": guideText },
});

const [virtual] = delta.opened;
const generated = projections.toVirtual(
  { uri: "guide.md", offset: 120 },
  {
    targetId: "web",
    artifactId: "dist/app.ts",
    stage: "assembled",
    projectionVersion: virtual.version,
  },
);
const authored = projections.toSource(
  virtual.id,
  { start: 12, end: 18 },
  {
    projectionVersion: virtual.version,
  },
);

update() returns opened, changed, unchanged, and closed documents plus minimal-or-full text changes. scheduleUpdate() supports interactive and background work; a superseding update or AbortSignal prevents a stale build from becoming current. Treat returned virtual documents and deltas as immutable.

Mapping queries return every match because one authored piece can occur in many artifacts or expansion sites. Narrow them with targetId, artifactId, stage, and occurrenceId; use affinity at zero-width boundaries. Invalid or explicitly stale low-level queries return { ok: false, reason, matches: [] } rather than throwing. Service convenience methods return an empty match array for an invalid selection, so callers that need a reason should use the low-level mapSource*/mapVirtual* functions.

Provenance kinds

Each ProjectionSegment describes a generated UTF-16 offset range and its best available authored provenance.

| Kind | Meaning | Reverse-edit status | | ------------- | -------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | | exact | Generated code is character-for-character authored text. Exact subranges are reversible when source and generated lengths agree. | Eligible for policy-controlled edits. | | anchored | Generated text has a responsible invocation, definition, or transform location, but no character correspondence. | Navigation only. | | transformed | A declared offset or source-map transform preserves a character correspondence for this span. | Mappable, but not automatically editable by the current edit policy. | | opaque | A transform supplied no usable mapping; only a responsible anchor may remain. | Navigation only. | | synthetic | The tool inserted text with no authored destination. | Not editable without a separate host policy, such as an imports destination. |

writable: true on a mapping match is necessary, not sufficient, for an automatic source edit. A host must still enforce the stricter policy in @pieceful/ravel-language-service.

Expansion occurrences form a parent/child tree and preserve invocation and definition locations. generatedContext() returns the occurrence breadcrumb, sibling expansions, a bounded visible range, and categorized highlights for a generated-code overlay. It does not infer a unique occurrence when the source appears more than once.

Projection stages

Stages are semantic labels, not an implied build pipeline:

  • authoring: a language-shaped view closest to the authored chunk.
  • assembled: expanded chunks arranged as an artifact; the normal native language-service input.
  • transformed: output after a declared analysis transform.
  • emitted: final generated output. Its default capabilities disable completion and writable edits while retaining navigation and diagnostics.

The other stages default to navigation, diagnostics, completion, and writable mapping support. stageCapabilities() or build options can reduce these capabilities. Do not advertise a later stage if the transform needed to create it executes effects: validateAnalysisTransform() accepts only transforms declared pure, without effects or authorities, and with a valid mapping capability.

Transform authors

Transform helpers are exported from @pieceful/ravel-projection/transforms.

import {
  applyTransformMap,
  createIndentOffsetMap,
} from "@pieceful/ravel-projection/transforms";

const indented = createIndentOffsetMap(assembled.text, 2);
if (!indented.ok) throw new Error(indented.reason);

const transformed = applyTransformMap(assembled, indented.text, indented.map, {
  name: "indent",
  stage: "transformed",
});

Use the narrowest honest mapping capability:

  • identityTransformMap() preserves the input mapping kind.
  • Offset maps use ordered copy, mapped, inserted, and removed spans. Indent, dedent, EOL normalization, offset lookup, and composition helpers are included. A non-identity copied/mapped span becomes transformed; inserted output becomes anchored when transformSource is supplied and synthetic otherwise; removed input has no output range.
  • normalizeSourceMap() decodes a version-3 source map. applyTransformMap() converts matching points into UTF-16 offset spans for one input virtual document. Gaps, foreign sources, and source-map regions without usable points remain unmapped; this is not a proof that arbitrary source-map edits are reversible.
  • opaqueTransformMap() deliberately degrades the entire output to opaque provenance, optionally retaining an anchor. Use it whenever a transform cannot supply a truthful map.

applyTransformMap() rejects invalid maps and maps whose declared input or output lengths do not match the supplied texts. Offset-map composition only works when adjacent map lengths agree. All public offsets are UTF-16 code-unit offsets; createLineIndex(), positionAt(), and offsetAt() provide explicit UTF-8, UTF-16, or UTF-32 line/character conversion for protocol boundaries.

MIT © James Taylor