Skip to content

astro-fusion/af-sweph

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

91 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

@af/sweph

The ultimate Swiss Ephemeris library for Vedic Astrology, supporting Node.js, Browser (WASM), and React Native with a unified API.

CI Build

🌟 Features

  • βœ… Auto-initialization - Native module loads automatically
  • βœ… TypeScript First - Complete type safety with IntelliSense
  • βœ… Vedic Astrology - Ayanamsa, Rashis, Nakshatras built-in
  • βœ… Multi-Platform - Node.js, Browser (WASM), React Native
  • βœ… Vercel Ready - Pre-built binaries for serverless 15: 16: ## ⚠️ Vercel / Serverless Considerations 17: 18: Deploying native modules to Serverless environments involves specific challenges: 19: 20: 1. Core Problem: Compatibility between build environment (CI) and runtime environment (Lambda/Vercel). 21: 2. Common "Sloppy Code" Pitfalls: 22: * Relying on __dirname which changes in bundled environments. 23: * Assuming npm install binaries persist (they don't). 24: * Ignoring local "Module not found" errors. 25: 26: > [!IMPORTANT] 27: > For a comprehensive guide on fixing deployment crashes, bundle size limits, and proper configuration, please read our Next.js & Vercel Deployment Guide.

πŸš€ Quick Start

Installation

# npm
npm install @af/sweph

# pnpm
pnpm add @af/sweph

# Or from GitHub
pnpm add github:astro-fusion/af-sweph

Usage

import { createSweph, AYANAMSA } from '@af/sweph';

async function main() {
  // Create instance (auto-initializes native module)
  const sweph = await createSweph();

  // Define calculation date once for consistency
  const calculationDate = new Date();

  // Calculate planetary positions
  const planets = await sweph.calculatePlanets(calculationDate, {
    ayanamsa: AYANAMSA.LAHIRI,
    timezone: 5.75, // Nepal
  });

  console.log('Sun:', planets.find(p => p.id === 'sun'));
  console.log('Moon:', planets.find(p => p.id === 'moon'));

  // Calculate Lagna (Ascendant)
  const lagna = await sweph.calculateLagna(
    calculationDate,
    { latitude: 27.7, longitude: 85.3, timezone: 5.75 },
    { ayanamsa: AYANAMSA.LAHIRI }
  );

  console.log('Ascendant:', lagna.longitude, 'in', sweph.RASHIS[lagna.rasi]);

  // Calculate Moon Phase
  const moonPhase = await sweph.calculateMoonPhase(calculationDate);
  console.log('Moon Phase:', moonPhase.phaseName, `(${Math.round(moonPhase.illumination * 100)}%)`);
}

main();

πŸ“¦ API Reference

createSweph(options?): Promise<SwephInstance>

Creates an auto-initialized Swiss Ephemeris instance.

const sweph = await createSweph({
  ephePath: '/path/to/ephemeris', // Optional: custom ephemeris path
  preWarm: true, // Optional: pre-calculate to warm cache
});

SwephInstance Methods

Planetary Calculations

// All 9 Vedic planets
const planets = await sweph.calculatePlanets(date, {
  ayanamsa: AYANAMSA.LAHIRI, // Lahiri
  timezone: 0, // UTC
});

// Single planet (0=Sun, 1=Moon, 2=Mars, etc.)
const sun = await sweph.calculatePlanet(0, date, { ayanamsa: AYANAMSA.LAHIRI });

// Rise, Set, Transit times
const riseSet = await sweph.calculateRiseSet(0, date, {
  latitude: 27.7,
  longitude: 85.3,
});

Lagna & Houses

const lagna = await sweph.calculateLagna(
  date,
  { latitude: 27.7, longitude: 85.3 },
  { ayanamsa: AYANAMSA.LAHIRI }
);

console.log(lagna.longitude); // Ascendant in degrees
console.log(lagna.rasi); // Ascendant sign (1-12)
console.log(lagna.houses); // Array of 12 house cusps

Sun Calculations

const date = new Date();
const location = { latitude: 27.7, longitude: 85.3 };

// Sunrise, Sunset, Solar Noon
const sunTimes = await sweph.calculateSunTimes(date, location);

// Solar Noon with altitude
const noon = await sweph.calculateSolarNoon(date, location);

// Sun path throughout the day
const path = await sweph.calculateSunPath(date, location);

Moon Calculations

const date = new Date();
const location = { latitude: 27.7, longitude: 85.3 };

// Moon data (position, rise/set, phase)
const moonData = await sweph.calculateMoonData(date, location);

// Current moon phase
const phase = await sweph.calculateMoonPhase(date);
console.log(phase.phaseName); // "Waxing Crescent", "Full Moon", etc.
console.log(phase.illumination); // 0.0 to 1.0

// Next moon phases
const nextPhases = await sweph.calculateNextMoonPhases(date);
console.log('Next New Moon:', nextPhases.newMoon);
console.log('Next Full Moon:', nextPhases.fullMoon);

Utilities

// Get ayanamsa value
const ayanamsa = sweph.getAyanamsa(date, AYANAMSA.LAHIRI);

// Convert to Julian Day
const jd = sweph.dateToJulian(date);

// Set ephemeris path
sweph.setEphePath('/custom/path/to/ephe');

Constants

import { PLANETS, AYANAMSA, RASHIS, NAKSHATRAS } from '@af/sweph';

// Planet IDs
PLANETS.SUN;     // 0
PLANETS.MOON;    // 1
PLANETS.MARS;    // 4
PLANETS.MERCURY; // 2
PLANETS.JUPITER; // 5
PLANETS.VENUS;   // 3
PLANETS.SATURN;  // 6
PLANETS.RAHU;    // 10
PLANETS.KETU;    // 11

// Ayanamsa types
AYANAMSA.LAHIRI;       // 1 (default)
AYANAMSA.KRISHNAMURTI; // 5
AYANAMSA.RAMAN;        // 3

// Rashi names
RASHIS[1];  // "Aries"
RASHIS[4];  // "Cancer"
RASHIS[10]; // "Capricorn"

// Nakshatra names
NAKSHATRAS[1];  // "Ashwini"
NAKSHATRAS[14]; // "Chitra"
NAKSHATRAS[27]; // "Revati"

πŸ—οΈ Multi-Platform Architecture

Package Environment Technology
@af/sweph-node Node.js Native C++ bindings
@af/sweph-wasm Browser WebAssembly
@af/sweph-react-native Mobile JSI/Turbo Modules
@af/sweph-core All Shared TypeScript

πŸš€ Serverless Deployment

Vercel Deployment

@af/sweph is optimized for Vercel serverless functions. Here's the recommended setup:

1. Environment Variables

# In Vercel dashboard or vercel.json
NODE_VERSION=20
SWEPH_DISABLE_CACHE=false  # Enable caching for better performance

2. Function Configuration

// api/planets.ts
import { createSweph } from '@af/sweph';

export default async function handler(req, res) {
  // Create optimized instance for serverless
  const sweph = await createSweph({
    serverlessMode: true,
    enableCaching: true
  });

  const planets = await sweph.calculatePlanets(new Date());
  res.status(200).json(planets);
}

Important

Serverless Cold Starts: In local development, the process stays alive. In Serverless (Vercel/Lambda), every request might be a new process. The createSweph() function above automatically awaits initialization. However, if you use legacy functions or internal helpers, you MUST call await initializeSweph() before any calculations.

3. Bundle Size Optimization

// next.config.js
module.exports = {
  experimental: {
    serverComponentsExternalPackages: ['@af/sweph']
  },
  webpack: (config) => {
    // Exclude native binaries from bundling
    config.externals.push({
      '@af/sweph': '@af/sweph'
    });
    return config;
  }
};

AWS Lambda Deployment

For AWS Lambda, use the Node.js runtime with the provided prebuilds:

// lambda/index.js
const { createSweph } = require('@af/sweph');

let swephInstance = null;

exports.handler = async (event) => {
  // Reuse instance across warm invocations
  if (!swephInstance) {
    swephInstance = await createSweph({
      serverlessMode: true,
      enableCaching: true
    });
  }

  const result = await swephInstance.calculatePlanets(new Date());
  return {
    statusCode: 200,
    body: JSON.stringify(result)
  };
};

Netlify Functions

// netlify/functions/planets.ts
import { createSweph } from '@af/sweph';

export async function handler(event) {
  const sweph = await createSweph({
    serverlessMode: true,
    enableCaching: true
  });

  const planets = await sweph.calculatePlanets(new Date());
  return {
    statusCode: 200,
    body: JSON.stringify(planets)
  };
}

Serverless Performance Tips

Memory Management

// For memory-constrained environments
const sweph = await createSweph({
  serverlessMode: true,
  enableCaching: false  // Disable caching to save memory
});

Connection Pooling

import { withSwephInstance, createServerlessSweph } from '@af/sweph';

// Option 1: Automatic connection pooling
export default async function handler(req, res) {
  const result = await withSwephInstance(async (sweph) => {
    return await sweph.calculatePlanets(new Date());
  });
  res.json(result);
}

// Option 2: Dedicated serverless instance
let swephInstance = null;

export default async function handler(req, res) {
  if (!swephInstance) {
    swephInstance = await createServerlessSweph();
  }
  const result = await swephInstance.calculatePlanets(new Date());
  res.json(result);
}

Cold Start Optimization

// Pre-warm critical calculations
const sweph = await createSweph({
  preWarm: true,  // Slightly slower init, but faster first request
  serverlessMode: true
});

πŸ› Troubleshooting

Module not found on Vercel

Ensure pre-built binaries are installed:

ls node_modules/@af/sweph/packages/node/prebuilds/
# Should show: linux-x64/, darwin-arm64/, etc.

πŸ“š For detailed Next.js and Vercel configuration, see docs/NEXTJS_VERCEL.md

Native module errors

Set NODE_VERSION=20 in your environment.

Memory issues in serverless

Disable caching to reduce memory usage:

SWEPH_DISABLE_CACHE=true

Or in code:

const sweph = await createSweph({
  serverlessMode: true,
  enableCaching: false
});

Bundle size issues

Use dynamic imports for better tree shaking:

const { createSweph } = await import('@af/sweph');

Building Pre-built Binaries

For production deployments, you can build native binaries for multiple Node.js versions:

cd packages/node

# Build ALL versions (Node 18/20/22) for ALL platforms (requires Docker)
pnpm prebuild:all

# Build single platform
pnpm prebuild:linux          # Linux x64
pnpm prebuild:linux-arm64    # Linux ARM64 (Vercel/Lambda Graviton)

# Copy macOS binary from local build
pnpm copy:darwin-arm64       # macOS Apple Silicon
pnpm copy:darwin-x64         # macOS Intel

The prebuild:all script creates binaries for:

  • Node.js versions: 18, 20, 22
  • Platforms: linux-x64, linux-arm64, darwin-arm64, darwin-x64

πŸ’‘ Tip: Run the GitHub Actions workflow Build Prebuilds to automatically generate all binaries.

πŸ“ Project Structure & Templates

Quick setup templates are available in the templates/ directory:

  • vercel-api.ts - Vercel API routes (Pages Router & App Router)
  • aws-lambda.ts - AWS Lambda functions
  • netlify-function.ts - Netlify Functions
  • nextjs-component.tsx - Next.js client components

πŸ”§ Advanced Configuration

Environment Variables

# Disable caching in memory-constrained environments
SWEPH_DISABLE_CACHE=true

# Disable native module caching in serverless
SWEPH_CACHE_MODULE=false

# Set Node.js version for Vercel
NODE_VERSION=20

Custom Ephemeris Path

const sweph = await createSweph({
  ephePath: '/custom/path/to/ephemeris'
});

Platform-Specific Builds

The library includes pre-built binaries for:

  • linux-x64 (Vercel, AWS Lambda, most Linux servers)
  • linux-arm64 (AWS Lambda Graviton, ARM64 Linux)
  • darwin-arm64 (macOS M1/M2/M3)
  • darwin-x64 (macOS Intel)
  • win32-x64 (Windows x64)

🀝 Contributing

git clone https://github.com/astro-fusion/af-sweph
cd af-sweph
pnpm install
pnpm -r build
pnpm -r test

πŸ“„ License

MIT

❀️ Credits

About

Swiss Ephemeris library for Vedic astrology calculations with pre-built native binaries

Topics

Resources

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors