@india-boundary-corrector/maplibre-protocol 0.0.4 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/dist/index.cjs +9 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.global.js +784 -158
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +9 -4
- package/dist/index.js.map +1 -1
- package/dist/india_boundary_corrections.pmtiles +0 -0
- package/dist/india_boundary_corrections.pmtiles.gz +0 -0
- package/package.json +4 -4
- package/src/index.js +12 -4
package/README.md
CHANGED
|
@@ -106,8 +106,9 @@ protocol.addLayerConfig(new LayerConfig({
|
|
|
106
106
|
tileUrlTemplates: ['https://tile.openstreetmap.de/{z}/{x}/{y}.png'],
|
|
107
107
|
lineWidthStops: { 1: 0.5, 2: 0.6, 3: 0.7, 4: 1.0, 10: 3.75 },
|
|
108
108
|
lineStyles: [
|
|
109
|
-
|
|
110
|
-
{ color: 'rgb(
|
|
109
|
+
// layerSuffix determines which PMTiles layer to use
|
|
110
|
+
{ color: 'rgb(180, 200, 180)', layerSuffix: 'osm' },
|
|
111
|
+
{ color: 'rgb(121, 146, 127)', layerSuffix: 'osm', widthFraction: 1/3, dashArray: [30, 2, 8, 2] },
|
|
111
112
|
],
|
|
112
113
|
}));
|
|
113
114
|
|
package/dist/index.cjs
CHANGED
|
@@ -186,16 +186,21 @@ var CorrectionProtocol = class {
|
|
|
186
186
|
} else {
|
|
187
187
|
layerConfig = self._registry.detectFromTileUrls([tileUrl]);
|
|
188
188
|
}
|
|
189
|
+
const fetchOptions = {
|
|
190
|
+
signal: abortController?.signal,
|
|
191
|
+
credentials: params.credentials ?? "same-origin"
|
|
192
|
+
};
|
|
193
|
+
if (params.credentials === "include") {
|
|
194
|
+
fetchOptions.mode = "cors";
|
|
195
|
+
}
|
|
189
196
|
const { data, correctionsFailed, correctionsError } = await self._tileFixer.fetchAndFixTile(
|
|
190
197
|
tileUrl,
|
|
191
198
|
z,
|
|
192
199
|
x,
|
|
193
200
|
y,
|
|
194
201
|
layerConfig,
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
fallbackOnCorrectionFailure: self._fallbackOnCorrectionFailure
|
|
198
|
-
}
|
|
202
|
+
fetchOptions,
|
|
203
|
+
self._fallbackOnCorrectionFailure
|
|
199
204
|
);
|
|
200
205
|
if (correctionsFailed && correctionsError?.name !== "AbortError") {
|
|
201
206
|
console.warn("[CorrectionProtocol] Corrections fetch failed:", correctionsError);
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.js"],"sourcesContent":["import { getPmtilesUrl } from '@india-boundary-corrector/data';\nimport { layerConfigs } from '@india-boundary-corrector/layer-configs';\nimport { TileFixer } from '@india-boundary-corrector/tilefixer';\n\n// Re-export for convenience\nexport { layerConfigs, LayerConfig } from '@india-boundary-corrector/layer-configs';\nexport { getPmtilesUrl } from '@india-boundary-corrector/data';\n\nconst PROTOCOL_PREFIX = 'ibc';\n\n/**\n * Extract tile coordinates from a URL using generic z/x/y pattern matching.\n * Handles standard tile URL patterns including retina suffixes (@2x, @3x, etc.).\n * \n * @param {string} url - The tile URL to parse\n * @returns {{ z: number, x: number, y: number } | null} Parsed coordinates or null if not found\n */\nfunction extractTileCoordsFromUrl(url) {\n try {\n const urlObj = new URL(url);\n const pathParts = urlObj.pathname.split('/').filter(p => p.length > 0);\n \n // Find z/x/y pattern - typically last 3 numeric segments\n for (let i = pathParts.length - 1; i >= 2; i--) {\n // Remove extension and retina suffix (e.g., \"5@2x.png\" -> \"5\")\n const yPart = pathParts[i].replace(/(@\\d+x)?\\.[^.]+$/, '');\n const xPart = pathParts[i - 1];\n const zPart = pathParts[i - 2];\n \n if (/^\\d+$/.test(zPart) && /^\\d+$/.test(xPart) && /^\\d+$/.test(yPart)) {\n return {\n z: parseInt(zPart, 10),\n x: parseInt(xPart, 10),\n y: parseInt(yPart, 10)\n };\n }\n }\n } catch {\n // Invalid URL\n }\n return null;\n}\n\n/**\n * Parse an ibc:// URL.\n * Format: ibc://[configId@]originalUrl\n * Examples:\n * ibc://https://tile.openstreetmap.org/{z}/{x}/{y}.png\n * ibc://osm-carto@https://tile.openstreetmap.org/{z}/{x}/{y}.png\n * \n * @param {string} url - The full URL with ibc:// prefix\n * @param {import('@india-boundary-corrector/layer-configs').LayerConfigRegistry} registry - Registry to use for parsing\n * @returns {{ configId: string|null, tileUrl: string, z: number|undefined, x: number|undefined, y: number|undefined }}\n */\nfunction parseCorrectionsUrl(url, registry) {\n // Remove protocol prefix\n const withoutProtocol = url.replace(`${PROTOCOL_PREFIX}://`, '');\n \n // Check for configId@url format\n let configId = null;\n let tileUrl = withoutProtocol;\n \n const atIndex = withoutProtocol.indexOf('@');\n const slashIndex = withoutProtocol.indexOf('/');\n // Config ID exists if @ comes before first / (or if there's no /)\n if (atIndex > 0 && (slashIndex === -1 || atIndex < slashIndex)) {\n // Has configId prefix\n configId = withoutProtocol.substring(0, atIndex);\n tileUrl = withoutProtocol.substring(atIndex + 1);\n }\n \n // If configId is explicit, use generic parsing (URL may not match config's patterns)\n // Otherwise, use registry detection only (unregistered URLs won't get corrections)\n let coords = null;\n if (configId) {\n coords = extractTileCoordsFromUrl(tileUrl);\n } else {\n const parsed = registry.parseTileUrl(tileUrl);\n coords = parsed?.coords ?? null;\n }\n \n return { \n configId, \n tileUrl, \n z: coords?.z, \n x: coords?.x, \n y: coords?.y \n };\n}\n\n/**\n * India boundary corrections protocol for MapLibre GL.\n * \n * Usage:\n * const protocol = new CorrectionProtocol();\n * protocol.register(maplibregl);\n * \n * // In your style:\n * tiles: ['ibc://https://tile.openstreetmap.org/{z}/{x}/{y}.png']\n * // Or with explicit config:\n * tiles: ['ibc://osm-carto@https://tile.openstreetmap.org/{z}/{x}/{y}.png']\n */\nexport class CorrectionProtocol {\n /**\n * @param {Object} [options]\n * @param {string} [options.pmtilesUrl] - URL to PMTiles file (defaults to CDN)\n * @param {boolean} [options.fallbackOnCorrectionFailure=true] - Return original tile if corrections fail\n */\n constructor(options = {}) {\n this._pmtilesUrl = options.pmtilesUrl ?? getPmtilesUrl();\n this._fallbackOnCorrectionFailure = options.fallbackOnCorrectionFailure ?? true;\n this._tileFixer = TileFixer.getOrCreate(this._pmtilesUrl);\n this._registry = layerConfigs.createMergedRegistry();\n /** @type {Map<string, Set<Function>>} */\n this._listeners = new Map();\n \n this._loadFn = this._createLoadFunction();\n }\n\n /**\n * Add a listener for an event.\n * @param {'correctionerror'} event - Event name\n * @param {Function} listener - Callback function receiving event data\n * @returns {this}\n */\n on(event, listener) {\n if (!this._listeners.has(event)) {\n this._listeners.set(event, new Set());\n }\n this._listeners.get(event).add(listener);\n return this;\n }\n\n /**\n * Remove an event listener.\n * @param {'correctionerror'} event - Event name\n * @param {Function} listener - Callback to remove\n * @returns {this}\n */\n off(event, listener) {\n this._listeners.get(event)?.delete(listener);\n return this;\n }\n\n /**\n * Emit an event to all listeners.\n * @param {string} event - Event name\n * @param {Object} data - Event data\n * @private\n */\n _emit(event, data) {\n this._listeners.get(event)?.forEach(fn => fn(data));\n }\n\n /**\n * Add a custom layer config to the registry.\n * @param {Object} layerConfig - LayerConfig to add\n * @returns {this}\n */\n addLayerConfig(layerConfig) {\n this._registry.register(layerConfig);\n return this;\n }\n\n /**\n * Get the registry.\n * @returns {LayerConfigRegistry}\n */\n getRegistry() {\n return this._registry;\n }\n\n /**\n * Get the TileFixer instance.\n * @returns {TileFixer}\n */\n getTileFixer() {\n return this._tileFixer;\n }\n\n /**\n * Register the protocol with MapLibre GL.\n * @param {typeof import('maplibre-gl')} maplibregl - MapLibre GL namespace\n * @returns {this}\n */\n register(maplibregl) {\n maplibregl.addProtocol(PROTOCOL_PREFIX, this._loadFn);\n return this;\n }\n\n /**\n * Unregister the protocol from MapLibre GL.\n * @param {typeof import('maplibre-gl')} maplibregl - MapLibre GL namespace\n * @returns {this}\n */\n unregister(maplibregl) {\n maplibregl.removeProtocol(PROTOCOL_PREFIX);\n return this;\n }\n\n /**\n * Create the protocol load function.\n * @returns {Function}\n * @private\n */\n _createLoadFunction() {\n const self = this;\n \n return async (params, abortController) => {\n const { configId, tileUrl, z, x, y } = parseCorrectionsUrl(params.url, self._registry);\n \n // Validate parsed coordinates\n if (z === undefined || x === undefined || y === undefined) {\n console.warn(`[CorrectionProtocol] Could not parse tile coordinates from URL: ${params.url}, falling back to original`);\n const response = await fetch(tileUrl, { signal: abortController?.signal });\n return { data: await response.arrayBuffer() };\n }\n \n // Resolve layer config\n let layerConfig;\n if (configId) {\n layerConfig = self._registry.get(configId);\n } else {\n layerConfig = self._registry.detectFromTileUrls([tileUrl]);\n }\n \n const { data, correctionsFailed, correctionsError } = await self._tileFixer.fetchAndFixTile(\n tileUrl, z, x, y, layerConfig, { \n signal: abortController?.signal,\n fallbackOnCorrectionFailure: self._fallbackOnCorrectionFailure\n }\n );\n \n if (correctionsFailed && correctionsError?.name !== 'AbortError') {\n console.warn('[CorrectionProtocol] Corrections fetch failed:', correctionsError);\n self._emit('correctionerror', { error: correctionsError, coords: { z, x, y }, tileUrl });\n }\n \n return { data };\n };\n }\n}\n\n/**\n * Create and register a correction protocol with MapLibre GL.\n * \n * @param {typeof import('maplibre-gl')} maplibregl - MapLibre GL namespace\n * @param {Object} [options] - Protocol options\n * @param {string} [options.pmtilesUrl] - URL to PMTiles file\n * @param {boolean} [options.fallbackOnCorrectionFailure=true] - Return original tile if corrections fail\n * @returns {CorrectionProtocol}\n * \n * @example\n * import maplibregl from 'maplibre-gl';\n * import { registerCorrectionProtocol } from '@india-boundary-corrector/maplibre-protocol';\n * \n * const protocol = registerCorrectionProtocol(maplibregl);\n * \n * // Use in style:\n * const map = new maplibregl.Map({\n * container: 'map',\n * style: {\n * sources: {\n * osm: {\n * type: 'raster',\n * tiles: ['ibc://https://tile.openstreetmap.org/{z}/{x}/{y}.png'],\n * tileSize: 256,\n * attribution: '© OpenStreetMap contributors'\n * }\n * },\n * layers: [{ id: 'osm', type: 'raster', source: 'osm' }]\n * }\n * });\n */\nexport function registerCorrectionProtocol(maplibregl, options = {}) {\n const protocol = new CorrectionProtocol(options);\n return protocol.register(maplibregl);\n}\n\n// Export for testing\nexport { parseCorrectionsUrl };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAA8B;AAC9B,2BAA6B;AAC7B,uBAA0B;AAG1B,IAAAA,wBAA0C;AAC1C,IAAAC,eAA8B;AAE9B,IAAM,kBAAkB;AASxB,SAAS,yBAAyB,KAAK;AACrC,MAAI;AACF,UAAM,SAAS,IAAI,IAAI,GAAG;AAC1B,UAAM,YAAY,OAAO,SAAS,MAAM,GAAG,EAAE,OAAO,OAAK,EAAE,SAAS,CAAC;AAGrE,aAAS,IAAI,UAAU,SAAS,GAAG,KAAK,GAAG,KAAK;AAE9C,YAAM,QAAQ,UAAU,CAAC,EAAE,QAAQ,oBAAoB,EAAE;AACzD,YAAM,QAAQ,UAAU,IAAI,CAAC;AAC7B,YAAM,QAAQ,UAAU,IAAI,CAAC;AAE7B,UAAI,QAAQ,KAAK,KAAK,KAAK,QAAQ,KAAK,KAAK,KAAK,QAAQ,KAAK,KAAK,GAAG;AACrE,eAAO;AAAA,UACL,GAAG,SAAS,OAAO,EAAE;AAAA,UACrB,GAAG,SAAS,OAAO,EAAE;AAAA,UACrB,GAAG,SAAS,OAAO,EAAE;AAAA,QACvB;AAAA,MACF;AAAA,IACF;AAAA,EACF,QAAQ;AAAA,EAER;AACA,SAAO;AACT;AAaA,SAAS,oBAAoB,KAAK,UAAU;AAE1C,QAAM,kBAAkB,IAAI,QAAQ,GAAG,eAAe,OAAO,EAAE;AAG/D,MAAI,WAAW;AACf,MAAI,UAAU;AAEd,QAAM,UAAU,gBAAgB,QAAQ,GAAG;AAC3C,QAAM,aAAa,gBAAgB,QAAQ,GAAG;AAE9C,MAAI,UAAU,MAAM,eAAe,MAAM,UAAU,aAAa;AAE9D,eAAW,gBAAgB,UAAU,GAAG,OAAO;AAC/C,cAAU,gBAAgB,UAAU,UAAU,CAAC;AAAA,EACjD;AAIA,MAAI,SAAS;AACb,MAAI,UAAU;AACZ,aAAS,yBAAyB,OAAO;AAAA,EAC3C,OAAO;AACL,UAAM,SAAS,SAAS,aAAa,OAAO;AAC5C,aAAS,QAAQ,UAAU;AAAA,EAC7B;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,GAAG,QAAQ;AAAA,IACX,GAAG,QAAQ;AAAA,IACX,GAAG,QAAQ;AAAA,EACb;AACF;AAcO,IAAM,qBAAN,MAAyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAM9B,YAAY,UAAU,CAAC,GAAG;AACxB,SAAK,cAAc,QAAQ,kBAAc,2BAAc;AACvD,SAAK,+BAA+B,QAAQ,+BAA+B;AAC3E,SAAK,aAAa,2BAAU,YAAY,KAAK,WAAW;AACxD,SAAK,YAAY,kCAAa,qBAAqB;AAEnD,SAAK,aAAa,oBAAI,IAAI;AAE1B,SAAK,UAAU,KAAK,oBAAoB;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,GAAG,OAAO,UAAU;AAClB,QAAI,CAAC,KAAK,WAAW,IAAI,KAAK,GAAG;AAC/B,WAAK,WAAW,IAAI,OAAO,oBAAI,IAAI,CAAC;AAAA,IACtC;AACA,SAAK,WAAW,IAAI,KAAK,EAAE,IAAI,QAAQ;AACvC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,IAAI,OAAO,UAAU;AACnB,SAAK,WAAW,IAAI,KAAK,GAAG,OAAO,QAAQ;AAC3C,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,OAAO,MAAM;AACjB,SAAK,WAAW,IAAI,KAAK,GAAG,QAAQ,QAAM,GAAG,IAAI,CAAC;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,eAAe,aAAa;AAC1B,SAAK,UAAU,SAAS,WAAW;AACnC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,cAAc;AACZ,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,eAAe;AACb,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,SAAS,YAAY;AACnB,eAAW,YAAY,iBAAiB,KAAK,OAAO;AACpD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,WAAW,YAAY;AACrB,eAAW,eAAe,eAAe;AACzC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,sBAAsB;AACpB,UAAM,OAAO;AAEb,WAAO,OAAO,QAAQ,oBAAoB;AACxC,YAAM,EAAE,UAAU,SAAS,GAAG,GAAG,EAAE,IAAI,oBAAoB,OAAO,KAAK,KAAK,SAAS;AAGrF,UAAI,MAAM,UAAa,MAAM,UAAa,MAAM,QAAW;AACzD,gBAAQ,KAAK,mEAAmE,OAAO,GAAG,4BAA4B;AACtH,cAAM,WAAW,MAAM,MAAM,SAAS,EAAE,QAAQ,iBAAiB,OAAO,CAAC;AACzE,eAAO,EAAE,MAAM,MAAM,SAAS,YAAY,EAAE;AAAA,MAC9C;AAGA,UAAI;AACJ,UAAI,UAAU;AACZ,sBAAc,KAAK,UAAU,IAAI,QAAQ;AAAA,MAC3C,OAAO;AACL,sBAAc,KAAK,UAAU,mBAAmB,CAAC,OAAO,CAAC;AAAA,MAC3D;AAEA,YAAM,EAAE,MAAM,mBAAmB,iBAAiB,IAAI,MAAM,KAAK,WAAW;AAAA,QAC1E;AAAA,QAAS;AAAA,QAAG;AAAA,QAAG;AAAA,QAAG;AAAA,QAAa;AAAA,UAC7B,QAAQ,iBAAiB;AAAA,UACzB,6BAA6B,KAAK;AAAA,QACpC;AAAA,MACF;AAEA,UAAI,qBAAqB,kBAAkB,SAAS,cAAc;AAChE,gBAAQ,KAAK,kDAAkD,gBAAgB;AAC/E,aAAK,MAAM,mBAAmB,EAAE,OAAO,kBAAkB,QAAQ,EAAE,GAAG,GAAG,EAAE,GAAG,QAAQ,CAAC;AAAA,MACzF;AAEA,aAAO,EAAE,KAAK;AAAA,IAChB;AAAA,EACF;AACF;AAiCO,SAAS,2BAA2B,YAAY,UAAU,CAAC,GAAG;AACnE,QAAM,WAAW,IAAI,mBAAmB,OAAO;AAC/C,SAAO,SAAS,SAAS,UAAU;AACrC;","names":["import_layer_configs","import_data"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.js"],"sourcesContent":["import { getPmtilesUrl } from '@india-boundary-corrector/data';\nimport { layerConfigs } from '@india-boundary-corrector/layer-configs';\nimport { TileFixer } from '@india-boundary-corrector/tilefixer';\n\n// Re-export for convenience\nexport { layerConfigs, LayerConfig } from '@india-boundary-corrector/layer-configs';\nexport { getPmtilesUrl } from '@india-boundary-corrector/data';\n\nconst PROTOCOL_PREFIX = 'ibc';\n\n/**\n * Extract tile coordinates from a URL using generic z/x/y pattern matching.\n * Handles standard tile URL patterns including retina suffixes (@2x, @3x, etc.).\n * \n * @param {string} url - The tile URL to parse\n * @returns {{ z: number, x: number, y: number } | null} Parsed coordinates or null if not found\n */\nfunction extractTileCoordsFromUrl(url) {\n try {\n const urlObj = new URL(url);\n const pathParts = urlObj.pathname.split('/').filter(p => p.length > 0);\n \n // Find z/x/y pattern - typically last 3 numeric segments\n for (let i = pathParts.length - 1; i >= 2; i--) {\n // Remove extension and retina suffix (e.g., \"5@2x.png\" -> \"5\")\n const yPart = pathParts[i].replace(/(@\\d+x)?\\.[^.]+$/, '');\n const xPart = pathParts[i - 1];\n const zPart = pathParts[i - 2];\n \n if (/^\\d+$/.test(zPart) && /^\\d+$/.test(xPart) && /^\\d+$/.test(yPart)) {\n return {\n z: parseInt(zPart, 10),\n x: parseInt(xPart, 10),\n y: parseInt(yPart, 10)\n };\n }\n }\n } catch {\n // Invalid URL\n }\n return null;\n}\n\n/**\n * Parse an ibc:// URL.\n * Format: ibc://[configId@]originalUrl\n * Examples:\n * ibc://https://tile.openstreetmap.org/{z}/{x}/{y}.png\n * ibc://osm-carto@https://tile.openstreetmap.org/{z}/{x}/{y}.png\n * \n * @param {string} url - The full URL with ibc:// prefix\n * @param {import('@india-boundary-corrector/layer-configs').LayerConfigRegistry} registry - Registry to use for parsing\n * @returns {{ configId: string|null, tileUrl: string, z: number|undefined, x: number|undefined, y: number|undefined }}\n */\nfunction parseCorrectionsUrl(url, registry) {\n // Remove protocol prefix\n const withoutProtocol = url.replace(`${PROTOCOL_PREFIX}://`, '');\n \n // Check for configId@url format\n let configId = null;\n let tileUrl = withoutProtocol;\n \n const atIndex = withoutProtocol.indexOf('@');\n const slashIndex = withoutProtocol.indexOf('/');\n // Config ID exists if @ comes before first / (or if there's no /)\n if (atIndex > 0 && (slashIndex === -1 || atIndex < slashIndex)) {\n // Has configId prefix\n configId = withoutProtocol.substring(0, atIndex);\n tileUrl = withoutProtocol.substring(atIndex + 1);\n }\n \n // If configId is explicit, use generic parsing (URL may not match config's patterns)\n // Otherwise, use registry detection only (unregistered URLs won't get corrections)\n let coords = null;\n if (configId) {\n coords = extractTileCoordsFromUrl(tileUrl);\n } else {\n const parsed = registry.parseTileUrl(tileUrl);\n coords = parsed?.coords ?? null;\n }\n \n return { \n configId, \n tileUrl, \n z: coords?.z, \n x: coords?.x, \n y: coords?.y \n };\n}\n\n/**\n * India boundary corrections protocol for MapLibre GL.\n * \n * Usage:\n * const protocol = new CorrectionProtocol();\n * protocol.register(maplibregl);\n * \n * // In your style:\n * tiles: ['ibc://https://tile.openstreetmap.org/{z}/{x}/{y}.png']\n * // Or with explicit config:\n * tiles: ['ibc://osm-carto@https://tile.openstreetmap.org/{z}/{x}/{y}.png']\n */\nexport class CorrectionProtocol {\n /**\n * @param {Object} [options]\n * @param {string} [options.pmtilesUrl] - URL to PMTiles file (defaults to CDN)\n * @param {boolean} [options.fallbackOnCorrectionFailure=true] - Return original tile if corrections fail\n */\n constructor(options = {}) {\n this._pmtilesUrl = options.pmtilesUrl ?? getPmtilesUrl();\n this._fallbackOnCorrectionFailure = options.fallbackOnCorrectionFailure ?? true;\n this._tileFixer = TileFixer.getOrCreate(this._pmtilesUrl);\n this._registry = layerConfigs.createMergedRegistry();\n /** @type {Map<string, Set<Function>>} */\n this._listeners = new Map();\n \n this._loadFn = this._createLoadFunction();\n }\n\n /**\n * Add a listener for an event.\n * @param {'correctionerror'} event - Event name\n * @param {Function} listener - Callback function receiving event data\n * @returns {this}\n */\n on(event, listener) {\n if (!this._listeners.has(event)) {\n this._listeners.set(event, new Set());\n }\n this._listeners.get(event).add(listener);\n return this;\n }\n\n /**\n * Remove an event listener.\n * @param {'correctionerror'} event - Event name\n * @param {Function} listener - Callback to remove\n * @returns {this}\n */\n off(event, listener) {\n this._listeners.get(event)?.delete(listener);\n return this;\n }\n\n /**\n * Emit an event to all listeners.\n * @param {string} event - Event name\n * @param {Object} data - Event data\n * @private\n */\n _emit(event, data) {\n this._listeners.get(event)?.forEach(fn => fn(data));\n }\n\n /**\n * Add a custom layer config to the registry.\n * @param {Object} layerConfig - LayerConfig to add\n * @returns {this}\n */\n addLayerConfig(layerConfig) {\n this._registry.register(layerConfig);\n return this;\n }\n\n /**\n * Get the registry.\n * @returns {LayerConfigRegistry}\n */\n getRegistry() {\n return this._registry;\n }\n\n /**\n * Get the TileFixer instance.\n * @returns {TileFixer}\n */\n getTileFixer() {\n return this._tileFixer;\n }\n\n /**\n * Register the protocol with MapLibre GL.\n * @param {typeof import('maplibre-gl')} maplibregl - MapLibre GL namespace\n * @returns {this}\n */\n register(maplibregl) {\n maplibregl.addProtocol(PROTOCOL_PREFIX, this._loadFn);\n return this;\n }\n\n /**\n * Unregister the protocol from MapLibre GL.\n * @param {typeof import('maplibre-gl')} maplibregl - MapLibre GL namespace\n * @returns {this}\n */\n unregister(maplibregl) {\n maplibregl.removeProtocol(PROTOCOL_PREFIX);\n return this;\n }\n\n /**\n * Create the protocol load function.\n * @returns {Function}\n * @private\n */\n _createLoadFunction() {\n const self = this;\n \n return async (params, abortController) => {\n const { configId, tileUrl, z, x, y } = parseCorrectionsUrl(params.url, self._registry);\n \n // Validate parsed coordinates\n if (z === undefined || x === undefined || y === undefined) {\n console.warn(`[CorrectionProtocol] Could not parse tile coordinates from URL: ${params.url}, falling back to original`);\n const response = await fetch(tileUrl, { signal: abortController?.signal });\n return { data: await response.arrayBuffer() };\n }\n \n // Resolve layer config\n let layerConfig;\n if (configId) {\n layerConfig = self._registry.get(configId);\n } else {\n layerConfig = self._registry.detectFromTileUrls([tileUrl]);\n }\n \n // Build fetch options from request parameters\n // MapLibre's default is same-origin for credentials\n const fetchOptions = {\n signal: abortController?.signal,\n credentials: params.credentials ?? 'same-origin',\n };\n // Set mode to cors if credentials are explicitly set to include\n if (params.credentials === 'include') {\n fetchOptions.mode = 'cors';\n }\n \n const { data, correctionsFailed, correctionsError } = await self._tileFixer.fetchAndFixTile(\n tileUrl, z, x, y, layerConfig, fetchOptions, self._fallbackOnCorrectionFailure\n );\n \n if (correctionsFailed && correctionsError?.name !== 'AbortError') {\n console.warn('[CorrectionProtocol] Corrections fetch failed:', correctionsError);\n self._emit('correctionerror', { error: correctionsError, coords: { z, x, y }, tileUrl });\n }\n \n return { data };\n };\n }\n}\n\n/**\n * Create and register a correction protocol with MapLibre GL.\n * \n * @param {typeof import('maplibre-gl')} maplibregl - MapLibre GL namespace\n * @param {Object} [options] - Protocol options\n * @param {string} [options.pmtilesUrl] - URL to PMTiles file\n * @param {boolean} [options.fallbackOnCorrectionFailure=true] - Return original tile if corrections fail\n * @returns {CorrectionProtocol}\n * \n * @example\n * import maplibregl from 'maplibre-gl';\n * import { registerCorrectionProtocol } from '@india-boundary-corrector/maplibre-protocol';\n * \n * const protocol = registerCorrectionProtocol(maplibregl);\n * \n * // Use in style:\n * const map = new maplibregl.Map({\n * container: 'map',\n * style: {\n * sources: {\n * osm: {\n * type: 'raster',\n * tiles: ['ibc://https://tile.openstreetmap.org/{z}/{x}/{y}.png'],\n * tileSize: 256,\n * attribution: '© OpenStreetMap contributors'\n * }\n * },\n * layers: [{ id: 'osm', type: 'raster', source: 'osm' }]\n * }\n * });\n */\nexport function registerCorrectionProtocol(maplibregl, options = {}) {\n const protocol = new CorrectionProtocol(options);\n return protocol.register(maplibregl);\n}\n\n// Export for testing\nexport { parseCorrectionsUrl };\n"],"mappings":"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","names":["import_layer_configs","import_data"]}
|