Skip to content

Releases: celikgo/blaeu-lib

v0.1.1 — the kernel, twelve packages, three presets

Choose a tag to compare

@celikgo celikgo released this 19 Aug 18:30

The first tagged release of Blaeu — a plugin-first geospatial editing kernel in TypeScript.

This tag is a source release, not an npm release. @blaeu/* is not published yet; npm install @blaeu/core does not resolve, and nothing in the docs asks you to run it. See what is not here below, and docs/PUBLISHING.md for the two credentialled steps that close it.

📖 Documentation: https://celikgo.github.io/blaeu-lib/

Run it

git clone https://github.com/celikgo/blaeu-lib && cd blaeu-lib
npm install && npm run build
npm run dev -w @blaeu/example-02-cadastre

The kernel

The core owns five extension mechanisms — a typed event bus with cancellable before: hooks, a plugin registry, two middleware pipelines (one synchronous for interaction, one asynchronous for commits), a command bus, and a feature store — plus the services those cannot work without and no plugin may replace: CRS, layers, tools, validation, theme and i18n.

Nothing domain-specific. Drawing, snapping, editing, measurement, selection, undo/redo, topology and even layer types are plugins registering through extension points the core owns. npm run lint:boundaries fails CI on a core→plugin or plugin→plugin import, so the arrows only ever point down.

Twelve packages

Kernel@blaeu/core, including the MapLibre renderer behind a Renderer seam and @blaeu/core/testing (fake renderer + headless harness).

Pluginsplugin-draw (point/line/polygon/rectangle/circle/freehand), plugin-snap (snapping as interaction middleware; 7 built-in providers, pluggable), plugin-edit (vertex editing, transforms, split, merge, topological mode), plugin-select (click, multi-select, box, lasso), plugin-measure (distance, area, grid bearing — planar, in the working CRS), plugin-history (undo/redo for every plugin, including ones that do not exist yet), plugin-topology (overlap, gap, sliver, self-intersection, ring closure, via JSTS), plugin-ui (framework-free chrome).

Presetspreset-cadastre, preset-urban, preset-game. A preset is a value, not a subclass: a plain-data bundle of plugins, config, layers, validation rules, theme and messages. The three exist to make the central claim checkable — one unforked kernel driving a land-registry tool, an urban-planning tool and a tile-based game level editor, with no if (domain === …) anywhere inside it.

Every plugin peer-depends on @blaeu/core, never depends on it. Two kernels in one node_modules means two event buses, and the failure is silent.

Coordinate reference systems

The store is WGS84; survey mathematics happens in a projected working CRS, in metres. All seven Turkish TUREF/TM belts (EPSG:5253–5259) ship built in, along with the legacy ED50 Gauss-Krüger belts (EPSG:2319–2325) that decades of cadastral archive live in, UTM 35N/36N/37N, and Web Mercator as a deliberately-not-survey-grade default.

One 2 000 m² parcel near Ankara, measured three ways by this release:

Working CRS Area Off by
EPSG:5255 TUREF / TM33 — its belt 2000.000 m²
EPSG:5254 TUREF / TM30 — next belt over 2002.894 m² +2.894 m²
EPSG:3857 Web Mercator 3405.467 m² +1405.467 m² (+70 %)

Quantisation is to the millimetre grid of the projected plane, not to decimal places of longitude. Shared parcel corners have a single topological identity, so neighbours move together and cannot be dragged apart into a sliver of unowned land. Areas are planar, with the shoelace sum translated to a local origin first — a Turkish northing is ~4.4 × 10⁶, and the naive version throws away six significant digits.

Full treatment, including a worked parcel with real coordinates: docs/CRS.md.

Verified in this release

  • 789 tests across 44 files, headless against FakeRenderer, whose analytically-invertible project/unproject is what makes a pixel-denominated snap tolerance testable at all.
  • 22 browser tests mounting a real MapLibre Map in headless Chromium — asserting the two things a fake cannot honestly reach: that MapLibre accepts the LayerStyle→paint/layout translation, and that pointer/touch normalisation matches events a browser actually makes.
  • npm run verify — scaffold check, boundary rules, typecheck (sources, examples, tests), lint, documentation fences, tests, build.
  • All twelve packages pack cleanly with dist/ (ESM + .d.ts + sourcemaps), README and LICENSE.
  • Seventeen ADRs, each recording the alternatives rejected.

What is not here

Taken from the README's own "what this is not, and what is unfinished", because a library honest about its edges is worth more than one that is not:

  • Not on npm. The packaging is done and verified; the registry step is not.
  • Hit testing is only verified on a GPU runner. Headless SwiftShader never completes a render pass, so queryRenderedFeatures returns nothing and four browser tests are gated behind a probe and skip with a warning. Relatedly, maplibre 6 rendering is unverified at runtime — the peer range claims >=4.7.0 <7 and tsc agrees, but the browser suite is 21/21 on 5.24 and 18/21 on 6.4. CI runs it on both, v6 non-blocking, so the gap stays visible. It closes on a GPU runner.
  • No React (or Vue, or Svelte) binding. plugin-ui is framework-free DOM on purpose and every subscription returns a Disposable, but there is no @blaeu/react.
  • No 3D and no terrain. The Renderer interface is the seam one would come through; nothing is behind it.
  • Collaboration is designed for, not built. The command bus is the right seam. That is not the same as it working.
  • Not a basemap, a tile server, or a replacement for a GIS. No raster reprojection, no geoprocessing suite, no attribute joins. It is an editing kernel.
  • ED50→TUREF conversion is for viewing, not for the deed. The seven-parameter shift is good to a couple of metres; a legally defensible conversion uses the official regional transformation, which this library does not pretend to do.

MIT.