@pygmalionjs/pygmalion 0.18.0 → 0.19.0

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.
@@ -20749,7 +20749,7 @@ function z_(t) {
20749
20749
  stamped: u ? i.isStampedFrozenPreview(u.root) : null
20750
20750
  },
20751
20751
  lodState: a.__debugFrameLodState(),
20752
- readFramesNow: (await import("./CameraLayer-Clqgdcjb.js")).__debugReadEditorFrames(t).find((h) => h.id === n)
20752
+ readFramesNow: (await import("./CameraLayer-Bv1TqRim.js")).__debugReadEditorFrames(t).find((h) => h.id === n)
20753
20753
  };
20754
20754
  },
20755
20755
  /** Flow-session delivery states for headless diagnosis of the captureless supply. */
@@ -20984,26 +20984,26 @@ export {
20984
20984
  Vu as b7,
20985
20985
  Ha as b8,
20986
20986
  WS as b9,
20987
- i0 as bA,
20988
- $0 as bB,
20989
- R0 as bC,
20990
- Ld as bD,
20991
- Fd as bE,
20992
- Jy as bF,
20993
- pI as bG,
20994
- X0 as bH,
20995
- _w as bI,
20996
- Aw as bJ,
20997
- eI as bK,
20998
- n0 as bL,
20999
- r0 as bM,
21000
- b0 as bN,
21001
- bu as bO,
21002
- Uu as bP,
21003
- uo as bQ,
21004
- co as bR,
21005
- Pp as bS,
21006
- Ba as bT,
20987
+ gw as bA,
20988
+ i0 as bB,
20989
+ $0 as bC,
20990
+ R0 as bD,
20991
+ Ld as bE,
20992
+ Fd as bF,
20993
+ Jy as bG,
20994
+ pI as bH,
20995
+ X0 as bI,
20996
+ _w as bJ,
20997
+ Aw as bK,
20998
+ eI as bL,
20999
+ n0 as bM,
21000
+ r0 as bN,
21001
+ b0 as bO,
21002
+ bu as bP,
21003
+ Uu as bQ,
21004
+ uo as bR,
21005
+ co as bS,
21006
+ Pp as bT,
21007
21007
  gI as bU,
21008
21008
  J_ as bV,
21009
21009
  x0 as bW,
@@ -21013,30 +21013,30 @@ export {
21013
21013
  nb as b_,
21014
21014
  HS as ba,
21015
21015
  lo as bb,
21016
- e_ as bc,
21017
- ro as bd,
21018
- xc as be,
21019
- Ro as bf,
21020
- h_ as bg,
21021
- dt as bh,
21022
- pd as bi,
21023
- kd as bj,
21024
- yI as bk,
21025
- mI as bl,
21026
- M0 as bm,
21027
- T0 as bn,
21028
- p0 as bo,
21029
- k0 as bp,
21030
- C0 as bq,
21031
- cr as br,
21032
- pu as bs,
21033
- Rv as bt,
21034
- $v as bu,
21035
- qy as bv,
21036
- l0 as bw,
21037
- Dv as bx,
21038
- QS as by,
21039
- gw as bz,
21016
+ Ba as bc,
21017
+ e_ as bd,
21018
+ ro as be,
21019
+ xc as bf,
21020
+ Ro as bg,
21021
+ h_ as bh,
21022
+ dt as bi,
21023
+ pd as bj,
21024
+ kd as bk,
21025
+ yI as bl,
21026
+ mI as bm,
21027
+ M0 as bn,
21028
+ T0 as bo,
21029
+ p0 as bp,
21030
+ k0 as bq,
21031
+ C0 as br,
21032
+ cr as bs,
21033
+ pu as bt,
21034
+ Rv as bu,
21035
+ $v as bv,
21036
+ qy as bw,
21037
+ l0 as bx,
21038
+ Dv as by,
21039
+ QS as bz,
21040
21040
  Zn as c,
21041
21041
  B0 as c0,
21042
21042
  Q0 as c1,
@@ -1,5 +1,5 @@
1
- import { b$ as l, T as u } from "./runtime-B8Qu1ung.js";
2
- import { bo as y, ch as b, ci as E, cj as P, bk as $, aw as T } from "./runtime-B8Qu1ung.js";
1
+ import { b$ as d, T as u } from "./runtime-DlZpODq8.js";
2
+ import { bp as y, ch as b, ci as E, cj as P, bl as $, aw as T } from "./runtime-DlZpODq8.js";
3
3
  const v = {
4
4
  mirror: ["status", "refresh", "refs"],
5
5
  session: ["open", "check", "previewVisual", "applyVisual", "revertVisual"],
@@ -9,7 +9,7 @@ const v = {
9
9
  storyboard: ["environment", "sourceUsage", "componentBranches"]
10
10
  };
11
11
  function h(m = {}, t = {}) {
12
- const n = [], d = t.origin ?? "", r = (e) => {
12
+ const n = [], l = t.origin ?? "", r = (e) => {
13
13
  var a;
14
14
  const i = {};
15
15
  for (const o of v[e]) {
@@ -26,8 +26,8 @@ function h(m = {}, t = {}) {
26
26
  };
27
27
  return {
28
28
  calls: n,
29
- endpoints: l(t.endpoints),
30
- resolveUrl: (e) => `${d}${e}`,
29
+ endpoints: d(t.endpoints),
30
+ resolveUrl: (e) => `${l}${e}`,
31
31
  mirror: r("mirror"),
32
32
  session: r("session"),
33
33
  inspect: r("inspect"),
@@ -8,6 +8,43 @@ export interface VariableBinding {
8
8
  }
9
9
  export type VariableBindings = Record<string, VariableBinding>;
10
10
  export type VariableValueCodec = (library: TokenLibraryDocument, resolved: TokenValueResolution) => VariableScalar;
11
+ export type VariableModeProvider = {
12
+ kind: 'binding';
13
+ } | {
14
+ kind: 'node';
15
+ nodeId: string;
16
+ } | {
17
+ kind: 'instance';
18
+ instanceId: string;
19
+ overrideAddress: string;
20
+ } | {
21
+ kind: 'default';
22
+ };
23
+ export interface VariableModeResolution {
24
+ collectionId: string;
25
+ /** The requested mode, even when an alias is authored in a fallback mode. */
26
+ modeId: string;
27
+ provider: VariableModeProvider;
28
+ visitedNodeIds: readonly string[];
29
+ }
30
+ export interface VariableInstanceAddress {
31
+ instanceId: string;
32
+ overrideAddress: string;
33
+ }
34
+ export type VariableOccurrenceAddress = {
35
+ nodeId: string;
36
+ } | VariableInstanceAddress;
37
+ export interface VariableOccurrencePlan {
38
+ address: VariableOccurrenceAddress;
39
+ property: VariableTarget;
40
+ binding: VariableBinding;
41
+ mode: VariableModeResolution;
42
+ resolved: TokenValueResolution;
43
+ value: VariableScalar;
44
+ before: DocumentValue | undefined;
45
+ /** Literal projection only. Binding identity and transaction ownership stay with the caller. */
46
+ patch: DocumentNodePatch;
47
+ }
11
48
  export interface VariableChange {
12
49
  nodeId: string;
13
50
  overrideAddress?: string;
@@ -50,8 +87,15 @@ export declare function isVariableBinding(value: unknown): value is VariableBind
50
87
  export declare function nodeVariableBindings(node: Pick<DocumentNode, 'properties'>): VariableBindings;
51
88
  /** Built-in values are JSON scalars. Other syntax remains the host codec's responsibility. */
52
89
  export declare function resolveScalarVariable(library: TokenLibraryDocument, resolved: TokenValueResolution, seen?: Set<string>): VariableScalar;
90
+ export declare function resolveVariableModeForNode(document: DesignDocument, nodeId: string, library: TokenLibraryDocument, tokenId: string, explicit?: string): VariableModeResolution;
53
91
  export declare function variableModeForNode(document: DesignDocument, nodeId: string, library: TokenLibraryDocument, tokenId: string, explicit?: string): string;
92
+ /** Resolves an opaque override address through the actual component resolver. */
93
+ export declare function resolveVariableModeForInstance(document: DesignDocument, address: VariableInstanceAddress, library: TokenLibraryDocument, binding: VariableBinding): VariableModeResolution;
54
94
  export declare function variableTargetsForNode(node: DocumentNode): VariableTarget[];
95
+ /** Override projection stays sparse; unrelated inherited properties never become local overrides. */
96
+ export declare function projectVariableScalar(node: DocumentNode, property: VariableTarget, value: VariableScalar, placement: 'own' | 'override'): DocumentNodePatch;
97
+ /** Reads one occurrence without refreshing unrelated nodes or changing either document. */
98
+ export declare function planVariableOccurrence(document: DesignDocument, address: VariableOccurrenceAddress, property: VariableTarget, library: TokenLibraryDocument, codec?: VariableValueCodec): VariableOccurrencePlan;
55
99
  export declare function bindVariablePatch(document: DesignDocument, nodeId: string, property: VariableTarget, library: TokenLibraryDocument, binding: VariableBinding, codec?: VariableValueCodec): DocumentNodePatch;
56
100
  export declare function detachVariablePatch(node: DocumentNode, property: VariableTarget): DocumentNodePatch;
57
101
  /** A refresh plan records all affected nodes before the caller commits one history entry. */
@@ -1,10 +1,14 @@
1
1
  import type { DesignDocument, DocumentEngineOptions, DocumentTransaction } from '../../document/contracts.js';
2
+ import type { ProjectedDocumentNode } from './projection.js';
2
3
  import type { DataProjection } from '../../binding/preview.js';
3
4
 
4
- export declare function ArrangeLayers({ document, selected, projection, preflight, act, compact }: {
5
+ export declare function ArrangeLayers({ document, selected, projection, scene, visibleRootIds, isGeometryCurrent, preflight, act, compact }: {
5
6
  document: DesignDocument;
6
7
  selected: readonly string[];
7
8
  projection: DataProjection | null;
9
+ scene?: ProjectedDocumentNode;
10
+ visibleRootIds?: readonly string[];
11
+ isGeometryCurrent?: () => boolean;
8
12
  compact?: boolean;
9
13
  preflight?: DocumentEngineOptions['preflight'];
10
14
  act(label: string, apply: (transaction: DocumentTransaction) => void): boolean;
@@ -1,13 +1,17 @@
1
1
  import type { DataProjection } from '../../binding/preview.js';
2
2
  import type { WorkspaceCamera } from '../contracts.js';
3
+ import { type ProjectedDocumentNode } from './projection.js';
3
4
  import type { DesignDocument, DocumentNode, DocumentTransaction } from '../../document/contracts.js';
4
5
 
5
6
  type Act = (label: string, apply: (transaction: DocumentTransaction) => void) => unknown;
6
7
  /** A camera mounts rulers in viewport pixels and transforms document annotations exactly once. */
7
- export declare function CanvasGuides({ document, selected, projection, camera, zoom: suppliedZoom, act, width, height, visibleRootIds }: {
8
+ export declare function CanvasGuides({ document, selected, projection, scene, geometryKey, isGeometryCurrent, camera, zoom: suppliedZoom, act, width, height, visibleRootIds }: {
8
9
  document: DesignDocument;
9
10
  selected?: readonly string[];
10
11
  projection?: DataProjection | null;
12
+ scene?: ProjectedDocumentNode;
13
+ geometryKey?: string;
14
+ isGeometryCurrent?: () => boolean;
11
15
  camera?: WorkspaceCamera;
12
16
  zoom?: number;
13
17
  act: Act;
@@ -1,3 +1,4 @@
1
+ import type { ProjectedDocumentNode } from './projection.js';
1
2
  import type { DataProjection } from '../../binding/preview.js';
2
3
  import type { DesignDocument, DocumentTransaction } from '../../document/contracts.js';
3
4
  import { type PrototypeConnectionSelection } from './prototypeWiringModel.js';
@@ -8,6 +9,9 @@ export interface PrototypeWiringProps {
8
9
  selected: readonly string[];
9
10
  projection: DataProjection | null;
10
11
  zoom: number;
12
+ scene?: ProjectedDocumentNode;
13
+ geometryKey?: string;
14
+ isGeometryCurrent?: () => boolean;
11
15
  visibleRootIds?: readonly string[];
12
16
  selectedConnection: PrototypeConnectionSelection | null;
13
17
  onSelectConnection(value: PrototypeConnectionSelection | null): void;
@@ -1,5 +1,6 @@
1
1
  import type { DataProjection } from '../../binding/preview.js';
2
2
  import type { DesignDocument, DocumentTransaction } from '../../document/contracts.js';
3
+ import type { ProjectedDocumentNode } from './projection.js';
3
4
  import { type LayerPlacement, type SnapGuide } from './geometryHandles.js';
4
5
 
5
6
  type Act = (label: string, apply: (transaction: DocumentTransaction) => void) => boolean;
@@ -11,6 +12,11 @@ export interface SelectionHandlesProps {
11
12
  selected: readonly string[];
12
13
  visibleRootIds?: readonly string[];
13
14
  projection: DataProjection | null;
15
+ scene?: ProjectedDocumentNode;
16
+ /** Measurement/provider lifetime, including changes that return to the same screen. */
17
+ geometryKey?: string;
18
+ /** Synchronous owner check, captured at gesture start and checked before committing. */
19
+ isGeometryCurrent?: () => boolean;
14
20
  /** Canvas scale; handles keep a constant screen size and snapping a constant screen tolerance. */
15
21
  zoom: number;
16
22
  act: Act;
@@ -41,15 +47,17 @@ export declare const SELECTION_BOX_ID = "selection";
41
47
  * mirroring layer arrangement. The dimension badge follows the live world bounds without
42
48
  * applying its own document changes.
43
49
  */
44
- export declare function SelectionHandles({ document, selected, visibleRootIds, projection, zoom, act, movePreview, movePreviews, onPreview, onPreviewMany }: SelectionHandlesProps): import("react").JSX.Element;
50
+ export declare function SelectionHandles({ document, selected, visibleRootIds, projection, scene, geometryKey, isGeometryCurrent, zoom, act, movePreview, movePreviews, onPreview, onPreviewMany }: SelectionHandlesProps): import("react").JSX.Element;
45
51
  /**
46
52
  * Inspector section: the geometry policy for the whole selection, plus parent-relative rotation
47
53
  * in degrees and resize constraints when exactly one layer is selected.
48
54
  */
49
- export declare function LayerGeometryInspector({ document, selected, projection, act, compact }: {
55
+ export declare function LayerGeometryInspector({ document, selected, projection, scene, isGeometryCurrent, act, compact }: {
50
56
  document: DesignDocument;
51
57
  selected: readonly string[];
52
58
  projection: DataProjection | null;
59
+ scene?: ProjectedDocumentNode;
60
+ isGeometryCurrent?: () => boolean;
53
61
  act: Act;
54
62
  compact?: boolean;
55
63
  }): import("react").JSX.Element | null;
@@ -3,6 +3,7 @@ import type { DataProjection } from '../../binding/preview.js';
3
3
  import type { DesignDocument, DocumentNode, DocumentTransaction } from '../../document/contracts.js';
4
4
  import { type VectorAnchor, type VectorAnchorAddress, type VectorBooleanOperation, type VectorProperties, type VectorShape } from '../../document/vector.js';
5
5
  import { type VectorAnchorAction, type VectorAnchorActions, type VectorBooleanPlan, type VectorEditPlan, type VectorStyle, type VectorTool } from './vectorTools.js';
6
+ import type { ProjectedDocumentNode } from './projection.js';
6
7
 
7
8
  type Act = (label: string, apply: (transaction: DocumentTransaction) => void) => boolean;
8
9
  /** Box geometry a canvas gesture is previewing for one layer; the surface draws it instead of the stored path. */
@@ -13,6 +14,12 @@ export interface VectorGeometryPreview {
13
14
  export interface VectorEditingSession {
14
15
  readonly document: DesignDocument;
15
16
  readonly projection: DataProjection | null;
17
+ /** The same disposable measured scene rendered by the canvas. */
18
+ readonly scene?: ProjectedDocumentNode;
19
+ readonly geometryKey?: string;
20
+ /** Captured at gesture start and checked again before any document command. */
21
+ readonly isGeometryCurrent?: () => boolean;
22
+ readonly visibleRootIds?: readonly string[];
16
23
  readonly selection: readonly string[];
17
24
  readonly tool: VectorTool;
18
25
  setTool(tool: VectorTool): void;
@@ -42,6 +49,10 @@ export interface VectorEditingInput {
42
49
  document: DesignDocument;
43
50
  selection: readonly string[];
44
51
  projection: DataProjection | null;
52
+ scene?: ProjectedDocumentNode;
53
+ geometryKey?: string;
54
+ isGeometryCurrent?: () => boolean;
55
+ visibleRootIds?: readonly string[];
45
56
  act: Act;
46
57
  select(id: string): void;
47
58
  }
@@ -67,7 +78,7 @@ export declare function VectorNodeSurface({ node, width, height, vector }: {
67
78
  * The returned `toolbar` and `inspector` are ready to mount; the canvas mounts `VectorEditor`
68
79
  * with the same session inside the stage.
69
80
  */
70
- export declare function useVectorEditing({ document, selection, projection, act, select }: VectorEditingInput): VectorEditing;
81
+ export declare function useVectorEditing({ document, selection, projection, scene, geometryKey, isGeometryCurrent, visibleRootIds, act, select }: VectorEditingInput): VectorEditing;
71
82
  /**
72
83
  * Canvas overlay inside the scaled stage. With the pen tool it covers the stage and turns
73
84
  * clicks into anchors (a click on the first anchor closes the path, Enter finishes an open
@@ -1,6 +1,7 @@
1
1
  import type { DataProjection } from '../../binding/preview.js';
2
2
  import type { DesignDocument, DocumentNode } from '../../document/contracts.js';
3
3
  import { type VectorShape } from '../../document/vector.js';
4
+ import { type ProjectedDocumentNode } from './projection.js';
4
5
  export interface CanvasBox {
5
6
  x: number;
6
7
  y: number;
@@ -13,7 +14,11 @@ export interface CanvasEntry {
13
14
  topLevel: boolean;
14
15
  }
15
16
  export type DrawingTool = 'frame' | 'text' | VectorShape;
16
- export declare function canvasEntries(document: DesignDocument, projection: DataProjection | null, selected?: readonly string[], visibleRootIds?: readonly string[]): CanvasEntry[];
17
+ /** A selected definition descendant keeps its shared root visible without exposing inactive pages. */
18
+ export declare function selectedSharedRootIds(document: DesignDocument, selected: readonly string[]): readonly string[];
19
+ export declare function canvasEntries(document: DesignDocument, projection: DataProjection | null, selected?: readonly string[], visibleRootIds?: readonly string[], scene?: ProjectedDocumentNode): CanvasEntry[];
20
+ /** A mixed unavailable/preparing scene must not finalize a fit using partial bounds. */
21
+ export declare function canvasGeometryReady(scene: ProjectedDocumentNode): boolean;
17
22
  export declare function canvasBounds(entries: readonly CanvasEntry[]): CanvasBox;
18
23
  export declare function marqueeSelection(document: DesignDocument, entries: readonly CanvasEntry[], box: CanvasBox): readonly string[];
19
24
  export declare function drawingBox(start: {
@@ -1,6 +1,7 @@
1
1
  import type { DataProjection } from '../../binding/preview.js';
2
2
  import type { DesignDocument, DocumentDiagnostic, DocumentMatrix, DocumentNodeConstraints, DocumentTransaction } from '../../document/contracts.js';
3
3
  import { documentTransformedBounds } from '../../document/geometry.js';
4
+ import { type ProjectedDocumentNode } from './projection.js';
4
5
  /**
5
6
  * Pure geometry for the selection handles: which layers may be edited on the
6
7
  * canvas, how a handle drag becomes a new size and placement, how a rotation
@@ -36,6 +37,15 @@ export interface LayerGeometry extends LayerPlacement {
36
37
  readonly width: boolean;
37
38
  readonly height: boolean;
38
39
  };
40
+ /** Canonical sizes are retained even when the disposable scene derives an axis. */
41
+ readonly authoredSize?: {
42
+ readonly width: number;
43
+ readonly height: number;
44
+ };
45
+ readonly derivedAxes?: {
46
+ readonly width: boolean;
47
+ readonly height: boolean;
48
+ };
39
49
  readonly notes: readonly DocumentDiagnostic[];
40
50
  readonly constraints: DocumentNodeConstraints | undefined;
41
51
  /** Constraints only act inside a free-placement container that can itself be resized. */
@@ -95,6 +105,8 @@ export interface SnapResult {
95
105
  readonly guides: readonly SnapGuide[];
96
106
  }
97
107
  export interface SnapCandidateOptions {
108
+ /** The same disposable final scene used by the canvas, including measured text. */
109
+ readonly scene?: ProjectedDocumentNode;
98
110
  /** Ordinary root layers visible on the current page; undefined retains the complete scene. */
99
111
  readonly visibleRootIds?: readonly string[];
100
112
  /** Include the moving layers' own children: right for a resize, wrong for a move (the children travel along). */
@@ -226,6 +238,6 @@ export declare function snapMove(session: MoveSnapSession, delta: {
226
238
  * uses `resize` so child constraints apply, a placement change uses `move`, and a rotation
227
239
  * replaces the transform. Nothing is issued when the placement is unchanged.
228
240
  */
229
- export declare function applyLayerPlacement(transaction: DocumentTransaction, nodeId: string, before: LayerPlacement, after: LayerPlacement): boolean;
241
+ export declare function applyLayerPlacement(transaction: DocumentTransaction, nodeId: string, before: LayerPlacement & Pick<LayerGeometry, 'authoredSize' | 'derivedAxes' | 'resizeAxes'>, after: LayerPlacement): boolean;
230
242
  /** Commit every member of a selection gesture in the caller's transaction; true when any layer changed. */
231
243
  export declare function applySelectionPlacements(transaction: DocumentTransaction, layers: readonly LayerGeometry[], placements: readonly SelectionPlacement[]): boolean;
@@ -1,5 +1,6 @@
1
1
  import type { DataProjection } from '../../binding/preview.js';
2
2
  import type { DesignDocument, DocumentDiagnostic, DocumentEngineOptions, DocumentTransaction } from '../../document/contracts.js';
3
+ import { type ProjectedDocumentNode } from './projection.js';
3
4
  export type DocumentLayerArrangement = 'align-left' | 'align-center-x' | 'align-right' | 'align-top' | 'align-center-y' | 'align-bottom' | 'distribute-horizontal' | 'distribute-vertical';
4
5
  export interface DocumentLayerArrangementRequest {
5
6
  nodeIds: readonly string[];
@@ -7,6 +8,8 @@ export interface DocumentLayerArrangementRequest {
7
8
  }
8
9
  export interface DocumentLayerArrangementOptions extends Pick<DocumentEngineOptions, 'preflight'> {
9
10
  projection?: DataProjection | null;
11
+ scene?: ProjectedDocumentNode;
12
+ visibleRootIds?: readonly string[];
10
13
  }
11
14
  export interface ReadyDocumentLayerArrangement {
12
15
  readonly status: 'ready';
@@ -36,4 +39,4 @@ export type DocumentLayerArrangementPlan = ReadyDocumentLayerArrangement | {
36
39
  */
37
40
  export declare function planDocumentLayerArrangement(document: DesignDocument, request: DocumentLayerArrangementRequest, options?: DocumentLayerArrangementOptions): DocumentLayerArrangementPlan;
38
41
  /** Run as the only move batch in one live transaction; let validation errors roll it back. */
39
- export declare function applyDocumentLayerArrangement(transaction: DocumentTransaction, plan: ReadyDocumentLayerArrangement, currentDocument: DesignDocument, projection?: DataProjection | null): void;
42
+ export declare function applyDocumentLayerArrangement(transaction: DocumentTransaction, plan: ReadyDocumentLayerArrangement, currentDocument: DesignDocument, projection?: DataProjection | null, scene?: ProjectedDocumentNode): void;
@@ -1,6 +1,7 @@
1
1
  import type { BindingRuntimeScope } from '../../binding/contracts.js';
2
2
  import type { DataProjection } from '../../binding/preview.js';
3
- import type { DesignDocument, DocumentNode, DocumentResolveOptions } from '../../document/contracts.js';
3
+ import type { DesignDocument, DocumentDiagnostic, DocumentNode, DocumentResolveOptions } from '../../document/contracts.js';
4
+ import type { TextLayoutSnapshot } from '../../document/textLayout.js';
4
5
  export interface ProjectedDocumentNode {
5
6
  sourceNodeId: string;
6
7
  instanceId?: string;
@@ -9,6 +10,27 @@ export interface ProjectedDocumentNode {
9
10
  rowPath: BindingRuntimeScope['rowPath'];
10
11
  node: DocumentNode;
11
12
  children: ProjectedDocumentNode[];
13
+ /** Disposable measured geometry; never serialized into the authored document. */
14
+ textLayout?: ProjectedTextLayout;
12
15
  }
16
+ export interface ProjectedTextLayout {
17
+ readonly status: 'preparing' | 'ready' | 'unavailable' | 'failed';
18
+ readonly authoredSize: {
19
+ readonly width: number;
20
+ readonly height: number;
21
+ };
22
+ readonly derivedAxes: {
23
+ readonly width: boolean;
24
+ readonly height: boolean;
25
+ };
26
+ readonly diagnostics: readonly DocumentDiagnostic[];
27
+ readonly snapshot?: TextLayoutSnapshot;
28
+ /** Parent bounds may be fixed while unresolved layout changes its child placements. */
29
+ readonly childrenPending?: boolean;
30
+ }
31
+ /** Fixed parent bounds remain usable; only derived size or unresolved ancestor placement is refused. */
32
+ export declare function projectedGeometryDiagnostics(item: ProjectedDocumentNode, ancestors?: readonly ProjectedDocumentNode[]): readonly DocumentDiagnostic[];
33
+ /** Reuses the canonical layout solver on a disposable scene, including repeated index addresses. */
34
+ export declare function reflowProjectedDocumentScene(scene: ProjectedDocumentNode): ProjectedDocumentNode;
13
35
  /** Fixture rows affect this disposable scene only, never canonical document geometry. */
14
36
  export declare function projectDocumentScene(document: DesignDocument, data: DataProjection | null, resolveOptions?: DocumentResolveOptions, resolveRowOptions?: (rowPath: BindingRuntimeScope['rowPath']) => DocumentResolveOptions): ProjectedDocumentNode;
@@ -1,6 +1,7 @@
1
1
  import type { DataProjection } from '../../binding/preview.js';
2
2
  import type { DesignDocument, DocumentTransaction } from '../../document/contracts.js';
3
3
  import { type PrototypeAction, type PrototypeInteraction } from '../../document/prototype.js';
4
+ import { type ProjectedDocumentNode } from './projection.js';
4
5
  export type PrototypeActionPath = readonly (number | 'branches' | 'actions' | 'otherwise')[];
5
6
  export interface PrototypeConnectionSelection {
6
7
  nodeId: string;
@@ -35,7 +36,7 @@ export declare const connectionKey: (value: PrototypeConnectionSelection) => str
35
36
  /** Only explicit destination actions become wires. No flow or action is inferred. */
36
37
  export declare function prototypeConnections(document: DesignDocument): PrototypeConnection[];
37
38
  /** Canonical, uniquely placed layers only; projected rows and instance leaves cannot acquire shared actions accidentally. */
38
- export declare function planPrototypeWiring(document: DesignDocument, projection: DataProjection | null, selected?: readonly string[], visibleRootIds?: readonly string[]): PrototypeWiringPlan;
39
+ export declare function planPrototypeWiring(document: DesignDocument, projection: DataProjection | null, selected?: readonly string[], visibleRootIds?: readonly string[], scene?: ProjectedDocumentNode): PrototypeWiringPlan;
39
40
  /** Builds a complete detached edit before the caller opens its single history transaction. */
40
41
  export declare function preparePrototypeConnection(document: DesignDocument, sourceId: string, destinationId: string | null, selection?: PrototypeConnectionSelection, interactionId?: string): PrototypeInteraction[];
41
42
  export declare function writePrototypeConnection(transaction: DocumentTransaction, document: DesignDocument, sourceId: string, interactions: readonly PrototypeInteraction[]): void;
@@ -0,0 +1,28 @@
1
+ import type { DataProjection } from '../../binding/preview.js';
2
+ import type { DesignDocument, DocumentDiagnostic } from '../../document/contracts.js';
3
+ import { type ProjectedDocumentNode, type ProjectedTextLayout } from './projection.js';
4
+ import type { TextLayoutRuntime } from './textLayoutRuntime.js';
5
+ export interface TextLayoutSceneOptions {
6
+ readonly scene: ProjectedDocumentNode;
7
+ readonly revisionKey: string;
8
+ readonly visibleRootIds?: readonly string[];
9
+ readonly projection?: DataProjection | null;
10
+ readonly sourceMapped?: boolean;
11
+ }
12
+ export interface TextLayoutScene {
13
+ readonly scene: ProjectedDocumentNode;
14
+ readonly status: ProjectedTextLayout['status'];
15
+ readonly diagnostics: readonly DocumentDiagnostic[];
16
+ }
17
+ /** Carries unresolved derived axes to ancestors before any asynchronous work starts. */
18
+ export declare function prepareTextLayoutScene(document: DesignDocument, options: TextLayoutSceneOptions, available?: boolean): TextLayoutScene;
19
+ /** One bounded disposable layout, shared by rendering and every geometry reader. */
20
+ export declare function measureTextLayoutScene(document: DesignDocument, options: TextLayoutSceneOptions & {
21
+ runtime: TextLayoutRuntime;
22
+ signal?: AbortSignal;
23
+ retry?: boolean;
24
+ }): Promise<TextLayoutScene>;
25
+ /** Position-only candidate validation. The caller must also retain the original scene lifetime guard. */
26
+ export declare function reuseTextLayoutScene(document: DesignDocument, options: TextLayoutSceneOptions & {
27
+ measuredScene: ProjectedDocumentNode;
28
+ }): TextLayoutScene;
@@ -0,0 +1,19 @@
1
+ import type { DocumentEngine } from '../../document/contracts.js';
2
+ import { type TextLayoutScene, type TextLayoutSceneOptions } from './textLayoutProjection.js';
3
+ import type { TextLayoutRuntime } from './textLayoutRuntime.js';
4
+ export interface UseTextLayoutOptions extends TextLayoutSceneOptions {
5
+ readonly engine: DocumentEngine;
6
+ readonly runtime?: TextLayoutRuntime | null;
7
+ readonly lifetimeKey: string;
8
+ /** Fires synchronously for target, mode, page or provider transitions, including batched round trips. */
9
+ readonly subscribeLifetime?: (invalidate: () => void) => () => void;
10
+ readonly ownerDocument?: Document;
11
+ }
12
+ export interface TextLayoutState extends TextLayoutScene {
13
+ readonly geometryKey: string;
14
+ /** Capture this function at gesture start; a later render cannot revive that geometry. */
15
+ readonly isCurrent: () => boolean;
16
+ readonly retry: () => void;
17
+ }
18
+ /** One subscription owns the disposable scene and its synchronous invalidation epoch. */
19
+ export declare function useTextLayout(options: UseTextLayoutOptions): TextLayoutState;
@@ -1,8 +1,8 @@
1
1
  import type { DataProjection } from '../../binding/preview.js';
2
2
  import type { DesignDocument, DocumentDiagnostic, DocumentMatrix, DocumentNode, DocumentNodePatch, DocumentTransaction } from '../../document/contracts.js';
3
3
  import { booleanVectorPrecision, type VectorAnchor, type VectorAnchorAddress, type VectorBooleanOperation, type VectorFillRule, type VectorPoint, type VectorProperties, type VectorShape, type VectorStroke } from '../../document/vector.js';
4
- import { type LayerGeometry } from './geometryHandles.js';
5
- import type { ProjectedDocumentNode } from './projection.js';
4
+ import { type LayerGeometry, type SnapCandidateOptions } from './geometryHandles.js';
5
+ import { type ProjectedDocumentNode } from './projection.js';
6
6
  /**
7
7
  * Pure editing model for `vector` layers. The document stores path data under
8
8
  * `node.properties.vector` in the layer's own space; the layer box is the geometry's
@@ -91,7 +91,9 @@ export declare function vectorGeometryPatch(node: DocumentNode, next: VectorProp
91
91
  /** Changes paint and corner keys without touching geometry; an `undefined` value removes the key. */
92
92
  export declare function vectorStylePatch(node: DocumentNode, style: Partial<VectorStyle>): DocumentNodePatch;
93
93
  /** Canvas placement of a layer: the world transform with the root's own transform removed, as the canvas renders it. */
94
- export declare function renderedWorldTransform(document: DesignDocument, nodeId: string): DocumentMatrix;
94
+ export declare function renderedWorldTransform(document: DesignDocument, nodeId: string, options?: SnapCandidateOptions & {
95
+ projection?: DataProjection | null;
96
+ }): DocumentMatrix;
95
97
  /** New layers join the selected container, or the root; the rule matches text insertion. */
96
98
  export declare function vectorInsertParent(document: DesignDocument, selection: readonly string[]): string;
97
99
  /** A default-sized shape placed inside the parent, offset by the number of existing children so repeated inserts stay visible. */
@@ -105,13 +107,15 @@ export declare function penPathNode(points: readonly VectorAnchor[], closed: boo
105
107
  * selection handles use, so an auto layout child, a source layout fragment, or a repeated
106
108
  * row is refused with the same diagnostic instead of a guessed box.
107
109
  */
108
- export declare function planVectorEdit(document: DesignDocument, selection: readonly string[], projection: DataProjection | null): VectorEditPlan;
110
+ export declare function planVectorEdit(document: DesignDocument, selection: readonly string[], projection: DataProjection | null, options?: SnapCandidateOptions): VectorEditPlan;
109
111
  /** Anchor operations the current anchor selection allows. */
110
112
  export declare function vectorAnchorActions(vector: VectorProperties, anchors: readonly VectorAnchorAddress[]): VectorAnchorActions;
111
113
  /** Applies one anchor action to the box geometry; the caller commits the result as one transaction. */
112
114
  export declare function applyVectorAnchorAction(vector: VectorProperties, anchors: readonly VectorAnchorAddress[], action: VectorAnchorAction): VectorAnchorActionResult;
113
115
  /** Two vector layers sharing a parent; the lower layer (earlier in the parent order) is the base of a subtraction. */
114
- export declare function planVectorBoolean(document: DesignDocument, selection: readonly string[]): VectorBooleanPlan;
116
+ export declare function planVectorBoolean(document: DesignDocument, selection: readonly string[], options?: SnapCandidateOptions & {
117
+ projection?: DataProjection | null;
118
+ }): VectorBooleanPlan;
115
119
  /** The combined layer, in the parent's space, with the lower layer's paint. Throws when the result has no shape. */
116
120
  export declare function vectorBooleanNode(plan: Extract<VectorBooleanPlan, {
117
121
  status: 'ready';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pygmalionjs/pygmalion",
3
- "version": "0.18.0",
3
+ "version": "0.19.0",
4
4
  "description": "Code-backed DOM design sandbox and visual QA editor",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {