The library provides three async loader functions for lazy-loading datasets. These loaders use dynamic imports for code splitting, keeping your initial bundle size minimal.
Overview
All data loaders are asynchronous and should be called once at app startup:
import {
loadQuranData,
loadMorphology,
loadWordMap,
type QuranText,
type MorphologyAya,
type WordMap,
} from 'quran-search-engine';
const [quranData, morphologyMap, wordMap] = await Promise.all([
loadQuranData(),
loadMorphology(),
loadWordMap(),
]);
// Example output:
// quranData.length => 6236
// morphologyMap.size => 6236
// Object.keys(wordMap).length => (depends on dataset)
Load Quran data
loadQuranData()
Loads the complete Quran dataset containing 6,236 verses with text in both standard and Uthmani scripts.
Returns: Promise<QuranText[]>
Use case: Load once at app startup (browser or Node), then reuse in searches.
import { loadQuranData, type QuranText } from 'quran-search-engine';
const quranData: QuranText[] = await loadQuranData();
// Example output:
// quranData[0] => {
// gid: 1,
// uthmani: '...',
// standard: '...',
// sura_id: 1,
// aya_id: 1,
// ...
// }
The QuranText type includes fields like sura_id, aya_id, gid, page_id, juz_id, sura_name, uthmani, standard, and more.
Load morphology data
loadMorphology()
Loads morphological analysis data (lemmas and roots) for all verses. This large dataset is loaded asynchronously to avoid increasing the initial bundle size.
Returns: Promise<Map<number, MorphologyAya>>
Use case: Enable lemma/root search and scoring.
import { loadMorphology, type MorphologyAya } from 'quran-search-engine';
const morphologyMap: Map<number, MorphologyAya> = await loadMorphology();
// Example output:
// morphologyMap.get(1) => {
// gid: 1,
// lemmas: ['...'],
// roots: ['...']
// }
The morphology data is stored as a Map for O(1) access by verse GID.
Load word map
loadWordMap()
Loads the word map dictionary that maps normalized Arabic tokens to their canonical lemma and root forms.
Returns: Promise<WordMap>
Use case: Map normalized query tokens to their canonical lemma/root for linguistic matching.
import { loadWordMap, type WordMap } from 'quran-search-engine';
const wordMap: WordMap = await loadWordMap();
// Example output:
// wordMap['الله'] => { lemma: 'الله', root: 'ا ل ه' }
Error handling
All loader functions include built-in error handling. If a required data file is missing, they throw descriptive errors:
try {
const quranData = await loadQuranData();
} catch (error) {
console.error('Failed to load Quran data:', error);
// Error: Could not load Quran data. Ensure src/data/quran.json exists.
}
Ensure all data files exist in src/data/ before running the loaders:
src/data/quran.json
src/data/morphology.json
src/data/word-map.json
Data sources
The bundled lemma (morphology) data and word map were downloaded from Quranic Arabic Corpus v4.0: https://corpus.quran.com
Implementation details
From src/utils/loader.ts:9-31:
export const loadMorphology = async (): Promise<Map<number, MorphologyAya>> => {
try {
// Dynamic import for code splitting
const morphologyModule = await import('../data/morphology.json');
// The JSON is likely an array (or has a 'default' property if it's a module).
// We handle both cases to be safe with different bundlers.
const morphologyArray = (morphologyModule.default || morphologyModule) as MorphologyAya[];
// Transform array to Map for O(1) access
const morphologyMap = new Map<number, MorphologyAya>();
for (const item of morphologyArray) {
if (item && typeof item.gid === 'number') {
morphologyMap.set(item.gid, item);
}
}
return morphologyMap;
} catch (error) {
console.error('Failed to load morphology data:', error);
throw new Error('Could not load morphology data. Ensure src/data/morphology.json exists.');
}
};
The loader:
- Uses dynamic imports for automatic code splitting
- Handles both default and named exports for bundler compatibility
- Transforms the array into a Map for optimal lookup performance
- Validates data structure before adding to the map