import type React from 'react'; import { CloudProviderRegistry } from '../cloudProvider/CloudProviderRegistry'; import type { OverrideRegistry } from './override.registry'; /** * This queues OverrideComponent registration until the registries are ready. */ export class RegistrationQueue { private queue: Function[] = []; private overrideRegistry: OverrideRegistry; public setRegistries(overrideRegistry: OverrideRegistry) { this.overrideRegistry = overrideRegistry; this.flush(); } public register(component: React.ComponentType, key: string, cloudProvider?: string) { this.queue.push(() => { if (!cloudProvider) { this.overrideRegistry.overrideComponent(key, component); } else { CloudProviderRegistry.overrideValue(cloudProvider, key, component); } }); this.flush(); } private flush() { if (!this.overrideRegistry || !CloudProviderRegistry) { return; } while (this.queue.length) { this.queue.splice(0, 1)[0](); } } } export const overrideRegistrationQueue = new RegistrationQueue(); /** * Registers a component as a replacement for some other component. * * This is a Class Decorator which should be applied to a React Component Class. * The component class will be used instead of the OverridableComponent with the same key. * * If an (optional) cloudProvider is specified, the component override takes effect only for that cloud provider. * * @Overrides('overrideKey', "aws") * class MyOverridingCmp extends React.Component { * render() { return

Overridden component

} * } */ export function Overrides(key: string, cloudProvider?: string) { return function >(targetComponent: T): void { overrideRegistrationQueue.register(targetComponent, key, cloudProvider); }; } /** * Registers a component as a replacement for some other component. * * This should be applied to a React Function Component, since they cannot utilize decorators. * The component class will be used instead of the OverridableComponent with the same key. * * If an (optional) cloudProvider is specified, the component override takes effect only for that cloud provider. * If not, this is the same as using the override registry to override the component. */ export const overridesComponent = (targetComponent: React.ComponentType, key: string, cloudProvider?: string) => { overrideRegistrationQueue.register(targetComponent, key, cloudProvider); };