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

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 (78) hide show
  1. package/README.md +1 -1
  2. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateData.elmo +0 -0
  3. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
  4. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/i.dat +0 -0
  5. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/o.dat +0 -0
  6. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm.json +1 -1
  7. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Reporter.elm.js +1326 -121
  8. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Runner.elm.js +15156 -13244
  9. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
  10. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_supervisor.js +1 -1
  11. package/generator/dead-code-review/elm.json +6 -5
  12. package/generator/dead-code-review/src/Pages/Review/DeadCodeEliminateData.elm +1 -0
  13. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
  14. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/i.dat +0 -0
  15. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/o.dat +0 -0
  16. package/generator/review/elm-stuff/tests-0.19.1/elm.json +1 -1
  17. package/generator/review/elm-stuff/tests-0.19.1/js/Reporter.elm.js +1326 -121
  18. package/generator/review/elm-stuff/tests-0.19.1/js/Runner.elm.js +14574 -12631
  19. package/generator/review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
  20. package/generator/review/elm-stuff/tests-0.19.1/js/node_supervisor.js +1 -1
  21. package/generator/review/elm.json +6 -6
  22. package/generator/src/build.js +6 -9
  23. package/generator/src/cli.js +120 -42
  24. package/generator/src/codegen.js +11 -10
  25. package/generator/src/compatibility-key.js +1 -1
  26. package/generator/src/elm-codegen.js +3 -0
  27. package/generator/src/render-worker.js +1 -1
  28. package/generator/src/render.js +222 -37
  29. package/generator/src/request-cache.js +1 -0
  30. package/generator/src/rewrite-elm-json.js +3 -3
  31. package/package.json +12 -12
  32. package/src/ApiRoute.elm +147 -9
  33. package/src/DataSource/Env.elm +27 -3
  34. package/src/DataSource.elm +11 -22
  35. package/src/Form.elm +32 -32
  36. package/src/Head.elm +112 -8
  37. package/src/MultiDict.elm +49 -0
  38. package/src/Pages/Generate.elm +4 -1
  39. package/src/Pages/GeneratorProgramConfig.elm +15 -0
  40. package/src/Pages/Internal/Platform/CompatibilityKey.elm +1 -1
  41. package/src/Pages/Internal/Platform/GeneratorApplication.elm +455 -0
  42. package/src/Pages/Manifest.elm +24 -0
  43. package/src/Pages/Script.elm +100 -0
  44. package/src/PairingHeap.elm +137 -0
  45. package/src/Parser/Extra/String.elm +33 -0
  46. package/src/Parser/Extra.elm +69 -0
  47. package/src/ProgramTest/ComplexQuery.elm +360 -0
  48. package/src/ProgramTest/EffectSimulation.elm +122 -0
  49. package/src/ProgramTest/Failure.elm +367 -0
  50. package/src/ProgramTest/HtmlHighlighter.elm +116 -0
  51. package/src/ProgramTest/HtmlParserHacks.elm +58 -0
  52. package/src/ProgramTest/HtmlRenderer.elm +73 -0
  53. package/src/ProgramTest/Program.elm +30 -0
  54. package/src/ProgramTest/StringLines.elm +26 -0
  55. package/src/ProgramTest/TestHtmlHacks.elm +132 -0
  56. package/src/ProgramTest/TestHtmlParser.elm +201 -0
  57. package/src/ProgramTest.elm +2339 -0
  58. package/src/Query/Extra.elm +55 -0
  59. package/src/Result/Extra.elm +21 -0
  60. package/src/Server/Request.elm +2 -2
  61. package/src/SimulatedEffect/Cmd.elm +69 -0
  62. package/src/SimulatedEffect/Http.elm +330 -0
  63. package/src/SimulatedEffect/Navigation.elm +69 -0
  64. package/src/SimulatedEffect/Ports.elm +62 -0
  65. package/src/SimulatedEffect/Process.elm +24 -0
  66. package/src/SimulatedEffect/Sub.elm +48 -0
  67. package/src/SimulatedEffect/Task.elm +252 -0
  68. package/src/SimulatedEffect/Time.elm +25 -0
  69. package/src/SimulatedEffect.elm +42 -0
  70. package/src/String/Extra.elm +6 -0
  71. package/src/Test/Http.elm +145 -0
  72. package/src/TestResult.elm +35 -0
  73. package/src/TestState.elm +305 -0
  74. package/src/Url/Extra.elm +100 -0
  75. package/src/Vendored/Diff.elm +321 -0
  76. package/src/Vendored/Failure.elm +217 -0
  77. package/src/Vendored/FormatMonochrome.elm +44 -0
  78. package/src/Vendored/Highlightable.elm +53 -0
package/src/Head.elm CHANGED
@@ -9,14 +9,118 @@ module Head exposing
9
9
  , toJson, canonicalLink
10
10
  )
11
11
 
12
- {-| This module contains low-level functions for building up
13
- values that will be rendered into the page's `<head>` tag
14
- when you run `elm-pages build`. Most likely the `Head.Seo` module
15
- will do everything you need out of the box, and you will just need to import `Head`
16
- so you can use the `Tag` type in your type annotations.
17
-
18
- But this module might be useful if you have a special use case, or if you are
19
- writing a plugin package to extend `elm-pages`.
12
+ {-| This module contains functions for building up
13
+ tags with metadata that will be rendered into the page's `<head>` tag
14
+ when your page is pre-rendered (or server-rendered, in the case of your server-rendered Route Modules). See also [`Head.Seo`](Head-Seo),
15
+ which has some helper functions for defining OpenGraph and Twitter tags.
16
+
17
+ One of the unique benefits of using `elm-pages` is that all of your routes (both pre-rendered and server-rendered) fully
18
+ render the HTML of your page. That includes the full initial `view` (with the DataSource resolved, and the `Model` from `init`).
19
+ The HTML response also includes all of the `Head` tags, which are defined in two places:
20
+
21
+ 1. `app/Site.elm` - there is a `head` definition in `Site.elm` where you define global head tags that will be included on every rendered page.
22
+
23
+ 2. In each Route Module - there is a `head` function where you have access to both the resolved `DataSource` and the `RouteParams` for the page and can return head tags based on that.
24
+
25
+ Here is a common set of global head tags that we can define in `Site.elm`:
26
+
27
+ module Site exposing (canonicalUrl, config)
28
+
29
+ import DataSource exposing (DataSource)
30
+ import Head
31
+ import MimeType
32
+ import SiteConfig exposing (SiteConfig)
33
+
34
+ config : SiteConfig
35
+ config =
36
+ { canonicalUrl = "<https://elm-pages.com">
37
+ , head = head
38
+ }
39
+
40
+ head : DataSource (List Head.Tag)
41
+ head =
42
+ [ Head.metaName "viewport" (Head.raw "width=device-width,initial-scale=1")
43
+ , Head.metaName "mobile-web-app-capable" (Head.raw "yes")
44
+ , Head.metaName "theme-color" (Head.raw "#ffffff")
45
+ , Head.metaName "apple-mobile-web-app-capable" (Head.raw "yes")
46
+ , Head.metaName "apple-mobile-web-app-status-bar-style" (Head.raw "black-translucent")
47
+ , Head.icon [ ( 32, 32 ) ] MimeType.Png (cloudinaryIcon MimeType.Png 32)
48
+ , Head.icon [ ( 16, 16 ) ] MimeType.Png (cloudinaryIcon MimeType.Png 16)
49
+ , Head.appleTouchIcon (Just 180) (cloudinaryIcon MimeType.Png 180)
50
+ , Head.appleTouchIcon (Just 192) (cloudinaryIcon MimeType.Png 192)
51
+ ]
52
+ |> DataSource.succeed
53
+
54
+ And here is a `head` function for a Route Module for a blog post. Note that we have access to our `DataSource` Data and
55
+ are using it to populate article metadata like the article's image, publish date, etc.
56
+
57
+ import Article
58
+ import DataSource
59
+ import Date
60
+ import Head
61
+ import Head.Seo
62
+ import Path
63
+ import Route exposing (Route)
64
+ import RouteBuilder exposing (StatelessRoute, StaticPayload)
65
+
66
+ type alias RouteParams =
67
+ { slug : String }
68
+
69
+ type alias Data =
70
+ { metadata : ArticleMetadata
71
+ , body : List Markdown.Block.Block
72
+ }
73
+
74
+ route : StatelessRoute RouteParams Data ActionData
75
+ route =
76
+ RouteBuilder.preRender
77
+ { data = data
78
+ , head = head
79
+ , pages = pages
80
+ }
81
+ |> RouteBuilder.buildNoState { view = view }
82
+
83
+ head :
84
+ StaticPayload Data ActionData RouteParams
85
+ -> List Head.Tag
86
+ head static =
87
+ let
88
+ metadata =
89
+ static.data.metadata
90
+ in
91
+ Head.Seo.summaryLarge
92
+ { canonicalUrlOverride = Nothing
93
+ , siteName = "elm-pages"
94
+ , image =
95
+ { url = metadata.image
96
+ , alt = metadata.description
97
+ , dimensions = Nothing
98
+ , mimeType = Nothing
99
+ }
100
+ , description = metadata.description
101
+ , locale = Nothing
102
+ , title = metadata.title
103
+ }
104
+ |> Head.Seo.article
105
+ { tags = []
106
+ , section = Nothing
107
+ , publishedTime = Just (DateOrDateTime.Date metadata.published)
108
+ , modifiedTime = Nothing
109
+ , expirationTime = Nothing
110
+ }
111
+
112
+
113
+ ## Why is pre-rendered HTML important? Does it still matter for SEO?
114
+
115
+ Many search engines are able to execute JavaScript now. However, not all are, and even with crawlers like Google, there
116
+ is a longer lead time for your pages to be indexed when you have HTML with a blank page that is only visible after the JavaScript executes.
117
+
118
+ But most importantly, many tools that unfurl links will not execute JavaScript at all, but rather simply do a simple pass to parse your `<head>` tags.
119
+ It is not viable or reliable to add `<head>` tags for metadata on the client-side, it must be present in the initial HTML payload. Otherwise you may not
120
+ get unfurling preview content when you share a link to your site on Slack, Twitter, etc.
121
+
122
+
123
+ ## Building up Head Tags
20
124
 
21
125
  @docs Tag, metaName, metaProperty, metaRedirect
22
126
  @docs rssLink, sitemapLink, rootLanguage, manifestLink
@@ -0,0 +1,49 @@
1
+ module MultiDict exposing (MultiDict, empty, get, insert, keys, remove, set)
2
+
3
+ import Dict exposing (Dict)
4
+ import List.Extra
5
+ import List.Nonempty as NonEmpty
6
+
7
+
8
+ type alias NonEmpty a =
9
+ NonEmpty.Nonempty a
10
+
11
+
12
+ type MultiDict k v
13
+ = MultiDict (Dict k (NonEmpty v))
14
+
15
+
16
+ empty : MultiDict k v
17
+ empty =
18
+ MultiDict Dict.empty
19
+
20
+
21
+ insert : comparable -> v -> MultiDict comparable v -> MultiDict comparable v
22
+ insert key value (MultiDict dict) =
23
+ MultiDict
24
+ (Dict.update key (Maybe.map (NonEmpty.cons value) >> Maybe.withDefault (NonEmpty.fromElement value) >> Just) dict)
25
+
26
+
27
+ get : comparable -> MultiDict comparable v -> List v
28
+ get key (MultiDict dict) =
29
+ Dict.get key dict
30
+ |> Maybe.map NonEmpty.toList
31
+ |> Maybe.withDefault []
32
+
33
+
34
+ keys : MultiDict k v -> List k
35
+ keys (MultiDict dict) =
36
+ Dict.toList dict
37
+ |> List.concatMap (\( k, vs ) -> List.repeat (NonEmpty.length vs) k)
38
+
39
+
40
+ remove : comparable -> v -> MultiDict comparable v -> MultiDict comparable v
41
+ remove key value (MultiDict dict) =
42
+ MultiDict
43
+ (Dict.update key (Maybe.andThen (NonEmpty.toList >> List.Extra.remove value >> NonEmpty.fromList)) dict)
44
+
45
+
46
+ set : comparable -> List v -> MultiDict comparable v -> MultiDict comparable v
47
+ set key values (MultiDict dict) =
48
+ MultiDict
49
+ (Dict.update key (\_ -> NonEmpty.fromList values) dict)
@@ -5,7 +5,10 @@ module Pages.Generate exposing
5
5
  , preRender, single
6
6
  )
7
7
 
8
- {-|
8
+ {-| This module provides some functions for scaffolding code for a new Route Module. It uses [`elm-codegen`'s API](https://package.elm-lang.org/packages/mdgriffith/elm-codegen/latest/) for generating code.
9
+
10
+ Typically you'll want to use this via the `elm-pages codegen` CLI command. The default starter template includes a file that uses these functions, which you can tweak to customize your scaffolding commands.
11
+ Learn more about [the `elm-pages run` CLI command in its docs page](https://elm-pages.com/docs/run-command).
9
12
 
10
13
 
11
14
  ## Initializing the Generator Builder
@@ -0,0 +1,15 @@
1
+ module Pages.GeneratorProgramConfig exposing (GeneratorProgramConfig)
2
+
3
+ import Json.Decode as Decode
4
+ import Json.Encode
5
+ import Pages.Internal.Platform.ToJsPayload
6
+ import Pages.Script exposing (Script)
7
+
8
+
9
+ type alias GeneratorProgramConfig =
10
+ { data : Script
11
+ , toJsPort : Json.Encode.Value -> Cmd Never
12
+ , fromJsPort : Sub Decode.Value
13
+ , gotBatchSub : Sub Decode.Value
14
+ , sendPageData : Pages.Internal.Platform.ToJsPayload.NewThingForPort -> Cmd Never
15
+ }
@@ -3,4 +3,4 @@ module Pages.Internal.Platform.CompatibilityKey exposing (currentCompatibilityKe
3
3
 
4
4
  currentCompatibilityKey : Int
5
5
  currentCompatibilityKey =
6
- 1
6
+ 2
@@ -0,0 +1,455 @@
1
+ module Pages.Internal.Platform.GeneratorApplication exposing (Flags, Model, Msg(..), init, requestDecoder, update, app)
2
+
3
+ {-| Exposed for internal use only (used in generated code).
4
+
5
+ @docs Flags, Model, Msg, init, requestDecoder, update, app
6
+
7
+ -}
8
+
9
+ import BuildError exposing (BuildError)
10
+ import Cli.Program as Program exposing (FlagsIncludingArgv)
11
+ import Codec
12
+ import DataSource exposing (DataSource)
13
+ import Dict
14
+ import HtmlPrinter
15
+ import Json.Decode as Decode
16
+ import Json.Encode
17
+ import Pages.GeneratorProgramConfig exposing (GeneratorProgramConfig)
18
+ import Pages.Internal.Platform.CompatibilityKey
19
+ import Pages.Internal.Platform.Effect as Effect exposing (Effect)
20
+ import Pages.Internal.Platform.StaticResponses as StaticResponses exposing (StaticResponses)
21
+ import Pages.Internal.Platform.ToJsPayload as ToJsPayload
22
+ import Pages.Script exposing (Script(..))
23
+ import Pages.StaticHttp.Request
24
+ import Pages.StaticHttpRequest as StaticHttpRequest
25
+ import RequestsAndPending exposing (RequestsAndPending)
26
+ import TerminalText as Terminal
27
+
28
+
29
+ {-| -}
30
+ type alias Flags =
31
+ { compatibilityKey : Int
32
+ }
33
+
34
+
35
+ {-| -}
36
+ type alias Model =
37
+ { staticResponses : StaticResponses
38
+ , errors : List BuildError
39
+ , allRawResponses : RequestsAndPending
40
+ , done : Bool
41
+ }
42
+
43
+
44
+ {-| -}
45
+ type Msg
46
+ = GotDataBatch
47
+ (List
48
+ { request : Pages.StaticHttp.Request.Request
49
+ , response : RequestsAndPending.Response
50
+ }
51
+ )
52
+ | GotBuildError BuildError
53
+
54
+
55
+ {-| -}
56
+ app :
57
+ GeneratorProgramConfig
58
+ -> Program.StatefulProgram Model Msg (DataSource ()) Flags
59
+ app config =
60
+ let
61
+ cliConfig : Program.Config (DataSource ())
62
+ cliConfig =
63
+ case config.data of
64
+ Generator theCliConfig ->
65
+ theCliConfig HtmlPrinter.htmlToString
66
+ in
67
+ Program.stateful
68
+ { init =
69
+ \flags cliOptions ->
70
+ init cliOptions flags
71
+ |> Tuple.mapSecond (perform config)
72
+ , update =
73
+ \cliOptions msg model ->
74
+ update cliOptions msg model
75
+ |> Tuple.mapSecond (perform config)
76
+ , subscriptions =
77
+ \_ ->
78
+ Sub.batch
79
+ [ config.fromJsPort
80
+ |> Sub.map
81
+ (\jsonValue ->
82
+ let
83
+ decoder : Decode.Decoder Msg
84
+ decoder =
85
+ Decode.field "tag" Decode.string
86
+ |> Decode.andThen
87
+ (\tag ->
88
+ case tag of
89
+ "BuildError" ->
90
+ Decode.field "data"
91
+ (Decode.map2
92
+ (\message title ->
93
+ { title = title
94
+ , message = message
95
+ , fatal = True
96
+ , path = "" -- TODO wire in current path here
97
+ }
98
+ )
99
+ (Decode.field "message" Decode.string |> Decode.map Terminal.fromAnsiString)
100
+ (Decode.field "title" Decode.string)
101
+ )
102
+ |> Decode.map GotBuildError
103
+
104
+ _ ->
105
+ Decode.fail "Unhandled msg"
106
+ )
107
+ in
108
+ Decode.decodeValue decoder jsonValue
109
+ |> Result.mapError
110
+ (\error ->
111
+ ("From location 1: "
112
+ ++ (error
113
+ |> Decode.errorToString
114
+ )
115
+ )
116
+ |> BuildError.internal
117
+ |> GotBuildError
118
+ )
119
+ |> mergeResult
120
+ )
121
+ , config.gotBatchSub
122
+ |> Sub.map
123
+ (\newBatch ->
124
+ Decode.decodeValue batchDecoder newBatch
125
+ |> Result.map GotDataBatch
126
+ |> Result.mapError
127
+ (\error ->
128
+ ("From location 2: "
129
+ ++ (error
130
+ |> Decode.errorToString
131
+ )
132
+ )
133
+ |> BuildError.internal
134
+ |> GotBuildError
135
+ )
136
+ |> mergeResult
137
+ )
138
+ ]
139
+ , config = cliConfig
140
+ , printAndExitFailure =
141
+ \string ->
142
+ ToJsPayload.Errors
143
+ [ { title = "Invalid CLI arguments"
144
+ , path = ""
145
+ , message =
146
+ [ Terminal.text string
147
+ ]
148
+ , fatal = True
149
+ }
150
+ ]
151
+ |> Codec.encodeToValue (ToJsPayload.successCodecNew2 "" "")
152
+ |> config.toJsPort
153
+ |> Cmd.map never
154
+ , printAndExitSuccess = \string -> config.toJsPort (Json.Encode.string string) |> Cmd.map never
155
+ }
156
+
157
+
158
+ batchDecoder : Decode.Decoder (List { request : Pages.StaticHttp.Request.Request, response : RequestsAndPending.Response })
159
+ batchDecoder =
160
+ Decode.map2 (\request response -> { request = request, response = response })
161
+ (Decode.field "request" requestDecoder)
162
+ (Decode.field "response" RequestsAndPending.decoder)
163
+ |> Decode.list
164
+
165
+
166
+ mergeResult : Result a a -> a
167
+ mergeResult r =
168
+ case r of
169
+ Ok rr ->
170
+ rr
171
+
172
+ Err rr ->
173
+ rr
174
+
175
+
176
+ {-| -}
177
+ requestDecoder : Decode.Decoder Pages.StaticHttp.Request.Request
178
+ requestDecoder =
179
+ Pages.StaticHttp.Request.codec
180
+ |> Codec.decoder
181
+
182
+
183
+ flatten : GeneratorProgramConfig -> List Effect -> Cmd Msg
184
+ flatten config list =
185
+ Cmd.batch (flattenHelp [] config list)
186
+
187
+
188
+ flattenHelp : List (Cmd Msg) -> GeneratorProgramConfig -> List Effect -> List (Cmd Msg)
189
+ flattenHelp soFar config list =
190
+ case list of
191
+ first :: rest ->
192
+ flattenHelp
193
+ (perform config first :: soFar)
194
+ config
195
+ rest
196
+
197
+ [] ->
198
+ soFar
199
+
200
+
201
+ perform :
202
+ GeneratorProgramConfig
203
+ -> Effect
204
+ -> Cmd Msg
205
+ perform config effect =
206
+ let
207
+ canonicalSiteUrl : String
208
+ canonicalSiteUrl =
209
+ ""
210
+ in
211
+ case effect of
212
+ Effect.NoEffect ->
213
+ Cmd.none
214
+
215
+ Effect.Batch list ->
216
+ flatten config list
217
+
218
+ Effect.FetchHttp unmasked ->
219
+ ToJsPayload.DoHttp unmasked unmasked.useCache
220
+ |> Codec.encoder (ToJsPayload.successCodecNew2 canonicalSiteUrl "")
221
+ |> config.toJsPort
222
+ |> Cmd.map never
223
+
224
+ Effect.SendSinglePage info ->
225
+ let
226
+ currentPagePath : String
227
+ currentPagePath =
228
+ case info of
229
+ ToJsPayload.PageProgress toJsSuccessPayloadNew ->
230
+ toJsSuccessPayloadNew.route
231
+
232
+ _ ->
233
+ ""
234
+ in
235
+ info
236
+ |> Codec.encoder (ToJsPayload.successCodecNew2 canonicalSiteUrl currentPagePath)
237
+ |> config.toJsPort
238
+ |> Cmd.map never
239
+
240
+ Effect.SendSinglePageNew rawBytes info ->
241
+ let
242
+ currentPagePath : String
243
+ currentPagePath =
244
+ case info of
245
+ ToJsPayload.PageProgress toJsSuccessPayloadNew ->
246
+ toJsSuccessPayloadNew.route
247
+
248
+ _ ->
249
+ ""
250
+ in
251
+ { oldThing =
252
+ info
253
+ |> Codec.encoder (ToJsPayload.successCodecNew2 canonicalSiteUrl currentPagePath)
254
+ , binaryPageData = rawBytes
255
+ }
256
+ |> config.sendPageData
257
+ |> Cmd.map never
258
+
259
+ Effect.Continue ->
260
+ Cmd.none
261
+
262
+
263
+
264
+ -- TODO use Json.Decode.Value for flagsDecoder instead of hardcoded record flags
265
+ --flagsDecoder :
266
+ -- Decode.Decoder
267
+ -- { staticHttpCache : RequestsAndPending
268
+ -- , compatibilityKey : Int
269
+ -- }
270
+ --flagsDecoder =
271
+ -- Decode.map3
272
+ -- (\staticHttpCache compatibilityKey ->
273
+ -- { staticHttpCache = staticHttpCache
274
+ -- , isDevServer = isDevServer
275
+ -- , compatibilityKey = compatibilityKey
276
+ -- }
277
+ -- )
278
+ -- (Decode.succeed Dict.empty)
279
+ -- (Decode.field "compatibilityKey" Decode.int)
280
+
281
+
282
+ {-| -}
283
+ init :
284
+ DataSource ()
285
+ -> FlagsIncludingArgv Flags
286
+ -> ( Model, Effect )
287
+ init execute flags =
288
+ if flags.compatibilityKey == Pages.Internal.Platform.CompatibilityKey.currentCompatibilityKey then
289
+ initLegacy execute { staticHttpCache = Dict.empty }
290
+
291
+ else
292
+ let
293
+ elmPackageAheadOfNpmPackage : Bool
294
+ elmPackageAheadOfNpmPackage =
295
+ Pages.Internal.Platform.CompatibilityKey.currentCompatibilityKey > flags.compatibilityKey
296
+
297
+ message : String
298
+ message =
299
+ "The NPM package and Elm package you have installed are incompatible. If you are updating versions, be sure to update both the elm-pages Elm and NPM package.\n\n"
300
+ ++ (if elmPackageAheadOfNpmPackage then
301
+ "The elm-pages Elm package is ahead of the elm-pages NPM package. Try updating the elm-pages NPM package?"
302
+
303
+ else
304
+ "The elm-pages NPM package is ahead of the elm-pages Elm package. Try updating the elm-pages Elm package?"
305
+ )
306
+ in
307
+ updateAndSendPortIfDone execute
308
+ { staticResponses = StaticResponses.empty
309
+ , errors =
310
+ [ { title = "Incompatible NPM and Elm package versions"
311
+ , message = [ Terminal.text <| message ]
312
+ , fatal = True
313
+ , path = ""
314
+ }
315
+ ]
316
+ , allRawResponses = Dict.empty
317
+ , done = False
318
+ }
319
+
320
+
321
+ initLegacy :
322
+ DataSource ()
323
+ -> { staticHttpCache : RequestsAndPending }
324
+ -> ( Model, Effect )
325
+ initLegacy execute { staticHttpCache } =
326
+ let
327
+ staticResponses : StaticResponses
328
+ staticResponses =
329
+ StaticResponses.renderApiRequest execute
330
+
331
+ initialModel : Model
332
+ initialModel =
333
+ { staticResponses = staticResponses
334
+ , errors = []
335
+ , allRawResponses = staticHttpCache
336
+ , done = False
337
+ }
338
+ in
339
+ StaticResponses.nextStep initialModel Nothing
340
+ |> nextStepToEffect execute
341
+ initialModel
342
+
343
+
344
+ updateAndSendPortIfDone :
345
+ DataSource ()
346
+ -> Model
347
+ -> ( Model, Effect )
348
+ updateAndSendPortIfDone execute model =
349
+ StaticResponses.nextStep
350
+ model
351
+ Nothing
352
+ |> nextStepToEffect execute model
353
+
354
+
355
+ {-| -}
356
+ update :
357
+ DataSource ()
358
+ -> Msg
359
+ -> Model
360
+ -> ( Model, Effect )
361
+ update execute msg model =
362
+ case msg of
363
+ GotDataBatch batch ->
364
+ let
365
+ updatedModel : Model
366
+ updatedModel =
367
+ model
368
+ |> StaticResponses.batchUpdate batch
369
+ in
370
+ StaticResponses.nextStep
371
+ updatedModel
372
+ Nothing
373
+ |> nextStepToEffect execute updatedModel
374
+
375
+ GotBuildError buildError ->
376
+ let
377
+ updatedModel : Model
378
+ updatedModel =
379
+ { model
380
+ | errors =
381
+ buildError :: model.errors
382
+ }
383
+ in
384
+ StaticResponses.nextStep
385
+ updatedModel
386
+ Nothing
387
+ |> nextStepToEffect execute updatedModel
388
+
389
+
390
+ nextStepToEffect :
391
+ DataSource ()
392
+ -> Model
393
+ -> ( StaticResponses, StaticResponses.NextStep route )
394
+ -> ( Model, Effect )
395
+ nextStepToEffect execute model ( updatedStaticResponsesModel, nextStep ) =
396
+ case nextStep of
397
+ StaticResponses.Continue updatedAllRawResponses httpRequests _ ->
398
+ let
399
+ updatedModel : Model
400
+ updatedModel =
401
+ { model
402
+ | allRawResponses = updatedAllRawResponses
403
+ , staticResponses = updatedStaticResponsesModel
404
+ }
405
+ in
406
+ if List.isEmpty httpRequests then
407
+ nextStepToEffect execute
408
+ updatedModel
409
+ (StaticResponses.nextStep
410
+ updatedModel
411
+ Nothing
412
+ )
413
+
414
+ else
415
+ ( updatedModel
416
+ , (httpRequests
417
+ |> List.map Effect.FetchHttp
418
+ )
419
+ |> Effect.Batch
420
+ )
421
+
422
+ StaticResponses.Finish toJsPayload ->
423
+ case toJsPayload of
424
+ StaticResponses.ApiResponse ->
425
+ let
426
+ apiResponse : Effect
427
+ apiResponse =
428
+ StaticHttpRequest.resolve
429
+ execute
430
+ model.allRawResponses
431
+ |> Result.mapError (StaticHttpRequest.toBuildError "TODO - path from request")
432
+ |> (\response ->
433
+ case response of
434
+ Ok () ->
435
+ { body = Json.Encode.null
436
+ , staticHttpCache = Dict.empty
437
+ , statusCode = 200
438
+ }
439
+ |> ToJsPayload.SendApiResponse
440
+ |> Effect.SendSinglePage
441
+
442
+ Err error ->
443
+ [ error ]
444
+ |> ToJsPayload.Errors
445
+ |> Effect.SendSinglePage
446
+ )
447
+ in
448
+ ( model
449
+ , apiResponse
450
+ )
451
+
452
+ StaticResponses.Errors errors ->
453
+ ( model
454
+ , errors |> ToJsPayload.Errors |> Effect.SendSinglePage
455
+ )