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

@type-editor/transform

v0.0.3

Published

This is a refactored version of the ProseMirror's 'transform' module. Original: https://github.com/ProseMirror/prosemirror-transform

Readme

@type-editor/transform

This is a refactored version of the prosemirror-transform module.

This module implements document transformations, which are used by the editor to treat changes as first-class values that can be saved, shared, and reasoned about.

Installation

npm install @type-editor/transform

Overview

The transform module defines a way of modifying documents that allows changes to be recorded, replayed, and reordered. Transformations happen in atomic units called "steps", which can be applied, inverted, and mapped between document versions.

This is essential for:

  • Undo/Redo history - Steps can be inverted to undo changes
  • Collaborative editing - Steps can be rebased and merged
  • Change tracking - All modifications are recorded as discrete operations

Steps

Transforming happens in Steps, which are atomic, well-defined modifications to a document. Applying a step produces a new document.

Each step provides a change map that maps positions in the old document to positions in the transformed document. Steps can be inverted to create a step that undoes their effect, and chained together in a convenience object called a Transform.

@Step @StepResult

Step Types

The module provides several built-in step types:

@ReplaceStep @ReplaceAroundStep @AddMarkStep @RemoveMarkStep @AddNodeMarkStep @RemoveNodeMarkStep @AttrStep @DocAttrStep

Position Mapping

Mapping positions from one document to another by running through the step maps produced by steps is an important operation. It is used, for example, for updating the selection when the document changes.

Document Transforms

Because you often need to collect a number of steps together to effect a composite change, the module provides the Transform abstraction to make this easy. State transactions are a subclass of transforms.

Transform Methods

The Transform class provides methods for common document modifications:

  • Content replacement: replace, replaceWith, delete, insert
  • Mark operations: addMark, removeMark, addNodeMark, removeNodeMark
  • Block changes: setBlockType, setNodeMarkup, split, join, wrap, lift
  • Attribute changes: setNodeAttribute, setDocAttribute

Helper Functions

The following helper functions can be useful when creating transformations or determining whether they are even possible.

@replaceStep @liftTarget @findWrapping @canSplit @canJoin @joinPoint @insertPoint @dropPoint

Usage Example

import { Transform, ReplaceStep, StepMap, Mapping } from '@type-editor/transform';
import { Node, Slice } from '@type-editor/model';

// Create a transform from a document
const tr = new Transform(doc);

// Apply changes using the fluent API
tr.delete(0, 5)
  .insertText("Hello", 0)
  .addMark(0, 5, schema.marks.bold.create());

// Check if document changed
if (tr.docChanged) {
  const newDoc = tr.doc;
  const steps = tr.steps;
  const mapping = tr.mapping;
}

// Map positions through changes
const newPos = tr.mapping.map(originalPos);

API Reference

Transform

The main class for building document transformations:

class Transform {
  doc: PmNode;              // The current (transformed) document
  steps: Step[];            // All applied steps
  docs: PmNode[];           // Document state before each step
  mapping: Mapping;         // Combined position mapping
  before: PmNode;           // The starting document
  docChanged: boolean;      // Whether any steps were applied
  
  step(step: Step): this;           // Apply a step (throws on failure)
  maybeStep(step: Step): StepResult; // Apply a step (returns result)
}

Step

The base class for all atomic document changes:

abstract class Step {
  apply(doc: PmNode): StepResult;   // Apply to a document
  invert(doc: PmNode): Step;        // Create inverse step
  map(mapping: Mappable): Step | null; // Map through position changes
  getMap(): StepMap;                // Get the position map
  toJSON(): object;                 // Serialize to JSON
  
  static fromJSON(schema, json): Step; // Deserialize from JSON
  static registerStep(id, class): void; // Register custom step type
}

StepMap

Maps positions through a single step's changes:

class StepMap {
  map(pos: number, assoc?: number): number;
  mapResult(pos: number, assoc?: number): MapResult;
  invert(): StepMap;
  
  static empty: StepMap;            // Empty (no-op) map
  static offset(n: number): StepMap; // Offset all positions
}

Mapping

A pipeline of step maps for multi-step transformations:

class Mapping {
  maps: StepMap[];          // The step maps in sequence
  
  map(pos: number, assoc?: number): number;
  mapResult(pos: number, assoc?: number): MapResult;
  appendMap(map: StepMap, mirrors?: number): void;
  appendMapping(mapping: Mapping): void;
  slice(from?: number, to?: number): Mapping;
}

License

MIT