elm-pages 3.0.0-beta.40 → 3.0.0-beta.41

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 (37) hide show
  1. package/README.md +1 -1
  2. package/codegen/elm-pages-codegen.cjs +204 -262
  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/js/node_runner.js +1 -1
  5. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_supervisor.js +1 -1
  6. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
  7. package/generator/review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
  8. package/generator/review/elm-stuff/tests-0.19.1/js/node_supervisor.js +1 -1
  9. package/generator/src/RouteBuilder.elm +9 -8
  10. package/generator/src/SharedTemplate.elm +5 -5
  11. package/generator/src/compatibility-key.js +2 -2
  12. package/package.json +1 -1
  13. package/src/BackendTask.elm +18 -24
  14. package/src/Head/Seo.elm +4 -4
  15. package/src/Pages/ConcurrentSubmission.elm +127 -0
  16. package/src/Pages/Form.elm +151 -40
  17. package/src/Pages/FormData.elm +18 -0
  18. package/src/Pages/Internal/NotFoundReason.elm +4 -4
  19. package/src/Pages/Internal/Platform/Cli.elm +15 -15
  20. package/src/Pages/Internal/Platform/CompatibilityKey.elm +1 -1
  21. package/src/Pages/Internal/Platform.elm +39 -38
  22. package/src/Pages/Internal/ResponseSketch.elm +2 -2
  23. package/src/Pages/Manifest.elm +23 -7
  24. package/src/Pages/Navigation.elm +87 -0
  25. package/src/Pages/PageUrl.elm +3 -3
  26. package/src/Pages/ProgramConfig.elm +10 -9
  27. package/src/Pages/Script.elm +64 -7
  28. package/src/Pages/Url.elm +3 -3
  29. package/src/PagesMsg.elm +9 -3
  30. package/src/RenderRequest.elm +7 -7
  31. package/src/Scaffold/Form.elm +28 -5
  32. package/src/Scaffold/Route.elm +12 -3
  33. package/src/Server/Request.elm +2 -1
  34. package/src/Server/Session.elm +1 -1
  35. package/src/Server/SetCookie.elm +71 -31
  36. package/src/{Path.elm → UrlPath.elm} +21 -21
  37. package/src/Pages/Transition.elm +0 -79
@@ -75,7 +75,7 @@ console.elmlog = (str) => logs.push(str + "\n");
75
75
  const { Elm } = require("./Runner.elm.js");
76
76
 
77
77
  // Start the Elm app
78
- const flags = { initialSeed: 2220181744, fuzzRuns: 100, filter: null };
78
+ const flags = { initialSeed: 386019384, fuzzRuns: 100, filter: null };
79
79
  const app = Elm.Runner.init({ flags: flags });
80
80
 
81
81
  // Record the timing at which we received the last "runTest" message
@@ -82,7 +82,7 @@ const verbosity = 0;
82
82
  // Create a long lived reporter worker
83
83
  const { Elm } = require("./Reporter.elm.js");
84
84
  const flags = {
85
- initialSeed: 2220181744,
85
+ initialSeed: 386019384,
86
86
  fuzzRuns: 100,
87
87
  mode: "consoleColor",
88
88
  verbosity: verbosity,
@@ -75,7 +75,7 @@ console.elmlog = (str) => logs.push(str + "\n");
75
75
  const { Elm } = require("./Runner.elm.js");
76
76
 
77
77
  // Start the Elm app
78
- const flags = { initialSeed: 1451258136, fuzzRuns: 100, filter: null };
78
+ const flags = { initialSeed: 4127127384, fuzzRuns: 100, filter: null };
79
79
  const app = Elm.Runner.init({ flags: flags });
80
80
 
81
81
  // Record the timing at which we received the last "runTest" message
@@ -82,7 +82,7 @@ const verbosity = 0;
82
82
  // Create a long lived reporter worker
83
83
  const { Elm } = require("./Reporter.elm.js");
84
84
  const flags = {
85
- initialSeed: 1451258136,
85
+ initialSeed: 4127127384,
86
86
  fuzzRuns: 100,
87
87
  mode: "consoleColor",
88
88
  verbosity: verbosity,
@@ -94,13 +94,14 @@ import Form
94
94
  import Head
95
95
  import Http
96
96
  import Json.Decode
97
+ import Pages.ConcurrentSubmission
97
98
  import Pages.Fetcher
98
99
  import Pages.Internal.NotFoundReason exposing (NotFoundReason)
99
100
  import Pages.Internal.RoutePattern exposing (RoutePattern)
100
101
  import Pages.PageUrl exposing (PageUrl)
101
- import Pages.Transition
102
+ import Pages.Navigation
102
103
  import PagesMsg exposing (PagesMsg)
103
- import Path exposing (Path)
104
+ import UrlPath exposing (UrlPath)
104
105
  import Server.Request
105
106
  import Server.Response
106
107
  import Shared
@@ -122,7 +123,7 @@ type alias StatefulRoute routeParams data action model msg =
122
123
  -> List Head.Tag
123
124
  , init : Shared.Model -> App data action routeParams -> ( model, Effect msg )
124
125
  , update : App data action routeParams -> msg -> model -> Shared.Model -> ( model, Effect msg, Maybe Shared.Msg )
125
- , subscriptions : routeParams -> Path -> model -> Shared.Model -> Sub msg
126
+ , subscriptions : routeParams -> UrlPath -> model -> Shared.Model -> Sub msg
126
127
  , handleRoute : { moduleName : List String, routePattern : RoutePattern } -> (routeParams -> List ( String, String )) -> routeParams -> BackendTask FatalError (Maybe NotFoundReason)
127
128
  , kind : String
128
129
  , onAction : Maybe (action -> msg)
@@ -139,14 +140,14 @@ type alias App data action routeParams =
139
140
  { data : data
140
141
  , sharedData : Shared.Data
141
142
  , routeParams : routeParams
142
- , path : Path
143
+ , path : UrlPath
143
144
  , url : Maybe PageUrl
144
145
  , action : Maybe action
145
146
  , submit :
146
147
  { fields : List ( String, String ), headers : List ( String, String ) }
147
148
  -> Pages.Fetcher.Fetcher (Result Http.Error action)
148
- , transition : Maybe Pages.Transition.Transition
149
- , fetchers : Dict String (Pages.Transition.FetcherState (Maybe action))
149
+ , navigation : Maybe Pages.Navigation.Navigation
150
+ , concurrentSubmissions : Dict String (Pages.ConcurrentSubmission.ConcurrentSubmission (Maybe action))
150
151
  , pageFormState : Form.Model
151
152
  }
152
153
 
@@ -213,7 +214,7 @@ buildWithLocalState :
213
214
  -> View (PagesMsg msg)
214
215
  , init : App data action routeParams -> Shared.Model -> ( model, Effect msg )
215
216
  , update : App data action routeParams -> Shared.Model -> msg -> model -> ( model, Effect msg )
216
- , subscriptions : routeParams -> Path -> Shared.Model -> model -> Sub msg
217
+ , subscriptions : routeParams -> UrlPath -> Shared.Model -> model -> Sub msg
217
218
  }
218
219
  -> Builder routeParams data action
219
220
  -> StatefulRoute routeParams data action model msg
@@ -253,7 +254,7 @@ buildWithSharedState :
253
254
  -> View (PagesMsg msg)
254
255
  , init : App data action routeParams -> Shared.Model -> ( model, Effect msg )
255
256
  , update : App data action routeParams -> Shared.Model -> msg -> model -> ( model, Effect msg, Maybe Shared.Msg )
256
- , subscriptions : routeParams -> Path -> Shared.Model -> model -> Sub msg
257
+ , subscriptions : routeParams -> UrlPath -> Shared.Model -> model -> Sub msg
257
258
  }
258
259
  -> Builder routeParams data action
259
260
  -> StatefulRoute routeParams data action model msg
@@ -6,7 +6,7 @@ import FatalError exposing (FatalError)
6
6
  import Html exposing (Html)
7
7
  import Pages.Flags exposing (Flags)
8
8
  import Pages.PageUrl exposing (PageUrl)
9
- import Path exposing (Path)
9
+ import UrlPath exposing (UrlPath)
10
10
  import Route exposing (Route)
11
11
  import View exposing (View)
12
12
 
@@ -17,7 +17,7 @@ type alias SharedTemplate msg sharedModel sharedData mappedMsg =
17
17
  ->
18
18
  Maybe
19
19
  { path :
20
- { path : Path
20
+ { path : UrlPath
21
21
  , query : Maybe String
22
22
  , fragment : Maybe String
23
23
  }
@@ -29,7 +29,7 @@ type alias SharedTemplate msg sharedModel sharedData mappedMsg =
29
29
  , view :
30
30
  sharedData
31
31
  ->
32
- { path : Path
32
+ { path : UrlPath
33
33
  , route : Maybe Route
34
34
  }
35
35
  -> sharedModel
@@ -37,10 +37,10 @@ type alias SharedTemplate msg sharedModel sharedData mappedMsg =
37
37
  -> View mappedMsg
38
38
  -> { body : List (Html mappedMsg), title : String }
39
39
  , data : BackendTask.BackendTask FatalError sharedData
40
- , subscriptions : Path -> sharedModel -> Sub msg
40
+ , subscriptions : UrlPath -> sharedModel -> Sub msg
41
41
  , onPageChange :
42
42
  Maybe
43
- ({ path : Path
43
+ ({ path : UrlPath
44
44
  , query : Maybe String
45
45
  , fragment : Maybe String
46
46
  }
@@ -1,3 +1,3 @@
1
- export const compatibilityKey = 17;
1
+ export const compatibilityKey = 18;
2
2
 
3
- export const packageVersion = "3.0.0-beta.40";
3
+ export const packageVersion = "3.0.0-beta.41";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "elm-pages",
3
3
  "type": "module",
4
- "version": "3.0.0-beta.40",
4
+ "version": "3.0.0-beta.41",
5
5
  "homepage": "https://elm-pages.com",
6
6
  "moduleResolution": "node",
7
7
  "description": "Type-safe static sites, written in pure elm with your own custom elm-markup syntax.",
@@ -98,28 +98,19 @@ type alias BackendTask error value =
98
98
  RawRequest error value
99
99
 
100
100
 
101
- {-| Transform a request into an arbitrary value. The same underlying HTTP requests will be performed during the build
102
- step, but mapping allows you to change the resulting values by applying functions to the results.
103
-
104
- A common use for this is to map your data into your elm-pages view:
101
+ {-| Transform a request into an arbitrary value. The same underlying task will be performed,
102
+ but mapping allows you to change the resulting values by applying functions to the results.
105
103
 
106
104
  import BackendTask
105
+ import BackendTask.Http
107
106
  import Json.Decode as Decode exposing (Decoder)
108
107
 
109
- view =
110
- BackendTask.Http.get
111
- (Secrets.succeed "https://api.github.com/repos/dillonkearns/elm-pages")
108
+ starsMessage =
109
+ BackendTask.Http.getJson
110
+ "https://api.github.com/repos/dillonkearns/elm-pages"
112
111
  (Decode.field "stargazers_count" Decode.int)
113
112
  |> BackendTask.map
114
- (\stars ->
115
- { view =
116
- \model viewForPage ->
117
- { title = "Current stars: " ++ String.fromInt stars
118
- , body = Html.text <| "⭐️ " ++ String.fromInt stars
119
- , head = []
120
- }
121
- }
122
- )
113
+ (\stars -> "⭐️ " ++ String.fromInt stars)
123
114
 
124
115
  -}
125
116
  map : (a -> b) -> BackendTask error a -> BackendTask error b
@@ -146,7 +137,7 @@ resolve =
146
137
  andThen combine
147
138
 
148
139
 
149
- {-| Turn a list of `StaticHttp.Request`s into a single one.
140
+ {-| Turn a list of `BackendTask`s into a single one.
150
141
 
151
142
  import BackendTask
152
143
  import Json.Decode as Decode exposing (Decoder)
@@ -156,10 +147,10 @@ resolve =
156
147
  , sprite : String
157
148
  }
158
149
 
159
- pokemonDetailRequest : StaticHttp.Request (List Pokemon)
150
+ pokemonDetailRequest : BackendTask (List Pokemon)
160
151
  pokemonDetailRequest =
161
- StaticHttp.get
162
- (Secrets.succeed "https://pokeapi.co/api/v2/pokemon/?limit=3")
152
+ BackendTask.Http.getJson
153
+ "https://pokeapi.co/api/v2/pokemon/?limit=3"
163
154
  (Decode.field "results"
164
155
  (Decode.list
165
156
  (Decode.map2 Tuple.pair
@@ -167,7 +158,7 @@ resolve =
167
158
  (Decode.field "url" Decode.string)
168
159
  |> Decode.map
169
160
  (\( name, url ) ->
170
- StaticHttp.get (Secrets.succeed url)
161
+ BackendTask.Http.getJson url
171
162
  (Decode.at
172
163
  [ "sprites", "front_default" ]
173
164
  Decode.string
@@ -177,7 +168,7 @@ resolve =
177
168
  )
178
169
  )
179
170
  )
180
- |> StaticHttp.andThen StaticHttp.combine
171
+ |> BackendTask.andThen BackendTask.combine
181
172
 
182
173
  -}
183
174
  combine : List (BackendTask error value) -> BackendTask error (List value)
@@ -353,7 +344,7 @@ fail error =
353
344
  ApiRoute (Err error)
354
345
 
355
346
 
356
- {-| Turn an Err into a BackendTask failure.
347
+ {-| Turn `Ok` into `BackendTask.succeed` and `Err` into `BackendTask.fail`.
357
348
  -}
358
349
  fromResult : Result error value -> BackendTask error value
359
350
  fromResult result =
@@ -523,7 +514,10 @@ map9 combineFn request1 request2 request3 request4 request5 request6 request7 re
523
514
  |> map2 (|>) request9
524
515
 
525
516
 
526
- {-| -}
517
+ {-| Ignore any recoverable error data and propagate the `FatalError`. Similar to a `Cmd` in The Elm Architecture,
518
+ a `FatalError` will not do anything except if it is returned at the top-level of your application. Read more
519
+ in the [`FatalError` docs](FatalError).
520
+ -}
527
521
  allowFatal : BackendTask { error | fatal : FatalError } data -> BackendTask FatalError data
528
522
  allowFatal backendTask =
529
523
  mapError .fatal backendTask
package/src/Head/Seo.elm CHANGED
@@ -1,13 +1,13 @@
1
1
  module Head.Seo exposing (Common, Image, article, audioPlayer, book, profile, song, summary, summaryLarge, videoPlayer, website)
2
2
 
3
- {-| <https://ogp.me/#>
4
- <https://developers.facebook.com/docs/sharing/opengraph>
3
+ {-| <https://developers.facebook.com/docs/sharing/opengraph>
5
4
 
6
5
  This module encapsulates some of the best practices for SEO for your site.
7
6
 
8
- `elm-pages` will pre-render each of the static pages (in your `content` directory) so that
7
+ `elm-pages` pre-renders the HTML for your pages (either at build-time or server-render time) so that
9
8
  web crawlers can efficiently and accurately process it. The functions in this module are for use
10
- with the `head` function that you pass to your Pages config (`Pages.application`).
9
+ with the `head` function in your `Route` modules to help you build up a set of `<meta>` tags that
10
+ includes common meta tags used for rich link previews, namely [OpenGraph tags](https://ogp.me/) and [Twitter card tags](https://developer.twitter.com/en/docs/twitter-for-websites/cards/overview/abouts-cards).
11
11
 
12
12
  import Date
13
13
  import Head
@@ -0,0 +1,127 @@
1
+ module Pages.ConcurrentSubmission exposing
2
+ ( ConcurrentSubmission, Status(..)
3
+ , map
4
+ )
5
+
6
+ {-| When you render a `Form` with the [`Pages.Form.withConcurrent`](Pages-Form#withConcurrent) `Option`, the state of in-flight and completed submissions will be available
7
+ from your `Route` module through `app.concurrentSubmissions` as a `Dict String (ConcurrentSubmission (Maybe Action))`.
8
+
9
+ You can use this state to declaratively derive Pending UI or Optimistic UI from your pending submissions (without managing the state in your `Model`, since `elm-pages`
10
+ manages form submission state for you).
11
+
12
+ You can [see the full-stack TodoMVC example](https://github.com/dillonkearns/elm-pages-v3-beta/blob/master/examples/todos/app/Route/Visibility__.elm) for a complete example of deriving Pending UI state from `app.concurrentSubmissions`.
13
+
14
+ For example, this how the TodoMVC example derives the list of new items that are being created (but are still pending).
15
+
16
+ view :
17
+ App Data ActionData RouteParams
18
+ -> Shared.Model
19
+ -> Model
20
+ -> View (PagesMsg Msg)
21
+ view app shared model =
22
+ let
23
+ pendingActions : List Action
24
+ pendingActions =
25
+ app.concurrentSubmissions
26
+ |> Dict.values
27
+ |> List.filterMap
28
+ (\{ status, payload } ->
29
+ case status of
30
+ Pages.ConcurrentSubmission.Complete _ ->
31
+ Nothing
32
+
33
+ _ ->
34
+ allForms
35
+ |> Form.Handler.run payload.fields
36
+ |> Form.toResult
37
+ |> Result.toMaybe
38
+ )
39
+
40
+ newPendingItems : List Entry
41
+ newPendingItems =
42
+ pendingActions
43
+ |> List.filterMap
44
+ (\submission ->
45
+ case submission of
46
+ Add description ->
47
+ Just
48
+ { description = description
49
+ , completed = False
50
+ , id = ""
51
+ , isPending = True
52
+ }
53
+
54
+ _ ->
55
+ -- `newPendingItems` only cares about pending Add actions. Other values will use
56
+ -- pending submissions for other types of Actions.
57
+ Nothing
58
+ )
59
+ in
60
+ itemsView app newPendingItems
61
+
62
+ allForms : Form.Handler.Handler String Action
63
+ allForms =
64
+ |> Form.Handler.init Add addItemForm
65
+ -- |> Form.Handler.with ...
66
+
67
+
68
+ type Action
69
+ = UpdateEntry ( String, String )
70
+ | Add String
71
+ | Delete String
72
+ | DeleteComplete
73
+ | Check ( Bool, String )
74
+ | CheckAll Bool
75
+
76
+ @docs ConcurrentSubmission, Status
77
+
78
+ @docs map
79
+
80
+ -}
81
+
82
+ import Pages.FormData exposing (FormData)
83
+ import Time
84
+
85
+
86
+ {-| -}
87
+ type alias ConcurrentSubmission actionData =
88
+ { status : Status actionData
89
+ , payload : FormData
90
+ , initiatedAt : Time.Posix
91
+ }
92
+
93
+
94
+ {-| The status of a `ConcurrentSubmission`.
95
+
96
+ - `Submitting` - The submission is in-flight.
97
+ - `Reloading` - The submission has completed, and the page is now reloading the `Route`'s `data` to reflect the new state. The `actionData` holds any data returned from the `Route`'s `action`.
98
+ - `Complete` - The submission has completed, and the `Route`'s `data` has since reloaded so the state reflects the refreshed state after completing this specific form submission. The `actionData` holds any data returned from the `Route`'s `action`.
99
+
100
+ -}
101
+ type Status actionData
102
+ = Submitting
103
+ | Reloading actionData
104
+ | Complete actionData
105
+
106
+
107
+ {-| `map` a `ConcurrentSubmission`. Not needed for most high-level cases since this state is managed by the `elm-pages` framework for you.
108
+ -}
109
+ map : (a -> b) -> ConcurrentSubmission a -> ConcurrentSubmission b
110
+ map mapFn fetcherState =
111
+ { status = mapStatus mapFn fetcherState.status
112
+ , payload = fetcherState.payload
113
+ , initiatedAt = fetcherState.initiatedAt
114
+ }
115
+
116
+
117
+ mapStatus : (a -> b) -> Status a -> Status b
118
+ mapStatus mapFn fetcherSubmitStatus =
119
+ case fetcherSubmitStatus of
120
+ Submitting ->
121
+ Submitting
122
+
123
+ Reloading value ->
124
+ Reloading (mapFn value)
125
+
126
+ Complete value ->
127
+ Complete (mapFn value)