Internal module guide. This module is now part of
@astrology/astrology-core; use the public package README for application setup.
astrology-semantics module
@astrology/astrology-core is a separate deterministic workspace package because chart, transit,
panchang and other future modules need the same derivation rules without importing providers,
background workers or a facade. It depends on the shared contract for types/errors and the
shared logger for contextual aspect-profile diagnostics.
import { NormalizingAdapter } from '@astrology/ephemeris';
import { resolveSign, resolveNakshatra, resolveMotion, resolveHouse, resolveAspects, resolveDrishti }
from '@astrology/astrology-core';
// `adapter` is any EphemerisAdapter; the facade owns execution and response assembly.
const normalized = new NormalizingAdapter(adapter);
const positions = await normalized.positions(request);
const annotations = positions.data.positions.map(position => ({
body: position.body,
...resolveSign(position.longitude),
nakshatra: resolveNakshatra(position.longitude, positions.declaration.zodiac),
motion: resolveMotion(position.speedLongitude),
drishti: resolveDrishti(position.body, position.longitude),
}));
Functions accept canonical degree/AU values after normalization and neither round nor apply
an ayanamsa (the offset between the tropical and sidereal zodiacs). Invalid longitude, speed, cusp geometry or aspect profiles throw AdapterError
with INVALID_REQUEST. No provider I/O or localization is used. Aspect resolution emits debug
summaries and invalid aspect policies emit warn events; scalar lookups do not log.
-
resolveSign(longitude)returns a canonical sign id (one of twelve 30° slices of the zodiac) and degree within it. -
resolveNakshatra(longitude, zodiac)returns nakshatra (one of 27 lunar mansions of 13°20′) and pada (its quarter) for sidereal input andnullfor tropical input. All 108 pada boundaries are half-open; exact boundaries start the next pada. -
resolveMotion(speedLongitude)distinguishes unknown (null), stationary (zero), direct and retrograde (apparent backward motion along the zodiac). Tiny speeds keep their sign. Nodes follow the adapter’s selected mean/true model; the host retains the request’snodeTypealongside these annotations. -
resolveHouse(longitude, cusps)returns house 1–12 using twelve distinct cusps (the boundary longitudes where each house begins) ordered in one forward revolution. It handles wrap and unequal widths and uses the actual cusps for whole-sign houses too. Cusps must share the position’s instant, observer and zodiac; validating that context belongs to the caller. No house-system approximation is performed. -
resolveAspects(first, second, profile?)returns matching ids, separation, absolute orb (distance from the exact aspect angle) and instantaneous phase. Default major aspects have explicit 8/4/6/6/8 degree orbs for conjunction/sextile/square/trine/opposition. These are versioned application defaults, not a claim of universal astrological convention; a caller may replace the profile. -
resolveDrishti(body, longitude, profile?)returns the signs a body aspects under whole-sign graha drishti (the Vedic sign-based aspect a planet casts), ordered by inclusive count from its own sign (own sign 1, opposite 7). The defaultPARASHARI_DRISHTIgives every classical planet the seventh, plus Mars 4/8, Jupiter 5/9 and Saturn 3/10. Degree and orb play no part. A body without a rule, including Rahu, Ketu and the outer planets by default, returnsnullrather than an empty list; node rules vary by school, so a caller must supply them explicitly. Pair checks resolve the target’s sign and look it up. Rashi drishti is not included. -
resolveSphutaDrishti(caster, target, curve?)returns the degree-based (sphuta) drishti value in virupas (0–60) cast forward fromcastertotarget. The defaultSPHUTA_DRISHTI_CURVEis the common BPHS ch. 26 curve: 15 at 60°, 45 at 90°, 30 at 120°, 0 at 150°, 60 at 180°, falling linearly to 0 at 300°, and 0 below 30°. Mars, Jupiter and Saturn’s special-aspect additions differ between translations, so they are not built in; a caller can supply its own contiguous 0–360 curve. A gapped curve or an invalid longitude throwsINVALID_REQUEST.
Aspect bounds are inclusive. Relative longitude speed and the shortest arc determine applying or separating. Zero relative speed is stationary; missing speed is unknown; an exact aspect is exact even without speed. These are instantaneous phases, not predictions of a future aspect under accelerating or reversing motion.
SIGNS, NAKSHATRAS, MAJOR_ASPECTS, PARASHARI_DRISHTI and SPHUTA_DRISHTI_CURVE are frozen; identifiers are lowercase English keys.
Hosts caching annotations should namespace their chosen profile and SEMANTICS_VERSION.
Call only the functions a feature needs; the package adds no chart orchestration layer.
Source ownership follows those features: src/sign.ts, src/nakshatra.ts, src/motion.ts,
src/house.ts, src/aspect.ts and src/drishti.ts keep their resolver and related reference data/types together.
src/validation.ts owns the shared longitude guard, and src/version.ts owns the cache version.
src/index.ts only re-exports the public API; existing package imports remain unchanged.
From the workspace root: pnpm build:astrology-core, pnpm check:astrology-core, pnpm test:astrology-core.
Tests cover every pada boundary, sign/house intervals, wrap, invalid geometry, motion, aspects and drishti.
See the reference design.