mirror of
https://github.com/acamarata/moon-cycle.git
synced 2026-06-30 18:54:29 +00:00
style: replace em dashes with colons in docs and wiki
This commit is contained in:
parent
c80a139d4f
commit
0744ae0080
6 changed files with 45 additions and 45 deletions
|
|
@ -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"`.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
14
CHANGELOG.md
14
CHANGELOG.md
|
|
@ -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
|
||||
|
||||
|
|
|
|||
18
README.md
18
README.md
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue