2024-08-30 10:09:01 +02:00
import type { PluginExtensionAddedLinkConfig , PluginExtensionExposedComponentConfig } from '@grafana/data' ;
import { PluginExtensionAddedComponentConfig } from '@grafana/data/src/types/pluginExtensions' ;
2023-03-02 15:42:00 +01:00
import type { AppPluginConfig } from '@grafana/runtime' ;
2023-05-10 11:03:15 +02:00
import { startMeasure , stopMeasure } from 'app/core/utils/metrics' ;
2023-11-14 08:35:40 +01:00
import { getPluginSettings } from 'app/features/plugins/pluginSettings' ;
2022-04-22 14:33:13 +01:00
2024-08-30 10:09:01 +02:00
import { PluginExtensionRegistries } from './extensions/registry/types' ;
2024-09-09 10:38:35 +01:00
import { importPluginModule } from './plugin_loader' ;
2021-11-10 19:06:55 +01:00
2023-03-02 15:42:00 +01:00
export type PluginPreloadResult = {
pluginId : string ;
error? : unknown ;
2024-08-30 10:09:01 +02:00
exposedComponentConfigs : PluginExtensionExposedComponentConfig [ ] ;
addedComponentConfigs? : PluginExtensionAddedComponentConfig [ ] ;
addedLinkConfigs? : PluginExtensionAddedLinkConfig [ ] ;
2023-03-02 15:42:00 +01:00
} ;
2024-04-24 15:37:22 +02:00
export async function preloadPlugins (
apps : AppPluginConfig [ ] = [ ] ,
2024-08-27 11:14:04 +02:00
registries : PluginExtensionRegistries ,
2024-04-24 15:37:22 +02:00
eventName = 'frontend_plugins_preload'
) {
startMeasure ( eventName ) ;
2024-04-24 09:33:16 +02:00
const promises = apps . filter ( ( config ) = > config . preload ) . map ( ( config ) = > preload ( config ) ) ;
const preloadedPlugins = await Promise . all ( promises ) ;
for ( const preloadedPlugin of preloadedPlugins ) {
2024-08-19 08:43:11 +02:00
if ( preloadedPlugin . error ) {
console . error ( ` [Plugins] Skip loading extensions for " ${ preloadedPlugin . pluginId } " due to an error. ` ) ;
continue ;
}
2024-08-27 11:14:04 +02:00
registries . exposedComponentsRegistry . register ( {
2024-08-19 08:43:11 +02:00
pluginId : preloadedPlugin.pluginId ,
configs : preloadedPlugin.exposedComponentConfigs ,
} ) ;
2024-08-27 11:14:04 +02:00
registries . addedComponentsRegistry . register ( {
pluginId : preloadedPlugin.pluginId ,
2024-08-30 10:09:01 +02:00
configs : preloadedPlugin.addedComponentConfigs || [ ] ,
} ) ;
registries . addedLinksRegistry . register ( {
pluginId : preloadedPlugin.pluginId ,
configs : preloadedPlugin.addedLinkConfigs || [ ] ,
2024-08-27 11:14:04 +02:00
} ) ;
2024-04-24 09:33:16 +02:00
}
2024-04-24 15:37:22 +02:00
stopMeasure ( eventName ) ;
2021-11-10 19:06:55 +01:00
}
2023-03-02 15:42:00 +01:00
async function preload ( config : AppPluginConfig ) : Promise < PluginPreloadResult > {
2024-09-09 10:38:35 +01:00
const { path , version , id : pluginId , loadingStrategy } = config ;
2021-11-10 19:06:55 +01:00
try {
2023-05-10 11:03:15 +02:00
startMeasure ( ` frontend_plugin_preload_ ${ pluginId } ` ) ;
2024-09-09 10:38:35 +01:00
const { plugin } = await importPluginModule ( {
2023-06-05 10:51:36 +02:00
path ,
version ,
2023-11-10 11:44:54 +01:00
isAngular : config.angular.detected ,
2023-06-05 10:51:36 +02:00
pluginId ,
2024-09-09 10:38:35 +01:00
loadingStrategy ,
2023-06-05 10:51:36 +02:00
} ) ;
2024-08-30 10:09:01 +02:00
const { exposedComponentConfigs = [ ] , addedComponentConfigs = [ ] , addedLinkConfigs = [ ] } = plugin ;
2023-11-14 08:35:40 +01:00
// Fetching meta-information for the preloaded app plugin and caching it for later.
// (The function below returns a promise, but it's not awaited for a reason: we don't want to block the preload process, we would only like to cache the result for later.)
getPluginSettings ( pluginId ) ;
2024-08-30 10:09:01 +02:00
return { pluginId , exposedComponentConfigs , addedComponentConfigs , addedLinkConfigs } ;
2023-03-02 15:42:00 +01:00
} catch ( error ) {
console . error ( ` [Plugins] Failed to preload plugin: ${ path } (version: ${ version } ) ` , error ) ;
2024-08-30 10:09:01 +02:00
return {
pluginId ,
error ,
exposedComponentConfigs : [ ] ,
addedComponentConfigs : [ ] ,
addedLinkConfigs : [ ] ,
} ;
2023-05-10 11:03:15 +02:00
} finally {
stopMeasure ( ` frontend_plugin_preload_ ${ pluginId } ` ) ;
2021-11-10 19:06:55 +01:00
}
}