Creating Hooks.

Hook management solution.

Usage Documentation for Befter

Introduction

Befter is a simple and effective JavaScript library for managing hooks in your applications. It provides a way to add hooks to specific labels and manage them efficiently, allowing you to execute, update, and remove hooks dynamically. Befter also supports before and after hooks, enabling more complex workflows.

Core APIs and Usage

Creating befter

createBefter()

Definition

The createBefter function is used to create a new hook manager. It returns an object that can hold various hooks associated with labels.

Hook Options

The HookOptions interface allows customization of the hook system within createBefter, including execution behavior, storage type, and Redis configuration.

type HookFunctionRunner = "serial" | "parallel";

interface HookOptions {
  afterRunner?: HookFunctionRunner;
  beforeRunner?: HookFunctionRunner;
  runner?: HookFunctionRunner;
  storage?: Storage;
}

interface Storage {
  type: "local" | "redis";
  url?: string;
  client?: RedisClient; // or any client that we support refer to client section
}
  • afterRunner – Defines how after hooks run ("serial" or "parallel").
  • beforeRunner – Defines how before hooks run ("serial" or "parallel").
  • runner – Controls execution mode for all hooks unless overridden ("serial" or "parallel").
  • storage – Determines where hooks are stored with a type of ("local" for in-memory, "redis" for Redis storage) and url or client if any type is other than local which somehow needs a client.

Usage

import { createBefter, hook, callHook } from "@farming-labs/befter";
const hooks = createBefter({});
  • Arguments: None. - No options
  • Returns: An object representing the hook manager.

Storage Options

Befter supports the following storage options:

  • Local: Stores hooks in-memory, suitable for single-instance applications and illustrated on above examples.
  • Redis: Stores hooks in a Redis database, enabling distributed hook execution across multiple instances

Real-World Example

In a larger application, you would call createBefter() to initialize your hook manager:

// Using Redis storage
import { createBefter, hook } from "@farming-labs/befter";
import { createClient } from "redis";

// using redis locally
const redisClient = createClient({ url: "redis://localhost:6379" });
await redisClient.connect();

// Initialize the hook manager
const hooks = createBefter({
  storage: {
    type: "redis",
    url: "redis://localhost:6379",
    client: redisClient,
  },
});

await hook(hooks, "hook1", () => console.log("This is a Redis hook"));
// Initialize the hook manager
const hooks = createBefter();

Hooking a function

hook(hooks, label, fn)

Definition

The hook function allows you to associate a hook function with a specific label. This function will be stored in the hook manager, and you can call it later. Befter supports multiple storage backends, including Redis, enabling distributed hook management.

Usage

const { currHook, removeHook } = await hook(hooks, "hook1", () =>
  console.log("This is a hook"),
);
  • Arguments:
    • hooks (Object): The hook manager object.
    • label (String): A label to associate with the hook.
    • fn (Function): The function to be executed when the hook is called.
      • This could also be an array of fn (function) to be excuted serially by default but could be parallel based on your config. See here.
  • Returns: An object containing:
    • currHook: The current list of functions for the specified label.
    • removeHook: A function used to remove a specific hook.

Real-World Example

Imagine you need to handle form submission and want to execute hooks before and after the form is submitted:

const hooks = createBefter();

// Add a hook for form submission
await hook(hooks, "formSubmit", () => console.log("Form submitted!"));