← Back to scenarios
ScenarioCatalog DB

Macro command sequence

Bundle several actions into a reusable macro that runs from one trigger.

Problem

A productivity tool must package an ordered set of actions as one reusable operation while allowing the invoker to execute the macro through the same command interface as individual actions.

Related patterns

Implementations

Command

TypeScriptApplication

Command in TypeScript

Encapsulates document actions as objects so an editor can execute, queue, and undo operations without knowing their implementation details.

TypeScript
interface Command {
  execute(): void;
  undo(): void;
}

class Document {
  private content = "";

  append(text: string) {
    this.content += text;
  }

  removeLast(count: number) {
    this.content = this.content.slice(0, -count);
  }

  print() {
    console.log(this.content);
  }
}

class AppendTextCommand implements Command {
  constructor(
    private readonly document: Document,
    private readonly text: string,
  ) {}

  execute() {
    this.document.append(this.text);
  }

  undo() {
    this.document.removeLast(this.text.length);
  }
}

class Editor {
  private readonly history: Command[] = [];

  run(command: Command) {
    command.execute();
    this.history.push(command);
  }

  undo() {
    this.history.pop()?.undo();
  }
}

const document = new Document();
const editor = new Editor();

editor.run(new AppendTextCommand(document, "Hello, "));
editor.run(new AppendTextCommand(document, "world!"));

document.print();

editor.undo();
document.print();

Associated technologies