@maproll/map-url
The maproll map URL grammar: build an
api.maproll.io map URL from parameters, and parse one back.
Every maproll map is a URL. This package is the single definition of how that
URL is written and read, shared by the editor (app.maproll.io) and the MCP
server (@maproll/mcp) so the two cannot drift.
Pure, dependency-free, isomorphic — browser, Node, and Workers.
import { buildUrl, parseUrl, serializeDataRows } from "@maproll/map-url";
const url = buildUrl({
scope: "world",
title: "Coffee consumption per capita",
data: serializeDataRows([
{ kind: "value", id: "FI", value: 12 },
{ kind: "value", id: "US", value: 4.2 },
]),
});
const { params, markers, routes } = parseUrl(url);
What's in it
buildUrl, buildEmbed | Params → URL, or a ready <img> tag |
parseUrl, parseMarkers, parseRoutes, hasMapParams | URL → params |
applyPatch | Merge a partial update (null clears, undefined leaves alone) |
serializeDataRows, parseDataString, replaceColorRows, isHexColor | The four data= pair shapes |
serializeMarkers, serializeRoutes | Layer serialisation |
SCOPES, GROUP_SCOPES, ALL_SCOPES, SCOPE_CODES | Scope catalog |
MapParams, MarkerEntry, RouteEntry, DataRow, … | Types |
Design notes
Parsing is forgiving, but never silently wrong. A malformed marker or
route is skipped so a hand-edited link still yields the map it mostly
describes — but input that would parse into a plausible wrong value is
rejected instead. Number("") is 0, so markers=10, would have put a
marker on the equator; a route colour written without its # (008000)
would have become a stroke width of 8000.
parseUrl only accepts known keys. buildUrl serialises whatever it is
handed, so carrying unknown keys through would push a utm_source from a
shared link into the render URL. A param added to the API is ignored here
until MAP_PARAM_KEYS learns about it — add it in the same change.
Round-tripping preserves the map, not the string. parseUrl fills in
defaults, so a minimal URL comes back with them spelled out. Key order is not
stable; compare params, not URLs.
Scripts
npm run build
npm test
npm run typecheck
src/scopes.ts is generated from the editor's scope list; regenerate it when
scopes change.