> For the complete documentation index, see [llms.txt](/llms.txt).
> The full corpus is at [llms-full.txt](/llms-full.txt).

# Editor

> **Editor** = `object`

Defined in: packages/editor/src/editor.ts:59

## Properties

### dom

> **dom**: `EditorDom`

Defined in: packages/editor/src/editor.ts:60

***

### getSnapshot()

> **getSnapshot**: () => [`EditorSnapshot`](/api/editor/type-aliases/editorsnapshot/)

Defined in: packages/editor/src/editor.ts:61

#### Returns

[`EditorSnapshot`](/api/editor/type-aliases/editorsnapshot/)

***

### on()

> **on**: \{\<`TType`\>(`type`, `listener`, `options`): `object`; \<`TType`\>(`type`, `listener`, `options?`): `object`; \}

Defined in: packages/editor/src/editor.ts:128

Register an event listener.

With `{batch: true}` the listener is called once per burst with
`Array<Event>`, every matching event emitted before control returns to the
event loop (one synchronous `editor.send` worth, normalization included),
in delivery order, on the trailing microtask. That is the same boundary at
which the editor settles its own state, so each call is one fully-applied,
normalized change. Without it (the default), the listener runs
synchronously for every event and receives a single event.

#### Call Signature

> \<`TType`\>(`type`, `listener`, `options`): `object`

##### Type Parameters

###### TType

`TType` *extends* `"*"` \| `"blurred"` \| `"editable"` \| `"focused"` \| `"invalid value"` \| `"mutation"` \| `"operation"` \| `"patch"` \| `"read only"` \| `"ready"` \| `"selection"` \| `"value changed"`

##### Parameters

###### type

`TType`

###### listener

(`events`) => `void`

###### options

###### batch

`true`

##### Returns

`object`

###### unsubscribe()

> **unsubscribe**: () => `void`

###### Returns

`void`

#### Call Signature

> \<`TType`\>(`type`, `listener`, `options?`): `object`

##### Type Parameters

###### TType

`TType` *extends* `"*"` \| `"blurred"` \| `"editable"` \| `"focused"` \| `"invalid value"` \| `"mutation"` \| `"operation"` \| `"patch"` \| `"read only"` \| `"ready"` \| `"selection"` \| `"value changed"`

##### Parameters

###### type

`TType`

###### listener

(`event`) => `void`

###### options?

###### batch?

`false`

##### Returns

`object`

###### unsubscribe()

> **unsubscribe**: () => `void`

###### Returns

`void`

***

### registerBehavior()

> **registerBehavior**: (`config`) => () => `void`

Defined in: packages/editor/src/editor.ts:65

#### Parameters

##### config

###### behavior

`Behavior`

#### Returns

> (): `void`

##### Returns

`void`

***

### registerDecorations()

> **registerDecorations**: (`config`) => [`DecorationRegistration`](/api/editor/interfaces/decorationregistration/)

Defined in: packages/editor/src/editor.ts:105

Register decorations, independent of any `PortableTextEditable`'s
`rangeDecorations` prop. Multiple sources (the prop and any number
of registrations) compose: their decorations flatten with every
`PortableTextEditable`'s prop decorations first (in mount order when
there's more than one editable), then each registration in the order
it was made. The prop always renders outermost, even when a
registration's decoration mounts before the `PortableTextEditable`
carrying the prop. Nesting is outer-to-inner across sources the same
way array order nests within one registration.

Each decoration needs a stable, unique `id` so `update` can
reconcile by identity: a decoration whose `id` carries over keeps its
live position (and any in-flight move) across the call, only
adopting a new `range` when the `id`'s `range` actually changed,
while always picking up a new `render` reference. Registering (or
updating with) more than one decoration sharing an `id` throws
synchronously, before any state change. `update` and `unregister`
after `unregister` are no-ops.

Registered decorations keep transforming and delivering `onMapped`
while the editor is read-only; the `rangeDecorations` prop freezes
when read-only.

This is the low-level primitive higher-level decoration tooling
builds on.

:::caution[Beta]
This API should not be used in production and may be trimmed from a public release.
:::

#### Parameters

##### config

###### decorations

[`Decoration`](/api/editor/interfaces/decoration/)[]

###### onMapped?

(`mappings`) => `void`

Synchronous, per engine operation that moved, touched, or
destroyed at least one of this registration's decorations, one
entry per affected decoration. Fires mid-apply: do not dispatch
editor events from it. Fixed at registration. No calls before
`ready`, none from `update()` reconciliation.

#### Returns

[`DecorationRegistration`](/api/editor/interfaces/decorationregistration/)

***

### registerNode()

> **registerNode**: (`config`) => () => `void`

Defined in: packages/editor/src/editor.ts:75

Register a node renderer. The `node` argument is the result of one
of the `defineX` factories (`defineContainer`, `defineTextBlock`,
`defineSpan`, `defineBlockObject`, `defineInlineObject`,
`defineDecorator`, `defineAnnotation`). Returns a function that
unregisters the node when called.

#### Parameters

##### config

###### node

[`RegistrableNode`](/api/editor/type-aliases/registrablenode/)

#### Returns

> (): `void`

##### Returns

`void`

***

### send()

> **send**: (`event`) => `void`

Defined in: packages/editor/src/editor.ts:116

#### Parameters

##### event

[`EditorEvent`](/api/editor/type-aliases/editorevent/)

#### Returns

`void`

## Methods

### subscribe()

> **subscribe**(`observer`): `object`

Defined in: packages/editor/src/editor.ts:164

Subscribe to editor state changes. The observer's `next` callback fires
with the current `EditorSnapshot` on relevant transitions (selection
updates, content mutations, behavior dispatch, configuration changes).

Notifications are coalesced: a synchronous burst of transitions (e.g. the
many operations one action applies, like undoing a large delete) delivers
a single `next` with the settled snapshot on the next microtask, rather
than one `next` per transition. The snapshot is cumulative, so only
intermediate per-transition states are skipped. To observe every
operation, use `editor.on('operation', ...)`.

The editor has no terminal state and no error path, so `error` and
`complete` are part of the observable contract but never fire. They are
kept for structural compatibility with `useSyncExternalStore`,
`@xstate/react`'s `useSelector`, and other observer-shaped consumers.

#### Parameters

##### observer

###### complete?

() => `void`

###### error?

(`err`) => `void`

###### next?

(`snapshot`) => `void`

#### Returns

`object`

##### unsubscribe()

> **unsubscribe**: () => `void`

###### Returns

`void`