elm-pages 3.0.0-beta.3 → 3.0.0-beta.30

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 (123) hide show
  1. package/README.md +10 -1
  2. package/codegen/{elm-pages-codegen.js → elm-pages-codegen.cjs} +2864 -2589
  3. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateData.elmi +0 -0
  4. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateData.elmo +0 -0
  5. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateDataTest.elmo +0 -0
  6. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
  7. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/i.dat +0 -0
  8. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/o.dat +0 -0
  9. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm.json +1 -1
  10. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Reporter.elm.js +1327 -122
  11. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Runner.elm.js +15295 -13271
  12. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
  13. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_supervisor.js +4 -4
  14. package/generator/dead-code-review/elm.json +8 -6
  15. package/generator/dead-code-review/src/Pages/Review/DeadCodeEliminateData.elm +59 -10
  16. package/generator/dead-code-review/tests/Pages/Review/DeadCodeEliminateDataTest.elm +52 -36
  17. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
  18. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/i.dat +0 -0
  19. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/o.dat +0 -0
  20. package/generator/review/elm-stuff/tests-0.19.1/elm.json +1 -1
  21. package/generator/review/elm-stuff/tests-0.19.1/js/Reporter.elm.js +1327 -122
  22. package/generator/review/elm-stuff/tests-0.19.1/js/Runner.elm.js +14621 -12637
  23. package/generator/review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
  24. package/generator/review/elm-stuff/tests-0.19.1/js/node_supervisor.js +4 -4
  25. package/generator/review/elm.json +8 -8
  26. package/generator/src/RouteBuilder.elm +113 -107
  27. package/generator/src/SharedTemplate.elm +3 -2
  28. package/generator/src/SiteConfig.elm +3 -2
  29. package/generator/src/basepath-middleware.js +3 -3
  30. package/generator/src/build.js +123 -87
  31. package/generator/src/cli.js +256 -77
  32. package/generator/src/codegen.js +29 -27
  33. package/generator/src/compatibility-key.js +3 -0
  34. package/generator/src/compile-elm.js +25 -25
  35. package/generator/src/config.js +39 -0
  36. package/generator/src/copy-dir.js +2 -2
  37. package/generator/src/dev-server.js +150 -133
  38. package/generator/src/dir-helpers.js +9 -26
  39. package/generator/src/elm-codegen.js +5 -4
  40. package/generator/src/elm-file-constants.js +2 -3
  41. package/generator/src/error-formatter.js +12 -11
  42. package/generator/src/file-helpers.js +3 -4
  43. package/generator/src/generate-template-module-connector.js +23 -22
  44. package/generator/src/init.js +9 -8
  45. package/generator/src/pre-render-html.js +39 -28
  46. package/generator/src/render-test.js +109 -0
  47. package/generator/src/render-worker.js +25 -28
  48. package/generator/src/render.js +322 -142
  49. package/generator/src/request-cache.js +252 -163
  50. package/generator/src/rewrite-client-elm-json.js +5 -5
  51. package/generator/src/rewrite-elm-json.js +7 -7
  52. package/generator/src/route-codegen-helpers.js +16 -31
  53. package/generator/src/seo-renderer.js +12 -7
  54. package/generator/src/vite-utils.js +77 -0
  55. package/generator/static-code/hmr.js +79 -13
  56. package/generator/template/app/Api.elm +6 -5
  57. package/generator/template/app/Effect.elm +123 -0
  58. package/generator/template/app/ErrorPage.elm +37 -6
  59. package/generator/template/app/Route/Index.elm +17 -10
  60. package/generator/template/app/Shared.elm +24 -47
  61. package/generator/template/app/Site.elm +19 -6
  62. package/generator/template/app/View.elm +1 -8
  63. package/generator/template/elm-tooling.json +0 -3
  64. package/generator/template/elm.json +34 -25
  65. package/generator/template/package.json +10 -4
  66. package/package.json +23 -22
  67. package/src/ApiRoute.elm +199 -61
  68. package/src/BackendTask/Custom.elm +325 -0
  69. package/src/BackendTask/Env.elm +90 -0
  70. package/src/{DataSource → BackendTask}/File.elm +128 -43
  71. package/src/{DataSource → BackendTask}/Glob.elm +136 -125
  72. package/src/BackendTask/Http.elm +673 -0
  73. package/src/{DataSource → BackendTask}/Internal/Glob.elm +1 -1
  74. package/src/BackendTask/Internal/Request.elm +28 -0
  75. package/src/BackendTask/Random.elm +79 -0
  76. package/src/BackendTask/Time.elm +47 -0
  77. package/src/BackendTask.elm +537 -0
  78. package/src/FatalError.elm +89 -0
  79. package/src/Form/Field.elm +21 -9
  80. package/src/Form/FieldView.elm +94 -14
  81. package/src/Form.elm +275 -400
  82. package/src/Head.elm +237 -7
  83. package/src/HtmlPrinter.elm +7 -3
  84. package/src/Internal/ApiRoute.elm +7 -5
  85. package/src/PageServerResponse.elm +6 -1
  86. package/src/Pages/FormState.elm +6 -5
  87. package/src/Pages/GeneratorProgramConfig.elm +15 -0
  88. package/src/Pages/Internal/FatalError.elm +5 -0
  89. package/src/Pages/Internal/Form.elm +21 -1
  90. package/src/Pages/{Msg.elm → Internal/Msg.elm} +26 -16
  91. package/src/Pages/Internal/Platform/Cli.elm +507 -763
  92. package/src/Pages/Internal/Platform/CompatibilityKey.elm +6 -0
  93. package/src/Pages/Internal/Platform/Effect.elm +1 -2
  94. package/src/Pages/Internal/Platform/GeneratorApplication.elm +373 -0
  95. package/src/Pages/Internal/Platform/StaticResponses.elm +73 -270
  96. package/src/Pages/Internal/Platform/ToJsPayload.elm +4 -7
  97. package/src/Pages/Internal/Platform.elm +215 -102
  98. package/src/Pages/Internal/Script.elm +17 -0
  99. package/src/Pages/Internal/StaticHttpBody.elm +35 -1
  100. package/src/Pages/Manifest.elm +29 -4
  101. package/src/Pages/PageUrl.elm +23 -9
  102. package/src/Pages/ProgramConfig.elm +14 -10
  103. package/src/Pages/Script.elm +109 -0
  104. package/src/Pages/SiteConfig.elm +3 -2
  105. package/src/Pages/StaticHttp/Request.elm +2 -2
  106. package/src/Pages/StaticHttpRequest.elm +23 -98
  107. package/src/PagesMsg.elm +92 -0
  108. package/src/Path.elm +16 -19
  109. package/src/QueryParams.elm +21 -172
  110. package/src/RequestsAndPending.elm +8 -19
  111. package/src/Result/Extra.elm +26 -0
  112. package/src/Scaffold/Form.elm +484 -0
  113. package/src/Scaffold/Route.elm +1376 -0
  114. package/src/Server/Request.elm +43 -37
  115. package/src/Server/Session.elm +34 -34
  116. package/src/Server/SetCookie.elm +1 -1
  117. package/src/Test/Html/Internal/ElmHtml/ToString.elm +8 -9
  118. package/src/DataSource/Env.elm +0 -38
  119. package/src/DataSource/Http.elm +0 -446
  120. package/src/DataSource/Internal/Request.elm +0 -20
  121. package/src/DataSource/Port.elm +0 -90
  122. package/src/DataSource.elm +0 -538
  123. package/src/Pages/Generate.elm +0 -800
@@ -31,13 +31,14 @@ import Pages.ContentCache as ContentCache
31
31
  import Pages.Fetcher
32
32
  import Pages.Flags
33
33
  import Pages.FormState
34
+ import Pages.Internal.Msg
34
35
  import Pages.Internal.NotFoundReason exposing (NotFoundReason)
35
36
  import Pages.Internal.ResponseSketch as ResponseSketch exposing (ResponseSketch)
36
37
  import Pages.Internal.String as String
37
- import Pages.Msg
38
38
  import Pages.ProgramConfig exposing (ProgramConfig)
39
39
  import Pages.StaticHttpRequest as StaticHttpRequest
40
40
  import Pages.Transition
41
+ import PagesMsg exposing (PagesMsg)
41
42
  import Path exposing (Path)
42
43
  import QueryParams
43
44
  import Task
@@ -45,11 +46,6 @@ import Time
45
46
  import Url exposing (Url)
46
47
 
47
48
 
48
- type Transition
49
- = Loading Int Path
50
- | Submitting FormData
51
-
52
-
53
49
  {-| -}
54
50
  type alias Program userModel userMsg pageData actionData sharedData errorPage =
55
51
  Platform.Program Flags (Model userModel pageData actionData sharedData) (Msg userMsg pageData actionData sharedData errorPage)
@@ -58,7 +54,7 @@ type alias Program userModel userMsg pageData actionData sharedData errorPage =
58
54
  mainView :
59
55
  ProgramConfig userMsg userModel route pageData actionData sharedData effect (Msg userMsg pageData actionData sharedData errorPage) errorPage
60
56
  -> Model userModel pageData actionData sharedData
61
- -> { title : String, body : List (Html (Pages.Msg.Msg userMsg)) }
57
+ -> { title : String, body : List (Html (PagesMsg userMsg)) }
62
58
  mainView config model =
63
59
  case model.notFound of
64
60
  Just info ->
@@ -230,7 +226,7 @@ init config flags url key =
230
226
  , host = url.host
231
227
  , port_ = url.port_
232
228
  , path = pagePath
233
- , query = url.query |> Maybe.map QueryParams.fromString
229
+ , query = url.query |> Maybe.map QueryParams.fromString |> Maybe.withDefault Dict.empty
234
230
  , fragment = url.fragment
235
231
  }
236
232
  }
@@ -274,7 +270,7 @@ init config flags url key =
274
270
  , url = url
275
271
  , currentPath = url.path
276
272
  , pageData = Err "Not found"
277
- , ariaNavigationAnnouncement = "Error" -- TODO use error page title for announcement?
273
+ , ariaNavigationAnnouncement = "Page Not Found" -- TODO use error page title for announcement?
278
274
  , userFlags = flags
279
275
  , notFound = Just info
280
276
  , transition = Nothing
@@ -313,16 +309,21 @@ init config flags url key =
313
309
  type Msg userMsg pageData actionData sharedData errorPage
314
310
  = LinkClicked Browser.UrlRequest
315
311
  | UrlChanged Url
316
- | UserMsg (Pages.Msg.Msg userMsg)
312
+ | UserMsg (PagesMsg userMsg)
317
313
  | SetField { formId : String, name : String, value : String }
318
314
  | UpdateCacheAndUrlNew Bool Url (Maybe userMsg) (Result Http.Error ( Url, ResponseSketch pageData actionData sharedData ))
319
- | FetcherComplete Bool String Int (Result Http.Error ( Maybe userMsg, Maybe actionData ))
315
+ | FetcherComplete Bool String Int (Result Http.Error ( Maybe userMsg, ActionDataOrRedirect actionData ))
320
316
  | FetcherStarted String Int FormData Time.Posix
321
317
  | PageScrollComplete
322
318
  | HotReloadCompleteNew Bytes
323
319
  | ProcessFetchResponse Int (Result Http.Error ( Url, ResponseSketch pageData actionData sharedData )) (Result Http.Error ( Url, ResponseSketch pageData actionData sharedData ) -> Msg userMsg pageData actionData sharedData errorPage)
324
320
 
325
321
 
322
+ type ActionDataOrRedirect action
323
+ = ActionResponse (Maybe action)
324
+ | RedirectResponse String
325
+
326
+
326
327
  {-| -}
327
328
  type alias Model userModel pageData actionData sharedData =
328
329
  { key : Maybe Browser.Navigation.Key
@@ -414,7 +415,7 @@ update config appMsg model =
414
415
  model
415
416
 
416
417
  Nothing ->
417
- if model.url.path == url.path then
418
+ if model.url.path == url.path && model.url.query == url.query then
418
419
  ( { model
419
420
  | -- update the URL in case query params or fragment changed
420
421
  url = url
@@ -423,46 +424,57 @@ update config appMsg model =
423
424
  )
424
425
 
425
426
  else
426
- ( { model
427
- | url = url
428
- }
427
+ ( model
429
428
  , NoEffect
430
429
  )
431
430
  -- TODO is it reasonable to always re-fetch route data if you re-navigate to the current route? Might be a good
432
431
  -- parallel to the browser behavior
433
432
  |> startNewGetLoad url (UpdateCacheAndUrlNew True url Nothing)
434
433
 
435
- FetcherComplete forPageReload fetcherKey transitionId___ userMsgResult ->
434
+ FetcherComplete _ fetcherKey _ userMsgResult ->
436
435
  case userMsgResult of
437
- Ok ( userMsg, maybeFetcherDoneActionData ) ->
438
- ( { model
439
- | inFlightFetchers =
440
- model.inFlightFetchers
441
- |> Dict.update fetcherKey
442
- (Maybe.map
443
- (\( transitionId, fetcherState ) ->
444
- ( transitionId
445
- , { fetcherState
446
- | status =
447
- maybeFetcherDoneActionData
448
- |> Maybe.map Pages.Transition.FetcherReloading
449
- -- TODO remove this bad default, FetcherSubmitting is incorrect
450
- |> Maybe.withDefault Pages.Transition.FetcherSubmitting
451
- }
436
+ Ok ( userMsg, actionOrRedirect ) ->
437
+ case actionOrRedirect of
438
+ ActionResponse maybeFetcherDoneActionData ->
439
+ ( { model
440
+ | inFlightFetchers =
441
+ model.inFlightFetchers
442
+ |> Dict.update fetcherKey
443
+ (Maybe.map
444
+ (\( transitionId, fetcherState ) ->
445
+ ( transitionId
446
+ , { fetcherState
447
+ | status =
448
+ maybeFetcherDoneActionData
449
+ |> Maybe.map Pages.Transition.FetcherReloading
450
+ -- TODO remove this bad default, FetcherSubmitting is incorrect
451
+ |> Maybe.withDefault Pages.Transition.FetcherSubmitting
452
+ }
453
+ )
454
+ )
452
455
  )
453
- )
454
- )
455
- }
456
- , NoEffect
457
- )
458
- |> (case userMsg of
459
- Just justUserMsg ->
460
- performUserMsg justUserMsg config
461
-
462
- Nothing ->
463
- identity
464
- )
465
- |> startNewGetLoad (currentUrlWithPath model.url.path model) (UpdateCacheAndUrlNew False model.url Nothing)
456
+ }
457
+ , NoEffect
458
+ )
459
+ |> (case userMsg of
460
+ Just justUserMsg ->
461
+ performUserMsg justUserMsg config
462
+
463
+ Nothing ->
464
+ identity
465
+ )
466
+ |> startNewGetLoad (currentUrlWithPath model.url.path model) (UpdateCacheAndUrlNew False model.url Nothing)
467
+
468
+ RedirectResponse redirectTo ->
469
+ ( { model
470
+ | inFlightFetchers =
471
+ model.inFlightFetchers
472
+ |> Dict.remove fetcherKey
473
+ , pendingRedirect = True
474
+ }
475
+ , NoEffect
476
+ )
477
+ |> startNewGetLoad (currentUrlWithPath redirectTo model) (UpdateCacheAndUrlNew False model.url Nothing)
466
478
 
467
479
  Err _ ->
468
480
  -- TODO how to handle error?
@@ -480,11 +492,11 @@ update config appMsg model =
480
492
 
481
493
  UserMsg userMsg_ ->
482
494
  case userMsg_ of
483
- Pages.Msg.UserMsg userMsg ->
495
+ Pages.Internal.Msg.UserMsg userMsg ->
484
496
  ( model, NoEffect )
485
497
  |> performUserMsg userMsg config
486
498
 
487
- Pages.Msg.Submit fields ->
499
+ Pages.Internal.Msg.Submit fields ->
488
500
  ( { model
489
501
  | transition =
490
502
  Just
@@ -496,7 +508,7 @@ update config appMsg model =
496
508
  , Submit fields
497
509
  )
498
510
 
499
- Pages.Msg.SubmitIfValid formId fields isValid ->
511
+ Pages.Internal.Msg.SubmitIfValid formId fields isValid maybeUserMsg ->
500
512
  if isValid then
501
513
  ( { model
502
514
  -- TODO should I setSubmitAttempted here, too?
@@ -509,6 +521,13 @@ update config appMsg model =
509
521
  }
510
522
  , Submit fields
511
523
  )
524
+ |> (case maybeUserMsg of
525
+ Just justUserMsg ->
526
+ performUserMsg justUserMsg config
527
+
528
+ Nothing ->
529
+ identity
530
+ )
512
531
 
513
532
  else
514
533
  ( { model
@@ -519,7 +538,7 @@ update config appMsg model =
519
538
  , NoEffect
520
539
  )
521
540
 
522
- Pages.Msg.SubmitFetcher fetcherKey fields isValid maybeUserMsg ->
541
+ Pages.Internal.Msg.SubmitFetcher fetcherKey fields isValid maybeUserMsg ->
523
542
  if isValid then
524
543
  -- TODO should I setSubmitAttempted here, too?
525
544
  ( { model | nextTransitionKey = model.nextTransitionKey + 1 }
@@ -542,12 +561,15 @@ update config appMsg model =
542
561
  , NoEffect
543
562
  )
544
563
 
545
- Pages.Msg.FormFieldEvent value ->
564
+ Pages.Internal.Msg.FormFieldEvent value ->
546
565
  -- TODO when init is called for a new page, also need to clear out client-side `pageFormState`
547
566
  ( { model | pageFormState = Pages.FormState.update value model.pageFormState }
548
567
  , NoEffect
549
568
  )
550
569
 
570
+ Pages.Internal.Msg.NoOp ->
571
+ ( model, NoEffect )
572
+
551
573
  UpdateCacheAndUrlNew scrollToTopWhenDone urlWithoutRedirectResolution maybeUserMsg updateResult ->
552
574
  -- TODO remove all fetchers that are in the state `FetcherReloading` here -- I think that's the right logic?
553
575
  case
@@ -605,27 +627,32 @@ update config appMsg model =
605
627
  , actionData = newActionData
606
628
  }
607
629
 
608
- ( userModel, _ ) =
630
+ ( userModel, userEffect ) =
609
631
  -- TODO if urlWithoutRedirectResolution is different from the url with redirect resolution, then
610
632
  -- instead of calling update, call pushUrl (I think?)
611
633
  -- TODO include user Cmd
612
- config.update model.pageFormState
613
- (model.inFlightFetchers |> toFetcherState)
614
- (model.transition |> Maybe.map Tuple.second)
615
- newSharedData
616
- newPageData
617
- model.key
618
- (config.onPageChange
619
- { protocol = model.url.protocol
620
- , host = model.url.host
621
- , port_ = model.url.port_
622
- , path = urlPathToPath urlWithoutRedirectResolution
623
- , query = urlWithoutRedirectResolution.query
624
- , fragment = urlWithoutRedirectResolution.fragment
625
- , metadata = config.urlToRoute urlWithoutRedirectResolution
626
- }
627
- )
628
- previousPageData.userModel
634
+ if stayingOnSamePath then
635
+ ( previousPageData.userModel, NoEffect )
636
+
637
+ else
638
+ config.update model.pageFormState
639
+ (model.inFlightFetchers |> toFetcherState)
640
+ (model.transition |> Maybe.map Tuple.second)
641
+ newSharedData
642
+ newPageData
643
+ model.key
644
+ (config.onPageChange
645
+ { protocol = model.url.protocol
646
+ , host = model.url.host
647
+ , port_ = model.url.port_
648
+ , path = urlPathToPath urlWithoutRedirectResolution
649
+ , query = urlWithoutRedirectResolution.query
650
+ , fragment = urlWithoutRedirectResolution.fragment
651
+ , metadata = config.urlToRoute urlWithoutRedirectResolution
652
+ }
653
+ )
654
+ previousPageData.userModel
655
+ |> Tuple.mapSecond UserCmd
629
656
 
630
657
  updatedModel : Model userModel pageData actionData sharedData
631
658
  updatedModel =
@@ -656,10 +683,13 @@ update config appMsg model =
656
683
  , currentPath = newUrl.path
657
684
  }
658
685
  , if not stayingOnSamePath && scrollToTopWhenDone then
659
- ScrollToTop
686
+ Batch
687
+ [ ScrollToTop
688
+ , userEffect
689
+ ]
660
690
 
661
691
  else
662
- NoEffect
692
+ userEffect
663
693
  )
664
694
  |> (case maybeUserMsg of
665
695
  Just userMsg ->
@@ -679,10 +709,10 @@ update config appMsg model =
679
709
  Err _ ->
680
710
  {-
681
711
  When there is an error loading the content.dat, we are either
682
- 1) in the dev server, and should show the relevant DataSource error for the page
712
+ 1) in the dev server, and should show the relevant BackendTask error for the page
683
713
  we're navigating to. This could be done more cleanly, but it's simplest to just
684
714
  do a fresh page load and use the code path for presenting an error for a fresh page.
685
- 2) In a production app. That means we had a successful build, so there were no DataSource failures,
715
+ 2) In a production app. That means we had a successful build, so there were no BackendTask failures,
686
716
  so the app must be stale (unless it's in some unexpected state from a bug). In the future,
687
717
  it probably makes sense to include some sort of hash of the app version we are fetching, match
688
718
  it with the current version that's running, and perform this logic when we see there is a mismatch.
@@ -745,7 +775,86 @@ update config appMsg model =
745
775
  _ ->
746
776
  ( model, NoEffect )
747
777
  )
748
- |> Result.withDefault ( model, NoEffect )
778
+ |> Result.withDefault
779
+ (let
780
+ pageDataResult : Maybe (InitKind sharedData pageData actionData errorPage)
781
+ pageDataResult =
782
+ case Bytes.Decode.decode config.decodeResponse pageDataBytes of
783
+ Just (ResponseSketch.RenderPage _ _) ->
784
+ Nothing
785
+
786
+ Just (ResponseSketch.HotUpdate pageData shared actionData) ->
787
+ OkPage shared pageData actionData
788
+ |> Just
789
+
790
+ Just (ResponseSketch.NotFound notFound) ->
791
+ NotFound notFound
792
+ |> Just
793
+
794
+ _ ->
795
+ Nothing
796
+ in
797
+ case pageDataResult of
798
+ Just (OkPage sharedData pageData actionData) ->
799
+ let
800
+ urls : { currentUrl : Url, basePath : List String }
801
+ urls =
802
+ { currentUrl = model.url
803
+ , basePath = config.basePath
804
+ }
805
+
806
+ pagePath : Path
807
+ pagePath =
808
+ urlsToPagePath urls
809
+
810
+ userFlags : Pages.Flags.Flags
811
+ userFlags =
812
+ model.userFlags
813
+ |> Decode.decodeValue
814
+ (Decode.field "userFlags" Decode.value)
815
+ |> Result.withDefault Json.Encode.null
816
+ |> Pages.Flags.BrowserFlags
817
+
818
+ ( userModel, userCmd ) =
819
+ Just
820
+ { path =
821
+ { path = pagePath
822
+ , query = model.url.query
823
+ , fragment = model.url.fragment
824
+ }
825
+ , metadata = config.urlToRoute model.url
826
+ , pageUrl =
827
+ Just
828
+ { protocol = model.url.protocol
829
+ , host = model.url.host
830
+ , port_ = model.url.port_
831
+ , path = pagePath
832
+ , query = model.url.query |> Maybe.map QueryParams.fromString |> Maybe.withDefault Dict.empty
833
+ , fragment = model.url.fragment
834
+ }
835
+ }
836
+ |> config.init userFlags sharedData pageData actionData
837
+
838
+ cmd : Effect userMsg pageData actionData sharedData userEffect errorPage
839
+ cmd =
840
+ UserCmd userCmd
841
+ in
842
+ ( { model
843
+ | pageData =
844
+ Ok
845
+ { userModel = userModel
846
+ , sharedData = sharedData
847
+ , pageData = pageData
848
+ , actionData = actionData
849
+ }
850
+ , notFound = Nothing
851
+ }
852
+ , cmd
853
+ )
854
+
855
+ _ ->
856
+ ( model, NoEffect )
857
+ )
749
858
 
750
859
  FetcherStarted fetcherKey transitionId fetcherData initiatedAt ->
751
860
  ( { model
@@ -766,7 +875,7 @@ update config appMsg model =
766
875
  toFetcherState : Dict String ( Int, Pages.Transition.FetcherState actionData ) -> Dict String (Pages.Transition.FetcherState actionData)
767
876
  toFetcherState inFlightFetchers =
768
877
  inFlightFetchers
769
- |> Dict.map (\_ ( index, fetcherState ) -> fetcherState)
878
+ |> Dict.map (\_ ( _, fetcherState ) -> fetcherState)
770
879
 
771
880
 
772
881
  performUserMsg :
@@ -828,7 +937,7 @@ perform config model effect =
828
937
  |> Maybe.withDefault Cmd.none
829
938
 
830
939
  FetchPageData transitionKey maybeRequestInfo url toMsg ->
831
- fetchRouteData True transitionKey toMsg config url maybeRequestInfo
940
+ fetchRouteData transitionKey toMsg config url maybeRequestInfo
832
941
 
833
942
  Submit fields ->
834
943
  if fields.method == Get then
@@ -843,7 +952,7 @@ perform config model effect =
843
952
  -- TODO add optional path parameter to Submit variant to allow submitting to other routes
844
953
  model.url
845
954
  in
846
- fetchRouteData False -1 (UpdateCacheAndUrlNew False model.url Nothing) config urlToSubmitTo (Just fields)
955
+ fetchRouteData -1 (UpdateCacheAndUrlNew False model.url Nothing) config urlToSubmitTo (Just fields)
847
956
 
848
957
  SubmitFetcher fetcherKey transitionId formData ->
849
958
  startFetcher2 config False fetcherKey transitionId formData model
@@ -863,7 +972,7 @@ perform config model effect =
863
972
  |> config.perform
864
973
  { fetchRouteData =
865
974
  \fetchInfo ->
866
- fetchRouteData False
975
+ fetchRouteData
867
976
  -1
868
977
  (prepare fetchInfo.toMsg)
869
978
  config
@@ -873,13 +982,13 @@ perform config model effect =
873
982
  ---- TODO map the Msg with the wrapper type (like in the PR branch)
874
983
  , submit =
875
984
  \fetchInfo ->
876
- fetchRouteData False -1 (prepare fetchInfo.toMsg) config (fetchInfo.values.action |> Url.fromString |> Maybe.withDefault model.url) (Just fetchInfo.values)
985
+ fetchRouteData -1 (prepare fetchInfo.toMsg) config (fetchInfo.values.action |> Url.fromString |> Maybe.withDefault model.url) (Just fetchInfo.values)
877
986
  , runFetcher =
878
987
  \(Pages.Fetcher.Fetcher options) ->
879
988
  -- TODO need to get the fetcherId here
880
989
  -- TODO need to increment and pass in the transitionId
881
990
  startFetcher "TODO" -1 options model
882
- , fromPageMsg = Pages.Msg.UserMsg >> UserMsg
991
+ , fromPageMsg = Pages.Internal.Msg.UserMsg >> UserMsg
883
992
  , key = key
884
993
  , setField = \info -> Task.succeed (SetField info) |> Task.perform identity
885
994
  }
@@ -927,10 +1036,10 @@ startFetcher fetcherKey transitionId options model =
927
1036
  Http.expectBytesResponse (FetcherComplete False fetcherKey model.nextTransitionKey)
928
1037
  (\bytes ->
929
1038
  case bytes of
930
- Http.GoodStatus_ metadata bytesBody ->
1039
+ Http.GoodStatus_ _ bytesBody ->
931
1040
  ( options.decoder (Ok bytesBody)
932
1041
  |> Just
933
- , Nothing
1042
+ , ActionResponse Nothing
934
1043
  )
935
1044
  |> Ok
936
1045
 
@@ -943,7 +1052,7 @@ startFetcher fetcherKey transitionId options model =
943
1052
  Http.NetworkError_ ->
944
1053
  Err <| Http.NetworkError
945
1054
 
946
- Http.BadStatus_ metadata body ->
1055
+ Http.BadStatus_ metadata _ ->
947
1056
  Err <| Http.BadStatus metadata.statusCode
948
1057
  )
949
1058
  , tracker = Nothing
@@ -974,7 +1083,7 @@ startFetcher2 config fromPageReload fetcherKey transitionId formData model =
974
1083
  Cmd.batch
975
1084
  [ cancelStaleFetchers model
976
1085
  , case Dict.get fetcherKey model.inFlightFetchers of
977
- Just ( inFlightId, inFlightFetcher ) ->
1086
+ Just ( inFlightId, _ ) ->
978
1087
  Http.cancel (String.fromInt inFlightId)
979
1088
 
980
1089
  Nothing ->
@@ -985,22 +1094,26 @@ startFetcher2 config fromPageReload fetcherKey transitionId formData model =
985
1094
  Http.expectBytesResponse (FetcherComplete fromPageReload fetcherKey model.nextTransitionKey)
986
1095
  (\bytes ->
987
1096
  case bytes of
988
- Http.GoodStatus_ metadata bytesBody ->
1097
+ Http.GoodStatus_ _ bytesBody ->
989
1098
  let
990
- decodedAction : Maybe actionData
1099
+ decodedAction : ActionDataOrRedirect actionData
991
1100
  decodedAction =
992
1101
  case Bytes.Decode.decode config.decodeResponse bytesBody of
1102
+ -- @@@
1103
+ Just (ResponseSketch.Redirect redirectTo) ->
1104
+ RedirectResponse redirectTo
1105
+
993
1106
  Just (ResponseSketch.RenderPage _ maybeAction) ->
994
- maybeAction
1107
+ ActionResponse maybeAction
995
1108
 
996
- Just (ResponseSketch.HotUpdate pageData shared maybeAction) ->
997
- maybeAction
1109
+ Just (ResponseSketch.HotUpdate _ _ maybeAction) ->
1110
+ ActionResponse maybeAction
998
1111
 
999
- Just (ResponseSketch.NotFound notFound) ->
1000
- Nothing
1112
+ Just (ResponseSketch.NotFound _) ->
1113
+ ActionResponse Nothing
1001
1114
 
1002
1115
  _ ->
1003
- Nothing
1116
+ ActionResponse Nothing
1004
1117
  in
1005
1118
  -- TODO maybe have an optional way to pass the bytes through?
1006
1119
  Ok ( Nothing, decodedAction )
@@ -1014,7 +1127,7 @@ startFetcher2 config fromPageReload fetcherKey transitionId formData model =
1014
1127
  Http.NetworkError_ ->
1015
1128
  Err <| Http.NetworkError
1016
1129
 
1017
- Http.BadStatus_ metadata body ->
1130
+ Http.BadStatus_ metadata _ ->
1018
1131
  Err <| Http.BadStatus metadata.statusCode
1019
1132
  )
1020
1133
  , tracker = Just (String.fromInt transitionId)
@@ -1036,7 +1149,7 @@ cancelStaleFetchers model =
1036
1149
  model.inFlightFetchers
1037
1150
  |> Dict.toList
1038
1151
  |> List.filterMap
1039
- (\( fetcherKey, ( id, fetcher ) ) ->
1152
+ (\( _, ( id, fetcher ) ) ->
1040
1153
  case fetcher.status of
1041
1154
  Pages.Transition.FetcherReloading _ ->
1042
1155
  Http.cancel (String.fromInt id)
@@ -1104,7 +1217,7 @@ application config =
1104
1217
  [ config.subscriptions (model.url |> config.urlToRoute)
1105
1218
  (urls.currentUrl |> config.urlToRoute |> config.routeToPath |> Path.join)
1106
1219
  pageData.userModel
1107
- |> Sub.map (Pages.Msg.UserMsg >> UserMsg)
1220
+ |> Sub.map (Pages.Internal.Msg.UserMsg >> UserMsg)
1108
1221
  , config.hotReloadData
1109
1222
  |> Sub.map HotReloadCompleteNew
1110
1223
  ]
@@ -1157,14 +1270,13 @@ urlPathToPath urls =
1157
1270
 
1158
1271
 
1159
1272
  fetchRouteData :
1160
- Bool
1161
- -> Int
1273
+ Int
1162
1274
  -> (Result Http.Error ( Url, ResponseSketch pageData actionData sharedData ) -> Msg userMsg pageData actionData sharedData errorPage)
1163
1275
  -> ProgramConfig userMsg userModel route pageData actionData sharedData effect (Msg userMsg pageData actionData sharedData errorPage) errorPage
1164
1276
  -> Url
1165
1277
  -> Maybe FormData
1166
1278
  -> Cmd (Msg userMsg pageData actionData sharedData errorPage)
1167
- fetchRouteData forPageDataReload transitionKey toMsg config url details =
1279
+ fetchRouteData transitionKey toMsg config url details =
1168
1280
  {-
1169
1281
  TODO:
1170
1282
  - [X] `toMsg` needs a parameter for the callback Msg so it can pass it on if there is a Redirect response
@@ -1251,7 +1363,7 @@ fetchRouteData forPageDataReload transitionKey toMsg config url details =
1251
1363
  Http.NetworkError_ ->
1252
1364
  Err Http.NetworkError
1253
1365
 
1254
- Http.BadStatus_ metadata body ->
1366
+ Http.BadStatus_ _ body ->
1255
1367
  body
1256
1368
  |> Bytes.Decode.decode config.decodeResponse
1257
1369
  |> Result.fromMaybe "Decoding error"
@@ -1303,7 +1415,7 @@ startNewGetLoad urlToGet toMsg ( model, effect ) =
1303
1415
  cancelIfStale : Effect userMsg pageData actionData sharedData userEffect errorPage
1304
1416
  cancelIfStale =
1305
1417
  case model.transition of
1306
- Just ( transitionKey, Pages.Transition.Loading path loadingKind ) ->
1418
+ Just ( transitionKey, Pages.Transition.Loading _ _ ) ->
1307
1419
  CancelRequest transitionKey
1308
1420
 
1309
1421
  _ ->
@@ -1314,13 +1426,13 @@ startNewGetLoad urlToGet toMsg ( model, effect ) =
1314
1426
  , transition =
1315
1427
  ( model.nextTransitionKey
1316
1428
  , case model.transition of
1317
- Just ( transitionKey, Pages.Transition.LoadAfterSubmit submitData _ _ ) ->
1429
+ Just ( _, Pages.Transition.LoadAfterSubmit submitData _ _ ) ->
1318
1430
  Pages.Transition.LoadAfterSubmit
1319
1431
  submitData
1320
1432
  (urlToGet.path |> Path.fromString)
1321
1433
  Pages.Transition.Load
1322
1434
 
1323
- Just ( transitionKey, Pages.Transition.Submitting submitData ) ->
1435
+ Just ( _, Pages.Transition.Submitting submitData ) ->
1324
1436
  Pages.Transition.LoadAfterSubmit
1325
1437
  submitData
1326
1438
  (urlToGet.path |> Path.fromString)
@@ -1392,6 +1504,7 @@ loadDataAndUpdateUrl ( newPageData, newSharedData, newActionData ) maybeUserMsg
1392
1504
  , actionData = newActionData
1393
1505
  }
1394
1506
 
1507
+ -- TODO use userEffect here?
1395
1508
  ( userModel, _ ) =
1396
1509
  -- TODO if urlWithoutRedirectResolution is different from the url with redirect resolution, then
1397
1510
  -- instead of calling update, call pushUrl (I think?)
@@ -1467,10 +1580,10 @@ loadDataAndUpdateUrl ( newPageData, newSharedData, newActionData ) maybeUserMsg
1467
1580
  Err _ ->
1468
1581
  {-
1469
1582
  When there is an error loading the content.dat, we are either
1470
- 1) in the dev server, and should show the relevant DataSource error for the page
1583
+ 1) in the dev server, and should show the relevant BackendTask error for the page
1471
1584
  we're navigating to. This could be done more cleanly, but it's simplest to just
1472
1585
  do a fresh page load and use the code path for presenting an error for a fresh page.
1473
- 2) In a production app. That means we had a successful build, so there were no DataSource failures,
1586
+ 2) In a production app. That means we had a successful build, so there were no BackendTask failures,
1474
1587
  so the app must be stale (unless it's in some unexpected state from a bug). In the future,
1475
1588
  it probably makes sense to include some sort of hash of the app version we are fetching, match
1476
1589
  it with the current version that's running, and perform this logic when we see there is a mismatch.
@@ -0,0 +1,17 @@
1
+ module Pages.Internal.Script exposing (Script(..))
2
+
3
+ import BackendTask exposing (BackendTask)
4
+ import Cli.Program as Program
5
+ import FatalError exposing (FatalError)
6
+ import Html exposing (Html)
7
+
8
+
9
+ {-| -}
10
+ type Script
11
+ = Script
12
+ ((Maybe { indent : Int, newLines : Bool }
13
+ -> Html Never
14
+ -> String
15
+ )
16
+ -> Program.Config (BackendTask FatalError ())
17
+ )