feat: accept UN/LOCODE port codes as origin/destination - #20
Merged
Conversation
mayurrawte
force-pushed
the
feat/issue-7-port-codes
branch
2 times, most recently
from
July 3, 2026 09:10
01ce5b2 to
905b499
Compare
seaRoute/seaRouteMulti/seaRouteAlternatives accept a UN/LOCODE string anywhere a point is accepted (mixable with coordinates). The ~1600-port dataset ships behind the searoute-ts/ports subpath. Adds loadPorts(url) to fetch and register the dataset at runtime instead of bundling it, and emits a raw dist/ports.json so jsDelivr/unpkg serve it versioned. Closes #7
mayurrawte
force-pushed
the
feat/issue-7-port-codes
branch
from
July 3, 2026 09:11
905b499 to
656cd64
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Logistics and supply-chain users think in port codes, not coordinates. This PR lets a UN/LOCODE string be used anywhere an origin/destination is accepted:
Design
searoute-ts/portsso the core stays lean and consumers only pay for it if they use it. Importing the subpath (for any export, or purely for its side effect) registers a UN/LOCODE→coordinates resolver into the core, which is what enablesseaRoute('CNSHA', …).package.jsonsideEffectsis narrowed to an array so bundlers keep that registration.[lon, lat]and then follows the existing snap → Dijkstra path — no new routing logic. Works forseaRoute,seaRouteMulti, andseaRouteAlternatives.UnknownPortError; if a code is passed without the dataset registered, the error explains to importsearoute-ts/ports.New API
searoute-ts/ports:lookupPort(code) → { code, name, country, coordinates },resolvePort(code) → [lon, lat],PORTS,PORT_COUNT, typesPort/PortRecord.UnknownPortError,registerPortResolver, typePortResolver;PointInputnow also acceptsstring.Dataset & provenance
scripts/build-ports.cjs(documented URL + steps in the script header).Notes
src/ports/data.tsand compiled into both builds, mirroring the existingmarnet.tsconvention (it does ship in both CJS and ESM; the shared-asset approach from Halve package size: load the network from a single shared asset instead of inlining it in both builds #10 could later apply here too, but that's out of scope).Validation
All steps CI runs, from a clean tree:
npm cinpm run lint✅npm run format:check✅npm run build✅npm test✅ (54 tests; +1 core test that a code throwsUnknownPortErrorwithout the dataset, +9 in a newsrc/ports/index.spec.tscovering lookup/resolve, case-insensitivity, aliases, unknown-code errors, andseaRoute('CNSHA','NLRTM')landing in the Shanghai→Rotterdam distance band)Also verified end-to-end against the built
distin both CJS (require) and ESM (import):seaRoute('CNSHA','NLRTM')≈ 19,753 km, mixed code+coord identical,PORT_COUNT1610, unknown code →UnknownPortError.Closes #7