@tileflow/capture 0.1.0-alpha.34 → 0.1.0-alpha.36
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 +6 -6
- package/dist/index.js +26 -1
- package/package.json +9 -10
- package/docs/receipts-and-comparison.md +0 -107
package/README.md
CHANGED
|
@@ -25,6 +25,9 @@ and a system Chrome installation is not a substitute. `allowBrowserInstall: true
|
|
|
25
25
|
first-use download. Provision the matching shell and system libraries ahead of time in restricted
|
|
26
26
|
CI environments; never assume that installing the npm package installed the browser.
|
|
27
27
|
|
|
28
|
+
On Windows, Capture disables Chromium's TCP port randomization to avoid intermittent loopback
|
|
29
|
+
connection failures, preserving Playwright's other launch defaults and sandboxing.
|
|
30
|
+
|
|
28
31
|
Local capture needs no Tileflow API key. Configs are executable trusted code; remote tiles, fonts,
|
|
29
32
|
and sprites may still require network access and their own permissions.
|
|
30
33
|
|
|
@@ -113,7 +116,7 @@ per-user browser cache.
|
|
|
113
116
|
|
|
114
117
|
## Render a timed shot
|
|
115
118
|
|
|
116
|
-
A [capture shot](https://github.com/tileflow/tileflow-sdk/blob/main/packages/core/
|
|
119
|
+
A [capture shot](https://github.com/tileflow/tileflow-sdk/blob/main/packages/core/README.md)
|
|
117
120
|
is a committed camera move with keyframes and an optional theme blend. This module assumes a
|
|
118
121
|
`dusk-flyover` shot in `tileflow.config.ts` and writes its WebM video and receipt:
|
|
119
122
|
|
|
@@ -252,8 +255,6 @@ requiring compatible framing, renderer, and data identity. It accepts captures w
|
|
|
252
255
|
retained `definition`; when present, that definition must match the explicit review definition.
|
|
253
256
|
`analyzeTileflowCaptureReference` analyzes
|
|
254
257
|
an external PNG without claiming receipt compatibility. Neither operation approves a baseline.
|
|
255
|
-
See the [receipt and comparison reference](https://github.com/tileflow/tileflow-sdk/blob/main/packages/capture/docs/receipts-and-comparison.md),
|
|
256
|
-
also included under `docs/` in the installed package, for identities, metrics, and limits.
|
|
257
258
|
|
|
258
259
|
## Errors, receipts, and reproducibility
|
|
259
260
|
|
|
@@ -271,6 +272,5 @@ available tiles while preserving the scene camera. Retries reuse the same frozen
|
|
|
271
272
|
Remote-dependent rendering is not a guarantee of globally identical pixels
|
|
272
273
|
across platforms or future runs.
|
|
273
274
|
|
|
274
|
-
Read
|
|
275
|
-
for
|
|
276
|
-
for runtime licenses. For release-specific behavior, prefer installed declarations and docs over `main`.
|
|
275
|
+
Read [third-party notices](https://github.com/tileflow/tileflow-sdk/blob/main/packages/capture/THIRD_PARTY_NOTICES.md)
|
|
276
|
+
for runtime licenses. For release-specific behavior, prefer installed README and declarations over `main`.
|
package/dist/index.js
CHANGED
|
@@ -204,9 +204,32 @@ var TileflowCaptureBrowserManager = class {
|
|
|
204
204
|
}
|
|
205
205
|
}
|
|
206
206
|
};
|
|
207
|
+
var windowsChromiumDisabledFeatures = [
|
|
208
|
+
"AvoidUnnecessaryBeforeUnloadCheckSync",
|
|
209
|
+
"BoundaryEventDispatchTracksNodeRemoval",
|
|
210
|
+
"DestroyProfileOnBrowserClose",
|
|
211
|
+
"DialMediaRouteProvider",
|
|
212
|
+
"GlobalMediaControls",
|
|
213
|
+
"HttpsUpgrades",
|
|
214
|
+
"LensOverlay",
|
|
215
|
+
"MediaRouter",
|
|
216
|
+
"PaintHolding",
|
|
217
|
+
"ThirdPartyStoragePartitioning",
|
|
218
|
+
"BlockOriginHeaderModificationOnRedirect",
|
|
219
|
+
"Translate",
|
|
220
|
+
"AutoDeElevate",
|
|
221
|
+
"OptimizationHints",
|
|
222
|
+
"msForceBrowserSignIn",
|
|
223
|
+
"msEdgeUpdateLaunchServicesPreferredVersion",
|
|
224
|
+
// Avoid intermittent Windows loopback failures: https://issues.chromium.org/issues/572515601.
|
|
225
|
+
"TcpPortRandomizationWin"
|
|
226
|
+
];
|
|
207
227
|
function launchPinnedBrowser() {
|
|
208
228
|
return chromium.launch({
|
|
209
|
-
args: [
|
|
229
|
+
args: [
|
|
230
|
+
"--disable-dev-shm-usage",
|
|
231
|
+
...process.platform === "win32" ? [`--disable-features=${windowsChromiumDisabledFeatures.join(",")}`] : []
|
|
232
|
+
],
|
|
210
233
|
chromiumSandbox: true,
|
|
211
234
|
env: createTileflowCaptureBrowserEnvironment(),
|
|
212
235
|
handleSIGHUP: false,
|
|
@@ -348,6 +371,7 @@ var tileflowBrowserModule = `${readFileSync2(
|
|
|
348
371
|
"utf8"
|
|
349
372
|
)}
|
|
350
373
|
globalThis.__tileflowRegisterContourProtocol = registerTileflowContourProtocol;
|
|
374
|
+
globalThis.__tileflowRegisterPathGroundProtocol = registerTileflowPathGroundProtocol;
|
|
351
375
|
globalThis.__tileflowRegisterPmtilesProtocol = registerTileflowPmtilesProtocol;
|
|
352
376
|
globalThis.__tileflowAttachAtmosphere = attachTileflowAtmosphere;
|
|
353
377
|
globalThis.__tileflowAttachNotices = attachTileflowNotices;
|
|
@@ -998,6 +1022,7 @@ window.__tileflowCaptureLoad = async function(input) {
|
|
|
998
1022
|
try {
|
|
999
1023
|
await loadTileflowFontFaces(input.fontFaces || []);
|
|
1000
1024
|
window.__tileflowRegisterContourProtocol?.({addProtocol: window.maplibregl.addProtocol});
|
|
1025
|
+
window.__tileflowRegisterPathGroundProtocol?.({addProtocol: window.maplibregl.addProtocol});
|
|
1001
1026
|
window.__tileflowRegisterPmtilesProtocol?.({addProtocol: window.maplibregl.addProtocol});
|
|
1002
1027
|
const data = input.style.metadata?.["tileflow:data"];
|
|
1003
1028
|
const worldSourceId = data?.kind === "tileflow-world" ? data.sourceId : undefined;
|
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.36",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"description": "Deterministic local visual capture and comparison for Tileflow maps.",
|
|
6
6
|
"engines": {
|
|
@@ -28,7 +28,6 @@
|
|
|
28
28
|
"types": "./dist/index.d.ts",
|
|
29
29
|
"files": [
|
|
30
30
|
"dist",
|
|
31
|
-
"docs",
|
|
32
31
|
"THIRD_PARTY_NOTICES.md",
|
|
33
32
|
"LICENSE"
|
|
34
33
|
],
|
|
@@ -48,8 +47,8 @@
|
|
|
48
47
|
"access": "public"
|
|
49
48
|
},
|
|
50
49
|
"dependencies": {
|
|
51
|
-
"@tileflow/core": ">=0.1.0-alpha.
|
|
52
|
-
"@tileflow/dev": ">=0.1.0-alpha.
|
|
50
|
+
"@tileflow/core": ">=0.1.0-alpha.43 <0.1.0-beta.0",
|
|
51
|
+
"@tileflow/dev": ">=0.1.0-alpha.39 <0.1.0-beta.0",
|
|
53
52
|
"maplibre-gl": "6.13.0",
|
|
54
53
|
"pixelmatch": "7.2.0",
|
|
55
54
|
"playwright": "1.62.1",
|
|
@@ -57,7 +56,7 @@
|
|
|
57
56
|
},
|
|
58
57
|
"devDependencies": {
|
|
59
58
|
"@sveltejs/vite-plugin-svelte": "^7.3.0",
|
|
60
|
-
"@types/node": "^
|
|
59
|
+
"@types/node": "^26.6.5",
|
|
61
60
|
"@types/pngjs": "6.0.5",
|
|
62
61
|
"@vitejs/plugin-vue": "^6.0.8",
|
|
63
62
|
"maplibre-gl-min": "npm:maplibre-gl@6.4.1",
|
|
@@ -68,12 +67,12 @@
|
|
|
68
67
|
"vite": "^8.3.4",
|
|
69
68
|
"vue": "^3.5.43",
|
|
70
69
|
"webpack": "5.108.3",
|
|
71
|
-
"@tileflow/maps": "0.1.0-alpha.
|
|
70
|
+
"@tileflow/maps": "0.1.0-alpha.17",
|
|
72
71
|
"@tileflow/next": "0.1.0-alpha.25",
|
|
73
|
-
"@tileflow/react": "0.1.0-alpha.
|
|
74
|
-
"@tileflow/
|
|
75
|
-
"@tileflow/
|
|
76
|
-
"@tileflow/
|
|
72
|
+
"@tileflow/react": "0.1.0-alpha.36",
|
|
73
|
+
"@tileflow/svelte": "0.1.0-alpha.34",
|
|
74
|
+
"@tileflow/vite": "0.1.0-alpha.26",
|
|
75
|
+
"@tileflow/vue": "0.1.0-alpha.34",
|
|
77
76
|
"@tileflow/webpack": "0.1.0-alpha.25"
|
|
78
77
|
},
|
|
79
78
|
"scripts": {
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
# Capture receipts and visual comparison
|
|
2
|
-
|
|
3
|
-
`createTileflowCaptureReceipt`, `parseTileflowCaptureReceipt`,
|
|
4
|
-
`validateTileflowCaptureReceipt`, and `serializeTileflowCaptureReceipt` implement the strict,
|
|
5
|
-
bounded schema-version-4 receipt contract. A receipt contains the concrete theme,
|
|
6
|
-
image/scene/style hashes, dimensions,
|
|
7
|
-
renderer/platform identity, the required resolved `data` identity, explicit style/data verification,
|
|
8
|
-
and remote-dependency state. Standalone map receipts mark configured style and data as `rendered`;
|
|
9
|
-
application receipts mark them as `expected-unverified` because capture cannot inspect an arbitrary
|
|
10
|
-
application's live MapLibre instance. Vector endpoints are represented by a query-free SHA-256
|
|
11
|
-
fingerprint rather than a raw URL. Receipts contain no time, user, origin, path, query, signed token,
|
|
12
|
-
repository, absolute filesystem path, config source, environment, or credential.
|
|
13
|
-
|
|
14
|
-
For Tileflow World, Capture resolves the map's TileJSON selector once per session, requires
|
|
15
|
-
`tileflow.world` to identify `world-v1` with exact release, descriptor, archive, data-contract, and
|
|
16
|
-
product-contract SHA-256 values, and renders every standalone scene from the returned immutable tile
|
|
17
|
-
template. Repeated scenes and retries reuse that one resolution; another selector in the same
|
|
18
|
-
session fails instead of mixing releases. Parsing accepts only schema version 4.
|
|
19
|
-
|
|
20
|
-
Capture reuses Core's exact World V1 release-ID contract: 12–128 characters matching
|
|
21
|
-
`^world-v1-[a-z0-9][a-z0-9._-]*[a-z0-9]$`. Selector responses and durable receipts reject rather
|
|
22
|
-
than normalize uppercase, whitespace, another generation, or an incomplete boundary value.
|
|
23
|
-
|
|
24
|
-
Receipt-only tooling can import these contracts from `@tileflow/capture/receipt` without loading the
|
|
25
|
-
Playwright capture runtime.
|
|
26
|
-
|
|
27
|
-
`createTileflowShotReceipt`, `parseTileflowShotReceipt`, `validateTileflowShotReceipt`, and
|
|
28
|
-
`serializeTileflowShotReceipt` implement the separate schema-version-1 shot receipt, identified by
|
|
29
|
-
`kind: "shot"` and bounded to 64 KiB. It records the shot and its theme and blend styles, timing,
|
|
30
|
-
dimensions, renderer, platform, data identity, and two hashes: `frames.sha256`, computed from every
|
|
31
|
-
frame's PNG SHA-256 in order, identifies the rendered pixels, and `output.sha256` identifies the
|
|
32
|
-
written WebM file or, for the `frames` output, equals `frames.sha256`. The still-receipt parser
|
|
33
|
-
rejects shot receipts, and the shot-receipt parser rejects still receipts.
|
|
34
|
-
|
|
35
|
-
The following comparison fragments assume captures and PNG/receipt bytes that the caller has
|
|
36
|
-
already loaded and validated. See the package README for a complete baseline-file example.
|
|
37
|
-
|
|
38
|
-
```ts
|
|
39
|
-
import {compareTileflowCaptureToBaseline} from '@tileflow/capture';
|
|
40
|
-
|
|
41
|
-
const comparison = await compareTileflowCaptureToBaseline(result.captures[0], {
|
|
42
|
-
png: baselinePng,
|
|
43
|
-
receipt: baselineReceiptJson,
|
|
44
|
-
});
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
Comparison validates PNG CRC, hash, dimensions, pixel bounds, and receipt identity before reading
|
|
48
|
-
pixels. It classifies unchanged, changed, missing, scene-mismatch, and runtime-mismatch results,
|
|
49
|
-
reports exact RGBA changed pixels plus a fixed 0.1 perceptual metric, and returns an optional
|
|
50
|
-
transparent high-contrast diff PNG. Exact RGBA inequality determines `changed`.
|
|
51
|
-
|
|
52
|
-
To review two deliberate Tileflow renders that are allowed to use different maps, themes, and
|
|
53
|
-
styles, use the separate review primitive:
|
|
54
|
-
|
|
55
|
-
```ts
|
|
56
|
-
import {
|
|
57
|
-
compareTileflowCapturesForReview,
|
|
58
|
-
createTileflowVisualReviewDocument,
|
|
59
|
-
} from '@tileflow/capture';
|
|
60
|
-
|
|
61
|
-
const review = await compareTileflowCapturesForReview(
|
|
62
|
-
{capture: leftCapture, definition: leftDefinition},
|
|
63
|
-
{capture: rightCapture, definition: rightDefinition},
|
|
64
|
-
{includeDiff: true, region: {x: 0, y: 0, width: 1200, height: 760}},
|
|
65
|
-
);
|
|
66
|
-
const document = createTileflowVisualReviewDocument(review);
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
Review requires each PNG, its schema-v4 receipt, and the exact normalized definition used to
|
|
70
|
-
produce it. It authenticates both sides before comparing pixels. Different map/style/theme
|
|
71
|
-
identities are intentional, but camera, viewport, target frame, physical dimensions, renderer, and
|
|
72
|
-
resolved data identity must agree before exact or perceptual metrics are meaningful. Statuses are
|
|
73
|
-
`comparable`, `frame-mismatch`, `dimensions-mismatch`, `runtime-mismatch`, and `data-mismatch`.
|
|
74
|
-
Inputs are snapshotted from plain accessor-free data before asynchronous work, and both individual
|
|
75
|
-
and aggregate PNG byte limits are enforced before hashing. Pixelmatch runs only for compatible
|
|
76
|
-
captures; `includeDiff: false` does not allocate or encode a diff. The optional diff is contextual
|
|
77
|
-
evidence only; this API never reads, writes, or approves a visual baseline.
|
|
78
|
-
|
|
79
|
-
Every comparable review also reports `appearance: {region, left, right, rightMinusLeft}`. Profiles
|
|
80
|
-
contain linear luminance, OKLab lightness/chroma (`mean`, `p10`, `p50`, `p90`), edge density, and
|
|
81
|
-
local contrast. The optional region is one bounded physical-pixel rectangle from the top-left and
|
|
82
|
-
affects only `appearance`; exact/perceptual metrics and the diff still describe the complete frame.
|
|
83
|
-
|
|
84
|
-
Review documents are a schema-version-1 compatibility boundary, exposed through
|
|
85
|
-
`tileflowVisualReviewSchemaVersion`. `tileflowVisualReviewLimits.maximumAggregatePngBytes` exposes
|
|
86
|
-
the 256 MiB aggregate input cap; each input is also subject to the 256 MiB
|
|
87
|
-
`tileflowVisualArtifactLimits.maximumPngBytes` cap and the shared decoded-pixel limits. Invalid,
|
|
88
|
-
non-plain, unauthenticated, or over-limit inputs throw `TileflowVisualReviewError` with stable code
|
|
89
|
-
`VISUAL_REVIEW_INVALID`. `createTileflowVisualReviewDocument` removes contextual `diffPng` bytes
|
|
90
|
-
while retaining the versioned identities, status, metrics, and warnings.
|
|
91
|
-
|
|
92
|
-
For an external design screenshot that has no Tileflow receipt, use the separate exploratory
|
|
93
|
-
primitive:
|
|
94
|
-
|
|
95
|
-
```ts
|
|
96
|
-
import {analyzeTileflowCaptureReference} from '@tileflow/capture';
|
|
97
|
-
|
|
98
|
-
const analysis = await analyzeTileflowCaptureReference(result.captures[0], referencePng, {
|
|
99
|
-
region: {x: 0, y: 0, width: 1200, height: 760},
|
|
100
|
-
});
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
It strictly validates the bounded non-interlaced PNG, reports dimensions and up to 16 deterministic
|
|
104
|
-
quantized palette entries, and—only for equal dimensions—exact/perceptual changed pixels, mean
|
|
105
|
-
absolute RGBA-channel difference, a high-contrast diff PNG, and
|
|
106
|
-
`appearance.actualMinusReference` with the same signed profile. It does not assert scene/runtime
|
|
107
|
-
compatibility, accept a receipt for the reference, or create a baseline.
|