@tileflow/dev 0.1.0-alpha.16 → 0.1.0-alpha.17
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/README.md +16 -0
- package/dist/index.d.ts +19 -2
- package/dist/index.js +102 -8
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -45,6 +45,22 @@ edits retain the last good snapshot, and caller-supplied output directories can
|
|
|
45
45
|
feedback loops. `tileflow dev`, `capture --watch`, and framework adapters use this shared status
|
|
46
46
|
vocabulary.
|
|
47
47
|
|
|
48
|
+
Custom preview servers can select the same map or standalone scene semantics as the CLI:
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
import {createTileflowDevRequestHandler} from '@tileflow/dev';
|
|
52
|
+
|
|
53
|
+
const fetch = createTileflowDevRequestHandler({
|
|
54
|
+
session,
|
|
55
|
+
scene: 'madrid-mobile',
|
|
56
|
+
});
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
`map` and `scene` are mutually exclusive. Map preview uses the configured `view`; scene preview
|
|
60
|
+
uses its committed camera and CSS viewport. `resolveTileflowPreview()` exposes the validated
|
|
61
|
+
selection for custom integrations. Application-target scenes remain the responsibility of the
|
|
62
|
+
application's development server.
|
|
63
|
+
|
|
48
64
|
If a map uses `icons: './icons/brand'`, build artifacts include the generated
|
|
49
65
|
MapLibre `sprite.json`, `sprite.png`, `sprite@2x.json`, and `sprite@2x.png`
|
|
50
66
|
assets alongside the styles.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { IncomingMessage, ServerResponse } from 'node:http';
|
|
2
|
-
import { TileflowIconPackageFileName, TileflowIconPackageManifest, TileflowProjectConfig, MapLibreStyle, TileflowManifest, ValidationMessage, TileflowStyleOptions } from '@tileflow/core';
|
|
2
|
+
import { TileflowIconPackageFileName, TileflowIconPackageManifest, TileflowProjectConfig, MapLibreStyle, NormalizedTileflowCaptureScene, TileflowManifest, ValidationMessage, TileflowStyleOptions } from '@tileflow/core';
|
|
3
3
|
|
|
4
4
|
declare const tileflowArtifactSessionSchemaVersion: 1;
|
|
5
5
|
type TileflowArtifactDiagnostic = {
|
|
@@ -244,11 +244,27 @@ type TileflowDevRequestHandlerOptions = {
|
|
|
244
244
|
basePath?: string;
|
|
245
245
|
config?: string;
|
|
246
246
|
cwd?: string;
|
|
247
|
+
map?: string;
|
|
247
248
|
onError?: (error: unknown) => void;
|
|
249
|
+
scene?: string;
|
|
248
250
|
session?: TileflowArtifactSession;
|
|
249
251
|
styleBaseUrl?: string;
|
|
250
252
|
tileBaseUrl?: string;
|
|
251
253
|
};
|
|
254
|
+
type TileflowPreviewSelection = {
|
|
255
|
+
map?: string;
|
|
256
|
+
scene?: string;
|
|
257
|
+
};
|
|
258
|
+
type ResolvedTileflowPreview = {
|
|
259
|
+
camera: NormalizedTileflowCaptureScene['camera'];
|
|
260
|
+
label: string;
|
|
261
|
+
mapName: string;
|
|
262
|
+
viewport?: NormalizedTileflowCaptureScene['viewport'];
|
|
263
|
+
};
|
|
264
|
+
declare class TileflowPreviewSelectionError extends Error {
|
|
265
|
+
readonly code: "PREVIEW_SELECTION_INVALID";
|
|
266
|
+
constructor(message: string);
|
|
267
|
+
}
|
|
252
268
|
type TileflowBuildArtifactsOptions = {
|
|
253
269
|
assetBaseUrl?: string;
|
|
254
270
|
config?: string;
|
|
@@ -278,6 +294,7 @@ declare function assertValidTileflowConfig(project: TileflowProjectConfig): void
|
|
|
278
294
|
declare function asTileflowProjectConfig(input: unknown): TileflowProjectConfig;
|
|
279
295
|
declare function getTileflowMapNames(project: TileflowProjectConfig): string[];
|
|
280
296
|
declare function getFirstTileflowMapName(project: TileflowProjectConfig): string;
|
|
297
|
+
declare function resolveTileflowPreview(project: TileflowProjectConfig, selection?: TileflowPreviewSelection): ResolvedTileflowPreview;
|
|
281
298
|
declare function getTileflowStyleMapName(path: string): string;
|
|
282
299
|
declare function createTileflowManifest(project: TileflowProjectConfig, options?: TileflowManifestOptions): TileflowManifest;
|
|
283
300
|
declare function createTileflowStyle(project: TileflowProjectConfig, mapName: string, options?: TileflowStyleOptions): MapLibreStyle;
|
|
@@ -302,4 +319,4 @@ declare function createTileflowArtifactStatus(state: TileflowArtifactSessionStat
|
|
|
302
319
|
};
|
|
303
320
|
declare function normalizeTileflowBasePath(value?: string): string;
|
|
304
321
|
|
|
305
|
-
export { type CompileTileflowIconPackagesResult, type CompiledTileflowIconPackage, type CompiledTileflowIconPackageFile, type InspectTileflowIconCatalogsOptions, type LoadTileflowConfigOptions, type PreparedTileflowProject, type TileflowArtifactDiagnostic, type TileflowArtifactSession, type TileflowArtifactSessionOptions, type TileflowArtifactSessionState, type TileflowBuildArtifacts, type TileflowBuildArtifactsOptions, type TileflowBuildAsset, type TileflowDevRequestHandlerOptions, type TileflowFeatureInspection, type TileflowFeatureInspectionOptions, type TileflowIconCatalog, type TileflowIconCatalogAtlasRectangle, type TileflowIconCatalogIcon, type TileflowIconCatalogInspection, type TileflowIconCatalogMap, type TileflowIconCatalogMappedFrom, type TileflowIconCatalogMapping, type TileflowIconCatalogRenderedDensity, type TileflowIconCatalogSourceFormat, TileflowIconCompilationError, type TileflowIconCompilationIssue, type TileflowIconCompilationTarget, type TileflowInspectedFeature, type TileflowInspectedProperty, type TileflowManifestOptions, type TileflowMapIconPackageBinding, TileflowStyleValidationError, type TileflowStyleValidationIssue, TileflowValidationError, type WriteTileflowBuildArtifactsOptions, asTileflowProjectConfig, assertValidTileflowConfig, assertValidTileflowStyle, compileTileflowIconPackages, createTileflowArtifactDiagnostics, createTileflowArtifactSession, createTileflowArtifactStatus, createTileflowBuildArtifacts, createTileflowDevRequestHandler, createTileflowManifest, createTileflowNodeRequest, createTileflowStyle, createTileflowStyles, defaultTileflowApiUrl, defaultTileflowConfigPath, defaultTileflowManifestPath, defaultTileflowTileset, getFirstTileflowMapName, getTileflowAssetBasePath, getTileflowAssetFileName, getTileflowMapNames, getTileflowStyleMapName, getTileflowWatchPaths, iconFileExtensions, inspectTileflowFeatures, inspectTileflowIconCatalogs, isTileflowRequestUrl, joinTileflowPublicUrl, loadTileflowConfig, loadValidTileflowConfig, normalizeTileflowBasePath, prepareTileflowProjectIcons, tileflowArtifactSessionSchemaVersion, validateTileflowStyle, writeTileflowBuildArtifacts, writeTileflowNodeResponse };
|
|
322
|
+
export { type CompileTileflowIconPackagesResult, type CompiledTileflowIconPackage, type CompiledTileflowIconPackageFile, type InspectTileflowIconCatalogsOptions, type LoadTileflowConfigOptions, type PreparedTileflowProject, type ResolvedTileflowPreview, type TileflowArtifactDiagnostic, type TileflowArtifactSession, type TileflowArtifactSessionOptions, type TileflowArtifactSessionState, type TileflowBuildArtifacts, type TileflowBuildArtifactsOptions, type TileflowBuildAsset, type TileflowDevRequestHandlerOptions, type TileflowFeatureInspection, type TileflowFeatureInspectionOptions, type TileflowIconCatalog, type TileflowIconCatalogAtlasRectangle, type TileflowIconCatalogIcon, type TileflowIconCatalogInspection, type TileflowIconCatalogMap, type TileflowIconCatalogMappedFrom, type TileflowIconCatalogMapping, type TileflowIconCatalogRenderedDensity, type TileflowIconCatalogSourceFormat, TileflowIconCompilationError, type TileflowIconCompilationIssue, type TileflowIconCompilationTarget, type TileflowInspectedFeature, type TileflowInspectedProperty, type TileflowManifestOptions, type TileflowMapIconPackageBinding, type TileflowPreviewSelection, TileflowPreviewSelectionError, TileflowStyleValidationError, type TileflowStyleValidationIssue, TileflowValidationError, type WriteTileflowBuildArtifactsOptions, asTileflowProjectConfig, assertValidTileflowConfig, assertValidTileflowStyle, compileTileflowIconPackages, createTileflowArtifactDiagnostics, createTileflowArtifactSession, createTileflowArtifactStatus, createTileflowBuildArtifacts, createTileflowDevRequestHandler, createTileflowManifest, createTileflowNodeRequest, createTileflowStyle, createTileflowStyles, defaultTileflowApiUrl, defaultTileflowConfigPath, defaultTileflowManifestPath, defaultTileflowTileset, getFirstTileflowMapName, getTileflowAssetBasePath, getTileflowAssetFileName, getTileflowMapNames, getTileflowStyleMapName, getTileflowWatchPaths, iconFileExtensions, inspectTileflowFeatures, inspectTileflowIconCatalogs, isTileflowRequestUrl, joinTileflowPublicUrl, loadTileflowConfig, loadValidTileflowConfig, normalizeTileflowBasePath, prepareTileflowProjectIcons, resolveTileflowPreview, tileflowArtifactSessionSchemaVersion, validateTileflowStyle, writeTileflowBuildArtifacts, writeTileflowNodeResponse };
|
package/dist/index.js
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
compareCodeUnits as compareCodeUnits3,
|
|
9
9
|
createManifest,
|
|
10
10
|
createStyleFromProject as createStyleFromProject2,
|
|
11
|
+
normalizeTileflowCaptureScene,
|
|
11
12
|
validateConfig
|
|
12
13
|
} from "@tileflow/core";
|
|
13
14
|
|
|
@@ -1840,6 +1841,13 @@ var defaultTileflowApiUrl = "https://api.tileflow.dev";
|
|
|
1840
1841
|
var defaultTileflowConfigPath = "tileflow.config.ts";
|
|
1841
1842
|
var defaultTileflowManifestPath = "public/tileflow/manifest.json";
|
|
1842
1843
|
var defaultTileflowTileset = "world";
|
|
1844
|
+
var TileflowPreviewSelectionError = class extends Error {
|
|
1845
|
+
code = "PREVIEW_SELECTION_INVALID";
|
|
1846
|
+
constructor(message) {
|
|
1847
|
+
super(message);
|
|
1848
|
+
this.name = "TileflowPreviewSelectionError";
|
|
1849
|
+
}
|
|
1850
|
+
};
|
|
1843
1851
|
var TileflowValidationError = class extends Error {
|
|
1844
1852
|
code = "CONFIG_INVALID";
|
|
1845
1853
|
messages;
|
|
@@ -1903,6 +1911,52 @@ function getFirstTileflowMapName(project) {
|
|
|
1903
1911
|
}
|
|
1904
1912
|
return mapName;
|
|
1905
1913
|
}
|
|
1914
|
+
function resolveTileflowPreview(project, selection = {}) {
|
|
1915
|
+
if (selection.map !== void 0 && selection.scene !== void 0) {
|
|
1916
|
+
throw new TileflowPreviewSelectionError(
|
|
1917
|
+
"Choose either a Tileflow preview map or scene, not both."
|
|
1918
|
+
);
|
|
1919
|
+
}
|
|
1920
|
+
if (selection.scene !== void 0) {
|
|
1921
|
+
const scene = Object.hasOwn(project.scenes ?? {}, selection.scene) ? project.scenes?.[selection.scene] : void 0;
|
|
1922
|
+
if (!scene) {
|
|
1923
|
+
throw new TileflowPreviewSelectionError(`Unknown Tileflow scene: ${selection.scene}`);
|
|
1924
|
+
}
|
|
1925
|
+
const normalized = normalizeTileflowCaptureScene(scene);
|
|
1926
|
+
if (normalized.target.kind === "application") {
|
|
1927
|
+
throw new TileflowPreviewSelectionError(
|
|
1928
|
+
`Tileflow scene "${selection.scene}" targets an application. Preview it through the application's development server.`
|
|
1929
|
+
);
|
|
1930
|
+
}
|
|
1931
|
+
if (!Object.hasOwn(project.maps, normalized.map)) {
|
|
1932
|
+
throw new TileflowPreviewSelectionError(
|
|
1933
|
+
`Tileflow scene "${selection.scene}" references an unknown map: ${normalized.map}`
|
|
1934
|
+
);
|
|
1935
|
+
}
|
|
1936
|
+
return {
|
|
1937
|
+
camera: normalized.camera,
|
|
1938
|
+
label: `${normalized.map} / ${selection.scene} \xB7 ${normalized.viewport.width}\xD7${normalized.viewport.height}`,
|
|
1939
|
+
mapName: normalized.map,
|
|
1940
|
+
viewport: normalized.viewport
|
|
1941
|
+
};
|
|
1942
|
+
}
|
|
1943
|
+
const mapName = selection.map ?? getFirstTileflowMapName(project);
|
|
1944
|
+
const map = Object.hasOwn(project.maps, mapName) ? project.maps[mapName] : void 0;
|
|
1945
|
+
if (!map) {
|
|
1946
|
+
throw new TileflowPreviewSelectionError(`Unknown Tileflow map: ${mapName}`);
|
|
1947
|
+
}
|
|
1948
|
+
return {
|
|
1949
|
+
camera: {
|
|
1950
|
+
type: "center",
|
|
1951
|
+
center: map.view?.center ? [map.view.center[0], map.view.center[1]] : [0, 0],
|
|
1952
|
+
zoom: map.view?.zoom ?? 0,
|
|
1953
|
+
bearing: map.view?.bearing ?? 0,
|
|
1954
|
+
pitch: 0
|
|
1955
|
+
},
|
|
1956
|
+
label: mapName,
|
|
1957
|
+
mapName
|
|
1958
|
+
};
|
|
1959
|
+
}
|
|
1906
1960
|
function getTileflowStyleMapName(path) {
|
|
1907
1961
|
const fileName = path.split("/").pop() ?? "";
|
|
1908
1962
|
return fileName.replace(/\.json$/, "");
|
|
@@ -2092,8 +2146,8 @@ function createTileflowDevRequestHandler(options = {}) {
|
|
|
2092
2146
|
return jsonResponse(createTileflowArtifactStatus(state));
|
|
2093
2147
|
}
|
|
2094
2148
|
if (path === "/" || path === "") {
|
|
2095
|
-
const
|
|
2096
|
-
return htmlResponse(previewHtml(
|
|
2149
|
+
const preview = artifacts ? resolveTileflowPreview(artifacts.project, { map: options.map, scene: options.scene }) : void 0;
|
|
2150
|
+
return htmlResponse(previewHtml(preview, basePath, state));
|
|
2097
2151
|
}
|
|
2098
2152
|
if (!artifacts) return unavailableArtifactsResponse(state);
|
|
2099
2153
|
if (path === "/manifest.json") {
|
|
@@ -2199,6 +2253,9 @@ function stripTileflowBasePath(pathname, basePath) {
|
|
|
2199
2253
|
return null;
|
|
2200
2254
|
}
|
|
2201
2255
|
function tileflowErrorResponse(error) {
|
|
2256
|
+
if (error instanceof TileflowPreviewSelectionError) {
|
|
2257
|
+
return jsonResponse({ error: error.message }, 400);
|
|
2258
|
+
}
|
|
2202
2259
|
if (error instanceof TileflowStyleValidationError) {
|
|
2203
2260
|
return jsonResponse(
|
|
2204
2261
|
{
|
|
@@ -2263,9 +2320,23 @@ function resolveAssetBaseUrl(options) {
|
|
|
2263
2320
|
function isRelativePublicUrl(value) {
|
|
2264
2321
|
return !(value.startsWith("http://") || value.startsWith("https://") || value.startsWith("/") || value.startsWith("data:"));
|
|
2265
2322
|
}
|
|
2266
|
-
function previewHtml(
|
|
2267
|
-
const styleUrl =
|
|
2323
|
+
function previewHtml(preview, basePath, state) {
|
|
2324
|
+
const styleUrl = preview ? `${basePath}/styles/${preview.mapName}.json` : void 0;
|
|
2268
2325
|
const initialStatus = createTileflowArtifactStatus(state);
|
|
2326
|
+
const mapOptions = preview ? previewMapOptions(preview) : void 0;
|
|
2327
|
+
const viewportCss = preview?.viewport ? `
|
|
2328
|
+
html, body { min-height: 100%; margin: 0; }
|
|
2329
|
+
body {
|
|
2330
|
+
display: grid;
|
|
2331
|
+
place-items: center;
|
|
2332
|
+
overflow: auto;
|
|
2333
|
+
background: #E8E5DE;
|
|
2334
|
+
}
|
|
2335
|
+
#map {
|
|
2336
|
+
width: ${preview.viewport.width}px;
|
|
2337
|
+
height: ${preview.viewport.height}px;
|
|
2338
|
+
box-shadow: 0 24px 80px rgba(37, 34, 29, 0.18);
|
|
2339
|
+
}` : "html, body, #map { height: 100%; margin: 0; }";
|
|
2269
2340
|
return `<!doctype html>
|
|
2270
2341
|
<html lang="en">
|
|
2271
2342
|
<head>
|
|
@@ -2274,7 +2345,7 @@ function previewHtml(mapName, basePath, state) {
|
|
|
2274
2345
|
<title>Tileflow Preview</title>
|
|
2275
2346
|
<link rel="stylesheet" href="${basePath}/__runtime/maplibre-gl.css" />
|
|
2276
2347
|
<style>
|
|
2277
|
-
|
|
2348
|
+
${viewportCss}
|
|
2278
2349
|
body { font-family: ui-sans-serif, system-ui, sans-serif; }
|
|
2279
2350
|
.badge {
|
|
2280
2351
|
position: fixed;
|
|
@@ -2315,20 +2386,21 @@ function previewHtml(mapName, basePath, state) {
|
|
|
2315
2386
|
const initialGeneration = initialStatus.generation;
|
|
2316
2387
|
const badge = document.getElementById("badge");
|
|
2317
2388
|
const status = document.getElementById("status");
|
|
2389
|
+
const previewLabel = ${JSON.stringify(preview?.label)};
|
|
2318
2390
|
const styleUrl = ${JSON.stringify(styleUrl)};
|
|
2391
|
+
const previewMapOptions = ${JSON.stringify(mapOptions)};
|
|
2319
2392
|
|
|
2320
2393
|
if (styleUrl) {
|
|
2321
2394
|
const map = new maplibregl.Map({
|
|
2322
2395
|
container: "map",
|
|
2323
2396
|
style: styleUrl,
|
|
2324
|
-
|
|
2325
|
-
zoom: 12
|
|
2397
|
+
...previewMapOptions
|
|
2326
2398
|
});
|
|
2327
2399
|
map.addControl(new maplibregl.NavigationControl(), "top-right");
|
|
2328
2400
|
}
|
|
2329
2401
|
|
|
2330
2402
|
function applyStatus(next) {
|
|
2331
|
-
badge.textContent = "Tileflow preview
|
|
2403
|
+
badge.textContent = ["Tileflow preview", previewLabel, next.status].filter(Boolean).join(" \xB7 ");
|
|
2332
2404
|
if (next.status === "invalid") {
|
|
2333
2405
|
const diagnostics = next.diagnostics || [];
|
|
2334
2406
|
status.textContent = diagnostics.map((item) =>
|
|
@@ -2352,6 +2424,26 @@ function previewHtml(mapName, basePath, state) {
|
|
|
2352
2424
|
</body>
|
|
2353
2425
|
</html>`;
|
|
2354
2426
|
}
|
|
2427
|
+
function previewMapOptions(preview) {
|
|
2428
|
+
if (preview.camera.type === "center") {
|
|
2429
|
+
return {
|
|
2430
|
+
bearing: preview.camera.bearing,
|
|
2431
|
+
center: preview.camera.center,
|
|
2432
|
+
pitch: preview.camera.pitch,
|
|
2433
|
+
zoom: preview.camera.zoom
|
|
2434
|
+
};
|
|
2435
|
+
}
|
|
2436
|
+
const [west, south, east, north] = preview.camera.bounds;
|
|
2437
|
+
return {
|
|
2438
|
+
bearing: preview.camera.bearing,
|
|
2439
|
+
bounds: [
|
|
2440
|
+
[west, south],
|
|
2441
|
+
[east, north]
|
|
2442
|
+
],
|
|
2443
|
+
fitBoundsOptions: { padding: preview.camera.padding },
|
|
2444
|
+
pitch: preview.camera.pitch
|
|
2445
|
+
};
|
|
2446
|
+
}
|
|
2355
2447
|
var localRequire = createRequire(import.meta.url);
|
|
2356
2448
|
var localMapLibreJavaScript;
|
|
2357
2449
|
var localMapLibreStylesheet;
|
|
@@ -2398,6 +2490,7 @@ function isPathWithin(root, candidate) {
|
|
|
2398
2490
|
}
|
|
2399
2491
|
export {
|
|
2400
2492
|
TileflowIconCompilationError,
|
|
2493
|
+
TileflowPreviewSelectionError,
|
|
2401
2494
|
TileflowStyleValidationError,
|
|
2402
2495
|
TileflowValidationError,
|
|
2403
2496
|
asTileflowProjectConfig,
|
|
@@ -2432,6 +2525,7 @@ export {
|
|
|
2432
2525
|
loadValidTileflowConfig,
|
|
2433
2526
|
normalizeTileflowBasePath,
|
|
2434
2527
|
prepareTileflowProjectIcons,
|
|
2528
|
+
resolveTileflowPreview,
|
|
2435
2529
|
tileflowArtifactSessionSchemaVersion,
|
|
2436
2530
|
validateTileflowStyle,
|
|
2437
2531
|
writeTileflowBuildArtifacts,
|
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.17",
|
|
4
4
|
"description": "Node development utilities for Tileflow configs and builds.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -38,12 +38,12 @@
|
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@mapbox/vector-tile": "2.0.5",
|
|
40
40
|
"@maplibre/maplibre-gl-style-spec": "24.8.5",
|
|
41
|
+
"@tileflow/core": ">=0.1.0-alpha.17 <0.1.0-beta.0",
|
|
41
42
|
"chokidar": "4.0.3",
|
|
42
43
|
"jiti": "^2.7.0",
|
|
43
44
|
"maplibre-gl": "5.24.0",
|
|
44
45
|
"pbf": "4.0.2",
|
|
45
|
-
"saxes": "6.0.0"
|
|
46
|
-
"@tileflow/core": "0.1.0-alpha.16"
|
|
46
|
+
"saxes": "6.0.0"
|
|
47
47
|
},
|
|
48
48
|
"optionalDependencies": {
|
|
49
49
|
"sharp": "0.35.3"
|