@versatiles/versatiles-rs 4.8.0 → 4.9.1

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.
Files changed (7) hide show
  1. package/README.md +71 -4
  2. package/index.cjs +57 -54
  3. package/index.d.ts +227 -19
  4. package/index.js +58 -55
  5. package/package.json +11 -11
  6. package/vpl.d.ts +430 -142
  7. package/vpl.js +99 -33
package/index.d.ts CHANGED
@@ -499,6 +499,8 @@ export declare class TileSource {
499
499
  * # Arguments
500
500
  *
501
501
  * * `path` - File path or URL to the tile container
502
+ * * `options` - Optional source options; `sshIdentity` names a private key
503
+ * file for an `sftp://` path
502
504
  *
503
505
  * # Returns
504
506
  *
@@ -519,9 +521,14 @@ export declare class TileSource {
519
521
  *
520
522
  * // Open remote file
521
523
  * const reader = await ContainerReader.from_path('https://example.com/tiles.pmtiles');
524
+ *
525
+ * // Open an SFTP file with a specific key
526
+ * const reader = await TileSource.fromPath('sftp://host/tiles.pmtiles', {
527
+ * sshIdentity: '/home/deploy/.ssh/id_ed25519',
528
+ * });
522
529
  * ```
523
530
  */
524
- static fromPath(path: string): Promise<TileSource>
531
+ static fromPath(path: string, options?: SourceOptions | undefined | null): Promise<TileSource>
525
532
  /**
526
533
  * Create a TileSource from a VPL (VersaTiles Pipeline Language) string
527
534
  *
@@ -586,7 +593,7 @@ export declare class TileSource {
586
593
  * VPL sources can be converted using `convertTo()` just like any other tile source.
587
594
  * The conversion will process the pipeline and write the output tiles to the target format.
588
595
  */
589
- static fromVpl(vpl: string, dir?: string | undefined | null): Promise<TileSource>
596
+ static fromVpl(vpl: string, dir?: string | undefined | null, options?: SourceOptions | undefined | null): Promise<TileSource>
590
597
  /**
591
598
  * Create a TileSource from a pipeline definition (JSON)
592
599
  *
@@ -598,8 +605,10 @@ export declare class TileSource {
598
605
  * * `steps_json` - JSON string describing the pipeline steps
599
606
  * * `dir` - Optional base directory for resolving relative file paths.
600
607
  * Defaults to the current working directory if not specified.
608
+ * * `options` - Optional source options; `sshIdentity` names a private key
609
+ * file for `sftp://` sources inside the pipeline
601
610
  */
602
- static fromPipeline(stepsJson: string, dir?: string | undefined | null): Promise<TileSource>
611
+ static fromPipeline(stepsJson: string, dir?: string | undefined | null, options?: SourceOptions | undefined | null): Promise<TileSource>
603
612
  /**
604
613
  * Convert this tile source to another format
605
614
  *
@@ -609,7 +618,7 @@ export declare class TileSource {
609
618
  *
610
619
  * # Arguments
611
620
  *
612
- * * `output` - Path to the output tile container
621
+ * * `output` - Path to the output tile container, or an `sftp://` URL
613
622
  * * `options` - Optional conversion options (zoom range, bbox, compression, etc.)
614
623
  * * `on_progress` - Optional callback for progress updates
615
624
  * * `on_message` - Optional callback for step/warning/error messages
@@ -621,7 +630,11 @@ export declare class TileSource {
621
630
  * - `bboxBorder`: Add border tiles around bbox (in tile units)
622
631
  * - `compress`: Output compression ("gzip", "brotli", "uncompressed")
623
632
  * - `flipY`: Flip tiles vertically (TMS ↔ XYZ coordinate systems)
624
- * - `swapXY`: Swap X and Y tile coordinates
633
+ * - `swapXy`: Swap X and Y tile coordinates
634
+ * - `writerOptions`: Format-specific settings for the output writer, keyed by the
635
+ * writer's own `snake_case` names, e.g. `{ allow_unclustered: 'true' }` for PMTiles
636
+ * - `sshIdentity`: Private key file for an `sftp://` input, defaulting to
637
+ * `VERSATILES_SSH_IDENTITY`
625
638
  *
626
639
  * # Progress Callbacks
627
640
  *
@@ -780,6 +793,34 @@ export declare class TileSource {
780
793
  sourceType(): SourceType
781
794
  }
782
795
 
796
+ /**
797
+ * Checks VPL text against the known operations, without building the pipeline.
798
+ *
799
+ * Building opens files and fetches URLs, so it cannot run on a keystroke — and it conflates two
800
+ * failures. `from_container filename=missing.mbtiles` is the *world* being wrong; `from_debug
801
+ * format=png nonsense=1` is the *pipeline* being wrong. This reports only the second kind, and
802
+ * performs no I/O.
803
+ *
804
+ * Returns a JSON string, with the same result shape as [`parse_vpl`]:
805
+ *
806
+ * - on success, `{"ok": true, "problems": [{"message": "...", "path": [0], "property": "nonsense"}]}`
807
+ * — an empty `problems` array means nothing is wrong with the pipeline
808
+ * - on failure, `{"ok": false, "error": {...}}` — the text did not parse at all
809
+ *
810
+ * `path` addresses the offending node by index: `[2]` is the third node of the pipeline, and
811
+ * descending into a node's bracketed sources appends the source index and then the node index.
812
+ * The same walk applies to the tree from `parseVplCst`, which is how this becomes a span.
813
+ *
814
+ * A parameter whose type has a parser is handed to it, so `format=notaformat` is reported and
815
+ * the alias `format=pbf` is not — the parser decides, never the list of values a picker offers.
816
+ * A value whose type has no parser is deliberately *not* validated, because doing so would
817
+ * reject VPL that runs: `color=red` passes here and fails at build time.
818
+ *
819
+ * @param vpl - the VPL text to check
820
+ * @returns a JSON string describing either the problems found or a parse error
821
+ */
822
+ export declare function checkVpl(vpl: string): string
823
+
783
824
  /**
784
825
  * Convert tiles from one container format to another
785
826
  *
@@ -790,7 +831,7 @@ export declare class TileSource {
790
831
  * # Arguments
791
832
  *
792
833
  * * `input` - Path or URL to the input tile container
793
- * * `output` - Path to the output tile container
834
+ * * `output` - Path to the output tile container, or an `sftp://` URL
794
835
  * * `options` - Optional conversion options (zoom range, bbox, compression, etc.)
795
836
  * * `on_progress` - Optional callback for progress updates
796
837
  * * `on_message` - Optional callback for step/warning/error messages
@@ -802,7 +843,11 @@ export declare class TileSource {
802
843
  * - `bboxBorder`: Add border tiles around bbox (in tile units)
803
844
  * - `compress`: Output compression ("gzip", "brotli", "uncompressed")
804
845
  * - `flipY`: Flip tiles vertically (TMS ↔ XYZ coordinate systems)
805
- * - `swapXY`: Swap X and Y tile coordinates
846
+ * - `swapXy`: Swap X and Y tile coordinates
847
+ * - `writerOptions`: Format-specific settings for the output writer, keyed by the
848
+ * writer's own `snake_case` names, e.g. `{ allow_unclustered: 'true' }` for PMTiles
849
+ * - `sshIdentity`: Private key file for an `sftp://` input, defaulting to
850
+ * `VERSATILES_SSH_IDENTITY`
806
851
  *
807
852
  * # Progress Callbacks
808
853
  *
@@ -951,8 +996,73 @@ export interface ConvertOptions {
951
996
  * **Default:** `false` (no swapping)
952
997
  */
953
998
  swapXy?: boolean
999
+ /**
1000
+ * Format-specific options for the output writer
1001
+ *
1002
+ * Which options exist depends on the output format. An option the chosen
1003
+ * writer does not accept is an error, not a no-op, and the message lists
1004
+ * what that format does accept.
1005
+ *
1006
+ * Keys reach the writer verbatim, so they keep the writer's own spelling —
1007
+ * `snake_case`, unlike the camelCase fields around them here.
1008
+ *
1009
+ * PMTiles accepts three; every other format accepts none:
1010
+ * - `allow_unclustered` — write an archive that is not physically clustered,
1011
+ * in a single pass, at the cost of more range requests when serving it
1012
+ * - `reorder` — stay clustered by writing the tile data twice, at the cost of
1013
+ * a second pass and temporary disk the size of the output
1014
+ * - `temp_dir` — where `reorder` puts that temporary file (default: the
1015
+ * output file's own directory)
1016
+ *
1017
+ * They matter only for a source that cannot supply Hilbert order, such as a
1018
+ * pipeline containing `raster_overview`; writing one to `.pmtiles` without
1019
+ * either opt-in is an error. Asking for both is also an error, since they buy
1020
+ * different things. Booleans are strings — `'true'`, `'1'` or `'yes'`,
1021
+ * case-insensitively, and likewise for false.
1022
+ *
1023
+ * **Example:** `{ allow_unclustered: 'true' }` when writing PMTiles
1024
+ *
1025
+ * **Default:** No writer options
1026
+ */
1027
+ writerOptions?: Record<string, string>
1028
+ /**
1029
+ * SSH identity (private key) file used for `sftp://` sources
1030
+ *
1031
+ * A path to a private key file on disk — the same thing the CLI's
1032
+ * `--ssh-identity` names. It is read when the input is an `sftp://` URL, and
1033
+ * ignored otherwise.
1034
+ *
1035
+ * Without it, the `VERSATILES_SSH_IDENTITY` environment variable is used;
1036
+ * without that, a password in the URL, the SSH agent and the usual `~/.ssh`
1037
+ * defaults still apply.
1038
+ *
1039
+ * **Example:** `'/home/deploy/.ssh/id_ed25519'`
1040
+ *
1041
+ * **Default:** `VERSATILES_SSH_IDENTITY`, if set
1042
+ */
1043
+ sshIdentity?: string
954
1044
  }
955
1045
 
1046
+ /**
1047
+ * Reformats a lossless syntax tree, keeping the comments in it.
1048
+ *
1049
+ * [`stringify_vpl`] formats the semantic pipeline, which has already forgotten the comments, so
1050
+ * "reformat this file" and "keep what I wrote" are otherwise exclusive. This applies the same
1051
+ * layout — one tab per level, `|` at the pipeline's own level, parameters one level in — to the
1052
+ * tree that still has them.
1053
+ *
1054
+ * Whitespace and nothing else is rewritten: parameters keep the order they were written in, and
1055
+ * values keep the quotes the author chose. Every comment keeps the token it was attached to and
1056
+ * takes that token's line and indentation.
1057
+ *
1058
+ * Returns the formatted tree rather than the text, so the `span` of every token is fresh and
1059
+ * addresses the formatted result. Print it with [`stringify_vpl_cst`].
1060
+ *
1061
+ * @param cstJson - JSON string describing the syntax tree
1062
+ * @returns a JSON string describing the formatted syntax tree
1063
+ */
1064
+ export declare function formatVplCst(cstJson: string): string
1065
+
956
1066
  /**
957
1067
  * Generate the VPL TypeScript builder source code from Rust operation metadata.
958
1068
  *
@@ -961,6 +1071,77 @@ export interface ConvertOptions {
961
1071
  */
962
1072
  export declare function generateVplTypescript(): string
963
1073
 
1074
+ /**
1075
+ * Compute the per-layer byte breakdown of an uncompressed vector tile.
1076
+ *
1077
+ * # Arguments
1078
+ *
1079
+ * * `tile` - Uncompressed MVT bytes, as returned by `TileSource.getTile()`.
1080
+ *
1081
+ * # Returns
1082
+ *
1083
+ * One entry per layer, in the order the layers appear in the tile. A tile with
1084
+ * no layers — including a zero-byte buffer, which is what an empty tile encodes
1085
+ * to — yields an empty array. `getTile()` signals a missing tile with `null`,
1086
+ * so an empty buffer means an empty tile rather than a mistake.
1087
+ *
1088
+ * # Errors
1089
+ *
1090
+ * Returns an error if the buffer is not an uncompressed vector tile. Compressed
1091
+ * input and raster input are named as such rather than surfacing as a protobuf
1092
+ * parse failure.
1093
+ *
1094
+ * # Examples
1095
+ *
1096
+ * ```javascript
1097
+ * const { TileSource, layerStats } = require('@versatiles/versatiles-rs');
1098
+ *
1099
+ * const source = await TileSource.fromPath('berlin.mbtiles');
1100
+ * const tile = await source.getTile(14, 8802, 5373);
1101
+ * if (tile) {
1102
+ * for (const layer of layerStats(tile)) {
1103
+ * console.log(layer.name, layer.geometryBytes, layer.propertyBytes, layer.encodedBytes);
1104
+ * }
1105
+ * }
1106
+ * ```
1107
+ */
1108
+ export declare function layerStats(tile: Buffer): Array<LayerStats>
1109
+
1110
+ /**
1111
+ * Byte breakdown of a single layer within a vector tile.
1112
+ *
1113
+ * All figures are uncompressed MVT content — what can actually be shrunk.
1114
+ * The named categories plus `otherBytes` sum exactly to `encodedBytes`, so a
1115
+ * stacked bar built from them adds up without a fudge factor.
1116
+ */
1117
+ export interface LayerStats {
1118
+ /** Layer name. */
1119
+ name: string
1120
+ /** Number of features in the layer. */
1121
+ featureCount: number
1122
+ /** Total number of geometry vertices across all features. */
1123
+ vertexCount: number
1124
+ /** Geometry command streams. */
1125
+ geometryBytes: number
1126
+ /** Per-feature property references (the packed `tag_ids` varints). */
1127
+ tagBytes: number
1128
+ /** Key strings in the property table. */
1129
+ keyBytes: number
1130
+ /** Encoded value messages in the property table. */
1131
+ valueBytes: number
1132
+ /** `keyBytes + valueBytes` — the whole property table. */
1133
+ propertyBytes: number
1134
+ /** Feature ids. Zero for sources that carry none. */
1135
+ idBytes: number
1136
+ /**
1137
+ * Framing, geometry-type fields and the layer name: whatever the named
1138
+ * categories do not account for.
1139
+ */
1140
+ otherBytes: number
1141
+ /** Exact serialized size of the layer. */
1142
+ encodedBytes: number
1143
+ }
1144
+
964
1145
  /**
965
1146
  * Status or diagnostic message from an operation
966
1147
  *
@@ -1022,18 +1203,6 @@ export declare function parseVpl(vpl: string): string
1022
1203
  */
1023
1204
  export declare function parseVplCst(vpl: string): string
1024
1205
 
1025
- /** Probe result with container information */
1026
- export interface ProbeResult {
1027
- /** Source name or path */
1028
- sourceName: string
1029
- /** Container type (e.g., "mbtiles", "versatiles") */
1030
- containerName: string
1031
- /** TileJSON metadata as JSON string */
1032
- tileJsonRaw: string
1033
- /** Reader parameters */
1034
- parameters: SourceMetadata
1035
- }
1036
-
1037
1206
  /**
1038
1207
  * Progress information for long-running operations
1039
1208
  *
@@ -1195,6 +1364,20 @@ export interface ServerOptions {
1195
1364
  * **Default:** `false` (optimal recompression)
1196
1365
  */
1197
1366
  minimalRecompression?: boolean
1367
+ /**
1368
+ * `Cache-Control` header sent with every tile
1369
+ *
1370
+ * Tile URLs are stable — built from a mount name and a coordinate — so
1371
+ * when the tiles behind a mount change, the URL does not, and the browser
1372
+ * answers from its own cache. A dev server or an interactive preview that
1373
+ * re-mounts under the same name will otherwise keep showing the previous
1374
+ * edit.
1375
+ *
1376
+ * Example: `"no-cache"`.
1377
+ *
1378
+ * **Default:** `"public, max-age=2419200, no-transform"` (four weeks)
1379
+ */
1380
+ cacheControl?: string
1198
1381
  }
1199
1382
 
1200
1383
  /** Tile source metadata describing output characteristics */
@@ -1209,6 +1392,31 @@ export interface SourceMetadata {
1209
1392
  maxZoom: number
1210
1393
  }
1211
1394
 
1395
+ /**
1396
+ * Options for opening a tile source
1397
+ *
1398
+ * Everything here is optional; an omitted field keeps the default behaviour.
1399
+ */
1400
+ export interface SourceOptions {
1401
+ /**
1402
+ * SSH identity (private key) file used for `sftp://` sources
1403
+ *
1404
+ * A path to a private key file on disk — the same thing the CLI's
1405
+ * `--ssh-identity` names. It is read when the source is an `sftp://` URL,
1406
+ * including one reached through a pipeline, and ignored otherwise.
1407
+ *
1408
+ * Without it, the `VERSATILES_SSH_IDENTITY` environment variable is used;
1409
+ * without that, a password in the URL, the SSH agent and the usual `~/.ssh`
1410
+ * defaults still apply. Set this to give one source a different key than the
1411
+ * rest of the process.
1412
+ *
1413
+ * **Example:** `'/home/deploy/.ssh/id_ed25519'`
1414
+ *
1415
+ * **Default:** `VERSATILES_SSH_IDENTITY`, if set
1416
+ */
1417
+ sshIdentity?: string
1418
+ }
1419
+
1212
1420
  /**
1213
1421
  * Writes a pipeline as VPL text.
1214
1422
  *