@diginestai/pmtiles — PMTiles Hosting & Protocol
@diginestai/pmtiles handles PMTiles protocol registration, hosting configuration, Service Worker offline caching, and Comlink-based range-request batching for the DigiNest Maps SDK.
Installation
pnpm add @diginestai/pmtilesQuick Start
The pmtiles:// protocol is registered automatically by <SpatialProvider> (via a module-level singleton). Use this package directly when you need hosting configuration, Service Worker caching, or manual protocol control.
import { validateHostingProfile, registerProtocol } from '@diginestai/pmtiles';
const profile: PMTilesHostingProfile = {
provider: 'cloudflare-r2',
bucketName: 'my-tiles',
publicUrl: 'https://tiles.example.com',
};
validateHostingProfile(profile);PMTilesHostingProfile
Discriminated union describing where PMTiles archives are served from.
Cloudflare R2
{
provider: 'cloudflare-r2';
bucketName: string;
publicUrl: string; // Public R2 bucket URL or custom domain
accountId?: string; // Required for private-bucket access
}AWS S3 + CloudFront
{
provider: 'aws-s3-cloudfront';
bucketName: string;
region: string; // e.g. 'us-east-1'
cloudfrontDomain: string; // e.g. 'abc123.cloudfront.net'
publicUrl: string; // CloudFront distribution URL
}Self-Hosted
{
provider: 'self-hosted';
publicUrl: string; // Custom origin URL
}Hosting Options
| Provider | Latency | Egress Cost | Notes |
|---|---|---|---|
| Cloudflare R2 | Lowest (edge cache) | Zero egress | Best default choice. Use accountId for private buckets. |
| AWS S3 + CloudFront | Low (CDN PoPs) | Standard CloudFront rates | Set Cache-Control: max-age=31536000 on .pmtiles objects. |
| Self-Hosted | Depends on infra | Depends on infra | Nginx / Caddy with Range request support required. |
API Reference
validateHostingProfile(profile)
Validates a PMTilesHostingProfile at runtime. Warns to the console if required fields are missing. Call once during app initialisation.
validateHostingProfile(profile); // throws/warns on malformed profilesregisterProtocol(map)
Registers the pmtiles:// URL protocol on a MapLibre-compatible map instance. Subsequent calls are no-ops (module-level singleton guard).
import { registerProtocol } from '@diginestai/pmtiles';
import maplibregl from 'maplibre-gl';
const map = new maplibregl.Map({ ... });
registerProtocol(map);unregisterProtocol(map)
Removes the pmtiles:// protocol and resets the singleton guard so registerProtocol can be called again after map unmount/remount.
createProtocol()
Returns a new configured pmtiles.Protocol instance for advanced use cases where you need direct control over the Protocol object.
registerSpatialServiceWorker(options?)
Registers the Spatial Service Worker that intercepts PMTiles range requests and caches responses in the Cache API for offline use.
import { registerSpatialServiceWorker } from '@diginestai/pmtiles';
await registerSpatialServiceWorker({
buildingIds: ['https://tiles.example.com/building-a'],
maxCacheBytes: 200 * 1024 * 1024, // 200 MB
});SWOptions
| Option | Type | Default | Description |
|---|---|---|---|
buildingIds | string[] | [] | PMTiles archive URLs to pre-cache on Service Worker install. |
maxCacheBytes | number | 0 (unlimited) | Maximum tile cache size. Evicts LRU entries when exceeded. |
swUrl | string | '/spatial-sw.js' | URL of the compiled Service Worker script. |
validatePMTilesUrl(url)
Validates a PMTiles URL string. Accepts pmtiles:// and https:// prefixes; rejects http:// and all other schemes.
import { validatePMTilesUrl } from '@diginestai/pmtiles';
const result = validatePMTilesUrl('pmtiles://https://tiles.example.com/building.pmtiles');
// { valid: true }
const bad = validatePMTilesUrl('http://tiles.example.com/building.pmtiles');
// { valid: false, error: 'Insecure http:// URLs are not allowed; use https:// or pmtiles://' }PMTilesUrlValidationResult
| Field | Type | Description |
|---|---|---|
valid | boolean | Whether the URL is acceptable. |
error | string? | Human-readable error message when valid is false. |
Comlink Worker
Range-request batching runs in a dedicated Web Worker via Comlink RPC. The worker is created by createPMTilesWorker() and is managed automatically by <SpatialProvider>. You rarely need to call this directly.
import { createPMTilesWorker } from '@diginestai/pmtiles';
const { api, terminate } = createPMTilesWorker();
// api satisfies PMTilesWorkerAPI
// Call terminate() on unmount/teardown — Comlink's releaseProxy() alone
// closes the MessagePort but does not stop the worker thread.
terminate();