@daisugi/daisugi
v0.4.2
Published
Daisugi is a minimalist functional middleware engine.
Downloads
169
Readme
@daisugi/daisugi
This project is part of the @daisugi monorepo.
Well tested. | Without any external code dependencies and small size.
Daisugi was created with the purpose of organizing your code in an understandable execution pipeline.
Usage
import { Daisugi } from '@daisugi/daisugi';
const { sequenceOf } = new Daisugi();
function addName(arg) {
return `${arg} John`;
}
function addLastName(arg) {
return `${arg} Doe.`;
}
const handler = sequenceOf([addName, addLastName]);
handler('Hi');
// Hi John Doe.
Table of contents
Install
Using npm:
npm install @daisugi/daisugi
Using yarn:
yarn add @daisugi/daisugi
Downstream and downstream/upstream
Daisugi allows both types, perform sequential executions like traditional pipes do, by downstream
, to accomplish it you need to use simple functions (handlers
).
import { Daisugi } from '@daisugi/daisugi';
const { sequenceOf } = new Daisugi();
function addName(arg) {
return `${arg} John.`;
}
sequenceOf([addName])('Hi');
// Hi John.
Or by yielding downstream
, then flowing the control back upstream
, often used in middleware (like Koa does). This effect is called cascading. To get it, you only need to provide the injectToolkit
property to the meta
data of the function, that tells to Daisugi include the toolkit
with flow utilities (next
, nextWith
) as the last argument to your function.
import { Daisugi } from '@daisugi/daisugi';
const { sequenceOf } = new Daisugi();
function addName(arg, toolkit) {
arg.value = `${arg.value} John`;
return toolkit.next;
}
addName.meta = {
injectToolkit: true,
};
function addLastName(arg) {
return `${arg.value} Doe.`;
}
sequenceOf([addName])({ value: 'Hi' });
// 'Hi John.'
By default the type used is downstream
, its use is more common. But you can always switch to cascading to get more complex behavior (tracing, logger ...). Or you can mix the both types in the same sequence.
Synchronous and asynchronous
Daisugi allows handlers
to be synchronous or asynchronous.
import { Daisugi } from '@daisugi/daisugi';
const { sequenceOf } = new Daisugi();
async function waitForName(arg, toolkit) {
return await toolkit.next;
}
waitForName.meta = {
injectToolkit: true,
};
async function addName(arg) {
return `${arg} John.`;
}
await sequenceOf([waitForName, addName])('Hi');
// Hi John.
Nesting
Daisugi allows you to nest as many sequences within each other as needed, because each sequence is nothing more than a new handler
.
import { Daisugi } from '@daisugi/daisugi';
const { sequenceOf } = new Daisugi();
function addName(arg) {
return `${arg} John`;
}
function addLastName(arg) {
return `${arg} Doe.`;
}
sequenceOf([addName, sequenceOf([addLastName])])('Hi');
// Hi John Doe.
Flow control
In Daisugi you are the owner of the data flow, for that purpose you have available a few static methods:
stopPropagationWith
, gives you the possibility to stop and exit the execution of the current sequence.failWith
, stops the execution and exits from all sequences.
import { Daisugi } from '@daisugi/daisugi';
const { sequenceOf } = new Daisugi();
function addName(arg) {
return Daisugi.stopPropagationWith(`${arg} John.`);
}
function addLastName(arg) {
return `${arg} Doe.`;
}
sequenceOf([addName, addLastName])('Hi');
// Hi John.
import { Daisugi } from '@daisugi/daisugi';
const { sequenceOf } = new Daisugi();
function addName(arg) {
return Daisugi.failWith(`${arg} John`);
}
function addLastName(arg) {
return `${arg} Doe.`;
}
const response = sequenceOf([addName, addLastName])('Hi');
// response.getError().value === 'Hi John'.
Multiple arguments
The title speaks for itself, you can provide to the handlers
, nextWith
among others, much arguments as needed.
import { Daisugi } from '@daisugi/daisugi';
const { sequenceOf } = new Daisugi();
function addName(arg1, arg2, arg3) {
return `${arg} ${arg2} ${arg3}.`;
}
sequenceOf([addName])('Hi', 'John', 'Doe');
// Hi John Doe.
Extendable
Daisugi gives you the freedom to extend any handler
at execution time or during initialization, using the decorators.
import { Daisugi } from '@daisugi/daisugi';
function decorator(handler) {
return function addName(arg) {
handler(`${arg} ${handler.meta.arg}`);
};
}
const { sequenceOf } = new Daisugi([decorator]);
function addLastName(arg) {
return `${arg} Doe.`;
}
addLastName.meta = {
arg: 'John',
};
sequenceOf([addLastName])('Hi');
// Hi John Doe.
Goal
Daisugi goal is to keep the core as simple as possible, and extend its functionality through the provided tools.
Etymology
Daisugi is a Japanese forestry technique, originated in the 14th century, where specially planted cedar trees are pruned heavily to produce "shoots" that become perfectly uniform, straight and completely knot free lumber.
More info: https://twitter.com/wrathofgnon/status/1250287741247426565