mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-11-13 15:51:00 +00:00
1696162d22
GHSA-jrc7-96c5-q579 covers every maplibre-gl up to 6.4.0 and has no 5.x release, so npm audit kept flagging the patched 5.24.0. Moving to 6.15.0 retires the local backport: patch-maplibre.mjs and its postinstall, predev and prebuild hooks go, along with the Dockerfile copy and its format-baseline entry. 6.x sanitizes attributions against an allow list. What the major changes for TREK: - ESM only, no default export: the engine module imports the namespace and hands that out as its default, so every caller stays as it was. - The worker is no longer inlined, and inside a bundle MapLibre cannot find it next to its own module. The engine sets it from Vite's ?worker&url build before any map, the Leaflet bridge's included. - WebGL2 only: the probe asks for webgl2 alone, so a WebGL1-only browser gets the raster basemap instead of a GPUInitializationError. - 6.9 shapes right-to-left text itself and deprecated setRTLTextPlugin; the old plugin would replace that and could only run through eval in the module worker, so MapLibre no longer registers it. Mapbox does. The lockfile moves maplibre-gl and its own dependencies only; the Leaflet bridge already allows ^6.0.0 as its peer.
51 lines
2.5 KiB
TypeScript
51 lines
2.5 KiB
TypeScript
/**
|
||
* Arabic, Hebrew, Persian and Urdu labels need two things a GL engine does not do
|
||
* on its own: the bidirectional algorithm, and Arabic contextual shaping (a letter
|
||
* is drawn differently depending on its neighbours). Without them the engine lays
|
||
* the codepoints out one by one, left to right, in isolated forms — so القاهرة
|
||
* comes out as ة ر ه ا ق ل ا, unjoined and reversed. Raster basemaps never showed
|
||
* this because their labels are drawn server-side, which is why it only surfaced
|
||
* once the default basemap became a vector style.
|
||
*
|
||
* Mapbox GL exposes the fix as an optional plugin and does not load it by
|
||
* default. Registering is global to the engine, so it happens once in the engine
|
||
* module rather than at each map's construction site. MapLibre needed the same
|
||
* plugin up to version 5; since 6.9 it shapes and reorders the text itself, and
|
||
* its engine module registers nothing.
|
||
*
|
||
* The call itself stays with the caller: Mapbox GL 3 takes
|
||
* `(url, callback, deferred)` and returns nothing, while MapLibre took
|
||
* `(url, lazy)` and returned a promise, so the guard below accepts either rather
|
||
* than guessing an arity.
|
||
*
|
||
* Deliberately no getRTLTextPluginStatus() pre-check: reading it made MapLibre
|
||
* build its worker pool, which is an eager side effect for a module that is
|
||
* imported for its default export, and throws outright under jsdom. Registering
|
||
* twice is reported — by a throw or a rejected promise depending on the engine —
|
||
* and both are handled below, so the probe bought nothing.
|
||
*/
|
||
|
||
/**
|
||
* Runs a GL engine's RTL-plugin registration, swallowing the ways it can fail.
|
||
*
|
||
* Callers register lazily, so the payload is only fetched once a map actually
|
||
* paints RTL text and a user who never leaves Latin script downloads nothing.
|
||
*
|
||
* @returns whether the registration call completed without throwing.
|
||
*/
|
||
export function registerRtlTextPlugin(register: () => void | Promise<unknown>): boolean {
|
||
try {
|
||
const pending = register()
|
||
// MapLibre reports a failed or duplicate registration by rejecting; Mapbox
|
||
// routes the same through its callback. Neither is worth surfacing: a map
|
||
// with unshaped labels still renders, and an unhandled rejection would not
|
||
// give the user anything to act on.
|
||
if (pending instanceof Promise) pending.catch(() => {})
|
||
return true
|
||
} catch {
|
||
// Already registered, or the engine refused outright. Registering the plugin
|
||
// must never be able to break map creation.
|
||
return false
|
||
}
|
||
}
|