@marianmeres/midware
v1.3.4
Published
A minimalistic, type-safe middleware framework for executing functions in series.
Readme
@marianmeres/midware
A minimalistic, type-safe middleware framework for executing functions in series.
Features
- Type-safe: Full TypeScript support with generic middleware arguments
- Timeout protection: Per-middleware and total execution timeouts
- Priority sorting: Optional execution order based on middleware priority
- Duplicate detection: Optional prevention of duplicate middleware registration
- Early termination: Any middleware can stop the chain by returning a non-undefined value
- Zero dependencies: Lightweight and self-contained
Installation
# Deno
deno add jsr:@marianmeres/midware# Node.js
npx jsr add @marianmeres/midwareQuick Start
import { Midware } from "@marianmeres/midware";
// Create a middleware manager with typed arguments
const app = new Midware<[{ user?: string; authorized?: boolean }]>();
// Register middlewares
app.use((ctx) => {
ctx.user = "john";
});
app.use((ctx) => {
ctx.authorized = true;
});
// Execute all middlewares in series
const ctx = {};
await app.execute([ctx]);
console.log(ctx); // { user: "john", authorized: true }API
Midware<T>
The main middleware manager class. T is a tuple type representing the arguments passed to all middlewares.
| Method | Description |
|--------|-------------|
| use(midware, timeout?) | Add middleware to the end of the stack |
| unshift(midware, timeout?) | Add middleware to the beginning of the stack |
| remove(midware) | Remove a specific middleware (returns true if found) |
| clear() | Remove all middlewares |
| execute(args, timeout?) | Execute all middlewares in series |
Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| preExecuteSortEnabled | boolean | false | Sort middlewares by __midwarePreExecuteSortOrder before execution |
| duplicatesCheckEnabled | boolean | false | Throw error if the same middleware is added twice |
Utilities
withTimeout(fn, timeout, errMessage?)- Wraps a function with timeout protectionsleep(timeout, ref?)- Promise-based delay utilityTimeoutError- Custom error class for timeouts
For complete API documentation with detailed parameters, return types, and examples, see API.md.
Examples
Early Termination
const app = new Midware<[{ authorized: boolean }]>();
app.use((ctx) => {
if (!ctx.authorized) {
return { error: "Forbidden" }; // Stops execution chain
}
});
app.use((ctx) => {
console.log("This won't run if unauthorized");
});
const result = await app.execute([{ authorized: false }]);
console.log(result); // { error: "Forbidden" }Timeout Protection
const app = new Midware<[any]>();
// Per-middleware timeout (1 second)
app.use(async (ctx) => {
await someSlowOperation();
}, 1000);
// Total execution timeout (5 seconds)
try {
await app.execute([{}], 5000);
} catch (e) {
if (e instanceof TimeoutError) {
console.log("Operation timed out");
}
}Priority Sorting
const app = new Midware<[string[]]>([], { preExecuteSortEnabled: true });
const logger: MidwareUseFn<[string[]]> = (log) => { log.push("logger"); };
logger.__midwarePreExecuteSortOrder = 10;
const auth: MidwareUseFn<[string[]]> = (log) => { log.push("auth"); };
auth.__midwarePreExecuteSortOrder = 1;
app.use(logger); // Added first
app.use(auth); // Added second, but runs first due to lower sort order
const log: string[] = [];
await app.execute([log]);
console.log(log); // ["auth", "logger"]Duplicate Prevention
const app = new Midware<[any]>([], { duplicatesCheckEnabled: true });
const middleware = (ctx) => { /* ... */ };
app.use(middleware);
app.use(middleware); // Throws Error: "Midware already exist..."
// Allow duplicates for specific middleware
const duplicable = (ctx) => { /* ... */ };
duplicable.__midwareDuplicable = true;
app.use(duplicable);
app.use(duplicable); // OKDynamic Middleware Management
const app = new Midware<[any]>();
const tempMiddleware = (ctx) => { ctx.temp = true; };
app.use(tempMiddleware);
// ... later
app.remove(tempMiddleware); // Returns true
// Or clear everything
app.clear();License
MIT
