@mmapp/player-core 0.1.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +1436 -0
- package/dist/index.d.ts +1436 -0
- package/dist/index.js +4828 -0
- package/dist/index.mjs +4762 -0
- package/package.json +35 -0
- package/package.json.backup +35 -0
- package/src/__tests__/actions.test.ts +187 -0
- package/src/__tests__/blueprint-e2e.test.ts +706 -0
- package/src/__tests__/blueprint-test-runner.test.ts +680 -0
- package/src/__tests__/core-functions.test.ts +78 -0
- package/src/__tests__/dsl-compiler.test.ts +1382 -0
- package/src/__tests__/dsl-grammar.test.ts +1682 -0
- package/src/__tests__/events.test.ts +200 -0
- package/src/__tests__/expression.test.ts +296 -0
- package/src/__tests__/failure-policies.test.ts +110 -0
- package/src/__tests__/frontend-context.test.ts +182 -0
- package/src/__tests__/integration.test.ts +256 -0
- package/src/__tests__/security.test.ts +190 -0
- package/src/__tests__/state-machine.test.ts +450 -0
- package/src/__tests__/testing-engine.test.ts +671 -0
- package/src/actions/dispatcher.ts +80 -0
- package/src/actions/index.ts +7 -0
- package/src/actions/types.ts +25 -0
- package/src/dsl/compiler/component-mapper.ts +289 -0
- package/src/dsl/compiler/field-mapper.ts +187 -0
- package/src/dsl/compiler/index.ts +82 -0
- package/src/dsl/compiler/manifest-compiler.ts +76 -0
- package/src/dsl/compiler/symbol-table.ts +214 -0
- package/src/dsl/compiler/utils.ts +48 -0
- package/src/dsl/compiler/view-compiler.ts +286 -0
- package/src/dsl/compiler/workflow-compiler.ts +600 -0
- package/src/dsl/index.ts +66 -0
- package/src/dsl/ir-migration.ts +221 -0
- package/src/dsl/ir-types.ts +416 -0
- package/src/dsl/lexer.ts +579 -0
- package/src/dsl/parser.ts +115 -0
- package/src/dsl/types.ts +256 -0
- package/src/events/event-bus.ts +68 -0
- package/src/events/index.ts +9 -0
- package/src/events/pattern-matcher.ts +61 -0
- package/src/events/types.ts +27 -0
- package/src/expression/evaluator.ts +676 -0
- package/src/expression/functions.ts +214 -0
- package/src/expression/index.ts +13 -0
- package/src/expression/types.ts +64 -0
- package/src/index.ts +61 -0
- package/src/state-machine/index.ts +16 -0
- package/src/state-machine/interpreter.ts +319 -0
- package/src/state-machine/types.ts +89 -0
- package/src/testing/action-trace.ts +209 -0
- package/src/testing/blueprint-test-runner.ts +214 -0
- package/src/testing/graph-walker.ts +249 -0
- package/src/testing/index.ts +69 -0
- package/src/testing/nrt-comparator.ts +199 -0
- package/src/testing/nrt-types.ts +230 -0
- package/src/testing/test-actions.ts +645 -0
- package/src/testing/test-compiler.ts +278 -0
- package/src/testing/test-runner.ts +444 -0
- package/src/testing/types.ts +231 -0
- package/src/validation/definition-validator.ts +812 -0
- package/src/validation/index.ts +13 -0
- package/tsconfig.json +26 -0
- package/vitest.config.ts +8 -0
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NRT (Normalized Render Trace) — platform-agnostic representation of rendered UI.
|
|
3
|
+
*
|
|
4
|
+
* NRT captures the semantic structure of a rendered workflow view,
|
|
5
|
+
* abstracting away platform-specific rendering details. This enables:
|
|
6
|
+
*
|
|
7
|
+
* 1. Cross-platform testing (browser, iOS, terminal all produce same NRT)
|
|
8
|
+
* 2. Visual regression detection without screenshots
|
|
9
|
+
* 3. Accessibility auditing (every visible element has semantic info)
|
|
10
|
+
* 4. LLM-based test generation (structured, predictable format)
|
|
11
|
+
*
|
|
12
|
+
* Usage:
|
|
13
|
+
* const nrt = exportNRT(renderedTree);
|
|
14
|
+
* expect(nrt.root.children).toHaveLength(3);
|
|
15
|
+
* expect(findNode(nrt, 'submit-button').events?.click.target.transition).toBe('submit');
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
// =============================================================================
|
|
19
|
+
// Core Types
|
|
20
|
+
// =============================================================================
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* A complete Normalized Render Trace snapshot.
|
|
24
|
+
*/
|
|
25
|
+
export interface NRT {
|
|
26
|
+
/** NRT format version. */
|
|
27
|
+
version: 1;
|
|
28
|
+
/** The root node of the rendered tree. */
|
|
29
|
+
root: NRTNode;
|
|
30
|
+
/** Currently focused element ID (if applicable). */
|
|
31
|
+
focus?: string;
|
|
32
|
+
/** Navigation state (if router workflow is active). */
|
|
33
|
+
nav?: NRTNavState;
|
|
34
|
+
/** Timestamp of the snapshot. */
|
|
35
|
+
timestamp?: string;
|
|
36
|
+
/** Workflow state at time of capture. */
|
|
37
|
+
workflowState?: string;
|
|
38
|
+
/** Instance ID if bound to a specific instance. */
|
|
39
|
+
instanceId?: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* A single node in the NRT tree.
|
|
44
|
+
*/
|
|
45
|
+
export interface NRTNode {
|
|
46
|
+
/** Unique ID within the tree. */
|
|
47
|
+
id: string;
|
|
48
|
+
/** Component type (e.g., 'Stack', 'Button', 'Text', 'TextInput'). */
|
|
49
|
+
type: string;
|
|
50
|
+
/** Text content (for text-bearing elements). */
|
|
51
|
+
text?: string;
|
|
52
|
+
/** Current value (for input elements). */
|
|
53
|
+
value?: unknown;
|
|
54
|
+
/** Whether this node is visible. */
|
|
55
|
+
visible: boolean;
|
|
56
|
+
/** Whether this node is enabled/interactive. */
|
|
57
|
+
enabled?: boolean;
|
|
58
|
+
/** Whether this node has focus. */
|
|
59
|
+
focused?: boolean;
|
|
60
|
+
/** Semantic role (for accessibility). */
|
|
61
|
+
role?: string;
|
|
62
|
+
/** Accessibility label. */
|
|
63
|
+
label?: string;
|
|
64
|
+
/** Key-value props that affect behavior (not styling). */
|
|
65
|
+
props?: Record<string, unknown>;
|
|
66
|
+
/** Interactive events this node can receive. */
|
|
67
|
+
events?: Record<string, NRTEvent>;
|
|
68
|
+
/** Child nodes. */
|
|
69
|
+
children: NRTNode[];
|
|
70
|
+
/** Data binding expression (if bound to workflow data). */
|
|
71
|
+
binding?: string;
|
|
72
|
+
/** Condition that controls visibility. */
|
|
73
|
+
visibleWhen?: string;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* An interactive event on an NRT node.
|
|
78
|
+
*/
|
|
79
|
+
export interface NRTEvent {
|
|
80
|
+
/** What kind of action this event triggers. */
|
|
81
|
+
kind: 'transition' | 'mutation' | 'navigation' | 'custom';
|
|
82
|
+
/** Target workflow operation. */
|
|
83
|
+
target: NRTEventTarget;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Target of an NRT event.
|
|
88
|
+
*/
|
|
89
|
+
export interface NRTEventTarget {
|
|
90
|
+
/** Workflow slug. */
|
|
91
|
+
workflow?: string;
|
|
92
|
+
/** Transition name to fire. */
|
|
93
|
+
transition?: string;
|
|
94
|
+
/** Mutation type (create, update, delete). */
|
|
95
|
+
mutation?: string;
|
|
96
|
+
/** Navigation path. */
|
|
97
|
+
path?: string;
|
|
98
|
+
/** Custom handler name. */
|
|
99
|
+
handler?: string;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Navigation state for router-bound NRT.
|
|
104
|
+
*/
|
|
105
|
+
export interface NRTNavState {
|
|
106
|
+
/** Current route state name. */
|
|
107
|
+
routeState: string;
|
|
108
|
+
/** Current URL path. */
|
|
109
|
+
path: string;
|
|
110
|
+
/** Route parameters. */
|
|
111
|
+
params: Record<string, string>;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// =============================================================================
|
|
115
|
+
// Comparison Types
|
|
116
|
+
// =============================================================================
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Result of comparing two NRT snapshots.
|
|
120
|
+
*/
|
|
121
|
+
export interface NRTDiff {
|
|
122
|
+
/** Whether the two snapshots are semantically equivalent. */
|
|
123
|
+
equal: boolean;
|
|
124
|
+
/** List of differences found. */
|
|
125
|
+
changes: NRTChange[];
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* A single difference between two NRT snapshots.
|
|
130
|
+
*/
|
|
131
|
+
export interface NRTChange {
|
|
132
|
+
/** Type of change. */
|
|
133
|
+
type: 'added' | 'removed' | 'modified';
|
|
134
|
+
/** Path to the changed node (e.g., 'root.children[0].children[1]'). */
|
|
135
|
+
path: string;
|
|
136
|
+
/** Node ID if available. */
|
|
137
|
+
nodeId?: string;
|
|
138
|
+
/** What changed. */
|
|
139
|
+
field: string;
|
|
140
|
+
/** Previous value (for modified/removed). */
|
|
141
|
+
oldValue?: unknown;
|
|
142
|
+
/** New value (for modified/added). */
|
|
143
|
+
newValue?: unknown;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// =============================================================================
|
|
147
|
+
// Utilities
|
|
148
|
+
// =============================================================================
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Creates an empty NRT snapshot.
|
|
152
|
+
*/
|
|
153
|
+
export function createEmptyNRT(): NRT {
|
|
154
|
+
return {
|
|
155
|
+
version: 1,
|
|
156
|
+
root: {
|
|
157
|
+
id: 'root',
|
|
158
|
+
type: 'Root',
|
|
159
|
+
visible: true,
|
|
160
|
+
children: [],
|
|
161
|
+
},
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Finds a node by ID in the NRT tree.
|
|
167
|
+
*/
|
|
168
|
+
export function findNode(nrt: NRT, nodeId: string): NRTNode | undefined {
|
|
169
|
+
return findNodeRecursive(nrt.root, nodeId);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function findNodeRecursive(node: NRTNode, nodeId: string): NRTNode | undefined {
|
|
173
|
+
if (node.id === nodeId) return node;
|
|
174
|
+
for (const child of node.children) {
|
|
175
|
+
const found = findNodeRecursive(child, nodeId);
|
|
176
|
+
if (found) return found;
|
|
177
|
+
}
|
|
178
|
+
return undefined;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Finds all visible nodes in the NRT tree.
|
|
183
|
+
*/
|
|
184
|
+
export function findVisibleNodes(nrt: NRT): NRTNode[] {
|
|
185
|
+
const result: NRTNode[] = [];
|
|
186
|
+
collectVisible(nrt.root, result);
|
|
187
|
+
return result;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function collectVisible(node: NRTNode, result: NRTNode[]): void {
|
|
191
|
+
if (node.visible) {
|
|
192
|
+
result.push(node);
|
|
193
|
+
for (const child of node.children) {
|
|
194
|
+
collectVisible(child, result);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Finds all interactive nodes (nodes with events) in the NRT tree.
|
|
201
|
+
*/
|
|
202
|
+
export function findInteractiveNodes(nrt: NRT): NRTNode[] {
|
|
203
|
+
const result: NRTNode[] = [];
|
|
204
|
+
collectInteractive(nrt.root, result);
|
|
205
|
+
return result;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
function collectInteractive(node: NRTNode, result: NRTNode[]): void {
|
|
209
|
+
if (node.events && Object.keys(node.events).length > 0) {
|
|
210
|
+
result.push(node);
|
|
211
|
+
}
|
|
212
|
+
for (const child of node.children) {
|
|
213
|
+
collectInteractive(child, result);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Counts total nodes in the NRT tree.
|
|
219
|
+
*/
|
|
220
|
+
export function countNodes(nrt: NRT): number {
|
|
221
|
+
return countNodesRecursive(nrt.root);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function countNodesRecursive(node: NRTNode): number {
|
|
225
|
+
let count = 1;
|
|
226
|
+
for (const child of node.children) {
|
|
227
|
+
count += countNodesRecursive(child);
|
|
228
|
+
}
|
|
229
|
+
return count;
|
|
230
|
+
}
|