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

@open-ot/core

v0.3.0

Published

The foundational package for OpenOT, providing the core interfaces and built-in OT types.

Readme

@open-ot/core

The foundational package for OpenOT, providing the core interfaces and built-in OT types.

Overview

@open-ot/core defines the OTType interface, which is the contract for implementing Operational Transformation on any data structure. It also includes production-ready implementations for Text and JSON types.

Installation

npm install @open-ot/core

What's Included

Core Interfaces

OTType<Snapshot, Op>

The fundamental interface that defines how to synchronize a data structure:

interface OTType<Snapshot, Op> {
  name: string;
  create(): Snapshot;
  apply(snapshot: Snapshot, op: Op): Snapshot;
  transform(opA: Op, opB: Op, side: 'left' | 'right'): Op;
  compose(opA: Op, opB: Op): Op;
  invert?(op: Op): Op; // Optional
}
  • name: Unique identifier for the type (e.g., "text", "json").
  • create(): Returns the initial empty state.
  • apply(snapshot, op): Applies an operation to a snapshot, producing a new snapshot.
  • transform(opA, opB, side): Transforms opA to apply after opB. The side parameter handles tie-breaking for concurrent inserts.
  • compose(opA, opB): Merges two consecutive operations into a single efficient operation.
  • invert(op): (Optional) Generates an operation that undoes the given operation.

TransportAdapter<TMessage>

Defines the interface for network communication:

interface TransportAdapter<TMessage = unknown> {
  connect(onReceive: (msg: TMessage) => void): Promise<void>;
  send(msg: TMessage): Promise<void>;
  disconnect(): Promise<void>;
}

Built-in Types

TextType

A production-ready OT implementation for plain text using Retain/Insert/Delete operations.

Operation Format:

type TextOperation = Array<
  | { r: number }      // Retain n characters
  | { i: string }      // Insert string
  | { d: number }      // Delete n characters
>;

Example:

import { TextType } from '@open-ot/core';

const snapshot = "Hello World";
const op = [
  { r: 6 },           // Retain "Hello "
  { i: "Beautiful " }, // Insert "Beautiful "
  { r: 5 }            // Retain "World"
];

const result = TextType.apply(snapshot, op);
// => "Hello Beautiful World"

Features:

  • Efficient composition and transformation
  • Handles concurrent edits with tie-breaking
  • Normalizes operations to minimize size
  • Validates operations for correctness

JsonType

A wrapper around the battle-tested ot-json1 library for collaborative JSON editing.

Example:

import { JsonType } from '@open-ot/core';

const snapshot = { users: ["Alice"] };
const op = [
  { p: ["users", 1], li: "Bob" } // Insert "Bob" at index 1
];

const result = JsonType.apply(snapshot, op);
// => { users: ["Alice", "Bob"] }

Advanced: Custom JSON Type with Hooks

You can create a custom JSON type with semantic validation:

import { createJsonType } from '@open-ot/core';

const CustomJsonType = createJsonType({
  validate: (op, doc) => {
    // Reject operations that violate your schema
    return isValidSchema(doc);
  },
  normalize: (doc) => {
    // Post-process the document after applying an operation
    return sortKeys(doc);
  }
});

Creating Your Own Type

To synchronize a custom data structure, implement the OTType interface:

import { OTType } from '@open-ot/core';

interface MySnapshot {
  // Your data structure
}

type MyOp = {
  // Your operation format
};

export const MyCustomType: OTType<MySnapshot, MyOp> = {
  name: 'my-custom-type',
  
  create() {
    return { /* initial state */ };
  },
  
  apply(snapshot, op) {
    // Apply the operation to the snapshot
    return newSnapshot;
  },
  
  transform(opA, opB, side) {
    // Transform opA to apply after opB
    return transformedOpA;
  },
  
  compose(opA, opB) {
    // Merge two consecutive operations
    return composedOp;
  }
};

Use Cases

  • Text Editors: Use TextType for collaborative plain text editing.
  • Rich Text Editors: Serialize ProseMirror/Lexical state to JSON and use JsonType.
  • Configuration Tools: Sync JSON configuration files in real-time.
  • Custom Data Structures: Implement your own OTType for domain-specific collaboration (e.g., whiteboards, spreadsheets).

API Reference

TextType

  • TextType.create()""
  • TextType.apply(snapshot, op)string
  • TextType.transform(opA, opB, side)TextOperation
  • TextType.compose(opA, opB)TextOperation

Helpers:

  • isInsert(op), isRetain(op), isDelete(op) — Type guards
  • getLength(op) — Get the length of an operation component
  • normalize(op) — Merge consecutive operations of the same type
  • checkOp(op) — Validate operation structure

JsonType

  • JsonType.create()null
  • JsonType.apply(snapshot, op)json1.Doc
  • JsonType.transform(opA, opB, side)JsonOp
  • JsonType.compose(opA, opB)JsonOp

For detailed JSON operation syntax, see the ot-json1 documentation.

License

MIT