style: replace em dashes with colons in docs and wiki

This commit is contained in:
Aric Camarata 2026-03-08 17:28:03 -04:00
parent c80a139d4f
commit 0744ae0080
6 changed files with 45 additions and 45 deletions

View file

@ -117,10 +117,10 @@ Returns a jsDelivr CDN URL serving the specified image directly from the GitHub
| 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 |
| `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"`.

View file

@ -12,8 +12,8 @@ All images originate from NASA's Scientific Visualization Studio visualization "
The raw frames were converted to WebP and organized into eight folders combining two image sets, two resolutions, and two quality levels:
- `mm-*` 708 images covering one synodic month (monthly set)
- `my-*` 8,760 images covering the full year 2023 (yearly set)
- `mm-*`: 708 images covering one synodic month (monthly set)
- `my-*`: 8,760 images covering the full year 2023 (yearly set)
Images are named with zero-padded integers starting at 1 (`001.webp` to `708.webp` for monthly, `0001.webp` to `8760.webp` for yearly).
@ -21,7 +21,7 @@ Images are named with zero-padded integers starting at 1 (`001.webp` to `708.web
### Concept
The synodic month is the time between two identical lunar phases as seen from Earth new moon to new moon. Its IAU mean value is **29.53058821398858 days**. The 708 images in the monthly set span exactly one such cycle at hourly resolution.
The synodic month is the time between two identical lunar phases as seen from Earth: new moon to new moon. Its IAU mean value is **29.53058821398858 days**. The 708 images in the monthly set span exactly one such cycle at hourly resolution.
To find the correct image for any date, the algorithm:
@ -45,13 +45,13 @@ index = floor(fraction * 708) + 1
### Limitation
The synodic month is not exactly 29.53058821398858 days that value is the IAU *mean* (averaged over centuries). The actual length of a given synodic month varies by up to ~7 hours depending on the Moon's position in its elliptical orbit. For dates far from the 2023 reference period, accumulated drift means the image may be off by a few frames from the true observed phase. For UI purposes, this is imperceptible.
The synodic month is not exactly 29.53058821398858 days: that value is the IAU *mean* (averaged over centuries). The actual length of a given synodic month varies by up to ~7 hours depending on the Moon's position in its elliptical orbit. For dates far from the 2023 reference period, accumulated drift means the image may be off by a few frames from the true observed phase. For UI purposes, this is imperceptible.
## Algorithm 2: Calendar Year (`cycleYear`)
### Concept
The yearly set contains 8,760 images one per hour of the 365-day year 2023. Rather than tracking lunar phase directly, `cycleYear` maps any date to its hour-of-year equivalent and uses that to index into the 2023 imagery.
The yearly set contains 8,760 images: one per hour of the 365-day year 2023. Rather than tracking lunar phase directly, `cycleYear` maps any date to its hour-of-year equivalent and uses that to index into the 2023 imagery.
The algorithm:
@ -75,7 +75,7 @@ index = floor(fraction * 8760) + 1
### Limitation
The year 2023 had 365 days (not a leap year), so the 8,760 images correspond exactly to one non-leap year. For years with 366 days, there is a subtle 24-image offset in the second half of the year the hour-of-year for December 31 in a leap year wraps around slightly differently than in 2023. This is a cosmetic artifact, not a functional error.
The year 2023 had 365 days (not a leap year), so the 8,760 images correspond exactly to one non-leap year. For years with 366 days, there is a subtle 24-image offset in the second half of the year: the hour-of-year for December 31 in a leap year wraps around slightly differently than in 2023. This is a cosmetic artifact, not a functional error.
## Choosing Between the Two
@ -85,14 +85,14 @@ The year 2023 had 365 days (not a leap year), so the 8,760 images correspond exa
| Animate through a year of moon phases for a calendar app | `cycleYear` |
| Show a consistent seasonal moon appearance | `cycleYear` |
| Compute when the next full moon occurs | `cycleMonth` + `SYNODIC_MONTH` |
| Display a decorative moon that changes daily | Either `cycleYear` has smoother hourly progression |
| Display a decorative moon that changes daily | Either: `cycleYear` has smoother hourly progression |
## Package Structure
```
moon-cycle/
├── src/
│ ├── index.ts # Public API re-exports all named exports
│ ├── index.ts # Public API: re-exports all named exports
│ ├── types.ts # Types, constants, anchor dates
│ ├── cycleMonth.ts # Synodic algorithm
│ ├── cycleYear.ts # Calendar-year algorithm
@ -112,10 +112,10 @@ moon-cycle/
The source is TypeScript, compiled by [tsup](https://tsup.egoist.dev/) (esbuild-based). tsup produces four output files from `src/index.ts`:
- `dist/index.cjs` CommonJS for `require()`
- `dist/index.mjs` ESM for `import`
- `dist/index.d.ts` type definitions for CJS consumers
- `dist/index.d.mts` type definitions for ESM consumers
- `dist/index.cjs`: CommonJS for `require()`
- `dist/index.mjs`: ESM for `import`
- `dist/index.d.ts`: type definitions for CJS consumers
- `dist/index.d.mts`: type definitions for ESM consumers
The `exports` field in `package.json` uses types-first conditional exports so TypeScript resolves the correct declaration file regardless of `moduleResolution` setting.

View file

@ -27,7 +27,7 @@ pnpm add moon-cycle
```ts
import { cycleMonth, cdnUrl } from 'moon-cycle';
const file = cycleMonth(); // e.g. "354.webp" current lunar phase
const file = cycleMonth(); // e.g. "354.webp": current lunar phase
const url = cdnUrl(file, 'mm', 256, 75);
// => 'https://cdn.jsdelivr.net/gh/acamarata/moon-cycle@main/mm-256-75/354.webp'
```
@ -47,9 +47,9 @@ All eight combinations (`mm`/`my` × `256`/`512` × `75`/`85`) are available. Us
## Pages
- [API Reference](API-Reference) full function and type documentation
- [Architecture](Architecture) algorithm design, dataset description, tradeoffs
- [Migration Guide](Migration) upgrading from v1
- [API Reference](API-Reference): full function and type documentation
- [Architecture](Architecture): algorithm design, dataset description, tradeoffs
- [Migration Guide](Migration): upgrading from v1
## Source

View file

@ -5,7 +5,7 @@ Upgrading from moon-cycle v1 to v2.
## Summary of Breaking Changes
1. **Off-by-one fix:** `cycleMonth` and `cycleYear` now return 1-indexed filenames
2. **No default export:** Functions are now named exports only (this was always the case `require('moon-cycle')` still works, but `require('moon-cycle').default` does not exist)
2. **No default export:** Functions are now named exports only (this was always the case: `require('moon-cycle')` still works, but `require('moon-cycle').default` does not exist)
## 1. Off-by-one correction
@ -24,7 +24,7 @@ v2 corrects this. The returned filenames now match the actual files in the datas
v1 shipped a hand-written `index.d.ts` that incorrectly declared both functions as returning `{ result: string }`:
```ts
// v1 incorrect
// v1: incorrect
export function cycleMonth(date: Date): MonthResult;
interface MonthResult { result: string }
```
@ -32,7 +32,7 @@ interface MonthResult { result: string }
The actual runtime behavior in v1 was to return a plain `string`, not an object. v2 types match the implementation:
```ts
// v2 correct
// v2: correct
export function cycleMonth(date?: Date): string;
```
@ -52,10 +52,10 @@ const src = `/mm-256-75/${filename}`;
v2 adds several exports that did not exist in v1. These are additive and do not break existing code:
- `imageFolder(set, size, quality)` constructs folder name strings
- `cdnUrl(filename, set, size, quality, ref?)` constructs jsDelivr CDN URLs
- `SYNODIC_MONTH`, `MONTH_IMAGES`, `YEAR_IMAGES`, `MONTH_ANCHOR`, `YEAR_ANCHOR` constants
- `ImageSet`, `ImageSize`, `ImageQuality` TypeScript types
- `imageFolder(set, size, quality)`: constructs folder name strings
- `cdnUrl(filename, set, size, quality, ref?)`: constructs jsDelivr CDN URLs
- `SYNODIC_MONTH`, `MONTH_IMAGES`, `YEAR_IMAGES`, `MONTH_ANCHOR`, `YEAR_ANCHOR`: constants
- `ImageSet`, `ImageSize`, `ImageQuality`: TypeScript types
## 4. Optional `date` parameter
@ -68,8 +68,8 @@ v2 ships dual CJS and ESM builds. If you use a bundler, it will now automaticall
## Migration Checklist
- [ ] Update to `moon-cycle@2.0.0`
- [ ] Verify image filenames if you referenced `000.webp` or `0000.webp` directly, rename to `001.webp` / `0001.webp`
- [ ] Remove any `.result` property access both functions return `string` directly
- [ ] Verify image filenames: if you referenced `000.webp` or `0000.webp` directly, rename to `001.webp` / `0001.webp`
- [ ] Remove any `.result` property access: both functions return `string` directly
- [ ] Update TypeScript types if you had manual overrides working around the incorrect v1 declarations
- [ ] Consider using `cdnUrl()` if you were constructing CDN URLs manually

View file

@ -6,14 +6,14 @@ All notable changes to this project will be documented in this file. Format foll
### Added
- TypeScript source (`src/`) with full type definitions dual CJS and ESM builds via tsup
- TypeScript source (`src/`) with full type definitions: dual CJS and ESM builds via tsup
- `imageFolder(set, size, quality)` helper to construct image directory names
- `cdnUrl(filename, set, size, quality, ref?)` helper to generate jsDelivr CDN URLs, enabling image serving without self-hosting the ~438 MB dataset
- Exported constants: `SYNODIC_MONTH`, `MONTH_IMAGES`, `YEAR_IMAGES`, `MONTH_ANCHOR`, `YEAR_ANCHOR`
- Exported types: `ImageSet`, `ImageSize`, `ImageQuality`
- Dual ESM and CJS builds with `.mjs` / `.cjs` extensions and matching `.d.ts` / `.d.mts` type definitions
- Proper `exports` map in `package.json` (types-first conditional exports)
- `test.mjs` and `test-cjs.cjs` full assertion-based test suites covering bounds, anchor dates, edge cases, and all exported functions
- `test.mjs` and `test-cjs.cjs`: full assertion-based test suites covering bounds, anchor dates, edge cases, and all exported functions
- GitHub Actions CI workflow: Node 20/22/24 test matrix, typecheck job, pack-check job
- GitHub Actions wiki-sync workflow: syncs `.wiki/` to GitHub Wiki on push to `main`
- `.wiki/` documentation: Home, API Reference, Architecture, Migration Guide
@ -21,20 +21,20 @@ All notable changes to this project will be documented in this file. Format foll
### Changed
- Package is now npm-publishable: `files` field restricts the npm package to `dist/`, README, LICENSE, and CHANGELOG images are excluded
- Package is now npm-publishable: `files` field restricts the npm package to `dist/`, README, LICENSE, and CHANGELOG: images are excluded
- `package.json` fully updated: correct author name, accurate description, `engines`, `sideEffects`, `publishConfig`, `repository.url` with `git+https://` prefix, expanded keywords
- `repository.url` corrected to use `git+https://` prefix per npm convention
### Fixed
- **Off-by-one bug in both algorithms.** The v1 implementation mapped dates to 0-indexed filenames (`000.webp` to `707.webp` monthly, `0000.webp` to `8759.webp` yearly). The image dataset is 1-indexed (`001.webp` to `708.webp`, `0001.webp` to `8760.webp`). Both functions now return the correct 1-indexed filename. This is a breaking change for anyone who was working around the bug or had a local image set starting at `000.webp`.
- TypeScript definitions in `index.d.ts` were incorrect both functions were typed as returning `{ result: string }` instead of `string`. The new generated types are accurate.
- TypeScript definitions in `index.d.ts` were incorrect: both functions were typed as returning `{ result: string }` instead of `string`. The new generated types are accurate.
### Removed
- `index.js`, `cycleMonth.js`, `cycleYear.js` replaced by `src/` TypeScript source and `dist/` build output
- `index.d.ts` replaced by generated `dist/index.d.ts` and `dist/index.d.mts`
- `test.js` replaced by `test.mjs` and `test-cjs.cjs`
- `index.js`, `cycleMonth.js`, `cycleYear.js`: replaced by `src/` TypeScript source and `dist/` build output
- `index.d.ts`: replaced by generated `dist/index.d.ts` and `dist/index.d.mts`
- `test.js`: replaced by `test.mjs` and `test-cjs.cjs`
## [1.0.1] - 2023-11-14

View file

@ -44,7 +44,7 @@ const { cycleMonth, cycleYear, cdnUrl } = require('moon-cycle');
Maps a date to an image filename in the monthly (synodic) dataset.
Uses the IAU mean synodic month (29.530588 days) and a 2023-11-13 new moon anchor. The 708 hourly images span one complete synodic cycle. The result wraps continuously any past or future date resolves to a valid image.
Uses the IAU mean synodic month (29.530588 days) and a 2023-11-13 new moon anchor. The 708 hourly images span one complete synodic cycle. The result wraps continuously: any past or future date resolves to a valid image.
| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
@ -91,10 +91,10 @@ const url = cdnUrl(file, 'mm', 256, 75);
| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| `filename` | `string` | | Result from `cycleMonth` or `cycleYear` |
| `set` | `'mm' \| 'my'` | | Monthly or yearly dataset |
| `size` | `256 \| 512` | | Image dimension |
| `quality` | `75 \| 85` | | WebP quality |
| `filename` | `string` |: | Result from `cycleMonth` or `cycleYear` |
| `set` | `'mm' \| 'my'` |: | Monthly or yearly dataset |
| `size` | `256 \| 512` |: | Image dimension |
| `quality` | `75 \| 85` |: | WebP quality |
| `ref` | `string` | `'main'` | Branch, tag, or commit SHA |
### Constants
@ -175,10 +175,10 @@ Full reference: [GitHub Wiki](https://github.com/acamarata/moon-cycle/wiki)
## Related
- [nrel-spa](https://github.com/acamarata/nrel-spa) Pure JS NREL Solar Position Algorithm, zero dependencies
- [pray-calc](https://github.com/acamarata/pray-calc) Islamic prayer times with dynamic angle algorithm
- [luxon-hijri](https://github.com/acamarata/luxon-hijri) Hijri/Gregorian calendar conversion
- [moon-sighting](https://github.com/acamarata/moon-sighting) Lunar crescent visibility using Yallop and Odeh criteria
- [nrel-spa](https://github.com/acamarata/nrel-spa): Pure JS NREL Solar Position Algorithm, zero dependencies
- [pray-calc](https://github.com/acamarata/pray-calc): Islamic prayer times with dynamic angle algorithm
- [luxon-hijri](https://github.com/acamarata/luxon-hijri): Hijri/Gregorian calendar conversion
- [moon-sighting](https://github.com/acamarata/moon-sighting): Lunar crescent visibility using Yallop and Odeh criteria
## Acknowledgments