pmtiles-swarm 0.69.0 → 0.70.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/CHANGELOG.md +27 -3
- package/docs/tile-stacks.md +14 -0
- package/package.json +1 -1
- package/src/bake-jobs.js +29 -6
- package/src/web/index.html +15 -7
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,33 @@
|
|
|
7
7
|
### 🐞 Bug fixes
|
|
8
8
|
- _...Add new stuff here..._
|
|
9
9
|
|
|
10
|
+
## 0.70.0
|
|
11
|
+
### ✨ Features and improvements
|
|
12
|
+
- **An export works on the disk the archive is going to.** It worked under the data directory and
|
|
13
|
+
moved the finished file afterwards, which is the wrong disk twice over. The bytes have to go
|
|
14
|
+
where there is room for them, and a 700 GiB archive is not something a data directory is sized
|
|
15
|
+
for - while the disk chosen to hold the finished archive is, by definition.
|
|
16
|
+
|
|
17
|
+
The second problem was the move. `publish` renames within a filesystem and copies across one, so
|
|
18
|
+
a bake that worked elsewhere ended with a full copy of the whole archive - and until that
|
|
19
|
+
finished, the buffered tile data and the finished file both sat on the data directory's disk.
|
|
20
|
+
Working at the destination makes the last step a rename and removes the second full-size write.
|
|
21
|
+
|
|
22
|
+
Nothing appears at the destination until the end either way: the archive is assembled in one
|
|
23
|
+
pass at finalize, so until then `<destination>/bakes/<stack>/` holds the buffered tiles and the
|
|
24
|
+
checkpoint and no `.pmtiles` at all.
|
|
25
|
+
|
|
26
|
+
### 🐞 Bug fixes
|
|
27
|
+
- **A stack said "without sharp installed, its tiles answer 501" whether or not sharp was
|
|
28
|
+
installed.** It is a conditional the console can resolve and the reader cannot: nothing on the
|
|
29
|
+
page said which way it fell, so the line told somebody with a working stack that it might not
|
|
30
|
+
be, and somebody with a broken one that it might be fine.
|
|
31
|
+
|
|
32
|
+
`/api/stacks` has always reported the codec. Now the stack row uses it. With one installed there
|
|
33
|
+
is nothing to say, so nothing is said - and the "needs a codec" badge is gone too, because a
|
|
34
|
+
warning on something that works teaches people to ignore warnings. Without one it says the tiles
|
|
35
|
+
answer 501 *here*, names the field responsible, and says what to install.
|
|
36
|
+
|
|
10
37
|
## 0.69.0
|
|
11
38
|
### ✨ Features and improvements
|
|
12
39
|
- **An export merges several tiles at once.** It did one at a time, start to finish, before
|
|
@@ -40,9 +67,6 @@
|
|
|
40
67
|
while it ran was never looked at again, and the export completed as though nobody had asked it
|
|
41
68
|
to stop. Checked around each batch as well now.
|
|
42
69
|
|
|
43
|
-
### 🐞 Bug fixes
|
|
44
|
-
- _...Add new stuff here..._
|
|
45
|
-
|
|
46
70
|
## 0.68.3
|
|
47
71
|
### 🐞 Bug fixes
|
|
48
72
|
- **Exporting a stack failed on its first merged tile.** "Cannot transfer object of unsupported
|
package/docs/tile-stacks.md
CHANGED
|
@@ -789,6 +789,20 @@ One bake per stack at a time. Two runs of one recipe write the same checkpoint
|
|
|
789
789
|
files over each other, and the second would resume the first's work believing it
|
|
790
790
|
were its own.
|
|
791
791
|
|
|
792
|
+
The work happens **on the filesystem the archive is going to** — under
|
|
793
|
+
`<destination>/bakes/<stack>/` — not under the data directory. The bytes have
|
|
794
|
+
to go where there is room for them, and a 700 GiB archive is not something a
|
|
795
|
+
data directory is sized for, while the disk chosen to hold the finished archive
|
|
796
|
+
is by definition. It also turns the last step of a long job from a copy of the
|
|
797
|
+
whole archive into a rename, and means the buffered tile data and the finished
|
|
798
|
+
archive never both have to fit on the data directory's disk.
|
|
799
|
+
|
|
800
|
+
Nothing appears at the destination itself until the end. The archive is
|
|
801
|
+
assembled in one pass at finalize, so until then the directory holds the
|
|
802
|
+
buffered tiles and the checkpoint and no `.pmtiles` at all. Choosing a different
|
|
803
|
+
location for a resumed bake looks for the checkpoint in the new place and finds
|
|
804
|
+
none, so it starts over.
|
|
805
|
+
|
|
792
806
|
### What exists now
|
|
793
807
|
|
|
794
808
|
`src/pmtiles-write.js` writes archives, `src/pmtiles-scan.js` reads back what one
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pmtiles-swarm",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.70.0",
|
|
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",
|
package/src/bake-jobs.js
CHANGED
|
@@ -24,9 +24,36 @@ import { outputFormat } from './stack-tile.js';
|
|
|
24
24
|
* first's work as if it were its own.
|
|
25
25
|
*/
|
|
26
26
|
|
|
27
|
-
/**
|
|
27
|
+
/** What the working directory is called, wherever it sits. */
|
|
28
28
|
const WORK_DIR = 'bakes';
|
|
29
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Where a bake does its work.
|
|
32
|
+
*
|
|
33
|
+
* On the filesystem the archive is going to, not under the data directory.
|
|
34
|
+
* Two reasons, and the first is the one that decides it: the bytes have to go
|
|
35
|
+
* somewhere there is room for them, and a 700 GiB archive is not something a
|
|
36
|
+
* data directory is sized for -- while the disk chosen to hold the finished
|
|
37
|
+
* archive is, by definition.
|
|
38
|
+
*
|
|
39
|
+
* The second falls out of the first. `publish` renames the finished file into
|
|
40
|
+
* place where it can and copies it where it cannot, so working on the
|
|
41
|
+
* destination's filesystem turns the last step of a long job from a full copy
|
|
42
|
+
* of the whole archive into a rename. That also removes the second full-size
|
|
43
|
+
* write, since the buffered tile data and the finished archive no longer have
|
|
44
|
+
* to exist on the data directory's disk at the same time.
|
|
45
|
+
*
|
|
46
|
+
* The directory is removed when the bake finishes. A cancelled one keeps it,
|
|
47
|
+
* which is the point of it.
|
|
48
|
+
* @param {object} job - The job, carrying where it will publish to.
|
|
49
|
+
* @param {object} config - The node's configuration.
|
|
50
|
+
* @returns {string} - The working directory.
|
|
51
|
+
*/
|
|
52
|
+
export function workDirFor(job, config = {}) {
|
|
53
|
+
const root = job.publishDir ?? config.savePath ?? config.dataDir ?? './data';
|
|
54
|
+
return path.join(root, WORK_DIR, job.stackId);
|
|
55
|
+
}
|
|
56
|
+
|
|
30
57
|
/** A bake that has finished is kept this long, so the console can report it. */
|
|
31
58
|
const KEEP_FINISHED_MS = 10 * 60 * 1000;
|
|
32
59
|
|
|
@@ -173,11 +200,7 @@ export class BakeManager {
|
|
|
173
200
|
* @returns {Promise<void>} - Resolves when the archive is in the catalog.
|
|
174
201
|
*/
|
|
175
202
|
async #run(job, resolved, codec, options) {
|
|
176
|
-
const workDir =
|
|
177
|
-
this.#config.dataDir ?? './data',
|
|
178
|
-
WORK_DIR,
|
|
179
|
-
job.stackId,
|
|
180
|
-
);
|
|
203
|
+
const workDir = workDirFor(job, this.#config);
|
|
181
204
|
const destination = path.join(workDir, job.name);
|
|
182
205
|
const format = outputFormat(resolved);
|
|
183
206
|
|
package/src/web/index.html
CHANGED
|
@@ -5225,7 +5225,7 @@ Every piece is hashed against the ` +
|
|
|
5225
5225
|
},
|
|
5226
5226
|
{
|
|
5227
5227
|
key: 'stacks.bakePauseMs',
|
|
5228
|
-
label: 'Pause between
|
|
5228
|
+
label: 'Pause between batches while exporting',
|
|
5229
5229
|
type: 'number',
|
|
5230
5230
|
placeholder: '0',
|
|
5231
5231
|
unit: 'ms',
|
|
@@ -7042,11 +7042,15 @@ Every piece is hashed against the ` +
|
|
|
7042
7042
|
// The shapes this node has, so a source can be clipped to one by name
|
|
7043
7043
|
// rather than by remembering a filename.
|
|
7044
7044
|
let stackCutlines = [];
|
|
7045
|
+
// Which codec is installed, or null. A stack row needs it to say whether
|
|
7046
|
+
// its pixel work is a problem here or merely a fact about the recipe.
|
|
7047
|
+
let stackCodec = null;
|
|
7045
7048
|
|
|
7046
7049
|
const loadStacks = async () => {
|
|
7047
7050
|
const body = await api('/api/stacks');
|
|
7048
7051
|
const { stacks, codec } = body;
|
|
7049
7052
|
stackCutlines = body.cutlines ?? [];
|
|
7053
|
+
stackCodec = codec ?? null;
|
|
7050
7054
|
// A category resolving to a new build changes this, which is the
|
|
7051
7055
|
// reason to poll at all -- but most polls change nothing, and
|
|
7052
7056
|
// repainting a list somebody is about to click is worse than not.
|
|
@@ -7108,8 +7112,12 @@ Every piece is hashed against the ` +
|
|
|
7108
7112
|
if (unresolved.length) {
|
|
7109
7113
|
badges.push('<span class="pill warn">sources missing</span>');
|
|
7110
7114
|
}
|
|
7111
|
-
|
|
7112
|
-
|
|
7115
|
+
// Only where it is actually a problem. With a codec installed the
|
|
7116
|
+
// recipe asking for pixel work is a fact about the recipe, not
|
|
7117
|
+
// something wrong with it, and a warning badge on a working stack
|
|
7118
|
+
// teaches people to ignore warning badges.
|
|
7119
|
+
if (stack.needsCodec && !stackCodec) {
|
|
7120
|
+
badges.push('<span class="pill warn">no codec for this</span>');
|
|
7113
7121
|
}
|
|
7114
7122
|
if (stack.pinned) badges.push('<span class="pill">pinned</span>');
|
|
7115
7123
|
|
|
@@ -7191,10 +7199,10 @@ Every piece is hashed against the ` +
|
|
|
7191
7199
|
}
|
|
7192
7200
|
${bakeLine}
|
|
7193
7201
|
${
|
|
7194
|
-
stack.needsCodec
|
|
7195
|
-
? `<p class="
|
|
7196
|
-
(<code>${escapeHtml(stack.needsCodec)}</code>)
|
|
7197
|
-
<code>sharp</code
|
|
7202
|
+
stack.needsCodec && !stackCodec
|
|
7203
|
+
? `<p class="bad">Its tiles answer 501 here: serving this means
|
|
7204
|
+
decoding pixels (<code>${escapeHtml(stack.needsCodec)}</code>)
|
|
7205
|
+
and this node has no codec. <code>npm install sharp</code>.</p>`
|
|
7198
7206
|
: ''
|
|
7199
7207
|
}
|
|
7200
7208
|
<table class="tight">
|