@chrtco/sdk 0.10.0 → 0.10.1

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/CHANGELOG.md CHANGED
@@ -3,6 +3,57 @@
3
3
  All notable changes to `@chrtco/sdk` will be documented in this file.
4
4
 
5
5
  ## [Unreleased]
6
+
7
+ ### Added
8
+ - **Served styles now render in MapLibre Native as shipped.** Every generated
9
+ style begins with a `chrt-background` layer (S-52 NODTA backdrop per
10
+ palette) — previously native renderers drew a black void and
11
+ `didFinishLoading` never fired, because unlike a web app compositing over a
12
+ basemap, native draws exactly and only what the style declares.
13
+ - **`sprite` is declared in every served s52/chrt/raster style** —
14
+ `{tileBaseUrl}/v1/sprites/{family}-{theme}`, a standard GL sprite pair
15
+ (public, unauthenticated) generated from the same atlas registries the
16
+ style generator reads. GL JS behaviour is unchanged (runtime-registered
17
+ images win); native renderers get buoys, beacons, wrecks and patterns with
18
+ no client work. s101 styles deliberately declare **no** sprite until the
19
+ vendored S-100 artwork clears licence review.
20
+ - **Offline styles carry everything a chart needs**: `sprite` and `glyphs`
21
+ now point at `{protocol}://assets/…` inside the chart-assets pack served by
22
+ `GET /v1/offline/assets` (sprite sheets + Open Sans glyph PBFs). An offline
23
+ chart previously rendered mute geometry — no labels, no soundings figures,
24
+ no symbols.
25
+ - Style `metadata` carries `chrt:style-rev` beside `chrt:style-id` when a
26
+ custom style is bound — provenance that survives every cache and proxy.
27
+
28
+ ### Known limits
29
+ - MapLibre Native iOS silently collapses its entire render pass above ~482
30
+ symbol layers (measured externally; exact threshold). Served styles
31
+ currently ship 575 symbol layers, pinned by a ratchet test; reduction below
32
+ the cliff is in progress. Native consumers should avoid stacking many
33
+ additional symbol layers on top of the served style.
34
+
35
+ - **SOUNDG depth-number labels use a single-font stack (`["Open Sans
36
+ Semibold"]`), and every text-font in every served style is now pinned to
37
+ one vendored font.** The previous semibold stack carried a Regular
38
+ "fallback" — but MapLibre joins a multi-font stack into ONE glyph URL
39
+ (`Open Sans Semibold,Open Sans Regular/0-255.pbf`), which no static glyph
40
+ host serves. fonts.openmaptiles.org answers it with an HTML error page as
41
+ HTTP 200: GL JS swallowed the garbage and simply never drew those glyphs,
42
+ MapLibre **Native fatally parses it as protobuf** — the sounding depth
43
+ numbers were the casualty, on the one surface where they matter most. The
44
+ fallback therefore broke the primary; it is gone, and a served-style test
45
+ now rejects any multi-font stack. Caught by the new MapLibre Native
46
+ golden-image harness (`scripts/native-render/`) on its first run.
47
+ - **The offline chart-assets pack now vendors Open Sans Semibold** (0-255 /
48
+ 256-511, OFL, same origin as Regular/Italic). Offline charts previously
49
+ rendered SOUNDG depth numbers and all 60 nav-aid labels (beacons, fog
50
+ signals…) textless — the zip only carried fonts the style half-used.
51
+ - **`applyChrtSymbolSet` is passed the active palette at both serving
52
+ routes** (offline styles, and online custom-style composition). Omitting
53
+ it silently resolved the house cable/pipeline dash colours against DAY —
54
+ NIGHT/DUSK offline charts shipped day-bright dashes. Caught by the
55
+ harness's online≡offline twin gate.
56
+
6
57
  - **`/v1/cells` now sends flat `bbox_north` / `bbox_south` / `bbox_east` / `bbox_west`, matching `CellDetail`.** This is a **wire change to `/v1/cells` and `/v1/cells/{id}`**, not just a type change — read it before upgrading a REST client.
7
58
  - The bug: the SDK declared flat `bbox_*`, the endpoint returned a nested `bbox` object. `cell.bbox_north` typechecked and was `undefined` on **every** response — TypeScript vouching for a field that never arrived, which is worse than no type at all.
8
59
  - **The endpoint was the outlier, so the endpoint moved.** `enc_cells`' own columns, `/v1/coverage/route`'s `CoverageRouteCell`, and every published `CellDetail` are flat; `formatCell()` alone nested. One shape across the API is the point.
package/README.md CHANGED
@@ -210,6 +210,10 @@ const sources = buildSources({ region: 'NOAA_ENC' });
210
210
 
211
211
  ## Using CHRT without JavaScript
212
212
 
213
+ > **Prefer codegen?** The whole HTTP surface is described by an OpenAPI 3.1 spec at
214
+ > **https://api.chrt.co/openapi.json** — generate a typed Swift/Kotlin/Python/Go client
215
+ > from it instead of hand-rolling the calls below.
216
+
213
217
  Native iOS/Android, Swift, Kotlin, Python and plain `curl` clients cannot call `chrt.style()` — it is
214
218
  a JavaScript function that builds a style object in-process. **Use the served style API instead.**
215
219
  It is two HTTP calls, no SDK required.
package/dist/index.cjs CHANGED
@@ -22420,7 +22420,7 @@ function getLabelConfig(layerName, opts = {}) {
22420
22420
  screenColors.deeper
22421
22421
  ] : screenColors.shoaler;
22422
22422
  const haloColor = screenColors.halo;
22423
- const fontStack = weight === "semibold" ? ["Open Sans Semibold", "Open Sans Regular"] : ["Open Sans Regular"];
22423
+ const fontStack = weight === "semibold" ? ["Open Sans Semibold"] : ["Open Sans Regular"];
22424
22424
  return {
22425
22425
  type: "symbol",
22426
22426
  // Property name varies by source path:
@@ -27699,7 +27699,14 @@ function generateStyle(palette = "DAY", opts = {}) {
27699
27699
  const sources = buildSources(opts);
27700
27700
  const sourceId = opts.region ?? DEFAULT_REGION;
27701
27701
  const orderedClasses = getOrderedClasses();
27702
- const layers = [];
27702
+ const backgroundLayer = {
27703
+ id: "chrt-background",
27704
+ type: "background",
27705
+ // A background layer takes no source; StyleLayer models sourced layers,
27706
+ // so the never-used source fields are absent via the unknown hop.
27707
+ paint: { "background-color": resolveColor("NODTA", palette) }
27708
+ };
27709
+ const layers = [backgroundLayer];
27703
27710
  const labelLayers = [];
27704
27711
  const chartCascade = opts.chartMode ? CHART_CASCADE_CODES[opts.chartMode.band] : null;
27705
27712
  const chartRequestedCodes = opts.chartMode ? CHART_BAND_CODES[opts.chartMode.band] : null;
@@ -27813,6 +27820,7 @@ function generateStyle(palette = "DAY", opts = {}) {
27813
27820
  layers.push(...labelLayers);
27814
27821
  }
27815
27822
  const symbolSet = opts.symbolSet ?? "s52";
27823
+ const spriteBase = `${opts.tileBaseUrl ?? "https://tiles.chrt.co"}/v1/sprites`;
27816
27824
  const style = {
27817
27825
  version: 8,
27818
27826
  name: `CHRT ${SYMBOL_SET_LABELS[symbolSet]} ${PALETTE_NAMES[palette]}${opts.chartMode ? ` \u2014 chart:${opts.chartMode.band}` : ""}`,
@@ -27826,13 +27834,21 @@ function generateStyle(palette = "DAY", opts = {}) {
27826
27834
  "chrt:description": "IHO S-52 portrayal rules for Electronic Navigational Charts (ENCs). Generated from the CHRT atlas engine."
27827
27835
  },
27828
27836
  sources,
27829
- // TODO(Phase 9): the superadmin style-generator emits a reference JSON
27830
- // intended for external upload to Mapbox Studio. That flow is vestigial —
27831
- // we're decommissioning Mapbox MTS. When the page is repurposed to
27832
- // generate a MapLibre-native style for self-hosted consumers, wire the
27833
- // `sprite` field back in against a CHRT-hosted sprite route (see
27834
- // `.chrt/` follow-ups). Runtime maps load S-52 symbols via
27835
- // `loadS52SymbolImages()` — no sprite fetch happens at runtime.
27837
+ // A standard GL sprite, declared in the style — the mechanism every GL
27838
+ // renderer (JS and native) already implements. The web app additionally
27839
+ // registers atlas images at runtime via loadS52SymbolImages() (which wins
27840
+ // when both are present, so JS behavior is unchanged); native consumers
27841
+ // get their icons from this declaration alone. s52 sheets are per-palette
27842
+ // (the artwork carries S-52 colour tokens); chrt and raster are
27843
+ // fixed-palette, one sheet each. s101 deliberately declares NO sprite
27844
+ // until the vendored S-100 artwork clears licence review — see
27845
+ // assets/s101/PROVENANCE.md. CHRTsail #122.
27846
+ // Every non-s101 family is palette-scoped: chrt and raster keep fixed
27847
+ // palettes for their OWN glyphs, but both fall back to s52 artwork for
27848
+ // classes they don't remap — and that artwork carries colour tokens.
27849
+ ...symbolSet !== "s101" && {
27850
+ sprite: `${spriteBase}/${symbolSet}-${palette.toLowerCase()}`
27851
+ },
27836
27852
  glyphs: "https://fonts.openmaptiles.org/{fontstack}/{range}.pbf",
27837
27853
  layers
27838
27854
  };