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 🙏

© 2026 – Pkg Stats / Ryan Hefner

jerk-hooked-lib

v2.0.0

Published

Sistema de Hooks y Filters para el Framework JERK

Readme

Hooked Lib 2.0

Hooked Lib Logo

Description / Descripción

Hooked Lib is a lightweight library that allows implementing extensibility patterns through hooks and filters, similar to those used in WordPress. It enables developers to extend the functionality of their applications without modifying the core code.

Hooked Lib es una biblioteca ligera que permite implementar patrones de extensibilidad mediante hooks y filtros, similar a los utilizados en WordPress. Permite a los desarrolladores extender la funcionalidad de sus aplicaciones sin modificar el código base.

Official Page / Página oficial: https://jerk.page.gd/

Installation / Instalación

# Using npm
# Usando npm
npm install jerk-hooked-lib

# Or copy the hooks.js file to your project
# O copia el archivo hooks.js a tu proyecto

Basic Usage / Uso Básico

Import the library / Importar la biblioteca

// After installing via npm
// Después de instalar vía npm
const HookSystem = require('jerk-hooked-lib');
const hooks = new HookSystem();

// Or using ES6 modules
// O usando módulos ES6
import HookSystem from 'jerk-hooked-lib';
const hooks = new HookSystem();

// Or if you copied the hooks.js file to your project
// O si copiaste el archivo hooks.js a tu proyecto
const HookSystem = require('./hooks.js');
const hooks = new HookSystem();

Register and execute actions / Registrar y ejecutar acciones

// Register an action / Registrar una acción
hooks.addAction('greeting', function(name) {
  console.log(`Hello, ${name}!`);
});

// Execute the action / Ejecutar la acción
hooks.doAction('greeting', 'John');
// Output: Hello, John! / Salida: Hello, John!

// Registrar una acción
hooks.addAction('saludo', function(nombre) {
  console.log(`¡Hola, ${nombre}!`);
});

// Ejecutar la acción
hooks.doAction('saludo', 'Juan');
// Salida: ¡Hola, Juan!

Register and apply filters / Registrar y aplicar filtros

// Register a filter / Registrar un filtro
hooks.addFilter('uppercase', function(text) {
  return text.toUpperCase();
});

// Apply the filter / Aplicar el filtro
let result = hooks.applyFilters('uppercase', 'hello world');
// result = 'HELLO WORLD'

// Registrar un filtro
hooks.addFilter('mayusculas', function(texto) {
  return texto.toUpperCase();
});

// Aplicar el filtro
let resultado = hooks.applyFilters('mayusculas', 'hola mundo');
// resultado = 'HOLA MUNDO'

Full API / API Completa

addAction(hookName, callback, priority = 10, acceptedArgs = 1, identifier = null)

Registers a new action (hook) that can be executed later.

Registra una nueva acción (hook) que se puede ejecutar posteriormente.

  • hookName: Name of the hook (can include namespace like namespace::name) / Nombre del hook (puede incluir namespace como namespace::nombre)
  • callback: Function to execute when the hook is called / Función a ejecutar cuando se llame al hook
  • priority: Priority (lower executes first), defaults to 10 / Prioridad (más bajo se ejecuta primero), por defecto 10
  • acceptedArgs: Number of arguments the function accepts, defaults to 1 / Número de argumentos que acepta la función, por defecto 1
  • identifier: Optional identifier for the callback (allows removing by name) / Identificador opcional para el callback (permite eliminarlo por nombre)

doAction(hookName, ...args)

Executes all registered actions for a specific hook.

Ejecuta todas las acciones registradas para un hook específico.

  • hookName: Name of the hook to execute (can include namespace like namespace::name) / Nombre del hook a ejecutar (puede incluir namespace como namespace::nombre)
  • ...args: Arguments to pass to the callback functions / Argumentos a pasar a las funciones callback

doActionAsync(hookName, ...args)

Executes all registered actions for a specific hook asynchronously.

Ejecuta todas las acciones registradas para un hook específico de forma asíncrona.

  • hookName: Name of the hook to execute (can include namespace like namespace::name) / Nombre del hook a ejecutar (puede incluir namespace como namespace::nombre)
  • ...args: Arguments to pass to the callback functions / Argumentos a pasar a las funciones callback

addFilter(hookName, callback, priority = 10, acceptedArgs = 1, identifier = null)

Registers a new filter that can transform a value.

Registra un nuevo filtro que puede transformar un valor.

  • hookName: Name of the filter (can include namespace like namespace::name) / Nombre del filtro (puede incluir namespace como namespace::nombre)
  • callback: Function that transforms the value / Función que transforma el valor
  • priority: Priority (lower executes first), defaults to 10 / Prioridad (más bajo se ejecuta primero), por defecto 10
  • acceptedArgs: Number of arguments the function accepts, defaults to 1 / Número de argumentos que acepta la función, por defecto 1
  • identifier: Optional identifier for the callback (allows removing by name) / Identificador opcional para el callback (permite eliminarlo por nombre)

applyFilters(hookName, value, ...additionalArgs)

Applies all registered filters to a value.

Aplica todos los filtros registrados a un valor.

  • hookName: Name of the filter to apply (can include namespace like namespace::name) / Nombre del filtro a aplicar (puede incluir namespace como namespace::nombre)
  • value: Value to transform / Valor a transformar
  • ...additionalArgs: Additional arguments for the filters / Argumentos adicionales para los filtros

applyFiltersAsync(hookName, value, ...additionalArgs)

Applies all registered filters to a value asynchronously.

Aplica todos los filtros registrados a un valor de forma asíncrona.

  • hookName: Name of the filter to apply (can include namespace like namespace::name) / Nombre del filtro a aplicar (puede incluir namespace como namespace::nombre)
  • value: Value to transform / Valor a transformar
  • ...additionalArgs: Additional arguments for the filters / Argumentos adicionales para los filtros

hasAction(hookName)

Checks if there are registered actions for a specific hook.

Verifica si hay acciones registradas para un hook específico.

  • hookName: Name of the hook to check (can include namespace like namespace::name) / Nombre del hook a verificar (puede incluir namespace como namespace::nombre)

hasFilter(hookName)

Checks if there are registered filters for a specific hook.

Verifica si hay filtros registrados para un hook específico.

  • hookName: Name of the hook to check (can include namespace like namespace::name) / Nombre del hook a verificar (puede incluir namespace como namespace::nombre)

actionsCount(hookName)

Gets the number of registered actions for a specific hook.

Obtiene el número de acciones registradas para un hook específico.

  • hookName: Name of the hook (can include namespace like namespace::name) / Nombre del hook (puede incluir namespace como namespace::nombre)

filtersCount(hookName)

Gets the number of registered filters for a specific hook.

Obtiene el número de filtros registrados para un hook específico.

  • hookName: Name of the hook (can include namespace like namespace::name) / Nombre del hook (puede incluir namespace como namespace::nombre)

removeAction(hookName, callbackOrIdentifier, priority = 10)

Removes a specific action.

Elimina una acción específica.

  • hookName: Name of the hook (can include namespace like namespace::name) / Nombre del hook (puede incluir namespace como namespace::nombre)
  • callbackOrIdentifier: Callback function or identifier to remove / Función callback o identificador a eliminar
  • priority: Callback priority, defaults to 10 (optional if using identifier exclusively) / Prioridad del callback, por defecto 10 (opcional si se usa identificador exclusivamente)

removeFilter(hookName, callbackOrIdentifier, priority = 10)

Removes a specific filter.

Elimina un filtro específico.

  • hookName: Name of the filter (can include namespace like namespace::name) / Nombre del filtro (puede incluir namespace como namespace::nombre)
  • callbackOrIdentifier: Callback function or identifier to remove / Función callback o identificador a eliminar
  • priority: Callback priority, defaults to 10 (optional if using identifier exclusively) / Prioridad del callback, por defecto 10 (opcional si se usa identificador exclusivamente)

Removal by identifier / Eliminación por identificador

When calling removeAction or removeFilter with only two parameters (hookName and identifier), all callbacks with that identifier will be removed at all priorities.

Cuando se llama a removeAction o removeFilter solo con dos parámetros (hookName e identificador), se eliminarán todos los callbacks con ese identificador en todas las prioridades.

Example / Ejemplo:

// Remove all callbacks with identifier 'my_callback' regardless of priority
// Eliminar todos los callbacks con identificador 'mi_callback' sin importar la prioridad
hooks.removeAction('my_event', 'my_callback');
hooks.removeFilter('my_filter', 'my_identifier');

hooks.removeAction('mi_evento', 'mi_callback');
hooks.removeFilter('mi_filtro', 'mi_identificador');

removeAllActions(hookName)

Removes all actions of a specific hook (if a name is provided) or all actions (if no name is provided).

Elimina todas las acciones de un hook específico (si se proporciona el nombre) o todas las acciones (si no se proporciona nombre).

  • hookName: Name of the hook (optional, can include namespace like namespace::name) / Nombre del hook (opcional, puede incluir namespace como namespace::nombre)

removeAllFilters(hookName)

Removes all filters of a specific hook (if a name is provided) or all filters (if no name is provided).

Elimina todos los filtros de un hook específico (si se proporciona el nombre) o todos los filtros (si no se proporciona nombre).

  • hookName: Name of the filter (optional, can include namespace like namespace::name) / Nombre del filtro (opcional, puede incluir namespace como namespace::nombre)

Advanced Examples / Ejemplos Avanzados

Priorities / Prioridades

// Register actions with different priorities
// Registrar acciones con diferentes prioridades
hooks.addAction('event', function() {
  console.log('Will execute second (priority 5)');
}, 5);

hooks.addAction('event', function() {
  console.log('Will execute first (priority 1)');
}, 1);

hooks.addAction('event', function() {
  console.log('Will execute third (priority 10, default)');
});

hooks.doAction('event');
// Output:
// Will execute first (priority 1)
// Will execute second (priority 5)
// Will execute third (priority 10, default)

// Registrar acciones con diferentes prioridades
hooks.addAction('evento', function() {
  console.log('Se ejecutará segundo (prioridad 5)');
}, 5);

hooks.addAction('evento', function() {
  console.log('Se ejecutará primero (prioridad 1)');
}, 1);

hooks.addAction('evento', function() {
  console.log('Se ejecutará tercero (prioridad 10, por defecto)');
});

hooks.doAction('evento');
// Salida:
// Se ejecutará primero (prioridad 1)
// Se ejecutará segundo (prioridad 5)
// Se ejecutará tercero (prioridad 10, por defecto)

Multiple arguments / Múltiples argumentos

// Action that accepts multiple arguments
// Acción que acepta múltiples argumentos
hooks.addAction('user_event', function(user, action, date) {
  console.log(`${user} performed ${action} on ${date}`);
}, 10, 3); // Priority 10, accepts 3 arguments / Prioridad 10, acepta 3 argumentos

hooks.doAction('user_event', 'Peter', 'logged in', '2023-05-15');
// Output: Peter performed logged in on 2023-05-15 / Salida: Peter performed logged in on 2023-05-15

// Filtro con múltiples argumentos
hooks.addAction('evento_usuario', function(usuario, accion, fecha) {
  console.log(`${usuario} realizó ${accion} el ${fecha}`);
}, 10, 3); // Prioridad 10, acepta 3 argumentos

hooks.doAction('evento_usuario', 'Pedro', 'inicio sesión', '2023-05-15');
// Salida: Pedro realizó inicio sesión el 2023-05-15

// Filter with multiple arguments / Filtro con múltiples argumentos
hooks.addFilter('calculate_discount', function(price, percentage) {
  return price * (1 - percentage / 100);
}, 10, 2); // Priority 10, accepts 2 arguments / Prioridad 10, acepta 2 argumentos

let discountedPrice = hooks.applyFilters('calculate_discount', 100, 10);
// discountedPrice = 90

// Filtro con múltiples argumentos
hooks.addFilter('calcular_descuento', function(precio, porcentaje) {
  return precio * (1 - porcentaje / 100);
}, 10, 2); // Prioridad 10, acepta 2 argumentos

let precioConDescuento = hooks.applyFilters('calcular_descuento', 100, 10);
// precioConDescuento = 90

Filter chain / Cadena de filtros

// Register multiple filters to transform a value
// Registrar varios filtros para transformar un valor
hooks.addFilter('process_text', function(text) {
  return text.trim();
});

hooks.addFilter('process_text', function(text) {
  return text.toLowerCase();
});

hooks.addFilter('process_text', function(text) {
  return text.replace(/\s+/g, '_');
});

let result = hooks.applyFilters('process_text', '  EXAMPLE TEXT  ');
// result = 'example_text'

// Registrar varios filtros para transformar un valor
hooks.addFilter('procesar_texto', function(texto) {
  return texto.trim();
});

hooks.addFilter('procesar_texto', function(texto) {
  return texto.toLowerCase();
});

hooks.addFilter('procesar_texto', function(texto) {
  return texto.replace(/\s+/g, '_');
});

let resultado = hooks.applyFilters('procesar_texto', '  TEXTO de EJEMPLO  ');
// resultado = 'texto_de_ejemplo'

Named callback identification / Identificación de callbacks con nombres

// Register an action with identifier
// Registrar una acción con identificador
hooks.addAction('event', function() {
  console.log('Callback 1');
}, 10, 1, 'callback_one');

hooks.addAction('event', function() {
  console.log('Callback 2');
}, 5, 1, 'callback_two');

// Remove by identifier
// Eliminar por identificador
hooks.removeAction('event', 'callback_one', 10);

hooks.doAction('event');
// Output: Callback 2

// Registrar una acción con identificador
hooks.addAction('evento', function() {
  console.log('Callback 1');
}, 10, 1, 'callback_uno');

hooks.addAction('evento', function() {
  console.log('Callback 2');
}, 5, 1, 'callback_dos');

// Eliminar por identificador
hooks.removeAction('evento', 'callback_uno', 10);

hooks.doAction('evento');
// Salida: Callback 2

Asynchronous operations / Operaciones asíncronas

// Asynchronous action
// Acción asíncrona
hooks.addAction('async_event', async function(name) {
  await new Promise(resolve => setTimeout(resolve, 1000));
  console.log(`Hello ${name} after 1 second`);
});

// Execute asynchronously
// Ejecutar de forma asíncrona
await hooks.doActionAsync('async_event', 'John');

// Asynchronous filter
// Filtro asíncrono
hooks.addFilter('async_filter', async function(value) {
  await new Promise(resolve => setTimeout(resolve, 500));
  return value.toUpperCase();
});

// Apply asynchronously
// Aplicar de forma asíncrona
const result = await hooks.applyFiltersAsync('async_filter', 'hello');
// result = 'HELLO'

// Acción asíncrona
hooks.addAction('evento_async', async function(nombre) {
  await new Promise(resolve => setTimeout(resolve, 1000));
  console.log(`Hola ${nombre} después de 1 segundo`);
});

// Ejecutar de forma asíncrona
await hooks.doActionAsync('evento_async', 'Juan');

// Filtro asíncrono
hooks.addFilter('filtrar_async', async function(valor) {
  await new Promise(resolve => setTimeout(resolve, 500));
  return valor.toUpperCase();
});

// Aplicar de forma asíncrona
const resultado = await hooks.applyFiltersAsync('filtrar_async', 'hola');
// resultado = 'HOLA'

Namespaces

// Register hooks with namespaces
// Registrar hooks con namespaces
hooks.addAction('user_module::registration', function(user) {
  console.log(`User registered: ${user}`);
});

hooks.addFilter('product_module::price', function(price) {
  return price * 0.9; // 10% discount / 10% de descuento
});

// Execute hooks with namespaces
// Ejecutar hooks con namespaces
hooks.doAction('user_module::registration', 'Anna');
hooks.applyFilters('product_module::price', 100);

// Registrar hooks con namespaces
hooks.addAction('modulo_usuarios::registro', function(usuario) {
  console.log(`Usuario registrado: ${usuario}`);
});

hooks.addFilter('modulo_productos::precio', function(precio) {
  return precio * 0.9; // 10% de descuento
});

// Ejecutar hooks con namespaces
hooks.doAction('modulo_usuarios::registro', 'Ana');
hooks.applyFilters('modulo_productos::precio', 100);

Input Validation / Validación de Entradas

The library includes comprehensive input validation:

La biblioteca incluye validación exhaustiva de entradas:

  • hookName must be a non-empty string / hookName debe ser una cadena no vacía
  • callback must be a function / callback debe ser una función
  • priority must be a non-negative integer / priority debe ser un número entero no negativo
  • acceptedArgs must be a non-negative integer / acceptedArgs debe ser un número entero no negativo
  • identifier must be a string or null / identifier debe ser una cadena o null

Error Handling / Gestión de Errores

Callbacks that throw errors are individually captured to prevent interruptions in the execution of other hooks.

Los callbacks que lanzan errores son capturados individualmente para evitar interrupciones en la ejecución de otros hooks.

Examples / Ejemplos

You can find detailed examples in the examples/ directory:

Puedes encontrar ejemplos detallados en el directorio examples/:

  • examples_basic.js - Basic usage of addAction and doAction / Uso básico de addAction y doAction
  • examples_filters.js - Usage of addFilter and applyFilters / Uso de addFilter y applyFilters
  • examples_priorities.js - Handling priorities in hooks / Manejo de prioridades en hooks
  • examples_utilities.js - Utility functions like hasAction, hasFilter, etc. / Funciones de utilidad como hasAction, hasFilter, etc.
  • examples_removal_v2.js - Hook removal functions / Funciones de eliminación de hooks
  • practical_example.js - Complete example of real-world application / Ejemplo completo de aplicación real
  • examples_new_features.js - Demonstration of new features (namespaces, asynchronous operations, etc.) / Demostración de las nuevas funcionalidades (namespaces, operaciones asíncronas, etc.)
  • example_remove_by_id.js - Example of the new identifier-based removal functionality / Ejemplo de la nueva funcionalidad de eliminación por identificador

Contribution / Contribución

Contributions are welcome. If you find any issues or have improvement suggestions, please open an issue or submit a pull request.

Las contribuciones son bienvenidas. Si encuentras algún problema o tienes sugerencias de mejora, por favor abre un issue o envía un pull request.

License / Licencia

Apache 2.0