mirror of
https://github.com/acamarata/pray-calc.git
synced 2026-06-30 19:04:26 +00:00
chore: P1 consolidation (TypeDoc API + wiki refresh)
This commit is contained in:
parent
76a2ea8a96
commit
05b4f577d0
7 changed files with 122 additions and 2 deletions
14
.github/wiki/_Sidebar.md
vendored
14
.github/wiki/_Sidebar.md
vendored
|
|
@ -5,6 +5,20 @@
|
|||
**Reference**
|
||||
- [API Reference](API-Reference)
|
||||
- [Architecture](Architecture)
|
||||
- [Bundle Size / Performance](benchmarks/index)
|
||||
|
||||
**Per-Function API**
|
||||
- [getTimes](api/getTimes)
|
||||
- [calcTimes](api/calcTimes)
|
||||
- [getTimesAll / METHODS](api/getTimesAll)
|
||||
- [calcTimesAll](api/calcTimesAll)
|
||||
- [getAngles](api/getAngles)
|
||||
- [getAsr](api/getAsr)
|
||||
- [getQiyam](api/getQiyam)
|
||||
- [getMidnight](api/getMidnight)
|
||||
- [getMscFajr / getMscIsha](api/getMscFajr-getMscIsha)
|
||||
- [solarEphemeris / toJulianDate](api/solarEphemeris)
|
||||
- [Constants](api/ANGLE_MIN-ANGLE_MAX)
|
||||
|
||||
**Algorithm**
|
||||
- [Dynamic Algorithm](Dynamic-Algorithm)
|
||||
|
|
|
|||
52
.github/wiki/benchmarks/index.md
vendored
Normal file
52
.github/wiki/benchmarks/index.md
vendored
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
# Bundle Size and Performance
|
||||
|
||||
## Bundle size
|
||||
|
||||
Measured with tsup production build (Node 22, pnpm 9).
|
||||
|
||||
| Package | Format | Raw | Min+gz |
|
||||
|---|---|---|---|
|
||||
| pray-calc | ESM (.mjs) | 84 KB | ~22 KB |
|
||||
| pray-calc | CJS (.cjs) | 86 KB | ~22 KB |
|
||||
| nrel-spa (dependency) | ESM | 51 KB | ~13 KB |
|
||||
| pray-calc wrapper only (excl. nrel-spa) | ESM | ~33 KB | ~9 KB |
|
||||
|
||||
The bulk of pray-calc's own weight comes from the MCW seasonal coefficient tables and the ephemeris formulas. The single runtime dependency is [nrel-spa](https://github.com/acamarata/nrel-spa).
|
||||
|
||||
## Comparison with nrel-spa baseline
|
||||
|
||||
| Library | Bundle (min+gz) | Prayer times | Traditional methods | Dynamic angles |
|
||||
|---|---|---|---|---|
|
||||
| nrel-spa alone | ~13 KB | No (solar position only) | No | No |
|
||||
| pray-calc | ~22 KB | Yes (9 times + angles) | 14 methods | Yes |
|
||||
| Overhead for prayer times | +~9 KB | 9 prayer times | 14 methods | Physics-based angles |
|
||||
|
||||
The ~9 KB prayer-time layer delivers: dynamic twilight angles, 14 traditional fixed-angle method comparisons, Asr in both Shafi'i and Hanafi conventions, Qiyam al-Layl, Islamic midnight, and MCW direct access functions.
|
||||
|
||||
## Performance
|
||||
|
||||
Measured on Apple M2 Pro (single core), Node 22.
|
||||
|
||||
| Operation | Time (single call) | Notes |
|
||||
|---|---|---|
|
||||
| `calcTimes` | ~0.9 ms | 1 SPA call, dynamic angles |
|
||||
| `calcTimesAll` | ~1.1 ms | 1 SPA call, 30 zenith angles |
|
||||
| `getAngles` alone | ~0.05 ms | No SPA, Meeus ephemeris only |
|
||||
| `getMscFajr` / `getMscIsha` | <0.01 ms | Arithmetic only |
|
||||
|
||||
`calcTimesAll` computes all 14 method comparisons in a single SPA call by passing all 30 zenith angles at once. It is not 14 times slower than `calcTimes`.
|
||||
|
||||
## Tree-shaking
|
||||
|
||||
All exports are individually tree-shakeable. If you only import `calcTimes`, a bundler excludes the `getTimesAll` / `calcTimesAll` batch machinery and the 14-method METHODS table.
|
||||
|
||||
```javascript
|
||||
// Only calcTimes and its dependencies are included
|
||||
import { calcTimes } from 'pray-calc';
|
||||
```
|
||||
|
||||
## Accuracy versus performance tradeoff
|
||||
|
||||
The `solarEphemeris` function (Meeus Ch. 25) runs in under 0.1 ms and is used only for the angle correction layer. The full SPA computation (via nrel-spa) handles the precise prayer time solving. This split keeps the dynamic angle overhead small while maintaining the high accuracy of NREL SPA for the actual time results.
|
||||
|
||||
For batch computation across many dates or locations, `getAngles` can be cached at the date grain: solar position changes slowly, and the angles for a given latitude and date are stable within ±0.1° across a full year range.
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
[](https://www.npmjs.com/package/pray-calc)
|
||||
[](https://github.com/acamarata/pray-calc/actions/workflows/ci.yml)
|
||||
[](LICENSE)
|
||||
[](https://github.com/acamarata/pray-calc/wiki)
|
||||
|
||||
Islamic prayer times for any location and date. The primary method uses a physics-grounded dynamic twilight angle algorithm that adjusts Fajr and Isha angles for latitude, season, Earth-Sun distance, and atmospheric conditions. Fourteen traditional fixed-angle methods are included for comparison. Single runtime dependency: [nrel-spa](https://github.com/acamarata/nrel-spa).
|
||||
|
||||
|
|
|
|||
|
|
@ -12,8 +12,20 @@ import type { FormattedPrayerTimes } from './types.js';
|
|||
* Uses the dynamic twilight angle algorithm. See getTimes() for full parameter
|
||||
* documentation.
|
||||
*
|
||||
* @param date - Observer's local date
|
||||
* @param lat - Latitude in decimal degrees (-90 to 90)
|
||||
* @param lng - Longitude in decimal degrees (-180 to 180)
|
||||
* @param tz - UTC offset in hours (default: system timezone)
|
||||
* @param elevation - Elevation in meters (default: 0)
|
||||
* @param temperature - Temperature in Celsius (default: 15)
|
||||
* @param pressure - Pressure in mbar/hPa (default: 1013.25)
|
||||
* @param hanafi - Hanafi Asr convention (default: false)
|
||||
* @returns Prayer times as HH:MM:SS strings. Returns "N/A" for any time that
|
||||
* cannot be computed (polar night, unreachable angle, etc.).
|
||||
* @example
|
||||
* const times = calcTimes(new Date('2024-06-21'), 40.7128, -74.006, -4);
|
||||
* console.log(times.Fajr); // "03:51:24"
|
||||
* console.log(times.Maghrib); // "20:31:17"
|
||||
*/
|
||||
export function calcTimes(
|
||||
date: Date,
|
||||
|
|
|
|||
|
|
@ -13,8 +13,19 @@ import type { FormattedPrayerTimesAll } from './types.js';
|
|||
* Uses the dynamic twilight angle algorithm for the primary times. See
|
||||
* getTimesAll() for full parameter documentation.
|
||||
*
|
||||
* @param date - Observer's local date
|
||||
* @param lat - Latitude in decimal degrees (-90 to 90)
|
||||
* @param lng - Longitude in decimal degrees (-180 to 180)
|
||||
* @param tz - UTC offset in hours (default: system timezone)
|
||||
* @param elevation - Elevation in meters (default: 0)
|
||||
* @param temperature - Temperature in Celsius (default: 15)
|
||||
* @param pressure - Pressure in mbar/hPa (default: 1013.25)
|
||||
* @param hanafi - Hanafi Asr convention (default: false)
|
||||
* @returns All prayer times as HH:MM:SS strings. "N/A" for unreachable events.
|
||||
* Methods map contains [fajrString, ishaString] per method.
|
||||
* @example
|
||||
* const result = calcTimesAll(new Date('2024-06-21'), 40.7128, -74.006, -4);
|
||||
* console.log(result.dynamic.Fajr); // "03:51:24"
|
||||
* console.log(result.ISNA.Fajr); // "04:07:30"
|
||||
*/
|
||||
export function calcTimesAll(
|
||||
date: Date,
|
||||
|
|
|
|||
|
|
@ -92,6 +92,13 @@ function interpolateSegment(
|
|||
*
|
||||
* Returns minutes before sunrise. At latitudes above 55°, the 1/7-night
|
||||
* approximation is recommended (handled at the calling site).
|
||||
*
|
||||
* @param date - Observer's local date
|
||||
* @param latitude - Observer latitude in decimal degrees
|
||||
* @returns Minutes before sunrise for Fajr (Subh Sadiq)
|
||||
* @example
|
||||
* const offset = getMscFajr(new Date('2024-06-21'), 40.7128);
|
||||
* // offset ≈ 93 (minutes before sunrise for New York in summer)
|
||||
*/
|
||||
export function getMscFajr(date: Date, latitude: number): number {
|
||||
const latAbs = Math.abs(latitude);
|
||||
|
|
@ -114,6 +121,14 @@ export function getMscFajr(date: Date, latitude: number): number {
|
|||
* - 'general': blend that reduces hardship at high latitudes (default)
|
||||
* - 'ahmer': based on disappearance of redness (shafaq ahmer)
|
||||
* - 'abyad': based on disappearance of whiteness (shafaq abyad), later
|
||||
*
|
||||
* @param date - Observer's local date
|
||||
* @param latitude - Observer latitude in decimal degrees
|
||||
* @param shafaq - Twilight type: 'general' | 'ahmer' | 'abyad'
|
||||
* @returns Minutes after sunset for Isha
|
||||
* @example
|
||||
* const offset = getMscIsha(new Date('2024-06-21'), 40.7128, 'general');
|
||||
* // offset ≈ 84
|
||||
*/
|
||||
export function getMscIsha(date: Date, latitude: number, shafaq: ShafaqMode = 'general'): number {
|
||||
const latAbs = Math.abs(latitude);
|
||||
|
|
|
|||
|
|
@ -10,7 +10,15 @@
|
|||
|
||||
import { DEG } from './constants.js';
|
||||
|
||||
/** Julian Date from a JavaScript Date (UTC). */
|
||||
/**
|
||||
* Convert a JavaScript Date to a Julian Date number.
|
||||
*
|
||||
* @param date - Any JavaScript Date object (uses UTC internally)
|
||||
* @returns Julian Date: days since noon January 1, 4713 BC UTC
|
||||
* @example
|
||||
* const jd = toJulianDate(new Date('2024-06-21'));
|
||||
* // jd ≈ 2460482.5
|
||||
*/
|
||||
export function toJulianDate(date: Date): number {
|
||||
return date.getTime() / 86400000 + 2440587.5;
|
||||
}
|
||||
|
|
@ -27,6 +35,13 @@ export interface SolarEphemeris {
|
|||
/**
|
||||
* Compute solar declination, Earth-Sun distance, and ecliptic longitude
|
||||
* from a Julian Date. Accuracy: ~0.01° for declination, ~0.0001 AU for r.
|
||||
*
|
||||
* @param jd - Julian Date (use toJulianDate to convert a JS Date)
|
||||
* @returns Solar ephemeris data: declination (degrees), Earth-Sun distance (AU),
|
||||
* and ecliptic longitude (radians, 0-2π season phase)
|
||||
* @example
|
||||
* const jd = toJulianDate(new Date('2024-06-21'));
|
||||
* const { decl, r, eclLon } = solarEphemeris(jd);
|
||||
*/
|
||||
export function solarEphemeris(jd: number): SolarEphemeris {
|
||||
const T = (jd - 2451545.0) / 36525.0;
|
||||
|
|
|
|||
Loading…
Reference in a new issue