@tileflow/capture 0.1.0-alpha.24 → 0.1.0-alpha.26
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 +4 -1
- package/dist/index.d.ts +8 -3
- package/dist/index.js +33 -3
- package/package.json +10 -10
package/README.md
CHANGED
|
@@ -198,7 +198,10 @@ query strings, response bodies, raw browser stacks, or DOM contents.
|
|
|
198
198
|
New receipts use schema version 4. Version-2 and version-3 receipts remain readable as historical
|
|
199
199
|
evidence, not as newly verified version-4 captures. Import `@tileflow/capture/receipt` for receipt-only
|
|
200
200
|
tooling without loading the capture runtime. World selectors resolve once per capture session to
|
|
201
|
-
an immutable release.
|
|
201
|
+
an immutable release. Capture retains the complete resolved TileJSON, including its zoom range,
|
|
202
|
+
bounds, attribution and vector-layer metadata. Above the data's maximum zoom, MapLibre enlarges
|
|
203
|
+
available tiles while preserving the scene camera. Retries reuse the same frozen metadata.
|
|
204
|
+
Remote-dependent rendering is not a guarantee of globally identical pixels
|
|
202
205
|
across platforms or future runs.
|
|
203
206
|
|
|
204
207
|
Read the [capture contract](https://github.com/tileflow/tileflow-sdk/blob/main/docs/contracts/local-visual-capture.md)
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { Browser } from 'playwright';
|
|
|
2
2
|
import { T as TileflowCaptureRendererIdentity, a as TileflowCaptureReceiptV4, b as TileflowCaptureDataInput, c as TileflowCaptureWorldIdentityV3, d as TileflowCaptureReceipt } from './receipt-Q7wQ68tG.js';
|
|
3
3
|
export { C as CreateTileflowCaptureReceiptInput, e as TileflowCaptureDataBindingsV2, f as TileflowCaptureDataCapabilitiesV2, g as TileflowCaptureDataIdentityV2, h as TileflowCaptureDataIdentityV3, i as TileflowCaptureDataSemanticsV2, j as TileflowCaptureDataSourceV2, k as TileflowCaptureReceiptV2, l as TileflowCaptureReceiptV3, m as TileflowCaptureVectorIdentityV3, n as TileflowCaptureVerificationV2, o as createTileflowCaptureReceipt, p as createTileflowCaptureRendererIdentity, q as parseTileflowCaptureReceipt, s as serializeTileflowCaptureReceipt, t as tileflowCaptureReceiptLimits, r as tileflowCaptureReceiptSchemaVersion, u as tileflowCaptureRuntime, v as validateTileflowCaptureReceipt } from './receipt-Q7wQ68tG.js';
|
|
4
4
|
import { TileflowCaptureScene, MapLibreStyle, NormalizedTileflowCaptureScene } from '@tileflow/core';
|
|
5
|
-
import { TileflowIconResolutionOptions, TileflowBuildArtifacts } from '@tileflow/dev/artifacts';
|
|
5
|
+
import { TileflowIconResolutionOptions, TileflowBuildArtifacts, TileflowBuildAsset } from '@tileflow/dev/artifacts';
|
|
6
6
|
|
|
7
7
|
type TileflowBrowserInstallProgress = 'installing' | 'installed';
|
|
8
8
|
type TileflowBrowserLaunchOptions = {
|
|
@@ -106,6 +106,11 @@ declare class TileflowCaptureError extends Error {
|
|
|
106
106
|
}
|
|
107
107
|
declare function captureErrorMessage(error: unknown, fallback: string): string;
|
|
108
108
|
|
|
109
|
+
declare const tileflowSyntheticAssetOrigin = "https://tileflow.local.invalid";
|
|
110
|
+
type TileflowCaptureAsset = TileflowBuildAsset & {
|
|
111
|
+
url?: string;
|
|
112
|
+
};
|
|
113
|
+
|
|
109
114
|
declare const tileflowWorldCurrentTileJsonUrl: "https://api.tileflow.dev/tiles/world/tiles.json";
|
|
110
115
|
type FetchTileJson = (input: string, init: {
|
|
111
116
|
cache: 'no-store';
|
|
@@ -115,9 +120,11 @@ type FetchTileJson = (input: string, init: {
|
|
|
115
120
|
type TileflowCaptureResolvedWorldV1 = Readonly<{
|
|
116
121
|
identity: Omit<TileflowCaptureWorldIdentityV3, 'kind' | 'schema' | 'schemaVersion' | 'semantics' | 'sourceId'>;
|
|
117
122
|
tileJsonUrl: string;
|
|
123
|
+
tileJson: string;
|
|
118
124
|
tiles: readonly [string];
|
|
119
125
|
}>;
|
|
120
126
|
type PreparedTileflowCaptureStyle = Readonly<{
|
|
127
|
+
assets?: TileflowCaptureAsset[];
|
|
121
128
|
data: TileflowCaptureDataInput;
|
|
122
129
|
style: MapLibreStyle;
|
|
123
130
|
}>;
|
|
@@ -135,8 +142,6 @@ declare function resolveTileflowCaptureWorldTileJson(tileJsonUrl: string, option
|
|
|
135
142
|
signal?: AbortSignal;
|
|
136
143
|
}): Promise<TileflowCaptureResolvedWorldV1>;
|
|
137
144
|
|
|
138
|
-
declare const tileflowSyntheticAssetOrigin = "https://tileflow.local.invalid";
|
|
139
|
-
|
|
140
145
|
declare function resolveTileflowApplicationUrl(input: {
|
|
141
146
|
appOrigin?: string;
|
|
142
147
|
appUrl?: string;
|
package/dist/index.js
CHANGED
|
@@ -318,7 +318,11 @@ import { createRequire as createRequire2 } from "module";
|
|
|
318
318
|
import { dirname as dirname2, join as join2 } from "path";
|
|
319
319
|
import { getTileflowStyleFontFaces } from "@tileflow/core/runtime";
|
|
320
320
|
import { assertValidTileflowStyle, TileflowStyleValidationError } from "@tileflow/dev/validation";
|
|
321
|
+
|
|
322
|
+
// src/assets.ts
|
|
321
323
|
var tileflowSyntheticAssetOrigin = "https://tileflow.local.invalid";
|
|
324
|
+
|
|
325
|
+
// src/standalone.ts
|
|
322
326
|
var require3 = createRequire2(import.meta.url);
|
|
323
327
|
var mapLibreRuntimePaths = Object.freeze({
|
|
324
328
|
css: require3.resolve("maplibre-gl/dist/maplibre-gl.css"),
|
|
@@ -396,6 +400,9 @@ async function captureStandaloneTileflowScene(input) {
|
|
|
396
400
|
}, timeoutMs);
|
|
397
401
|
timeout.unref?.();
|
|
398
402
|
const assets = new Map(input.assets.map((asset) => [asset.fileName, asset]));
|
|
403
|
+
const frozenResources = new Map(
|
|
404
|
+
input.assets.filter((asset) => asset.url !== void 0).map((asset) => [asset.url, asset])
|
|
405
|
+
);
|
|
399
406
|
const localTilesets = new Map(
|
|
400
407
|
(input.localTilesets ?? []).map((tileset) => [tileset.fileName, tileset])
|
|
401
408
|
);
|
|
@@ -414,6 +421,16 @@ async function captureStandaloneTileflowScene(input) {
|
|
|
414
421
|
};
|
|
415
422
|
await context.route("**/*", async (route) => {
|
|
416
423
|
const url = new URL(route.request().url());
|
|
424
|
+
const frozenResource = frozenResources.get(url.toString());
|
|
425
|
+
if (frozenResource) {
|
|
426
|
+
await route.fulfill({
|
|
427
|
+
body: typeof frozenResource.source === "string" ? frozenResource.source : Buffer.from(frozenResource.source),
|
|
428
|
+
contentType: frozenResource.contentType,
|
|
429
|
+
headers: { "Access-Control-Allow-Origin": "*" },
|
|
430
|
+
status: 200
|
|
431
|
+
});
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
417
434
|
if (url.origin === mapLibreRuntimeUrls.origin) {
|
|
418
435
|
const runtime = getMapLibreRuntimeResponse(url.pathname, input.scene.viewport);
|
|
419
436
|
if (runtime) {
|
|
@@ -887,8 +904,10 @@ window.__tileflowCaptureLoad = async function(input) {
|
|
|
887
904
|
await loadTileflowFontFaces(input.fontFaces || []);
|
|
888
905
|
window.__tileflowRegisterContourProtocol?.({addProtocol: window.maplibregl.addProtocol});
|
|
889
906
|
window.__tileflowRegisterPmtilesProtocol?.({addProtocol: window.maplibregl.addProtocol});
|
|
907
|
+
const data = input.style.metadata?.["tileflow:data"];
|
|
908
|
+
const worldSourceId = data?.kind === "tileflow-world" ? data.sourceId : undefined;
|
|
890
909
|
window.__tileflowCaptureLoopbackSourceIds = Object.entries(input.style.sources || {})
|
|
891
|
-
.filter(([, source]) => isLoopbackSourceUrl(source?.url))
|
|
910
|
+
.filter(([sourceId, source]) => sourceId !== worldSourceId && isLoopbackSourceUrl(source?.url))
|
|
892
911
|
.map(([sourceId]) => sourceId);
|
|
893
912
|
const map = new window.maplibregl.Map({
|
|
894
913
|
attributionControl: false,
|
|
@@ -1299,6 +1318,7 @@ async function captureApplicationTileflowScene(input) {
|
|
|
1299
1318
|
if (termination === "aborted") {
|
|
1300
1319
|
throw new TileflowCaptureError("ABORTED", "Tileflow capture was aborted.", { cause: error });
|
|
1301
1320
|
}
|
|
1321
|
+
if (error instanceof TileflowCaptureError && error.code === "APPLICATION_ERROR") throw error;
|
|
1302
1322
|
if (termination === "timeout") {
|
|
1303
1323
|
throw new TileflowCaptureError(
|
|
1304
1324
|
"CAPTURE_TIMEOUT",
|
|
@@ -1455,6 +1475,7 @@ function compareCodeUnits2(left, right) {
|
|
|
1455
1475
|
}
|
|
1456
1476
|
|
|
1457
1477
|
// src/world.ts
|
|
1478
|
+
import { createHash } from "crypto";
|
|
1458
1479
|
import {
|
|
1459
1480
|
isTileflowWorldReleaseId,
|
|
1460
1481
|
tileflowWorldTileJsonUrl
|
|
@@ -1486,13 +1507,21 @@ var TileflowCaptureWorldSession = class {
|
|
|
1486
1507
|
sourceId: requireLiteral(metadata.sourceId, "tileflow", "sourceId")
|
|
1487
1508
|
};
|
|
1488
1509
|
const { tiles: _mutableTiles, url: _mutableUrl, ...sourceWithoutSelector } = source;
|
|
1510
|
+
const tileJsonSha256 = createHash("sha256").update(resolution.tileJson).digest("hex");
|
|
1511
|
+
const fileName = `capture/world/${tileJsonSha256}.json`;
|
|
1512
|
+
const exactSelector = new URL(resolution.tileJsonUrl);
|
|
1513
|
+
exactSelector.searchParams.set("worldReleaseId", resolution.identity.releaseId);
|
|
1514
|
+
exactSelector.searchParams.set("worldDescriptorSha256", resolution.identity.descriptorSha256);
|
|
1515
|
+
const url = exactSelector.toString();
|
|
1489
1516
|
return {
|
|
1517
|
+
assets: [{ contentType: "application/json", fileName, source: resolution.tileJson, url }],
|
|
1490
1518
|
data,
|
|
1491
1519
|
style: {
|
|
1492
1520
|
...style,
|
|
1521
|
+
metadata: { ...style.metadata, "tileflow:captureWorldTileJsonSha256": tileJsonSha256 },
|
|
1493
1522
|
sources: {
|
|
1494
1523
|
...style.sources,
|
|
1495
|
-
tileflow: { ...sourceWithoutSelector,
|
|
1524
|
+
tileflow: { ...sourceWithoutSelector, url }
|
|
1496
1525
|
}
|
|
1497
1526
|
}
|
|
1498
1527
|
};
|
|
@@ -1579,6 +1608,7 @@ async function resolveTileflowCaptureWorldTileJson(tileJsonUrl, options = {}) {
|
|
|
1579
1608
|
releaseId
|
|
1580
1609
|
},
|
|
1581
1610
|
tileJsonUrl: normalizedUrl,
|
|
1611
|
+
tileJson: text,
|
|
1582
1612
|
tiles: [tileTemplate]
|
|
1583
1613
|
};
|
|
1584
1614
|
}
|
|
@@ -1838,7 +1868,7 @@ var TileflowCaptureSessionImpl = class {
|
|
|
1838
1868
|
signal,
|
|
1839
1869
|
timeoutMs: this.#options.timeoutMs
|
|
1840
1870
|
}) : await captureStandaloneTileflowScene({
|
|
1841
|
-
assets: artifacts.assets,
|
|
1871
|
+
assets: [...artifacts.assets, ...prepared.assets ?? []],
|
|
1842
1872
|
browser,
|
|
1843
1873
|
...artifacts.localTilesets ? { localTilesets: artifacts.localTilesets } : {},
|
|
1844
1874
|
scene,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tileflow/capture",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.26",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"description": "Deterministic local visual capture and comparison for Tileflow maps.",
|
|
6
6
|
"engines": {
|
|
@@ -48,8 +48,8 @@
|
|
|
48
48
|
"access": "public"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@tileflow/core": ">=0.1.0-alpha.
|
|
52
|
-
"@tileflow/dev": ">=0.1.0-alpha.
|
|
51
|
+
"@tileflow/core": ">=0.1.0-alpha.28 <0.1.0-beta.0",
|
|
52
|
+
"@tileflow/dev": ">=0.1.0-alpha.26 <0.1.0-beta.0",
|
|
53
53
|
"maplibre-gl": "6.9.0",
|
|
54
54
|
"pixelmatch": "7.2.0",
|
|
55
55
|
"playwright": "1.62.1",
|
|
@@ -68,13 +68,13 @@
|
|
|
68
68
|
"vite": "^8.0.16",
|
|
69
69
|
"vue": "^3.5.39",
|
|
70
70
|
"webpack": "5.108.3",
|
|
71
|
-
"@tileflow/maps": "0.1.0-alpha.
|
|
72
|
-
"@tileflow/
|
|
73
|
-
"@tileflow/
|
|
74
|
-
"@tileflow/
|
|
75
|
-
"@tileflow/vite": "0.1.0-alpha.
|
|
76
|
-
"@tileflow/
|
|
77
|
-
"@tileflow/
|
|
71
|
+
"@tileflow/maps": "0.1.0-alpha.5",
|
|
72
|
+
"@tileflow/next": "0.1.0-alpha.24",
|
|
73
|
+
"@tileflow/svelte": "0.1.0-alpha.25",
|
|
74
|
+
"@tileflow/react": "0.1.0-alpha.26",
|
|
75
|
+
"@tileflow/vite": "0.1.0-alpha.24",
|
|
76
|
+
"@tileflow/vue": "0.1.0-alpha.25",
|
|
77
|
+
"@tileflow/webpack": "0.1.0-alpha.24"
|
|
78
78
|
},
|
|
79
79
|
"scripts": {
|
|
80
80
|
"build": "tsup src/index.ts src/receipt.ts --format esm --dts --clean --platform node",
|