pmtiles-swarm 0.98.2 โ†’ 0.98.3

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/CHANGELOG.md CHANGED
@@ -7,6 +7,22 @@
7
7
  ### ๐Ÿž Bug fixes
8
8
  - _...Add new stuff here..._
9
9
 
10
+ ## 0.98.3
11
+ ### โœจ Features and improvements
12
+
13
+ ### ๐Ÿž Bug fixes
14
+ - **A stack could not be pointed at a completed MBTiles archive.** The source picker offered only
15
+ PMTiles, so an MBTiles the node was perfectly able to serve tiles from was simply absent from the
16
+ menu. It offers a complete one now, by the same rule the tile route enforces โ€” and still hides one
17
+ that is arriving, since a stack naming that would answer 503 for every tile until the download
18
+ finished.
19
+ - **A planet dump was offered as a stack source.** The same filter read an archive with no recorded
20
+ kind as PMTiles, which is not a harmless default: a mirrored `.osm.pbf` appeared in the menu, and
21
+ naming it would have produced a recipe that failed at its first tile. The kind now falls back to
22
+ the filename before anything is assumed, which is how `prewarm.js` resolves it after the identical
23
+ mistake sent every mirrored dump round the header-read backoff for ever. Such an archive is also
24
+ labelled `unknown ยท not servable` in the list, where it previously said nothing at all.
25
+
10
26
  ## 0.98.2
11
27
  ### โœจ Features and improvements
12
28
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pmtiles-swarm",
3
- "version": "0.98.2",
3
+ "version": "0.98.3",
4
4
  "description": "BitTorrent distribution for PMTiles map archives: create torrents, watch folders, publish and subscribe to RSS feeds, and seed through qBittorrent or an embedded client",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -1836,11 +1836,31 @@
1836
1836
  * @returns {boolean} - Whether to offer the tile endpoints.
1837
1837
  */
1838
1838
  const isServable = (entry) => {
1839
- const kind = entry.kind ?? 'pmtiles';
1839
+ const kind = kindOf(entry);
1840
1840
  if (kind === 'pmtiles') return true;
1841
1841
  return kind === 'mbtiles' && entry.complete === true;
1842
1842
  };
1843
1843
 
1844
+ /**
1845
+ * What kind of archive this is, from the record or failing that the name.
1846
+ *
1847
+ * An entry from before the kind was recorded carries none, and reading
1848
+ * that as PMTiles is not a harmless default: it is how a planet dump ends
1849
+ * up labelled servable and offered as a stack source, where naming it
1850
+ * would produce a recipe that fails at its first tile. `prewarm.js`
1851
+ * resolves it exactly this way, after the same mistake sent every
1852
+ * mirrored .osm.pbf round the header-read backoff for ever.
1853
+ * @param {object} entry - A catalog entry.
1854
+ * @returns {string} - 'pmtiles', 'mbtiles', or 'unknown'.
1855
+ */
1856
+ const kindOf = (entry) => {
1857
+ if (entry.kind) return entry.kind;
1858
+ const name = entry.name ?? '';
1859
+ if (/\.pmtiles$/i.test(name)) return 'pmtiles';
1860
+ if (/\.mbtiles$/i.test(name)) return 'mbtiles';
1861
+ return 'unknown';
1862
+ };
1863
+
1844
1864
  /**
1845
1865
  * What to say under the size about an archive that is not PMTiles.
1846
1866
  *
@@ -1852,7 +1872,7 @@
1852
1872
  * @returns {string} - The note, or empty for a PMTiles archive.
1853
1873
  */
1854
1874
  const kindNote = (entry) => {
1855
- const kind = entry.kind ?? 'pmtiles';
1875
+ const kind = kindOf(entry);
1856
1876
  if (kind === 'pmtiles') return '';
1857
1877
  if (kind !== 'mbtiles') return `${escapeHtml(kind)} ยท not servable`;
1858
1878
  return entry.complete === true
@@ -2563,7 +2583,7 @@
2563
2583
  // anything for an archive read out of the swarm. An MBTiles is read
2564
2584
  // whole or not at all โ€” once it is here there is nothing left to
2565
2585
  // fetch, and before that there is no tile to warm.
2566
- const warmable = (entry.kind ?? 'pmtiles') === 'pmtiles';
2586
+ const warmable = kindOf(entry) === 'pmtiles';
2567
2587
  const torrentUrl = `${base}/archives/${entry.infoHash}/archive.torrent`;
2568
2588
  const summary = entry.pmtiles ?? {};
2569
2589
  const mode = entry.mode ?? 'mirror';
@@ -2648,7 +2668,7 @@
2648
2668
  ${
2649
2669
  servable
2650
2670
  ? `<div class="sub" style="margin-bottom:1rem"><code>${escapeHtml(tileJson)}</code></div>`
2651
- : (entry.kind ?? 'pmtiles') === 'mbtiles'
2671
+ : kindOf(entry) === 'mbtiles'
2652
2672
  ? `<div class="sub" style="margin-bottom:1rem">
2653
2673
  This MBTiles archive is still arriving, so it has no tile endpoint yet. It is
2654
2674
  SQLite, which cannot be read a byte range at a time out of the swarm the way
@@ -8175,10 +8195,12 @@ Every piece is hashed against the ` +
8175
8195
  // missing from a menu the operator is looking at. This is the same
8176
8196
  // endpoint the Archives view reads, and it answers a bare array.
8177
8197
  const held = await api('/api/torrents');
8198
+ // The same rule the tile route enforces, because a stack source is
8199
+ // read through exactly that path: a complete MBTiles belongs here,
8200
+ // and one still arriving does not -- a stack naming it would answer
8201
+ // 503 for every tile until the download finished.
8178
8202
  const free = (held ?? []).filter(
8179
- (entry) =>
8180
- !taken.has(entry.infoHash) &&
8181
- (entry.kind ?? 'pmtiles') === 'pmtiles',
8203
+ (entry) => !taken.has(entry.infoHash) && isServable(entry),
8182
8204
  );
8183
8205
  if (free.length) {
8184
8206
  groups.push(