Skip to content

Commands and selectors

Commands are actions that plugins provide, and selectors are how plugins share their data. You can call any command or selector, and decorate it to change how it behaves.

Returns every available command.

getCommands(): Commands
Example
const { buyItem } = getCommands();
const { didBuy } = await buyItem({ itemId: "brass-key", price: 5 });

Returns every available selector.

getSelectors(): Selectors

Selectors work well with onChange.

Example
const { getInventory } = getSelectors();
onChange(getInventory, ({ inventory }) =>
console.log(`Now carrying ${inventory.length} items`),
);

Wraps a command with your own function.

decorateCommand<TName extends keyof Commands>(
commandName: TName,
fn: (context: Parameters<Commands[TName]>[0], next: Commands[TName]) => ReturnType<Commands[TName]>,
priority?: number
): void
ParameterDescription
commandNameThe command to wrap.
fnReceives the command’s arguments, and next, which calls the implementation beneath yours.
priorityDecorators with higher numbers run first. Defaults to 0. Decorators with the same priority run in the order their plugins were loaded.
PriorityRuns
Above 0Before the default behavior
Below 0After the default behavior
Number.MAX_VALUEFirst
-Number.MAX_VALUELast

Always call next, unless you mean to replace the command’s behavior completely.

Example
decorateCommand("init", (context, next) => {
console.log("Before init");
const result = next(context);
console.log("After init");
return result;
});

Wraps a selector with your own function. Works the same way as decorateCommand.

decorateSelector<TName extends keyof Selectors>(
name: TName,
fn: (context: Parameters<Selectors[TName]>[0], next: Selectors[TName]) => ReturnType<Selectors[TName]>,
priority?: number
): void
Example
decorateSelector("getInventory", (context, next) => {
const { inventory } = next(context);
return { inventory: [...inventory].sort() };
});