@tileflow/dev 0.1.0-alpha.16 → 0.1.0-alpha.18

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 CHANGED
@@ -45,6 +45,24 @@ 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. The built-in preview records longitude, latitude, zoom, bearing,
63
+ and pitch in the current URL after the camera moves, so browser refreshes and config-triggered
64
+ reloads return to the same view. Removing those query parameters restores the configured camera.
65
+
48
66
  If a map uses `icons: './icons/brand'`, build artifacts include the generated
49
67
  MapLibre `sprite.json`, `sprite.png`, `sprite@2x.json`, and `sprite@2x.png`
50
68
  assets alongside the styles.
@@ -86,8 +104,14 @@ const result = await compileTileflowIconPackages(project, {
86
104
  });
87
105
  ```
88
106
 
107
+ When a Streets map does not select a local or external icon set, the pipeline compiles the built-in
108
+ `tileflow-streets` POI catalog and merges any mapping-only overrides on top of its semantic mapping.
109
+ `modules.poi.icons: false`, a disabled POI module, or the `none` POI preset suppresses that implicit
110
+ package. An explicit local source or hosted sprite always replaces it.
111
+
89
112
  The hosted target enforces repository containment, portable icon IDs, safe SVG
90
- references, deterministic ordering, and the public package limits. It returns
113
+ references, deterministic ordering, and the public package limits. The package-owned Streets
114
+ catalog is trusted input and is the only source exempt from project-root containment. It returns
91
115
  deduplicated generated files plus a canonical manifest/content hash. Upload only
92
116
  those generated files: source icons and absolute paths remain local. External
93
117
  sprite URLs are preserved as references and are not downloaded.
@@ -0,0 +1,11 @@
1
+ # Third-party notices
2
+
3
+ ## Google Places icons
4
+
5
+ The glyph artwork in `assets/streets-poi` is adapted from Google Places icons published in the
6
+ [Google Places API documentation](https://developers.google.com/maps/documentation/places/web-service/icons).
7
+ Copyright Google LLC. The documentation content is licensed under the
8
+ [Creative Commons Attribution 4.0 License](https://creativecommons.org/licenses/by/4.0/).
9
+
10
+ Tileflow modifies the source artwork by resizing and recoloring the glyphs, then composing them
11
+ inside circular category markers with a white rim and shadow.
@@ -0,0 +1,10 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
2
+ <title>Cafe</title>
3
+ <circle cx="12" cy="13" r="10.5" fill="#44515E" opacity=".08"/>
4
+ <circle cx="12" cy="12.5" r="10" fill="#44515E" opacity=".22"/>
5
+ <circle cx="12" cy="11" r="10" fill="#FFFFFF"/>
6
+ <circle cx="12" cy="11" r="8.25" fill="#FF9E67"/>
7
+ <svg x="6.75" y="7" width="10.5" height="7.875" viewBox="0 0 12 9" fill="#FFFFFF">
8
+ <path transform="translate(-5 -7)" fill-rule="evenodd" d="M13.4656593,7 L15.1589761,7 C15.6924964,7 16.125,7.43246448 16.125,7.96611494 L16.125,9.90201693 C16.125,10.4355875 15.6906762,10.8681319 15.1589761,10.8681319 L13.7074176,10.8681319 L11.8942308,13.043956 L8.0260989,13.043956 L6.09203297,10.8681319 L5.125,7 L13.4656593,7 Z M5.48763736,14.2527473 L15.157967,14.2527473 L15.157967,15.7032967 L5.48763736,15.7032967 Z M13.7074176,7.96703297 L15.157967,7.96703297 L15.157967,9.9010989 L13.7074176,9.9010989 Z"/>
9
+ </svg>
10
+ </svg>
@@ -0,0 +1,10 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
2
+ <title>Hospital</title>
3
+ <circle cx="12" cy="13" r="10.5" fill="#44515E" opacity=".08"/>
4
+ <circle cx="12" cy="12.5" r="10" fill="#44515E" opacity=".22"/>
5
+ <circle cx="12" cy="11" r="10" fill="#FFFFFF"/>
6
+ <circle cx="12" cy="11" r="8.25" fill="#F88181"/>
7
+ <svg x="8.5" y="6" width="7" height="10" viewBox="0 0 7 10" fill="#FFFFFF">
8
+ <path transform="translate(-7 -5)" fill-rule="evenodd" d="M8.55555556,14.8333333 L7,14.8333333 L7,5.5 L8.55555556,5.5 L8.55555556,9.38888889 L12.4444444,9.38888889 L12.4444444,5.5 L14,5.5 L14,14.8333333 L12.4444444,14.8333333 L12.4444444,10.9444444 L8.55555556,10.9444444 Z"/>
9
+ </svg>
10
+ </svg>
@@ -0,0 +1,10 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
2
+ <title>Lodging</title>
3
+ <circle cx="12" cy="13" r="10.5" fill="#44515E" opacity=".08"/>
4
+ <circle cx="12" cy="12.5" r="10" fill="#44515E" opacity=".22"/>
5
+ <circle cx="12" cy="11" r="10" fill="#FFFFFF"/>
6
+ <circle cx="12" cy="11" r="8.25" fill="#909CE1"/>
7
+ <svg x="6.5" y="7.5" width="11" height="7" viewBox="0 0 11 7" fill="#FFFFFF">
8
+ <path transform="translate(-5 -7)" fill-rule="evenodd" d="M5.86454849,7 C6.07788926,7 6.25083612,7.16733023 6.25083612,7.38333841 L6.25026087,11.23 L13.8162609,11.23 L13.8162609,11.229 L9.55363082,11.2296026 L9.55363082,7.94186138 C9.55363082,7.94186138 10.4141238,8.05735202 10.7150234,8.05735206 C12.2129784,8.05735203 13.5048382,9.50607239 14.0681491,10.3167693 L14.7461904,7.83035651 L14.7482609,8.617 L14.7491639,8.01836305 C14.7491639,7.83291732 14.8863533,7.67819481 15.0593924,7.64241177 L15.1354515,7.63461538 C15.3487923,7.63461538 15.5217391,7.8115966 15.5217391,8.01836305 L15.5217391,13.7692308 L14.7491639,13.7692308 L14.7482609,12.5 L6.25026087,12.5 L6.25083612,13.7692308 L5.47826087,13.7692308 L5.47826087,7.38333841 C5.47826087,7.19809045 5.61545027,7.04353295 5.78848942,7.00778807 L5.86454849,7 Z M7.98913043,8.05769231 C8.62915273,8.05769231 9.14799331,8.62594628 9.14799331,9.32692308 C9.14799331,10.0278999 8.62915273,10.5961538 7.98913043,10.5961538 C7.34910814,10.5961538 6.83026756,10.0278999 6.83026756,9.32692308 C6.83026756,8.62594628 7.34910814,8.05769231 7.98913043,8.05769231 Z"/>
9
+ </svg>
10
+ </svg>
@@ -0,0 +1,10 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
2
+ <title>Museum</title>
3
+ <circle cx="12" cy="13" r="10.5" fill="#44515E" opacity=".08"/>
4
+ <circle cx="12" cy="12.5" r="10" fill="#44515E" opacity=".22"/>
5
+ <circle cx="12" cy="11" r="10" fill="#FFFFFF"/>
6
+ <circle cx="12" cy="11" r="8.25" fill="#13B5C7"/>
7
+ <svg x="7.5" y="5.75" width="9" height="9.82" viewBox="0 0 11 12" fill="#FFFFFF">
8
+ <path transform="translate(-5 -4)" fill-rule="evenodd" d="M10.5,4.5 L16,8.5 L16,9.5 L15,9.5 L15,15 L16,15 L16,16 L5,16 L5,15 L6,15 L6,9.5 L5,9.5 L5,8.5 L10.5,4.5 Z M14,8.5 L7,8.5 L7,15 L14,15 L14,8.5 Z M8.99948459,9.49839952 L10.5053982,11.6376682 L12,9.512 L12,9.5 L13,9.5 L13,14 L12,14 L12,11.264 L10.5053982,13.6524794 L8.999,11.277 L9,14 L8,14 L8,9.5 L9,9.5 Z"/>
9
+ </svg>
10
+ </svg>
@@ -0,0 +1,10 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
2
+ <title>Restaurant</title>
3
+ <circle cx="12" cy="13" r="10.5" fill="#44515E" opacity=".08"/>
4
+ <circle cx="12" cy="12.5" r="10" fill="#44515E" opacity=".22"/>
5
+ <circle cx="12" cy="11" r="10" fill="#FFFFFF"/>
6
+ <circle cx="12" cy="11" r="8.25" fill="#FF9E67"/>
7
+ <svg x="8.5" y="6" width="7" height="9.625" viewBox="0 0 8 11" fill="#FFFFFF">
8
+ <path transform="translate(-6 -6)" fill-rule="evenodd" d="M12.4864865,12.0540541 L12.4864865,16.1621622 L14,16.1621622 L14,6.21621622 L12.4864865,6.21621622 L11.6216216,7.94594595 L11.6216216,10.7567568 L12.4864865,12.0540541 Z M9.02702703,10.7567568 L9.02702703,11.1891892 L10.7567568,10.3243243 L10.7567568,9.89189189 L10.7567568,7.08108108 L9.67567568,6.21621622 L9.67567568,9.45945946 L9.13513514,9.45945946 L8.81081081,9.45945946 L8.81081081,6 L7.94594595,6 L7.94594595,9.45945946 L7.62162162,9.45945946 L7.08108108,9.45945946 L7.08108108,6.21621622 L6,7.08108108 L6,9.89189189 L6,10.3243243 L7.72972973,11.1891892 L7.72972973,10.7567568 L7.72972973,16.1621622 L9.02702703,16.1621622 Z"/>
9
+ </svg>
10
+ </svg>
@@ -0,0 +1,10 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
2
+ <title>School</title>
3
+ <circle cx="12" cy="13" r="10.5" fill="#44515E" opacity=".08"/>
4
+ <circle cx="12" cy="12.5" r="10" fill="#44515E" opacity=".22"/>
5
+ <circle cx="12" cy="11" r="10" fill="#FFFFFF"/>
6
+ <circle cx="12" cy="11" r="8.25" fill="#7B9EB0"/>
7
+ <svg x="6.75" y="6.5" width="10.5" height="8.9" viewBox="0 0 13 11" fill="#FFFFFF">
8
+ <path transform="translate(-4 -5)" fill-rule="evenodd" d="M14.0097657,12.019911 L14.0097657,13.8695475 C13.1038778,15.4241579 10.6537375,15.3674047 10.5024279,15.3623802 C10.3511182,15.3674047 7.90097798,15.4241579 6.99509006,13.8695475 L6.99509006,12.019911 C6.99509006,12.019911 9.60423929,13.5859459 10.5024279,13.6268096 C11.4006164,13.5859459 14.0097657,12.019911 14.0097657,12.019911 Z M10.5,5 L17,8.25037977 L17,9.23855252 L16,9.738 L16,14.7579754 L15,14.7579754 L15,10.238 L10.5,12.4889323 L4,9.23855252 L4,8.25037977 L10.5,5 Z"/>
9
+ </svg>
10
+ </svg>
@@ -0,0 +1,10 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
2
+ <title>Services</title>
3
+ <circle cx="12" cy="13" r="10.5" fill="#44515E" opacity=".08"/>
4
+ <circle cx="12" cy="12.5" r="10" fill="#44515E" opacity=".22"/>
5
+ <circle cx="12" cy="11" r="10" fill="#FFFFFF"/>
6
+ <circle cx="12" cy="11" r="8.25" fill="#7B9EB0"/>
7
+ <svg x="6.75" y="6.25" width="10.5" height="9.55" viewBox="0 0 11 10" fill="#FFFFFF">
8
+ <path transform="translate(-5 -6)" fill-rule="evenodd" d="M11.015625,7.32533488 C13.2436218,5.65449747 15.9996948,6.04597697 15.9996948,6.04597697 L15.999,7.327 L16,7.32722697 L16,14.327227 L15.9140184,14.3269458 C11.9704111,14.3496822 11.930542,15.8108695 11.930542,15.8108695 L11.0158997,15.8108695 L11.015,14.327 L11,14.327227 L11,7.32722697 L12.123,7.327 Z M5.0078125,6.03795084 C5.0078125,6.03795084 7.7638855,5.65449747 9.99188232,7.32533488 L8.883,7.327 L10.0075073,7.32722697 L10.0075073,14.327227 L9.991,14.327 L9.99160767,15.8108695 L9.07696533,15.8108695 C9.06464946,15.6770402 8.85223435,14.3486164 5.09348894,14.3269458 L5.00750732,14.327227 L5.0078125,6.03795084 Z"/>
9
+ </svg>
10
+ </svg>
@@ -0,0 +1,10 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
2
+ <title>Shopping</title>
3
+ <circle cx="12" cy="13" r="10.5" fill="#44515E" opacity=".08"/>
4
+ <circle cx="12" cy="12.5" r="10" fill="#44515E" opacity=".22"/>
5
+ <circle cx="12" cy="11" r="10" fill="#FFFFFF"/>
6
+ <circle cx="12" cy="11" r="8.25" fill="#4B96F3"/>
7
+ <svg x="7" y="6.25" width="10" height="9.23" viewBox="0 0 13 12" fill="#FFFFFF">
8
+ <path transform="translate(-4 -3)" fill-rule="evenodd" d="M7.49019231,10.9275 C7.49019231,10.6215865 7.75802885,10.3747356 8.09141827,10.3747356 C8.42242788,10.3747356 8.69286058,10.6215865 8.69286058,10.9275 C8.69286058,11.6896875 9.46045673,12.3811298 10.5012981,12.3852404 C11.5421394,12.3811298 12.3060577,11.6896875 12.3086538,10.9275 C12.311899,10.6215865 12.5777885,10.3747356 12.9107452,10.3747356 C13.2415385,10.3747356 13.5137019,10.6215865 13.5137019,10.9275 C13.503101,12.3852404 12.1208654,13.4855769 10.5012981,13.4864423 C8.88259615,13.4855769 7.49689904,12.3852404 7.49019231,10.9275 Z M9.41415865,5.7046875 C9.77740385,5.03704327 10.2157212,4.76574519 10.5038942,4.78024038 C10.7881731,4.76574519 11.2264904,5.03704327 11.5901683,5.7046875 C11.8982452,6.26675481 12.1091827,7.15074519 12.1665144,8.03971154 L8.83608173,8.03971154 C8.89341346,7.15074519 9.10478365,6.26675481 9.41415865,5.7046875 M15.5291827,8.18855769 C15.4253365,8.09293269 15.2786538,8.03971154 15.130024,8.03971154 L13.2858894,8.03971154 C13.1439663,5.85439904 12.2803125,3.879375 10.5038942,3.75 C8.72314904,3.879375 7.85819712,5.85439904 7.71670673,8.03971154 L5.87213942,8.03971154 C5.72394231,8.03971154 5.57725962,8.09293269 5.47254808,8.18855769 C5.36848558,8.28569712 5.30769231,8.4159375 5.30769231,8.55439904 L4.875,14.4861779 C4.875,14.6222596 4.93665865,14.7548798 5.03985577,14.8496394 C5.14802885,14.9459135 5.29125,15 5.43944712,15 L15.5627163,15 C15.7139423,15 15.8541346,14.9476442 15.9590625,14.8496394 C16.0678846,14.7525 16.125,14.6248558 16.125,14.4861779 L15.6923077,8.55439904 C15.6923077,8.41918269 15.6328125,8.28569712 15.5291827,8.18855769"/>
9
+ </svg>
10
+ </svg>
@@ -0,0 +1,10 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
2
+ <title>Train and rail</title>
3
+ <circle cx="12" cy="13" r="10.5" fill="#44515E" opacity=".08"/>
4
+ <circle cx="12" cy="12.5" r="10" fill="#44515E" opacity=".22"/>
5
+ <circle cx="12" cy="11" r="10" fill="#FFFFFF"/>
6
+ <circle cx="12" cy="11" r="8.25" fill="#10BDFF"/>
7
+ <svg x="7.875" y="5.9" width="8.25" height="9.8" viewBox="0 0 16 19" fill="#FFFFFF">
8
+ <path d="M8,0C4,0,0,.5,0,4v9.5A3.5,3.5,0,0,0,3.5,17L2,18.5V19H4.23l2-2H10l2,2h2v-.5L12.5,17A3.5,3.5,0,0,0,16,13.5V4c0-3.5-3.58-4-8-4ZM3.5,15A1.5,1.5,0,1,1,5,13.5,1.5,1.5,0,0,1,3.5,15ZM7,8H2V4H7V8ZM9,8V4h5V8Zm3.5,7A1.5,1.5,0,1,1,14,13.5,1.5,1.5,0,0,1,12.5,15Z"/>
9
+ </svg>
10
+ </svg>
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 = {
@@ -163,6 +163,7 @@ declare function prepareTileflowProjectIcons(project: TileflowProjectConfig, opt
163
163
  }): Promise<PreparedTileflowProject>;
164
164
 
165
165
  type TileflowFeatureInspectionOptions = {
166
+ apiBaseUrl?: string;
166
167
  center: readonly [number, number];
167
168
  fetch?: typeof fetch;
168
169
  height?: number;
@@ -170,7 +171,6 @@ type TileflowFeatureInspectionOptions = {
170
171
  properties?: readonly string[];
171
172
  signal?: AbortSignal;
172
173
  sourceLayers: readonly string[];
173
- tileBaseUrl?: string;
174
174
  timeoutMs?: number;
175
175
  width?: number;
176
176
  zoom: number;
@@ -231,30 +231,44 @@ declare function validateTileflowStyle(style: MapLibreStyle, map: string): Tilef
231
231
  declare const defaultTileflowApiUrl = "https://api.tileflow.dev";
232
232
  declare const defaultTileflowConfigPath = "tileflow.config.ts";
233
233
  declare const defaultTileflowManifestPath = "public/tileflow/manifest.json";
234
- declare const defaultTileflowTileset = "world";
235
234
  type LoadTileflowConfigOptions = {
236
235
  cwd?: string;
237
236
  fresh?: boolean;
238
237
  };
239
238
  type TileflowManifestOptions = {
240
239
  styleBaseUrl?: string;
241
- tileBaseUrl?: string;
242
240
  };
243
241
  type TileflowDevRequestHandlerOptions = {
242
+ apiBaseUrl?: string;
244
243
  basePath?: string;
245
244
  config?: string;
246
245
  cwd?: string;
246
+ map?: string;
247
247
  onError?: (error: unknown) => void;
248
+ scene?: string;
248
249
  session?: TileflowArtifactSession;
249
250
  styleBaseUrl?: string;
250
- tileBaseUrl?: string;
251
251
  };
252
+ type TileflowPreviewSelection = {
253
+ map?: string;
254
+ scene?: string;
255
+ };
256
+ type ResolvedTileflowPreview = {
257
+ camera: NormalizedTileflowCaptureScene['camera'];
258
+ label: string;
259
+ mapName: string;
260
+ viewport?: NormalizedTileflowCaptureScene['viewport'];
261
+ };
262
+ declare class TileflowPreviewSelectionError extends Error {
263
+ readonly code: "PREVIEW_SELECTION_INVALID";
264
+ constructor(message: string);
265
+ }
252
266
  type TileflowBuildArtifactsOptions = {
267
+ apiBaseUrl?: string;
253
268
  assetBaseUrl?: string;
254
269
  config?: string;
255
270
  cwd?: string;
256
271
  styleBaseUrl?: string;
257
- tileBaseUrl?: string;
258
272
  };
259
273
  type TileflowBuildArtifacts = {
260
274
  assets: TileflowBuildAsset[];
@@ -278,6 +292,7 @@ declare function assertValidTileflowConfig(project: TileflowProjectConfig): void
278
292
  declare function asTileflowProjectConfig(input: unknown): TileflowProjectConfig;
279
293
  declare function getTileflowMapNames(project: TileflowProjectConfig): string[];
280
294
  declare function getFirstTileflowMapName(project: TileflowProjectConfig): string;
295
+ declare function resolveTileflowPreview(project: TileflowProjectConfig, selection?: TileflowPreviewSelection): ResolvedTileflowPreview;
281
296
  declare function getTileflowStyleMapName(path: string): string;
282
297
  declare function createTileflowManifest(project: TileflowProjectConfig, options?: TileflowManifestOptions): TileflowManifest;
283
298
  declare function createTileflowStyle(project: TileflowProjectConfig, mapName: string, options?: TileflowStyleOptions): MapLibreStyle;
@@ -302,4 +317,4 @@ declare function createTileflowArtifactStatus(state: TileflowArtifactSessionStat
302
317
  };
303
318
  declare function normalizeTileflowBasePath(value?: string): string;
304
319
 
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 };
320
+ 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, 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,12 +8,14 @@ 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
 
14
15
  // src/icons.ts
15
16
  import { readdir, readFile, realpath, stat } from "fs/promises";
16
17
  import { basename, extname, isAbsolute, relative, resolve, sep } from "path";
18
+ import { fileURLToPath } from "url";
17
19
  import { SaxesParser } from "saxes";
18
20
  import {
19
21
  compareCodeUnits,
@@ -24,7 +26,8 @@ import {
24
26
  tileflowHostedIconIdPattern,
25
27
  tileflowIconPackageLabelSchema,
26
28
  tileflowIconPackageLimits,
27
- tileflowIconPackageManifestSchema
29
+ tileflowIconPackageManifestSchema,
30
+ tileflowStreetsPoiIconMapping
28
31
  } from "@tileflow/core";
29
32
  var TileflowIconCompilationError = class extends Error {
30
33
  code = "ICON_INVALID";
@@ -43,6 +46,7 @@ var TileflowIconCompilationError = class extends Error {
43
46
  };
44
47
  var iconFileExtensions = /* @__PURE__ */ new Set([".svg", ".png", ".jpg", ".jpeg", ".webp"]);
45
48
  var iconSpriteSize = 24;
49
+ var streetsPoiIconSourceDir = fileURLToPath(new URL("../assets/streets-poi", import.meta.url));
46
50
  async function compileTileflowIconPackages(project, options) {
47
51
  const result = await compileIconSources(project, options);
48
52
  const packagesByHash = /* @__PURE__ */ new Map();
@@ -66,7 +70,11 @@ async function compileTileflowIconPackages(project, options) {
66
70
  packages: [...packagesByHash.values()].sort(
67
71
  (left, right) => compareCodeUnits(left.contentHash, right.contentHash)
68
72
  ),
69
- watchPaths: [...result.compiledBySource.keys()].sort(compareCodeUnits)
73
+ watchPaths: [
74
+ ...new Set(
75
+ result.resolvedRequests.filter((request) => !request.builtIn).map((request) => request.realSourceDir)
76
+ )
77
+ ].sort(compareCodeUnits)
70
78
  };
71
79
  }
72
80
  async function inspectTileflowIconCatalogs(project, options) {
@@ -192,7 +200,7 @@ async function compileIconSources(project, options) {
192
200
  for (const request of requests) {
193
201
  try {
194
202
  const realSourceDir = await realpath(request.sourceDir);
195
- if (options.target === "hosted" && realCwd && !isPathInside(realCwd, realSourceDir)) {
203
+ if (options.target === "hosted" && realCwd && !request.builtIn && !isPathInside(realCwd, realSourceDir)) {
196
204
  issues.push({
197
205
  message: "Hosted icon sources must remain inside the selected working tree",
198
206
  path: sourcePath(request.mapName)
@@ -292,9 +300,9 @@ async function prepareTileflowProjectIcons(project, options) {
292
300
  };
293
301
  }
294
302
  function getTileflowIconWatchPaths(project, cwd) {
295
- return uniqueStrings(getLocalIconRequests(project, cwd).map((request) => request.sourceDir)).sort(
296
- compareCodeUnits
297
- );
303
+ return uniqueStrings(
304
+ getLocalIconRequests(project, cwd).filter((request) => !request.builtIn).map((request) => request.sourceDir)
305
+ ).sort(compareCodeUnits);
298
306
  }
299
307
  function getLocalIconRequests(project, cwd) {
300
308
  return getMapIconRequests(project, cwd).filter(
@@ -309,6 +317,18 @@ function getMapIconRequests(project, cwd, mapNames) {
309
317
  throw new Error(`Unknown Tileflow map: ${mapName}`);
310
318
  }
311
319
  const iconSet = resolveIconSet(mapConfig.icons, project.icons);
320
+ if (!iconSet?.source && !iconSet?.sprite && usesBuiltInStreetsPoiIcons(mapConfig)) {
321
+ const mapping2 = sortMapping({ ...tileflowStreetsPoiIconMapping, ...iconSet?.mapping });
322
+ return {
323
+ builtIn: true,
324
+ kind: "local",
325
+ label: "tileflow-streets",
326
+ mapName,
327
+ ...mapping2 ? { mapping: mapping2 } : {},
328
+ source: "@tileflow/dev/assets/streets-poi",
329
+ sourceDir: streetsPoiIconSourceDir
330
+ };
331
+ }
312
332
  const mapping = sortMapping(iconSet?.mapping);
313
333
  if (iconSet?.source) {
314
334
  return {
@@ -327,6 +347,10 @@ function getMapIconRequests(project, cwd, mapNames) {
327
347
  };
328
348
  });
329
349
  }
350
+ function usesBuiltInStreetsPoiIcons(mapConfig) {
351
+ const poi = mapConfig.modules?.poi;
352
+ return mapConfig.basemap?.type === "streets" && poi?.enabled !== false && poi?.preset !== "none" && poi?.icons !== false;
353
+ }
330
354
  function resolveIconSet(icons, iconSets, path = []) {
331
355
  if (!icons) {
332
356
  return void 0;
@@ -993,11 +1017,11 @@ var TileflowArtifactSessionImpl = class {
993
1017
  this.#ignoredPaths = (options.ignoredPaths ?? []).map((path) => resolve2(this.#cwd, path));
994
1018
  this.#buildArtifacts = buildArtifacts;
995
1019
  this.#buildOptions = {
1020
+ apiBaseUrl: options.apiBaseUrl,
996
1021
  assetBaseUrl: options.assetBaseUrl,
997
1022
  config: options.config,
998
1023
  cwd: this.#cwd,
999
- styleBaseUrl: options.styleBaseUrl,
1000
- tileBaseUrl: options.tileBaseUrl
1024
+ styleBaseUrl: options.styleBaseUrl
1001
1025
  };
1002
1026
  }
1003
1027
  async start() {
@@ -1428,7 +1452,7 @@ async function inspectTileflowFeatures(project, mapName, input) {
1428
1452
  `Unknown map "${mapName}". Available maps: ${available.join(", ") || "(none)"}`
1429
1453
  );
1430
1454
  }
1431
- const style = createStyleFromProject(project, mapName, { tileBaseUrl: options.tileBaseUrl });
1455
+ const style = createStyleFromProject(project, mapName, { apiBaseUrl: options.apiBaseUrl });
1432
1456
  assertValidTileflowStyle(style, mapName);
1433
1457
  const source = resolveVectorSource(style, options.sourceLayers);
1434
1458
  const fetchImplementation = options.fetch ?? globalThis.fetch;
@@ -1494,7 +1518,8 @@ async function inspectTileflowFeatures(project, mapName, input) {
1494
1518
  }
1495
1519
  const uniqueFeatures = deduplicateFeatures(features).sort(compareInspectedFeatures);
1496
1520
  const limitedFeatures = uniqueFeatures.slice(0, options.limit);
1497
- const metadataVersion = style.metadata?.["tileflow:tilesetVersion"];
1521
+ const dataIdentity = style.metadata?.["tileflow:data"];
1522
+ const metadataVersion = dataIdentity && typeof dataIdentity === "object" && "revision" in dataIdentity ? dataIdentity.revision : void 0;
1498
1523
  return {
1499
1524
  schemaVersion: 1,
1500
1525
  map: mapName,
@@ -1839,7 +1864,13 @@ function isRecord(value) {
1839
1864
  var defaultTileflowApiUrl = "https://api.tileflow.dev";
1840
1865
  var defaultTileflowConfigPath = "tileflow.config.ts";
1841
1866
  var defaultTileflowManifestPath = "public/tileflow/manifest.json";
1842
- var defaultTileflowTileset = "world";
1867
+ var TileflowPreviewSelectionError = class extends Error {
1868
+ code = "PREVIEW_SELECTION_INVALID";
1869
+ constructor(message) {
1870
+ super(message);
1871
+ this.name = "TileflowPreviewSelectionError";
1872
+ }
1873
+ };
1843
1874
  var TileflowValidationError = class extends Error {
1844
1875
  code = "CONFIG_INVALID";
1845
1876
  messages;
@@ -1881,17 +1912,7 @@ function asTileflowProjectConfig(input) {
1881
1912
  if (input && typeof input === "object" && "maps" in input && typeof input.maps === "object") {
1882
1913
  return input;
1883
1914
  }
1884
- return {
1885
- tilesets: {
1886
- [defaultTileflowTileset]: {
1887
- id: defaultTileflowTileset,
1888
- name: "World"
1889
- }
1890
- },
1891
- maps: {
1892
- main: input
1893
- }
1894
- };
1915
+ return { maps: { main: input } };
1895
1916
  }
1896
1917
  function getTileflowMapNames(project) {
1897
1918
  return Object.keys(project.maps);
@@ -1903,6 +1924,52 @@ function getFirstTileflowMapName(project) {
1903
1924
  }
1904
1925
  return mapName;
1905
1926
  }
1927
+ function resolveTileflowPreview(project, selection = {}) {
1928
+ if (selection.map !== void 0 && selection.scene !== void 0) {
1929
+ throw new TileflowPreviewSelectionError(
1930
+ "Choose either a Tileflow preview map or scene, not both."
1931
+ );
1932
+ }
1933
+ if (selection.scene !== void 0) {
1934
+ const scene = Object.hasOwn(project.scenes ?? {}, selection.scene) ? project.scenes?.[selection.scene] : void 0;
1935
+ if (!scene) {
1936
+ throw new TileflowPreviewSelectionError(`Unknown Tileflow scene: ${selection.scene}`);
1937
+ }
1938
+ const normalized = normalizeTileflowCaptureScene(scene);
1939
+ if (normalized.target.kind === "application") {
1940
+ throw new TileflowPreviewSelectionError(
1941
+ `Tileflow scene "${selection.scene}" targets an application. Preview it through the application's development server.`
1942
+ );
1943
+ }
1944
+ if (!Object.hasOwn(project.maps, normalized.map)) {
1945
+ throw new TileflowPreviewSelectionError(
1946
+ `Tileflow scene "${selection.scene}" references an unknown map: ${normalized.map}`
1947
+ );
1948
+ }
1949
+ return {
1950
+ camera: normalized.camera,
1951
+ label: `${normalized.map} / ${selection.scene} \xB7 ${normalized.viewport.width}\xD7${normalized.viewport.height}`,
1952
+ mapName: normalized.map,
1953
+ viewport: normalized.viewport
1954
+ };
1955
+ }
1956
+ const mapName = selection.map ?? getFirstTileflowMapName(project);
1957
+ const map = Object.hasOwn(project.maps, mapName) ? project.maps[mapName] : void 0;
1958
+ if (!map) {
1959
+ throw new TileflowPreviewSelectionError(`Unknown Tileflow map: ${mapName}`);
1960
+ }
1961
+ return {
1962
+ camera: {
1963
+ type: "center",
1964
+ center: map.view?.center ? [map.view.center[0], map.view.center[1]] : [0, 0],
1965
+ zoom: map.view?.zoom ?? 0,
1966
+ bearing: map.view?.bearing ?? 0,
1967
+ pitch: map.view?.pitch ?? 0
1968
+ },
1969
+ label: mapName,
1970
+ mapName
1971
+ };
1972
+ }
1906
1973
  function getTileflowStyleMapName(path) {
1907
1974
  const fileName = path.split("/").pop() ?? "";
1908
1975
  return fileName.replace(/\.json$/, "");
@@ -1937,13 +2004,12 @@ async function createTileflowBuildArtifacts(options = {}) {
1937
2004
  assetBaseUrl: resolveAssetBaseUrl(options),
1938
2005
  cwd: options.cwd ?? process.cwd()
1939
2006
  });
1940
- const styleOptions = { tileBaseUrl: options.tileBaseUrl };
2007
+ const styleOptions = { apiBaseUrl: options.apiBaseUrl };
1941
2008
  const styles = createTileflowStyles(prepared.project, styleOptions);
1942
2009
  return {
1943
2010
  assets: prepared.assets,
1944
2011
  manifest: createManifest(prepared.project, {
1945
- styleBaseUrl: options.styleBaseUrl,
1946
- tileBaseUrl: options.tileBaseUrl
2012
+ styleBaseUrl: options.styleBaseUrl
1947
2013
  }),
1948
2014
  project: prepared.project,
1949
2015
  styles,
@@ -2048,7 +2114,7 @@ function createTileflowDevRequestHandler(options = {}) {
2048
2114
  const basePath = normalizeTileflowBasePath(options.basePath);
2049
2115
  const configPath = options.config ?? defaultTileflowConfigPath;
2050
2116
  const cwd = options.cwd ?? process.cwd();
2051
- const tileBaseUrl = options.tileBaseUrl ?? defaultTileflowApiUrl;
2117
+ const apiBaseUrl = options.apiBaseUrl ?? defaultTileflowApiUrl;
2052
2118
  return async function handleTileflowDevRequest(request) {
2053
2119
  if (request.method !== "GET" && request.method !== "HEAD") {
2054
2120
  return jsonResponse({ error: "Method not allowed" }, 405);
@@ -2079,7 +2145,7 @@ function createTileflowDevRequestHandler(options = {}) {
2079
2145
  config: configPath,
2080
2146
  cwd,
2081
2147
  styleBaseUrl: options.styleBaseUrl ?? `${url.origin}${basePath}`,
2082
- tileBaseUrl
2148
+ apiBaseUrl
2083
2149
  });
2084
2150
  state = {
2085
2151
  artifacts,
@@ -2092,8 +2158,8 @@ function createTileflowDevRequestHandler(options = {}) {
2092
2158
  return jsonResponse(createTileflowArtifactStatus(state));
2093
2159
  }
2094
2160
  if (path === "/" || path === "") {
2095
- const mapName = artifacts ? getFirstTileflowMapName(artifacts.project) : void 0;
2096
- return htmlResponse(previewHtml(mapName, basePath, state));
2161
+ const preview = artifacts ? resolveTileflowPreview(artifacts.project, { map: options.map, scene: options.scene }) : void 0;
2162
+ return htmlResponse(previewHtml(preview, basePath, state));
2097
2163
  }
2098
2164
  if (!artifacts) return unavailableArtifactsResponse(state);
2099
2165
  if (path === "/manifest.json") {
@@ -2199,6 +2265,9 @@ function stripTileflowBasePath(pathname, basePath) {
2199
2265
  return null;
2200
2266
  }
2201
2267
  function tileflowErrorResponse(error) {
2268
+ if (error instanceof TileflowPreviewSelectionError) {
2269
+ return jsonResponse({ error: error.message }, 400);
2270
+ }
2202
2271
  if (error instanceof TileflowStyleValidationError) {
2203
2272
  return jsonResponse(
2204
2273
  {
@@ -2263,9 +2332,23 @@ function resolveAssetBaseUrl(options) {
2263
2332
  function isRelativePublicUrl(value) {
2264
2333
  return !(value.startsWith("http://") || value.startsWith("https://") || value.startsWith("/") || value.startsWith("data:"));
2265
2334
  }
2266
- function previewHtml(mapName, basePath, state) {
2267
- const styleUrl = mapName ? `${basePath}/styles/${mapName}.json` : void 0;
2335
+ function previewHtml(preview, basePath, state) {
2336
+ const styleUrl = preview ? `${basePath}/styles/${preview.mapName}.json` : void 0;
2268
2337
  const initialStatus = createTileflowArtifactStatus(state);
2338
+ const mapOptions = preview ? previewMapOptions(preview) : void 0;
2339
+ const viewportCss = preview?.viewport ? `
2340
+ html, body { min-height: 100%; margin: 0; }
2341
+ body {
2342
+ display: grid;
2343
+ place-items: center;
2344
+ overflow: auto;
2345
+ background: #E8E5DE;
2346
+ }
2347
+ #map {
2348
+ width: ${preview.viewport.width}px;
2349
+ height: ${preview.viewport.height}px;
2350
+ box-shadow: 0 24px 80px rgba(37, 34, 29, 0.18);
2351
+ }` : "html, body, #map { height: 100%; margin: 0; }";
2269
2352
  return `<!doctype html>
2270
2353
  <html lang="en">
2271
2354
  <head>
@@ -2274,7 +2357,7 @@ function previewHtml(mapName, basePath, state) {
2274
2357
  <title>Tileflow Preview</title>
2275
2358
  <link rel="stylesheet" href="${basePath}/__runtime/maplibre-gl.css" />
2276
2359
  <style>
2277
- html, body, #map { height: 100%; margin: 0; }
2360
+ ${viewportCss}
2278
2361
  body { font-family: ui-sans-serif, system-ui, sans-serif; }
2279
2362
  .badge {
2280
2363
  position: fixed;
@@ -2315,20 +2398,85 @@ function previewHtml(mapName, basePath, state) {
2315
2398
  const initialGeneration = initialStatus.generation;
2316
2399
  const badge = document.getElementById("badge");
2317
2400
  const status = document.getElementById("status");
2401
+ const previewLabel = ${JSON.stringify(preview?.label)};
2318
2402
  const styleUrl = ${JSON.stringify(styleUrl)};
2403
+ const previewMapOptions = ${JSON.stringify(mapOptions)};
2404
+
2405
+ const cameraRanges = {
2406
+ bearing: [-180, 180],
2407
+ lat: [-90, 90],
2408
+ lng: [-180, 180],
2409
+ pitch: [0, 85],
2410
+ zoom: [0, 24]
2411
+ };
2412
+
2413
+ function readCameraFromUrl() {
2414
+ const params = new URL(location.href).searchParams;
2415
+ const camera = {};
2416
+
2417
+ for (const [name, range] of Object.entries(cameraRanges)) {
2418
+ const values = params.getAll(name);
2419
+ if (values.length !== 1 || values[0].trim() === "") return undefined;
2420
+ const value = Number(values[0]);
2421
+ if (!Number.isFinite(value) || value < range[0] || value > range[1]) return undefined;
2422
+ camera[name] = value;
2423
+ }
2424
+
2425
+ return {
2426
+ bearing: camera.bearing,
2427
+ center: [camera.lng, camera.lat],
2428
+ pitch: camera.pitch,
2429
+ zoom: camera.zoom
2430
+ };
2431
+ }
2432
+
2433
+ function resolveInitialMapOptions(options) {
2434
+ const camera = readCameraFromUrl();
2435
+ if (!camera) return options;
2436
+ const resolved = {...options};
2437
+ delete resolved.bounds;
2438
+ delete resolved.fitBoundsOptions;
2439
+ return {...resolved, ...camera};
2440
+ }
2441
+
2442
+ function formatCameraNumber(value) {
2443
+ return String(Number(value.toFixed(6)));
2444
+ }
2445
+
2446
+ function wrapLongitude(value) {
2447
+ return ((value + 180) % 360 + 360) % 360 - 180;
2448
+ }
2449
+
2450
+ function writeCameraToUrl(map) {
2451
+ const center = map.getCenter();
2452
+ const url = new URL(location.href);
2453
+ const camera = {
2454
+ bearing: map.getBearing(),
2455
+ lat: center.lat,
2456
+ lng: wrapLongitude(center.lng),
2457
+ pitch: map.getPitch(),
2458
+ zoom: map.getZoom()
2459
+ };
2460
+
2461
+ for (const [name, value] of Object.entries(camera)) {
2462
+ url.searchParams.set(name, formatCameraNumber(value));
2463
+ }
2464
+ history.replaceState(history.state, "", url.href);
2465
+ }
2319
2466
 
2320
2467
  if (styleUrl) {
2321
2468
  const map = new maplibregl.Map({
2322
2469
  container: "map",
2323
2470
  style: styleUrl,
2324
- center: [-3.7038, 40.4168],
2325
- zoom: 12
2471
+ ...resolveInitialMapOptions(previewMapOptions)
2326
2472
  });
2327
2473
  map.addControl(new maplibregl.NavigationControl(), "top-right");
2474
+ map.on("load", () => writeCameraToUrl(map));
2475
+ map.on("moveend", () => writeCameraToUrl(map));
2328
2476
  }
2329
2477
 
2330
2478
  function applyStatus(next) {
2331
- badge.textContent = "Tileflow preview \xB7 " + next.status;
2479
+ badge.textContent = ["Tileflow preview", previewLabel, next.status].filter(Boolean).join(" \xB7 ");
2332
2480
  if (next.status === "invalid") {
2333
2481
  const diagnostics = next.diagnostics || [];
2334
2482
  status.textContent = diagnostics.map((item) =>
@@ -2352,6 +2500,26 @@ function previewHtml(mapName, basePath, state) {
2352
2500
  </body>
2353
2501
  </html>`;
2354
2502
  }
2503
+ function previewMapOptions(preview) {
2504
+ if (preview.camera.type === "center") {
2505
+ return {
2506
+ bearing: preview.camera.bearing,
2507
+ center: preview.camera.center,
2508
+ pitch: preview.camera.pitch,
2509
+ zoom: preview.camera.zoom
2510
+ };
2511
+ }
2512
+ const [west, south, east, north] = preview.camera.bounds;
2513
+ return {
2514
+ bearing: preview.camera.bearing,
2515
+ bounds: [
2516
+ [west, south],
2517
+ [east, north]
2518
+ ],
2519
+ fitBoundsOptions: { padding: preview.camera.padding },
2520
+ pitch: preview.camera.pitch
2521
+ };
2522
+ }
2355
2523
  var localRequire = createRequire(import.meta.url);
2356
2524
  var localMapLibreJavaScript;
2357
2525
  var localMapLibreStylesheet;
@@ -2398,6 +2566,7 @@ function isPathWithin(root, candidate) {
2398
2566
  }
2399
2567
  export {
2400
2568
  TileflowIconCompilationError,
2569
+ TileflowPreviewSelectionError,
2401
2570
  TileflowStyleValidationError,
2402
2571
  TileflowValidationError,
2403
2572
  asTileflowProjectConfig,
@@ -2416,7 +2585,6 @@ export {
2416
2585
  defaultTileflowApiUrl,
2417
2586
  defaultTileflowConfigPath,
2418
2587
  defaultTileflowManifestPath,
2419
- defaultTileflowTileset,
2420
2588
  getFirstTileflowMapName,
2421
2589
  getTileflowAssetBasePath,
2422
2590
  getTileflowAssetFileName,
@@ -2432,6 +2600,7 @@ export {
2432
2600
  loadValidTileflowConfig,
2433
2601
  normalizeTileflowBasePath,
2434
2602
  prepareTileflowProjectIcons,
2603
+ resolveTileflowPreview,
2435
2604
  tileflowArtifactSessionSchemaVersion,
2436
2605
  validateTileflowStyle,
2437
2606
  writeTileflowBuildArtifacts,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tileflow/dev",
3
- "version": "0.1.0-alpha.16",
3
+ "version": "0.1.0-alpha.18",
4
4
  "description": "Node development utilities for Tileflow configs and builds.",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -23,7 +23,9 @@
23
23
  "main": "./dist/index.js",
24
24
  "types": "./dist/index.d.ts",
25
25
  "files": [
26
- "dist"
26
+ "assets",
27
+ "dist",
28
+ "THIRD_PARTY_NOTICES.md"
27
29
  ],
28
30
  "exports": {
29
31
  ".": {
@@ -38,12 +40,12 @@
38
40
  "dependencies": {
39
41
  "@mapbox/vector-tile": "2.0.5",
40
42
  "@maplibre/maplibre-gl-style-spec": "24.8.5",
43
+ "@tileflow/core": ">=0.1.0-alpha.19 <0.1.0-beta.0",
41
44
  "chokidar": "4.0.3",
42
45
  "jiti": "^2.7.0",
43
46
  "maplibre-gl": "5.24.0",
44
47
  "pbf": "4.0.2",
45
- "saxes": "6.0.0",
46
- "@tileflow/core": "0.1.0-alpha.16"
48
+ "saxes": "6.0.0"
47
49
  },
48
50
  "optionalDependencies": {
49
51
  "sharp": "0.35.3"