wyreframe 0.1.5 → 0.2.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.
@@ -69,17 +69,23 @@ function mergeInteractionsIntoAST(ast, sceneInteractions) {
69
69
  }
70
70
  }
71
71
 
72
- function parseSingleScene(sceneContent, sceneMetadata, errors) {
72
+ function parseSingleScene(sceneContent, sceneMetadata, lineOffset, errors) {
73
73
  let gridResult = scanGrid(sceneContent);
74
74
  if (gridResult.TAG === "Ok") {
75
75
  let grid = gridResult._0;
76
76
  let shapesResult = ShapeDetector.detect(grid);
77
77
  let shapes;
78
78
  if (shapesResult.TAG === "Ok") {
79
- shapes = shapesResult._0;
79
+ let match = shapesResult._0;
80
+ match[1].forEach(w => {
81
+ let adjusted = ErrorTypes.adjustLineOffset(w, lineOffset);
82
+ errors.push(adjusted);
83
+ });
84
+ shapes = match[0];
80
85
  } else {
81
86
  shapesResult._0.forEach(err => {
82
- errors.push(err);
87
+ let adjusted = ErrorTypes.adjustLineOffset(err, lineOffset);
88
+ errors.push(adjusted);
83
89
  });
84
90
  shapes = [];
85
91
  }
@@ -106,28 +112,32 @@ function parseSingleScene(sceneContent, sceneMetadata, errors) {
106
112
  };
107
113
  }
108
114
  gridResult._0.forEach(err => {
109
- errors.push(err);
115
+ let adjusted = ErrorTypes.adjustLineOffset(err, lineOffset);
116
+ errors.push(adjusted);
110
117
  });
111
118
  }
112
119
 
113
120
  function parseInternal(wireframe, interactions) {
114
- let allErrors = [];
121
+ let allIssues = [];
115
122
  let sceneBlocks = SemanticParser.splitSceneBlocks(wireframe);
116
123
  let trimmed = wireframe.trim();
117
124
  if (sceneBlocks.length === 0 && trimmed === "") {
118
125
  return {
119
126
  TAG: "Ok",
120
- _0: {
121
- scenes: []
122
- }
127
+ _0: [
128
+ {
129
+ scenes: []
130
+ },
131
+ []
132
+ ]
123
133
  };
124
134
  }
125
135
  let scenes = [];
126
136
  sceneBlocks.forEach(block => {
127
137
  let lines = block.split("\n");
128
- let match = SemanticParser.parseSceneDirectives(lines);
129
- let sceneContent = match[1].join("\n");
130
- let scene = parseSingleScene(sceneContent, match[0], allErrors);
138
+ let match = SemanticParser.parseSceneDirectivesWithOffset(lines);
139
+ let sceneContent = match.contentLines.join("\n");
140
+ let scene = parseSingleScene(sceneContent, match.metadata, match.lineOffset, allIssues);
131
141
  if (scene !== undefined) {
132
142
  scenes.push(scene);
133
143
  return;
@@ -143,23 +153,28 @@ function parseInternal(wireframe, interactions) {
143
153
  finalAst = mergeInteractionsIntoAST(baseAst, interactionsResult._0);
144
154
  } else {
145
155
  interactionsResult._0.forEach(err => {
146
- allErrors.push(err);
156
+ allIssues.push(err);
147
157
  });
148
158
  finalAst = baseAst;
149
159
  }
150
160
  } else {
151
161
  finalAst = baseAst;
152
162
  }
163
+ let errors = allIssues.filter(ErrorTypes.isError);
164
+ let warnings = allIssues.filter(ErrorTypes.isWarning);
153
165
  let totalElements = Core__Array.reduce(finalAst.scenes, 0, (acc, scene) => acc + scene.elements.length | 0);
154
- if (allErrors.length > 0 && totalElements === 0) {
166
+ if (errors.length > 0 && totalElements === 0) {
155
167
  return {
156
168
  TAG: "Error",
157
- _0: allErrors
169
+ _0: allIssues
158
170
  };
159
171
  } else {
160
172
  return {
161
173
  TAG: "Ok",
162
- _0: finalAst
174
+ _0: [
175
+ finalAst,
176
+ warnings
177
+ ]
163
178
  };
164
179
  }
165
180
  }
@@ -8,10 +8,11 @@
8
8
  // ============================================================================
9
9
 
10
10
  /**
11
- * Parse result type - either a successful AST or an array of parse errors.
11
+ * Parse result type - either a successful (AST, warnings) tuple or an array of parse errors.
12
+ * Warnings are non-fatal issues like misaligned borders that don't prevent parsing.
12
13
  * This Result type is compatible with TypeScript through GenType.
13
14
  */
14
- type parseResult = result<Types.ast, array<ErrorTypes.t>>
15
+ type parseResult = result<(Types.ast, array<ErrorTypes.t>), array<ErrorTypes.t>>
15
16
 
16
17
  /**
17
18
  * Interaction parse result type.
@@ -65,11 +66,11 @@ let scanGrid = (wireframe: string): result<Grid.t, array<ErrorTypes.t>> => {
65
66
  * and builds parent-child hierarchy.
66
67
  *
67
68
  * @param grid The 2D grid from Stage 1
68
- * @returns Result containing root boxes or errors
69
+ * @returns Result containing (root boxes, warnings) or errors
69
70
  *
70
71
  * Requirements: REQ-3, REQ-4, REQ-5, REQ-6, REQ-7 (Shape Detection)
71
72
  */
72
- let detectShapes = (grid: Grid.t): result<array<box>, array<ErrorTypes.t>> => {
73
+ let detectShapes = (grid: Grid.t): result<(array<box>, array<ErrorTypes.t>), array<ErrorTypes.t>> => {
73
74
  // Use ShapeDetector to detect all shapes in the grid
74
75
  ShapeDetector.detect(grid)
75
76
  }
@@ -190,12 +191,14 @@ let mergeInteractionsIntoAST = (
190
191
  *
191
192
  * @param sceneContent ASCII wireframe content for one scene (without directives)
192
193
  * @param sceneMetadata Scene metadata from directives
194
+ * @param lineOffset Number of directive lines stripped (for adjusting error line numbers)
193
195
  * @param errors Accumulator for errors
194
196
  * @returns Parsed scene or None if parsing failed
195
197
  */
196
198
  let parseSingleScene = (
197
199
  sceneContent: string,
198
200
  sceneMetadata: SemanticParser.sceneMetadata,
201
+ lineOffset: int,
199
202
  errors: array<ErrorTypes.t>,
200
203
  ): option<Types.scene> => {
201
204
  // Stage 1: Grid Scanner
@@ -203,7 +206,11 @@ let parseSingleScene = (
203
206
 
204
207
  switch gridResult {
205
208
  | Error(gridErrors) => {
206
- gridErrors->Array.forEach(err => errors->Array.push(err)->ignore)
209
+ // Adjust line numbers by offset before adding to errors
210
+ gridErrors->Array.forEach(err => {
211
+ let adjusted = ErrorTypes.adjustLineOffset(err, lineOffset)
212
+ errors->Array.push(adjusted)->ignore
213
+ })
207
214
  None
208
215
  }
209
216
  | Ok(grid) => {
@@ -212,10 +219,22 @@ let parseSingleScene = (
212
219
 
213
220
  let shapes = switch shapesResult {
214
221
  | Error(shapeErrors) => {
215
- shapeErrors->Array.forEach(err => errors->Array.push(err)->ignore)
222
+ // Adjust line numbers by offset before adding to errors
223
+ shapeErrors->Array.forEach(err => {
224
+ let adjusted = ErrorTypes.adjustLineOffset(err, lineOffset)
225
+ errors->Array.push(adjusted)->ignore
226
+ })
216
227
  []
217
228
  }
218
- | Ok(shapes) => shapes
229
+ | Ok((boxes, warnings)) => {
230
+ // Collect warnings (non-fatal issues like misaligned borders)
231
+ // Adjust line numbers by offset before adding to errors
232
+ warnings->Array.forEach(w => {
233
+ let adjusted = ErrorTypes.adjustLineOffset(w, lineOffset)
234
+ errors->Array.push(adjusted)->ignore
235
+ })
236
+ boxes
237
+ }
219
238
  }
220
239
 
221
240
  // Stage 3: Parse box content into elements
@@ -273,8 +292,8 @@ let parseSingleScene = (
273
292
  * @returns Result containing AST or array of parse errors
274
293
  */
275
294
  let parseInternal = (wireframe: string, interactions: option<string>): parseResult => {
276
- // Accumulator for all errors across stages
277
- let allErrors = []
295
+ // Accumulator for all issues (errors and warnings) across stages
296
+ let allIssues = []
278
297
 
279
298
  // Split wireframe into scene blocks
280
299
  let sceneBlocks = SemanticParser.splitSceneBlocks(wireframe)
@@ -282,22 +301,23 @@ let parseInternal = (wireframe: string, interactions: option<string>): parseResu
282
301
  // Check if wireframe is empty
283
302
  let trimmed = wireframe->String.trim
284
303
  if sceneBlocks->Array.length === 0 && trimmed === "" {
285
- // Empty wireframe - return empty AST
286
- Ok({scenes: []})
304
+ // Empty wireframe - return empty AST with no warnings
305
+ Ok(({scenes: []}: Types.ast, []))
287
306
  } else {
288
307
  // Parse each scene block
289
308
  let scenes = []
290
309
 
291
310
  sceneBlocks->Array.forEach(block => {
292
- // Parse scene directives
311
+ // Parse scene directives and get line offset
293
312
  let lines = block->String.split("\n")
294
- let (metadata, contentLines) = SemanticParser.parseSceneDirectives(lines)
313
+ let {metadata, contentLines, lineOffset} = SemanticParser.parseSceneDirectivesWithOffset(lines)
295
314
 
296
315
  // Rejoin content lines (without directives)
297
316
  let sceneContent = contentLines->Array.join("\n")
298
317
 
299
318
  // Parse this scene through 3-stage pipeline
300
- switch parseSingleScene(sceneContent, metadata, allErrors) {
319
+ // Pass lineOffset to adjust error/warning line numbers
320
+ switch parseSingleScene(sceneContent, metadata, lineOffset, allIssues) {
301
321
  | Some(scene) => scenes->Array.push(scene)->ignore
302
322
  | None => () // Scene parsing failed, errors already collected
303
323
  }
@@ -314,7 +334,7 @@ let parseInternal = (wireframe: string, interactions: option<string>): parseResu
314
334
 
315
335
  switch interactionsResult {
316
336
  | Error(errors) => {
317
- errors->Array.forEach(err => allErrors->Array.push(err)->ignore)
337
+ errors->Array.forEach(err => allIssues->Array.push(err)->ignore)
318
338
  baseAst // Return AST without interactions on error
319
339
  }
320
340
  | Ok(sceneInteractions) => {
@@ -325,19 +345,23 @@ let parseInternal = (wireframe: string, interactions: option<string>): parseResu
325
345
  }
326
346
  }
327
347
 
348
+ // Separate errors from warnings
349
+ let errors = allIssues->Array.filter(issue => ErrorTypes.isError(issue))
350
+ let warnings = allIssues->Array.filter(issue => ErrorTypes.isWarning(issue))
351
+
328
352
  // Return final result
329
- // Return Error if all boxes failed to parse and we have errors
330
- // Return Ok if at least some elements were parsed successfully
353
+ // Return Error if all boxes failed to parse and we have actual errors
354
+ // Return Ok with warnings if at least some elements were parsed successfully
331
355
  let totalElements = finalAst.scenes->Array.reduce(0, (acc, scene) => {
332
356
  acc + Array.length(scene.elements)
333
357
  })
334
358
 
335
- if Array.length(allErrors) > 0 && totalElements === 0 {
336
- // No elements parsed and we have errors - return error
337
- Error(allErrors)
359
+ if Array.length(errors) > 0 && totalElements === 0 {
360
+ // No elements parsed and we have errors - return error (include warnings too)
361
+ Error(allIssues)
338
362
  } else {
339
- // Either no errors, or some elements were parsed - return Ok
340
- Ok(finalAst)
363
+ // Either no errors, or some elements were parsed - return Ok with warnings
364
+ Ok((finalAst, warnings))
341
365
  }
342
366
  }
343
367
  }
@@ -141,7 +141,7 @@ function defaultSceneMetadata() {
141
141
  };
142
142
  }
143
143
 
144
- function parseSceneDirectives(lines) {
144
+ function parseSceneDirectivesWithOffset(lines) {
145
145
  let sceneId = {
146
146
  contents: undefined
147
147
  };
@@ -155,7 +155,10 @@ function parseSceneDirectives(lines) {
155
155
  contents: undefined
156
156
  };
157
157
  let contentLines = [];
158
- lines.forEach(line => {
158
+ let firstContentLineIndex = {
159
+ contents: undefined
160
+ };
161
+ lines.forEach((line, lineIndex) => {
159
162
  let trimmed = line.trim();
160
163
  if (trimmed.startsWith("@scene:")) {
161
164
  let id = trimmed.replace("@scene:", "").trim();
@@ -176,6 +179,9 @@ function parseSceneDirectives(lines) {
176
179
  if (trimmed.startsWith("@")) {
177
180
  return;
178
181
  } else {
182
+ if (firstContentLineIndex.contents === undefined) {
183
+ firstContentLineIndex.contents = lineIndex;
184
+ }
179
185
  contentLines.push(line);
180
186
  return;
181
187
  }
@@ -204,9 +210,20 @@ function parseSceneDirectives(lines) {
204
210
  transition: finalTransition,
205
211
  device: finalDevice
206
212
  };
213
+ let idx = firstContentLineIndex.contents;
214
+ let lineOffset = idx !== undefined ? idx : 0;
215
+ return {
216
+ metadata: metadata,
217
+ contentLines: contentLines,
218
+ lineOffset: lineOffset
219
+ };
220
+ }
221
+
222
+ function parseSceneDirectives(lines) {
223
+ let result = parseSceneDirectivesWithOffset(lines);
207
224
  return [
208
- metadata,
209
- contentLines
225
+ result.metadata,
226
+ result.contentLines
210
227
  ];
211
228
  }
212
229
 
@@ -824,6 +841,7 @@ export {
824
841
  hasContent,
825
842
  getContentLineCount,
826
843
  defaultSceneMetadata,
844
+ parseSceneDirectivesWithOffset,
827
845
  parseSceneDirectives,
828
846
  splitSceneBlocks,
829
847
  groupContentByScenes,
@@ -261,7 +261,32 @@ let defaultSceneMetadata = (): sceneMetadata => {
261
261
  * ```
262
262
  * Returns: ({id: "login", title: "Login Page", transition: "slide"}, ["+--Login--+", ...])
263
263
  */
264
- let parseSceneDirectives = (lines: array<string>): (sceneMetadata, array<string>) => {
264
+ /**
265
+ * Result type for parseSceneDirectives that includes line offset information.
266
+ * The lineOffset indicates how many lines were removed from the beginning
267
+ * before the first content line, which is needed to correctly report
268
+ * line numbers in warnings and errors.
269
+ */
270
+ type directiveParseResult = {
271
+ metadata: sceneMetadata,
272
+ contentLines: array<string>,
273
+ lineOffset: int, // Number of directive lines stripped from the beginning
274
+ }
275
+
276
+ /**
277
+ * Parse scene directives and track line offset.
278
+ * Returns metadata, content lines, and the number of lines stripped from the beginning.
279
+ *
280
+ * The lineOffset is calculated as the index of the first content line in the original
281
+ * input. This offset is needed to convert grid row numbers back to original file line numbers.
282
+ *
283
+ * Example:
284
+ * - Input: ["@scene: login", "", "+---+", ...]
285
+ * - Output: contentLines = ["", "+---+", ...], lineOffset = 1
286
+ *
287
+ * Grid row 0 corresponds to original line (0 + lineOffset + 1) = line 2 (1-indexed)
288
+ */
289
+ let parseSceneDirectivesWithOffset = (lines: array<string>): directiveParseResult => {
265
290
  // Use mutable refs to accumulate directive values
266
291
  let sceneId = ref(None)
267
292
  let title = ref(None)
@@ -269,7 +294,10 @@ let parseSceneDirectives = (lines: array<string>): (sceneMetadata, array<string>
269
294
  let device = ref(None)
270
295
  let contentLines = []
271
296
 
272
- lines->Array.forEach(line => {
297
+ // Track the index of the first content line (for line offset calculation)
298
+ let firstContentLineIndex = ref(None)
299
+
300
+ lines->Array.forEachWithIndex((line, lineIndex) => {
273
301
  let trimmed = line->String.trim
274
302
 
275
303
  if trimmed->String.startsWith("@scene:") {
@@ -301,6 +329,10 @@ let parseSceneDirectives = (lines: array<string>): (sceneMetadata, array<string>
301
329
  ()
302
330
  } else {
303
331
  // Non-directive line - add to content
332
+ // Track the index of the first content line
333
+ if firstContentLineIndex.contents === None {
334
+ firstContentLineIndex := Some(lineIndex)
335
+ }
304
336
  contentLines->Array.push(line)
305
337
  }
306
338
  })
@@ -334,7 +366,27 @@ let parseSceneDirectives = (lines: array<string>): (sceneMetadata, array<string>
334
366
  device: finalDevice,
335
367
  }
336
368
 
337
- (metadata, contentLines)
369
+ // Calculate line offset: index of first content line
370
+ // If no content lines, offset is 0
371
+ let lineOffset = switch firstContentLineIndex.contents {
372
+ | Some(idx) => idx
373
+ | None => 0
374
+ }
375
+
376
+ {
377
+ metadata,
378
+ contentLines,
379
+ lineOffset,
380
+ }
381
+ }
382
+
383
+ /**
384
+ * Parse scene directives from an array of lines.
385
+ * This is the original API that returns just (metadata, contentLines) for backward compatibility.
386
+ */
387
+ let parseSceneDirectives = (lines: array<string>): (sceneMetadata, array<string>) => {
388
+ let result = parseSceneDirectivesWithOffset(lines)
389
+ (result.metadata, result.contentLines)
338
390
  }
339
391
 
340
392
  /**
@@ -22,6 +22,11 @@ export type renderOptions = {
22
22
  /** * Scene management interface returned by render function. */
23
23
  export type sceneManager = {
24
24
  readonly goto: (_1:string) => void;
25
+ readonly back: () => void;
26
+ readonly forward: () => void;
27
+ readonly refresh: () => void;
28
+ readonly canGoBack: () => boolean;
29
+ readonly canGoForward: () => boolean;
25
30
  readonly getCurrentScene: () => (undefined | string);
26
31
  readonly getSceneIds: () => string[]
27
32
  };
@@ -34,7 +39,8 @@ export type renderResult = { readonly root: DomBindings_element; readonly sceneM
34
39
  export type createUISuccessResult = {
35
40
  readonly root: DomBindings_element;
36
41
  readonly sceneManager: sceneManager;
37
- readonly ast: Types_ast
42
+ readonly ast: Types_ast;
43
+ readonly warnings: ErrorTypes_t[]
38
44
  };
39
45
 
40
46
  export type createUIResult =
@@ -284,7 +284,13 @@ function createSceneManager(scenes) {
284
284
  let currentScene = {
285
285
  contents: undefined
286
286
  };
287
- let goto = id => {
287
+ let historyStack = {
288
+ contents: []
289
+ };
290
+ let forwardStack = {
291
+ contents: []
292
+ };
293
+ let switchToScene = id => {
288
294
  let currentId = currentScene.contents;
289
295
  if (currentId !== undefined) {
290
296
  let el = scenes.get(currentId);
@@ -299,10 +305,74 @@ function createSceneManager(scenes) {
299
305
  return;
300
306
  }
301
307
  };
308
+ let goto = id => {
309
+ let currentId = currentScene.contents;
310
+ if (currentId !== undefined && currentId !== id) {
311
+ historyStack.contents = historyStack.contents.concat([currentId]);
312
+ forwardStack.contents = [];
313
+ }
314
+ switchToScene(id);
315
+ };
316
+ let back = () => {
317
+ let history = historyStack.contents;
318
+ let len = history.length;
319
+ if (len <= 0) {
320
+ return;
321
+ }
322
+ let prevId = history[len - 1 | 0];
323
+ if (prevId === undefined) {
324
+ return;
325
+ }
326
+ let currentId = currentScene.contents;
327
+ if (currentId !== undefined) {
328
+ forwardStack.contents = forwardStack.contents.concat([currentId]);
329
+ }
330
+ historyStack.contents = history.slice(0, len - 1 | 0);
331
+ switchToScene(prevId);
332
+ };
333
+ let forward = () => {
334
+ let fwdStack = forwardStack.contents;
335
+ let len = fwdStack.length;
336
+ if (len <= 0) {
337
+ return;
338
+ }
339
+ let nextId = fwdStack[len - 1 | 0];
340
+ if (nextId === undefined) {
341
+ return;
342
+ }
343
+ let currentId = currentScene.contents;
344
+ if (currentId !== undefined) {
345
+ historyStack.contents = historyStack.contents.concat([currentId]);
346
+ }
347
+ forwardStack.contents = fwdStack.slice(0, len - 1 | 0);
348
+ switchToScene(nextId);
349
+ };
350
+ let refresh = () => {
351
+ let id = currentScene.contents;
352
+ if (id === undefined) {
353
+ return;
354
+ }
355
+ let el = scenes.get(id);
356
+ if (el === undefined) {
357
+ return;
358
+ }
359
+ let el$1 = Primitive_option.valFromOption(el);
360
+ el$1.classList.remove("active");
361
+ setTimeout(() => {
362
+ el$1.classList.add("active");
363
+ }, 0);
364
+ };
365
+ let canGoBack = () => historyStack.contents.length > 0;
366
+ let canGoForward = () => forwardStack.contents.length > 0;
302
367
  let getCurrentScene = () => currentScene.contents;
303
368
  let getSceneIds = () => Array.from(scenes.keys());
304
369
  return {
305
370
  goto: goto,
371
+ back: back,
372
+ forward: forward,
373
+ refresh: refresh,
374
+ canGoBack: canGoBack,
375
+ canGoForward: canGoForward,
306
376
  getCurrentScene: getCurrentScene,
307
377
  getSceneIds: getSceneIds
308
378
  };
@@ -338,16 +408,41 @@ function render(ast, options) {
338
408
  let gotoRef = {
339
409
  contents: undefined
340
410
  };
411
+ let backRef = {
412
+ contents: undefined
413
+ };
414
+ let forwardRef = {
415
+ contents: undefined
416
+ };
341
417
  let handleAction = action => {
342
418
  if (typeof action !== "object") {
343
- return;
344
- }
345
- if (action.TAG !== "Goto") {
346
- return;
347
- }
348
- let goto = gotoRef.contents;
349
- if (goto !== undefined) {
350
- return goto(action.target);
419
+ if (action === "Back") {
420
+ let back = backRef.contents;
421
+ if (back !== undefined) {
422
+ return back();
423
+ } else {
424
+ return;
425
+ }
426
+ }
427
+ let forward = forwardRef.contents;
428
+ if (forward !== undefined) {
429
+ return forward();
430
+ } else {
431
+ return;
432
+ }
433
+ } else {
434
+ switch (action.TAG) {
435
+ case "Goto" :
436
+ let goto = gotoRef.contents;
437
+ if (goto !== undefined) {
438
+ return goto(action.target);
439
+ } else {
440
+ return;
441
+ }
442
+ case "Validate" :
443
+ case "Call" :
444
+ return;
445
+ }
351
446
  }
352
447
  };
353
448
  let sceneMap = new Map();
@@ -358,6 +453,8 @@ function render(ast, options) {
358
453
  });
359
454
  let manager = createSceneManager(sceneMap);
360
455
  gotoRef.contents = manager.goto;
456
+ backRef.contents = manager.back;
457
+ forwardRef.contents = manager.forward;
361
458
  if (ast.scenes.length > 0) {
362
459
  let firstScene$1 = ast.scenes[0];
363
460
  if (firstScene$1 !== undefined) {
@@ -375,37 +472,41 @@ function toHTMLString(_ast, _options) {
375
472
  }
376
473
 
377
474
  function createUI(text, options) {
378
- let ast = Parser.parse(text);
379
- if (ast.TAG !== "Ok") {
475
+ let errors = Parser.parse(text);
476
+ if (errors.TAG !== "Ok") {
380
477
  return {
381
478
  TAG: "Error",
382
- _0: ast._0
479
+ _0: errors._0
383
480
  };
384
481
  }
385
- let ast$1 = ast._0;
386
- let match = render(ast$1, options);
482
+ let match = errors._0;
483
+ let ast = match[0];
484
+ let match$1 = render(ast, options);
387
485
  return {
388
486
  TAG: "Ok",
389
487
  _0: {
390
- root: match.root,
391
- sceneManager: match.sceneManager,
392
- ast: ast$1
488
+ root: match$1.root,
489
+ sceneManager: match$1.sceneManager,
490
+ ast: ast,
491
+ warnings: match[1]
393
492
  }
394
493
  };
395
494
  }
396
495
 
397
496
  function createUIOrThrow(text, options) {
398
- let ast = Parser.parse(text);
399
- if (ast.TAG === "Ok") {
400
- let ast$1 = ast._0;
401
- let match = render(ast$1, options);
497
+ let errors = Parser.parse(text);
498
+ if (errors.TAG === "Ok") {
499
+ let match = errors._0;
500
+ let ast = match[0];
501
+ let match$1 = render(ast, options);
402
502
  return {
403
- root: match.root,
404
- sceneManager: match.sceneManager,
405
- ast: ast$1
503
+ root: match$1.root,
504
+ sceneManager: match$1.sceneManager,
505
+ ast: ast,
506
+ warnings: match[1]
406
507
  };
407
508
  }
408
- let messages = ast._0.map(err => ErrorMessages.getTitle(err.code)).join("\n");
509
+ let messages = errors._0.map(err => ErrorMessages.getTitle(err.code)).join("\n");
409
510
  return Stdlib_JsError.throwWithMessage("Parse failed:\n" + messages);
410
511
  }
411
512