Skip to content

hyperse-io/pipeline

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

38 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@hyperse/pipeline

build stable version GitHub top language Licence

A middleware engine written in typescript, it will be used on a couples of projects, such as tracker

Usage

1、Pipe With Middleware

When you call the pipeline function and assign it to a variable, you are able to pass a coma separated list of middleware functions to add to the middleware queue.

import { Pipeline } from '@hyperse/pipeline';

interface Context {
  [key: string]: any;
}

const engine = new Pipeline<Context>((ctx, next) => {
  ctx.foobar = 'baz';
  next();
});

Not all middleware has to be added when the factory function is first invoked. Instead, you can assign middldeware to the system later with the use method.

engine.use(async (ctx, next) => {
  await new Promise((res) => setTimeout(() => res, 2000));
  ctx.another = 123;
  next();
});

Then when we're ready to run the middleware engine, we'll create it's it's initial context, and then pass that context to the engine for processing.

(async () => {
  const context: Context = {};
  await engine.execute(context);
  console.log(context);
})();
// => { foobar: "baz", another: 123 }

Errors

If an error happens in your middleware pipeline, you can assign an error handling middleware at the end of the queue.

engine.use((ctx, next) => {
  fs.readFile(ctx.path, {}, (err, file) => {
    if (err) next(err);
    // .. Do something
    next();
  });
});
// .. More middleware ...
engine.use((cyx, next, error) => {
  if (error) console.error(error.message);
});

2、Pipe With Array Function

You can easily use pipeline to manage a stream of events in the following ways

  • Basic
const resp = await pipe(
  () => 123,
  (n) => n + 1
)();
expect(resp + 1).toEqual(125);
  • Provides a global context for the pipeline (❗ mutable)
const resp = await pipe(
  () => 123,
  pipeContext((ctx: { n: number }) => (n) => n + ctx.n),
  (n) => n + 1
).context({ n: 1 })();
expect(resp + 1).toEqual(126);
  • Exit pipeline
const resp = await pipe(
  () => 123,
  (n) => exitPipe(n + 1),
  () => 'qwe'
)();
if (isExitPipeValue(resp)) {
  expect(resp.r + 1).toEqual(125);
}
  • Dynamically replace nodes in the pipeline (❗ mutable)
const fn = pipe(
  () => 123,
  (n) => n + 1
);
fn.replace([[0, () => 124]]);
fn.replaceUndo();
expect((await fn()) + 1).toEqual(125);
  • Support promise
const resp = await pipe(
  () => Promise.resolve(123),
  (n) => n + 1
)();
expect(resp + 1).toEqual(125);
  • Promise can include anything supported
const resp = await pipe(
  () => 123,
  (n) => Promise.resolve(exitPipe(n + 1)),
  () => 'qwe'
)();
if (isExitPipeValue(resp)) {
  expect(resp.r + 1).toEqual(125);
}

Development

yarn install

Testing

yarn test