Control and shape the destiny of your events
Nornir is a TypeScript lib that provides a strongly typed middleware chain for event processing in Node.js with a fluent API.
It allows developers to create a chain of middleware functions that execute one after the other, passing a result from one function to the next.
You can install Nornir using NPM or Yarn:
``bash`
npm install @nornir/core
`bash`
yarn add @nornir/core
`typescript
import nornir from "@nornir/core";
import type { ALBEvent, ALBHandler } from "aws-lambda";
interface Event1 {
type: "Event1";
data: string;
}
interface Event2 {
type: "Event2";
thing: number;
stuff: {
other: boolean;
test: true;
};
}
type Event = Event1 | Event2;
export const handler: ALBHandler = nornir
.use(input => [{ type: "Event1", data: input.body } as Event])
.split(
chain =>
chain
.use(input => ({ cool: input.type, event: input }))
.use(input => input.event),
)
.use(input => input[0].unwrap())
.match("type", {
Event1: chain => chain.use(input => input.data),
Event2: chain => chain,
})
.use(input => {
return {
statusCode: 200,
body: JSON.stringify(input),
};
})
.build();
`
All methods
#### use(handler: (input: StepInput, registry: AttachmentRegistry) => StepOutput)
Adds a middleware function to the chain.
The middleware function takes the output of the previous step as an input and returns a new output.
The function can be either synchronous or asynchronous.
`typescript`
nornir.use((input: MyStepInputType, registry: AttachmentRegistry) => {
// Do something with the input
return input.thing;
});
#### useResult(handler: (input: Result
Adds a middleware function to the chain.
Identitical to use, but the input is wrapped in a Result object that allows you to unwrap the value or handle errors.
`typescript`
nornir.useResult(
async (input: Result
// Unwrap the input and do something with it
return input.unwrap();
},
);
#### useChain(chain: Nornir
Adds a Nornir chain to the current chain.
Allows developers to compose multiple Nornir chains.
`typescript
const subChain = new Nornir
.use((input, registry) => {
// Do something with the input
return mySubChainOutput;
});
nornir.useChain(subChain);
`
#### split(builder: (chain: Nornir
Splits an array of inputs and processes them through a chain with configurable concurrency.
Returns an array of result objects.
Execution will not stop if an item fails, they can all resolve or reject individually.
`typescript`
nornir.split(chain =>
chain.use(item => item.property++)
.use(item => ({ test: item }))
).use(outputs => outputs.map(output => output.unwrap()));
#### match(tag: string, match: object): Nornir
Pattern match on a property of a discriminated union.
Branch is chosen based on the value of the property.
Matching is exhaustive, so all possible values of the property must be handled.
`typescript
interface Event1 {
type: "Event1";
data: string;
}
interface Event2 {
type: "Event2";
thing: number;
stuff: {
other: boolean;
test: true;
};
}
type Event = Event1 | Event2;
export const handler = nornir
.match("type", {
Event1: chain => chain.use(input => input.data),
Event2: chain => chain,
});
``