UNPKG

cmpstr

Version:

CmpStr is a lightweight, fast and well performing package for calculating string similarity

188 lines (186 loc) 7 kB
// CmpStr v3.0.1 dev-052fa0c-250614 by Paul Köhler @komed3 / MIT License /** * Filter Utility * src/utils/Filter.ts * * This module provides a Filter class that allows for the management and application of * filters to strings based on hooks. Filters can be added, removed, paused, resumed, and * applied to input strings. Each filter has an id, a function, a priority, and options * for activation and overrideability. * * @module Utils/Filter * @author Paul Köhler (komed3) * @license MIT */ /** * The Filter class provides a way to manage and apply filters to strings based on hooks. */ class Filter { /** * A static map to hold all filters. * The key is the hook name, and the value is an array of FilterEntry objects. */ static filters = new Map(); /** * Finds a filter by its hook and id. * * @param {string} hook - The name of the hook * @param {string} id - The id of the filter * @returns {FilterEntry|undefined} - The FilterEntry if found, otherwise undefined */ static find(hook, id) { return Filter.filters.get(hook)?.find((f) => f.id === id); } /** * Adds a filter to the specified hook. * * @param {string} hook - The name of the hook * @param {string} id - The id of the filter * @param {FilterFn} fn - The filter function * @param {FilterOptions} [opt] - Additional options for the filter * @returns {boolean} - Returns true if the filter was added, false if it was not added due to override restrictions */ static add(hook, id, fn, opt = {}) { const { priority = 10, active = true, overrideable = true } = opt; // Check if the filter already exists const filter = Filter.filters.get(hook) ?? []; const index = filter.findIndex((f) => f.id === id); // If the filter already exists and is not overrideable, return false if (index >= 0) { const f = filter[index]; if (!f.overrideable) return false; filter.splice(index, 1); } // Add the new filter entry filter.push({ id, fn, priority, active, overrideable }); // Sort the filters by priority filter.sort((a, b) => a.priority - b.priority); // Update the filters map Filter.filters.set(hook, filter); return true; } /** * Removes a filter by its hook and id. * * @param {string} hook - The name of the hook * @param {string} id - The id of the filter * @returns {boolean} - Returns true if the filter was removed, false if it was not found */ static remove(hook, id) { // Get the filter array for the specified hook const filter = Filter.filters.get(hook); // If the filter array does not exist, return false if (!filter) return false; // Find the index of the filter with the specified id const index = filter.findIndex((f) => f.id === id); // If the filter is found, remove it and return true if (index >= 0) { filter.splice(index, 1); return true; } return false; } /** * Pauses a filter by its hook and id. * * @param {string} hook - The name of the hook * @param {string} id - The id of the filter * @returns {boolean} - Returns true if the filter was paused, false if it was not found */ static pause(hook, id) { // Find the filter entry by hook and id const f = Filter.find(hook, id); if (!f) return false; // Set the active property to false to pause the filter f.active = false; return true; } /** * Resumes a filter by its hook and id. * * @param {string} hook - The name of the hook * @param {string} id - The id of the filter * @returns {boolean} - Returns true if the filter was resumed, false if it was not found */ static resume(hook, id) { // Find the filter entry by hook and id const f = Filter.find(hook, id); if (!f) return false; // Set the active property to true to resume the filter f.active = true; return true; } /** * Lists all filters for a given hook. * * @param {string} hook - The name of the hook * @param {boolean} active - If true, only list active filters * @returns {string[]} - An array of filter ids */ static list(hook, active = false) { // Get the filter array for the specified hook const filter = Filter.filters.get(hook) ?? []; const list = []; // If active is true, filter the entries based on their active status for (const f of filter) if (!active || f.active) list.push(f.id); return list; } /** * Applies all active filters for a given hook to the input string(s). * * @param {string} hook - The name of the hook * @param {string|string[]} input - The input string(s) to be filtered * @returns {string|string[]} - The filtered string(s) */ static apply(hook, input) { // Get the filter array for the specified hook const filter = Filter.filters.get(hook); // If no filters are found for the hook or if no filters are active, return the input unchanged if (!filter || filter.every((f) => !f.active)) return input; // Apply each active filter function to the given string const applyOne = (s) => { for (const f of filter) if (f.active) s = f.fn(s); return s; }; // If the input is an array, apply the filter to each element, otherwise just once return Array.isArray(input) ? input.map(applyOne) : applyOne(input); } /** * Applies all active filters for a given hook to the input string(s) asynchronously. * Each filter function may return a Promise or a plain string; all are awaited in order. * * @param {string} hook - The name of the hook * @param {string|string[]} input - The input string(s) to be filtered * @returns {Promise<string|string[]>} - The filtered string(s) */ static async applyAsync(hook, input) { // Get the filter array for the specified hook const filter = Filter.filters.get(hook); // If no filters are found for the hook or if no filters are active, return the input unchanged if (!filter || filter.every((f) => !f.active)) return input; // Apply each active filter function to the given string // Support both sync and async filter functions const applyOne = async (s) => { for (const f of filter) if (f.active) s = await Promise.resolve(f.fn(s)); return s; }; // If the input is an array, apply the filter to each element, otherwise just once // Use Promise.all to handle multiple promises if input is an array return Array.isArray(input) ? Promise.all(input.map(applyOne)) : applyOne(input); } /** * Clears all filters or filters for a specific hook. * * @param {string} [hook] - Optional name of the hook to clear filters for */ static clear(hook) { // If a specific hook is provided, delete its filters if (hook) Filter.filters.delete(hook); // If no hook is provided, clear all filters else Filter.filters.clear(); } } export { Filter }; //# sourceMappingURL=Filter.js.map