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 withreMediator.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:
Constructor + data: instantiate + hydrate
await reMediator.send( GetUserQuery, // request class { id: "u1" }, // partial properties request, // raw Request object [logMiddleware] // optional per-call middleware );
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
reqfields - 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