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.
- package/README.md +1 -1
- package/codegen/elm-pages-codegen.js +1496 -1126
- 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/Runner.elm.js +151 -39
- 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 +1 -1
- package/generator/dead-code-review/elm.json +3 -2
- package/generator/dead-code-review/src/Pages/Review/DeadCodeEliminateData.elm +58 -10
- package/generator/dead-code-review/tests/Pages/Review/DeadCodeEliminateDataTest.elm +45 -29
- 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/Runner.elm.js +45 -4
- 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 +1 -1
- package/generator/review/elm.json +3 -3
- package/generator/src/RouteBuilder.elm +66 -52
- package/generator/src/SharedTemplate.elm +3 -2
- package/generator/src/SiteConfig.elm +3 -2
- package/generator/src/build.js +6 -6
- package/generator/src/cli.js +12 -7
- package/generator/src/compatibility-key.js +1 -1
- package/generator/src/dev-server.js +7 -7
- package/generator/src/render-test.js +109 -0
- package/generator/src/render.js +77 -51
- package/generator/src/request-cache.js +149 -158
- package/generator/template/app/Api.elm +2 -2
- package/generator/template/app/Route/Index.elm +3 -3
- package/generator/template/app/Shared.elm +3 -3
- package/generator/template/app/Site.elm +3 -3
- package/package.json +11 -11
- package/src/ApiRoute.elm +63 -57
- package/src/BackendTask/Env.elm +87 -0
- package/src/{DataSource → BackendTask}/File.elm +89 -43
- package/src/{DataSource → BackendTask}/Glob.elm +134 -125
- package/src/BackendTask/Http.elm +637 -0
- package/src/{DataSource → BackendTask}/Internal/Glob.elm +1 -1
- package/src/BackendTask/Internal/Request.elm +28 -0
- package/src/BackendTask/Port.elm +202 -0
- package/src/{DataSource.elm → BackendTask.elm} +223 -207
- package/src/Exception.elm +37 -0
- package/src/Form.elm +20 -20
- package/src/Head.elm +7 -7
- package/src/Internal/ApiRoute.elm +7 -5
- package/src/PageServerResponse.elm +6 -1
- package/src/Pages/Generate.elm +35 -63
- package/src/Pages/Internal/Platform/Cli.elm +422 -731
- package/src/Pages/Internal/Platform/Cli.elm.bak +22 -22
- package/src/Pages/Internal/Platform/CompatibilityKey.elm +1 -1
- package/src/Pages/Internal/Platform/Effect.elm +0 -1
- package/src/Pages/Internal/Platform/GeneratorApplication.elm +53 -113
- package/src/Pages/Internal/Platform/StaticResponses.elm +72 -256
- package/src/Pages/Internal/Platform/ToJsPayload.elm +4 -4
- package/src/Pages/Internal/Platform.elm +25 -31
- package/src/Pages/Internal/Script.elm +17 -0
- package/src/Pages/Internal/StaticHttpBody.elm +35 -1
- package/src/Pages/Manifest.elm +5 -4
- package/src/Pages/ProgramConfig.elm +8 -7
- package/src/Pages/Script.elm +34 -25
- package/src/Pages/SiteConfig.elm +3 -2
- package/src/Pages/StaticHttp/Request.elm +2 -2
- package/src/Pages/StaticHttpRequest.elm +37 -90
- package/src/RequestsAndPending.elm +8 -19
- package/src/Server/Request.elm +14 -14
- package/src/Server/Session.elm +34 -34
- package/src/Server/SetCookie.elm +1 -1
- package/src/DataSource/Env.elm +0 -62
- package/src/DataSource/Http.elm +0 -446
- package/src/DataSource/Internal/Request.elm +0 -20
- 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
|
|
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
|
|
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
|
|
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 :
|
|
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
|
|
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
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
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
|
|
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 {
|
|
284
|
+
Ok { isDevServer, compatibilityKey } ->
|
|
379
285
|
if compatibilityKey == currentCompatibilityKey then
|
|
380
|
-
initLegacy site renderRequest {
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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 =
|
|
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
|
-
-> {
|
|
377
|
+
-> { isDevServer : Bool }
|
|
478
378
|
-> ProgramConfig userMsg userModel route pageData actionData sharedData effect mappedMsg errorPage
|
|
479
379
|
-> ( Model route, Effect )
|
|
480
|
-
initLegacy site renderRequest {
|
|
380
|
+
initLegacy site ((RenderRequest.SinglePage includeHtml singleRequest _) as renderRequest) { isDevServer } config =
|
|
481
381
|
let
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
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
|
-
|
|
532
|
-
|
|
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
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
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
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
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
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
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
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
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 =
|
|
764
|
+
{ staticResponses = staticResponsesNew
|
|
566
765
|
, errors = []
|
|
567
|
-
, allRawResponses =
|
|
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
|
|
574
|
-
|> nextStepToEffect
|
|
575
|
-
config
|
|
771
|
+
StaticResponses.nextStep initialModel
|
|
772
|
+
|> nextStepToEffect
|
|
576
773
|
initialModel
|
|
577
774
|
|
|
578
775
|
|
|
579
776
|
updateAndSendPortIfDone :
|
|
580
|
-
|
|
581
|
-
-> ProgramConfig userMsg userModel route pageData actionData sharedData effect mappedMsg errorPage
|
|
582
|
-
-> Model route
|
|
777
|
+
Model route
|
|
583
778
|
-> ( Model route, Effect )
|
|
584
|
-
updateAndSendPortIfDone
|
|
779
|
+
updateAndSendPortIfDone model =
|
|
585
780
|
StaticResponses.nextStep
|
|
586
781
|
model
|
|
587
|
-
|
|
588
|
-
|> nextStepToEffect site config model
|
|
782
|
+
|> nextStepToEffect model
|
|
589
783
|
|
|
590
784
|
|
|
591
785
|
{-| -}
|
|
592
786
|
update :
|
|
593
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
624
|
-
|> nextStepToEffect site config updatedModel
|
|
814
|
+
|> nextStepToEffect updatedModel
|
|
625
815
|
|
|
626
816
|
|
|
627
817
|
nextStepToEffect :
|
|
628
|
-
|
|
629
|
-
->
|
|
630
|
-
-> Model route
|
|
631
|
-
-> ( StaticResponses, StaticResponses.NextStep route )
|
|
818
|
+
Model route
|
|
819
|
+
-> StaticResponses.NextStep route Effect
|
|
632
820
|
-> ( Model route, Effect )
|
|
633
|
-
nextStepToEffect
|
|
821
|
+
nextStepToEffect model nextStep =
|
|
634
822
|
case nextStep of
|
|
635
|
-
StaticResponses.Continue
|
|
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
|
-
|
|
|
656
|
-
, staticResponses = updatedStaticResponsesModel
|
|
657
|
-
, unprocessedPages = updatedUnprocessedPages
|
|
828
|
+
| staticResponses = updatedStaticResponsesModel
|
|
658
829
|
}
|
|
659
830
|
in
|
|
660
831
|
if List.isEmpty httpRequests then
|
|
661
|
-
nextStepToEffect
|
|
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.
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
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
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
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
|
-
->
|
|
860
|
+
-> Bool
|
|
1170
861
|
-> Path
|
|
1171
862
|
-> NotFoundReason
|
|
1172
863
|
-> Effect
|
|
1173
|
-
render404Page config sharedData
|
|
1174
|
-
case (
|
|
864
|
+
render404Page config sharedData isDevServer path notFoundReason =
|
|
865
|
+
case ( isDevServer, sharedData ) of
|
|
1175
866
|
( False, Just justSharedData ) ->
|
|
1176
867
|
let
|
|
1177
868
|
byteEncodedPageData : Bytes
|