@tileflow/core 0.1.0-alpha.47 → 0.1.0-alpha.48

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/build.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import { T as TileflowCaptureScene, a as TileflowCaptureShot } from './capture-shot-ChPQvPyi.js';
2
- import { T as TileflowRenderedIconIdentity, a as TileflowIconCompositionV1, R as ResolvedTileflowMap, b as TileflowDataRequirementsV1, c as TileflowSourceRequirementsV1, d as TileflowMap, e as TileflowStyleOptions, f as TileflowInspectedStyle, g as TileflowPreparedMapAssets } from './icon-composition-CInvkr7s.js';
3
- export { h as TileflowDataCompatibilityIssue, i as TileflowDataFieldRequirement, j as TileflowDataFieldType, k as TileflowDataLayerRequirement, l as TileflowObservedDataContractV1, m as TileflowStyleInspection, n as TileflowStyleInspectionContribution, o as TileflowStyleInspectionLayer, p as TileflowStyleInspectionRenderOperation, q as collectMapLineage, r as inferTileflowDataRequirements, s as inferTileflowSourceRequirements, t as tileflowStyleInspectionSchemaVersion, v as validateTileflowDataCompatibility } from './icon-composition-CInvkr7s.js';
4
- import { M as MapLibreStyle, f as TileflowTimeOfDayVariants, T as TileflowRuntimeManifest } from './manifest-types-CcD4OQkJ.js';
5
- export { j as TileflowStyleFamily, k as createTileflowStyleFamily, l as expandTileflowFamilyTemplate, m as expandTileflowStyleFamily, n as materializeTileflowStyleFamily, p as parseTileflowStyleFamily, o as tileflowStyleFamilyLimits, w as withTileflowFamilyTemplate } from './manifest-types-CcD4OQkJ.js';
2
+ import { T as TileflowRenderedIconIdentity, a as TileflowIconCompositionV1, R as ResolvedTileflowMap, b as TileflowDataRequirementsV1, c as TileflowSourceRequirementsV1, d as TileflowMap, e as TileflowStyleOptions, f as TileflowInspectedStyle, g as TileflowPreparedMapAssets } from './icon-composition-2nsUbE87.js';
3
+ export { h as TileflowDataCompatibilityIssue, i as TileflowDataFieldRequirement, j as TileflowDataFieldType, k as TileflowDataLayerRequirement, l as TileflowObservedDataContractV1, m as TileflowStyleInspection, n as TileflowStyleInspectionContribution, o as TileflowStyleInspectionLayer, p as TileflowStyleInspectionRenderOperation, q as collectMapLineage, r as inferTileflowDataRequirements, s as inferTileflowSourceRequirements, t as tileflowStyleInspectionSchemaVersion, v as validateTileflowDataCompatibility } from './icon-composition-2nsUbE87.js';
4
+ import { M as MapLibreStyle, f as TileflowTimeOfDayVariants, T as TileflowRuntimeManifest } from './manifest-types-U7JPDNAo.js';
5
+ export { j as TileflowStyleFamily, k as createTileflowStyleFamily, l as expandTileflowFamilyTemplate, m as expandTileflowStyleFamily, n as materializeTileflowStyleFamily, p as parseTileflowStyleFamily, o as tileflowStyleFamilyLimits, w as withTileflowFamilyTemplate } from './manifest-types-U7JPDNAo.js';
6
6
  import { z } from 'zod';
7
7
 
8
8
  declare const tileflowMapRevisionSchemaVersion: 1;
package/dist/build.js CHANGED
@@ -2181,6 +2181,8 @@ var tileflowWorldLayerFields = Object.freeze({
2181
2181
  name: { type: "String" },
2182
2182
  "name_<lang>": { type: "String" },
2183
2183
  name_latin: { type: "String" },
2184
+ network: { type: "String" },
2185
+ official: { type: "Number" },
2184
2186
  oneway: { type: "Boolean" },
2185
2187
  outer_radius_m: { type: "Number", required: true },
2186
2188
  radius_m: { type: "Number", required: true },
@@ -11867,92 +11869,6 @@ function asRecord3(value) {
11867
11869
  return value && typeof value === "object" && !Array.isArray(value) ? value : {};
11868
11870
  }
11869
11871
 
11870
- // src/manifest-schema-classic.ts
11871
- import { z as z3 } from "zod";
11872
-
11873
- // src/native-zod-object.ts
11874
- import { z as z2 } from "zod";
11875
- function strictNativeObject(shape) {
11876
- const object3 = new z2.core.$ZodObject({
11877
- type: "object",
11878
- shape,
11879
- catchall: z2.never()
11880
- });
11881
- return z2.lazy(() => object3);
11882
- }
11883
-
11884
- // src/manifest-schema-classic.ts
11885
- function classic(schema) {
11886
- return schema;
11887
- }
11888
- var classicManifestStringOperations = {
11889
- string: () => z3.string(),
11890
- minLength(schema, minimum2) {
11891
- return schema.min(
11892
- minimum2
11893
- );
11894
- },
11895
- maxLength(schema, maximum2) {
11896
- return schema.max(
11897
- maximum2
11898
- );
11899
- },
11900
- regex: (schema, pattern, message) => schema.regex(pattern, { message }),
11901
- refine: (schema, check, message) => classic(schema).refine(check, message)
11902
- };
11903
- var classicManifestSchemaOperations = {
11904
- ...classicManifestStringOperations,
11905
- number: (minimum2, maximum2) => z3.number().finite().min(minimum2).max(maximum2),
11906
- unknown: () => z3.unknown(),
11907
- optional: (schema) => classic(schema).optional(),
11908
- array: (schema) => z3.array(classic(schema)),
11909
- enum(values) {
11910
- return z3.enum(values);
11911
- },
11912
- literal: (value) => z3.literal(value),
11913
- union: (left, right) => z3.union([classic(left), classic(right)]),
11914
- tuplePair(left, right) {
11915
- return z3.tuple([classic(left), classic(right)]);
11916
- },
11917
- object(shape) {
11918
- return strictNativeObject(shape);
11919
- },
11920
- record(key, value) {
11921
- return z3.record(classic(key), classic(value));
11922
- },
11923
- superRefine: (schema, check) => classic(schema).superRefine(check),
11924
- pipe: (input, output) => classic(input).pipe(classic(output))
11925
- };
11926
-
11927
- // src/portable-identity-schema.ts
11928
- function createPortableIdentitySchemas(operations) {
11929
- const bounded2 = operations.maxLength(
11930
- operations.minLength(operations.string(), 1),
11931
- tileflowPortableIdMaximumLength
11932
- );
11933
- const pattern = operations.regex(
11934
- bounded2,
11935
- tileflowPortableIdPattern,
11936
- "Expected lowercase kebab-case beginning with a letter"
11937
- );
11938
- const tileflowPortableIdSchema2 = operations.refine(
11939
- pattern,
11940
- (name) => !["constructor", "prototype"].includes(name) && !/^(?:AUX|CON|NUL|PRN|COM[1-9]|LPT[1-9])$/i.test(name),
11941
- "Expected a portable identifier that is not a reserved filename or prototype key"
11942
- );
11943
- const tileflowThemeNameSchema2 = operations.refine(
11944
- tileflowPortableIdSchema2,
11945
- isTileflowThemeName,
11946
- "Expected a concrete theme name; system is browser-only"
11947
- );
11948
- return { tileflowPortableIdSchema: tileflowPortableIdSchema2, tileflowThemeNameSchema: tileflowThemeNameSchema2 };
11949
- }
11950
-
11951
- // src/portable-identity.ts
11952
- var schemas = createPortableIdentitySchemas(classicManifestStringOperations);
11953
- var tileflowPortableIdSchema = schemas.tileflowPortableIdSchema;
11954
- var tileflowThemeNameSchema = schemas.tileflowThemeNameSchema;
11955
-
11956
11872
  // src/overlays.ts
11957
11873
  var tileflowOverlayPlacements = [
11958
11874
  "above-water",
@@ -11963,6 +11879,8 @@ var tileflowOverlayPlacements = [
11963
11879
  "above-labels"
11964
11880
  ];
11965
11881
  var tileflowHostedSourceLimit = 16;
11882
+ var tileflowInlineGeoJsonByteLimit = 512e3;
11883
+ var tileflowClusterMetadataKey = "tileflow:cluster";
11966
11884
  function isTileflowRemoveOperation(value) {
11967
11885
  return isPlainRecord3(value) && value.op === "remove" && Object.keys(value).length === 1;
11968
11886
  }
@@ -12001,6 +11919,10 @@ function resolveTileflowHostedSources(mapId, sources, reservedSourceIds) {
12001
11919
  `Source ID "${sourceId}" conflicts with a Tileflow source.`
12002
11920
  );
12003
11921
  }
11922
+ if (source.kind === "geojson") {
11923
+ definitions[sourceId] = createTileflowGeoJsonSourceDefinition(source);
11924
+ continue;
11925
+ }
12004
11926
  const duplicate = tilesets.get(source.tileset);
12005
11927
  if (duplicate) {
12006
11928
  throw new TileflowOverlayCompilationError(
@@ -12025,8 +11947,17 @@ function resolveTileflowHostedSources(mapId, sources, reservedSourceIds) {
12025
11947
  }
12026
11948
  return { definitions, identities };
12027
11949
  }
11950
+ function createTileflowGeoJsonSourceDefinition(source) {
11951
+ return {
11952
+ ...source.attribution === void 0 ? {} : { attribution: source.attribution },
11953
+ ...pickClusterOptions(source),
11954
+ data: cloneJson18(source.data),
11955
+ type: "geojson"
11956
+ };
11957
+ }
12028
11958
  function insertTileflowOverlays(input) {
12029
11959
  const availableSources = new Set(input.sourceIds);
11960
+ const labelFont = readTileflowLabelFont(input.basemapLayers);
12030
11961
  const identities = {};
12031
11962
  const groups = /* @__PURE__ */ new Map();
12032
11963
  const layerIds = new Set(
@@ -12054,8 +11985,17 @@ function insertTileflowOverlays(input) {
12054
11985
  );
12055
11986
  }
12056
11987
  layerIds.add(layer.id);
11988
+ if (readClusterRole(layer) && input.sourceDefinitions?.[overlay.source]?.cluster !== true) {
11989
+ throw new TileflowOverlayCompilationError(
11990
+ "TF_OVERLAY_CLUSTER_SOURCE_INVALID",
11991
+ `${path}.source`,
11992
+ `Cluster overlay "${overlayId}" needs a GeoJSON source declared with cluster: true.`,
11993
+ `Use geojsonSource({cluster: true}) for source "${overlay.source}".`
11994
+ );
11995
+ }
11996
+ const label = readClusterRole(layer) === "count" ? withLabelFont(layer, labelFont, path) : layer;
12057
11997
  return {
12058
- ...cloneJson18(layer),
11998
+ ...cloneJson18(label),
12059
11999
  source: overlay.source,
12060
12000
  metadata: {
12061
12001
  ...isPlainRecord3(layer.metadata) ? cloneJson18(layer.metadata) : {},
@@ -12079,6 +12019,42 @@ function insertTileflowOverlays(input) {
12079
12019
  }
12080
12020
  return { identities, layers: layers2 };
12081
12021
  }
12022
+ function readTileflowLabelFont(layers2) {
12023
+ for (const layer of layers2) {
12024
+ const font = isPlainRecord3(layer.layout) ? layer.layout["text-font"] : void 0;
12025
+ if (Array.isArray(font) && font.length > 0 && font.every((face) => typeof face === "string" && !parseTileflowLineBackgroundFontStack(face))) {
12026
+ return font;
12027
+ }
12028
+ }
12029
+ return void 0;
12030
+ }
12031
+ function readClusterRole(layer) {
12032
+ const metadata = isPlainRecord3(layer.metadata) ? layer.metadata : void 0;
12033
+ const cluster = metadata?.[tileflowClusterMetadataKey];
12034
+ return isPlainRecord3(cluster) ? cluster.role : void 0;
12035
+ }
12036
+ function withLabelFont(layer, font, path) {
12037
+ const layout = layer.layout;
12038
+ if (layout["text-font"] !== void 0) return layer;
12039
+ if (!font) {
12040
+ throw new TileflowOverlayCompilationError(
12041
+ "TF_OVERLAY_FONT_UNAVAILABLE",
12042
+ `${path}.font`,
12043
+ `Cluster count layer "${layer.id}" has no label font to share.`,
12044
+ "Pass font to clusterOverlay() with a stack the map declares."
12045
+ );
12046
+ }
12047
+ return { ...layer, layout: { ...layout, "text-font": [...font] } };
12048
+ }
12049
+ function pickClusterOptions(source) {
12050
+ return {
12051
+ ...source.cluster === void 0 ? {} : { cluster: source.cluster },
12052
+ ...source.clusterMaxZoom === void 0 ? {} : { clusterMaxZoom: source.clusterMaxZoom },
12053
+ ...source.clusterMinPoints === void 0 ? {} : { clusterMinPoints: source.clusterMinPoints },
12054
+ ...source.clusterProperties === void 0 ? {} : { clusterProperties: cloneJson18(source.clusterProperties) },
12055
+ ...source.clusterRadius === void 0 ? {} : { clusterRadius: source.clusterRadius }
12056
+ };
12057
+ }
12082
12058
  function isSafeLocalPmtilesPath(value) {
12083
12059
  if (typeof value !== "string" || value.length > 512 || !value.endsWith(".pmtiles") || value.includes("\\") || /[\p{Cc}?#]/u.test(value)) {
12084
12060
  return false;
@@ -12119,6 +12095,92 @@ function isPlainRecord3(value) {
12119
12095
  return prototype === Object.prototype || prototype === null;
12120
12096
  }
12121
12097
 
12098
+ // src/manifest-schema-classic.ts
12099
+ import { z as z3 } from "zod";
12100
+
12101
+ // src/native-zod-object.ts
12102
+ import { z as z2 } from "zod";
12103
+ function strictNativeObject(shape) {
12104
+ const object3 = new z2.core.$ZodObject({
12105
+ type: "object",
12106
+ shape,
12107
+ catchall: z2.never()
12108
+ });
12109
+ return z2.lazy(() => object3);
12110
+ }
12111
+
12112
+ // src/manifest-schema-classic.ts
12113
+ function classic(schema) {
12114
+ return schema;
12115
+ }
12116
+ var classicManifestStringOperations = {
12117
+ string: () => z3.string(),
12118
+ minLength(schema, minimum2) {
12119
+ return schema.min(
12120
+ minimum2
12121
+ );
12122
+ },
12123
+ maxLength(schema, maximum2) {
12124
+ return schema.max(
12125
+ maximum2
12126
+ );
12127
+ },
12128
+ regex: (schema, pattern, message) => schema.regex(pattern, { message }),
12129
+ refine: (schema, check, message) => classic(schema).refine(check, message)
12130
+ };
12131
+ var classicManifestSchemaOperations = {
12132
+ ...classicManifestStringOperations,
12133
+ number: (minimum2, maximum2) => z3.number().finite().min(minimum2).max(maximum2),
12134
+ unknown: () => z3.unknown(),
12135
+ optional: (schema) => classic(schema).optional(),
12136
+ array: (schema) => z3.array(classic(schema)),
12137
+ enum(values) {
12138
+ return z3.enum(values);
12139
+ },
12140
+ literal: (value) => z3.literal(value),
12141
+ union: (left, right) => z3.union([classic(left), classic(right)]),
12142
+ tuplePair(left, right) {
12143
+ return z3.tuple([classic(left), classic(right)]);
12144
+ },
12145
+ object(shape) {
12146
+ return strictNativeObject(shape);
12147
+ },
12148
+ record(key, value) {
12149
+ return z3.record(classic(key), classic(value));
12150
+ },
12151
+ superRefine: (schema, check) => classic(schema).superRefine(check),
12152
+ pipe: (input, output) => classic(input).pipe(classic(output))
12153
+ };
12154
+
12155
+ // src/portable-identity-schema.ts
12156
+ function createPortableIdentitySchemas(operations) {
12157
+ const bounded2 = operations.maxLength(
12158
+ operations.minLength(operations.string(), 1),
12159
+ tileflowPortableIdMaximumLength
12160
+ );
12161
+ const pattern = operations.regex(
12162
+ bounded2,
12163
+ tileflowPortableIdPattern,
12164
+ "Expected lowercase kebab-case beginning with a letter"
12165
+ );
12166
+ const tileflowPortableIdSchema2 = operations.refine(
12167
+ pattern,
12168
+ (name) => !["constructor", "prototype"].includes(name) && !/^(?:AUX|CON|NUL|PRN|COM[1-9]|LPT[1-9])$/i.test(name),
12169
+ "Expected a portable identifier that is not a reserved filename or prototype key"
12170
+ );
12171
+ const tileflowThemeNameSchema2 = operations.refine(
12172
+ tileflowPortableIdSchema2,
12173
+ isTileflowThemeName,
12174
+ "Expected a concrete theme name; system is browser-only"
12175
+ );
12176
+ return { tileflowPortableIdSchema: tileflowPortableIdSchema2, tileflowThemeNameSchema: tileflowThemeNameSchema2 };
12177
+ }
12178
+
12179
+ // src/portable-identity.ts
12180
+ var schemas = createPortableIdentitySchemas(classicManifestStringOperations);
12181
+ var tileflowPortableIdSchema = schemas.tileflowPortableIdSchema;
12182
+ var tileflowThemeNameSchema = schemas.tileflowThemeNameSchema;
12183
+
12122
12184
  // src/boundary-areas/schema.ts
12123
12185
  var tileflowBoundaryClasses = [
12124
12186
  "country",
@@ -16771,7 +16833,30 @@ var hostedTilesetSourceSchema = z5.object({
16771
16833
  });
16772
16834
  }
16773
16835
  });
16774
- var hostedSourcesSchema = z5.record(tileflowMapIdSchema, hostedTilesetSourceSchema).superRefine((sources, context) => {
16836
+ var geojsonFeatureCollectionSchema = z5.object({
16837
+ features: z5.array(z5.record(z5.string(), z5.unknown())),
16838
+ type: z5.literal("FeatureCollection")
16839
+ }).refine(
16840
+ (data) => new TextEncoder().encode(JSON.stringify(data)).byteLength <= tileflowInlineGeoJsonByteLimit,
16841
+ `Expected at most ${tileflowInlineGeoJsonByteLimit} bytes of inline GeoJSON`
16842
+ );
16843
+ var geojsonSourceSchema = z5.object({
16844
+ attribution: z5.string().trim().min(1).max(4096).optional(),
16845
+ cluster: z5.boolean().optional(),
16846
+ clusterMaxZoom: z5.number().min(0).max(24).optional(),
16847
+ clusterMinPoints: z5.number().int().min(2).optional(),
16848
+ clusterProperties: z5.record(z5.string(), z5.tuple([z5.unknown(), z5.unknown()])).optional(),
16849
+ clusterRadius: z5.number().positive().optional(),
16850
+ data: z5.union([
16851
+ geojsonFeatureCollectionSchema,
16852
+ z5.string().refine((value) => value.startsWith("https://"), "Expected an https:// URL")
16853
+ ]),
16854
+ kind: z5.literal("geojson")
16855
+ }).strict();
16856
+ var hostedSourcesSchema = z5.record(
16857
+ tileflowMapIdSchema,
16858
+ z5.discriminatedUnion("kind", [hostedTilesetSourceSchema, geojsonSourceSchema])
16859
+ ).superRefine((sources, context) => {
16775
16860
  if (Object.keys(sources).length > tileflowHostedSourceLimit) {
16776
16861
  context.addIssue({
16777
16862
  code: "too_big",
@@ -19561,6 +19646,7 @@ function compileSemanticStyleInternal(input, options, inspect, onReport) {
19561
19646
  basemapLayers,
19562
19647
  mapId: config.id,
19563
19648
  overlays: validateBoundaryChoroplethOverlays(config.id, config.overlays, boundaryAreas),
19649
+ sourceDefinitions: hostedSources.definitions,
19564
19650
  sourceIds: [
19565
19651
  ...Object.keys(hostedSources.definitions),
19566
19652
  ...boundaryAreas ? [boundaryAreas.sourceId] : []
@@ -22170,6 +22256,7 @@ function normalizeRevisionCartography(input) {
22170
22256
  ...input,
22171
22257
  sources: Object.fromEntries(
22172
22258
  Object.entries(input.sources).sort(([left], [right]) => compareCodeUnits8(left, right)).map(([sourceId, source]) => {
22259
+ if (source.kind === "geojson") return [sourceId, source];
22173
22260
  const { local: _local, ...logicalSource } = source;
22174
22261
  return [sourceId, logicalSource];
22175
22262
  })