mirror of
https://github.com/acamarata/moon-cycle.git
synced 2026-06-30 18:54:29 +00:00
Port to TypeScript with dual CJS/ESM build via tsup. Fix off-by-one bug in both cycleMonth and cycleYear (images are 1-indexed; v1 returned 000.webp/0000.webp which don't exist). Add imageFolder and cdnUrl helpers for jsDelivr CDN integration. Export constants and types. Separate the ~438 MB image dataset from the npm package via the files field, making moon-cycle publishable to npm for the first time. Add CI workflow with Node 20/22/24 matrix, typecheck, and pack-check jobs. Add wiki-sync workflow and full .wiki/ documentation (Home, API Reference, Architecture, Migration Guide).
30 lines
1.2 KiB
TypeScript
30 lines
1.2 KiB
TypeScript
import { SYNODIC_MONTH, MONTH_IMAGES, MONTH_ANCHOR } from './types.js';
|
|
|
|
const SYNODIC_SECONDS = SYNODIC_MONTH * 24 * 60 * 60;
|
|
|
|
/**
|
|
* Maps a date to the corresponding NASA moon phase image for the monthly cycle.
|
|
*
|
|
* The monthly dataset contains 708 hourly images spanning exactly one synodic
|
|
* month (29.53 days). This function computes the fractional position within
|
|
* the current synodic month relative to the 2023-11-13 new moon anchor and
|
|
* maps that fraction to an image index in [1, 708].
|
|
*
|
|
* @param date - The date to resolve. Defaults to the current time.
|
|
* @returns A zero-padded filename string, e.g. `"354.webp"`.
|
|
*/
|
|
export function cycleMonth(date: Date = new Date()): string {
|
|
// Seconds elapsed since the known new moon anchor
|
|
const elapsed = (date.getTime() - MONTH_ANCHOR.getTime()) / 1000;
|
|
|
|
// Total synodic months elapsed (may be negative for past dates)
|
|
const months = elapsed / SYNODIC_SECONDS;
|
|
|
|
// Fractional part of the current month: always in [0, 1)
|
|
const fraction = months - Math.floor(months);
|
|
|
|
// Map to 1-indexed image number: 1 to MONTH_IMAGES
|
|
const index = Math.floor(fraction * MONTH_IMAGES) + 1;
|
|
|
|
return index.toString().padStart(3, '0') + '.webp';
|
|
}
|