elm-pages 3.0.0-beta.8 → 3.0.0

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 (164) hide show
  1. package/README.md +11 -2
  2. package/adapter/netlify.js +207 -0
  3. package/codegen/{elm-pages-codegen.js → elm-pages-codegen.cjs} +2730 -2938
  4. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateData.elmi +0 -0
  5. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateData.elmo +0 -0
  6. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateDataTest.elmo +0 -0
  7. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
  8. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/i.dat +0 -0
  9. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/o.dat +0 -0
  10. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm.json +1 -1
  11. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Reporter.elm.js +1527 -422
  12. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Runner.elm.js +16840 -13653
  13. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
  14. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_supervisor.js +2 -2
  15. package/generator/dead-code-review/elm.json +9 -7
  16. package/generator/dead-code-review/src/Pages/Review/DeadCodeEliminateData.elm +59 -10
  17. package/generator/dead-code-review/tests/Pages/Review/DeadCodeEliminateDataTest.elm +52 -36
  18. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Internal-RoutePattern.elmi +0 -0
  19. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Internal-RoutePattern.elmo +0 -0
  20. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-NoContractViolations.elmi +0 -0
  21. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-NoContractViolations.elmo +0 -0
  22. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
  23. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/i.dat +0 -0
  24. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/o.dat +0 -0
  25. package/generator/review/elm-stuff/tests-0.19.1/elm.json +1 -1
  26. package/generator/review/elm-stuff/tests-0.19.1/js/Reporter.elm.js +1527 -422
  27. package/generator/review/elm-stuff/tests-0.19.1/js/Runner.elm.js +25118 -21832
  28. package/generator/review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
  29. package/generator/review/elm-stuff/tests-0.19.1/js/node_supervisor.js +2 -2
  30. package/generator/review/elm.json +10 -10
  31. package/generator/src/RouteBuilder.elm +93 -128
  32. package/generator/src/SharedTemplate.elm +8 -7
  33. package/generator/src/SiteConfig.elm +3 -2
  34. package/generator/src/basepath-middleware.js +3 -3
  35. package/generator/src/build.js +147 -63
  36. package/generator/src/cli.js +292 -88
  37. package/generator/src/codegen.js +29 -27
  38. package/generator/src/compatibility-key.js +3 -0
  39. package/generator/src/compile-elm.js +43 -26
  40. package/generator/src/config.js +2 -4
  41. package/generator/src/copy-dir.js +2 -2
  42. package/generator/src/dev-server.js +159 -92
  43. package/generator/src/dir-helpers.js +9 -26
  44. package/generator/src/elm-codegen.js +5 -4
  45. package/generator/src/elm-file-constants.js +2 -3
  46. package/generator/src/error-formatter.js +12 -11
  47. package/generator/src/file-helpers.js +3 -4
  48. package/generator/src/generate-template-module-connector.js +23 -23
  49. package/generator/src/init.js +9 -8
  50. package/generator/src/pre-render-html.js +10 -13
  51. package/generator/src/render-test.js +109 -0
  52. package/generator/src/render-worker.js +25 -28
  53. package/generator/src/render.js +321 -142
  54. package/generator/src/request-cache.js +265 -162
  55. package/generator/src/resolve-elm-module.js +64 -0
  56. package/generator/src/rewrite-client-elm-json.js +6 -5
  57. package/generator/src/rewrite-elm-json-help.js +56 -0
  58. package/generator/src/rewrite-elm-json.js +17 -7
  59. package/generator/src/route-codegen-helpers.js +16 -31
  60. package/generator/src/seo-renderer.js +12 -7
  61. package/generator/src/vite-utils.js +1 -2
  62. package/generator/static-code/elm-pages.js +10 -0
  63. package/generator/static-code/hmr.js +79 -13
  64. package/generator/template/app/Api.elm +3 -2
  65. package/generator/template/app/Effect.elm +155 -0
  66. package/generator/template/app/ErrorPage.elm +49 -6
  67. package/generator/template/app/Route/Blog/Slug_.elm +86 -0
  68. package/generator/template/app/Route/Greet.elm +107 -0
  69. package/generator/template/app/Route/Hello.elm +119 -0
  70. package/generator/template/app/Route/Index.elm +26 -25
  71. package/generator/template/app/Shared.elm +38 -39
  72. package/generator/template/app/Site.elm +4 -7
  73. package/generator/template/app/View.elm +9 -8
  74. package/generator/template/codegen/elm.codegen.json +18 -0
  75. package/generator/template/custom-backend-task.ts +3 -0
  76. package/generator/template/elm-pages.config.mjs +13 -0
  77. package/generator/template/elm-tooling.json +0 -3
  78. package/generator/template/elm.json +25 -20
  79. package/generator/template/index.ts +1 -2
  80. package/generator/template/netlify.toml +4 -1
  81. package/generator/template/package.json +10 -4
  82. package/generator/template/script/.elm-pages/compiled-ports/custom-backend-task.mjs +7 -0
  83. package/generator/template/script/custom-backend-task.ts +3 -0
  84. package/generator/template/script/elm.json +61 -0
  85. package/generator/template/script/src/AddRoute.elm +312 -0
  86. package/generator/template/script/src/Stars.elm +42 -0
  87. package/package.json +30 -27
  88. package/src/ApiRoute.elm +249 -85
  89. package/src/BackendTask/Custom.elm +325 -0
  90. package/src/BackendTask/Env.elm +90 -0
  91. package/src/{DataSource → BackendTask}/File.elm +171 -56
  92. package/src/{DataSource → BackendTask}/Glob.elm +136 -125
  93. package/src/BackendTask/Http.elm +679 -0
  94. package/src/{DataSource → BackendTask}/Internal/Glob.elm +1 -1
  95. package/src/BackendTask/Internal/Request.elm +69 -0
  96. package/src/BackendTask/Random.elm +79 -0
  97. package/src/BackendTask/Time.elm +47 -0
  98. package/src/BackendTask.elm +531 -0
  99. package/src/FatalError.elm +90 -0
  100. package/src/FormData.elm +21 -18
  101. package/src/Head/Seo.elm +4 -4
  102. package/src/Head.elm +237 -7
  103. package/src/Internal/ApiRoute.elm +7 -5
  104. package/src/Internal/Request.elm +84 -4
  105. package/src/PageServerResponse.elm +6 -1
  106. package/src/Pages/ConcurrentSubmission.elm +127 -0
  107. package/src/Pages/Form.elm +340 -0
  108. package/src/Pages/FormData.elm +19 -0
  109. package/src/Pages/GeneratorProgramConfig.elm +15 -0
  110. package/src/Pages/Internal/FatalError.elm +5 -0
  111. package/src/Pages/Internal/Msg.elm +93 -0
  112. package/src/Pages/Internal/NotFoundReason.elm +4 -4
  113. package/src/Pages/Internal/Platform/Cli.elm +629 -767
  114. package/src/Pages/Internal/Platform/CompatibilityKey.elm +6 -0
  115. package/src/Pages/Internal/Platform/Effect.elm +1 -2
  116. package/src/Pages/Internal/Platform/GeneratorApplication.elm +379 -0
  117. package/src/Pages/Internal/Platform/StaticResponses.elm +65 -276
  118. package/src/Pages/Internal/Platform/ToJsPayload.elm +6 -9
  119. package/src/Pages/Internal/Platform.elm +330 -203
  120. package/src/Pages/Internal/ResponseSketch.elm +2 -2
  121. package/src/Pages/Internal/Script.elm +17 -0
  122. package/src/Pages/Internal/StaticHttpBody.elm +35 -1
  123. package/src/Pages/Manifest.elm +52 -11
  124. package/src/Pages/Navigation.elm +85 -0
  125. package/src/Pages/PageUrl.elm +26 -12
  126. package/src/Pages/ProgramConfig.elm +32 -22
  127. package/src/Pages/Script.elm +166 -0
  128. package/src/Pages/SiteConfig.elm +3 -2
  129. package/src/Pages/StaticHttp/Request.elm +2 -2
  130. package/src/Pages/StaticHttpRequest.elm +23 -99
  131. package/src/Pages/Url.elm +3 -3
  132. package/src/PagesMsg.elm +88 -0
  133. package/src/QueryParams.elm +21 -172
  134. package/src/RenderRequest.elm +7 -7
  135. package/src/RequestsAndPending.elm +37 -20
  136. package/src/Result/Extra.elm +26 -0
  137. package/src/Scaffold/Form.elm +569 -0
  138. package/src/Scaffold/Route.elm +1431 -0
  139. package/src/Server/Request.elm +476 -1001
  140. package/src/Server/Response.elm +130 -36
  141. package/src/Server/Session.elm +181 -111
  142. package/src/Server/SetCookie.elm +80 -32
  143. package/src/Stub.elm +53 -0
  144. package/src/Test/Html/Internal/ElmHtml/ToString.elm +8 -9
  145. package/src/{Path.elm → UrlPath.elm} +33 -36
  146. package/generator/template/public/images/icon-png.png +0 -0
  147. package/src/DataSource/Env.elm +0 -38
  148. package/src/DataSource/Http.elm +0 -446
  149. package/src/DataSource/Internal/Request.elm +0 -20
  150. package/src/DataSource/Port.elm +0 -90
  151. package/src/DataSource.elm +0 -538
  152. package/src/Form/Field.elm +0 -717
  153. package/src/Form/FieldStatus.elm +0 -36
  154. package/src/Form/FieldView.elm +0 -417
  155. package/src/Form/FormData.elm +0 -22
  156. package/src/Form/Validation.elm +0 -391
  157. package/src/Form/Value.elm +0 -118
  158. package/src/Form.elm +0 -1683
  159. package/src/FormDecoder.elm +0 -102
  160. package/src/Pages/FormState.elm +0 -256
  161. package/src/Pages/Generate.elm +0 -1151
  162. package/src/Pages/Internal/Form.elm +0 -17
  163. package/src/Pages/Msg.elm +0 -79
  164. package/src/Pages/Transition.elm +0 -70
@@ -20,34 +20,29 @@ import BuildError exposing (BuildError)
20
20
  import Bytes exposing (Bytes)
21
21
  import Bytes.Decode
22
22
  import Dict exposing (Dict)
23
- import Form.FormData exposing (FormData, Method(..))
24
- import FormDecoder
23
+ import Form
25
24
  import Html exposing (Html)
26
25
  import Html.Attributes as Attr
27
26
  import Http
28
27
  import Json.Decode as Decode
29
28
  import Json.Encode
29
+ import Pages.ConcurrentSubmission
30
30
  import Pages.ContentCache as ContentCache
31
31
  import Pages.Fetcher
32
32
  import Pages.Flags
33
- import Pages.FormState
33
+ import Pages.Internal.Msg
34
34
  import Pages.Internal.NotFoundReason exposing (NotFoundReason)
35
35
  import Pages.Internal.ResponseSketch as ResponseSketch exposing (ResponseSketch)
36
36
  import Pages.Internal.String as String
37
- import Pages.Msg
37
+ import Pages.Navigation
38
38
  import Pages.ProgramConfig exposing (ProgramConfig)
39
39
  import Pages.StaticHttpRequest as StaticHttpRequest
40
- import Pages.Transition
41
- import Path exposing (Path)
40
+ import PagesMsg exposing (PagesMsg)
42
41
  import QueryParams
43
42
  import Task
44
43
  import Time
45
44
  import Url exposing (Url)
46
-
47
-
48
- type Transition
49
- = Loading Int Path
50
- | Submitting FormData
45
+ import UrlPath exposing (UrlPath)
51
46
 
52
47
 
53
48
  {-| -}
@@ -58,7 +53,7 @@ type alias Program userModel userMsg pageData actionData sharedData errorPage =
58
53
  mainView :
59
54
  ProgramConfig userMsg userModel route pageData actionData sharedData effect (Msg userMsg pageData actionData sharedData errorPage) errorPage
60
55
  -> Model userModel pageData actionData sharedData
61
- -> { title : String, body : List (Html (Pages.Msg.Msg userMsg)) }
56
+ -> { title : String, body : List (Html (PagesMsg userMsg)) }
62
57
  mainView config model =
63
58
  case model.notFound of
64
59
  Just info ->
@@ -81,7 +76,7 @@ mainView config model =
81
76
  (config.view model.pageFormState
82
77
  (model.inFlightFetchers |> toFetcherState)
83
78
  (model.transition |> Maybe.map Tuple.second)
84
- { path = ContentCache.pathForUrl urls |> Path.join
79
+ { path = ContentCache.pathForUrl urls |> UrlPath.join
85
80
  , route = config.urlToRoute { currentUrl | path = model.currentPath }
86
81
  }
87
82
  Nothing
@@ -101,14 +96,14 @@ mainView config model =
101
96
 
102
97
  urlsToPagePath :
103
98
  { currentUrl : Url, basePath : List String }
104
- -> Path
99
+ -> UrlPath
105
100
  urlsToPagePath urls =
106
101
  urls.currentUrl.path
107
102
  |> String.chopForwardSlashes
108
103
  |> String.split "/"
109
104
  |> List.filter ((/=) "")
110
105
  |> List.drop (List.length urls.basePath)
111
- |> Path.join
106
+ |> UrlPath.join
112
107
 
113
108
 
114
109
  {-| -}
@@ -150,7 +145,7 @@ type alias Flags =
150
145
 
151
146
  type InitKind shared page actionData errorPage
152
147
  = OkPage shared page (Maybe actionData)
153
- | NotFound { reason : NotFoundReason, path : Path }
148
+ | NotFound { reason : NotFoundReason, path : UrlPath }
154
149
 
155
150
 
156
151
  {-| -}
@@ -204,7 +199,7 @@ init config flags url key =
204
199
  , basePath = config.basePath
205
200
  }
206
201
 
207
- pagePath : Path
202
+ pagePath : UrlPath
208
203
  pagePath =
209
204
  urlsToPagePath urls
210
205
 
@@ -230,7 +225,7 @@ init config flags url key =
230
225
  , host = url.host
231
226
  , port_ = url.port_
232
227
  , path = pagePath
233
- , query = url.query |> Maybe.map QueryParams.fromString
228
+ , query = url.query |> Maybe.map QueryParams.fromString |> Maybe.withDefault Dict.empty
234
229
  , fragment = url.fragment
235
230
  }
236
231
  }
@@ -274,7 +269,7 @@ init config flags url key =
274
269
  , url = url
275
270
  , currentPath = url.path
276
271
  , pageData = Err "Not found"
277
- , ariaNavigationAnnouncement = "Error" -- TODO use error page title for announcement?
272
+ , ariaNavigationAnnouncement = "Page Not Found" -- TODO use error page title for announcement?
278
273
  , userFlags = flags
279
274
  , notFound = Just info
280
275
  , transition = Nothing
@@ -313,16 +308,23 @@ init config flags url key =
313
308
  type Msg userMsg pageData actionData sharedData errorPage
314
309
  = LinkClicked Browser.UrlRequest
315
310
  | UrlChanged Url
316
- | UserMsg (Pages.Msg.Msg userMsg)
317
- | SetField { formId : String, name : String, value : String }
311
+ -- TODO rename to PagesMsg
312
+ | UserMsg (PagesMsg userMsg)
313
+ --| SetField { formId : String, name : String, value : String }
314
+ | FormMsg (Form.Msg (Msg userMsg pageData actionData sharedData errorPage))
318
315
  | 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 ))
316
+ | FetcherComplete Bool String Int (Result Http.Error ( Maybe userMsg, ActionDataOrRedirect actionData ))
320
317
  | FetcherStarted String Int FormData Time.Posix
321
318
  | PageScrollComplete
322
319
  | HotReloadCompleteNew Bytes
323
320
  | 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
321
 
325
322
 
323
+ type ActionDataOrRedirect action
324
+ = ActionResponse (Maybe action)
325
+ | RedirectResponse String
326
+
327
+
326
328
  {-| -}
327
329
  type alias Model userModel pageData actionData sharedData =
328
330
  { key : Maybe Browser.Navigation.Key
@@ -337,12 +339,12 @@ type alias Model userModel pageData actionData sharedData =
337
339
  , sharedData : sharedData
338
340
  , actionData : Maybe actionData
339
341
  }
340
- , notFound : Maybe { reason : NotFoundReason, path : Path }
342
+ , notFound : Maybe { reason : NotFoundReason, path : UrlPath }
341
343
  , userFlags : Decode.Value
342
- , transition : Maybe ( Int, Pages.Transition.Transition )
344
+ , transition : Maybe ( Int, Pages.Navigation.Navigation )
343
345
  , nextTransitionKey : Int
344
- , inFlightFetchers : Dict String ( Int, Pages.Transition.FetcherState actionData )
345
- , pageFormState : Pages.FormState.PageFormState
346
+ , inFlightFetchers : Dict String ( Int, Pages.ConcurrentSubmission.ConcurrentSubmission actionData )
347
+ , pageFormState : Form.Model
346
348
  , pendingRedirect : Bool
347
349
  , pendingData : Maybe ( pageData, sharedData, Maybe actionData )
348
350
  }
@@ -361,6 +363,7 @@ type Effect userMsg pageData actionData sharedData userEffect errorPage
361
363
  | Batch (List (Effect userMsg pageData actionData sharedData userEffect errorPage))
362
364
  | UserCmd userEffect
363
365
  | CancelRequest Int
366
+ | RunCmd (Cmd (Msg userMsg pageData actionData sharedData errorPage))
364
367
 
365
368
 
366
369
  {-| -}
@@ -371,6 +374,18 @@ update :
371
374
  -> ( Model userModel pageData actionData sharedData, Effect userMsg pageData actionData sharedData userEffect errorPage )
372
375
  update config appMsg model =
373
376
  case appMsg of
377
+ FormMsg formMsg ->
378
+ let
379
+ -- TODO trigger formCmd
380
+ ( newModel, formCmd ) =
381
+ Form.update formMsg model.pageFormState
382
+ in
383
+ ( { model
384
+ | pageFormState = newModel
385
+ }
386
+ , RunCmd formCmd
387
+ )
388
+
374
389
  LinkClicked urlRequest ->
375
390
  case urlRequest of
376
391
  Browser.Internal url ->
@@ -396,11 +411,6 @@ update config appMsg model =
396
411
  , BrowserLoadUrl href
397
412
  )
398
413
 
399
- SetField info ->
400
- ( { model | pageFormState = Pages.FormState.setField info model.pageFormState }
401
- , NoEffect
402
- )
403
-
404
414
  UrlChanged url ->
405
415
  case model.pendingData of
406
416
  Just ( newPageData, newSharedData, newActionData ) ->
@@ -414,7 +424,7 @@ update config appMsg model =
414
424
  model
415
425
 
416
426
  Nothing ->
417
- if model.url.path == url.path then
427
+ if model.url.path == url.path && model.url.query == url.query then
418
428
  ( { model
419
429
  | -- update the URL in case query params or fragment changed
420
430
  url = url
@@ -430,37 +440,50 @@ update config appMsg model =
430
440
  -- parallel to the browser behavior
431
441
  |> startNewGetLoad url (UpdateCacheAndUrlNew True url Nothing)
432
442
 
433
- FetcherComplete forPageReload fetcherKey transitionId___ userMsgResult ->
443
+ FetcherComplete _ fetcherKey _ userMsgResult ->
434
444
  case userMsgResult of
435
- Ok ( userMsg, maybeFetcherDoneActionData ) ->
436
- ( { model
437
- | inFlightFetchers =
438
- model.inFlightFetchers
439
- |> Dict.update fetcherKey
440
- (Maybe.map
441
- (\( transitionId, fetcherState ) ->
442
- ( transitionId
443
- , { fetcherState
444
- | status =
445
- maybeFetcherDoneActionData
446
- |> Maybe.map Pages.Transition.FetcherReloading
447
- -- TODO remove this bad default, FetcherSubmitting is incorrect
448
- |> Maybe.withDefault Pages.Transition.FetcherSubmitting
449
- }
445
+ Ok ( userMsg, actionOrRedirect ) ->
446
+ case actionOrRedirect of
447
+ ActionResponse maybeFetcherDoneActionData ->
448
+ ( { model
449
+ | inFlightFetchers =
450
+ model.inFlightFetchers
451
+ |> Dict.update fetcherKey
452
+ (Maybe.map
453
+ (\( transitionId, fetcherState ) ->
454
+ ( transitionId
455
+ , { fetcherState
456
+ | status =
457
+ maybeFetcherDoneActionData
458
+ |> Maybe.map Pages.ConcurrentSubmission.Reloading
459
+ -- TODO remove this bad default, FetcherSubmitting is incorrect
460
+ |> Maybe.withDefault Pages.ConcurrentSubmission.Submitting
461
+ }
462
+ )
463
+ )
450
464
  )
451
- )
452
- )
453
- }
454
- , NoEffect
455
- )
456
- |> (case userMsg of
457
- Just justUserMsg ->
458
- performUserMsg justUserMsg config
459
-
460
- Nothing ->
461
- identity
462
- )
463
- |> startNewGetLoad (currentUrlWithPath model.url.path model) (UpdateCacheAndUrlNew False model.url Nothing)
465
+ }
466
+ , NoEffect
467
+ )
468
+ |> (case userMsg of
469
+ Just justUserMsg ->
470
+ performUserMsg justUserMsg config
471
+
472
+ Nothing ->
473
+ identity
474
+ )
475
+ |> startNewGetLoad (currentUrlWithPath model.url.path model) (UpdateCacheAndUrlNew False model.url Nothing)
476
+
477
+ RedirectResponse redirectTo ->
478
+ ( { model
479
+ | inFlightFetchers =
480
+ model.inFlightFetchers
481
+ |> Dict.remove fetcherKey
482
+ , pendingRedirect = True
483
+ }
484
+ , NoEffect
485
+ )
486
+ |> startNewGetLoad (currentUrlWithPath redirectTo model) (UpdateCacheAndUrlNew False model.url Nothing)
464
487
 
465
488
  Err _ ->
466
489
  -- TODO how to handle error?
@@ -478,74 +501,70 @@ update config appMsg model =
478
501
 
479
502
  UserMsg userMsg_ ->
480
503
  case userMsg_ of
481
- Pages.Msg.UserMsg userMsg ->
504
+ Pages.Internal.Msg.UserMsg userMsg ->
482
505
  ( model, NoEffect )
483
506
  |> performUserMsg userMsg config
484
507
 
485
- Pages.Msg.Submit fields ->
486
- ( { model
487
- | transition =
488
- Just
489
- ( -- TODO remove hardcoded number
490
- -1
491
- , Pages.Transition.Submitting fields
492
- )
493
- }
494
- , Submit fields
495
- )
496
-
497
- Pages.Msg.SubmitIfValid formId fields isValid ->
498
- if isValid then
499
- ( { model
500
- -- TODO should I setSubmitAttempted here, too?
501
- | transition =
502
- Just
503
- ( -- TODO remove hardcoded number
504
- -1
505
- , Pages.Transition.Submitting fields
506
- )
507
- }
508
- , Submit fields
509
- )
510
-
511
- else
512
- ( { model
513
- | pageFormState =
514
- model.pageFormState
515
- |> Pages.FormState.setSubmitAttempted formId
516
- }
517
- , NoEffect
518
- )
519
-
520
- Pages.Msg.SubmitFetcher fetcherKey fields isValid maybeUserMsg ->
521
- if isValid then
522
- -- TODO should I setSubmitAttempted here, too?
523
- ( { model | nextTransitionKey = model.nextTransitionKey + 1 }
524
- , SubmitFetcher fetcherKey model.nextTransitionKey fields
525
- )
526
- |> (case maybeUserMsg of
527
- Just justUserMsg ->
528
- performUserMsg justUserMsg config
508
+ Pages.Internal.Msg.Submit fields ->
509
+ if fields.valid then
510
+ let
511
+ payload : { fields : List ( String, String ), method : Form.Method, action : String, id : Maybe String }
512
+ payload =
513
+ { fields = fields.fields
514
+ , method = fields.method
515
+ , action = fields.action
516
+ , id = Just fields.id
517
+ }
518
+ in
519
+ if fields.useFetcher then
520
+ ( { model | nextTransitionKey = model.nextTransitionKey + 1 }
521
+ , SubmitFetcher fields.id model.nextTransitionKey payload
522
+ )
523
+ |> (case fields.msg of
524
+ Just justUserMsg ->
525
+ performUserMsg justUserMsg config
526
+
527
+ Nothing ->
528
+ identity
529
+ )
530
+
531
+ else
532
+ ( { model
533
+ -- TODO should I setSubmitAttempted here, too?
534
+ | transition =
535
+ Just
536
+ ( -- TODO remove hardcoded number
537
+ -1
538
+ , Pages.Navigation.Submitting payload
539
+ )
540
+ }
541
+ , Submit payload
542
+ )
543
+ |> (case fields.msg of
544
+ Just justUserMsg ->
545
+ performUserMsg justUserMsg config
529
546
 
530
- Nothing ->
531
- identity
532
- )
547
+ Nothing ->
548
+ identity
549
+ )
533
550
 
534
551
  else
535
- ( { model
536
- | pageFormState =
537
- model.pageFormState
538
- |> Pages.FormState.setSubmitAttempted fetcherKey
539
- }
540
- , NoEffect
541
- )
552
+ -- TODO should the user msg still be run if the form is invalid?
553
+ ( model, NoEffect )
542
554
 
543
- Pages.Msg.FormFieldEvent value ->
555
+ Pages.Internal.Msg.FormMsg formMsg ->
544
556
  -- TODO when init is called for a new page, also need to clear out client-side `pageFormState`
545
- ( { model | pageFormState = Pages.FormState.update value model.pageFormState }
546
- , NoEffect
557
+ let
558
+ ( formModel, formCmd ) =
559
+ Form.update formMsg model.pageFormState
560
+ in
561
+ ( { model | pageFormState = formModel }
562
+ , RunCmd (Cmd.map UserMsg formCmd)
547
563
  )
548
564
 
565
+ Pages.Internal.Msg.NoOp ->
566
+ ( model, NoEffect )
567
+
549
568
  UpdateCacheAndUrlNew scrollToTopWhenDone urlWithoutRedirectResolution maybeUserMsg updateResult ->
550
569
  -- TODO remove all fetchers that are in the state `FetcherReloading` here -- I think that's the right logic?
551
570
  case
@@ -685,10 +704,10 @@ update config appMsg model =
685
704
  Err _ ->
686
705
  {-
687
706
  When there is an error loading the content.dat, we are either
688
- 1) in the dev server, and should show the relevant DataSource error for the page
707
+ 1) in the dev server, and should show the relevant BackendTask error for the page
689
708
  we're navigating to. This could be done more cleanly, but it's simplest to just
690
709
  do a fresh page load and use the code path for presenting an error for a fresh page.
691
- 2) In a production app. That means we had a successful build, so there were no DataSource failures,
710
+ 2) In a production app. That means we had a successful build, so there were no BackendTask failures,
692
711
  so the app must be stale (unless it's in some unexpected state from a bug). In the future,
693
712
  it probably makes sense to include some sort of hash of the app version we are fetching, match
694
713
  it with the current version that's running, and perform this logic when we see there is a mismatch.
@@ -751,7 +770,86 @@ update config appMsg model =
751
770
  _ ->
752
771
  ( model, NoEffect )
753
772
  )
754
- |> Result.withDefault ( model, NoEffect )
773
+ |> Result.withDefault
774
+ (let
775
+ pageDataResult : Maybe (InitKind sharedData pageData actionData errorPage)
776
+ pageDataResult =
777
+ case Bytes.Decode.decode config.decodeResponse pageDataBytes of
778
+ Just (ResponseSketch.RenderPage _ _) ->
779
+ Nothing
780
+
781
+ Just (ResponseSketch.HotUpdate pageData shared actionData) ->
782
+ OkPage shared pageData actionData
783
+ |> Just
784
+
785
+ Just (ResponseSketch.NotFound notFound) ->
786
+ NotFound notFound
787
+ |> Just
788
+
789
+ _ ->
790
+ Nothing
791
+ in
792
+ case pageDataResult of
793
+ Just (OkPage sharedData pageData actionData) ->
794
+ let
795
+ urls : { currentUrl : Url, basePath : List String }
796
+ urls =
797
+ { currentUrl = model.url
798
+ , basePath = config.basePath
799
+ }
800
+
801
+ pagePath : UrlPath
802
+ pagePath =
803
+ urlsToPagePath urls
804
+
805
+ userFlags : Pages.Flags.Flags
806
+ userFlags =
807
+ model.userFlags
808
+ |> Decode.decodeValue
809
+ (Decode.field "userFlags" Decode.value)
810
+ |> Result.withDefault Json.Encode.null
811
+ |> Pages.Flags.BrowserFlags
812
+
813
+ ( userModel, userCmd ) =
814
+ Just
815
+ { path =
816
+ { path = pagePath
817
+ , query = model.url.query
818
+ , fragment = model.url.fragment
819
+ }
820
+ , metadata = config.urlToRoute model.url
821
+ , pageUrl =
822
+ Just
823
+ { protocol = model.url.protocol
824
+ , host = model.url.host
825
+ , port_ = model.url.port_
826
+ , path = pagePath
827
+ , query = model.url.query |> Maybe.map QueryParams.fromString |> Maybe.withDefault Dict.empty
828
+ , fragment = model.url.fragment
829
+ }
830
+ }
831
+ |> config.init userFlags sharedData pageData actionData
832
+
833
+ cmd : Effect userMsg pageData actionData sharedData userEffect errorPage
834
+ cmd =
835
+ UserCmd userCmd
836
+ in
837
+ ( { model
838
+ | pageData =
839
+ Ok
840
+ { userModel = userModel
841
+ , sharedData = sharedData
842
+ , pageData = pageData
843
+ , actionData = actionData
844
+ }
845
+ , notFound = Nothing
846
+ }
847
+ , cmd
848
+ )
849
+
850
+ _ ->
851
+ ( model, NoEffect )
852
+ )
755
853
 
756
854
  FetcherStarted fetcherKey transitionId fetcherData initiatedAt ->
757
855
  ( { model
@@ -760,7 +858,7 @@ update config appMsg model =
760
858
  |> Dict.insert fetcherKey
761
859
  ( transitionId
762
860
  , { payload = fetcherData
763
- , status = Pages.Transition.FetcherSubmitting
861
+ , status = Pages.ConcurrentSubmission.Submitting
764
862
  , initiatedAt = initiatedAt
765
863
  }
766
864
  )
@@ -769,10 +867,10 @@ update config appMsg model =
769
867
  )
770
868
 
771
869
 
772
- toFetcherState : Dict String ( Int, Pages.Transition.FetcherState actionData ) -> Dict String (Pages.Transition.FetcherState actionData)
870
+ toFetcherState : Dict String ( Int, Pages.ConcurrentSubmission.ConcurrentSubmission actionData ) -> Dict String (Pages.ConcurrentSubmission.ConcurrentSubmission actionData)
773
871
  toFetcherState inFlightFetchers =
774
872
  inFlightFetchers
775
- |> Dict.map (\_ ( index, fetcherState ) -> fetcherState)
873
+ |> Dict.map (\_ ( _, fetcherState ) -> fetcherState)
776
874
 
777
875
 
778
876
  performUserMsg :
@@ -806,6 +904,9 @@ perform config model effect =
806
904
  NoEffect ->
807
905
  Cmd.none
808
906
 
907
+ RunCmd cmd ->
908
+ cmd
909
+
809
910
  Batch effects ->
810
911
  effects
811
912
  |> List.map (perform config model)
@@ -834,10 +935,10 @@ perform config model effect =
834
935
  |> Maybe.withDefault Cmd.none
835
936
 
836
937
  FetchPageData transitionKey maybeRequestInfo url toMsg ->
837
- fetchRouteData True transitionKey toMsg config url maybeRequestInfo
938
+ fetchRouteData transitionKey toMsg config url maybeRequestInfo
838
939
 
839
940
  Submit fields ->
840
- if fields.method == Get then
941
+ if fields.method == Form.Get then
841
942
  model.key
842
943
  |> Maybe.map (\key -> Browser.Navigation.pushUrl key (appendFormQueryParams fields))
843
944
  |> Maybe.withDefault Cmd.none
@@ -849,7 +950,7 @@ perform config model effect =
849
950
  -- TODO add optional path parameter to Submit variant to allow submitting to other routes
850
951
  model.url
851
952
  in
852
- fetchRouteData False -1 (UpdateCacheAndUrlNew False model.url Nothing) config urlToSubmitTo (Just fields)
953
+ fetchRouteData -1 (UpdateCacheAndUrlNew False model.url Nothing) config urlToSubmitTo (Just fields)
853
954
 
854
955
  SubmitFetcher fetcherKey transitionId formData ->
855
956
  startFetcher2 config False fetcherKey transitionId formData model
@@ -869,7 +970,7 @@ perform config model effect =
869
970
  |> config.perform
870
971
  { fetchRouteData =
871
972
  \fetchInfo ->
872
- fetchRouteData False
973
+ fetchRouteData
873
974
  -1
874
975
  (prepare fetchInfo.toMsg)
875
976
  config
@@ -879,15 +980,19 @@ perform config model effect =
879
980
  ---- TODO map the Msg with the wrapper type (like in the PR branch)
880
981
  , submit =
881
982
  \fetchInfo ->
882
- fetchRouteData False -1 (prepare fetchInfo.toMsg) config (fetchInfo.values.action |> Url.fromString |> Maybe.withDefault model.url) (Just fetchInfo.values)
983
+ fetchRouteData -1 (prepare fetchInfo.toMsg) config (fetchInfo.values.action |> Url.fromString |> Maybe.withDefault model.url) (Just fetchInfo.values)
883
984
  , runFetcher =
884
985
  \(Pages.Fetcher.Fetcher options) ->
885
986
  -- TODO need to get the fetcherId here
886
987
  -- TODO need to increment and pass in the transitionId
887
988
  startFetcher "TODO" -1 options model
888
- , fromPageMsg = Pages.Msg.UserMsg >> UserMsg
989
+ , fromPageMsg = Pages.Internal.Msg.UserMsg >> UserMsg
889
990
  , key = key
890
- , setField = \info -> Task.succeed (SetField info) |> Task.perform identity
991
+ , setField =
992
+ \_ ->
993
+ --Task.succeed (SetField info) |> Task.perform identity
994
+ -- TODO
995
+ Cmd.none
891
996
  }
892
997
 
893
998
  Nothing ->
@@ -902,21 +1007,12 @@ startFetcher fetcherKey transitionId options model =
902
1007
  let
903
1008
  encodedBody : String
904
1009
  encodedBody =
905
- FormDecoder.encodeFormData
906
- { fields = options.fields
907
-
908
- -- TODO remove hardcoding
909
- , action = ""
910
-
911
- -- TODO remove hardcoding
912
- , method = Post
913
- , id = Nothing
914
- }
1010
+ encodeFormData options.fields
915
1011
 
916
- formData : { method : Method, action : String, fields : List ( String, String ), id : Maybe String }
1012
+ formData : { method : Form.Method, action : String, fields : List ( String, String ), id : Maybe String }
917
1013
  formData =
918
1014
  { -- TODO remove hardcoding
919
- method = Get
1015
+ method = Form.Get
920
1016
 
921
1017
  -- TODO pass FormData directly
922
1018
  , action = options.url |> Maybe.withDefault model.url.path
@@ -933,10 +1029,10 @@ startFetcher fetcherKey transitionId options model =
933
1029
  Http.expectBytesResponse (FetcherComplete False fetcherKey model.nextTransitionKey)
934
1030
  (\bytes ->
935
1031
  case bytes of
936
- Http.GoodStatus_ metadata bytesBody ->
1032
+ Http.GoodStatus_ _ bytesBody ->
937
1033
  ( options.decoder (Ok bytesBody)
938
1034
  |> Just
939
- , Nothing
1035
+ , ActionResponse Nothing
940
1036
  )
941
1037
  |> Ok
942
1038
 
@@ -949,13 +1045,13 @@ startFetcher fetcherKey transitionId options model =
949
1045
  Http.NetworkError_ ->
950
1046
  Err <| Http.NetworkError
951
1047
 
952
- Http.BadStatus_ metadata body ->
1048
+ Http.BadStatus_ metadata _ ->
953
1049
  Err <| Http.BadStatus metadata.statusCode
954
1050
  )
955
1051
  , tracker = Nothing
956
1052
  , body = Http.stringBody "application/x-www-form-urlencoded" encodedBody
957
1053
  , headers = options.headers |> List.map (\( name, value ) -> Http.header name value)
958
- , url = options.url |> Maybe.withDefault (Path.join [ model.url.path, "content.dat" ] |> Path.toAbsolute)
1054
+ , url = options.url |> Maybe.withDefault (UrlPath.join [ model.url.path, "content.dat" ] |> UrlPath.toAbsolute)
959
1055
  , method = "POST"
960
1056
  , timeout = Nothing
961
1057
  }
@@ -974,13 +1070,13 @@ startFetcher2 config fromPageReload fetcherKey transitionId formData model =
974
1070
  let
975
1071
  encodedBody : String
976
1072
  encodedBody =
977
- FormDecoder.encodeFormData formData
1073
+ encodeFormData formData.fields
978
1074
  in
979
1075
  -- TODO make sure that `actionData` isn't updated in Model for fetchers
980
1076
  Cmd.batch
981
1077
  [ cancelStaleFetchers model
982
1078
  , case Dict.get fetcherKey model.inFlightFetchers of
983
- Just ( inFlightId, inFlightFetcher ) ->
1079
+ Just ( inFlightId, _ ) ->
984
1080
  Http.cancel (String.fromInt inFlightId)
985
1081
 
986
1082
  Nothing ->
@@ -991,22 +1087,26 @@ startFetcher2 config fromPageReload fetcherKey transitionId formData model =
991
1087
  Http.expectBytesResponse (FetcherComplete fromPageReload fetcherKey model.nextTransitionKey)
992
1088
  (\bytes ->
993
1089
  case bytes of
994
- Http.GoodStatus_ metadata bytesBody ->
1090
+ Http.GoodStatus_ _ bytesBody ->
995
1091
  let
996
- decodedAction : Maybe actionData
1092
+ decodedAction : ActionDataOrRedirect actionData
997
1093
  decodedAction =
998
1094
  case Bytes.Decode.decode config.decodeResponse bytesBody of
1095
+ -- @@@
1096
+ Just (ResponseSketch.Redirect redirectTo) ->
1097
+ RedirectResponse redirectTo
1098
+
999
1099
  Just (ResponseSketch.RenderPage _ maybeAction) ->
1000
- maybeAction
1100
+ ActionResponse maybeAction
1001
1101
 
1002
- Just (ResponseSketch.HotUpdate pageData shared maybeAction) ->
1003
- maybeAction
1102
+ Just (ResponseSketch.HotUpdate _ _ maybeAction) ->
1103
+ ActionResponse maybeAction
1004
1104
 
1005
- Just (ResponseSketch.NotFound notFound) ->
1006
- Nothing
1105
+ Just (ResponseSketch.NotFound _) ->
1106
+ ActionResponse Nothing
1007
1107
 
1008
1108
  _ ->
1009
- Nothing
1109
+ ActionResponse Nothing
1010
1110
  in
1011
1111
  -- TODO maybe have an optional way to pass the bytes through?
1012
1112
  Ok ( Nothing, decodedAction )
@@ -1020,7 +1120,7 @@ startFetcher2 config fromPageReload fetcherKey transitionId formData model =
1020
1120
  Http.NetworkError_ ->
1021
1121
  Err <| Http.NetworkError
1022
1122
 
1023
- Http.BadStatus_ metadata body ->
1123
+ Http.BadStatus_ metadata _ ->
1024
1124
  Err <| Http.BadStatus metadata.statusCode
1025
1125
  )
1026
1126
  , tracker = Just (String.fromInt transitionId)
@@ -1030,8 +1130,8 @@ startFetcher2 config fromPageReload fetcherKey transitionId formData model =
1030
1130
  , headers = []
1031
1131
 
1032
1132
  -- TODO use formData.method to do either query params or POST body
1033
- , url = formData.action |> Url.fromString |> Maybe.map (\{ path } -> Path.join [ path, "content.dat" ] |> Path.toAbsolute) |> Maybe.withDefault "/"
1034
- , method = formData.method |> FormDecoder.methodToString
1133
+ , url = formData.action |> Url.fromString |> Maybe.map (\{ path } -> UrlPath.join [ path, "content.dat" ] |> UrlPath.toAbsolute) |> Maybe.withDefault "/"
1134
+ , method = formData.method |> methodToString
1035
1135
  , timeout = Nothing
1036
1136
  }
1037
1137
  ]
@@ -1042,16 +1142,16 @@ cancelStaleFetchers model =
1042
1142
  model.inFlightFetchers
1043
1143
  |> Dict.toList
1044
1144
  |> List.filterMap
1045
- (\( fetcherKey, ( id, fetcher ) ) ->
1145
+ (\( _, ( id, fetcher ) ) ->
1046
1146
  case fetcher.status of
1047
- Pages.Transition.FetcherReloading _ ->
1147
+ Pages.ConcurrentSubmission.Reloading _ ->
1048
1148
  Http.cancel (String.fromInt id)
1049
1149
  |> Just
1050
1150
 
1051
- Pages.Transition.FetcherSubmitting ->
1151
+ Pages.ConcurrentSubmission.Submitting ->
1052
1152
  Nothing
1053
1153
 
1054
- Pages.Transition.FetcherComplete _ ->
1154
+ Pages.ConcurrentSubmission.Complete _ ->
1055
1155
  Nothing
1056
1156
  )
1057
1157
  |> Cmd.batch
@@ -1065,10 +1165,10 @@ appendFormQueryParams fields =
1065
1165
  |> Maybe.withDefault "/"
1066
1166
  )
1067
1167
  ++ (case fields.method of
1068
- Get ->
1069
- "?" ++ FormDecoder.encodeFormData fields
1168
+ Form.Get ->
1169
+ "?" ++ encodeFormData fields.fields
1070
1170
 
1071
- Post ->
1171
+ Form.Post ->
1072
1172
  ""
1073
1173
  )
1074
1174
 
@@ -1108,9 +1208,9 @@ application config =
1108
1208
  in
1109
1209
  Sub.batch
1110
1210
  [ config.subscriptions (model.url |> config.urlToRoute)
1111
- (urls.currentUrl |> config.urlToRoute |> config.routeToPath |> Path.join)
1211
+ (urls.currentUrl |> config.urlToRoute |> config.routeToPath |> UrlPath.join)
1112
1212
  pageData.userModel
1113
- |> Sub.map (Pages.Msg.UserMsg >> UserMsg)
1213
+ |> Sub.map (Pages.Internal.Msg.UserMsg >> UserMsg)
1114
1214
  , config.hotReloadData
1115
1215
  |> Sub.map HotReloadCompleteNew
1116
1216
  ]
@@ -1157,20 +1257,19 @@ withUserMsg config userMsg ( model, effect ) =
1157
1257
  ( model, effect )
1158
1258
 
1159
1259
 
1160
- urlPathToPath : Url -> Path
1260
+ urlPathToPath : Url -> UrlPath
1161
1261
  urlPathToPath urls =
1162
- urls.path |> Path.fromString
1262
+ urls.path |> UrlPath.fromString
1163
1263
 
1164
1264
 
1165
1265
  fetchRouteData :
1166
- Bool
1167
- -> Int
1266
+ Int
1168
1267
  -> (Result Http.Error ( Url, ResponseSketch pageData actionData sharedData ) -> Msg userMsg pageData actionData sharedData errorPage)
1169
1268
  -> ProgramConfig userMsg userModel route pageData actionData sharedData effect (Msg userMsg pageData actionData sharedData errorPage) errorPage
1170
1269
  -> Url
1171
1270
  -> Maybe FormData
1172
1271
  -> Cmd (Msg userMsg pageData actionData sharedData errorPage)
1173
- fetchRouteData forPageDataReload transitionKey toMsg config url details =
1272
+ fetchRouteData transitionKey toMsg config url details =
1174
1273
  {-
1175
1274
  TODO:
1176
1275
  - [X] `toMsg` needs a parameter for the callback Msg so it can pass it on if there is a Redirect response
@@ -1184,14 +1283,14 @@ fetchRouteData forPageDataReload transitionKey toMsg config url details =
1184
1283
 
1185
1284
  -}
1186
1285
  let
1187
- formMethod : Method
1286
+ formMethod : Form.Method
1188
1287
  formMethod =
1189
1288
  details
1190
1289
  |> Maybe.map .method
1191
- |> Maybe.withDefault Get
1290
+ |> Maybe.withDefault Form.Get
1192
1291
  in
1193
1292
  Http.request
1194
- { method = details |> Maybe.map (.method >> FormDecoder.methodToString) |> Maybe.withDefault "GET"
1293
+ { method = details |> Maybe.map (.method >> methodToString) |> Maybe.withDefault "GET"
1195
1294
  , headers = []
1196
1295
  , url =
1197
1296
  "/"
@@ -1209,34 +1308,34 @@ fetchRouteData forPageDataReload transitionKey toMsg config url details =
1209
1308
  |> String.join "/"
1210
1309
  )
1211
1310
  ++ (case formMethod of
1212
- Post ->
1311
+ Form.Post ->
1213
1312
  "/"
1214
1313
 
1215
- Get ->
1314
+ Form.Get ->
1216
1315
  details
1217
- |> Maybe.map FormDecoder.encodeFormData
1316
+ |> Maybe.map (.fields >> encodeFormData)
1218
1317
  |> Maybe.map (\encoded -> "?" ++ encoded)
1219
1318
  |> Maybe.withDefault ""
1220
1319
  )
1221
1320
  ++ (case formMethod of
1222
1321
  -- TODO extract this to something unit testable
1223
1322
  -- TODO make states mutually exclusive for submissions and direct URL requests (shouldn't be possible to append two query param strings)
1224
- Post ->
1323
+ Form.Post ->
1225
1324
  ""
1226
1325
 
1227
- Get ->
1326
+ Form.Get ->
1228
1327
  url.query
1229
1328
  |> Maybe.map (\encoded -> "?" ++ encoded)
1230
1329
  |> Maybe.withDefault ""
1231
1330
  )
1232
1331
  , body =
1233
1332
  case formMethod of
1234
- Post ->
1333
+ Form.Post ->
1235
1334
  let
1236
1335
  urlEncodedFields : Maybe String
1237
1336
  urlEncodedFields =
1238
1337
  details
1239
- |> Maybe.map FormDecoder.encodeFormData
1338
+ |> Maybe.map (.fields >> encodeFormData)
1240
1339
  in
1241
1340
  urlEncodedFields
1242
1341
  |> Maybe.map (\encoded -> Http.stringBody "application/x-www-form-urlencoded" encoded)
@@ -1257,7 +1356,7 @@ fetchRouteData forPageDataReload transitionKey toMsg config url details =
1257
1356
  Http.NetworkError_ ->
1258
1357
  Err Http.NetworkError
1259
1358
 
1260
- Http.BadStatus_ metadata body ->
1359
+ Http.BadStatus_ _ body ->
1261
1360
  body
1262
1361
  |> Bytes.Decode.decode config.decodeResponse
1263
1362
  |> Result.fromMaybe "Decoding error"
@@ -1309,7 +1408,7 @@ startNewGetLoad urlToGet toMsg ( model, effect ) =
1309
1408
  cancelIfStale : Effect userMsg pageData actionData sharedData userEffect errorPage
1310
1409
  cancelIfStale =
1311
1410
  case model.transition of
1312
- Just ( transitionKey, Pages.Transition.Loading path loadingKind ) ->
1411
+ Just ( transitionKey, Pages.Navigation.Loading _ _ ) ->
1313
1412
  CancelRequest transitionKey
1314
1413
 
1315
1414
  _ ->
@@ -1320,22 +1419,22 @@ startNewGetLoad urlToGet toMsg ( model, effect ) =
1320
1419
  , transition =
1321
1420
  ( model.nextTransitionKey
1322
1421
  , case model.transition of
1323
- Just ( transitionKey, Pages.Transition.LoadAfterSubmit submitData _ _ ) ->
1324
- Pages.Transition.LoadAfterSubmit
1422
+ Just ( _, Pages.Navigation.LoadAfterSubmit submitData _ _ ) ->
1423
+ Pages.Navigation.LoadAfterSubmit
1325
1424
  submitData
1326
- (urlToGet.path |> Path.fromString)
1327
- Pages.Transition.Load
1425
+ (urlToGet.path |> UrlPath.fromString)
1426
+ Pages.Navigation.Load
1328
1427
 
1329
- Just ( transitionKey, Pages.Transition.Submitting submitData ) ->
1330
- Pages.Transition.LoadAfterSubmit
1428
+ Just ( _, Pages.Navigation.Submitting submitData ) ->
1429
+ Pages.Navigation.LoadAfterSubmit
1331
1430
  submitData
1332
- (urlToGet.path |> Path.fromString)
1333
- Pages.Transition.Load
1431
+ (urlToGet.path |> UrlPath.fromString)
1432
+ Pages.Navigation.Load
1334
1433
 
1335
1434
  _ ->
1336
- Pages.Transition.Loading
1337
- (urlToGet.path |> Path.fromString)
1338
- Pages.Transition.Load
1435
+ Pages.Navigation.Loading
1436
+ (urlToGet.path |> UrlPath.fromString)
1437
+ Pages.Navigation.Load
1339
1438
  )
1340
1439
  |> Just
1341
1440
  }
@@ -1361,9 +1460,9 @@ clearLoadingFetchersAfterDataLoad completedTransitionId model =
1361
1460
  -- TODO fetchers are never removed from the list. Need to decide how and when to remove them.
1362
1461
  --(fetcherState.status /= Pages.Transition.FetcherReloading) || (transitionId > completedTransitionId)
1363
1462
  case ( transitionId > completedTransitionId, fetcherState.status ) of
1364
- ( False, Pages.Transition.FetcherReloading actionData ) ->
1463
+ ( False, Pages.ConcurrentSubmission.Reloading actionData ) ->
1365
1464
  ( transitionId
1366
- , { fetcherState | status = Pages.Transition.FetcherComplete actionData }
1465
+ , { fetcherState | status = Pages.ConcurrentSubmission.Complete actionData }
1367
1466
  )
1368
1467
 
1369
1468
  _ ->
@@ -1399,7 +1498,7 @@ loadDataAndUpdateUrl ( newPageData, newSharedData, newActionData ) maybeUserMsg
1399
1498
  }
1400
1499
 
1401
1500
  -- TODO use userEffect here?
1402
- ( userModel, userEffect ) =
1501
+ ( userModel, _ ) =
1403
1502
  -- TODO if urlWithoutRedirectResolution is different from the url with redirect resolution, then
1404
1503
  -- instead of calling update, call pushUrl (I think?)
1405
1504
  -- TODO include user Cmd
@@ -1474,10 +1573,10 @@ loadDataAndUpdateUrl ( newPageData, newSharedData, newActionData ) maybeUserMsg
1474
1573
  Err _ ->
1475
1574
  {-
1476
1575
  When there is an error loading the content.dat, we are either
1477
- 1) in the dev server, and should show the relevant DataSource error for the page
1576
+ 1) in the dev server, and should show the relevant BackendTask error for the page
1478
1577
  we're navigating to. This could be done more cleanly, but it's simplest to just
1479
1578
  do a fresh page load and use the code path for presenting an error for a fresh page.
1480
- 2) In a production app. That means we had a successful build, so there were no DataSource failures,
1579
+ 2) In a production app. That means we had a successful build, so there were no BackendTask failures,
1481
1580
  so the app must be stale (unless it's in some unexpected state from a bug). In the future,
1482
1581
  it probably makes sense to include some sort of hash of the app version we are fetching, match
1483
1582
  it with the current version that's running, and perform this logic when we see there is a mismatch.
@@ -1490,3 +1589,31 @@ loadDataAndUpdateUrl ( newPageData, newSharedData, newActionData ) maybeUserMsg
1490
1589
  |> Url.toString
1491
1590
  |> BrowserLoadUrl
1492
1591
  )
1592
+
1593
+
1594
+ methodToString : Form.Method -> String
1595
+ methodToString method =
1596
+ case method of
1597
+ Form.Get ->
1598
+ "GET"
1599
+
1600
+ Form.Post ->
1601
+ "POST"
1602
+
1603
+
1604
+ encodeFormData : List ( String, String ) -> String
1605
+ encodeFormData fields =
1606
+ fields
1607
+ |> List.map
1608
+ (\( name, value ) ->
1609
+ Url.percentEncode name ++ "=" ++ Url.percentEncode value
1610
+ )
1611
+ |> String.join "&"
1612
+
1613
+
1614
+ type alias FormData =
1615
+ { fields : List ( String, String )
1616
+ , method : Form.Method
1617
+ , action : String
1618
+ , id : Maybe String
1619
+ }