---
title: "Types"
description: "TypeScript type definitions for the Tiptap Compare package."
canonical_url: "https://tiptap.dev/docs/compare/api-reference/types"
---

# Types

TypeScript type definitions for the Tiptap Compare package.

The Compare package exports TypeScript types for working with changesets, changes, diff suggestions, document history, and serialized schemas. Parameter interfaces for utilities and commands are documented alongside their respective APIs.

## `TrackedChangeMetadata`

Metadata stored on a tracked change created from a changeset.

```ts
interface TrackedChangeMetadata extends ChangeMetadata {
  id: string
  type: 'add' | 'delete' | 'replace' | 'markChange'
  userId: string | null
  createdAt: string | null
  updatedAt: string | null
  userMetadata: unknown
  markChanges?: TrackedChangeMarkMutation[]
}
```

`TrackedChangeMarkMutation` describes a formatting change with `operation` (`'added' | 'removed'`), `markName`, and `markAttrs`.

## `TrackedChangeData`

Pairs the metadata for an encoded tracked change with its range in the generated document.

```ts
interface TrackedChangeData {
  metadata: TrackedChangeMetadata
  range: Range
}
```

## `TrackedChangesDocumentFactoryResult`

The result returned by `TrackedChangesDocumentFactory.fromChangeset`.

```ts
interface TrackedChangesDocumentFactoryResult {
  doc: JSONContent
  trackedChanges: TrackedChangeData[]
}
```

## `JSONFragment`

A JSON representation of a ProseMirror fragment.

```ts
type JSONFragment = JSONContent[] | null
```

## `ChangesetJSON`

JSON-serializable representation of a `Changeset`.

```ts
interface ChangesetJSON {
  fragmentA: JSONFragment
  fragmentB: JSONFragment
  changes: Change[]
}
```

## `ChangeMetadata`

Arbitrary metadata attached to a change or document step.

```ts
/**
 * Arbitrary non-null metadata attached to a step.
 *
 * The metadata is treated as a shallow object when comparing adjacent steps.
 */
type ChangeMetadata = Record<string, unknown>
```

## `Change`

Represents one difference between two documents.

```ts
/**
 * Represents a single change between two documents.
 */
interface Change {
  /** The range in the original document (`docA`) that changed. */
  rangeA: Range
  /** The matching range in the changed document (`docB`). */
  rangeB: Range
  /** The content scope. Default: `'inline'`. */
  scope?: ChangeScope
  /** Whether multiple inline changes were grouped into one block-level change. */
  isInlineGroup?: boolean
  /** Metadata associated with the step that produced this change. */
  metadata?: ChangeMetadata
  /** Later changes contained inside this change. */
  nestedChanges?: NestedChange[]
}
```

## `ChangeScope`

Whether a change covers inline or block content.

```ts
type ChangeScope = 'inline' | 'block'
```

## `NestedChange`

Later change contained in a parent `Change`. Its range is an absolute position in the final document (`docB`).

```ts
interface NestedChange {
  range: Range
  metadata: ChangeMetadata
  scope: ChangeScope
}
```

## `DiffOptions`

Controls how document and fragment comparisons are calculated.

```ts
/** Options that control filtering and diff behavior. */
type DiffOptions = {
  /** Simplify nearby changes in inline mode. Default: `false`. */
  simplifyChanges?: boolean
  /** Attributes to remove before comparison. Default: `['id', 'data-thread-id', '_hash']`. */
  ignoreAttributes?: string[]
  /** Marks to remove before comparison. Default: `['inlineThread']`. */
  ignoreMarks?: string[]
  /** Node types to unwrap or remove before comparison. */
  ignoreNodes?: string[]
  /** Minimum unchanged range that separates changes. Default: `5`. */
  changeMergeDistance?: number | null
  /** Threshold for grouping inline changes into a block-level change in smart mode. Default: `2`. */
  groupInlineChanges?: number
  /** Comparison mode. Default: `'smart'`. */
  mode?: 'inline' | 'block' | 'smart'
  /** Node types whose full inline changes should become block changes. */
  expandBlockChanges?: string[]
}
```

## `DiffSuggestion`

Represents a proposed replacement displayed in the editor.

```ts
/** A proposed change to a range of editor content. */
interface DiffSuggestion {
  /** A unique identifier for the suggestion. */
  id: string
  /** The range of editor content affected by the suggestion. */
  range: Range
  /** The replacement content. */
  content: Slice
  /** Optional custom metadata. */
  metadata?: Record<string, any>
  /** Options for rendering the suggestion. */
  displayOptions?: DisplayOptions
  /** Whether the suggestion groups multiple inline changes. */
  isInlineGroup?: boolean
  /** A range that can be mapped through document transactions. */
  mappableRange?: MappableRange
  /** Informational changes displayed inside this suggestion. */
  nestedChanges?: DiffSuggestionNestedChange[]
}
```

## `DiffSuggestionNestedChange`

A nested change contained inside a diff suggestion.

```ts
interface DiffSuggestionNestedChange extends NestedChange {
  mappableRange?: MappableRange
}
```

## `DisplayOptions`

Controls the default rendering of a diff suggestion.

```ts
/** Options for how to display a diff suggestion in the editor. */
interface DisplayOptions {
  /** Whether to show replacement content. Default: `true`. */
  showReplacement?: boolean
  /** Whether to show sub-changes in inline groups. Default: `true`. */
  showSubChanges?: boolean
  /** Extra HTML attributes for the original-content decoration. */
  attributes?: Record<string, any>
  /** Extra HTML attributes for the replacement decoration. */
  replacementAttributes?: Record<string, any>
  /** Extra HTML attributes for inline sub-change decorations. */
  subChangeAttributes?: Record<string, any>
  /** Extra HTML attributes for sub-changes inside replacement content. */
  replacementSubChangeAttributes?: Record<string, any>
  /** Returns HTML attributes for an explicit nested change. */
  getNestedChangeAttributes?: (options: NestedChangeAttributesOptions) => Record<string, string>
  /** A function that renders the suggestion as ProseMirror decorations. */
  renderDecorations?: RenderDecorations
}
```

`getNestedChangeAttributes` receives the nested change, its actionable parent suggestion, and whether that parent is selected. If it returns a `class`, Compare appends it to the default nested-change classes.

```ts
interface NestedChangeAttributesOptions {
  nestedChange: DiffSuggestionNestedChange
  suggestion: DiffSuggestion
  isSelected: boolean
}
```

## Custom decoration rendering

Use these types with `DisplayOptions.renderDecorations` to replace or adjust the default rendering.

```ts
/** Options passed to `defaultRenderDecorations`. */
interface DefaultRenderDecorationsOptions {
  /** Whether to render the main content and sub-change decorations. Default: `true`. */
  showMainDecorations?: boolean
  /** Whether to render replacement content. Default: `true`. */
  showReplacement?: boolean
  /** Whether to render sub-changes in inline groups. Default: `true`. */
  showSubChanges?: boolean
  /** Extra HTML attributes for the original-content decoration. */
  attributes?: Record<string, any>
  /** Extra HTML attributes for the replacement decoration. */
  replacementAttributes?: Record<string, any>
  /** Extra HTML attributes for inline sub-change decorations. */
  subChangeAttributes?: Record<string, any>
  /** Extra HTML attributes for sub-changes inside replacement content. */
  replacementSubChangeAttributes?: Record<string, any>
}

/** Values passed to a custom diff-suggestion renderer. */
interface RenderDecorationsOptions {
  /** The range occupied by the suggestion. */
  range: Range
  /** Whether the suggestion is selected. */
  isSelected: boolean
  /** The suggestion being rendered. */
  suggestion: DiffSuggestion
  /** Renders the default decorations, optionally with overridden options. */
  defaultRenderDecorations: (options?: DefaultRenderDecorationsOptions) => Decoration[]
}

/** A function that renders a suggestion as ProseMirror decorations. */
type RenderDecorations = (options: RenderDecorationsOptions) => Decoration[]
```

## `Step`

Represents one transition in a `StepSequence`.

```ts
/** One document transition in a step sequence. */
interface Step {
  /** Document state before the step was applied. */
  before: Node
  /** Document state after the step was applied. */
  after: Node
  /** Metadata associated with the step. */
  metadata: ChangeMetadata
  /** Cached changes, or `null` when they need to be computed. */
  changes: Change[] | null
  /** Cached affected area, or `null` when unavailable. */
  changedArea: Change | null
}
```

## `StepSequenceJSON`

JSON-serializable state for a `StepSequence`.

```ts
/** JSON-serializable state for a step sequence. */
type StepSequenceJSON = {
  /** Document state before any steps were applied. */
  before: ReturnType<Node['toJSON']>
  /** Document states after each recorded step. */
  docs: Array<ReturnType<Node['toJSON']>>
  /** Metadata for each recorded step. */
  metadata: ChangeMetadata[]
  /** Cached changes for each recorded step. */
  changes: Array<Change[] | null>
  /** Cached affected areas for each recorded step. */
  changedAreas: Array<Change | null>
}
```
