@tileflow/dev 0.1.0-alpha.29 → 0.1.0-alpha.30

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
@@ -123,7 +123,7 @@ Use `/artifacts` for preparation and output, `/server` for HTTP handling, `/conf
123
123
  loading, `/icons` and `/fonts` for asset preparation, `/inspect` for bounded inspection, `/tilesets`
124
124
  for local PMTiles inspection, and `/validation` for diagnostics. `/preview` is the local preview
125
125
  contract, including experimental preview-only rendering; it does not promise hosted support.
126
- The root retains compatibility re-exports.
126
+ The package has no root entry point.
127
127
 
128
128
  Invalid compiled styles throw `TileflowStyleValidationError` with bounded issues. Keep diagnostics
129
129
  structured; do not return executable config, local paths, credentials, or complete generated byte
@@ -180,7 +180,9 @@ the previous complete lock intact; remove a stale `.writing` guard only after co
180
180
  writer has exited. Ordinary reads and Core validation never acquire write guards.
181
181
 
182
182
  A package supports up to 1,000 effective icons, subject to a 2,048-pixel atlas dimension,
183
- 4 MiB per generated file, and 8 MiB per package. Larger artwork can hit those limits before
183
+ 4 MiB per generated file, and 8 MiB per package. Paired densities share a logical layout capped
184
+ at 1,024 pixels per dimension at 1× and 2,048 at 2×. Mixed-size artwork retains matching placements
185
+ without resampling either density. Larger artwork can hit those limits before
184
186
  1,000 icons. Several individually valid sets can exceed the effective map limit; composition
185
187
  fails explicitly instead of clipping. Cache and composition do not create Team resources or
186
188
  publish anything. Every normal entry point composes declared shared descriptors through this path;
@@ -58,28 +58,28 @@ copyright 2020 Arjun Barrett and is distributed under the MIT License.
58
58
  - PMTiles source and license: <https://github.com/protomaps/PMTiles/tree/v4.5.0/js>
59
59
  - fflate source and license: <https://github.com/101arrowz/fflate/tree/v0.8.3>
60
60
 
61
- ## sharp 0.35.4
61
+ ## sharp 0.35.5
62
62
 
63
63
  `@tileflow/dev` declares `sharp` as an optional dependency and loads it dynamically only when local
64
64
  SVG or raster icon sources must be inspected and packed. The Tileflow build externalizes `sharp`
65
65
  rather than bundling it. `sharp` is copyright Lovell Fuller and contributors and is distributed under
66
66
  the Apache License 2.0.
67
67
 
68
- - Source: <https://github.com/lovell/sharp/tree/v0.35.4>
69
- - License: <https://github.com/lovell/sharp/blob/v0.35.4/LICENSE>
68
+ - Source: <https://github.com/lovell/sharp/tree/v0.35.5>
69
+ - License: <https://github.com/lovell/sharp/blob/v0.35.5/LICENSE>
70
70
 
71
- ## sharp libvips distributions 1.3.3
71
+ ## sharp libvips distributions 1.3.4
72
72
 
73
73
  `sharp` selects a separate optional `@img/sharp-libvips-*` package for the current platform. The
74
74
  installed platform-package manifest declares `LGPL-3.0-or-later`; the packaging scripts themselves
75
75
  are distributed under Apache-2.0. The packages contain prebuilt libvips and separately licensed
76
- runtime dependencies. For `sharp` 0.35.4 the selected libvips ABI is 8.18.6.
76
+ runtime dependencies. For `sharp` 0.35.5 the selected libvips ABI is 8.18.7.
77
77
 
78
- - Packaging source: <https://github.com/lovell/sharp-libvips/tree/v1.3.3>
79
- - Packaging-script license: <https://github.com/lovell/sharp-libvips/blob/v1.3.3/LICENSE>
80
- - libvips 8.18.6 source: <https://github.com/libvips/libvips/tree/v8.18.6>
81
- - libvips 8.18.6 license (LGPL-2.1-or-later):
82
- <https://github.com/libvips/libvips/blob/v8.18.6/LICENSE>
78
+ - Packaging source: <https://github.com/lovell/sharp-libvips/tree/v1.3.4>
79
+ - Packaging-script license: <https://github.com/lovell/sharp-libvips/blob/v1.3.4/LICENSE>
80
+ - libvips 8.18.7 source: <https://github.com/libvips/libvips/tree/v8.18.7>
81
+ - libvips 8.18.7 license (LGPL-2.1-or-later):
82
+ <https://github.com/libvips/libvips/blob/v8.18.7/LICENSE>
83
83
 
84
84
  Because `sharp` remains a separately installed optional package, users can install, update, remove,
85
85
  or replace it independently of `@tileflow/dev`. Tileflow does not modify libvips and does not place a
package/dist/artifacts.js CHANGED
@@ -27,8 +27,7 @@ import {
27
27
  usesTileflowLineBackgroundGlyphs,
28
28
  writeTileflowArtifactPlan,
29
29
  writeTileflowBuildArtifacts
30
- } from "./chunk-LXSFLPIU.js";
31
- import "./chunk-ONYQNLNA.js";
30
+ } from "./chunk-L56FLV4R.js";
32
31
  import {
33
32
  getTileflowAssetBasePath,
34
33
  getTileflowAssetFileName,
@@ -36,13 +35,14 @@ import {
36
35
  normalizeTileflowBasePath,
37
36
  resolveTileflowArtifactPublicUrls
38
37
  } from "./chunk-UTRO4IBQ.js";
39
- import "./chunk-EJPVUSX4.js";
38
+ import "./chunk-A2VTI43Y.js";
40
39
  import "./chunk-7C4F6GAX.js";
41
40
  import "./chunk-KDFTE4Q5.js";
42
41
  import {
43
42
  defaultTileflowConfigPath
44
43
  } from "./chunk-6MGFMKG3.js";
45
44
  import "./chunk-D4OE4ITL.js";
45
+ import "./chunk-ONYQNLNA.js";
46
46
  export {
47
47
  TileflowHostedManifestOverwriteError,
48
48
  TileflowLocalTilesetProductionError,
@@ -173,15 +173,16 @@ async function packTileflowRenderedIcons(input) {
173
173
  function createSpriteLayout(icons, pixelRatio) {
174
174
  const columns = Math.ceil(Math.sqrt(icons.length));
175
175
  const widest = Math.max(...icons.map((icon) => icon.width));
176
- const targetWidth = Math.min(tileflowIconPackageLimits.maxAtlasDimension, columns * widest);
176
+ const maxDimension = tileflowIconPackageLimits.maxAtlasDimension / 2 * pixelRatio;
177
+ const targetWidth = Math.min(maxDimension, columns * widest);
177
178
  const placements = [];
178
179
  let left = 0;
179
180
  let rowHeight = 0;
180
181
  let top = 0;
181
182
  for (const icon of icons) {
182
- if (icon.width > tileflowIconPackageLimits.maxAtlasDimension)
183
+ if (icon.width > maxDimension)
183
184
  throw new Error(
184
- `Generated sprite exceeds ${tileflowIconPackageLimits.maxAtlasDimension} pixels per dimension`
185
+ `Generated sprite exceeds ${maxDimension} pixels per dimension at ${pixelRatio}x`
185
186
  );
186
187
  if (left > 0 && left + icon.width > targetWidth) {
187
188
  top += rowHeight;
@@ -194,9 +195,9 @@ function createSpriteLayout(icons, pixelRatio) {
194
195
  }
195
196
  const width = targetWidth;
196
197
  const height = top + rowHeight;
197
- if (width > tileflowIconPackageLimits.maxAtlasDimension || height > tileflowIconPackageLimits.maxAtlasDimension)
198
+ if (width > maxDimension || height > maxDimension)
198
199
  throw new Error(
199
- `Generated sprite exceeds ${tileflowIconPackageLimits.maxAtlasDimension} pixels per dimension`
200
+ `Generated sprite exceeds ${maxDimension} pixels per dimension at ${pixelRatio}x`
200
201
  );
201
202
  const index = Object.fromEntries(
202
203
  icons.map((icon, ordinal) => {
@@ -1741,15 +1742,13 @@ async function readTileflowIconDirectory(source, options) {
1741
1742
  message: `One icon contributor supports at most ${tileflowIconPackageLimits4.maxIconCount} exports`
1742
1743
  }
1743
1744
  ]);
1744
- const entries = inspected.icons.map(
1745
- (icon) => ({
1746
- byteLength: icon.source.byteLength,
1747
- format: icon.format,
1748
- id: icon.name,
1749
- kind: icon.kind,
1750
- path: icon.displayPath
1751
- })
1752
- );
1745
+ const entries = inspected.icons.map((icon) => ({
1746
+ byteLength: icon.source.byteLength,
1747
+ format: icon.format,
1748
+ id: icon.name,
1749
+ kind: icon.kind,
1750
+ path: icon.displayPath
1751
+ }));
1753
1752
  return {
1754
1753
  containmentRoot: directory.containmentRoot,
1755
1754
  entries,
@@ -1,6 +1,3 @@
1
- import {
2
- inspectTileflowPmtilesForLocalUse
3
- } from "./chunk-ONYQNLNA.js";
4
1
  import {
5
2
  TileflowFontCompilationError,
6
3
  getTileflowFontWatchPaths,
@@ -11,7 +8,7 @@ import {
11
8
  import {
12
9
  getTileflowIconWatchPaths,
13
10
  prepareTileflowCatalogIcons
14
- } from "./chunk-EJPVUSX4.js";
11
+ } from "./chunk-A2VTI43Y.js";
15
12
  import {
16
13
  TileflowStyleValidationError,
17
14
  normalizeTileflowStyleValidationIssues,
@@ -26,6 +23,9 @@ import {
26
23
  import {
27
24
  isPathWithin
28
25
  } from "./chunk-D4OE4ITL.js";
26
+ import {
27
+ inspectTileflowPmtilesForLocalUse
28
+ } from "./chunk-ONYQNLNA.js";
29
29
 
30
30
  // src/artifacts.ts
31
31
  import { createHash as createHash4 } from "crypto";
@@ -706,6 +706,7 @@ var nativeLoweringLimits = Object.freeze({
706
706
  maximumLayers: 4096,
707
707
  maximumDashLength: 64
708
708
  });
709
+ var overlapProperties = ["icon-overlap", "text-overlap"];
709
710
  var NativeLoweringError = class extends Error {
710
711
  constructor(path, reason = "shape") {
711
712
  super(
@@ -1156,6 +1157,21 @@ function lowerLayer(layer, index, vector) {
1156
1157
  }
1157
1158
  return { variants, properties };
1158
1159
  }
1160
+ function replaceSymbolOverlap(layer, index) {
1161
+ if (layer.type !== "symbol" || !object2(layer.layout)) return;
1162
+ const properties = overlapProperties.filter((property) => layer.layout[property] !== void 0);
1163
+ if (!properties.length) return;
1164
+ const layout = { ...layer.layout };
1165
+ for (const property of properties) {
1166
+ const mode = layout[property];
1167
+ if (mode !== "never" && mode !== "always" && mode !== "cooperative") {
1168
+ fail(`/layers/${index}/layout/${property}`);
1169
+ }
1170
+ delete layout[property];
1171
+ layout[property === "icon-overlap" ? "icon-allow-overlap" : "text-allow-overlap"] = mode !== "never";
1172
+ }
1173
+ return { layer: { ...layer, layout }, properties };
1174
+ }
1159
1175
  function lowerNativeStyleRepresentation(input, normalizeFilter = (filter) => filter) {
1160
1176
  if (!Array.isArray(input.layers) || input.layers.length > nativeLoweringLimits.maximumLayers)
1161
1177
  fail("/layers", "budget");
@@ -1174,11 +1190,14 @@ function lowerNativeStyleRepresentation(input, normalizeFilter = (filter) => fil
1174
1190
  }
1175
1191
  const layers = [];
1176
1192
  const transformations = [];
1193
+ const symbolOverlap = [];
1177
1194
  for (const [index, layer] of originalLayers.entries()) {
1178
1195
  const source = object2(input.sources) && typeof layer.source === "string" ? input.sources[layer.source] : void 0;
1179
1196
  const lowered = lowerLayer(layer, index, object2(source) && source.type === "vector");
1180
1197
  if (!lowered) {
1181
- layers.push(layer);
1198
+ const replaced = replaceSymbolOverlap(layer, index);
1199
+ if (replaced) symbolOverlap.push({ inputLayer: index, properties: replaced.properties });
1200
+ layers.push(replaced?.layer ?? layer);
1182
1201
  continue;
1183
1202
  }
1184
1203
  if (layers.length + lowered.variants.length + originalLayers.length - index - 1 > nativeLoweringLimits.maximumLayers) {
@@ -1208,13 +1227,14 @@ function lowerNativeStyleRepresentation(input, normalizeFilter = (filter) => fil
1208
1227
  properties: lowered.properties
1209
1228
  });
1210
1229
  }
1211
- const changed = projection !== "none" || transformations.length > 0;
1230
+ const changed = projection !== "none" || transformations.length > 0 || symbolOverlap.length > 0;
1212
1231
  const output = changed ? { ...input, layers } : input;
1213
1232
  if (changed && projection !== "none") delete output.projection;
1214
1233
  return {
1215
1234
  style: output,
1216
1235
  projection,
1217
1236
  layers: transformations,
1237
+ symbolOverlap,
1218
1238
  inputLayers: originalLayers.length,
1219
1239
  outputLayers: layers.length
1220
1240
  };
@@ -1245,7 +1265,9 @@ function lowerTileflowNativeCompiledStyles(input, policy = {}) {
1245
1265
  const options = { ...urlOptions(map, theme, policy), deferFontClosure: true };
1246
1266
  const pending = validateTileflowNativeStyle(original, options);
1247
1267
  const blockers = pending.filter(
1248
- (issue) => issue.code !== "NATIVE_UNSUPPORTED_STYLE" || !(issue.path === "/projection" || /^\/layers\/\d+\/(?:layout\/line-cap|paint\/line-dasharray)(?:\/|$)/u.test(issue.path))
1268
+ (issue) => issue.code !== "NATIVE_UNSUPPORTED_STYLE" || !(issue.path === "/projection" || /^\/layers\/\d+\/(?:layout\/line-cap|paint\/line-dasharray)(?:\/|$)/u.test(
1269
+ issue.path
1270
+ ) || /^\/layers\/\d+\/layout\/(?:icon|text)-overlap$/u.test(issue.path))
1249
1271
  );
1250
1272
  if (blockers.length)
1251
1273
  throw new TileflowNativeCompatibilityError(
@@ -1301,7 +1323,8 @@ function lowerTileflowNativeCompiledStyles(input, policy = {}) {
1301
1323
  inputLayers: lowered.inputLayers,
1302
1324
  outputLayers: lowered.outputLayers,
1303
1325
  projection: lowered.projection,
1304
- layers: lowered.layers
1326
+ layers: lowered.layers,
1327
+ symbolOverlap: lowered.symbolOverlap
1305
1328
  });
1306
1329
  } catch (error) {
1307
1330
  if (!(error instanceof NativeLoweringError)) throw error;
@@ -2444,9 +2467,10 @@ function createGenerationArtifactFiles(artifacts, generation, nativeUrls) {
2444
2467
  };
2445
2468
  })
2446
2469
  );
2447
- const immutableAssets = artifacts.assets.map(
2448
- (asset) => ({ ...asset, fileName: `${prefix}/${asset.fileName}` })
2449
- );
2470
+ const immutableAssets = artifacts.assets.map((asset) => ({
2471
+ ...asset,
2472
+ fileName: `${prefix}/${asset.fileName}`
2473
+ }));
2450
2474
  return validateArtifactFiles([...stableFiles, ...immutableStyles, ...immutableAssets]);
2451
2475
  }
2452
2476
  function createFontAwareManifest(manifest, styles) {
package/dist/icons.js CHANGED
@@ -16,7 +16,7 @@ import {
16
16
  storeTileflowIconSetArtifact,
17
17
  verifyTileflowIconArtifact,
18
18
  writeTileflowIconsLockfile
19
- } from "./chunk-EJPVUSX4.js";
19
+ } from "./chunk-A2VTI43Y.js";
20
20
  import "./chunk-7C4F6GAX.js";
21
21
  export {
22
22
  TileflowIconCompilationError,