/// /// import * as Redux from 'redux'; import { ThrottledStore } from './throttledStore'; import { INTERNAL_DONT_USE_SHELL_GET_APP_HOST } from './__internal'; import { CustomCreateExtensionSlot } from './extensionSlot'; export interface AnySlotKey { readonly name: string; readonly public?: boolean; } /** * A key that represents an {ExtensionSlot} of shape T that's held in the {AppHost} * Created be calling {Shell.declareSlot} * Retrieved by calling {Shell.getSlot} (scoped to specific {Shell}) * * @export * @interface SlotKey * @extends {AnySlotKey} * @template T */ export interface SlotKey extends AnySlotKey { /** * Holds no value, only triggers type-checking of T */ readonly empty?: T; /** * Application layer/layers that will restrict usage of APIs contributed by this entry point. * Layers hierarchy is defined in the host options * @See {AppHostOptions.layers} */ readonly layer?: string | string[]; /** * Version of the API that will be part of the API key unique identification */ readonly version?: number; } export { AppHostAPI } from './appHostServices'; export type ScopedStore = Pick, 'dispatch' | 'getState' | 'subscribe' | 'flush' | 'hasPendingSubscribers' | 'deferSubscriberNotifications'>; export type ReactComponentContributor = (props?: TProps) => React.ReactNode; export type ReducersMapObjectContributor = () => Redux.ReducersMapObject; export type ContributionPredicate = () => boolean; export interface EntryPointTags { [name: string]: string; } export type ShellsChangedCallback = (shellNames: string[]) => void; export type DeclarationsChangedCallback = () => void; export type UnsubscribeFromDeclarationsChanged = () => void; export type ShellBoundaryAspect = React.FunctionComponent>; /** * Application part that will receive a {Shell} when loaded into the {AppHost} * @export * @interface EntryPoint */ export interface EntryPoint { /** * Unique name that will represent this entry point in the host */ readonly name: string; readonly tags?: EntryPointTags; /** * Application layer / layers that will restrict usage of APIs contributed by this entry point. * Layers hierarchy is defined in the host options * See {AppHostOptions.layers} */ readonly layer?: string | string[]; /** * Define which API keys (a.k.a. contracts) are mandatory for this entry point to be executed * @return {SlotKey[]} API keys to wait for implementation */ getDependencyAPIs?(): SlotKey[]; /** * Define which API keys (a.k.a. contracts) this entry point is going to implement and contribute * @return {SlotKey[]} API keys that will be contributed */ declareAPIs?(): SlotKey[]; /** * Execute logic that is independent from other entry points * Most commonly - contribute APIs and state * @param {Shell} shell */ attach?(shell: Shell): void; /** * Execute logic that is dependent on other entry points * @param {Shell} shell */ extend?(shell: Shell): void; /** * Clean side effects * @param {Shell} shell */ detach?(shell: Shell): void; } export type AnyEntryPoint = EntryPoint; export type EntryPointOrPackage = AnyEntryPoint | AnyEntryPoint[]; export interface EntryPointOrPackagesMap { [name: string]: EntryPointOrPackage; } export type ExtensionItemFilter = (extensionItem: ExtensionItem) => boolean; /** * A slot/container for holding any contribution of shape T * Access to the slot is scoped to the {Shell} * * @export * @interface ExtensionSlot * @template T */ export interface ExtensionSlot { /** * a unique identifier for the slot */ readonly name: string; readonly host: AppHost; /** * Which {Shell} owns this slot */ readonly declaringShell?: Shell; /** * Add an item to the slot * * @param {Shell} shell Who owns the contributed item * @param {T} item Extension item to be added to the slot * @param {ContributionPredicate} [condition] A predicate to condition the retrieval of the item when slot items are requested with {ExtensionSlot.getItems} */ contribute(shell: Shell, item: T, condition?: ContributionPredicate): void; /** * Get all items contributed to the slot * * @param {boolean} [forceAll] Ignore items' contribution predicates and get all anyway * @return {ExtensionItem[]} All items contributed to the slot */ getItems(forceAll?: boolean): ExtensionItem[]; /** * Get the first item in the slot * * @return {ExtensionItem} The first item in the slot */ getSingleItem(): ExtensionItem | undefined; /** * Get a specific item in the slot * * @param {string} name Extension item name * @return {ExtensionItem | undefined} Extension item */ getItemByName(name: string): ExtensionItem | undefined; /** * Remove items from the slot by predicate * * @param {ExtensionItemFilter | undefined} predicate Remove all items matching this predicate */ discardBy(predicate: ExtensionItemFilter): void; } export interface PrivateExtensionSlot extends ExtensionSlot { subscribe(callback: () => void): () => void; } export interface CustomExtensionSlotHandler { contribute(fromShell: Shell, item: T, condition?: ContributionPredicate): void; discardBy(predicate: ExtensionItemFilter): void; } export interface CustomExtensionSlot extends CustomExtensionSlotHandler { readonly name: string; readonly host: AppHost; readonly declaringShell?: Shell; } /** * Item of shape T that is contributed to a slot of shape T * * @export * @interface ExtensionItem * @template T */ export interface ExtensionItem { readonly name?: string; /** * Which {Shell} owns this item */ readonly shell: Shell; /** * Contribution content */ readonly contribution: T; /** * Condition for the retrieval of this item by {ExtensionSlot.getItems} */ readonly condition: ContributionPredicate; readonly uniqueId: string; } /** * An application content container that will accept {EntryPoint} and provide registry for contracts * * @export * @interface AppHost */ export interface AppHost { /** * Get the root store of the application * * @return {ThrottledStore} */ getStore(): ThrottledStore; /** * Get an implementation of API previously contributed to the {AppHost} * * @template TAPI * @param {SlotKey} key API Key * @return {*} {TAPI} */ getAPI(key: SlotKey): TAPI; /** * Check if an API implementation has been contributed to the {AppHost} * * @template TAPI * @param {SlotKey} key API Key * @return {*} {boolean} */ hasAPI(key: SlotKey): boolean; /** * Get an extension slot defined on the host * * @template TItem * @param {SlotKey} key * @return {ExtensionSlot} */ getSlot(key: SlotKey): ExtensionSlot; /** * Check if an extension slot has been contributed to the {AppHost} * * @template TItem * @param {SlotKey} key * @return {boolean} */ hasSlot(key: SlotKey): boolean; /** * Get all the extension slots defined on the host * * @return {*} {AnySlotKey[]} */ getAllSlotKeys(): AnySlotKey[]; /** * Get all {EntryPoint}s addded to the {AppHost} * * @return {EntryPointsInfo[]} */ getAllEntryPoints(): EntryPointsInfo[]; /** * Does the {AppHost} contain a specific {Shell} * * @param {string} name * @return {boolean} */ hasShell(name: string): boolean; /** * Dynamically add {Shell}s after the host is created * * @param {EntryPointOrPackage[]} entryPointsOrPackages New packages or entry points to be added to the {AppHost} * @return {Promise} */ addShells(entryPointsOrPackages: EntryPointOrPackage[]): Promise; /** * Dynamically remove {Shell}s after the host is created * * @param {string[]} names {Shell} names to be removed * @return {Promise} */ removeShells(names: string[]): Promise; /** * Subscribe to changes in host declarations. This includes: * - API additions and removals * - Extension slot additions and removals * * @param {DeclarationsChangedCallback} callback Function to be called when host declarations change * @return {UnsubscribeFromDeclarationsChanged} Function to unsubscribe from host declarations changes */ onDeclarationsChanged(callback: DeclarationsChangedCallback): UnsubscribeFromDeclarationsChanged; onShellsChanged(callback: ShellsChangedCallback): string; removeShellsChangedCallback(callbackId: string): void; /** * Verify if there are pending entry points waiting for APIs that will never be available. * This usually happens when trying to consume a private API as a public API. * * @throws {Error} If there are pending entry points with API mismatches */ verifyPendingEntryPointsAPIsMismatch(): void; readonly log: HostLogger; readonly options: AppHostOptions; } export interface PrivateAppHost extends AppHost { executeWhenFree(identifier: string, callback: () => void): void; } export interface MonitoringOptions { enablePerformance?: boolean; readonly disableMonitoring?: boolean; readonly disableMemoization?: boolean; readonly debugMemoization?: boolean; } export interface Trace { name: string; duration: number; startTime: number; res: any; args: any[]; } export interface APILayer { level: number; name: string; } interface AppHostPlugins { extensionSlot?: { customCreateExtensionSlot: CustomCreateExtensionSlot; }; } export type { CustomCreateExtensionSlot }; export interface AppHostOptions { readonly logger?: HostLogger; readonly monitoring: MonitoringOptions; readonly layers?: APILayer[] | APILayer[][]; readonly disableLayersValidation?: boolean; readonly disableCheckCircularDependencies?: boolean; readonly enableStickyErrorBoundaries?: boolean; readonly enableReduxDevtoolsExtension?: boolean; readonly experimentalCyclicMode?: boolean; readonly shouldScopeReducers?: boolean; readonly plugins?: AppHostPlugins; } export interface MemoizeMissHit { miss: number; calls: number; hit: number; printHitMiss(): void; } export type enrichedMemoizationFunction = MemoizeMissHit & AnyFunction & _.MemoizedFunction; export interface StatisticsMemoization { func: enrichedMemoizationFunction; name: string; } export interface ContributeAPIOptions { includesNamespaces?: boolean; disableMonitoring?: boolean | (keyof TAPI)[]; } export type StateObserverUnsubscribe = () => void; export type StateObserver = (next: TSelectorAPI) => void; export interface ObservableState { subscribe(fromShell: Shell, callback: StateObserver): StateObserverUnsubscribe; current(allowUnsafeReading?: boolean): TSelectorAPI; } export type AnyFunction = (...args: any[]) => any; export type FunctionWithSameArgs = (...args: Parameters) => any; export interface Lazy { get(): T; } /** * An scoped communication terminal provided for an {EntryPoint} * in order to contribute its application content to the {AppHost} * * @export * @interface Shell * @extends {(Pick>)} */ export interface Shell extends Pick> { /** * Unique name of the matching {EntryPoint} */ readonly name: string; readonly log: ShellLogger; /** * Get store that is scoped for this {Shell} * * @template TState * @return {ScopedStore} Scoped store for this {Shell} */ getStore(): ScopedStore; /** * Are APIs ready to be requested * * @return {*} {boolean} */ canUseAPIs(): boolean; /** * Is store ready to be requested * * @return {*} {boolean} */ canUseStore(): boolean; /** * Did the execution of {EntryPoint}s' lifecycle phases (attach, detach) are done * * @return {*} {boolean} */ wasInitializationCompleted(): boolean; runLateInitializer(initializer: () => T): T; /** * Create an {ExtensionSlot} * * @template TItem * @param {SlotKey} key Key that will represent the slot (an will be used for retrieval) * @return {ExtensionSlot} Actual slot */ declareSlot(key: SlotKey): ExtensionSlot; declareCustomSlot(key: SlotKey, handler: CustomExtensionSlotHandler): CustomExtensionSlot; /** * Contribute an implementation of an API (a.k.a contract) * * @template TAPI * @param {SlotKey} key API Key that represents an interface TAPI * @param {() => TAPI} factory Create an implementation of TAPI * @param {ContributeAPIOptions} [options] Contribution options {ContributeAPIOptions} * @return {TAPI} Result of the factory execution */ contributeAPI(key: SlotKey, factory: () => TAPI, options?: ContributeAPIOptions): TAPI; /** * Contribute a Redux reducer that will be added to the host store. * Use it for slowly changing state (e.g. not changing because of mouse movement) * * @template TState * @param {ReducersMapObjectContributor} contributor */ contributeState(contributor: ReducersMapObjectContributor): void; /** * Contribute a Redux reducer that will be added to the host store * Use it for rapidly changing state (e.g. changing on every mouse movement event) * Changes to this state won't trigger the usual subscribers. * In order to subscribe to changes in this state, use the observer object returned by this function. * * @template TState * @param {ReducersMapObjectContributor} contributor * @return {TAPI} Observer object for subscribing to state changes. The observer can also be passed to {connectWithShell}. */ contributeObservableState(contributor: ReducersMapObjectContributor, selectorFactory: (state: TState) => TSelector): ObservableState; /** * Contribute the main view (root) of the application * Intended to be used by a single {Shell} in an application * * @param {Shell} fromShell Who owns the main view * @param {ReactComponentContributor} contributor Create the main view component */ contributeMainView(fromShell: Shell, contributor: ReactComponentContributor): void; contributeBoundaryAspect(component: ShellBoundaryAspect): void; /** * Create a function with internal cache until any state change in the {AppHost} store * * @template T * @param {T} func Function to build cache for * @param {FunctionWithSameArgs} resolver Key creator to index results by * @param {() => boolean} [shouldClear] Custom clear condition (if not provided, behaves like () => true) * @return {*} {(((...args: Parameters) => ReturnType) & Partial<_.MemoizedFunction> & Partial)} */ memoizeForState(func: T, resolver: FunctionWithSameArgs, shouldClear?: () => boolean): ((...args: Parameters) => ReturnType) & Partial<_.MemoizedFunction> & Partial; /** * Manually trigger clear condition for function memoized with {Shell.memoizeForState} */ flushMemoizedForState(): void; /** * Create a function with internal cache * * @template T * @param {T} func Function to build cache for * @param {FunctionWithSameArgs} resolver Key creator to index results by * @return {*} {(((...args: Parameters) => ReturnType) & Partial<_.MemoizedFunction> & Partial)} */ memoize(func: T, resolver: FunctionWithSameArgs): ((...args: Parameters) => ReturnType) & Partial<_.MemoizedFunction> & Partial; /** * Clear cache of a memoized function * * @param {(Partial<_.MemoizedFunction> & Partial)} memoizedFunction */ clearCache(memoizedFunction: Partial<_.MemoizedFunction> & Partial): void; /** * Creates a lazy-evaluated value. The function `func` is only executed once when `get` is called for the first time, * and the result is cached for subsequent calls. * * @template T * @param {F} func - The function that will be lazily evaluated. It should not take any arguments. * @returns {Lazy} An object with a `get` method that returns the lazily evaluated value of type `T`. */ lazyEvaluator>(func: F): Lazy; } export interface PrivateShell extends Shell { readonly entryPoint: EntryPoint; setDependencyAPIs(APIs: AnySlotKey[]): void; setLifecycleState(enableStore: boolean, enableAPIs: boolean, initCompleted: boolean): void; getBoundaryAspects(): ShellBoundaryAspect[]; getHostOptions(): AppHostOptions; [INTERNAL_DONT_USE_SHELL_GET_APP_HOST](): AppHost; } export interface EntryPointsInfo { readonly name: string; readonly lazy: boolean; readonly attached: boolean; } export interface EntryPointInterceptor { interceptName?(innerName: string): string; interceptTags?(innerTags?: EntryPointTags): EntryPointTags; interceptGetDependencyAPIs?(innerGetDependencyAPIs?: EntryPoint['getDependencyAPIs']): EntryPoint['getDependencyAPIs']; interceptDeclareAPIs?(innerDeclareAPIs?: EntryPoint['declareAPIs']): EntryPoint['declareAPIs']; interceptAttach?(innerAttach?: EntryPoint['attach']): EntryPoint['attach']; interceptDetach?(innerDetach?: EntryPoint['detach']): EntryPoint['detach']; interceptExtend?(innerExtend?: EntryPoint['extend']): EntryPoint['extend']; } export type LogSeverity = 'verbose' | 'debug' | 'info' | 'event' | 'warning' | 'error' | 'critical'; export type LogSpanFlag = 'begin' | 'end'; export interface HostLogger { log(severity: LogSeverity, id: string, error?: Error, keyValuePairs?: Object): void; spanChild(messageId: string, keyValuePairs?: Object): ShellLoggerSpan; spanRoot(messageId: string, keyValuePairs?: Object): ShellLoggerSpan; } export interface ShellLogger extends HostLogger { verbose(messageId: string, keyValuePairs?: Object): void; debug(messageId: string, keyValuePairs?: Object): void; info(messageId: string, keyValuePairs?: Object): void; warning(messageId: string, keyValuePairs?: Object): void; error(messageId: string, error?: Error, keyValuePairs?: Object): void; critical(messageId: string, error?: Error, keyValuePairs?: Object): void; spanChild(messageId: string, keyValuePairs?: Object): ShellLoggerSpan; spanRoot(messageId: string, keyValuePairs?: Object): ShellLoggerSpan; monitor(messageId: string, keyValuePairs: Object, monitoredCode: () => T): T; } export interface ShellLoggerSpan { end(success: boolean, error?: Error, keyValuePairs?: Object): void; } //# sourceMappingURL=API.d.ts.map