import { ComponentId } from '../annotation/component'; import { Provider, ComponentFilterRegistry } from './provider-protocol'; import { Container } from '../container'; import { Prioritizeable } from '../utils'; const DEFAULT_GET_PRIORITY: Prioritizeable.GetPrioritySync = value => { if (value) { if ('priority' in value) { return value.priority; } else if ('order' in value) { return value.order; } return 0; } }; export class ContainerBasedProvider implements Provider { protected components: T[] | undefined; constructor( protected readonly componentId: ComponentId, protected readonly container: Container ) { } get(recursive?: boolean): T[] { if (this.components === undefined) { const currentComponents: T[] = []; let filterRegistry: ComponentFilterRegistry | undefined; let currentContainer: Container | null = this.container; // eslint-disable-next-line no-null/no-null while (currentContainer !== null) { if (currentContainer.isBound(this.componentId)) { try { currentComponents.push(...currentContainer.getAll(this.componentId)); } catch (error) { console.error(error); } } if (filterRegistry === undefined && currentContainer.isBound(ComponentFilterRegistry)) { filterRegistry = currentContainer.get(ComponentFilterRegistry); } // eslint-disable-next-line no-null/no-null currentContainer = recursive === true ? currentContainer.parent : null; } this.components = filterRegistry ? filterRegistry.applyFilters(currentComponents, this.componentId) : currentComponents; } return this.components; } sortSync(getPriority: Prioritizeable.GetPrioritySync = DEFAULT_GET_PRIORITY, recursive?: boolean): T[] { this.components = Prioritizeable.prioritizeAllSync(this.get(recursive), getPriority).map(c => c.value); return this.components; } async sort(getPriority: Prioritizeable.GetPriority = DEFAULT_GET_PRIORITY, recursive?: boolean): Promise { const result = await Prioritizeable.prioritizeAll(this.get(recursive), getPriority); this.components = result.map(c => c.value); return this.components; } }