Before And After Hooks.

Hook management solution.

How to Use Before and After Hooks in Befter

In the befter module, you can register before and after hooks that will run before and after the main hook function, respectively. Here's how to use them effectively.

1. Setting Up Before Hooks

Steps to use before hooks:

  • Create a hook with a label using the hook() function.

  • Access the beforeMeta() method, which returns two things:

    1. The current list of before hooks.
    2. A function to add new before hooks.
  • Add a before hook using the provided function from beforeMeta().

Example:

import { createBefter, hook, callHook } from "@farming-labs/befter";

// Create a new hook container
const hooks = createBefter();

// Create a hook labeled "hook1" with a main function
const { beforeMeta: bf } =  await hook(hooks, "hook1", () => {
  console.log("Main function executed");
});

// Access the current before hooks list and the function to add a new one
const [currBf, addBf] = await bf();

// Add a before hook
await addBf(() => {
  console.log("Before hook executed");
});

// Call the hook, which will execute the before hook first, then the main function
await callHook(hooks, "hook1");

Expected Output

Before hook executed
Main function executed

1. Setting Up After Hooks

Steps to use after hooks:

  • Create a hook with a label using the hook() function.

  • Access the afterMeta() method, which returns two things:

    1. The current list of after hooks.
    2. A function to add new after hooks.
  • Add a after hook using the provided function from afterMeta().

Example:

import { createBefter, hook, callHook } from "@farming-labs/befter";

// Create a new hook container
const hooks = createBefter();

// Create a hook labeled "hook1" with a main function
const { afterMeta: af } = await hook(hooks, "hook1", () => {
  console.log("Main function executed");
});

// Access the current after hooks list and the function to add a new one
const [currAf, addAf] = await af();

// Add an after hook
await addAf(() => {
  console.log("After hook executed");
});

// Call the hook, which will execute the main function first, then the after hook
await callHook(hooks, "hook1");
Main function executed
After hook executed

Real-World Example Use Cases

Example 1: Task Completion Flow

In this scenario, after performing the main task (like sending an email), you may want to perform additional cleanup operations (like logging the success or updating the database).

Code Example:


import { createBefter, hook, callHook } from "@farming-labs/befter";

// Create a new hook container
const hooks = createBefter();

// Create a hook labeled "userLogin" with a main function for user login
const { beforeMeta: bf, afterMeta: af } = await hook(hooks, "userLogin", () => {
  console.log("User logged in successfully");
});

// Access the current before hooks list and the function to add a new one
const [currBf, addBf] = await bf();

// Add a before hook for authentication check
await addBf(() => {
  console.log("Checking user credentials...");
});

// Access the current after hooks list and the function to add a new one
const [currAf, addAf] = await af();

// Add an after hook to send a confirmation email
await addAf(() => {
  console.log("Sending confirmation email...");
});

// Call the hook, which will execute the before hook first, then the main function, and finally the after hook
await callHook(hooks, "userLogin");

Checking user credentials...
User logged in successfully
Sending confirmation email...

These real-world examples show how before and after hooks in Befter can be used to manage logic flow around a central action (e.g., sending emails, processing data, logging in users). By adding custom functionality before or after the main function, you can create more modular, maintainable, and flexible applications.

3. Controlling Hook Execution: Serial vs Parallel

You can control the execution of hooks by configuring them to run serially (one after another) or in parallel (concurrently). This is done by setting the runner option when calling the hook.

Serial Execution

In serial(default) execution, hooks are executed one after another in sequence.

Parallel Execution

In parallel execution, hooks are executed concurrently, improving performance when tasks can be done independently.

Example: Serial vs Parallel Execution

import { createBefter, hook, callHook } from "@farming-labs/befter";

// Create a new hook container
const hooks = createBefter();

// Hook 1 with serial after execution
const { beforeMeta: bf1, afterMeta: af1 } = await hook(hooks, "hook1", () => {
  console.log("This is hook1");
});
const [currAf1, addAf1] = await af1();
addAf1(() => {
  console.log("This is after hook1");
});

// Hook 2 with parallel after execution
const { beforeMeta: bf2, afterMeta: af2 } = await hook(hooks, "hook2", () => {
  console.log("This is hook2");
});
const [currAf2, addAf2] = await af2();
addAf2(() => {
  console.log("This is after hook2");
});

// Call hook with serial execution
await callHook(hooks, "hook1", { runner: "serial" });
//alterntively , you can do this - since it is defaulted to serial
await callHook(hooks, "hook1");


// Call hook with parallel execution
await callHook(hooks, "hook2", { runner: "parallel" });