@pygmalionjs/pygmalion 0.5.32 → 0.5.33
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-lib/{FrozenRoutePreview-BGssXLP2.js → FrozenRoutePreview-hofdx4eP.js} +3080 -2925
- package/dist-lib/pygmalion.js +1387 -1336
- package/dist-lib/testing.js +1 -1
- package/dist-lib/types/editor/domImport.d.ts +21 -0
- package/dist-lib/types/editor/importFidelity.d.ts +85 -0
- package/dist-lib/types/editor/store.d.ts +20 -1
- package/package.json +1 -1
package/dist-lib/testing.js
CHANGED
|
@@ -2,6 +2,25 @@ import type { InstanceHit, InstanceResolver } from './fiberMap';
|
|
|
2
2
|
import type { NodeJSON } from './store';
|
|
3
3
|
/** Keeps a real 0 — the value that hides hover-only affordances. */
|
|
4
4
|
export declare function clampOpacity(value: string): number;
|
|
5
|
+
/**
|
|
6
|
+
* Where an imported layer sat in the source document, in model px relative to
|
|
7
|
+
* the imported root. The walk reads every element's client rect anyway; keeping
|
|
8
|
+
* the boxes lets the fidelity check (importFidelity.ts) re-measure the mounted
|
|
9
|
+
* layer tree and compare — a reconstruction is only trustworthy when it puts
|
|
10
|
+
* the same boxes in the same places the capture had them.
|
|
11
|
+
*
|
|
12
|
+
* Entries are addressed by child-index path, not node id: the store re-issues
|
|
13
|
+
* ids when it deserializes an imported tree, while the tree structure survives
|
|
14
|
+
* unchanged.
|
|
15
|
+
*/
|
|
16
|
+
export interface ImportedGeometryEntry {
|
|
17
|
+
/** Child-index chain from the imported root ([] is the root itself). */
|
|
18
|
+
path: readonly number[];
|
|
19
|
+
x: number;
|
|
20
|
+
y: number;
|
|
21
|
+
width: number;
|
|
22
|
+
height: number;
|
|
23
|
+
}
|
|
5
24
|
export interface DomImportDiagnostic {
|
|
6
25
|
severity: 'warning';
|
|
7
26
|
stage: 'capture';
|
|
@@ -51,6 +70,8 @@ export interface DomImportResult {
|
|
|
51
70
|
truncated: boolean;
|
|
52
71
|
diagnostics: readonly DomImportDiagnostic[];
|
|
53
72
|
metrics: DomImportMetrics;
|
|
73
|
+
/** Source boxes of the imported layers, for the post-mount fidelity check. */
|
|
74
|
+
geometry: readonly ImportedGeometryEntry[];
|
|
54
75
|
}
|
|
55
76
|
/** Transformation entry point starting from Element in the same document (or iframe document) — win is the window to which el belongs. */
|
|
56
77
|
export declare function importDomFromElement(el: Element, win: Window, opts?: DomImportOptions): DomImportResult | null;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { ImportedGeometryEntry } from './domImport';
|
|
2
|
+
/** The shape of a mounted layer tree this check needs — NodeModel satisfies it. */
|
|
3
|
+
export interface LayerImportFidelityNode {
|
|
4
|
+
id: string;
|
|
5
|
+
name?: string;
|
|
6
|
+
hidden?: boolean;
|
|
7
|
+
children?: readonly LayerImportFidelityNode[];
|
|
8
|
+
}
|
|
9
|
+
interface MeasuredBox {
|
|
10
|
+
x: number;
|
|
11
|
+
y: number;
|
|
12
|
+
width: number;
|
|
13
|
+
height: number;
|
|
14
|
+
}
|
|
15
|
+
export interface MeasurableElement {
|
|
16
|
+
getBoundingClientRect(): MeasuredBox;
|
|
17
|
+
ownerDocument?: {
|
|
18
|
+
createRange?: () => {
|
|
19
|
+
selectNodeContents(node: unknown): void;
|
|
20
|
+
getBoundingClientRect(): MeasuredBox;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export interface LayerImportBox {
|
|
25
|
+
x: number;
|
|
26
|
+
y: number;
|
|
27
|
+
width: number;
|
|
28
|
+
height: number;
|
|
29
|
+
}
|
|
30
|
+
export interface LayerImportDrift {
|
|
31
|
+
nodeId: string;
|
|
32
|
+
name: string;
|
|
33
|
+
path: readonly number[];
|
|
34
|
+
/** Where the capture had the layer, model px relative to the root. */
|
|
35
|
+
source: LayerImportBox;
|
|
36
|
+
/** Where the reconstruction put it. */
|
|
37
|
+
rendered: LayerImportBox;
|
|
38
|
+
dx: number;
|
|
39
|
+
dy: number;
|
|
40
|
+
dwidth: number;
|
|
41
|
+
dheight: number;
|
|
42
|
+
/** Largest absolute component of the drift, in model px. */
|
|
43
|
+
drift: number;
|
|
44
|
+
}
|
|
45
|
+
export interface LayerImportFidelityReport {
|
|
46
|
+
/** Layers that had both a source box and a mounted element to measure. */
|
|
47
|
+
checked: number;
|
|
48
|
+
/** Layers whose box moved or resized beyond the tolerance. */
|
|
49
|
+
drifted: number;
|
|
50
|
+
maxDriftPx: number;
|
|
51
|
+
/** The largest offenders, capped, largest first. */
|
|
52
|
+
worst: readonly LayerImportDrift[];
|
|
53
|
+
/** False when the reconstruction should not be trusted as the screen. */
|
|
54
|
+
ok: boolean;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Sub-tolerance drift is expected, not suspicious: fit/fill sizing modes
|
|
58
|
+
* quantize to whole px, text metrics round per line, and the canvas transform
|
|
59
|
+
* divides back out through floating point. 4px keeps that noise out of the
|
|
60
|
+
* report while catching any real layout change — one dropped wrap moves a
|
|
61
|
+
* box by a line height.
|
|
62
|
+
*/
|
|
63
|
+
export declare const LAYER_DRIFT_TOLERANCE_PX = 4;
|
|
64
|
+
/** A single layer this far off means the screen no longer reads as captured. */
|
|
65
|
+
export declare const LAYER_FIDELITY_MAX_DRIFT_PX = 12;
|
|
66
|
+
/** Many slightly-off layers are as untrustworthy as one badly-off layer. */
|
|
67
|
+
export declare const LAYER_FIDELITY_MAX_DRIFT_RATIO = 0.05;
|
|
68
|
+
/** Resolves a geometry path (child-index chain) inside a mounted layer tree. */
|
|
69
|
+
export declare function nodeAtGeometryPath(root: LayerImportFidelityNode, path: readonly number[]): LayerImportFidelityNode | null;
|
|
70
|
+
export interface LayerImportFidelityInput {
|
|
71
|
+
root: LayerImportFidelityNode;
|
|
72
|
+
geometry: readonly ImportedGeometryEntry[];
|
|
73
|
+
/** Canvas zoom at measurement time — rendered rects are visual px. */
|
|
74
|
+
scale: number;
|
|
75
|
+
/** data-node-id lookup, injectable so the comparison is testable. */
|
|
76
|
+
resolveElement: (nodeId: string) => MeasurableElement | null;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Measures the mounted layer tree against the source geometry the import
|
|
80
|
+
* recorded. Returns null when the tree is not measurable yet (the root element
|
|
81
|
+
* is unmounted, or nothing could be paired) — callers retry after mount; a
|
|
82
|
+
* report, once produced, is final for that import.
|
|
83
|
+
*/
|
|
84
|
+
export declare function assessLayerImportFidelity(input: LayerImportFidelityInput): LayerImportFidelityReport | null;
|
|
85
|
+
export {};
|
|
@@ -4,6 +4,7 @@ import { type CardBadgeOption, type CardSlotDef, type ScreenCardDef } from './sc
|
|
|
4
4
|
import { type ScreenListDef } from './screenLists';
|
|
5
5
|
import { type DesignImportAsset, type DesignImportKind, type DesignFrameSizeMode, type DesignScreenAssertion, type DesignScreenInteraction, type DesignScreenPreset, type StoryboardEnvironment } from './designImport';
|
|
6
6
|
import { type DomImportDiagnostic, type DomImportResult } from './domImport';
|
|
7
|
+
import { type LayerImportFidelityReport, type MeasurableElement } from './importFidelity';
|
|
7
8
|
import { type DesignFrameHeightMode } from './frameHeight';
|
|
8
9
|
import { type RegistryPropValue } from './registry';
|
|
9
10
|
import { type PrimitiveSourceValue } from './inspect';
|
|
@@ -231,6 +232,8 @@ export interface PageModel {
|
|
|
231
232
|
layerImportTruncated?: boolean;
|
|
232
233
|
layerImportDiagnostics?: readonly DomImportDiagnostic[];
|
|
233
234
|
layerImportError?: string;
|
|
235
|
+
/** Post-mount geometry comparison of the imported layers vs their capture. */
|
|
236
|
+
layerImportFidelity?: LayerImportFidelityReport;
|
|
234
237
|
/** Page edit revision recorded when the layers were imported. */
|
|
235
238
|
layerImportRevision?: number;
|
|
236
239
|
/** Frame width the layers were imported at — their geometry is only valid there. */
|
|
@@ -425,6 +428,8 @@ export declare class EditorStore {
|
|
|
425
428
|
private pageEditRevisions;
|
|
426
429
|
/** pageId → edit revision at the moment a frozen preview was promoted without a boot (D2). */
|
|
427
430
|
private provisionalLayerImports;
|
|
431
|
+
/** pageId → source geometry awaiting its post-mount fidelity measurement. */
|
|
432
|
+
private pendingLayerImportGeometry;
|
|
428
433
|
private contentLayoutScheduled;
|
|
429
434
|
private contentLayoutCanvases;
|
|
430
435
|
constructor();
|
|
@@ -680,8 +685,22 @@ export declare class EditorStore {
|
|
|
680
685
|
/** Keeps the current (user-edited) tree and stops further live re-import attempts for the page. */
|
|
681
686
|
discardProvisionalLayerImport(pageId: string): void;
|
|
682
687
|
/** Design importer automatically inserts the capture results into the existing frame. The route is maintained for live preview. */
|
|
683
|
-
replacePageRootFromDom(pageId: string, rootJson: NodeJSON, result?: Pick<DomImportResult, 'count' | 'truncated'> & Partial<Pick<DomImportResult, 'diagnostics' | 'metrics'>>): void;
|
|
688
|
+
replacePageRootFromDom(pageId: string, rootJson: NodeJSON, result?: Pick<DomImportResult, 'count' | 'truncated'> & Partial<Pick<DomImportResult, 'diagnostics' | 'metrics' | 'geometry'>>): void;
|
|
684
689
|
setPageLayerImportError(pageId: string, message: string): void;
|
|
690
|
+
/**
|
|
691
|
+
* Runs the fidelity measurement once the imported tree has committed and
|
|
692
|
+
* laid out — one frame for React, one for layout. FrameView re-invokes the
|
|
693
|
+
* assessment on mount as well, because a frame can import while its canvas
|
|
694
|
+
* surface is detached (LOD) and only become measurable later.
|
|
695
|
+
*/
|
|
696
|
+
private scheduleLayerImportFidelityCheck;
|
|
697
|
+
/**
|
|
698
|
+
* Compares the mounted layer tree against the source geometry its import
|
|
699
|
+
* recorded (importFidelity.ts). Idempotent per import: the pending geometry
|
|
700
|
+
* is consumed by the first measurement that finds the tree mounted, and a
|
|
701
|
+
* re-import queues fresh geometry.
|
|
702
|
+
*/
|
|
703
|
+
assessLayerImportFidelityForPage(pageId: string, resolveElement?: (nodeId: string) => MeasurableElement | null): void;
|
|
685
704
|
/** Switch pages by name — Path used by the host fixture's actual button handler (pygmalionNavigate). */
|
|
686
705
|
navigateToPageByName(name: string): void;
|
|
687
706
|
/** Show preview overlay — page navigation with Scyllender, linkTo/host navigation without editor chrome. */
|