npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@codeinkit/flows

v3.0.1

Published

Flows is a library that aim to make writing code concept flow based.

Downloads

31

Readme

Status GitHub Issues GitHub Pull Requests License


📝 Table of Contents

🧐 About

When writing code we want to build a good architecture in order to scale and maintain our code.

Nowadays the most common architectures are MVC-like (Model View Controller).

MVC is great, but it lacks the ability to separate the code to readable chunks, which makes the code harder to maintain and scale when it grows larger.

A flow based approach can help keep the architecture clean, and easy to scale.

When writing in flow base architecture every action (function in flow) can stand by itself, this fact makes the code separable which also makes it also easy to check, debug and develop.

🏁 Getting Started

Prerequisites

NodeJS

Installing

npm i @codeinkit/flows

🔧 Running the tests

npm test

Example

const { Flows } = require('@codeinkit/flows');

//create the flow
const flows = new Flows();

//first action
function first_action(flowData) {
  console.log('action can do simple stuff');
  const variable = 'all variable should be in the function scope (no state outside an action)';
  return {
    ...flowData,
    variable: 'returning object will move all the data to the next action in the flow'
  };
}

//second action
function second_action(flowData) {
  console.log(flowData.variable);
  //this function will throw an exception since it doesn't return an object
  //return {...flowData}
}

//third action
function third_action(flowData) {
  console.log('flowData is unique on each action therefore you need to add only serialize variable default serialization use JSON.stringify');
  return {message:'done'};
}

//register the functions to the flow
flows.register('flow_name', [first_action, second_action, third_action]);

//register a 'pre_action' hook that will printout the input of each function
flows.hook('pre_action', ({flowName, input, output, i, actionFn, error}) => {
  console.log(input);
});

//register an 'exception' hook that will printout the error
flows.hook('exception', ({flowName, input, output, i, actionFn, error}) => {
  console.log(error);
});

//execute the flow
flows.execute('flow_name', {});

🎈 Usage

there are 2 basic things you can do with flow, register and execute.

Flow Registration

// the flow name should always be a string
// the array in the second parameter is the list of action, each action is a function, 
// it's called action because it's a part of a flow.
// the flows library will execute the actions in order.
flows.register('flow_name', []);

Flow Execution

// the flow name should be a name that was registered, it the flow is not registered an error will occurs
// the second parameter is the initial data that pass to the first action
flows.execute('flow_name', {});

Actions

An action is a function that exists in a flow.

An action can be async, meaning it will return promise that resolve some data. If the promise is rejected and nothing catches the exception it will be available in the exception hook.

An action gets data through the 'data' parameter. That data is the data returned from the previous action (or from the flow execution command, if this is the first action).

Actions are required to return an object when it is done (that will be sent to the next action). The returned data must be serializable with JSON.stringify().

The $$ object

When returning a data object from an action, the action can also pass execution instructions to the flow. It does that by adding a "$$" object to the returned object.

The $$ object supports the following:

  • done - boolean - indicates to the flow execution to end the flow
  • jump - string - the name of another flow to jump to

done example

function action(data) {
  return {$$: {done: true}};
}

jump example

function action(data) {
  return {$$: {jump: 'other_flow'}};
}

Hooks

hook registration is done with

flows.hook('hook_name', () => {});

there are 5 types of hooks pre_action, post_action, pre_flow, post_flow, exception.

  • pre_flow - run at the beginning of the flow flows.hook('pre_flow', ({flowName, input}) => {});
  • post_flow - run at the end of the flow flows.hook('post_flow', ({flowName, output}) => {});
  • pre_action - run at the beginning of each action flows.hook('pre_action', ({flowName, i, actionFn, input}) => {});
  • post_action - run at the end of each action flows.hook('post_action', ({flowName, i, actionFn, input, output}) => {});
  • exception - run when exception accrue in action flows.hook('exception', ({flowName, i, actionFn, input, error}) => {});

the parameters that pass to the hooks are

  • flowName - a string represent the flow name
  • input - the object provided to the action
  • output - the object returned by the action
  • i - the index of the action in the flow
  • actionFn - the function of the action
  • error - the error of the exception

✍️ Authors

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Please make sure to update tests as appropriate.