Skip to main content
Glama
loadRemoteDictionaries.ts4.95 kB
import { getIntlayerAPIProxy } from '@intlayer/api'; // @ts-ignore @intlayer/backend is not build yet import type { DictionaryAPI } from '@intlayer/backend'; import { getConfiguration } from '@intlayer/config'; import { getRemoteDictionaries } from '@intlayer/remote-dictionaries-entry'; import type { Dictionary, DictionaryId, DictionaryKey } from '@intlayer/types'; import { fetchDistantDictionaries } from '../fetchDistantDictionaries'; import type { DictionariesStatus } from '../loadDictionaries/loadDictionaries'; import { sortAlphabetically } from '../utils/sortAlphabetically'; export const formatDistantDictionaries = ( dictionaries: (DictionaryAPI | Dictionary)[] ): Dictionary[] => dictionaries.map((dict) => ({ ...dict, localId: `${dict.key}::remote::${dict.id}`, location: 'remote' as const, })); export const loadRemoteDictionaries = async ( configuration = getConfiguration(), onStatusUpdate?: (status: DictionariesStatus[]) => void, options?: { onStartRemoteCheck?: () => void; onStopRemoteCheck?: () => void; onError?: (error: Error) => void; } ): Promise<Dictionary[]> => { const { editor } = configuration; const remoteDictionariesRecord = getRemoteDictionaries(configuration); const hasRemoteDictionaries = Boolean(editor.clientId && editor.clientSecret); if (!hasRemoteDictionaries) return []; try { options?.onStartRemoteCheck?.(); const intlayerAPI = getIntlayerAPIProxy(undefined, configuration); // Get the list of dictionary keys const getDictionariesKeysResult = await intlayerAPI.dictionary.getDictionariesUpdateTimestamp(); const distantDictionaryUpdateTimeStamp: Record< DictionaryId, { key: DictionaryKey; updatedAt: number } > | null = getDictionariesKeysResult.data; if (!distantDictionaryUpdateTimeStamp) { throw new Error('No distant dictionaries found'); } const dictionariesIdToFetch = Object.entries( distantDictionaryUpdateTimeStamp ).filter(([dictionaryId, data]) => { // If remote doesn't provide updatedAt, fetch to be safe if (!data.updatedAt) return true; // If no local cache exists, fetch const local: Dictionary | undefined = remoteDictionariesRecord[ data.key ]?.find((dictionary) => dictionary.id === dictionaryId); if (!local) return true; const localUpdatedAtRaw = (local as any)?.updatedAt as | number | string | undefined; const localUpdatedAt = typeof localUpdatedAtRaw === 'number' ? localUpdatedAtRaw : localUpdatedAtRaw ? new Date(localUpdatedAtRaw).getTime() : undefined; // If local timestamp missing or older than remote, fetch if (typeof localUpdatedAt !== 'number') return true; return data.updatedAt > localUpdatedAt; }); const flatRemoteDictionariesRecord: DictionaryAPI[] = Object.values( remoteDictionariesRecord ).flat(); const cachedDictionaries: Dictionary[] = flatRemoteDictionariesRecord.filter((dictionary) => { const remoteUpdatedAt = distantDictionaryUpdateTimeStamp[dictionary.id!].updatedAt; const localUpdatedAtRaw = dictionary.updatedAt; const localUpdatedAt = typeof localUpdatedAtRaw === 'number' ? localUpdatedAtRaw : localUpdatedAtRaw ? new Date(localUpdatedAtRaw).getTime() : undefined; // Consider as cached/imported when local exists and is up-to-date or newer return ( typeof localUpdatedAt === 'number' && typeof remoteUpdatedAt === 'number' && localUpdatedAt >= remoteUpdatedAt ); }); // Report cached as already imported if (cachedDictionaries.length > 0) { onStatusUpdate?.( cachedDictionaries.map((dictionary) => ({ dictionaryKey: dictionary.key, type: 'remote', status: 'imported', })) ); } const orderedDistantDictionaryKeys = dictionariesIdToFetch .map(([, data]) => data.key) .sort(sortAlphabetically); // Report pending for keys to be fetched so totals are visible immediately if (orderedDistantDictionaryKeys.length > 0) { onStatusUpdate?.( orderedDistantDictionaryKeys.map((key) => ({ dictionaryKey: key, type: 'remote', status: 'pending', })) ); } const distantDictionariesData = await fetchDistantDictionaries( { dictionaryKeys: orderedDistantDictionaryKeys, }, onStatusUpdate ); const distantDictionaries: Dictionary[] = formatDistantDictionaries( distantDictionariesData ); return [...cachedDictionaries, ...distantDictionaries]; } catch (error) { options?.onError?.(error as Error); return []; } finally { options?.onStopRemoteCheck?.(); } };

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/aymericzip/intlayer'

If you have feedback or need assistance with the MCP directory API, please join our Discord server