* Generate the map styles with @versatiles/style v6
v6 removed the colorful and eclipse builders; osm({ theme }) replaces
them, with eclipse mapping to the retuned colorful-dark palette. The
sprite sheet is renamed from basics to base and its icon ids change,
so core's tile proxy has to serve the base sheet before this ships.
v6 also defaults to the globe projection and the styles keep it. Only
the MapLibre engine renders them: from ha-map the Leaflet engine runs
without WebGL2 or raster-only after a MapLibre failure, so nothing
ties the map to Mercator any more.
* Bundle the VersaTiles base sprite sheet
The styles referenced the sprite sheet through core's proxy, which
fetched it from the OpenStreetMap Foundation. The OSMF only mirrors
the retired v5 basics sheet, and VersaTiles warns that the assets on
tiles.versatiles.org change with every release, so neither is a stable
source for the exact sheet the pinned @versatiles/style expects.
The base sheet now ships with the frontend under static/map/sprites,
fetched from the versatiles-style release matching the installed
package with `yarn gulp update-map-sprites`. The style build checks
that every icon the styles reference exists in the bundled sheet, so a
bump that renames icons fails the build instead of shipping POIs
without icons. Sprites resolve against the page rather than the
instance, since on Cast the frontend is not served by the instance,
and the demo no longer needs its own sprite override.
* Open a PR when the bundled map sprite sheet drifts
Runs the sprite update after a push to dev touches package.json, which
is how a @versatiles/style bump lands, and opens a PR with the
re-vendored sheet when it changed. Mirrors the device class and sensor
constant sync workflows.
* Exclude vendored map sprite metadata from Prettier
The sprite JSON is extracted verbatim from the @versatiles/style release
in its upstream compact form, which fails prettier --check. Ignoring it
keeps lint green and keeps the sync workflow's drift check byte-identical
with upstream.
* Format map-assets.js with Prettier
* Note that the sprite sheet ships with the frontend
The module header still said sprites come through core's proxy, which
stopped being true when the sheet was bundled.
* Gate merges on the bundled map sprite sheet
A @versatiles/style bump that references new icons used to fail only the
build job, which the dev ruleset does not require, so the bump could be
merged red and the post-merge sync workflow was left to repair it. Run
the sprite check in the required lint job instead, so the sheet has to be
re-vendored on the dependency PR itself, and drop the sync workflow that
existed to clean up after the merge.
* Only treat image properties as sprite references
The sprite check walked every string under layout and paint, so any
base-prefixed text value would have failed the required lint job without
asking for an image. Collect from the image-bearing properties only.
* Version the sprite URL with a hash of the vendored sheet
Core serves /static with a month of max-age and the service worker does
not precache the map assets, so a re-vendored sheet at the same URL would
keep coming from the browser cache next to a freshly fetched style that
expects the new icons. Append a short content hash of the four sheet
files as a query parameter. MapLibre appends the format and extension to
the pathname, so the query survives, and the test now guards that the
absolute-URL rewrite keeps it too.
* Load MapLibre RTL text plugin so Hebrew and Arabic map labels read correctly
The vector base map never registered MapLibre's RTL text plugin, so
right-to-left scripts were shaped left to right and every label came out
reversed. Ship @mapbox/mapbox-gl-rtl-text from /static/map/ alongside the
glyphs (no third-party host) and register it once, lazily, before the
first vector layer is created.
Fixes#53851
* Add the English name to map labels in non-Latin scripts
Before the move to vector tiles the CARTO basemap showed English names
everywhere. The OSM style shows local names, which most users cannot
read in Cyrillic, Arabic, Hebrew or CJK regions. Keep the local name and
add the English one from the tiles under it - in parentheses for street
labels, which cannot break lines. Latin-script names are left alone, so
Köln stays Köln.
Compress with zopfli in a worker pool
compress-app gzips every build artifact with zopfli, but @gfx/zopfli is
synchronous WASM: it ran on the main thread, pinned a single core and blocked
the event loop for the whole step, so it dominated the production build.
Replace gulp-zopfli-green with an equivalent gulp transform that runs the same
compressor in a pool of worker_threads sized to availableParallelism(). The
compressed output is byte-identical, and @gfx/zopfli is no longer loaded on the
main thread of every gulp invocation.
On a 12-core machine compress-app drops from 6.98 min to 1.27 min, and the full
production build from 8.87 min to 3.32 min.
* Shared build and runner for all build,dev,test flows
* Harden managed process lifecycle
* Make build workflows deterministic
* Test build management contracts
* Queue shared generated output work
* Isolate generated inputs for dev servers
* Preserve dev server child failures
* Make generated lock test deterministic
* Keep test navigator configurable
* Block concurrent frontend workflows
* Simplify workflow lock ownership
* Focus workflow locking on managed commands
* Trim workflow lock unit tests
* Consolidate dev server lifecycle handlers