machinalayout 0.2.0 → 0.3.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.
- package/README.md +15 -0
- package/dist/chunk-2ZQ2RFFI.js +400 -0
- package/dist/chunk-33CKBEJH.js +186 -0
- package/dist/{chunk-TR24ERZT.js → chunk-SVWYWI7I.js} +3 -10
- package/dist/chunk-VREK57S3.js +13 -0
- package/dist/{chunk-HU6XYOH7.js → chunk-ZVDE7PX4.js} +106 -17
- package/dist/debugOverlay-pJpj0n5H.d.ts +125 -0
- package/dist/deus/index.d.ts +14 -0
- package/dist/deus/index.js +26 -0
- package/dist/handoff/index.d.ts +44 -0
- package/dist/handoff/index.js +83 -0
- package/dist/index.d.ts +46 -5
- package/dist/index.js +168 -3
- package/dist/inspect/index.d.ts +8 -0
- package/dist/inspect/index.js +97 -0
- package/dist/react/index.d.ts +10 -2
- package/dist/react/index.js +4 -2
- package/dist/react-native/index.d.ts +1 -1
- package/dist/react-native/index.js +2 -1
- package/dist/screenCatalog-ZjonGiOi.d.ts +46 -0
- package/dist/{types-BudfpzZX.d.ts → types-B90jb3RW.d.ts} +1 -1
- package/dist/types-DLYAhNXw.d.ts +32 -0
- package/dist/vue/index.d.ts +1 -1
- package/dist/vue/index.js +2 -1
- package/docs/deusmachina.md +108 -0
- package/docs/error-codes.md +11 -0
- package/docs/inspection-and-handoff.md +126 -0
- package/docs/react-adapter.md +23 -0
- package/docs/screen-catalog-and-viewports.md +124 -0
- package/docs/stack-geometry-helpers.md +115 -0
- package/package.json +127 -115
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getMachinaDebugOverlayBehavior
|
|
3
|
+
} from "./chunk-2ZQ2RFFI.js";
|
|
1
4
|
import {
|
|
2
5
|
toResolvedTree
|
|
3
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-SVWYWI7I.js";
|
|
4
7
|
|
|
5
8
|
// src/react/MachinaReactView.tsx
|
|
6
9
|
import React from "react";
|
|
@@ -88,6 +91,88 @@ function renderNode(node, parentRect, views, viewData, nodeData, nodeClassName,
|
|
|
88
91
|
node.id
|
|
89
92
|
);
|
|
90
93
|
}
|
|
94
|
+
function collectOverlayNodes(node) {
|
|
95
|
+
return [node, ...node.children.flatMap((child) => collectOverlayNodes(child))];
|
|
96
|
+
}
|
|
97
|
+
function renderDebugOverlay(tree, options) {
|
|
98
|
+
const board = {
|
|
99
|
+
mode: options.mode ?? "collapsed",
|
|
100
|
+
labels: options.labels ?? true,
|
|
101
|
+
borders: options.borders ?? true,
|
|
102
|
+
selectedNodeId: options.selectedNodeId
|
|
103
|
+
};
|
|
104
|
+
const behavior = getMachinaDebugOverlayBehavior(board);
|
|
105
|
+
if (!behavior.visible) return null;
|
|
106
|
+
const nodes = collectOverlayNodes(tree);
|
|
107
|
+
return /* @__PURE__ */ jsxs(
|
|
108
|
+
"div",
|
|
109
|
+
{
|
|
110
|
+
"data-testid": "machina-debug-overlay",
|
|
111
|
+
"data-machina-debug-overlay-mode": board.mode,
|
|
112
|
+
style: {
|
|
113
|
+
position: "absolute",
|
|
114
|
+
inset: 0,
|
|
115
|
+
pointerEvents: behavior.pointerEvents,
|
|
116
|
+
zIndex: 1e4,
|
|
117
|
+
boxSizing: "border-box"
|
|
118
|
+
},
|
|
119
|
+
children: [
|
|
120
|
+
nodes.map((node) => /* @__PURE__ */ jsx(
|
|
121
|
+
"div",
|
|
122
|
+
{
|
|
123
|
+
"data-testid": `machina-debug-overlay-node-${node.id}`,
|
|
124
|
+
"data-machina-debug-overlay-node-id": node.id,
|
|
125
|
+
style: {
|
|
126
|
+
position: "absolute",
|
|
127
|
+
left: node.rect.x - tree.rect.x,
|
|
128
|
+
top: node.rect.y - tree.rect.y,
|
|
129
|
+
width: node.rect.width,
|
|
130
|
+
height: node.rect.height,
|
|
131
|
+
boxSizing: "border-box",
|
|
132
|
+
border: behavior.showBorders ? "1px solid rgba(14, 165, 233, 0.9)" : "0",
|
|
133
|
+
pointerEvents: behavior.pointerEvents
|
|
134
|
+
},
|
|
135
|
+
children: behavior.showLabels ? /* @__PURE__ */ jsx(
|
|
136
|
+
"span",
|
|
137
|
+
{
|
|
138
|
+
style: {
|
|
139
|
+
position: "absolute",
|
|
140
|
+
left: 0,
|
|
141
|
+
top: 0,
|
|
142
|
+
fontSize: 10,
|
|
143
|
+
lineHeight: "12px",
|
|
144
|
+
background: "rgba(14, 165, 233, 0.9)",
|
|
145
|
+
color: "white",
|
|
146
|
+
padding: "0 3px"
|
|
147
|
+
},
|
|
148
|
+
children: node.debugLabel ?? node.id
|
|
149
|
+
}
|
|
150
|
+
) : null
|
|
151
|
+
},
|
|
152
|
+
node.id
|
|
153
|
+
)),
|
|
154
|
+
behavior.showPanel ? /* @__PURE__ */ jsxs(
|
|
155
|
+
"div",
|
|
156
|
+
{
|
|
157
|
+
"data-testid": "machina-debug-overlay-panel",
|
|
158
|
+
style: {
|
|
159
|
+
position: "absolute",
|
|
160
|
+
right: 8,
|
|
161
|
+
top: 8,
|
|
162
|
+
background: "rgba(15, 23, 42, 0.92)",
|
|
163
|
+
color: "white",
|
|
164
|
+
padding: 8
|
|
165
|
+
},
|
|
166
|
+
children: [
|
|
167
|
+
"Debug overlay",
|
|
168
|
+
board.selectedNodeId ? `: ${board.selectedNodeId}` : ""
|
|
169
|
+
]
|
|
170
|
+
}
|
|
171
|
+
) : null
|
|
172
|
+
]
|
|
173
|
+
}
|
|
174
|
+
);
|
|
175
|
+
}
|
|
91
176
|
function MachinaReactView(props) {
|
|
92
177
|
const {
|
|
93
178
|
layout,
|
|
@@ -102,7 +187,8 @@ function MachinaReactView(props) {
|
|
|
102
187
|
nodeContentVisibility = "none",
|
|
103
188
|
nodeContainIntrinsicSize,
|
|
104
189
|
layers = { base: { z: 0 } },
|
|
105
|
-
defaultLayer = "base"
|
|
190
|
+
defaultLayer = "base",
|
|
191
|
+
debugOverlay
|
|
106
192
|
} = props;
|
|
107
193
|
const tree = toResolvedTree(layout);
|
|
108
194
|
const wrapperStyle = {
|
|
@@ -111,21 +197,24 @@ function MachinaReactView(props) {
|
|
|
111
197
|
height: tree.rect.height,
|
|
112
198
|
...style
|
|
113
199
|
};
|
|
114
|
-
return /* @__PURE__ */
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
200
|
+
return /* @__PURE__ */ jsxs("div", { className, style: wrapperStyle, "data-machina-root-id": tree.id, children: [
|
|
201
|
+
renderNode(
|
|
202
|
+
tree,
|
|
203
|
+
tree.rect,
|
|
204
|
+
views,
|
|
205
|
+
viewData,
|
|
206
|
+
nodeData,
|
|
207
|
+
nodeClassName,
|
|
208
|
+
debug,
|
|
209
|
+
nodeContainment,
|
|
210
|
+
nodeContentVisibility,
|
|
211
|
+
nodeContainIntrinsicSize,
|
|
212
|
+
layout.nodes,
|
|
213
|
+
layers,
|
|
214
|
+
defaultLayer
|
|
215
|
+
),
|
|
216
|
+
debugOverlay ? renderDebugOverlay(tree, debugOverlay) : null
|
|
217
|
+
] });
|
|
129
218
|
}
|
|
130
219
|
|
|
131
220
|
export {
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
declare class DeusMachinaError extends Error {
|
|
2
|
+
readonly code: string;
|
|
3
|
+
constructor(code: string, message: string);
|
|
4
|
+
}
|
|
5
|
+
type UtilityScore<TContext> = number | ((context: TContext) => number);
|
|
6
|
+
type UtilityCandidate<TContext, TKey extends string = string> = {
|
|
7
|
+
key: TKey;
|
|
8
|
+
when?: (context: TContext) => boolean;
|
|
9
|
+
score: UtilityScore<TContext>;
|
|
10
|
+
reason?: string | ((context: TContext) => string);
|
|
11
|
+
};
|
|
12
|
+
type UtilityCandidateResult<TKey extends string = string> = {
|
|
13
|
+
key: TKey;
|
|
14
|
+
eligible: boolean;
|
|
15
|
+
score: number;
|
|
16
|
+
index: number;
|
|
17
|
+
reason?: string;
|
|
18
|
+
};
|
|
19
|
+
type UtilityJudgment<TKey extends string = string> = {
|
|
20
|
+
selected: UtilityCandidateResult<TKey> | null;
|
|
21
|
+
candidates: UtilityCandidateResult<TKey>[];
|
|
22
|
+
};
|
|
23
|
+
type JudgeUtilityOptions<TKey extends string = string> = {
|
|
24
|
+
previousKey?: TKey;
|
|
25
|
+
hysteresis?: number;
|
|
26
|
+
};
|
|
27
|
+
type DeusStatePath = readonly string[];
|
|
28
|
+
type DeusEvent = {
|
|
29
|
+
type: string;
|
|
30
|
+
};
|
|
31
|
+
type DeusAction<TBoard, TEvent extends DeusEvent> = (board: TBoard, event: TEvent) => void;
|
|
32
|
+
type DeusStateRow<TBoard, TEvent extends DeusEvent> = {
|
|
33
|
+
path: DeusStatePath;
|
|
34
|
+
onEnter?: DeusAction<TBoard, TEvent>;
|
|
35
|
+
onExit?: DeusAction<TBoard, TEvent>;
|
|
36
|
+
};
|
|
37
|
+
type DeusUtilityTransitionCandidate<TBoard, TEvent extends DeusEvent, TKey extends string = string> = {
|
|
38
|
+
key: TKey;
|
|
39
|
+
when?: (board: TBoard, event: TEvent) => boolean;
|
|
40
|
+
score: number | ((board: TBoard, event: TEvent) => number);
|
|
41
|
+
do?: DeusAction<TBoard, TEvent>;
|
|
42
|
+
reason?: string | ((board: TBoard, event: TEvent) => string);
|
|
43
|
+
};
|
|
44
|
+
type DeusTransitionRow<TBoard, TEvent extends DeusEvent> = {
|
|
45
|
+
key: string;
|
|
46
|
+
from: DeusStatePath;
|
|
47
|
+
event?: TEvent["type"];
|
|
48
|
+
to?: DeusStatePath | ((board: TBoard, event: TEvent) => DeusStatePath);
|
|
49
|
+
when?: (board: TBoard, event: TEvent) => boolean;
|
|
50
|
+
score?: number | ((board: TBoard, event: TEvent) => number);
|
|
51
|
+
do?: DeusAction<TBoard, TEvent>;
|
|
52
|
+
reason?: string | ((board: TBoard, event: TEvent) => string);
|
|
53
|
+
utility?: readonly DeusUtilityTransitionCandidate<TBoard, TEvent>[];
|
|
54
|
+
hysteresis?: {
|
|
55
|
+
previous: (board: TBoard) => string | undefined;
|
|
56
|
+
margin: number;
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
type DeusMachine<TBoard, TEvent extends DeusEvent> = {
|
|
60
|
+
initial: DeusStatePath;
|
|
61
|
+
states: readonly DeusStateRow<TBoard, TEvent>[];
|
|
62
|
+
transitions: readonly DeusTransitionRow<TBoard, TEvent>[];
|
|
63
|
+
};
|
|
64
|
+
type DeusSnapshot<TBoard> = {
|
|
65
|
+
state: DeusStatePath;
|
|
66
|
+
board: TBoard;
|
|
67
|
+
stepIndex: number;
|
|
68
|
+
};
|
|
69
|
+
type DeusTransitionTrace = {
|
|
70
|
+
key: string;
|
|
71
|
+
from: DeusStatePath;
|
|
72
|
+
to?: DeusStatePath;
|
|
73
|
+
event?: string;
|
|
74
|
+
eligible: boolean;
|
|
75
|
+
score: number;
|
|
76
|
+
index: number;
|
|
77
|
+
reason?: string;
|
|
78
|
+
utility?: UtilityJudgment<string>;
|
|
79
|
+
};
|
|
80
|
+
type DeusStepTrace = {
|
|
81
|
+
stateBefore: DeusStatePath;
|
|
82
|
+
stateAfter: DeusStatePath;
|
|
83
|
+
event: string;
|
|
84
|
+
selectedTransition?: DeusTransitionTrace;
|
|
85
|
+
transitions: DeusTransitionTrace[];
|
|
86
|
+
};
|
|
87
|
+
type DeusStepResult<TBoard> = {
|
|
88
|
+
snapshot: DeusSnapshot<TBoard>;
|
|
89
|
+
trace: DeusStepTrace;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
type MachinaDebugOverlayMode = "collapsed" | "nonInteractiveOverlay" | "interactivePanel";
|
|
93
|
+
type MachinaDebugOverlayBoard = {
|
|
94
|
+
mode: MachinaDebugOverlayMode;
|
|
95
|
+
labels: boolean;
|
|
96
|
+
borders: boolean;
|
|
97
|
+
selectedNodeId?: string;
|
|
98
|
+
};
|
|
99
|
+
type MachinaDebugOverlayEvent = {
|
|
100
|
+
type: "showOverlay";
|
|
101
|
+
} | {
|
|
102
|
+
type: "openPanel";
|
|
103
|
+
nodeId?: string;
|
|
104
|
+
} | {
|
|
105
|
+
type: "collapse";
|
|
106
|
+
} | {
|
|
107
|
+
type: "toggleLabels";
|
|
108
|
+
} | {
|
|
109
|
+
type: "toggleBorders";
|
|
110
|
+
} | {
|
|
111
|
+
type: "selectNode";
|
|
112
|
+
nodeId: string;
|
|
113
|
+
};
|
|
114
|
+
type MachinaDebugOverlayBehavior = {
|
|
115
|
+
visible: boolean;
|
|
116
|
+
pointerEvents: "none" | "auto";
|
|
117
|
+
consumesLayoutSpace: boolean;
|
|
118
|
+
showPanel: boolean;
|
|
119
|
+
showLabels: boolean;
|
|
120
|
+
showBorders: boolean;
|
|
121
|
+
};
|
|
122
|
+
declare function createMachinaDebugOverlayMachine(): DeusMachine<MachinaDebugOverlayBoard, MachinaDebugOverlayEvent>;
|
|
123
|
+
declare function getMachinaDebugOverlayBehavior(board: MachinaDebugOverlayBoard): MachinaDebugOverlayBehavior;
|
|
124
|
+
|
|
125
|
+
export { type DeusEvent as D, type JudgeUtilityOptions as J, type MachinaDebugOverlayBehavior as M, type UtilityCandidate as U, type UtilityJudgment as a, type DeusMachine as b, type DeusSnapshot as c, type DeusStatePath as d, type DeusStepTrace as e, type DeusStepResult as f, type DeusAction as g, DeusMachinaError as h, type DeusStateRow as i, type DeusTransitionRow as j, type DeusTransitionTrace as k, type DeusUtilityTransitionCandidate as l, type MachinaDebugOverlayBoard as m, type MachinaDebugOverlayEvent as n, type MachinaDebugOverlayMode as o, type UtilityCandidateResult as p, type UtilityScore as q, createMachinaDebugOverlayMachine as r, getMachinaDebugOverlayBehavior as s };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { U as UtilityCandidate, J as JudgeUtilityOptions, a as UtilityJudgment, D as DeusEvent, b as DeusMachine, c as DeusSnapshot, d as DeusStatePath, e as DeusStepTrace, f as DeusStepResult } from '../debugOverlay-pJpj0n5H.js';
|
|
2
|
+
export { g as DeusAction, h as DeusMachinaError, i as DeusStateRow, j as DeusTransitionRow, k as DeusTransitionTrace, l as DeusUtilityTransitionCandidate, M as MachinaDebugOverlayBehavior, m as MachinaDebugOverlayBoard, n as MachinaDebugOverlayEvent, o as MachinaDebugOverlayMode, p as UtilityCandidateResult, q as UtilityScore, r as createMachinaDebugOverlayMachine, s as getMachinaDebugOverlayBehavior } from '../debugOverlay-pJpj0n5H.js';
|
|
3
|
+
|
|
4
|
+
declare function judgeUtility<TContext, TKey extends string = string>(context: TContext, candidates: readonly UtilityCandidate<TContext, TKey>[], options?: JudgeUtilityOptions<TKey>): UtilityJudgment<TKey>;
|
|
5
|
+
|
|
6
|
+
declare function formatDeusPath(path: DeusStatePath): string;
|
|
7
|
+
declare function sameDeusPath(a: DeusStatePath, b: DeusStatePath): boolean;
|
|
8
|
+
declare function isDeusAncestorPath(ancestor: DeusStatePath, path: DeusStatePath): boolean;
|
|
9
|
+
declare function defineDeusMachine<TBoard, TEvent extends DeusEvent>(machine: DeusMachine<TBoard, TEvent>): DeusMachine<TBoard, TEvent>;
|
|
10
|
+
declare function createDeusSnapshot<TBoard, TEvent extends DeusEvent>(machine: DeusMachine<TBoard, TEvent>, board: TBoard): DeusSnapshot<TBoard>;
|
|
11
|
+
declare function stepDeusMachine<TBoard, TEvent extends DeusEvent>(machine: DeusMachine<TBoard, TEvent>, snapshot: DeusSnapshot<TBoard>, event: NoInfer<TEvent>): DeusStepResult<TBoard>;
|
|
12
|
+
declare function formatDeusStepTrace(trace: DeusStepTrace): string;
|
|
13
|
+
|
|
14
|
+
export { DeusEvent, DeusMachine, DeusSnapshot, DeusStatePath, DeusStepResult, DeusStepTrace, JudgeUtilityOptions, UtilityCandidate, UtilityJudgment, createDeusSnapshot, defineDeusMachine, formatDeusPath, formatDeusStepTrace, isDeusAncestorPath, judgeUtility, sameDeusPath, stepDeusMachine };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DeusMachinaError,
|
|
3
|
+
createDeusSnapshot,
|
|
4
|
+
createMachinaDebugOverlayMachine,
|
|
5
|
+
defineDeusMachine,
|
|
6
|
+
formatDeusPath,
|
|
7
|
+
formatDeusStepTrace,
|
|
8
|
+
getMachinaDebugOverlayBehavior,
|
|
9
|
+
isDeusAncestorPath,
|
|
10
|
+
judgeUtility,
|
|
11
|
+
sameDeusPath,
|
|
12
|
+
stepDeusMachine
|
|
13
|
+
} from "../chunk-2ZQ2RFFI.js";
|
|
14
|
+
export {
|
|
15
|
+
DeusMachinaError,
|
|
16
|
+
createDeusSnapshot,
|
|
17
|
+
createMachinaDebugOverlayMachine,
|
|
18
|
+
defineDeusMachine,
|
|
19
|
+
formatDeusPath,
|
|
20
|
+
formatDeusStepTrace,
|
|
21
|
+
getMachinaDebugOverlayBehavior,
|
|
22
|
+
isDeusAncestorPath,
|
|
23
|
+
judgeUtility,
|
|
24
|
+
sameDeusPath,
|
|
25
|
+
stepDeusMachine
|
|
26
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { M as MachinaDomSummary } from '../types-DLYAhNXw.js';
|
|
2
|
+
import { M as MachinaViewport, a as MachinaScreenViewportTask } from '../screenCatalog-ZjonGiOi.js';
|
|
3
|
+
import '../types-B90jb3RW.js';
|
|
4
|
+
|
|
5
|
+
type MachinaHandoffArtifactPaths = {
|
|
6
|
+
screenshot?: string;
|
|
7
|
+
domSummary?: string;
|
|
8
|
+
layoutSnapshot?: string;
|
|
9
|
+
manifest: string;
|
|
10
|
+
};
|
|
11
|
+
type MachinaHandoffBundleManifest = {
|
|
12
|
+
schemaVersion: 1;
|
|
13
|
+
createdAt: string;
|
|
14
|
+
route?: string;
|
|
15
|
+
fixture?: string;
|
|
16
|
+
screenKey?: string;
|
|
17
|
+
viewportKey?: string;
|
|
18
|
+
viewport?: MachinaViewport;
|
|
19
|
+
tags?: readonly string[];
|
|
20
|
+
artifactBaseName?: string;
|
|
21
|
+
artifacts: MachinaHandoffArtifactPaths;
|
|
22
|
+
metadata?: Record<string, unknown>;
|
|
23
|
+
};
|
|
24
|
+
type WriteMachinaHandoffBundleInput = {
|
|
25
|
+
outputDir: string;
|
|
26
|
+
artifactBaseName?: string;
|
|
27
|
+
screenshotPath?: string;
|
|
28
|
+
domSummary?: MachinaDomSummary;
|
|
29
|
+
layoutSnapshot?: unknown;
|
|
30
|
+
task?: MachinaScreenViewportTask;
|
|
31
|
+
route?: string;
|
|
32
|
+
fixture?: string;
|
|
33
|
+
tags?: readonly string[];
|
|
34
|
+
metadata?: Record<string, unknown>;
|
|
35
|
+
createdAt?: string;
|
|
36
|
+
};
|
|
37
|
+
type WriteMachinaHandoffBundleResult = {
|
|
38
|
+
manifest: MachinaHandoffBundleManifest;
|
|
39
|
+
paths: MachinaHandoffArtifactPaths;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
declare function writeMachinaHandoffBundle(input: WriteMachinaHandoffBundleInput): Promise<WriteMachinaHandoffBundleResult>;
|
|
43
|
+
|
|
44
|
+
export { type MachinaHandoffArtifactPaths, type MachinaHandoffBundleManifest, type WriteMachinaHandoffBundleInput, type WriteMachinaHandoffBundleResult, writeMachinaHandoffBundle };
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import {
|
|
2
|
+
slugMachinaArtifactName
|
|
3
|
+
} from "../chunk-33CKBEJH.js";
|
|
4
|
+
import "../chunk-VREK57S3.js";
|
|
5
|
+
|
|
6
|
+
// src/handoff/writeMachinaHandoffBundle.ts
|
|
7
|
+
import { copyFile, mkdir, writeFile } from "fs/promises";
|
|
8
|
+
import path from "path";
|
|
9
|
+
function artifactBaseName(input) {
|
|
10
|
+
const candidate = input.artifactBaseName ?? input.task?.artifactBaseName ?? [
|
|
11
|
+
input.route ?? input.task?.route,
|
|
12
|
+
input.fixture ?? input.task?.fixture,
|
|
13
|
+
input.task?.viewportKey
|
|
14
|
+
].filter((part) => typeof part === "string" && part.trim() !== "").join("-") ?? "";
|
|
15
|
+
return slugMachinaArtifactName(candidate === "" ? "machina-handoff" : candidate);
|
|
16
|
+
}
|
|
17
|
+
function orderedUnique(...groups) {
|
|
18
|
+
const result = [];
|
|
19
|
+
for (const group of groups) {
|
|
20
|
+
for (const tag of group ?? []) {
|
|
21
|
+
if (!result.includes(tag)) result.push(tag);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return result.length === 0 ? void 0 : result;
|
|
25
|
+
}
|
|
26
|
+
function json(value) {
|
|
27
|
+
return `${JSON.stringify(value, null, 2)}
|
|
28
|
+
`;
|
|
29
|
+
}
|
|
30
|
+
function screenshotExtension(screenshotPath) {
|
|
31
|
+
const extension = path.extname(screenshotPath);
|
|
32
|
+
return extension === "" ? ".png" : extension;
|
|
33
|
+
}
|
|
34
|
+
async function writeMachinaHandoffBundle(input) {
|
|
35
|
+
if (typeof input.outputDir !== "string" || input.outputDir.trim() === "") {
|
|
36
|
+
throw new Error("outputDir must be a non-empty string");
|
|
37
|
+
}
|
|
38
|
+
const outputDir = path.resolve(input.outputDir);
|
|
39
|
+
await mkdir(outputDir, { recursive: true });
|
|
40
|
+
const base = artifactBaseName(input);
|
|
41
|
+
const artifactNames = { manifest: `${base}__handoff.json` };
|
|
42
|
+
const paths = {
|
|
43
|
+
manifest: path.join(outputDir, artifactNames.manifest)
|
|
44
|
+
};
|
|
45
|
+
if (input.screenshotPath !== void 0) {
|
|
46
|
+
artifactNames.screenshot = `${base}__screenshot${screenshotExtension(input.screenshotPath)}`;
|
|
47
|
+
paths.screenshot = path.join(outputDir, artifactNames.screenshot);
|
|
48
|
+
await copyFile(input.screenshotPath, paths.screenshot);
|
|
49
|
+
}
|
|
50
|
+
if (input.domSummary !== void 0) {
|
|
51
|
+
artifactNames.domSummary = `${base}__dom-summary.json`;
|
|
52
|
+
paths.domSummary = path.join(outputDir, artifactNames.domSummary);
|
|
53
|
+
await writeFile(paths.domSummary, json(input.domSummary), "utf8");
|
|
54
|
+
}
|
|
55
|
+
if (input.layoutSnapshot !== void 0) {
|
|
56
|
+
artifactNames.layoutSnapshot = `${base}__machina-snapshot.json`;
|
|
57
|
+
paths.layoutSnapshot = path.join(outputDir, artifactNames.layoutSnapshot);
|
|
58
|
+
await writeFile(paths.layoutSnapshot, json(input.layoutSnapshot), "utf8");
|
|
59
|
+
}
|
|
60
|
+
const tags = orderedUnique(input.task?.tags, input.tags);
|
|
61
|
+
const manifest = {
|
|
62
|
+
schemaVersion: 1,
|
|
63
|
+
createdAt: input.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
64
|
+
artifacts: artifactNames
|
|
65
|
+
};
|
|
66
|
+
const route = input.route ?? input.task?.route;
|
|
67
|
+
const fixture = input.fixture ?? input.task?.fixture;
|
|
68
|
+
if (route !== void 0) manifest.route = route;
|
|
69
|
+
if (fixture !== void 0) manifest.fixture = fixture;
|
|
70
|
+
if (input.task !== void 0) {
|
|
71
|
+
manifest.screenKey = input.task.screenKey;
|
|
72
|
+
manifest.viewportKey = input.task.viewportKey;
|
|
73
|
+
manifest.viewport = input.task.viewport;
|
|
74
|
+
}
|
|
75
|
+
if (tags !== void 0) manifest.tags = tags;
|
|
76
|
+
manifest.artifactBaseName = base;
|
|
77
|
+
if (input.metadata !== void 0) manifest.metadata = input.metadata;
|
|
78
|
+
await writeFile(paths.manifest, json(manifest), "utf8");
|
|
79
|
+
return { manifest, paths };
|
|
80
|
+
}
|
|
81
|
+
export {
|
|
82
|
+
writeMachinaHandoffBundle
|
|
83
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import { E as EdgeInsets, U as UiLength, R as Rect, O as OffsetSpec, L as LayoutRow, c as LayoutDocument, F as FrameSpec, b as ResolvedLayoutDocument, d as ResolvedLayoutTree, a as ResolvedLayoutNode } from './types-
|
|
2
|
-
export {
|
|
3
|
-
export { MachinaReactView, MachinaReactViewProps, MachinaSlotProps } from './react/index.js';
|
|
1
|
+
import { E as EdgeInsets, U as UiLength, R as Rect, O as OffsetSpec, L as LayoutRow, c as LayoutDocument, F as FrameSpec, b as ResolvedLayoutDocument, d as ResolvedLayoutTree, a as ResolvedLayoutNode, N as NodeId, e as LayerName, S as StackAxis, A as ArrangeSpec } from './types-B90jb3RW.js';
|
|
2
|
+
export { f as AbsoluteFrame, g as AnchorFrame, C as CellFrame, h as EdgeRef, i as FillFrame, j as FixedFrame, G as GridArrange, k as GridTrack, l as GuideFrame, m as GuideLength, n as LayoutNode, o as LayoutRowVariant, p as LayoutVariantCondition, q as RectEdge, r as RootFrame, s as StackAlign, t as StackArrange, u as StackJustify } from './types-B90jb3RW.js';
|
|
3
|
+
export { MachinaReactDebugOverlayOptions, MachinaReactView, MachinaReactViewProps, MachinaSlotProps } from './react/index.js';
|
|
4
4
|
export { c as MachinaBulletItem, d as MachinaInline, e as MachinaTextAlign, f as MachinaTextBlock, g as MachinaTextDiagnostic, h as MachinaTextDiagnosticCode, i as MachinaTextDiagnosticLevel, b as MachinaTextDocument, j as MachinaTextLeading, k as MachinaTextOverflow, a as MachinaTextSource, M as MachinaTextSpec, l as MachinaTextVariant, m as MachinaTextVerticalAlign, n as MachinaTextWrap, P as ParseMachinaTextResult } from './types-C4poVJpR.js';
|
|
5
5
|
export { parseMachinaText, parseMachinaTextInline } from './text/index.js';
|
|
6
6
|
export { MachinaTextView, MachinaTextViewProps } from './text/react/index.js';
|
|
7
|
+
export { b as MachinaScreen, c as MachinaScreenCatalog, a as MachinaScreenViewportTask, M as MachinaViewport, d as MachinaViewportMatrix, e as createViewportMatrix, f as defineMachinaScreens, g as defineMachinaViewports, h as expandScreenViewportTasks, i as getMachinaViewport, s as slugMachinaArtifactName } from './screenCatalog-ZjonGiOi.js';
|
|
7
8
|
import 'react';
|
|
9
|
+
import './debugOverlay-pJpj0n5H.js';
|
|
8
10
|
|
|
9
|
-
type MachinaLayoutErrorCode = "EmptyRows" | "MissingRoot" | "MultipleRoots" | "DuplicateId" | "InvalidId" | "MissingParent" | "UnknownParent" | "SelfParent" | "Cycle" | "UnreachableNode" | "NonFiniteNumber" | "InvalidLengthUnit" | "InvalidZ" | "InvalidVariantCondition" | "NegativeSize" | "NegativeGap" | "NegativePadding" | "InvalidAnchorHorizontal" | "InvalidAnchorVertical" | "NegativeResolvedSize" | "FixedFrameWithoutArranger" | "FillFrameWithoutArranger" | "InvalidFillWeight" | "StackChildMustBeFixed" | "StackContentNegative" | "StackOverflow" | "CellFrameWithoutGrid" | "GridChildMustBeCell" | "InvalidGridTrack" | "InvalidGridCell" | "GridContentNegative" | "GridOverflow" | "RootFrameNotRoot" | "RootFrameWithoutRoot" | "IncompatibleLayouts" | "GuideTargetNotFound" | "GuideSelfReference" | "GuideReferenceCycle" | "GuideInvalidEdgeForAxis" | "GuideTooManyReferencesPerAxis" | "InvalidGuideFrame" | "GuideTargetUnresolved";
|
|
11
|
+
type MachinaLayoutErrorCode = "EmptyRows" | "MissingRoot" | "MultipleRoots" | "DuplicateId" | "InvalidId" | "MissingParent" | "UnknownParent" | "SelfParent" | "Cycle" | "UnreachableNode" | "NonFiniteNumber" | "InvalidLengthUnit" | "InvalidZ" | "InvalidVariantCondition" | "NegativeSize" | "NegativeGap" | "NegativePadding" | "InvalidAnchorHorizontal" | "InvalidAnchorVertical" | "NegativeResolvedSize" | "FixedFrameWithoutArranger" | "FillFrameWithoutArranger" | "InvalidFillWeight" | "StackChildMustBeFixed" | "StackContentNegative" | "StackOverflow" | "ExpectedStackArrange" | "StackQueryInvalidRange" | "CellFrameWithoutGrid" | "GridChildMustBeCell" | "InvalidGridTrack" | "InvalidGridCell" | "GridContentNegative" | "GridOverflow" | "RootFrameNotRoot" | "RootFrameWithoutRoot" | "IncompatibleLayouts" | "GuideTargetNotFound" | "GuideSelfReference" | "GuideReferenceCycle" | "GuideInvalidEdgeForAxis" | "GuideTooManyReferencesPerAxis" | "InvalidGuideFrame" | "GuideTargetUnresolved" | "InvalidViewport" | "DuplicateViewportKey" | "UnknownViewportKey" | "InvalidScreen" | "DuplicateScreenKey" | "UnknownScreenKey";
|
|
10
12
|
declare class MachinaLayoutError extends Error {
|
|
11
13
|
readonly code: MachinaLayoutErrorCode;
|
|
12
14
|
constructor(code: MachinaLayoutErrorCode, message: string);
|
|
@@ -39,8 +41,47 @@ declare function flattenResolvedTree(tree: ResolvedLayoutTree): ResolvedLayoutNo
|
|
|
39
41
|
|
|
40
42
|
declare function formatRect(rect: Rect): string;
|
|
41
43
|
|
|
44
|
+
type StackChildMetric = {
|
|
45
|
+
id: NodeId;
|
|
46
|
+
rect: Rect;
|
|
47
|
+
mainStart: number;
|
|
48
|
+
mainEnd: number;
|
|
49
|
+
mainSize: number;
|
|
50
|
+
crossStart: number;
|
|
51
|
+
crossEnd: number;
|
|
52
|
+
crossSize: number;
|
|
53
|
+
frameKind: FrameSpec["kind"];
|
|
54
|
+
z?: number;
|
|
55
|
+
layer?: LayerName;
|
|
56
|
+
};
|
|
57
|
+
type StackMainAxisMetrics = {
|
|
58
|
+
parentId: NodeId;
|
|
59
|
+
axis: StackAxis;
|
|
60
|
+
parentRect: Rect;
|
|
61
|
+
contentRect: Rect;
|
|
62
|
+
padding: EdgeInsets;
|
|
63
|
+
gap: number;
|
|
64
|
+
childIds: NodeId[];
|
|
65
|
+
childMetrics: StackChildMetric[];
|
|
66
|
+
contentMainSize: number;
|
|
67
|
+
contentCrossSize: number;
|
|
68
|
+
totalChildMainSize: number;
|
|
69
|
+
totalGapSize: number;
|
|
70
|
+
usedMainSize: number;
|
|
71
|
+
unusedMainSize: number;
|
|
72
|
+
};
|
|
73
|
+
declare function getArrangeContentRect(parentRect: Rect, arrange?: ArrangeSpec): Rect;
|
|
74
|
+
declare function getStackContentRect(layout: ResolvedLayoutDocument, parentId: NodeId): Rect;
|
|
75
|
+
declare function getStackMainAxisMetrics(layout: ResolvedLayoutDocument, parentId: NodeId): StackMainAxisMetrics;
|
|
76
|
+
declare function getStackChildRects(layout: ResolvedLayoutDocument, parentId: NodeId): Record<NodeId, Rect>;
|
|
77
|
+
declare function getRemainingStackRect(layout: ResolvedLayoutDocument, options: {
|
|
78
|
+
parentId: NodeId;
|
|
79
|
+
afterChildren?: NodeId[];
|
|
80
|
+
beforeChildren?: NodeId[];
|
|
81
|
+
}): Rect;
|
|
82
|
+
|
|
42
83
|
declare function lerpNumber(a: number, b: number, t: number): number;
|
|
43
84
|
declare function lerpRect(a: Rect, b: Rect, t: number): Rect;
|
|
44
85
|
declare function lerpResolvedLayouts(a: ResolvedLayoutDocument, b: ResolvedLayoutDocument, t: number): ResolvedLayoutDocument;
|
|
45
86
|
|
|
46
|
-
export { EdgeInsets, FrameSpec, LayoutDocument, LayoutRow, MachinaLayoutError, type MachinaLayoutErrorCode, OffsetSpec, Rect, ResolvedLayoutDocument, ResolvedLayoutNode, ResolvedLayoutTree, UiLength, applyOffset, assertFiniteNumber, assertNonNegativeGap, assertNonNegativePadding, assertNonNegativeSize, compileLayoutRows, flattenResolvedTree, formatRect, lerpNumber, lerpRect, lerpResolvedLayouts, normalizePadding, resolveFrame, resolveLayoutDocument, resolveLayoutRows, resolveUiLength, selectLayoutRowsForRoot, toResolvedTree };
|
|
87
|
+
export { ArrangeSpec, EdgeInsets, FrameSpec, LayerName, LayoutDocument, LayoutRow, MachinaLayoutError, type MachinaLayoutErrorCode, NodeId, OffsetSpec, Rect, ResolvedLayoutDocument, ResolvedLayoutNode, ResolvedLayoutTree, StackAxis, type StackChildMetric, type StackMainAxisMetrics, UiLength, applyOffset, assertFiniteNumber, assertNonNegativeGap, assertNonNegativePadding, assertNonNegativeSize, compileLayoutRows, flattenResolvedTree, formatRect, getArrangeContentRect, getRemainingStackRect, getStackChildRects, getStackContentRect, getStackMainAxisMetrics, lerpNumber, lerpRect, lerpResolvedLayouts, normalizePadding, resolveFrame, resolveLayoutDocument, resolveLayoutRows, resolveUiLength, selectLayoutRowsForRoot, toResolvedTree };
|