import * as React from 'react'; import * as ReactRouter from 'react-router'; /** * Defines the API accessible from pilets. */ export interface PiletApi extends EventEmitter, PiletCustomApi, PiletCoreApi { /** * Gets the metadata of the current pilet. */ meta: PiletMetadata; } /** * The emitter for Piral app shell events. */ export interface EventEmitter { /** * Attaches a new event listener. * @param type The type of the event to listen for. * @param callback The callback to trigger. */ on(type: K, callback: Listener): EventEmitter; /** * Attaches a new event listener that is removed once the event fired. * @param type The type of the event to listen for. * @param callback The callback to trigger. */ once(type: K, callback: Listener): EventEmitter; /** * Detaches an existing event listener. * @param type The type of the event to listen for. * @param callback The callback to trigger. */ off(type: K, callback: Listener): EventEmitter; /** * Emits a new event with the given type. * @param type The type of the event to emit. * @param arg The payload of the event. */ emit(type: K, arg: PiralEventMap[K]): EventEmitter; } /** * Custom Pilet API parts defined outside of piral-core. */ export interface PiletCustomApi extends PiletLazyApi, PiletLocaleApi, PiletDashboardApi, PiletMenuApi, PiletNotificationsApi, PiletModalsApi, PiletFeedsApi, SitelessApi {} /** * Defines the Pilet API from piral-core. * This interface will be consumed by pilet developers so that their pilet can interact with the piral instance. */ export interface PiletCoreApi { /** * Gets a shared data value. * @param name The name of the data to retrieve. */ getData(name: TKey): SharedData[TKey]; /** * Sets the data using a given name. The name needs to be used exclusively by the current pilet. * Using the name occupied by another pilet will result in no change. * @param name The name of the data to store. * @param value The value of the data to store. * @param options The optional configuration for storing this piece of data. * @returns True if the data could be set, otherwise false. */ setData(name: TKey, value: SharedData[TKey], options?: DataStoreOptions): boolean; /** * Registers a route for predefined page component. * The route needs to be unique and can contain params. * Params are following the path-to-regexp notation, e.g., :id for an id parameter. * @param route The route to register. * @param Component The component to render the page. * @param meta The optional metadata to use. */ registerPage(route: string, Component: AnyComponent, meta?: PiralPageMeta): RegistrationDisposer; /** * Unregisters the page identified by the given route. * @param route The route that was previously registered. */ unregisterPage(route: string): void; /** * Registers an extension component with a predefined extension component. * The name must refer to the extension slot. * @param name The global name of the extension slot. * @param Component The component to be rendered. * @param defaults Optionally, sets the default values for the expected data. */ registerExtension(name: TName extends string ? TName : string, Component: AnyExtensionComponent, defaults?: Partial>): RegistrationDisposer; /** * Unregisters a global extension component. * Only previously registered extension components can be unregistered. * @param name The name of the extension slot to unregister from. * @param Component The registered extension component to unregister. */ unregisterExtension(name: TName extends string ? TName : string, Component: AnyExtensionComponent): void; /** * React component for displaying extensions for a given name. * @param props The extension's rendering props. * @return The created React element. */ Extension(props: ExtensionSlotProps): React.ReactElement | null; /** * Renders an extension in a plain DOM component. * @param element The DOM element or shadow root as a container for rendering the extension. * @param props The extension's rendering props. * @return The disposer to clear the extension. */ renderHtmlExtension(element: HTMLElement | ShadowRoot, props: ExtensionSlotProps): Disposable; } /** * Describes the metadata of a pilet available in its API. */ export interface PiletMetadata { /** * The name of the pilet, i.e., the package id. */ name: string; /** * The version of the pilet. Should be semantically versioned. */ version: string; /** * Provides the version of the specification for this pilet. */ spec: string; /** * Provides some custom metadata for the pilet. */ custom?: any; /** * Optionally indicates the global require reference, if any. */ requireRef?: string; /** * Additional shared dependencies from the pilet. */ dependencies: Record; /** * Provides some configuration to be used in the pilet. */ config: Record; /** * The URL of the main script of the pilet. */ link: string; /** * The base path to the pilet. Can be used to make resource requests * and override the public path. */ basePath: string; } /** * Listener for Piral app shell events. */ export interface Listener { /** * Receives an event of type T. */ (arg: T): void; } /** * The map of known Piral app shell events. */ export interface PiralEventMap extends PiralCustomEventMap { "unload-pilet": PiralUnloadPiletEvent; [custom: string]: any; "store-data": PiralStoreDataEvent; "unhandled-error": PiralUnhandledErrorEvent; "loading-pilets": PiralLoadingPiletsEvent; "loaded-pilets": PiralLoadedPiletsEvent; } /** * Defines the provided set of lazy loading Pilet API extensions. */ export interface PiletLazyApi { /** * Defines a dependency for lazy loading. * @param name The name of the dependency. * @param loader The associated dependency loader. */ defineDependency(name: string, loader: LazyDependencyLoader): void; /** * Properly introduces a lazy loaded foreign component. * @param cb The callback to trigger when the component should be loaded. * @param deps The optional names of the dependencies to load beforehand. * @returns The lazy loading component. */ fromLazy(cb: LazyComponentLoader, deps?: Array): React.ComponentType; }>; } export interface PiletLocaleApi { /** * Adds a list of translations to the existing translations. * * Internally, setTranslations is used, which means the translations will be exclusively used for * retrieving translations for the pilet. * @param messagesList The list of messages that extend the existing translations * @param isOverriding Indicates whether the new translations overwrite the existing translations */ addTranslations(messagesList: Array, isOverriding?: boolean): void; /** * Gets the currently selected language directly. */ getCurrentLanguage(): string; /** * Gets the currently selected language in a callback that is also invoked when the * selected language changes. Returns a disposable to stop the notifications. */ getCurrentLanguage(cb: (currently: string) => void): Disposable; /** * Translates the given tag (using the optional variables) into a string using the current language. * The used template can contain placeholders in form of `{{variableName}}`. * @param tag The tag to translate. * @param variables The optional variables to fill into the temnplate. */ translate>(tag: string, variables?: T): string; /** * Provides translations to the application. * The translations will be exclusively used for retrieving translations for the pilet. * @param messages The messages to use as translation basis. */ setTranslations(messages: AnyLocalizationMessages): void; /** * Gets the currently provided translations by the pilet. */ getTranslations(): LocalizationMessages; } export interface PiletDashboardApi { /** * Registers a tile with a predefined tile components. * The name has to be unique within the current pilet. * @param name The name of the tile. * @param Component The component to be rendered within the Dashboard. * @param preferences The optional preferences to be supplied to the Dashboard for the tile. */ registerTile(name: string, Component: AnyComponent, preferences?: TilePreferences): RegistrationDisposer; /** * Registers a tile for predefined tile components. * @param Component The component to be rendered within the Dashboard. * @param preferences The optional preferences to be supplied to the Dashboard for the tile. */ registerTile(Component: AnyComponent, preferences?: TilePreferences): RegistrationDisposer; /** * Unregisters a tile known by the given name. * Only previously registered tiles can be unregistered. * @param name The name of the tile to unregister. */ unregisterTile(name: string): void; } export interface PiletMenuApi { /** * Registers a menu item for a predefined menu component. * The name has to be unique within the current pilet. * @param name The name of the menu item. * @param Component The component to be rendered within the menu. * @param settings The optional configuration for the menu item. */ registerMenu(name: string, Component: AnyComponent, settings?: MenuSettings): RegistrationDisposer; /** * Registers a menu item for a predefined menu component. * @param Component The component to be rendered within the menu. * @param settings The optional configuration for the menu item. */ registerMenu(Component: AnyComponent, settings?: MenuSettings): RegistrationDisposer; /** * Unregisters a menu item known by the given name. * Only previously registered menu items can be unregistered. * @param name The name of the menu item to unregister. */ unregisterMenu(name: string): void; } export interface PiletNotificationsApi { /** * Shows a notification in the determined spot using the provided content. * @param content The content to display. Normally, a string would be sufficient. * @param options The options to consider for showing the notification. * @returns A callback to trigger closing the notification. */ showNotification(content: string | React.ReactElement | AnyComponent, options?: NotificationOptions): Disposable; } export interface PiletModalsApi { /** * Shows a modal dialog with the given name. * The modal can be optionally programmatically closed using the returned callback. * @param name The name of the registered modal. * @param options Optional arguments for creating the modal. * @returns A callback to trigger closing the modal. */ showModal(name: T extends string ? T : string, options?: ModalOptions): Disposable; /** * Registers a modal dialog using a React component. * The name needs to be unique to be used without the pilet's name. * @param name The name of the modal to register. * @param Component The component to render the page. * @param defaults Optionally, sets the default values for the inserted options. * @param layout Optionally, sets the layout options for the dialog wrapper. */ registerModal(name: T extends string ? T : string, Component: AnyComponent>, defaults?: ModalOptions, layout?: ModalLayoutOptions): RegistrationDisposer; /** * Unregisters a modal by its name. * @param name The name that was previously registered. */ unregisterModal(name: T extends string ? T : string): void; } export interface PiletFeedsApi { /** * Creates a connector for wrapping components with data relations. * @param resolver The resolver for the initial data set. */ createConnector(resolver: FeedResolver): FeedConnector; /** * Creates a connector for wrapping components with data relations. * @param options The options for creating the connector. */ createConnector>(options: FeedConnectorOptions): FeedConnector; } export interface SitelessApi { /** * Sets layout components in the application. * @param components The components to define. */ setLayout(components: GenericComponents): void; /** * Sets errors components in the application. * @param errors The error handlers to define. */ setErrors(errors: GenericComponents): void; /** * Gets a snapshot of the current global state. * @param select The selection function to obtain the desired slice. */ readState(select: (state: GlobalState) => T): T; /** * Connects to the global state. * @param select The selection function to obtain the desired slice. */ useState(select: (state: GlobalState) => T): T; } /** * Defines the shape of the data store for storing shared data. */ export interface SharedData { [key: string]: TValue; } /** * Defines the options to be used for storing data. */ export type DataStoreOptions = DataStoreTarget | CustomDataStoreOptions; /** * Possible shapes for a component. */ export type AnyComponent = React.ComponentType | FirstParametersOf>; /** * The props used by a page component. */ export interface PageComponentProps, UrlState = any> extends RouteBaseProps { /** * The meta data registered with the page. */ meta: PiralPageMeta; /** * The children of the page. */ children: React.ReactNode; } /** * The meta data registered for a page. */ export interface PiralPageMeta extends PiralCustomPageMeta {} /** * The shape of an implicit unregister function. */ export interface RegistrationDisposer { /** * Cleans up the previous registration. */ (): void; } /** * Shorthand for the definition of an extension component. */ export type AnyExtensionComponent = TName extends keyof PiralExtensionSlotMap ? AnyComponent> : TName extends string ? AnyComponent> : AnyComponent>; /** * Gives the extension params shape for the given extension slot name. */ export type ExtensionParams = TName extends keyof PiralExtensionSlotMap ? PiralExtensionSlotMap[TName] : TName extends string ? any : TName; /** * The props for defining an extension slot. */ export type ExtensionSlotProps = BaseExtensionSlotProps>; /** * Can be implemented by functions to be used for disposal purposes. */ export interface Disposable { /** * Disposes the created resource. */ (): void; } /** * Custom events defined outside of piral-core. */ export interface PiralCustomEventMap { "select-language": PiralSelectLanguageEvent; } /** * Gets fired when a pilet gets unloaded. */ export interface PiralUnloadPiletEvent { /** * The name of the pilet to be unloaded. */ name: string; } /** * Gets fired when a data item gets stored in piral. */ export interface PiralStoreDataEvent { /** * The name of the item that was stored. */ name: string; /** * The storage target of the item. */ target: string; /** * The value that was stored. */ value: TValue; /** * The owner of the item. */ owner: string; /** * The expiration of the item. */ expires: number; } /** * Gets fired when an unhandled error in a component has been prevented. */ export interface PiralUnhandledErrorEvent { /** * The type of the error, i.e., the type of component that crashed. */ errorType: string; /** * The actual error that was emitted. */ error: Error; /** * The name of the pilet containing the problematic component. */ pilet: string; } /** * Gets fired when the loading of pilets is triggered. */ export interface PiralLoadingPiletsEvent { /** * The options that have been supplied for loading the pilets. */ options: LoadPiletsOptions; } /** * Gets fired when all pilets have been loaded. */ export interface PiralLoadedPiletsEvent { /** * The pilets that have been loaded. */ pilets: Array; /** * The loading error, if any. */ error?: Error; } export interface LazyDependencyLoader { (): Promise; } export interface LazyComponentLoader { (): Promise>; } /** * The props that every registered component obtains. */ export interface BaseComponentProps { /** * The currently used pilet API. */ piral: PiletApi; } export type AnyLocalizationMessages = LocalizationMessages | NestedLocalizationMessages; export interface LocalizationMessages { [lang: string]: Translations; } export type TileComponentProps = BaseComponentProps & BareTileComponentProps; export interface TilePreferences extends PiralCustomTilePreferences { /** * Sets the desired initial number of columns. * This may be overridden either by the user (if resizable true), or by the dashboard. */ initialColumns?: number; /** * Sets the desired initial number of rows. * This may be overridden either by the user (if resizable true), or by the dashboard. */ initialRows?: number; /** * Determines if the tile can be resized by the user. * By default the size of the tile is fixed. */ resizable?: boolean; /** * Declares a set of custom properties to be used with user-specified values. */ customProperties?: Array; } export interface MenuComponentProps extends BaseComponentProps {} export type MenuSettings = PiralCustomMenuSettings & PiralSpecificMenuSettings; export type NotificationComponentProps = BaseComponentProps & BareNotificationProps; export type NotificationOptions = PiralCustomNotificationOptions & PiralStandardNotificationOptions & PiralSpecificNotificationOptions; export type ModalOptions = T extends keyof PiralModalsMap ? PiralModalsMap[T] & BaseModalOptions : T extends string ? BaseModalOptions : T; export type ModalComponentProps = BaseComponentProps & BareModalComponentProps>; /** * The options provided for the dialog layout. */ export interface ModalLayoutOptions {} export interface FeedResolver { /** * Function to derive the initial set of data. * @returns The promise for retrieving the initial data set. */ (): Promise; } export type FeedConnector = GetActions & { /** * Connector function for wrapping a component. * @param component The component to connect by providing a data prop. */ (component: React.ComponentType>): React.FC; /** * Invalidates the underlying feed connector. * Forces a reload on next use. */ invalidate(): void; }; export interface FeedConnectorOptions = {}> { /** * Function to derive the initial set of data. * @returns The promise for retrieving the initial data set. */ initialize: FeedResolver; /** * Function to be called for connecting to a live data feed. * @param callback The function to call when an item updated. * @returns A callback for disconnecting from the feed. */ connect?: FeedSubscriber; /** * Function to be called when some data updated. * @param data The current set of data. * @param item The updated item to include. * @returns The promise for retrieving the updated data set or the updated data set. */ update?: FeedReducer; /** * Defines the optional reducers for modifying the data state. */ reducers?: TReducers; /** * Optional flag to avoid lazy loading and initialize the data directly. */ immediately?: boolean; } export interface FeedConnectorReducers { [name: string]: (data: TData, ...args: any) => Promise | TData; } export type GenericComponents = Partial<{ [P in keyof T]: T[P] extends React.ComponentType ? AnyComponent : T[P]; }>; /** * The Piral global app sub-state container for shared components. */ export interface ComponentsState extends PiralCustomComponentsState { /** * The loading indicator renderer. */ LoadingIndicator: React.ComponentType; /** * The error renderer. */ ErrorInfo: React.ComponentType; /** * The router context. */ Router: React.ComponentType; /** * The layout used for pages. */ Layout: React.ComponentType; /** * The route switch used for determining the route registration. */ RouteSwitch: React.ComponentType; /** * A component that can be used for debugging purposes. */ Debug?: React.ComponentType; } export type ErrorComponentsState = { [P in keyof Errors]?: React.ComponentType; }; /** * The Piral global app state container. */ export interface GlobalState extends PiralCustomState { /** * The relevant state for the app itself. */ app: AppState; /** * The relevant state for rendering errors of the app. */ errorComponents: ErrorComponentsState; /** * The relevant state for rendering parts of the app. */ components: ComponentsState; /** * The relevant state for the registered components. */ registry: RegistryState; /** * Gets the loaded modules. */ modules: Array; /** * The foreign component portals to render. */ portals: Record>; /** * The application's shared data. */ data: Dict; /** * The used (exact) application routes. */ routes: Dict> & { /** * The optional meta data registered with the page. */ meta?: PiralPageMeta; }>; /** * The current provider. */ provider?: React.ComponentType; } /** * Defines the potential targets when storing data. */ export type DataStoreTarget = "memory" | "local" | "remote"; /** * Defines the custom options for storing data. */ export interface CustomDataStoreOptions { /** * The target data store. By default the data is only stored in memory. */ target?: DataStoreTarget; /** * Optionally determines when the data expires. */ expires?: "never" | Date | number; } export type FirstParametersOf = { [K in keyof T]: T[K] extends (arg: any) => any ? FirstParameter : never; }[keyof T]; /** * Mapping of available component converters. */ export interface ComponentConverters extends PiralCustomComponentConverters { /** * Converts the HTML component to a framework-independent component. * @param component The vanilla JavaScript component to be converted. */ html(component: HtmlComponent): ForeignComponent; } /** * The props that every registered page component obtains. */ export interface RouteBaseProps extends BaseComponentProps { /** * The history API to navigate. */ history: History; /** * Information about the current location. */ location: Location; /** * Information about the matching of the current route. */ match: RouteMatch; } /** * Custom meta data to include for pages. */ export interface PiralCustomPageMeta {} /** * The props of an extension component. */ export interface ExtensionComponentProps extends BaseComponentProps { /** * The provided parameters for showing the extension. */ params: T extends keyof PiralExtensionSlotMap ? PiralExtensionSlotMap[T] : T extends string ? any : T; /** * The optional children to receive, if any. */ children?: React.ReactNode; } /** * The mapping of the existing (known) extension slots. */ export interface PiralExtensionSlotMap extends PiralCustomExtensionSlotMap {} /** * The basic props for defining an extension slot. */ export interface BaseExtensionSlotProps { /** * The children to transport, if any. */ children?: React.ReactNode; /** * Defines what should be rendered when no components are available * for the specified extension. */ empty?(props: TParams): React.ReactNode; /** * Determines if the `render` function should be called in case no * components are available for the specified extension. * * If true, `empty` will be called and returned from the slot. * If false, `render` will be called with the result of calling `empty`. * The result of calling `render` will then be returned from the slot. */ emptySkipsRender?: boolean; /** * Defines the order of the components to render. * May be more convient than using `render` w.r.t. ordering extensions * by their supplied metadata. * @param extensions The registered extensions. * @returns The ordered extensions. */ order?(extensions: Array): Array; /** * Defines how the provided nodes should be rendered. * @param nodes The rendered extension nodes. * @returns The rendered nodes, i.e., an ReactElement. */ render?(nodes: Array): React.ReactElement | null; /** * The custom parameters for the given extension. */ params?: TParams; /** * The name of the extension to render. */ name: TName; } export interface PiralSelectLanguageEvent { /** * Gets the previously selected language. */ previousLanguage: string; /** * Gets the currently selected language. */ currentLanguage: string; } /** * The options for loading pilets. */ export interface LoadPiletsOptions { /** * The callback function for creating an API object. * The API object is passed on to a specific pilet. */ createApi: PiletApiCreator; /** * The callback for fetching the dynamic pilets. */ fetchPilets: PiletRequester; /** * Optionally, some already existing evaluated pilets, e.g., * helpful when debugging or in SSR scenarios. */ pilets?: Array; /** * Optionally, configures the default loader. */ config?: DefaultLoaderConfig; /** * Optionally, defines the default way how to load a pilet. */ loadPilet?: PiletLoader; /** * Optionally, defines loaders for custom specifications. */ loaders?: CustomSpecLoaders; /** * Optionally, defines a set of loading hooks to be used. */ hooks?: PiletLifecycleHooks; /** * Gets the map of globally available dependencies with their names * as keys and their evaluated pilet content as value. */ dependencies?: AvailableDependencies; /** * Optionally, defines the loading strategy to use. */ strategy?: PiletLoadingStrategy; } /** * An evaluated pilet, i.e., a full pilet: functionality and metadata. */ export type Pilet = SinglePilet | MultiPilet; export interface NestedLocalizationMessages { [lang: string]: NestedTranslations; } export interface Translations { [tag: string]: string; } export interface BareTileComponentProps { /** * The currently used number of columns. */ columns: number; /** * The currently used number of rows. */ rows: number; } export interface PiralCustomTilePreferences {} export interface PiralCustomMenuSettings {} export type PiralSpecificMenuSettings = UnionOf<{ [P in keyof PiralMenuType]: Partial & { /** * The type of the menu used. */ type?: P; }; }>; export interface BareNotificationProps { /** * Callback for closing the notification programmatically. */ onClose(): void; /** * Provides the passed in options for this particular notification. */ options: NotificationOptions; } export interface PiralCustomNotificationOptions {} export interface PiralStandardNotificationOptions { /** * The title of the notification, if any. */ title?: string; /** * Determines when the notification should automatically close in milliseconds. * A value of 0 or undefined forces the user to close the notification. */ autoClose?: number; } export type PiralSpecificNotificationOptions = UnionOf<{ [P in keyof PiralNotificationTypes]: Partial & { /** * The type of the notification used when displaying the message. * By default info is used. */ type?: P; }; }>; export interface BaseModalOptions {} export interface PiralModalsMap extends PiralCustomModalsMap {} export interface BareModalComponentProps { /** * Callback for closing the modal programmatically. */ onClose(): void; /** * Provides the passed in options for this particular modal. */ options?: TOpts; } export type GetActions = { [P in keyof TReducers]: (...args: RemainingArgs) => void; }; export interface FeedConnectorProps { /** * The current data from the feed. */ data: TData; } export interface FeedSubscriber { (callback: (value: TItem) => void): Disposable; } export interface FeedReducer { (data: TData, item: TAction): Promise | TData; } /** * Custom parts of the global custom component state defined outside of piral-core. */ export interface PiralCustomComponentsState { /** * Represents the component for rendering a language selection. */ LanguagesPicker: React.ComponentType; /** * The dashboard container component. */ DashboardContainer: React.ComponentType; /** * The dashboard tile component. */ DashboardTile: React.ComponentType; /** * The menu container component. */ MenuContainer: React.ComponentType; /** * The menu item component. */ MenuItem: React.ComponentType; /** * The host component for notifications. */ NotificationsHost: React.ComponentType; /** * The notification toast component. */ NotificationsToast: React.ComponentType; /** * The host component for modal dialogs. */ ModalsHost: React.ComponentType; /** * The modal dialog component. */ ModalsDialog: React.ComponentType; } /** * The props of a Loading indicator component. */ export interface LoadingIndicatorProps {} /** * The props for the ErrorInfo component. */ export type ErrorInfoProps = UnionOf; /** * The props of a Router component. */ export interface RouterProps { /** * The content to be rendered inside the router. */ children?: React.ReactNode; /** * The public path to use. */ publicPath: string; } /** * The props of a Layout component. */ export interface LayoutProps { /** * The currently selected layout type. */ currentLayout: LayoutType; /** * The page's content. */ children: React.ReactNode; } /** * The props of the RouteSwitch component. */ export interface RouteSwitchProps extends ReactRouter.SwitchProps { /** * The component that should be used in case nothing was found. */ NotFound: React.ComponentType; /** * The component to register for the different paths. */ paths: Array; } /** * Map of all error types to their respective props. */ export interface Errors extends PiralCustomErrors { /** * The props type for an extension error. */ extension: ExtensionErrorInfoProps; /** * The props type for a loading error. */ loading: LoadingErrorInfoProps; /** * The props type for a page error. */ page: PageErrorInfoProps; /** * The props type for a not found error. */ not_found: NotFoundErrorInfoProps; /** * The props type for an unknown error. */ unknown: UnknownErrorInfoProps; } /** * Custom state extensions defined outside of piral-core. */ export interface PiralCustomState { /** * Information for the language display. */ language: { /** * Gets if languages are currently loading. */ loading: boolean; /** * The selected, i.e., active, language. */ selected: string; /** * The available languages. */ available: Array; }; /** * The currently open notifications. */ notifications: Array; /** * The currently open modal dialogs. */ modals: Array; /** * The relevant state for the registered feeds. */ feeds: FeedsState; } /** * The Piral global app sub-state container for app information. */ export interface AppState { /** * Gets if the application is currently performing a background loading * activity, e.g., for loading modules asynchronously or fetching * translations. */ loading: boolean; /** * Gets an unrecoverable application error, if any. */ error: Error | undefined; /** * Gets if the components from the micro frontends should be wrapped * in a piral-component element. */ wrap: boolean; } /** * The Piral global app sub-state container for component registrations. */ export interface RegistryState extends PiralCustomRegistryState { /** * The registered page components for the router. */ pages: Dict; /** * The registered extension components for extension slots. */ extensions: Dict>; /** * The registered wrappers for any component. */ wrappers: Dict>; } export type Dict = Record; /** * Defines the shape of a shared data item. */ export interface SharedDataItem { /** * Gets the associated value. */ value: TValue; /** * Gets the owner of the item. */ owner: string; /** * Gets the storage location. */ target: DataStoreTarget; /** * Gets the expiration of the item. */ expires: number; } export type FirstParameter any> = T extends (arg: infer P) => any ? P : never; /** * Custom component converters defined outside of piral-core. */ export interface PiralCustomComponentConverters {} /** * Definition of a vanilla JavaScript component. */ export interface HtmlComponent { /** * Renders a component into the provided element using the given props and context. */ component: ForeignComponent; /** * The type of the HTML component. */ type: "html"; } /** * Generic definition of a framework-independent component. */ export interface ForeignComponent { /** * Called when the component is mounted. * @param element The container hosting the element. * @param props The props to transport. * @param ctx The associated context. * @param locals The local state of this component instance. */ mount(element: HTMLElement, props: TProps, ctx: ComponentContext, locals: Record): void; /** * Called when the component should be updated. * @param element The container hosting the element. * @param props The props to transport. * @param ctx The associated context. * @param locals The local state of this component instance. */ update?(element: HTMLElement, props: TProps, ctx: ComponentContext, locals: Record): void; /** * Called when a component is unmounted. * @param element The container that was hosting the element. * @param locals The local state of this component instance. */ unmount?(element: HTMLElement, locals: Record): void; } export interface History { length: number; action: Action; location: Location; push(location: Path | LocationDescriptor, state?: HistoryLocationState): void; replace(location: Path | LocationDescriptor, state?: HistoryLocationState): void; go(n: number): void; goBack(): void; goForward(): void; block(prompt?: boolean | string | TransitionPromptHook): UnregisterCallback; listen(listener: LocationListener): UnregisterCallback; createHref(location: LocationDescriptorObject): Href; } export interface Location { pathname: Pathname; search: Search; state: S; hash: Hash; key?: LocationKey | undefined; } /** * The match object determining what exactly has been matched for the current navigation. */ export interface RouteMatch { /** * The parameters extracted from the current navigation. */ params: Params; /** * Indicates if the parameters have been matched exactly. */ isExact: boolean; /** * The relative path. */ path: string; /** * The fully qualified URL. */ url: string; } /** * Custom extension slots outside of piral-core. */ export interface PiralCustomExtensionSlotMap {} /** * The interface modeling the registration of a pilet extension component. */ export interface ExtensionRegistration extends BaseRegistration { /** * The wrapped registered extension component. */ component: WrappedComponent>; /** * The original extension component that has been registered. */ reference: any; /** * The default params (i.e., meta) of the extension. */ defaults: any; } /** * The creator function for the pilet API. */ export interface PiletApiCreator { /** * Creates an API for the given raw pilet. * @param target The raw (meta) content of the pilet. * @returns The API object to be used with the pilet. */ (target: PiletMetadata): PiletApi; } /** * The interface describing a function capable of fetching pilets. */ export interface PiletRequester { /** * Gets the raw pilets (e.g., from a server) asynchronously. */ (): Promise; } /** * Additional configuration options for the default loader. */ export interface DefaultLoaderConfig { /** * Sets the cross-origin attribute of potential script tags. * For pilets v1 this may be useful. Otherwise, only pilets that * have an integrity defined will be set to "anonymous". */ crossOrigin?: string; /** * Sets the override function for attaching a stylesheet. * This option will only affect `v3` pilets. * @param pilet The pilet containing the style sheet reference. * @param url The style sheet reference URL. */ attachStyles?(pilet: Pilet, url: string): void; } /** * The callback to be used to load a single pilet. */ export interface PiletLoader { (entry: PiletEntry): Promise; } /** * Defines the spec identifiers for custom loading. */ export type CustomSpecLoaders = Record; /** * A set of pipeline hooks used by the Piral loading orchestrator. */ export interface PiletLifecycleHooks { /** * Hook fired before a pilet is loaded. */ loadPilet?(pilet: PiletMetadata): void; /** * Hook fired before a pilet is being set up. */ setupPilet?(pilet: Pilet): void; /** * Hook fired before a pilet is being cleaned up. */ cleanupPilet?(pilet: Pilet): void; } /** * The record containing all available dependencies. */ export interface AvailableDependencies { [name: string]: any; } /** * The strategy for how pilets are loaded at runtime. */ export interface PiletLoadingStrategy { (options: LoadPiletsOptions, pilets: PiletsLoaded): PromiseLike; } /** * An evaluated single pilet. */ export type SinglePilet = SinglePiletApp & PiletMetadata; /** * An evaluated multi pilet. */ export type MultiPilet = MultiPiletApp & PiletMetadata; export interface NestedTranslations { [tag: string]: string | NestedTranslations; } export type UnionOf = { [K in keyof T]: T[K]; }[keyof T]; export interface PiralMenuType extends PiralCustomMenuTypes { /** * The general type. No extra options. */ general: {}; /** * The admin type. No extra options. */ admin: {}; /** * The user type. No extra options. */ user: {}; /** * The header type. No extra options. */ header: {}; /** * The footer type. No extra options. */ footer: {}; } export interface PiralNotificationTypes extends PiralCustomNotificationTypes { /** * The info type. No extra options. */ info: {}; /** * The success type. No extra options. */ success: {}; /** * The warning type. No extra options. */ warning: {}; /** * The error type. No extra options. */ error: {}; } export interface PiralCustomModalsMap {} export type RemainingArgs = T extends (_: any, ...args: infer U) => any ? U : never; export interface LanguagesPickerProps { /** * The currently selected language. */ selected: string; /** * The languages available for selection. */ available: Array; } export interface DashboardContainerProps { /** * The tiles to display. */ children?: React.ReactNode; } export interface DashboardTileProps { /** * The currently used number of columns. */ columns: number; /** * The currently used number of rows. */ rows: number; /** * The resizable status. */ resizable: boolean; /** * The provided tile preferences. */ meta: TilePreferences; /** * The content of the tile to display. */ children?: React.ReactNode; } export interface MenuContainerProps { /** * The type of the menu. */ type: MenuType; /** * The menu items to display. */ children?: React.ReactNode; } export interface MenuItemProps { /** * The type of the menu. */ type: MenuType; /** * The provided menu settings. */ meta: MenuSettings; /** * The content of the menu item. */ children?: React.ReactNode; } export interface NotificationsHostProps { /** * The notifications to display. */ children?: React.ReactNode; } export interface NotificationsToastProps extends BareNotificationProps { /** * The content of the toast to display. */ children?: React.ReactNode; } export interface ModalsHostProps { /** * Gets if the modal is currently open or closed. */ open: boolean; /** * Callback to invoke closing the modal dialog. */ close(): void; /** * The dialogs to display. */ children?: React.ReactNode; } export interface ModalsDialogProps extends OpenModalDialog { /** * The layout options given for the current dialog. */ layout: ModalLayoutOptions; /** * The provided default options. */ defaults: any; /** * The content of the dialog to display. */ children?: React.ReactNode; } /** * The different known layout types. */ export type LayoutType = "mobile" | "tablet" | "desktop"; /** * Represents a path in the app registration. */ export interface AppPath { /** * The exact path to use. */ path: string; /** * The associated route matcher. */ matcher: RegExp; /** * The page metadata. */ meta: PiralPageMeta; /** * The component to register for this path. */ Component: React.ComponentType; } /** * Custom errors defined outside of piral-core. */ export interface PiralCustomErrors { tile: TileErrorInfoProps; menu: MenuItemErrorInfoProps; modal: ModalErrorInfoProps; feed: FeedErrorInfoProps; } /** * The error used when a registered extension component crashed. */ export interface ExtensionErrorInfoProps { /** * The type of the error. */ type: "extension"; /** * The provided error details. */ error: any; /** * The name of the pilet emitting the error. */ pilet?: string; } /** * The error used when the app could not be loaded. */ export interface LoadingErrorInfoProps { /** * The type of the error. */ type: "loading"; /** * The provided error details. */ error: any; } /** * The error used when a registered page component crashes. */ export interface PageErrorInfoProps extends ReactRouter.RouteComponentProps { /** * The type of the error. */ type: "page"; /** * The provided error details. */ error: any; /** * The name of the pilet emitting the error. */ pilet?: string; } /** * The error used when a route cannot be resolved. */ export interface NotFoundErrorInfoProps extends ReactRouter.RouteComponentProps { /** * The type of the error. */ type: "not_found"; } /** * The error used when the exact type is unknown. */ export interface UnknownErrorInfoProps { /** * The type of the error. */ type: "unknown"; /** * The provided error details. */ error: any; /** * The name of the pilet emitting the error. */ pilet?: string; } export interface OpenNotification { id: string; component: React.ComponentType; options: NotificationOptions; close(): void; } export interface OpenModalDialog { /** * Gets the ID of the modal to open. For tracking its state. */ id: string; /** * Specifies the fully qualified name of the dialog to show. */ name: string; /** * Specifies the alternative (original) name of the dialog to show. */ alternative?: string; /** * Defines the transported options. */ options: BaseModalOptions; /** * Closes the modal dialog. */ close(): void; } export interface FeedsState { [id: string]: FeedDataState; } /** * Custom parts of the global registry state defined outside of piral-core. */ export interface PiralCustomRegistryState { /** * The registered tile components for a dashboard. */ tiles: Dict; /** * The registered menu items for global display. */ menuItems: Dict; /** * The registered modal dialog components. */ modals: Dict; } /** * The interface modeling the registration of a pilet page component. */ export interface PageRegistration extends BaseRegistration { /** * The registered page component. */ component: WrappedComponent; /** * The page's associated metadata. */ meta: PiralPageMeta; } /** * The context to be transported into the generic components. */ export interface ComponentContext { /** * The router-independent navigation API. */ navigation: NavigationApi; /** * The internal router object. * @deprecated Exposes internals that can change at any time. */ router: any; /** * The public path of the application. */ publicPath: string; } export type Action = "PUSH" | "POP" | "REPLACE"; export type Path = Path___1; export type LocationDescriptor = LocationDescriptor___1; export type TransitionPromptHook = TransitionPromptHook___1; export type UnregisterCallback = () => void; export type LocationListener = LocationListener___1; export interface LocationDescriptorObject { pathname?: Pathname | undefined; search?: Search | undefined; state?: S | undefined; hash?: Hash | undefined; key?: LocationKey | undefined; } export type Href = Href___1; export type LocationState = LocationState___1; export type Pathname = Pathname___1; export type Search = Search___1; export type Hash = Hash___1; export type LocationKey = LocationKey___1; /** * The base type for pilet component registration in the global state context. */ export interface BaseRegistration { /** * The pilet registering the component. */ pilet: string; } export type WrappedComponent = React.ComponentType>>; /** * The entries representing pilets from a feed service response. */ export type PiletEntries = Array; /** * Pilet entry representing part of a response from the feed service. */ export type PiletEntry = MultiPiletEntry | SinglePiletEntry; /** * The callback to be used when pilets have been loaded. */ export interface PiletsLoaded { (error: Error | undefined, pilets: Array): void; } /** * The pilet app, i.e., the functional exports. */ export interface SinglePiletApp { /** * Integrates the evaluated pilet into the application. * @param api The API to access the application. */ setup(api: PiletApi): void | Promise; /** * Optional function for cleanup. * @param api The API to access the application. */ teardown?(api: PiletApi): void; /** * The referenced stylesheets to load / integrate. * This would only be used by v3 pilets. */ styles?: Array; /** * The referenced WebAssembly binaries to load / integrate. * This would only be used by v3 pilets. */ assemblies?: Array; } /** * The pilet app, i.e., the functional exports. */ export interface MultiPiletApp { /** * Integrates the evaluated pilet into the application. * @param api The API to access the application. */ setup(apiFactory: PiletApiCreator): void | Promise; } export interface PiralCustomMenuTypes {} export interface PiralCustomNotificationTypes {} export type MenuType = PiralSpecificMenuSettings["type"]; export interface TileErrorInfoProps { /** * The type of the error. */ type: "tile"; /** * The provided error details. */ error: any; /** * The currently used number of columns. */ columns: number; /** * The currently used number of rows. */ rows: number; /** * The name of the pilet emitting the error. */ pilet?: string; } /** * The error used when a registered menu item component crashed. */ export interface MenuItemErrorInfoProps { /** * The type of the error. */ type: "menu"; /** * The provided error details. */ error: any; /** * The type of the used menu. */ menu: MenuType; /** * The name of the pilet emitting the error. */ pilet?: string; } /** * The error used when a registered modal dialog crashed. */ export interface ModalErrorInfoProps { /** * The type of the error. */ type: "modal"; /** * The provided error details. */ error: any; /** * Callback for closing the modal programmatically. */ onClose(): void; /** * The name of the pilet emitting the error. */ pilet?: string; } /** * The error used when loading a feed resulted in an error. */ export interface FeedErrorInfoProps { /** * The type of the error. */ type: "feed"; /** * The provided error details. */ error: any; /** * The name of the pilet emitting the error. */ pilet?: string; } export interface FeedDataState { /** * Determines if the feed data is currently loading. */ loading: boolean; /** * Indicates if the feed data was already loaded and is active. */ loaded: boolean; /** * Stores the potential error when initializing or loading the feed. */ error: any; /** * The currently stored feed data. */ data: any; } export interface TileRegistration extends BaseRegistration { component: WrappedComponent; preferences: TilePreferences; } export interface MenuItemRegistration extends BaseRegistration { component: WrappedComponent; settings: MenuSettings; } export interface ModalRegistration extends BaseRegistration { name: string; component: WrappedComponent>; defaults: any; layout: ModalLayoutOptions; } export interface NavigationApi { /** * Pushes a new location onto the history stack. */ push(target: string, state?: any): void; /** * Replaces the current location with another. */ replace(target: string, state?: any): void; /** * Changes the current index in the history stack by a given delta. */ go(n: number): void; /** * Prevents changes to the history stack from happening. * This is useful when you want to prevent the user navigating * away from the current page, for example when they have some * unsaved data on the current page. * @param blocker The function being called with a transition request. * @returns The disposable for stopping the block. */ block(blocker: NavigationBlocker): Disposable; /** * Starts listening for location changes and calls the given * callback with an Update when it does. * @param listener The function being called when the route changes. * @returns The disposable for stopping the block. */ listen(listener: NavigationListener): Disposable; /** * Gets the current navigation / application path. */ path: string; /** * Gets the current navigation path incl. search and hash parts. */ url: string; /** * The original router behind the navigation. Don't depend on this * as the implementation is router specific and may change over time. */ router: any; /** * Gets the public path of the application. */ publicPath: string; } export type Path___1 = string; export type LocationDescriptor___1 = Path___1 | LocationDescriptorObject; export type TransitionPromptHook___1 = (location: Location, action: Action) => string | false | void; export type LocationListener___1 = (location: Location, action: Action) => void; export type Href___1 = string; export type LocationState___1 = unknown; export type Pathname___1 = string; export type Search___1 = string; export type Hash___1 = string; export type LocationKey___1 = string; export type Without = Pick>; /** * The metadata response for a multi pilet. */ export type MultiPiletEntry = PiletBundleEntry; /** * The metadata response for a single pilet. */ export type SinglePiletEntry = PiletV0Entry | PiletV1Entry | PiletV2Entry | PiletV3Entry | PiletMfEntry | PiletVxEntry; export interface NavigationBlocker { (tx: NavigationTransition): void; } export interface NavigationListener { (update: NavigationUpdate): void; } /** * Metadata for pilets using the bundle schema. */ export interface PiletBundleEntry { /** * The name of the bundle pilet, i.e., the package id. */ name?: string; /** * Optionally provides the version of the specification for this pilet. */ spec?: "v1"; /** * The link for retrieving the bundle content of the pilet. */ link: string; /** * The reference name for the global bundle-shared require. */ bundle: string; /** * The computed integrity of the pilet. Will be used to set the * integrity value of the script. */ integrity?: string; /** * Optionally provides some custom metadata for the pilet. */ custom?: any; /** * Additional shared dependency script files. */ dependencies?: Record; } /** * Metadata for pilets using the v0 schema. */ export type PiletV0Entry = PiletV0ContentEntry | PiletV0LinkEntry; /** * Metadata for pilets using the v1 schema. */ export interface PiletV1Entry { /** * The name of the pilet, i.e., the package id. */ name: string; /** * The version of the pilet. Should be semantically versioned. */ version: string; /** * Optionally provides the version of the specification for this pilet. */ spec?: "v1"; /** * The link for retrieving the content of the pilet. */ link: string; /** * The reference name for the global require. */ requireRef: string; /** * The computed integrity of the pilet. Will be used to set the * integrity value of the script. */ integrity?: string; /** * Optionally provides some custom metadata for the pilet. */ custom?: any; /** * Optionally provides some configuration to be used in the pilet. */ config?: Record; /** * Additional shared dependency script files. */ dependencies?: Record; } /** * Metadata for pilets using the v2 schema. */ export interface PiletV2Entry { /** * The name of the pilet, i.e., the package id. */ name: string; /** * The version of the pilet. Should be semantically versioned. */ version: string; /** * Provides the version of the specification for this pilet. */ spec: "v2"; /** * The reference name for the global require. */ requireRef: string; /** * The computed integrity of the pilet. */ integrity?: string; /** * The link for retrieving the content of the pilet. */ link: string; /** * Optionally provides some custom metadata for the pilet. */ custom?: any; /** * Optionally provides some configuration to be used in the pilet. */ config?: Record; /** * Additional shared dependency script files. */ dependencies?: Record; } /** * Metadata for pilets using the v3 schema. */ export interface PiletV3Entry { /** * The name of the pilet, i.e., the package id. */ name: string; /** * The version of the pilet. Should be semantically versioned. */ version: string; /** * Provides the version of the specification for this pilet. */ spec: "v3"; /** * The reference name for the global require. */ requireRef: string; /** * The computed integrity of the pilet. */ integrity?: string; /** * The fallback link for retrieving the content of the pilet. */ link: string; /** * The links for specific variations of the pilet, e.g., "client", "server", ... */ variations?: Record; /** * Optionally provides some custom metadata for the pilet. */ custom?: any; /** * Optionally provides some configuration to be used in the pilet. */ config?: Record; /** * Additional shared dependency script files. */ dependencies?: Record; } /** * Metadata for pilets using the mf schema. */ export interface PiletMfEntry { /** * The name of the pilet, i.e., the package id. */ name: string; /** * The version of the pilet. Should be semantically versioned. */ version: string; /** * Provides the version of the specification for this pilet. */ spec: "mf"; /** * The computed integrity of the pilet. */ integrity?: string; /** * The fallback link for retrieving the content of the pilet. */ link: string; /** * Optionally provides some custom metadata for the pilet. */ custom?: any; /** * Optionally provides some configuration to be used in the pilet. */ config?: Record; } export interface PiletVxEntry { /** * The name of the pilet, i.e., the package id. */ name: string; /** * The version of the pilet. Should be semantically versioned. */ version: string; /** * Provides an identifier for the custom specification. */ spec: string; /** * Optionally provides some custom metadata for the pilet. */ custom?: any; /** * Optionally provides some configuration to be used in the pilet. */ config?: Record; /** * Additional shared dependency script files. */ dependencies?: Record; } export interface NavigationTransition extends NavigationUpdate { retry?(): void; } export interface NavigationUpdate { action: NavigationAction; location: NavigationLocation; } /** * Metadata for pilets using the v0 schema with a content. */ export interface PiletV0ContentEntry extends PiletV0BaseEntry { /** * The content of the pilet. If the content is not available * the link will be used (unless caching has been activated). */ content: string; /** * If available indicates that the pilet should not be cached. * In case of a string this is interpreted as the expiration time * of the cache. In case of an accurate hash this should not be * required or set. */ noCache?: boolean | string; } /** * Metadata for pilets using the v0 schema with a link. */ export interface PiletV0LinkEntry extends PiletV0BaseEntry { /** * The link for retrieving the content of the pilet. */ link: string; } export type NavigationAction = "POP" | "PUSH" | "REPLACE"; export interface NavigationLocation { /** * The fully qualified URL incl. the origin and base path. */ href: string; /** * The location.pathname property is a string that contains an initial "/" * followed by the remainder of the URL up to the ?. */ pathname: string; /** * The location.search property is a string that contains an initial "?" * followed by the key=value pairs in the query string. If there are no * parameters, this value may be the empty string (i.e. ''). */ search: string; /** * The location.hash property is a string that contains an initial "#" * followed by fragment identifier of the URL. If there is no fragment * identifier, this value may be the empty string (i.e. ''). */ hash: string; /** * The location.state property is a user-supplied State object that is * associated with this location. This can be a useful place to store * any information you do not want to put in the URL, e.g. session-specific * data. */ state: unknown; /** * The location.key property is a unique string associated with this location. * On the initial location, this will be the string default. On all subsequent * locations, this string will be a unique identifier. */ key?: string; } /** * Basic metadata for pilets using the v0 schema. */ export interface PiletV0BaseEntry { /** * The name of the pilet, i.e., the package id. */ name: string; /** * The version of the pilet. Should be semantically versioned. */ version: string; /** * Optionally provides the version of the specification for this pilet. */ spec?: "v0"; /** * The computed hash value of the pilet's content. Should be * accurate to allow caching. */ hash: string; /** * Optionally provides some custom metadata for the pilet. */ custom?: any; /** * Optionally provides some configuration to be used in the pilet. */ config?: Record; /** * Additional shared dependency script files. */ dependencies?: Record; }