elm-pages 3.0.0-beta.3 → 3.0.0-beta.30

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 (123) hide show
  1. package/README.md +10 -1
  2. package/codegen/{elm-pages-codegen.js → elm-pages-codegen.cjs} +2864 -2589
  3. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateData.elmi +0 -0
  4. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateData.elmo +0 -0
  5. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/Pages-Review-DeadCodeEliminateDataTest.elmo +0 -0
  6. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
  7. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/i.dat +0 -0
  8. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/o.dat +0 -0
  9. package/generator/dead-code-review/elm-stuff/tests-0.19.1/elm.json +1 -1
  10. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Reporter.elm.js +1327 -122
  11. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/Runner.elm.js +15295 -13271
  12. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
  13. package/generator/dead-code-review/elm-stuff/tests-0.19.1/js/node_supervisor.js +4 -4
  14. package/generator/dead-code-review/elm.json +8 -6
  15. package/generator/dead-code-review/src/Pages/Review/DeadCodeEliminateData.elm +59 -10
  16. package/generator/dead-code-review/tests/Pages/Review/DeadCodeEliminateDataTest.elm +52 -36
  17. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/d.dat +0 -0
  18. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/i.dat +0 -0
  19. package/generator/review/elm-stuff/tests-0.19.1/elm-stuff/0.19.1/o.dat +0 -0
  20. package/generator/review/elm-stuff/tests-0.19.1/elm.json +1 -1
  21. package/generator/review/elm-stuff/tests-0.19.1/js/Reporter.elm.js +1327 -122
  22. package/generator/review/elm-stuff/tests-0.19.1/js/Runner.elm.js +14621 -12637
  23. package/generator/review/elm-stuff/tests-0.19.1/js/node_runner.js +1 -1
  24. package/generator/review/elm-stuff/tests-0.19.1/js/node_supervisor.js +4 -4
  25. package/generator/review/elm.json +8 -8
  26. package/generator/src/RouteBuilder.elm +113 -107
  27. package/generator/src/SharedTemplate.elm +3 -2
  28. package/generator/src/SiteConfig.elm +3 -2
  29. package/generator/src/basepath-middleware.js +3 -3
  30. package/generator/src/build.js +123 -87
  31. package/generator/src/cli.js +256 -77
  32. package/generator/src/codegen.js +29 -27
  33. package/generator/src/compatibility-key.js +3 -0
  34. package/generator/src/compile-elm.js +25 -25
  35. package/generator/src/config.js +39 -0
  36. package/generator/src/copy-dir.js +2 -2
  37. package/generator/src/dev-server.js +150 -133
  38. package/generator/src/dir-helpers.js +9 -26
  39. package/generator/src/elm-codegen.js +5 -4
  40. package/generator/src/elm-file-constants.js +2 -3
  41. package/generator/src/error-formatter.js +12 -11
  42. package/generator/src/file-helpers.js +3 -4
  43. package/generator/src/generate-template-module-connector.js +23 -22
  44. package/generator/src/init.js +9 -8
  45. package/generator/src/pre-render-html.js +39 -28
  46. package/generator/src/render-test.js +109 -0
  47. package/generator/src/render-worker.js +25 -28
  48. package/generator/src/render.js +322 -142
  49. package/generator/src/request-cache.js +252 -163
  50. package/generator/src/rewrite-client-elm-json.js +5 -5
  51. package/generator/src/rewrite-elm-json.js +7 -7
  52. package/generator/src/route-codegen-helpers.js +16 -31
  53. package/generator/src/seo-renderer.js +12 -7
  54. package/generator/src/vite-utils.js +77 -0
  55. package/generator/static-code/hmr.js +79 -13
  56. package/generator/template/app/Api.elm +6 -5
  57. package/generator/template/app/Effect.elm +123 -0
  58. package/generator/template/app/ErrorPage.elm +37 -6
  59. package/generator/template/app/Route/Index.elm +17 -10
  60. package/generator/template/app/Shared.elm +24 -47
  61. package/generator/template/app/Site.elm +19 -6
  62. package/generator/template/app/View.elm +1 -8
  63. package/generator/template/elm-tooling.json +0 -3
  64. package/generator/template/elm.json +34 -25
  65. package/generator/template/package.json +10 -4
  66. package/package.json +23 -22
  67. package/src/ApiRoute.elm +199 -61
  68. package/src/BackendTask/Custom.elm +325 -0
  69. package/src/BackendTask/Env.elm +90 -0
  70. package/src/{DataSource → BackendTask}/File.elm +128 -43
  71. package/src/{DataSource → BackendTask}/Glob.elm +136 -125
  72. package/src/BackendTask/Http.elm +673 -0
  73. package/src/{DataSource → BackendTask}/Internal/Glob.elm +1 -1
  74. package/src/BackendTask/Internal/Request.elm +28 -0
  75. package/src/BackendTask/Random.elm +79 -0
  76. package/src/BackendTask/Time.elm +47 -0
  77. package/src/BackendTask.elm +537 -0
  78. package/src/FatalError.elm +89 -0
  79. package/src/Form/Field.elm +21 -9
  80. package/src/Form/FieldView.elm +94 -14
  81. package/src/Form.elm +275 -400
  82. package/src/Head.elm +237 -7
  83. package/src/HtmlPrinter.elm +7 -3
  84. package/src/Internal/ApiRoute.elm +7 -5
  85. package/src/PageServerResponse.elm +6 -1
  86. package/src/Pages/FormState.elm +6 -5
  87. package/src/Pages/GeneratorProgramConfig.elm +15 -0
  88. package/src/Pages/Internal/FatalError.elm +5 -0
  89. package/src/Pages/Internal/Form.elm +21 -1
  90. package/src/Pages/{Msg.elm → Internal/Msg.elm} +26 -16
  91. package/src/Pages/Internal/Platform/Cli.elm +507 -763
  92. package/src/Pages/Internal/Platform/CompatibilityKey.elm +6 -0
  93. package/src/Pages/Internal/Platform/Effect.elm +1 -2
  94. package/src/Pages/Internal/Platform/GeneratorApplication.elm +373 -0
  95. package/src/Pages/Internal/Platform/StaticResponses.elm +73 -270
  96. package/src/Pages/Internal/Platform/ToJsPayload.elm +4 -7
  97. package/src/Pages/Internal/Platform.elm +215 -102
  98. package/src/Pages/Internal/Script.elm +17 -0
  99. package/src/Pages/Internal/StaticHttpBody.elm +35 -1
  100. package/src/Pages/Manifest.elm +29 -4
  101. package/src/Pages/PageUrl.elm +23 -9
  102. package/src/Pages/ProgramConfig.elm +14 -10
  103. package/src/Pages/Script.elm +109 -0
  104. package/src/Pages/SiteConfig.elm +3 -2
  105. package/src/Pages/StaticHttp/Request.elm +2 -2
  106. package/src/Pages/StaticHttpRequest.elm +23 -98
  107. package/src/PagesMsg.elm +92 -0
  108. package/src/Path.elm +16 -19
  109. package/src/QueryParams.elm +21 -172
  110. package/src/RequestsAndPending.elm +8 -19
  111. package/src/Result/Extra.elm +26 -0
  112. package/src/Scaffold/Form.elm +484 -0
  113. package/src/Scaffold/Route.elm +1376 -0
  114. package/src/Server/Request.elm +43 -37
  115. package/src/Server/Session.elm +34 -34
  116. package/src/Server/SetCookie.elm +1 -1
  117. package/src/Test/Html/Internal/ElmHtml/ToString.elm +8 -9
  118. package/src/DataSource/Env.elm +0 -38
  119. package/src/DataSource/Http.elm +0 -446
  120. package/src/DataSource/Internal/Request.elm +0 -20
  121. package/src/DataSource/Port.elm +0 -90
  122. package/src/DataSource.elm +0 -538
  123. package/src/Pages/Generate.elm +0 -800
@@ -1,11 +1,9 @@
1
- module.exports = { gather };
2
-
3
1
  /** @typedef { { type: 'root'; keyValuePair: [string, string] } } RootTagModifier */
4
2
 
5
3
  /**
6
4
  * @param {( SeoTag | RootTagModifier )[]} tags
7
5
  */
8
- function gather(tags) {
6
+ export function gather(tags) {
9
7
  const withoutRootModifiers = tags.flatMap((value) => {
10
8
  if (value.type === "root") {
11
9
  return [];
@@ -43,11 +41,16 @@ function headTag(rootModifiers) {
43
41
 
44
42
  function toString(/** @type { SeoTag[] } */ tags) {
45
43
  return tags
46
- .map((headTag) => {
44
+ .flatMap((headTag) => {
47
45
  if (headTag.type === "head") {
48
- return appendTag(headTag);
46
+ return [appendTag(headTag)];
49
47
  } else if (headTag.type === "json-ld") {
50
- return appendJsonLdTag(headTag);
48
+ return [appendJsonLdTag(headTag)];
49
+ } else if (headTag.type === "stripped") {
50
+ console.warn(
51
+ `WARNING: Head.nonLoadingTag value ignored because it used a loading tag: ${headTag.message}`
52
+ );
53
+ return [];
51
54
  } else {
52
55
  throw new Error(`Unknown tag type ${JSON.stringify(headTag)}`);
53
56
  }
@@ -55,7 +58,7 @@ function toString(/** @type { SeoTag[] } */ tags) {
55
58
  .join("");
56
59
  }
57
60
 
58
- /** @typedef {HeadTag | JsonLdTag} SeoTag */
61
+ /** @typedef {HeadTag | JsonLdTag | StrippedTag} SeoTag */
59
62
 
60
63
  /** @typedef {{ name: string; attributes: string[][]; type: 'head' }} HeadTag */
61
64
  function appendTag(/** @type {HeadTag} */ tagDetails) {
@@ -66,6 +69,8 @@ function appendTag(/** @type {HeadTag} */ tagDetails) {
66
69
  }
67
70
 
68
71
  /** @typedef {{ contents: Object; type: 'json-ld' }} JsonLdTag */
72
+ /** @typedef {{ message: string; type: 'stripped' }} StrippedTag */
73
+
69
74
  function appendJsonLdTag(/** @type {JsonLdTag} */ tagDetails) {
70
75
  return `<script type="application/ld+json">
71
76
  ${JSON.stringify(tagDetails.contents)}
@@ -0,0 +1,77 @@
1
+ /** This code is from https://github.com/sveltejs/kit/blob/3b457f67d4d7c59fc63bb3f600a490e4dacc2e62/packages/kit/src/exports/vite/utils.js */
2
+
3
+ /**
4
+ * @param {...import('vite').UserConfig} configs
5
+ * @returns {import('vite').UserConfig}
6
+ */
7
+ export function merge_vite_configs(...configs) {
8
+ return deep_merge(
9
+ ...configs.map((config) => ({
10
+ ...config,
11
+ resolve: {
12
+ ...config.resolve,
13
+ alias: normalize_alias(config.resolve?.alias || {}),
14
+ },
15
+ }))
16
+ );
17
+ }
18
+
19
+ /**
20
+ * Takes zero or more objects and returns a new object that has all the values
21
+ * deeply merged together. None of the original objects will be mutated at any
22
+ * level, and the returned object will have no references to the original
23
+ * objects at any depth. If there's a conflict the last one wins, except for
24
+ * arrays which will be combined.
25
+ * @param {...Object} objects
26
+ * @returns {Record<string, any>} the merged object
27
+ */
28
+ function deep_merge(...objects) {
29
+ const result = {};
30
+ /** @type {string[]} */
31
+ objects.forEach((o) => merge_into(result, o));
32
+ return result;
33
+ }
34
+
35
+ /**
36
+ * normalize kit.vite.resolve.alias as an array
37
+ * @param {import('vite').AliasOptions} o
38
+ * @returns {import('vite').Alias[]}
39
+ */
40
+ function normalize_alias(o) {
41
+ if (Array.isArray(o)) return o;
42
+ return Object.entries(o).map(([find, replacement]) => ({
43
+ find,
44
+ replacement,
45
+ }));
46
+ }
47
+
48
+ /**
49
+ * Merges b into a, recursively, mutating a.
50
+ * @param {Record<string, any>} a
51
+ * @param {Record<string, any>} b
52
+ */
53
+ function merge_into(a, b) {
54
+ /**
55
+ * Checks for "plain old Javascript object", typically made as an object
56
+ * literal. Excludes Arrays and built-in types like Buffer.
57
+ * @param {any} x
58
+ */
59
+ const is_plain_object = (x) =>
60
+ typeof x === "object" && x.constructor === Object;
61
+
62
+ for (const prop in b) {
63
+ if (is_plain_object(b[prop])) {
64
+ if (!is_plain_object(a[prop])) {
65
+ a[prop] = {};
66
+ }
67
+ merge_into(a[prop], b[prop]);
68
+ } else if (Array.isArray(b[prop])) {
69
+ if (!Array.isArray(a[prop])) {
70
+ a[prop] = [];
71
+ }
72
+ a[prop].push(...b[prop]);
73
+ } else {
74
+ a[prop] = b[prop];
75
+ }
76
+ }
77
+ }
@@ -5,15 +5,69 @@ var eventSource = null;
5
5
  let updateAppContentJson = new Promise((resolve, reject) => resolve(() => {}));
6
6
 
7
7
  function connect(sendContentJsonPort, initialErrorPage) {
8
+ let reconnectFrequencySeconds = 1;
9
+ // reconnect logic based on: https://stackoverflow.com/a/61148682/383983
8
10
  // Listen for the server to tell us that an HMR update is available
9
- eventSource = new EventSource("/stream");
10
- window.reloadOnOk = initialErrorPage;
11
- if (initialErrorPage) {
12
- handleEvent(sendContentJsonPort, { data: "content.dat" });
11
+ function waitFunc() {
12
+ return reconnectFrequencySeconds * 1000;
13
13
  }
14
- eventSource.onmessage = async function (evt) {
15
- handleEvent(sendContentJsonPort, evt);
16
- };
14
+ function tryToSetupFunc() {
15
+ setupEventSource();
16
+ reconnectFrequencySeconds *= 2;
17
+ if (reconnectFrequencySeconds >= 8) {
18
+ reconnectFrequencySeconds = 8;
19
+ }
20
+ }
21
+ function reconnectFunc() {
22
+ console.log(
23
+ `Attempting dev server reconnect in ${reconnectFrequencySeconds}...`
24
+ );
25
+ setTimeout(tryToSetupFunc, waitFunc());
26
+ }
27
+ function setupEventSource() {
28
+ eventSource = new EventSource("/stream");
29
+ window.reloadOnOk = initialErrorPage;
30
+
31
+ try {
32
+ if (initialErrorPage) {
33
+ handleEvent(sendContentJsonPort, { data: "content.dat" });
34
+ }
35
+ } catch (e) {}
36
+ eventSource.onopen = async function () {
37
+ hideError();
38
+ reconnectFrequencySeconds = 1;
39
+ };
40
+ eventSource.onerror = async function (evt) {
41
+ eventSource && eventSource.close();
42
+ reconnectFunc();
43
+
44
+ showReconnectBanner();
45
+ };
46
+ eventSource.onmessage = async function (evt) {
47
+ handleEvent(sendContentJsonPort, evt);
48
+ };
49
+ }
50
+
51
+ setupEventSource();
52
+ }
53
+
54
+ function showReconnectBanner() {
55
+ showError({
56
+ type: "compile-errors",
57
+ errors: [
58
+ {
59
+ path: "",
60
+ name: "",
61
+ problems: [
62
+ {
63
+ title: "",
64
+ // region: "",
65
+ message: ["Dev server is disconnected..."],
66
+ },
67
+ ],
68
+ },
69
+ ],
70
+ });
17
71
  }
18
72
 
19
73
  async function handleEvent(sendContentJsonPort, evt) {
@@ -28,8 +82,7 @@ async function handleEvent(sendContentJsonPort, evt) {
28
82
 
29
83
  try {
30
84
  await fetchContentJson;
31
- const elmJsResponse = await elmJsRequest;
32
- thenApplyHmr(elmJsResponse);
85
+ thenApplyHmr(await elmJsRequest);
33
86
  } catch (errorJson) {
34
87
  if (typeof errorJson === "string") {
35
88
  errorJson = JSON.parse(errorJson);
@@ -116,8 +169,7 @@ var myDisposeCallback = function () {
116
169
  var module = {
117
170
  hot: {
118
171
  accept: async function () {
119
- const sendInUpdatedContentJson = await updateAppContentJson;
120
- sendInUpdatedContentJson();
172
+ (await updateAppContentJson)();
121
173
  },
122
174
 
123
175
  dispose: function (callback) {
@@ -224,8 +276,11 @@ function htmlSanitize(str, type) {
224
276
  );
225
277
  }
226
278
 
227
- const parseHeader = (title, path) =>
228
- `-- ${title.replace("-", " ")} --------------- ${path}`;
279
+ function parseHeader(title, path) {
280
+ return `-- ${(title || "ERROR").replace("-", " ")} --------------- ${
281
+ path || ""
282
+ }`;
283
+ }
229
284
 
230
285
  /*
231
286
  |-------------------------------------------------------------------------------
@@ -253,6 +308,14 @@ const parseConsoleErrors =
253
308
  * */
254
309
  (info) => {
255
310
  if (info.rule) {
311
+ if (info.details) {
312
+ return joinMessage(
313
+ info.details.reduce(consoleMsg, {
314
+ error: [consoleHeader(info.rule, path)],
315
+ style: [styleColor("blue")],
316
+ })
317
+ );
318
+ }
256
319
  return joinMessage(
257
320
  info.formatted.reduce(consoleMsg, {
258
321
  error: [consoleHeader(info.rule, path)],
@@ -313,6 +376,9 @@ const parseHtmlErrors = (path) => (info) => {
313
376
  if (info.rule) {
314
377
  return info.formatted.reduce(htmlMsg, htmlHeader(info.rule, path));
315
378
  } else {
379
+ if (info.details) {
380
+ return info.details.reduce(htmlMsg, htmlHeader(info.title, path));
381
+ }
316
382
  return info.message.reduce(htmlMsg, htmlHeader(info.title, path));
317
383
  }
318
384
  };
@@ -1,16 +1,17 @@
1
1
  module Api exposing (routes)
2
2
 
3
- import ApiRoute exposing (ApiRoute)
4
- import DataSource exposing (DataSource)
3
+ import ApiRoute
4
+ import BackendTask exposing (BackendTask)
5
+ import FatalError exposing (FatalError)
5
6
  import Html exposing (Html)
6
7
  import Pages.Manifest as Manifest
7
8
  import Route exposing (Route)
8
9
 
9
10
 
10
11
  routes :
11
- DataSource (List Route)
12
- -> (Html Never -> String)
13
- -> List (ApiRoute ApiRoute.Response)
12
+ BackendTask FatalError (List Route)
13
+ -> (Maybe { indent : Int, newLines : Bool } -> Html Never -> String)
14
+ -> List (ApiRoute.ApiRoute ApiRoute.Response)
14
15
  routes getStaticRoutes htmlToString =
15
16
  []
16
17
 
@@ -0,0 +1,123 @@
1
+ module Effect exposing (Effect(..), batch, fromCmd, map, none, perform)
2
+
3
+ import Browser.Navigation
4
+ import Form.FormData exposing (FormData)
5
+ import Http
6
+ import Json.Decode as Decode
7
+ import Pages.Fetcher
8
+ import Url exposing (Url)
9
+
10
+
11
+ type Effect msg
12
+ = None
13
+ | Cmd (Cmd msg)
14
+ | Batch (List (Effect msg))
15
+ | SetField { formId : String, name : String, value : String }
16
+ | FetchRouteData
17
+ { data : Maybe FormData
18
+ , toMsg : Result Http.Error Url -> msg
19
+ }
20
+ | Submit
21
+ { values : FormData
22
+ , toMsg : Result Http.Error Url -> msg
23
+ }
24
+ | SubmitFetcher (Pages.Fetcher.Fetcher msg)
25
+
26
+
27
+ type alias RequestInfo =
28
+ { contentType : String
29
+ , body : String
30
+ }
31
+
32
+
33
+ none : Effect msg
34
+ none =
35
+ None
36
+
37
+
38
+ batch : List (Effect msg) -> Effect msg
39
+ batch =
40
+ Batch
41
+
42
+
43
+ fromCmd : Cmd msg -> Effect msg
44
+ fromCmd =
45
+ Cmd
46
+
47
+
48
+ map : (a -> b) -> Effect a -> Effect b
49
+ map fn effect =
50
+ case effect of
51
+ None ->
52
+ None
53
+
54
+ Cmd cmd ->
55
+ Cmd (Cmd.map fn cmd)
56
+
57
+ Batch list ->
58
+ Batch (List.map (map fn) list)
59
+
60
+ FetchRouteData fetchInfo ->
61
+ FetchRouteData
62
+ { data = fetchInfo.data
63
+ , toMsg = fetchInfo.toMsg >> fn
64
+ }
65
+
66
+ Submit fetchInfo ->
67
+ Submit
68
+ { values = fetchInfo.values
69
+ , toMsg = fetchInfo.toMsg >> fn
70
+ }
71
+
72
+ SetField info ->
73
+ SetField info
74
+
75
+ SubmitFetcher fetcher ->
76
+ fetcher
77
+ |> Pages.Fetcher.map fn
78
+ |> SubmitFetcher
79
+
80
+
81
+ perform :
82
+ { fetchRouteData :
83
+ { data : Maybe FormData
84
+ , toMsg : Result Http.Error Url -> pageMsg
85
+ }
86
+ -> Cmd msg
87
+ , submit :
88
+ { values : FormData
89
+ , toMsg : Result Http.Error Url -> pageMsg
90
+ }
91
+ -> Cmd msg
92
+ , runFetcher :
93
+ Pages.Fetcher.Fetcher pageMsg
94
+ -> Cmd msg
95
+ , fromPageMsg : pageMsg -> msg
96
+ , key : Browser.Navigation.Key
97
+ , setField : { formId : String, name : String, value : String } -> Cmd msg
98
+ }
99
+ -> Effect pageMsg
100
+ -> Cmd msg
101
+ perform ({ fromPageMsg, key } as helpers) effect =
102
+ case effect of
103
+ None ->
104
+ Cmd.none
105
+
106
+ Cmd cmd ->
107
+ Cmd.map fromPageMsg cmd
108
+
109
+ SetField info ->
110
+ helpers.setField info
111
+
112
+ Batch list ->
113
+ Cmd.batch (List.map (perform helpers) list)
114
+
115
+ FetchRouteData fetchInfo ->
116
+ helpers.fetchRouteData
117
+ fetchInfo
118
+
119
+ Submit record ->
120
+ helpers.submit record
121
+
122
+ SubmitFetcher record ->
123
+ helpers.runFetcher record
@@ -1,6 +1,36 @@
1
- module ErrorPage exposing (ErrorPage(..), internalError, notFound, statusCode, view)
1
+ module ErrorPage exposing (ErrorPage(..), Model, Msg, head, init, internalError, notFound, statusCode, update, view)
2
2
 
3
+ import Effect exposing (Effect)
4
+ import Head
3
5
  import Html exposing (Html)
6
+ import View exposing (View)
7
+
8
+
9
+ type Msg
10
+ = NoOp
11
+
12
+
13
+ type alias Model =
14
+ {}
15
+
16
+
17
+ init : ErrorPage -> ( Model, Effect Msg )
18
+ init errorPage =
19
+ ( {}
20
+ , Effect.none
21
+ )
22
+
23
+
24
+ update : ErrorPage -> Msg -> Model -> ( Model, Effect Msg )
25
+ update errorPage msg model =
26
+ case msg of
27
+ NoOp ->
28
+ ( {}, Effect.none )
29
+
30
+
31
+ head : ErrorPage -> List Head.Tag
32
+ head errorPage =
33
+ []
4
34
 
5
35
 
6
36
  type ErrorPage
@@ -18,13 +48,14 @@ internalError =
18
48
  InternalError
19
49
 
20
50
 
21
- view : ErrorPage -> { body : Html msg, title : String }
22
- view error =
51
+ view : ErrorPage -> Model -> View Msg
52
+ view error model =
23
53
  { body =
24
- Html.div []
25
- [ Html.text "Hi! This is a NotFound error"
54
+ [ Html.div []
55
+ [ Html.p [] [ Html.text "Page not found. Maybe try another URL?" ]
26
56
  ]
27
- , title = "Error"
57
+ ]
58
+ , title = "Page Not Found"
28
59
  }
29
60
 
30
61
 
@@ -1,14 +1,17 @@
1
- module Route.Index exposing (Data, Model, Msg, route)
1
+ module Route.Index exposing (ActionData, Data, Model, Msg, route)
2
2
 
3
- import DataSource exposing (DataSource)
3
+ import BackendTask exposing (BackendTask)
4
+ import FatalError exposing (FatalError)
4
5
  import Head
5
6
  import Head.Seo as Seo
6
7
  import Html
7
- import Html.Attributes as Attr
8
+ import Html.Styled.Attributes as Attr
9
+ import PagesMsg exposing (PagesMsg)
8
10
  import Pages.PageUrl exposing (PageUrl)
9
11
  import Pages.Url
10
12
  import Path
11
- import RouteBuilder exposing (StatelessRoute, StaticPayload)
13
+ import Route
14
+ import RouteBuilder exposing (StatefulRoute, StatelessRoute, App)
12
15
  import Shared
13
16
  import View exposing (View)
14
17
 
@@ -25,7 +28,7 @@ type alias RouteParams =
25
28
  {}
26
29
 
27
30
 
28
- type alias Data =
31
+ type alias ActionData =
29
32
  {}
30
33
 
31
34
 
@@ -38,13 +41,17 @@ route =
38
41
  |> RouteBuilder.buildNoState { view = view }
39
42
 
40
43
 
41
- data : DataSource Data
44
+ type alias Data =
45
+ ()
46
+
47
+
48
+ data : BackendTask FatalError Data
42
49
  data =
43
- DataSource.succeed Data
50
+ BackendTask.succeed ()
44
51
 
45
52
 
46
53
  head :
47
- StaticPayload Data ActionData RouteParams
54
+ App Data ActionData RouteParams
48
55
  -> List Head.Tag
49
56
  head static =
50
57
  Seo.summary
@@ -66,8 +73,8 @@ head static =
66
73
  view :
67
74
  Maybe PageUrl
68
75
  -> Shared.Model
69
- -> StaticPayload Data ActionData RouteParams
70
- -> View Msg
76
+ -> App Data ActionData RouteParams
77
+ -> View (PagesMsg Msg)
71
78
  view maybeUrl sharedModel static =
72
79
  { title = "elm-pages is running"
73
80
  , body =
@@ -1,9 +1,9 @@
1
1
  module Shared exposing (Data, Model, Msg(..), SharedMsg(..), template)
2
2
 
3
- import Browser.Navigation
4
- import DataSource
3
+ import BackendTask exposing (BackendTask)
4
+ import Effect exposing (Effect)
5
+ import FatalError exposing (FatalError)
5
6
  import Html exposing (Html)
6
- import Html.Events
7
7
  import Pages.Flags
8
8
  import Pages.PageUrl exposing (PageUrl)
9
9
  import Path exposing (Path)
@@ -19,13 +19,16 @@ template =
19
19
  , view = view
20
20
  , data = data
21
21
  , subscriptions = subscriptions
22
- , onPageChange = Nothing
22
+ , onPageChange = Just OnPageChange
23
23
  }
24
24
 
25
25
 
26
26
  type Msg
27
- = SharedMsg SharedMsg
28
- | MenuClicked
27
+ = OnPageChange
28
+ { path : Path
29
+ , query : Maybe String
30
+ , fragment : Maybe String
31
+ }
29
32
 
30
33
 
31
34
  type alias Data =
@@ -37,13 +40,12 @@ type SharedMsg
37
40
 
38
41
 
39
42
  type alias Model =
40
- { showMenu : Bool
43
+ { showMobileMenu : Bool
41
44
  }
42
45
 
43
46
 
44
47
  init :
45
- Maybe Browser.Navigation.Key
46
- -> Pages.Flags.Flags
48
+ Pages.Flags.Flags
47
49
  ->
48
50
  Maybe
49
51
  { path :
@@ -54,21 +56,18 @@ init :
54
56
  , metadata : route
55
57
  , pageUrl : Maybe PageUrl
56
58
  }
57
- -> ( Model, Cmd Msg )
58
- init navigationKey flags maybePagePath =
59
- ( { showMenu = False }
60
- , Cmd.none
59
+ -> ( Model, Effect Msg )
60
+ init flags maybePagePath =
61
+ ( { showMobileMenu = False }
62
+ , Effect.none
61
63
  )
62
64
 
63
65
 
64
- update : Msg -> Model -> ( Model, Cmd Msg )
66
+ update : Msg -> Model -> ( Model, Effect Msg )
65
67
  update msg model =
66
68
  case msg of
67
- SharedMsg globalMsg ->
68
- ( model, Cmd.none )
69
-
70
- MenuClicked ->
71
- ( { model | showMenu = not model.showMenu }, Cmd.none )
69
+ OnPageChange _ ->
70
+ ( { model | showMobileMenu = False }, Effect.none )
72
71
 
73
72
 
74
73
  subscriptions : Path -> Model -> Sub Msg
@@ -76,9 +75,9 @@ subscriptions _ _ =
76
75
  Sub.none
77
76
 
78
77
 
79
- data : DataSource.DataSource Data
78
+ data : BackendTask FatalError Data
80
79
  data =
81
- DataSource.succeed ()
80
+ BackendTask.succeed ()
82
81
 
83
82
 
84
83
  view :
@@ -90,32 +89,10 @@ view :
90
89
  -> Model
91
90
  -> (Msg -> msg)
92
91
  -> View msg
93
- -> { body : Html msg, title : String }
94
- view sharedData page model toMsg pageView =
92
+ -> { body : List (Html msg), title : String }
93
+ view stars page model toMsg pageView =
95
94
  { body =
96
- Html.div []
97
- [ Html.nav []
98
- [ Html.button
99
- [ Html.Events.onClick MenuClicked ]
100
- [ Html.text
101
- (if model.showMenu then
102
- "Close Menu"
103
-
104
- else
105
- "Open Menu"
106
- )
107
- ]
108
- , if model.showMenu then
109
- Html.ul []
110
- [ Html.li [] [ Html.text "Menu item 1" ]
111
- , Html.li [] [ Html.text "Menu item 2" ]
112
- ]
113
-
114
- else
115
- Html.text ""
116
- ]
117
- |> Html.map toMsg
118
- , Html.main_ [] pageView.body
119
- ]
95
+ [ Html.div [] pageView.body
96
+ ]
120
97
  , title = pageView.title
121
98
  }
@@ -1,19 +1,32 @@
1
- module Site exposing (config)
1
+ module Site exposing (canonicalUrl, config)
2
2
 
3
- import DataSource exposing (DataSource)
3
+ import BackendTask exposing (BackendTask)
4
+ import FatalError exposing (FatalError)
4
5
  import Head
6
+ import MimeType
7
+ import Pages.Url
5
8
  import SiteConfig exposing (SiteConfig)
6
9
 
7
10
 
8
11
  config : SiteConfig
9
12
  config =
10
- { canonicalUrl = "https://elm-pages.com"
13
+ { canonicalUrl = canonicalUrl
11
14
  , head = head
12
15
  }
13
16
 
14
17
 
15
- head : DataSource (List Head.Tag)
18
+ head : BackendTask FatalError (List Head.Tag)
16
19
  head =
17
- [ Head.sitemapLink "/sitemap.xml"
20
+ [ Head.metaName "viewport" (Head.raw "width=device-width,initial-scale=1")
21
+ , Head.metaName "mobile-web-app-capable" (Head.raw "yes")
22
+ , Head.metaName "theme-color" (Head.raw "#ffffff")
23
+ , Head.metaName "apple-mobile-web-app-capable" (Head.raw "yes")
24
+ , Head.metaName "apple-mobile-web-app-status-bar-style" (Head.raw "black-translucent")
25
+ , Head.sitemapLink "/sitemap.xml"
18
26
  ]
19
- |> DataSource.succeed
27
+ |> BackendTask.succeed
28
+
29
+
30
+ canonicalUrl : String
31
+ canonicalUrl =
32
+ "https://elm-pages.com"