moon-cycle/.wiki/API-Reference.md
Aric Camarata 24db90e9f5 feat: v2.0.0 — TypeScript rewrite, npm-publishable, off-by-one fix
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).
2026-02-25 15:34:10 -05:00

5.9 KiB

API Reference

Complete reference for moon-cycle v2.

Functions

cycleMonth(date?)

function cycleMonth(date?: Date): string

Maps a date to an image filename in the monthly (synodic) dataset.

The 708 images cover one complete synodic month at hourly resolution. The function computes how far into the current synodic cycle the given date falls and maps that fraction to an image index in [1, 708].

Parameters:

Name Type Default Description
date Date new Date() The date to resolve

Returns: A zero-padded filename string, e.g. "354.webp". Always in the range "001.webp" to "708.webp".

Example:

import { cycleMonth } from 'moon-cycle';

cycleMonth();                              // current lunar phase
cycleMonth(new Date('2024-01-15'));        // specific date
cycleMonth(new Date('2020-06-21'));        // any past date works

cycleYear(date?)

function cycleYear(date?: Date): string

Maps a date to an image filename in the yearly dataset.

The 8,760 images cover the full calendar year 2023 at hourly resolution. The function extracts the hour-of-year position from the given date, cycling through the same 8,760 images every year.

Parameters:

Name Type Default Description
date Date new Date() The date to resolve

Returns: A zero-padded filename string, e.g. "4380.webp". Always in the range "0001.webp" to "8760.webp".

Example:

import { cycleYear } from 'moon-cycle';

cycleYear();                              // current hour-of-year position
cycleYear(new Date('2025-07-04T12:00Z')); // July 4, noon

imageFolder(set, size, quality)

function imageFolder(set: ImageSet, size: ImageSize, quality: ImageQuality): string

Returns the directory name for a given combination of image set, size, and quality.

Directory names follow the pattern {set}-{size}-{quality}, matching the layout in the repository.

Parameters:

Name Type Description
set 'mm' | 'my' Monthly or yearly dataset
size 256 | 512 Image dimension in pixels
quality 75 | 85 WebP compression quality

Returns: A string like "mm-256-75".

Example:

import { imageFolder } from 'moon-cycle';

imageFolder('mm', 256, 75)  // => 'mm-256-75'
imageFolder('my', 512, 85)  // => 'my-512-85'

// Use with a local public directory:
const filename = cycleMonth();
const folder   = imageFolder('mm', 512, 85);
const localUrl = `/public/${folder}/${filename}`;

cdnUrl(filename, set, size, quality, ref?)

function cdnUrl(
  filename: string,
  set: ImageSet,
  size: ImageSize,
  quality: ImageQuality,
  ref?: string
): string

Returns a jsDelivr CDN URL serving the specified image directly from the GitHub repository. jsDelivr caches GitHub content via a global CDN with no account or configuration required.

Parameters:

Name Type Default Description
filename string Filename from cycleMonth() or cycleYear()
set 'mm' | 'my' Monthly or yearly dataset
size 256 | 512 Image dimension in pixels
quality 75 | 85 WebP compression quality
ref string 'main' Branch name, git tag, or commit SHA

Returns: A full URL string, e.g. "https://cdn.jsdelivr.net/gh/acamarata/moon-cycle@main/mm-256-75/354.webp".

Example:

import { cycleMonth, cdnUrl } from 'moon-cycle';

// Current phase, served via CDN
const file = cycleMonth();
const url  = cdnUrl(file, 'mm', 256, 75);

// Pin to a specific release for cache stability
const stableUrl = cdnUrl(file, 'mm', 256, 75, 'v2.0.0');

// Use in a React component
function MoonImage() {
  const file = cycleMonth();
  return <img src={cdnUrl(file, 'mm', 256, 85)} alt="Current moon phase" />;
}

Constants

Export Type Value Description
SYNODIC_MONTH number 29.53058821398858 IAU mean synodic month in days
MONTH_IMAGES number 708 Image count in the monthly dataset
YEAR_IMAGES number 8760 Image count in the yearly dataset
MONTH_ANCHOR Date 2023-11-13T09:27:00Z New moon reference for cycleMonth
YEAR_ANCHOR Date 2023-01-01T00:00:00Z Year start reference for cycleYear

Example:

import { SYNODIC_MONTH, MONTH_ANCHOR } from 'moon-cycle';

// Compute the next new moon after a given date
function nextNewMoon(after: Date): Date {
  const elapsed = (after.getTime() - MONTH_ANCHOR.getTime()) / (1000 * 60 * 60 * 24);
  const cycles  = Math.ceil(elapsed / SYNODIC_MONTH);
  return new Date(MONTH_ANCHOR.getTime() + cycles * SYNODIC_MONTH * 86400000);
}

Types

/** 'mm' = monthly dataset (synodic cycle, 708 images) */
/** 'my' = yearly dataset (calendar year, 8,760 images) */
type ImageSet = 'mm' | 'my';

/** Image dimension in pixels (square). */
type ImageSize = 256 | 512;

/** WebP compression quality level. */
type ImageQuality = 75 | 85;

Image Dataset Reference

Folder Set Images Resolution Quality Approx. Size
mm-256-75 monthly 708 256x256 75 ~4 MB
mm-256-85 monthly 708 256x256 85 ~5 MB
mm-512-75 monthly 708 512x512 75 ~9 MB
mm-512-85 monthly 708 512x512 85 ~14 MB
my-256-75 yearly 8,760 256x256 75 ~51 MB
my-256-85 yearly 8,760 256x256 85 ~66 MB
my-512-75 yearly 8,760 512x512 75 ~113 MB
my-512-85 yearly 8,760 512x512 85 ~176 MB

All images are square WebP, transparent background, named with zero-padded indices (001.webp to 708.webp for monthly, 0001.webp to 8760.webp for yearly).


Home | Architecture | Migration Guide