@squawk/navaids

Pure logic library for querying US navaid data. Look up navaids by identifier,
frequency, geographic proximity, type, or fuzzy text search. Contains no bundled data -
accepts an array of Navaid records at initialization. For zero-config use, pair
with @squawk/navaid-data.
Part of the @squawk aviation library suite. See all packages on npm.
Usage
import { usBundledNavaids } from '@squawk/navaid-data';
import { createNavaidResolver } from '@squawk/navaids';
const resolver = createNavaidResolver({ data: usBundledNavaids.records });
const bos = resolver.byIdent('BOS');
const onFreq = resolver.byFrequency({ frequency: 113.7 });
const nearby = resolver.nearest({ lat: 42.3656, lon: -71.0096 });
for (const result of nearby) {
console.log(result.navaid.name, result.distanceNm, 'nm');
}
const vors = resolver.byType(new Set(['VOR', 'VORTAC', 'VOR/DME']));
const results = resolver.search({ text: 'boston' });
console.log(results[0]?.navaid.name, results[0]?.score);
Consumers who have their own navaid data can use this package standalone:
import { createNavaidResolver } from '@squawk/navaids';
const resolver = createNavaidResolver({ data: myNavaids });
Browser / SPA usage
The resolver factory has no Node-specific imports and ships an explicit /browser subpath for SPAs and edge runtimes. Pair it with @squawk/navaid-data/browser:
import { loadUsBundledNavaids } from '@squawk/navaid-data/browser';
import { createNavaidResolver } from '@squawk/navaids/browser';
const dataset = await loadUsBundledNavaids();
const resolver = createNavaidResolver({ data: dataset.records });
The /browser entry is identical to the main entry; the separate subpath exists so browser support is an explicit, publint-verified part of the public API surface.
API
createNavaidResolver(options)
Creates a resolver object from an array of Navaid records.
Parameters:
options.data - an array of Navaid objects (from @squawk/types)
Returns: NavaidResolver - an object with the lookup methods described below.
resolver.byIdent(ident)
Looks up navaids by identifier (e.g. "BOS", "JFK"). Multiple navaids can share
the same identifier (e.g. an NDB and a VOR at different locations).
Case-insensitive. Returns Navaid[].
resolver.byIdentAtPosition(ident, lat, lon, toleranceNm?)
Looks up the single navaid sharing the given identifier that lies nearest to a
geographic position. Multiple navaids can publish the same identifier (a
co-located NDB and VOR/DME, or two distant stations reusing a code); this
disambiguates them by proximity to a known point such as a map-click location or
an adjacent route waypoint.
ident | string | Navaid identifier (case-insensitive) |
lat | number | Latitude of the reference position in decimal degrees (WGS84) |
lon | number | Longitude of the reference position in decimal degrees (WGS84) |
toleranceNm | number | Optional. Maximum great-circle distance in nautical miles. Omit to let the nearest match win regardless |
Returns the nearest matching Navaid by great-circle distance, or undefined
when no navaid carries the identifier or none fall within toleranceNm.
const navaid = resolver.byIdentAtPosition('AA', 47.45, -122.31);
resolver.byFrequency(query)
Finds navaids operating on a given frequency. For VOR-family navaids the
frequency is in MHz; for NDB-family navaids it is in kHz.
frequency | number | Frequency value to match (MHz for VOR-family, kHz for NDB-family) |
types | ReadonlySet<NavaidType> | Optional. When provided, only navaids of these types are returned |
limit | number | Optional. Maximum number of results. Defaults to 20 |
Returns Navaid[], sorted alphabetically by identifier.
resolver.nearest(query)
Finds navaids nearest to a geographic position, sorted by distance ascending.
lat | number | Latitude in decimal degrees (WGS84) |
lon | number | Longitude in decimal degrees (WGS84) |
maxDistanceNm | number | Optional. Maximum distance in nautical miles. Defaults to 30 |
limit | number | Optional. Maximum number of results. Defaults to 10 |
types | ReadonlySet<NavaidType> | Optional. When provided, only navaids of these types are returned |
Returns NearestNavaidResult[], each containing:
navaid - the matched Navaid record
distanceNm - great-circle distance in nautical miles (rounded to 2 decimal places)
const nearby = resolver.nearest({
lat: 42.3656,
lon: -71.0096,
maxDistanceNm: 50,
limit: 5,
types: new Set(['VORTAC']),
});
resolver.byType(types)
Returns all navaids matching the given type(s), sorted alphabetically by identifier.
const ndbs = resolver.byType(new Set(['NDB', 'NDB/DME']));
resolver.search(query)
Fuzzy-searches navaids across identifier and name. Matching is case-insensitive and
tolerant of prefixes, substrings, subsequences, and small typos. Results are scored
and returned best-match first.
text | string | Search text, matched fuzzily against each navaid's identifier and name |
limit | number | Optional. Maximum number of results. Defaults to 20 |
types | ReadonlySet<NavaidType> | Optional. When provided, only navaids of these types are returned |
minScore | number | Optional. Minimum match score (exclusive) in [0, 1] a result must reach. Defaults to 0 |
Returns NavaidSearchResult[], sorted by descending score, each containing:
navaid - the matched Navaid record
score - match strength in [0, 1], where 1 is an exact identifier or name match
matchedField - which field produced the best match: 'identifier' or 'name'
ranges - matched character ranges within the best-matching field's text, for highlighting
const results = resolver.search({ text: 'boston', limit: 10 });
for (const { navaid, score, matchedField } of results) {
console.log(navaid.identifier, score, `(matched ${matchedField})`);
}