/** * Core runtime package of the dynamic plugin SDK. * * @remarks * This package allows loading, managing and interpreting dynamic plugins at runtime. * * @packageDocumentation */ import type { FC } from 'react'; import type { PropsWithChildren } from 'react'; /** * The type `{}` doesn't mean "any empty object", it means "any non-nullish value". * * Use the `AnyObject` type for objects whose structure is unknown. * * @see https://github.com/typescript-eslint/typescript-eslint/issues/2063#issuecomment-675156492 */ export declare type AnyObject = Record; /** * Marks `codeRef` to be interpreted as a {@link CodeRef} function. */ export declare const applyCodeRefSymbol: (codeRef: T) => T; /** * Create new object by recursively assigning property defaults to `obj`. */ export declare const applyDefaults: (obj: TObject, defaults: unknown) => TObject; /** * Create new object by recursively assigning property overrides to `obj`. */ export declare const applyOverrides: (obj: TObject, overrides: unknown) => TObject; /** * Variation of Lodash `cloneDeep` function that keeps existing object references * for uncloneable values (functions, DOM nodes, `WeakMap` and `Error` objects). * * @see https://github.com/lodash/lodash/blob/dec55b7a3b382da075e2eac90089b4cd00a26cbb/lodash.js#L323 */ export declare const cloneDeepOnlyCloneableValues: (obj: TObject) => TObject; /** * Code reference, represented as an async function that returns the expected value. */ export declare type CodeRef = () => Promise; export declare type CodeRefsToEncodedCodeRefs = T extends CodeRef ? EncodedCodeRef : T extends (infer U)[] ? CodeRefsToEncodedCodeRefs[] : T extends object ? MapCodeRefsToEncodedCodeRefs : T; export declare type CodeRefsToValues = T extends CodeRef ? TValue : T extends (infer U)[] ? CodeRefsToValues[] : T extends object ? MapCodeRefsToValues : T; /** * {@link Logger} implementation that uses the {@link console} API. */ export declare const consoleLogger: Logger; /** * Base class for custom errors. */ export declare class CustomError extends Error { constructor(message?: string); } /** * Recursive variant of `Readonly` that supports objects and arrays. * * @see https://github.com/microsoft/TypeScript/issues/13923#issuecomment-372258196 */ export declare type DeepReadonly = T extends Primitive ? T : T extends Array ? DeepReadonlyArray : DeepReadonlyObject; export declare interface DeepReadonlyArray extends ReadonlyArray> { } export declare type DeepReadonlyObject = { readonly [K in keyof T]: DeepReadonly; }; /** * Either TypeA properties or TypeB properties -- never both. * * @example * ```ts * type MyType = EitherNotBoth<{ foo: boolean }, { bar: boolean }>; * * // Valid usages: * const objA: MyType = { * foo: true, * }; * const objB: MyType = { * bar: true, * }; * * // TS Error -- can't have both properties: * const objBoth: MyType = { * foo: true, * bar: true, * }; * * // TS Error -- must have at least one property: * const objNeither: MyType = { * }; * ``` */ export declare type EitherNotBoth = (TypeA & Never) | (TypeB & Never); /** * Either TypeA properties or TypeB properties or neither of the properties -- never both. * * @example * ```ts * type MyType = EitherOrNone<{ foo: boolean }, { bar: boolean }>; * * // Valid usages: * const objA: MyType = { * foo: true, * }; * const objB: MyType = { * bar: true, * }; * const objNeither: MyType = { * }; * * // TS Error -- can't have both properties: * const objBoth: MyType = { * foo: true, * bar: true, * }; * ``` */ export declare type EitherOrNone = EitherNotBoth | (Never & Never); /** * Code reference, encoded as an object literal for JSON serialization purposes. * * The value of `$codeRef` property should be formatted as either `moduleName.exportName` * (refers to the module's named export) or `moduleName` (refers to the module's `default` * export). */ export declare type EncodedCodeRef = { $codeRef: string; }; /** * Modify `TExtension` type by replacing `CodeRef` property values with `EncodedCodeRef` values. */ export declare type EncodedExtension = ReplaceProperties, MapCodeRefsToEncodedCodeRefs>>; }>; /** * An extension of your application. * * Each extension instance extends the application's functionality in a specific way. * A plugin consists of one or more extension instances that, combined together, adapt * or extend the base application's functionality. * * The `type` property determines the kind of the extension, while the `properties` * object contains data and/or code necessary to interpret the given extension type. * * We recommend using a structured extension type format, for example: * ```js * app.page/route // adds new route that renders the given page component * app.page/resource/list // adds new list page for the given resource * app.page/resource/details // adds new details page for the given resource * ``` * * The `properties` object may contain code references represented as {@link CodeRef} * values. Each code reference should be resolved (e.g. referenced value loaded over * the network via `import()` function) only when needed. Therefore, any code reference * resolution errors should be handled as part of interpreting the given extension type. * * Extensions may also use feature flags to express condition(s) of their enablement. * * @see {@link ExtensionFlags} */ export declare type Extension = { type: TType; properties: TProperties; flags?: ExtensionFlags; [customProperty: string]: unknown; }; /** * An extension's feature flag requirements. * * In order for an extension to be in use: * - for every flag name in `required` list - flag value must be `true` * - for every flag name in `disallowed` list - flag value must be `false` or `undefined` */ export declare type ExtensionFlags = Partial<{ required: string[]; disallowed: string[]; }>; /** * Type guard that acts as a predicate to filter extensions of a specific type. */ export declare type ExtensionPredicate = (e: Extension) => e is TExtension; /** * Infer the properties type from extension type `T`. */ export declare type ExtractExtensionProperties = T extends Extension ? TProperties : never; /** * Internal entry on a plugin in `failed` state. */ export declare type FailedPlugin = { manifest: DeepReadonly; errorMessage: string; errorCause?: unknown; }; /** * Information on a plugin in `failed` state. * * Plugins in this state failed to load or get processed properly. */ export declare type FailedPluginInfoEntry = { status: 'failed'; } & Pick; /** * Feature flags used to control enablement of all extensions. */ export declare type FeatureFlags = { [flagName: string]: FeatureFlagValue; }; /** * Feature flag value type. * * If a flag requires asynchronous resolution, its value may be `undefined` until * the resolution is complete. Flags with `undefined` values represent known feature * flags which are not resolved yet. */ export declare type FeatureFlagValue = boolean | undefined; /** * Checks if the given object is a valid {@link CodeRef} function. */ export declare const isCodeRef: (obj: unknown) => obj is CodeRef; /** * Checks if the given object is a valid {@link EncodedCodeRef} object. */ export declare const isEncodedCodeRef: (obj: unknown) => obj is EncodedCodeRef; /** * Runtime extension interface, with `CodeRef` property values resolved to `T` values. */ export declare type LoadedAndResolvedExtension = LoadedExtension>; /** * Runtime extension interface, exposing additional metadata. * * The value of `uid` property is guaranteed to be unique for each extension instance. * This value can be used when rendering associated React JSX elements that require the * `key` prop. */ export declare type LoadedExtension = TExtension & { pluginName: string; uid: string; }; /** * Internal entry on a plugin in `loaded` state. */ export declare type LoadedPlugin = { manifest: DeepReadonly; loadedExtensions: ReadonlyArray>; entryModule?: PluginEntryModule; enabled: boolean; disableReason?: string; }; /** * Information on a plugin in `loaded` state. * * Plugins in this state were successfully loaded and processed. */ export declare type LoadedPluginInfoEntry = { status: 'loaded'; } & Pick; /** * Plugin manifest created directly by your application. * * Code references within each extension's properties should be represented as `CodeRef` * functions, i.e. there is no JSON deserialization of code references for plugins loaded * from local manifests. * * This is the local representation of a plugin manifest; you can use it to implement the * concept of plugins which are statically linked to the host application at its build time. * * Note that plugins defined this way will have no entry module and no exposed modules. */ export declare type LocalPluginManifest = PluginRuntimeMetadata & { extensions: Extension[]; registrationMethod: 'local'; }; export declare type LogFunction = (message?: any, ...optionalParams: any[]) => void; /** * Minimal logger interface. */ export declare type Logger = Record<'info' | 'warn' | 'error', LogFunction>; export declare type MapCodeRefsToEncodedCodeRefs = { [K in keyof T]: CodeRefsToEncodedCodeRefs; }; export declare type MapCodeRefsToValues = { [K in keyof T]: CodeRefsToValues; }; /** * Never allow any properties of `T`. * * Utility type, probably never a reason to export. */ export declare type Never = { [K in keyof T]?: never; }; /** * Parse data from the {@link EncodedCodeRef} object. * * Returns `undefined` if the `$codeRef` value is malformed or missing. */ export declare const parseEncodedCodeRef: (ref: EncodedCodeRef) => { moduleName: string; exportName: string; } | undefined; /** * Internal entry on a plugin in `pending` state. */ export declare type PendingPlugin = { manifest: DeepReadonly; }; /** * Information on a plugin in `pending` state. * * Plugins in this state are currently being loaded. */ export declare type PendingPluginInfoEntry = { status: 'pending'; } & Pick; /** * This interface can be extended by the host application to type the * {@link PluginRuntimeMetadata.customProperties} object to reflect supported * application or environment specific properties. * * @example * ``` * // in your d.ts declaration file * import type { SupportedCustomProperties } from './types'; * * declare module '@openshift/dynamic-plugin-sdk' { * interface PluginCustomProperties extends SupportedCustomProperties {} * } * ``` */ export declare interface PluginCustomProperties { } /** * Remote webpack container interface. * * @see https://webpack.js.org/concepts/module-federation/#dynamic-remote-containers */ export declare type PluginEntryModule = { /** Initialize the container with shared modules. */ init: (sharedScope: AnyObject) => void | Promise; /** Get a module exposed through the container. */ get: (moduleRequest: string) => Promise<() => TModule>; }; export declare enum PluginEventType { /** * Triggers when the list of extensions, which are currently in use, changes. * * See the `getExtensions` function for details on evaluating extensions which are * currently in use. * * Associated data getter: {@link PluginStoreInterface.getExtensions} */ ExtensionsChanged = "ExtensionsChanged", /** * Triggers on changes which have an impact on current plugin information: * - plugin was successfully loaded, processed and added to the `PluginStore` * - plugin failed to load, or there was an error while processing the plugin * - plugin was enabled or disabled * * This may also trigger event {@link PluginEventType.ExtensionsChanged} in response * to enabling or disabling a plugin. * * Associated data getter: {@link PluginStoreInterface.getPluginInfo} */ PluginInfoChanged = "PluginInfoChanged", /** * Triggers when feature flags have changed. * * This may also trigger event {@link PluginEventType.ExtensionsChanged} in response * to re-evaluating extensions which are currently in use based on new feature flags. * * Associated data getter: {@link PluginStoreInterface.getFeatureFlags} */ FeatureFlagsChanged = "FeatureFlagsChanged" } export declare type PluginInfoEntry = PendingPluginInfoEntry | LoadedPluginInfoEntry | FailedPluginInfoEntry; /** * Loads plugin assets from remote sources. */ export declare class PluginLoader implements PluginLoaderInterface { private readonly options; /** Plugins processed by this loader. */ private readonly plugins; private readonly loadListeners; constructor(options?: PluginLoaderOptions); private invokeLoadListeners; loadPluginManifest(manifestURL: string): Promise; transformPluginManifest(manifest: T): T; /** * @remarks * * In order to load plugins using the `callback` registration method, the host application * must register a global entry callback function to be called by the plugin's entry script. * This function should be called with two arguments: plugin name and entry module object. * * In order to load plugins using the `custom` registration method, the host application must * provide a way to retrieve the entry module that was loaded by the plugin's entry script. * If not implemented properly, plugins using this registration method will fail to load. * * For plugins loaded from a local plugin manifest, the `entryModule` will be `undefined`. * * @see {@link PluginLoaderOptions.entryCallbackSettings} * @see {@link PluginLoaderOptions.getPluginEntryModule} */ loadPlugin(manifest: PluginManifest): Promise; /** * Load all scripts of the given plugin. */ private loadPluginScripts; /** * Initialize the plugin with provided shared modules. */ private initSharedModules; private getCurrentPluginResolutions; /** * Resolve all dependencies of the given plugin. * * Fail early if there are any unsuccessful or unmet dependency resolutions. */ private resolvePluginDependencies; private createPluginEntryCallback; /** * Register the global callback function used by plugin entry scripts. * * This must be called in order to load plugins using the `callback` registration method. */ registerPluginEntryCallback(): void; } /** * Common interface implemented by the `PluginLoader`. */ export declare type PluginLoaderInterface = { /** * Load a plugin manifest from the given URL. * * The implementation should also perform basic validation of the manifest object. */ loadPluginManifest: (manifestURL: string) => Promise; /** * Transform the plugin manifest before loading the associated plugin. * * This method can also be used to perform custom validation of the manifest object. */ transformPluginManifest: (manifest: T) => T; /** * Load a plugin from the given manifest. * * The implementation is responsible for decoding any code references in extensions * listed in the plugin manifest (except when loading from a local plugin manifest). * * The resulting Promise never rejects; any plugin load error(s) will be contained * within the {@link PluginLoadResult} object. */ loadPlugin: (manifest: PluginManifest) => Promise; }; export declare type PluginLoaderOptions = Partial<{ /** * Control whether a plugin can be loaded from the given manifest. * * The `reload` argument indicates whether an already loaded plugin is to be reloaded. * * By default, all plugins are allowed to be loaded and reloaded. */ canLoadPlugin: (manifest: PluginManifest, reload: boolean) => boolean; /** * Control whether the given plugin script can be reloaded when attempting to reload * the associated plugin. * * By default, all plugin scripts are allowed to be reloaded. */ canReloadScript: (manifest: RemotePluginManifest, scriptName: string) => boolean; /** * Customize the global callback function used by plugin entry scripts. * * This option applies only to plugins using the `callback` registration method. */ entryCallbackSettings: Partial<{ /** * Control whether to register the callback function. * * Default value: `true`. */ registerCallback: boolean; /** * Name of the callback function. * * Default value: `__load_plugin_entry__`. */ name: string; }>; /** * Custom resource fetch implementation. * * The custom implementation may specify any host application or environment specific * request headers that are necessary to fetch plugin resources over the network. * * By default, a basic {@link fetch} API based implementation is used. */ fetchImpl: ResourceFetch; /** * Custom resolutions for processing plugin dependencies. * * This option allows the host application to support additional application or environment * specific (i.e. non-plugin) dependencies when loading its plugins. Entries with invalid * semver string values will be discarded. * * When not specified, plugins may only depend on other plugins. * * Default value: empty object. * * @example * ```js * customDependencyResolutions: { * // Plugins may depend on sample-app, resolved version will be 1.0.0 * 'sample-app': '1.0.0', * } * ``` */ customDependencyResolutions: Record; /** * Allow the host application to bypass resolution of dependencies. * * By default, all dependencies are considered to be resolvable. */ isDependencyResolvable: (depName: string, isOptional: boolean) => boolean; /** * webpack share scope object for initializing `PluginEntryModule` containers. * * Host applications built with webpack should use dedicated webpack specific APIs * such as `__webpack_init_sharing__` and `__webpack_share_scopes__` to initialize * and access this object. * * Default value: empty object. * * @see https://webpack.js.org/concepts/module-federation/#dynamic-remote-containers */ sharedScope: AnyObject; /** * Transform the plugin manifest before loading the associated plugin. * * By default, no transformation is performed on the manifest. */ transformPluginManifest: (manifest: T) => T; /** * Provide access to the plugin's entry module. * * This option applies only to plugins using the `custom` registration method. * * For example, if a plugin was built with `var` library type (i.e. its entry module is * assigned to a global variable), you can access the entry module as `window[pluginName]`. * * By default, this function does nothing. */ getPluginEntryModule: (manifest: RemotePluginManifest) => PluginEntryModule | void; }>; export declare type PluginLoadResult = { success: true; loadedExtensions: LoadedExtension[]; entryModule?: PluginEntryModule; } | { success: false; errorMessage: string; errorCause?: unknown; }; export declare type PluginManifest = RemotePluginManifest | LocalPluginManifest; /** * Runtime plugin metadata. * * There can be only one plugin with the given `name` loaded at any time. * * Any dependencies on other plugins will be resolved as part of the plugin's load process. * * The `customProperties` object may contain additional information to be interpreted by the host * application. We recommend scoping related application or environment specific properties under * the same key, for example: * * ```js * customProperties: { * sampleApp: { * // Custom properties supported by the sample application * } * } * ``` */ export declare type PluginRuntimeMetadata = { name: string; version: string; dependencies?: Record; optionalDependencies?: Record; customProperties?: PluginCustomProperties; }; /** * Manages plugins and their extensions. */ export declare class PluginStore implements PluginStoreInterface { private readonly options; private readonly loader; private readonly pendingPromises; /** Plugins that are currently being loaded. */ private readonly pendingPlugins; /** Plugins that were successfully loaded and processed. */ private readonly loadedPlugins; /** Plugins that failed to load or get processed properly. */ private readonly failedPlugins; /** Extensions which are currently in use. */ private extensions; /** Subscribed event listeners. */ private readonly listeners; /** Feature flags used to control enablement of all extensions. */ private featureFlags; readonly sdkVersion: string; constructor(options?: PluginStoreOptions & PluginStoreLoaderSettings); subscribe(eventTypes: PluginEventType[], listener: VoidFunction): VoidFunction; private invokeListeners; getExtensions(): LoadedExtension[]; getPluginInfo(): PluginInfoEntry[]; getFeatureFlags(): { [flagName: string]: FeatureFlagValue; }; setFeatureFlags(newFlags: FeatureFlags): void; loadPlugin(manifest: PluginManifest | string, forceReload?: boolean): Promise; private setPluginsEnabled; enablePlugins(pluginNames: string[]): void; disablePlugins(pluginNames: string[], disableReason?: string): void; private isExtensionInUse; private updateExtensions; protected addPendingPlugin(manifest: PluginManifest): void; /** * @remarks * * Once added, the plugin is disabled by default. Enable it to put its extensions into use. */ protected addLoadedPlugin(manifest: PluginManifest, loadedExtensions: LoadedExtension[], entryModule?: PluginEntryModule): void; protected addFailedPlugin(manifest: PluginManifest, errorMessage: string, errorCause?: unknown): void; getExposedModule(pluginName: string, moduleName: string): Promise; } /** * Common interface implemented by the `PluginStore`. */ export declare type PluginStoreInterface = { /** * Current build version of the `@openshift/dynamic-plugin-sdk` package. */ readonly sdkVersion: string; /** * Subscribe to events emitted by the `PluginStore`. * * See {@link PluginEventType} for information on specific event types. * * Returns a function for unsubscribing the provided listener. */ subscribe: (eventTypes: PluginEventType[], listener: VoidFunction) => VoidFunction; /** * Get extensions which are currently in use. * * An extension is in use when the associated plugin is currently enabled and its * feature flag requirements (if any) are met according to current feature flags. * * If you need to enhance or modify existing extension objects after the associated * plugin has been loaded and processed, we recommend using a custom React hook which * calls `useExtensions` or `useResolvedExtensions` and returns new extension object * instances. In other words, we strongly discourage modifying the original extension * objects managed by the `PluginStore`. * * This method always returns a new array instance. */ getExtensions: () => LoadedExtension[]; /** * Get current information on all plugins. * * This method always returns a new array instance. */ getPluginInfo: () => PluginInfoEntry[]; /** * Get current feature flags. * * This method always returns a new object. */ getFeatureFlags: () => FeatureFlags; /** * Set current feature flags by merging them with `newFlags`. * * Entries with non-boolean values will be discarded. */ setFeatureFlags: (newFlags: FeatureFlags) => void; /** * Start loading a plugin from the given manifest. * * The manifest can be provided as an object or referenced by URL. When referenced * by URL, the manifest will be loaded and validated as a remote plugin manifest. * * Depending on the plugin's current load status, this method works as follows: * - plugin is still loading - do nothing * - plugin has been loaded - reload only if `forceReload` is `true` * - plugin has failed to load - always reload * * The resulting Promise resolves when the load operation is complete. If the given * plugin is still loading when this method is invoked, the same Promise instance that * represents the load operation is returned. * * The resulting Promise rejects only when the plugin manifest cannot be loaded or * processed by the `PluginLoader` implementation. * * Use the `subscribe` method to respond to events emitted by the `PluginStore`. * * Be advised that any plugin modules which are already loaded by the host application * will _not_ be replaced upon reloading the associated plugin. This is due to webpack * module caching which also applies to federated modules. If a host application detects * changes in a plugin's deployment, users should be prompted to reload the application * to ensure all plugin modules in use are up to date. */ loadPlugin: (manifest: PluginManifest | string, forceReload?: boolean) => Promise; /** * Enable the given plugin(s). * * Enabling a plugin puts all of its extensions into use. */ enablePlugins: (pluginNames: string[]) => void; /** * Disable the given plugin(s) with an optional reason. * * Disabling a plugin puts all of its extensions out of use. */ disablePlugins: (pluginNames: string[], disableReason?: string) => void; /** * Get a module exposed by the given plugin. * * The plugin is expected to be loaded from a remote plugin manifest. */ getExposedModule: (pluginName: string, moduleName: string) => Promise; }; export declare type PluginStoreLoaderSettings = EitherNotBoth<{ /** * Options passed to `PluginLoader` instance created by the `PluginStore`. */ loaderOptions?: PluginLoaderOptions; }, { /** * Custom `PluginLoader` implementation to be used by the `PluginStore`. */ loader: PluginLoaderInterface; }>; export declare type PluginStoreOptions = Partial<{ /** * Control whether to enable plugins automatically once they are loaded. * * Default value: `true`. */ autoEnableLoadedPlugins: boolean; }>; /** * React Context provider for passing the {@link PluginStore} down the component tree. */ export declare const PluginStoreProvider: FC; export declare type PluginStoreProviderProps = PropsWithChildren<{ store: PluginStoreInterface; }>; /** * Union of all primitive types. * * With strict null checks enabled, `null` and `undefined` must be explicitly included. */ export declare type Primitive = string | number | bigint | boolean | symbol | null | undefined; /** * Plugin manifest generated as part of the plugin's webpack build. * * The `extensions` list contains all extensions contributed by the plugin. Code references * within each extension's properties are serialized as JSON objects `{ $codeRef: string }`. * * The `baseURL` should be used when loading all plugin assets, including the ones listed * in `loadScripts`. * * This is the standard representation of a plugin manifest; we load the specified scripts * from remote sources in order to initialize the plugin and provide access to its exposed * modules. */ export declare type RemotePluginManifest = PluginRuntimeMetadata & { baseURL: string; extensions: Extension[]; loadScripts: string[]; registrationMethod: 'callback' | 'custom'; buildHash?: string; }; /** * Replace existing direct properties of `T` with ones declared in `R`. */ export declare type ReplaceProperties = { [K in keyof T]: K extends keyof R ? R[K] : T[K]; }; /** * Modify `TExtension` type by replacing `CodeRef` property values with `T` values. */ export declare type ResolvedExtension = ReplaceProperties, MapCodeRefsToValues>>; }>; /** * An implementation of {@link fetch} that fetches a resource over HTTP * and returns the {@link Response} object. */ export declare type ResourceFetch = (url: string, requestInit?: RequestInit) => Promise; /** * `PluginStore` implementation intended for testing purposes. */ export declare class TestPluginStore extends PluginStore { addPendingPlugin(...args: Parameters): void; addLoadedPlugin(...args: Parameters): void; addFailedPlugin(...args: Parameters): void; } /** * React hook that provides extensions which are currently in use. * * An extension is in use when the associated plugin is currently enabled and its * feature flag requirements (if any) are met according to current feature flags. * * The optional `predicate` parameter may be used to filter resulting extensions. * * This hook re-renders the component whenever the list of matching extensions changes. * * The hook's result is guaranteed to be referentially stable across re-renders, assuming referential * stability of the `predicate` parameter. * * @example * ```tsx * const MyComponent = () => { * const extensions = useExtensions(isSampleAppExtension); * * const renderExtensions = extensions.map((e) => ( *
* {e.properties.text} *
* )); * * return renderExtensions; * }; * ``` */ export declare const useExtensions: (predicate?: ExtensionPredicate) => LoadedExtension[]; /** * React hook that provides access to a feature flag. * * This hook re-renders the component whenever the value of the given flag is updated. * * The hook's result is guaranteed to be referentially stable across re-renders. * * @example * ```ts * const [flag, setFlag] = useFeatureFlag('FOO'); * setFlag(true); * ``` */ export declare const useFeatureFlag: (name: string) => UseFeatureFlagResult; export declare type UseFeatureFlagResult = [ currentValue: FeatureFlagValue, setValue: (newValue: FeatureFlagValue) => void ]; /** * React hook that provides current information on all plugins. * * This hook re-renders the component whenever the plugin information changes. * * The hook's result is guaranteed to be referentially stable across re-renders. */ export declare const usePluginInfo: () => PluginInfoEntry[]; /** * React hook that provides access to the {@link PluginStore} functionality. */ export declare const usePluginStore: () => PluginStoreInterface; /** * React hook that resolves all code references in the provided extensions. * * Resolving code references to their corresponding values is an asynchronous operation. Initially, * this hook returns a pending result tuple `[resolvedExtensions: [], resolved: false, errors: []]`. * * Once the resolution is complete, this hook re-renders the component with a result tuple containing * extensions that had their code references resolved successfully along with any errors that occurred * during the process. * * When the list of provided extensions changes, the resolution is restarted. In such case, the hook * will _not_ re-render the component with empty initial result since it's preferable to use existing * state until the current resolution completes. * * This hook supports an options argument to customize its default behavior. * * The hook's result is guaranteed to be referentially stable across re-renders, assuming referential * stability of all hook parameters. * * @example * ```tsx * const MyComponent = () => { * const extensions = useExtensions(isSampleAppExtension); * const [resolvedExtensions, resolved] = useResolvedExtensions(extensions); * * let renderExtensions = null; * * if (resolved) { * renderExtensions = resolvedExtensions.map((e) => ( *
* *
* )); * } * * return renderExtensions; * }; * ``` * * @see {@link useExtensions} */ export declare const useResolvedExtensions: (extensions?: LoadedExtension[], options?: UseResolvedExtensionsOptions) => UseResolvedExtensionsResult; export declare type UseResolvedExtensionsOptions = Partial<{ /** * Control how to deal with extensions that have code reference resolution errors. * * - `true` - include these extensions in the hook's result * - `false` - do not include these extensions in the hook's result * * Note that each code reference resolution error will cause the associated property value to be * set to `undefined`. Therefore, set this option to `true` only if the code that interprets the * extensions is able to deal with potentially `undefined` values within the `properties` object. * * Default value: `false`. */ includeExtensionsWithResolutionErrors: boolean; }>; export declare type UseResolvedExtensionsResult = [ resolvedExtensions: LoadedAndResolvedExtension[], resolved: boolean, errors: unknown[] ]; /** * Recursive equivalent of Lodash `forOwn` function that traverses objects and arrays. */ export declare const visitDeep: (obj: AnyObject, predicate: (value: unknown) => value is TValue, valueCallback: (value: TValue, key: string, container: AnyObject) => void, isObject?: (obj: unknown) => obj is AnyObject) => void; export { }