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
- Node.js (with npm)
- Emscripten SDK - only needed if working on WASM code. Verify by running
em++ -v.
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 buildThis removes previous
distandwasm-builddirectories, compiles the C++ code to WASM (release builds), and then compiles the TypeScript source withtsc. -
run the following NPM script to run tests with Vitest:
npm test
These is a full list of all available NPM scripts:
| Script | Description |
|---|---|
build | Builds everything (WASM release + TypeScript) |
copy | Copies built library from dist to the SGP4 verification application's directory |
lint | Lints source code in src with ESLint |
test | Runs main test projects: js, wasm_release, wasm_debug |
test:catalog | Runs the full SGP4 satellite catalog verification test |
test:watch | Runs tests in watch mode |
test:coverage | Runs tests with V8 coverage summary |
wasm:build | Builds all four WASM compilations (base + pthreads, debug + release) |
wasm:build:release | Builds only the two release WASM compilations |
wasm:test | Runs only WASM test projects (wasm_release and wasm_debug) |
wasm:bench | Runs 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:
| Module | Purpose |
|---|---|
io.ts | Parsing TLE (twoline2satrec) and OMM JSON (json2satrec) into SatRec |
propagation.ts | Re-exports propagate, sgp4, gstime from propagation/ |
propagation/sgp4.ts | Core SGP4 propagation algorithm |
propagation/sgp4init.ts | Initializes SatRec with orbital elements |
propagation/SatRec.ts | SatRec interface and SatRecError enum |
transforms.ts | Coordinate conversions (ECI ↔ ECF ↔ geodetic ↔ look angles) |
dopplerFactor.ts | Doppler factor calculation |
sun.ts | Sun position from Julian date |
shadow.ts | Earth shadow (umbra/penumbra) fraction |
ext.ts | Julian date helpers (jday, invjday) |
constants.ts | Physical and mathematical constants |
common-types.ts | Shared 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. Seesrc-cpp/README.mdfor details.src/wasm/- TypeScript orchestration layer that wraps the WASM modules.bulk-propagator.ts- MainBulkPropagatorclass 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:
| Variant | Files compiled | Use |
|---|---|---|
base-debug | common.cpp + base.cpp + debug.cpp | Debug tests, with AddressSanitizer and LeakSanitizer |
base-release | common.cpp + base.cpp | Production single-thread |
pthreads-debug | common.cpp + pthreads.cpp + debug.cpp | Debug tests, multi-threaded |
pthreads-release | common.cpp + pthreads.cpp | Production 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 forsatrecproperties, becausesgp4andsgp4initextensively 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...ofloops 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):
| Project | Includes | Description |
|---|---|---|
js | test/*.test.ts | Core JS/TS unit tests |
wasm_release | test/wasm/**/*.user.test.ts | WASM tests against release builds |
wasm_debug | test/wasm/**/*.user.test.ts, *.struct.test.ts, *.leaks.test.ts | WASM tests against debug builds (includes struct and leak tests) |
catalog | test/propagation/sgp4Catalog.test.ts | Full 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 ortest/wasm/for WASM tests. - Name test files with
.test.tsextension. - 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- Recommendsms-vscode.wasm-dwarf-debugging(for stepping into C++ in WASM) andms-vscode.cpptools.launch.json- Atsxlaunch configuration for running/debugging individual TypeScript files.settings.example.jsonandc_cpp_properties.example.json- Templates for C++ IntelliSense with Emscripten. Copy and rename them (remove.example), then replacepath_to_emsdkwith your Emscripten SDK path.
Working on WASM Code
If your contribution involves the WASM layer:
- Install Emscripten SDK - follow https://github.com/emscripten-core/emsdk. Confirm with
em++ -v. - Set up VS Code C++ IntelliSense - copy the example settings as described in IDE Setup above.
- Learn more about the state of WASM build: refer to
src-cpp/README.mdand keep it updated. - Build WASM -
npm run wasm:buildcompiles all four variants. For faster iteration during development, build only what you need:npm run wasm:base:build:debug- single-thread debugnpm run wasm:base:build:release- single-thread releasenpm run wasm:pthreads:build:debug- multi-thread debugnpm run wasm:pthreads:build:release- multi-thread release
- Test WASM -
npm run wasm:testruns only the WASM test projects. - Benchmark -
npm run wasm:benchruns 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(notmaster) npm run lintpasses with no errorsnpm testpasses (all three test projects)- If you have made changes to sgp4 algorithm,
npm test:catalogalso passes
- If you have made changes to sgp4 algorithm,
- New features or bug fixes include corresponding tests
- Changes are mentioned in
CHANGELOG.md