@neilberkman/sidereon 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +105 -0
- package/package.json +32 -0
- package/pkg/sidereon.d.ts +4724 -0
- package/pkg/sidereon.js +10807 -0
- package/pkg/sidereon_bg.wasm +0 -0
- package/pkg/sidereon_bg.wasm.d.ts +761 -0
- package/pkg-node/sidereon.d.ts +3938 -0
- package/pkg-node/sidereon.js +10919 -0
- package/pkg-node/sidereon_bg.wasm +0 -0
- package/pkg-node/sidereon_bg.wasm.d.ts +761 -0
- package/types/sidereon-extra.d.ts +896 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Neil Berkman
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# @neilberkman/sidereon
|
|
2
|
+
|
|
3
|
+
A WebAssembly / JavaScript interface over the [sidereon](https://github.com/neilberkman/sidereon)
|
|
4
|
+
GNSS + astrodynamics engine. It loads SP3 precise ephemerides, runs single-point
|
|
5
|
+
positioning (SPP), queries IONEX slant ionospheric delay, and propagates SGP4 /
|
|
6
|
+
TLE orbits with ground-station look angles. The numbers come straight from
|
|
7
|
+
`sidereon-core`; this package only marshals across the wasm boundary.
|
|
8
|
+
|
|
9
|
+
The binding calls the engine's serial paths only, so no thread pool is spawned
|
|
10
|
+
under wasm32.
|
|
11
|
+
|
|
12
|
+
## Install / build
|
|
13
|
+
|
|
14
|
+
The published package ships the prebuilt wasm. To build from source:
|
|
15
|
+
|
|
16
|
+
```sh
|
|
17
|
+
wasm-pack build --target web --out-dir pkg --out-name sidereon
|
|
18
|
+
wasm-pack build --target nodejs --out-dir pkg-node --out-name sidereon
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Usage (ESM, async init)
|
|
22
|
+
|
|
23
|
+
The `web` build follows the standard wasm-pack pattern: import the default
|
|
24
|
+
`init`, await it once, then call the API. In the browser `init()` fetches the
|
|
25
|
+
`.wasm` for you; in Node, hand it the bytes.
|
|
26
|
+
|
|
27
|
+
```js
|
|
28
|
+
import init, { loadSp3, loadIonex, Tle, GroundStation } from "@neilberkman/sidereon";
|
|
29
|
+
import { readFile } from "node:fs/promises";
|
|
30
|
+
|
|
31
|
+
// Browser: await init(); Node: pass the wasm bytes.
|
|
32
|
+
await init({ module_or_path: await readFile(new URL("./pkg/sidereon_bg.wasm", import.meta.url)) });
|
|
33
|
+
|
|
34
|
+
const sp3 = loadSp3(new Uint8Array(await readFile("COD0MGXFIN.SP3")));
|
|
35
|
+
console.log(sp3.epochCount, sp3.satellites);
|
|
36
|
+
|
|
37
|
+
// Positions come back as Float64Array; epochs as plain numbers (seconds J2000).
|
|
38
|
+
const epochs = sp3.epochsJ2000Seconds();
|
|
39
|
+
const { positionM, clockS } = sp3.interpolate("G01", epochs.slice(0, 1));
|
|
40
|
+
|
|
41
|
+
// Single-point positioning. Pass one options object (see the SppRequest type).
|
|
42
|
+
const solution = sp3.solveSpp({
|
|
43
|
+
observations: [{ satelliteId: "G01", pseudorangeM: 22853110.4 }, /* ... */],
|
|
44
|
+
tRxJ2000S: 649728000,
|
|
45
|
+
tRxSecondOfDayS: 86400,
|
|
46
|
+
dayOfYear: 176,
|
|
47
|
+
corrections: { ionosphere: false, troposphere: false },
|
|
48
|
+
});
|
|
49
|
+
console.log(solution.positionM, solution.rxClockS, solution.usedSats);
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
For CommonJS / synchronous Node, `require("@neilberkman/sidereon")` resolves to
|
|
53
|
+
the `nodejs` build, which loads the wasm at require time (no init step):
|
|
54
|
+
|
|
55
|
+
```js
|
|
56
|
+
const { loadSp3 } = require("@neilberkman/sidereon");
|
|
57
|
+
const sp3 = loadSp3(require("fs").readFileSync("COD0MGXFIN.SP3"));
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## IONEX slant delay
|
|
61
|
+
|
|
62
|
+
```js
|
|
63
|
+
const ionex = loadIonex(new Uint8Array(await readFile("igsg.20i")));
|
|
64
|
+
const epochs = ionex.mapEpochsJ2000S; // Float64Array, seconds since J2000
|
|
65
|
+
// receiver lat/lon deg, satellite az/el deg, epoch, carrier Hz -> metres
|
|
66
|
+
const delayM = ionex.slantDelay(37.4, -122.1, 135, 30, epochs[0], 1575.42e6);
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## SGP4 propagation and look angles
|
|
70
|
+
|
|
71
|
+
```js
|
|
72
|
+
const tle = new Tle(line1, line2 /*, "improved" | "afspc" */);
|
|
73
|
+
const t0 = BigInt(Date.now()) * 1000n; // unix microseconds
|
|
74
|
+
const epochs = new BigInt64Array([t0, t0 + 600n * 1_000_000n]);
|
|
75
|
+
|
|
76
|
+
const { positionKm, velocityKmS } = tle.propagate(epochs); // TEME, flat [x,y,z,...]
|
|
77
|
+
|
|
78
|
+
const station = new GroundStation(37.7749, -122.4194 /*, altitudeM */);
|
|
79
|
+
const { azimuthDeg, elevationDeg, rangeKm } = tle.lookAngles(station, epochs);
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Errors
|
|
83
|
+
|
|
84
|
+
Engine failures (parse rejections, non-converging solves, SGP4 error codes)
|
|
85
|
+
throw a JS `Error` carrying the engine's own message. Bad input throws
|
|
86
|
+
`TypeError` (wrong shape or an unparseable satellite token) or `RangeError`
|
|
87
|
+
(non-finite or out-of-domain numbers). Nothing traps or panics across the
|
|
88
|
+
boundary.
|
|
89
|
+
|
|
90
|
+
## Data conventions
|
|
91
|
+
|
|
92
|
+
- Positions and vectors cross as `Float64Array`. Multi-epoch arrays are flat,
|
|
93
|
+
row-major: `[x0, y0, z0, x1, y1, z1, ...]`, length `3 * epochCount`.
|
|
94
|
+
- Epochs are plain numbers (seconds since J2000) except SGP4 epoch grids, which
|
|
95
|
+
are `BigInt64Array` of unix microseconds.
|
|
96
|
+
- SPP positions are ECEF metres; geodetic output is `[latRad, lonRad, heightM]`.
|
|
97
|
+
- SGP4 states are TEME, kilometres and km/s.
|
|
98
|
+
|
|
99
|
+
## Scope
|
|
100
|
+
|
|
101
|
+
Exposed: SP3 load/query, SPP solve, IONEX slant delay, SGP4 propagate /
|
|
102
|
+
look angles. Not yet exposed: RTK, PPP, RINEX OBS/NAV/clock, velocity, and the
|
|
103
|
+
broader astro event/conjunction surface. The rayon-parallel batch solves are
|
|
104
|
+
intentionally omitted (wasm32 is single-threaded; the serial paths produce the
|
|
105
|
+
same numbers).
|
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@neilberkman/sidereon",
|
|
3
|
+
"version": "0.8.0",
|
|
4
|
+
"description": "WebAssembly / JavaScript interface over the sidereon GNSS + astrodynamics engine: SP3 loading and multi-product merge, SPP / RTK (float + fixed) / PPP (float + fixed) positioning, IONEX slant delay, SGP4 and numerical orbit propagation, RINEX observation/navigation/clock parsing, CRINEX (Hatanaka) decoding, observable-domain math (carrier combinations, cycle slips, Hatch smoothing, weighting, velocity, GPS C/A signal), and the astro domain (scale-tagged time, frame transforms, Sun/Moon ephemerides, eclipse / body angles, DOP, passes / visibility, conjunction + collision probability, CDM / OMM / ANTEX parsing, RF link budget)",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./pkg/sidereon.d.ts",
|
|
10
|
+
"import": "./pkg/sidereon.js",
|
|
11
|
+
"require": "./pkg-node/sidereon.js"
|
|
12
|
+
},
|
|
13
|
+
"./types": "./types/sidereon-extra.d.ts"
|
|
14
|
+
},
|
|
15
|
+
"types": "./pkg/sidereon.d.ts",
|
|
16
|
+
"files": [
|
|
17
|
+
"pkg/sidereon.js",
|
|
18
|
+
"pkg/sidereon.d.ts",
|
|
19
|
+
"pkg/sidereon_bg.wasm",
|
|
20
|
+
"pkg/sidereon_bg.wasm.d.ts",
|
|
21
|
+
"pkg-node/sidereon.js",
|
|
22
|
+
"pkg-node/sidereon.d.ts",
|
|
23
|
+
"pkg-node/sidereon_bg.wasm",
|
|
24
|
+
"pkg-node/sidereon_bg.wasm.d.ts",
|
|
25
|
+
"types/sidereon-extra.d.ts",
|
|
26
|
+
"README.md"
|
|
27
|
+
],
|
|
28
|
+
"scripts": {
|
|
29
|
+
"build": "wasm-pack build --target web --out-dir pkg --out-name sidereon && wasm-pack build --target nodejs --out-dir pkg-node --out-name sidereon",
|
|
30
|
+
"test": "node --test"
|
|
31
|
+
}
|
|
32
|
+
}
|