Releases: celikgo/blaeu-lib
Release list
v0.1.1 — the kernel, twelve packages, three presets
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-cadastreThe 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).
Plugins — plugin-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).
Presets — preset-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-invertibleproject/unprojectis what makes a pixel-denominated snap tolerance testable at all. - 22 browser tests mounting a real MapLibre
Mapin headless Chromium — asserting the two things a fake cannot honestly reach: that MapLibre accepts theLayerStyle→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
queryRenderedFeaturesreturns 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 <7andtscagrees, 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-uiis framework-free DOM on purpose and every subscription returns aDisposable, but there is no@blaeu/react. - No 3D and no terrain. The
Rendererinterface 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.