UNPKG

@signalk/nmea0183-utilities

Version:

Various utilities for transforming NMEA0183 units into SI units for use in SK.

106 lines (85 loc) 5.17 kB
# Changelog ## 1.1.0 ### Non-breaking additions - **`intOrNull(n)` / `floatOrNull(n)`** — null-preserving variants of `int` / `float`. Return `null` for empty / whitespace / `null` / `undefined` / non-numeric input, instead of silently coercing to `0`. `intOrNull('0')` still returns `0`, so legitimate zero measurements stay distinguishable from "not available". - **`transformOrNull(value, from, to)`** — null-short-circuiting unit conversion. Identical to `transform` for real input; returns `null` when `value` doesn't parse. Unsupported unit pairs still throw. - **`magneticVariationOrNull(degrees, pole)`** — null-preserving magnetic variation. Returns `null` when degrees or pole is missing or unparseable (including lowercase / unknown pole letters), rather than throwing or returning `0`. Motivation: IEC 61162-1 §7.2.3.4 defines a null NMEA field as "sensor working, value not available" — distinct from a legitimate zero. Legacy `int` / `float` collapse both into `0`, which has caused bugs like SignalK/nmea0183-signalk#192 (magnetic variation reported as 0° from an empty RMC field, causing a 13° error in one reporter's case). Use the `*OrNull` family when passing through to Signal K, which maps `null` in a delta value onto the same semantic. Existing `int` / `float` / `transform` / `magneticVariation` are unchanged for back-compat. ## 1.0.0 First stable release. The package is now authored in TypeScript with strict mode enabled, ships type definitions, and drops a handful of legacy aliases. ### Breaking changes - **Removed `magneticVariaton`** (long-standing typo). Use `magneticVariation` instead. Signature unchanged. - **Removed `integer`** (alias for `int`). Use `int`. - **Removed `double`** (alias for `float`). Use `float`. - **`transform(value, from, to)`**`from` and `to` are now typed as `UnitFormat` (the lowercase union of supported units). TypeScript callers that previously passed arbitrary strings get a compile error. The runtime `.toLowerCase()` coercion present in 0.x was removed, so a JS caller that passes `'KNOTS'` / `'MS'` / similar now throws `unsupported conversion: KNOTS -> MS` instead of silently succeeding. - **`magneticVariation(degrees, pole)` / `coordinate(value, pole)`**`pole` is now typed as `Pole` (`'N' | 'S' | 'E' | 'W'`, uppercase only, matching IEC 61162-1). The lowercase variants from the 0.x union are gone, and the runtime `.toUpperCase()` coercion was removed. Passing an unknown letter now throws `unsupported pole: <value>` instead of silently returning the wrong-sign result. - **`zero(n)`** — only accepts `number`. Previously accepted `number | string` and coerced internally. Also now requires a finite integer: `zero(NaN)`, `zero(Infinity)`, and `zero(0.5)` throw `TypeError` rather than returning the nonsense strings `"NaN"`, `"Infinity"`, `"00.5"` they used to. - **Year handling in `timestamp()`**. A 2-digit `YY` now follows the IEC 61162-1 convention: `YY < 80 → 20YY`, `YY >= 80 → 19YY`. Previously always computed `2000 + YY`, so archival logs from the 1980s and 1990s were stamped as 2080+. Live fixes in this millennium are unaffected (they always take the `20YY` branch). ### Migration | Before | After | | ----------------------------------- | ----------------------------------- | | `utils.magneticVariaton(d, p)` | `utils.magneticVariation(d, p)` | | `utils.integer(n)` | `utils.int(n)` | | `utils.double(n)` | `utils.float(n)` | | `utils.zero('5')` | `utils.zero(Number('5'))` | | `utils.transform(x, 'KNOTS', 'MS')` | `utils.transform(x, 'knots', 'ms')` | | `utils.magneticVariation(d, 's')` | `utils.magneticVariation(d, 'S')` | | `utils.coordinate(v, 'w')` | `utils.coordinate(v, 'W')` | The in-org consumer `@signalk/nmea0183-signalk` uses `magneticVariaton` in its RMC hook; update that import when bumping. ### Non-breaking additions - TypeScript source in `src/index.ts`, compiled to `dist/` with `.d.ts`, `.d.ts.map`, `.js.map`. Strict mode with `noUncheckedIndexedAccess`. - Default export aggregate so `import utils from '@signalk/nmea0183-utilities'` (ESM default-import) works. CJS `require()` is unchanged. - `exports` conditional field for explicit type + runtime resolution. - `sideEffects: false` for tree-shaking. - `engines.node >= 22` (current active Node LTS). Node 18 is EOL; Node 20 reaches EOL 2026-04-30. `signalk-server` already requires `>=22`, so the floor matches the primary consumer of this package. ## 0.12.0 - fix: preserve milliseconds in `timestamp()` (#36). NMEA time fields with a fractional tail (e.g. `173456.75` from a u-blox 10 Hz receiver) now round-trip through `timestamp()` with the hundredths preserved. ## 0.11.0 - chore: release cumulative work from v0.10.0. - test: Stryker mutation testing added, 100% mutation score achieved. - docs: scoped package name (`@signalk/nmea0183-utilities`) in README. ## 0.10.0 See git history.