# Source: registry/transforms.js

    import {RegistryBase} from './base';
    import * as transforms from '../helpers/transforms';

    /**
     * Registry of transformation functions that may be applied to template values to control how values are rendered.
     * Provides syntactic sugar atop a standard registry.
     * @public
     * @extends module:registry/base:RegistryBase
     * @inheritDoc
     */
    class TransformationFunctionsRegistry extends RegistryBase {
        /**
         * Helper function that turns a sequence of function names into a single callable
         * @param template_string
         * @return {function(*=): *}
         * @private
         */
        _collectTransforms(template_string) {
            const funcs = template_string
                .match(/\|([^|]+)/g)
                .map((item) => super.get(item.substring(1)));

            return (value) => {
                return funcs.reduce(
                    (acc, func) => func(acc),
                    value,
                );
            };
        }

        /**
         * In templates, we often use a single concatenated string to ask for several transformation functions at once:
         *  `value|func1|func2`
         * This class offers syntactical sugar to retrieve the entire sequence of transformations as a single callable
         * @param name
         */
        get(name) {
            if (!name) {
                // This function is sometimes called with no value, and the expected behavior is to return null instead of
                //  a callable
                return null;
            }
            if (name.substring(0, 1) === '|') {
                // Legacy artifact of how this function is called- if a pipe is present, this is the template string
                //  (`|func1|func2...`), rather than any one single transformation function.
                // A sequence of transformation functions is expected
                return this._collectTransforms(name);
            } else {
                // If not a template string, then user is asking for an item by name directly
                return super.get(name);
            }
        }
    }

    /**
     * A plugin registry that allows plots to use both pre-defined and user-provided transformation functions, which
     *  can be used to modify a value in the input data in a predefined way. For example, these can be used to let APIs
     *  that return p_values work with plots that display -log10(p)
     * @alias module:LocusZoom~TransformationFunctions
     * @type {TransformationFunctionsRegistry}
     */
    const registry = new TransformationFunctionsRegistry();
    for (let [name, type] of Object.entries(transforms)) {
        registry.add(name, type);
    }

    export default registry;
    // Export helper class for unit testing
    export { TransformationFunctionsRegistry as _TransformationFunctions };