Product
Introducing Ruby Support in Socket
Socket is launching Ruby support for all users. Enhance your Rails projects with AI-powered security scans for vulnerabilities and supply chain threats. Now in Beta!
A nodejs library for composing tiny functions together in a sequential manner
A nodejs library for composing tiny functions together in a sequential manner
npm i f-composer
This library has a backbone component which is Workflow
, basically the workflow is a collection of tiny functions are combined together to form a bigger implementation, these tiny functions are called steps, these steps are exeucted in a sequential manner, you can also inject some hooks for each steps to be exeucted before or after the step execution
This library borrows some concepts from functional programming, one of these concepts, each step added to this workflow should have input or output, and each output of the function will be the input for the next one.
The concept of workflows is about grouping multiple and related functionalities and compose them in one method, suppose you have a function like place an order as the following:
function placeOrder() {
createOrder()
doPayment()
clearCart()
sendEmail()
}
In this example, you see you have a big functionality that knows about everything related to creating and order, doing payment, clearing cart and sending emails, and you are calling these method in a sequence, so instead of calling these methods in that way in a bigger function, you just create a workflow and start adding the steps and the library will compose these functions together
This library aims to help you devide your code into very small, specific functions that do one thing, based on single responsibility principle, this will help you to make your code more testable and extendable
This library could be used in typescript or javascript, also can run either on nodejs server or on browser
const workflow = Workflow.NewWorkflow();
NewWorkflow
method is used to create new workflow object
Then you can add steps as much as you want, you can add one step using the following method
workflow.addStep(step, ...hooks);
This method takes endless arguments, the first argument is an object, which represents the actual step that needs to be executed and the rest of arguments are hooks that can be executed before
or after
the step execution
Step Fields
field | value type | required | description |
---|---|---|---|
func | function | true | the function that should be executed in this step |
options | object | false | this is an optional object contains some configuration for the step |
Options Object
field | value type | required | default value | description |
---|---|---|---|---|
readFromOriginalInput | boolean | false | false | if sat to true, it will read from the original input not from the output of the previous step |
defaultReturningInput | boolean | false | false | if sat to true and there is no result returned from this step, the workflow will automatically return the input of this step as its result |
Here is an example for step object
workflow.addStep({
func: () => {
// here is logic for step to be executed
},
options: {
readFromOriginalInput: false,
defaultReturningInput: false
}
});
Note each step function can return an output, this output will be used to feed the next function input
you can add multiple steps in one call using the following method:
workflow.addSteps([step, ...hooks], [step, ...hooks]);
this method takes endless arguments, each argument should be an array with at least one argument, the first argument is the step that you want to execute, and the other arguments are optional, each one could be an object represents a hook that should be executed before or after executing the actual step, please refer to addStep
method above
Note the functions are executed sequentially and in FIFO mode, which means the first function registered to this workflow it will be the first one executed
After adding steps to the workflow now you need to compose/build the workflow you created, by combining the steps in a series, this is done using a function called composeAsync
, if you are working with typescript, this function takes a generic type which is the returned type from this workflow
workflow.composeAsync<string>();
While you can add multiple steps to be executed in a sequence, you can also use something called hooks
that will be attached to each step in the workflow
Suppose you have the following scenario:
you have three steps, and each step, and each step does specific action and you want to log the input and the output for each step, in this case you can attach hooks which are type of functions that can be executed before executing the step or after executing it
Example
const workflow = Workflow.NewWorkflow()
const stepOne = () => {
// do implementation for step one here
}
const stepTwo = () => {
// do implementation for step two here
}
const loggerHook = (inp) => {
console.log('=============== logger', inp);
return inp;
}
workflow.addStep({
func: stepOne,
}, {
type: HookType.before,
func: loggerHook,
})
workflow.addStep({
func: stepTwo,
}, {
type: HookType.before,
func: loggerHook
})
Each hook is an object that has multiple fields, type
which is the hook type, func
field which is the function that will be executed as a hook, and options
which is some options to decide the hook behavior
Step Fields
field | value type | required | description |
---|---|---|---|
type | before , after , workflowError , stepError | true | the type of the hook to be executed before or after the step execution |
func | function | true | the function that should be executed in this step |
options | object | false | this is an optional object contains some configuration for the step |
Options Object
field | value type | required | default value | description |
---|---|---|---|---|
readFromOriginalInput | boolean | false | false | if sat to true, it will read from the original input not from the output of the previous step |
defaultReturningInput | boolean | false | false | if sat to true and there is no result returned from this hook, the workflow will automatically return the input of this hook as its result |
Note the following
before
type will change the inputs of the stepbefore
hooks are executed in a sequence with FIFO order before executing the step functionafter
hooks are executed in setImmediate mode to enable the workflow to execute the rest of stepsafter
hooks doesn't affect other steps inputsdefaultReturningInput
this option doesn't take effect on hooks with after
typeyou can use hooks to do the following "not limited to":
after
type to the step without affecting the main workflow like sending emails or notificationsThis example shows you how to attach a logger before executing the workflow steps and after executing them
const workflow = Workflow.NewWorkflow();
const startLoggerStep = (...args: any) => {
console.log('started executing workflow', args);
return args;
};
const endLoggerStep = (result: number) => {
console.log('ending executing workflow', result);
return result;
};
const add1Step = (num: number): number => {
return num + 1;
}
const adder1Service = workflow.addStep(startLoggerStep).addStep(add1Step).addStep(endLoggerStep).composeAsync<number>();
(async () => {
const result = await adder1Service(1)
console.log(result);
})()
FAQs
A nodejs library for composing tiny functions together in a sequential manner
The npm package f-composer receives a total of 1 weekly downloads. As such, f-composer popularity was classified as not popular.
We found that f-composer demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Product
Socket is launching Ruby support for all users. Enhance your Rails projects with AI-powered security scans for vulnerabilities and supply chain threats. Now in Beta!
Product
Ensure open-source compliance with Socket’s License Enforcement Beta. Set up your License Policy and secure your software!
Product
We're launching a new set of license analysis and compliance features for analyzing, managing, and complying with licenses across a range of supported languages and ecosystems.