Skip to Content

@jumentix/message-mediator

Pacote de workspace para contratos do Message Mediator Jumentix e seu adaptador in-memory de referência.

Escopo extraído atual:

  • contratos principais (IMessage, IMessageResponse, metadados)
  • barramento de eventos e interfaces de mediador
  • adaptador in-memory;
  • adaptador RabbitMQ;
  • adaptador BullMQ;
  • helper compileMessageMediator orientado pelo ambiente.

Responsabilidade no escopo

  • Camada: messaging / adaptador de aplicação
  • Responsável por: mediação em processo ou via broker
  • Usado com: use-cases de backend
  • Não responsável por: rotas OpenAPI ou persistência de banco

Experimente no navegador

Mediator in-memory:

Mediator em memória

Troque mensagens entre os domínios Category e Task e componha um read model via request/response do mediator.

const domainMessages = [];
const events = [];
const mediator = api.createInMemory();

const categories = new Map([
  ['work', { id: 'work', name: 'Work', color: '#2563eb' }],
  ['home', { id: 'home', name: 'Home', color: '#16a34a' }]
]);
const tasks = [];

await mediator.subscribe('tasks.created', async (event) => {
  events.push({
    title: event.payload.title,
    categoryId: event.payload.categoryId
  });
});

mediator.registerHandler('categories.get.v1', async (message) => {
  domainMessages.push({
    from: message.metadata.sourceDomain,
    to: 'Categories',
    contract: 'categories.get.v1',
    categoryId: message.payload.id
  });
  return {
    ok: true,
    result: categories.get(message.payload.id) ?? null
  };
});

mediator.registerHandler('tasks.create.v1', async (message) => {
  const task = {
    id: message.payload.id,
    title: message.payload.title,
    categoryId: message.payload.categoryId,
    completed: false
  };
  tasks.push(task);
  await mediator.publish({ name: 'tasks.created', payload: task });
  return { ok: true, result: task };
});

mediator.registerHandler('tasks.board.v1', async () => {
  const cards = await Promise.all(tasks.map(async (task) => {
    const category = await mediator.request({
      contract: 'categories.get.v1',
      payload: { id: task.categoryId },
      metadata: {
        sourceDomain: 'Tasks',
        reason: 'compose task board read model'
      }
    });
    return {
      id: task.id,
      title: task.title,
      categoryName: category.result?.name ?? 'Uncategorized',
      categoryColor: category.result?.color ?? '#64748b'
    };
  }));
  return {
    ok: true,
    result: {
      readModel: 'TaskBoard',
      composedFrom: ['Tasks', 'Categories'],
      cards
    }
  };
});

const response = await mediator.request({
  contract: 'tasks.create.v1',
  payload: {
    id: 'task-1',
    title: 'Wire mediator events',
    categoryId: 'work'
  },
  metadata: { source: 'browser-playground' }
});
const board = await mediator.request({
  contract: 'tasks.board.v1',
  payload: {},
  metadata: { source: 'task-board-page' }
});

return {
  createdTask: response.result,
  board: board.result,
  domainMessages,
  events
};

Documentação completa

Veja o guia de uso.