tileserver-gl-light 5.2.0-pre.0 → 5.2.0-pre.2

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.
@@ -21,6 +21,11 @@ jobs:
21
21
  with:
22
22
  ref: ${{ github.event.pull_request.head.sha }}
23
23
 
24
+ - name: Install dependencies (Ubuntu) 🚀
25
+ run: >-
26
+ sudo apt-get install -qq libcairo2-dev libjpeg8-dev libpango1.0-dev
27
+ libgif-dev build-essential
28
+
24
29
  - name: Setup node env 📦
25
30
  uses: actions/setup-node@v4
26
31
  with:
@@ -65,6 +65,22 @@ jobs:
65
65
  context: .
66
66
  push: false
67
67
  platforms: linux/arm64,linux/amd64
68
- # experimental: https://github.com/docker/build-push-action/blob/master/docs/advanced/cache.md#cache-backend-api
68
+ cache-from: type=gha
69
+ cache-to: type=gha,mode=max
70
+
71
+ - name: Create Tileserver Light Directory
72
+ run: node publish.js --no-publish
73
+
74
+ - name: Install node dependencies
75
+ run: npm ci --prefer-offline --no-audit
76
+ working-directory: ./light
77
+
78
+ - name: Test Light Version to Docker Hub
79
+ uses: docker/build-push-action@v6
80
+ with:
81
+ context: ./light
82
+ file: ./light/Dockerfile
83
+ push: false
84
+ platforms: linux/arm64,linux/amd64
69
85
  cache-from: type=gha
70
86
  cache-to: type=gha,mode=max
package/CHANGELOG.md CHANGED
@@ -1,10 +1,13 @@
1
1
  # tileserver-gl changelog
2
2
 
3
- ## 5.2.0-pre.0
3
+ ## 5.2.0-pre.2
4
4
  * Use npm packages for public/resources (https://github.com/maptiler/tileserver-gl/pull/1427) by @okimiko
5
5
  * use ttf files of googlefonts/opensans (https://github.com/maptiler/tileserver-gl/pull/1447) by @okimiko
6
- * fix memory leak on SIGHUP (https://github.com/maptiler/tileserver-gl/pull/1455) by @okimiko
7
6
  * Limit Elevation Lat/Long Output Length (https://github.com/maptiler/tileserver-gl/pull/1457) by @okimiko
7
+ * Fetch style from url (https://github.com/maptiler/tileserver-gl/pull/1462) by @YoelRidgway
8
+ * fix: memory leak on SIGHUP (https://github.com/maptiler/tileserver-gl/pull/1455) by @okimiko
9
+ * fix: resolves Unimplemented type: 3 error for geojson format (https://github.com/maptiler/tileserver-gl/pull/1465) by @rjdjohnston
10
+ * fix: Test light version in ct workflow - fix sqlite build in light (https://github.com/maptiler/tileserver-gl/pull/2034) by @acalcutt
8
11
 
9
12
  ## 5.1.3
10
13
  * Fix SIGHUP (broken since 5.1.x) (https://github.com/maptiler/tileserver-gl/pull/1452) by @okimiko
package/Dockerfile CHANGED
@@ -1,4 +1,42 @@
1
- FROM ubuntu:jammy
1
+ FROM ubuntu:jammy AS builder
2
+
3
+ ENV NODE_ENV="production"
4
+
5
+ SHELL ["/bin/bash", "-o", "pipefail", "-c"]
6
+
7
+ RUN export DEBIAN_FRONTEND=noninteractive && \
8
+ apt-get update && \
9
+ apt-get install -y --no-install-recommends --no-install-suggests \
10
+ build-essential \
11
+ ca-certificates \
12
+ curl \
13
+ gnupg && \
14
+ mkdir -p /etc/apt/keyrings && \
15
+ curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg && \
16
+ echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_22.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list && \
17
+ apt-get -qq update && \
18
+ apt-get install -y --no-install-recommends --no-install-suggests nodejs && \
19
+ npm i -g npm@latest && \
20
+ apt-get -y remove curl gnupg && \
21
+ apt-get -y --purge autoremove && \
22
+ apt-get clean && \
23
+ rm -rf /var/lib/apt/lists/*
24
+
25
+ RUN mkdir -p /usr/src/app
26
+
27
+ WORKDIR /usr/src/app
28
+
29
+ COPY package.json /usr/src/app
30
+ COPY package-lock.json /usr/src/app
31
+
32
+ RUN npm config set maxsockets 1 && \
33
+ npm config set fetch-retries 5 && \
34
+ npm config set fetch-retry-mintimeout 100000 && \
35
+ npm config set fetch-retry-maxtimeout 600000 && \
36
+ npm ci --omit=dev && \
37
+ chown -R root:root /usr/src/app
38
+
39
+ FROM ubuntu:jammy AS final
2
40
 
3
41
  ENV \
4
42
  NODE_ENV="production" \
@@ -26,16 +64,9 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
26
64
  apt-get clean && \
27
65
  rm -rf /var/lib/apt/lists/*
28
66
 
29
- WORKDIR /usr/src/app
30
- COPY . .
67
+ COPY --from=builder /usr/src/app /usr/src/app
31
68
 
32
- RUN npm config set maxsockets 1 && \
33
- npm config set fetch-retries 5 && \
34
- npm config set fetch-retry-mintimeout 100000 && \
35
- npm config set fetch-retry-maxtimeout 600000 && \
36
- npm install --omit=dev && \
37
- chown -R root:root . && \
38
- chmod +x ./docker-entrypoint.sh
69
+ COPY . /usr/src/app
39
70
 
40
71
  RUN mkdir -p /data && chown node:node /data
41
72
  VOLUME /data
@@ -1,5 +1,8 @@
1
1
  * Use npm packages for public/resources (https://github.com/maptiler/tileserver-gl/pull/1427) by @okimiko
2
2
  * use ttf files of googlefonts/opensans (https://github.com/maptiler/tileserver-gl/pull/1447) by @okimiko
3
- * fix memory leak on SIGHUP (https://github.com/maptiler/tileserver-gl/pull/1455) by @okimiko
4
3
  * Limit Elevation Lat/Long Output Length (https://github.com/maptiler/tileserver-gl/pull/1457) by @okimiko
4
+ * Fetch style from url (https://github.com/maptiler/tileserver-gl/pull/1462) by @YoelRidgway
5
+ * fix: memory leak on SIGHUP (https://github.com/maptiler/tileserver-gl/pull/1455) by @okimiko
6
+ * fix: resolves Unimplemented type: 3 error for geojson format (https://github.com/maptiler/tileserver-gl/pull/1465) by @rjdjohnston
7
+ * fix: Test light version in ct workflow - fix sqlite build in light (https://github.com/maptiler/tileserver-gl/pull/2034) by @acalcutt
5
8
 
package/docs/config.rst CHANGED
@@ -57,6 +57,9 @@ Example:
57
57
  "tilejson": {
58
58
  "format": "webp"
59
59
  }
60
+ },
61
+ "remote": {
62
+ "style": "https://demotiles.maplibre.org/style.json"
60
63
  }
61
64
  },
62
65
  "data": {
@@ -209,7 +212,7 @@ Not used by default.
209
212
 
210
213
  Each item in this object defines one style (map). It can have the following options:
211
214
 
212
- * ``style`` -- name of the style json file [required]
215
+ * ``style`` -- name of the style json file or url of a remote hosted style [required]
213
216
  * ``serve_rendered`` -- whether to render the raster tiles for this style or not
214
217
  * ``serve_data`` -- whether to allow access to the original tiles, sprites and required glyphs
215
218
  * ``tilejson`` -- properties to add to the TileJSON created for the raster data
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tileserver-gl-light",
3
- "version": "5.2.0-pre.0",
3
+ "version": "5.2.0-pre.2",
4
4
  "description": "Map tile server for JSON GL styles - serving vector tiles",
5
5
  "main": "src/main.js",
6
6
  "bin": "src/main.js",
@@ -33,11 +33,12 @@
33
33
  "@maplibre/maplibre-gl-style-spec": "20.3.1",
34
34
  "@sindresorhus/fnv1a": "3.1.0",
35
35
  "advanced-pool": "0.3.3",
36
- "axios": "^1.7.7",
36
+ "axios": "^1.8.2",
37
37
  "chokidar": "3.6.0",
38
38
  "clone": "2.1.2",
39
39
  "color": "4.2.3",
40
40
  "commander": "12.1.0",
41
+ "copyfiles": "2.4.1",
41
42
  "cors": "2.8.5",
42
43
  "express": "5.0.1",
43
44
  "handlebars": "4.7.8",
package/src/serve_data.js CHANGED
@@ -21,6 +21,7 @@ import { openMbTilesWrapper } from './mbtiles_wrapper.js';
21
21
 
22
22
  import fs from 'node:fs';
23
23
  import { fileURLToPath } from 'url';
24
+
24
25
  const packageJson = JSON.parse(
25
26
  fs.readFileSync(
26
27
  path.dirname(fileURLToPath(import.meta.url)) + '/../package.json',
@@ -113,12 +114,13 @@ export const serve_data = {
113
114
  let headers = fetchTile.headers;
114
115
  let isGzipped = data.slice(0, 2).indexOf(Buffer.from([0x1f, 0x8b])) === 0;
115
116
 
117
+ if (isGzipped) {
118
+ data = await gunzipP(data);
119
+ isGzipped = false;
120
+ }
121
+
116
122
  if (tileJSONFormat === 'pbf') {
117
123
  if (options.dataDecoratorFunc) {
118
- if (isGzipped) {
119
- data = await gunzipP(data);
120
- isGzipped = false;
121
- }
122
124
  data = options.dataDecoratorFunc(
123
125
  req.params.id,
124
126
  'data',
@@ -1027,10 +1027,19 @@ export const serve_rendered = {
1027
1027
  * @param {object} params Parameters object.
1028
1028
  * @param {string} id ID of the item.
1029
1029
  * @param {object} programOpts - An object containing the program options
1030
+ * @param {object} style pre-fetched/read StyleJSON object.
1030
1031
  * @param {Function} dataResolver Function to resolve data.
1031
1032
  * @returns {Promise<void>}
1032
1033
  */
1033
- add: async function (options, repo, params, id, programOpts, dataResolver) {
1034
+ add: async function (
1035
+ options,
1036
+ repo,
1037
+ params,
1038
+ id,
1039
+ programOpts,
1040
+ style,
1041
+ dataResolver,
1042
+ ) {
1034
1043
  const map = {
1035
1044
  renderers: [],
1036
1045
  renderersStatic: [],
@@ -1040,7 +1049,7 @@ export const serve_rendered = {
1040
1049
 
1041
1050
  const { publicUrl, verbose } = programOpts;
1042
1051
 
1043
- let styleJSON;
1052
+ const styleJSON = clone(style);
1044
1053
  /**
1045
1054
  * Creates a pool of renderers.
1046
1055
  * @param {number} ratio Pixel ratio
@@ -1229,12 +1238,6 @@ export const serve_rendered = {
1229
1238
 
1230
1239
  const styleFile = params.style;
1231
1240
  const styleJSONPath = path.resolve(options.paths.styles, styleFile);
1232
- try {
1233
- styleJSON = JSON.parse(await fsp.readFile(styleJSONPath));
1234
- } catch (e) {
1235
- console.log('Error parsing style file');
1236
- return false;
1237
- }
1238
1241
 
1239
1242
  if (styleJSON.sprite) {
1240
1243
  if (!Array.isArray(styleJSON.sprite)) {
@@ -196,9 +196,10 @@ export const serve_style = {
196
196
  * @param {object} params Parameters object containing style path
197
197
  * @param {string} id ID of the style.
198
198
  * @param {object} programOpts - An object containing the program options
199
+ * @param {object} style pre-fetched/read StyleJSON object.
199
200
  * @param {Function} reportTiles Function for reporting tile sources.
200
201
  * @param {Function} reportFont Function for reporting font usage
201
- * @returns {boolean} true if add is succesful
202
+ * @returns {boolean} true if add is successful
202
203
  */
203
204
  add: function (
204
205
  options,
@@ -206,21 +207,14 @@ export const serve_style = {
206
207
  params,
207
208
  id,
208
209
  programOpts,
210
+ style,
209
211
  reportTiles,
210
212
  reportFont,
211
213
  ) {
212
214
  const { publicUrl } = programOpts;
213
215
  const styleFile = path.resolve(options.paths.styles, params.style);
216
+ const styleJSON = clone(style);
214
217
 
215
- let styleFileData;
216
- try {
217
- styleFileData = fs.readFileSync(styleFile); // TODO: could be made async if this function was
218
- } catch (e) {
219
- console.log(`Error reading style file "${params.style}"`);
220
- return false;
221
- }
222
-
223
- const styleJSON = JSON.parse(styleFileData);
224
218
  const validationErrors = validateStyleMin(styleJSON);
225
219
  if (validationErrors.length > 0) {
226
220
  console.log(`The file "${params.style}" is not a valid style file:`);
package/src/server.js CHANGED
@@ -178,10 +178,29 @@ async function start(opts) {
178
178
  * @param {object} item - The style configuration object.
179
179
  * @param {boolean} allowMoreData - Whether to allow adding more data sources.
180
180
  * @param {boolean} reportFonts - Whether to report fonts.
181
- * @returns {void}
181
+ * @returns {Promise<void>}
182
182
  */
183
- function addStyle(id, item, allowMoreData, reportFonts) {
183
+ async function addStyle(id, item, allowMoreData, reportFonts) {
184
184
  let success = true;
185
+
186
+ let styleJSON;
187
+ try {
188
+ if (isValidHttpUrl(item.style)) {
189
+ const res = await fetch(item.style);
190
+ if (!res.ok) {
191
+ throw new Error(`fetch error ${res.status}`);
192
+ }
193
+ styleJSON = await res.json();
194
+ } else {
195
+ const styleFile = path.resolve(options.paths.styles, item.style);
196
+ const styleFileData = await fs.promises.readFile(styleFile);
197
+ styleJSON = JSON.parse(styleFileData);
198
+ }
199
+ } catch (e) {
200
+ console.log(`Error getting style file "${item.style}"`);
201
+ return false;
202
+ }
203
+
185
204
  if (item.serve_data !== false) {
186
205
  success = serve_style.add(
187
206
  options,
@@ -189,6 +208,7 @@ async function start(opts) {
189
208
  item,
190
209
  id,
191
210
  opts,
211
+ styleJSON,
192
212
  (styleSourceId, protocol) => {
193
213
  let dataItemId;
194
214
  for (const id of Object.keys(data)) {
@@ -246,6 +266,7 @@ async function start(opts) {
246
266
  item,
247
267
  id,
248
268
  opts,
269
+ styleJSON,
249
270
  function dataResolver(styleSourceId) {
250
271
  let fileType;
251
272
  let inputFile;
@@ -271,6 +292,7 @@ async function start(opts) {
271
292
  item.serve_rendered = false;
272
293
  }
273
294
  }
295
+ return success;
274
296
  }
275
297
 
276
298
  for (const id of Object.keys(config.styles || {})) {
@@ -279,8 +301,7 @@ async function start(opts) {
279
301
  console.log(`Missing "style" property for ${id}`);
280
302
  continue;
281
303
  }
282
-
283
- addStyle(id, item, true, true);
304
+ startupPromises.push(addStyle(id, item, true, true));
284
305
  }
285
306
  startupPromises.push(
286
307
  serve_font(options, serving.fonts, opts).then((sub) => {