wyreframe 0.1.0 → 0.1.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.
Files changed (59) hide show
  1. package/LICENSE +692 -0
  2. package/README.md +65 -5
  3. package/package.json +8 -7
  4. package/src/index.ts +425 -0
  5. package/src/renderer/Renderer.gen.tsx +49 -0
  6. package/src/renderer/Renderer.mjs +41 -1
  7. package/src/renderer/Renderer.res +78 -0
  8. package/src/test/Expect.mjs +9 -0
  9. package/src/parser/Core/__tests__/Bounds_test.mjs +0 -326
  10. package/src/parser/Core/__tests__/Bounds_test.res +0 -412
  11. package/src/parser/Core/__tests__/Grid_test.mjs +0 -322
  12. package/src/parser/Core/__tests__/Grid_test.res +0 -319
  13. package/src/parser/Core/__tests__/Types_test.mjs +0 -614
  14. package/src/parser/Core/__tests__/Types_test.res +0 -650
  15. package/src/parser/Detector/__tests__/BoxTracer_test.mjs +0 -70
  16. package/src/parser/Detector/__tests__/BoxTracer_test.res +0 -92
  17. package/src/parser/Detector/__tests__/HierarchyBuilder_test.mjs +0 -489
  18. package/src/parser/Detector/__tests__/HierarchyBuilder_test.res +0 -849
  19. package/src/parser/Detector/__tests__/ShapeDetector_test.mjs +0 -377
  20. package/src/parser/Detector/__tests__/ShapeDetector_test.res +0 -563
  21. package/src/parser/Interactions/__tests__/InteractionMerger_test.mjs +0 -576
  22. package/src/parser/Interactions/__tests__/InteractionMerger_test.res +0 -646
  23. package/src/parser/Scanner/__tests__/Grid_manual.mjs +0 -214
  24. package/src/parser/Scanner/__tests__/Grid_manual.res +0 -141
  25. package/src/parser/Semantic/Elements/__tests__/ButtonParser_test.mjs +0 -189
  26. package/src/parser/Semantic/Elements/__tests__/ButtonParser_test.res +0 -257
  27. package/src/parser/Semantic/Elements/__tests__/CheckboxParser_test.mjs +0 -202
  28. package/src/parser/Semantic/Elements/__tests__/CheckboxParser_test.res +0 -250
  29. package/src/parser/Semantic/Elements/__tests__/CodeTextParser_manual.mjs +0 -293
  30. package/src/parser/Semantic/Elements/__tests__/CodeTextParser_manual.res +0 -134
  31. package/src/parser/Semantic/Elements/__tests__/InputParser_test.mjs +0 -253
  32. package/src/parser/Semantic/Elements/__tests__/InputParser_test.res +0 -304
  33. package/src/parser/Semantic/Elements/__tests__/LinkParser_test.mjs +0 -289
  34. package/src/parser/Semantic/Elements/__tests__/LinkParser_test.res +0 -402
  35. package/src/parser/Semantic/Elements/__tests__/TextParser_test.mjs +0 -149
  36. package/src/parser/Semantic/Elements/__tests__/TextParser_test.res +0 -167
  37. package/src/parser/Semantic/__tests__/ASTBuilder_test.mjs +0 -187
  38. package/src/parser/Semantic/__tests__/ASTBuilder_test.res +0 -192
  39. package/src/parser/Semantic/__tests__/ParserRegistry_test.mjs +0 -154
  40. package/src/parser/Semantic/__tests__/ParserRegistry_test.res +0 -191
  41. package/src/parser/Semantic/__tests__/SemanticParser_integration_test.mjs +0 -768
  42. package/src/parser/Semantic/__tests__/SemanticParser_integration_test.res +0 -1069
  43. package/src/parser/Semantic/__tests__/SemanticParser_manual.mjs +0 -1329
  44. package/src/parser/Semantic/__tests__/SemanticParser_manual.res +0 -544
  45. package/src/parser/__tests__/GridScanner_integration.test.mjs +0 -632
  46. package/src/parser/__tests__/GridScanner_integration.test.res +0 -816
  47. package/src/parser/__tests__/Performance.test.mjs +0 -244
  48. package/src/parser/__tests__/Performance.test.res +0 -371
  49. package/src/parser/__tests__/PerformanceFixtures.mjs +0 -200
  50. package/src/parser/__tests__/PerformanceFixtures.res +0 -284
  51. package/src/parser/__tests__/WyreframeParser_integration.test.mjs +0 -770
  52. package/src/parser/__tests__/WyreframeParser_integration.test.res +0 -1008
  53. package/src/parser/__tests__/fixtures/alignment-test.txt +0 -9
  54. package/src/parser/__tests__/fixtures/all-elements.txt +0 -16
  55. package/src/parser/__tests__/fixtures/login-scene.txt +0 -17
  56. package/src/parser/__tests__/fixtures/multi-scene.txt +0 -25
  57. package/src/parser/__tests__/fixtures/nested-boxes.txt +0 -15
  58. package/src/parser/__tests__/fixtures/simple-box.txt +0 -5
  59. package/src/parser/__tests__/fixtures/with-dividers.txt +0 -14
@@ -1,154 +0,0 @@
1
- // Generated by ReScript, PLEASE EDIT WITH CARE
2
-
3
- import * as Types from "../../Core/Types.mjs";
4
- import * as Vitest from "rescript-vitest/src/Vitest.mjs";
5
- import * as LinkParser from "../Elements/LinkParser.mjs";
6
- import * as TextParser from "../Elements/TextParser.mjs";
7
- import * as InputParser from "../Elements/InputParser.mjs";
8
- import * as CheckboxParser from "../Elements/CheckboxParser.mjs";
9
- import * as ParserRegistry from "../ParserRegistry.mjs";
10
-
11
- Vitest.describe("ParserRegistry", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
12
- Vitest.describe("make", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => Vitest.test("creates an empty registry", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
13
- let registry = ParserRegistry.make();
14
- t.expect(registry.parsers.length).toBe(0);
15
- }));
16
- Vitest.describe("register", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
17
- Vitest.test("adds a parser to the registry", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
18
- let registry = ParserRegistry.make();
19
- let parser = TextParser.make();
20
- ParserRegistry.register(registry, parser);
21
- t.expect(registry.parsers.length).toBe(1);
22
- });
23
- Vitest.test("sorts parsers by priority (descending)", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
24
- let registry = ParserRegistry.make();
25
- ParserRegistry.register(registry, TextParser.make());
26
- ParserRegistry.register(registry, InputParser.make());
27
- ParserRegistry.register(registry, CheckboxParser.make());
28
- ParserRegistry.register(registry, LinkParser.make());
29
- t.expect(registry.parsers[0].priority).toBe(90);
30
- t.expect(registry.parsers[1].priority).toBe(85);
31
- t.expect(registry.parsers[2].priority).toBe(80);
32
- t.expect(registry.parsers[3].priority).toBe(1);
33
- });
34
- Vitest.test("maintains sort order when registering multiple parsers", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
35
- let registry = ParserRegistry.make();
36
- ParserRegistry.register(registry, LinkParser.make());
37
- ParserRegistry.register(registry, InputParser.make());
38
- ParserRegistry.register(registry, TextParser.make());
39
- t.expect(registry.parsers[0].priority).toBe(90);
40
- t.expect(registry.parsers[1].priority).toBe(80);
41
- t.expect(registry.parsers[2].priority).toBe(1);
42
- });
43
- });
44
- Vitest.describe("parse", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
45
- let testPosition = Types.Position.make(0, 0);
46
- let testBounds = Types.Bounds.make(0, 0, 10, 10);
47
- Vitest.test("tries parsers in priority order", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
48
- let registry = ParserRegistry.make();
49
- ParserRegistry.register(registry, InputParser.make());
50
- ParserRegistry.register(registry, TextParser.make());
51
- let result = ParserRegistry.parse(registry, "#email", testPosition, testBounds);
52
- if (result.TAG === "Input") {
53
- return t.expect(result.id).toBe("email");
54
- } else {
55
- return t.expect(true).toBe(false);
56
- }
57
- });
58
- Vitest.test("falls back to lower priority parser if higher priority fails", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
59
- let registry = ParserRegistry.make();
60
- ParserRegistry.register(registry, InputParser.make());
61
- ParserRegistry.register(registry, TextParser.make());
62
- let result = ParserRegistry.parse(registry, "plain text", testPosition, testBounds);
63
- if (result.TAG === "Text") {
64
- return t.expect(result.content).toBe("plain text");
65
- } else {
66
- return t.expect(true).toBe(false);
67
- }
68
- });
69
- Vitest.test("parses checkbox content correctly", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
70
- let registry = ParserRegistry.make();
71
- ParserRegistry.register(registry, CheckboxParser.make());
72
- ParserRegistry.register(registry, TextParser.make());
73
- let result = ParserRegistry.parse(registry, "[x] Accept terms", testPosition, testBounds);
74
- if (result.TAG !== "Checkbox") {
75
- return t.expect(true).toBe(false);
76
- }
77
- t.expect(result.checked).toBe(true);
78
- t.expect(result.label).toBe("Accept terms");
79
- });
80
- Vitest.test("parses link content correctly", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
81
- let registry = ParserRegistry.make();
82
- ParserRegistry.register(registry, LinkParser.make());
83
- ParserRegistry.register(registry, TextParser.make());
84
- let result = ParserRegistry.parse(registry, "\"Click Here\"", testPosition, testBounds);
85
- if (result.TAG !== "Link") {
86
- return t.expect(true).toBe(false);
87
- }
88
- t.expect(result.text).toBe("Click Here");
89
- t.expect(result.id).toBe("click-here");
90
- });
91
- Vitest.test("returns text element as fallback when no parser matches", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
92
- let registry = ParserRegistry.make();
93
- ParserRegistry.register(registry, InputParser.make());
94
- let result = ParserRegistry.parse(registry, "unmatched content", testPosition, testBounds);
95
- if (result.TAG === "Text") {
96
- return t.expect(result.content).toBe("unmatched content");
97
- } else {
98
- return t.expect(true).toBe(false);
99
- }
100
- });
101
- });
102
- Vitest.describe("makeDefault", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
103
- Vitest.test("creates registry with built-in parsers", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
104
- let registry = ParserRegistry.makeDefault();
105
- t.expect(registry.parsers.length).toBeGreaterThanOrEqual(4);
106
- });
107
- Vitest.test("default registry can parse input fields", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
108
- let registry = ParserRegistry.makeDefault();
109
- let testPosition = Types.Position.make(5, 10);
110
- let testBounds = Types.Bounds.make(0, 0, 20, 30);
111
- let result = ParserRegistry.parse(registry, "#password", testPosition, testBounds);
112
- if (result.TAG === "Input") {
113
- return t.expect(result.id).toBe("password");
114
- } else {
115
- return t.expect(true).toBe(false);
116
- }
117
- });
118
- Vitest.test("default registry can parse checkboxes", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
119
- let registry = ParserRegistry.makeDefault();
120
- let testPosition = Types.Position.make(0, 0);
121
- let testBounds = Types.Bounds.make(0, 0, 10, 10);
122
- let result = ParserRegistry.parse(registry, "[ ] Unchecked", testPosition, testBounds);
123
- if (result.TAG === "Checkbox") {
124
- return t.expect(result.checked).toBe(false);
125
- } else {
126
- return t.expect(true).toBe(false);
127
- }
128
- });
129
- Vitest.test("default registry can parse links", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
130
- let registry = ParserRegistry.makeDefault();
131
- let testPosition = Types.Position.make(0, 0);
132
- let testBounds = Types.Bounds.make(0, 0, 10, 10);
133
- let result = ParserRegistry.parse(registry, "\"Sign Up\"", testPosition, testBounds);
134
- if (result.TAG === "Link") {
135
- return t.expect(result.text).toBe("Sign Up");
136
- } else {
137
- return t.expect(true).toBe(false);
138
- }
139
- });
140
- Vitest.test("default registry falls back to text for unrecognized content", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, t => {
141
- let registry = ParserRegistry.makeDefault();
142
- let testPosition = Types.Position.make(0, 0);
143
- let testBounds = Types.Bounds.make(0, 0, 10, 10);
144
- let result = ParserRegistry.parse(registry, "Random text", testPosition, testBounds);
145
- if (result.TAG === "Text") {
146
- return t.expect(result.content).toBe("Random text");
147
- } else {
148
- return t.expect(true).toBe(false);
149
- }
150
- });
151
- });
152
- });
153
-
154
- /* Not a pure module */
@@ -1,191 +0,0 @@
1
- // ParserRegistry_test.res
2
- // Unit tests for ParserRegistry module
3
-
4
- open Vitest
5
-
6
- describe("ParserRegistry", t => {
7
- describe("make", t => {
8
- test("creates an empty registry", t => {
9
- let registry = ParserRegistry.make()
10
- t->expect(registry.parsers->Array.length)->Expect.toBe(0)
11
- })
12
- })
13
-
14
- describe("register", t => {
15
- test("adds a parser to the registry", t => {
16
- let registry = ParserRegistry.make()
17
- let parser = TextParser.make()
18
-
19
- registry->ParserRegistry.register(parser)
20
-
21
- t->expect(registry.parsers->Array.length)->Expect.toBe(1)
22
- })
23
-
24
- test("sorts parsers by priority (descending)", t => {
25
- let registry = ParserRegistry.make()
26
-
27
- // Register parsers in random order
28
- registry->ParserRegistry.register(TextParser.make()) // priority 1
29
- registry->ParserRegistry.register(InputParser.make()) // priority 90
30
- registry->ParserRegistry.register(CheckboxParser.make()) // priority 85
31
- registry->ParserRegistry.register(LinkParser.make()) // priority 80
32
-
33
- // Verify they are sorted by priority descending
34
- t->expect(Array.getUnsafe(registry.parsers, 0).priority)->Expect.toBe(90) // InputParser
35
- t->expect(Array.getUnsafe(registry.parsers, 1).priority)->Expect.toBe(85) // CheckboxParser
36
- t->expect(Array.getUnsafe(registry.parsers, 2).priority)->Expect.toBe(80) // LinkParser
37
- t->expect(Array.getUnsafe(registry.parsers, 3).priority)->Expect.toBe(1) // TextParser
38
- })
39
-
40
- test("maintains sort order when registering multiple parsers", t => {
41
- let registry = ParserRegistry.make()
42
-
43
- registry->ParserRegistry.register(LinkParser.make()) // priority 80
44
- registry->ParserRegistry.register(InputParser.make()) // priority 90
45
- registry->ParserRegistry.register(TextParser.make()) // priority 1
46
-
47
- t->expect(Array.getUnsafe(registry.parsers, 0).priority)->Expect.toBe(90)
48
- t->expect(Array.getUnsafe(registry.parsers, 1).priority)->Expect.toBe(80)
49
- t->expect(Array.getUnsafe(registry.parsers, 2).priority)->Expect.toBe(1)
50
- })
51
- })
52
-
53
- describe("parse", t => {
54
- let testPosition = Types.Position.make(0, 0)
55
- let testBounds = Types.Bounds.make(~top=0, ~left=0, ~bottom=10, ~right=10)
56
-
57
- test("tries parsers in priority order", t => {
58
- let registry = ParserRegistry.make()
59
- registry->ParserRegistry.register(InputParser.make())
60
- registry->ParserRegistry.register(TextParser.make())
61
-
62
- // Should match InputParser (higher priority)
63
- let result = registry->ParserRegistry.parse("#email", testPosition, testBounds)
64
-
65
- switch result {
66
- | Types.Input({id}) => t->expect(id)->Expect.toBe("email")
67
- | _ => t->expect(true)->Expect.toBe(false) // fail: Expected Input element
68
- }
69
- })
70
-
71
- test("falls back to lower priority parser if higher priority fails", t => {
72
- let registry = ParserRegistry.make()
73
- registry->ParserRegistry.register(InputParser.make())
74
- registry->ParserRegistry.register(TextParser.make())
75
-
76
- // Should fall back to TextParser (InputParser won't match)
77
- let result = registry->ParserRegistry.parse("plain text", testPosition, testBounds)
78
-
79
- switch result {
80
- | Types.Text({content}) => t->expect(content)->Expect.toBe("plain text")
81
- | _ => t->expect(true)->Expect.toBe(false) // fail: Expected Text element
82
- }
83
- })
84
-
85
- test("parses checkbox content correctly", t => {
86
- let registry = ParserRegistry.make()
87
- registry->ParserRegistry.register(CheckboxParser.make())
88
- registry->ParserRegistry.register(TextParser.make())
89
-
90
- let result = registry->ParserRegistry.parse("[x] Accept terms", testPosition, testBounds)
91
-
92
- switch result {
93
- | Types.Checkbox({checked, label}) => {
94
- t->expect(checked)->Expect.toBe(true)
95
- t->expect(label)->Expect.toBe("Accept terms")
96
- }
97
- | _ => t->expect(true)->Expect.toBe(false) // fail: Expected Checkbox element
98
- }
99
- })
100
-
101
- test("parses link content correctly", t => {
102
- let registry = ParserRegistry.make()
103
- registry->ParserRegistry.register(LinkParser.make())
104
- registry->ParserRegistry.register(TextParser.make())
105
-
106
- let result = registry->ParserRegistry.parse("\"Click Here\"", testPosition, testBounds)
107
-
108
- switch result {
109
- | Types.Link({text, id}) => {
110
- t->expect(text)->Expect.toBe("Click Here")
111
- t->expect(id)->Expect.toBe("click-here")
112
- }
113
- | _ => t->expect(true)->Expect.toBe(false) // fail: Expected Link element
114
- }
115
- })
116
-
117
- test("returns text element as fallback when no parser matches", t => {
118
- // Create registry without TextParser to test fallback
119
- let registry = ParserRegistry.make()
120
- registry->ParserRegistry.register(InputParser.make())
121
-
122
- let result = registry->ParserRegistry.parse("unmatched content", testPosition, testBounds)
123
-
124
- switch result {
125
- | Types.Text({content}) => t->expect(content)->Expect.toBe("unmatched content")
126
- | _ => t->expect(true)->Expect.toBe(false) // fail: Expected fallback Text element
127
- }
128
- })
129
- })
130
-
131
- describe("makeDefault", t => {
132
- test("creates registry with built-in parsers", t => {
133
- let registry = ParserRegistry.makeDefault()
134
-
135
- // Should have at least InputParser, CheckboxParser, LinkParser, TextParser
136
- t->expect(registry.parsers->Array.length)->Expect.Int.toBeGreaterThanOrEqual(4)
137
- })
138
-
139
- test("default registry can parse input fields", t => {
140
- let registry = ParserRegistry.makeDefault()
141
- let testPosition = Types.Position.make(5, 10)
142
- let testBounds = Types.Bounds.make(~top=0, ~left=0, ~bottom=20, ~right=30)
143
-
144
- let result = registry->ParserRegistry.parse("#password", testPosition, testBounds)
145
-
146
- switch result {
147
- | Types.Input({id}) => t->expect(id)->Expect.toBe("password")
148
- | _ => t->expect(true)->Expect.toBe(false) // fail: Expected Input element
149
- }
150
- })
151
-
152
- test("default registry can parse checkboxes", t => {
153
- let registry = ParserRegistry.makeDefault()
154
- let testPosition = Types.Position.make(0, 0)
155
- let testBounds = Types.Bounds.make(~top=0, ~left=0, ~bottom=10, ~right=10)
156
-
157
- let result = registry->ParserRegistry.parse("[ ] Unchecked", testPosition, testBounds)
158
-
159
- switch result {
160
- | Types.Checkbox({checked}) => t->expect(checked)->Expect.toBe(false)
161
- | _ => t->expect(true)->Expect.toBe(false) // fail: Expected Checkbox element
162
- }
163
- })
164
-
165
- test("default registry can parse links", t => {
166
- let registry = ParserRegistry.makeDefault()
167
- let testPosition = Types.Position.make(0, 0)
168
- let testBounds = Types.Bounds.make(~top=0, ~left=0, ~bottom=10, ~right=10)
169
-
170
- let result = registry->ParserRegistry.parse("\"Sign Up\"", testPosition, testBounds)
171
-
172
- switch result {
173
- | Types.Link({text}) => t->expect(text)->Expect.toBe("Sign Up")
174
- | _ => t->expect(true)->Expect.toBe(false) // fail: Expected Link element
175
- }
176
- })
177
-
178
- test("default registry falls back to text for unrecognized content", t => {
179
- let registry = ParserRegistry.makeDefault()
180
- let testPosition = Types.Position.make(0, 0)
181
- let testBounds = Types.Bounds.make(~top=0, ~left=0, ~bottom=10, ~right=10)
182
-
183
- let result = registry->ParserRegistry.parse("Random text", testPosition, testBounds)
184
-
185
- switch result {
186
- | Types.Text({content}) => t->expect(content)->Expect.toBe("Random text")
187
- | _ => t->expect(true)->Expect.toBe(false) // fail: Expected Text element
188
- }
189
- })
190
- })
191
- })