A lightweight, type-safe command pattern implementation with plugin support:
npm install @collidor/command
import { CommandBus } from "your-package-name"; // 1. Define command class CreateUser extends Command<{ id: string }> {} // 2. Create bus const bus = new CommandBus(); // 3. Register handler bus.register(CreateUser, (command, context) => ({ id: Math.random().toString(36).substr(2, 9), })); // 4. Execute (type inferred as { id: string }) const user = bus.execute(new CreateUser());
const asyncBus = new CommandBus({ plugin: (command, ctx, handler) => { return Promise.resolve(handler?.(command, ctx)); } }); // Returns Promise<{ id: string }> const futureUser = asyncBus.execute(new CreateUser());
const streamBus = new CommandBus({ plugin: async function* (command, ctx, handler) { yield await handler?.(command, ctx); yield await handler?.(command, ctx); } }); // Returns AsyncIterable<{ id: string }> for await (const result of streamBus.execute(new CreateUser())) { console.log(result); }
CommandBus<TContext, TPlugin>
Method | Description |
---|---|
register<C> |
Register command handler |
execute<C> |
Execute command with type inference |
type PluginHandler<C, TContext, R> = ( command: C, context: TContext, handler?: (command: C, context: TContext) => R ) => R;
interface AppContext { requestId: string; user: { id: string }; } const bus = new CommandBus<AppContext>({ context: { requestId: "123", user: { id: "system" } } }); bus.register(CreateUser, (cmd, ctx) => { console.log(ctx.user.id); // "system" return { id: ctx.requestId }; });
const errorHandlingPlugin: PluginHandler<Command, any> = (command, ctx, handler) => { try { return handler?.(command, ctx); } catch (error) { console.error("Command failed:", command); throw error; } }; const safeBus = new CommandBus({ plugin: errorHandlingPlugin });
Automatic return type wrapping based on plugin:
// Given this plugin: const plugin = (command, ctx, handler) => [handler?.(command, ctx)]; // Return type becomes Array<{ id: string }> const result = bus.execute(new CreateUser());
MIT © Alykam Burdzaki
Add Package
deno add jsr:@collidor/command
Import symbol
import * as command from "@collidor/command";
---- OR ----
Import directly with a jsr specifier
import * as command from "jsr:@collidor/command";
Add Package
npx jsr add @collidor/command
Import symbol
import * as command from "@collidor/command";
Add Package
yarn dlx jsr add @collidor/command
Import symbol
import * as command from "@collidor/command";
Add Package
pnpm dlx jsr add @collidor/command
Import symbol
import * as command from "@collidor/command";
Add Package
bunx jsr add @collidor/command
Import symbol
import * as command from "@collidor/command";