{"version":3,"file":"dataSource.cjs","sources":["../../../../src/services/dataSource/dataSource.ts"],"sourcesContent":["import { DataSourceApi, type DataSourceInstanceSettings, type DataSourceRef, type ScopedVars } from '@grafana/data';\n\nimport { isExpressionReference } from '../../utils/expressionRef';\nimport { UserStorage } from '../../utils/userStorage';\nimport { getDataSourceSrv, type RuntimeDataSourceRegistration } from '../dataSourceSrv';\n\nimport { FALLBACK_TO_LEGACY_INSTANCE_WARNING } from './constants';\nimport { getExpressionDataSourceInstance } from './expressionDs';\nimport { describeRef, logDataSourceInstanceError, logDataSourceWarning } from './logging';\nimport { getCachedPlugin, setCachedPlugin, setRuntimePlugin } from './pluginCache';\nimport { getDataSourceInstanceSettings, upsertRuntimeDataSourceInstanceSettings } from './settings';\nimport { type ImportDataSourcePluginFn } from './types';\n\nlet importDataSourcePlugin: ImportDataSourcePluginFn | undefined;\nconst inflightLoads = new Map<string, Promise<DataSourceApi>>();\n\n/**\n * Register the data source plugin importer. Called once from application boot.\n * The runtime package cannot depend on `public/app/features/plugins`, so the\n * concrete import function is injected here at startup.\n *\n * @internal\n */\nexport function setDataSourcePluginImporter(fn: ImportDataSourcePluginFn): void {\n  importDataSourcePlugin = fn;\n}\n\n/**\n * Load and return a data source plugin instance. Resolves the data source by\n * name, uid, or {@link DataSourceRef}, caches the constructed instance, and\n * reuses it on subsequent calls. Concurrent callers for the same uid share\n * a single in-flight load.\n *\n * @public\n */\nexport async function getDataSourceInstance(\n  ref?: DataSourceRef | string | null,\n  scopedVars?: ScopedVars\n): Promise<DataSourceApi> {\n  ref = normalizeEmptyRef(ref);\n\n  if (isExpressionReference(ref)) {\n    const expressionDs = getExpressionDataSourceInstance();\n    if (!expressionDs) {\n      throw new Error(\n        'Expression datasource has not been initialised. Call setExpressionDataSourceInstance during application boot.'\n      );\n    }\n    return expressionDs;\n  }\n\n  try {\n    let settings = await getDataSourceInstanceSettings(ref, scopedVars);\n    if (!settings) {\n      throw new Error(`Datasource ${describeRef(ref)} was not found`);\n    }\n\n    // When ref is a template variable, the settings keep the variable string in uid/name\n    // (e.g. \"${datasource}\") with the resolved uid in rawRef — correct for the settings API,\n    // but a plugin instance built from them would carry the variable as its identity. Legacy\n    // DatasourceSrv.get() interpolates and returns the concrete instance, so re-resolve\n    // through rawRef and construct/cache from the concrete settings.\n    if (settings.rawRef && settings.rawRef.uid !== settings.uid) {\n      settings = await getDataSourceInstanceSettings(settings.rawRef);\n      if (!settings) {\n        throw new Error(`Datasource ${describeRef(ref)} was not found`);\n      }\n    }\n\n    const cacheUid = settings.uid;\n\n    const cached = getCachedPlugin(cacheUid);\n    if (cached) {\n      return cached;\n    }\n\n    const inflight = inflightLoads.get(cacheUid);\n    if (inflight) {\n      // `await` (not a bare `return`) so a rejection routes through the catch below to the\n      // fallback. A bare `return` adopts the promise without awaiting, so concurrent callers\n      // would skip the fallback that the first caller (which awaits) gets.\n      return await inflight;\n    }\n\n    const promise = loadDataSourceInstance(cacheUid, settings);\n    inflightLoads.set(cacheUid, promise);\n\n    try {\n      return await promise;\n    } finally {\n      inflightLoads.delete(cacheUid);\n    }\n  } catch (err) {\n    return getDataSourceInstanceFallback(ref, scopedVars, err);\n  }\n}\n\n// Legacy DataSourceSrv.get() treats an empty ref ('' or { uid: '' }) as \"default datasource\"\n// (or a type-only lookup when ref.type is set). getDataSourceInstanceSettings only does this\n// for null/undefined, so normalize here to keep getDataSourceInstance in parity with get().\nfunction normalizeEmptyRef(ref: DataSourceRef | string | null | undefined): DataSourceRef | string | null | undefined {\n  if (ref === '') {\n    return undefined;\n  }\n  if (typeof ref === 'object' && ref !== null && ref.uid === '') {\n    // Keep the object only when a type-only lookup is possible; otherwise this is a plain\n    // \"default datasource\" request (same as an empty string), and normalizing to undefined\n    // lets describeRef report 'default' instead of 'unknown' if resolution fails.\n    return ref.type ? { ...ref, uid: undefined } : undefined;\n  }\n  return ref;\n}\n\nasync function loadDataSourceInstance(cacheUid: string, settings: DataSourceInstanceSettings): Promise<DataSourceApi> {\n  if (!importDataSourcePlugin) {\n    throw new Error('Data source importer has not been set. Call setDataSourcePluginImporter during application boot.');\n  }\n\n  let dsPlugin;\n  try {\n    dsPlugin = await importDataSourcePlugin(settings.meta);\n  } catch (error) {\n    logDataSourceInstanceError(`Failed to import datasource plugin ${settings.name} (${settings.uid})`, error, {\n      pluginId: settings.meta.id,\n      uid: settings.uid,\n      name: settings.name,\n    });\n    throw error;\n  }\n\n  const racedCache = getCachedPlugin(cacheUid);\n  if (racedCache) {\n    return racedCache;\n  }\n\n  const instance = new dsPlugin.DataSourceClass(settings);\n  instance.components = dsPlugin.components;\n\n  if (!instance.userStorage) {\n    instance.userStorage = new UserStorage(settings.type);\n  }\n\n  if (!(instance instanceof DataSourceApi)) {\n    const anyInstance: { [key: string]: unknown } = instance;\n    anyInstance.name = settings.name;\n    anyInstance.id = settings.id;\n    anyInstance.type = settings.type;\n    anyInstance.meta = settings.meta;\n    anyInstance.uid = settings.uid;\n    anyInstance.getRef = DataSourceApi.prototype.getRef;\n  }\n\n  setCachedPlugin(cacheUid, instance);\n  return instance;\n}\n\n/**\n * Register a runtime data source. Writes to both the instance-settings cache\n * and the plugin-instance cache so the data source is available to\n * {@link getDataSourceInstanceSettings} and {@link getDataSourceInstance}.\n *\n * Runtime data sources are intentionally excluded from {@link getDataSourceInstanceList}\n * results, matching the behaviour of the legacy `DatasourceSrv.registerRuntimeDataSourceInstance`.\n *\n * @public\n */\nexport function registerRuntimeDataSourceInstance(entry: RuntimeDataSourceRegistration): void {\n  const { dataSource } = entry;\n\n  if (getCachedPlugin(dataSource.uid)) {\n    throw new Error(`A runtime data source with uid ${dataSource.uid} has already been registered`);\n  }\n\n  upsertRuntimeDataSourceInstanceSettings(dataSource.instanceSettings);\n  setRuntimePlugin(dataSource.uid, dataSource);\n}\n\n/**\n * Last resort while the legacy `DataSourceSrv` still exists: the new path failed to resolve\n * the data source. If the legacy service can resolve it, that's a divergence worth tracking;\n * otherwise rethrow the original error so a genuine \"not found\" stays an error and is not\n * logged. Delete this (and its call site) once `DataSourceSrv` is gone.\n */\nasync function getDataSourceInstanceFallback(\n  ref: DataSourceRef | string | null | undefined,\n  scopedVars: ScopedVars | undefined,\n  originalError: unknown\n): Promise<DataSourceApi> {\n  const srv = getDataSourceSrv();\n  if (srv) {\n    const legacy = await srv.get(ref, scopedVars).catch(() => undefined);\n    if (legacy) {\n      logDataSourceWarning(FALLBACK_TO_LEGACY_INSTANCE_WARNING, { ref: describeRef(ref) });\n      return legacy;\n    }\n  }\n  throw originalError;\n}\n\n/**\n * Test helper — resets module-local state. Should only be called from tests.\n *\n * @internal\n */\nexport function _resetForTests(): void {\n  if (process.env.NODE_ENV !== 'test') {\n    throw new Error('_resetForTests must only be called from tests');\n  }\n  importDataSourcePlugin = undefined;\n  inflightLoads.clear();\n}\n"],"names":["isExpressionReference","expressionDs","getExpressionDataSourceInstance","settings","getDataSourceInstanceSettings","describeRef","getCachedPlugin","logDataSourceInstanceError","UserStorage","DataSourceApi","setCachedPlugin","upsertRuntimeDataSourceInstanceSettings","setRuntimePlugin","getDataSourceSrv","logDataSourceWarning","FALLBACK_TO_LEGACY_INSTANCE_WARNING"],"mappings":"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"}