import { Obj } from '@ephox/katamari';
import { SugarBody } from '@ephox/sugar';
import { EventRegistry } from '../events/EventRegistry';
import * as AlloyLogger from '../log/AlloyLogger';
import * as Tagger from './Tagger';
export const Registry = () => {
    const events = EventRegistry();
    // An index of uid -> built components
    const components = {};
    const readOrTag = (component) => {
        const elem = component.element;
        return Tagger.read(elem).getOrThunk(() => 
        // No existing tag, so add one.
        Tagger.write('uid-', component.element));
    };
    const failOnDuplicate = (component, tagId) => {
        const conflict = components[tagId];
        if (conflict === component) {
            unregister(component);
        }
        else {
            throw new Error('The tagId "' + tagId + '" is already used by: ' + AlloyLogger.element(conflict.element) + '\nCannot use it for: ' + AlloyLogger.element(component.element) + '\n' +
                'The conflicting element is' + (SugarBody.inBody(conflict.element) ? ' ' : ' not ') + 'already in the DOM');
        }
    };
    const register = (component) => {
        const tagId = readOrTag(component);
        if (Obj.hasNonNullableKey(components, tagId)) {
            failOnDuplicate(component, tagId);
        }
        // Component is passed through an an extra argument to all events
        const extraArgs = [component];
        events.registerId(extraArgs, tagId, component.events);
        components[tagId] = component;
    };
    const unregister = (component) => {
        Tagger.read(component.element).each((tagId) => {
            delete components[tagId];
            events.unregisterId(tagId);
        });
    };
    const filter = (type) => events.filterByType(type);
    const find = (isAboveRoot, type, target) => events.find(isAboveRoot, type, target);
    const getById = (id) => Obj.get(components, id);
    return {
        find,
        filter,
        register,
        unregister,
        getById
    };
};
//# sourceMappingURL=Registry.js.map