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/history

v0.0.3

Published

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

Readme

@type-editor/history

A refactored version of ProseMirror's prosemirror-history module, providing undo/redo history functionality for rich text editors.

Installation

npm install @type-editor/history

Overview

This module implements a selective undo/redo history for ProseMirror-based editors. Unlike a simple rollback mechanism, this history is selective, meaning it can undo specific changes while keeping other, later changes intact. This is essential for collaborative editing scenarios where multiple users may be editing simultaneously.

How It Works

ProseMirror's history isn't simply a way to roll back to a previous state, because ProseMirror supports applying changes without adding them to the history (for example during collaboration).

Each history 'Branch' (one for undo, one for redo) maintains an array of 'Items' that can optionally hold a step (an actual undoable change) and always hold a position map (needed to adjust positions for changes below them).

An item that has both a step and a selection bookmark marks the start of an 'event' — a group of changes that will be undone or redone together.

Usage

Basic Setup

import { history, undo, redo } from '@type-editor/history';
import { keymap } from '@type-editor/keymap';
import { EditorState } from '@type-editor/state';

const state = EditorState.create({
  schema,
  plugins: [
    history(),
    keymap({
      'Mod-z': undo,
      'Mod-Shift-z': redo
    })
  ]
});

Configuration Options

The history() plugin accepts an optional configuration object:

history({
  depth: 100,        // Maximum number of history events (default: 100)
  newGroupDelay: 500 // Delay in ms before starting a new group (default: 500)
});

| Option | Type | Default | Description | |-----------------|----------|---------|-------------------------------------------------------------------------------------------------------------------------------------------------------| | depth | number | 100 | The number of history events to keep before the oldest events are discarded | | newGroupDelay | number | 500 | The delay in milliseconds between changes after which a new history group should be started. Adjacent changes within this delay are grouped together. |

Commands

Undo Commands

| Command | Description | |----------------|----------------------------------------------------------------------------------------------| | undo | Undoes the last change and scrolls the selection into view. Typically bound to Mod-z. | | undoNoScroll | Undoes the last change without scrolling. Useful when you want to handle scrolling manually. |

Redo Commands

| Command | Description | |----------------|------------------------------------------------------------------------------------------------------------------------------| | redo | Redoes the last undone change and scrolls the selection into view. Typically bound to Mod-Shift-z (or Mod-y on Windows). | | redoNoScroll | Redoes the last undone change without scrolling. |

Example

import { undo, redo, undoNoScroll, redoNoScroll } from '@type-editor/history';
import { keymap } from '@type-editor/keymap';

const historyKeymap = keymap({
  'Mod-z': undo,
  'Mod-Shift-z': redo,
  'Mod-y': redo // Alternative redo binding for Windows
});

Helper Functions

undoDepth

Returns the number of undoable events available in the editor's history.

import { undoDepth } from '@type-editor/history';

const canUndo = undoDepth(state) > 0;
console.log(`You can undo ${undoDepth(state)} changes`);

redoDepth

Returns the number of redoable events available in the editor's history.

import { redoDepth } from '@type-editor/history';

const canRedo = redoDepth(state) > 0;
console.log(`You can redo ${redoDepth(state)} changes`);

closeHistory

Forces subsequent changes to be recorded as a separate history event, preventing them from being merged with the previous event.

import { closeHistory } from '@type-editor/history';

// Force the next change to start a new history event
const tr = closeHistory(state.tr);
dispatch(tr.insertText('new text'));

isHistoryTransaction

Returns true if the given transaction was generated by the history plugin (i.e., an undo or redo operation).

import { isHistoryTransaction } from '@type-editor/history';

// In a plugin's appendTransaction
appendTransaction(transactions, oldState, newState) {
  if (transactions.some(isHistoryTransaction)) {
    // Handle undo/redo transactions differently
  }
}

Controlling History

Preventing Changes from Being Recorded

You can prevent a transaction from being added to the history by setting the addToHistory metadata to false:

const tr = state.tr.insertText('text').setMeta('addToHistory', false);
dispatch(tr);

This is useful for:

  • Collaborative changes from other users
  • UI state changes that shouldn't be undoable
  • Decorations or annotations

Grouping Changes

Changes made within the newGroupDelay window (default 500ms) are automatically grouped together as a single undo event. You can force a new group to start by using closeHistory:

import { closeHistory } from '@type-editor/history';

// First change
dispatch(state.tr.insertText('Hello'));

// Force next change to be a separate event
dispatch(closeHistory(state.tr));

// This will be a separate undo event
dispatch(state.tr.insertText(' World'));

API Reference

Exports

| Export | Type | Description | |------------------------|------------|--------------------------------------| | history | function | Creates the history plugin | | undo | Command | Undo command with scroll | | undoNoScroll | Command | Undo command without scroll | | redo | Command | Redo command with scroll | | redoNoScroll | Command | Redo command without scroll | | undoDepth | function | Get number of undo events | | redoDepth | function | Get number of redo events | | closeHistory | function | Close current history event | | isHistoryTransaction | function | Check if transaction is from history | | HistoryState | class | The history state class | | HistoryOptions | type | Configuration options interface | | mustPreserveItems | function | Check if items should be preserved |

License

MIT