All files / src/timeline currentValueQueries.ts

93.75% Statements 45/48
75.67% Branches 28/37
100% Functions 9/9
100% Lines 40/40

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98                            812x                         884x 884x 884x 884x 884x             884x 884x 922x 922x 922x 922x 922x 922x 922x 921x   921x 921x 921x   921x 888x       884x               809x   809x 837x 837x 836x 836x 837x 835x 835x     809x   809x 812x 812x 812x                 809x 809x 812x 811x    
import type { ApolloClient, NormalizedCacheObject } from '@apollo/client';
import { normalizeTangoAttributeInputs } from '@ska-octopus-widget-sdk/widget-sdk';
import { CURR_VALUE_ENDPOINT_OP } from '../graphql/operations';
import { canonicalAttr } from '../utils/utils';
 
export interface AttributeSourceEntry {
  endpoint?: string | { value?: unknown; label?: unknown };
  attribute?: string | { value?: unknown; attribute?: unknown; name?: unknown };
}
 
export type EndpointByAttribute = Record<string, string>;
export type HdbByEndpoint = Record<string, number>;
 
function dedupe(values: string[]): string[] {
  return Array.from(new Set(values));
}
 
export function resolveAttributeSources(
  rawAttributes: unknown,
  fallbackAttributes: string[],
  legacyEndpoint?: string,
  variables?: Record<string, unknown>
): {
  attributes: string[];
  endpointByAttribute: EndpointByAttribute;
  hdbByEndpoint: HdbByEndpoint;
} {
  const endpointByAttribute: EndpointByAttribute = {};
  const hdbByEndpoint: HdbByEndpoint = {};
  const fallback = (fallbackAttributes ?? []).map((item) => String(item).trim()).filter(Boolean);
  const legacy = String(legacyEndpoint ?? '').trim();
  const normalized = normalizeTangoAttributeInputs({
    attributes: Array.isArray(rawAttributes) ? (rawAttributes as any[]) : undefined,
    fallbackAttributes: fallback,
    fallbackEndpoint: legacy,
    variables
  });
 
  const attributes: string[] = [];
  normalized.forEach((entry) => {
    const value = String(entry ?? '').trim();
    Iif (!value) return;
    const sep = value.lastIndexOf('://');
    const endpoint = sep > 0 ? value.slice(0, sep).trim() : legacy;
    const attribute = sep > 0 ? value.slice(sep + 3).trim() : value;
    Iif (!attribute) return;
    if (!endpoint) return;
    attributes.push(attribute);
 
    const key = canonicalAttr(attribute).toLowerCase();
    Eif (!endpointByAttribute[key]) {
      endpointByAttribute[key] = endpoint;
    }
    if (!(endpoint in hdbByEndpoint)) {
      hdbByEndpoint[endpoint] = Object.keys(hdbByEndpoint).length;
    }
  });
 
  return { attributes, endpointByAttribute, hdbByEndpoint };
}
 
export async function queryCurrentValueRows(
  client: ApolloClient<NormalizedCacheObject>,
  fullNames: string[],
  endpointByAttribute: EndpointByAttribute = {}
): Promise<any[]> {
  const endpointGroups: Record<string, string[]> = {};
 
  fullNames.forEach((rawName) => {
    const name = String(rawName ?? '').trim();
    if (!name) return;
    const key = canonicalAttr(name).toLowerCase();
    const endpoint = String(endpointByAttribute[key] ?? '').trim();
    if (!endpoint) return;
    if (!endpointGroups[endpoint]) endpointGroups[endpoint] = [];
    endpointGroups[endpoint].push(name);
  });
 
  const calls: Promise<any>[] = [];
 
  Object.entries(endpointGroups).forEach(([endpoint, names]) => {
    const uniqueNames = dedupe(names);
    Iif (uniqueNames.length === 0) return;
    calls.push(
      client.query({
        query: CURR_VALUE_ENDPOINT_OP,
        variables: { fullNames: uniqueNames, endpoint },
        fetchPolicy: 'network-only'
      })
    );
  });
 
  const settled = await Promise.allSettled(calls);
  return settled
    .filter((result): result is PromiseFulfilledResult<any> => result.status === 'fulfilled')
    .flatMap((result) => result.value?.data?.attributes ?? []);
}