Skip to main content

Contributing

This repo follows Gitflow Workflow. Before starting a work on new pull request, please, checkout your feature or bugfix branch from develop branch:

git checkout develop
git checkout -b my-feature

Make sure that your changes don't break the existing code by running

npm test

If you have made changes to SGP4 algorithm, also check the full catalog run:

npm run test:catalog

In order to get test code coverage run the following:

npm run test:coverage

Make sure that your code follows Airbnb style

npm run lint

When implementing new functions or features, provide tests to cover them and mention your works in Changelog.

When releasing, update package.json with a new version, update Changelog with that version, and merge to master.

Prerequisites

Building

The source code is written in TypeScript and uses a strict tsconfig.

In order to build the library follow these steps:

  • install Node.js and Node Package Manager;

  • install Emscripten using Emscripten SDK;

  • install all required packages with NPM by running the following command from repository's root directory:

    npm install
  • run the following NPM script to build everything:

    npm run build

    This removes previous dist and wasm-build directories, compiles the C++ code to WASM (release builds), and then compiles the TypeScript source with tsc.

  • run the following NPM script to run tests with Vitest:

    npm test

These is a full list of all available NPM scripts:

ScriptDescription
buildBuilds everything (WASM release + TypeScript)
copyCopies built library from dist to the SGP4 verification application's directory
lintLints source code in src with ESLint
testRuns main test projects: js, wasm_release, wasm_debug
test:catalogRuns the full SGP4 satellite catalog verification test
test:watchRuns tests in watch mode
test:coverageRuns tests with V8 coverage summary
wasm:buildBuilds all four WASM compilations (base + pthreads, debug + release)
wasm:build:releaseBuilds only the two release WASM compilations
wasm:testRuns only WASM test projects (wasm_release and wasm_debug)
wasm:benchRuns WASM benchmarks

Project Structure

satellite-js/
├── src/ TypeScript source code of the library
│ ├── propagation/ SGP4/SDP4 propagation model
│ └── wasm/ WASM bulk propagation layer
├── src-cpp/ C++ source compiled to WASM via Emscripten
├── test/ Vitest tests
│ ├── propagation/ SGP4 catalog verification tests
│ └── wasm/ WASM bulk propagator tests
├── dist/ Compiled JS output (generated)
├── wasm-build/ Compiled WASM modules (generated)
│ ├── base-debug/
│ ├── base-release/
│ ├── pthreads-debug/
│ └── pthreads-release/
└── docs/ Docusaurus documentation site

TypeScript Source (src/)

The library exposes its public API from src/index.ts. The main modules are:

ModulePurpose
io.tsParsing TLE (twoline2satrec) and OMM JSON (json2satrec) into SatRec
propagation.tsRe-exports propagate, sgp4, gstime from propagation/
propagation/sgp4.tsCore SGP4 propagation algorithm
propagation/sgp4init.tsInitializes SatRec with orbital elements
propagation/SatRec.tsSatRec interface and SatRecError enum
transforms.tsCoordinate conversions (ECI ↔ ECF ↔ geodetic ↔ look angles)
dopplerFactor.tsDoppler factor calculation
sun.tsSun position from Julian date
shadow.tsEarth shadow (umbra/penumbra) fraction
ext.tsJulian date helpers (jday, invjday)
constants.tsPhysical and mathematical constants
common-types.tsShared type aliases (Kilometer, Radians, EciVec3, etc.)

WASM Source (src-cpp/ and src/wasm/)

The WASM layer provides a high-performance bulk propagation API that runs SGP4 in compiled C++. It consists of:

  • src-cpp/ - C++ source files compiled to WASM via Emscripten. See src-cpp/README.md for details.
  • src/wasm/ - TypeScript orchestration layer that wraps the WASM modules.
    • bulk-propagator.ts - Main BulkPropagator class for propagating many satellites at many dates at once.
    • calculators/ - Pluggable calculator classes (ECI, ECF, geodetic, look angles, doppler, sun, shadow).
    • runtimes/ - Single-thread and multi-thread WASM runtimes.

The WASM code is compiled into four variants:

VariantFiles compiledUse
base-debugcommon.cpp + base.cpp + debug.cppDebug tests, with AddressSanitizer and LeakSanitizer
base-releasecommon.cpp + base.cppProduction single-thread
pthreads-debugcommon.cpp + pthreads.cpp + debug.cppDebug tests, multi-threaded
pthreads-releasecommon.cpp + pthreads.cppProduction multi-thread

debug.cpp is only included in debug builds; it exports additional functions needed by tests but not by users.

TypeScript Conventions

The project uses the strictest TypeScript configuration. It uses strict: true with many additional strict flags enabled (exactOptionalPropertyTypes, noUncheckedIndexedAccess etc.)

Type System

The library uses type aliases to document units - for example Kilometer, Radians, KilometerPerSecond, AU, EarthRadii. These are number at runtime but communicate intent:

export type Kilometer = number;
export type Radians = number;

Coordinate frames use generic interfaces:

export interface EciVec3<T> { x: T; y: T; z: T; }
export interface EcfVec3<T> { x: T; y: T; z: T; }

Linting

ESLint is configured with eslint-config-airbnb-extended (the Airbnb style guide). There are some project-specific overrides:

  • no-param-reassign: Allowed for satrec properties, because sgp4 and sgp4init extensively mutate the satellite record.
  • no-underscore-dangle: Turned off, since Emscripten exports C++ functions with leading underscores (e.g. _malloc, _free).
  • import/no-default-export: Default exports are not allowed. Use named exports, which autocomplete and refactor more easily.
  • no-restricted-syntax: for...of loops are allowed (unlike vanilla Airbnb) as they are used for performance.
  • no-plusplus: ++ is allowed in for-loop afterthoughts.

Linting ignores wasm-build/, docs/, and config files.

Testing

Tests use Vitest and are organized into several test projects (see vitest.config.ts):

ProjectIncludesDescription
jstest/*.test.tsCore JS/TS unit tests
wasm_releasetest/wasm/**/*.user.test.tsWASM tests against release builds
wasm_debugtest/wasm/**/*.user.test.ts, *.struct.test.ts, *.leaks.test.tsWASM tests against debug builds (includes struct and leak tests)
catalogtest/propagation/sgp4Catalog.test.tsFull satellite catalog verification (run separately via npm run test:catalog)

Running npm test runs the js, wasm_release, and wasm_debug projects.

Writing Tests

  • Place test files in test/ for TS tests or test/wasm/ for WASM tests.
  • Name test files with .test.ts extension.
  • Test data lives alongside tests as JSON files (e.g. io.json, io-edge.json, transforms.json).

IDE Setup (VS Code)

The repository includes VS Code configuration in .vscode/:

  • extensions.json - Recommends ms-vscode.wasm-dwarf-debugging (for stepping into C++ in WASM) and ms-vscode.cpptools.
  • launch.json - A tsx launch configuration for running/debugging individual TypeScript files.
  • settings.example.json and c_cpp_properties.example.json - Templates for C++ IntelliSense with Emscripten. Copy and rename them (remove .example), then replace path_to_emsdk with your Emscripten SDK path.

Working on WASM Code

If your contribution involves the WASM layer:

  1. Install Emscripten SDK - follow https://github.com/emscripten-core/emsdk. Confirm with em++ -v.
  2. Set up VS Code C++ IntelliSense - copy the example settings as described in IDE Setup above.
  3. Learn more about the state of WASM build: refer to src-cpp/README.md and keep it updated.
  4. Build WASM - npm run wasm:build compiles all four variants. For faster iteration during development, build only what you need:
    • npm run wasm:base:build:debug - single-thread debug
    • npm run wasm:base:build:release - single-thread release
    • npm run wasm:pthreads:build:debug - multi-thread debug
    • npm run wasm:pthreads:build:release - multi-thread release
  5. Test WASM - npm run wasm:test runs only the WASM test projects.
  6. Benchmark - npm run wasm:bench runs WASM benchmarks.

Debug builds enable AddressSanitizer and LeakSanitizer to catch memory bugs.

Pull Request Checklist

Before submitting a pull request, make sure:

  • Branch is based on develop (not master)
  • npm run lint passes with no errors
  • npm test passes (all three test projects)
    • If you have made changes to sgp4 algorithm, npm test:catalog also passes
  • New features or bug fixes include corresponding tests
  • Changes are mentioned in CHANGELOG.md