@pygmalionjs/pygmalion 0.5.14 → 0.5.16

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.
Files changed (112) hide show
  1. package/dist-lib/{FrozenRoutePreview-BR5CBAD3.js → FrozenRoutePreview-CZOpvN6z.js} +1545 -1515
  2. package/dist-lib/pygmalion.js +5034 -4955
  3. package/dist-lib/testing.js +1 -1
  4. package/dist-lib/types/App.d.ts +5 -0
  5. package/dist-lib/types/canvas/CameraLayer.d.ts +9 -0
  6. package/dist-lib/types/canvas/Canvas.d.ts +19 -0
  7. package/dist-lib/types/canvas/FrameLabelBanner.d.ts +7 -0
  8. package/dist-lib/types/canvas/FrameView.d.ts +9 -0
  9. package/dist-lib/types/canvas/FrozenRoutePreview.d.ts +12 -0
  10. package/dist-lib/types/canvas/InspectOverlay.d.ts +10 -0
  11. package/dist-lib/types/canvas/LightweightCanvas.d.ts +10 -0
  12. package/dist-lib/types/canvas/ObjectControls.d.ts +22 -0
  13. package/dist-lib/types/canvas/Preview.d.ts +3 -0
  14. package/dist-lib/types/canvas/SectionBoxes.d.ts +24 -0
  15. package/dist-lib/types/canvas/ShadowRoutePreview.d.ts +14 -0
  16. package/dist-lib/types/canvas/StoryboardConnections.d.ts +31 -0
  17. package/dist-lib/types/canvas/cameraPlacement.d.ts +45 -0
  18. package/dist-lib/types/canvas/domTags.d.ts +10 -0
  19. package/dist-lib/types/canvas/layoutContext.d.ts +9 -0
  20. package/dist-lib/types/canvas/useFlowSession.d.ts +36 -0
  21. package/dist-lib/types/canvas/useFrameLod.d.ts +35 -0
  22. package/dist-lib/types/editor/adaptiveFrameLayout.d.ts +67 -0
  23. package/dist-lib/types/editor/assetEditing.d.ts +10 -0
  24. package/dist-lib/types/editor/bannerStyle.d.ts +18 -0
  25. package/dist-lib/types/editor/catalog.d.ts +101 -0
  26. package/dist-lib/types/editor/codegen.d.ts +11 -0
  27. package/dist-lib/types/editor/componentConnections.d.ts +63 -0
  28. package/dist-lib/types/editor/componentInstances.d.ts +27 -0
  29. package/dist-lib/types/editor/contentBounds.d.ts +34 -0
  30. package/dist-lib/types/editor/designCompiler.d.ts +100 -0
  31. package/dist-lib/types/editor/designImport.d.ts +448 -0
  32. package/dist-lib/types/editor/documentSync.d.ts +28 -0
  33. package/dist-lib/types/editor/domImport.d.ts +58 -0
  34. package/dist-lib/types/editor/editModePolicy.d.ts +17 -0
  35. package/dist-lib/types/editor/fiberMap.d.ts +16 -0
  36. package/dist-lib/types/editor/flowSessionScheduler.d.ts +97 -0
  37. package/dist-lib/types/editor/flowSessions.d.ts +137 -0
  38. package/dist-lib/types/editor/frameHeight.d.ts +14 -0
  39. package/dist-lib/types/editor/frameIdentity.d.ts +9 -0
  40. package/dist-lib/types/editor/frameLabels.d.ts +124 -0
  41. package/dist-lib/types/editor/frameLanes.d.ts +62 -0
  42. package/dist-lib/types/editor/frameLod.d.ts +123 -0
  43. package/dist-lib/types/editor/frameLodRuntime.d.ts +64 -0
  44. package/dist-lib/types/editor/framePointerHit.d.ts +67 -0
  45. package/dist-lib/types/editor/framePointerIntent.d.ts +53 -0
  46. package/dist-lib/types/editor/framePreviewChannels.d.ts +26 -0
  47. package/dist-lib/types/editor/framePreviewKeys.d.ts +21 -0
  48. package/dist-lib/types/editor/frameWheelRouting.d.ts +16 -0
  49. package/dist-lib/types/editor/frozenImport.d.ts +70 -0
  50. package/dist-lib/types/editor/host.d.ts +133 -0
  51. package/dist-lib/types/editor/inspect.d.ts +225 -0
  52. package/dist-lib/types/editor/interactiveStates.d.ts +103 -0
  53. package/dist-lib/types/editor/livePreviewInstances.d.ts +93 -0
  54. package/dist-lib/types/editor/liveScreens.d.ts +20 -0
  55. package/dist-lib/types/editor/nodeSelector.d.ts +20 -0
  56. package/dist-lib/types/editor/previewBootstrap.d.ts +189 -0
  57. package/dist-lib/types/editor/previewEnvironmentControls.d.ts +33 -0
  58. package/dist-lib/types/editor/previewHydration.d.ts +5 -0
  59. package/dist-lib/types/editor/previewIntent.d.ts +17 -0
  60. package/dist-lib/types/editor/previewSweep.d.ts +129 -0
  61. package/dist-lib/types/editor/previewWarmup.d.ts +77 -0
  62. package/dist-lib/types/editor/projectBootGate.d.ts +45 -0
  63. package/dist-lib/types/editor/projectRuntime.d.ts +138 -0
  64. package/dist-lib/types/editor/registry.d.ts +38 -0
  65. package/dist-lib/types/editor/routePreview.d.ts +285 -0
  66. package/dist-lib/types/editor/routePreviewArtifactV2.d.ts +34 -0
  67. package/dist-lib/types/editor/routePreviewArtifactV3.d.ts +64 -0
  68. package/dist-lib/types/editor/routePreviewPlacement.d.ts +9 -0
  69. package/dist-lib/types/editor/routePreviewStatus.d.ts +48 -0
  70. package/dist-lib/types/editor/scenarioCoverage.d.ts +167 -0
  71. package/dist-lib/types/editor/screenCards.d.ts +101 -0
  72. package/dist-lib/types/editor/screenDimensions.d.ts +63 -0
  73. package/dist-lib/types/editor/screenFlows.d.ts +47 -0
  74. package/dist-lib/types/editor/screenInteractions.d.ts +4 -0
  75. package/dist-lib/types/editor/screenLists.d.ts +40 -0
  76. package/dist-lib/types/editor/screenStateGroups.d.ts +36 -0
  77. package/dist-lib/types/editor/screenshotBitmaps.d.ts +20 -0
  78. package/dist-lib/types/editor/sectionHeaders.d.ts +117 -0
  79. package/dist-lib/types/editor/shadowPreview.d.ts +103 -0
  80. package/dist-lib/types/editor/sharedSource.d.ts +40 -0
  81. package/dist-lib/types/editor/sourceJournal.d.ts +27 -0
  82. package/dist-lib/types/editor/store.d.ts +838 -0
  83. package/dist-lib/types/editor/storyboardComposition.d.ts +116 -0
  84. package/dist-lib/types/editor/storyboardDiscovery.d.ts +105 -0
  85. package/dist-lib/types/editor/storyboardEnvironment.d.ts +22 -0
  86. package/dist-lib/types/editor/storyboardGraph.d.ts +120 -0
  87. package/dist-lib/types/editor/storyboardGraphRuntime.d.ts +12 -0
  88. package/dist-lib/types/editor/storyboardGraphView.d.ts +104 -0
  89. package/dist-lib/types/editor/surfaceDemands.d.ts +138 -0
  90. package/dist-lib/types/editor/tokens.d.ts +26 -0
  91. package/dist-lib/types/editor/useObserved.d.ts +1 -0
  92. package/dist-lib/types/editor/viewportPresets.d.ts +21 -0
  93. package/dist-lib/types/editor/visualQa.d.ts +50 -0
  94. package/dist-lib/types/lib.d.ts +365 -0
  95. package/dist-lib/types/shell/ApplyPanel.d.ts +1 -0
  96. package/dist-lib/types/shell/AssetsPanel.d.ts +3 -0
  97. package/dist-lib/types/shell/CanvasStatusProbe.d.ts +5 -0
  98. package/dist-lib/types/shell/CodePanel.d.ts +1 -0
  99. package/dist-lib/types/shell/ComponentStateControls.d.ts +108 -0
  100. package/dist-lib/types/shell/ContextMenu.d.ts +1 -0
  101. package/dist-lib/types/shell/LayerTree.d.ts +7 -0
  102. package/dist-lib/types/shell/PropsPanel.d.ts +1 -0
  103. package/dist-lib/types/shell/StoryboardGraphPanel.d.ts +23 -0
  104. package/dist-lib/types/shell/ZoomIndicator.d.ts +4 -0
  105. package/dist-lib/types/shell/qaPresentation.d.ts +9 -0
  106. package/dist-lib/types/testing.d.ts +8 -0
  107. package/dist-lib/types/ui/SourceRefControl.d.ts +38 -0
  108. package/dist-lib/types/ui/icons.d.ts +30 -0
  109. package/node/dev-mirror.mjs +63 -17
  110. package/package.json +7 -8
  111. package/testing.d.ts +0 -26
  112. package/types.d.ts +0 -2675
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Which frame the pointer is over, computed from geometry rather than hit testing.
3
+ *
4
+ * The canvas camera layer turns off hit testing unless the select tool is active,
5
+ * so a canvas tool can drag across frame content. That also means a frame never
6
+ * sees a real pointer event in those modes — and hover is exactly when preparing
7
+ * the next frame pays off. The canvas surface still owns the pointer, so the frame
8
+ * under it is resolved from the camera transform and the frame boxes instead.
9
+ */
10
+ export interface FrameBox {
11
+ frameId: string;
12
+ x: number;
13
+ y: number;
14
+ width: number;
15
+ height: number;
16
+ }
17
+ export interface CanvasCamera {
18
+ panX: number;
19
+ panY: number;
20
+ zoom: number;
21
+ }
22
+ export interface ClientRectLike {
23
+ left: number;
24
+ top: number;
25
+ }
26
+ /** Converts a client point into canvas coordinates. Mirrors the marquee math in the canvas surface. */
27
+ export declare function canvasPointFromClient(client: {
28
+ clientX: number;
29
+ clientY: number;
30
+ }, rect: ClientRectLike, camera: CanvasCamera): {
31
+ x: number;
32
+ y: number;
33
+ } | null;
34
+ /**
35
+ * Returns the frame containing a canvas point, or null.
36
+ *
37
+ * Later frames win, matching paint order: a frame drawn on top of another is the
38
+ * one the designer is pointing at.
39
+ */
40
+ export declare function frameAtCanvasPoint(frames: readonly FrameBox[], point: {
41
+ x: number;
42
+ y: number;
43
+ } | null): string | null;
44
+ export type FrameHoverTransition = {
45
+ action: 'idle';
46
+ } | {
47
+ action: 'restart';
48
+ frameId: string;
49
+ } | {
50
+ action: 'clear';
51
+ };
52
+ /**
53
+ * Decides what a pointer move does to the pending dwell.
54
+ *
55
+ * Leaving a frame forgets it, which is what makes returning to it start over. If
56
+ * the frame were remembered, a pointer that left before the dwell elapsed and came
57
+ * back would look like it had never moved, and that frame would never be prepared.
58
+ */
59
+ export declare function resolveFrameHoverTransition(previousFrameId: string | null, frameId: string | null): FrameHoverTransition;
60
+ /**
61
+ * Reports whether the canvas surface has to resolve hover itself.
62
+ *
63
+ * With the select tool the frames receive real pointer events, so the frame's own
64
+ * hover path already noted the intent; resolving it again from the surface would
65
+ * note the same frame twice.
66
+ */
67
+ export declare function canvasOwnsFrameHover(editMode: boolean, tool: string): boolean;
@@ -0,0 +1,53 @@
1
+ export type FramePointerIntent = 'select-frame' | 'delegate-to-layer' | 'delegate-to-canvas';
2
+ export type ImportedRouteSurface = 'editable-layers' | 'responsive-preview';
3
+ /**
4
+ * The first pointer press on an inactive frame selects the frame shell only.
5
+ * A later press may reach its editable DOM layers. Canvas tools always retain
6
+ * ownership of the pointer so panning and section operations remain available.
7
+ */
8
+ export declare function resolveFramePointerIntent(active: boolean, tool: string): FramePointerIntent;
9
+ /**
10
+ * Imported route layers stay interactive while the frame shell is selected.
11
+ * The frozen responsive preview covers every window in which the captured
12
+ * layer geometry cannot follow the frame's viewport: a resize gesture in
13
+ * progress, and a committed size change whose re-import has not landed yet.
14
+ */
15
+ export declare function resolveImportedRouteSurface(snapshotAvailable: boolean, sizeTransitionActive: boolean): ImportedRouteSurface;
16
+ /**
17
+ * True while a frame's viewport is moving or has moved away from the width
18
+ * its layers were imported at. Imported layer geometry is only valid at its
19
+ * import width — rendering it at another width overlaps and collides. A
20
+ * viewport preset click commits a resize with no drag gesture; the frozen
21
+ * replay covers the frame until the provisional re-import lands at the new
22
+ * width. An edited tree schedules no re-import (edits win), so it settles
23
+ * back to its editable layers immediately.
24
+ */
25
+ export declare function frameSizeTransitionPending({ resizeDraftActive, importedAtCommittedWidth, reimportScheduled, }: {
26
+ /** A resize drag gesture is in progress. */
27
+ resizeDraftActive: boolean;
28
+ /** The committed width equals the width the layers were imported at. */
29
+ importedAtCommittedWidth: boolean;
30
+ /** A provisional re-import is scheduled for the committed size. */
31
+ reimportScheduled: boolean;
32
+ }): boolean;
33
+ /**
34
+ * The whole activating gesture belongs to frame selection, not just its
35
+ * mousedown. Activation imports the frozen preview synchronously (the D2
36
+ * contract in docs/perf-contracts.md), so by the time the browser dispatches
37
+ * the gesture's trailing `click`, an interactive imported tree already sits
38
+ * under the pointer — and a design-surface selection click must never reach
39
+ * application handlers (it navigated the host app's router when it did).
40
+ *
41
+ * The gate arms on the select-frame mousedown, consumes exactly one trailing
42
+ * click, and releases when the gesture is over — releasing also covers the
43
+ * click that never comes (press, drag off the frame, release elsewhere).
44
+ */
45
+ export interface FrameActivationClickGate {
46
+ /** Arm on the select-frame mousedown that activates the frame. */
47
+ arm(): void;
48
+ /** The gesture ended without a suppressible click — disarm. */
49
+ release(): void;
50
+ /** True exactly once for the click belonging to the arming gesture. */
51
+ consume(): boolean;
52
+ }
53
+ export declare function createFrameActivationClickGate(): FrameActivationClickGate;
@@ -0,0 +1,26 @@
1
+ /** Channels that stay global: they change rarely and invalidate every frame. */
2
+ export declare function useGlobalPreviewChannels(): {
3
+ appOrigin: string;
4
+ previewRevision: string;
5
+ environmentControlRevision: number;
6
+ };
7
+ /**
8
+ * Channels scoped to one frame. Artifact events arrive under two key spaces —
9
+ * the recipe cache key and the frame identity — so both are subscribed; a
10
+ * whole-store event bumps an epoch inside every version getter. cacheHydrated
11
+ * composes the canvas-wide prehydration flag with this frame's own keys and is
12
+ * kept fresh by the per-key snapshot subscription.
13
+ */
14
+ export declare function useFrameKeyChannels(keys: {
15
+ pageId: string;
16
+ routePreviewKey: string;
17
+ authoredRoutePreviewKey: string;
18
+ canonicalId: string;
19
+ fingerprint: string | null;
20
+ /** The batched prehydration flag; defaults to false until the caller threads it. */
21
+ batchHydrated?: boolean;
22
+ }): {
23
+ artifactRevision: number;
24
+ previewIntended: boolean;
25
+ cacheHydrated: boolean;
26
+ };
@@ -0,0 +1,21 @@
1
+ import { type PageModel } from './store';
2
+ /**
3
+ * The preview environment of one page: its own declared environment, plus the
4
+ * host's preview-environment override when the page is the active one.
5
+ *
6
+ * `active` matters for reactivity, not just for the merge. The default reads
7
+ * `editor.activePageId`, and inside a MobX observer render that read
8
+ * subscribes the component to every selection change — which is how a single
9
+ * click used to re-render all 79 frames. A caller that already knows whether
10
+ * its page is active (FrameView receives it as a prop) must pass `active`
11
+ * explicitly so its render never touches the selection observable.
12
+ */
13
+ export declare function pagePreviewEnvironment(page: PageModel, active?: boolean): import("./designImport").StoryboardEnvironment | undefined;
14
+ /**
15
+ * The recipe cache key of one page. `active` is forwarded to
16
+ * pagePreviewEnvironment — see its note on selection reactivity.
17
+ */
18
+ export declare function routePreviewCacheKey(page: PageModel, previewRevision: string, viewport?: {
19
+ width: number;
20
+ height: number;
21
+ }, active?: boolean): string;
@@ -0,0 +1,16 @@
1
+ export type FrameWheelRoute = 'canvas' | 'native-preview' | 'programmatic-preview';
2
+ export interface ScrollMetrics {
3
+ scrollLeft: number;
4
+ scrollTop: number;
5
+ scrollWidth: number;
6
+ scrollHeight: number;
7
+ clientWidth: number;
8
+ clientHeight: number;
9
+ }
10
+ export declare function canConsumeWheelDelta(metrics: ScrollMetrics, deltaX: number, deltaY: number): boolean;
11
+ /**
12
+ * Keeps a wheel gesture inside an active frame while its rendered DOM can
13
+ * consume the requested delta. Once the inner scroller reaches its edge, the
14
+ * same gesture falls back to the infinite canvas.
15
+ */
16
+ export declare function routeFrameWheel(event: WheelEvent): FrameWheelRoute;
@@ -0,0 +1,70 @@
1
+ import type { DomImportOptions, DomImportResult } from './domImport';
2
+ import type { InstanceResolver } from './fiberMap';
3
+ import type { ShadowPreviewHandle } from './shadowPreview';
4
+ /** Reads Track-D stamped attributes back into the fiberMap InstanceHit shape. */
5
+ export declare function createStampedInstanceResolver(): InstanceResolver;
6
+ /**
7
+ * `file#localName` CSS-module source of a frozen-preview element. The stamped
8
+ * attribute wins; the sourceTargetOf fallback reads __PYG_CSS_MODULES__ from
9
+ * the element's own window, which is usually absent in the editor realm — a
10
+ * harmless miss that yields ''.
11
+ */
12
+ export declare function resolveStampedSourceStyle(el: Element): string;
13
+ /** True when the document carries the Track-D body marker — unstamped frozen previews keep the boot path. */
14
+ export declare function isStampedFrozenPreview(root: ParentNode): boolean;
15
+ export type ShadowPreviewImportOptions = Omit<DomImportOptions, 'resolveInstance' | 'resolveSourceStyle'>;
16
+ /**
17
+ * Whether a not-yet-mounted snapshot would support the D2 promotion once
18
+ * mounted — the string-level counterpart of `isStampedFrozenPreview`, used to
19
+ * decide surfaces before paying for the mount (a hover should not warm-boot
20
+ * the live pipeline when the frozen preview can deliver the editable tree).
21
+ */
22
+ export declare function frozenSnapshotStamped(input: {
23
+ bodyAttributes?: string | null;
24
+ snapshotHtml?: string | null;
25
+ }): boolean;
26
+ /**
27
+ * Imports the mounted frozen preview under `handle` as a layer tree, or null
28
+ * when the promotion cannot produce a faithful result (torn-down handle,
29
+ * unstamped snapshot, skipped rendering, or no design-import controller). The
30
+ * controller supplies the same layer options the live captureIframeWhenStable
31
+ * import uses, so the provisional tree matches what the live swap delivers.
32
+ */
33
+ /**
34
+ * The minimum plausible import size for a replay of `sourceElements`
35
+ * elements. An import far below the floor means the replay was measured in
36
+ * a broken state (styles missing, half torn down) — committing it would pin
37
+ * a near-empty tree as final, so the promotion refuses and retries when the
38
+ * next ready mount registers. Tiny sources import as-is: a floor there would
39
+ * only reject legitimate minimal screens.
40
+ */
41
+ export declare function importCountFloor(sourceElements: number): number;
42
+ /**
43
+ * Element-count magnitude of a serialized capture, for cross-source
44
+ * plausibility checks: a live import of a screen whose verified capture
45
+ * holds hundreds of elements cannot plausibly be a handful of divs — that is
46
+ * a half-booted app shell (dead backend, unfinished replay), not the screen.
47
+ * Counts opening tags; the floor only needs the order of magnitude.
48
+ */
49
+ export declare function countMarkupElements(markup: string | null | undefined, limit?: number): number;
50
+ export declare function importDomFromShadowPreview(handle: ShadowPreviewHandle, options?: ShadowPreviewImportOptions): DomImportResult | null;
51
+ export interface LiveImportSwapInput {
52
+ /** True when the page tree changed after the provisional frozen import. */
53
+ editedSinceImport: boolean;
54
+ }
55
+ /**
56
+ * Decides whether an arriving live-import result may replace a provisional
57
+ * frozen import. Edits win: a user tree is never clobbered by the background
58
+ * boot — the existing stale affordance covers manual refresh instead.
59
+ */
60
+ export declare function shouldSwapLiveImport(input: LiveImportSwapInput): boolean;
61
+ /**
62
+ * Registers the live mount handle for a page. The returned cleanup removes
63
+ * exactly this registration, so a newer mount is never clobbered by a stale
64
+ * teardown.
65
+ */
66
+ export declare function registerMountedShadowPreview(pageId: string, handle: ShadowPreviewHandle, options?: {
67
+ stale?: boolean;
68
+ }): () => void;
69
+ /** The mounted handle for a page, or null when none is mounted or the mounted preview is stale. */
70
+ export declare function getMountedShadowPreviewHandle(pageId: string): ShadowPreviewHandle | null;
@@ -0,0 +1,133 @@
1
+ import type { InspectApplyPayload } from './inspect';
2
+ import type { DesignImportKind } from './designImport';
3
+ import type { InspectQaResult } from './visualQa';
4
+ export interface ApplyPayload {
5
+ tokens: {
6
+ name: string;
7
+ value: string;
8
+ }[];
9
+ pages: {
10
+ id: string;
11
+ name: string;
12
+ path: string;
13
+ width: number;
14
+ height: number;
15
+ canvas: string;
16
+ section?: string;
17
+ jsx: string;
18
+ }[];
19
+ }
20
+ /** Result returned after the host applies inspected source changes. */
21
+ export interface InspectApplyResult {
22
+ applied: number;
23
+ /** Modification session branch created by the host. */
24
+ branch?: string;
25
+ /** Result of merging with latest development code. */
26
+ integration?: 'up_to_date' | 'auto_merged' | 'review_required' | 'conflict' | 'offline';
27
+ /** Text of application results to show to the designer. */
28
+ message?: string;
29
+ /** Comparison of DOM·PNG recapture of the impact screen immediately after application. */
30
+ qa?: InspectQaResult;
31
+ }
32
+ export interface InspectPreviewResult {
33
+ revision: number;
34
+ files: {
35
+ file: string;
36
+ diff: string;
37
+ }[];
38
+ affectedFiles: string[];
39
+ /** Based on comparison of impact screens captured in current revision. */
40
+ qa?: InspectQaResult;
41
+ }
42
+ export interface InspectImpactResult {
43
+ files: string[];
44
+ }
45
+ /**
46
+ * Unit of code edited on the canvas.
47
+ * The save UI is not divided according to asset type. icon/atom/component/screen are all
48
+ * It is the same JSX document, and the only difference is that the token is a value document, leaving the transport payload.
49
+ */
50
+ export interface DesignCodeDocument {
51
+ type: 'document';
52
+ id: string;
53
+ kind: DesignImportKind;
54
+ name: string;
55
+ canvas: string;
56
+ section?: string;
57
+ path?: string;
58
+ route?: string;
59
+ width: number;
60
+ height: number;
61
+ assetIds: string[];
62
+ sourcePaths: string[];
63
+ jsx: string;
64
+ }
65
+ export interface DesignTokenDocument {
66
+ type: 'token';
67
+ id: string;
68
+ kind: 'design-tokens';
69
+ name: string;
70
+ value: string;
71
+ }
72
+ export type DesignElementDocument = DesignCodeDocument | DesignTokenDocument;
73
+ export interface DesignElementChange {
74
+ operation: 'upsert' | 'delete';
75
+ element: DesignElementDocument;
76
+ }
77
+ /** Successive edits of one element are combined into one final state and delivered to the host. */
78
+ export interface DesignChangePayload {
79
+ revision: number;
80
+ changes: DesignElementChange[];
81
+ }
82
+ export interface DesignChangeResult {
83
+ saved: number;
84
+ files?: string[];
85
+ message?: string;
86
+ }
87
+ export declare function setAppOrigin(origin: string): void;
88
+ export declare function getAppOrigin(): string;
89
+ export declare function subscribeAppOrigin(listener: () => void): () => void;
90
+ export declare function setArtifactOrigin(origin: string): void;
91
+ /**
92
+ * Origin a captured snapshot resolves its relative assets against.
93
+ *
94
+ * This is not the same question as "where does the live screen run". A capture is
95
+ * already rendered — it needs somewhere to fetch the images and fonts its markup
96
+ * still points at — while a live frame needs the checkout of a specific revision.
97
+ * Answering both with one value tied the catalog to a checkout that takes minutes
98
+ * to build, so opening the editor showed a spinner instead of the frames sitting
99
+ * on disk.
100
+ *
101
+ * The order is most-accurate-first: an origin the host declared, then the live
102
+ * one once a runtime exists, then the editor's own — which serves the same
103
+ * application and lets the catalog paint immediately. Assets it cannot resolve
104
+ * are the ones the working tree no longer has; the live origin replaces them the
105
+ * moment it comes up, because these readers re-run when it does.
106
+ */
107
+ export declare function getArtifactOrigin(): string;
108
+ export declare function subscribeArtifactOrigin(listener: () => void): () => void;
109
+ /** Baseline code version of the preview (dev SHA, etc.). When a change is made, a new static screen cache of the same URL is also created. */
110
+ export declare function setPreviewRevision(revision: string): void;
111
+ export declare function getPreviewRevision(): string;
112
+ export declare function subscribePreviewRevision(listener: () => void): () => void;
113
+ export declare function setFlowCanvas(canvas: string): void;
114
+ export declare function getFlowCanvas(): string;
115
+ export declare function setStaticFrameSurface(surface: 'bitmap' | 'dom'): void;
116
+ export declare function getStaticFrameSurface(): 'bitmap' | 'dom';
117
+ export declare function setOnApply(cb: ((payload: ApplyPayload) => Promise<{
118
+ branch: string;
119
+ } | void>) | null): void;
120
+ export declare function getOnApply(): ((payload: ApplyPayload) => Promise<{
121
+ branch: string;
122
+ } | void>) | null;
123
+ export declare function setOnInspectApply(cb: ((payload: InspectApplyPayload) => Promise<InspectApplyResult | void>) | null): void;
124
+ export declare function getOnInspectApply(): ((payload: InspectApplyPayload) => Promise<InspectApplyResult | void>) | null;
125
+ export declare function setOnInspectPreview(cb: ((payload: InspectApplyPayload) => Promise<InspectPreviewResult>) | null): void;
126
+ export declare function getOnInspectPreview(): ((payload: InspectApplyPayload) => Promise<InspectPreviewResult>) | null;
127
+ export declare function setOnInspectImpact(cb: ((componentFiles: string[]) => Promise<InspectImpactResult>) | null): void;
128
+ export declare function getOnInspectImpact(): ((componentFiles: string[]) => Promise<InspectImpactResult>) | null;
129
+ export declare function setOnDesignChange(cb: ((payload: DesignChangePayload) => Promise<DesignChangeResult | void>) | null): void;
130
+ export declare function getOnDesignChange(): ((payload: DesignChangePayload) => Promise<DesignChangeResult | void>) | null;
131
+ /** ▶ Synchronize the preview open status with the host router. */
132
+ export declare function setOnPreviewOpenChange(cb: ((open: boolean) => void) | null): void;
133
+ export declare function getOnPreviewOpenChange(): ((open: boolean) => void) | null;
@@ -0,0 +1,225 @@
1
+ /**
2
+ * css module source mapping — host vite plugin (pygmalion-inspect-plugin)
3
+ * window.__PYG_CSS_MODULES__ Derived from registration stacked in an array (scope class → scss file/local name).
4
+ */
5
+ export interface SourceTarget {
6
+ /** .module.scss path (relative to host project root). */
7
+ file: string;
8
+ /** The component file that imported the scss (text write-back target). */
9
+ componentFile: string;
10
+ /** Local class name (e.g. row). */
11
+ localName: string;
12
+ }
13
+ /** Source mapping to the element's first css module class — null if not present (live-only editing). */
14
+ export declare function sourceTargetOf(el: Element): SourceTarget | null;
15
+ /** Target file for text write-back — componentFile of the first css module mapping class of itself/ancestor. */
16
+ export declare function nearestComponentFile(el: Element): string | null;
17
+ /** A safe structured representation of `componentFile|sourceStart|elementName` that the Vite transform injects into the DOM. */
18
+ export interface SourceIdentity {
19
+ componentFile: string;
20
+ sourceStart: number;
21
+ elementName: string;
22
+ }
23
+ export interface SourceAffectedFrame {
24
+ id: string;
25
+ name: string;
26
+ }
27
+ export type SourceEditScope = 'instance' | 'shared-source';
28
+ export type PrimitiveSourceValue = string | number | boolean;
29
+ export type PrimitiveSourceValueType = 'string' | 'number' | 'boolean';
30
+ export interface SourceInsertComponent {
31
+ name: string;
32
+ importPath: string;
33
+ importKind: 'named';
34
+ props: Record<string, PrimitiveSourceValue>;
35
+ children?: string;
36
+ }
37
+ export type SourceEditOperation = {
38
+ kind: 'prop';
39
+ identity: SourceIdentity;
40
+ prop: string;
41
+ from: PrimitiveSourceValue;
42
+ to: PrimitiveSourceValue;
43
+ valueType: PrimitiveSourceValueType;
44
+ scope: SourceEditScope;
45
+ affectedFrames: SourceAffectedFrame[];
46
+ } | {
47
+ kind: 'text';
48
+ identity: SourceIdentity;
49
+ from: string;
50
+ to: string;
51
+ scope: SourceEditScope;
52
+ affectedFrames: SourceAffectedFrame[];
53
+ } | {
54
+ kind: 'insert';
55
+ mode: 'clone';
56
+ identity: SourceIdentity;
57
+ fromIndex: number;
58
+ toIndex: number;
59
+ scope: SourceEditScope;
60
+ affectedFrames: SourceAffectedFrame[];
61
+ } | {
62
+ kind: 'insert';
63
+ mode: 'component';
64
+ identity: SourceIdentity;
65
+ slot: 'children';
66
+ toIndex: number;
67
+ component: SourceInsertComponent;
68
+ scope: SourceEditScope;
69
+ affectedFrames: SourceAffectedFrame[];
70
+ } | {
71
+ kind: 'remove';
72
+ identity: SourceIdentity;
73
+ fromIndex: number;
74
+ scope: SourceEditScope;
75
+ affectedFrames: SourceAffectedFrame[];
76
+ } | {
77
+ kind: 'move';
78
+ identity: SourceIdentity;
79
+ fromIndex: number;
80
+ toIndex: number;
81
+ scope: SourceEditScope;
82
+ affectedFrames: SourceAffectedFrame[];
83
+ };
84
+ /** Parse strictly to avoid using untrustworthy DOM attributes as file paths/offsets. */
85
+ export declare function parseSourceIdentity(raw: string | null | undefined): SourceIdentity | null;
86
+ export declare function sourceIdentityOf(el: Element): SourceIdentity | null;
87
+ /** The JSX opening that owns the rendered host element, independent of forwarded component props. */
88
+ export declare function ownSourceIdentityOf(el: Element): SourceIdentity | null;
89
+ /** Primitive literals authored on the owning JSX opening and safe for guarded AST replacement. */
90
+ export declare function parsePrimitiveSourceProps(raw: string | null | undefined): Record<string, PrimitiveSourceValue>;
91
+ /** Number of static direct JSX elements of the slot owner injected by instrumentation. The number of DOM children may differ from the slot, so it is not used. */
92
+ export declare function sourceSlotChildCountOf(el: Element): number | null;
93
+ /** The basic scope of influence for JSX component calls is the corresponding call-site instance, and for intrinsic DOM, the same source element. */
94
+ export declare function sourceEditScopeFor(identity: SourceIdentity): SourceEditScope;
95
+ /** Component props that do not correspond to the DOM, such as variants, are false — the actual results are visible after AST reflection/HMR. */
96
+ export declare function canPreviewSourceProp(el: HTMLElement, prop: string): boolean;
97
+ /** Relative paths whose meaning varies based on the target file are excluded. This slice supports only alias and bare package. */
98
+ export declare function isSafeComponentImportPath(importPath: string): boolean;
99
+ /** Normalize registry metadata only when it can be shared as is with AST payload and UI. */
100
+ export declare function sourceInsertComponentFor(componentName: string): SourceInsertComponent | null;
101
+ interface ComponentStructurePreview {
102
+ wrapper: HTMLElement;
103
+ mount: () => boolean;
104
+ unmount: () => void;
105
+ status: () => 'component' | 'placeholder';
106
+ }
107
+ export interface InspectEntry {
108
+ id: number;
109
+ kind: 'style' | 'text' | 'prop' | 'structure';
110
+ el: HTMLElement;
111
+ /** Display name — Registered component name or tag.localClass. */
112
+ label: string;
113
+ /** style: CSS property / text: 'text' / prop: JSX prop name. */
114
+ prop: string;
115
+ from: string;
116
+ to: string;
117
+ /** Whether the value is a var(--…) token (for log badges). */
118
+ token: boolean;
119
+ /** style write-back target (live only if none). */
120
+ source: SourceTarget | null;
121
+ /** text write-back destination file (live only if none). */
122
+ componentFile: string | null;
123
+ /** If not present, default rule; if present, responsive rule for the corresponding viewport scope. */
124
+ media: InspectMedia | null;
125
+ /** AST-based prop/text reflection target. If not, use the existing CSS/exact text replacement path. */
126
+ sourceIdentity: SourceIdentity | null;
127
+ sourceScope: SourceEditScope | null;
128
+ valueType: PrimitiveSourceValueType | null;
129
+ /** Whether the change is previewed immediately. Otherwise it appears after source apply and HMR. */
130
+ previewApplied: boolean;
131
+ affectedFrames: SourceAffectedFrame[];
132
+ /** DOM staging metadata for structure entries only. */
133
+ structureKind?: 'insert' | 'remove' | 'move';
134
+ structureInsertMode?: 'clone' | 'component';
135
+ structureParent?: HTMLElement;
136
+ structureClone?: HTMLElement;
137
+ structureComponent?: SourceInsertComponent;
138
+ structurePreview?: ComponentStructurePreview;
139
+ }
140
+ export interface InspectMedia {
141
+ minWidth?: number;
142
+ maxWidth?: number;
143
+ }
144
+ /** Source edit payload posted through a host-provided write-back endpoint. */
145
+ export interface InspectApplyPayload {
146
+ /** Final bundle of declarations per (scss file, local class). */
147
+ styles: {
148
+ file: string;
149
+ className: string;
150
+ componentFile: string;
151
+ declarations: Record<string, string>;
152
+ affectedFrames: SourceAffectedFrame[];
153
+ media?: InspectMedia;
154
+ }[];
155
+ /** Initial text for each element → Final text (assuming one-time exact matching substitution in the source). */
156
+ texts: {
157
+ componentFile: string;
158
+ oldText: string;
159
+ newText: string;
160
+ affectedFrames: SourceAffectedFrame[];
161
+ }[];
162
+ /** AST-based prop/text editing using injected JSX source locations. */
163
+ operations: SourceEditOperation[];
164
+ }
165
+ export declare class InspectSession {
166
+ /** Final commit candidate. Only one combination of the same element, attribute, and breakpoint is always maintained. */
167
+ entries: InspectEntry[];
168
+ toastMsg: string;
169
+ toastSeq: number;
170
+ private seq;
171
+ /** Undo/Redo is a session memory cache separate from the final patch. */
172
+ private undoHistory;
173
+ private redoHistory;
174
+ /** Original value before editing for each (element, property, breakpoint). */
175
+ private originals;
176
+ private listeners;
177
+ get canUndo(): boolean;
178
+ get canRedo(): boolean;
179
+ subscribe(fn: () => void): () => void;
180
+ private notify;
181
+ reset(): void;
182
+ toast(msg: string): void;
183
+ private scopeKey;
184
+ private originalValue;
185
+ private setOriginalValue;
186
+ private sameTarget;
187
+ private pendingFor;
188
+ /** Fold 1 manipulation into the final patch. When it returns to its original value, it is removed from the commit candidates. */
189
+ private updatePending;
190
+ private pushOperation;
191
+ /** Commit style edits — apply DOM immediately + record history + merge final patches. */
192
+ recordStyle(el: HTMLElement, prop: string, value: string, label: string, media?: InspectMedia | null, affectedFrames?: readonly SourceAffectedFrame[]): void;
193
+ hasPendingValueEdit(el: HTMLElement): boolean;
194
+ hasPendingStructuralEdit(el: HTMLElement): boolean;
195
+ structuralEditKind(el: HTMLElement): InspectEntry['structureKind'] | null;
196
+ /** A source element stages only one value or structure, and a DOM parent stages only one structure change. */
197
+ structuralBlockReason(el: HTMLElement, requested: 'insert' | 'remove' | 'move'): string | null;
198
+ /** Check whether the registry component can be placed in the children slot of the selection element. */
199
+ componentInsertBlockReason(el: HTMLElement, targetComponentName?: string | null): string | null;
200
+ /** Text edit commit — Only one final text per element is kept as a commit candidate. */
201
+ recordText(el: HTMLElement, newText: string, label: string, affectedFrames?: readonly SourceAffectedFrame[]): boolean;
202
+ /** Editing primitive component props — Possible DOM properties are reflected immediately, variants, etc. are reflected after application/HMR. */
203
+ recordProp(el: HTMLElement, prop: string, originalValue: PrimitiveSourceValue, newValue: PrimitiveSourceValue, label: string, identity?: SourceIdentity | null, affectedFrames?: readonly SourceAffectedFrame[]): boolean;
204
+ recordDuplicate(el: HTMLElement, label: string, affectedFrames?: readonly SourceAffectedFrame[]): boolean;
205
+ /** Inserts the registry component directly into the children slot of the selected element. */
206
+ recordComponentInsert(slotOwner: HTMLElement, componentName: string, toIndex: number, label: string, targetComponentName?: string | null, affectedFrames?: readonly SourceAffectedFrame[]): boolean;
207
+ recordRemove(el: HTMLElement, label: string, affectedFrames?: readonly SourceAffectedFrame[]): boolean;
208
+ recordMove(el: HTMLElement, direction: -1 | 1, label: string, affectedFrames?: readonly SourceAffectedFrame[]): boolean;
209
+ private applyValue;
210
+ undo(): void;
211
+ redo(): void;
212
+ /** Returns all unapplied operations to their original values. Redo cache is preserved. */
213
+ restoreOriginal(): void;
214
+ /** Restore every unapplied change and clear undo and redo history. */
215
+ discardPending(): void;
216
+ /** Build the apply payload using AST operations or the legacy CSS and exact-text path. */
217
+ buildApplyPayload(): InspectApplyPayload;
218
+ /** Impact graph results are reflected in the current source operation. If they are the same, they are not re-rendered. */
219
+ updateAffectedFrames(frames: readonly SourceAffectedFrame[]): void;
220
+ /** After successful reflection — only the mapped and reflected entries are emptied from the log (leaving live-only entries). */
221
+ clearApplied(): void;
222
+ }
223
+ export declare function isSourceBackedEntry(entry: InspectEntry): boolean;
224
+ export declare const inspectSession: InspectSession;
225
+ export {};