JSPM

  • Created
  • Published
  • Downloads 13
  • Score
    100M100P100Q52573F
  • License ISC

Remix/React Router 7 Mediator

Package Exports

  • @remediator/core

Readme

@remediator/core

⚑ Lightweight frontend mediator for Remix, React Router, Vite & Webpack.

A simple CQRS-style mediator that lets you register handlers and middleware, and dispatch commands or queries with minimal ceremony.


πŸ”§ Install

npm install @remediator/core

πŸ“ Conventions

  • Request classes implement IRequest<TResult>
  • Handlers implement IRequestHandler<TRequest, TResult>
  • Registration pairs a request ctor with its handler via reMediator.register(...)
  • Middleware are functions matching (req, ctx, next) => Promise<TResult> and added with reMediator.use(...)

πŸš€ Setup

Register your handlers and middleware once at app startup (e.g. Remix root, server entry, or React Router loader):

// register handlers
reMediator.register(GetUserQuery, new GetUserQueryHandler());
reMediator.register(UpdateOrderCommand, new UpdateOrderCommandHandler());

// register global middleware (optional)
reMediator.use(authMiddleware);

πŸ“‘ Dispatching Requests

reMediator.send() has two overloads:

  1. Constructor + data: instantiate + hydrate

    await reMediator.send(
      GetUserQuery, // request class
      { id: "u1" }, // partial properties
      request, // raw Request object
      [logMiddleware] // optional per-call middleware
    );
  2. Instance: use an existing request object

    const cmd = new UpdateOrderCommand();
    cmd.orderId = "A123";
    cmd.status = "Shipped";
    
    await reMediator.send(
      cmd, // fully-built instance
      request,
      [auditMiddleware] // optional
    );

Both return the handler’s result type.


πŸ› οΈ Middleware

Middleware run before the handler and can:

  • Examine or modify req fields
  • Read/request context via ctx.rawRequest
  • Short-circuit or throw errors
  • Invoke await next() to continue the pipeline
export const authMiddleware: Pipeline = async (req, ctx, next) => {
  const token = ctx.rawRequest.headers.get("Authorization");
  if (!token) throw new UnauthorizedError();
  ctx.user = verifyToken(token);
  return next();
};

πŸ“¦ Full Example

// Handler registration
reMediator.register(GetUserQuery, new GetUserQueryHandler());
reMediator.use(authMiddleware);

// In a Remix loader
export async function loader({ request }: LoaderFunctionArgs) {
  // 1) Ctor + data
  const user1 = await reMediator.send(GetUserQuery, { id: "u1" }, request);

  // 2) Instance
  const q = new GetUserQuery();
  q.id = "u2";
  const user2 = await reMediator.send(q, request);

  return json({ user1, user2 });
}

Simple, explicit, and easy to test β€” perfect for clean frontend CQRS.

Β© 2025 @remediator/core