@tileflow/dev 0.1.0-alpha.41 → 0.1.0-alpha.43
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/dist/artifacts.js
CHANGED
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
usesTileflowLineBackgroundGlyphs,
|
|
33
33
|
writeTileflowArtifactPlan,
|
|
34
34
|
writeTileflowBuildArtifacts
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-3IHCBD7R.js";
|
|
36
36
|
import {
|
|
37
37
|
getTileflowAssetBasePath,
|
|
38
38
|
getTileflowAssetFileName,
|
|
@@ -51,7 +51,7 @@ import {
|
|
|
51
51
|
defaultTileflowConfigPath
|
|
52
52
|
} from "./chunk-AQUGMUZW.js";
|
|
53
53
|
import "./chunk-D4OE4ITL.js";
|
|
54
|
-
import "./chunk-
|
|
54
|
+
import "./chunk-6SLT6ONM.js";
|
|
55
55
|
export {
|
|
56
56
|
TileflowHostedManifestOverwriteError,
|
|
57
57
|
TileflowLocalTilesetProductionError,
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
} from "./chunk-D4OE4ITL.js";
|
|
26
26
|
import {
|
|
27
27
|
inspectTileflowPmtilesForLocalUse
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-6SLT6ONM.js";
|
|
29
29
|
|
|
30
30
|
// src/artifacts.ts
|
|
31
31
|
import { createHash as createHash5 } from "crypto";
|
|
@@ -70,6 +70,58 @@ import {
|
|
|
70
70
|
} from "@tileflow/core/native-profile";
|
|
71
71
|
import { prepareTileflowStyleFamilyForRendering } from "@tileflow/core/runtime";
|
|
72
72
|
|
|
73
|
+
// src/family-style-resources.ts
|
|
74
|
+
function rebaseTileflowFamilyStyle(style, mapName, themeName) {
|
|
75
|
+
const rebase = (value) => {
|
|
76
|
+
let start = 0;
|
|
77
|
+
let end = value.length;
|
|
78
|
+
while (start < end && value.charCodeAt(start) <= 32) start++;
|
|
79
|
+
while (end > start && value.charCodeAt(end - 1) <= 32) end--;
|
|
80
|
+
const reference = value.slice(start, end);
|
|
81
|
+
if (/^[\\/]/u.test(reference) || /^[a-z][a-z\d+.-]*:/iu.test(reference)) return value;
|
|
82
|
+
const target = !reference || /^[?#]/u.test(reference) ? `${themeName}.json${reference}` : reference;
|
|
83
|
+
return `../styles/${mapName}/${target}`;
|
|
84
|
+
};
|
|
85
|
+
const property = (value, key2) => {
|
|
86
|
+
if (record(value) && typeof value[key2] === "string") value[key2] = rebase(value[key2]);
|
|
87
|
+
};
|
|
88
|
+
const result = structuredClone(style);
|
|
89
|
+
property(result, "glyphs");
|
|
90
|
+
if (typeof result.sprite === "string") result.sprite = rebase(result.sprite);
|
|
91
|
+
else if (Array.isArray(result.sprite))
|
|
92
|
+
for (const sprite of result.sprite) property(sprite, "url");
|
|
93
|
+
const fontFaces = result["font-faces"];
|
|
94
|
+
if (record(fontFaces))
|
|
95
|
+
for (const [family, face] of Object.entries(fontFaces)) {
|
|
96
|
+
if (typeof face === "string") fontFaces[family] = rebase(face);
|
|
97
|
+
else property(face, "url");
|
|
98
|
+
}
|
|
99
|
+
for (const source of Object.values(result.sources)) {
|
|
100
|
+
property(source, "url");
|
|
101
|
+
if (source.type === "geojson") property(source, "data");
|
|
102
|
+
for (const key2 of ["tiles", "urls"]) {
|
|
103
|
+
const value = source[key2];
|
|
104
|
+
if (Array.isArray(value))
|
|
105
|
+
source[key2] = value.map(
|
|
106
|
+
(url) => typeof url === "string" ? rebase(url) : url
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
const fonts = result.metadata?.["tileflow:fontFaces"];
|
|
111
|
+
if (Array.isArray(fonts)) for (const face of fonts) property(face, "source");
|
|
112
|
+
for (const key2 of ["tileflow:buildings", "tileflow:vegetation"]) {
|
|
113
|
+
const descriptor = result.metadata?.[key2];
|
|
114
|
+
if (!record(descriptor)) continue;
|
|
115
|
+
if (Array.isArray(descriptor.models))
|
|
116
|
+
for (const model of descriptor.models) property(model, "url");
|
|
117
|
+
property(descriptor.landmarks, "url");
|
|
118
|
+
}
|
|
119
|
+
return result;
|
|
120
|
+
}
|
|
121
|
+
function record(value) {
|
|
122
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
123
|
+
}
|
|
124
|
+
|
|
73
125
|
// src/image-source-assets.ts
|
|
74
126
|
import { createHash } from "crypto";
|
|
75
127
|
function prepareEmbeddedImageSources(input) {
|
|
@@ -326,6 +378,7 @@ async function prepareTileflowLocalTilesets(project, styles, options) {
|
|
|
326
378
|
for (const [sourceId, source] of Object.entries(map.sources ?? {}).sort(
|
|
327
379
|
([left], [right]) => compareCodeUnits(left, right)
|
|
328
380
|
)) {
|
|
381
|
+
if (source.kind !== "hosted-tileset") continue;
|
|
329
382
|
const requestedPath = resolve2(options.baseDirectory, source.local);
|
|
330
383
|
const sourcePath = await realpath(requestedPath).catch(() => requestedPath);
|
|
331
384
|
if (!isPathWithin(projectRoot, sourcePath)) {
|
|
@@ -2034,8 +2087,8 @@ function optionalDiagnosticPath(value) {
|
|
|
2034
2087
|
}
|
|
2035
2088
|
function isTileflowMapResolutionDiagnostic(value, path) {
|
|
2036
2089
|
if (!value || typeof value !== "object" || !path) return false;
|
|
2037
|
-
const
|
|
2038
|
-
return
|
|
2090
|
+
const record2 = value;
|
|
2091
|
+
return record2.name === "TileflowMapResolutionError" && typeof record2.code === "string" && typeof record2.mapId === "string" && path.startsWith("/modules/") && !/[\p{Cc}]/u.test(path) && !/~(?:[^01]|$)/u.test(path);
|
|
2039
2092
|
}
|
|
2040
2093
|
function removeSemanticResolutionPath(message, path) {
|
|
2041
2094
|
if (!path) return message;
|
|
@@ -2443,7 +2496,7 @@ function getStableTileflowArtifactFiles(artifacts) {
|
|
|
2443
2496
|
...!artifacts.nativeBuild ? Object.entries(artifacts.styles).map(([mapName, styles]) => ({
|
|
2444
2497
|
contentType: "application/json; charset=utf-8",
|
|
2445
2498
|
fileName: `families/${mapName}.json`,
|
|
2446
|
-
source: `${JSON.stringify(
|
|
2499
|
+
source: `${JSON.stringify(prepareArtifactStyleFamily(mapName, styles))}
|
|
2447
2500
|
`
|
|
2448
2501
|
})) : [],
|
|
2449
2502
|
...artifacts.assets,
|
|
@@ -2458,6 +2511,18 @@ function getStableTileflowArtifactFiles(artifacts) {
|
|
|
2458
2511
|
];
|
|
2459
2512
|
return validateArtifactFiles(files);
|
|
2460
2513
|
}
|
|
2514
|
+
function prepareArtifactStyleFamily(mapName, styles) {
|
|
2515
|
+
return prepareTileflowStyleFamilyForRendering(
|
|
2516
|
+
createTileflowStyleFamily(
|
|
2517
|
+
Object.fromEntries(
|
|
2518
|
+
Object.entries(styles).map(([theme, style]) => [
|
|
2519
|
+
theme,
|
|
2520
|
+
rebaseTileflowFamilyStyle(style, mapName, theme)
|
|
2521
|
+
])
|
|
2522
|
+
)
|
|
2523
|
+
)
|
|
2524
|
+
);
|
|
2525
|
+
}
|
|
2461
2526
|
function validateArtifactFiles(files) {
|
|
2462
2527
|
const seen = /* @__PURE__ */ new Set();
|
|
2463
2528
|
for (const file of files) {
|
|
@@ -2553,20 +2618,19 @@ function createGenerationArtifactFiles(artifacts, generation, nativeUrls) {
|
|
|
2553
2618
|
contentType: "application/json; charset=utf-8",
|
|
2554
2619
|
fileName: `${prefix}/families/${mapName}.json`,
|
|
2555
2620
|
source: `${JSON.stringify(
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
)
|
|
2621
|
+
prepareArtifactStyleFamily(
|
|
2622
|
+
mapName,
|
|
2623
|
+
Object.fromEntries(
|
|
2624
|
+
Object.keys(artifacts.styles[mapName]).map((theme) => [
|
|
2625
|
+
theme,
|
|
2626
|
+
JSON.parse(
|
|
2627
|
+
String(
|
|
2628
|
+
immutableStyles.find(
|
|
2629
|
+
(file) => file.fileName === `${prefix}/styles/${mapName}/${theme}.json`
|
|
2630
|
+
).source
|
|
2567
2631
|
)
|
|
2568
|
-
|
|
2569
|
-
)
|
|
2632
|
+
)
|
|
2633
|
+
])
|
|
2570
2634
|
)
|
|
2571
2635
|
)
|
|
2572
2636
|
)}
|
|
@@ -2788,7 +2852,9 @@ function assertNoLocalTilesetsForProduction(artifacts) {
|
|
|
2788
2852
|
if (artifacts.localTilesets?.length) throw new TileflowLocalTilesetProductionError();
|
|
2789
2853
|
}
|
|
2790
2854
|
function hasLocalTilesetSources(project) {
|
|
2791
|
-
return Object.values(project.maps).some(
|
|
2855
|
+
return Object.values(project.maps).some(
|
|
2856
|
+
(map) => Object.values(map.sources ?? {}).some((source) => source.kind === "hosted-tileset")
|
|
2857
|
+
);
|
|
2792
2858
|
}
|
|
2793
2859
|
async function assertTileflowSelfHostedManifestTarget(manifestPath, options = {}) {
|
|
2794
2860
|
if (options.overwriteHostedManifest) return;
|
|
@@ -24,7 +24,7 @@ var inspectionLimits = Object.freeze({
|
|
|
24
24
|
maxValuesPerField: 16
|
|
25
25
|
});
|
|
26
26
|
var maxArchiveBytes = 8e9;
|
|
27
|
-
var maximumDecodedBytes =
|
|
27
|
+
var maximumDecodedBytes = 8 * 1024 * 1024 * 1024;
|
|
28
28
|
var minimumDecodedBytes = 64 * 1024 * 1024;
|
|
29
29
|
var maxDecompressedSectionBytes = 16 * 1024 * 1024;
|
|
30
30
|
var defaultMaximumDirectoryDepth = 32;
|
|
@@ -420,9 +420,20 @@ async function validatePmtilesDirectoryTree(source, header, budget, maximumDirec
|
|
|
420
420
|
];
|
|
421
421
|
const countedDirectories = /* @__PURE__ */ new Set();
|
|
422
422
|
const processedContexts = /* @__PURE__ */ new Set();
|
|
423
|
-
const clusteredContents = /* @__PURE__ */ new Set();
|
|
424
423
|
const decompressDirectory = createSectionDecompressor(budget);
|
|
425
|
-
let clusteredEnd =
|
|
424
|
+
let clusteredEnd = 0;
|
|
425
|
+
const advanceClusteredFrontier = (offset, length) => {
|
|
426
|
+
const end = offset + length;
|
|
427
|
+
if (offset === clusteredEnd) {
|
|
428
|
+
clusteredEnd = end;
|
|
429
|
+
} else if (offset > clusteredEnd || end > clusteredEnd) {
|
|
430
|
+
throw inspectionError(
|
|
431
|
+
"TF_TILESET_ARCHIVE_INVALID",
|
|
432
|
+
"archive",
|
|
433
|
+
"PMTiles clustered contents are not contiguous in TileID order."
|
|
434
|
+
);
|
|
435
|
+
}
|
|
436
|
+
};
|
|
426
437
|
let addressedTiles = 0;
|
|
427
438
|
let totalEntries = 0;
|
|
428
439
|
let tileEntries = 0;
|
|
@@ -430,20 +441,7 @@ async function validatePmtilesDirectoryTree(source, header, budget, maximumDirec
|
|
|
430
441
|
signal?.throwIfAborted();
|
|
431
442
|
const item = pending.pop();
|
|
432
443
|
if (item.kind === "clustered-content") {
|
|
433
|
-
|
|
434
|
-
if (clusteredContents.has(key)) continue;
|
|
435
|
-
if (clusteredEnd === null ? item.offset !== 0 : item.offset !== clusteredEnd) {
|
|
436
|
-
throw inspectionError(
|
|
437
|
-
"TF_TILESET_ARCHIVE_INVALID",
|
|
438
|
-
"archive",
|
|
439
|
-
"PMTiles clustered contents are not contiguous in TileID order."
|
|
440
|
-
);
|
|
441
|
-
}
|
|
442
|
-
clusteredContents.add(key);
|
|
443
|
-
clusteredEnd = item.offset + item.length;
|
|
444
|
-
assertParserMemory(
|
|
445
|
-
processedContexts.size + countedDirectories.size + clusteredContents.size + pending.length
|
|
446
|
-
);
|
|
444
|
+
advanceClusteredFrontier(item.offset, item.length);
|
|
447
445
|
continue;
|
|
448
446
|
}
|
|
449
447
|
const current = item;
|
|
@@ -459,9 +457,7 @@ async function validatePmtilesDirectoryTree(source, header, budget, maximumDirec
|
|
|
459
457
|
processedContexts.add(contextKey);
|
|
460
458
|
const firstPhysicalVisit = !countedDirectories.has(current.key);
|
|
461
459
|
countedDirectories.add(current.key);
|
|
462
|
-
assertParserMemory(
|
|
463
|
-
processedContexts.size + countedDirectories.size + clusteredContents.size + pending.length
|
|
464
|
-
);
|
|
460
|
+
assertParserMemory(processedContexts.size + countedDirectories.size + pending.length);
|
|
465
461
|
const response = await source.getBytes(current.offset, current.length, signal);
|
|
466
462
|
if (response.data.byteLength !== current.length) {
|
|
467
463
|
throw inspectionError("TF_TILESET_ARCHIVE_INVALID", "archive", "Short PMTiles directory.");
|
|
@@ -537,11 +533,15 @@ async function validatePmtilesDirectoryTree(source, header, budget, maximumDirec
|
|
|
537
533
|
addressedTiles += entry.runLength;
|
|
538
534
|
tileEntries += 1;
|
|
539
535
|
if (header.clustered) {
|
|
540
|
-
nextItems.
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
536
|
+
if (nextItems.length === 0) {
|
|
537
|
+
advanceClusteredFrontier(entry.offset, entry.length);
|
|
538
|
+
} else {
|
|
539
|
+
nextItems.push({
|
|
540
|
+
kind: "clustered-content",
|
|
541
|
+
length: entry.length,
|
|
542
|
+
offset: entry.offset
|
|
543
|
+
});
|
|
544
|
+
}
|
|
545
545
|
}
|
|
546
546
|
}
|
|
547
547
|
if (!Number.isSafeInteger(addressedTiles) || !Number.isSafeInteger(tileEntries)) {
|
|
@@ -551,9 +551,7 @@ async function validatePmtilesDirectoryTree(source, header, budget, maximumDirec
|
|
|
551
551
|
for (let index = nextItems.length - 1; index >= 0; index -= 1) {
|
|
552
552
|
pending.push(nextItems[index]);
|
|
553
553
|
}
|
|
554
|
-
assertParserMemory(
|
|
555
|
-
processedContexts.size + countedDirectories.size + clusteredContents.size + pending.length
|
|
556
|
-
);
|
|
554
|
+
assertParserMemory(processedContexts.size + countedDirectories.size + pending.length);
|
|
557
555
|
}
|
|
558
556
|
if (header.numAddressedTiles !== 0 && addressedTiles !== header.numAddressedTiles || header.numTileEntries !== 0 && tileEntries !== header.numTileEntries) {
|
|
559
557
|
throw inspectionError(
|
package/dist/server.js
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
parseTileflowLineBackgroundGlyphPath,
|
|
6
6
|
tileflowArtifactSessionSchemaVersion,
|
|
7
7
|
tileflowLineBackgroundGlyphRoute
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-3IHCBD7R.js";
|
|
9
9
|
import {
|
|
10
10
|
getTileflowAssetBasePath,
|
|
11
11
|
getTileflowAssetFileName,
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
defaultTileflowConfigPath
|
|
25
25
|
} from "./chunk-AQUGMUZW.js";
|
|
26
26
|
import "./chunk-D4OE4ITL.js";
|
|
27
|
-
import "./chunk-
|
|
27
|
+
import "./chunk-6SLT6ONM.js";
|
|
28
28
|
|
|
29
29
|
// src/server.ts
|
|
30
30
|
import { open } from "fs/promises";
|
package/dist/tilesets.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tileflow/dev",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.43",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"description": "Node development utilities for Tileflow configs and builds.",
|
|
6
6
|
"type": "module",
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
"dependencies": {
|
|
84
84
|
"@mapbox/vector-tile": "3.0.0",
|
|
85
85
|
"@maplibre/maplibre-gl-style-spec": "26.4.4",
|
|
86
|
-
"@tileflow/core": ">=0.1.0-alpha.
|
|
86
|
+
"@tileflow/core": ">=0.1.0-alpha.48 <0.1.0-beta.0",
|
|
87
87
|
"chokidar": "6.0.0",
|
|
88
88
|
"fontkit": "2.0.4",
|
|
89
89
|
"jiti": "^2.7.0",
|
|
@@ -95,14 +95,14 @@
|
|
|
95
95
|
"three": "0.185.1"
|
|
96
96
|
},
|
|
97
97
|
"devDependencies": {
|
|
98
|
-
"@tileflow/maps": "0.1.0-alpha.
|
|
98
|
+
"@tileflow/maps": "0.1.0-alpha.20"
|
|
99
99
|
},
|
|
100
100
|
"optionalDependencies": {
|
|
101
101
|
"sharp": "0.35.5"
|
|
102
102
|
},
|
|
103
103
|
"scripts": {
|
|
104
104
|
"build": "tsup src/artifacts.ts src/config.ts src/fonts.ts src/icons.ts src/inspect.ts src/preview.ts src/server.ts src/tilesets.ts src/validation.ts --format esm --dts --clean --platform node --external sharp && tsup --config tsup.inspector.config.ts",
|
|
105
|
-
"test": "tsx --test test/*.test.ts",
|
|
105
|
+
"test": "tsx --test --test-concurrency=2 test/*.test.ts",
|
|
106
106
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
107
107
|
"lint": "tsc -p tsconfig.json --noEmit",
|
|
108
108
|
"verify": "pnpm run typecheck && pnpm run test"
|