@daisugi/daisugi
TypeScript icon, indicating that this package has built-in type declarations

0.4.2 • Public • Published

@daisugi/daisugi

daisugi

Daisugi is a minimalist functional middleware engine.

version

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

🔝 back to top

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.

🔝 back to top

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.

🔝 back to top

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.

🔝 back to top

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'.

🔝 back to top

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.

🔝 back to top

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.

🔝 back to top

Goal

Daisugi goal is to keep the core as simple as possible, and extend its functionality through the provided tools.

🔝 back to top

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

🔝 back to top

Other projects

Meet the ecosystem

🔝 back to top

License

MIT

Package Sidebar

Install

npm i @daisugi/daisugi

Weekly Downloads

28

Version

0.4.2

License

MIT

Unpacked Size

42.5 kB

Total Files

16

Last publish

Collaborators

  • sviridoff
  • mawrkus