Packages3 MIN READ70 / 116

Internal module guide. This module is now part of @astrology/ephemeris; use the public package README for application setup.

swiss-ephemeris-adapter module

The shared logger emits operation summaries at debug, explicit capability probe completion at info, and worker capacity/provider failures at warn. Events are emitted in the parent process and use the host’s reporters; requests, native messages and file paths are omitted.

@astrology/ephemeris is a reusable Node.js TypeScript workspace module implementing EphemerisAdapter from @astrology/astronomy-contracts. The internal provider module exports SwissAdapter and SwissAdapterOptions; canonical types, validation, and fluent requests are imported from the contract package. It has no server, routes, listening port, or automatic startup probe.

From the repository root (Node 22.12+ and pnpm 11):

pnpm install
pnpm setup:ephemeris
pnpm build:ephemeris
pnpm check:ephemeris
pnpm test:ephemeris

The setup command downloads and verifies two pinned official JPL DE441-derived files into this package’s ignored ephemeris/ directory. Importing or constructing the adapter does not start processes or read files. Each operation starts a bounded, disposable child process to isolate Swiss’s global native settings. It verifies installed files and returns a complete result or rejects with a shared AdapterError.

Consumer packages declare both workspace dependencies:

{
  "dependencies": {
    "@astrology/astronomy-contracts": "workspace:*",
    "@astrology/ephemeris/swiss": "workspace:*"
  }
}
import { PositionQuery, type EphemerisAdapter } from '@astrology/astronomy-contracts';
import { SwissAdapter } from './providers/swiss/index.js';

const adapter: EphemerisAdapter = new SwissAdapter();
const request = PositionQuery.at('2000-01-01T12:00:00Z', { zodiac: 'tropical' })
  .forBodies('sun', 'moon', 'rahu', 'ketu')
  .nodes('true')
  .withSpeed()
  .build();

const capabilities = await adapter.capabilities();
const positions = await adapter.positions(request);
const houses = await adapter.houses({
  instant: request.instant,
  zodiac: 'sidereal',
  ayanamsa: 'lahiri',
  observer: { latitude: 19.076, longitude: 72.8777 },
  system: 'placidus',
});

new SwissAdapter({ ephemerisDirectory, timeoutMs, maxConcurrency }) controls the file location and worker budget. Defaults are this package’s ephemeris/, 5000 ms including startup, and four concurrent operations per instance. There is no environment-based host or port configuration. Applications can explicitly call capabilities() during their own startup if desired. Hosts should reuse an instance to share its concurrency limit.

Installed coverage is conservative Terrestrial Time (TT) Julian Day (JD) 2378497.5–2597650.3591467496, approximately 1800–2400. Moshier fallback is refused. Missing/altered files, unpinned time-model override files, polar house failures, overload, timeout, and worker failures reject with stable codes. Precision is null because no per-request accuracy guarantee has been established. Native sidereal output must not have ayanamsa (the tropical-to-sidereal offset) subtracted again.

pnpm test:ephemeris runs independent contract tests plus real native integration and consumer-import tests. Swiss tests require the verified files and never silently skip. pnpm --filter @astrology/ephemeris reference:swiss-adapter compiles the official pinned C swetest source to reproduce numerical references; this optional command needs network access and a C compiler.

This package does not implement NASA, routing, caching, normalisation, astrology semantics, or a complete application. The existing Swiss licence decision remains a distribution/deployment requirement. See the implementation evidence.

Hindu solar events

riseSet(request) uses native swe_rise_trans with SE_BIT_HINDU_RISING, in the existing isolated worker. The request supplies observer, absolute start/end, zodiac context, definition: 'hindu' and optional includeSunset. Windows must be nonempty and at most 72 hours, with both endpoints in installed coverage. Native circumpolar status (a body that never rises or sets that day) becomes null. UT1 (Earth-rotation time) event roots are converted through swe_jdut1_to_utc and rounded once to UTC milliseconds.

Native tests cover Mumbai, London, polar Tromso, clipping and coverage edges. The reference command above also compiles reference-riseset.c against its pinned official C download, independently of the Node binding. Event tolerance is one second; agreement checks the integration/time conversion, not a separate astronomy model.