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.
@@ -77,6 +77,11 @@ let defaultOptions: renderOptions = {
77
77
  */
78
78
  type sceneManager = {
79
79
  goto: string => unit,
80
+ back: unit => unit,
81
+ forward: unit => unit,
82
+ refresh: unit => unit,
83
+ canGoBack: unit => bool,
84
+ canGoForward: unit => bool,
80
85
  getCurrentScene: unit => option<string>,
81
86
  getSceneIds: unit => array<string>,
82
87
  }
@@ -415,8 +420,11 @@ let renderScene = (scene: scene, ~onAction: option<actionHandler>=?): DomBinding
415
420
 
416
421
  let createSceneManager = (scenes: Map.t<string, DomBindings.element>): sceneManager => {
417
422
  let currentScene = ref(None)
423
+ let historyStack: ref<array<string>> = ref([])
424
+ let forwardStack: ref<array<string>> = ref([])
418
425
 
419
- let goto = (id: string): unit => {
426
+ // Internal function to switch scenes without affecting history
427
+ let switchToScene = (id: string): unit => {
420
428
  switch currentScene.contents {
421
429
  | Some(currentId) => {
422
430
  switch scenes->Map.get(currentId) {
@@ -436,6 +444,88 @@ let createSceneManager = (scenes: Map.t<string, DomBindings.element>): sceneMana
436
444
  }
437
445
  }
438
446
 
447
+ let goto = (id: string): unit => {
448
+ // Add current scene to history before navigating
449
+ switch currentScene.contents {
450
+ | Some(currentId) if currentId != id => {
451
+ historyStack := historyStack.contents->Array.concat([currentId])
452
+ // Clear forward stack when navigating to new scene
453
+ forwardStack := []
454
+ }
455
+ | _ => ()
456
+ }
457
+ switchToScene(id)
458
+ }
459
+
460
+ let back = (): unit => {
461
+ let history = historyStack.contents
462
+ let len = history->Array.length
463
+ if len > 0 {
464
+ switch history->Array.get(len - 1) {
465
+ | Some(prevId) => {
466
+ // Add current scene to forward stack
467
+ switch currentScene.contents {
468
+ | Some(currentId) => {
469
+ forwardStack := forwardStack.contents->Array.concat([currentId])
470
+ }
471
+ | None => ()
472
+ }
473
+ // Remove last item from history
474
+ historyStack := history->Array.slice(~start=0, ~end=len - 1)
475
+ // Navigate to previous scene
476
+ switchToScene(prevId)
477
+ }
478
+ | None => ()
479
+ }
480
+ }
481
+ }
482
+
483
+ let forward = (): unit => {
484
+ let fwdStack = forwardStack.contents
485
+ let len = fwdStack->Array.length
486
+ if len > 0 {
487
+ switch fwdStack->Array.get(len - 1) {
488
+ | Some(nextId) => {
489
+ // Add current scene to history
490
+ switch currentScene.contents {
491
+ | Some(currentId) => {
492
+ historyStack := historyStack.contents->Array.concat([currentId])
493
+ }
494
+ | None => ()
495
+ }
496
+ // Remove last item from forward stack
497
+ forwardStack := fwdStack->Array.slice(~start=0, ~end=len - 1)
498
+ // Navigate to next scene
499
+ switchToScene(nextId)
500
+ }
501
+ | None => ()
502
+ }
503
+ }
504
+ }
505
+
506
+ let refresh = (): unit => {
507
+ switch currentScene.contents {
508
+ | Some(id) => {
509
+ // Remove active class and re-add it to trigger any CSS animations
510
+ switch scenes->Map.get(id) {
511
+ | Some(el) => {
512
+ el->DomBindings.classList->DomBindings.remove("active")
513
+ // Use setTimeout to ensure the class removal is processed
514
+ let _ = Js.Global.setTimeout(() => {
515
+ el->DomBindings.classList->DomBindings.add("active")
516
+ }, 0)
517
+ }
518
+ | None => ()
519
+ }
520
+ }
521
+ | None => ()
522
+ }
523
+ }
524
+
525
+ let canGoBack = (): bool => historyStack.contents->Array.length > 0
526
+
527
+ let canGoForward = (): bool => forwardStack.contents->Array.length > 0
528
+
439
529
  let getCurrentScene = (): option<string> => currentScene.contents
440
530
 
441
531
  let getSceneIds = (): array<string> => {
@@ -444,6 +534,11 @@ let createSceneManager = (scenes: Map.t<string, DomBindings.element>): sceneMana
444
534
 
445
535
  {
446
536
  goto,
537
+ back,
538
+ forward,
539
+ refresh,
540
+ canGoBack,
541
+ canGoForward,
447
542
  getCurrentScene,
448
543
  getSceneIds,
449
544
  }
@@ -494,10 +589,12 @@ let render = (ast: ast, options: option<renderOptions>): renderResult => {
494
589
  | None => ()
495
590
  }
496
591
 
497
- // Create a ref to hold the goto function (set after sceneManager is created)
592
+ // Create refs to hold navigation functions (set after sceneManager is created)
498
593
  let gotoRef: ref<option<string => unit>> = ref(None)
594
+ let backRef: ref<option<unit => unit>> = ref(None)
595
+ let forwardRef: ref<option<unit => unit>> = ref(None)
499
596
 
500
- // Create action handler that uses the gotoRef
597
+ // Create action handler that uses the refs
501
598
  let handleAction = (action: interactionAction): unit => {
502
599
  switch action {
503
600
  | Goto({target, _}) => {
@@ -507,12 +604,16 @@ let render = (ast: ast, options: option<renderOptions>): renderResult => {
507
604
  }
508
605
  }
509
606
  | Back => {
510
- // TODO: Implement history-based back navigation
511
- ()
607
+ switch backRef.contents {
608
+ | Some(back) => back()
609
+ | None => ()
610
+ }
512
611
  }
513
612
  | Forward => {
514
- // TODO: Implement history-based forward navigation
515
- ()
613
+ switch forwardRef.contents {
614
+ | Some(forward) => forward()
615
+ | None => ()
616
+ }
516
617
  }
517
618
  | Validate(_) => {
518
619
  // TODO: Implement field validation
@@ -535,8 +636,10 @@ let render = (ast: ast, options: option<renderOptions>): renderResult => {
535
636
 
536
637
  let manager = createSceneManager(sceneMap)
537
638
 
538
- // Now that sceneManager is created, set the gotoRef
639
+ // Now that sceneManager is created, set the refs
539
640
  gotoRef := Some(manager.goto)
641
+ backRef := Some(manager.back)
642
+ forwardRef := Some(manager.forward)
540
643
 
541
644
  if ast.scenes->Array.length > 0 {
542
645
  switch ast.scenes->Array.get(0) {
@@ -568,6 +671,7 @@ type createUISuccessResult = {
568
671
  root: DomBindings.element,
569
672
  sceneManager: sceneManager,
570
673
  ast: Types.ast,
674
+ warnings: array<ErrorTypes.t>,
571
675
  }
572
676
 
573
677
  type createUIResult = result<createUISuccessResult, array<ErrorTypes.t>>
@@ -595,9 +699,9 @@ type createUIResult = result<createUISuccessResult, array<ErrorTypes.t>>
595
699
  @genType
596
700
  let createUI = (text: string, options: option<renderOptions>): createUIResult => {
597
701
  switch Parser.parse(text) {
598
- | Ok(ast) => {
702
+ | Ok((ast, warnings)) => {
599
703
  let {root, sceneManager} = render(ast, options)
600
- Ok({root, sceneManager, ast})
704
+ Ok({root, sceneManager, ast, warnings})
601
705
  }
602
706
  | Error(errors) => Error(errors)
603
707
  }
@@ -621,9 +725,9 @@ let createUI = (text: string, options: option<renderOptions>): createUIResult =>
621
725
  @genType
622
726
  let createUIOrThrow = (text: string, options: option<renderOptions>): createUISuccessResult => {
623
727
  switch Parser.parse(text) {
624
- | Ok(ast) => {
728
+ | Ok((ast, warnings)) => {
625
729
  let {root, sceneManager} = render(ast, options)
626
- {root, sceneManager, ast}
730
+ {root, sceneManager, ast, warnings}
627
731
  }
628
732
  | Error(errors) => {
629
733
  let messages = errors