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

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 (81) hide show
  1. package/README.md +1 -1
  2. package/codegen/elm-pages-codegen.js +66 -118
  3. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateData.elmo +0 -0
  4. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateDataTest.elmo +0 -0
  5. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
  6. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Runner.elm.js +20 -20
  7. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
  8. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_supervisor.js +1 -1
  9. package/generator/dead-code-review/src/Pages/Review/DeadCodeEliminateData.elm +5 -5
  10. package/generator/dead-code-review/tests/Pages/Review/DeadCodeEliminateDataTest.elm +21 -21
  11. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
  12. package/generator/review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
  13. package/generator/review/elm-stuff/tests-0.19.1/js/node_supervisor.js +1 -1
  14. package/generator/src/RouteBuilder.elm +23 -23
  15. package/generator/src/SharedTemplate.elm +2 -2
  16. package/generator/src/SiteConfig.elm +2 -2
  17. package/generator/src/cli.js +2 -2
  18. package/generator/src/compatibility-key.js +1 -1
  19. package/generator/src/error-formatter.js +7 -3
  20. package/generator/src/render.js +6 -15
  21. package/generator/src/request-cache.js +34 -4
  22. package/generator/static-code/hmr.js +16 -2
  23. package/package.json +1 -1
  24. package/src/ApiRoute.elm +13 -16
  25. package/src/BackendTask/Env.elm +11 -8
  26. package/src/BackendTask/File.elm +49 -10
  27. package/src/BackendTask/Glob.elm +6 -6
  28. package/src/BackendTask/Http.elm +49 -13
  29. package/src/BackendTask/Port.elm +59 -47
  30. package/src/BackendTask.elm +8 -22
  31. package/src/FatalError.elm +101 -0
  32. package/src/Form.elm +3 -2
  33. package/src/Internal/ApiRoute.elm +5 -5
  34. package/src/Pages/Generate.elm +300 -103
  35. package/src/Pages/Internal/FatalError.elm +5 -0
  36. package/src/Pages/Internal/Platform/Cli.elm +21 -41
  37. package/src/Pages/Internal/Platform/CompatibilityKey.elm +1 -1
  38. package/src/Pages/Internal/Platform/GeneratorApplication.elm +24 -48
  39. package/src/Pages/Internal/Platform/StaticResponses.elm +18 -31
  40. package/src/Pages/Internal/Script.elm +2 -2
  41. package/src/Pages/Manifest.elm +2 -2
  42. package/src/Pages/ProgramConfig.elm +7 -7
  43. package/src/Pages/Script.elm +4 -4
  44. package/src/Pages/SiteConfig.elm +2 -2
  45. package/src/Pages/StaticHttpRequest.elm +1 -23
  46. package/src/Server/Request.elm +3 -2
  47. package/src/Exception.elm +0 -37
  48. package/src/MultiDict.elm +0 -49
  49. package/src/PairingHeap.elm +0 -137
  50. package/src/Parser/Extra/String.elm +0 -33
  51. package/src/Parser/Extra.elm +0 -69
  52. package/src/ProgramTest/ComplexQuery.elm +0 -360
  53. package/src/ProgramTest/EffectSimulation.elm +0 -122
  54. package/src/ProgramTest/Failure.elm +0 -367
  55. package/src/ProgramTest/HtmlHighlighter.elm +0 -116
  56. package/src/ProgramTest/HtmlParserHacks.elm +0 -58
  57. package/src/ProgramTest/HtmlRenderer.elm +0 -73
  58. package/src/ProgramTest/Program.elm +0 -30
  59. package/src/ProgramTest/StringLines.elm +0 -26
  60. package/src/ProgramTest/TestHtmlHacks.elm +0 -132
  61. package/src/ProgramTest/TestHtmlParser.elm +0 -201
  62. package/src/ProgramTest.elm +0 -2339
  63. package/src/Query/Extra.elm +0 -55
  64. package/src/SimulatedEffect/Cmd.elm +0 -69
  65. package/src/SimulatedEffect/Http.elm +0 -330
  66. package/src/SimulatedEffect/Navigation.elm +0 -69
  67. package/src/SimulatedEffect/Ports.elm +0 -62
  68. package/src/SimulatedEffect/Process.elm +0 -24
  69. package/src/SimulatedEffect/Sub.elm +0 -48
  70. package/src/SimulatedEffect/Task.elm +0 -252
  71. package/src/SimulatedEffect/Time.elm +0 -25
  72. package/src/SimulatedEffect.elm +0 -42
  73. package/src/String/Extra.elm +0 -6
  74. package/src/Test/Http.elm +0 -145
  75. package/src/TestResult.elm +0 -35
  76. package/src/TestState.elm +0 -305
  77. package/src/Url/Extra.elm +0 -100
  78. package/src/Vendored/Diff.elm +0 -321
  79. package/src/Vendored/Failure.elm +0 -217
  80. package/src/Vendored/FormatMonochrome.elm +0 -44
  81. package/src/Vendored/Highlightable.elm +0 -53
package/src/ApiRoute.elm CHANGED
@@ -173,7 +173,7 @@ You define your ApiRoute's in `app/Api.elm`. Here's a simple example:
173
173
  -}
174
174
 
175
175
  import BackendTask exposing (BackendTask)
176
- import Exception exposing (Throwable)
176
+ import FatalError exposing (FatalError)
177
177
  import Head
178
178
  import Internal.ApiRoute exposing (ApiRoute(..), ApiRouteBuilder(..))
179
179
  import Json.Decode as Decode
@@ -192,14 +192,14 @@ type alias ApiRoute response =
192
192
  {-| Same as [`preRender`](#preRender), but for an ApiRoute that has no dynamic segments. This is just a bit simpler because
193
193
  since there are no dynamic segments, you don't need to provide a BackendTask with the list of dynamic segments to pre-render because there is only a single possible route.
194
194
  -}
195
- single : ApiRouteBuilder (BackendTask Throwable String) (List String) -> ApiRoute Response
195
+ single : ApiRouteBuilder (BackendTask FatalError String) (List String) -> ApiRoute Response
196
196
  single handler =
197
197
  handler
198
198
  |> preRender (\constructor -> BackendTask.succeed [ constructor ])
199
199
 
200
200
 
201
201
  {-| -}
202
- serverRender : ApiRouteBuilder (Server.Request.Parser (BackendTask Never (Server.Response.Response Never Never))) constructor -> ApiRoute Response
202
+ serverRender : ApiRouteBuilder (Server.Request.Parser (BackendTask FatalError (Server.Response.Response Never Never))) constructor -> ApiRoute Response
203
203
  serverRender ((ApiRouteBuilder patterns pattern _ _ _) as fullHandler) =
204
204
  ApiRoute
205
205
  { regex = Regex.fromString ("^" ++ pattern ++ "$") |> Maybe.withDefault Regex.never
@@ -218,14 +218,13 @@ serverRender ((ApiRouteBuilder patterns pattern _ _ _) as fullHandler) =
218
218
  |> BackendTask.onError
219
219
  (\stringError ->
220
220
  -- TODO make error with title and better context/formatting
221
- Exception.fromString stringError |> BackendTask.fail
221
+ FatalError.fromString stringError |> BackendTask.fail
222
222
  )
223
223
  |> BackendTask.andThen
224
224
  (\rendered ->
225
225
  case rendered of
226
226
  Just (Ok okRendered) ->
227
227
  okRendered
228
- |> BackendTask.onError never
229
228
 
230
229
  Just (Err errors) ->
231
230
  errors
@@ -233,13 +232,11 @@ serverRender ((ApiRouteBuilder patterns pattern _ _ _) as fullHandler) =
233
232
  |> Server.Response.plainText
234
233
  |> Server.Response.withStatusCode 400
235
234
  |> BackendTask.succeed
236
- |> BackendTask.onError never
237
235
 
238
236
  Nothing ->
239
237
  Server.Response.plainText "No matching request handler"
240
238
  |> Server.Response.withStatusCode 400
241
239
  |> BackendTask.succeed
242
- |> BackendTask.onError never
243
240
  )
244
241
  )
245
242
  |> Maybe.map (BackendTask.map (Server.Response.toJson >> Just))
@@ -263,10 +260,10 @@ serverRender ((ApiRouteBuilder patterns pattern _ _ _) as fullHandler) =
263
260
 
264
261
 
265
262
  {-| -}
266
- preRenderWithFallback : (constructor -> BackendTask Throwable (List (List String))) -> ApiRouteBuilder (BackendTask Throwable (Server.Response.Response Never Never)) constructor -> ApiRoute Response
263
+ preRenderWithFallback : (constructor -> BackendTask FatalError (List (List String))) -> ApiRouteBuilder (BackendTask FatalError (Server.Response.Response Never Never)) constructor -> ApiRoute Response
267
264
  preRenderWithFallback buildUrls ((ApiRouteBuilder patterns pattern _ toString constructor) as fullHandler) =
268
265
  let
269
- buildTimeRoutes__ : BackendTask Throwable (List String)
266
+ buildTimeRoutes__ : BackendTask FatalError (List String)
270
267
  buildTimeRoutes__ =
271
268
  buildUrls (constructor [])
272
269
  |> BackendTask.map (List.map toString)
@@ -305,15 +302,15 @@ encodeStaticFileBody fileBody =
305
302
 
306
303
 
307
304
  {-| -}
308
- preRender : (constructor -> BackendTask Throwable (List (List String))) -> ApiRouteBuilder (BackendTask Throwable String) constructor -> ApiRoute Response
305
+ preRender : (constructor -> BackendTask FatalError (List (List String))) -> ApiRouteBuilder (BackendTask FatalError String) constructor -> ApiRoute Response
309
306
  preRender buildUrls ((ApiRouteBuilder patterns pattern _ toString constructor) as fullHandler) =
310
307
  let
311
- buildTimeRoutes__ : BackendTask Throwable (List String)
308
+ buildTimeRoutes__ : BackendTask FatalError (List String)
312
309
  buildTimeRoutes__ =
313
310
  buildUrls (constructor [])
314
311
  |> BackendTask.map (List.map toString)
315
312
 
316
- preBuiltMatches : BackendTask Throwable (List (List String))
313
+ preBuiltMatches : BackendTask FatalError (List (List String))
317
314
  preBuiltMatches =
318
315
  buildUrls (constructor [])
319
316
  in
@@ -326,7 +323,7 @@ preRender buildUrls ((ApiRouteBuilder patterns pattern _ toString constructor) a
326
323
  matches =
327
324
  Internal.ApiRoute.pathToMatches path fullHandler
328
325
 
329
- routeFound : BackendTask Throwable Bool
326
+ routeFound : BackendTask FatalError Bool
330
327
  routeFound =
331
328
  preBuiltMatches
332
329
  |> BackendTask.map (List.member matches)
@@ -434,19 +431,19 @@ capture (ApiRouteBuilder patterns pattern previousHandler toString constructor)
434
431
 
435
432
  {-| For internal use by generated code. Not so useful in user-land.
436
433
  -}
437
- getBuildTimeRoutes : ApiRoute response -> BackendTask Throwable (List String)
434
+ getBuildTimeRoutes : ApiRoute response -> BackendTask FatalError (List String)
438
435
  getBuildTimeRoutes (ApiRoute handler) =
439
436
  handler.buildTimeRoutes
440
437
 
441
438
 
442
439
  {-| Include head tags on every page's HTML.
443
440
  -}
444
- withGlobalHeadTags : BackendTask Throwable (List Head.Tag) -> ApiRoute response -> ApiRoute response
441
+ withGlobalHeadTags : BackendTask FatalError (List Head.Tag) -> ApiRoute response -> ApiRoute response
445
442
  withGlobalHeadTags globalHeadTags (ApiRoute handler) =
446
443
  ApiRoute { handler | globalHeadTags = Just globalHeadTags }
447
444
 
448
445
 
449
446
  {-| -}
450
- getGlobalHeadTagsBackendTask : ApiRoute response -> Maybe (BackendTask Throwable (List Head.Tag))
447
+ getGlobalHeadTagsBackendTask : ApiRoute response -> Maybe (BackendTask FatalError (List Head.Tag))
451
448
  getGlobalHeadTagsBackendTask (ApiRoute handler) =
452
449
  handler.globalHeadTags
@@ -8,22 +8,23 @@ down into the final `Data` value, it won't end up in the client!
8
8
 
9
9
  import BackendTask exposing (BackendTask)
10
10
  import BackendTask.Env
11
+ import FatalError exposing (FatalError)
11
12
 
12
13
  type alias EnvVariables =
13
14
  { sendGridKey : String
14
15
  , siteUrl : String
15
16
  }
16
17
 
17
- sendEmail : Email -> BackendTask ()
18
+ sendEmail : Email -> BackendTask FatalError ()
18
19
  sendEmail email =
19
20
  BackendTask.map2 EnvVariables
20
- (BackendTask.Env.expect "SEND_GRID_KEY")
21
+ (BackendTask.Env.expect "SEND_GRID_KEY" |> BackendTask.allowFatal)
21
22
  (BackendTask.Env.get "BASE_URL"
22
23
  |> BackendTask.map (Maybe.withDefault "http://localhost:1234")
23
24
  )
24
25
  |> BackendTask.andThen (sendEmailBackendTask email)
25
26
 
26
- sendEmailBackendTask : Email -> EnvVariables -> BackendTask ()
27
+ sendEmailBackendTask : Email -> EnvVariables -> BackendTask FatalError ()
27
28
  sendEmailBackendTask email envVariables =
28
29
  Debug.todo "Not defined here"
29
30
 
@@ -39,7 +40,7 @@ down into the final `Data` value, it won't end up in the client!
39
40
  import BackendTask exposing (BackendTask)
40
41
  import BackendTask.Http
41
42
  import BackendTask.Internal.Request
42
- import Exception exposing (Catchable)
43
+ import FatalError exposing (FatalError)
43
44
  import Json.Decode as Decode
44
45
  import Json.Encode as Encode
45
46
  import TerminalText
@@ -50,7 +51,8 @@ type Error
50
51
  = MissingEnvVariable String
51
52
 
52
53
 
53
- {-| Get an environment variable, or Nothing if there is no environment variable matching that name.
54
+ {-| Get an environment variable, or Nothing if there is no environment variable matching that name. This `BackendTask`
55
+ will never fail, but instead will return `Nothing` if the environment variable is missing.
54
56
  -}
55
57
  get : String -> BackendTask error (Maybe String)
56
58
  get envVariableName =
@@ -63,9 +65,9 @@ get envVariableName =
63
65
  }
64
66
 
65
67
 
66
- {-| Get an environment variable, or a BackendTask failure if there is no environment variable matching that name.
68
+ {-| Get an environment variable, or a BackendTask FatalError if there is no environment variable matching that name.
67
69
  -}
68
- expect : String -> BackendTask (Catchable Error) String
70
+ expect : String -> BackendTask { fatal : FatalError, recoverable : Error } String
69
71
  expect envVariableName =
70
72
  envVariableName
71
73
  |> get
@@ -73,7 +75,7 @@ expect envVariableName =
73
75
  (\maybeValue ->
74
76
  maybeValue
75
77
  |> Result.fromMaybe
76
- (Exception.Catchable (MissingEnvVariable envVariableName)
78
+ (FatalError.recoverable
77
79
  { title = "Missing Env Variable"
78
80
  , body =
79
81
  [ TerminalText.text "BackendTask.Env.expect was expecting a variable `"
@@ -82,6 +84,7 @@ expect envVariableName =
82
84
  ]
83
85
  |> TerminalText.toString
84
86
  }
87
+ (MissingEnvVariable envVariableName)
85
88
  )
86
89
  |> BackendTask.fromResult
87
90
  )
@@ -51,7 +51,7 @@ plain old JSON in Elm.
51
51
  import BackendTask exposing (BackendTask)
52
52
  import BackendTask.Http
53
53
  import BackendTask.Internal.Request
54
- import Exception exposing (Catchable)
54
+ import FatalError exposing (FatalError)
55
55
  import Json.Decode as Decode exposing (Decoder)
56
56
  import TerminalText
57
57
 
@@ -141,7 +141,15 @@ It's common to parse the body with a markdown parser or other format.
141
141
  )
142
142
 
143
143
  -}
144
- bodyWithFrontmatter : (String -> Decoder frontmatter) -> String -> BackendTask (Catchable (FileReadError Decode.Error)) frontmatter
144
+ bodyWithFrontmatter :
145
+ (String -> Decoder frontmatter)
146
+ -> String
147
+ ->
148
+ BackendTask
149
+ { fatal : FatalError
150
+ , recoverable : FileReadError Decode.Error
151
+ }
152
+ frontmatter
145
153
  bodyWithFrontmatter frontmatterDecoder filePath =
146
154
  read filePath
147
155
  (body
@@ -213,7 +221,15 @@ the [`BackendTask`](BackendTask) API along with [`BackendTask.Glob`](BackendTask
213
221
  |> BackendTask.resolve
214
222
 
215
223
  -}
216
- onlyFrontmatter : Decoder frontmatter -> String -> BackendTask (Catchable (FileReadError Decode.Error)) frontmatter
224
+ onlyFrontmatter :
225
+ Decoder frontmatter
226
+ -> String
227
+ ->
228
+ BackendTask
229
+ { fatal : FatalError
230
+ , recoverable : FileReadError Decode.Error
231
+ }
232
+ frontmatter
217
233
  onlyFrontmatter frontmatterDecoder filePath =
218
234
  read filePath
219
235
  (frontmatter frontmatterDecoder)
@@ -240,7 +256,14 @@ Hey there! This is my first post :)
240
256
  Then data will yield the value `"Hey there! This is my first post :)"`.
241
257
 
242
258
  -}
243
- bodyWithoutFrontmatter : String -> BackendTask (Catchable (FileReadError decoderError)) String
259
+ bodyWithoutFrontmatter :
260
+ String
261
+ ->
262
+ BackendTask
263
+ { fatal : FatalError
264
+ , recoverable : FileReadError decoderError
265
+ }
266
+ String
244
267
  bodyWithoutFrontmatter filePath =
245
268
  read filePath
246
269
  body
@@ -264,7 +287,7 @@ You could read a file called `hello.txt` in your root project directory like thi
264
287
  File.rawFile "hello.txt"
265
288
 
266
289
  -}
267
- rawFile : String -> BackendTask (Catchable (FileReadError decoderError)) String
290
+ rawFile : String -> BackendTask { fatal : FatalError, recoverable : FileReadError decoderError } String
268
291
  rawFile filePath =
269
292
  read filePath (Decode.field "rawFile" Decode.string)
270
293
 
@@ -286,7 +309,15 @@ The Decode will strip off any unused JSON data.
286
309
  "elm.json"
287
310
 
288
311
  -}
289
- jsonFile : Decoder a -> String -> BackendTask (Catchable (FileReadError Decode.Error)) a
312
+ jsonFile :
313
+ Decoder a
314
+ -> String
315
+ ->
316
+ BackendTask
317
+ { fatal : FatalError
318
+ , recoverable : FileReadError Decode.Error
319
+ }
320
+ a
290
321
  jsonFile jsonFileDecoder filePath =
291
322
  rawFile filePath
292
323
  |> BackendTask.andThen
@@ -295,13 +326,14 @@ jsonFile jsonFileDecoder filePath =
295
326
  |> Decode.decodeString jsonFileDecoder
296
327
  |> Result.mapError
297
328
  (\jsonDecodeError ->
298
- Exception.Catchable (DecodingError jsonDecodeError)
329
+ FatalError.recoverable
299
330
  { title = "JSON Decoding Error"
300
331
  , body =
301
332
  [ TerminalText.text (Decode.errorToString jsonDecodeError)
302
333
  ]
303
334
  |> TerminalText.toString
304
335
  }
336
+ (DecodingError jsonDecodeError)
305
337
  )
306
338
  |> BackendTask.fromResult
307
339
  )
@@ -314,7 +346,7 @@ body =
314
346
  Decode.field "withoutFrontmatter" Decode.string
315
347
 
316
348
 
317
- read : String -> Decoder a -> BackendTask (Catchable (FileReadError error)) a
349
+ read : String -> Decoder a -> BackendTask { fatal : FatalError, recoverable : FileReadError error } a
318
350
  read filePath decoder =
319
351
  BackendTask.Internal.Request.request
320
352
  { name = "read-file"
@@ -330,10 +362,16 @@ read filePath decoder =
330
362
  |> BackendTask.andThen BackendTask.fromResult
331
363
 
332
364
 
333
- errorDecoder : String -> Decoder (Catchable (FileReadError decoding))
365
+ errorDecoder :
366
+ String
367
+ ->
368
+ Decoder
369
+ { fatal : FatalError.FatalError
370
+ , recoverable : FileReadError decoding
371
+ }
334
372
  errorDecoder filePath =
335
373
  Decode.succeed
336
- (Exception.Catchable FileDoesntExist
374
+ (FatalError.recoverable
337
375
  { title = "File Doesn't Exist"
338
376
  , body =
339
377
  [ TerminalText.text "Couldn't find file at path `"
@@ -342,4 +380,5 @@ errorDecoder filePath =
342
380
  ]
343
381
  |> TerminalText.toString
344
382
  }
383
+ FileDoesntExist
345
384
  )
@@ -229,7 +229,7 @@ import BackendTask exposing (BackendTask)
229
229
  import BackendTask.Http
230
230
  import BackendTask.Internal.Glob exposing (Glob(..))
231
231
  import BackendTask.Internal.Request
232
- import Exception exposing (Catchable, Throwable)
232
+ import FatalError exposing (FatalError, Recoverable)
233
233
  import Json.Decode as Decode
234
234
  import Json.Encode as Encode
235
235
  import List.Extra
@@ -1054,7 +1054,7 @@ so it's ideal to make this kind of assertion rather than having fallback behavio
1054
1054
  issues (like if we had instead ignored the case where there are two or more matching blog post files).
1055
1055
 
1056
1056
  -}
1057
- expectUniqueMatch : Glob a -> BackendTask (Catchable String) a
1057
+ expectUniqueMatch : Glob a -> BackendTask (Recoverable String) a
1058
1058
  expectUniqueMatch glob =
1059
1059
  glob
1060
1060
  |> toBackendTask
@@ -1066,14 +1066,14 @@ expectUniqueMatch glob =
1066
1066
 
1067
1067
  [] ->
1068
1068
  BackendTask.fail <|
1069
- Exception.fromStringWithValue
1070
- ("No files matched the pattern: " ++ toPatternString glob)
1069
+ FatalError.recoverable
1070
+ { title = "Non-Unique Glob", body = "No files matched the pattern: " ++ toPatternString glob }
1071
1071
  ("No files matched the pattern: " ++ toPatternString glob)
1072
1072
 
1073
1073
  _ ->
1074
1074
  BackendTask.fail <|
1075
- Exception.fromStringWithValue
1076
- "More than one file matched."
1075
+ FatalError.recoverable
1076
+ { title = "Non-Unique Glob", body = "Expected a unique match, but more than one file matched." }
1077
1077
  "More than one file matched."
1078
1078
  )
1079
1079
 
@@ -71,7 +71,22 @@ and describe your use case!
71
71
 
72
72
  ## Caching Options
73
73
 
74
- `elm-pages` performs GET requests using a local HTTP cache by default.
74
+ `elm-pages` performs GET requests using a local HTTP cache by default. These requests are not performed using Elm's `elm/http`,
75
+ but rather are performed in NodeJS. Under the hood it uses [the NPM package `make-fetch-happen`](https://github.com/npm/make-fetch-happen).
76
+ Only GET requests made with `get`, `getJson`, or `getWithOptions` use local caching. Requests made with [`BackendTask.Http.request`](#request)
77
+ are not cached, even if the method is set to `GET`.
78
+
79
+ In dev mode, assets are cached more aggressively by default, whereas for a production build assets use a default to revalidate each cached response's freshness before using it (the `ForceRevalidate` [`CacheStrategy`](#CacheStrategy)).
80
+
81
+ The default caching behavior for GET requests is to use a local cache in `.elm-pages/http-cache`. This uses the same caching behavior
82
+ that browsers use to avoid re-downloading content when it hasn't changed. Servers can set HTTP response headers to explicitly control
83
+ this caching behavior.
84
+
85
+ - [`cache-control` HTTP response headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control) let you set a length of time before considering an asset stale. This could mean that the server considers it acceptable for an asset to be somewhat outdated, or this could mean that the asset is guaranteed to be up-to-date until it is stale - those semantics are up to the server.
86
+ - `Last-Modified` and `ETag` HTTP response headers can be returned by the server allow [Conditional Requests](https://developer.mozilla.org/en-US/docs/Web/HTTP/Conditional_requests). Conditional Requests let us send back the `Last-Modified` timestamp or `etag` hash for assets that are in our local cache to the server to check if the asset is fresh, and skip re-downloading it if it is unchanged (or download a fresh one otherwise).
87
+
88
+ It's important to note that depending on how the server sets these HTTP response headers, we may have outdated data - either because the server explicitly allows assets to become outdated with their cache-control headers, OR because cache-control headers are not set. When these headers aren't explicitly set, [clients are allowed to cache assets for 10% of the amount of time since it was last modified](https://httpwg.org/specs/rfc7234.html#heuristic.freshness).
89
+ For production builds, the default caching will ignore both the implicit and explicit information about an asset's freshness and _always_ revalidate it before using a locally cached response.
75
90
 
76
91
  @docs getWithOptions
77
92
 
@@ -89,7 +104,7 @@ import Base64
89
104
  import Bytes exposing (Bytes)
90
105
  import Bytes.Decode
91
106
  import Dict exposing (Dict)
92
- import Exception exposing (Catchable)
107
+ import FatalError exposing (FatalError, Recoverable)
93
108
  import Json.Decode
94
109
  import Json.Encode as Encode
95
110
  import Pages.Internal.StaticHttpBody as Body
@@ -138,15 +153,16 @@ type alias Body =
138
153
  Body.Body
139
154
 
140
155
 
141
- {-| A simplified helper around [`BackendTask.Http.request`](#request), which builds up a BackendTask.Http GET request.
156
+ {-| A simplified helper around [`BackendTask.Http.get`](#get), which builds up a BackendTask.Http GET request with `expectJson`.
142
157
 
143
158
  import BackendTask
144
159
  import BackendTask.Http
160
+ import FatalError exposing (FatalError)
145
161
  import Json.Decode as Decode exposing (Decoder)
146
162
 
147
- getRequest : BackendTask Int
163
+ getRequest : BackendTask (FatalError Error) Int
148
164
  getRequest =
149
- BackendTask.Http.get
165
+ BackendTask.Http.getJson
150
166
  "https://api.github.com/repos/dillonkearns/elm-pages"
151
167
  (Decode.field "stargazers_count" Decode.int)
152
168
 
@@ -154,7 +170,7 @@ type alias Body =
154
170
  getJson :
155
171
  String
156
172
  -> Json.Decode.Decoder a
157
- -> BackendTask (Catchable Error) a
173
+ -> BackendTask (Recoverable Error) a
158
174
  getJson url decoder =
159
175
  getWithOptions
160
176
  { url = url
@@ -167,11 +183,25 @@ getJson url decoder =
167
183
  }
168
184
 
169
185
 
170
- {-| -}
186
+ {-| A simplified helper around [`BackendTask.Http.getWithOptions`](#getWithOptions), which builds up a GET request with
187
+ the default retries, timeout, and HTTP caching options. If you need to configure those options or include HTTP request headers,
188
+ use the more flexible `getWithOptions`.
189
+
190
+ import BackendTask
191
+ import BackendTask.Http
192
+ import FatalError exposing (FatalError)
193
+
194
+ getRequest : BackendTask (FatalError Error) String
195
+ getRequest =
196
+ BackendTask.Http.get
197
+ "https://api.github.com/repos/dillonkearns/elm-pages"
198
+ BackendTask.Http.expectString
199
+
200
+ -}
171
201
  get :
172
202
  String
173
203
  -> Expect a
174
- -> BackendTask (Catchable Error) a
204
+ -> BackendTask { fatal : FatalError, recoverable : Error } a
175
205
  get url expect =
176
206
  getWithOptions
177
207
  { url = url
@@ -185,6 +215,12 @@ get url expect =
185
215
 
186
216
 
187
217
  {-| Perform a GET request, with some additional options for the HTTP request, including options for caching behavior.
218
+
219
+ - `retries` - Default is 0. Will try performing request again if set to a number greater than 0.
220
+ - `timeoutInMs` - Default is no timeout.
221
+ - `cacheStrategy` - The [caching options are passed to the NPM package `make-fetch-happen`](https://github.com/npm/make-fetch-happen#opts-cache)
222
+ - `cachePath` - override the default directory for the local HTTP cache. This can be helpful if you want more granular control to clear some HTTP caches more or less frequently than others. Or you may want to preserve the local cache for some requests in your build server, but not store the cache for other requests.
223
+
188
224
  -}
189
225
  getWithOptions :
190
226
  { url : String
@@ -195,7 +231,7 @@ getWithOptions :
195
231
  , timeoutInMs : Maybe Int
196
232
  , cachePath : Maybe String
197
233
  }
198
- -> BackendTask (Catchable Error) a
234
+ -> BackendTask (Recoverable Error) a
199
235
  getWithOptions request__ =
200
236
  let
201
237
  request_ : HashRequest.Request
@@ -222,7 +258,7 @@ post :
222
258
  String
223
259
  -> Body
224
260
  -> Expect a
225
- -> BackendTask (Catchable Error) a
261
+ -> BackendTask (Recoverable Error) a
226
262
  post url body expect =
227
263
  request
228
264
  { url = url
@@ -361,7 +397,7 @@ request :
361
397
  , timeoutInMs : Maybe Int
362
398
  }
363
399
  -> Expect a
364
- -> BackendTask (Catchable Error) a
400
+ -> BackendTask (Recoverable Error) a
365
401
  request request__ expect =
366
402
  let
367
403
  request_ : HashRequest.Request
@@ -439,7 +475,7 @@ with this as a low-level detail, or you can use functions like [BackendTask.Http
439
475
  requestRaw :
440
476
  HashRequest.Request
441
477
  -> Expect a
442
- -> BackendTask (Catchable Error) a
478
+ -> BackendTask (Recoverable Error) a
443
479
  requestRaw request__ expect =
444
480
  let
445
481
  request_ : HashRequest.Request
@@ -537,7 +573,7 @@ requestRaw request__ expect =
537
573
  |> BackendTask.fromResult
538
574
  |> BackendTask.mapError
539
575
  (\error ->
540
- Exception.Catchable error (errorToString error)
576
+ FatalError.recoverable (errorToString error) error
541
577
  )
542
578
  )
543
579