5
Komputasi Rentang Juz
juzData adalah satu-satunya tempat di repository ini yang memotong larik verses milik data/quran.json berdasarkan batas yang tersimpan di data/juz.json. Fungsi menerima nomor juz 1-based dan mengembalikan satu objek berisi ayat gabungan dari satu atau beberapa surah. Endpoint /juz/:juz mendaftarkan JuzHandler.getJuz bersama middleware caching sebagai penanganannya (api/routes.js:381).
Titik masuk dan penyelarasan indeks
Handler mengubah parameter juz dari path menjadi bilangan dengan parseInt, lalu memperlakukan hasil null sebagai 404 dengan pesan Juz "<juz>" is not found. (api/handlers/juz.js:8-152). Di dalam juzData, metadata juz diambil lewat juz[_inputJuz - 1], dan fungsi langsung berhenti bila entri itu tidak ada (api/lib/juz.js:4-73). Sesudah itu empat nilai batas dihitung sekali di awal, sebelum percabangan apa pun (api/lib/juz.js:9-124).
| Ekspresi | Variabel | Nilai untuk juz 30 (78:1 → 114:6) | Peran |
|---|---|---|---|
inputJuz.start.index - 1 | startSurah | 77 | posisi surah awal di larik quran |
inputJuz.start.verse - 1 | startAyah | 0 | batas awal slice yang inklusif |
inputJuz.end.index - 1 | endSurah | 113 | posisi surah akhir di larik quran |
inputJuz.end.verse | endAyah | 6 | batas akhir slice yang eksklusif |
Perhatikan bahwa hanya endAyah yang tetap memakai nilai 1-based. slice memperlakukan argumen keduanya sebagai batas eksklusif, sehingga slice(0, 6) pada surah 114 menghasilkan ayat 1 sampai 6. Sebaliknya startAyah dan endSurah harus turun satu karena dipakai sebagai posisi larik. Kedua sumber batas memakai bentuk {"index", "verse"} yang sama, misalnya entri juz 1 (data/juz.json:4-155) dan entri juz 30 (data/juz.json:324-3346).
Tiga cabang pengirisan
Setelah indeks diselaraskan, juzData memilih satu dari tiga jalur pengirisan berdasarkan jarak antara startSurah dan endSurah.
graph TD
A["juzData(_inputJuz)"] --> B["inputJuz = juz[_inputJuz - 1]"]
B -->|tidak ada| C["return null"]
C --> Z["404 di JuzHandler.getJuz"]
B --> D["startSurah, startAyah, endSurah, endAyah"]
D --> E{"startSurah === endSurah"}
E -->|ya| F["verses.slice(startAyah, endAyah)"]
E -->|tidak| G{"selisih endSurah - startSurah lebih dari 1"}
G -->|ya| H["slice(startAyah) + quran.slice(startSurah + 1, endSurah) + slice(0, endAyah)"]
G -->|tidak| I["slice(startAyah) + slice(0, endAyah)"]
F --> J["juzAyah"]
H --> J
I --> J
style A fill:#f59e0b,color:#000
style C fill:#dc2626,color:#fff
style Z fill:#dc2626,color:#fff
style H fill:#8b5cf6,color:#fff
style J fill:#2d7d46,color:#fff
%% fig: Percabangan juzData dari metadata juz sampai juzAyah
%% desc: Satu kondisi kesamaan surah dan satu kondisi jarak surah menentukan tiga cara pemotongan verses, lalu semuanya bertemu di juzAyah.Cabang pertama berlaku ketika juz tidak melewati batas surah, dan cukup satu pemotongan verses.slice(startAyah, endAyah) (api/lib/juz.js:16-177). Cabang kedua dipakai saat juz melintasi lebih dari dua surah: surah pertama dipotong sampai habis, surah-surah di tengah diratakan, dan surah terakhir dipotong dari awal (api/lib/juz.js:18-288). Cabang ketiga menangani juz yang hanya menyentuh dua surah, dengan menggabungkan potongan ekor surah awal dan potongan kepala surah akhir (api/lib/juz.js:29-339).
| Juz | Batas di juz.json | startSurah / endSurah | Cabang | Irisan yang dihasilkan |
|---|---|---|---|---|
| 1 | 1:1 → 2:141 | 0 / 1 | ketiga (dua surah) | slice(0) surah 1 (7 ayat) + slice(0, 141) surah 2 = 148 ayat |
| 2 | 2:142 → 2:252 | 1 / 1 | pertama (satu surah) | slice(141, 252) = 111 ayat |
| 3 | 2:253 → 3:92 | 1 / 2 | ketiga (dua surah) | slice(252) surah 2 (34 ayat, dari numberOfVerses 286) + slice(0, 92) surah 3 = 126 ayat |
| 30 | 78:1 → 114:6 | 77 / 113 | kedua (lebih dari dua surah) | slice(0) surah 78 + seluruh surah 79 sampai 113 + slice(0, 6) surah 114 |
Angka 7 untuk surah 1 dan 286 untuk surah 2 adalah numberOfVerses yang tercatat di quran.json (data/quran.json:910) (data/quran.json:31711). Juz 3 menunjukkan bahwa selisih satu surah tetap masuk cabang ketiga, karena syarat cabang kedua adalah selisih yang lebih besar dari satu.
Meratakan surah di tengah
Pada cabang kedua, larik surah di tengah diambil dengan quran.slice(startSurah + 1, endSurah), sehingga surah batas tidak ikut terambil dua kali (api/lib/juz.js:18-288). Hasil slice itu masih berupa larik surah, jadi dua map bersarang dipakai untuk mendorong setiap ayat ke _middleSurah satu per satu. Sesudah perataan, juzAyah dibentuk dengan spread [..._firstSurah, ..._middleSurah, ..._lastSurah], sehingga urutan surah dan urutan ayat di dalam tiap surah tetap terjaga.
Objek ayat yang didorong membawa penomoran gandanya sendiri, number.inQuran dan number.inSurah (data/quran.json:33-3512). Karena itu daftar ayat yang sudah rata tetap bisa dilacak asal surahnya meskipun verses pada response berupa satu larik datar.
⚠️
juz[_inputJuz - 1]bergantung pada urutan larik didata/juz.json, bukan pada pencarian fieldindex.parseIntpada handler juga berarti masukan non-numerik menjadiNaN, sehinggajuz[NaN]bernilaiundefineddan response berakhir di 404, bukan di error 500 (api/lib/juz.js:4-73).
Merakit objek keluaran
Setelah juzAyah terkumpul, fungsi mengambil nama surah awal dan surah akhir dari name.transliteration.id, lalu menyusun objek data (api/lib/juz.js:35-4513).
graph LR
S1["inputJuz.start.verse"] --> I1["juzStartInfo"]
N1["quran[startSurah].name.transliteration.id"] --> I1
S2["inputJuz.end.verse"] --> I2["juzEndInfo"]
N2["quran[endSurah].name.transliteration.id"] --> I2
E1["inputJuz.start.index"] --> B1["juzStartSurahNumber"]
E2["inputJuz.end.index"] --> B2["juzEndSurahNumber"]
J["juzAyah"] --> T["totalVerses = juzAyah.length"]
J --> V["verses"]
style J fill:#8b5cf6,color:#fff
style T fill:#2d7d46,color:#fff
style V fill:#336791,color:#fff
style I1 fill:#f59e0b,color:#000
style I2 fill:#f59e0b,color:#000
%% fig: Perakitan field response dari juzAyah dan metadata juz
%% desc: Nama surah dan nomor ayat membentuk label info, sedangkan juzAyah menjadi verses sekaligus sumber totalVerses.| Field | Sumber |
|---|---|
juz | _inputJuz apa adanya |
juzStartSurahNumber | inputJuz.start.index |
juzEndSurahNumber | inputJuz.end.index |
juzStartInfo | template ${startSurahName} - ${inputJuz.start.verse} |
juzEndInfo | template ${endSurahName} - ${inputJuz.end.verse} |
totalVerses | juzAyah.length, yaitu jumlah ayat gabungan |
verses | juzAyah |
Karena totalVerses dihitung dari panjang juzAyah, nilainya selalu konsisten dengan isi verses tanpa perlu menjumlahkan numberOfVerses surah satu per satu (api/lib/juz.js:35-4513). Bentuk response lengkap dan pembungkusan code/status/message dijelaskan di Kontrak Response dan Penanganan Error, sedangkan struktur kedua berkas sumbernya dibahas di Model Data quran.json dan juz.json.