@bitruvius/foundation
v0.3.2
Published
Bitruvius SDK foundation: the domain-agnostic, geo-free base every Bitruvius SDK builds on (task/worker scheduling, runtime capability detection, request authorization, SDK config, and error types).
Readme
@bitruvius/foundation
The dependency root of the Bitruvius SDK: scheduling, capability detection, transport authorization, configuration and errors, with nothing underneath it.
Internal building block. This package exists so that
@bitruvius/sdk-maplibreand the Bitruvius codecs can resolve their dependencies on npm. It has no standalone product story. Unless you are deliberately building against it, install the SDK instead.
Why it is a separate package
Bitruvius ships as many small packages: a codec per format, a geospatial layer, an auth adapter, a renderer SDK. They all need the same worker pool, the same error type and the same configuration store, and none of them may depend on each other. A raster codec cannot depend on the geospatial layer, and the geospatial layer cannot depend on a raster codec.
So the shared pieces moved down to the one package with nothing beneath it. This package has zero runtime dependencies and touches no WebGL, DOM, wasm or geospatial code. That is what lets @bitruvius/ript, a scientific raster codec with no interest in maps, take the same worker pool as @bitruvius/sdk-maplibre. The geospatial layer is @bitruvius/geo-core, which builds on this.
Two more things force a single low-level home:
Configuration has to be shared across copies of the SDK. configure() writes to a namespaced key on globalThis, not to a module-scoped variable. A page can load several per-package CDN bundles, each carrying its own copy of the SDK, and they must still see one wasmBaseUrl and one signed-in ArcGIS session.
Errors have to survive duplicate bundles. BitruviusError.is() duck-types on shape instead of using instanceof, for the same reason: two copies of the SDK on one page each throw errors that fail the other's instanceof. The stable BVX_* code set is defined exactly once, here, so every package throws identifiers you can still branch on after minification.
What is in it
Scheduling. WorkerPool is a transferable Web Worker pool with per-task AbortSignal handling, a warm-up handshake, broadcast, and self-healing respawn under a budget, so a broken worker module or wasm URL fails the pool loudly rather than hanging every tile. TaskQueue bounds concurrency. createCdnWorkerTrampoline solves the cross-origin worker problem: new Worker(crossOriginUrl) throws a synchronous SecurityError before any network request is made, so a CDN-hosted SDK fetches its worker chunk's text and spawns it from a same-origin blob: URL instead. reportWorkerDegradation makes the main-thread fallback audible once per label, because a layer that renders slowly and a layer that renders nothing were both shipping silently.
Capability detection. detectCapabilities() probes WebGL2, WebGPU, Workers, transferables and WebAssembly SIMD. SIMD is a hard gate rather than a preference: the codec wasm is compiled with +simd128 and there is no non-SIMD build, so recommendDecodeBackend() throws instead of pretending. DecodeBackend names the execution model a decoder will use.
Transport. RequestAuthorizer is a drop-in replacement for fetch, scoped to one streaming session. It is a fetch override rather than an authorize() callback because every call site already calls fetch, and because only the override holds the Response, which is what lets @bitruvius/esri-auth detect the ArcGIS challenge that arrives as HTTP 200 with { error: { code: 498 } } in the body.
publicAuthorizer() also enforces a credential trust boundary. A tileset is a third-party document that names further URLs, and the streaming engines fetch every one of them. Without the boundary, a tileset naming https://attacker.example/tile.glb harvests a Cesium ion token or a Google API key, both reusable and both billable, delivered by our own transport. Credentials go to the origin they were minted for and to nowhere else; other hosts get the request without them, and are warned once. A tile that fails to load is recoverable in a way that a leaked key is not.
fetchBinaryAsset() fails on the transport problem instead of handing a wrong-typed body to a codec. A missing file that 404s to an HTML fallback page otherwise surfaces as a bad magic number of 1868833084, which is the ASCII <!do of <!doctype html>, and sends you off to debug a decoder that is working correctly.
Configuration. configure, getConfig, configuredWasmUrl and resolveAuth. One call points every codec at a wasm folder; an explicit per-decoder wasmUrl or wasmBytes still wins over it.
Errors. BitruviusError, BvxCode, BVX_CODES and asBitruviusError, plus abortError and isAbortError, which follow the WHATWG cancellation convention with a plain Error named AbortError rather than a DOMException, since that is not constructible in every worker or test realm.
Depending on it directly
Inside the SDK, @bitruvius/geo-core, @bitruvius/codec-runtime, @bitruvius/esri-auth, @bitruvius/sdk-maplibre and the codec packages all depend on it, which is why it is published at all.
Outside the SDK, reach for it in two cases: you are writing a custom RequestAuthorizer, or you are catching SDK errors and want the error type and code list at their source. Both are re-exported by @bitruvius/sdk-maplibre, so installing this package on its own is rarely the answer.
npm i @bitruvius/foundationimport { BitruviusError, configure } from '@bitruvius/foundation';
// Serve every codec's .wasm from one folder (note the trailing slash).
configure({ wasmBaseUrl: 'https://my.app/assets/bitruvius/' });
try {
await layer.load();
} catch (e) {
if (BitruviusError.is(e, 'BVX_GL_UNAVAILABLE')) showWebGl2Warning();
else throw e;
}Trademarks
Esri and ArcGIS are trademarks of Environmental Systems Research Institute, Inc. Cesium is a trademark of Cesium GS, Inc. Google is a trademark of Google LLC. MapLibre is a trademark of the MapLibre organization. All other marks are the property of their respective owners.
These names are used solely to describe the data formats this software interoperates with. WebGL is a trademark of The Khronos Group Inc.
Bitruvius is not affiliated with, sponsored by, or endorsed by any of them, and no such relationship is implied.
License
Proprietary. The full terms ship as LICENSE inside this package, and are readable
before installing at cdn.bitruvius.com/legal/sdk-license-v1.txt.
© Bitruvius, Inc.
