@typescriptify/sweph 1.0.0

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 (211) hide show
  1. package/README.md +422 -0
  2. package/ephe/semo_18.se1 +0 -0
  3. package/ephe/sepl_18.se1 +0 -0
  4. package/originalCode/.eslintrc.json +124 -0
  5. package/originalCode/.gitattributes +2 -0
  6. package/originalCode/.github/FUNDING.yml +5 -0
  7. package/originalCode/.github/workflows/test.yml +35 -0
  8. package/originalCode/LICENSE +840 -0
  9. package/originalCode/README.md +91 -0
  10. package/originalCode/binding.gyp +41 -0
  11. package/originalCode/constants.js +366 -0
  12. package/originalCode/docs.gif +0 -0
  13. package/originalCode/index.d.ts +5115 -0
  14. package/originalCode/index.js +7 -0
  15. package/originalCode/index.mjs +109 -0
  16. package/originalCode/package.json +55 -0
  17. package/originalCode/src/functions/azalt.cpp +39 -0
  18. package/originalCode/src/functions/azalt_rev.cpp +35 -0
  19. package/originalCode/src/functions/calc.cpp +29 -0
  20. package/originalCode/src/functions/calc_pctr.cpp +31 -0
  21. package/originalCode/src/functions/calc_ut.cpp +29 -0
  22. package/originalCode/src/functions/close.cpp +6 -0
  23. package/originalCode/src/functions/cotrans.cpp +26 -0
  24. package/originalCode/src/functions/cotrans_sp.cpp +26 -0
  25. package/originalCode/src/functions/cs2degstr.cpp +19 -0
  26. package/originalCode/src/functions/cs2lonlatstr.cpp +23 -0
  27. package/originalCode/src/functions/cs2timestr.cpp +23 -0
  28. package/originalCode/src/functions/csnorm.cpp +15 -0
  29. package/originalCode/src/functions/csroundsec.cpp +15 -0
  30. package/originalCode/src/functions/d2l.cpp +15 -0
  31. package/originalCode/src/functions/date_conversion.cpp +30 -0
  32. package/originalCode/src/functions/day_of_week.cpp +15 -0
  33. package/originalCode/src/functions/degnorm.cpp +15 -0
  34. package/originalCode/src/functions/deltat.cpp +15 -0
  35. package/originalCode/src/functions/deltat_ex.cpp +24 -0
  36. package/originalCode/src/functions/difcs2n.cpp +19 -0
  37. package/originalCode/src/functions/difcsn.cpp +19 -0
  38. package/originalCode/src/functions/difdeg2n.cpp +19 -0
  39. package/originalCode/src/functions/difdegn.cpp +19 -0
  40. package/originalCode/src/functions/fixstar.cpp +32 -0
  41. package/originalCode/src/functions/fixstar2.cpp +32 -0
  42. package/originalCode/src/functions/fixstar2_mag.cpp +28 -0
  43. package/originalCode/src/functions/fixstar2_ut.cpp +32 -0
  44. package/originalCode/src/functions/fixstar_mag.cpp +28 -0
  45. package/originalCode/src/functions/fixstar_ut.cpp +32 -0
  46. package/originalCode/src/functions/gauquelin_sector.cpp +44 -0
  47. package/originalCode/src/functions/get_ayanamsa.cpp +15 -0
  48. package/originalCode/src/functions/get_ayanamsa_ex.cpp +27 -0
  49. package/originalCode/src/functions/get_ayanamsa_ex_ut.cpp +27 -0
  50. package/originalCode/src/functions/get_ayanamsa_name.cpp +19 -0
  51. package/originalCode/src/functions/get_ayanamsa_ut.cpp +15 -0
  52. package/originalCode/src/functions/get_current_file_data.cpp +28 -0
  53. package/originalCode/src/functions/get_library_path.cpp +8 -0
  54. package/originalCode/src/functions/get_orbital_elements.cpp +29 -0
  55. package/originalCode/src/functions/get_planet_name.cpp +19 -0
  56. package/originalCode/src/functions/get_tid_acc.cpp +7 -0
  57. package/originalCode/src/functions/heliacal_pheno_ut.cpp +52 -0
  58. package/originalCode/src/functions/heliacal_ut.cpp +52 -0
  59. package/originalCode/src/functions/helio_cross.cpp +33 -0
  60. package/originalCode/src/functions/helio_cross_ut.cpp +33 -0
  61. package/originalCode/src/functions/house_name.cpp +20 -0
  62. package/originalCode/src/functions/house_pos.cpp +36 -0
  63. package/originalCode/src/functions/houses.cpp +35 -0
  64. package/originalCode/src/functions/houses_armc.cpp +38 -0
  65. package/originalCode/src/functions/houses_armc_ex2.cpp +47 -0
  66. package/originalCode/src/functions/houses_ex.cpp +37 -0
  67. package/originalCode/src/functions/houses_ex2.cpp +46 -0
  68. package/originalCode/src/functions/jdet_to_utc.cpp +38 -0
  69. package/originalCode/src/functions/jdut1_to_utc.cpp +38 -0
  70. package/originalCode/src/functions/julday.cpp +25 -0
  71. package/originalCode/src/functions/lat_to_lmt.cpp +27 -0
  72. package/originalCode/src/functions/lmt_to_lat.cpp +27 -0
  73. package/originalCode/src/functions/lun_eclipse_how.cpp +34 -0
  74. package/originalCode/src/functions/lun_eclipse_when.cpp +31 -0
  75. package/originalCode/src/functions/lun_eclipse_when_loc.cpp +39 -0
  76. package/originalCode/src/functions/lun_occult_when_glob.cpp +35 -0
  77. package/originalCode/src/functions/lun_occult_when_loc.cpp +43 -0
  78. package/originalCode/src/functions/lun_occult_where.cpp +34 -0
  79. package/originalCode/src/functions/mooncross.cpp +26 -0
  80. package/originalCode/src/functions/mooncross_node.cpp +30 -0
  81. package/originalCode/src/functions/mooncross_node_ut.cpp +30 -0
  82. package/originalCode/src/functions/mooncross_ut.cpp +26 -0
  83. package/originalCode/src/functions/nod_aps.cpp +42 -0
  84. package/originalCode/src/functions/nod_aps_ut.cpp +42 -0
  85. package/originalCode/src/functions/orbit_max_min_true_distance.cpp +37 -0
  86. package/originalCode/src/functions/pheno.cpp +29 -0
  87. package/originalCode/src/functions/pheno_ut.cpp +29 -0
  88. package/originalCode/src/functions/radnorm.cpp +15 -0
  89. package/originalCode/src/functions/refrac.cpp +23 -0
  90. package/originalCode/src/functions/refrac_extended.cpp +32 -0
  91. package/originalCode/src/functions/revjul.cpp +33 -0
  92. package/originalCode/src/functions/rise_trans.cpp +44 -0
  93. package/originalCode/src/functions/rise_trans_true_hor.cpp +46 -0
  94. package/originalCode/src/functions/set_delta_t_userdef.cpp +14 -0
  95. package/originalCode/src/functions/set_ephe_path.cpp +14 -0
  96. package/originalCode/src/functions/set_jpl_file.cpp +14 -0
  97. package/originalCode/src/functions/set_sid_mode.cpp +20 -0
  98. package/originalCode/src/functions/set_tid_acc.cpp +14 -0
  99. package/originalCode/src/functions/set_topo.cpp +20 -0
  100. package/originalCode/src/functions/sidtime.cpp +15 -0
  101. package/originalCode/src/functions/sidtime0.cpp +21 -0
  102. package/originalCode/src/functions/sol_eclipse_how.cpp +34 -0
  103. package/originalCode/src/functions/sol_eclipse_when_glob.cpp +31 -0
  104. package/originalCode/src/functions/sol_eclipse_when_loc.cpp +39 -0
  105. package/originalCode/src/functions/sol_eclipse_where.cpp +30 -0
  106. package/originalCode/src/functions/solcross.cpp +26 -0
  107. package/originalCode/src/functions/solcross_ut.cpp +26 -0
  108. package/originalCode/src/functions/split_deg.cpp +35 -0
  109. package/originalCode/src/functions/time_equ.cpp +25 -0
  110. package/originalCode/src/functions/utc_time_zone.cpp +48 -0
  111. package/originalCode/src/functions/utc_to_jd.cpp +37 -0
  112. package/originalCode/src/functions/version.cpp +8 -0
  113. package/originalCode/src/functions/vis_limit_mag.cpp +50 -0
  114. package/originalCode/src/sweph.cpp +150 -0
  115. package/originalCode/src/sweph.h +119 -0
  116. package/originalCode/swisseph/swecl.c +6428 -0
  117. package/originalCode/swisseph/swedate.c +588 -0
  118. package/originalCode/swisseph/swedate.h +81 -0
  119. package/originalCode/swisseph/swehel.c +3511 -0
  120. package/originalCode/swisseph/swehouse.c +3143 -0
  121. package/originalCode/swisseph/swehouse.h +98 -0
  122. package/originalCode/swisseph/swejpl.c +958 -0
  123. package/originalCode/swisseph/swejpl.h +103 -0
  124. package/originalCode/swisseph/swemmoon.c +1930 -0
  125. package/originalCode/swisseph/swemplan.c +967 -0
  126. package/originalCode/swisseph/swemptab.h +10640 -0
  127. package/originalCode/swisseph/swenut2000a.h +2819 -0
  128. package/originalCode/swisseph/sweodef.h +326 -0
  129. package/originalCode/swisseph/sweph.c +8614 -0
  130. package/originalCode/swisseph/sweph.h +849 -0
  131. package/originalCode/swisseph/swephexp.h +1020 -0
  132. package/originalCode/swisseph/swephlib.c +4634 -0
  133. package/originalCode/swisseph/swephlib.h +189 -0
  134. package/package.json +28 -0
  135. package/scripts/gen-swemptab.js +177 -0
  136. package/scripts/gen-swenut2000a.js +106 -0
  137. package/src/SwissEph/README.md +268 -0
  138. package/src/SwissEph/UseCases/Ayanamsa.md +363 -0
  139. package/src/SwissEph/UseCases/AzimuthAltitude.md +408 -0
  140. package/src/SwissEph/UseCases/CoordinateSystems.md +337 -0
  141. package/src/SwissEph/UseCases/DateAndTime.md +368 -0
  142. package/src/SwissEph/UseCases/DeltaT.md +258 -0
  143. package/src/SwissEph/UseCases/EphemerisFiles.md +338 -0
  144. package/src/SwissEph/UseCases/FixedStars.md +300 -0
  145. package/src/SwissEph/UseCases/GauquelinSectors.md +304 -0
  146. package/src/SwissEph/UseCases/HeliacalEvents.md +396 -0
  147. package/src/SwissEph/UseCases/HelioCrossings.md +325 -0
  148. package/src/SwissEph/UseCases/HousePosition.md +254 -0
  149. package/src/SwissEph/UseCases/HouseSystems.md +279 -0
  150. package/src/SwissEph/UseCases/LunarEclipse.md +326 -0
  151. package/src/SwissEph/UseCases/MeridianTransit.md +279 -0
  152. package/src/SwissEph/UseCases/MoonCrossings.md +373 -0
  153. package/src/SwissEph/UseCases/NodesAndApsides.md +307 -0
  154. package/src/SwissEph/UseCases/Occultation.md +352 -0
  155. package/src/SwissEph/UseCases/OrbitalElements.md +469 -0
  156. package/src/SwissEph/UseCases/Phenomena.md +328 -0
  157. package/src/SwissEph/UseCases/PlanetPositions.md +366 -0
  158. package/src/SwissEph/UseCases/Planetocentric.md +278 -0
  159. package/src/SwissEph/UseCases/Refraction.md +314 -0
  160. package/src/SwissEph/UseCases/RiseAndSet.md +433 -0
  161. package/src/SwissEph/UseCases/SiderealTime.md +302 -0
  162. package/src/SwissEph/UseCases/SolarEclipse.md +379 -0
  163. package/src/SwissEph/UseCases/SunCrossings.md +275 -0
  164. package/src/SwissEph/UseCases/TopocentricCorrection.md +335 -0
  165. package/src/SwissEph/errors.ts +10 -0
  166. package/src/SwissEph/index.ts +823 -0
  167. package/src/SwissEph/types.ts +291 -0
  168. package/src/constants.ts +762 -0
  169. package/src/file-reader.ts +147 -0
  170. package/src/index.ts +10 -0
  171. package/src/swecl.ts +4526 -0
  172. package/src/swedate.ts +376 -0
  173. package/src/swehel.ts +1939 -0
  174. package/src/swehouse.ts +2167 -0
  175. package/src/swejpl.ts +470 -0
  176. package/src/swemmoon.ts +1318 -0
  177. package/src/swemplan.ts +585 -0
  178. package/src/swemptab.ts +4448 -0
  179. package/src/swenut2000a.ts +2763 -0
  180. package/src/sweph.ts +3993 -0
  181. package/src/swephlib.ts +2720 -0
  182. package/src/types.ts +490 -0
  183. package/tests/c-style/ayanamsa.test.ts +63 -0
  184. package/tests/c-style/config.test.ts +96 -0
  185. package/tests/c-style/crossings.test.ts +81 -0
  186. package/tests/c-style/date-time.test.ts +114 -0
  187. package/tests/c-style/eclipses.test.ts +84 -0
  188. package/tests/c-style/fixed-stars.test.ts +66 -0
  189. package/tests/c-style/heliacal.test.ts +34 -0
  190. package/tests/c-style/houses.test.ts +135 -0
  191. package/tests/c-style/math-utils.test.ts +160 -0
  192. package/tests/c-style/orbital.test.ts +78 -0
  193. package/tests/c-style/phenomena.test.ts +42 -0
  194. package/tests/c-style/planetocentric.test.ts +26 -0
  195. package/tests/c-style/planets.test.ts +117 -0
  196. package/tests/c-style/rise-set.test.ts +71 -0
  197. package/tests/helpers.ts +21 -0
  198. package/tests/modern/ayanamsa.test.ts +47 -0
  199. package/tests/modern/calc.test.ts +113 -0
  200. package/tests/modern/config.test.ts +46 -0
  201. package/tests/modern/crossings.test.ts +45 -0
  202. package/tests/modern/eclipses.test.ts +81 -0
  203. package/tests/modern/errors.test.ts +71 -0
  204. package/tests/modern/heliacal.test.ts +30 -0
  205. package/tests/modern/houses.test.ts +87 -0
  206. package/tests/modern/orbital.test.ts +79 -0
  207. package/tests/modern/phenomena.test.ts +41 -0
  208. package/tests/modern/rise-set.test.ts +60 -0
  209. package/tests/modern/statics.test.ts +99 -0
  210. package/tests/modern/utilities.test.ts +70 -0
  211. package/tsconfig.json +20 -0
package/README.md ADDED
@@ -0,0 +1,422 @@
1
+ # @typescriptify/sweph
2
+
3
+ A pure TypeScript translation of the [Swiss Ephemeris](https://www.astro.com/swisseph/) — the gold standard library for astronomical and astrological calculations.
4
+
5
+ This library lets you calculate the positions of the Sun, Moon, planets, and stars with high precision. You can compute house cusps, eclipses, rise/set times, and much more — all from TypeScript or JavaScript, with no native dependencies.
6
+
7
+ ## What can it do?
8
+
9
+ - **Planet positions** — get the longitude, latitude, and distance of any planet at any date
10
+ - **House systems** — calculate house cusps for 24+ house systems (Placidus, Koch, Whole Sign, etc.)
11
+ - **Fixed stars** — positions and magnitudes of key stars (Spica, Regulus, Aldebaran, etc.)
12
+ - **Eclipses** — find solar/lunar eclipses, occultations, compute eclipse paths
13
+ - **Rise/set times** — sunrise, sunset, moonrise, planet transits
14
+ - **Ayanamsa** — sidereal zodiac support with 40+ ayanamsa modes (Lahiri, True Citra, etc.)
15
+ - **Heliacal events** — heliacal rising/setting of planets and stars
16
+ - **Orbital elements** — Keplerian elements, nodes, apsides
17
+ - **Date conversions** — Julian day, UTC, Delta T, sidereal time
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ npm install @typescriptify/sweph
23
+ ```
24
+
25
+ ## Two API Styles
26
+
27
+ This library provides two ways to use it:
28
+
29
+ | | C-style API | Modern TypeScript API |
30
+ |---|---|---|
31
+ | **Style** | Direct translation of the C functions | Class-based wrapper with named return types |
32
+ | **State** | Thread `swed: SweData` manually | Managed inside `SwissEph` instance |
33
+ | **Returns** | `Float64Array`, positional indexing (`xx[0]`) | Named objects (`{ longitude, latitude, ... }`) |
34
+ | **Errors** | Check return codes (`ERR = -1`) | Throws `SwissEphError` |
35
+ | **Time mode** | Separate `*Ut` / `*Et` functions | Automatic routing via `timeMode` option |
36
+ | **Docs** | This README (below) | [`src/SwissEph/`](./src/SwissEph/) — see [README](./src/SwissEph/README.md) and [UseCases](./src/SwissEph/UseCases/) |
37
+
38
+ **Modern API** — if you want a clean, idiomatic TypeScript experience:
39
+
40
+ ```typescript
41
+ import { SwissEph } from '@typescriptify/sweph/SwissEph';
42
+ import { SE_SUN, SE_MARS } from '@typescriptify/sweph/constants';
43
+
44
+ const swe = new SwissEph();
45
+ const jd = SwissEph.julianDay(2025, 1, 1, 12);
46
+
47
+ const sun = swe.calc(jd, SE_SUN);
48
+ console.log(`Sun: ${sun.longitude.toFixed(4)}°, speed: ${sun.longitudeSpeed.toFixed(4)}°/day`);
49
+
50
+ swe.close();
51
+ ```
52
+
53
+ See [`src/SwissEph/README.md`](./src/SwissEph/README.md) for full documentation and [`src/SwissEph/UseCases/`](./src/SwissEph/UseCases/) for 27 detailed use case guides covering everything from planet positions to heliacal events.
54
+
55
+ ---
56
+
57
+ **C-style API** — if you're familiar with the original Swiss Ephemeris C interface, the rest of this README is for you.
58
+
59
+ ## Quick Start
60
+
61
+ Every function takes a `swed` state object as its first argument. Create one at startup and reuse it:
62
+
63
+ ```typescript
64
+ import { createDefaultSweData } from '@typescriptify/sweph/types';
65
+ import { sweCalc } from '@typescriptify/sweph/sweph';
66
+ import { julDay } from '@typescriptify/sweph/swedate';
67
+ import {
68
+ SE_SUN, SE_MOON, SE_MARS,
69
+ SEFLG_MOSEPH, SEFLG_SPEED,
70
+ SE_GREG_CAL,
71
+ } from '@typescriptify/sweph/constants';
72
+
73
+ // 1. Create the state object (do this once)
74
+ const swed = createDefaultSweData();
75
+
76
+ // 2. Convert a calendar date to a Julian day number
77
+ // (January 1, 2025 at noon UT)
78
+ const jd = julDay(2025, 1, 1, 12.0, SE_GREG_CAL);
79
+
80
+ // 3. Calculate the Sun's position
81
+ const sun = sweCalc(swed, jd, SE_SUN, SEFLG_MOSEPH | SEFLG_SPEED);
82
+
83
+ console.log(`Sun longitude: ${sun.xx[0].toFixed(4)}°`); // ecliptic longitude
84
+ console.log(`Sun latitude: ${sun.xx[1].toFixed(4)}°`); // ecliptic latitude
85
+ console.log(`Sun distance: ${sun.xx[2].toFixed(6)} AU`); // distance in AU
86
+ console.log(`Sun speed: ${sun.xx[3].toFixed(4)}°/day`); // daily motion
87
+ ```
88
+
89
+ The result `xx` is a `Float64Array` with 6 elements: `[longitude, latitude, distance, lonSpeed, latSpeed, distSpeed]`.
90
+
91
+ ### Calculating the Moon
92
+
93
+ ```typescript
94
+ const moon = sweCalc(swed, jd, SE_MOON, SEFLG_MOSEPH | SEFLG_SPEED);
95
+ console.log(`Moon: ${moon.xx[0].toFixed(4)}° at ${moon.xx[3].toFixed(2)}°/day`);
96
+ ```
97
+
98
+ ### Calculating houses
99
+
100
+ ```typescript
101
+ import { sweHouses } from '@typescriptify/sweph/swehouse';
102
+
103
+ const cusps = new Array(37).fill(0); // cusp[1]..cusp[12]
104
+ const ascmc = new Array(10).fill(0); // ascmc[0]=AC, ascmc[1]=MC, ascmc[2]=ARMC, etc.
105
+
106
+ // Placidus houses for London at the given time
107
+ sweHouses(swed, jd, 51.5074, -0.1276, 'P', cusps, ascmc);
108
+
109
+ console.log(`Ascendant: ${ascmc[0].toFixed(2)}°`);
110
+ console.log(`Midheaven: ${ascmc[1].toFixed(2)}°`);
111
+ for (let i = 1; i <= 12; i++) {
112
+ console.log(` House ${i}: ${cusps[i].toFixed(2)}°`);
113
+ }
114
+ ```
115
+
116
+ House system codes: `'P'` = Placidus, `'K'` = Koch, `'E'` = Equal, `'W'` = Whole Sign, `'C'` = Campanus, `'R'` = Regiomontanus, `'B'` = Alcabitius, and [many more](#house-systems).
117
+
118
+ ## Ephemeris Modes
119
+
120
+ This library supports three levels of precision:
121
+
122
+ | Mode | Flag | Precision | Data files needed? |
123
+ |---|---|---|---|
124
+ | **Moshier** | `SEFLG_MOSEPH` | ~1 arcsecond | No (built-in) |
125
+ | **Swiss Ephemeris** | `SEFLG_SWIEPH` | ~0.001 arcsecond | Yes (`.se1` files) |
126
+ | **JPL** | `SEFLG_JPLEPH` | ~0.001 arcsecond | Yes (JPL DE file) |
127
+
128
+ **Moshier mode** works out of the box with no data files. It uses built-in analytical models and is accurate enough for most purposes.
129
+
130
+ **Swiss Ephemeris mode** reads pre-computed binary data files (`.se1`) for higher precision. See [Loading Ephemeris Data Files](#loading-ephemeris-data-files) below.
131
+
132
+ **JPL mode** reads NASA JPL Development Ephemeris binary files (e.g., `de441.eph`). See [Loading JPL Files](#loading-jpl-files) below.
133
+
134
+ ## Loading Ephemeris Data Files
135
+
136
+ ### Where to download
137
+
138
+ Download `.se1` files from the official Swiss Ephemeris site:
139
+ - **https://www.astro.com/ftp/swisseph/ephe/**
140
+
141
+ The most common files you'll need:
142
+ - `sepl_18.se1` — planet data (1800 AD - 2400 AD)
143
+ - `semo_18.se1` — Moon data (1800 AD - 2400 AD)
144
+
145
+ For other date ranges, download the corresponding files (e.g., `sepl_06.se1` for 600 AD - 1200 AD).
146
+
147
+ ### How to load them
148
+
149
+ Since this is a pure TypeScript library (no filesystem access), you load files as `ArrayBuffer`s. How you get the `ArrayBuffer` depends on your environment:
150
+
151
+ **Node.js:**
152
+ ```typescript
153
+ import { readFileSync } from 'fs';
154
+ import { sweSetEphemerisFile, sweCalc } from '@typescriptify/sweph/sweph';
155
+ import { createDefaultSweData } from '@typescriptify/sweph/types';
156
+ import { SE_SUN, SEFLG_SWIEPH, SEFLG_SPEED } from '@typescriptify/sweph/constants';
157
+
158
+ const swed = createDefaultSweData();
159
+
160
+ // Load the planet and moon ephemeris files
161
+ const seplBuf = readFileSync('./ephe/sepl_18.se1');
162
+ const semoBuf = readFileSync('./ephe/semo_18.se1');
163
+
164
+ sweSetEphemerisFile('sepl_18.se1', seplBuf.buffer, swed);
165
+ sweSetEphemerisFile('semo_18.se1', semoBuf.buffer, swed);
166
+
167
+ // Now you can use SEFLG_SWIEPH for higher precision
168
+ const sun = sweCalc(swed, 2451545.0, SE_SUN, SEFLG_SWIEPH | SEFLG_SPEED);
169
+ console.log(`Sun (SWIEPH): ${sun.xx[0].toFixed(6)}°`);
170
+ ```
171
+
172
+ **Browser (fetch):**
173
+ ```typescript
174
+ const response = await fetch('/ephe/sepl_18.se1');
175
+ const buffer = await response.arrayBuffer();
176
+ sweSetEphemerisFile('sepl_18.se1', buffer, swed);
177
+ ```
178
+
179
+ **React Native (expo-file-system, react-native-fs, etc.):**
180
+ ```typescript
181
+ // Read the file into an ArrayBuffer using your preferred file library,
182
+ // then pass it to sweSetEphemerisFile() the same way.
183
+ ```
184
+
185
+ ### Loading JPL files
186
+
187
+ For the highest precision using NASA JPL ephemerides:
188
+
189
+ ```typescript
190
+ import { sweLoadJplFile, sweCalc } from '@typescriptify/sweph/sweph';
191
+ import { SEFLG_JPLEPH, SEFLG_SPEED, SE_MARS } from '@typescriptify/sweph/constants';
192
+
193
+ // Download a JPL DE file (e.g., de441.eph) from:
194
+ // https://ssd.jpl.nasa.gov/ftp/eph/planets/Linux/
195
+ const jplBuffer = readFileSync('./ephe/de441.eph');
196
+
197
+ const result = sweLoadJplFile(swed, jplBuffer.buffer, 'de441.eph');
198
+ if (result.retc < 0) {
199
+ console.error('Failed to load JPL file:', result.serr);
200
+ }
201
+
202
+ // Now use SEFLG_JPLEPH
203
+ const mars = sweCalc(swed, 2451545.0, SE_MARS, SEFLG_JPLEPH | SEFLG_SPEED);
204
+ ```
205
+
206
+ ## More Examples
207
+
208
+ ### Sidereal zodiac (ayanamsa)
209
+
210
+ ```typescript
211
+ import { sweSetSidMode, sweGetAyanamsa } from '@typescriptify/sweph/sweph';
212
+ import { SE_SIDM_LAHIRI } from '@typescriptify/sweph/constants';
213
+
214
+ sweSetSidMode(swed, SE_SIDM_LAHIRI, 0, 0);
215
+ const ayanamsa = sweGetAyanamsa(swed, jd);
216
+ console.log(`Lahiri ayanamsa: ${ayanamsa.toFixed(4)}°`);
217
+
218
+ // To get sidereal positions, add SEFLG_SIDEREAL to your flags:
219
+ import { SEFLG_SIDEREAL } from '@typescriptify/sweph/constants';
220
+ const sunSid = sweCalc(swed, jd, SE_SUN, SEFLG_MOSEPH | SEFLG_SIDEREAL);
221
+ console.log(`Sun (sidereal): ${sunSid.xx[0].toFixed(4)}°`);
222
+ ```
223
+
224
+ ### Fixed stars
225
+
226
+ ```typescript
227
+ import { sweFixstar } from '@typescriptify/sweph/sweph';
228
+
229
+ const spica = sweFixstar(swed, 'Spica', jd, SEFLG_MOSEPH);
230
+ console.log(`Spica: ${spica.xx[0].toFixed(4)}°`);
231
+ ```
232
+
233
+ ### Sunrise and sunset
234
+
235
+ ```typescript
236
+ import { sweRiseTrans } from '@typescriptify/sweph/swecl';
237
+ import { SE_CALC_RISE, SE_CALC_SET } from '@typescriptify/sweph/constants';
238
+ import { revJul } from '@typescriptify/sweph/swedate';
239
+
240
+ const geopos = [-0.1276, 51.5074, 0]; // [longitude, latitude, altitude_meters]
241
+
242
+ const rise = sweRiseTrans(
243
+ swed, jd, SE_SUN, null, SEFLG_MOSEPH,
244
+ SE_CALC_RISE, geopos, 1013.25, 10, null
245
+ );
246
+
247
+ if (rise.retval >= 0) {
248
+ const d = revJul(rise.tret, SE_GREG_CAL);
249
+ console.log(`Sunrise: ${d.year}-${d.month}-${d.day} ${d.hour.toFixed(2)} UT`);
250
+ }
251
+ ```
252
+
253
+ ### Solar eclipse search
254
+
255
+ ```typescript
256
+ import { sweSolEclipseWhenGlob, sweSolEclipseWhere } from '@typescriptify/sweph/swecl';
257
+
258
+ // Find the next solar eclipse after January 1, 2025
259
+ const startJd = julDay(2025, 1, 1, 0, SE_GREG_CAL);
260
+ const ecl = sweSolEclipseWhenGlob(swed, startJd, SEFLG_MOSEPH, 0, 0);
261
+
262
+ if (ecl.retval > 0) {
263
+ const d = revJul(ecl.tret[0], SE_GREG_CAL);
264
+ console.log(`Eclipse maximum: ${d.year}-${d.month}-${d.day} ${d.hour.toFixed(2)} UT`);
265
+
266
+ const where = sweSolEclipseWhere(swed, ecl.tret[0], SEFLG_MOSEPH);
267
+ console.log(`Central path: lon=${where.geopos[0].toFixed(1)}° lat=${where.geopos[1].toFixed(1)}°`);
268
+ }
269
+ ```
270
+
271
+ ### Azimuth and altitude
272
+
273
+ ```typescript
274
+ import { sweAzalt } from '@typescriptify/sweph/swecl';
275
+ import { SE_ECL2HOR } from '@typescriptify/sweph/constants';
276
+
277
+ const xaz = [0, 0, 0]; // [azimuth, trueAltitude, apparentAltitude]
278
+ sweAzalt(
279
+ swed, jd, SE_ECL2HOR,
280
+ [-0.1276, 51.5074, 0], // geopos
281
+ 1013.25, 10, // pressure (mbar), temperature (C)
282
+ [sun.xx[0], sun.xx[1], sun.xx[2]], // ecliptic lon, lat, distance
283
+ xaz
284
+ );
285
+ console.log(`Sun azimuth: ${xaz[0].toFixed(2)}°, altitude: ${xaz[2].toFixed(2)}°`);
286
+ ```
287
+
288
+ ### Orbital elements
289
+
290
+ ```typescript
291
+ import { sweGetOrbitalElements } from '@typescriptify/sweph/swecl';
292
+
293
+ const orb = sweGetOrbitalElements(swed, jd, SE_MARS, SEFLG_MOSEPH);
294
+ console.log(`Mars semi-major axis: ${orb.dret[0].toFixed(4)} AU`);
295
+ console.log(`Mars eccentricity: ${orb.dret[1].toFixed(4)}`);
296
+ console.log(`Mars inclination: ${orb.dret[2].toFixed(2)}°`);
297
+ ```
298
+
299
+ ### Planetary nodes and apsides
300
+
301
+ ```typescript
302
+ import { sweNodAps } from '@typescriptify/sweph/swecl';
303
+
304
+ const nod = sweNodAps(swed, jd, SE_MARS, SEFLG_MOSEPH, 0);
305
+ console.log(`Mars ascending node: ${nod.xnasc[0].toFixed(4)}°`);
306
+ console.log(`Mars descending node: ${nod.xndsc[0].toFixed(4)}°`);
307
+ console.log(`Mars perihelion: ${nod.xperi[0].toFixed(4)}°`);
308
+ console.log(`Mars aphelion: ${nod.xaphe[0].toFixed(4)}°`);
309
+ ```
310
+
311
+ ### Heliacal rising
312
+
313
+ ```typescript
314
+ import { sweHeliacalUt } from '@typescriptify/sweph/swehel';
315
+
316
+ const hel = sweHeliacalUt(
317
+ swed, jd,
318
+ [-0.1276, 51.5074, 0], // geopos
319
+ [1013.25, 10, 50, 0.25, 0, 0], // atmospheric conditions
320
+ [0, 0, 0, 0, 0, 0], // observer conditions
321
+ 'Venus', 1, SEFLG_MOSEPH
322
+ );
323
+ if (hel.retval >= 0) {
324
+ const d = revJul(hel.dret[0], SE_GREG_CAL);
325
+ console.log(`Venus heliacal rising: ${d.year}-${d.month}-${d.day}`);
326
+ }
327
+ ```
328
+
329
+ ### Topocentric positions
330
+
331
+ ```typescript
332
+ import { sweSetTopo } from '@typescriptify/sweph/sweph';
333
+ import { SEFLG_TOPOCTR } from '@typescriptify/sweph/constants';
334
+
335
+ // Set observer location: London
336
+ sweSetTopo(swed, -0.1276, 51.5074, 0);
337
+
338
+ const moonTopo = sweCalc(swed, jd, SE_MOON, SEFLG_MOSEPH | SEFLG_TOPOCTR | SEFLG_SPEED);
339
+ console.log(`Moon (topocentric): ${moonTopo.xx[0].toFixed(4)}°`);
340
+ ```
341
+
342
+ ### Cleanup
343
+
344
+ When you're done, free resources:
345
+
346
+ ```typescript
347
+ import { sweClose } from '@typescriptify/sweph/sweph';
348
+ sweClose(swed);
349
+ ```
350
+
351
+ ## House Systems
352
+
353
+ | Code | Name |
354
+ |---|---|
355
+ | `P` | Placidus |
356
+ | `K` | Koch |
357
+ | `O` | Porphyrius |
358
+ | `R` | Regiomontanus |
359
+ | `C` | Campanus |
360
+ | `E` | Equal (from Ascendant) |
361
+ | `W` | Whole Sign |
362
+ | `B` | Alcabitius |
363
+ | `M` | Morinus |
364
+ | `X` | Axial Rotation (Meridian) |
365
+ | `H` | Azimuthal (Horizontal) |
366
+ | `T` | Polich/Page (Topocentric) |
367
+ | `G` | Gauquelin sectors (36 cusps) |
368
+ | `A` | Equal (from Aries 0) |
369
+ | `D` | Equal (MC) |
370
+ | `F` | Carter (Poli-Equatorial) |
371
+ | `I` | Sunshine / Makransky |
372
+ | `J` | Sunshine / Treindl |
373
+ | `L` | Pullen SD (sinusoidal delta) |
374
+ | `N` | Pullen SR (sinusoidal ratio) |
375
+ | `Q` | Pullen cumulative |
376
+ | `S` | Sripati |
377
+ | `U` | Krusinski-Pisa-Goelzer |
378
+ | `V` | Vehlow Equal |
379
+ | `Y` | APC houses |
380
+
381
+ ## Planet Constants
382
+
383
+ | Constant | Planet |
384
+ |---|---|
385
+ | `SE_SUN` | Sun |
386
+ | `SE_MOON` | Moon |
387
+ | `SE_MERCURY` | Mercury |
388
+ | `SE_VENUS` | Venus |
389
+ | `SE_MARS` | Mars |
390
+ | `SE_JUPITER` | Jupiter |
391
+ | `SE_SATURN` | Saturn |
392
+ | `SE_URANUS` | Uranus |
393
+ | `SE_NEPTUNE` | Neptune |
394
+ | `SE_PLUTO` | Pluto |
395
+ | `SE_MEAN_NODE` | Mean Lunar Node |
396
+ | `SE_TRUE_NODE` | True Lunar Node |
397
+ | `SE_MEAN_APOG` | Mean Lunar Apogee (Black Moon Lilith) |
398
+ | `SE_OSCU_APOG` | Osculating Lunar Apogee |
399
+ | `SE_CHIRON` | Chiron |
400
+ | `SE_EARTH` | Earth |
401
+
402
+ ## About This Project
403
+
404
+ This is a line-by-line TypeScript translation of the [Swiss Ephemeris C library](https://www.astro.com/swisseph/) (~30,000 lines of C translated to ~15 TypeScript source files). All 9 C source files have been translated, covering all 106 public API functions.
405
+
406
+ Key design decisions:
407
+ - **No global state** — all functions take an explicit `swed: SweData` parameter
408
+ - **No filesystem access** — ephemeris files are loaded as `ArrayBuffer`s, making the library work in any JavaScript environment (Node.js, browsers, React Native, etc.)
409
+ - **No native dependencies** — pure TypeScript, no WASM, no C bindings
410
+
411
+ This is a TypeScript translation based on the Node.js wrapper [sweph](https://github.com/timotejroiko/sweph) by Timotej Valentin Rojko. The underlying Swiss Ephemeris is by Astrodienst AG.
412
+
413
+ ## License
414
+
415
+ This project is a TypeScript translation and is bound by the license of the original Swiss Ephemeris:
416
+
417
+ - **AGPL-3.0** for open-source use
418
+ - **LGPL-3.0** for holders of a professional Swiss Ephemeris license from [Astrodienst AG](https://www.astro.com/swisseph/)
419
+
420
+ See the original repository for full license details: https://github.com/timotejroiko/sweph
421
+
422
+ The Swiss Ephemeris itself is Copyright (C) 1997-2021 Astrodienst AG, Switzerland.
Binary file
Binary file
@@ -0,0 +1,124 @@
1
+ {
2
+ "extends": "eslint:recommended",
3
+ "parserOptions": {
4
+ "ecmaVersion": 2020,
5
+ "sourceType": "script"
6
+ },
7
+ "overrides": [
8
+ {
9
+ "files": [ "*.mjs" ],
10
+ "parserOptions": {
11
+ "sourceType": "module"
12
+ }
13
+ }
14
+ ],
15
+ "env": {
16
+ "node": true,
17
+ "es2020": true
18
+ },
19
+ "rules": {
20
+ "no-extra-parens":["error", "all", { "enforceForArrowConditionals": false, "conditionalAssign": false }],
21
+ "no-loss-of-precision": "error",
22
+ "no-promise-executor-return": "error",
23
+ "no-template-curly-in-string": "error",
24
+ "template-curly-spacing": "error",
25
+ "no-unreachable-loop": "error",
26
+ "no-useless-backreference": "error",
27
+ "require-atomic-updates": "error",
28
+ "accessor-pairs": "warn",
29
+ "array-callback-return": "error",
30
+ "block-scoped-var":"error",
31
+ "curly":"error",
32
+ "dot-notation": "error",
33
+ "eqeqeq":"error",
34
+ "grouped-accessor-pairs":"error",
35
+ "guard-for-in":"error",
36
+ "no-alert":"error",
37
+ "no-caller":"error",
38
+ "no-constructor-return":"error",
39
+ "no-div-regex":"error",
40
+ "no-else-return":"error",
41
+ "no-eq-null":"error",
42
+ "no-extend-native":"error",
43
+ "no-extra-bind":"error",
44
+ "no-extra-label":"error",
45
+ "no-floating-decimal":"error",
46
+ "no-implicit-coercion":"error",
47
+ "no-implicit-globals":"error",
48
+ "no-implied-eval":"error",
49
+ "no-invalid-this":"error",
50
+ "no-iterator":"error",
51
+ "no-labels":"error",
52
+ "no-lone-blocks":"error",
53
+ "no-loop-func":"error",
54
+ "no-multi-spaces":"error",
55
+ "no-multi-str":"error",
56
+ "no-new":"error",
57
+ "no-new-func":"error",
58
+ "no-new-wrappers":"error",
59
+ "no-octal-escape":"error",
60
+ "no-param-reassign":"error",
61
+ "no-proto":"error",
62
+ "no-return-assign":"error",
63
+ "no-return-await":"error",
64
+ "no-script-url":"error",
65
+ "no-self-compare":"error",
66
+ "no-throw-literal":"error",
67
+ "no-undefined": "error",
68
+ "no-unmodified-loop-condition":"error",
69
+ "no-unused-expressions":"error",
70
+ "no-useless-call":"error",
71
+ "no-useless-concat":"error",
72
+ "no-useless-return":"error",
73
+ "prefer-const":"error",
74
+ "prefer-named-capture-group":"error",
75
+ "prefer-promise-reject-errors":"error",
76
+ "prefer-regex-literals":"error",
77
+ "require-await":"error",
78
+ "wrap-iife":"error",
79
+ "yoda":"error",
80
+ "semi":"error",
81
+ "strict":"error",
82
+ "no-shadow":"error",
83
+ "comma-dangle":"error",
84
+ "comma-spacing":"error",
85
+ "eol-last":"error",
86
+ "indent": ["error", "tab", { "SwitchCase": 1 }],
87
+ "new-cap":"error",
88
+ "new-parens":"error",
89
+ "no-array-constructor":"error",
90
+ "no-lonely-if":"error",
91
+ "no-mixed-operators":"error",
92
+ "no-mixed-spaces-and-tabs":"error",
93
+ "no-new-object":"error",
94
+ "no-trailing-spaces":"error",
95
+ "no-unneeded-ternary":"error",
96
+ "no-whitespace-before-property":"error",
97
+ "object-curly-newline":["error", { "multiline": true }],
98
+ "object-curly-spacing": ["error", "always"],
99
+ "object-property-newline":"error",
100
+ "key-spacing": ["error"],
101
+ "computed-property-spacing": ["error", "never"],
102
+ "operator-assignment":"error",
103
+ "prefer-exponentiation-operator":"error",
104
+ "prefer-object-spread":"error",
105
+ "quotes": ["error", "double"],
106
+ "space-before-blocks":"error",
107
+ "space-infix-ops":"error",
108
+ "space-unary-ops":"error",
109
+ "spaced-comment":"error",
110
+ "switch-colon-spacing":"error",
111
+ "wrap-regex":"error",
112
+ "arrow-spacing":"error",
113
+ "no-confusing-arrow":"error",
114
+ "no-useless-computed-key":"error",
115
+ "no-useless-constructor":"error",
116
+ "no-var":"error",
117
+ "prefer-arrow-callback":"error",
118
+ //"prefer-destructuring":"error",
119
+ "prefer-numeric-literals":"error",
120
+ "prefer-spread":"error",
121
+ "prefer-template":"error",
122
+ "symbol-description":"error"
123
+ }
124
+ }
@@ -0,0 +1,2 @@
1
+ # Auto detect text files and perform LF normalization
2
+ * text=auto
@@ -0,0 +1,5 @@
1
+ # These are supported funding model platforms
2
+
3
+ github: timotejroiko
4
+ patreon: timotejroiko
5
+ custom: https://paypal.me/timotejroiko
@@ -0,0 +1,35 @@
1
+ name: test
2
+
3
+ on:
4
+ workflow_dispatch:
5
+
6
+ defaults:
7
+ run:
8
+ shell: bash
9
+
10
+ jobs:
11
+ test:
12
+ name: Test sweph on ${{ matrix.os }}
13
+ strategy:
14
+ matrix:
15
+ os: [ubuntu-latest, macos-latest, windows-latest]
16
+ runs-on: ${{ matrix.os }}
17
+ steps:
18
+ - name: Checkout Repository
19
+ uses: actions/checkout@v3
20
+
21
+ - name: Setup Node ${{ matrix.node-version }}
22
+ uses: actions/setup-node@v3
23
+ with:
24
+ node-version: lts/*
25
+
26
+ - name: Setup Python
27
+ uses: actions/setup-python@v4
28
+ with:
29
+ python-version: 3.x
30
+
31
+ - name: Setup Msbuild
32
+ if: ${{ matrix.os == 'windows-latest' }}
33
+ uses: microsoft/setup-msbuild@v1.1
34
+
35
+ - run: npm install