@chrtco/sdk
v0.6.0
Published
Official TypeScript SDK for the CHRT nautical chart API
Maintainers
Readme
@chrtco/sdk
Official TypeScript SDK for the CHRT nautical chart API.
Zero dependencies · Works in Node 18+, browsers, Deno, Bun · Full TypeScript types
Install
npm install @chrtco/sdkQuick Start
import { Chrt } from '@chrtco/sdk';
const chrt = new Chrt('chrt_live_...');
// Get depth areas in a bounding box
const features = await chrt.features({
bbox: [-71, 42, -70, 43],
layer: 'DEPARE',
});
// Find buoys near a position
const nearby = await chrt.query({
point: [-70.86, 42.02],
radius: 2000,
layer: 'BOYCAR,BOYLAT',
});
// List ENC cells
const cells = await chrt.cells.list({ source: 'NOAA' });
// Get a specific cell
const cell = await chrt.cells.get('US5MA11M');Mapbox GL JS / MapLibre
import mapboxgl from 'mapbox-gl';
import { Chrt } from '@chrtco/sdk';
const chrt = new Chrt('chrt_live_...');
const map = new mapboxgl.Map({
container: 'map',
style: chrt.styleUrl(),
center: [-70.25, 43.66],
zoom: 12,
transformRequest: chrt.transformRequest(),
});Configuration
const chrt = new Chrt({
apiKey: 'chrt_live_...',
baseUrl: 'https://api.chrt.co/v1', // default
retries: 2, // retry on 5xx, default 2
});API Reference
chrt.features(options)
Query GeoJSON features by bounding box.
| Option | Type | Required | Description |
|--------|------|----------|-------------|
| bbox | [w, s, e, n] | ✓ | Bounding box |
| layer | string | | S-57 layer code (e.g. DEPARE) |
| limit | number | | Max results (default 100) |
| offset | number | | Pagination offset |
chrt.query(options)
Spatial proximity search around a point.
| Option | Type | Required | Description |
|--------|------|----------|-------------|
| point | [lng, lat] | ✓ | Centre point |
| radius | number | | Radius in metres (default 1000) |
| layer | string | | Comma-separated layer codes |
| limit | number | | Max results |
chrt.cells.list(options?)
List available ENC cells.
chrt.cells.get(cellId)
Get metadata for a specific cell.
chrt.tiles.styleUrl()
Returns a Mapbox/MapLibre-compatible style.json URL.
chrt.tiles.tileUrl(z, x, y)
Returns a single vector tile URL.
chrt.tiles.groups()
List available tileset groups.
chrt.styleUrl()
Shortcut for chrt.tiles.styleUrl().
chrt.transformRequest()
Returns a transformRequest function for Mapbox GL / MapLibre that auto-injects the API key.
Error Handling
import { Chrt, ChrtError } from '@chrtco/sdk';
try {
await chrt.features({ bbox: [-71, 42, -70, 43] });
} catch (e) {
if (e instanceof ChrtError) {
console.error(e.status, e.code, e.message);
}
}Offline Downloads (CHRToffline)
Download MBTiles bundles for offline rendering. Bundles are SHA-256 verified before commit. Interrupted downloads resume from a .partial sidecar file.
Runtime support in v1: Node 18+, Bun, Deno. Browser and React Native are deferred to a follow-up.
import { Chrt } from '@chrtco/sdk';
import { nodeFileSystemAdapter } from '@chrtco/sdk/node';
const chrt = new Chrt({
apiKey: process.env.CHRT_API_KEY!,
// Required for offline.* — generate once at first launch, persist per
// install. Echoed into the offline JWT + heartbeat for device-level usage
// tracking.
deviceId: 'my-app-install-uuid',
// Optional — enables budget enforcement + `list()` of local state. If
// unset, budget is not enforced and `setStorageBudget()` throws.
manifestPath: './chrt-offline-manifest.json',
});
const fs = nodeFileSystemAdapter();
// Optional: cap total local storage across all regions.
await chrt.offline.setStorageBudget(10 * 1024 ** 3, fs); // 10 GB
// List what you're licensed to download.
const regions = await chrt.offline.list();
// Download a region. Resumes from a partial if one exists.
await chrt.offline.download('NOAA_ENC', {
path: './noaa.mbtiles',
fs,
onProgress: (p) => console.log(`${p.fraction * 100}%`),
});
// Remove a region (deletes the file + updates manifest + heartbeats).
await chrt.offline.remove('NOAA_ENC', { path: './noaa.mbtiles', fs });
// Manual heartbeat — call at app launch + every 24h while running.
await chrt.offline.heartbeat({ fs }); // derives regions + total from manifestTyped offline errors
import { OfflineError } from '@chrtco/sdk';
try {
await chrt.offline.download('NOAA_ENC', { path: './noaa.mbtiles', fs });
} catch (e) {
if (e instanceof OfflineError) {
switch (e.code) {
case 'budget_exceeded': console.log(e.detail); break;
case 'download_corrupt': console.log('SHA mismatch'); break;
case 'network_interrupted': console.log('resume later'); break;
case 'coverage_denied': console.log('region not licensed'); break;
case 'offline_not_enabled': console.log('enable use_offline on this API key'); break;
}
}
}Notes
- The SDK mints its own short-lived JWTs internally. You never see them.
- Heartbeats in v1 are manual — auto-scheduling comes in a later phase.
- A budget smaller than current usage will not auto-prune; it only refuses new downloads. Use
remove()explicitly.
License
MIT
