@motioncomplex/cosmos-lib 1.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/README.md +125 -0
  2. package/dist/api.d.ts +246 -0
  3. package/dist/cache.d.ts +11 -0
  4. package/dist/clock.d.ts +181 -0
  5. package/dist/constants.d.ts +43 -0
  6. package/dist/data/constellations.d.ts +58 -0
  7. package/dist/data/cutouts.d.ts +70 -0
  8. package/dist/data/deep-sky.d.ts +27 -0
  9. package/dist/data/images.d.ts +147 -0
  10. package/dist/data/index.d.ts +422 -0
  11. package/dist/data/messier.d.ts +61 -0
  12. package/dist/data/ps1-files.d.ts +11 -0
  13. package/dist/data/showers.d.ts +62 -0
  14. package/dist/data/solar-system.d.ts +34 -0
  15. package/dist/data/stars.d.ts +57 -0
  16. package/dist/data/textures.d.ts +67 -0
  17. package/dist/eclipse.d.ts +176 -0
  18. package/dist/index.cjs +1 -0
  19. package/dist/index.d.ts +237 -0
  20. package/dist/index.js +713 -0
  21. package/dist/math.d.ts +532 -0
  22. package/dist/media-DVOcIMa1.js +252 -0
  23. package/dist/media-DlE7RKBL.cjs +1 -0
  24. package/dist/media.d.ts +217 -0
  25. package/dist/moon.d.ts +170 -0
  26. package/dist/planner.d.ts +224 -0
  27. package/dist/react/index.cjs +1 -0
  28. package/dist/react/index.d.ts +167 -0
  29. package/dist/react/index.js +163 -0
  30. package/dist/skymap-hittest.d.ts +69 -0
  31. package/dist/skymap-interactive-CLg6FA0X.js +6377 -0
  32. package/dist/skymap-interactive-D2OZFwJ7.cjs +1 -0
  33. package/dist/skymap-interactive.d.ts +153 -0
  34. package/dist/skymap.d.ts +172 -0
  35. package/dist/sun.d.ts +119 -0
  36. package/dist/three/factories.d.ts +160 -0
  37. package/dist/three/flight.d.ts +116 -0
  38. package/dist/three/index.cjs +20 -0
  39. package/dist/three/index.d.ts +21 -0
  40. package/dist/three/index.js +404 -0
  41. package/dist/three/lod.d.ts +100 -0
  42. package/dist/three/shaders.d.ts +22 -0
  43. package/dist/three/types.d.ts +169 -0
  44. package/dist/transitions.d.ts +246 -0
  45. package/dist/types.d.ts +730 -0
  46. package/dist/units.d.ts +132 -0
  47. package/package.json +93 -0
package/README.md ADDED
@@ -0,0 +1,125 @@
1
+ # cosmos-lib
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@motioncomplex/cosmos-lib.svg)](https://www.npmjs.com/package/@motioncomplex/cosmos-lib)
4
+ [![npm downloads](https://img.shields.io/npm/dm/@motioncomplex/cosmos-lib.svg)](https://www.npmjs.com/package/@motioncomplex/cosmos-lib)
5
+ [![license](https://img.shields.io/npm/l/@motioncomplex/cosmos-lib.svg)](https://github.com/MotionComplex/cosmos-lib/blob/main/LICENSE)
6
+
7
+ Reusable TypeScript library for astronomical data, coordinate math, sky maps, NASA/ESA APIs, media loading, and UI transitions. Zero runtime dependencies — Three.js and React support are optional peer dependencies in separate entry points.
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ npm install @motioncomplex/cosmos-lib
13
+ ```
14
+
15
+ Optional peer dependencies (only install what you use):
16
+
17
+ ```bash
18
+ npm install three # for cosmos-lib/three (3D scene helpers)
19
+ npm install react # for cosmos-lib/react (React hooks & components)
20
+ ```
21
+
22
+ ## Quick start
23
+
24
+ ```ts
25
+ import Cosmos from '@motioncomplex/cosmos-lib'
26
+
27
+ // Search the built-in catalog (300+ stars, 110 Messier, 88 constellations)
28
+ const results = Cosmos.Data.search('orion')
29
+ const nebulae = Cosmos.Data.getByType('nebula')
30
+ const near = Cosmos.Data.nearby({ ra: 83.8, dec: -5.4 }, 20)
31
+
32
+ // Coordinate transforms
33
+ const { alt, az } = Cosmos.Math.equatorialToHorizontal(
34
+ { ra: 101.287, dec: -16.716 }, // Sirius
35
+ { lat: 47.05, lng: 8.31, date: new Date() } // Lucerne
36
+ )
37
+
38
+ // Sun, Moon & eclipses
39
+ const sunPos = Cosmos.Sun.position()
40
+ const moonPhase = Cosmos.Moon.phase()
41
+ const twilight = Cosmos.Sun.twilight({ lat: 51.5, lng: -0.1 })
42
+
43
+ // NASA APIs
44
+ const apod = await Cosmos.API.NASA.apod()
45
+ const imgs = await Cosmos.API.NASA.searchImages('pillars of creation', { pageSize: 5 })
46
+ ```
47
+
48
+ ## Tree-shakeable named exports
49
+
50
+ ```ts
51
+ import { AstroMath, Data, NASA, Units, renderSkyMap, staggerIn } from '@motioncomplex/cosmos-lib'
52
+ ```
53
+
54
+ ## React hooks (optional)
55
+
56
+ ```ts
57
+ import { useSkyPosition, useMoonPhase, useWhatsUp, useTwilight, SkyMap } from '@motioncomplex/cosmos-lib/react'
58
+
59
+ // Reactive sky position — auto-updates every 10s
60
+ const pos = useSkyPosition('sirius', { lat: 47.05, lng: 8.31 })
61
+
62
+ // What's visible tonight?
63
+ const visible = useWhatsUp({ lat: 47.05, lng: 8.31 }, { magnitudeLimit: 4 })
64
+ ```
65
+
66
+ ## Three.js helpers (optional)
67
+
68
+ ```ts
69
+ import { createPlanet, LODTextureManager, CameraFlight } from '@motioncomplex/cosmos-lib/three'
70
+ import * as THREE from 'three'
71
+
72
+ const { group, dispose } = createPlanet({
73
+ radius: 6.5,
74
+ textureUrl: 'earth-bluemarble-4k.jpg',
75
+ atmosphere: { color: 0x4488ff, intensity: 1.3 },
76
+ }, THREE)
77
+ scene.add(group)
78
+ ```
79
+
80
+ ## Features
81
+
82
+ | Module | Description | Docs |
83
+ |--------|-------------|------|
84
+ | **Data** | 300+ bright stars, 110 Messier objects, 88 constellations, 20 meteor showers, solar system bodies. Fuzzy search, proximity queries, image resolution. | [Data](docs/api/data.md) |
85
+ | **AstroMath** | Julian dates, sidereal time, coordinate transforms (equatorial, horizontal, galactic, ecliptic), Kepler solver, planetary ephemeris, precession, nutation, refraction, rise/transit/set. | [Math](docs/api/math.md) |
86
+ | **Sun / Moon / Eclipse** | Solar & lunar positions, moon phases, twilight times, eclipse prediction. | [Sun/Moon/Eclipse](docs/api/sun-moon-eclipse.md) |
87
+ | **NASA / ESA / Simbad** | NASA Image Library, APOD, ESA Hubble archive, CDS Simbad object resolution. | [API Integrations](docs/api/api-integrations.md) |
88
+ | **Planner** | "What's up tonight?" — visible objects, best observation windows, visibility curves, moon interference scoring, airmass, planet oppositions/conjunctions. | [Planner](docs/api/planner.md) |
89
+ | **AstroClock** | Simulation clock with speed control, forward/reverse playback, snap-to-event, and requestAnimationFrame support. | [Clock](docs/api/clock.md) |
90
+ | **Sky Map** | Stereographic, Mollweide, and gnomonic projections. Interactive canvas sky chart with pan, zoom, click-to-identify, FOV overlays, HUD, and real-time tracking. | [Sky Map](docs/api/skymap.md) |
91
+ | **React Hooks** | `useSkyPosition`, `useMoonPhase`, `useAstroClock`, `useWhatsUp`, `useTwilight`, `<SkyMap />`. SSR-safe. Optional peer dependency. | [React](docs/api/react.md) |
92
+ | **Media** | Progressive image loading with fallback chains, Wikimedia/Cloudinary URL builders, responsive `srcset` generation. | [Media](docs/api/media.md) |
93
+ | **Transitions** | View Transitions API wrappers: morph, stagger reveal, fade, crossfade, hero expand/collapse. | [Transitions](docs/api/transitions.md) |
94
+ | **Three.js** | Planet/nebula/starfield factories, LOD texture management, camera flights. Optional peer dependency. | [Three.js](docs/api/three.md) |
95
+ | **Constants & Units** | Astronomical constants (IAU 2012), distance/angle conversions, RA/Dec formatters. | [Constants & Units](docs/api/constants-and-units.md) |
96
+
97
+ ## Documentation
98
+
99
+ Full documentation lives in the [`docs/`](docs/README.md) folder:
100
+
101
+ - [Getting Started](docs/getting-started.md) — installation, import patterns, quick start
102
+ - [API Reference](docs/README.md#api-reference) — per-module docs with signatures, parameters, and examples
103
+ - [Guides](docs/README.md#guides) — conceptual walkthroughs for coordinate systems, catalog data, and Three.js integration
104
+ - [Type Reference](docs/types.md) — quick-reference table of all exported types
105
+
106
+ Generate HTML API docs from TSDoc comments:
107
+
108
+ ```bash
109
+ npm run docs
110
+ ```
111
+
112
+ ## Development
113
+
114
+ ```bash
115
+ npm install
116
+ npm test # run tests
117
+ npm run test:watch # watch mode
118
+ npm run typecheck # tsc --noEmit
119
+ npm run build # compile to dist/
120
+ npm run docs # generate TypeDoc API reference
121
+ ```
122
+
123
+ ## License
124
+
125
+ MIT
package/dist/api.d.ts ADDED
@@ -0,0 +1,246 @@
1
+ import type { NASAImageResult, APODResult, ESAHubbleResult, SimbadResult } from './types.js';
2
+ /**
3
+ * Options for filtering and paginating NASA Image and Video Library searches.
4
+ *
5
+ * @see {@link NASA.searchImages} for usage.
6
+ */
7
+ export interface NASASearchOptions {
8
+ /** Media type filter. Defaults to `'image'`. */
9
+ mediaType?: 'image' | 'video' | 'audio';
10
+ /** Restrict results to items published on or after this year. */
11
+ yearStart?: number;
12
+ /** Restrict results to items published on or before this year. */
13
+ yearEnd?: number;
14
+ /** Number of results per page. Defaults to `10`. */
15
+ pageSize?: number;
16
+ /** 1-based page number for pagination. Defaults to `1`. */
17
+ page?: number;
18
+ }
19
+ /**
20
+ * Client for the NASA public APIs, including the Image and Video Library
21
+ * and the Astronomy Picture of the Day (APOD) service.
22
+ *
23
+ * By default requests use the `DEMO_KEY` API key, which is subject to
24
+ * strict rate limits. Call {@link NASA.setApiKey} with a free key from
25
+ * {@link https://api.nasa.gov} before making production requests.
26
+ *
27
+ * @example
28
+ * ```ts
29
+ * import { NASA } from 'cosmos-lib'
30
+ *
31
+ * NASA.setApiKey('your-api-key')
32
+ * const results = await NASA.searchImages('pillars of creation')
33
+ * console.log(results[0].title)
34
+ * ```
35
+ */
36
+ export declare const NASA: {
37
+ /**
38
+ * Set the NASA API key used for APOD requests.
39
+ *
40
+ * The default key (`DEMO_KEY`) is heavily rate-limited (30 req/hr,
41
+ * 50 req/day). Register for a free key at {@link https://api.nasa.gov}
42
+ * to raise these limits to 1,000 req/hr.
43
+ *
44
+ * @param key - Your NASA API key.
45
+ *
46
+ * @example
47
+ * ```ts
48
+ * NASA.setApiKey('Ab12Cd34Ef56Gh78Ij90KlMnOpQrStUvWxYz0123')
49
+ * ```
50
+ */
51
+ setApiKey(key: string): void;
52
+ /**
53
+ * Search the NASA Image and Video Library.
54
+ *
55
+ * Queries the public NASA images API and returns an array of
56
+ * {@link NASAImageResult} objects containing metadata and preview URLs.
57
+ *
58
+ * @param query - Free-text search term (e.g. `'pillars of creation'`).
59
+ * @param opts - Optional filters and pagination settings.
60
+ *
61
+ * @returns An array of search results. An empty array is returned when
62
+ * the query matches nothing.
63
+ *
64
+ * @throws {Error} If the NASA API responds with a non-2xx status code.
65
+ *
66
+ * @example
67
+ * ```ts
68
+ * const results = await NASA.searchImages('pillars of creation', {
69
+ * yearStart: 2010,
70
+ * pageSize: 5,
71
+ * })
72
+ * for (const r of results) {
73
+ * console.log(r.title, r.previewUrl)
74
+ * }
75
+ * ```
76
+ *
77
+ * @see {@link https://images.nasa.gov/docs/images.nasa.gov_api_docs.pdf | NASA Image API docs}
78
+ */
79
+ searchImages(query: string, opts?: NASASearchOptions): Promise<NASAImageResult[]>;
80
+ /**
81
+ * Fetch all asset URLs for a given NASA image ID.
82
+ *
83
+ * Returns the full list of available renditions (JPEG, TIFF, etc.)
84
+ * sorted by quality: original, large, medium, small, then thumbnail.
85
+ *
86
+ * @param nasaId - The NASA-assigned identifier (e.g. `'PIA06890'`).
87
+ *
88
+ * @returns An array of absolute URLs sorted from highest to lowest quality.
89
+ *
90
+ * @throws {Error} If the NASA asset endpoint responds with a non-2xx status.
91
+ *
92
+ * @example
93
+ * ```ts
94
+ * const urls = await NASA.getAssets('PIA06890')
95
+ * console.log(urls[0]) // highest quality rendition
96
+ * ```
97
+ */
98
+ getAssets(nasaId: string): Promise<string[]>;
99
+ /**
100
+ * Convenience helper that returns the single highest-quality image URL
101
+ * for a NASA asset ID.
102
+ *
103
+ * Internally calls {@link NASA.getAssets} and filters for image file
104
+ * extensions (JPEG, PNG, GIF, TIFF), returning the first match (which
105
+ * is the original-resolution rendition when available).
106
+ *
107
+ * @param nasaId - The NASA-assigned identifier (e.g. `'PIA06890'`).
108
+ *
109
+ * @returns The URL of the best available image, or `null` if no image
110
+ * renditions exist for the given ID.
111
+ *
112
+ * @throws {Error} If the underlying {@link NASA.getAssets} call fails.
113
+ *
114
+ * @example
115
+ * ```ts
116
+ * const url = await NASA.getBestImageUrl('PIA06890')
117
+ * if (url) {
118
+ * document.querySelector('img')!.src = url
119
+ * }
120
+ * ```
121
+ */
122
+ getBestImageUrl(nasaId: string): Promise<string | null>;
123
+ /**
124
+ * Fetch the NASA Astronomy Picture of the Day (APOD).
125
+ *
126
+ * Returns a single {@link APODResult} containing the title, explanation,
127
+ * standard and HD image URLs, and copyright information.
128
+ *
129
+ * @param date - An ISO-8601 date string (`'2024-06-15'`) or a `Date`
130
+ * object. When omitted the API returns today's picture.
131
+ *
132
+ * @returns The APOD entry for the requested date.
133
+ *
134
+ * @throws {Error} If the APOD API responds with a non-2xx status code
135
+ * (e.g. 403 for an invalid API key, 404 for a date with
136
+ * no entry).
137
+ *
138
+ * @example
139
+ * ```ts
140
+ * // Today's APOD
141
+ * const today = await NASA.apod()
142
+ * console.log(today.title, today.hdUrl)
143
+ *
144
+ * // A specific date
145
+ * const historic = await NASA.apod('1995-06-16')
146
+ * ```
147
+ */
148
+ apod(date?: string | Date): Promise<APODResult>;
149
+ /**
150
+ * Fetch a random selection of recent APOD entries.
151
+ *
152
+ * Uses the `count` parameter of the APOD API to retrieve multiple
153
+ * randomly-selected entries at once. Thumbnails are requested for
154
+ * video entries.
155
+ *
156
+ * @param count - Number of random entries to return. Defaults to `7`.
157
+ * The NASA API supports a maximum of `100`.
158
+ *
159
+ * @returns An array of {@link APODResult} objects.
160
+ *
161
+ * @throws {Error} If the APOD API responds with a non-2xx status code.
162
+ *
163
+ * @example
164
+ * ```ts
165
+ * const week = await NASA.recentAPOD()
166
+ * for (const entry of week) {
167
+ * console.log(`${entry.date}: ${entry.title}`)
168
+ * }
169
+ *
170
+ * // Fetch 20 random entries
171
+ * const batch = await NASA.recentAPOD(20)
172
+ * ```
173
+ */
174
+ recentAPOD(count?: number): Promise<APODResult[]>;
175
+ };
176
+ /**
177
+ * Client for the European Space Agency (ESA) Hubble Space Telescope
178
+ * public image archive.
179
+ *
180
+ * @example
181
+ * ```ts
182
+ * import { ESA } from 'cosmos-lib'
183
+ *
184
+ * const images = await ESA.searchHubble('crab nebula', 5)
185
+ * console.log(images[0].title, images[0].imageUrl)
186
+ * ```
187
+ */
188
+ export declare const ESA: {
189
+ /**
190
+ * Search the ESA Hubble Space Telescope image archive.
191
+ *
192
+ * Queries the ESAHubble public REST API and returns an array of
193
+ * {@link ESAHubbleResult} objects with image metadata and URLs.
194
+ *
195
+ * @param query - Free-text search term (e.g. `'crab nebula'`).
196
+ * @param limit - Maximum number of results to return. Defaults to `10`.
197
+ *
198
+ * @returns An array of matching Hubble image results. Each result
199
+ * includes both a full-resolution `imageUrl` and a
200
+ * screen-sized `thumbUrl`.
201
+ *
202
+ * @throws {Error} If the ESA API responds with a non-2xx status code.
203
+ *
204
+ * @example
205
+ * ```ts
206
+ * const results = await ESA.searchHubble('crab nebula', 3)
207
+ * for (const r of results) {
208
+ * console.log(r.title, r.thumbUrl)
209
+ * }
210
+ * ```
211
+ *
212
+ * @see {@link https://esahubble.org/api/v1/ | ESA Hubble API docs}
213
+ */
214
+ searchHubble(query: string, limit?: number): Promise<ESAHubbleResult[]>;
215
+ };
216
+ /**
217
+ * Resolve an astronomical object name through the CDS SIMBAD TAP service.
218
+ *
219
+ * Performs an ADQL query against the SIMBAD database at the Strasbourg
220
+ * Astronomical Data Centre (CDS) and returns the J2000 equatorial
221
+ * coordinates and object type for the first match.
222
+ *
223
+ * @param objectName - Any object identifier recognised by SIMBAD
224
+ * (e.g. `'M1'`, `'NGC 6611'`, `'Betelgeuse'`).
225
+ *
226
+ * @returns A {@link SimbadResult} with the main identifier, RA/Dec in
227
+ * degrees, and the SIMBAD object-type code, or `null` if the
228
+ * object name could not be resolved.
229
+ *
230
+ * @throws {Error} If the SIMBAD TAP endpoint responds with a non-2xx
231
+ * status code.
232
+ *
233
+ * @example
234
+ * ```ts
235
+ * import { resolveSimbad } from 'cosmos-lib'
236
+ *
237
+ * const m1 = await resolveSimbad('M1')
238
+ * if (m1) {
239
+ * console.log(`RA: ${m1.ra}, Dec: ${m1.dec}, Type: ${m1.type}`)
240
+ * }
241
+ *
242
+ * const star = await resolveSimbad('Betelgeuse')
243
+ * // => { id: '* alf Ori', ra: 88.792..., dec: 7.407..., type: 'LP*' }
244
+ * ```
245
+ */
246
+ export declare function resolveSimbad(objectName: string): Promise<SimbadResult | null>;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Time-bucketed memoization for astronomical position functions.
3
+ *
4
+ * Rounds Date inputs to the nearest `bucketMs` milliseconds to create
5
+ * cache keys. Uses LRU eviction via Map insertion order.
6
+ *
7
+ * @param fn - Pure function accepting a Date as its first argument.
8
+ * @param bucketMs - Time bucket size in milliseconds (default: 60 000 = 1 minute).
9
+ * @param maxSize - Maximum cache entries before LRU eviction (default: 128).
10
+ */
11
+ export declare function memoByTime<T>(fn: (date: Date) => T, bucketMs?: number, maxSize?: number): (date?: Date) => T;
@@ -0,0 +1,181 @@
1
+ import type { ObserverParams } from './types.js';
2
+ /** Event types emitted by {@link AstroClock}. */
3
+ export interface AstroClockEventMap {
4
+ /** Fired on each tick with the current simulation date. */
5
+ tick: {
6
+ date: Date;
7
+ speed: number;
8
+ playing: boolean;
9
+ };
10
+ /** Fired when playback starts or resumes. */
11
+ play: {
12
+ date: Date;
13
+ speed: number;
14
+ };
15
+ /** Fired when playback pauses. */
16
+ pause: {
17
+ date: Date;
18
+ };
19
+ /** Fired when the date is set programmatically (including snap-to-event). */
20
+ datechange: {
21
+ date: Date;
22
+ reason: 'set' | 'snap';
23
+ };
24
+ /** Fired when the speed multiplier changes. */
25
+ speedchange: {
26
+ speed: number;
27
+ };
28
+ }
29
+ /** Options for creating an {@link AstroClock}. */
30
+ export interface AstroClockOptions {
31
+ /** Initial simulation date. @defaultValue `new Date()` */
32
+ startDate?: Date;
33
+ /** Speed multiplier (1 = real-time, 60 = 1 minute/second, -1 = reverse). @defaultValue `1` */
34
+ speed?: number;
35
+ /** Tick interval in milliseconds (used in timer mode). @defaultValue `1000` */
36
+ tickInterval?: number;
37
+ /** Use `requestAnimationFrame` for frame-accurate ticking. @defaultValue `false` */
38
+ useRAF?: boolean;
39
+ /** Auto-start playback on creation. @defaultValue `false` */
40
+ autoPlay?: boolean;
41
+ }
42
+ /** An astronomical event type for snap-to-event navigation. */
43
+ export type AstroEventType = 'sunrise' | 'sunset' | 'moonrise' | 'moonset' | 'solar-noon' | 'moon-transit' | 'civil-dawn' | 'civil-dusk' | 'nautical-dawn' | 'nautical-dusk' | 'astro-dawn' | 'astro-dusk';
44
+ /**
45
+ * A simulation clock that decouples observation time from wall-clock time.
46
+ *
47
+ * `AstroClock` maintains a virtual date that advances at a configurable speed
48
+ * multiplier. It supports forward and reverse playback, pause/resume, snap-to-event
49
+ * navigation, and both timer-based and `requestAnimationFrame`-based ticking.
50
+ *
51
+ * @remarks
52
+ * The clock advances the simulation date by `elapsed_ms * speed` on each tick.
53
+ * A speed of 1 means real-time; 60 means 1 minute of simulated time per second
54
+ * of wall-clock time; -1 means reverse real-time. The clock emits typed events
55
+ * via `on()`/`off()` for integration with UI frameworks.
56
+ *
57
+ * @example
58
+ * ```ts
59
+ * import { AstroClock } from '@motioncomplex/cosmos-lib'
60
+ *
61
+ * const clock = new AstroClock({ speed: 60, useRAF: true, autoPlay: true })
62
+ *
63
+ * clock.on('tick', ({ date }) => {
64
+ * updateSkyMap(date)
65
+ * updateUI(date)
66
+ * })
67
+ *
68
+ * // Jump to a specific date
69
+ * clock.setDate(new Date('2024-12-21T00:00:00Z'))
70
+ *
71
+ * // Snap to next sunset
72
+ * clock.snapTo('sunset', { lat: 47.05, lng: 8.31 })
73
+ *
74
+ * // Reverse playback at 10x speed
75
+ * clock.setSpeed(-10)
76
+ *
77
+ * // Clean up
78
+ * clock.dispose()
79
+ * ```
80
+ */
81
+ export declare class AstroClock {
82
+ private _date;
83
+ private _speed;
84
+ private _tickInterval;
85
+ private _useRAF;
86
+ private _playing;
87
+ private _disposed;
88
+ private _lastWallTime;
89
+ private _timerId;
90
+ private _rafId;
91
+ private _listeners;
92
+ constructor(options?: AstroClockOptions);
93
+ /**
94
+ * Subscribe to a clock event.
95
+ *
96
+ * @param event - Event name.
97
+ * @param handler - Callback invoked when the event fires.
98
+ *
99
+ * @example
100
+ * ```ts
101
+ * clock.on('tick', ({ date, speed }) => console.log(date, speed))
102
+ * clock.on('pause', () => console.log('Paused'))
103
+ * ```
104
+ */
105
+ on<K extends keyof AstroClockEventMap>(event: K, handler: (data: AstroClockEventMap[K]) => void): void;
106
+ /**
107
+ * Unsubscribe from a clock event.
108
+ */
109
+ off<K extends keyof AstroClockEventMap>(event: K, handler: (data: AstroClockEventMap[K]) => void): void;
110
+ private _emit;
111
+ /**
112
+ * Start or resume playback.
113
+ *
114
+ * The simulation date advances by `elapsed_ms * speed` on each tick.
115
+ * If already playing, this is a no-op.
116
+ */
117
+ play(): void;
118
+ /**
119
+ * Pause playback. The simulation date freezes at its current value.
120
+ */
121
+ pause(): void;
122
+ /** Whether the clock is currently playing. */
123
+ get playing(): boolean;
124
+ /**
125
+ * Set the simulation date. Emits `'datechange'`.
126
+ *
127
+ * @param date - The new simulation date.
128
+ */
129
+ setDate(date: Date): void;
130
+ /** Get the current simulation date. */
131
+ get date(): Date;
132
+ /**
133
+ * Set the speed multiplier. Emits `'speedchange'`.
134
+ *
135
+ * @param speed - New speed (1 = real-time, 60 = 1min/sec, -1 = reverse real-time).
136
+ *
137
+ * @example
138
+ * ```ts
139
+ * clock.setSpeed(3600) // 1 hour per second
140
+ * clock.setSpeed(-60) // reverse, 1 minute per second
141
+ * clock.setSpeed(0) // frozen (like pause but still "playing")
142
+ * ```
143
+ */
144
+ setSpeed(speed: number): void;
145
+ /** Get the current speed multiplier. */
146
+ get speed(): number;
147
+ /**
148
+ * Jump to the next occurrence of an astronomical event.
149
+ *
150
+ * Computes the next rise, set, or transit for the Sun or Moon from the
151
+ * current simulation date and observer location, then sets the clock to
152
+ * that time.
153
+ *
154
+ * @param eventType - The event to snap to.
155
+ * @param observer - Observer location (date is ignored; current sim date is used).
156
+ * @returns The date snapped to, or `null` if the event doesn't occur.
157
+ *
158
+ * @example
159
+ * ```ts
160
+ * clock.snapTo('sunset', { lat: 47.05, lng: 8.31 })
161
+ * clock.snapTo('moonrise', { lat: 51.5, lng: -0.1 })
162
+ * ```
163
+ */
164
+ snapTo(eventType: AstroEventType, observer: ObserverParams): Date | null;
165
+ /**
166
+ * If the event time is in the past (relative to current sim date),
167
+ * try the next day. Returns null if the event is null.
168
+ */
169
+ private _nextOccurrence;
170
+ /**
171
+ * Stop the clock, remove all listeners, and release resources.
172
+ * The instance should not be used after calling `dispose()`.
173
+ */
174
+ dispose(): void;
175
+ private _advance;
176
+ private _tick;
177
+ private _rafTick;
178
+ private _emitTick;
179
+ private _scheduleNext;
180
+ private _cancelScheduled;
181
+ }
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Fundamental astronomical and physical constants used throughout the library.
3
+ *
4
+ * All values follow IAU 2012 / IERS conventions unless otherwise noted.
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * import { CONSTANTS } from '@motioncomplex/cosmos-lib'
9
+ * const earthSunKm = 1 * CONSTANTS.AU_TO_KM // 149 597 870.7
10
+ * ```
11
+ */
12
+ export declare const CONSTANTS: {
13
+ /** One Astronomical Unit in kilometres (IAU 2012 exact definition). */
14
+ readonly AU_TO_KM: 149597870.7;
15
+ /** One light-year in kilometres. */
16
+ readonly LY_TO_KM: 9460730472580.8;
17
+ /** One parsec in light-years. */
18
+ readonly PC_TO_LY: 3.261563777;
19
+ /** One parsec in kilometres. */
20
+ readonly PC_TO_KM: 30856775810000;
21
+ /** Speed of light in km/s (exact, SI definition). */
22
+ readonly C_KM_S: 299792.458;
23
+ /** Newtonian gravitational constant in m^3 kg^-1 s^-2 (CODATA 2018). */
24
+ readonly G: 6.674e-11;
25
+ /** Solar mass in kilograms. */
26
+ readonly SOLAR_MASS_KG: 1.989e+30;
27
+ /** Solar radius in kilometres. */
28
+ readonly SOLAR_RADIUS_KM: 695700;
29
+ /** Earth mass in kilograms. */
30
+ readonly EARTH_MASS_KG: 5.972e+24;
31
+ /** Mean Earth radius in kilometres (IUGG). */
32
+ readonly EARTH_RADIUS_KM: 6371;
33
+ /** Julian Date of the J2000.0 epoch (2000-01-01T12:00:00 TT). */
34
+ readonly J2000: 2451545;
35
+ /** Mean obliquity of the ecliptic at J2000.0, in degrees. */
36
+ readonly ECLIPTIC_OBL: 23.4392911;
37
+ /** Conversion factor: degrees to radians. */
38
+ readonly DEG_TO_RAD: number;
39
+ /** Conversion factor: radians to degrees. */
40
+ readonly RAD_TO_DEG: number;
41
+ };
42
+ /** The type of the {@link CONSTANTS} object. */
43
+ export type Constants = typeof CONSTANTS;
@@ -0,0 +1,58 @@
1
+ /**
2
+ * All 88 IAU constellations with metadata and stick-figure asterism line segments.
3
+ *
4
+ * Coordinates are J2000 epoch, in degrees.
5
+ * Stick-figure segments connect the major naked-eye stars of each traditional
6
+ * Western asterism (similar to Stellarium's default patterns).
7
+ * Each segment is `[ra1, dec1, ra2, dec2]` in degrees.
8
+ *
9
+ * @module
10
+ */
11
+ /**
12
+ * An IAU constellation with boundary metadata and a stick-figure asterism.
13
+ *
14
+ * Contains the official 3-letter abbreviation, full and genitive names,
15
+ * approximate center coordinates for label placement, the official area
16
+ * in square degrees, the brightest star name, and an array of line
17
+ * segments that form the traditional stick-figure pattern.
18
+ */
19
+ export interface Constellation {
20
+ /** 3-letter IAU abbreviation (e.g., "Ori") */
21
+ abbr: string;
22
+ /** Full name (e.g., "Orion") */
23
+ name: string;
24
+ /** Genitive form (e.g., "Orionis") */
25
+ genitive: string;
26
+ /** Approximate center RA for labeling (degrees) */
27
+ ra: number;
28
+ /** Approximate center Dec for labeling (degrees) */
29
+ dec: number;
30
+ /** IAU official area in square degrees */
31
+ area: number;
32
+ /** Array of line segments, each [ra1_deg, dec1_deg, ra2_deg, dec2_deg] */
33
+ stickFigure: number[][];
34
+ /** IAU proper name of the brightest star */
35
+ brightestStar: string;
36
+ }
37
+ /**
38
+ * All 88 IAU constellations with stick-figure asterism data.
39
+ *
40
+ * Each constellation includes center coordinates for label placement,
41
+ * its official area in square degrees, its brightest star, and an array
42
+ * of line segments (`[ra1, dec1, ra2, dec2]`) defining the traditional
43
+ * Western asterism pattern.
44
+ *
45
+ * @example
46
+ * ```ts
47
+ * import { CONSTELLATIONS } from '@motioncomplex/cosmos-lib'
48
+ *
49
+ * const orion = CONSTELLATIONS.find(c => c.abbr === 'Ori')
50
+ * console.log(orion?.name) // 'Orion'
51
+ * console.log(orion?.brightestStar) // 'Rigel'
52
+ * console.log(orion?.stickFigure.length) // number of line segments
53
+ *
54
+ * // Get all constellations larger than 1000 sq deg
55
+ * const large = CONSTELLATIONS.filter(c => c.area > 1000)
56
+ * ```
57
+ */
58
+ export declare const CONSTELLATIONS: readonly Constellation[];