Files
bible-app/accordance-api.js
T
christianandClaude Opus 5 0db5e9b07d Bible App 1.4.34 — full source
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>
2026-09-24 13:05:20 -04:00

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
};
}