jerk-hooked-lib
v2.0.0
Published
Sistema de Hooks y Filters para el Framework JERK
Maintainers
Readme
Hooked Lib 2.0

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 proyectoBasic 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 hookpriority: Priority (lower executes first), defaults to 10 / Prioridad (más bajo se ejecuta primero), por defecto 10acceptedArgs: Number of arguments the function accepts, defaults to 1 / Número de argumentos que acepta la función, por defecto 1identifier: 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 valorpriority: Priority (lower executes first), defaults to 10 / Prioridad (más bajo se ejecuta primero), por defecto 10acceptedArgs: Number of arguments the function accepts, defaults to 1 / Número de argumentos que acepta la función, por defecto 1identifier: 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 eliminarpriority: 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 eliminarpriority: 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 = 90Filter 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 2Asynchronous 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:
hookNamemust be a non-empty string /hookNamedebe ser una cadena no vacíacallbackmust be a function /callbackdebe ser una funciónprioritymust be a non-negative integer /prioritydebe ser un número entero no negativoacceptedArgsmust be a non-negative integer /acceptedArgsdebe ser un número entero no negativoidentifiermust be a string or null /identifierdebe 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
