pmtiles-swarm 0.98.1 β†’ 0.98.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.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,21 @@
7
7
  ### 🐞 Bug fixes
8
8
  - _...Add new stuff here..._
9
9
 
10
+ ## 0.98.2
11
+ ### ✨ Features and improvements
12
+
13
+ ### 🐞 Bug fixes
14
+ - **The console called a complete MBTiles archive "not servable".** It is, and has been since the
15
+ tile store learned to open one: PMTiles always, MBTiles from a complete local copy. The console
16
+ never followed. It tested `kind === 'pmtiles'` in two places, so an MBTiles that had finished
17
+ hashing was labelled `mbtiles Β· not servable` in the list and had its TileJSON, preview and tile
18
+ endpoint hidden in the panel β€” all of which the node was answering perfectly well.
19
+
20
+ One rule now, matching what the tile route actually enforces, and an archive still arriving reads
21
+ as `servable once complete` rather than as one that never will be. Warming stays PMTiles-only: it
22
+ fetches the pieces a region's tiles live in, and an MBTiles is read whole or not at all, so there
23
+ is never a region of one to warm.
24
+
10
25
  ## 0.98.1
11
26
  ### ✨ Features and improvements
12
27
  - **The two archive readers no longer import each other.** Summarising an MBTiles archive reached
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pmtiles-swarm",
3
- "version": "0.98.1",
3
+ "version": "0.98.2",
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",
@@ -1823,6 +1823,43 @@
1823
1823
  }
1824
1824
  };
1825
1825
 
1826
+ /**
1827
+ * Whether this archive has a tile endpoint at all.
1828
+ *
1829
+ * The same rule the tile route applies, rather than a second opinion
1830
+ * about it: PMTiles always, MBTiles once the file is whole. MBTiles is
1831
+ * SQLite, so it cannot be read a byte range at a time out of the swarm β€”
1832
+ * but a complete one on local disk is an ordinary database holding the
1833
+ * same tiles, and refusing to serve it is refusing something that works.
1834
+ * See docs/internals.md β€” "Serving an MBTiles archive".
1835
+ * @param {object} entry - A catalog entry.
1836
+ * @returns {boolean} - Whether to offer the tile endpoints.
1837
+ */
1838
+ const isServable = (entry) => {
1839
+ const kind = entry.kind ?? 'pmtiles';
1840
+ if (kind === 'pmtiles') return true;
1841
+ return kind === 'mbtiles' && entry.complete === true;
1842
+ };
1843
+
1844
+ /**
1845
+ * What to say under the size about an archive that is not PMTiles.
1846
+ *
1847
+ * An MBTiles that is here in full is servable, and saying "not servable"
1848
+ * beside a finished file was simply wrong. One that is still arriving is
1849
+ * not servable *yet*, which is a different thing to tell somebody: it
1850
+ * becomes one by waiting, where an .osm.pbf never will.
1851
+ * @param {object} entry - A catalog entry.
1852
+ * @returns {string} - The note, or empty for a PMTiles archive.
1853
+ */
1854
+ const kindNote = (entry) => {
1855
+ const kind = entry.kind ?? 'pmtiles';
1856
+ if (kind === 'pmtiles') return '';
1857
+ if (kind !== 'mbtiles') return `${escapeHtml(kind)} Β· not servable`;
1858
+ return entry.complete === true
1859
+ ? escapeHtml(kind)
1860
+ : `${escapeHtml(kind)} Β· servable once complete`;
1861
+ };
1862
+
1826
1863
  /**
1827
1864
  * Closes the details, panel and row together.
1828
1865
  *
@@ -1891,8 +1928,8 @@
1891
1928
  .join(' Β· ')}</div>
1892
1929
  </td>
1893
1930
  <td>${bytes(entry.size)}${
1894
- (entry.kind ?? 'pmtiles') !== 'pmtiles'
1895
- ? `<div class="sub">${escapeHtml(entry.kind)} Β· not servable</div>`
1931
+ kindNote(entry)
1932
+ ? `<div class="sub">${kindNote(entry)}</div>`
1896
1933
  : ''
1897
1934
  }</td>
1898
1935
  <td>${added(entry.createdAt)}</td>
@@ -2518,10 +2555,15 @@
2518
2555
 
2519
2556
  const base = location.origin;
2520
2557
  const tileJson = `${base}/archives/${entry.infoHash}/tiles.json`;
2521
- // Only PMTiles can be a tile endpoint. Offering the URL for anything
2522
- // else hands out a link that will never work and reads as a fault in
2523
- // the server rather than a fact about the archive.
2524
- const servable = (entry.kind ?? 'pmtiles') === 'pmtiles';
2558
+ // Offering the URL for something that cannot serve tiles hands out a
2559
+ // link that will never work and reads as a fault in the server rather
2560
+ // than a fact about the archive.
2561
+ const servable = isServable(entry);
2562
+ // Warming pulls the pieces a region's tiles live in, so it only means
2563
+ // anything for an archive read out of the swarm. An MBTiles is read
2564
+ // whole or not at all β€” once it is here there is nothing left to
2565
+ // fetch, and before that there is no tile to warm.
2566
+ const warmable = (entry.kind ?? 'pmtiles') === 'pmtiles';
2525
2567
  const torrentUrl = `${base}/archives/${entry.infoHash}/archive.torrent`;
2526
2568
  const summary = entry.pmtiles ?? {};
2527
2569
  const mode = entry.mode ?? 'mirror';
@@ -2606,11 +2648,18 @@
2606
2648
  ${
2607
2649
  servable
2608
2650
  ? `<div class="sub" style="margin-bottom:1rem"><code>${escapeHtml(tileJson)}</code></div>`
2609
- : `<div class="sub" style="margin-bottom:1rem">
2610
- This is ${escapeHtml(entry.kind ?? 'not a PMTiles')} archive, so it has no tile
2611
- endpoint β€” only PMTiles can be read a byte range at a time, which is what
2612
- serving tiles from a swarm needs. It is still distributed and seeded normally.
2613
- </div>`
2651
+ : (entry.kind ?? 'pmtiles') === 'mbtiles'
2652
+ ? `<div class="sub" style="margin-bottom:1rem">
2653
+ This MBTiles archive is still arriving, so it has no tile endpoint yet. It is
2654
+ SQLite, which cannot be read a byte range at a time out of the swarm the way
2655
+ PMTiles can β€” so it becomes servable when the download finishes rather than as
2656
+ pieces land. It is distributed and seeded normally in the meantime.
2657
+ </div>`
2658
+ : `<div class="sub" style="margin-bottom:1rem">
2659
+ This is ${escapeHtml(entry.kind ?? 'not a PMTiles')} archive, so it has no tile
2660
+ endpoint β€” only PMTiles and MBTiles can be served as tiles. It is still
2661
+ distributed and seeded normally.
2662
+ </div>`
2614
2663
  }
2615
2664
 
2616
2665
  <h2>Completion hook</h2>
@@ -2665,7 +2714,7 @@
2665
2714
 
2666
2715
  <h2>Actions</h2>
2667
2716
  <div class="actions">
2668
- ${servable ? '<button id="warm">Warm region</button>' : ''}
2717
+ ${warmable ? '<button id="warm">Warm region</button>' : ''}
2669
2718
  <button id="set-location">Set location…</button>
2670
2719
  <button id="clear-cache" ${mode === 'cache' ? '' : 'disabled title="only cache-mode archives have a cache to clear"'}>Clear cache</button>
2671
2720
  <button id="recheck" title="Hash the files on disk again and believe the result. For an archive that reads 0% next to a file that is plainly there, or one that claims to be complete and is not β€” every other figure comes from something written down earlier, and this is the only thing that goes and looks.">Recheck files</button>
@@ -2895,7 +2944,7 @@
2895
2944
  }
2896
2945
  $('copy-hash').onclick = () => copy(entry.infoHash, 'Infohash');
2897
2946
 
2898
- if (servable) {
2947
+ if (warmable) {
2899
2948
  $('warm').onclick = () => openWarmDialog(entry);
2900
2949
  }
2901
2950