Skip to content

@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

bash
pnpm add @diginestai/pmtiles

Quick 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.

tsx
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

typescript
{
  provider: 'cloudflare-r2';
  bucketName: string;
  publicUrl: string;           // Public R2 bucket URL or custom domain
  accountId?: string;          // Required for private-bucket access
}

AWS S3 + CloudFront

typescript
{
  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

typescript
{
  provider: 'self-hosted';
  publicUrl: string;           // Custom origin URL
}

Hosting Options

ProviderLatencyEgress CostNotes
Cloudflare R2Lowest (edge cache)Zero egressBest default choice. Use accountId for private buckets.
AWS S3 + CloudFrontLow (CDN PoPs)Standard CloudFront ratesSet Cache-Control: max-age=31536000 on .pmtiles objects.
Self-HostedDepends on infraDepends on infraNginx / 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.

typescript
validateHostingProfile(profile); // throws/warns on malformed profiles

registerProtocol(map)

Registers the pmtiles:// URL protocol on a MapLibre-compatible map instance. Subsequent calls are no-ops (module-level singleton guard).

typescript
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.

typescript
import { registerSpatialServiceWorker } from '@diginestai/pmtiles';

await registerSpatialServiceWorker({
  buildingIds: ['https://tiles.example.com/building-a'],
  maxCacheBytes: 200 * 1024 * 1024, // 200 MB
});

SWOptions

OptionTypeDefaultDescription
buildingIdsstring[][]PMTiles archive URLs to pre-cache on Service Worker install.
maxCacheBytesnumber0 (unlimited)Maximum tile cache size. Evicts LRU entries when exceeded.
swUrlstring'/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.

typescript
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

FieldTypeDescription
validbooleanWhether the URL is acceptable.
errorstring?Human-readable error message when valid is false.

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.

typescript
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();

Released under commercial licensing.