nrel-spa/CHANGELOG.md
Aric Camarata 51dcf89d63 nrel-spa v2.0.1: validation, NaN returns, overloads, wiki comparison
Fixed:
- calcSpa with empty angles array no longer crashes (consistent guard with getSpa)
- getSpa with SPA_ZA/SPA_ZA_INC now returns NaN for sunrise/solarNoon/sunset
  instead of misleading 0; calcSpa returns "N/A" for those fields
- lib/spa.js header comment corrected from dist/spa.js to lib/spa.js
- dist/spa.js removed (file moved to lib/spa.js in v2.0.0, stale copy deleted)
- wiki-sync.yml handles first-run when GitHub Wiki repo does not yet exist
- CI pack-check grep uses word-boundary pattern to prevent false prefix matches
- Removed package-import-method=hardlink from .npmrc (pnpm default, caused npm warn)

Added:
- options.function validated before calculation; invalid code throws RangeError
- angles with non-RTS function code throws RangeError (requires suntransit)
- TypeScript function overloads for getSpa and calcSpa; angles typed as
  [number, ...number[]] non-empty tuple, narrows return type automatically
- SpaFormattedAnglesResult interface, consistent with SpaAnglesResult
- CI jobs declare explicit permissions: contents: read
- Wiki: Implementation Comparison page with accuracy table (8 locations vs C
  reference, max delta 0.49 s) and performance benchmarks (nrel-spa vs solar-spa
  vs C, both SPA_ZA_RTS and SPA_ZA modes, 200k iterations on Node v24.6.0)
- Wiki: API Reference updated with named types, all throws, Named Types block
- Wiki: Architecture updated with all exported interfaces
2026-02-25 11:54:03 -05:00

71 lines
4.1 KiB
Markdown

# Changelog
<!-- markdownlint-disable MD024 -->
## [2.0.1] - 2026-02-25
### Fixed
- **Runtime crash:** `calcSpa(... , [])` with an empty angles array no longer crashes. The empty-array guard is now consistent between `getSpa` and `calcSpa`.
- **Silent wrong output:** `getSpa` with `options.function: SPA_ZA` or `SPA_ZA_INC` now returns `NaN` for `sunrise`, `solarNoon`, and `sunset` instead of silently returning `0`. `calcSpa` returns `"N/A"` for those fields. The zero values were misleading — those fields are never computed by non-RTS function codes.
- `lib/spa.js` internal file header corrected from `// dist/spa.js` to `// lib/spa.js`.
- `wiki-sync.yml`: workflow now handles first-run initialization when the GitHub Wiki repository does not yet exist. Replaces `actions/checkout@v4` for the wiki step with a `git clone || git init` pattern.
- Removed `package-import-method=hardlink` from `.npmrc` — it is pnpm's default since v7 and caused `npm warn Unknown project config` because npm reads `.npmrc` too.
- CI pack-check grep now uses a word-boundary pattern, preventing false matches on files with similar prefixes.
### Added
- **Validation:** `options.function` is now validated before the SPA calculation. Passing an invalid function code throws a descriptive `RangeError` instead of silently producing wrong results.
- **Validation:** Passing custom `angles` with a non-RTS function code (`SPA_ZA` or `SPA_ZA_INC`) now throws `RangeError`. Custom angle calculations require `suntransit`, which is only computed by `SPA_ZA_RTS` and `SPA_ALL`.
- TypeScript function overloads for `getSpa` and `calcSpa`: the `angles` parameter is typed as `[number, ...number[]]` (non-empty tuple), so TypeScript rejects empty arrays at compile time and narrows the return type automatically.
- `SpaFormattedAnglesResult` interface for the formatted angles array, consistent with the existing `SpaAnglesResult` interface on the raw side.
- CI workflows now declare explicit `permissions: contents: read` on all jobs.
- API Reference wiki updated: inline anonymous types replaced with named `SpaAnglesResult` and `SpaFormattedAnglesResult` interfaces; new Named Types import block added; `angles` parameter type and new throws documented.
- Architecture wiki updated to document all exported interfaces from `src/types.ts`.
---
## [2.0.0] - 2026-02-25
### Added
- TypeScript wrapper (`src/index.ts`, `src/types.ts`) with full type definitions
- Dual CJS and ESM builds via tsup (`dist/index.cjs`, `dist/index.mjs`)
- TypeScript declaration files (`dist/index.d.ts`, `dist/index.d.mts`)
- `formatTime()` utility export for converting fractional hours to `HH:MM:SS`
- Input validation with descriptive `TypeError` and `RangeError` messages
- Function code exports: `SPA_ZA`, `SPA_ZA_INC`, `SPA_ZA_RTS`, `SPA_ALL`
- Test suite: 61 ESM assertions and 17 CJS assertions
- GitHub Actions CI workflow (Node 20/22/24 matrix, typecheck, pack-check)
- GitHub Wiki with architecture, API reference, twilight calculations, and algorithm documentation
- NREL attribution in `LICENSE` and `README`
- `pnpm-workspace.yaml`, `.editorconfig`, `.npmrc`, `.nvmrc` config files
### Changed
- Core algorithm moved from `dist/spa.js` to `lib/spa.js` (same code, clearer location)
- `package.json` rewritten: proper `exports` map, `files`, `engines`, `sideEffects`, all required fields
- Author corrected to "Aric Camarata"
- `repository.url` corrected to use `git+https://` prefix (no npm publish warnings)
- `engines.node` set to `>=20`
- Description expanded with full keyword coverage
- LICENSE year corrected to `2023-2026`
- README rewritten with badges, full API tables, quick start, and NREL acknowledgments
## [1.3.0] - 2025-05-04
- Major fix for discrepancies between this implementation and the original NREL C reference
- Added `bin/` folder for compiling and testing against the C reference executable
- All 10 global test cases now produce identical output to the C reference
## [1.2.2] - 2023-11-12
- Moved timezone to main function arguments and changed default behavior
- Updated test cases and README
## [1.1.0] - 2023-11-11
- Committed `dist/` folder (core algorithm) to git
## [1.0.0] - 2023-11-11
- Initial release