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.
- package/README.md +10 -1
- package/codegen/{elm-pages-codegen.js → elm-pages-codegen.cjs} +2864 -2589
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateData.elmi +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateData.elmo +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateDataTest.elmo +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/i.dat +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/o.dat +0 -0
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm.json +1 -1
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Reporter.elm.js +1327 -122
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Runner.elm.js +15295 -13271
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
- package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_supervisor.js +4 -4
- package/generator/dead-code-review/elm.json +8 -6
- package/generator/dead-code-review/src/Pages/Review/DeadCodeEliminateData.elm +59 -10
- package/generator/dead-code-review/tests/Pages/Review/DeadCodeEliminateDataTest.elm +52 -36
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/i.dat +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/o.dat +0 -0
- package/generator/review/elm-stuff/tests-0.19.1/elm.json +1 -1
- package/generator/review/elm-stuff/tests-0.19.1/js/Reporter.elm.js +1327 -122
- package/generator/review/elm-stuff/tests-0.19.1/js/Runner.elm.js +14621 -12637
- package/generator/review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
- package/generator/review/elm-stuff/tests-0.19.1/js/node_supervisor.js +4 -4
- package/generator/review/elm.json +8 -8
- package/generator/src/RouteBuilder.elm +113 -107
- package/generator/src/SharedTemplate.elm +3 -2
- package/generator/src/SiteConfig.elm +3 -2
- package/generator/src/basepath-middleware.js +3 -3
- package/generator/src/build.js +123 -87
- package/generator/src/cli.js +256 -77
- package/generator/src/codegen.js +29 -27
- package/generator/src/compatibility-key.js +3 -0
- package/generator/src/compile-elm.js +25 -25
- package/generator/src/config.js +39 -0
- package/generator/src/copy-dir.js +2 -2
- package/generator/src/dev-server.js +150 -133
- package/generator/src/dir-helpers.js +9 -26
- package/generator/src/elm-codegen.js +5 -4
- package/generator/src/elm-file-constants.js +2 -3
- package/generator/src/error-formatter.js +12 -11
- package/generator/src/file-helpers.js +3 -4
- package/generator/src/generate-template-module-connector.js +23 -22
- package/generator/src/init.js +9 -8
- package/generator/src/pre-render-html.js +39 -28
- package/generator/src/render-test.js +109 -0
- package/generator/src/render-worker.js +25 -28
- package/generator/src/render.js +322 -142
- package/generator/src/request-cache.js +252 -163
- package/generator/src/rewrite-client-elm-json.js +5 -5
- package/generator/src/rewrite-elm-json.js +7 -7
- package/generator/src/route-codegen-helpers.js +16 -31
- package/generator/src/seo-renderer.js +12 -7
- package/generator/src/vite-utils.js +77 -0
- package/generator/static-code/hmr.js +79 -13
- package/generator/template/app/Api.elm +6 -5
- package/generator/template/app/Effect.elm +123 -0
- package/generator/template/app/ErrorPage.elm +37 -6
- package/generator/template/app/Route/Index.elm +17 -10
- package/generator/template/app/Shared.elm +24 -47
- package/generator/template/app/Site.elm +19 -6
- package/generator/template/app/View.elm +1 -8
- package/generator/template/elm-tooling.json +0 -3
- package/generator/template/elm.json +34 -25
- package/generator/template/package.json +10 -4
- package/package.json +23 -22
- package/src/ApiRoute.elm +199 -61
- package/src/BackendTask/Custom.elm +325 -0
- package/src/BackendTask/Env.elm +90 -0
- package/src/{DataSource → BackendTask}/File.elm +128 -43
- package/src/{DataSource → BackendTask}/Glob.elm +136 -125
- package/src/BackendTask/Http.elm +673 -0
- package/src/{DataSource → BackendTask}/Internal/Glob.elm +1 -1
- package/src/BackendTask/Internal/Request.elm +28 -0
- package/src/BackendTask/Random.elm +79 -0
- package/src/BackendTask/Time.elm +47 -0
- package/src/BackendTask.elm +537 -0
- package/src/FatalError.elm +89 -0
- package/src/Form/Field.elm +21 -9
- package/src/Form/FieldView.elm +94 -14
- package/src/Form.elm +275 -400
- package/src/Head.elm +237 -7
- package/src/HtmlPrinter.elm +7 -3
- package/src/Internal/ApiRoute.elm +7 -5
- package/src/PageServerResponse.elm +6 -1
- package/src/Pages/FormState.elm +6 -5
- package/src/Pages/GeneratorProgramConfig.elm +15 -0
- package/src/Pages/Internal/FatalError.elm +5 -0
- package/src/Pages/Internal/Form.elm +21 -1
- package/src/Pages/{Msg.elm → Internal/Msg.elm} +26 -16
- package/src/Pages/Internal/Platform/Cli.elm +507 -763
- package/src/Pages/Internal/Platform/CompatibilityKey.elm +6 -0
- package/src/Pages/Internal/Platform/Effect.elm +1 -2
- package/src/Pages/Internal/Platform/GeneratorApplication.elm +373 -0
- package/src/Pages/Internal/Platform/StaticResponses.elm +73 -270
- package/src/Pages/Internal/Platform/ToJsPayload.elm +4 -7
- package/src/Pages/Internal/Platform.elm +215 -102
- package/src/Pages/Internal/Script.elm +17 -0
- package/src/Pages/Internal/StaticHttpBody.elm +35 -1
- package/src/Pages/Manifest.elm +29 -4
- package/src/Pages/PageUrl.elm +23 -9
- package/src/Pages/ProgramConfig.elm +14 -10
- package/src/Pages/Script.elm +109 -0
- package/src/Pages/SiteConfig.elm +3 -2
- package/src/Pages/StaticHttp/Request.elm +2 -2
- package/src/Pages/StaticHttpRequest.elm +23 -98
- package/src/PagesMsg.elm +92 -0
- package/src/Path.elm +16 -19
- package/src/QueryParams.elm +21 -172
- package/src/RequestsAndPending.elm +8 -19
- package/src/Result/Extra.elm +26 -0
- package/src/Scaffold/Form.elm +484 -0
- package/src/Scaffold/Route.elm +1376 -0
- package/src/Server/Request.elm +43 -37
- package/src/Server/Session.elm +34 -34
- package/src/Server/SetCookie.elm +1 -1
- package/src/Test/Html/Internal/ElmHtml/ToString.elm +8 -9
- package/src/DataSource/Env.elm +0 -38
- package/src/DataSource/Http.elm +0 -446
- package/src/DataSource/Internal/Request.elm +0 -20
- package/src/DataSource/Port.elm +0 -90
- package/src/DataSource.elm +0 -538
- 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 (
|
|
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 = "
|
|
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 (
|
|
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,
|
|
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
|
-
(
|
|
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
|
|
434
|
+
FetcherComplete _ fetcherKey _ userMsgResult ->
|
|
436
435
|
case userMsgResult of
|
|
437
|
-
Ok ( userMsg,
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
model
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
(
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
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
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
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
|
-
|
|
613
|
-
(
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
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
|
-
|
|
686
|
+
Batch
|
|
687
|
+
[ ScrollToTop
|
|
688
|
+
, userEffect
|
|
689
|
+
]
|
|
660
690
|
|
|
661
691
|
else
|
|
662
|
-
|
|
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
|
|
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
|
|
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
|
|
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 (\_ (
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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_
|
|
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
|
|
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,
|
|
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_
|
|
1097
|
+
Http.GoodStatus_ _ bytesBody ->
|
|
989
1098
|
let
|
|
990
|
-
decodedAction :
|
|
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
|
|
997
|
-
maybeAction
|
|
1109
|
+
Just (ResponseSketch.HotUpdate _ _ maybeAction) ->
|
|
1110
|
+
ActionResponse maybeAction
|
|
998
1111
|
|
|
999
|
-
Just (ResponseSketch.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
|
|
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
|
-
(\(
|
|
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
|
-
|
|
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
|
|
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_
|
|
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
|
|
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 (
|
|
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 (
|
|
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
|
|
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
|
|
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
|
+
)
|