First commit on the local Gitea server, made after moving the tree off the Windows machine. Build outputs, node_modules and the AI models stay out (see .gitignore); everything the installer build needs is tracked. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
196 lines
7.2 KiB
JavaScript
196 lines
7.2 KiB
JavaScript
// Accordance API Integration Module
|
|
// This module provides functions to query Accordance Bible Software via OSC
|
|
// for enhanced word information to display in popup cards
|
|
|
|
/**
|
|
* Query Accordance for word information
|
|
* @param {string} word - The word to look up
|
|
* @param {string} reference - Optional Bible reference (e.g., "John 3:16")
|
|
* @returns {Promise<Object>} Enhanced word information from Accordance
|
|
*/
|
|
export async function queryAccordanceWord(word, reference = null) {
|
|
try {
|
|
// Build request payload
|
|
const payload = {
|
|
word: word,
|
|
reference: reference || getCurrentReference()
|
|
};
|
|
|
|
console.log('[Accordance API] Querying word:', payload);
|
|
|
|
// Send request to server endpoint which proxies to Accordance via OSC
|
|
const response = await fetch('/api/accordance/word', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify(payload)
|
|
});
|
|
|
|
console.log('[Accordance API] Response status:', response.status);
|
|
|
|
if (!response.ok) {
|
|
const errorData = {
|
|
success: false,
|
|
error: `HTTP ${response.status}`,
|
|
word: word,
|
|
reference: reference
|
|
};
|
|
console.warn('[Accordance API] Response not OK:', errorData);
|
|
return errorData;
|
|
}
|
|
|
|
const data = await response.json();
|
|
console.log('[Accordance API] Response data:', data);
|
|
return data;
|
|
} catch (error) {
|
|
console.warn('[Accordance API] Failed to query word:', word, error);
|
|
// Return error object instead of null so enhancement function can process it
|
|
return {
|
|
success: false,
|
|
error: error.message || 'Network error',
|
|
word: word,
|
|
reference: reference
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get current Bible reference from active tab
|
|
* @returns {string|null} Current reference or null
|
|
*/
|
|
function getCurrentReference() {
|
|
try {
|
|
const activeTab = window.bibleApp?.tabs?.find(t => t.id === window.bibleApp?.activeTabId);
|
|
if (!activeTab) return null;
|
|
|
|
const book = activeTab.book || '';
|
|
const chapter = activeTab.chapter || '';
|
|
const verse = activeTab.verse || '';
|
|
|
|
if (book && chapter) {
|
|
return verse ? `${book} ${chapter}:${verse}` : `${book} ${chapter}`;
|
|
}
|
|
return null;
|
|
} catch (_) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Enhance word info object with Accordance data
|
|
* @param {Object} wordInfo - Base word info object
|
|
* @param {string} word - The word being looked up
|
|
* @param {string} reference - Optional Bible reference
|
|
* @returns {Promise<Object>} Enhanced word info with Accordance data
|
|
*/
|
|
export async function enhanceWordInfoWithAccordance(wordInfo, word, reference = null) {
|
|
try {
|
|
console.log('[Accordance API] Enhancing word info for:', word, 'reference:', reference);
|
|
const accordanceData = await queryAccordanceWord(word, reference);
|
|
console.log('[Accordance API] Received data:', accordanceData);
|
|
|
|
// Merge Accordance data into word info
|
|
const enhanced = { ...wordInfo };
|
|
|
|
// Always add Accordance section - this ensures it shows up in the popup
|
|
if (!accordanceData) {
|
|
// No response at all
|
|
enhanced.accordance = {
|
|
available: true,
|
|
attempted: true,
|
|
error: 'No response from Accordance API',
|
|
note: 'Accordance integration attempted but no response received'
|
|
};
|
|
console.log('[Accordance API] No response data, adding error info');
|
|
} else if (accordanceData.success) {
|
|
// Success - add all the data
|
|
enhanced.accordance = {
|
|
available: true,
|
|
strongs: accordanceData.strongs || null,
|
|
lexicalForm: accordanceData.lexicalForm || null,
|
|
morphology: accordanceData.morphology || null,
|
|
definition: accordanceData.definition || null,
|
|
usage: accordanceData.usage || null,
|
|
crossReferences: accordanceData.crossReferences || [],
|
|
commentaries: accordanceData.commentaries || [],
|
|
originalLanguage: accordanceData.originalLanguage || null,
|
|
note: accordanceData.note || null
|
|
};
|
|
console.log('[Accordance API] Enhanced wordInfo with Accordance data:', enhanced.accordance);
|
|
} else {
|
|
// Failed - still show section with error
|
|
enhanced.accordance = {
|
|
available: true,
|
|
attempted: true,
|
|
error: accordanceData.error || 'Accordance query failed',
|
|
note: accordanceData.note || 'Accordance integration attempted but no data received'
|
|
};
|
|
console.log('[Accordance API] Accordance query failed, adding error info:', enhanced.accordance);
|
|
}
|
|
|
|
console.log('[Accordance API] Final enhanced wordInfo:', enhanced);
|
|
|
|
// Enhance Greek data if available (guard derefs: enhanced.greek may be undefined)
|
|
if (accordanceData.greek && !(enhanced.greek && enhanced.greek.text)) {
|
|
enhanced.greek = {
|
|
text: accordanceData.greek.text || (enhanced.greek && enhanced.greek.text),
|
|
transliteration: accordanceData.greek.transliteration || (enhanced.greek && enhanced.greek.transliteration),
|
|
meaning: accordanceData.greek.meaning || (enhanced.greek && enhanced.greek.meaning)
|
|
};
|
|
}
|
|
|
|
// Enhance Hebrew data if available (guard derefs: enhanced.hebrew may be undefined)
|
|
if (accordanceData.hebrew && !(enhanced.hebrew && enhanced.hebrew.text)) {
|
|
enhanced.hebrew = {
|
|
text: accordanceData.hebrew.text || (enhanced.hebrew && enhanced.hebrew.text),
|
|
transliteration: accordanceData.hebrew.transliteration || (enhanced.hebrew && enhanced.hebrew.transliteration),
|
|
meaning: accordanceData.hebrew.meaning || (enhanced.hebrew && enhanced.hebrew.meaning)
|
|
};
|
|
}
|
|
|
|
return enhanced;
|
|
} catch (error) {
|
|
console.warn('[Accordance API] Failed to enhance word info:', error);
|
|
return wordInfo;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if Accordance integration is available
|
|
* @returns {Promise<boolean>} True if Accordance is available
|
|
*/
|
|
export async function checkAccordanceAvailability() {
|
|
try {
|
|
const response = await fetch('/api/accordance/status');
|
|
if (!response.ok) {
|
|
console.log('[Accordance API] Status check failed:', response.status);
|
|
// Still return true to attempt integration (graceful fallback)
|
|
return true;
|
|
}
|
|
const data = await response.json();
|
|
const available = data.available === true || data.configured === true || data.oscModuleInstalled === true;
|
|
console.log('[Accordance API] Availability check:', available, data);
|
|
return available;
|
|
} catch (error) {
|
|
console.warn('[Accordance API] Status check error:', error);
|
|
// Return true to attempt integration anyway (will gracefully handle errors)
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// Make functions available globally for backward compatibility
|
|
if (typeof window !== 'undefined') {
|
|
window.queryAccordanceWord = queryAccordanceWord;
|
|
window.enhanceWordInfoWithAccordance = enhanceWordInfoWithAccordance;
|
|
window.checkAccordanceAvailability = checkAccordanceAvailability;
|
|
|
|
// Also expose via window.accordance for namespacing
|
|
window.accordance = {
|
|
queryWord: queryAccordanceWord,
|
|
enhanceWordInfo: enhanceWordInfoWithAccordance,
|
|
checkAvailability: checkAccordanceAvailability
|
|
};
|
|
}
|
|
|