elm-pages 3.0.0-beta.12 → 3.0.0-beta.14

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 (77) hide show
  1. package/README.md +1 -1
  2. package/codegen/elm-pages-codegen.js +1496 -1126
  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/Runner.elm.js +151 -39
  11. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
  12. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_supervisor.js +1 -1
  13. package/generator/dead-code-review/elm.json +3 -2
  14. package/generator/dead-code-review/src/Pages/Review/DeadCodeEliminateData.elm +58 -10
  15. package/generator/dead-code-review/tests/Pages/Review/DeadCodeEliminateDataTest.elm +45 -29
  16. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
  17. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/i.dat +0 -0
  18. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/o.dat +0 -0
  19. package/generator/review/elm-stuff/tests-0.19.1/elm.json +1 -1
  20. package/generator/review/elm-stuff/tests-0.19.1/js/Runner.elm.js +45 -4
  21. package/generator/review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
  22. package/generator/review/elm-stuff/tests-0.19.1/js/node_supervisor.js +1 -1
  23. package/generator/review/elm.json +3 -3
  24. package/generator/src/RouteBuilder.elm +66 -52
  25. package/generator/src/SharedTemplate.elm +3 -2
  26. package/generator/src/SiteConfig.elm +3 -2
  27. package/generator/src/build.js +6 -6
  28. package/generator/src/cli.js +12 -7
  29. package/generator/src/compatibility-key.js +1 -1
  30. package/generator/src/dev-server.js +7 -7
  31. package/generator/src/render-test.js +109 -0
  32. package/generator/src/render.js +77 -51
  33. package/generator/src/request-cache.js +149 -158
  34. package/generator/template/app/Api.elm +2 -2
  35. package/generator/template/app/Route/Index.elm +3 -3
  36. package/generator/template/app/Shared.elm +3 -3
  37. package/generator/template/app/Site.elm +3 -3
  38. package/package.json +11 -11
  39. package/src/ApiRoute.elm +63 -57
  40. package/src/BackendTask/Env.elm +87 -0
  41. package/src/{DataSource → BackendTask}/File.elm +89 -43
  42. package/src/{DataSource → BackendTask}/Glob.elm +134 -125
  43. package/src/BackendTask/Http.elm +637 -0
  44. package/src/{DataSource → BackendTask}/Internal/Glob.elm +1 -1
  45. package/src/BackendTask/Internal/Request.elm +28 -0
  46. package/src/BackendTask/Port.elm +202 -0
  47. package/src/{DataSource.elm → BackendTask.elm} +223 -207
  48. package/src/Exception.elm +37 -0
  49. package/src/Form.elm +20 -20
  50. package/src/Head.elm +7 -7
  51. package/src/Internal/ApiRoute.elm +7 -5
  52. package/src/PageServerResponse.elm +6 -1
  53. package/src/Pages/Generate.elm +35 -63
  54. package/src/Pages/Internal/Platform/Cli.elm +422 -731
  55. package/src/Pages/Internal/Platform/Cli.elm.bak +22 -22
  56. package/src/Pages/Internal/Platform/CompatibilityKey.elm +1 -1
  57. package/src/Pages/Internal/Platform/Effect.elm +0 -1
  58. package/src/Pages/Internal/Platform/GeneratorApplication.elm +53 -113
  59. package/src/Pages/Internal/Platform/StaticResponses.elm +72 -256
  60. package/src/Pages/Internal/Platform/ToJsPayload.elm +4 -4
  61. package/src/Pages/Internal/Platform.elm +25 -31
  62. package/src/Pages/Internal/Script.elm +17 -0
  63. package/src/Pages/Internal/StaticHttpBody.elm +35 -1
  64. package/src/Pages/Manifest.elm +5 -4
  65. package/src/Pages/ProgramConfig.elm +8 -7
  66. package/src/Pages/Script.elm +34 -25
  67. package/src/Pages/SiteConfig.elm +3 -2
  68. package/src/Pages/StaticHttp/Request.elm +2 -2
  69. package/src/Pages/StaticHttpRequest.elm +37 -90
  70. package/src/RequestsAndPending.elm +8 -19
  71. package/src/Server/Request.elm +14 -14
  72. package/src/Server/Session.elm +34 -34
  73. package/src/Server/SetCookie.elm +1 -1
  74. package/src/DataSource/Env.elm +0 -62
  75. package/src/DataSource/Http.elm +0 -446
  76. package/src/DataSource/Internal/Request.elm +0 -20
  77. package/src/DataSource/Port.elm +0 -90
@@ -6,14 +6,14 @@ module Pages.Internal.Platform.Cli exposing (Flags, Model, Msg(..), Program, cli
6
6
 
7
7
  -}
8
8
 
9
- import ApiRoute
9
+ import BackendTask exposing (BackendTask)
10
10
  import BuildError exposing (BuildError)
11
11
  import Bytes exposing (Bytes)
12
12
  import Bytes.Encode
13
13
  import Codec
14
- import DataSource exposing (DataSource)
15
14
  import Dict
16
- import Head
15
+ import Exception exposing (Throwable)
16
+ import Head exposing (Tag)
17
17
  import Html exposing (Html)
18
18
  import HtmlPrinter
19
19
  import Internal.ApiRoute exposing (ApiRoute(..))
@@ -21,23 +21,19 @@ import Json.Decode as Decode
21
21
  import Json.Encode
22
22
  import PageServerResponse exposing (PageServerResponse)
23
23
  import Pages.Flags
24
- import Pages.Http
25
24
  import Pages.Internal.NotFoundReason as NotFoundReason exposing (NotFoundReason)
26
25
  import Pages.Internal.Platform.CompatibilityKey
27
26
  import Pages.Internal.Platform.Effect as Effect exposing (Effect)
28
- import Pages.Internal.Platform.StaticResponses as StaticResponses exposing (StaticResponses)
27
+ import Pages.Internal.Platform.StaticResponses as StaticResponses
29
28
  import Pages.Internal.Platform.ToJsPayload as ToJsPayload
30
29
  import Pages.Internal.ResponseSketch as ResponseSketch
31
- import Pages.Internal.StaticHttpBody as StaticHttpBody
32
30
  import Pages.Msg
33
31
  import Pages.ProgramConfig exposing (ProgramConfig)
34
32
  import Pages.SiteConfig exposing (SiteConfig)
35
33
  import Pages.StaticHttp.Request
36
- import Pages.StaticHttpRequest as StaticHttpRequest
37
34
  import Path exposing (Path)
38
35
  import RenderRequest exposing (RenderRequest)
39
36
  import RequestsAndPending exposing (RequestsAndPending)
40
- import Task
41
37
  import TerminalText as Terminal
42
38
  import Url exposing (Url)
43
39
 
@@ -55,10 +51,9 @@ currentCompatibilityKey =
55
51
 
56
52
  {-| -}
57
53
  type alias Model route =
58
- { staticResponses : StaticResponses
54
+ { staticResponses : BackendTask Throwable Effect
59
55
  , errors : List BuildError
60
56
  , allRawResponses : RequestsAndPending
61
- , unprocessedPages : List ( Path, route )
62
57
  , maybeRequestJson : RenderRequest route
63
58
  , isDevServer : Bool
64
59
  }
@@ -66,12 +61,7 @@ type alias Model route =
66
61
 
67
62
  {-| -}
68
63
  type Msg
69
- = GotDataBatch
70
- (List
71
- { request : Pages.StaticHttp.Request.Request
72
- , response : RequestsAndPending.Response
73
- }
74
- )
64
+ = GotDataBatch Decode.Value
75
65
  | GotBuildError BuildError
76
66
 
77
67
 
@@ -112,7 +102,7 @@ cliApplication config =
112
102
  |> Tuple.mapSecond (perform site renderRequest config)
113
103
  , update =
114
104
  \msg model ->
115
- update site config msg model
105
+ update msg model
116
106
  |> Tuple.mapSecond (perform site model.maybeRequestJson config)
117
107
  , subscriptions =
118
108
  \_ ->
@@ -159,35 +149,11 @@ cliApplication config =
159
149
  )
160
150
  |> mergeResult
161
151
  )
162
- , config.gotBatchSub
163
- |> Sub.map
164
- (\newBatch ->
165
- Decode.decodeValue batchDecoder newBatch
166
- |> Result.map GotDataBatch
167
- |> Result.mapError
168
- (\error ->
169
- ("From location 2: "
170
- ++ (error
171
- |> Decode.errorToString
172
- )
173
- )
174
- |> BuildError.internal
175
- |> GotBuildError
176
- )
177
- |> mergeResult
178
- )
152
+ , config.gotBatchSub |> Sub.map GotDataBatch
179
153
  ]
180
154
  }
181
155
 
182
156
 
183
- batchDecoder : Decode.Decoder (List { request : Pages.StaticHttp.Request.Request, response : RequestsAndPending.Response })
184
- batchDecoder =
185
- Decode.map2 (\request response -> { request = request, response = response })
186
- (Decode.field "request" requestDecoder)
187
- (Decode.field "response" RequestsAndPending.decoder)
188
- |> Decode.list
189
-
190
-
191
157
  mergeResult : Result a a -> a
192
158
  mergeResult r =
193
159
  case r of
@@ -245,60 +211,10 @@ perform site renderRequest config effect =
245
211
  flatten site renderRequest config list
246
212
 
247
213
  Effect.FetchHttp unmasked ->
248
- if unmasked.url == "$$elm-pages$$headers" then
249
- case
250
- renderRequest
251
- |> RenderRequest.maybeRequestPayload
252
- |> Maybe.map (\json -> RequestsAndPending.Response Nothing (RequestsAndPending.JsonBody json))
253
- |> Result.fromMaybe (Pages.Http.BadUrl "$$elm-pages$$headers is only available on server-side request (not on build).")
254
- of
255
- Ok okResponse ->
256
- Task.succeed
257
- [ { request = unmasked
258
- , response = okResponse
259
- }
260
- ]
261
- |> Task.perform GotDataBatch
262
-
263
- Err error ->
264
- { title = "Static HTTP Error"
265
- , message =
266
- [ Terminal.text "I got an error making an HTTP request to this URL: "
267
-
268
- -- TODO include HTTP method, headers, and body
269
- , Terminal.yellow unmasked.url
270
- , Terminal.text <| Json.Encode.encode 2 <| StaticHttpBody.encode unmasked.body
271
- , Terminal.text "\n\n"
272
- , case error of
273
- Pages.Http.BadStatus metadata body ->
274
- Terminal.text <|
275
- String.join "\n"
276
- [ "Bad status: " ++ String.fromInt metadata.statusCode
277
- , "Status message: " ++ metadata.statusText
278
- , "Body: " ++ body
279
- ]
280
-
281
- Pages.Http.BadUrl _ ->
282
- -- TODO include HTTP method, headers, and body
283
- Terminal.text <| "Invalid url: " ++ unmasked.url
284
-
285
- Pages.Http.Timeout ->
286
- Terminal.text "Timeout"
287
-
288
- Pages.Http.NetworkError ->
289
- Terminal.text "Network error"
290
- ]
291
- , fatal = True
292
- , path = "" -- TODO wire in current path here
293
- }
294
- |> Task.succeed
295
- |> Task.perform GotBuildError
296
-
297
- else
298
- ToJsPayload.DoHttp unmasked unmasked.useCache
299
- |> Codec.encoder (ToJsPayload.successCodecNew2 canonicalSiteUrl "")
300
- |> config.toJsPort
301
- |> Cmd.map never
214
+ ToJsPayload.DoHttp (Pages.StaticHttp.Request.hash unmasked) unmasked
215
+ |> Codec.encoder (ToJsPayload.successCodecNew2 canonicalSiteUrl "")
216
+ |> config.toJsPort
217
+ |> Cmd.map never
302
218
 
303
219
  Effect.SendSinglePage info ->
304
220
  let
@@ -335,9 +251,6 @@ perform site renderRequest config effect =
335
251
  |> config.sendPageData
336
252
  |> Cmd.map never
337
253
 
338
- Effect.Continue ->
339
- Cmd.none
340
-
341
254
 
342
255
  flagsDecoder :
343
256
  Decode.Decoder
@@ -353,15 +266,8 @@ flagsDecoder =
353
266
  , compatibilityKey = compatibilityKey
354
267
  }
355
268
  )
356
- --(Decode.field "staticHttpCache"
357
- -- (Decode.dict
358
- -- (Decode.string
359
- -- |> Decode.map Just
360
- -- )
361
- -- )
362
- --)
363
269
  -- TODO remove hardcoding and decode staticHttpCache here
364
- (Decode.succeed Dict.empty)
270
+ (Decode.succeed (Json.Encode.object []))
365
271
  (Decode.field "mode" Decode.string |> Decode.map (\mode -> mode == "dev-server"))
366
272
  (Decode.field "compatibilityKey" Decode.int)
367
273
 
@@ -375,9 +281,9 @@ init :
375
281
  -> ( Model route, Effect )
376
282
  init site renderRequest config flags =
377
283
  case Decode.decodeValue flagsDecoder flags of
378
- Ok { staticHttpCache, isDevServer, compatibilityKey } ->
284
+ Ok { isDevServer, compatibilityKey } ->
379
285
  if compatibilityKey == currentCompatibilityKey then
380
- initLegacy site renderRequest { staticHttpCache = staticHttpCache, isDevServer = isDevServer } config
286
+ initLegacy site renderRequest { isDevServer = isDevServer } config
381
287
 
382
288
  else
383
289
  let
@@ -396,9 +302,7 @@ init site renderRequest config flags =
396
302
  )
397
303
  in
398
304
  updateAndSendPortIfDone
399
- site
400
- config
401
- { staticResponses = StaticResponses.empty
305
+ { staticResponses = StaticResponses.empty Effect.NoEffect
402
306
  , errors =
403
307
  [ { title = "Incompatible NPM and Elm package versions"
404
308
  , message = [ Terminal.text <| message ]
@@ -406,17 +310,14 @@ init site renderRequest config flags =
406
310
  , path = ""
407
311
  }
408
312
  ]
409
- , allRawResponses = Dict.empty
410
- , unprocessedPages = []
313
+ , allRawResponses = Json.Encode.object []
411
314
  , maybeRequestJson = renderRequest
412
315
  , isDevServer = False
413
316
  }
414
317
 
415
318
  Err error ->
416
319
  updateAndSendPortIfDone
417
- site
418
- config
419
- { staticResponses = StaticResponses.empty
320
+ { staticResponses = StaticResponses.empty Effect.NoEffect
420
321
  , errors =
421
322
  [ { title = "Internal Error"
422
323
  , message = [ Terminal.text <| "Failed to parse flags: " ++ Decode.errorToString error ]
@@ -424,8 +325,7 @@ init site renderRequest config flags =
424
325
  , path = ""
425
326
  }
426
327
  ]
427
- , allRawResponses = Dict.empty
428
- , unprocessedPages = []
328
+ , allRawResponses = Json.Encode.object []
429
329
  , maybeRequestJson = renderRequest
430
330
  , isDevServer = False
431
331
  }
@@ -474,128 +374,420 @@ isActionDecoder =
474
374
  initLegacy :
475
375
  SiteConfig
476
376
  -> RenderRequest route
477
- -> { staticHttpCache : RequestsAndPending, isDevServer : Bool }
377
+ -> { isDevServer : Bool }
478
378
  -> ProgramConfig userMsg userModel route pageData actionData sharedData effect mappedMsg errorPage
479
379
  -> ( Model route, Effect )
480
- initLegacy site renderRequest { staticHttpCache, isDevServer } config =
380
+ initLegacy site ((RenderRequest.SinglePage includeHtml singleRequest _) as renderRequest) { isDevServer } config =
481
381
  let
482
- staticResponses : StaticResponses
483
- staticResponses =
484
- case renderRequest of
485
- RenderRequest.SinglePage _ singleRequest _ ->
486
- let
487
- globalHeadTags : DataSource (List Head.Tag)
488
- globalHeadTags =
489
- (config.globalHeadTags |> Maybe.withDefault (\_ -> DataSource.succeed [])) HtmlPrinter.htmlToString
490
- in
491
- case singleRequest of
492
- RenderRequest.Page serverRequestPayload ->
493
- let
494
- isAction : Maybe ActionRequest
495
- isAction =
496
- renderRequest
497
- |> RenderRequest.maybeRequestPayload
498
- |> Maybe.andThen (Decode.decodeValue isActionDecoder >> Result.withDefault Nothing)
499
- in
500
- StaticResponses.renderSingleRoute
501
- (case isAction of
502
- Just _ ->
503
- config.action serverRequestPayload.frontmatter
504
- |> DataSource.andThen
505
- (\something ->
506
- case something of
507
- PageServerResponse.ErrorPage _ _ ->
508
- DataSource.succeed something
509
- |> DataSource.map (\_ -> ())
510
-
511
- PageServerResponse.RenderPage _ _ ->
512
- DataSource.map3 (\_ _ _ -> ())
513
- (config.data serverRequestPayload.frontmatter)
514
- config.sharedData
515
- globalHeadTags
516
-
517
- PageServerResponse.ServerResponse _ ->
518
- DataSource.succeed something
519
- |> DataSource.map (\_ -> ())
520
- )
521
-
522
- Nothing ->
523
- DataSource.map3 (\_ _ _ -> ())
524
- (config.data serverRequestPayload.frontmatter)
525
- config.sharedData
526
- globalHeadTags
527
- )
528
- (if isDevServer then
529
- config.handleRoute serverRequestPayload.frontmatter
382
+ globalHeadTags : BackendTask Throwable (List Tag)
383
+ globalHeadTags =
384
+ (config.globalHeadTags |> Maybe.withDefault (\_ -> BackendTask.succeed [])) HtmlPrinter.htmlToString
385
+
386
+ staticResponsesNew : BackendTask Throwable Effect
387
+ staticResponsesNew =
388
+ StaticResponses.renderApiRequest
389
+ (case singleRequest of
390
+ RenderRequest.Page serverRequestPayload ->
391
+ let
392
+ isAction : Maybe ActionRequest
393
+ isAction =
394
+ renderRequest
395
+ |> RenderRequest.maybeRequestPayload
396
+ |> Maybe.andThen (Decode.decodeValue isActionDecoder >> Result.withDefault Nothing)
397
+
398
+ currentUrl : Url
399
+ currentUrl =
400
+ { protocol = Url.Https
401
+ , host = site.canonicalUrl
402
+ , port_ = Nothing
403
+ , path = serverRequestPayload.path |> Path.toRelative
404
+ , query = Nothing
405
+ , fragment = Nothing
406
+ }
407
+ in
408
+ --case isAction of
409
+ -- Just actionRequest ->
410
+ (if isDevServer then
411
+ config.handleRoute serverRequestPayload.frontmatter
530
412
 
531
- else
532
- DataSource.succeed Nothing
533
- )
413
+ else
414
+ BackendTask.succeed Nothing
415
+ )
416
+ |> BackendTask.andThen
417
+ (\pageFound ->
418
+ case pageFound of
419
+ Nothing ->
420
+ --sendSinglePageProgress site model.allRawResponses config model payload
421
+ (case isAction of
422
+ Just _ ->
423
+ config.action (RenderRequest.maybeRequestPayload renderRequest |> Maybe.withDefault Json.Encode.null) serverRequestPayload.frontmatter |> BackendTask.map Just
424
+
425
+ Nothing ->
426
+ BackendTask.succeed Nothing
427
+ )
428
+ |> BackendTask.andThen
429
+ (\something ->
430
+ let
431
+ actionHeaders2 : Maybe { statusCode : Int, headers : List ( String, String ) }
432
+ actionHeaders2 =
433
+ case something of
434
+ Just (PageServerResponse.RenderPage responseThing _) ->
435
+ Just responseThing
436
+
437
+ Just (PageServerResponse.ServerResponse responseThing) ->
438
+ Just
439
+ { headers = responseThing.headers
440
+ , statusCode = responseThing.statusCode
441
+ }
534
442
 
535
- RenderRequest.Api ( path, ApiRoute apiRequest ) ->
536
- StaticResponses.renderApiRequest
537
- (DataSource.map2 (\_ _ -> ())
538
- (apiRequest.matchesToResponse path)
539
- globalHeadTags
540
- )
443
+ _ ->
444
+ Nothing
445
+ in
446
+ BackendTask.map3
447
+ (\pageData sharedData tags ->
448
+ let
449
+ renderedResult : Effect
450
+ renderedResult =
451
+ case pageData of
452
+ PageServerResponse.RenderPage responseInfo pageData_ ->
453
+ let
454
+ currentPage : { path : Path, route : route }
455
+ currentPage =
456
+ { path = serverRequestPayload.path, route = urlToRoute config currentUrl }
457
+
458
+ maybeActionData : Maybe actionData
459
+ maybeActionData =
460
+ case something of
461
+ Just (PageServerResponse.RenderPage _ actionThing) ->
462
+ Just actionThing
463
+
464
+ _ ->
465
+ Nothing
466
+
467
+ pageModel : userModel
468
+ pageModel =
469
+ config.init
470
+ Pages.Flags.PreRenderFlags
471
+ sharedData
472
+ pageData_
473
+ maybeActionData
474
+ (Just
475
+ { path =
476
+ { path = currentPage.path
477
+ , query = Nothing
478
+ , fragment = Nothing
479
+ }
480
+ , metadata = currentPage.route
481
+ , pageUrl = Nothing
482
+ }
483
+ )
484
+ |> Tuple.first
485
+
486
+ viewValue : { title : String, body : List (Html (Pages.Msg.Msg userMsg)) }
487
+ viewValue =
488
+ (config.view Dict.empty Dict.empty Nothing currentPage Nothing sharedData pageData_ maybeActionData |> .view) pageModel
489
+
490
+ responseMetadata : { statusCode : Int, headers : List ( String, String ) }
491
+ responseMetadata =
492
+ actionHeaders2 |> Maybe.withDefault responseInfo
493
+ in
494
+ (case isAction of
495
+ Just actionRequestKind ->
496
+ let
497
+ actionDataResult : Maybe (PageServerResponse actionData errorPage)
498
+ actionDataResult =
499
+ something
500
+ in
501
+ case actionDataResult of
502
+ Just (PageServerResponse.RenderPage ignored2 actionData_) ->
503
+ case actionRequestKind of
504
+ ActionResponseRequest ->
505
+ ( ignored2.headers
506
+ , ResponseSketch.HotUpdate pageData_ sharedData (Just actionData_)
507
+ |> config.encodeResponse
508
+ |> Bytes.Encode.encode
509
+ )
510
+
511
+ ActionOnlyRequest ->
512
+ ---- TODO need to encode action data when only that is requested (not ResponseSketch?)
513
+ ( ignored2.headers
514
+ , actionData_
515
+ |> config.encodeAction
516
+ |> Bytes.Encode.encode
517
+ )
518
+
519
+ _ ->
520
+ ( responseMetadata.headers
521
+ , Bytes.Encode.encode (Bytes.Encode.unsignedInt8 0)
522
+ )
523
+
524
+ Nothing ->
525
+ ( responseMetadata.headers
526
+ , ResponseSketch.HotUpdate pageData_ sharedData Nothing
527
+ |> config.encodeResponse
528
+ |> Bytes.Encode.encode
529
+ )
530
+ )
531
+ |> (\( actionHeaders, byteEncodedPageData ) ->
532
+ let
533
+ rendered : { view : userModel -> { title : String, body : List (Html (Pages.Msg.Msg userMsg)) }, head : List Tag }
534
+ rendered =
535
+ config.view Dict.empty Dict.empty Nothing currentPage Nothing sharedData pageData_ maybeActionData
536
+ in
537
+ PageServerResponse.toRedirect responseMetadata
538
+ |> Maybe.map
539
+ (\{ location } ->
540
+ location
541
+ |> ResponseSketch.Redirect
542
+ |> config.encodeResponse
543
+ |> Bytes.Encode.encode
544
+ )
545
+ -- TODO handle other cases besides redirects?
546
+ |> Maybe.withDefault byteEncodedPageData
547
+ |> (\encodedData ->
548
+ { route = currentPage.path |> Path.toRelative
549
+ , contentJson = Dict.empty
550
+ , html = viewValue.body |> bodyToString
551
+ , errors = []
552
+ , head = rendered.head ++ tags
553
+ , title = viewValue.title
554
+ , staticHttpCache = Dict.empty
555
+ , is404 = False
556
+ , statusCode =
557
+ case includeHtml of
558
+ RenderRequest.OnlyJson ->
559
+ 200
560
+
561
+ RenderRequest.HtmlAndJson ->
562
+ responseMetadata.statusCode
563
+ , headers =
564
+ -- TODO should `responseInfo.headers` be used? Is there a problem in the case where there is both an action and data response in one? Do we need to make sure it is performed as two separate HTTP requests to ensure that the cookies are set correctly in that case?
565
+ actionHeaders
566
+ }
567
+ |> ToJsPayload.PageProgress
568
+ |> Effect.SendSinglePageNew encodedData
569
+ )
570
+ )
571
+
572
+ PageServerResponse.ServerResponse serverResponse ->
573
+ --PageServerResponse.ServerResponse serverResponse
574
+ -- TODO handle error?
575
+ let
576
+ responseMetadata : PageServerResponse.Response
577
+ responseMetadata =
578
+ case something of
579
+ Just (PageServerResponse.ServerResponse responseThing) ->
580
+ responseThing
581
+
582
+ _ ->
583
+ serverResponse
584
+ in
585
+ PageServerResponse.toRedirect responseMetadata
586
+ |> Maybe.map
587
+ (\_ ->
588
+ let
589
+ ( _, byteEncodedPageData ) =
590
+ ( serverResponse.headers
591
+ --ignored1.headers
592
+ , PageServerResponse.toRedirect serverResponse
593
+ |> Maybe.map
594
+ (\{ location } ->
595
+ location
596
+ |> ResponseSketch.Redirect
597
+ |> config.encodeResponse
598
+ )
599
+ -- TODO handle other cases besides redirects?
600
+ |> Maybe.withDefault (Bytes.Encode.unsignedInt8 0)
601
+ |> Bytes.Encode.encode
602
+ )
603
+ in
604
+ { route = serverRequestPayload.path |> Path.toRelative
605
+ , contentJson = Dict.empty
606
+ , html = "This is intentionally blank HTML"
607
+ , errors = []
608
+ , head = []
609
+ , title = "This is an intentionally blank title"
610
+ , staticHttpCache = Dict.empty
611
+ , is404 = False
612
+ , statusCode =
613
+ case includeHtml of
614
+ RenderRequest.OnlyJson ->
615
+ -- if this is a redirect for a `content.dat`, we don't want to send an *actual* redirect status code because the redirect needs to be handled in Elm (not by the Browser)
616
+ 200
617
+
618
+ RenderRequest.HtmlAndJson ->
619
+ responseMetadata.statusCode
620
+ , headers = responseMetadata.headers --serverResponse.headers
621
+ }
622
+ |> ToJsPayload.PageProgress
623
+ |> Effect.SendSinglePageNew byteEncodedPageData
624
+ )
625
+ |> Maybe.withDefault
626
+ ({ body = serverResponse |> PageServerResponse.toJson
627
+ , staticHttpCache = Dict.empty
628
+ , statusCode = serverResponse.statusCode
629
+ }
630
+ |> ToJsPayload.SendApiResponse
631
+ |> Effect.SendSinglePage
632
+ )
633
+
634
+ PageServerResponse.ErrorPage error record ->
635
+ let
636
+ currentPage : { path : Path, route : route }
637
+ currentPage =
638
+ { path = serverRequestPayload.path, route = urlToRoute config currentUrl }
639
+
640
+ pageModel : userModel
641
+ pageModel =
642
+ config.init
643
+ Pages.Flags.PreRenderFlags
644
+ sharedData
645
+ pageData2
646
+ Nothing
647
+ (Just
648
+ { path =
649
+ { path = currentPage.path
650
+ , query = Nothing
651
+ , fragment = Nothing
652
+ }
653
+ , metadata = currentPage.route
654
+ , pageUrl = Nothing
655
+ }
656
+ )
657
+ |> Tuple.first
658
+
659
+ pageData2 : pageData
660
+ pageData2 =
661
+ config.errorPageToData error
662
+
663
+ viewValue : { title : String, body : List (Html (Pages.Msg.Msg userMsg)) }
664
+ viewValue =
665
+ (config.view Dict.empty Dict.empty Nothing currentPage Nothing sharedData pageData2 Nothing |> .view) pageModel
666
+ in
667
+ (ResponseSketch.HotUpdate pageData2 sharedData Nothing
668
+ |> config.encodeResponse
669
+ |> Bytes.Encode.encode
670
+ )
671
+ |> (\encodedData ->
672
+ { route = currentPage.path |> Path.toRelative
673
+ , contentJson = Dict.empty
674
+ , html = viewValue.body |> bodyToString
675
+ , errors = []
676
+ , head = tags
677
+ , title = viewValue.title
678
+ , staticHttpCache = Dict.empty
679
+ , is404 = False
680
+ , statusCode =
681
+ case includeHtml of
682
+ RenderRequest.OnlyJson ->
683
+ 200
684
+
685
+ RenderRequest.HtmlAndJson ->
686
+ config.errorStatusCode error
687
+ , headers = record.headers
688
+ }
689
+ |> ToJsPayload.PageProgress
690
+ |> Effect.SendSinglePageNew encodedData
691
+ )
692
+ in
693
+ renderedResult
694
+ )
695
+ (config.data (RenderRequest.maybeRequestPayload renderRequest |> Maybe.withDefault Json.Encode.null) serverRequestPayload.frontmatter)
696
+ config.sharedData
697
+ globalHeadTags
698
+ )
541
699
 
542
- RenderRequest.NotFound _ ->
543
- StaticResponses.renderApiRequest
544
- (DataSource.map2 (\_ _ -> ())
545
- (DataSource.succeed [])
546
- globalHeadTags
700
+ Just notFoundReason ->
701
+ render404Page config
702
+ Nothing
703
+ -- TODO do I need sharedDataResult?
704
+ --(Result.toMaybe sharedDataResult)
705
+ isDevServer
706
+ serverRequestPayload.path
707
+ notFoundReason
708
+ |> BackendTask.succeed
547
709
  )
548
710
 
549
- unprocessedPages : List ( Path, route )
550
- unprocessedPages =
551
- case renderRequest of
552
- RenderRequest.SinglePage _ serverRequestPayload _ ->
553
- case serverRequestPayload of
554
- RenderRequest.Page pageData ->
555
- [ ( pageData.path, pageData.frontmatter ) ]
711
+ RenderRequest.Api ( path, ApiRoute apiHandler ) ->
712
+ BackendTask.map2
713
+ (\response _ ->
714
+ case response of
715
+ Just okResponse ->
716
+ { body = okResponse
717
+ , staticHttpCache = Dict.empty -- TODO do I need to serialize the full cache here, or can I handle that from the JS side?
718
+ , statusCode = 200
719
+ }
720
+ |> ToJsPayload.SendApiResponse
721
+ |> Effect.SendSinglePage
556
722
 
557
- RenderRequest.Api _ ->
558
- []
559
-
560
- RenderRequest.NotFound _ ->
561
- []
723
+ Nothing ->
724
+ render404Page config
725
+ -- TODO do I need sharedDataResult here?
726
+ Nothing
727
+ isDevServer
728
+ (Path.fromString path)
729
+ NotFoundReason.NoMatchingRoute
730
+ --Err error ->
731
+ -- [ error ]
732
+ -- |> ToJsPayload.Errors
733
+ -- |> Effect.SendSinglePage
734
+ )
735
+ (apiHandler.matchesToResponse
736
+ (renderRequest
737
+ |> RenderRequest.maybeRequestPayload
738
+ |> Maybe.withDefault Json.Encode.null
739
+ )
740
+ path
741
+ )
742
+ globalHeadTags
743
+
744
+ RenderRequest.NotFound notFoundPath ->
745
+ (BackendTask.map2
746
+ (\_ _ ->
747
+ render404Page config
748
+ Nothing
749
+ --(Result.toMaybe sharedDataResult)
750
+ --model
751
+ isDevServer
752
+ notFoundPath
753
+ NotFoundReason.NoMatchingRoute
754
+ )
755
+ (BackendTask.succeed [])
756
+ globalHeadTags
757
+ -- TODO is there a way to resolve sharedData but get it as a Result if it fails?
758
+ --config.sharedData
759
+ )
760
+ )
562
761
 
563
762
  initialModel : Model route
564
763
  initialModel =
565
- { staticResponses = staticResponses
764
+ { staticResponses = staticResponsesNew
566
765
  , errors = []
567
- , allRawResponses = staticHttpCache
568
- , unprocessedPages = unprocessedPages
766
+ , allRawResponses = Json.Encode.object []
569
767
  , maybeRequestJson = renderRequest
570
768
  , isDevServer = isDevServer
571
769
  }
572
770
  in
573
- StaticResponses.nextStep initialModel Nothing
574
- |> nextStepToEffect site
575
- config
771
+ StaticResponses.nextStep initialModel
772
+ |> nextStepToEffect
576
773
  initialModel
577
774
 
578
775
 
579
776
  updateAndSendPortIfDone :
580
- SiteConfig
581
- -> ProgramConfig userMsg userModel route pageData actionData sharedData effect mappedMsg errorPage
582
- -> Model route
777
+ Model route
583
778
  -> ( Model route, Effect )
584
- updateAndSendPortIfDone site config model =
779
+ updateAndSendPortIfDone model =
585
780
  StaticResponses.nextStep
586
781
  model
587
- Nothing
588
- |> nextStepToEffect site config model
782
+ |> nextStepToEffect model
589
783
 
590
784
 
591
785
  {-| -}
592
786
  update :
593
- SiteConfig
594
- -> ProgramConfig userMsg userModel route pageData actionData sharedData effect mappedMsg errorPage
595
- -> Msg
787
+ Msg
596
788
  -> Model route
597
789
  -> ( Model route, Effect )
598
- update site config msg model =
790
+ update msg model =
599
791
  case msg of
600
792
  GotDataBatch batch ->
601
793
  let
@@ -606,8 +798,7 @@ update site config msg model =
606
798
  in
607
799
  StaticResponses.nextStep
608
800
  updatedModel
609
- Nothing
610
- |> nextStepToEffect site config updatedModel
801
+ |> nextStepToEffect updatedModel
611
802
 
612
803
  GotBuildError buildError ->
613
804
  let
@@ -620,50 +811,28 @@ update site config msg model =
620
811
  in
621
812
  StaticResponses.nextStep
622
813
  updatedModel
623
- Nothing
624
- |> nextStepToEffect site config updatedModel
814
+ |> nextStepToEffect updatedModel
625
815
 
626
816
 
627
817
  nextStepToEffect :
628
- SiteConfig
629
- -> ProgramConfig userMsg userModel route pageData actionData sharedData effect mappedMsg errorPage
630
- -> Model route
631
- -> ( StaticResponses, StaticResponses.NextStep route )
818
+ Model route
819
+ -> StaticResponses.NextStep route Effect
632
820
  -> ( Model route, Effect )
633
- nextStepToEffect site config model ( updatedStaticResponsesModel, nextStep ) =
821
+ nextStepToEffect model nextStep =
634
822
  case nextStep of
635
- StaticResponses.Continue updatedAllRawResponses httpRequests maybeRoutes ->
823
+ StaticResponses.Continue httpRequests updatedStaticResponsesModel ->
636
824
  let
637
- updatedUnprocessedPages : List ( Path, route )
638
- updatedUnprocessedPages =
639
- case maybeRoutes of
640
- Just newRoutes ->
641
- newRoutes
642
- |> List.map
643
- (\route ->
644
- ( Path.join (config.routeToPath route)
645
- , route
646
- )
647
- )
648
-
649
- Nothing ->
650
- model.unprocessedPages
651
-
652
825
  updatedModel : Model route
653
826
  updatedModel =
654
827
  { model
655
- | allRawResponses = updatedAllRawResponses
656
- , staticResponses = updatedStaticResponsesModel
657
- , unprocessedPages = updatedUnprocessedPages
828
+ | staticResponses = updatedStaticResponsesModel
658
829
  }
659
830
  in
660
831
  if List.isEmpty httpRequests then
661
- nextStepToEffect site
662
- config
832
+ nextStepToEffect
663
833
  updatedModel
664
834
  (StaticResponses.nextStep
665
835
  updatedModel
666
- Nothing
667
836
  )
668
837
 
669
838
  else
@@ -674,504 +843,26 @@ nextStepToEffect site config model ( updatedStaticResponsesModel, nextStep ) =
674
843
  |> Effect.Batch
675
844
  )
676
845
 
677
- StaticResponses.Finish toJsPayload ->
678
- case toJsPayload of
679
- StaticResponses.ApiResponse ->
680
- let
681
- apiResponse : Effect
682
- apiResponse =
683
- case model.maybeRequestJson of
684
- RenderRequest.SinglePage _ requestPayload _ ->
685
- let
686
- sharedDataResult : Result BuildError sharedData
687
- sharedDataResult =
688
- StaticHttpRequest.resolve
689
- config.sharedData
690
- model.allRawResponses
691
- |> Result.mapError (StaticHttpRequest.toBuildError "")
692
- in
693
- case requestPayload of
694
- RenderRequest.Api ( path, ApiRoute apiHandler ) ->
695
- let
696
- thing : DataSource (Maybe ApiRoute.Response)
697
- thing =
698
- apiHandler.matchesToResponse path
699
- in
700
- StaticHttpRequest.resolve
701
- thing
702
- model.allRawResponses
703
- |> Result.mapError (StaticHttpRequest.toBuildError "TODO - path from request")
704
- |> (\response ->
705
- case response of
706
- Ok (Just okResponse) ->
707
- { body = okResponse
708
- , staticHttpCache = Dict.empty -- TODO do I need to serialize the full cache here, or can I handle that from the JS side?
709
-
710
- -- model.allRawResponses |> Dict.Extra.filterMap (\_ v -> v)
711
- , statusCode = 200
712
- }
713
- |> ToJsPayload.SendApiResponse
714
- |> Effect.SendSinglePage
715
-
716
- Ok Nothing ->
717
- render404Page config (Result.toMaybe sharedDataResult) model (Path.fromString path) NotFoundReason.NoMatchingRoute
718
-
719
- Err error ->
720
- [ error ]
721
- |> ToJsPayload.Errors
722
- |> Effect.SendSinglePage
723
- )
724
-
725
- RenderRequest.Page payload ->
726
- let
727
- pageFoundResult : Result BuildError (Maybe NotFoundReason)
728
- pageFoundResult =
729
- StaticHttpRequest.resolve
730
- (if model.isDevServer then
731
- -- TODO OPTIMIZATION this is redundant
732
- config.handleRoute payload.frontmatter
733
-
734
- else
735
- DataSource.succeed Nothing
736
- )
737
- model.allRawResponses
738
- |> Result.mapError (StaticHttpRequest.toBuildError (payload.path |> Path.toAbsolute))
739
- in
740
- case pageFoundResult of
741
- Ok Nothing ->
742
- sendSinglePageProgress site model.allRawResponses config model payload
743
-
744
- Ok (Just notFoundReason) ->
745
- render404Page config
746
- --Nothing
747
- (Result.toMaybe sharedDataResult)
748
- model
749
- payload.path
750
- notFoundReason
751
-
752
- Err error ->
753
- [ error ] |> ToJsPayload.Errors |> Effect.SendSinglePage
754
-
755
- RenderRequest.NotFound path ->
756
- render404Page config
757
- --Nothing
758
- (Result.toMaybe sharedDataResult)
759
- model
760
- path
761
- NotFoundReason.NoMatchingRoute
762
- in
763
- ( model
764
- , apiResponse
765
- )
766
-
767
- StaticResponses.Errors errors ->
768
- ( model
769
- , errors |> ToJsPayload.Errors |> Effect.SendSinglePage
770
- )
771
-
772
-
773
- sendSinglePageProgress :
774
- SiteConfig
775
- -> RequestsAndPending
776
- -> ProgramConfig userMsg userModel route pageData actionData sharedData effect mappedMsg errorPage
777
- -> Model route
778
- -> { path : Path, frontmatter : route }
779
- -> Effect
780
- sendSinglePageProgress site contentJson config model info =
781
- let
782
- ( page, route ) =
783
- ( info.path, info.frontmatter )
784
- in
785
- case model.maybeRequestJson of
786
- RenderRequest.SinglePage includeHtml _ _ ->
787
- let
788
- isAction : Maybe ActionRequest
789
- isAction =
790
- model.maybeRequestJson
791
- |> RenderRequest.maybeRequestPayload
792
- |> Maybe.andThen (Decode.decodeValue isActionDecoder >> Result.withDefault Nothing)
793
-
794
- pageFoundResult : Result BuildError (Maybe NotFoundReason)
795
- pageFoundResult =
796
- -- TODO OPTIMIZATION this is redundant
797
- StaticHttpRequest.resolve
798
- (if model.isDevServer then
799
- config.handleRoute route
800
-
801
- else
802
- DataSource.succeed Nothing
803
- )
804
- model.allRawResponses
805
- |> Result.mapError (StaticHttpRequest.toBuildError currentUrl.path)
806
-
807
- renderedResult : Result BuildError (PageServerResponse { head : List Head.Tag, view : String, title : String } errorPage)
808
- renderedResult =
809
- case includeHtml of
810
- RenderRequest.OnlyJson ->
811
- pageDataResult
812
- |> Result.map
813
- (\okPageData ->
814
- case okPageData of
815
- PageServerResponse.RenderPage responseInfo _ ->
816
- PageServerResponse.RenderPage
817
- { statusCode = responseInfo.statusCode
818
- , headers = responseInfo.headers
819
- }
820
- { head = []
821
- , view = "This page was not rendered because it is a JSON-only request."
822
- , title = "This page was not rendered because it is a JSON-only request."
823
- }
824
-
825
- PageServerResponse.ServerResponse serverResponse ->
826
- PageServerResponse.ServerResponse serverResponse
827
-
828
- PageServerResponse.ErrorPage error record ->
829
- PageServerResponse.ErrorPage error record
830
- )
831
-
832
- RenderRequest.HtmlAndJson ->
833
- Result.map2 Tuple.pair pageDataResult sharedDataResult
834
- |> Result.map
835
- (\( pageData_, sharedData ) ->
836
- case pageData_ of
837
- PageServerResponse.RenderPage responseInfo pageData ->
838
- let
839
- currentPage : { path : Path, route : route }
840
- currentPage =
841
- { path = page, route = urlToRoute config currentUrl }
842
-
843
- maybeActionData : Maybe actionData
844
- maybeActionData =
845
- case isAction of
846
- Just _ ->
847
- case actionDataResult of
848
- Ok (PageServerResponse.RenderPage _ actionData) ->
849
- Just actionData
850
-
851
- _ ->
852
- Nothing
853
-
854
- Nothing ->
855
- Nothing
856
-
857
- pageModel : userModel
858
- pageModel =
859
- config.init
860
- Pages.Flags.PreRenderFlags
861
- sharedData
862
- pageData
863
- maybeActionData
864
- (Just
865
- { path =
866
- { path = currentPage.path
867
- , query = Nothing
868
- , fragment = Nothing
869
- }
870
- , metadata = currentPage.route
871
- , pageUrl = Nothing
872
- }
873
- )
874
- |> Tuple.first
875
-
876
- viewValue : { title : String, body : List (Html (Pages.Msg.Msg userMsg)) }
877
- viewValue =
878
- (config.view Dict.empty Dict.empty Nothing currentPage Nothing sharedData pageData maybeActionData |> .view) pageModel
879
- in
880
- PageServerResponse.RenderPage responseInfo
881
- { head = config.view Dict.empty Dict.empty Nothing currentPage Nothing sharedData pageData maybeActionData |> .head
882
- , view = viewValue.body |> bodyToString
883
- , title = viewValue.title
884
- }
885
-
886
- PageServerResponse.ServerResponse serverResponse ->
887
- PageServerResponse.ServerResponse serverResponse
888
-
889
- PageServerResponse.ErrorPage error record ->
890
- let
891
- currentPage : { path : Path, route : route }
892
- currentPage =
893
- { path = page, route = urlToRoute config currentUrl }
894
-
895
- pageModel : userModel
896
- pageModel =
897
- config.init
898
- Pages.Flags.PreRenderFlags
899
- sharedData
900
- pageData
901
- Nothing
902
- (Just
903
- { path =
904
- { path = currentPage.path
905
- , query = Nothing
906
- , fragment = Nothing
907
- }
908
- , metadata = currentPage.route
909
- , pageUrl = Nothing
910
- }
911
- )
912
- |> Tuple.first
913
-
914
- pageData : pageData
915
- pageData =
916
- config.errorPageToData error
917
-
918
- viewValue : { title : String, body : List (Html (Pages.Msg.Msg userMsg)) }
919
- viewValue =
920
- (config.view Dict.empty Dict.empty Nothing currentPage Nothing sharedData pageData Nothing |> .view) pageModel
921
- in
922
- PageServerResponse.RenderPage
923
- { statusCode = config.errorStatusCode error
924
- , headers = record.headers
925
- }
926
- { head = config.view Dict.empty Dict.empty Nothing currentPage Nothing sharedData pageData Nothing |> .head
927
- , view = viewValue.body |> List.map (HtmlPrinter.htmlToString Nothing) |> String.join "\n"
928
- , title = viewValue.title
929
- }
930
- )
931
-
932
- currentUrl : Url
933
- currentUrl =
934
- { protocol = Url.Https
935
- , host = site.canonicalUrl
936
- , port_ = Nothing
937
- , path = page |> Path.toRelative
938
- , query = Nothing
939
- , fragment = Nothing
940
- }
941
-
942
- pageDataResult : Result BuildError (PageServerResponse pageData errorPage)
943
- pageDataResult =
944
- -- TODO OPTIMIZATION can these three be included in StaticResponses.Finish?
945
- StaticHttpRequest.resolve
946
- (case isAction of
947
- Just _ ->
948
- config.action (urlToRoute config currentUrl)
949
- |> DataSource.andThen
950
- (\something ->
951
- case something of
952
- PageServerResponse.ErrorPage a b ->
953
- PageServerResponse.ErrorPage a b
954
- |> DataSource.succeed
955
-
956
- PageServerResponse.RenderPage _ _ ->
957
- -- TODO the headers/response codes are ignored from the action here
958
- -- is that okay? Should you always do a redirect or another kind of
959
- -- server response if you want to control the headers/response code for an action (like logout & redirect, for example)?
960
- config.data (urlToRoute config currentUrl)
961
-
962
- PageServerResponse.ServerResponse a ->
963
- PageServerResponse.ServerResponse a
964
- |> DataSource.succeed
965
- )
966
-
967
- Nothing ->
968
- config.data (urlToRoute config currentUrl)
969
- )
970
- contentJson
971
- |> Result.mapError (StaticHttpRequest.toBuildError currentUrl.path)
972
-
973
- actionDataResult : Result BuildError (PageServerResponse actionData errorPage)
974
- actionDataResult =
975
- -- TODO OPTIMIZATION can these three be included in StaticResponses.Finish?
976
- StaticHttpRequest.resolve
977
- (config.action (urlToRoute config currentUrl))
978
- contentJson
979
- |> Result.mapError (StaticHttpRequest.toBuildError currentUrl.path)
980
-
981
- sharedDataResult : Result BuildError sharedData
982
- sharedDataResult =
983
- StaticHttpRequest.resolve
984
- config.sharedData
985
- contentJson
986
- |> Result.mapError (StaticHttpRequest.toBuildError currentUrl.path)
987
-
988
- globalHeadTags : DataSource (List Head.Tag)
989
- globalHeadTags =
990
- (config.globalHeadTags |> Maybe.withDefault (\_ -> DataSource.succeed [])) HtmlPrinter.htmlToString
991
-
992
- siteDataResult : Result BuildError (List Head.Tag)
993
- siteDataResult =
994
- StaticHttpRequest.resolve
995
- globalHeadTags
996
- model.allRawResponses
997
- |> Result.mapError (StaticHttpRequest.toBuildError "Site.elm")
998
- in
999
- case Result.map3 (\a b c -> ( a, b, c )) pageFoundResult renderedResult siteDataResult of
1000
- Ok ( maybeNotFoundReason, renderedOrApiResponse, siteData ) ->
1001
- case maybeNotFoundReason of
1002
- Nothing ->
1003
- let
1004
- ( actionHeaders, byteEncodedPageData ) =
1005
- case pageDataResult of
1006
- Ok pageServerResponse ->
1007
- case pageServerResponse of
1008
- PageServerResponse.RenderPage ignored1 pageData ->
1009
- -- TODO want to encode both shared and page data in dev server and HTML-embedded data
1010
- -- but not for writing out the content.dat files - would be good to optimize this redundant data out
1011
- --if model.isDevServer then
1012
- case isAction of
1013
- Just actionRequestKind ->
1014
- case actionDataResult of
1015
- Ok (PageServerResponse.RenderPage ignored2 actionData) ->
1016
- case actionRequestKind of
1017
- ActionResponseRequest ->
1018
- ( ignored2.headers
1019
- , sharedDataResult
1020
- |> Result.map (\sharedData -> ResponseSketch.HotUpdate pageData sharedData (Just actionData))
1021
- |> Result.withDefault (ResponseSketch.RenderPage pageData (Just actionData))
1022
- |> config.encodeResponse
1023
- |> Bytes.Encode.encode
1024
- )
1025
-
1026
- ActionOnlyRequest ->
1027
- ---- TODO need to encode action data when only that is requested (not ResponseSketch?)
1028
- ( ignored2.headers
1029
- , actionData
1030
- |> config.encodeAction
1031
- |> Bytes.Encode.encode
1032
- )
1033
-
1034
- _ ->
1035
- ( ignored1.headers
1036
- , Bytes.Encode.encode (Bytes.Encode.unsignedInt8 0)
1037
- )
1038
-
1039
- Nothing ->
1040
- ( ignored1.headers
1041
- , sharedDataResult
1042
- |> Result.map (\something -> ResponseSketch.HotUpdate pageData something Nothing)
1043
- |> Result.withDefault (ResponseSketch.RenderPage pageData Nothing)
1044
- |> config.encodeResponse
1045
- |> Bytes.Encode.encode
1046
- )
1047
-
1048
- --else
1049
- -- pageData
1050
- -- |> ResponseSketch.RenderPage
1051
- -- |> config.encodeResponse
1052
- -- |> Bytes.Encode.encode
1053
- PageServerResponse.ServerResponse serverResponse ->
1054
- -- TODO handle error?
1055
- ( serverResponse.headers
1056
- , PageServerResponse.toRedirect serverResponse
1057
- |> Maybe.map
1058
- (\{ location } ->
1059
- location
1060
- |> ResponseSketch.Redirect
1061
- |> config.encodeResponse
1062
- )
1063
- -- TODO handle other cases besides redirects?
1064
- |> Maybe.withDefault (Bytes.Encode.unsignedInt8 0)
1065
- |> Bytes.Encode.encode
1066
- )
1067
-
1068
- PageServerResponse.ErrorPage error { headers } ->
1069
- -- TODO this case should never happen
1070
- ( headers
1071
- , sharedDataResult
1072
- |> Result.map
1073
- (\sharedData ->
1074
- ResponseSketch.HotUpdate (config.errorPageToData error)
1075
- sharedData
1076
- Nothing
1077
- )
1078
- |> Result.map config.encodeResponse
1079
- |> Result.map Bytes.Encode.encode
1080
- |> Result.withDefault (Bytes.Encode.encode (Bytes.Encode.unsignedInt8 0))
1081
- )
1082
-
1083
- _ ->
1084
- -- TODO handle error?
1085
- ( []
1086
- , Bytes.Encode.encode (Bytes.Encode.unsignedInt8 0)
1087
- )
1088
- in
1089
- case renderedOrApiResponse of
1090
- PageServerResponse.RenderPage responseInfo rendered ->
1091
- { route = page |> Path.toRelative
1092
- , contentJson = Dict.empty
1093
- , html = rendered.view
1094
- , errors = []
1095
- , head = rendered.head ++ siteData
1096
- , title = rendered.title
1097
- , staticHttpCache = Dict.empty
1098
- , is404 = False
1099
- , statusCode = responseInfo.statusCode
1100
- , headers =
1101
- -- TODO should `responseInfo.headers` be used? Is there a problem in the case where there is both an action and data response in one? Do we need to make sure it is performed as two separate HTTP requests to ensure that the cookies are set correctly in that case?
1102
- actionHeaders
1103
- }
1104
- |> ToJsPayload.PageProgress
1105
- |> Effect.SendSinglePageNew byteEncodedPageData
1106
-
1107
- PageServerResponse.ServerResponse serverResponse ->
1108
- PageServerResponse.toRedirect serverResponse
1109
- |> Maybe.map
1110
- (\_ ->
1111
- { route = page |> Path.toRelative
1112
- , contentJson = Dict.empty
1113
- , html = "This is intentionally blank HTML"
1114
- , errors = []
1115
- , head = []
1116
- , title = "This is an intentionally blank title"
1117
- , staticHttpCache = Dict.empty
1118
- , is404 = False
1119
- , statusCode =
1120
- case includeHtml of
1121
- RenderRequest.OnlyJson ->
1122
- -- if this is a redirect for a `content.dat`, we don't want to send an *actual* redirect status code because the redirect needs to be handled in Elm (not by the Browser)
1123
- 200
1124
-
1125
- RenderRequest.HtmlAndJson ->
1126
- serverResponse.statusCode
1127
- , headers = serverResponse.headers
1128
- }
1129
- |> ToJsPayload.PageProgress
1130
- |> Effect.SendSinglePageNew byteEncodedPageData
1131
- )
1132
- |> Maybe.withDefault
1133
- ({ body = serverResponse |> PageServerResponse.toJson
1134
- , staticHttpCache = Dict.empty
1135
- , statusCode = serverResponse.statusCode
1136
- }
1137
- |> ToJsPayload.SendApiResponse
1138
- |> Effect.SendSinglePage
1139
- )
846
+ StaticResponses.FinishedWithErrors errors ->
847
+ ( model
848
+ , errors |> ToJsPayload.Errors |> Effect.SendSinglePage
849
+ )
1140
850
 
1141
- PageServerResponse.ErrorPage error responseInfo ->
1142
- -- TODO this case should never happen
1143
- { route = page |> Path.toRelative
1144
- , contentJson = Dict.empty
1145
- , html = "UNEXPECTED!" --HtmlPrinter.htmlToString rendered.body
1146
- , errors = []
1147
- , head = [] -- rendered.head ++ siteData -- TODO this should call ErrorPage.head maybe?
1148
- , title = "UNEXPECTED CASE" --rendered.title
1149
- , staticHttpCache = Dict.empty
1150
- , is404 = False
1151
- , statusCode = config.errorStatusCode error
1152
- , headers = responseInfo.headers
1153
- }
1154
- |> ToJsPayload.PageProgress
1155
- |> Effect.SendSinglePageNew byteEncodedPageData
1156
-
1157
- Just notFoundReason ->
1158
- render404Page config (Result.toMaybe sharedDataResult) model page notFoundReason
1159
-
1160
- Err error ->
1161
- [ error ]
1162
- |> ToJsPayload.Errors
1163
- |> Effect.SendSinglePage
851
+ StaticResponses.Finish finalValue ->
852
+ ( model
853
+ , finalValue
854
+ )
1164
855
 
1165
856
 
1166
857
  render404Page :
1167
858
  ProgramConfig userMsg userModel route pageData actionData sharedData effect mappedMsg errorPage
1168
859
  -> Maybe sharedData
1169
- -> Model route
860
+ -> Bool
1170
861
  -> Path
1171
862
  -> NotFoundReason
1172
863
  -> Effect
1173
- render404Page config sharedData model path notFoundReason =
1174
- case ( model.isDevServer, sharedData ) of
864
+ render404Page config sharedData isDevServer path notFoundReason =
865
+ case ( isDevServer, sharedData ) of
1175
866
  ( False, Just justSharedData ) ->
1176
867
  let
1177
868
  byteEncodedPageData : Bytes