> ## Documentation Index
> Fetch the complete documentation index at: https://docs.embededitor.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Commands

> Run the editor from code: get its handle, call a command, read what it holds and hear what changed.

The editor's handle, `EmbedEditorHandle`, runs the editor from code. Its commands do what the controls on screen do, its reads tell what the editor holds, and its events tell you what changed.

| Group | What it does | Page |
| - | - | - |
| `history` | Undo, Redo and Reset, as the toolbar. | [History and output](https://docs.embededitor.com/api-reference/commands/history-output.md) |
| `output` | Save, or the file Save would make. | [History and output](https://docs.embededitor.com/api-reference/commands/history-output.md#output) |
| `editor` | Close the editor. | [History and output](https://docs.embededitor.com/api-reference/commands/history-output.md#editor) |
| `menu` | Show a menu item, or tap its ring. | [Menu and reads](https://docs.embededitor.com/api-reference/commands/menu-read.md) |
| `read` | What the editor holds now. | [Menu and reads](https://docs.embededitor.com/api-reference/commands/menu-read.md#read) |
| `crop` | Crop, straighten, turn, mirror and zoom the photo, as Adjust. | [Adjust commands](https://docs.embededitor.com/api-reference/commands/adjust.md#crop) |
| `size` | The size Save writes, as Resize. | [Adjust commands](https://docs.embededitor.com/api-reference/commands/adjust.md#size) |
| `view` | Compare with the original, recenter, and zoom and move Annotate's view. | [Adjust commands](https://docs.embededitor.com/api-reference/commands/adjust.md#view) |
| `filter` | Choose a filter and its intensity. | [Filter, frame and adjustments](https://docs.embededitor.com/api-reference/commands/looks.md#filter) |
| `frame` | Choose a frame and its color. | [Filter, frame and adjustments](https://docs.embededitor.com/api-reference/commands/looks.md#frame) |
| `adjust` | Set the adjustments, as their rulers. | [Filter, frame and adjustments](https://docs.embededitor.com/api-reference/commands/looks.md#adjustments) |
| `auto` | Turn Auto on and off, and set its amount. | [Filter, frame and adjustments](https://docs.embededitor.com/api-reference/commands/looks.md#auto) |
| `palette` | Choose the set of colors every color row shows. | [Filter, frame and adjustments](https://docs.embededitor.com/api-reference/commands/looks.md#palette) |
| `obfuscate` | Draw, change, select and remove the areas that hide parts of the photo. | [Obfuscate and marks](https://docs.embededitor.com/api-reference/commands/obfuscate-marks.md#obfuscate) |
| `marks` | Adjust, place, hide and show the watermark and the signature. | [Obfuscate and marks](https://docs.embededitor.com/api-reference/commands/obfuscate-marks.md#marks) |
| `annotate` | Add, change and remove annotations, and open Annotate. | [Annotate](https://docs.embededitor.com/api-reference/commands/annotate.md) |
| `run`, `commands()` | Any command by its name, and the list of them, for a model. | [For AI](https://docs.embededitor.com/api-reference/commands/for-ai.md) |
| `ready`, `on` | The image on screen, and the events. | This page |

## Get the Handle

The same handle comes three ways: a `ref` on `EmbedEditor`, or what `mountEditor` and `openEditor` return. Both entries export the `EmbedEditorHandle` type.

```tsx React theme={"dark"}
import { useCallback, useRef } from 'react';
import { EmbedEditor } from '@embededitor/full/react';
import type { EmbedEditorHandle } from '@embededitor/full/react';

const PhotoEditor = ({ src }: { src: string }) => {
	const editor = useRef<EmbedEditorHandle>(null);

	const showFilters = useCallback(async () => {
		await editor.current?.menu.select({ item: 'FILTER' });
	}, []);

	return (
		<div style={{ height: 600 }}>
			<button onClick={showFilters}>Filters</button>
			<EmbedEditor
				ref={editor}
				src={src}
			/>
		</div>
	);
};
```

```ts mountEditor theme={"dark"}
import { mountEditor } from '@embededitor/full/standalone';

const editInline = async (element: HTMLElement, src: string) => {
	const editor = mountEditor(element, { src });

	// waits for the image, then shows the filters
	await editor.menu.select({ item: 'FILTER' });

	return editor;
};
```

```ts openEditor theme={"dark"}
import { openEditor } from '@embededitor/full/react';

const editPhoto = async (file: File) => {
	const editor = openEditor({ src: file });

	await editor.menu.select({ item: 'FILTER' });

	return editor;
};
```

* **`EmbedEditor`** forwards its `ref`, in React 18 and 19. The handle is made once and stays the same through every new set of props.
* **`mountEditor`** returns the handle with `update` and `destroy`. See [mountEditor()](https://docs.embededitor.com/api-reference/mount-editor.md).
* **`openEditor`** returns the handle with `close`. See [openEditor()](https://docs.embededitor.com/api-reference/open-editor.md).

The examples on these pages call the handle `editor`.

## How Every Command Behaves

* **It returns a Promise.** It resolves once the editor rendered the result: the step is in the history and on screen. It resolves to `null`, or to what it made (`output.save` gives `{ dest, state }`). A command that changes nothing, such as an undo with nothing to undo, still resolves.
* **It takes one object**, or nothing: `editor.menu.select({ item: 'FILTER' })`. The same object is its `input` in [`run`](https://docs.embededitor.com/api-reference/commands/for-ai).
* **It waits its turn.** Commands run one at a time, in the order you call them. You don't need to await one before you call the next.
* **It waits for the image.** `ready` resolves once the image is on screen, and commands start then. A command called before that waits for it, and doesn't fail. A load that fails keeps it waiting until a new `src`, or a picked image, loads.
* **It never runs under the user's hand.** While the user holds a drag, a pinch or an arrow key on a control, while a Save is on its way, or while they type the words of an annotation or a mark, a command waits, then runs.
* **An edit is one undo step**, as the same control on screen makes, and `history.undo` takes it back. A command that only changes what is shown, such as `menu.select`, makes no step.
* **Its values are the saved state's.** Coordinates are in the px of the size the editor works the image at (`read.size()`), adjustments run −100 to 100, rotation is in degrees, and filters and frames go by the ids the state writes. If you can read an [`EditState`](https://docs.embededitor.com/api-reference/state), you can write a command.
* **It acts from outside.** A command runs the same code as the control on screen, with its motion and its undo step, but not as a hand: the tool's name doesn't show over the photo, and a ruler doesn't go into its focus mode.

The undo below runs once the toggle is done, and takes it back:

```ts queue.ts theme={"dark"}
editor.menu.toggle({ item: 'FILTER' });
await editor.history.undo();
```

### When the Editor Leaves

Once the editor leaves the page, every command waiting and every one you call after rejects with `NOT_AVAILABLE`. A command running as it leaves rejects too, though what it already changed stays, and it changes nothing more, even once the editor is back. `ready` rejects the same way if the image wasn't on screen yet, and stays rejected: an editor shown again takes commands, but its `ready` doesn't come back.

* `EmbedEditor` unmounted. Hidden by an `<Activity>` instead, its commands work again once it is shown.
* `mountEditor`'s `destroy`, or another `mountEditor` on the same element: that handle takes no more commands.
* `openEditor`'s modal closed, however it closes (`close`, its Close button, Escape, a Save that went through): that handle takes no more commands.

Before the editor first mounts, a command waits for it.

### What Isn't a Command

Copy, Share and the eyedropper. The browser allows the clipboard, the share sheet and the eyedropper only inside a gesture of the user's own, so they stay buttons. For the file, call [`output.exportFile()`](https://docs.embededitor.com/api-reference/commands/history-output#exportfile) and copy or share it yourself.

## Errors

A command rejects with an [`EmbedEditorError`](https://docs.embededitor.com/api-reference/errors), whose `code` says what to fix. A rejected command changes nothing.

| `code` | When |
| - | - |
| `INVALID_COMMAND`, off the schema | The input is off the command's schema, or `run` names a command the handle doesn't have. `props` names each invalid path (`input.item`, or `command`), and `cause` holds the schema's own error (none for an unknown name). It rejects at once, without waiting its turn; on a handle whose editor was destroyed or left, `NOT_AVAILABLE` comes first. |
| `INVALID_COMMAND`, can't be taken here | The input fits the schema, but not where the editor stands: an area no drag would draw, a key the annotation's kind doesn't take, a size off the watermark's layout. It rejects on the command's turn, once the image is on screen, with `props` naming the paths and no `cause`. |
| `NOT_AVAILABLE` | The tool is off by a prop (`enableFilter: false`) or isn't in the edition, there is no close (`editor.close` with no `onClose`), or the editor was destroyed, closed or left the page. Each page lists its own cases. |
| `NOT_FOUND` | No area at that index, no annotation with that id. |
| `EXPORT_FAILED`, `MARK_FAILED` | `output.save`, `output.exportFile` or `read.screenshot` couldn't make the file, as Save. |

```ts errors.ts theme={"dark"}
import { EmbedEditorError } from '@embededitor/full/react';

try {
	await editor.run({ command: 'menu.select', input: { item: 'CURVES' } });
} catch (err) {
	if (err instanceof EmbedEditorError && err.code === 'INVALID_COMMAND') {
		console.error('invalid:', err.props.join(', '));
	}
}
```

## Events

```ts theme={"dark"}
on: <Name extends keyof EmbedEditorEvents>(name: Name, handler: (payload: EmbedEditorEvents[Name]) => void) => () => void;
```

`on` calls `handler` with what each event says, until you call the function it returns.

| Event | Payload | When |
| - | - | - |
| `load` | `{ file, size }` | The image is on screen, once per open, at the moment `onLoad` is called, with the same values. |
| `change` | `{ state }` | A step of the history landed: an edit (a command's, or the user's once they let go of a drag), an undo, a redo, a reset; or the ratio the host locks landing on the photo (no step to undo then). Never a gesture's preview, nor a command that changed nothing. `state` is an [`EditState`](https://docs.embededitor.com/api-reference/state). |
| `item` | `{ item, tool }` | The menu item or the tool on the stage changed. `tool` is `'ANNOTATE'` while Annotate is open. |
| `select` | `EmbedEditorSelection` | The selection changed: an Obfuscate area, by its index in `obfuscation`; in Annotate, an annotation (`{ kind: 'PIECE', id }`), an arrow added to a text (`{ kind: 'ARROW', id, index }`) or the Numbers' list (`{ kind: 'LIST' }`); or `null`. |
| `save` | `{ dest, state }` | A Save went through, its button's or `output.save`'s: what `onProcess` gets. |

A handler's own error is logged with `console.error`, never the editor's. After `destroy`, or once the modal closed, no event fires.

Keep a draft of every step, to reopen it later with the `state` prop:

```ts draft.ts theme={"dark"}
const stop = editor.on('change', ({ state }) => {
	localStorage.setItem('draft', JSON.stringify(state));
});
```

Call `stop()` when you no longer need it.

## Editions

Every edition has the same `EmbedEditorHandle`, as it has the same props. The Free and the Lite have Adjust alone:

* A command of a tool only the Full has is still on the handle. It rejects with `NOT_AVAILABLE`, and a read of it answers `null`. `commands()` leaves it out, so a model never sees it.
* `menu.select` and `menu.toggle` reject with `NOT_AVAILABLE` for an item the edition doesn't have, as for one a prop turned off.

The Full has every command.

> [card] [History and Output](https://docs.embededitor.com/api-reference/commands/history-output.md)
>
> Undo, Redo, Reset, Save, the file and Close.

> [card] [Menu and Reads](https://docs.embededitor.com/api-reference/commands/menu-read.md)
>
> The menu's items and what the editor holds.

> [card] [Adjust Commands](https://docs.embededitor.com/api-reference/commands/adjust.md)
>
> The crop, the size and the view.

> [card] [Filter, Frame and Adjustments](https://docs.embededitor.com/api-reference/commands/looks.md)
>
> The filter, the frame, the adjustments, Auto and the palette.

> [card] [Obfuscate and Marks](https://docs.embededitor.com/api-reference/commands/obfuscate-marks.md)
>
> The areas that hide parts of the photo, the watermark and the signature.

> [card] [Annotate](https://docs.embededitor.com/api-reference/commands/annotate.md)
>
> The annotations, their style, the action bar's verbs and the Numbers' list.

> [card] [For AI](https://docs.embededitor.com/api-reference/commands/for-ai.md)
>
> `run`, `commands()` and a model's tools.

> [card] [EmbedEditorError](https://docs.embededitor.com/api-reference/errors.md)
>
> The error and its codes.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.