etymology / frontend /js /utils.js
lucharo's picture
Super-squash branch 'main' using huggingface_hub
13812dc
/**
* Utility functions for Etymology Explorer
*/
export function getLangName(lang) {
// API provides lang_name from 2400+ code database
// This is only called as fallback when API doesn't return lang_name
if (!lang) return 'Unknown';
return lang; // Return raw code if no name available
}
export function escapeHtml(str) {
if (!str) return '';
return str
.replace(/&/g, '&')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#039;');
}
export function truncate(text, maxLength) {
if (!text || text.length <= maxLength) return text;
return text.slice(0, maxLength).trim() + '…';
}
export async function handleApiResponse(response, context = 'request') {
if (response.ok) return response;
if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After') || '60';
throw new Error(`Too many requests. Please wait ${retryAfter} seconds and try again.`);
}
if (response.status === 404) {
throw new Error(`Word not found in the database`);
}
if (response.status >= 500) {
throw new Error(`Server is temporarily unavailable. Please try again in a moment.`);
}
throw new Error(`Failed to complete ${context}`);
}
/**
* Check if a graph API response indicates the word exists but has no etymology.
* Returns { noEtymology: true, lexeme } if so, null otherwise.
*/
export function checkNoEtymology(data) {
if (data && data.no_etymology === true) {
return { noEtymology: true, lexeme: data.lexeme || '' };
}
return null;
}
export function buildNodeLabel(node) {
const langName = node.lang_name || getLangName(node.lang);
const displayWord = node.lexeme || node.id;
// Keep nodes clean: just word + language name
return displayWord + '\n(' + langName.toLowerCase() + ')';
}