From a062d92582ea06554018c9f8f19ee60d103256cb Mon Sep 17 00:00:00 2001 From: Yoel Ridgway-Lopez Date: Mon, 10 Feb 2025 16:20:08 +0100 Subject: [PATCH 1/5] made the serve_style.add and addStyle functions async and return promises --- src/serve_style.js | 15 +++++++++++---- src/server.js | 11 ++++++----- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/serve_style.js b/src/serve_style.js index 51b03d3de..ba6d0c89a 100644 --- a/src/serve_style.js +++ b/src/serve_style.js @@ -198,9 +198,9 @@ export const serve_style = { * @param {object} programOpts - An object containing the program options * @param {Function} reportTiles Function for reporting tile sources. * @param {Function} reportFont Function for reporting font usage - * @returns {boolean} true if add is succesful + * @returns {Promise} true if add is successful */ - add: function ( + add: async function ( options, repo, params, @@ -214,13 +214,20 @@ export const serve_style = { let styleFileData; try { - styleFileData = fs.readFileSync(styleFile); // TODO: could be made async if this function was + styleFileData = await fs.promises.readFile(styleFile); } catch (e) { console.log(`Error reading style file "${params.style}"`); return false; } - const styleJSON = JSON.parse(styleFileData); + let styleJSON; + try { + styleJSON = JSON.parse(styleFileData); + } catch (e) { + console.log(`Error parsing style JSON from "${params.style}"`); + return false; + } + const validationErrors = validateStyleMin(styleJSON); if (validationErrors.length > 0) { console.log(`The file "${params.style}" is not a valid style file:`); diff --git a/src/server.js b/src/server.js index 9a3f8a8e6..b619e0c98 100644 --- a/src/server.js +++ b/src/server.js @@ -178,12 +178,12 @@ async function start(opts) { * @param {object} item - The style configuration object. * @param {boolean} allowMoreData - Whether to allow adding more data sources. * @param {boolean} reportFonts - Whether to report fonts. - * @returns {void} + * @returns {Promise} */ - function addStyle(id, item, allowMoreData, reportFonts) { + async function addStyle(id, item, allowMoreData, reportFonts) { let success = true; if (item.serve_data !== false) { - success = serve_style.add( + success = await serve_style.add( options, serving.styles, item, @@ -271,6 +271,7 @@ async function start(opts) { item.serve_rendered = false; } } + return success; } for (const id of Object.keys(config.styles || {})) { @@ -279,8 +280,8 @@ async function start(opts) { console.log(`Missing "style" property for ${id}`); continue; } - - addStyle(id, item, true, true); + + startupPromises.push(addStyle(id, item, true, true)); } startupPromises.push( serve_font(options, serving.fonts, opts).then((sub) => { From 166130d142af6c9292c25cab5aec3f1b0bd71980 Mon Sep 17 00:00:00 2001 From: Yoel Ridgway-Lopez Date: Mon, 10 Feb 2025 17:30:40 +0100 Subject: [PATCH 2/5] added fetching to addStyle() function and parsed it into serve_style and serve_rendered --- src/serve_rendered.js | 11 +++-------- src/serve_style.js | 22 +++++----------------- src/server.js | 22 ++++++++++++++++++++++ 3 files changed, 30 insertions(+), 25 deletions(-) diff --git a/src/serve_rendered.js b/src/serve_rendered.js index 3dc3cd546..0a00d4908 100644 --- a/src/serve_rendered.js +++ b/src/serve_rendered.js @@ -1028,10 +1028,11 @@ export const serve_rendered = { * @param {object} params Parameters object. * @param {string} id ID of the item. * @param {object} programOpts - An object containing the program options + * @param {object} style pre-fetched/read StyleJSON object. * @param {Function} dataResolver Function to resolve data. * @returns {Promise} */ - add: async function (options, repo, params, id, programOpts, dataResolver) { + add: async function (options, repo, params, id, programOpts, style, dataResolver) { const map = { renderers: [], renderersStatic: [], @@ -1041,7 +1042,7 @@ export const serve_rendered = { const { publicUrl, verbose } = programOpts; - let styleJSON; + const styleJSON = clone(style); /** * Creates a pool of renderers. * @param {number} ratio Pixel ratio @@ -1230,12 +1231,6 @@ export const serve_rendered = { const styleFile = params.style; const styleJSONPath = path.resolve(options.paths.styles, styleFile); - try { - styleJSON = JSON.parse(await fsp.readFile(styleJSONPath)); - } catch (e) { - console.log('Error parsing style file'); - return false; - } if (styleJSON.sprite) { if (!Array.isArray(styleJSON.sprite)) { diff --git a/src/serve_style.js b/src/serve_style.js index ba6d0c89a..250a4eba2 100644 --- a/src/serve_style.js +++ b/src/serve_style.js @@ -12,6 +12,7 @@ import { allowedSpriteFormats, fixUrl, readFile, + isValidHttpUrl, } from './utils.js'; const httpTester = /^https?:\/\//i; @@ -196,6 +197,7 @@ export const serve_style = { * @param {object} params Parameters object containing style path * @param {string} id ID of the style. * @param {object} programOpts - An object containing the program options + * @param {object} style pre-fetched/read StyleJSON object. * @param {Function} reportTiles Function for reporting tile sources. * @param {Function} reportFont Function for reporting font usage * @returns {Promise} true if add is successful @@ -206,27 +208,13 @@ export const serve_style = { params, id, programOpts, + style, reportTiles, reportFont, ) { const { publicUrl } = programOpts; - const styleFile = path.resolve(options.paths.styles, params.style); - - let styleFileData; - try { - styleFileData = await fs.promises.readFile(styleFile); - } catch (e) { - console.log(`Error reading style file "${params.style}"`); - return false; - } - - let styleJSON; - try { - styleJSON = JSON.parse(styleFileData); - } catch (e) { - console.log(`Error parsing style JSON from "${params.style}"`); - return false; - } + const styleFile = path.resolve(options.paths.styles, params.style) + const styleJSON = clone(style); const validationErrors = validateStyleMin(styleJSON); if (validationErrors.length > 0) { diff --git a/src/server.js b/src/server.js index b619e0c98..e5bc96b1d 100644 --- a/src/server.js +++ b/src/server.js @@ -182,6 +182,26 @@ async function start(opts) { */ async function addStyle(id, item, allowMoreData, reportFonts) { let success = true; + + let styleJSON; + try { + if (isValidHttpUrl(item.style)){ + const res = await fetch(item.style); + if (!res.ok) { + throw new Error(`fetch error ${res.status}`); + } + styleJSON = await res.json(); + + } else { + const styleFile = path.resolve(options.paths.styles, item.style); + const styleFileData = await fs.promises.readFile(styleFile); + styleJSON = JSON.parse(styleFileData); + } + } catch (e) { + console.log(`Error getting style file "${item.style}"`); + return false; + } + if (item.serve_data !== false) { success = await serve_style.add( options, @@ -189,6 +209,7 @@ async function start(opts) { item, id, opts, + styleJSON, (styleSourceId, protocol) => { let dataItemId; for (const id of Object.keys(data)) { @@ -246,6 +267,7 @@ async function start(opts) { item, id, opts, + styleJSON, function dataResolver(styleSourceId) { let fileType; let inputFile; From 61422e171f6517052028a482b8d706c5934ebd49 Mon Sep 17 00:00:00 2001 From: Yoel Ridgway-Lopez Date: Mon, 10 Feb 2025 17:35:55 +0100 Subject: [PATCH 3/5] fixed linting issues --- src/serve_rendered.js | 10 +++++++++- src/serve_style.js | 2 +- src/server.js | 4 +--- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/serve_rendered.js b/src/serve_rendered.js index 0a00d4908..5d87b20ae 100644 --- a/src/serve_rendered.js +++ b/src/serve_rendered.js @@ -1032,7 +1032,15 @@ export const serve_rendered = { * @param {Function} dataResolver Function to resolve data. * @returns {Promise} */ - add: async function (options, repo, params, id, programOpts, style, dataResolver) { + add: async function ( + options, + repo, + params, + id, + programOpts, + style, + dataResolver, + ) { const map = { renderers: [], renderersStatic: [], diff --git a/src/serve_style.js b/src/serve_style.js index 250a4eba2..2e19d3f8e 100644 --- a/src/serve_style.js +++ b/src/serve_style.js @@ -213,7 +213,7 @@ export const serve_style = { reportFont, ) { const { publicUrl } = programOpts; - const styleFile = path.resolve(options.paths.styles, params.style) + const styleFile = path.resolve(options.paths.styles, params.style); const styleJSON = clone(style); const validationErrors = validateStyleMin(styleJSON); diff --git a/src/server.js b/src/server.js index e5bc96b1d..ea8c69a66 100644 --- a/src/server.js +++ b/src/server.js @@ -185,13 +185,12 @@ async function start(opts) { let styleJSON; try { - if (isValidHttpUrl(item.style)){ + if (isValidHttpUrl(item.style)) { const res = await fetch(item.style); if (!res.ok) { throw new Error(`fetch error ${res.status}`); } styleJSON = await res.json(); - } else { const styleFile = path.resolve(options.paths.styles, item.style); const styleFileData = await fs.promises.readFile(styleFile); @@ -302,7 +301,6 @@ async function start(opts) { console.log(`Missing "style" property for ${id}`); continue; } - startupPromises.push(addStyle(id, item, true, true)); } startupPromises.push( From 9c978d4a484764118fca2927c922496b51c584cf Mon Sep 17 00:00:00 2001 From: Yoel Ridgway-Lopez Date: Mon, 10 Feb 2025 18:08:55 +0100 Subject: [PATCH 4/5] removed async from synchronous functions --- src/serve_style.js | 5 ++--- src/server.js | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/serve_style.js b/src/serve_style.js index 2e19d3f8e..a9c96f64b 100644 --- a/src/serve_style.js +++ b/src/serve_style.js @@ -12,7 +12,6 @@ import { allowedSpriteFormats, fixUrl, readFile, - isValidHttpUrl, } from './utils.js'; const httpTester = /^https?:\/\//i; @@ -200,9 +199,9 @@ export const serve_style = { * @param {object} style pre-fetched/read StyleJSON object. * @param {Function} reportTiles Function for reporting tile sources. * @param {Function} reportFont Function for reporting font usage - * @returns {Promise} true if add is successful + * @returns {boolean} true if add is successful */ - add: async function ( + add: function ( options, repo, params, diff --git a/src/server.js b/src/server.js index ea8c69a66..fe1338ded 100644 --- a/src/server.js +++ b/src/server.js @@ -202,7 +202,7 @@ async function start(opts) { } if (item.serve_data !== false) { - success = await serve_style.add( + success = serve_style.add( options, serving.styles, item, From 924a840f847cc14c025497150d3b70e14761e8d9 Mon Sep 17 00:00:00 2001 From: Yoel Ridgway-Lopez Date: Mon, 10 Feb 2025 18:23:24 +0100 Subject: [PATCH 5/5] added fetch example to docs --- docs/config.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/config.rst b/docs/config.rst index cb84e4690..267fef9dc 100644 --- a/docs/config.rst +++ b/docs/config.rst @@ -57,6 +57,9 @@ Example: "tilejson": { "format": "webp" } + }, + "remote": { + "style": "https://demotiles.maplibre.org/style.json" } }, "data": { @@ -209,7 +212,7 @@ Not used by default. Each item in this object defines one style (map). It can have the following options: -* ``style`` -- name of the style json file [required] +* ``style`` -- name of the style json file or url of a remote hosted style [required] * ``serve_rendered`` -- whether to render the raster tiles for this style or not * ``serve_data`` -- whether to allow access to the original tiles, sprites and required glyphs * ``tilejson`` -- properties to add to the TileJSON created for the raster data