API / @aionbuilders/nabu/extend

ExtensionInit

Type Stability: stable

What an extension is made of: a block class and its component, hooks, serializers, actions, commands, paste interpreters and file handlers, input rules, slash menu entries and Loro text styles. Every field is optional; pass it to extension(name, init).

Related guide: Extensions →

Definition

TypeScript
import type { ExtensionInit } from '@aionbuilders/nabu/extend';
TypeScript
interface ExtensionInit {
  actions?: Record<string, (nabu: Nabu, data: any, topic: string) => any>;
  block?: typeof Block;
  commandContext?: (nabu: Nabu, ctx: CommandContext) => void | Record<string, any>;
  commands?: Record<string, CommandDef>;
  component?: Component<any, any, string>;
  defaultBlock?: boolean;
  hooks?: Partial<ExtensionHooks>;
  inputRules?: InputRule[];
  loroTextStyles?: Record<string, { expand: 'none' | 'after' | 'before' | 'both' }>;
  name?: string;
  pasteFileHandlers?: PasteFileHandler[];
  pasteInterpreters?: PasteInterpreter[];
  serializers?: Record<string, (nabu: Nabu) => any>;
  slashCommands?: SlashCommand[];
}

Properties

Properties of ExtensionInit
PropertyTypeDescription
actionsoptionalRecord<string, (nabu: Nabu, data: any, topic: string) => any>

Handlers of the action bus, by topic (nabu.exec(topic, data)). COLLISION RULE: several extensions may declare the same topic and ALL their handlers run (that is how an extension observes another one's topic), so give a topic of your own a distinctive name (namespace:verb): two extensions that each mean something different by code would both fire. Built-in topics: mark:*, block:*, list:*...

blockoptionaltypeof Blockn/a
commandContextoptional(nabu: Nabu, ctx: CommandContext) => void | Record<string, any>

Contributes FACTS to the context given to the when / run / label of commands (e.g. { atStartOfRegion: true }). Called once per candidate key press; keep it cheap. It cannot replace the engine's own fields.

commandsoptionalRecord<string, CommandDef>

Commands (ADR 017): { [id]: { label, keys?, when?, scope?, run(nabu, ctx, data?), confirm? } }. Each one is also an action of the bus (nabu.exec(id, data)); the engine resolves their keys at keydown, before the legacy onKeyDown hooks.

componentoptionalComponent<any, any, string>n/a
defaultBlockoptionalboolean

Marks block as the editor's DEFAULT text block (the one created when the engine needs an empty text block of its own: a caret below a trailing void block, …). Last one wins.

hooksoptionalPartial<ExtensionHooks>n/a
inputRulesoptionalInputRule[]

Declarative text-replacement rules applied while typing (e.g. markdown shortcuts, smart typography). Tested against the text before the cursor.

loroTextStylesoptionalRecord<string, { expand: 'none' | 'after' | 'before' | 'both' }>

Loro text style configuration required by this extension. Passed to LoroDoc.configTextStyle() during Nabu initialization so that applyDelta with these attributes works correctly.

nameoptionalstringn/a
pasteFileHandlersoptionalPasteFileHandler[]

Make a block of a file pasted from the clipboard (see PasteFileHandler).

pasteInterpretersoptionalPasteInterpreter[]n/a
serializersoptionalRecord<string, (nabu: Nabu) => any>n/a
slashCommandsoptionalSlashCommand[]

Entries this extension adds to the slash menu (collected in nabu.slashCommands; the menu has no entry of its own, so a block type absent from the editor is never offered). The menu sorts them by group, order, then declaration order, whatever the load order of the extensions. A when(engine, block) limits an entry to the places where it applies (the block holding the caret); without it the entry is always offered.

Source: src/lib/utils/extensions.js:163