58 lines
4.2 KiB
JavaScript
58 lines
4.2 KiB
JavaScript
// The Bibles the Reader can show, and one way to fetch a chapter of any of them. Used by the
|
|
// main reading text, the side-by-side view, and the verse "Compare" tab.
|
|
import { CHAPTER_COUNTS, parseBibleChapter } from './bibleUtils.jsx';
|
|
|
|
export const READER_TRANSLATIONS = [
|
|
{ id: 'BSB', name: 'Berean Standard Bible' },
|
|
{ id: 'ESV', name: 'English Standard Version', licensed: true,
|
|
notice: 'Scripture quotations are from the ESV® Bible (The Holy Bible, English Standard Version®), © 2001 by Crossway, a publishing ministry of Good News Publishers. Used by permission. All rights reserved.' },
|
|
{ id: 'NET', name: 'NET Bible', helloao: 'eng_net',
|
|
notice: 'Scripture quoted by permission. Quotations designated (NET) are from the NET Bible® copyright ©1996-2017 by Biblical Studies Press, L.L.C. http://netbible.com All rights reserved.' },
|
|
{ id: 'KJV', name: 'King James Version', helloao: 'eng_kjv', notice: 'The King James Version is in the public domain.' },
|
|
{ id: 'ASV', name: 'American Standard Version (1901)', helloao: 'eng_asv', notice: 'The American Standard Version (1901) is in the public domain.' },
|
|
{ id: 'LSV', name: 'Literal Standard Version', helloao: 'eng_lsv', notice: 'Literal Standard Version © 2020 Covenant Press and the Covenant Christian Coalition. Free to read and share. lsvbible.com' },
|
|
{ id: 'NLT', name: 'New Living Translation', licensed: true,
|
|
notice: 'Holy Bible, New Living Translation, Copyright © 2014, Tyndale House Publishers. All rights reserved. tyndale.com' },
|
|
{ id: 'CSB', name: 'Christian Standard Bible', licensed: true,
|
|
notice: 'Christian Standard Bible® and CSB® are federally registered trademarks of Holman Bible Publishers. All rights reserved. bhpublishinggroup.com' },
|
|
{ id: 'NASB', name: 'New American Standard Bible', licensed: true,
|
|
notice: 'New American Standard Bible®, Copyright © 1995, The Lockman Foundation. All rights reserved. lockman.org' },
|
|
];
|
|
|
|
// The address code helloao uses for a translation (NET is 'eng_net', the KJV 'eng_kjv'; BSB is its own)
|
|
export const helloaoCode = (id) => READER_TRANSLATIONS.find((t) => t.id === id)?.helloao ?? id ?? 'BSB';
|
|
export const translationName = (id) => READER_TRANSLATIONS.find((t) => t.id === id)?.name ?? id;
|
|
export const isLicensed = (id) => READER_TRANSLATIONS.find((t) => t.id === id)?.licensed === true;
|
|
|
|
// Free translations are kept for the visit so flipping between chapters, the side-by-side
|
|
// view and Compare don't re-download. Licensed text is never kept here (their terms limit
|
|
// storage); the server holds it briefly.
|
|
const freeChapters = new Map(); // "BSB/JHN/3" -> { verses, totalChapters }
|
|
|
|
export const clearChapterCache = () => freeChapters.clear();
|
|
|
|
// -> { verses: [{ number, text }], copyright, totalChapters }. Throws Error(message) on failure.
|
|
// Pass `signal` to cancel a request that is no longer wanted.
|
|
export async function fetchChapter(translation, bookAbbrev, chapter, { signal } = {}) {
|
|
const source = READER_TRANSLATIONS.find((t) => t.id === translation) ?? READER_TRANSLATIONS[0];
|
|
let totalChapters = CHAPTER_COUNTS[bookAbbrev] ?? chapter;
|
|
if (!source.licensed) {
|
|
const key = `${source.id}/${bookAbbrev}/${chapter}`;
|
|
const hit = freeChapters.get(key);
|
|
if (hit) return { verses: hit.verses, copyright: '', totalChapters: hit.totalChapters };
|
|
const res = await fetch(`https://bible.helloao.org/api/${source.helloao ?? source.id}/${bookAbbrev}/${chapter}.json`, { signal });
|
|
if (!res.ok) throw new Error('Unable to load chapter.');
|
|
const data = await res.json();
|
|
const verses = parseBibleChapter(data);
|
|
if (!Array.isArray(verses) || verses.length === 0) throw new Error('Invalid Bible data returned.');
|
|
totalChapters = data.book?.numberOfChapters ?? totalChapters;
|
|
freeChapters.set(key, { verses, totalChapters });
|
|
return { verses, copyright: '', totalChapters };
|
|
}
|
|
const res = await fetch(`/api/bible/${source.id}/${bookAbbrev}/${chapter}`, { credentials: 'include', signal });
|
|
const data = await res.json().catch(() => ({}));
|
|
if (!res.ok) throw new Error(data.error || `Unable to load ${source.id}.`);
|
|
if (!Array.isArray(data.verses) || data.verses.length === 0) throw new Error('Invalid Bible data returned.');
|
|
return { verses: data.verses, copyright: data.copyright ?? '', totalChapters };
|
|
}
|